noteconnection 1.6.8 → 1.8.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 (212) hide show
  1. package/LICENSE +674 -21
  2. package/README.md +258 -64
  3. package/dist/src/agent_workspace.contract.parity.test.js +475 -0
  4. package/dist/src/agent_workspace.frontend.test.js +9989 -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/copy.assets.contract.test.js +130 -0
  8. package/dist/src/core/PathBridge.js +28 -3
  9. package/dist/src/export/WorkspaceExportBundle.js +1130 -0
  10. package/dist/src/export/WorkspaceExportBundle.test.js +1480 -0
  11. package/dist/src/export/index.js +18 -0
  12. package/dist/src/export/types.js +2 -0
  13. package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
  14. package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
  15. package/dist/src/foundation.release.evidence.contract.test.js +406 -0
  16. package/dist/src/foundation.sqlite.runtime.contract.test.js +82 -0
  17. package/dist/src/frontend/README.md +258 -64
  18. package/dist/src/frontend/agent_workspace.js +5353 -0
  19. package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
  20. package/dist/src/frontend/analysis.js +31 -4
  21. package/dist/src/frontend/app.js +3597 -141
  22. package/dist/src/frontend/focus_mode_interactions.js +33 -0
  23. package/dist/src/frontend/godot_future_path_renderer.js +540 -0
  24. package/dist/src/frontend/godot_tree_interactions.js +178 -0
  25. package/dist/src/frontend/graph_state.mjs +105 -0
  26. package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
  27. package/dist/src/frontend/i18n.mjs +186 -0
  28. package/dist/src/frontend/index.html +641 -266
  29. package/dist/src/frontend/layout_gpu.js +12 -4
  30. package/dist/src/frontend/locales/en.json +721 -5
  31. package/dist/src/frontend/locales/zh.json +721 -5
  32. package/dist/src/frontend/main.mjs +60 -0
  33. package/dist/src/frontend/markdown_runtime.js +827 -0
  34. package/dist/src/frontend/notemd.css +49 -0
  35. package/dist/src/frontend/notemd.html +7 -1
  36. package/dist/src/frontend/notemd.js +64 -0
  37. package/dist/src/frontend/path.html +107 -0
  38. package/dist/src/frontend/path_app.js +2189 -150
  39. package/dist/src/frontend/path_layout.mjs +143 -0
  40. package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
  41. package/dist/src/frontend/path_modules_bridge.js +486 -0
  42. package/dist/src/frontend/path_state.mjs +118 -0
  43. package/dist/src/frontend/path_styles.css +146 -0
  44. package/dist/src/frontend/path_worker_bridge.mjs +85 -0
  45. package/dist/src/frontend/reader.js +522 -27
  46. package/dist/src/frontend/runtime_bridge.js +67 -54
  47. package/dist/src/frontend/runtime_bridge.mjs +279 -0
  48. package/dist/src/frontend/settings.js +130 -12
  49. package/dist/src/frontend/simulationWorker.js +241 -6
  50. package/dist/src/frontend/source_manager.js +190 -21
  51. package/dist/src/frontend/styles.css +2853 -72
  52. package/dist/src/frontend/workbench_state.mjs +101 -0
  53. package/dist/src/frontend/workspace_panes.js +10168 -0
  54. package/dist/src/frontend.locale.contract.test.js +62 -0
  55. package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
  56. package/dist/src/indexing/IndexLifecycle.js +195 -0
  57. package/dist/src/indexing/IndexLifecycle.test.js +49 -0
  58. package/dist/src/indexing/SegmentBuilder.js +64 -0
  59. package/dist/src/indexing/UnitBuilder.js +48 -0
  60. package/dist/src/indexing/types.js +2 -0
  61. package/dist/src/knowledge.api.contract.test.js +170 -0
  62. package/dist/src/learning/KnowledgeLearningPlatform.js +10386 -0
  63. package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +327 -0
  64. package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
  65. package/dist/src/learning/KnowledgeLearningPlatform.test.js +2971 -0
  66. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2974 -0
  67. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3928 -0
  68. package/dist/src/learning/answerReleaseReview.js +4319 -0
  69. package/dist/src/learning/answerReleaseReview.test.js +2888 -0
  70. package/dist/src/learning/api.js +2 -0
  71. package/dist/src/learning/conversationComposer.js +1480 -0
  72. package/dist/src/learning/conversationComposer.test.js +1817 -0
  73. package/dist/src/learning/domains/ConversationManager.js +53 -0
  74. package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
  75. package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
  76. package/dist/src/learning/domains/MasteryEngine.js +387 -0
  77. package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
  78. package/dist/src/learning/domains/QualityEvaluator.js +307 -0
  79. package/dist/src/learning/domains/TutorRouter.js +313 -0
  80. package/dist/src/learning/domains/index.js +33 -0
  81. package/dist/src/learning/domains/types.js +7 -0
  82. package/dist/src/learning/errors.js +29 -0
  83. package/dist/src/learning/evidenceContextAssembler.js +1176 -0
  84. package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
  85. package/dist/src/learning/graphContextAssembler.js +870 -0
  86. package/dist/src/learning/graphContextAssembler.test.js +1033 -0
  87. package/dist/src/learning/index.js +28 -0
  88. package/dist/src/learning/queryBackend.js +1898 -0
  89. package/dist/src/learning/queryBackend.test.js +955 -0
  90. package/dist/src/learning/ragContextPack.js +257 -0
  91. package/dist/src/learning/ragContextPack.test.js +160 -0
  92. package/dist/src/learning/ragPublicText.js +38 -0
  93. package/dist/src/learning/ragSufficiencyJudge.js +161 -0
  94. package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
  95. package/dist/src/learning/ragSufficiencyProviderJudge.js +227 -0
  96. package/dist/src/learning/ragSufficiencyProviderJudge.test.js +156 -0
  97. package/dist/src/learning/requestNormalization.js +198 -0
  98. package/dist/src/learning/runtimeCapability.js +4677 -0
  99. package/dist/src/learning/runtimeCapability.test.js +3635 -0
  100. package/dist/src/learning/store.js +1240 -0
  101. package/dist/src/learning/store.test.js +1126 -0
  102. package/dist/src/learning/tutorAdapter.js +2 -0
  103. package/dist/src/learning/types.js +2 -0
  104. package/dist/src/learning/vectorAccelerationAdapter.js +942 -0
  105. package/dist/src/learning/vectorAccelerationAdapter.test.js +382 -0
  106. package/dist/src/lfs.asset.policy.contract.test.js +153 -0
  107. package/dist/src/license.policy.contract.test.js +66 -0
  108. package/dist/src/memory/MemoryGovernance.js +74 -0
  109. package/dist/src/memory/MemoryGovernance.test.js +46 -0
  110. package/dist/src/memory/types.js +2 -0
  111. package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
  112. package/dist/src/middleware/auth.js +17 -0
  113. package/dist/src/middleware/body-parser.js +45 -0
  114. package/dist/src/middleware/cors.js +44 -0
  115. package/dist/src/middleware/index.js +21 -0
  116. package/dist/src/middleware/request-trace.js +96 -0
  117. package/dist/src/notemd/AppConfigToml.js +6 -4
  118. package/dist/src/notemd/MermaidProcessor.js +400 -50
  119. package/dist/src/notemd/NotemdService.js +498 -13
  120. package/dist/src/notemd/PromptManager.js +15 -0
  121. package/dist/src/notemd/cli/commands.js +357 -0
  122. package/dist/src/notemd/cli/dispatcher.js +225 -0
  123. package/dist/src/notemd/cli/index.js +169 -0
  124. package/dist/src/notemd/cli/parser.js +68 -0
  125. package/dist/src/notemd/cli/types.js +2 -0
  126. package/dist/src/notemd/constants.js +43 -0
  127. package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
  128. package/dist/src/notemd/diagram/diagramSpec.js +79 -0
  129. package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
  130. package/dist/src/notemd/diagram/intent.js +95 -0
  131. package/dist/src/notemd/diagram/planner.js +71 -0
  132. package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
  133. package/dist/src/notemd/diagram/types.js +18 -0
  134. package/dist/src/notemd/index.js +26 -0
  135. package/dist/src/notemd/operations/capabilityManifest.js +23 -0
  136. package/dist/src/notemd/operations/cliContracts.js +17 -0
  137. package/dist/src/notemd/operations/configProfileCommands.js +85 -0
  138. package/dist/src/notemd/operations/registry.contract.test.js +95 -0
  139. package/dist/src/notemd/operations/registry.js +991 -0
  140. package/dist/src/notemd/operations/types.js +2 -0
  141. package/dist/src/notemd/providerDiagnostics.js +220 -0
  142. package/dist/src/notemd/providerProfiles.js +42 -0
  143. package/dist/src/notemd/providerTemplates.js +231 -0
  144. package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
  145. package/dist/src/notemd/search/SearchManager.js +13 -0
  146. package/dist/src/notemd/search/SearchProvider.js +2 -0
  147. package/dist/src/notemd/search/TavilyProvider.js +44 -0
  148. package/dist/src/notemd.agent.manifest.test.js +85 -0
  149. package/dist/src/notemd.api.contract.test.js +14 -1
  150. package/dist/src/notemd.app_config_toml.test.js +2 -1
  151. package/dist/src/notemd.batch.workflow.test.js +117 -0
  152. package/dist/src/notemd.cli.e2e.test.js +136 -0
  153. package/dist/src/notemd.core.test.js +51 -0
  154. package/dist/src/notemd.diagram.pipeline.test.js +233 -0
  155. package/dist/src/notemd.providerTemplates.test.js +34 -0
  156. package/dist/src/notemd.server.integration.test.js +143 -35
  157. package/dist/src/notemd.workflow.pipeline.test.js +162 -0
  158. package/dist/src/pathbridge.handshake.contract.test.js +16 -2
  159. package/dist/src/pathmode.background.contract.test.js +69 -0
  160. package/dist/src/pathmode.settings.api.contract.test.js +9 -0
  161. package/dist/src/pkg.sidecar.contract.test.js +9 -3
  162. package/dist/src/platform/ExportProfile.js +58 -0
  163. package/dist/src/platform/PlatformCapabilities.js +45 -0
  164. package/dist/src/platform/PlatformCapabilities.test.js +30 -0
  165. package/dist/src/platform/RenderMaterializer.js +33 -0
  166. package/dist/src/platform/RenderMaterializer.test.js +32 -0
  167. package/dist/src/query_backend.external_http.integration.test.js +410 -0
  168. package/dist/src/reader_renderer.js +404 -3
  169. package/dist/src/reader_renderer.test.js +87 -0
  170. package/dist/src/release.godot.mirror.contract.test.js +73 -0
  171. package/dist/src/resources/ResourceRegistry.js +223 -0
  172. package/dist/src/resources/ResourceRegistry.test.js +61 -0
  173. package/dist/src/resources/types.js +2 -0
  174. package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
  175. package/dist/src/routes/data.js +267 -0
  176. package/dist/src/routes/diagnostics.js +51 -0
  177. package/dist/src/routes/index.js +23 -0
  178. package/dist/src/routes/knowledge.js +968 -0
  179. package/dist/src/routes/markdown.js +287 -0
  180. package/dist/src/routes/notemd.js +565 -0
  181. package/dist/src/routes/registry.contract.test.js +130 -0
  182. package/dist/src/routes/render.js +285 -0
  183. package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
  184. package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
  185. package/dist/src/routes/settings.js +6 -0
  186. package/dist/src/routes/staticFiles.js +94 -0
  187. package/dist/src/routes/types.js +2 -0
  188. package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
  189. package/dist/src/server.js +11090 -1549
  190. package/dist/src/server.migration.test.js +193 -21
  191. package/dist/src/server.port.fallback.contract.test.js +63 -0
  192. package/dist/src/session/SessionStateStore.js +81 -0
  193. package/dist/src/session/SessionStateStore.test.js +58 -0
  194. package/dist/src/session/types.js +2 -0
  195. package/dist/src/settings.runtime.contract.test.js +50 -0
  196. package/dist/src/shared/types.contract.test.js +107 -0
  197. package/dist/src/shared/types.js +22 -0
  198. package/dist/src/sidecar.replacement.boundary.contract.test.js +128 -0
  199. package/dist/src/sidecar.supply.readiness.contract.test.js +144 -0
  200. package/dist/src/source_manager.loadflow.test.js +46 -0
  201. package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
  202. package/dist/src/tauri.frontend.build.contract.test.js +60 -0
  203. package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
  204. package/dist/src/utils/RuntimePaths.js +4 -13
  205. package/dist/src/utils/platform.js +153 -0
  206. package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
  207. package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
  208. package/dist/src/workflows/types.js +2 -0
  209. package/dist/src/workspace/WorkspaceRegistry.js +122 -0
  210. package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
  211. package/dist/src/workspace/types.js +2 -0
  212. package/package.json +61 -10
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ /**
37
+ * Shared types contract test — validates shared type module integrity.
38
+ */
39
+ const path = __importStar(require("path"));
40
+ const fs = __importStar(require("fs"));
41
+ describe('shared types module', () => {
42
+ const sharedDir = path.resolve(__dirname);
43
+ const typesFile = path.join(sharedDir, 'types.ts');
44
+ test('shared types file exists on disk', () => {
45
+ expect(fs.existsSync(typesFile)).toBe(true);
46
+ });
47
+ test('shared types file is under 350 lines (contract boundary discipline, v2.9 expanded for CI contracts)', () => {
48
+ const source = fs.readFileSync(typesFile, 'utf8');
49
+ const lines = source.split('\n').length;
50
+ expect(lines).toBeLessThan(350);
51
+ });
52
+ test('shared types file contains canonical contract documentation', () => {
53
+ const source = fs.readFileSync(typesFile, 'utf8');
54
+ expect(source).toContain('Shared contract types');
55
+ expect(source).toContain('single source of truth');
56
+ expect(source).toContain('API contract boundary');
57
+ });
58
+ test('shared types re-exports from learning/types', () => {
59
+ const source = fs.readFileSync(typesFile, 'utf8');
60
+ expect(source).toContain("from '../learning/types'");
61
+ // Verify key contract types are re-exported
62
+ expect(source).toContain('KnowledgeAtom');
63
+ expect(source).toContain('KnowledgeQueryRequest');
64
+ expect(source).toContain('KnowledgeQueryResponse');
65
+ expect(source).toContain('AgentConversationRequest');
66
+ expect(source).toContain('AgentConversationResponse');
67
+ });
68
+ test('shared types defines RuntimeCapabilityContract', () => {
69
+ const source = fs.readFileSync(typesFile, 'utf8');
70
+ expect(source).toContain('RuntimeCapabilityContract');
71
+ expect(source).toContain('capabilityId');
72
+ expect(source).toContain('status');
73
+ });
74
+ test('shared types defines AgentWorkspaceContract', () => {
75
+ const source = fs.readFileSync(typesFile, 'utf8');
76
+ expect(source).toContain('AgentWorkspaceContract');
77
+ expect(source).toContain('conversationId');
78
+ expect(source).toContain('activePaneId');
79
+ });
80
+ test('shared types defines Notemd CLI and workflow contracts', () => {
81
+ const source = fs.readFileSync(typesFile, 'utf8');
82
+ expect(source).toContain('NotemdCliOperationContract');
83
+ expect(source).toContain('NotemdCliInvocationContract');
84
+ expect(source).toContain('NotemdWorkflowStageContract');
85
+ expect(source).toContain('NotemdWorkflowResultContract');
86
+ });
87
+ test('shared types defines Search and Diagram contracts', () => {
88
+ const source = fs.readFileSync(typesFile, 'utf8');
89
+ expect(source).toContain('SearchResultItemContract');
90
+ expect(source).toContain('SearchResultContract');
91
+ expect(source).toContain('DiagramGenerationContract');
92
+ expect(source).toContain('NotemdSettingsContract');
93
+ });
94
+ test('shared types defines CI and Infrastructure contracts (GitNexus pattern)', () => {
95
+ const source = fs.readFileSync(typesFile, 'utf8');
96
+ expect(source).toContain('CiGateStatusContract');
97
+ expect(source).toContain('CiDashboardContract');
98
+ expect(source).toContain('SnapshotStalenessContract');
99
+ });
100
+ test('SnapshotStalenessContract has staleness tracking fields', () => {
101
+ const source = fs.readFileSync(typesFile, 'utf8');
102
+ expect(source).toContain('lastSaveAt');
103
+ expect(source).toContain('staleSince');
104
+ expect(source).toContain('fileMtime');
105
+ expect(source).toContain('isStale');
106
+ });
107
+ });
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * src/shared/types.ts — Shared contract types
4
+ *
5
+ * This module defines and re-exports the canonical types shared between
6
+ * the frontend (.mjs) and backend (.ts) code. These types constitute the
7
+ * API contract boundary and should be treated as the single source of truth
8
+ * for cross-cutting type definitions.
9
+ *
10
+ * === Usage ===
11
+ * - Backend (TypeScript): import type { KnowledgeAtom, ... } from '../shared/types';
12
+ * - Frontend (JavaScript): @typedef {import('../shared/types').KnowledgeAtom} KnowledgeAtom
13
+ *
14
+ * === Design Principle ===
15
+ * Types defined here belong to the API contract, not to any single module.
16
+ * They are versioned with the project and must remain backward-compatible
17
+ * within a major version.
18
+ *
19
+ * @module shared/types
20
+ * @version 2.3.0 — added Notemd CLI, workflow, search, diagram contracts
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,128 @@
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('shows Android runtime decoupling without full build-chain decoupling yet', () => {
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 build:sidecar');
122
+ expect(pkg.scripts?.['tauri:android:build']).toContain('npm run build:sidecar');
123
+ expect(tauriAndroidConfig.bundle?.externalBin || []).toEqual([]);
124
+ expect(tauriLib).toContain('supports_sidecar: false');
125
+ expect(tauriLib).toContain('supports_build: true');
126
+ expect(tauriLib).toContain('Android startup: desktop sidecar and Godot launch are intentionally disabled.');
127
+ });
128
+ });
@@ -0,0 +1,144 @@
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('current repo pins archive digests and can disable upstream fallback for mirror-only release smoke runs', () => {
125
+ const result = utils.evaluateSidecarSupplyReadiness({
126
+ repoRoot,
127
+ platform: 'linux',
128
+ arch: 'x64',
129
+ env: {},
130
+ });
131
+ expect(result.ci.releaseWorkflowMirrorFirstDownload).toBe(true);
132
+ expect(result.ci.releaseWorkflowDirectUpstreamDownload).toBe(true);
133
+ expect(result.ci.releaseWorkflowArchiveDigestPinned).toBe(true);
134
+ expect(result.ci.releaseWorkflowMirrorOnlyModeAvailable).toBe(true);
135
+ expect(result.ci.releaseWorkflowDefaultUpstreamFallbackEnabled).toBe(true);
136
+ expect(result.legacyLfsProtectedPaths).toEqual([
137
+ 'src-tauri/bin/godot-x86_64-pc-windows-msvc.exe',
138
+ 'src-tauri/bin/server-aarch64-apple-darwin',
139
+ 'src-tauri/bin/server-x86_64-pc-windows-msvc.exe',
140
+ 'src-tauri/bin/server-x86_64-unknown-linux-gnu',
141
+ ]);
142
+ 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.');
143
+ });
144
+ });
@@ -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
  });
