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
|
@@ -42,12 +42,44 @@
|
|
|
42
42
|
|
|
43
43
|
let capacitorFsPermissionGranted = false;
|
|
44
44
|
let capacitorFsPermissionPromise = null;
|
|
45
|
-
const CAPACITOR_GRAPH_BUILD_MAX_FILES = 2000;
|
|
46
|
-
const CAPACITOR_GRAPH_BUILD_MAX_BYTES = 16 * 1024 * 1024;
|
|
47
45
|
const CAPACITOR_GRAPH_BUILD_WORKER_TIMEOUT_MS = 20000;
|
|
48
46
|
const CAPACITOR_BRIDGE_MAX_CHUNK_BYTES = 192 * 1024;
|
|
49
|
-
const CAPACITOR_BRIDGE_MAX_TEXT_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
50
47
|
const CAPACITOR_GRAPH_SERIALIZATION_MAX_BYTES = 48 * 1024 * 1024;
|
|
48
|
+
const CAPACITOR_BRIDGE_MAX_TEXT_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
49
|
+
const FALLBACK_MOBILE_RUNTIME_BUDGET = Object.freeze({
|
|
50
|
+
maxDocuments: 5000,
|
|
51
|
+
maxDocumentBytes: 16 * 1024 * 1024,
|
|
52
|
+
maxTotalInputBytes: 64 * 1024 * 1024,
|
|
53
|
+
maxEdges: 250000,
|
|
54
|
+
maxDepth: 64,
|
|
55
|
+
maxProjectionBytes: CAPACITOR_GRAPH_SERIALIZATION_MAX_BYTES
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
function getMobileRuntimeBudget() {
|
|
59
|
+
const candidate = typeof window !== 'undefined' ? window.NoteConnectionMobileBudget : null;
|
|
60
|
+
const runtime = candidate && candidate.runtime;
|
|
61
|
+
if (!runtime || typeof runtime !== 'object') {
|
|
62
|
+
return FALLBACK_MOBILE_RUNTIME_BUDGET;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const keys = Object.keys(FALLBACK_MOBILE_RUNTIME_BUDGET);
|
|
66
|
+
const isValid = keys.every((key) => Number.isInteger(runtime[key]) && runtime[key] > 0);
|
|
67
|
+
return isValid ? runtime : FALLBACK_MOBILE_RUNTIME_BUDGET;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function measureUtf8Bytes(textPayload) {
|
|
71
|
+
const text = String(textPayload || '');
|
|
72
|
+
if (!text) {
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
if (typeof TextEncoder === 'function') {
|
|
76
|
+
return new TextEncoder().encode(text).length;
|
|
77
|
+
}
|
|
78
|
+
if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
|
|
79
|
+
return Buffer.byteLength(text, 'utf8');
|
|
80
|
+
}
|
|
81
|
+
return text.length;
|
|
82
|
+
}
|
|
51
83
|
|
|
52
84
|
function getCapacitorDirectoryHints(filesystem) {
|
|
53
85
|
const directoryHints = [];
|
|
@@ -170,13 +202,40 @@
|
|
|
170
202
|
.pop() || '';
|
|
171
203
|
}
|
|
172
204
|
|
|
205
|
+
function canonicalMobileNodeIdFromIdentity(identity) {
|
|
206
|
+
const sourceUri = identity && typeof identity.sourceUri === 'string'
|
|
207
|
+
? identity.sourceUri
|
|
208
|
+
: '';
|
|
209
|
+
const prefix = 'note://workspace/v1/';
|
|
210
|
+
if (!sourceUri.startsWith(prefix)) {
|
|
211
|
+
return '';
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
return decodeURIComponent(sourceUri.slice(prefix.length))
|
|
215
|
+
.replace(/\.(?:md|markdown)$/i, '')
|
|
216
|
+
.trim();
|
|
217
|
+
} catch (_error) {
|
|
218
|
+
return '';
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function createMobileResourceIdentity(relativePath, legacyId, content) {
|
|
223
|
+
const identityContract = typeof globalThis !== 'undefined'
|
|
224
|
+
? globalThis.NoteConnectionMobileIdentity
|
|
225
|
+
: null;
|
|
226
|
+
if (!identityContract || typeof identityContract.createResourceIdentity !== 'function') {
|
|
227
|
+
throw new Error('Mobile identity contract is unavailable.');
|
|
228
|
+
}
|
|
229
|
+
return await identityContract.createResourceIdentity(relativePath, legacyId, content);
|
|
230
|
+
}
|
|
231
|
+
|
|
173
232
|
function extractWikiLinks(content) {
|
|
174
233
|
const links = new Set();
|
|
175
234
|
const regex = /\[\[(.*?)(?:\|.*?)?\]\]/g;
|
|
176
235
|
const text = String(content || '');
|
|
177
236
|
let match;
|
|
178
237
|
while ((match = regex.exec(text)) !== null) {
|
|
179
|
-
const linked =
|
|
238
|
+
const linked = String(match[1] || '').trim();
|
|
180
239
|
if (linked) {
|
|
181
240
|
links.add(linked);
|
|
182
241
|
}
|
|
@@ -184,6 +243,122 @@
|
|
|
184
243
|
return Array.from(links);
|
|
185
244
|
}
|
|
186
245
|
|
|
246
|
+
function extractMarkdownLinks(content) {
|
|
247
|
+
const links = new Set();
|
|
248
|
+
const regex = /\]\(([^)]+)\)/g;
|
|
249
|
+
const text = String(content || '');
|
|
250
|
+
let match;
|
|
251
|
+
while ((match = regex.exec(text)) !== null) {
|
|
252
|
+
const linked = String(match[1] || '').trim();
|
|
253
|
+
if (linked) {
|
|
254
|
+
links.add(linked);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return Array.from(links);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function normalizeCapacitorCanonicalId(value) {
|
|
261
|
+
const normalized = String(value || '')
|
|
262
|
+
.normalize('NFC')
|
|
263
|
+
.replace(/\\/g, '/')
|
|
264
|
+
.replace(/^knowledge_base\//i, '')
|
|
265
|
+
.replace(/^\/+/, '')
|
|
266
|
+
.trim();
|
|
267
|
+
const segments = [];
|
|
268
|
+
for (const segment of normalized.split('/')) {
|
|
269
|
+
if (!segment || segment === '.') {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (segment === '..') {
|
|
273
|
+
if (segments.length === 0) {
|
|
274
|
+
return '';
|
|
275
|
+
}
|
|
276
|
+
segments.pop();
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
segments.push(segment);
|
|
280
|
+
}
|
|
281
|
+
return segments.join('/').replace(/\.(?:md|markdown)$/i, '').toLowerCase();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function cleanCapacitorReference(rawReference) {
|
|
285
|
+
let reference = String(rawReference || '').trim();
|
|
286
|
+
const wikiMatch = reference.match(/^\[\[(.*?)(?:\|.*?)?\]\]$/);
|
|
287
|
+
if (wikiMatch) {
|
|
288
|
+
reference = String(wikiMatch[1] || '').trim();
|
|
289
|
+
}
|
|
290
|
+
reference = reference.replace(/^['"]|['"]$/g, '').trim();
|
|
291
|
+
reference = reference.split('#')[0].split('?')[0].trim();
|
|
292
|
+
if (!reference || /^[a-z][a-z0-9+.-]*:/i.test(reference) || reference.startsWith('/')) {
|
|
293
|
+
return '';
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
reference = decodeURIComponent(reference);
|
|
297
|
+
} catch (_error) {
|
|
298
|
+
return '';
|
|
299
|
+
}
|
|
300
|
+
return reference;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function resolveCapacitorReferencePath(sourceCanonicalId, rawReference) {
|
|
304
|
+
const reference = cleanCapacitorReference(rawReference);
|
|
305
|
+
if (!reference) {
|
|
306
|
+
return '';
|
|
307
|
+
}
|
|
308
|
+
const direct = normalizeCapacitorCanonicalId(reference);
|
|
309
|
+
const sourceSegments = normalizeCapacitorCanonicalId(sourceCanonicalId).split('/').filter(Boolean);
|
|
310
|
+
sourceSegments.pop();
|
|
311
|
+
const relative = normalizeCapacitorCanonicalId([...sourceSegments, reference].join('/'));
|
|
312
|
+
return { direct, relative };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function buildCapacitorReferenceIndex(files) {
|
|
316
|
+
const byCanonicalId = new Map();
|
|
317
|
+
const byLegacyId = new Map();
|
|
318
|
+
const byUniqueStem = new Map();
|
|
319
|
+
files.forEach((file) => {
|
|
320
|
+
const canonicalId = normalizeCapacitorCanonicalId(
|
|
321
|
+
file.canonicalId || canonicalMobileNodeIdFromIdentity(file) || file.path || file.id
|
|
322
|
+
);
|
|
323
|
+
if (!file.id || !canonicalId) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const legacyKey = String(file.id).normalize('NFC').toLowerCase();
|
|
327
|
+
if (byLegacyId.has(legacyKey)) {
|
|
328
|
+
throw new Error(`Capacitor graph contains an ambiguous legacy basename: ${file.id}`);
|
|
329
|
+
}
|
|
330
|
+
if (byCanonicalId.has(canonicalId)) {
|
|
331
|
+
throw new Error(`Capacitor graph contains duplicate canonical node id: ${canonicalId}`);
|
|
332
|
+
}
|
|
333
|
+
byLegacyId.set(legacyKey, file);
|
|
334
|
+
byCanonicalId.set(canonicalId, file);
|
|
335
|
+
const stem = canonicalId.split('/').pop() || canonicalId;
|
|
336
|
+
const stemCandidates = byUniqueStem.get(stem) || [];
|
|
337
|
+
stemCandidates.push(file);
|
|
338
|
+
byUniqueStem.set(stem, stemCandidates);
|
|
339
|
+
file.__canonicalId = canonicalId;
|
|
340
|
+
});
|
|
341
|
+
return { byCanonicalId, byLegacyId, byUniqueStem };
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function resolveCapacitorReference(sourceFile, rawReference, referenceIndex) {
|
|
345
|
+
const paths = resolveCapacitorReferencePath(sourceFile.__canonicalId, rawReference);
|
|
346
|
+
if (!paths) {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
const direct = referenceIndex.byCanonicalId.get(paths.direct);
|
|
350
|
+
if (direct) {
|
|
351
|
+
return direct;
|
|
352
|
+
}
|
|
353
|
+
const relative = referenceIndex.byCanonicalId.get(paths.relative);
|
|
354
|
+
if (relative) {
|
|
355
|
+
return relative;
|
|
356
|
+
}
|
|
357
|
+
const stem = paths.direct.split('/').pop() || paths.direct;
|
|
358
|
+
const candidates = referenceIndex.byUniqueStem.get(stem) || [];
|
|
359
|
+
return candidates.length === 1 ? candidates[0] : null;
|
|
360
|
+
}
|
|
361
|
+
|
|
187
362
|
function normalizeCapacitorPath(pathValue, options) {
|
|
188
363
|
const allowCurrentDir = Boolean(options && options.allowCurrentDir);
|
|
189
364
|
const normalized = String(pathValue || '').replace(/\\/g, '/').replace(/^\/+/, '');
|
|
@@ -235,6 +410,20 @@
|
|
|
235
410
|
return null;
|
|
236
411
|
}
|
|
237
412
|
|
|
413
|
+
function extractRelativePathFromWorkspaceUri(rawFilePath) {
|
|
414
|
+
const normalized = String(rawFilePath || '').replace(/\\/g, '/');
|
|
415
|
+
const prefix = 'note://workspace/v1/';
|
|
416
|
+
if (!normalized.toLowerCase().startsWith(prefix)) {
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
try {
|
|
420
|
+
const relative = decodeURIComponent(normalized.slice(prefix.length));
|
|
421
|
+
return relative.length > 0 ? relative : null;
|
|
422
|
+
} catch (_error) {
|
|
423
|
+
throw new Error('Invalid workspace source URI for Capacitor content read.');
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
238
427
|
function resolveCapacitorContentCandidatePath(rawFilePath) {
|
|
239
428
|
const raw = String(rawFilePath || '').trim();
|
|
240
429
|
if (!raw) {
|
|
@@ -247,6 +436,15 @@
|
|
|
247
436
|
return normalizeCapacitorPath(`Knowledge_Base/${relativeFromKb}`);
|
|
248
437
|
}
|
|
249
438
|
|
|
439
|
+
const relativeFromWorkspaceUri = extractRelativePathFromWorkspaceUri(raw);
|
|
440
|
+
if (relativeFromWorkspaceUri) {
|
|
441
|
+
return normalizeCapacitorPath(`Knowledge_Base/${relativeFromWorkspaceUri}`);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(normalized)) {
|
|
445
|
+
throw new Error('Cannot map non-workspace URI on Capacitor without Knowledge_Base marker.');
|
|
446
|
+
}
|
|
447
|
+
|
|
250
448
|
if (/^[A-Za-z]:\//.test(normalized) || normalized.startsWith('/')) {
|
|
251
449
|
throw new Error('Cannot map absolute desktop path on Capacitor without Knowledge_Base marker.');
|
|
252
450
|
}
|
|
@@ -404,20 +602,6 @@
|
|
|
404
602
|
}
|
|
405
603
|
}
|
|
406
604
|
|
|
407
|
-
function measureUtf8Bytes(textPayload) {
|
|
408
|
-
const text = String(textPayload || '');
|
|
409
|
-
if (!text) {
|
|
410
|
-
return 0;
|
|
411
|
-
}
|
|
412
|
-
if (typeof TextEncoder === 'function') {
|
|
413
|
-
return new TextEncoder().encode(text).length;
|
|
414
|
-
}
|
|
415
|
-
if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
|
|
416
|
-
return Buffer.byteLength(text, 'utf8');
|
|
417
|
-
}
|
|
418
|
-
return text.length;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
605
|
async function writeCapacitorChunkSequenceToDirectory(filesystem, normalizedPath, chunkSequenceFactory, options) {
|
|
422
606
|
const directory = options && Object.prototype.hasOwnProperty.call(options, 'directory')
|
|
423
607
|
? options.directory
|
|
@@ -580,6 +764,10 @@
|
|
|
580
764
|
const explicitDirectory = options && Object.prototype.hasOwnProperty.call(options, 'directory')
|
|
581
765
|
? options.directory
|
|
582
766
|
: undefined;
|
|
767
|
+
const maxBytes = Math.max(
|
|
768
|
+
1024,
|
|
769
|
+
Math.floor(Number(options && options.maxBytes) || CAPACITOR_BRIDGE_MAX_TEXT_PAYLOAD_BYTES)
|
|
770
|
+
);
|
|
583
771
|
const directoryHints = explicitDirectory === undefined
|
|
584
772
|
? getCapacitorDirectoryHints(filesystem)
|
|
585
773
|
: [explicitDirectory];
|
|
@@ -591,9 +779,41 @@
|
|
|
591
779
|
if (directory) {
|
|
592
780
|
args.directory = directory;
|
|
593
781
|
}
|
|
782
|
+
// Stat is a preflight guard: reading an oversized note first would
|
|
783
|
+
// defeat the low-memory contract even if the decoded text is later rejected.
|
|
784
|
+
if (typeof filesystem.stat === 'function') {
|
|
785
|
+
try {
|
|
786
|
+
const statResult = await filesystem.stat(args);
|
|
787
|
+
const reportedBytes = Number(statResult && statResult.size);
|
|
788
|
+
if (Number.isFinite(reportedBytes) && reportedBytes > maxBytes) {
|
|
789
|
+
const budgetError = new Error(
|
|
790
|
+
`Capacitor file exceeds ${maxBytes} bytes: ${normalizedPath}`
|
|
791
|
+
);
|
|
792
|
+
budgetError.code = 'MOBILE_BUDGET_EXCEEDED';
|
|
793
|
+
throw budgetError;
|
|
794
|
+
}
|
|
795
|
+
} catch (err) {
|
|
796
|
+
if (err && err.code === 'MOBILE_BUDGET_EXCEEDED') {
|
|
797
|
+
throw err;
|
|
798
|
+
}
|
|
799
|
+
// Some Capacitor versions do not expose stat for SAF handles;
|
|
800
|
+
// the bounded decoded-text check below remains the fallback.
|
|
801
|
+
}
|
|
802
|
+
}
|
|
594
803
|
const result = await filesystem.readFile(args);
|
|
595
|
-
|
|
804
|
+
const text = decodeCapacitorTextPayload(result);
|
|
805
|
+
if (measureUtf8Bytes(text) > maxBytes) {
|
|
806
|
+
const budgetError = new Error(
|
|
807
|
+
`Capacitor file exceeds ${maxBytes} bytes: ${normalizedPath}`
|
|
808
|
+
);
|
|
809
|
+
budgetError.code = 'MOBILE_BUDGET_EXCEEDED';
|
|
810
|
+
throw budgetError;
|
|
811
|
+
}
|
|
812
|
+
return text;
|
|
596
813
|
} catch (err) {
|
|
814
|
+
if (err && err.code === 'MOBILE_BUDGET_EXCEEDED') {
|
|
815
|
+
throw err;
|
|
816
|
+
}
|
|
597
817
|
lastError = err;
|
|
598
818
|
}
|
|
599
819
|
}
|
|
@@ -704,13 +924,21 @@
|
|
|
704
924
|
}
|
|
705
925
|
|
|
706
926
|
async function collectCapacitorMarkdownFiles(targetPath) {
|
|
707
|
-
const
|
|
927
|
+
const budget = getMobileRuntimeBudget();
|
|
928
|
+
const queue = [{
|
|
929
|
+
path: normalizeCapacitorPath(targetPath, { allowCurrentDir: true }),
|
|
930
|
+
depth: 0
|
|
931
|
+
}];
|
|
708
932
|
const visited = new Set();
|
|
709
933
|
const files = [];
|
|
710
934
|
let totalBytes = 0;
|
|
711
935
|
|
|
712
936
|
while (queue.length > 0) {
|
|
713
|
-
const
|
|
937
|
+
const currentEntry = queue.shift();
|
|
938
|
+
const current = currentEntry && currentEntry.path;
|
|
939
|
+
const currentDepth = currentEntry && Number.isInteger(currentEntry.depth)
|
|
940
|
+
? currentEntry.depth
|
|
941
|
+
: 0;
|
|
714
942
|
if (!current || visited.has(current)) {
|
|
715
943
|
continue;
|
|
716
944
|
}
|
|
@@ -723,23 +951,47 @@
|
|
|
723
951
|
}
|
|
724
952
|
|
|
725
953
|
const looksLikeMarkdown = /\.md$/i.test(entry.name);
|
|
954
|
+
const entryDepth = currentDepth + 1;
|
|
955
|
+
if (entryDepth > budget.maxDepth) {
|
|
956
|
+
throw new Error(
|
|
957
|
+
`Capacitor local build directory depth exceeds ${budget.maxDepth}. ` +
|
|
958
|
+
'Please flatten the knowledge base or build on desktop.'
|
|
959
|
+
);
|
|
960
|
+
}
|
|
726
961
|
if (entry.isDirectory === true) {
|
|
727
|
-
queue.push(entry.path);
|
|
962
|
+
queue.push({ path: entry.path, depth: entryDepth });
|
|
728
963
|
continue;
|
|
729
964
|
}
|
|
730
965
|
if (entry.isDirectory === null && !looksLikeMarkdown) {
|
|
731
|
-
queue.push(entry.path);
|
|
966
|
+
queue.push({ path: entry.path, depth: entryDepth });
|
|
732
967
|
continue;
|
|
733
968
|
}
|
|
734
969
|
if (!looksLikeMarkdown) {
|
|
735
970
|
continue;
|
|
736
971
|
}
|
|
737
972
|
|
|
738
|
-
|
|
739
|
-
totalBytes += rawText.length;
|
|
740
|
-
if (totalBytes > CAPACITOR_GRAPH_BUILD_MAX_BYTES) {
|
|
973
|
+
if (files.length >= budget.maxDocuments) {
|
|
741
974
|
throw new Error(
|
|
742
|
-
`Capacitor local build
|
|
975
|
+
`Capacitor local build file count exceeds ${budget.maxDocuments}. ` +
|
|
976
|
+
'Please build on desktop for large datasets.'
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const rawText = await capacitorReadText(entry.path, {
|
|
981
|
+
directory: entry.directory,
|
|
982
|
+
maxBytes: budget.maxDocumentBytes
|
|
983
|
+
});
|
|
984
|
+
const documentBytes = measureUtf8Bytes(rawText);
|
|
985
|
+
if (documentBytes > budget.maxDocumentBytes) {
|
|
986
|
+
throw new Error(
|
|
987
|
+
`Capacitor local build document exceeds ${budget.maxDocumentBytes} bytes. ` +
|
|
988
|
+
'Please split the note or build on desktop.'
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
totalBytes += documentBytes;
|
|
992
|
+
if (totalBytes > budget.maxTotalInputBytes) {
|
|
993
|
+
throw new Error(
|
|
994
|
+
`Capacitor local build payload exceeds ${budget.maxTotalInputBytes} bytes. ` +
|
|
743
995
|
'Please build on desktop for large datasets.'
|
|
744
996
|
);
|
|
745
997
|
}
|
|
@@ -753,22 +1005,21 @@
|
|
|
753
1005
|
const relativePath = entry.path;
|
|
754
1006
|
const segments = relativePath.split('/').filter(Boolean);
|
|
755
1007
|
const clusterId = segments.length > 1 ? segments[segments.length - 2] : 'root';
|
|
1008
|
+
const identity = await createMobileResourceIdentity(relativePath, filename, rawText);
|
|
756
1009
|
|
|
757
1010
|
files.push({
|
|
758
1011
|
id: filename,
|
|
1012
|
+
canonicalId: identity.canonicalId || canonicalMobileNodeIdFromIdentity(identity),
|
|
759
1013
|
label: filename,
|
|
760
1014
|
path: relativePath,
|
|
1015
|
+
sourceUri: identity.sourceUri,
|
|
1016
|
+
revision: identity.revision,
|
|
1017
|
+
identityAliases: identity.identityAliases,
|
|
761
1018
|
content: rawText,
|
|
762
1019
|
metadata,
|
|
763
1020
|
clusterId
|
|
764
1021
|
});
|
|
765
1022
|
|
|
766
|
-
if (files.length > CAPACITOR_GRAPH_BUILD_MAX_FILES) {
|
|
767
|
-
throw new Error(
|
|
768
|
-
`Capacitor local build file count exceeds ${CAPACITOR_GRAPH_BUILD_MAX_FILES}. ` +
|
|
769
|
-
'Please build on desktop for large datasets.'
|
|
770
|
-
);
|
|
771
|
-
}
|
|
772
1023
|
}
|
|
773
1024
|
}
|
|
774
1025
|
|
|
@@ -778,6 +1029,8 @@
|
|
|
778
1029
|
function buildCapacitorGraphData(files) {
|
|
779
1030
|
const nodeMap = new Map();
|
|
780
1031
|
const edgeMap = new Map();
|
|
1032
|
+
const sourceFiles = Array.isArray(files) ? files.filter((file) => file && file.id) : [];
|
|
1033
|
+
const referenceIndex = buildCapacitorReferenceIndex(sourceFiles);
|
|
781
1034
|
|
|
782
1035
|
const addEdge = (source, target, type) => {
|
|
783
1036
|
if (!source || !target || source === target) {
|
|
@@ -786,25 +1039,39 @@
|
|
|
786
1039
|
if (!nodeMap.has(source) || !nodeMap.has(target)) {
|
|
787
1040
|
return;
|
|
788
1041
|
}
|
|
789
|
-
const
|
|
1042
|
+
const edgeType = type || 'association';
|
|
1043
|
+
const key = `${source}->${target}:${edgeType}`;
|
|
790
1044
|
if (edgeMap.has(key)) {
|
|
791
1045
|
return;
|
|
792
1046
|
}
|
|
1047
|
+
const sourceNode = nodeMap.get(source);
|
|
1048
|
+
const targetNode = nodeMap.get(target);
|
|
793
1049
|
edgeMap.set(key, {
|
|
794
1050
|
source,
|
|
795
1051
|
target,
|
|
796
|
-
type:
|
|
1052
|
+
type: edgeType,
|
|
1053
|
+
kind: 'explicit',
|
|
1054
|
+
provenance: edgeType,
|
|
1055
|
+
sourceUri: sourceNode && sourceNode.sourceUri ? sourceNode.sourceUri : '',
|
|
1056
|
+
targetUri: targetNode && targetNode.sourceUri ? targetNode.sourceUri : '',
|
|
797
1057
|
weight: 1
|
|
798
1058
|
});
|
|
799
1059
|
};
|
|
800
1060
|
|
|
801
|
-
|
|
802
|
-
if (!file || !file.id
|
|
1061
|
+
sourceFiles.forEach((file) => {
|
|
1062
|
+
if (!file || !file.id) {
|
|
803
1063
|
return;
|
|
804
1064
|
}
|
|
1065
|
+
if (nodeMap.has(file.id)) {
|
|
1066
|
+
throw new Error(`Capacitor graph contains duplicate legacy node id: ${file.id}`);
|
|
1067
|
+
}
|
|
805
1068
|
nodeMap.set(file.id, {
|
|
806
1069
|
id: file.id,
|
|
1070
|
+
canonicalId: file.canonicalId || file.__canonicalId || '',
|
|
807
1071
|
label: file.label || file.id,
|
|
1072
|
+
sourceUri: file.sourceUri || '',
|
|
1073
|
+
revision: file.revision || '',
|
|
1074
|
+
identityAliases: Array.isArray(file.identityAliases) ? file.identityAliases : [],
|
|
808
1075
|
inDegree: 0,
|
|
809
1076
|
outDegree: 0,
|
|
810
1077
|
metadata: {
|
|
@@ -819,7 +1086,7 @@
|
|
|
819
1086
|
});
|
|
820
1087
|
});
|
|
821
1088
|
|
|
822
|
-
|
|
1089
|
+
sourceFiles.forEach((file) => {
|
|
823
1090
|
const sourceId = file.id;
|
|
824
1091
|
if (!nodeMap.has(sourceId)) {
|
|
825
1092
|
return;
|
|
@@ -829,24 +1096,37 @@
|
|
|
829
1096
|
? file.metadata.prerequisites
|
|
830
1097
|
: [];
|
|
831
1098
|
prerequisites.forEach((rawPrereq) => {
|
|
832
|
-
const
|
|
833
|
-
addEdge(
|
|
1099
|
+
const prerequisiteFile = resolveCapacitorReference(file, rawPrereq, referenceIndex);
|
|
1100
|
+
addEdge(prerequisiteFile && prerequisiteFile.id, sourceId, 'explicit-prerequisite');
|
|
834
1101
|
});
|
|
835
1102
|
|
|
836
1103
|
const nextItems = Array.isArray(file.metadata && file.metadata.next)
|
|
837
1104
|
? file.metadata.next
|
|
838
1105
|
: [];
|
|
839
1106
|
nextItems.forEach((rawNext) => {
|
|
840
|
-
const
|
|
841
|
-
addEdge(sourceId,
|
|
1107
|
+
const nextFile = resolveCapacitorReference(file, rawNext, referenceIndex);
|
|
1108
|
+
addEdge(sourceId, nextFile && nextFile.id, 'explicit-next');
|
|
1109
|
+
});
|
|
1110
|
+
|
|
1111
|
+
extractWikiLinks(file.content).forEach((rawLink) => {
|
|
1112
|
+
const linkedFile = resolveCapacitorReference(file, rawLink, referenceIndex);
|
|
1113
|
+
addEdge(sourceId, linkedFile && linkedFile.id, 'wiki-link');
|
|
842
1114
|
});
|
|
843
1115
|
|
|
844
|
-
|
|
845
|
-
|
|
1116
|
+
extractMarkdownLinks(file.content).forEach((rawLink) => {
|
|
1117
|
+
const linkedFile = resolveCapacitorReference(file, rawLink, referenceIndex);
|
|
1118
|
+
addEdge(sourceId, linkedFile && linkedFile.id, 'markdown-link');
|
|
846
1119
|
});
|
|
847
1120
|
});
|
|
848
1121
|
|
|
849
1122
|
const edges = Array.from(edgeMap.values());
|
|
1123
|
+
const budget = getMobileRuntimeBudget();
|
|
1124
|
+
if (edges.length > budget.maxEdges) {
|
|
1125
|
+
throw new Error(
|
|
1126
|
+
`Capacitor graph edge count exceeds ${budget.maxEdges}. ` +
|
|
1127
|
+
'Please reduce links or build on desktop for large datasets.'
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
850
1130
|
edges.forEach((edge) => {
|
|
851
1131
|
const sourceNode = nodeMap.get(edge.source);
|
|
852
1132
|
const targetNode = nodeMap.get(edge.target);
|
|
@@ -889,13 +1169,78 @@
|
|
|
889
1169
|
' try {',
|
|
890
1170
|
' var files = Array.isArray(event.data && event.data.files) ? event.data.files : [];',
|
|
891
1171
|
' function stripMarkdownExtension(value) {',
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
" .replace(/\\.md$/i, '')",
|
|
1172
|
+
' var normalized = String(value || "").trim()',
|
|
1173
|
+
" .replace(/\\.(?:md|markdown)$/i, '')",
|
|
895
1174
|
" .replace(/\\\\/g, '/')",
|
|
896
|
-
|
|
897
|
-
' .
|
|
898
|
-
'
|
|
1175
|
+
' .replace(/^knowledge_base\\//i, "")',
|
|
1176
|
+
' .replace(/^\\/+/, "");',
|
|
1177
|
+
' var parts = [];',
|
|
1178
|
+
' normalized.split("/").forEach(function(part) {',
|
|
1179
|
+
' if (!part || part === ".") return;',
|
|
1180
|
+
' if (part === "..") { if (parts.length > 0) parts.pop(); return; }',
|
|
1181
|
+
' parts.push(part);',
|
|
1182
|
+
' });',
|
|
1183
|
+
' return parts.join("/").normalize("NFC").toLowerCase();',
|
|
1184
|
+
' }',
|
|
1185
|
+
'',
|
|
1186
|
+
' function cleanReference(rawReference) {',
|
|
1187
|
+
' var reference = String(rawReference || "").trim();',
|
|
1188
|
+
' var wikiMatch = reference.match(/^\\[\\[(.*?)(?:\\|.*?)?\\]\\]$/);',
|
|
1189
|
+
' if (wikiMatch) reference = String(wikiMatch[1] || "").trim();',
|
|
1190
|
+
' reference = reference.replace(/^[\'\"]|[\'\"]$/g, "").split("#")[0].split("?")[0].trim();',
|
|
1191
|
+
' if (!reference || /^[a-z][a-z0-9+.-]*:/i.test(reference) || reference.charAt(0) === "/") return "";',
|
|
1192
|
+
' try { return decodeURIComponent(reference); } catch (_error) { return ""; }',
|
|
1193
|
+
' }',
|
|
1194
|
+
'',
|
|
1195
|
+
' function canonicalIdFromSourceUri(file) {',
|
|
1196
|
+
' var sourceUri = String(file && file.sourceUri || "");',
|
|
1197
|
+
' var prefix = "note://workspace/v1/";',
|
|
1198
|
+
' if (!sourceUri.startsWith(prefix)) return "";',
|
|
1199
|
+
' try { return stripMarkdownExtension(decodeURIComponent(sourceUri.slice(prefix.length))); }',
|
|
1200
|
+
' catch (_error) { return ""; }',
|
|
1201
|
+
' }',
|
|
1202
|
+
'',
|
|
1203
|
+
' function resolveReferencePath(sourceCanonicalId, rawReference) {',
|
|
1204
|
+
' var reference = cleanReference(rawReference);',
|
|
1205
|
+
' if (!reference) return null;',
|
|
1206
|
+
' var direct = stripMarkdownExtension(reference);',
|
|
1207
|
+
' var sourceSegments = stripMarkdownExtension(sourceCanonicalId).split("/").filter(Boolean);',
|
|
1208
|
+
' sourceSegments.pop();',
|
|
1209
|
+
' var relative = stripMarkdownExtension(sourceSegments.concat([reference]).join("/"));',
|
|
1210
|
+
' return { direct: direct, relative: relative };',
|
|
1211
|
+
' }',
|
|
1212
|
+
'',
|
|
1213
|
+
' function buildReferenceIndex(files) {',
|
|
1214
|
+
' var byCanonicalId = new Map();',
|
|
1215
|
+
' var byLegacyId = new Map();',
|
|
1216
|
+
' var byUniqueStem = new Map();',
|
|
1217
|
+
' files.forEach(function(file) {',
|
|
1218
|
+
' var canonicalId = stripMarkdownExtension(file.canonicalId || canonicalIdFromSourceUri(file) || file.path || file.id);',
|
|
1219
|
+
' var legacyKey = String(file.id || "").normalize("NFC").toLowerCase();',
|
|
1220
|
+
' if (!file.id || !canonicalId) return;',
|
|
1221
|
+
' if (byLegacyId.has(legacyKey)) throw new Error("Capacitor graph contains an ambiguous legacy basename: " + file.id);',
|
|
1222
|
+
' if (byCanonicalId.has(canonicalId)) throw new Error("Capacitor graph contains duplicate canonical node id: " + canonicalId);',
|
|
1223
|
+
' file.__canonicalId = canonicalId;',
|
|
1224
|
+
' byLegacyId.set(legacyKey, file);',
|
|
1225
|
+
' byCanonicalId.set(canonicalId, file);',
|
|
1226
|
+
' var stem = canonicalId.split("/").pop() || canonicalId;',
|
|
1227
|
+
' var candidates = byUniqueStem.get(stem) || [];',
|
|
1228
|
+
' candidates.push(file);',
|
|
1229
|
+
' byUniqueStem.set(stem, candidates);',
|
|
1230
|
+
' });',
|
|
1231
|
+
' return { byCanonicalId: byCanonicalId, byUniqueStem: byUniqueStem };',
|
|
1232
|
+
' }',
|
|
1233
|
+
'',
|
|
1234
|
+
' function resolveReference(sourceFile, rawReference, index) {',
|
|
1235
|
+
' var paths = resolveReferencePath(sourceFile.__canonicalId, rawReference);',
|
|
1236
|
+
' if (!paths) return null;',
|
|
1237
|
+
' var direct = index.byCanonicalId.get(paths.direct);',
|
|
1238
|
+
' if (direct) return direct;',
|
|
1239
|
+
' var relative = index.byCanonicalId.get(paths.relative);',
|
|
1240
|
+
' if (relative) return relative;',
|
|
1241
|
+
' var stem = paths.direct.split("/").pop() || paths.direct;',
|
|
1242
|
+
' var candidates = index.byUniqueStem.get(stem) || [];',
|
|
1243
|
+
' return candidates.length === 1 ? candidates[0] : null;',
|
|
899
1244
|
' }',
|
|
900
1245
|
'',
|
|
901
1246
|
' function extractWikiLinks(content) {',
|
|
@@ -904,7 +1249,21 @@
|
|
|
904
1249
|
" var text = String(content || '');",
|
|
905
1250
|
' var match;',
|
|
906
1251
|
' while ((match = regex.exec(text)) !== null) {',
|
|
907
|
-
' var linked =
|
|
1252
|
+
' var linked = String(match[1] || "").trim();',
|
|
1253
|
+
' if (linked) {',
|
|
1254
|
+
' links.add(linked);',
|
|
1255
|
+
' }',
|
|
1256
|
+
' }',
|
|
1257
|
+
' return Array.from(links);',
|
|
1258
|
+
' }',
|
|
1259
|
+
'',
|
|
1260
|
+
' function extractMarkdownLinks(content) {',
|
|
1261
|
+
' var links = new Set();',
|
|
1262
|
+
' var regex = /\\]\\(([^)]+)\\)/g;',
|
|
1263
|
+
" var text = String(content || '');",
|
|
1264
|
+
' var match;',
|
|
1265
|
+
' while ((match = regex.exec(text)) !== null) {',
|
|
1266
|
+
" var linked = String(match[1] || '').trim();",
|
|
908
1267
|
' if (linked) {',
|
|
909
1268
|
' links.add(linked);',
|
|
910
1269
|
' }',
|
|
@@ -914,6 +1273,7 @@
|
|
|
914
1273
|
'',
|
|
915
1274
|
' var nodeMap = new Map();',
|
|
916
1275
|
' var edgeMap = new Map();',
|
|
1276
|
+
' var referenceIndex = buildReferenceIndex(files);',
|
|
917
1277
|
'',
|
|
918
1278
|
' function addEdge(source, target, type) {',
|
|
919
1279
|
' if (!source || !target || source === target) {',
|
|
@@ -922,21 +1282,40 @@
|
|
|
922
1282
|
' if (!nodeMap.has(source) || !nodeMap.has(target)) {',
|
|
923
1283
|
' return;',
|
|
924
1284
|
' }',
|
|
925
|
-
' var
|
|
1285
|
+
' var edgeType = type || "association";',
|
|
1286
|
+
' var key = source + "->" + target + ":" + edgeType;',
|
|
926
1287
|
' if (edgeMap.has(key)) {',
|
|
927
1288
|
' return;',
|
|
928
1289
|
' }',
|
|
929
|
-
'
|
|
1290
|
+
' var sourceNode = nodeMap.get(source);',
|
|
1291
|
+
' var targetNode = nodeMap.get(target);',
|
|
1292
|
+
' edgeMap.set(key, {',
|
|
1293
|
+
' source: source,',
|
|
1294
|
+
' target: target,',
|
|
1295
|
+
' type: edgeType,',
|
|
1296
|
+
' kind: "explicit",',
|
|
1297
|
+
' provenance: edgeType,',
|
|
1298
|
+
' sourceUri: sourceNode && sourceNode.sourceUri ? sourceNode.sourceUri : "",',
|
|
1299
|
+
' targetUri: targetNode && targetNode.sourceUri ? targetNode.sourceUri : "",',
|
|
1300
|
+
' weight: 1',
|
|
1301
|
+
' });',
|
|
930
1302
|
' }',
|
|
931
1303
|
'',
|
|
932
1304
|
' files.forEach(function(file) {',
|
|
933
|
-
' if (!file || !file.id
|
|
1305
|
+
' if (!file || !file.id) {',
|
|
934
1306
|
' return;',
|
|
935
1307
|
' }',
|
|
1308
|
+
' if (nodeMap.has(file.id)) {',
|
|
1309
|
+
' throw new Error("Capacitor graph contains duplicate legacy node id: " + file.id);',
|
|
1310
|
+
' }',
|
|
936
1311
|
' var metadata = file.metadata || {};',
|
|
937
1312
|
' nodeMap.set(file.id, {',
|
|
938
1313
|
' id: file.id,',
|
|
1314
|
+
' canonicalId: file.canonicalId || file.__canonicalId || "",',
|
|
939
1315
|
' label: file.label || file.id,',
|
|
1316
|
+
' sourceUri: file.sourceUri || "",',
|
|
1317
|
+
' revision: file.revision || "",',
|
|
1318
|
+
' identityAliases: Array.isArray(file.identityAliases) ? file.identityAliases : [],',
|
|
940
1319
|
' inDegree: 0,',
|
|
941
1320
|
' outDegree: 0,',
|
|
942
1321
|
' metadata: {',
|
|
@@ -959,18 +1338,24 @@
|
|
|
959
1338
|
' var metadata = file.metadata || {};',
|
|
960
1339
|
' var prerequisites = Array.isArray(metadata.prerequisites) ? metadata.prerequisites : [];',
|
|
961
1340
|
' prerequisites.forEach(function(rawPrereq) {',
|
|
962
|
-
' var
|
|
963
|
-
' addEdge(
|
|
1341
|
+
' var prerequisiteFile = resolveReference(file, rawPrereq, referenceIndex);',
|
|
1342
|
+
' addEdge(prerequisiteFile && prerequisiteFile.id, sourceId, "explicit-prerequisite");',
|
|
964
1343
|
' });',
|
|
965
1344
|
'',
|
|
966
1345
|
' var nextItems = Array.isArray(metadata.next) ? metadata.next : [];',
|
|
967
1346
|
' nextItems.forEach(function(rawNext) {',
|
|
968
|
-
' var
|
|
969
|
-
' addEdge(sourceId,
|
|
1347
|
+
' var nextFile = resolveReference(file, rawNext, referenceIndex);',
|
|
1348
|
+
' addEdge(sourceId, nextFile && nextFile.id, "explicit-next");',
|
|
1349
|
+
' });',
|
|
1350
|
+
'',
|
|
1351
|
+
' extractWikiLinks(file.content).forEach(function(rawLink) {',
|
|
1352
|
+
' var linkedFile = resolveReference(file, rawLink, referenceIndex);',
|
|
1353
|
+
' addEdge(sourceId, linkedFile && linkedFile.id, "wiki-link");',
|
|
970
1354
|
' });',
|
|
971
1355
|
'',
|
|
972
|
-
'
|
|
973
|
-
'
|
|
1356
|
+
' extractMarkdownLinks(file.content).forEach(function(rawLink) {',
|
|
1357
|
+
' var linkedFile = resolveReference(file, rawLink, referenceIndex);',
|
|
1358
|
+
' addEdge(sourceId, linkedFile && linkedFile.id, "markdown-link");',
|
|
974
1359
|
' });',
|
|
975
1360
|
' });',
|
|
976
1361
|
'',
|
|
@@ -1143,9 +1528,22 @@
|
|
|
1143
1528
|
}
|
|
1144
1529
|
|
|
1145
1530
|
async function buildCapacitorGraphDataWithWorkerFallback(files) {
|
|
1531
|
+
const budget = getMobileRuntimeBudget();
|
|
1532
|
+
const validateGraphBudget = (graphData) => {
|
|
1533
|
+
if (!graphData || !Array.isArray(graphData.nodes) || !Array.isArray(graphData.edges)) {
|
|
1534
|
+
throw new Error('Capacitor graph payload is invalid.');
|
|
1535
|
+
}
|
|
1536
|
+
if (graphData.nodes.length > budget.maxDocuments) {
|
|
1537
|
+
throw new Error(`Capacitor graph node count exceeds ${budget.maxDocuments}.`);
|
|
1538
|
+
}
|
|
1539
|
+
if (graphData.edges.length > budget.maxEdges) {
|
|
1540
|
+
throw new Error(`Capacitor graph edge count exceeds ${budget.maxEdges}.`);
|
|
1541
|
+
}
|
|
1542
|
+
return graphData;
|
|
1543
|
+
};
|
|
1146
1544
|
if (!supportsCapacitorGraphBuildWorker()) {
|
|
1147
1545
|
return {
|
|
1148
|
-
graphData: buildCapacitorGraphData(files),
|
|
1546
|
+
graphData: validateGraphBudget(buildCapacitorGraphData(files)),
|
|
1149
1547
|
buildMode: 'single-thread'
|
|
1150
1548
|
};
|
|
1151
1549
|
}
|
|
@@ -1156,7 +1554,7 @@
|
|
|
1156
1554
|
throw new Error('Capacitor worker returned invalid graph payload.');
|
|
1157
1555
|
}
|
|
1158
1556
|
return {
|
|
1159
|
-
graphData: workerGraph,
|
|
1557
|
+
graphData: validateGraphBudget(workerGraph),
|
|
1160
1558
|
buildMode: 'worker'
|
|
1161
1559
|
};
|
|
1162
1560
|
} catch (workerErr) {
|
|
@@ -1166,7 +1564,7 @@
|
|
|
1166
1564
|
workerErr
|
|
1167
1565
|
);
|
|
1168
1566
|
return {
|
|
1169
|
-
graphData: buildCapacitorGraphData(files),
|
|
1567
|
+
graphData: validateGraphBudget(buildCapacitorGraphData(files)),
|
|
1170
1568
|
buildMode: 'single-thread-fallback',
|
|
1171
1569
|
warning
|
|
1172
1570
|
};
|
|
@@ -1208,16 +1606,27 @@
|
|
|
1208
1606
|
|
|
1209
1607
|
const files = await collectCapacitorMarkdownFiles(targetPath);
|
|
1210
1608
|
const buildResult = await buildCapacitorGraphDataWithWorkerFallback(files);
|
|
1211
|
-
const
|
|
1609
|
+
const projectionApi = window.NoteConnectionKnowledgeProjection;
|
|
1610
|
+
if (!projectionApi || typeof projectionApi.createKnowledgeProjection !== 'function') {
|
|
1611
|
+
throw new Error('Knowledge projection contract is unavailable in the mobile runtime.');
|
|
1612
|
+
}
|
|
1613
|
+
const graphData = projectionApi.createKnowledgeProjection(buildResult.graphData, {
|
|
1614
|
+
workspaceId: 'mobile-workspace',
|
|
1615
|
+
});
|
|
1616
|
+
const projectionMaxBytes = getMobileRuntimeBudget().maxProjectionBytes;
|
|
1617
|
+
const graphSerializationMaxBytes = Math.min(
|
|
1618
|
+
CAPACITOR_GRAPH_SERIALIZATION_MAX_BYTES,
|
|
1619
|
+
projectionMaxBytes
|
|
1620
|
+
);
|
|
1212
1621
|
const graphJsChunkFactory = createCapacitorGraphJavascriptChunkFactory(graphData);
|
|
1213
1622
|
const graphJsonChunkFactory = createCapacitorGraphJsonChunkFactory(graphData);
|
|
1214
1623
|
|
|
1215
1624
|
await capacitorWriteChunkSequence('data.js', graphJsChunkFactory, {
|
|
1216
|
-
maxPayloadBytes:
|
|
1625
|
+
maxPayloadBytes: graphSerializationMaxBytes,
|
|
1217
1626
|
payloadLabel: 'data.js graph payload'
|
|
1218
1627
|
});
|
|
1219
1628
|
await capacitorWriteChunkSequence('graph_data.json', graphJsonChunkFactory, {
|
|
1220
|
-
maxPayloadBytes:
|
|
1629
|
+
maxPayloadBytes: graphSerializationMaxBytes,
|
|
1221
1630
|
payloadLabel: 'graph_data.json graph payload'
|
|
1222
1631
|
});
|
|
1223
1632
|
|
|
@@ -1225,11 +1634,11 @@
|
|
|
1225
1634
|
const targetName = sanitizeTargetName(rawTarget);
|
|
1226
1635
|
if (targetName) {
|
|
1227
1636
|
await capacitorWriteChunkSequence(`data_${targetName}.js`, graphJsChunkFactory, {
|
|
1228
|
-
maxPayloadBytes:
|
|
1637
|
+
maxPayloadBytes: graphSerializationMaxBytes,
|
|
1229
1638
|
payloadLabel: `data_${targetName}.js graph payload`
|
|
1230
1639
|
});
|
|
1231
1640
|
await capacitorWriteChunkSequence(`graph_data_${targetName}.json`, graphJsonChunkFactory, {
|
|
1232
|
-
maxPayloadBytes:
|
|
1641
|
+
maxPayloadBytes: graphSerializationMaxBytes,
|
|
1233
1642
|
payloadLabel: `graph_data_${targetName}.json graph payload`
|
|
1234
1643
|
});
|
|
1235
1644
|
}
|
|
@@ -1295,6 +1704,23 @@
|
|
|
1295
1704
|
return new Error(`Storage provider operation is unsupported in this runtime: ${operation}`);
|
|
1296
1705
|
}
|
|
1297
1706
|
|
|
1707
|
+
function normalizeStorageProviderKind(value) {
|
|
1708
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
1709
|
+
if (normalized === 'sqlite' || normalized === 'embedded' || normalized === 'embedded-sqlite' || normalized === 'embedded_sqlite') {
|
|
1710
|
+
return 'sqlite';
|
|
1711
|
+
}
|
|
1712
|
+
if (normalized === 'file' || normalized === 'local-file' || normalized === 'snapshot') {
|
|
1713
|
+
return 'file';
|
|
1714
|
+
}
|
|
1715
|
+
if (normalized === 'projection' || normalized === 'mobile_projection' || normalized === 'mobile-slim') {
|
|
1716
|
+
return 'projection';
|
|
1717
|
+
}
|
|
1718
|
+
if (normalized === 'remote' || normalized === 'http' || normalized === 'external_http' || normalized === 'remote-http' || normalized === 'service') {
|
|
1719
|
+
return 'remote';
|
|
1720
|
+
}
|
|
1721
|
+
return null;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1298
1724
|
function formatCapacitorMtime(statObject) {
|
|
1299
1725
|
if (!statObject || typeof statObject !== 'object') {
|
|
1300
1726
|
return '';
|
|
@@ -1320,6 +1746,65 @@
|
|
|
1320
1746
|
class RuntimeStorageProvider {
|
|
1321
1747
|
constructor(runtimeCaps) {
|
|
1322
1748
|
this.runtimeCaps = runtimeCaps || {};
|
|
1749
|
+
this.mobileExactIndexPromise = null;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
getStorageResolution() {
|
|
1753
|
+
const runtimePlatform = String(this.runtimeCaps.platform || '').trim().toLowerCase();
|
|
1754
|
+
const mobileRuntime = isCapacitorNativeRuntime()
|
|
1755
|
+
|| runtimePlatform.includes('android')
|
|
1756
|
+
|| runtimePlatform.includes('ios')
|
|
1757
|
+
|| runtimePlatform === 'mobile';
|
|
1758
|
+
const requestedProvider = normalizeStorageProviderKind(
|
|
1759
|
+
this.runtimeCaps.storage_requested_provider
|
|
1760
|
+
) || (mobileRuntime ? 'projection' : 'sqlite');
|
|
1761
|
+
const reportedProvider = normalizeStorageProviderKind(this.runtimeCaps.storage_resolved_provider);
|
|
1762
|
+
const resolvedProvider = mobileRuntime
|
|
1763
|
+
? 'projection'
|
|
1764
|
+
: reportedProvider || undefined;
|
|
1765
|
+
const fallbackReason = String(
|
|
1766
|
+
this.runtimeCaps.storage_fallback_reason
|
|
1767
|
+
|| (mobileRuntime && requestedProvider === 'sqlite' ? 'native_sqlite_runtime_unavailable' : '')
|
|
1768
|
+
).trim();
|
|
1769
|
+
return Object.freeze({
|
|
1770
|
+
requestedProvider,
|
|
1771
|
+
resolvedProvider,
|
|
1772
|
+
fallbackReason: fallbackReason || undefined,
|
|
1773
|
+
supportsSqlite: !mobileRuntime && resolvedProvider === 'sqlite',
|
|
1774
|
+
supportsProjection: this.runtimeCaps.supports_projection_store !== false
|
|
1775
|
+
&& resolvedProvider === 'projection',
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
async refreshStorageResolution() {
|
|
1780
|
+
const current = this.getStorageResolution();
|
|
1781
|
+
if (isCapacitorNativeRuntime() || !this._supportsSidecar()) {
|
|
1782
|
+
return current;
|
|
1783
|
+
}
|
|
1784
|
+
try {
|
|
1785
|
+
const payload = await sidecarFetchJson('api/knowledge/store-diagnostics');
|
|
1786
|
+
const store = payload && payload.store && typeof payload.store === 'object'
|
|
1787
|
+
? payload.store
|
|
1788
|
+
: null;
|
|
1789
|
+
const resolvedProvider = normalizeStorageProviderKind(
|
|
1790
|
+
store && (store.resolvedProvider || store.storageEngine || store.provider)
|
|
1791
|
+
);
|
|
1792
|
+
if (resolvedProvider) {
|
|
1793
|
+
this.runtimeCaps = {
|
|
1794
|
+
...this.runtimeCaps,
|
|
1795
|
+
storage_requested_provider: normalizeStorageProviderKind(
|
|
1796
|
+
store.requestedProvider
|
|
1797
|
+
) || current.requestedProvider,
|
|
1798
|
+
storage_resolved_provider: resolvedProvider,
|
|
1799
|
+
storage_fallback_reason: String(store.fallbackReason || '').trim(),
|
|
1800
|
+
supports_sqlite: resolvedProvider === 'sqlite',
|
|
1801
|
+
};
|
|
1802
|
+
}
|
|
1803
|
+
} catch (_error) {
|
|
1804
|
+
// Capability probing is advisory; the normal storage operation
|
|
1805
|
+
// still owns the authoritative failure/fallback behavior.
|
|
1806
|
+
}
|
|
1807
|
+
return this.getStorageResolution();
|
|
1323
1808
|
}
|
|
1324
1809
|
|
|
1325
1810
|
_supportsSidecar() {
|
|
@@ -1558,6 +2043,95 @@
|
|
|
1558
2043
|
throw unsupportedOperationError('buildGraph');
|
|
1559
2044
|
}
|
|
1560
2045
|
|
|
2046
|
+
async _loadMobileExactIndex() {
|
|
2047
|
+
if (this.mobileExactIndexPromise) {
|
|
2048
|
+
return await this.mobileExactIndexPromise;
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
this.mobileExactIndexPromise = (async () => {
|
|
2052
|
+
const analyzer = window.NoteConnectionMobileExactAnalyzer;
|
|
2053
|
+
if (!analyzer || typeof analyzer.createMobileExactIndex !== 'function') {
|
|
2054
|
+
throw unsupportedOperationError('mobileExactAnalysis');
|
|
2055
|
+
}
|
|
2056
|
+
const storeApi = window.NoteConnectionKnowledgeProjectionStore;
|
|
2057
|
+
if (!storeApi || typeof storeApi.createProjectionStore !== 'function') {
|
|
2058
|
+
throw unsupportedOperationError('projectionStore');
|
|
2059
|
+
}
|
|
2060
|
+
const projectionStore = typeof storeApi.createFileProjectionStore === 'function'
|
|
2061
|
+
? storeApi.createFileProjectionStore({
|
|
2062
|
+
fileName: 'graph_data.json',
|
|
2063
|
+
maxBytes: getMobileRuntimeBudget().maxProjectionBytes,
|
|
2064
|
+
readFile: async (filename) => await this.readGeneratedAsset(filename),
|
|
2065
|
+
})
|
|
2066
|
+
: storeApi.createProjectionStore({
|
|
2067
|
+
maxBytes: getMobileRuntimeBudget().maxProjectionBytes,
|
|
2068
|
+
read: async () => await this.readGeneratedAsset('graph_data.json'),
|
|
2069
|
+
});
|
|
2070
|
+
const graph = await projectionStore.load();
|
|
2071
|
+
return analyzer.createMobileExactIndex(graph);
|
|
2072
|
+
})();
|
|
2073
|
+
|
|
2074
|
+
try {
|
|
2075
|
+
return await this.mobileExactIndexPromise;
|
|
2076
|
+
} catch (error) {
|
|
2077
|
+
this.mobileExactIndexPromise = null;
|
|
2078
|
+
throw error;
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
async queryKnowledgeBaseExact(request) {
|
|
2083
|
+
const payload = request && typeof request === 'object' ? request : {};
|
|
2084
|
+
const query = typeof payload.query === 'string' ? payload.query.trim() : '';
|
|
2085
|
+
if (!query) {
|
|
2086
|
+
throw new Error('Local exact query requires a non-empty query.');
|
|
2087
|
+
}
|
|
2088
|
+
const index = await this._loadMobileExactIndex();
|
|
2089
|
+
const matches = index.searchExact(query, payload.maxMatches);
|
|
2090
|
+
return {
|
|
2091
|
+
query,
|
|
2092
|
+
matches: matches.map((node) => ({
|
|
2093
|
+
...node,
|
|
2094
|
+
neighbors: index.neighbors(
|
|
2095
|
+
node.id,
|
|
2096
|
+
payload.maxNeighborsPerMatch,
|
|
2097
|
+
payload.edgeKinds
|
|
2098
|
+
),
|
|
2099
|
+
learningRoute: typeof index.learningRoute === 'function'
|
|
2100
|
+
? index.learningRoute(node.id, 6)
|
|
2101
|
+
: []
|
|
2102
|
+
})),
|
|
2103
|
+
statistics: index.statistics({ includeProvenance: true }),
|
|
2104
|
+
execution: 'local-exact',
|
|
2105
|
+
remoteInferenceUsed: false
|
|
2106
|
+
};
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
async findKnowledgePath(request) {
|
|
2110
|
+
const payload = request && typeof request === 'object' ? request : {};
|
|
2111
|
+
const sourceNodeId = typeof payload.sourceNodeId === 'string'
|
|
2112
|
+
? payload.sourceNodeId.trim()
|
|
2113
|
+
: '';
|
|
2114
|
+
const targetNodeId = typeof payload.targetNodeId === 'string'
|
|
2115
|
+
? payload.targetNodeId.trim()
|
|
2116
|
+
: '';
|
|
2117
|
+
if (!sourceNodeId || !targetNodeId) {
|
|
2118
|
+
throw new Error('Local knowledge path requires sourceNodeId and targetNodeId.');
|
|
2119
|
+
}
|
|
2120
|
+
const index = await this._loadMobileExactIndex();
|
|
2121
|
+
return {
|
|
2122
|
+
sourceNodeId,
|
|
2123
|
+
targetNodeId,
|
|
2124
|
+
path: index.shortestPath(
|
|
2125
|
+
sourceNodeId,
|
|
2126
|
+
targetNodeId,
|
|
2127
|
+
payload.maxDepth,
|
|
2128
|
+
payload.maxVisitedNodes
|
|
2129
|
+
),
|
|
2130
|
+
execution: 'local-exact',
|
|
2131
|
+
remoteInferenceUsed: false
|
|
2132
|
+
};
|
|
2133
|
+
}
|
|
2134
|
+
|
|
1561
2135
|
async readContent(filePath) {
|
|
1562
2136
|
if (!this._supportsContentApi()) {
|
|
1563
2137
|
throw unsupportedOperationError('readContent');
|
|
@@ -1565,7 +2139,9 @@
|
|
|
1565
2139
|
|
|
1566
2140
|
if (isCapacitorNativeRuntime()) {
|
|
1567
2141
|
const capacitorPath = resolveCapacitorContentCandidatePath(filePath);
|
|
1568
|
-
return await capacitorReadText(capacitorPath
|
|
2142
|
+
return await capacitorReadText(capacitorPath, {
|
|
2143
|
+
maxBytes: getMobileRuntimeBudget().maxDocumentBytes
|
|
2144
|
+
});
|
|
1569
2145
|
}
|
|
1570
2146
|
|
|
1571
2147
|
if (this._supportsSidecar()) {
|
|
@@ -1630,7 +2206,9 @@
|
|
|
1630
2206
|
try {
|
|
1631
2207
|
// Prefer local runtime-generated assets first so on-device builds
|
|
1632
2208
|
// are picked up without requiring an app rebundle.
|
|
1633
|
-
return await capacitorReadText(normalized
|
|
2209
|
+
return await capacitorReadText(normalized, {
|
|
2210
|
+
maxBytes: getMobileRuntimeBudget().maxProjectionBytes
|
|
2211
|
+
});
|
|
1634
2212
|
} catch (_fsErr) {
|
|
1635
2213
|
// Fall through to bundled asset fetch.
|
|
1636
2214
|
}
|
|
@@ -1658,6 +2236,18 @@
|
|
|
1658
2236
|
}
|
|
1659
2237
|
|
|
1660
2238
|
window.NoteConnectionStorage = {
|
|
1661
|
-
createProvider
|
|
2239
|
+
createProvider,
|
|
2240
|
+
measureUtf8Bytes
|
|
1662
2241
|
};
|
|
2242
|
+
|
|
2243
|
+
if (typeof module === 'object' && module.exports) {
|
|
2244
|
+
module.exports = {
|
|
2245
|
+
createProvider,
|
|
2246
|
+
buildCapacitorGraphData,
|
|
2247
|
+
getCapacitorGraphBuildWorkerSource,
|
|
2248
|
+
createMobileResourceIdentity,
|
|
2249
|
+
getMobileRuntimeBudget,
|
|
2250
|
+
measureUtf8Bytes,
|
|
2251
|
+
};
|
|
2252
|
+
}
|
|
1663
2253
|
}());
|