#!/usr/bin/env node "use strict"; const assert = require("node:assert"); const fs = require("node:fs"); const path = require("node:path"); const ROOT = process.cwd(); const OUTPUT_DIR = path.join(ROOT, "tmp", "task544-weknora-provider-bridge-static-smoke"); const RESULT_PATH = path.join(OUTPUT_DIR, "result.json"); function read(relativePath) { return fs.readFileSync(path.join(ROOT, relativePath), "utf8"); } function assertContains(content, needle, label) { assert(content.includes(needle), `${label} 缺少: ${needle}`); } function assertNotContains(content, needle, label) { assert(!content.includes(needle), `${label} 不应包含: ${needle}`); } function main() { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); const route = read("rust/crates/mnote-web/src/routes/knowledge_rag.rs"); const hermesKnowledge = read("rust/crates/mnote-web/src/hermes_tools/knowledge_rag.rs"); const manifest = read("rust/crates/mnote-web/src/hermes_tools/manifest.rs"); const toolRoute = read("rust/crates/mnote-web/src/routes/hermes_tools.rs"); const ui = read("rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js"); assertContains(route, 'const DEFAULT_KNOWLEDGE_PROVIDER: &str = "weknora";', "provider boundary"); assertContains(route, 'const LEGACY_KNOWLEDGE_PROVIDER: &str = "lightrag_legacy";', "legacy provider boundary"); assertContains(route, '"/knowledge-search"', "WeKnora endpoint"); assertContains(route, '"knowledge_base_ids"', "WeKnora request shape"); assertContains(route, '"knowledge_ids"', "WeKnora request shape"); assertContains(route, '"match_count"', "WeKnora request shape"); assertContains(route, '"providerConfig": knowledge_provider_config()', "status provider config"); assertContains(route, '"health": weknora_health(&context).await', "WeKnora health"); assertContains(route, '"registry": registry', "status registry"); assertContains(route, '"providerIds"', "WeKnora reference mapping"); assertContains(route, '"providerFilenameIsNotLocalPath": true', "WeKnora locator diagnostics"); assertContains(route, '"locatorDegraded": locator_degraded', "WeKnora degraded locator"); assertContains(route, '"reference": chunk', "WeKnora raw reference retention"); assertContains(route, 'Value::Null', "WeKnora filePath null guard"); assertContains(route, '"chunkMetadata"', "WeKnora metadata retention"); assertContains(route, '"imageInfo"', "WeKnora image info retention"); assertContains(route, '"parentChunk"', "WeKnora parent chunk retention"); assertContains(route, '"subChunks"', "WeKnora sub chunk retention"); assertContains(route, "ingest_weknora_registry_only", "WeKnora ingest branch"); assertContains(route, "upload_weknora_file", "WeKnora provider upload"); assertContains(route, '/knowledge-bases/{}/knowledge/file', "WeKnora file ingest endpoint"); assertContains(route, 'reqwest::multipart::Form::new()', "WeKnora multipart upload"); assertContains(route, '"fileName"', "WeKnora preserves root relative path"); assertContains(route, '"mnote_source_root_relative_path"', "WeKnora source metadata"); assertContains(route, '"scanSkipped": false', "WeKnora ingest uses provider upload"); assertContains(route, '"scanSkipReason": "weknora_provider_direct_upload"', "WeKnora ingest no LightRAG scan"); assertContains(route, '"pending_provider_ingest_missing_kb"', "WeKnora ingest missing kb pending"); assertContains(route, '"pending_provider_ingest"', "WeKnora ingest provider pending"); assertContains(route, '"registry_only"', "WeKnora ingest registry mapping"); assertContains(route, '"provider_mapped"', "WeKnora provider id mapping"); assertContains(route, "delete_weknora_registry_source", "WeKnora delete branch"); assertContains(route, '"providerDeleteAttempted": false', "WeKnora delete no provider call"); assertContains(route, '"localFileDeleted": false', "WeKnora delete keeps local file"); assertContains(route, '"pending_provider_delete"', "WeKnora delete pending provider marker"); assertContains(route, "weknora_section_context_payload", "WeKnora section-context branch"); assertContains(route, '"sidecarRead": false', "WeKnora section-context no LightRAG sidecar"); assertContains(route, '"degradedReason": "weknora_local_source_context_without_provider_chunks"', "WeKnora section-context degraded local fallback"); assertContains(route, 'if active_knowledge_provider() == DEFAULT_KNOWLEDGE_PROVIDER {\n return ingest_weknora_registry_only', "WeKnora ingest bypasses LightRAG staging"); assertContains(route, 'if active_knowledge_provider() == DEFAULT_KNOWLEDGE_PROVIDER {\n return delete_weknora_registry_source', "WeKnora delete bypasses LightRAG delete"); assertContains(route, "let payload = weknora_section_context_payload", "WeKnora section-context bypasses sidecar"); for (const toolName of [ "mnote.weknora.search", "mnote.weknora.list_sources", "mnote.weknora.get_source_status", "mnote.weknora.open_reference", ]) { assertContains(manifest, `"${toolName}"`, "manifest"); assertContains(toolRoute, `"${toolName}"`, "tool dispatch"); } assertContains(manifest, '"scope"', "WeKnora tool scope field"); assertContains(manifest, '"allowlist"', "WeKnora tool allowlist field"); assertContains(manifest, '"allowedRoots"', "WeKnora tool allowedRoots field"); assertContains(manifest, '"aiAccessScope"', "WeKnora tool aiAccessScope field"); assertContains(manifest, '"sourcePaths"', "WeKnora tool sourcePaths field"); assertContains(hermesKnowledge, "mnote_weknora_scope_required", "WeKnora tool scope guard"); assertNotContains(ui, "打开 LightRAG", "UI default provider copy"); assertNotContains(ui, "正在读取 LightRAG 状态", "UI default provider copy"); assertNotContains(ui, "无法连接 LightRAG 服务", "UI default provider copy"); assertContains(ui, "WeKnora", "UI provider label"); assertContains(ui, "知识库 provider", "UI neutral copy"); const result = { ok: true, checkedFiles: [ "rust/crates/mnote-web/src/routes/knowledge_rag.rs", "rust/crates/mnote-web/src/hermes_tools/knowledge_rag.rs", "rust/crates/mnote-web/src/hermes_tools/manifest.rs", "rust/crates/mnote-web/src/routes/hermes_tools.rs", "rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js", ], provider: "weknora", assertions: { providerBoundary: true, providerIds: true, locatorDegraded: true, manifestFacade: true, scopeFields: true, uiNoDefaultLightRagCopy: true, ingestNoLightRagScan: true, deleteNoLightRagDelete: true, sectionContextNoSidecar: true, }, }; fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); console.log(JSON.stringify(result, null, 2)); } main();