noteconnection 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -21
- package/README.md +260 -1626
- package/dist/src/agent_workspace.contract.parity.test.js +159 -0
- package/dist/src/agent_workspace.frontend.test.js +10388 -0
- package/dist/src/agent_workspace.locale.contract.test.js +95 -0
- package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
- package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
- package/dist/src/appimage.patchelf.test.js +113 -0
- package/dist/src/appimage.portability.test.js +156 -0
- package/dist/src/backend/FileLoader.js +18 -4
- package/dist/src/backend/FileLoader.test.js +125 -0
- package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
- package/dist/src/backend/GraphBuilder.js +66 -18
- package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
- package/dist/src/backend/GraphMetrics.js +0 -3
- package/dist/src/backend/ResourceIdentity.js +155 -0
- package/dist/src/backend/ResourceIdentity.test.js +113 -0
- package/dist/src/backend/algorithms/CycleDetection.js +0 -1
- package/dist/src/backend/algorithms/HybridEngine.js +0 -3
- package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
- package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
- package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
- package/dist/src/backend/build_dag.js +0 -1
- package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
- package/dist/src/capacitor.runtime.contract.test.js +11 -2
- package/dist/src/copy.assets.contract.test.js +130 -0
- package/dist/src/core/Graph.js +138 -42
- package/dist/src/core/Graph.test.js +74 -0
- package/dist/src/core/NoteConnection.js +2 -2
- package/dist/src/core/PathBridge.js +293 -5
- package/dist/src/core/ResourceReference.js +17 -0
- package/dist/src/desktop.godot.pack.test.js +142 -0
- package/dist/src/desktop.runtime.graph.test.js +66 -0
- package/dist/src/export/WorkspaceExportBundle.js +1174 -0
- package/dist/src/export/WorkspaceExportBundle.test.js +1541 -0
- package/dist/src/export/index.js +18 -0
- package/dist/src/export/types.js +2 -0
- package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
- package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
- package/dist/src/foundation.release.evidence.contract.test.js +524 -0
- package/dist/src/foundation.sqlite.runtime.contract.test.js +88 -0
- package/dist/src/frontend/README.md +260 -1626
- package/dist/src/frontend/agent_workspace.js +6011 -0
- package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
- package/dist/src/frontend/analysis.js +31 -4
- package/dist/src/frontend/app.js +2178 -62
- package/dist/src/frontend/focus_mode_interactions.js +33 -0
- package/dist/src/frontend/godot_future_path_renderer.js +540 -0
- package/dist/src/frontend/godot_tree_interactions.js +178 -0
- package/dist/src/frontend/graph_state.mjs +105 -0
- package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
- package/dist/src/frontend/i18n.mjs +186 -0
- package/dist/src/frontend/index.html +672 -268
- package/dist/src/frontend/knowledge_projection_contract.js +230 -0
- package/dist/src/frontend/knowledge_projection_store.js +214 -0
- package/dist/src/frontend/layout_gpu.js +12 -4
- package/dist/src/frontend/libs/path_core.js +158 -42
- package/dist/src/frontend/locales/en.json +753 -5
- package/dist/src/frontend/locales/zh.json +753 -5
- package/dist/src/frontend/main.mjs +60 -0
- package/dist/src/frontend/markdown_runtime.js +827 -0
- package/dist/src/frontend/mobile_budget_runtime.js +33 -0
- package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
- package/dist/src/frontend/mobile_identity_contract.js +221 -0
- package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
- package/dist/src/frontend/notemd.css +49 -0
- package/dist/src/frontend/notemd.html +7 -1
- package/dist/src/frontend/notemd.js +64 -0
- package/dist/src/frontend/path.html +113 -2
- package/dist/src/frontend/path_app.js +2108 -130
- package/dist/src/frontend/path_layout.mjs +143 -0
- package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
- package/dist/src/frontend/path_modules_bridge.js +486 -0
- package/dist/src/frontend/path_state.mjs +118 -0
- package/dist/src/frontend/path_styles.css +146 -0
- package/dist/src/frontend/path_worker_bridge.mjs +85 -0
- package/dist/src/frontend/reader.js +393 -33
- package/dist/src/frontend/runtime_bridge.js +67 -54
- package/dist/src/frontend/runtime_bridge.mjs +279 -0
- package/dist/src/frontend/settings.js +130 -12
- package/dist/src/frontend/simulationWorker.js +1 -1
- package/dist/src/frontend/source_manager.js +297 -22
- package/dist/src/frontend/storage_provider.js +661 -71
- package/dist/src/frontend/styles.css +2814 -72
- package/dist/src/frontend/workbench_state.mjs +101 -0
- package/dist/src/frontend/workspace_panes.js +10272 -0
- package/dist/src/frontend.locale.contract.test.js +62 -0
- package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
- package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
- package/dist/src/graph.answer.operator.contract.test.js +72 -0
- package/dist/src/index.js +6 -2
- package/dist/src/index.knowledge-root.test.js +118 -0
- package/dist/src/indexing/IndexLifecycle.js +217 -0
- package/dist/src/indexing/IndexLifecycle.test.js +73 -0
- package/dist/src/indexing/SegmentBuilder.js +64 -0
- package/dist/src/indexing/UnitBuilder.js +48 -0
- package/dist/src/indexing/types.js +2 -0
- package/dist/src/knowledge.api.contract.test.js +172 -0
- package/dist/src/knowledge_projection.contract.test.js +134 -0
- package/dist/src/knowledge_projection_store.test.js +200 -0
- package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
- package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
- package/dist/src/learning/KnowledgeLearningPlatform.js +11181 -0
- package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +745 -0
- package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
- package/dist/src/learning/KnowledgeLearningPlatform.test.js +3208 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2998 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3936 -0
- package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
- package/dist/src/learning/PublicAnswerContract.test.js +85 -0
- package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
- package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
- package/dist/src/learning/agentConversationExecution.js +211 -0
- package/dist/src/learning/agentConversationExecution.test.js +209 -0
- package/dist/src/learning/agentConversationSerialization.js +266 -0
- package/dist/src/learning/agentConversationSerialization.test.js +165 -0
- package/dist/src/learning/agentResponseBudget.js +179 -0
- package/dist/src/learning/agentResponseBudget.test.js +97 -0
- package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
- package/dist/src/learning/answerReleaseReview.js +5260 -0
- package/dist/src/learning/answerReleaseReview.test.js +4174 -0
- package/dist/src/learning/answerTaskPlan.js +473 -0
- package/dist/src/learning/api.js +2 -0
- package/dist/src/learning/conversationComposer.js +1721 -0
- package/dist/src/learning/conversationComposer.test.js +3220 -0
- package/dist/src/learning/domains/ConversationManager.js +53 -0
- package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
- package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
- package/dist/src/learning/domains/MasteryEngine.js +387 -0
- package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
- package/dist/src/learning/domains/QualityEvaluator.js +307 -0
- package/dist/src/learning/domains/TutorRouter.js +313 -0
- package/dist/src/learning/domains/index.js +33 -0
- package/dist/src/learning/domains/types.js +7 -0
- package/dist/src/learning/errors.js +29 -0
- package/dist/src/learning/evidenceContextAssembler.js +1368 -0
- package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
- package/dist/src/learning/graphAnswerCoverage.js +37 -0
- package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
- package/dist/src/learning/graphAnswerFacts.js +94 -0
- package/dist/src/learning/graphAnswerFacts.test.js +39 -0
- package/dist/src/learning/graphAnswerPlan.js +908 -0
- package/dist/src/learning/graphAnswerPlan.test.js +907 -0
- package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
- package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
- package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
- package/dist/src/learning/graphClaimMatcher.js +104 -0
- package/dist/src/learning/graphConditionedContext.js +109 -0
- package/dist/src/learning/graphConditionedContext.test.js +99 -0
- package/dist/src/learning/graphContextAssembler.js +860 -0
- package/dist/src/learning/graphContextAssembler.test.js +1033 -0
- package/dist/src/learning/graphExpansionPolicy.js +22 -0
- package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
- package/dist/src/learning/identityMetadata.test.js +26 -0
- package/dist/src/learning/index.js +29 -0
- package/dist/src/learning/mobileAnswerProjection.js +104 -0
- package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
- package/dist/src/learning/queryBackend.js +1922 -0
- package/dist/src/learning/queryBackend.test.js +976 -0
- package/dist/src/learning/ragContextPack.js +356 -0
- package/dist/src/learning/ragContextPack.test.js +311 -0
- package/dist/src/learning/ragEvidenceQuality.js +96 -0
- package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
- package/dist/src/learning/ragPublicText.js +101 -0
- package/dist/src/learning/ragPublicText.test.js +57 -0
- package/dist/src/learning/ragSufficiencyJudge.js +171 -0
- package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.js +217 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.test.js +207 -0
- package/dist/src/learning/requestNormalization.js +304 -0
- package/dist/src/learning/requestNormalization.test.js +101 -0
- package/dist/src/learning/runtimeCapability.js +4677 -0
- package/dist/src/learning/runtimeCapability.test.js +3635 -0
- package/dist/src/learning/store.js +1344 -0
- package/dist/src/learning/store.test.js +1425 -0
- package/dist/src/learning/tutorAdapter.js +2 -0
- package/dist/src/learning/types.js +2 -0
- package/dist/src/learning/vectorAccelerationAdapter.js +958 -0
- package/dist/src/learning/vectorAccelerationAdapter.test.js +412 -0
- package/dist/src/learning/workspaceHydration.js +168 -0
- package/dist/src/learning/workspaceHydration.test.js +30 -0
- package/dist/src/lfs.asset.policy.contract.test.js +153 -0
- package/dist/src/license.policy.contract.test.js +71 -0
- package/dist/src/markdown/MarkdownGateway.js +4 -0
- package/dist/src/markdown/MarkdownGateway.test.js +59 -0
- package/dist/src/memory/MemoryGovernance.js +74 -0
- package/dist/src/memory/MemoryGovernance.test.js +46 -0
- package/dist/src/memory/types.js +2 -0
- package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
- package/dist/src/middleware/SseResponseWriter.js +122 -0
- package/dist/src/middleware/SseResponseWriter.test.js +54 -0
- package/dist/src/middleware/auth.js +38 -0
- package/dist/src/middleware/auth.test.js +33 -0
- package/dist/src/middleware/body-parser.js +45 -0
- package/dist/src/middleware/cors.js +44 -0
- package/dist/src/middleware/index.js +22 -0
- package/dist/src/middleware/request-trace.js +96 -0
- package/dist/src/mobile.android.evidence.contract.test.js +146 -0
- package/dist/src/mobile.android.signing.contract.test.js +66 -0
- package/dist/src/mobile.artifact.contract.test.js +144 -0
- package/dist/src/mobile.budget.contract.test.js +90 -0
- package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
- package/dist/src/mobile.graph.parity.contract.test.js +207 -0
- package/dist/src/mobile.identity.contract.test.js +66 -0
- package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
- package/dist/src/mobile.identity.corpus.test.js +40 -0
- package/dist/src/mobile.native.recovery.contract.test.js +64 -0
- package/dist/src/mobile.pipeline.test.js +11 -1
- package/dist/src/mobile.profile.contract.test.js +225 -0
- package/dist/src/mobile.semantic.parity.test.js +92 -0
- package/dist/src/mobile_exact_analyzer.test.js +113 -0
- package/dist/src/notemd/AppConfigToml.js +6 -4
- package/dist/src/notemd/ContentGenerator.js +4 -9
- package/dist/src/notemd/FileProcessor.js +4 -9
- package/dist/src/notemd/MermaidProcessor.js +400 -50
- package/dist/src/notemd/NotemdService.js +506 -26
- package/dist/src/notemd/PromptManager.js +15 -0
- package/dist/src/notemd/Translator.js +4 -9
- package/dist/src/notemd/cli/commands.js +357 -0
- package/dist/src/notemd/cli/dispatcher.js +225 -0
- package/dist/src/notemd/cli/index.js +169 -0
- package/dist/src/notemd/cli/parser.js +68 -0
- package/dist/src/notemd/cli/types.js +2 -0
- package/dist/src/notemd/constants.js +43 -0
- package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
- package/dist/src/notemd/diagram/diagramSpec.js +79 -0
- package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
- package/dist/src/notemd/diagram/intent.js +95 -0
- package/dist/src/notemd/diagram/planner.js +71 -0
- package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
- package/dist/src/notemd/diagram/types.js +18 -0
- package/dist/src/notemd/index.js +26 -0
- package/dist/src/notemd/operations/capabilityManifest.js +23 -0
- package/dist/src/notemd/operations/cliContracts.js +17 -0
- package/dist/src/notemd/operations/configProfileCommands.js +85 -0
- package/dist/src/notemd/operations/registry.contract.test.js +95 -0
- package/dist/src/notemd/operations/registry.js +991 -0
- package/dist/src/notemd/operations/types.js +2 -0
- package/dist/src/notemd/progressReporter.js +9 -0
- package/dist/src/notemd/providerDiagnostics.js +220 -0
- package/dist/src/notemd/providerProfiles.js +42 -0
- package/dist/src/notemd/providerTemplates.js +231 -0
- package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
- package/dist/src/notemd/search/SearchManager.js +13 -0
- package/dist/src/notemd/search/SearchProvider.js +2 -0
- package/dist/src/notemd/search/TavilyProvider.js +44 -0
- package/dist/src/notemd.agent.manifest.test.js +85 -0
- package/dist/src/notemd.api.contract.test.js +14 -1
- package/dist/src/notemd.app_config_toml.test.js +2 -1
- package/dist/src/notemd.batch.workflow.test.js +117 -0
- package/dist/src/notemd.cli.e2e.test.js +136 -0
- package/dist/src/notemd.core.test.js +51 -0
- package/dist/src/notemd.diagram.pipeline.test.js +233 -0
- package/dist/src/notemd.providerTemplates.test.js +34 -0
- package/dist/src/notemd.server.integration.test.js +262 -39
- package/dist/src/notemd.workflow.pipeline.test.js +162 -0
- package/dist/src/pathbridge.handshake.contract.test.js +45 -2
- package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
- package/dist/src/pathcore.bundle.contract.test.js +8 -0
- package/dist/src/pathmode.background.contract.test.js +69 -0
- package/dist/src/pathmode.settings.api.contract.test.js +9 -0
- package/dist/src/pkg.sidecar.contract.test.js +9 -3
- package/dist/src/platform/ExportProfile.js +86 -0
- package/dist/src/platform/MobileBudget.js +11 -0
- package/dist/src/platform/PlatformCapabilities.js +59 -0
- package/dist/src/platform/PlatformCapabilities.test.js +36 -0
- package/dist/src/platform/RenderMaterializer.js +33 -0
- package/dist/src/platform/RenderMaterializer.test.js +32 -0
- package/dist/src/query_backend.external_http.integration.test.js +410 -0
- package/dist/src/reader_renderer.js +404 -3
- package/dist/src/reader_renderer.test.js +87 -0
- package/dist/src/release.godot.mirror.contract.test.js +97 -0
- package/dist/src/resources/ResourceRegistry.js +263 -0
- package/dist/src/resources/ResourceRegistry.test.js +97 -0
- package/dist/src/resources/types.js +2 -0
- package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
- package/dist/src/routes/index.js +19 -0
- package/dist/src/routes/knowledge.js +981 -0
- package/dist/src/routes/knowledgePayload.js +185 -0
- package/dist/src/routes/knowledgePayload.test.js +53 -0
- package/dist/src/routes/markdown.js +295 -0
- package/dist/src/routes/notemd.js +1321 -0
- package/dist/src/routes/registry.contract.test.js +133 -0
- package/dist/src/routes/registry.shadow.contract.test.js +22 -0
- package/dist/src/routes/render.js +248 -0
- package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
- package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
- package/dist/src/routes/settings.js +6 -0
- package/dist/src/routes/staticFiles.js +94 -0
- package/dist/src/routes/types.js +2 -0
- package/dist/src/runtime.capabilities.test.js +18 -2
- package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
- package/dist/src/server.js +10342 -1325
- package/dist/src/server.migration.test.js +584 -10
- package/dist/src/server.port.fallback.contract.test.js +63 -0
- package/dist/src/session/SessionStateStore.js +81 -0
- package/dist/src/session/SessionStateStore.test.js +58 -0
- package/dist/src/session/types.js +2 -0
- package/dist/src/settings.runtime.contract.test.js +50 -0
- package/dist/src/shared/types.contract.test.js +107 -0
- package/dist/src/shared/types.js +22 -0
- package/dist/src/sidecar.build.lock.contract.test.js +201 -0
- package/dist/src/sidecar.freshness.contract.test.js +184 -0
- package/dist/src/sidecar.replacement.boundary.contract.test.js +131 -0
- package/dist/src/sidecar.supply.readiness.contract.test.js +155 -0
- package/dist/src/simulation.worker.offline.test.js +104 -0
- package/dist/src/source_manager.loadflow.test.js +46 -0
- package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
- package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
- package/dist/src/storage.provider.contract.test.js +152 -1
- package/dist/src/tauri.frontend.build.contract.test.js +68 -0
- package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
- package/dist/src/tauri.window.evidence.execution.test.js +68 -0
- package/dist/src/utils/RuntimePaths.js +10 -13
- package/dist/src/utils/RuntimePaths.test.js +27 -0
- package/dist/src/utils/platform.js +153 -0
- package/dist/src/windows.installer.build.test.js +109 -0
- package/dist/src/windows.installer.payload.test.js +76 -0
- package/dist/src/windows.installer.runtime.test.js +69 -0
- package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
- package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
- package/dist/src/workflows/types.js +2 -0
- package/dist/src/workspace/WorkspaceRegistry.js +135 -0
- package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
- package/dist/src/workspace/types.js +2 -0
- package/package.json +80 -15
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
/**
|
|
37
|
+
* Workflow Pipeline contract test — validates the 4-stage
|
|
38
|
+
* runWorkflow pipeline (extract → wikilinks → generate → mermaid).
|
|
39
|
+
*/
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const NotemdService_1 = require("./notemd/NotemdService");
|
|
44
|
+
class TempDir {
|
|
45
|
+
constructor(prefix) { this.root = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), prefix)); }
|
|
46
|
+
file(rel, content) {
|
|
47
|
+
const p = path.join(this.root, rel);
|
|
48
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
49
|
+
fs.writeFileSync(p, content, 'utf8');
|
|
50
|
+
return p;
|
|
51
|
+
}
|
|
52
|
+
cleanup() { fs.rmSync(this.root, { recursive: true, force: true }); }
|
|
53
|
+
}
|
|
54
|
+
function defaultSettings(overrides = {}) {
|
|
55
|
+
return {
|
|
56
|
+
activeProvider: 'OpenAI',
|
|
57
|
+
searchProvider: 'duckduckgo',
|
|
58
|
+
language: 'en',
|
|
59
|
+
providers: [],
|
|
60
|
+
enableStableApiCall: true,
|
|
61
|
+
enableApiErrorDebugMode: false,
|
|
62
|
+
maxRetries: 0,
|
|
63
|
+
retryDelayMs: 0,
|
|
64
|
+
maxTokens: 256,
|
|
65
|
+
chunkWordCount: 100,
|
|
66
|
+
enableDuplicateDetection: false,
|
|
67
|
+
enableExperimentalDiagramPipeline: false,
|
|
68
|
+
enableBatchParallelism: false,
|
|
69
|
+
developerMode: false,
|
|
70
|
+
developerDiagnosticCallMode: 'runtime-stable',
|
|
71
|
+
developerDiagnosticTimeoutMs: 60000,
|
|
72
|
+
developerDiagnosticStabilityRuns: 3,
|
|
73
|
+
experimentalDiagramCompatibilityMode: 'legacy-mermaid',
|
|
74
|
+
autoMermaidFixAfterGenerate: true,
|
|
75
|
+
tavilyApiKey: '',
|
|
76
|
+
tavilyMaxResults: 5,
|
|
77
|
+
tavilySearchDepth: 'basic',
|
|
78
|
+
ddgFetchTimeout: 10000,
|
|
79
|
+
useCustomConceptNoteFolder: false,
|
|
80
|
+
conceptNoteFolder: '',
|
|
81
|
+
...overrides,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
describe('Notemd Workflow Pipeline', () => {
|
|
85
|
+
let temp;
|
|
86
|
+
let service;
|
|
87
|
+
beforeEach(() => { temp = new TempDir('notemd-workflow-'); service = new NotemdService_1.NotemdService(); });
|
|
88
|
+
afterEach(() => { temp.cleanup(); });
|
|
89
|
+
test('runWorkflow executes all 3 stages (extract → generate → mermaid) on a simple file', async () => {
|
|
90
|
+
const src = temp.file('notes/topic.md', '# Graph Theory\n\nGraph theory studies **nodes** and **edges**.\n\n```mermaid\ngraph TD\nA-->B\n```');
|
|
91
|
+
const result = await service.runWorkflow({ filePath: src }, defaultSettings());
|
|
92
|
+
expect(result.sourceFilePath).toBe(src);
|
|
93
|
+
expect(result.outputFolderPath).toContain('topic_notemd_output');
|
|
94
|
+
expect(fs.existsSync(result.outputFolderPath)).toBe(true);
|
|
95
|
+
// All 3 stages should be present (no wiki-links)
|
|
96
|
+
expect(result.stages.length).toBeGreaterThanOrEqual(3);
|
|
97
|
+
const stageNames = result.stages.map(s => s.stage);
|
|
98
|
+
expect(stageNames).toContain('extract-concepts');
|
|
99
|
+
expect(stageNames).toContain('generate-titles');
|
|
100
|
+
expect(stageNames).toContain('mermaid-fix');
|
|
101
|
+
// Extract stage should have completed
|
|
102
|
+
const extractStage = result.stages.find(s => s.stage === 'extract-concepts');
|
|
103
|
+
expect(['completed', 'error']).toContain(extractStage.status);
|
|
104
|
+
// Summary should have valid numbers
|
|
105
|
+
expect(typeof result.summary.conceptsExtracted).toBe('number');
|
|
106
|
+
expect(typeof result.summary.totalElapsedMs).toBe('number');
|
|
107
|
+
expect(result.summary.totalElapsedMs).toBeGreaterThanOrEqual(0);
|
|
108
|
+
});
|
|
109
|
+
test('runWorkflow with addWikiLinks injects wiki-links and writes _wikified file', async () => {
|
|
110
|
+
const src = temp.file('notes/test.md', '# Machine Learning\n\nMachine learning uses neural networks and deep learning.');
|
|
111
|
+
const result = await service.runWorkflow({ filePath: src, addWikiLinks: true, skipGenerate: true, skipMermaidFix: true }, defaultSettings());
|
|
112
|
+
// Wiki-links stage should be present and completed
|
|
113
|
+
const wikiStage = result.stages.find(s => s.stage === 'add-wikilinks');
|
|
114
|
+
expect(wikiStage).toBeDefined();
|
|
115
|
+
// May be 'completed' with links or 'skipped' if LLM returned no concepts
|
|
116
|
+
expect(['completed', 'skipped']).toContain(wikiStage.status);
|
|
117
|
+
// Add stage names check
|
|
118
|
+
const stageNames = result.stages.map(s => s.stage);
|
|
119
|
+
expect(stageNames).toContain('add-wikilinks');
|
|
120
|
+
expect(stageNames).not.toContain('generate-titles');
|
|
121
|
+
expect(stageNames).not.toContain('mermaid-fix');
|
|
122
|
+
});
|
|
123
|
+
test('runWorkflow with skipGenerate and skipMermaidFix only runs extract', async () => {
|
|
124
|
+
const src = temp.file('notes/simple.md', '# Simple\n\nJust a simple note.');
|
|
125
|
+
const result = await service.runWorkflow({ filePath: src, skipGenerate: true, skipMermaidFix: true }, defaultSettings());
|
|
126
|
+
// Only 1 stage should run (extract) since generate + mermaid are skipped
|
|
127
|
+
const runningStages = result.stages.filter(s => s.status !== 'skipped');
|
|
128
|
+
expect(runningStages.length).toBeGreaterThanOrEqual(1);
|
|
129
|
+
const stageNames = result.stages.map(s => s.stage);
|
|
130
|
+
expect(stageNames).toContain('extract-concepts');
|
|
131
|
+
});
|
|
132
|
+
test('runWorkflow with wikiLinksInPlace modifies source file directly', async () => {
|
|
133
|
+
const src = temp.file('notes/inplace.md', '# AI\n\nArtificial intelligence uses machine learning and deep learning algorithms.');
|
|
134
|
+
const originalContent = fs.readFileSync(src, 'utf8');
|
|
135
|
+
const result = await service.runWorkflow({ filePath: src, addWikiLinks: true, wikiLinksInPlace: true, skipGenerate: true, skipMermaidFix: true }, defaultSettings());
|
|
136
|
+
const wikiStage = result.stages.find(s => s.stage === 'add-wikilinks');
|
|
137
|
+
expect(wikiStage).toBeDefined();
|
|
138
|
+
// If wikilinks were injected in-place, file content should differ
|
|
139
|
+
if (wikiStage.status === 'completed') {
|
|
140
|
+
const newContent = fs.readFileSync(src, 'utf8');
|
|
141
|
+
// Either content changed or no concepts were found
|
|
142
|
+
expect(typeof newContent).toBe('string');
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
test('runWorkflow errors are collected per-stage without blocking other stages', async () => {
|
|
146
|
+
const src = temp.file('notes/errors.md', 'test content');
|
|
147
|
+
const result = await service.runWorkflow({ filePath: src }, defaultSettings());
|
|
148
|
+
// Each stage should report its status
|
|
149
|
+
result.stages.forEach(stage => {
|
|
150
|
+
expect(['completed', 'error', 'skipped', 'running']).toContain(stage.status);
|
|
151
|
+
});
|
|
152
|
+
// Result should always have a valid structure even on errors
|
|
153
|
+
expect(result.sourceFilePath).toBe(src);
|
|
154
|
+
expect(Array.isArray(result.errors)).toBe(true);
|
|
155
|
+
expect(typeof result.summary.totalElapsedMs).toBe('number');
|
|
156
|
+
});
|
|
157
|
+
test('runWorkflow output folder is created', async () => {
|
|
158
|
+
const src = temp.file('notes/output.md', '# Test\n\nJust testing.');
|
|
159
|
+
const result = await service.runWorkflow({ filePath: src }, defaultSettings());
|
|
160
|
+
expect(fs.existsSync(result.outputFolderPath)).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
@@ -46,6 +46,20 @@ describe('path bridge handshake and transport verification contracts', () => {
|
|
|
46
46
|
const pathModeUiPath = path.join(repoRoot, 'path_mode', 'scripts', 'path_mode_ui.gd');
|
|
47
47
|
const readerRenderClientPath = path.join(repoRoot, 'path_mode', 'scripts', 'reader_render_client.gd');
|
|
48
48
|
const pathRendererPath = path.join(repoRoot, 'path_mode', 'scripts', 'path_renderer.gd');
|
|
49
|
+
test('path bridge preserves explicit port zero for ephemeral bind fallback', async () => {
|
|
50
|
+
const bridge = new PathBridge_1.PathBridge({
|
|
51
|
+
port: 0,
|
|
52
|
+
host: '127.0.0.1',
|
|
53
|
+
});
|
|
54
|
+
try {
|
|
55
|
+
await bridge.waitUntilReady();
|
|
56
|
+
expect(bridge.getPort()).toBeGreaterThan(0);
|
|
57
|
+
expect(bridge.getPort()).not.toBe(9876);
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
bridge.close();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
49
63
|
test('path bridge supports explicit identify handshake and client tagging', () => {
|
|
50
64
|
const bridge = fs.readFileSync(bridgePath, 'utf8');
|
|
51
65
|
expect(bridge).toContain("case 'identify'");
|
|
@@ -77,6 +91,35 @@ describe('path bridge handshake and transport verification contracts', () => {
|
|
|
77
91
|
});
|
|
78
92
|
expect(validIdentify.ok).toBe(true);
|
|
79
93
|
expect(validIdentify.envelope?.type).toBe('identify');
|
|
94
|
+
const validQuery = (0, PathBridge_1.parseBridgeInboundEnvelope)({
|
|
95
|
+
type: 'query',
|
|
96
|
+
version: PathBridge_1.PATH_BRIDGE_PROTOCOL_VERSION,
|
|
97
|
+
payload: {
|
|
98
|
+
requestId: 'query-1',
|
|
99
|
+
workspaceId: 'mobile-workspace',
|
|
100
|
+
sourceUri: 'note://workspace/v1/algebra/index.md',
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
expect(validQuery.ok).toBe(true);
|
|
104
|
+
const invalidQuery = (0, PathBridge_1.parseBridgeInboundEnvelope)({
|
|
105
|
+
type: 'query',
|
|
106
|
+
payload: { requestId: '' },
|
|
107
|
+
});
|
|
108
|
+
expect(invalidQuery.ok).toBe(false);
|
|
109
|
+
expect(invalidQuery.reason).toContain('requestId');
|
|
110
|
+
const invalidCapabilities = (0, PathBridge_1.parseBridgeInboundEnvelope)({
|
|
111
|
+
type: 'capabilities',
|
|
112
|
+
payload: { protocolVersion: PathBridge_1.PATH_BRIDGE_PROTOCOL_VERSION, capabilities: [''] },
|
|
113
|
+
});
|
|
114
|
+
expect(invalidCapabilities.ok).toBe(false);
|
|
115
|
+
expect(invalidCapabilities.reason).toContain('non-empty strings');
|
|
116
|
+
expect(PathBridge_1.PATH_BRIDGE_CAPABILITIES).toEqual(expect.arrayContaining([
|
|
117
|
+
'knowledge.analyze',
|
|
118
|
+
'knowledge.query',
|
|
119
|
+
'knowledge.readEvidence',
|
|
120
|
+
'knowledge.exportBundle',
|
|
121
|
+
'request.cancel',
|
|
122
|
+
]));
|
|
80
123
|
const invalidSwitchCenter = (0, PathBridge_1.parseBridgeInboundEnvelope)({
|
|
81
124
|
type: 'switchCenter',
|
|
82
125
|
payload: {
|
|
@@ -149,7 +192,7 @@ describe('path bridge handshake and transport verification contracts', () => {
|
|
|
149
192
|
const invalidConfigureBrightness = (0, PathBridge_1.parseBridgeInboundEnvelope)({
|
|
150
193
|
type: 'configure',
|
|
151
194
|
payload: {
|
|
152
|
-
bg_brightness:
|
|
195
|
+
bg_brightness: 0.2,
|
|
153
196
|
},
|
|
154
197
|
});
|
|
155
198
|
expect(invalidConfigureBrightness.ok).toBe(false);
|
|
@@ -182,7 +225,7 @@ describe('path bridge handshake and transport verification contracts', () => {
|
|
|
182
225
|
retain_history: true,
|
|
183
226
|
focus_mode: false,
|
|
184
227
|
background: 'belfast_sunset_puresky_4k.exr',
|
|
185
|
-
bg_brightness:
|
|
228
|
+
bg_brightness: 0.08,
|
|
186
229
|
reading_mode: 'window',
|
|
187
230
|
reader_render_mode: 'render',
|
|
188
231
|
reader_toggle_source_shortcut: 'Ctrl+Shift+M',
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ws_1 = require("ws");
|
|
4
|
+
const PathBridge_1 = require("./core/PathBridge");
|
|
5
|
+
function waitForMessage(socket, predicate) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const timer = setTimeout(() => {
|
|
8
|
+
socket.off('message', onMessage);
|
|
9
|
+
reject(new Error('Timed out waiting for PathBridge message.'));
|
|
10
|
+
}, 3000);
|
|
11
|
+
const onMessage = (raw) => {
|
|
12
|
+
let payload;
|
|
13
|
+
try {
|
|
14
|
+
payload = JSON.parse(raw.toString('utf8'));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (!predicate(payload)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
socket.off('message', onMessage);
|
|
24
|
+
resolve(payload);
|
|
25
|
+
};
|
|
26
|
+
socket.on('message', onMessage);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function connectClient(port) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const socket = new ws_1.WebSocket(`ws://127.0.0.1:${port}`);
|
|
32
|
+
socket.once('open', () => resolve(socket));
|
|
33
|
+
socket.once('error', reject);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async function closeClient(socket) {
|
|
37
|
+
if (!socket || socket.readyState === ws_1.WebSocket.CLOSED) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
await new Promise((resolve) => {
|
|
41
|
+
socket.once('close', () => resolve());
|
|
42
|
+
socket.close();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
describe('PathBridge host adapter contract', () => {
|
|
46
|
+
test('executes knowledge requests in the host and returns correlated results', async () => {
|
|
47
|
+
const operations = [];
|
|
48
|
+
const bridge = new PathBridge_1.PathBridge({
|
|
49
|
+
port: 0,
|
|
50
|
+
hostAdapter: {
|
|
51
|
+
execute: async (operation) => {
|
|
52
|
+
operations.push(operation);
|
|
53
|
+
return { nodeCount: 2, execution: 'host' };
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
let client = null;
|
|
58
|
+
try {
|
|
59
|
+
await bridge.waitUntilReady();
|
|
60
|
+
client = await connectClient(bridge.getPort());
|
|
61
|
+
const capabilitiesPromise = waitForMessage(client, (message) => message.type === 'capabilities');
|
|
62
|
+
client.send(JSON.stringify({ type: 'identify', payload: { client: 'test-client' } }));
|
|
63
|
+
await capabilitiesPromise;
|
|
64
|
+
client.send(JSON.stringify({
|
|
65
|
+
type: 'query',
|
|
66
|
+
correlationId: 'corr-1',
|
|
67
|
+
payload: { requestId: 'query-1', workspaceId: 'mobile-workspace' },
|
|
68
|
+
}));
|
|
69
|
+
const result = await waitForMessage(client, (message) => message.type === 'operationResult');
|
|
70
|
+
expect(result.payload).toEqual(expect.objectContaining({
|
|
71
|
+
type: 'query',
|
|
72
|
+
requestId: 'query-1',
|
|
73
|
+
correlationId: 'corr-1',
|
|
74
|
+
ok: true,
|
|
75
|
+
result: { nodeCount: 2, execution: 'host' },
|
|
76
|
+
}));
|
|
77
|
+
expect(operations[0]).toEqual(expect.objectContaining({
|
|
78
|
+
type: 'query',
|
|
79
|
+
requestId: 'query-1',
|
|
80
|
+
correlationId: 'corr-1',
|
|
81
|
+
clientTag: 'test-client',
|
|
82
|
+
}));
|
|
83
|
+
expect(operations[0].signal).toBeInstanceOf(AbortSignal);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
await closeClient(client);
|
|
87
|
+
bridge.close();
|
|
88
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
test('propagates cancellation to the host adapter and does not leak pending work', async () => {
|
|
92
|
+
let cancelledRequestId = '';
|
|
93
|
+
let operationSignal = null;
|
|
94
|
+
const bridge = new PathBridge_1.PathBridge({
|
|
95
|
+
port: 0,
|
|
96
|
+
hostAdapter: {
|
|
97
|
+
execute: (operation) => {
|
|
98
|
+
operationSignal = operation.signal;
|
|
99
|
+
return new Promise((_resolve, reject) => {
|
|
100
|
+
operation.signal.addEventListener('abort', () => reject(new Error('aborted')));
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
cancel: (requestId) => {
|
|
104
|
+
cancelledRequestId = requestId;
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
let client = null;
|
|
109
|
+
try {
|
|
110
|
+
await bridge.waitUntilReady();
|
|
111
|
+
client = await connectClient(bridge.getPort());
|
|
112
|
+
const capabilitiesPromise = waitForMessage(client, (message) => message.type === 'capabilities');
|
|
113
|
+
client.send(JSON.stringify({ type: 'identify', payload: { client: 'cancel-client' } }));
|
|
114
|
+
await capabilitiesPromise;
|
|
115
|
+
client.send(JSON.stringify({ type: 'query', payload: { requestId: 'query-cancel' } }));
|
|
116
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
117
|
+
client.send(JSON.stringify({ type: 'cancel', payload: { requestId: 'query-cancel' } }));
|
|
118
|
+
const result = await waitForMessage(client, (message) => message.type === 'operationResult' && message.payload.type === 'cancel');
|
|
119
|
+
expect(result.payload).toEqual(expect.objectContaining({
|
|
120
|
+
requestId: 'query-cancel',
|
|
121
|
+
cancelled: true,
|
|
122
|
+
ok: false,
|
|
123
|
+
}));
|
|
124
|
+
expect(cancelledRequestId).toBe('query-cancel');
|
|
125
|
+
expect(operationSignal?.aborted).toBe(true);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
await closeClient(client);
|
|
129
|
+
bridge.close();
|
|
130
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
@@ -80,6 +80,14 @@ describe('path core bundle contract', () => {
|
|
|
80
80
|
['A', 'B', 'C', 'D'].forEach((id) => {
|
|
81
81
|
graph.addNode({ id, label: id, inDegree: 0, outDegree: 0 });
|
|
82
82
|
});
|
|
83
|
+
graph.addNode({
|
|
84
|
+
id: 'Alias',
|
|
85
|
+
label: 'Alias',
|
|
86
|
+
inDegree: 0,
|
|
87
|
+
outDegree: 0,
|
|
88
|
+
identityAliases: ['folder/alias.md'],
|
|
89
|
+
});
|
|
90
|
+
expect(graph.hasNode('folder\\alias.md')).toBe(true);
|
|
83
91
|
graph.addEdge('A', 'B');
|
|
84
92
|
graph.addEdge('A', 'C');
|
|
85
93
|
graph.addEdge('B', 'D');
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const fs = __importStar(require("fs"));
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
describe('pathmode background safety contract', () => {
|
|
39
|
+
const repoRoot = path.resolve(__dirname, '..');
|
|
40
|
+
const settingsPanelPath = path.join(repoRoot, 'path_mode', 'scripts', 'settings_panel.gd');
|
|
41
|
+
const pathRendererPath = path.join(repoRoot, 'path_mode', 'scripts', 'path_renderer.gd');
|
|
42
|
+
test('does not default path mode to a heavy HDR background at startup', () => {
|
|
43
|
+
const source = fs.readFileSync(settingsPanelPath, 'utf8');
|
|
44
|
+
expect(source).toContain('"background": ""');
|
|
45
|
+
expect(source).not.toContain('"background": "belfast_sunset_puresky_4k.exr"');
|
|
46
|
+
});
|
|
47
|
+
test('startup path-mode restore keeps runtime background values intact', () => {
|
|
48
|
+
const source = fs.readFileSync(pathRendererPath, 'utf8');
|
|
49
|
+
expect(source).toContain('func _filter_startup_settings(settings: Dictionary) -> Dictionary:');
|
|
50
|
+
expect(source).toContain('return settings.duplicate(true)');
|
|
51
|
+
});
|
|
52
|
+
test('desktop settings panel prefers runtime TOML over local cfg during load', () => {
|
|
53
|
+
const source = fs.readFileSync(settingsPanelPath, 'utf8');
|
|
54
|
+
expect(source).toContain('if not _runtime_base_url.is_empty():');
|
|
55
|
+
expect(source).toContain('call_deferred("_load_settings_from_runtime_async")');
|
|
56
|
+
expect(source).toContain('_load_settings_local()');
|
|
57
|
+
});
|
|
58
|
+
test('loads HDR backgrounds through the guarded resize-and-convert path', () => {
|
|
59
|
+
const source = fs.readFileSync(pathRendererPath, 'utf8');
|
|
60
|
+
expect(source).toContain('var _background_texture_cache: Dictionary = {}');
|
|
61
|
+
expect(source).toContain('var _last_applied_background_path: String = "__unset__"');
|
|
62
|
+
expect(source).toContain('func _load_hdr_background_safely(path: String) -> Texture2D:');
|
|
63
|
+
expect(source).toContain('var imported_tex = ResourceLoader.load(path)');
|
|
64
|
+
expect(source).toContain('var texture := imported_tex as Texture2D');
|
|
65
|
+
expect(source).not.toContain('MAX_SAFE_HDR_BACKGROUND_BYTES');
|
|
66
|
+
expect(source).not.toContain('(imported_tex as Texture2D).get_image()');
|
|
67
|
+
expect(source).not.toContain('var image_error := image.load(path)');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -45,4 +45,13 @@ describe('Path Mode settings API contract', () => {
|
|
|
45
45
|
expect(serverSource).toContain('extractPathModeSettingsFromAppConfig');
|
|
46
46
|
expect(serverSource).toContain('applyPathModeSettingsToAppConfig');
|
|
47
47
|
});
|
|
48
|
+
test('server path-mode settings loader does not short-circuit on stale in-memory cache', () => {
|
|
49
|
+
const loadStart = serverSource.indexOf('async function loadPathModeSettings(): Promise<PathModeSettings> {');
|
|
50
|
+
const loadEnd = serverSource.indexOf('async function persistPathModeSettings(settingsLike: unknown): Promise<PathModeSettings> {');
|
|
51
|
+
const loadSlice = serverSource.slice(loadStart, loadEnd);
|
|
52
|
+
expect(loadStart).toBeGreaterThanOrEqual(0);
|
|
53
|
+
expect(loadEnd).toBeGreaterThan(loadStart);
|
|
54
|
+
expect(loadSlice).toContain('const appConfig = await loadAppConfigToml();');
|
|
55
|
+
expect(loadSlice).not.toContain('if (cachedPathModeSettings)');
|
|
56
|
+
});
|
|
48
57
|
});
|
|
@@ -48,10 +48,14 @@ describe('pkg sidecar packaging contract', () => {
|
|
|
48
48
|
const pkg = packageJson.pkg || {};
|
|
49
49
|
const pkgScripts = pkg.scripts || [];
|
|
50
50
|
const pkgAssets = pkg.assets || [];
|
|
51
|
+
const scripts = packageJson.scripts || {};
|
|
51
52
|
expect(pkgScripts).toContain('dist/src/backend/workers/**/*.js');
|
|
52
53
|
expect(pkgAssets).toContain('dist/src/**/*');
|
|
53
|
-
expect(pkgAssets).toContain('data.js');
|
|
54
|
-
expect(pkgAssets).toContain('graph_data.json');
|
|
54
|
+
expect(pkgAssets).not.toContain('data.js');
|
|
55
|
+
expect(pkgAssets).not.toContain('graph_data.json');
|
|
56
|
+
expect(scripts['build:full']).toContain('--include-generated-graph-assets');
|
|
57
|
+
expect(scripts['tauri:build:full']).toContain('npm run build:full');
|
|
58
|
+
expect(scripts.prepublishOnly).toBe('npm run build');
|
|
55
59
|
});
|
|
56
60
|
test('retains hardened node22 sidecar build args and target mapping', () => {
|
|
57
61
|
const buildSidecar = fs.readFileSync(buildSidecarPath, 'utf8');
|
|
@@ -61,6 +65,8 @@ describe('pkg sidecar packaging contract', () => {
|
|
|
61
65
|
expect(buildSidecar).toContain("'--compress'");
|
|
62
66
|
expect(buildSidecar).toContain("'Brotli'");
|
|
63
67
|
expect(buildSidecar).toContain("'--no-bytecode'");
|
|
64
|
-
expect(buildSidecar).toContain("'--public'");
|
|
68
|
+
expect(buildSidecar).toContain("'--public-packages'");
|
|
69
|
+
expect(buildSidecar).toContain('PKG_NO_BYTECODE_RETRY_PATTERN');
|
|
70
|
+
expect(buildSidecar).toContain('without --no-bytecode');
|
|
65
71
|
});
|
|
66
72
|
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MOBILE_SLIM_MAX_RESIDENT_BYTES = exports.MOBILE_SLIM_ASSET_BUDGET_BYTES = void 0;
|
|
4
|
+
exports.getExportProfile = getExportProfile;
|
|
5
|
+
exports.listExportProfiles = listExportProfiles;
|
|
6
|
+
const MobileBudget_1 = require("./MobileBudget");
|
|
7
|
+
exports.MOBILE_SLIM_ASSET_BUDGET_BYTES = MobileBudget_1.MOBILE_LOW_ARTIFACT_BUDGET_BYTES;
|
|
8
|
+
exports.MOBILE_SLIM_MAX_RESIDENT_BYTES = MobileBudget_1.MOBILE_LOW_MAX_RESIDENT_BYTES;
|
|
9
|
+
const EXPORT_PROFILES = {
|
|
10
|
+
'desktop-full': {
|
|
11
|
+
id: 'desktop-full',
|
|
12
|
+
platformTarget: 'tauri',
|
|
13
|
+
description: 'Full desktop runtime with sidecar-backed retrieval, streaming, and indexing.',
|
|
14
|
+
supportsSidecar: true,
|
|
15
|
+
supportsBackgroundIndexing: true,
|
|
16
|
+
supportsConversationStreaming: true,
|
|
17
|
+
supportsSvgRenderArtifacts: true,
|
|
18
|
+
supportsPngRenderArtifacts: true,
|
|
19
|
+
supportsLocalIngest: true,
|
|
20
|
+
supportsLocalExactQuery: true,
|
|
21
|
+
supportsRemoteInference: true,
|
|
22
|
+
requiresRemoteInference: false,
|
|
23
|
+
assetBudgetBytes: null,
|
|
24
|
+
maxResidentBytes: null,
|
|
25
|
+
preferredMermaidRenderer: 'auto',
|
|
26
|
+
},
|
|
27
|
+
'desktop-reader': {
|
|
28
|
+
id: 'desktop-reader',
|
|
29
|
+
platformTarget: 'browser',
|
|
30
|
+
description: 'Reader-oriented desktop profile with lightweight retrieval and PNG-safe rendering.',
|
|
31
|
+
supportsSidecar: true,
|
|
32
|
+
supportsBackgroundIndexing: false,
|
|
33
|
+
supportsConversationStreaming: true,
|
|
34
|
+
supportsSvgRenderArtifacts: true,
|
|
35
|
+
supportsPngRenderArtifacts: true,
|
|
36
|
+
supportsLocalIngest: false,
|
|
37
|
+
supportsLocalExactQuery: true,
|
|
38
|
+
supportsRemoteInference: true,
|
|
39
|
+
requiresRemoteInference: false,
|
|
40
|
+
assetBudgetBytes: null,
|
|
41
|
+
maxResidentBytes: null,
|
|
42
|
+
preferredMermaidRenderer: 'auto',
|
|
43
|
+
},
|
|
44
|
+
'godot-path-mode': {
|
|
45
|
+
id: 'godot-path-mode',
|
|
46
|
+
platformTarget: 'godot',
|
|
47
|
+
description: 'Godot reader/profile with PNG-first render materialization and no SVG dependency.',
|
|
48
|
+
supportsSidecar: true,
|
|
49
|
+
supportsBackgroundIndexing: false,
|
|
50
|
+
supportsConversationStreaming: false,
|
|
51
|
+
supportsSvgRenderArtifacts: false,
|
|
52
|
+
supportsPngRenderArtifacts: true,
|
|
53
|
+
supportsLocalIngest: false,
|
|
54
|
+
supportsLocalExactQuery: false,
|
|
55
|
+
supportsRemoteInference: false,
|
|
56
|
+
requiresRemoteInference: false,
|
|
57
|
+
assetBudgetBytes: null,
|
|
58
|
+
maxResidentBytes: null,
|
|
59
|
+
preferredMermaidRenderer: 'auto',
|
|
60
|
+
},
|
|
61
|
+
'mobile-slim': {
|
|
62
|
+
id: 'mobile-slim',
|
|
63
|
+
platformTarget: 'mobile',
|
|
64
|
+
description: 'Slim mobile export with bounded memory footprint and PNG-only render artifacts.',
|
|
65
|
+
supportsSidecar: false,
|
|
66
|
+
supportsBackgroundIndexing: false,
|
|
67
|
+
supportsConversationStreaming: false,
|
|
68
|
+
supportsSvgRenderArtifacts: false,
|
|
69
|
+
supportsPngRenderArtifacts: true,
|
|
70
|
+
supportsLocalIngest: true,
|
|
71
|
+
supportsLocalExactQuery: true,
|
|
72
|
+
supportsRemoteInference: true,
|
|
73
|
+
requiresRemoteInference: false,
|
|
74
|
+
assetBudgetBytes: exports.MOBILE_SLIM_ASSET_BUDGET_BYTES,
|
|
75
|
+
maxResidentBytes: exports.MOBILE_SLIM_MAX_RESIDENT_BYTES,
|
|
76
|
+
preferredMermaidRenderer: 'local',
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
function getExportProfile(profileId) {
|
|
80
|
+
const normalized = typeof profileId === 'string' ? profileId.trim().toLowerCase() : '';
|
|
81
|
+
const candidate = normalized;
|
|
82
|
+
return EXPORT_PROFILES[candidate] || EXPORT_PROFILES['desktop-full'];
|
|
83
|
+
}
|
|
84
|
+
function listExportProfiles() {
|
|
85
|
+
return Object.values(EXPORT_PROFILES).map((profile) => ({ ...profile }));
|
|
86
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MOBILE_LOW_MAX_DEVICE_RAM_BYTES = exports.MOBILE_LOW_MAX_RESIDENT_BYTES = exports.MOBILE_LOW_ARTIFACT_BUDGET_BYTES = exports.MOBILE_BUDGET_SCHEMA_VERSION = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* TypeScript projection of config/mobile-budget.v1.json for server-side export metadata.
|
|
6
|
+
* Keep this small and compare it with the checked-in contract in mobile budget tests.
|
|
7
|
+
*/
|
|
8
|
+
exports.MOBILE_BUDGET_SCHEMA_VERSION = 1;
|
|
9
|
+
exports.MOBILE_LOW_ARTIFACT_BUDGET_BYTES = 25 * 1024 * 1024;
|
|
10
|
+
exports.MOBILE_LOW_MAX_RESIDENT_BYTES = 256 * 1024 * 1024;
|
|
11
|
+
exports.MOBILE_LOW_MAX_DEVICE_RAM_BYTES = 4 * 1024 * 1024 * 1024;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolvePlatformCapabilities = resolvePlatformCapabilities;
|
|
4
|
+
const ExportProfile_1 = require("./ExportProfile");
|
|
5
|
+
function cloneProfile(profile) {
|
|
6
|
+
return { ...profile };
|
|
7
|
+
}
|
|
8
|
+
function resolvePlatformCapabilities(input = {}) {
|
|
9
|
+
let profile = cloneProfile((0, ExportProfile_1.getExportProfile)(input.exportProfileId));
|
|
10
|
+
const requestedTarget = typeof input.platformTarget === 'string'
|
|
11
|
+
? input.platformTarget.trim().toLowerCase()
|
|
12
|
+
: '';
|
|
13
|
+
if (requestedTarget) {
|
|
14
|
+
const compatibleProfile = (requestedTarget === 'godot' ? (0, ExportProfile_1.getExportProfile)('godot-path-mode')
|
|
15
|
+
: requestedTarget === 'mobile' ? (0, ExportProfile_1.getExportProfile)('mobile-slim')
|
|
16
|
+
: requestedTarget === 'browser' ? (0, ExportProfile_1.getExportProfile)('desktop-reader')
|
|
17
|
+
: (0, ExportProfile_1.getExportProfile)('desktop-full'));
|
|
18
|
+
if (compatibleProfile.platformTarget === requestedTarget) {
|
|
19
|
+
profile = cloneProfile(compatibleProfile);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
exportProfileId: profile.id,
|
|
24
|
+
platformTarget: profile.platformTarget,
|
|
25
|
+
export: {
|
|
26
|
+
supportsWorkspaceBundles: true,
|
|
27
|
+
deterministicBundles: true,
|
|
28
|
+
bundlePackagingMode: profile.supportsSidecar ? 'full' : 'slim',
|
|
29
|
+
requiresIndexedReadiness: true,
|
|
30
|
+
assetBudgetBytes: profile.assetBudgetBytes,
|
|
31
|
+
maxResidentBytes: profile.maxResidentBytes,
|
|
32
|
+
},
|
|
33
|
+
render: {
|
|
34
|
+
supportsSvgArtifacts: profile.supportsSvgRenderArtifacts,
|
|
35
|
+
supportsPngArtifacts: profile.supportsPngRenderArtifacts,
|
|
36
|
+
preferredArtifact: profile.supportsSvgRenderArtifacts ? 'svg' : 'png',
|
|
37
|
+
preferredMermaidRenderer: profile.preferredMermaidRenderer,
|
|
38
|
+
},
|
|
39
|
+
retrieval: {
|
|
40
|
+
supportsSidecar: profile.supportsSidecar,
|
|
41
|
+
supportsBackgroundIndexing: profile.supportsBackgroundIndexing,
|
|
42
|
+
supportsLocalIngest: profile.supportsLocalIngest,
|
|
43
|
+
supportsLocalExactQuery: profile.supportsLocalExactQuery,
|
|
44
|
+
supportsRemoteInference: profile.supportsRemoteInference,
|
|
45
|
+
requiresRemoteInference: profile.requiresRemoteInference,
|
|
46
|
+
},
|
|
47
|
+
storage: {
|
|
48
|
+
preferredProvider: profile.platformTarget === 'mobile' ? 'projection' : 'sqlite',
|
|
49
|
+
supportedProviders: profile.platformTarget === 'mobile'
|
|
50
|
+
? ['projection']
|
|
51
|
+
: ['sqlite', 'file', 'remote'],
|
|
52
|
+
supportsSqlite: profile.platformTarget !== 'mobile',
|
|
53
|
+
supportsProjection: profile.platformTarget === 'mobile',
|
|
54
|
+
},
|
|
55
|
+
conversation: {
|
|
56
|
+
supportsStreaming: profile.supportsConversationStreaming,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|