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.
Files changed (328) hide show
  1. package/LICENSE +674 -21
  2. package/README.md +260 -1626
  3. package/dist/src/agent_workspace.contract.parity.test.js +159 -0
  4. package/dist/src/agent_workspace.frontend.test.js +10388 -0
  5. package/dist/src/agent_workspace.locale.contract.test.js +95 -0
  6. package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
  7. package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
  8. package/dist/src/appimage.patchelf.test.js +113 -0
  9. package/dist/src/appimage.portability.test.js +156 -0
  10. package/dist/src/backend/FileLoader.js +18 -4
  11. package/dist/src/backend/FileLoader.test.js +125 -0
  12. package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
  13. package/dist/src/backend/GraphBuilder.js +66 -18
  14. package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
  15. package/dist/src/backend/GraphMetrics.js +0 -3
  16. package/dist/src/backend/ResourceIdentity.js +155 -0
  17. package/dist/src/backend/ResourceIdentity.test.js +113 -0
  18. package/dist/src/backend/algorithms/CycleDetection.js +0 -1
  19. package/dist/src/backend/algorithms/HybridEngine.js +0 -3
  20. package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
  21. package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
  22. package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
  23. package/dist/src/backend/build_dag.js +0 -1
  24. package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
  25. package/dist/src/capacitor.runtime.contract.test.js +11 -2
  26. package/dist/src/copy.assets.contract.test.js +130 -0
  27. package/dist/src/core/Graph.js +138 -42
  28. package/dist/src/core/Graph.test.js +74 -0
  29. package/dist/src/core/NoteConnection.js +2 -2
  30. package/dist/src/core/PathBridge.js +293 -5
  31. package/dist/src/core/ResourceReference.js +17 -0
  32. package/dist/src/desktop.godot.pack.test.js +142 -0
  33. package/dist/src/desktop.runtime.graph.test.js +66 -0
  34. package/dist/src/export/WorkspaceExportBundle.js +1174 -0
  35. package/dist/src/export/WorkspaceExportBundle.test.js +1541 -0
  36. package/dist/src/export/index.js +18 -0
  37. package/dist/src/export/types.js +2 -0
  38. package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
  39. package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
  40. package/dist/src/foundation.release.evidence.contract.test.js +524 -0
  41. package/dist/src/foundation.sqlite.runtime.contract.test.js +88 -0
  42. package/dist/src/frontend/README.md +260 -1626
  43. package/dist/src/frontend/agent_workspace.js +6011 -0
  44. package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
  45. package/dist/src/frontend/analysis.js +31 -4
  46. package/dist/src/frontend/app.js +2178 -62
  47. package/dist/src/frontend/focus_mode_interactions.js +33 -0
  48. package/dist/src/frontend/godot_future_path_renderer.js +540 -0
  49. package/dist/src/frontend/godot_tree_interactions.js +178 -0
  50. package/dist/src/frontend/graph_state.mjs +105 -0
  51. package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
  52. package/dist/src/frontend/i18n.mjs +186 -0
  53. package/dist/src/frontend/index.html +672 -268
  54. package/dist/src/frontend/knowledge_projection_contract.js +230 -0
  55. package/dist/src/frontend/knowledge_projection_store.js +214 -0
  56. package/dist/src/frontend/layout_gpu.js +12 -4
  57. package/dist/src/frontend/libs/path_core.js +158 -42
  58. package/dist/src/frontend/locales/en.json +753 -5
  59. package/dist/src/frontend/locales/zh.json +753 -5
  60. package/dist/src/frontend/main.mjs +60 -0
  61. package/dist/src/frontend/markdown_runtime.js +827 -0
  62. package/dist/src/frontend/mobile_budget_runtime.js +33 -0
  63. package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
  64. package/dist/src/frontend/mobile_identity_contract.js +221 -0
  65. package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
  66. package/dist/src/frontend/notemd.css +49 -0
  67. package/dist/src/frontend/notemd.html +7 -1
  68. package/dist/src/frontend/notemd.js +64 -0
  69. package/dist/src/frontend/path.html +113 -2
  70. package/dist/src/frontend/path_app.js +2108 -130
  71. package/dist/src/frontend/path_layout.mjs +143 -0
  72. package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
  73. package/dist/src/frontend/path_modules_bridge.js +486 -0
  74. package/dist/src/frontend/path_state.mjs +118 -0
  75. package/dist/src/frontend/path_styles.css +146 -0
  76. package/dist/src/frontend/path_worker_bridge.mjs +85 -0
  77. package/dist/src/frontend/reader.js +393 -33
  78. package/dist/src/frontend/runtime_bridge.js +67 -54
  79. package/dist/src/frontend/runtime_bridge.mjs +279 -0
  80. package/dist/src/frontend/settings.js +130 -12
  81. package/dist/src/frontend/simulationWorker.js +1 -1
  82. package/dist/src/frontend/source_manager.js +297 -22
  83. package/dist/src/frontend/storage_provider.js +661 -71
  84. package/dist/src/frontend/styles.css +2814 -72
  85. package/dist/src/frontend/workbench_state.mjs +101 -0
  86. package/dist/src/frontend/workspace_panes.js +10272 -0
  87. package/dist/src/frontend.locale.contract.test.js +62 -0
  88. package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
  89. package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
  90. package/dist/src/graph.answer.operator.contract.test.js +72 -0
  91. package/dist/src/index.js +6 -2
  92. package/dist/src/index.knowledge-root.test.js +118 -0
  93. package/dist/src/indexing/IndexLifecycle.js +217 -0
  94. package/dist/src/indexing/IndexLifecycle.test.js +73 -0
  95. package/dist/src/indexing/SegmentBuilder.js +64 -0
  96. package/dist/src/indexing/UnitBuilder.js +48 -0
  97. package/dist/src/indexing/types.js +2 -0
  98. package/dist/src/knowledge.api.contract.test.js +172 -0
  99. package/dist/src/knowledge_projection.contract.test.js +134 -0
  100. package/dist/src/knowledge_projection_store.test.js +200 -0
  101. package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
  102. package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
  103. package/dist/src/learning/KnowledgeLearningPlatform.js +11181 -0
  104. package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +745 -0
  105. package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
  106. package/dist/src/learning/KnowledgeLearningPlatform.test.js +3208 -0
  107. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2998 -0
  108. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3936 -0
  109. package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
  110. package/dist/src/learning/PublicAnswerContract.test.js +85 -0
  111. package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
  112. package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
  113. package/dist/src/learning/agentConversationExecution.js +211 -0
  114. package/dist/src/learning/agentConversationExecution.test.js +209 -0
  115. package/dist/src/learning/agentConversationSerialization.js +266 -0
  116. package/dist/src/learning/agentConversationSerialization.test.js +165 -0
  117. package/dist/src/learning/agentResponseBudget.js +179 -0
  118. package/dist/src/learning/agentResponseBudget.test.js +97 -0
  119. package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
  120. package/dist/src/learning/answerReleaseReview.js +5260 -0
  121. package/dist/src/learning/answerReleaseReview.test.js +4174 -0
  122. package/dist/src/learning/answerTaskPlan.js +473 -0
  123. package/dist/src/learning/api.js +2 -0
  124. package/dist/src/learning/conversationComposer.js +1721 -0
  125. package/dist/src/learning/conversationComposer.test.js +3220 -0
  126. package/dist/src/learning/domains/ConversationManager.js +53 -0
  127. package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
  128. package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
  129. package/dist/src/learning/domains/MasteryEngine.js +387 -0
  130. package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
  131. package/dist/src/learning/domains/QualityEvaluator.js +307 -0
  132. package/dist/src/learning/domains/TutorRouter.js +313 -0
  133. package/dist/src/learning/domains/index.js +33 -0
  134. package/dist/src/learning/domains/types.js +7 -0
  135. package/dist/src/learning/errors.js +29 -0
  136. package/dist/src/learning/evidenceContextAssembler.js +1368 -0
  137. package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
  138. package/dist/src/learning/graphAnswerCoverage.js +37 -0
  139. package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
  140. package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
  141. package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
  142. package/dist/src/learning/graphAnswerFacts.js +94 -0
  143. package/dist/src/learning/graphAnswerFacts.test.js +39 -0
  144. package/dist/src/learning/graphAnswerPlan.js +908 -0
  145. package/dist/src/learning/graphAnswerPlan.test.js +907 -0
  146. package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
  147. package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
  148. package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
  149. package/dist/src/learning/graphClaimMatcher.js +104 -0
  150. package/dist/src/learning/graphConditionedContext.js +109 -0
  151. package/dist/src/learning/graphConditionedContext.test.js +99 -0
  152. package/dist/src/learning/graphContextAssembler.js +860 -0
  153. package/dist/src/learning/graphContextAssembler.test.js +1033 -0
  154. package/dist/src/learning/graphExpansionPolicy.js +22 -0
  155. package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
  156. package/dist/src/learning/identityMetadata.test.js +26 -0
  157. package/dist/src/learning/index.js +29 -0
  158. package/dist/src/learning/mobileAnswerProjection.js +104 -0
  159. package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
  160. package/dist/src/learning/queryBackend.js +1922 -0
  161. package/dist/src/learning/queryBackend.test.js +976 -0
  162. package/dist/src/learning/ragContextPack.js +356 -0
  163. package/dist/src/learning/ragContextPack.test.js +311 -0
  164. package/dist/src/learning/ragEvidenceQuality.js +96 -0
  165. package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
  166. package/dist/src/learning/ragPublicText.js +101 -0
  167. package/dist/src/learning/ragPublicText.test.js +57 -0
  168. package/dist/src/learning/ragSufficiencyJudge.js +171 -0
  169. package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
  170. package/dist/src/learning/ragSufficiencyProviderJudge.js +217 -0
  171. package/dist/src/learning/ragSufficiencyProviderJudge.test.js +207 -0
  172. package/dist/src/learning/requestNormalization.js +304 -0
  173. package/dist/src/learning/requestNormalization.test.js +101 -0
  174. package/dist/src/learning/runtimeCapability.js +4677 -0
  175. package/dist/src/learning/runtimeCapability.test.js +3635 -0
  176. package/dist/src/learning/store.js +1344 -0
  177. package/dist/src/learning/store.test.js +1425 -0
  178. package/dist/src/learning/tutorAdapter.js +2 -0
  179. package/dist/src/learning/types.js +2 -0
  180. package/dist/src/learning/vectorAccelerationAdapter.js +958 -0
  181. package/dist/src/learning/vectorAccelerationAdapter.test.js +412 -0
  182. package/dist/src/learning/workspaceHydration.js +168 -0
  183. package/dist/src/learning/workspaceHydration.test.js +30 -0
  184. package/dist/src/lfs.asset.policy.contract.test.js +153 -0
  185. package/dist/src/license.policy.contract.test.js +71 -0
  186. package/dist/src/markdown/MarkdownGateway.js +4 -0
  187. package/dist/src/markdown/MarkdownGateway.test.js +59 -0
  188. package/dist/src/memory/MemoryGovernance.js +74 -0
  189. package/dist/src/memory/MemoryGovernance.test.js +46 -0
  190. package/dist/src/memory/types.js +2 -0
  191. package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
  192. package/dist/src/middleware/SseResponseWriter.js +122 -0
  193. package/dist/src/middleware/SseResponseWriter.test.js +54 -0
  194. package/dist/src/middleware/auth.js +38 -0
  195. package/dist/src/middleware/auth.test.js +33 -0
  196. package/dist/src/middleware/body-parser.js +45 -0
  197. package/dist/src/middleware/cors.js +44 -0
  198. package/dist/src/middleware/index.js +22 -0
  199. package/dist/src/middleware/request-trace.js +96 -0
  200. package/dist/src/mobile.android.evidence.contract.test.js +146 -0
  201. package/dist/src/mobile.android.signing.contract.test.js +66 -0
  202. package/dist/src/mobile.artifact.contract.test.js +144 -0
  203. package/dist/src/mobile.budget.contract.test.js +90 -0
  204. package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
  205. package/dist/src/mobile.graph.parity.contract.test.js +207 -0
  206. package/dist/src/mobile.identity.contract.test.js +66 -0
  207. package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
  208. package/dist/src/mobile.identity.corpus.test.js +40 -0
  209. package/dist/src/mobile.native.recovery.contract.test.js +64 -0
  210. package/dist/src/mobile.pipeline.test.js +11 -1
  211. package/dist/src/mobile.profile.contract.test.js +225 -0
  212. package/dist/src/mobile.semantic.parity.test.js +92 -0
  213. package/dist/src/mobile_exact_analyzer.test.js +113 -0
  214. package/dist/src/notemd/AppConfigToml.js +6 -4
  215. package/dist/src/notemd/ContentGenerator.js +4 -9
  216. package/dist/src/notemd/FileProcessor.js +4 -9
  217. package/dist/src/notemd/MermaidProcessor.js +400 -50
  218. package/dist/src/notemd/NotemdService.js +506 -26
  219. package/dist/src/notemd/PromptManager.js +15 -0
  220. package/dist/src/notemd/Translator.js +4 -9
  221. package/dist/src/notemd/cli/commands.js +357 -0
  222. package/dist/src/notemd/cli/dispatcher.js +225 -0
  223. package/dist/src/notemd/cli/index.js +169 -0
  224. package/dist/src/notemd/cli/parser.js +68 -0
  225. package/dist/src/notemd/cli/types.js +2 -0
  226. package/dist/src/notemd/constants.js +43 -0
  227. package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
  228. package/dist/src/notemd/diagram/diagramSpec.js +79 -0
  229. package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
  230. package/dist/src/notemd/diagram/intent.js +95 -0
  231. package/dist/src/notemd/diagram/planner.js +71 -0
  232. package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
  233. package/dist/src/notemd/diagram/types.js +18 -0
  234. package/dist/src/notemd/index.js +26 -0
  235. package/dist/src/notemd/operations/capabilityManifest.js +23 -0
  236. package/dist/src/notemd/operations/cliContracts.js +17 -0
  237. package/dist/src/notemd/operations/configProfileCommands.js +85 -0
  238. package/dist/src/notemd/operations/registry.contract.test.js +95 -0
  239. package/dist/src/notemd/operations/registry.js +991 -0
  240. package/dist/src/notemd/operations/types.js +2 -0
  241. package/dist/src/notemd/progressReporter.js +9 -0
  242. package/dist/src/notemd/providerDiagnostics.js +220 -0
  243. package/dist/src/notemd/providerProfiles.js +42 -0
  244. package/dist/src/notemd/providerTemplates.js +231 -0
  245. package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
  246. package/dist/src/notemd/search/SearchManager.js +13 -0
  247. package/dist/src/notemd/search/SearchProvider.js +2 -0
  248. package/dist/src/notemd/search/TavilyProvider.js +44 -0
  249. package/dist/src/notemd.agent.manifest.test.js +85 -0
  250. package/dist/src/notemd.api.contract.test.js +14 -1
  251. package/dist/src/notemd.app_config_toml.test.js +2 -1
  252. package/dist/src/notemd.batch.workflow.test.js +117 -0
  253. package/dist/src/notemd.cli.e2e.test.js +136 -0
  254. package/dist/src/notemd.core.test.js +51 -0
  255. package/dist/src/notemd.diagram.pipeline.test.js +233 -0
  256. package/dist/src/notemd.providerTemplates.test.js +34 -0
  257. package/dist/src/notemd.server.integration.test.js +262 -39
  258. package/dist/src/notemd.workflow.pipeline.test.js +162 -0
  259. package/dist/src/pathbridge.handshake.contract.test.js +45 -2
  260. package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
  261. package/dist/src/pathcore.bundle.contract.test.js +8 -0
  262. package/dist/src/pathmode.background.contract.test.js +69 -0
  263. package/dist/src/pathmode.settings.api.contract.test.js +9 -0
  264. package/dist/src/pkg.sidecar.contract.test.js +9 -3
  265. package/dist/src/platform/ExportProfile.js +86 -0
  266. package/dist/src/platform/MobileBudget.js +11 -0
  267. package/dist/src/platform/PlatformCapabilities.js +59 -0
  268. package/dist/src/platform/PlatformCapabilities.test.js +36 -0
  269. package/dist/src/platform/RenderMaterializer.js +33 -0
  270. package/dist/src/platform/RenderMaterializer.test.js +32 -0
  271. package/dist/src/query_backend.external_http.integration.test.js +410 -0
  272. package/dist/src/reader_renderer.js +404 -3
  273. package/dist/src/reader_renderer.test.js +87 -0
  274. package/dist/src/release.godot.mirror.contract.test.js +97 -0
  275. package/dist/src/resources/ResourceRegistry.js +263 -0
  276. package/dist/src/resources/ResourceRegistry.test.js +97 -0
  277. package/dist/src/resources/types.js +2 -0
  278. package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
  279. package/dist/src/routes/index.js +19 -0
  280. package/dist/src/routes/knowledge.js +981 -0
  281. package/dist/src/routes/knowledgePayload.js +185 -0
  282. package/dist/src/routes/knowledgePayload.test.js +53 -0
  283. package/dist/src/routes/markdown.js +295 -0
  284. package/dist/src/routes/notemd.js +1321 -0
  285. package/dist/src/routes/registry.contract.test.js +133 -0
  286. package/dist/src/routes/registry.shadow.contract.test.js +22 -0
  287. package/dist/src/routes/render.js +248 -0
  288. package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
  289. package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
  290. package/dist/src/routes/settings.js +6 -0
  291. package/dist/src/routes/staticFiles.js +94 -0
  292. package/dist/src/routes/types.js +2 -0
  293. package/dist/src/runtime.capabilities.test.js +18 -2
  294. package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
  295. package/dist/src/server.js +10342 -1325
  296. package/dist/src/server.migration.test.js +584 -10
  297. package/dist/src/server.port.fallback.contract.test.js +63 -0
  298. package/dist/src/session/SessionStateStore.js +81 -0
  299. package/dist/src/session/SessionStateStore.test.js +58 -0
  300. package/dist/src/session/types.js +2 -0
  301. package/dist/src/settings.runtime.contract.test.js +50 -0
  302. package/dist/src/shared/types.contract.test.js +107 -0
  303. package/dist/src/shared/types.js +22 -0
  304. package/dist/src/sidecar.build.lock.contract.test.js +201 -0
  305. package/dist/src/sidecar.freshness.contract.test.js +184 -0
  306. package/dist/src/sidecar.replacement.boundary.contract.test.js +131 -0
  307. package/dist/src/sidecar.supply.readiness.contract.test.js +155 -0
  308. package/dist/src/simulation.worker.offline.test.js +104 -0
  309. package/dist/src/source_manager.loadflow.test.js +46 -0
  310. package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
  311. package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
  312. package/dist/src/storage.provider.contract.test.js +152 -1
  313. package/dist/src/tauri.frontend.build.contract.test.js +68 -0
  314. package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
  315. package/dist/src/tauri.window.evidence.execution.test.js +68 -0
  316. package/dist/src/utils/RuntimePaths.js +10 -13
  317. package/dist/src/utils/RuntimePaths.test.js +27 -0
  318. package/dist/src/utils/platform.js +153 -0
  319. package/dist/src/windows.installer.build.test.js +109 -0
  320. package/dist/src/windows.installer.payload.test.js +76 -0
  321. package/dist/src/windows.installer.runtime.test.js +69 -0
  322. package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
  323. package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
  324. package/dist/src/workflows/types.js +2 -0
  325. package/dist/src/workspace/WorkspaceRegistry.js +135 -0
  326. package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
  327. package/dist/src/workspace/types.js +2 -0
  328. package/package.json +80 -15
