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,184 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs"));
37
+ const os = __importStar(require("os"));
38
+ const path = __importStar(require("path"));
39
+ describe('sidecar input freshness contract', () => {
40
+ const fingerprintPath = path.join(__dirname, '..', 'scripts', 'sidecar-build-fingerprint.js');
41
+ let fingerprint;
42
+ beforeAll(() => {
43
+ fingerprint = require(fingerprintPath);
44
+ });
45
+ test('content fingerprint changes even when an input keeps an older mtime', () => {
46
+ const repoRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-sidecar-fingerprint-'));
47
+ const distRoot = path.join(repoRoot, 'dist', 'src');
48
+ try {
49
+ fs.mkdirSync(distRoot, { recursive: true });
50
+ fs.mkdirSync(path.join(repoRoot, 'scripts'), { recursive: true });
51
+ fs.writeFileSync(path.join(repoRoot, 'package.json'), '{"name":"fixture"}', 'utf8');
52
+ fs.writeFileSync(path.join(repoRoot, 'tsconfig.json'), '{}', 'utf8');
53
+ fs.writeFileSync(path.join(repoRoot, 'scripts', 'build-sidecar.js'), 'build-v1', 'utf8');
54
+ const entryPath = path.join(distRoot, 'server.js');
55
+ fs.writeFileSync(entryPath, 'payload-v1', 'utf8');
56
+ const before = fingerprint.computeSidecarInputFingerprint(repoRoot);
57
+ fs.writeFileSync(entryPath, 'payload-v2', 'utf8');
58
+ const after = fingerprint.computeSidecarInputFingerprint(repoRoot);
59
+ expect(after.digest).not.toBe(before.digest);
60
+ expect(after.files.some((file) => file.path === 'dist/src/server.js')).toBe(true);
61
+ }
62
+ finally {
63
+ fs.rmSync(repoRoot, { recursive: true, force: true });
64
+ }
65
+ });
66
+ test('manifest validation rejects a stale packaged input and accepts the current digest', () => {
67
+ const repoRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-sidecar-manifest-'));
68
+ try {
69
+ fs.mkdirSync(path.join(repoRoot, 'dist', 'src'), { recursive: true });
70
+ fs.mkdirSync(path.join(repoRoot, 'scripts'), { recursive: true });
71
+ fs.writeFileSync(path.join(repoRoot, 'package.json'), '{"name":"fixture"}', 'utf8');
72
+ fs.writeFileSync(path.join(repoRoot, 'tsconfig.json'), '{}', 'utf8');
73
+ fs.writeFileSync(path.join(repoRoot, 'scripts', 'build-sidecar.js'), 'build-v1', 'utf8');
74
+ const entryPath = path.join(repoRoot, 'dist', 'src', 'server.js');
75
+ fs.writeFileSync(entryPath, 'payload-v1', 'utf8');
76
+ fingerprint.writeSidecarBuildManifest(repoRoot, ['server-fixture']);
77
+ expect(fingerprint.isSidecarBuildManifestCurrent(repoRoot)).toBe(true);
78
+ fs.writeFileSync(entryPath, 'payload-v2', 'utf8');
79
+ expect(fingerprint.isSidecarBuildManifestCurrent(repoRoot)).toBe(false);
80
+ expect(fingerprint.readSidecarBuildManifest(repoRoot)).not.toBeNull();
81
+ }
82
+ finally {
83
+ fs.rmSync(repoRoot, { recursive: true, force: true });
84
+ }
85
+ });
86
+ test('build and ensure scripts consume the same manifest contract', () => {
87
+ const buildSource = fs.readFileSync(path.join(repoRoot(), 'scripts', 'build-sidecar.js'), 'utf8');
88
+ const ensureSource = fs.readFileSync(path.join(repoRoot(), 'scripts', 'ensure-sidecar-ready.js'), 'utf8');
89
+ expect(buildSource).toContain("require('./sidecar-build-fingerprint.js')");
90
+ expect(buildSource).toContain('writeSidecarBuildManifest');
91
+ expect(ensureSource).toContain("require('./sidecar-build-fingerprint.js')");
92
+ expect(ensureSource).toContain('isSidecarBuildManifestCurrent');
93
+ expect(ensureSource).toContain('Sidecar input fingerprint is missing or stale');
94
+ });
95
+ test('uncompiled source changes invalidate otherwise unchanged packaged inputs', () => {
96
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-source-fingerprint-'));
97
+ try {
98
+ fs.mkdirSync(path.join(root, 'src'), { recursive: true });
99
+ fs.mkdirSync(path.join(root, 'dist', 'src'), { recursive: true });
100
+ const source = path.join(root, 'src', 'server.ts');
101
+ fs.writeFileSync(source, 'const revision = 1;\r\n');
102
+ fs.writeFileSync(path.join(root, 'dist', 'src', 'server.js'), 'const revision = 1;\n');
103
+ fingerprint.writeSidecarBuildManifest(root, ['server-fixture']);
104
+ const inputs = fingerprint.computeSidecarInputFingerprint(root).digest;
105
+ fs.writeFileSync(source, 'const revision = 1;\n');
106
+ expect(fingerprint.isSidecarBuildManifestCurrent(root)).toBe(true);
107
+ fs.writeFileSync(source, 'const revision = 2;\n');
108
+ expect(fingerprint.computeSidecarInputFingerprint(root).digest).toBe(inputs);
109
+ expect(fingerprint.isSidecarBuildManifestCurrent(root)).toBe(false);
110
+ }
111
+ finally {
112
+ fs.rmSync(root, { recursive: true, force: true });
113
+ }
114
+ });
115
+ test('Rust WASM compiler caches do not change source identity', () => {
116
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-source-cache-'));
117
+ try {
118
+ const source = path.join(root, 'src', 'backend', 'wasm', 'src');
119
+ fs.mkdirSync(source, { recursive: true });
120
+ fs.writeFileSync(path.join(source, 'lib.rs'), 'pub fn compute() {}\n');
121
+ const before = fingerprint.computeSidecarSourceFingerprint(root);
122
+ const cache = path.join(root, 'src', 'backend', 'wasm', 'target', 'release');
123
+ fs.mkdirSync(cache, { recursive: true });
124
+ fs.writeFileSync(path.join(cache, '.rustc_info.json'), '{"host":"one"}');
125
+ fs.writeFileSync(path.join(cache, 'compiler-output.rlib'), Buffer.from([0, 1, 2, 3]));
126
+ expect(fingerprint.computeSidecarSourceFingerprint(root)).toEqual(before);
127
+ fs.writeFileSync(path.join(source, 'lib.rs'), 'pub fn compute() { panic!(); }\n');
128
+ expect(fingerprint.computeSidecarSourceFingerprint(root).digest).not.toBe(before.digest);
129
+ }
130
+ finally {
131
+ fs.rmSync(root, { recursive: true, force: true });
132
+ }
133
+ });
134
+ test.each(['Cargo.lock', 'src/lib.rs'])('%s has the same source identity under LF and CRLF checkouts', (relativePath) => {
135
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-source-newline-'));
136
+ try {
137
+ const file = path.join(root, 'src', 'backend', 'wasm', relativePath);
138
+ fs.mkdirSync(path.dirname(file), { recursive: true });
139
+ fs.writeFileSync(file, 'first line\nsecond line\n');
140
+ const before = fingerprint.computeSidecarSourceFingerprint(root).digest;
141
+ fs.writeFileSync(file, 'first line\r\nsecond line\r\n');
142
+ expect(fingerprint.computeSidecarSourceFingerprint(root).digest).toBe(before);
143
+ fs.writeFileSync(file, 'first line\nchanged line\n');
144
+ expect(fingerprint.computeSidecarSourceFingerprint(root).digest).not.toBe(before);
145
+ }
146
+ finally {
147
+ fs.rmSync(root, { recursive: true, force: true });
148
+ }
149
+ });
150
+ test('ordinary target directories and new tests remain source inputs', () => {
151
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-source-target-'));
152
+ try {
153
+ const directory = path.join(root, 'src', 'learning', 'target');
154
+ fs.mkdirSync(directory, { recursive: true });
155
+ const initial = fingerprint.computeSidecarSourceFingerprint(root).digest;
156
+ fs.writeFileSync(path.join(directory, 'Reducer.ts'), 'export const revision = 1;\n');
157
+ const withSource = fingerprint.computeSidecarSourceFingerprint(root).digest;
158
+ expect(withSource).not.toBe(initial);
159
+ fs.writeFileSync(path.join(directory, 'Reducer.test.ts'), 'test("revision", () => {});\n');
160
+ expect(fingerprint.computeSidecarSourceFingerprint(root).digest).not.toBe(withSource);
161
+ }
162
+ finally {
163
+ fs.rmSync(root, { recursive: true, force: true });
164
+ }
165
+ });
166
+ test('compiled target directories remain fully bound by the artifact input fingerprint', () => {
167
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-dist-target-'));
168
+ try {
169
+ const directory = path.join(root, 'dist', 'src', 'backend', 'wasm', 'target');
170
+ fs.mkdirSync(directory, { recursive: true });
171
+ const file = path.join(directory, 'runtime.wasm');
172
+ fs.writeFileSync(file, Buffer.from([0, 1, 2, 3]));
173
+ const before = fingerprint.computeSidecarInputFingerprint(root).digest;
174
+ fs.writeFileSync(file, Buffer.from([0, 1, 2, 4]));
175
+ expect(fingerprint.computeSidecarInputFingerprint(root).digest).not.toBe(before);
176
+ }
177
+ finally {
178
+ fs.rmSync(root, { recursive: true, force: true });
179
+ }
180
+ });
181
+ });
182
+ function repoRoot() {
183
+ return path.resolve(__dirname, '..');
184
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs"));
37
+ const path = __importStar(require("path"));
38
+ describe('sidecar replacement boundary contract', () => {
39
+ const repoRoot = path.resolve(__dirname, '..');
40
+ const packageJsonPath = path.join(repoRoot, 'package.json');
41
+ const tauriConfigPath = path.join(repoRoot, 'src-tauri', 'tauri.conf.json');
42
+ const tauriAndroidConfigPath = path.join(repoRoot, 'src-tauri', 'tauri.android.conf.json');
43
+ const tauriLibPath = path.join(repoRoot, 'src-tauri', 'src', 'lib.rs');
44
+ const sourceManagerPath = path.join(repoRoot, 'src', 'frontend', 'source_manager.js');
45
+ const pathAppPath = path.join(repoRoot, 'src', 'frontend', 'path_app.js');
46
+ const serverPath = path.join(repoRoot, 'src', 'server.ts');
47
+ const pathBridgePath = path.join(repoRoot, 'src', 'core', 'PathBridge.ts');
48
+ const buildSidecarPath = path.join(repoRoot, 'scripts', 'build-sidecar.js');
49
+ const buildMarkdownWorkerPath = path.join(repoRoot, 'scripts', 'build-markdown-worker.js');
50
+ const ensureSidecarReadyPath = path.join(repoRoot, 'scripts', 'ensure-sidecar-ready.js');
51
+ const ensureGodotSidecarPath = path.join(repoRoot, 'scripts', 'ensure-godot-sidecar.js');
52
+ const markdownGatewayPath = path.join(repoRoot, 'src', 'markdown', 'MarkdownGateway.ts');
53
+ function readText(filePath) {
54
+ return fs.readFileSync(filePath, 'utf8');
55
+ }
56
+ function readJson(filePath) {
57
+ return JSON.parse(readText(filePath));
58
+ }
59
+ test('keeps node sidecar on the desktop build and startup path', () => {
60
+ const pkg = readJson(packageJsonPath);
61
+ const tauriConfig = readJson(tauriConfigPath);
62
+ const tauriLib = readText(tauriLibPath);
63
+ const sourceManager = readText(sourceManagerPath);
64
+ expect(pkg.scripts?.['build:sidecar']).toContain('node scripts/build-sidecar.js');
65
+ expect(pkg.scripts?.['tauri:build']).toContain('npm run build:sidecar');
66
+ expect(pkg.scripts?.['tauri:dev']).toContain('npm run ensure:sidecar:dev');
67
+ expect(tauriConfig.bundle?.externalBin || []).toContain('bin/server');
68
+ expect(tauriLib).toContain('let mut sidecar_command = app.shell().sidecar("server").unwrap();');
69
+ expect(tauriLib).toContain('Failed to spawn Node.js sidecar');
70
+ expect(sourceManager).toContain('if (runtimeCaps.supports_sidecar) {');
71
+ expect(sourceManager).toContain('const sidecarData = await fetchFoldersViaSidecar();');
72
+ });
73
+ test('keeps Godot bootstrap and spawn flow as part of the desktop contract', () => {
74
+ const pkg = readJson(packageJsonPath);
75
+ const tauriConfig = readJson(tauriConfigPath);
76
+ const tauriLib = readText(tauriLibPath);
77
+ const ensureSidecarReady = readText(ensureSidecarReadyPath);
78
+ const ensureGodotSidecar = readText(ensureGodotSidecarPath);
79
+ expect(pkg.scripts?.['prepare:godot:bin']).toBe('node scripts/ensure-godot-sidecar.js');
80
+ expect(tauriConfig.bundle?.externalBin || []).toContain('bin/godot');
81
+ expect(ensureSidecarReady).toContain("runNpmScript('prepare:godot:bin')");
82
+ expect(ensureGodotSidecar).toContain('prepareGodotSidecar');
83
+ expect(ensureGodotSidecar).toContain('resolveGodotBootstrapContext');
84
+ expect(tauriLib).toContain('match resolve_godot_executable(&project_root)');
85
+ expect(tauriLib).toContain('let mut godot_command = std::process::Command::new(&godot_exe);');
86
+ expect(tauriLib).toContain('Successfully spawned local Godot application.');
87
+ });
88
+ test('keeps markdown worker as a sidecar-era desktop dependency', () => {
89
+ const tauriConfig = readJson(tauriConfigPath);
90
+ const buildSidecar = readText(buildSidecarPath);
91
+ const buildMarkdownWorker = readText(buildMarkdownWorkerPath);
92
+ const markdownGateway = readText(markdownGatewayPath);
93
+ const server = readText(serverPath);
94
+ expect(tauriConfig.bundle?.externalBin || []).toContain('bin/markdown-worker');
95
+ expect(buildSidecar).toContain('runMarkdownWorkerBuild(');
96
+ expect(buildMarkdownWorker).toContain("outputName: 'markdown-worker-x86_64-pc-windows-msvc.exe'");
97
+ expect(buildMarkdownWorker).toContain("outputName: 'markdown-worker-x86_64-unknown-linux-gnu'");
98
+ expect(markdownGateway).toContain("return 'markdown-worker-x86_64-pc-windows-msvc.exe';");
99
+ expect(markdownGateway).toContain("return 'markdown-worker-x86_64-unknown-linux-gnu';");
100
+ expect(server).toContain("if (postPathname === '/api/markdown/resolve-node') {");
101
+ expect(server).toContain("if (postPathname === '/api/markdown/resolve-wiki') {");
102
+ });
103
+ test('keeps PathBridge as the desktop Godot synchronization boundary', () => {
104
+ const server = readText(serverPath);
105
+ const pathBridge = readText(pathBridgePath);
106
+ const sourceManager = readText(sourceManagerPath);
107
+ const pathApp = readText(pathAppPath);
108
+ expect(server).toContain("import { PathBridge } from './core/PathBridge';");
109
+ expect(server).toContain('pathBridge = new PathBridge({');
110
+ expect(server).toContain('PathBridge initialized on ws://');
111
+ expect(pathBridge).toContain("console.log('[PathBridge] Godot requested path data');");
112
+ expect(sourceManager).toContain('const bootstrapDesktopPathProducer = () => {');
113
+ expect(sourceManager).toContain('window.pathApp.setupEarlyWebSocket({');
114
+ expect(pathApp).toContain("window.NoteConnectionRuntime.getBridgeWsUrl('frontend')");
115
+ expect(pathApp).toContain("this._sendBridgeMessage('identify', this._getBridgeIdentifyPayload('frontend'))");
116
+ });
117
+ test('keeps the default Android build sidecar-free and makes Godot opt-in', () => {
118
+ const pkg = readJson(packageJsonPath);
119
+ const tauriAndroidConfig = readJson(tauriAndroidConfigPath);
120
+ const tauriLib = readText(tauriLibPath);
121
+ expect(pkg.scripts?.['tauri:android:dev']).toContain('npm run mobile:prepare:slim');
122
+ expect(pkg.scripts?.['tauri:android:build']).toContain('npm run mobile:prepare:slim');
123
+ expect(pkg.scripts?.['tauri:android:dev']).not.toContain('npm run build:sidecar');
124
+ expect(pkg.scripts?.['tauri:android:build']).not.toContain('npm run build:sidecar');
125
+ expect(tauriAndroidConfig.bundle?.externalBin || []).toEqual([]);
126
+ expect(tauriAndroidConfig.build?.frontendDist).toBe('../dist/mobile-slim/frontend');
127
+ expect(tauriLib).toContain('supports_sidecar: false');
128
+ expect(tauriLib).toContain('supports_build: true');
129
+ expect(tauriLib).toContain('Android startup: desktop sidecar and Godot launch are intentionally disabled.');
130
+ });
131
+ });
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs"));
37
+ const os = __importStar(require("os"));
38
+ const path = __importStar(require("path"));
39
+ class TempDir {
40
+ constructor(prefix) {
41
+ this.path = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), `${prefix}-`));
42
+ }
43
+ child(relative) {
44
+ return path.join(this.path, relative);
45
+ }
46
+ mkdir(relative) {
47
+ const target = this.child(relative);
48
+ fs.mkdirSync(target, { recursive: true });
49
+ return target;
50
+ }
51
+ cleanup() {
52
+ fs.rmSync(this.path, { recursive: true, force: true });
53
+ }
54
+ }
55
+ describe('sidecar supply readiness contract', () => {
56
+ const repoRoot = path.resolve(__dirname, '..');
57
+ const packageJsonPath = path.join(repoRoot, 'package.json');
58
+ const utilsPath = path.join(repoRoot, 'scripts', 'sidecar-supply-readiness-utils.js');
59
+ let utils;
60
+ let temp;
61
+ beforeAll(() => {
62
+ utils = require(utilsPath);
63
+ });
64
+ beforeEach(() => {
65
+ temp = new TempDir('noteconnection-sidecar-supply');
66
+ });
67
+ afterEach(() => {
68
+ temp.cleanup();
69
+ });
70
+ test('package exposes a local sidecar supply verifier command', () => {
71
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
72
+ expect(pkg.scripts?.['verify:sidecar:supply']).toBe('node scripts/verify-sidecar-supply-readiness.js');
73
+ });
74
+ test('reports offline-ready when host artifacts already exist locally', () => {
75
+ const fakeRepo = temp.mkdir('repo');
76
+ const binDir = temp.mkdir(path.join('repo', 'src-tauri', 'bin'));
77
+ temp.mkdir(path.join('repo', '.github', 'workflows'));
78
+ fs.writeFileSync(path.join(fakeRepo, '.gitattributes'), '');
79
+ fs.writeFileSync(path.join(binDir, 'server-x86_64-unknown-linux-gnu'), 'server');
80
+ fs.writeFileSync(path.join(binDir, 'markdown-worker-x86_64-unknown-linux-gnu'), 'worker');
81
+ fs.writeFileSync(path.join(binDir, 'godot-x86_64-unknown-linux-gnu'), Buffer.alloc(1024 * 1024 + 64, 7));
82
+ const result = utils.evaluateSidecarSupplyReadiness({
83
+ repoRoot: fakeRepo,
84
+ platform: 'linux',
85
+ arch: 'x64',
86
+ env: {},
87
+ });
88
+ expect(result.offlineBootstrapReady).toBe(true);
89
+ expect(result.rating).toBe('offline-ready');
90
+ expect(result.artifacts.server.ready).toBe(true);
91
+ expect(result.artifacts.markdownWorker.ready).toBe(true);
92
+ expect(result.artifacts.godot.ready).toBe(true);
93
+ expect(result.artifacts.godot.networkRequiredForBootstrap).toBe(false);
94
+ expect(result.ci.releaseWorkflowMirrorFirstDownload).toBe(false);
95
+ expect(result.ci.releaseWorkflowDirectUpstreamDownload).toBe(false);
96
+ expect(result.ci.releaseWorkflowArchiveDigestPinned).toBe(false);
97
+ expect(result.ci.releaseWorkflowMirrorOnlyModeAvailable).toBe(false);
98
+ expect(result.ci.releaseWorkflowDefaultUpstreamFallbackEnabled).toBe(false);
99
+ });
100
+ test('reports network-dependent when godot is only reachable through configured download fallback', () => {
101
+ const fakeRepo = temp.mkdir('repo');
102
+ const binDir = temp.mkdir(path.join('repo', 'src-tauri', 'bin'));
103
+ temp.mkdir(path.join('repo', '.github', 'workflows'));
104
+ fs.writeFileSync(path.join(fakeRepo, '.gitattributes'), '');
105
+ fs.writeFileSync(path.join(binDir, 'server-x86_64-unknown-linux-gnu'), 'server');
106
+ fs.writeFileSync(path.join(binDir, 'markdown-worker-x86_64-unknown-linux-gnu'), 'worker');
107
+ const result = utils.evaluateSidecarSupplyReadiness({
108
+ repoRoot: fakeRepo,
109
+ platform: 'linux',
110
+ arch: 'x64',
111
+ env: {
112
+ NOTE_CONNECTION_GODOT_DOWNLOAD_URL: 'https://mirror.example/godot.zip',
113
+ NOTE_CONNECTION_GODOT_DOWNLOAD_SHA256: 'a'.repeat(64),
114
+ },
115
+ });
116
+ expect(result.offlineBootstrapReady).toBe(false);
117
+ expect(result.rating).toBe('network-dependent');
118
+ expect(result.artifacts.godot.ready).toBe(false);
119
+ expect(result.artifacts.godot.downloadConfigured).toBe(true);
120
+ expect(result.artifacts.godot.pinnedDownload).toBe(true);
121
+ expect(result.artifacts.godot.networkRequiredForBootstrap).toBe(true);
122
+ expect(result.artifacts.godot.sourceKindsAvailable).toContain('download');
123
+ });
124
+ test('does not accept a malformed centralized archive digest', () => {
125
+ const fakeRepo = temp.mkdir('repo');
126
+ temp.mkdir(path.join('repo', '.github', 'workflows'));
127
+ temp.mkdir(path.join('repo', 'config'));
128
+ fs.copyFileSync(path.join(repoRoot, '.github/workflows/release-desktop-multi-os.yml'), path.join(fakeRepo, '.github/workflows/release-desktop-multi-os.yml'));
129
+ const runtime = JSON.parse(fs.readFileSync(path.join(repoRoot, 'config/godot-desktop-runtime.json'), 'utf8'));
130
+ runtime.archives.windows.sha256 = 'unverified';
131
+ fs.writeFileSync(path.join(fakeRepo, 'config/godot-desktop-runtime.json'), JSON.stringify(runtime));
132
+ const result = utils.evaluateSidecarSupplyReadiness({ repoRoot: fakeRepo, platform: 'linux', arch: 'x64', env: {} });
133
+ expect(result.ci.releaseWorkflowArchiveDigestPinned).toBe(false);
134
+ });
135
+ test('current repo pins archive digests and can disable upstream fallback for mirror-only release smoke runs', () => {
136
+ const result = utils.evaluateSidecarSupplyReadiness({
137
+ repoRoot,
138
+ platform: 'linux',
139
+ arch: 'x64',
140
+ env: {},
141
+ });
142
+ expect(result.ci.releaseWorkflowMirrorFirstDownload).toBe(true);
143
+ expect(result.ci.releaseWorkflowDirectUpstreamDownload).toBe(true);
144
+ expect(result.ci.releaseWorkflowArchiveDigestPinned).toBe(true);
145
+ expect(result.ci.releaseWorkflowMirrorOnlyModeAvailable).toBe(true);
146
+ expect(result.ci.releaseWorkflowDefaultUpstreamFallbackEnabled).toBe(true);
147
+ expect(result.legacyLfsProtectedPaths).toEqual([
148
+ 'src-tauri/bin/godot-x86_64-pc-windows-msvc.exe',
149
+ 'src-tauri/bin/server-aarch64-apple-darwin',
150
+ 'src-tauri/bin/server-x86_64-pc-windows-msvc.exe',
151
+ 'src-tauri/bin/server-x86_64-unknown-linux-gnu',
152
+ ]);
153
+ expect(result.recommendations).toContain('Keep the release workflow mirror-first, keep archive digest pinning enforced, exercise mirror-only smoke runs regularly, and remove default upstream fallback reliance before strict no-LFS mode.');
154
+ });
155
+ });
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs"));
37
+ const path = __importStar(require("path"));
38
+ const vm = __importStar(require("vm"));
39
+ describe('offline graph simulation worker', () => {
40
+ beforeEach(() => jest.useFakeTimers());
41
+ afterEach(() => {
42
+ jest.clearAllTimers();
43
+ jest.useRealTimers();
44
+ });
45
+ test.each(['force', 'dag'])('computes %s layout using only packaged dependencies', (mode) => {
46
+ const frontend = path.join(__dirname, 'frontend');
47
+ const ticks = [];
48
+ const worker = vm.createContext({
49
+ console: { log() { }, warn() { }, error() { } },
50
+ Date,
51
+ performance: { now: () => Date.now() },
52
+ setTimeout,
53
+ clearTimeout,
54
+ setInterval,
55
+ clearInterval,
56
+ postMessage(message) {
57
+ if (message.type === 'tick')
58
+ ticks.push(message);
59
+ },
60
+ });
61
+ worker.self = worker;
62
+ worker.importScripts = (...scripts) => {
63
+ for (const script of scripts) {
64
+ const url = new URL(script, 'http://appimage.local/simulationWorker.js');
65
+ if (url.origin !== 'http://appimage.local') {
66
+ throw new Error(`External network is disabled: ${url.href}`);
67
+ }
68
+ const filename = path.join(frontend, url.pathname);
69
+ vm.runInContext(fs.readFileSync(filename, 'utf8'), worker, { filename });
70
+ }
71
+ };
72
+ vm.runInContext(fs.readFileSync(path.join(frontend, 'simulationWorker.js'), 'utf8'), worker);
73
+ worker.onmessage({ data: { type: 'init', payload: {
74
+ nodes: [{ id: 'start', rank: 0 }, { id: 'middle', rank: 1 }, { id: 'end', rank: 2 }],
75
+ links: [{ source: 'start', target: 'middle' }, { source: 'middle', target: 'end' }],
76
+ width: 800,
77
+ height: 600,
78
+ settings: { gpuRendering: false },
79
+ } } });
80
+ if (mode === 'dag')
81
+ worker.onmessage({ data: { type: 'updateLayout', payload: { mode, width: 800 } } });
82
+ jest.advanceTimersByTime(2500);
83
+ worker.onmessage({ data: { type: 'stop' } });
84
+ expect(ticks.length).toBeGreaterThan(5);
85
+ const first = ticks[0];
86
+ const last = ticks[ticks.length - 1];
87
+ expect(last.tickMode).toBe('full');
88
+ expect(last.nodes.map(node => node.id)).toEqual(['start', 'middle', 'end']);
89
+ expect(Number.isFinite(last.alpha)).toBe(true);
90
+ expect(last.alpha).toBeLessThan(first.alpha);
91
+ for (const node of last.nodes) {
92
+ expect(Number.isFinite(node.x)).toBe(true);
93
+ expect(Number.isFinite(node.y)).toBe(true);
94
+ for (const other of last.nodes.filter(other => other.id !== node.id)) {
95
+ expect(Math.hypot(node.x - other.x, node.y - other.y)).toBeGreaterThan(1);
96
+ }
97
+ }
98
+ expect(last.nodes.some((node, index) => Math.hypot(node.x - first.nodes[index].x, node.y - first.nodes[index].y) > 1)).toBe(true);
99
+ if (mode === 'dag') {
100
+ expect(last.nodes[0].y).toBeLessThan(last.nodes[1].y);
101
+ expect(last.nodes[1].y).toBeLessThan(last.nodes[2].y);
102
+ }
103
+ });
104
+ });
@@ -79,6 +79,7 @@ describe('source manager load-flow guards', () => {
79
79
  test('waits for sidecar readiness and retries data.js fetch during tauri startup race', () => {
80
80
  const source = fs.readFileSync(sourceManagerPath, 'utf8');
81
81
  expect(source).toContain('const waitForSidecarReady = async () => {');
82
+ expect(source).toContain("if (window.__TAURI__ && runtimeCaps.supports_sidecar) {");
82
83
  expect(source).toContain('await waitForSidecarReady();');
83
84
  expect(source).toContain("data.js fetch raced sidecar startup, retrying");
84
85
  expect(source).toContain('const maxAttempts = (window.__TAURI__ && runtimeCaps.supports_sidecar) ? 20 : 1;');
@@ -88,6 +89,7 @@ describe('source manager load-flow guards', () => {
88
89
  });
89
90
  test('parses graph payload fallback without runtime eval', () => {
90
91
  const source = fs.readFileSync(sourceManagerPath, 'utf8');
92
+ expect(source).toContain('const extractAssignedJson = (sourceText, equalsIndex) => {');
91
93
  expect(source).toContain('const assignmentTargets = [');
92
94
  expect(source).not.toContain('new Function(');
93
95
  expect(source).toContain('Invalid graph data payload from sidecar (unsupported format).');
@@ -114,6 +116,31 @@ describe('source manager load-flow guards', () => {
114
116
  expect(indexHtml.indexOf('<script src="runtime_bridge.js"></script>')).toBeLessThan(indexHtml.indexOf('<script src="source_manager.js"></script>'));
115
117
  expect(indexHtml.indexOf('<script src="storage_provider.js"></script>')).toBeLessThan(indexHtml.indexOf('<script src="source_manager.js"></script>'));
116
118
  });
119
+ test('disables ES module bootstrap when the legacy script chain is already active', () => {
120
+ const indexPath = path.join(repoRoot, 'src', 'frontend', 'index.html');
121
+ const mainModulePath = path.join(repoRoot, 'src', 'frontend', 'main.mjs');
122
+ const indexHtml = fs.readFileSync(indexPath, 'utf8');
123
+ const mainModule = fs.readFileSync(mainModulePath, 'utf8');
124
+ expect(indexHtml).toContain('<script type="module" src="./main.mjs"></script>');
125
+ expect(indexHtml).not.toContain('window.__NC_DISABLE_MODULE_BOOT = true;');
126
+ expect(mainModule).toContain('function shouldSkipModuleBootstrap()');
127
+ expect(mainModule).toContain('window.i18n || window.NoteConnectionRuntime || window.settingsManager');
128
+ expect(mainModule).toContain("src.endsWith('i18n.js')");
129
+ expect(mainModule).toContain("await import('./i18n.mjs');");
130
+ expect(mainModule).not.toContain("import './i18n.mjs';");
131
+ });
132
+ test('allows Tauri ipc localhost in frontend CSP without relying on meta frame-ancestors', () => {
133
+ const indexPath = path.join(repoRoot, 'src', 'frontend', 'index.html');
134
+ const notemdPath = path.join(repoRoot, 'src', 'frontend', 'notemd.html');
135
+ const indexHtml = fs.readFileSync(indexPath, 'utf8');
136
+ const notemdHtml = fs.readFileSync(notemdPath, 'utf8');
137
+ expect(indexHtml).toContain("http://ipc.localhost");
138
+ expect(indexHtml).toContain("ipc:");
139
+ expect(indexHtml).not.toContain("frame-ancestors");
140
+ expect(notemdHtml).toContain("http://ipc.localhost");
141
+ expect(notemdHtml).toContain("ipc:");
142
+ expect(notemdHtml).not.toContain("frame-ancestors");
143
+ });
117
144
  test('loads runtime bridge before path_app on the dedicated path mode page', () => {
118
145
  const pathHtmlPath = path.join(repoRoot, 'src', 'frontend', 'path.html');
119
146
  const pathHtml = fs.readFileSync(pathHtmlPath, 'utf8');
@@ -135,4 +162,23 @@ describe('source manager load-flow guards', () => {
135
162
  expect(pathAppSource).toContain("bridge.whenReady()");
136
163
  expect(() => new (require('vm').Script)(pathAppSource)).not.toThrow();
137
164
  });
165
+ test('keeps analysis panel resilient when graphData is not available yet', () => {
166
+ const analysisPath = path.join(repoRoot, 'src', 'frontend', 'analysis.js');
167
+ const analysisSource = fs.readFileSync(analysisPath, 'utf8');
168
+ expect(analysisSource).toContain('function getGraphDataSafe()');
169
+ expect(analysisSource).toContain('return { nodes: [], edges: [] };');
170
+ expect(analysisSource).toContain("const tot = graphData ? graphData.nodes.length : 0;");
171
+ });
172
+ test('treats detached frontend preview pages as backend-less runtimes and loads data assets via validated text parsing', () => {
173
+ const source = fs.readFileSync(sourceManagerPath, 'utf8');
174
+ const enLocale = fs.readFileSync(path.join(repoRoot, 'src', 'frontend', 'locales', 'en.json'), 'utf8');
175
+ const zhLocale = fs.readFileSync(path.join(repoRoot, 'src', 'frontend', 'locales', 'zh.json'), 'utf8');
176
+ expect(source).toContain('const canUseBrowserRuntimeBackend = () => {');
177
+ expect(source).toContain("Frontend preview runtime detected: backend-dependent APIs disabled");
178
+ expect(source).toContain('const isStandaloneFrontendPreviewRuntime = () =>');
179
+ expect(source).toContain('Loaded ${src} via frontend preview asset');
180
+ expect(source).toContain("previewOption.textContent = t('source.previewPath')");
181
+ expect(enLocale).toContain('"previewPath"');
182
+ expect(zhLocale).toContain('"previewPath"');
183
+ });
138
184
  });