noteconnection 1.8.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 (195) hide show
  1. package/README.md +257 -1803
  2. package/dist/src/agent_workspace.contract.parity.test.js +105 -421
  3. package/dist/src/agent_workspace.frontend.test.js +410 -11
  4. package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
  5. package/dist/src/appimage.patchelf.test.js +113 -0
  6. package/dist/src/appimage.portability.test.js +156 -0
  7. package/dist/src/backend/FileLoader.js +18 -4
  8. package/dist/src/backend/FileLoader.test.js +125 -0
  9. package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
  10. package/dist/src/backend/GraphBuilder.js +66 -18
  11. package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
  12. package/dist/src/backend/GraphMetrics.js +0 -3
  13. package/dist/src/backend/ResourceIdentity.js +155 -0
  14. package/dist/src/backend/ResourceIdentity.test.js +113 -0
  15. package/dist/src/backend/algorithms/CycleDetection.js +0 -1
  16. package/dist/src/backend/algorithms/HybridEngine.js +0 -3
  17. package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
  18. package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
  19. package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
  20. package/dist/src/backend/build_dag.js +0 -1
  21. package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
  22. package/dist/src/capacitor.runtime.contract.test.js +11 -2
  23. package/dist/src/core/Graph.js +138 -42
  24. package/dist/src/core/Graph.test.js +74 -0
  25. package/dist/src/core/NoteConnection.js +2 -2
  26. package/dist/src/core/PathBridge.js +265 -2
  27. package/dist/src/core/ResourceReference.js +17 -0
  28. package/dist/src/desktop.godot.pack.test.js +142 -0
  29. package/dist/src/desktop.runtime.graph.test.js +66 -0
  30. package/dist/src/export/WorkspaceExportBundle.js +44 -0
  31. package/dist/src/export/WorkspaceExportBundle.test.js +61 -0
  32. package/dist/src/foundation.release.evidence.contract.test.js +127 -9
  33. package/dist/src/foundation.sqlite.runtime.contract.test.js +6 -0
  34. package/dist/src/frontend/README.md +257 -1803
  35. package/dist/src/frontend/agent_workspace.js +665 -7
  36. package/dist/src/frontend/index.html +31 -2
  37. package/dist/src/frontend/knowledge_projection_contract.js +230 -0
  38. package/dist/src/frontend/knowledge_projection_store.js +214 -0
  39. package/dist/src/frontend/libs/path_core.js +158 -42
  40. package/dist/src/frontend/locales/en.json +32 -0
  41. package/dist/src/frontend/locales/zh.json +32 -0
  42. package/dist/src/frontend/mobile_budget_runtime.js +33 -0
  43. package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
  44. package/dist/src/frontend/mobile_identity_contract.js +221 -0
  45. package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
  46. package/dist/src/frontend/path.html +6 -2
  47. package/dist/src/frontend/simulationWorker.js +1 -1
  48. package/dist/src/frontend/source_manager.js +110 -4
  49. package/dist/src/frontend/storage_provider.js +661 -71
  50. package/dist/src/frontend/styles.css +107 -13
  51. package/dist/src/frontend/workspace_panes.js +111 -7
  52. package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
  53. package/dist/src/graph.answer.operator.contract.test.js +72 -0
  54. package/dist/src/index.js +6 -2
  55. package/dist/src/index.knowledge-root.test.js +118 -0
  56. package/dist/src/indexing/IndexLifecycle.js +22 -0
  57. package/dist/src/indexing/IndexLifecycle.test.js +24 -0
  58. package/dist/src/knowledge.api.contract.test.js +4 -2
  59. package/dist/src/knowledge_projection.contract.test.js +134 -0
  60. package/dist/src/knowledge_projection_store.test.js +200 -0
  61. package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
  62. package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
  63. package/dist/src/learning/KnowledgeLearningPlatform.js +4687 -3892
  64. package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +418 -0
  65. package/dist/src/learning/KnowledgeLearningPlatform.test.js +243 -6
  66. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +25 -1
  67. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +13 -5
  68. package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
  69. package/dist/src/learning/PublicAnswerContract.test.js +85 -0
  70. package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
  71. package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
  72. package/dist/src/learning/agentConversationExecution.js +211 -0
  73. package/dist/src/learning/agentConversationExecution.test.js +209 -0
  74. package/dist/src/learning/agentConversationSerialization.js +266 -0
  75. package/dist/src/learning/agentConversationSerialization.test.js +165 -0
  76. package/dist/src/learning/agentResponseBudget.js +179 -0
  77. package/dist/src/learning/agentResponseBudget.test.js +97 -0
  78. package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
  79. package/dist/src/learning/answerReleaseReview.js +1191 -250
  80. package/dist/src/learning/answerReleaseReview.test.js +1293 -7
  81. package/dist/src/learning/answerTaskPlan.js +473 -0
  82. package/dist/src/learning/conversationComposer.js +627 -386
  83. package/dist/src/learning/conversationComposer.test.js +1403 -0
  84. package/dist/src/learning/evidenceContextAssembler.js +312 -120
  85. package/dist/src/learning/graphAnswerCoverage.js +37 -0
  86. package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
  87. package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
  88. package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
  89. package/dist/src/learning/graphAnswerFacts.js +94 -0
  90. package/dist/src/learning/graphAnswerFacts.test.js +39 -0
  91. package/dist/src/learning/graphAnswerPlan.js +908 -0
  92. package/dist/src/learning/graphAnswerPlan.test.js +907 -0
  93. package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
  94. package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
  95. package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
  96. package/dist/src/learning/graphClaimMatcher.js +104 -0
  97. package/dist/src/learning/graphConditionedContext.js +109 -0
  98. package/dist/src/learning/graphConditionedContext.test.js +99 -0
  99. package/dist/src/learning/graphContextAssembler.js +3 -13
  100. package/dist/src/learning/graphContextAssembler.test.js +2 -2
  101. package/dist/src/learning/graphExpansionPolicy.js +22 -0
  102. package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
  103. package/dist/src/learning/identityMetadata.test.js +26 -0
  104. package/dist/src/learning/index.js +1 -0
  105. package/dist/src/learning/mobileAnswerProjection.js +104 -0
  106. package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
  107. package/dist/src/learning/queryBackend.js +34 -10
  108. package/dist/src/learning/queryBackend.test.js +21 -0
  109. package/dist/src/learning/ragContextPack.js +115 -16
  110. package/dist/src/learning/ragContextPack.test.js +151 -0
  111. package/dist/src/learning/ragEvidenceQuality.js +96 -0
  112. package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
  113. package/dist/src/learning/ragPublicText.js +67 -4
  114. package/dist/src/learning/ragPublicText.test.js +57 -0
  115. package/dist/src/learning/ragSufficiencyJudge.js +11 -1
  116. package/dist/src/learning/ragSufficiencyProviderJudge.js +16 -26
  117. package/dist/src/learning/ragSufficiencyProviderJudge.test.js +51 -0
  118. package/dist/src/learning/requestNormalization.js +106 -0
  119. package/dist/src/learning/requestNormalization.test.js +101 -0
  120. package/dist/src/learning/store.js +116 -12
  121. package/dist/src/learning/store.test.js +299 -0
  122. package/dist/src/learning/vectorAccelerationAdapter.js +22 -6
  123. package/dist/src/learning/vectorAccelerationAdapter.test.js +30 -0
  124. package/dist/src/learning/workspaceHydration.js +168 -0
  125. package/dist/src/learning/workspaceHydration.test.js +30 -0
  126. package/dist/src/license.policy.contract.test.js +9 -4
  127. package/dist/src/markdown/MarkdownGateway.js +4 -0
  128. package/dist/src/markdown/MarkdownGateway.test.js +59 -0
  129. package/dist/src/middleware/SseResponseWriter.js +122 -0
  130. package/dist/src/middleware/SseResponseWriter.test.js +54 -0
  131. package/dist/src/middleware/auth.js +28 -7
  132. package/dist/src/middleware/auth.test.js +33 -0
  133. package/dist/src/middleware/index.js +2 -1
  134. package/dist/src/mobile.android.evidence.contract.test.js +146 -0
  135. package/dist/src/mobile.android.signing.contract.test.js +66 -0
  136. package/dist/src/mobile.artifact.contract.test.js +144 -0
  137. package/dist/src/mobile.budget.contract.test.js +90 -0
  138. package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
  139. package/dist/src/mobile.graph.parity.contract.test.js +207 -0
  140. package/dist/src/mobile.identity.contract.test.js +66 -0
  141. package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
  142. package/dist/src/mobile.identity.corpus.test.js +40 -0
  143. package/dist/src/mobile.native.recovery.contract.test.js +64 -0
  144. package/dist/src/mobile.pipeline.test.js +11 -1
  145. package/dist/src/mobile.profile.contract.test.js +225 -0
  146. package/dist/src/mobile.semantic.parity.test.js +92 -0
  147. package/dist/src/mobile_exact_analyzer.test.js +113 -0
  148. package/dist/src/notemd/ContentGenerator.js +4 -9
  149. package/dist/src/notemd/FileProcessor.js +4 -9
  150. package/dist/src/notemd/NotemdService.js +12 -17
  151. package/dist/src/notemd/Translator.js +4 -9
  152. package/dist/src/notemd/progressReporter.js +9 -0
  153. package/dist/src/notemd.server.integration.test.js +119 -4
  154. package/dist/src/notemd.workflow.pipeline.test.js +1 -1
  155. package/dist/src/pathbridge.handshake.contract.test.js +29 -0
  156. package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
  157. package/dist/src/pathcore.bundle.contract.test.js +8 -0
  158. package/dist/src/platform/ExportProfile.js +28 -0
  159. package/dist/src/platform/MobileBudget.js +11 -0
  160. package/dist/src/platform/PlatformCapabilities.js +14 -0
  161. package/dist/src/platform/PlatformCapabilities.test.js +6 -0
  162. package/dist/src/query_backend.external_http.integration.test.js +2 -2
  163. package/dist/src/release.godot.mirror.contract.test.js +28 -4
  164. package/dist/src/resources/ResourceRegistry.js +40 -0
  165. package/dist/src/resources/ResourceRegistry.test.js +36 -0
  166. package/dist/src/routes/index.js +0 -4
  167. package/dist/src/routes/knowledge.js +46 -33
  168. package/dist/src/routes/knowledgePayload.js +185 -0
  169. package/dist/src/routes/knowledgePayload.test.js +53 -0
  170. package/dist/src/routes/markdown.js +8 -0
  171. package/dist/src/routes/notemd.js +990 -234
  172. package/dist/src/routes/registry.contract.test.js +5 -2
  173. package/dist/src/routes/registry.shadow.contract.test.js +22 -0
  174. package/dist/src/routes/render.js +14 -51
  175. package/dist/src/runtime.capabilities.test.js +18 -2
  176. package/dist/src/server.js +566 -1090
  177. package/dist/src/server.migration.test.js +417 -15
  178. package/dist/src/sidecar.build.lock.contract.test.js +201 -0
  179. package/dist/src/sidecar.freshness.contract.test.js +184 -0
  180. package/dist/src/sidecar.replacement.boundary.contract.test.js +6 -3
  181. package/dist/src/sidecar.supply.readiness.contract.test.js +11 -0
  182. package/dist/src/simulation.worker.offline.test.js +104 -0
  183. package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
  184. package/dist/src/storage.provider.contract.test.js +152 -1
  185. package/dist/src/tauri.frontend.build.contract.test.js +8 -0
  186. package/dist/src/tauri.window.evidence.execution.test.js +68 -0
  187. package/dist/src/utils/RuntimePaths.js +6 -0
  188. package/dist/src/utils/RuntimePaths.test.js +27 -0
  189. package/dist/src/windows.installer.build.test.js +109 -0
  190. package/dist/src/windows.installer.payload.test.js +76 -0
  191. package/dist/src/windows.installer.runtime.test.js +69 -0
  192. package/dist/src/workspace/WorkspaceRegistry.js +13 -0
  193. package/package.json +32 -10
  194. package/dist/src/routes/data.js +0 -267
  195. package/dist/src/routes/diagnostics.js +0 -51