@@ -0,0 +1,230 @@
1
+ (function attachKnowledgeProjectionContract(root, factory) {
2
+ const api = factory();
3
+ if (typeof module === 'object' && module.exports) {
4
+ module.exports = api;
5
+ }
6
+ if (root) {
7
+ root.NoteConnectionKnowledgeProjection = api;
8
+ }
9
+ }(typeof globalThis !== 'undefined' ? globalThis : this, function createKnowledgeProjectionContract() {
10
+ 'use strict';
11
+
12
+ const SCHEMA_VERSION = 1;
13
+ const MAX_NODES = 50000;
14
+ const MAX_EDGES = 250000;
15
+ const MAX_NEIGHBORS = 64;
16
+ const MAX_EVIDENCE_REFS = 8;
17
+
18
+ function isRecord(value) {
19
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
20
+ }
21
+
22
+ function cleanString(value) {
23
+ return typeof value === 'string' ? value.trim() : '';
24
+ }
25
+
26
+ function cleanStringList(value, fieldName, limit) {
27
+ if (value === undefined || value === null) {
28
+ return [];
29
+ }
30
+ if (!Array.isArray(value)) {
31
+ throw new Error(`${fieldName} must be an array when provided.`);
32
+ }
33
+ const values = Array.from(new Set(value.map(cleanString).filter(Boolean)));
34
+ if (values.length > limit) {
35
+ throw new Error(`${fieldName} exceeds the bounded limit of ${limit}.`);
36
+ }
37
+ return values;
38
+ }
39
+
40
+ function classifyEdgeKind(rawType, rawKind) {
41
+ const kind = cleanString(rawKind).toLowerCase();
42
+ if (kind === 'explicit' || kind === 'inferred' || kind === 'runtime') {
43
+ return kind;
44
+ }
45
+ const type = cleanString(rawType).toLowerCase();
46
+ if (type.includes('inferred') || type.includes('keyword') || type.includes('vector') || type.includes('statistical')) {
47
+ return 'inferred';
48
+ }
49
+ if (type === 'runtime' || type.includes('runtime')) {
50
+ return 'runtime';
51
+ }
52
+ return 'explicit';
53
+ }
54
+
55
+ function assertSupportedVersion(value) {
56
+ const version = value === undefined || value === null ? SCHEMA_VERSION : Number(value);
57
+ if (!Number.isInteger(version) || version < 1 || version > SCHEMA_VERSION) {
58
+ throw new Error(`Unsupported knowledge projection schema version: ${String(value)}.`);
59
+ }
60
+ return version;
61
+ }
62
+
63
+ function normalizeNode(rawNode, maxEvidenceRefs) {
64
+ if (!isRecord(rawNode)) {
65
+ throw new Error('Knowledge projection nodes must be objects.');
66
+ }
67
+ const id = cleanString(rawNode.id);
68
+ if (!id) {
69
+ throw new Error('Knowledge projection node id must be non-empty.');
70
+ }
71
+ return {
72
+ id,
73
+ canonicalId: cleanString(rawNode.canonicalId),
74
+ label: cleanString(rawNode.label) || id,
75
+ sourceUri: cleanString(rawNode.sourceUri),
76
+ revision: cleanString(rawNode.revision),
77
+ identityAliases: cleanStringList(rawNode.identityAliases, `node ${id}.identityAliases`, 16),
78
+ evidenceRefs: cleanStringList(rawNode.evidenceRefs, `node ${id}.evidenceRefs`, maxEvidenceRefs),
79
+ tags: cleanStringList(rawNode.tags || (rawNode.metadata && rawNode.metadata.tags), `node ${id}.tags`, 32),
80
+ };
81
+ }
82
+
83
+ function normalizeEdge(rawEdge, nodeById, maxEvidenceRefs) {
84
+ if (!isRecord(rawEdge)) {
85
+ throw new Error('Knowledge projection edges must be objects.');
86
+ }
87
+ const source = cleanString(rawEdge.source || rawEdge.from);
88
+ const target = cleanString(rawEdge.target || rawEdge.to);
89
+ if (!source || !target || source === target || !nodeById.has(source) || !nodeById.has(target)) {
90
+ throw new Error(`Knowledge projection edge references an invalid node: ${source || '?'} -> ${target || '?'}.`);
91
+ }
92
+ const type = cleanString(rawEdge.type) || 'association';
93
+ const confidence = Number(rawEdge.confidence ?? rawEdge.weight);
94
+ const sourceNode = nodeById.get(source);
95
+ const targetNode = nodeById.get(target);
96
+ return {
97
+ source,
98
+ target,
99
+ sourceUri: cleanString(rawEdge.sourceUri) || sourceNode.sourceUri,
100
+ targetUri: cleanString(rawEdge.targetUri) || targetNode.sourceUri,
101
+ type,
102
+ kind: classifyEdgeKind(type, rawEdge.kind),
103
+ provenance: cleanString(rawEdge.provenance) || type,
104
+ confidence: Number.isFinite(confidence) ? Math.max(0, Math.min(1, confidence)) : 1,
105
+ evidenceRefs: cleanStringList(rawEdge.evidenceRefs, `edge ${source}->${target}.evidenceRefs`, maxEvidenceRefs),
106
+ };
107
+ }
108
+
109
+ function buildAdjacency(nodes, edges, maxNeighbors) {
110
+ const adjacency = new Map(nodes.map((node) => [node.id, { outgoing: [], incoming: [] }]));
111
+ edges.forEach((edge) => {
112
+ const source = adjacency.get(edge.source);
113
+ const target = adjacency.get(edge.target);
114
+ if (source.outgoing.length < maxNeighbors && !source.outgoing.includes(edge.target)) {
115
+ source.outgoing.push(edge.target);
116
+ }
117
+ if (target.incoming.length < maxNeighbors && !target.incoming.includes(edge.source)) {
118
+ target.incoming.push(edge.source);
119
+ }
120
+ });
121
+ return Array.from(adjacency, ([nodeId, value]) => ({ nodeId, ...value }));
122
+ }
123
+
124
+ function normalizeProjection(rawProjection, options) {
125
+ if (!isRecord(rawProjection)) {
126
+ throw new Error('Knowledge projection must be an object.');
127
+ }
128
+ const maxNodes = Math.min(MAX_NODES, Math.max(1, Number(options && options.maxNodes) || MAX_NODES));
129
+ const maxEdges = Math.min(MAX_EDGES, Math.max(1, Number(options && options.maxEdges) || MAX_EDGES));
130
+ const maxNeighbors = Math.min(MAX_NEIGHBORS, Math.max(1, Number(options && options.maxNeighbors) || MAX_NEIGHBORS));
131
+ const maxEvidenceRefs = MAX_EVIDENCE_REFS;
132
+ const declaredSchemaVersion = rawProjection.schemaVersion !== undefined
133
+ ? rawProjection.schemaVersion
134
+ : rawProjection.projectionVersion;
135
+ const schemaVersion = assertSupportedVersion(declaredSchemaVersion);
136
+ const rawNodes = Array.isArray(rawProjection.nodes) ? rawProjection.nodes : [];
137
+ const rawEdges = Array.isArray(rawProjection.edges) ? rawProjection.edges : [];
138
+ if (rawNodes.length > maxNodes || rawEdges.length > maxEdges) {
139
+ throw new Error(`Knowledge projection exceeds bounded size: ${rawNodes.length} nodes / ${rawEdges.length} edges.`);
140
+ }
141
+
142
+ const nodes = rawNodes.map((node) => normalizeNode(node, maxEvidenceRefs));
143
+ const nodeIds = new Set();
144
+ const normalizedIds = new Set();
145
+ const canonicalIds = new Set();
146
+ nodes.forEach((node) => {
147
+ const normalizedId = node.id.normalize ? node.id.normalize('NFC').toLowerCase() : node.id.toLowerCase();
148
+ if (nodeIds.has(node.id) || normalizedIds.has(normalizedId)) {
149
+ throw new Error(`Knowledge projection contains a duplicate node id: ${node.id}.`);
150
+ }
151
+ nodeIds.add(node.id);
152
+ normalizedIds.add(normalizedId);
153
+ if (node.canonicalId) {
154
+ const normalizedCanonicalId = node.canonicalId.normalize
155
+ ? node.canonicalId.normalize('NFC').toLowerCase()
156
+ : node.canonicalId.toLowerCase();
157
+ if (canonicalIds.has(normalizedCanonicalId)
158
+ || (normalizedCanonicalId !== normalizedId && normalizedIds.has(normalizedCanonicalId))) {
159
+ throw new Error(`Knowledge projection contains a duplicate canonical node id: ${node.canonicalId}.`);
160
+ }
161
+ canonicalIds.add(normalizedCanonicalId);
162
+ }
163
+ });
164
+
165
+ const edgeKeys = new Set();
166
+ const nodeById = new Map(nodes.map((node) => [node.id, node]));
167
+ const edges = rawEdges.map((edge) => normalizeEdge(edge, nodeById, maxEvidenceRefs))
168
+ .filter((edge) => {
169
+ // Preserve distinct provenance for the same directed endpoints.
170
+ // Collapsing by kind loses whether a link was explicit-next, wiki, or markdown.
171
+ const key = `${edge.source}->${edge.target}:${edge.kind}:${edge.type}:${edge.provenance}`;
172
+ if (edgeKeys.has(key)) {
173
+ return false;
174
+ }
175
+ edgeKeys.add(key);
176
+ return true;
177
+ });
178
+
179
+ return {
180
+ schemaVersion,
181
+ projectionVersion: schemaVersion,
182
+ workspaceId: cleanString(rawProjection.workspaceId) || 'workspace',
183
+ revision: cleanString(rawProjection.revision),
184
+ nodes,
185
+ edges,
186
+ adjacency: buildAdjacency(nodes, edges, maxNeighbors),
187
+ extensions: isRecord(rawProjection.extensions) ? rawProjection.extensions : {},
188
+ };
189
+ }
190
+
191
+ function createKnowledgeProjection(graph, options) {
192
+ if (!isRecord(graph)) {
193
+ throw new Error('Knowledge graph payload must be an object.');
194
+ }
195
+ const projectionOptions = isRecord(options) ? options : {};
196
+ return normalizeProjection({
197
+ ...graph,
198
+ schemaVersion: graph.schemaVersion !== undefined
199
+ ? graph.schemaVersion
200
+ : (graph.projectionVersion !== undefined ? graph.projectionVersion : SCHEMA_VERSION),
201
+ workspaceId: projectionOptions.workspaceId !== undefined
202
+ ? projectionOptions.workspaceId
203
+ : graph.workspaceId,
204
+ revision: projectionOptions.revision !== undefined
205
+ ? projectionOptions.revision
206
+ : graph.revision,
207
+ }, projectionOptions);
208
+ }
209
+
210
+ function replayKnowledgeProjection(serialized, options) {
211
+ let payload = serialized;
212
+ if (typeof serialized === 'string') {
213
+ try {
214
+ payload = JSON.parse(serialized);
215
+ } catch (error) {
216
+ throw new Error(`Knowledge projection JSON is invalid: ${String(error && error.message || error)}.`);
217
+ }
218
+ }
219
+ return normalizeProjection(payload, options);
220
+ }
221
+
222
+ return Object.freeze({
223
+ schemaVersion: SCHEMA_VERSION,
224
+ limits: Object.freeze({ maxNodes: MAX_NODES, maxEdges: MAX_EDGES, maxNeighbors: MAX_NEIGHBORS, maxEvidenceRefs: MAX_EVIDENCE_REFS }),
225
+ classifyEdgeKind,
226
+ normalizeProjection,
227
+ createKnowledgeProjection,
228
+ replayKnowledgeProjection,
229
+ });
230
+ }));
@@ -0,0 +1,214 @@
1
+ (function attachKnowledgeProjectionStore(root, factory) {
2
+ const api = factory(root && root.NoteConnectionKnowledgeProjection);
3
+ if (typeof module === 'object' && module.exports) {
4
+ module.exports = api;
5
+ }
6
+ if (root) {
7
+ root.NoteConnectionKnowledgeProjectionStore = api;
8
+ }
9
+ }(typeof globalThis !== 'undefined' ? globalThis : this, function createProjectionStoreApi(projectionContract) {
10
+ 'use strict';
11
+
12
+ const STORE_VERSION = 1;
13
+ const FALLBACK_MAX_BYTES = 48 * 1024 * 1024;
14
+
15
+ function defaultMaxBytes() {
16
+ const root = typeof globalThis !== 'undefined' ? globalThis : null;
17
+ const runtime = root && root.NoteConnectionMobileBudget && root.NoteConnectionMobileBudget.runtime;
18
+ return runtime && Number.isInteger(runtime.maxProjectionBytes) && runtime.maxProjectionBytes > 0
19
+ ? runtime.maxProjectionBytes
20
+ : FALLBACK_MAX_BYTES;
21
+ }
22
+
23
+ function requireProjectionContract() {
24
+ if (!projectionContract || typeof projectionContract.replayKnowledgeProjection !== 'function') {
25
+ throw new Error('Knowledge projection contract is unavailable.');
26
+ }
27
+ return projectionContract;
28
+ }
29
+
30
+ function normalizeProjection(value, options) {
31
+ return requireProjectionContract().replayKnowledgeProjection(value, options);
32
+ }
33
+
34
+ function measureBytes(value) {
35
+ const text = String(value || '');
36
+ if (typeof TextEncoder === 'function') {
37
+ return new TextEncoder().encode(text).length;
38
+ }
39
+ if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
40
+ return Buffer.byteLength(text, 'utf8');
41
+ }
42
+ return text.length;
43
+ }
44
+
45
+ function metadataFor(projection) {
46
+ return Object.freeze({
47
+ schemaVersion: projection.schemaVersion,
48
+ projectionVersion: projection.projectionVersion,
49
+ workspaceId: projection.workspaceId,
50
+ revision: projection.revision,
51
+ nodeCount: projection.nodes.length,
52
+ edgeCount: projection.edges.length,
53
+ });
54
+ }
55
+
56
+ function createMemoryProjectionStore(initialProjection, options) {
57
+ const normalizedOptions = options && typeof options === 'object' ? options : {};
58
+ let current = initialProjection === undefined || initialProjection === null
59
+ ? null
60
+ : normalizeProjection(initialProjection, normalizedOptions);
61
+
62
+ return Object.freeze({
63
+ kind: 'memory',
64
+ async load() {
65
+ return current;
66
+ },
67
+ async save(projection) {
68
+ current = normalizeProjection(projection, normalizedOptions);
69
+ return current;
70
+ },
71
+ async metadata() {
72
+ return current ? metadataFor(current) : null;
73
+ },
74
+ });
75
+ }
76
+
77
+ function createPersistentProjectionStore(options) {
78
+ const normalizedOptions = options && typeof options === 'object' ? options : {};
79
+ const read = normalizedOptions.read;
80
+ const write = normalizedOptions.write;
81
+ if (typeof read !== 'function') {
82
+ return createMemoryProjectionStore(normalizedOptions.initialProjection, normalizedOptions);
83
+ }
84
+
85
+ const maxBytes = Math.max(1024, Math.floor(Number(normalizedOptions.maxBytes) || defaultMaxBytes()));
86
+ let cached = normalizedOptions.initialProjection === undefined || normalizedOptions.initialProjection === null
87
+ ? null
88
+ : normalizeProjection(normalizedOptions.initialProjection, normalizedOptions);
89
+ let hasLoaded = false;
90
+ let loadPromise = null;
91
+
92
+ const load = async () => {
93
+ if (hasLoaded && cached) {
94
+ return cached;
95
+ }
96
+ if (loadPromise) {
97
+ return await loadPromise;
98
+ }
99
+ loadPromise = (async () => {
100
+ let payload;
101
+ try {
102
+ payload = await read();
103
+ } catch (error) {
104
+ if (cached) {
105
+ return cached;
106
+ }
107
+ throw error;
108
+ }
109
+ const serialized = typeof payload === 'string' ? payload : JSON.stringify(payload);
110
+ if (typeof serialized !== 'string') {
111
+ throw new Error('Knowledge projection payload is not serializable.');
112
+ }
113
+ if (measureBytes(serialized) > maxBytes) {
114
+ throw new Error(`Knowledge projection payload exceeds ${maxBytes} bytes.`);
115
+ }
116
+ // Validation errors must not be hidden by a stale in-memory value.
117
+ cached = normalizeProjection(payload, normalizedOptions);
118
+ hasLoaded = true;
119
+ return cached;
120
+ })();
121
+ try {
122
+ return await loadPromise;
123
+ } finally {
124
+ loadPromise = null;
125
+ }
126
+ };
127
+
128
+ return Object.freeze({
129
+ kind: typeof write === 'function' ? 'persistent' : 'read-through',
130
+ load,
131
+ async save(projection) {
132
+ const next = normalizeProjection(projection, normalizedOptions);
133
+ const serialized = JSON.stringify(next);
134
+ if (measureBytes(serialized) > maxBytes) {
135
+ throw new Error(`Knowledge projection payload exceeds ${maxBytes} bytes.`);
136
+ }
137
+ if (typeof write !== 'function') {
138
+ throw new Error('Knowledge projection store is read-only in this runtime.');
139
+ }
140
+ await write(serialized, next);
141
+ cached = next;
142
+ hasLoaded = true;
143
+ return next;
144
+ },
145
+ async metadata() {
146
+ const projection = await load();
147
+ return projection ? metadataFor(projection) : null;
148
+ },
149
+ });
150
+ }
151
+
152
+ function createFileProjectionStore(options) {
153
+ const normalizedOptions = options && typeof options === 'object' ? options : {};
154
+ const fileName = typeof normalizedOptions.fileName === 'string'
155
+ ? normalizedOptions.fileName.trim()
156
+ : '';
157
+ const readFile = normalizedOptions.readFile;
158
+ const writeAtomic = normalizedOptions.writeAtomic;
159
+
160
+ if (!fileName) {
161
+ throw new Error('App-local projection file name is required.');
162
+ }
163
+ if (typeof readFile !== 'function') {
164
+ throw new Error('App-local projection readFile adapter is required.');
165
+ }
166
+ if (writeAtomic !== undefined && typeof writeAtomic !== 'function') {
167
+ throw new Error('App-local projection writeAtomic adapter must be callable.');
168
+ }
169
+ if (normalizedOptions.write !== undefined) {
170
+ throw new Error('App-local projection writes must use the writeAtomic adapter.');
171
+ }
172
+
173
+ const persistentOptions = {
174
+ ...Object.fromEntries(Object.entries(normalizedOptions).filter(([key]) => (
175
+ key !== 'fileName'
176
+ && key !== 'readFile'
177
+ && key !== 'writeAtomic'
178
+ && key !== 'read'
179
+ && key !== 'write'
180
+ ))),
181
+ read: async () => await readFile(fileName),
182
+ };
183
+ if (typeof writeAtomic === 'function') {
184
+ persistentOptions.write = async (serialized, projection) => {
185
+ await writeAtomic(fileName, serialized, projection);
186
+ };
187
+ }
188
+
189
+ const store = createPersistentProjectionStore(persistentOptions);
190
+ return Object.freeze({
191
+ ...store,
192
+ kind: typeof writeAtomic === 'function' ? 'file-persistent' : 'file-read-through',
193
+ fileName,
194
+ });
195
+ }
196
+
197
+ function createProjectionStore(options) {
198
+ const normalizedOptions = options && typeof options === 'object' ? options : {};
199
+ if (typeof normalizedOptions.read === 'function') {
200
+ return createPersistentProjectionStore(normalizedOptions);
201
+ }
202
+ return createMemoryProjectionStore(normalizedOptions.initialProjection, normalizedOptions);
203
+ }
204
+
205
+ return Object.freeze({
206
+ storeVersion: STORE_VERSION,
207
+ defaultMaxBytes: FALLBACK_MAX_BYTES,
208
+ createProjectionStore,
209
+ createMemoryProjectionStore,
210
+ createPersistentProjectionStore,
211
+ createFileProjectionStore,
212
+ metadataFor,
213
+ });
214
+ }));
@@ -232,7 +232,17 @@ class GPULinkForce {
232
232
  const nLinks = this._links.length;
233
233
  console.log(`[GPULink] Initializing for ${n} nodes, ${nLinks} links.`);
234
234
 
235
- if (n === 0) return;
235
+ if (this.kernel) {
236
+ this.kernel.destroy();
237
+ this.kernel = null;
238
+ }
239
+
240
+ if (n === 0 || nLinks === 0) {
241
+ this.adjHead = new Float32Array(n);
242
+ this.adjCount = new Float32Array(n);
243
+ this.flatIndices = new Float32Array(0);
244
+ return;
245
+ }
236
246
 
237
247
  // Build Adjacency List (Source <-> Target)
238
248
  // D3 Link Force is symmetric: force acts on both ends.
@@ -295,8 +305,6 @@ class GPULinkForce {
295
305
  // Limit max neighbors width for texture if needed?
296
306
  // gpu.js handles 1D arrays well.
297
307
 
298
- if (this.kernel) this.kernel.destroy();
299
-
300
308
  // ---------------------------------------------------------
301
309
  // KERNEL
302
310
  // ---------------------------------------------------------
@@ -368,7 +376,7 @@ class GPULinkForce {
368
376
  }
369
377
 
370
378
  force(alpha) {
371
- if (!this.available || this.nodes.length === 0) return;
379
+ if (!this.available || this.nodes.length === 0 || this._links.length === 0 || this.flatIndices.length === 0) return;
372
380
 
373
381
  const n = this.nodes.length;
374
382
  const posX = new Float32Array(n);