@@ -0,0 +1,57 @@
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('startup layout snapshot contract', () => {
39
+ const repoRoot = path.resolve(__dirname, '..');
40
+ const appPath = path.join(repoRoot, 'src', 'frontend', 'app.js');
41
+ test('rejects and purges degenerate persisted layout snapshots', () => {
42
+ const source = fs.readFileSync(appPath, 'utf8');
43
+ expect(source).toContain('async function deleteStartupLayoutSnapshotRecord(fingerprint)');
44
+ expect(source).toContain("reason: 'degenerate-layout'");
45
+ expect(source).toContain("reason: 'degenerate-layout-vs-source'");
46
+ expect(source).toContain('function isDegenerateLayoutSummary(summary)');
47
+ expect(source).toContain('function isSnapshotLayoutCollapsedVsSource(summary, sourceSummary)');
48
+ expect(source).toContain('if (validation.purge === true && record.fingerprint)');
49
+ });
50
+ test('restores startup snapshots without re-applying persisted fx/fy pinning and re-seeds collapsed layouts', () => {
51
+ const source = fs.readFileSync(appPath, 'utf8');
52
+ expect(source).toContain('n.fx = null;');
53
+ expect(source).toContain('n.fy = null;');
54
+ expect(source).toContain("restoreSourceLayoutOrJitterNodes(nodes, width, height, 'worker-init');");
55
+ expect(source).toContain('function restoreSourceLayoutOrJitterNodes(nodeList, viewportWidth, viewportHeight, reason = \'\')');
56
+ });
57
+ });
@@ -0,0 +1,60 @@
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('tauri frontend build contracts', () => {
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 wrapperScriptPath = path.join(repoRoot, 'scripts', 'run-tauri-frontend-build.js');
43
+ function readJson(filePath) {
44
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
45
+ }
46
+ test('tauri full build keeps explicit frontend full-mode through tauri beforeBuildCommand', () => {
47
+ const packageJson = readJson(packageJsonPath);
48
+ const tauriConfig = readJson(tauriConfigPath);
49
+ const scripts = packageJson.scripts || {};
50
+ expect(tauriConfig.build?.beforeBuildCommand).toBe('node scripts/run-tauri-frontend-build.js');
51
+ expect(scripts['tauri:build:full']).toContain('node scripts/run-tauri-build.js --frontend-build-mode full');
52
+ });
53
+ test('tauri frontend build wrapper defaults to runtime-first and supports explicit full mode', () => {
54
+ const wrapper = require(wrapperScriptPath);
55
+ expect(wrapper.resolveFrontendBuildCommand()).toBe('npm run build');
56
+ expect(wrapper.resolveFrontendBuildCommand({ frontendBuildMode: 'runtime-first' })).toBe('npm run build');
57
+ expect(wrapper.resolveFrontendBuildCommand({ frontendBuildMode: 'full' })).toBe('npm run build:full');
58
+ expect(() => wrapper.resolveFrontendBuildCommand({ frontendBuildMode: 'legacy-full' })).toThrow(/Unsupported tauri frontend build mode/i);
59
+ });
60
+ });
@@ -41,6 +41,7 @@ describe('tauri sidecar cleanup integration', () => {
41
41
  const cleanupScriptPath = path.join(repoRoot, 'scripts', 'cleanup-tauri-sidecars.js');
42
42
  const sidecarEnsureScriptPath = path.join(repoRoot, 'scripts', 'ensure-sidecar-ready.js');
43
43
  const tauriBuildRunnerPath = path.join(repoRoot, 'scripts', 'run-tauri-build.js');
44
+ const tauriDevRunnerPath = path.join(repoRoot, 'scripts', 'run-tauri-dev.js');
44
45
  const tauriRunnerPath = path.join(repoRoot, 'scripts', 'run-tauri-tests.js');
45
46
  test('desktop tauri scripts run stale sidecar cleanup before cargo build flow', () => {
46
47
  const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
@@ -51,6 +52,8 @@ describe('tauri sidecar cleanup integration', () => {
51
52
  expect(pkg.scripts['tauri:dev:mini']).toContain('npm run cleanup:tauri:sidecars');
52
53
  expect(pkg.scripts['tauri:dev']).toContain('npm run ensure:sidecar:dev');
53
54
  expect(pkg.scripts['tauri:dev:mini']).toContain('npm run ensure:sidecar:dev');
55
+ expect(pkg.scripts['tauri:dev']).toContain('node scripts/run-tauri-dev.js');
56
+ expect(pkg.scripts['tauri:dev:mini']).toContain('node scripts/run-tauri-dev.js');
54
57
  expect(pkg.scripts['tauri:build']).toContain('npm run cleanup:tauri:sidecars');
55
58
  expect(pkg.scripts['tauri:build:mini']).toContain('npm run cleanup:tauri:sidecars');
56
59
  expect(pkg.scripts['tauri:build']).toContain('node scripts/run-tauri-build.js');
@@ -64,6 +67,15 @@ describe('tauri sidecar cleanup integration', () => {
64
67
  expect(tauriBuildRunner).toContain('CARGO_PROFILE_RELEASE_OPT_LEVEL');
65
68
  expect(tauriBuildRunner).toContain('CARGO_PROFILE_RELEASE_CODEGEN_UNITS');
66
69
  expect(tauriBuildRunner).toContain("['tauri', 'build', '--ci'");
70
+ const tauriDevRunner = fs.readFileSync(tauriDevRunnerPath, 'utf8');
71
+ expect(tauriDevRunner).toContain('CARGO_TARGET_DIR');
72
+ expect(tauriDevRunner).toContain('target-dev-lowmem');
73
+ expect(tauriDevRunner).toContain('process.pid');
74
+ expect(tauriDevRunner).toContain('Date.now().toString(36)');
75
+ expect(tauriDevRunner).toContain('CARGO_BUILD_JOBS');
76
+ expect(tauriDevRunner).toContain('CARGO_PROFILE_DEV_DEBUG');
77
+ expect(tauriDevRunner).toContain('CARGO_INCREMENTAL');
78
+ expect(tauriDevRunner).toContain("['tauri', 'dev'");
67
79
  const sidecarEnsureScript = fs.readFileSync(sidecarEnsureScriptPath, 'utf8');
68
80
  expect(sidecarEnsureScript).toContain('Sidecar binaries are valid and up-to-date');
69
81
  expect(sidecarEnsureScript).toContain("runNodeScript('build-sidecar.js')");
@@ -71,9 +83,18 @@ describe('tauri sidecar cleanup integration', () => {
71
83
  });
72
84
  test('cleanup script targets copied tauri sidecars in debug and release outputs', () => {
73
85
  const script = fs.readFileSync(cleanupScriptPath, 'utf8');
86
+ expect(script).toContain("const defaultTargetRoots = [");
87
+ expect(script).toContain("path.join(repoRoot, 'src-tauri', 'target')");
88
+ expect(script).toContain("path.join(repoRoot, 'src-tauri', 'target-dev-lowmem')");
74
89
  expect(script).toContain("const targetModes = ['debug', 'release'];");
75
90
  expect(script).toContain("const sidecarNames = ['server', 'godot', 'markdown-worker'];");
91
+ expect(script).toContain('function resolveTargetRoots()');
92
+ expect(script).toContain('process.env.CARGO_TARGET_DIR');
76
93
  expect(script).toContain("targetRoot, mode, `${name}.exe`");
94
+ expect(script).toContain('function removeExistingArtifacts(targetPaths)');
95
+ expect(script).toContain('function runPowerShellNameFallbackCleanup(targetPath)');
96
+ expect(script).toContain('KILLED_BY_NAME|');
97
+ expect(script).toContain('[Tauri Sidecar Cleanup] REMOVED|');
77
98
  expect(script).toContain('Failed to terminate stale copied sidecars');
78
99
  });
79
100
  });