@@ -0,0 +1,201 @@
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
+ const child_process_1 = require("child_process");
40
+ function runChild(script, args = []) {
41
+ return new Promise((resolve, reject) => {
42
+ const child = (0, child_process_1.spawn)(process.execPath, ['-e', script, ...args], {
43
+ cwd: path.resolve(__dirname, '..'),
44
+ stdio: ['ignore', 'pipe', 'pipe'],
45
+ windowsHide: true,
46
+ });
47
+ let output = '';
48
+ child.stdout.on('data', (chunk) => { output += String(chunk); });
49
+ child.stderr.on('data', (chunk) => { output += String(chunk); });
50
+ child.once('error', reject);
51
+ child.once('close', (code) => resolve({ code, output }));
52
+ });
53
+ }
54
+ function waitForOutput(childScript, args = []) {
55
+ return new Promise((resolve, reject) => {
56
+ const child = (0, child_process_1.spawn)(process.execPath, ['-e', childScript, ...args], {
57
+ cwd: path.resolve(__dirname, '..'),
58
+ stdio: ['ignore', 'pipe', 'pipe'],
59
+ windowsHide: true,
60
+ });
61
+ let output = '';
62
+ let timer;
63
+ const onData = (chunk) => {
64
+ output += String(chunk);
65
+ if (output.includes('acquired')) {
66
+ clearTimeout(timer);
67
+ child.stdout.off('data', onData);
68
+ resolve({ child, output });
69
+ }
70
+ };
71
+ child.stdout.on('data', onData);
72
+ child.stderr.on('data', onData);
73
+ timer = setTimeout(() => {
74
+ child.kill();
75
+ reject(new Error(`Timed out waiting for child lock acquisition. Output: ${output}`));
76
+ }, 2500);
77
+ child.once('close', (code) => {
78
+ if (!output.includes('acquired')) {
79
+ clearTimeout(timer);
80
+ reject(new Error(`Lock holder exited before acquisition (code=${String(code)}). Output: ${output}`));
81
+ }
82
+ });
83
+ child.once('error', reject);
84
+ });
85
+ }
86
+ function waitForChildClose(child) {
87
+ if (child.exitCode !== null) {
88
+ return Promise.resolve();
89
+ }
90
+ return new Promise((resolve) => child.once('close', () => resolve()));
91
+ }
92
+ describe('sidecar build lock', () => {
93
+ test('rejects an empty lock path at the boundary', () => {
94
+ expect(() => {
95
+ const { acquireSidecarBuildLock } = require('../scripts/sidecar-build-lock.js');
96
+ acquireSidecarBuildLock('');
97
+ }).toThrow('A concrete sidecar build lock path is required.');
98
+ });
99
+ test('serializes independent ensure processes and releases the lock', async () => {
100
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-sidecar-lock-'));
101
+ const lockPath = path.join(tempRoot, 'sidecar-build.lock');
102
+ const holderScript = `
103
+ const { acquireSidecarBuildLock } = require('./scripts/sidecar-build-lock.js');
104
+ const lock = acquireSidecarBuildLock(process.argv[1], { timeoutMs: 3000, staleMs: 30000, pollMs: 25 });
105
+ console.log('acquired');
106
+ setTimeout(() => { lock.release(); process.exit(0); }, 800);
107
+ `;
108
+ const waiterScript = `
109
+ const { acquireSidecarBuildLock } = require('./scripts/sidecar-build-lock.js');
110
+ const startedAt = Date.now();
111
+ const lock = acquireSidecarBuildLock(process.argv[1], { timeoutMs: 3000, staleMs: 30000, pollMs: 25 });
112
+ console.log(JSON.stringify({ acquired: true, waitedMs: Date.now() - startedAt }));
113
+ lock.release();
114
+ `;
115
+ try {
116
+ const holder = await waitForOutput(holderScript, [lockPath]);
117
+ const waiter = await runChild(waiterScript, [lockPath]);
118
+ expect(waiter.code).toBe(0);
119
+ expect(waiter.output).toContain('acquired');
120
+ const parsed = JSON.parse(waiter.output.match(/\{[^\n]+\}/)?.[0] || '{}');
121
+ expect(Number(parsed.waitedMs || 0)).toBeGreaterThanOrEqual(250);
122
+ await waitForChildClose(holder.child);
123
+ expect(fs.existsSync(lockPath)).toBe(false);
124
+ }
125
+ finally {
126
+ fs.rmSync(tempRoot, { recursive: true, force: true });
127
+ }
128
+ });
129
+ test('reclaims an old lock whose owner process is no longer alive', async () => {
130
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-sidecar-lock-stale-'));
131
+ const lockPath = path.join(tempRoot, 'sidecar-build.lock');
132
+ try {
133
+ fs.writeFileSync(lockPath, JSON.stringify({
134
+ pid: 2147483647,
135
+ hostname: 'stale-test',
136
+ startedAt: '2020-01-01T00:00:00.000Z',
137
+ token: 'stale-token',
138
+ }), 'utf8');
139
+ const result = await runChild(`
140
+ const { acquireSidecarBuildLock } = require('./scripts/sidecar-build-lock.js');
141
+ const lock = acquireSidecarBuildLock(process.argv[1], { timeoutMs: 500, staleMs: 1, pollMs: 10 });
142
+ console.log('acquired');
143
+ lock.release();
144
+ `, [lockPath]);
145
+ expect(result.code).toBe(0);
146
+ expect(result.output).toContain('acquired');
147
+ expect(fs.existsSync(lockPath)).toBe(false);
148
+ }
149
+ finally {
150
+ fs.rmSync(tempRoot, { recursive: true, force: true });
151
+ }
152
+ });
153
+ test('reclaims an old lock owned by a different host without trusting a reused pid', async () => {
154
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-sidecar-lock-host-'));
155
+ const lockPath = path.join(tempRoot, 'sidecar-build.lock');
156
+ try {
157
+ fs.writeFileSync(lockPath, JSON.stringify({
158
+ pid: process.pid,
159
+ hostname: 'different-host',
160
+ startedAt: '2020-01-01T00:00:00.000Z',
161
+ token: 'foreign-token',
162
+ }), 'utf8');
163
+ const result = await runChild(`
164
+ const { acquireSidecarBuildLock } = require('./scripts/sidecar-build-lock.js');
165
+ const lock = acquireSidecarBuildLock(process.argv[1], { timeoutMs: 500, staleMs: 1, pollMs: 10 });
166
+ console.log('acquired');
167
+ lock.release();
168
+ `, [lockPath]);
169
+ expect(result.code).toBe(0);
170
+ expect(result.output).toContain('acquired');
171
+ expect(fs.existsSync(lockPath)).toBe(false);
172
+ }
173
+ finally {
174
+ fs.rmSync(tempRoot, { recursive: true, force: true });
175
+ }
176
+ });
177
+ test('fails closed when a live owner holds the lock past the wait budget', async () => {
178
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'noteconnection-sidecar-lock-timeout-'));
179
+ const lockPath = path.join(tempRoot, 'sidecar-build.lock');
180
+ const holderScript = `
181
+ const { acquireSidecarBuildLock } = require('./scripts/sidecar-build-lock.js');
182
+ const lock = acquireSidecarBuildLock(process.argv[1], { timeoutMs: 3000, staleMs: 30000, pollMs: 25 });
183
+ console.log('acquired');
184
+ setTimeout(() => { lock.release(); process.exit(0); }, 700);
185
+ `;
186
+ try {
187
+ const holder = await waitForOutput(holderScript, [lockPath]);
188
+ const result = await runChild(`
189
+ const { acquireSidecarBuildLock } = require('./scripts/sidecar-build-lock.js');
190
+ acquireSidecarBuildLock(process.argv[1], { timeoutMs: 100, staleMs: 30000, pollMs: 25 });
191
+ `, [lockPath]);
192
+ expect(result.code).not.toBe(0);
193
+ expect(result.output).toContain('Timed out waiting for sidecar build lock');
194
+ holder.child.kill();
195
+ await waitForChildClose(holder.child);
196
+ }
197
+ finally {
198
+ fs.rmSync(tempRoot, { recursive: true, force: true });
199
+ }
200
+ });
201
+ });
@@ -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
+ }
@@ -114,13 +114,16 @@ describe('sidecar replacement boundary contract', () => {
114
114
  expect(pathApp).toContain("window.NoteConnectionRuntime.getBridgeWsUrl('frontend')");
115
115
  expect(pathApp).toContain("this._sendBridgeMessage('identify', this._getBridgeIdentifyPayload('frontend'))");
116
116
  });
117
- test('shows Android runtime decoupling without full build-chain decoupling yet', () => {
117
+ test('keeps the default Android build sidecar-free and makes Godot opt-in', () => {
118
118
  const pkg = readJson(packageJsonPath);
119
119
  const tauriAndroidConfig = readJson(tauriAndroidConfigPath);
120
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');
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');
123
125
  expect(tauriAndroidConfig.bundle?.externalBin || []).toEqual([]);
126
+ expect(tauriAndroidConfig.build?.frontendDist).toBe('../dist/mobile-slim/frontend');
124
127
  expect(tauriLib).toContain('supports_sidecar: false');
125
128
  expect(tauriLib).toContain('supports_build: true');
126
129
  expect(tauriLib).toContain('Android startup: desktop sidecar and Godot launch are intentionally disabled.');
@@ -121,6 +121,17 @@ describe('sidecar supply readiness contract', () => {
121
121
  expect(result.artifacts.godot.networkRequiredForBootstrap).toBe(true);
122
122
  expect(result.artifacts.godot.sourceKindsAvailable).toContain('download');
123
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
+ });
124
135
  test('current repo pins archive digests and can disable upstream fallback for mirror-only release smoke runs', () => {
125
136
  const result = utils.evaluateSidecarSupplyReadiness({
126
137
  repoRoot,
@@ -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
+ });
@@ -41,6 +41,9 @@ describe('storage provider capacitor content mapping contract', () => {
41
41
  test('maps desktop-style Knowledge_Base paths for capacitor content reads', () => {
42
42
  const source = fs.readFileSync(storageProviderPath, 'utf8');
43
43
  expect(source).toContain('function extractRelativePathFromKbMarker(rawFilePath)');
44
+ expect(source).toContain('function extractRelativePathFromWorkspaceUri(rawFilePath)');
45
+ expect(source).toContain("const prefix = 'note://workspace/v1/'");
46
+ expect(source).toContain('const relativeFromWorkspaceUri = extractRelativePathFromWorkspaceUri(raw);');
44
47
  expect(source).toContain('function resolveCapacitorContentCandidatePath(rawFilePath)');
45
48
  expect(source).toContain("if (/^[A-Za-z]:\\//.test(normalized) || normalized.startsWith('/')) {");
46
49
  expect(source).toContain('Cannot map absolute desktop path on Capacitor without Knowledge_Base marker.');
@@ -49,6 +52,6 @@ describe('storage provider capacitor content mapping contract', () => {
49
52
  const source = fs.readFileSync(storageProviderPath, 'utf8');
50
53
  expect(source).toContain('if (isCapacitorNativeRuntime()) {');
51
54
  expect(source).toContain('const capacitorPath = resolveCapacitorContentCandidatePath(filePath);');
52
- expect(source).toContain('return await capacitorReadText(capacitorPath);');
55
+ expect(source).toContain('return await capacitorReadText(capacitorPath, {');
53
56
  });
54
57
  });