amalgm 0.1.245 → 0.1.246

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 (157) hide show
  1. package/README.md +12 -0
  2. package/lib/cli.js +146 -8
  3. package/lib/layout.js +89 -4
  4. package/lib/shared-realtime-tunnel.js +384 -43
  5. package/lib/supervisor.js +0 -3
  6. package/package.json +2 -2
  7. package/runtime/scripts/amalgm-mcp/adapters/contract.js +197 -0
  8. package/runtime/scripts/amalgm-mcp/adapters/filesystem.js +135 -0
  9. package/runtime/scripts/amalgm-mcp/adapters/git.js +84 -0
  10. package/runtime/scripts/amalgm-mcp/adapters/index.js +43 -0
  11. package/runtime/scripts/amalgm-mcp/adapters/reference.js +31 -0
  12. package/runtime/scripts/amalgm-mcp/adapters/truth.js +19 -0
  13. package/runtime/scripts/amalgm-mcp/browser/cookie-jar.js +20 -68
  14. package/runtime/scripts/amalgm-mcp/index.js +4 -0
  15. package/runtime/scripts/amalgm-mcp/lib/layout.js +89 -4
  16. package/runtime/scripts/amalgm-mcp/observer/README.md +259 -0
  17. package/runtime/scripts/amalgm-mcp/observer/apply.js +150 -0
  18. package/runtime/scripts/amalgm-mcp/observer/continuity.js +111 -0
  19. package/runtime/scripts/amalgm-mcp/observer/edges.js +111 -0
  20. package/runtime/scripts/amalgm-mcp/observer/index.js +1146 -0
  21. package/runtime/scripts/amalgm-mcp/observer/scan.js +387 -0
  22. package/runtime/scripts/amalgm-mcp/observer/store.js +262 -0
  23. package/runtime/scripts/amalgm-mcp/observer/verify.js +200 -0
  24. package/runtime/scripts/amalgm-mcp/observer/watch.js +62 -0
  25. package/runtime/scripts/amalgm-mcp/project-context/store.js +19 -87
  26. package/runtime/scripts/amalgm-mcp/registration/classify.js +33 -0
  27. package/runtime/scripts/amalgm-mcp/registration/entity-cloud.js +456 -0
  28. package/runtime/scripts/amalgm-mcp/registration/entity-content.js +345 -0
  29. package/runtime/scripts/amalgm-mcp/registration/index.js +752 -0
  30. package/runtime/scripts/amalgm-mcp/registration/refusal.js +42 -0
  31. package/runtime/scripts/amalgm-mcp/registration/repo-followers.js +127 -0
  32. package/runtime/scripts/amalgm-mcp/registration/repo-states.js +109 -0
  33. package/runtime/scripts/amalgm-mcp/registration/service.js +310 -0
  34. package/runtime/scripts/amalgm-mcp/registration/tree.js +178 -0
  35. package/runtime/scripts/amalgm-mcp/registry/evidence.js +826 -0
  36. package/runtime/scripts/amalgm-mcp/registry/index.js +666 -0
  37. package/runtime/scripts/amalgm-mcp/registry/store.js +290 -0
  38. package/runtime/scripts/amalgm-mcp/repocard/README.md +103 -0
  39. package/runtime/scripts/amalgm-mcp/repocard/apply.js +111 -0
  40. package/runtime/scripts/amalgm-mcp/repocard/capture-worker.js +94 -0
  41. package/runtime/scripts/amalgm-mcp/repocard/capture.js +149 -0
  42. package/runtime/scripts/amalgm-mcp/repocard/follow.js +310 -0
  43. package/runtime/scripts/amalgm-mcp/repocard/git.js +48 -0
  44. package/runtime/scripts/amalgm-mcp/repocard/index.js +48 -0
  45. package/runtime/scripts/amalgm-mcp/server/local-service-router.js +2 -0
  46. package/runtime/scripts/amalgm-mcp/server/routes/entities.js +287 -0
  47. package/runtime/scripts/amalgm-mcp/server/routes/state.js +0 -13
  48. package/runtime/scripts/amalgm-mcp/state/attachments.js +11 -45
  49. package/runtime/scripts/amalgm-mcp/state/db.js +46 -215
  50. package/runtime/scripts/amalgm-mcp/state/docs.js +301 -1101
  51. package/runtime/scripts/amalgm-mcp/state/mutation-contracts.js +0 -99
  52. package/runtime/scripts/amalgm-mcp/state/mutations.js +130 -507
  53. package/runtime/scripts/amalgm-mcp/state/promotions.js +1 -21
  54. package/runtime/scripts/amalgm-mcp/state/replicas.js +13 -134
  55. package/runtime/scripts/amalgm-mcp/state/shared-rest.js +3 -46
  56. package/runtime/scripts/amalgm-mcp/tests/adapters.test.js +379 -0
  57. package/runtime/scripts/amalgm-mcp/tests/browser-cookie-cloud.test.js +0 -193
  58. package/runtime/scripts/amalgm-mcp/tests/doorbell.matrix.life.test.js +449 -0
  59. package/runtime/scripts/amalgm-mcp/tests/doorbell.matrix.rig.js +107 -0
  60. package/runtime/scripts/amalgm-mcp/tests/doorbell.matrix.watch.test.js +213 -0
  61. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/adapter.js +72 -0
  62. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/assert.js +497 -0
  63. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/bind.js +91 -0
  64. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/graph.js +1031 -0
  65. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/ledger.js +234 -0
  66. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/referee.js +118 -0
  67. package/runtime/scripts/amalgm-mcp/tests/entity.oracle.test.js +1365 -0
  68. package/runtime/scripts/amalgm-mcp/tests/entity.registry.test.js +967 -0
  69. package/runtime/scripts/amalgm-mcp/tests/entity.rig.js +239 -0
  70. package/runtime/scripts/amalgm-mcp/tests/entity.storm.test.js +486 -0
  71. package/runtime/scripts/amalgm-mcp/tests/fake-watch.js +35 -0
  72. package/runtime/scripts/amalgm-mcp/tests/observer.links.test.js +289 -0
  73. package/runtime/scripts/amalgm-mcp/tests/observer.rig.js +103 -0
  74. package/runtime/scripts/amalgm-mcp/tests/observer.roots.test.js +505 -0
  75. package/runtime/scripts/amalgm-mcp/tests/observer.storm.test.js +389 -0
  76. package/runtime/scripts/amalgm-mcp/tests/observer.territory.test.js +845 -0
  77. package/runtime/scripts/amalgm-mcp/tests/observer.test.js +657 -0
  78. package/runtime/scripts/amalgm-mcp/tests/project-context.test.js +17 -32
  79. package/runtime/scripts/amalgm-mcp/tests/registration.service.test.js +256 -0
  80. package/runtime/scripts/amalgm-mcp/tests/registration.test.js +931 -0
  81. package/runtime/scripts/amalgm-mcp/tests/repocard.storm.test.js +284 -0
  82. package/runtime/scripts/amalgm-mcp/tests/repocard.test.js +371 -0
  83. package/runtime/scripts/amalgm-mcp/tests/repofollow.storm.test.js +435 -0
  84. package/runtime/scripts/amalgm-mcp/tests/repofollow.test.js +675 -0
  85. package/runtime/scripts/amalgm-mcp/tests/shared-tunnel-rehydration.test.js +0 -84
  86. package/runtime/scripts/amalgm-mcp/tests/state-docs.test.js +13 -376
  87. package/runtime/scripts/amalgm-mcp/tests/state-mutations.test.js +0 -309
  88. package/runtime/scripts/amalgm-mcp/tests/state-shared-replica.test.js +30 -758
  89. package/runtime/scripts/amalgm-mcp/tests/workspace-cards-store.test.js +3 -72
  90. package/runtime/scripts/amalgm-mcp/tests/workspace-cards.test.js +1 -89
  91. package/runtime/scripts/amalgm-mcp/tests/workspace-checkpoint-reducer.test.js +24 -55
  92. package/runtime/scripts/amalgm-mcp/tests/workspace-checkpoint.test.js +141 -424
  93. package/runtime/scripts/amalgm-mcp/tests/workspace-object-tunnel.test.js +3 -171
  94. package/runtime/scripts/amalgm-mcp/tests/workspace-objects.test.js +7 -220
  95. package/runtime/scripts/amalgm-mcp/tests/workspace-publication-invariants.test.js +236 -179
  96. package/runtime/scripts/amalgm-mcp/tests/workspace-reducer.test.js +326 -2228
  97. package/runtime/scripts/amalgm-mcp/tests/workspace-tree-cloud.test.js +3 -5319
  98. package/runtime/scripts/amalgm-mcp/tests/workspace-tree-core.test.js +1 -191
  99. package/runtime/scripts/amalgm-mcp/tests/workspace-tree-store.test.js +17 -3140
  100. package/runtime/scripts/amalgm-mcp/tests/workspace-wall.test.js +740 -137
  101. package/runtime/scripts/amalgm-mcp/workspace/access-store.js +1 -5
  102. package/runtime/scripts/amalgm-mcp/workspace/card.js +11 -35
  103. package/runtime/scripts/amalgm-mcp/workspace/cards.js +14 -39
  104. package/runtime/scripts/amalgm-mcp/workspace/checkpoint.js +147 -587
  105. package/runtime/scripts/amalgm-mcp/workspace/git.js +34 -406
  106. package/runtime/scripts/amalgm-mcp/workspace/merge.js +181 -102
  107. package/runtime/scripts/amalgm-mcp/workspace/objects.js +56 -221
  108. package/runtime/scripts/amalgm-mcp/workspace/reducer.js +538 -1964
  109. package/runtime/scripts/amalgm-mcp/workspace/rest.js +28 -49
  110. package/runtime/scripts/amalgm-mcp/workspace/store.js +4 -77
  111. package/runtime/scripts/amalgm-mcp/workspace/transition.js +192 -1734
  112. package/runtime/scripts/amalgm-mcp/workspace/tree/inclusion.js +1 -7
  113. package/runtime/scripts/amalgm-mcp/workspace/tree/local-state.js +61 -73
  114. package/runtime/scripts/amalgm-mcp/workspace/tree/reducer.js +6 -51
  115. package/runtime/scripts/amalgm-mcp/workspace/tree/snapshot.js +8 -79
  116. package/runtime/scripts/amalgm-mcp/workspace/tree-cloud.js +146 -3461
  117. package/runtime/scripts/amalgm-mcp/workspace/tree-store.js +71 -899
  118. package/runtime/scripts/amalgm-mcp/workspace/wall.js +538 -370
  119. package/runtime/scripts/local-gateway.js +1 -0
  120. package/runtime/scripts/amalgm-mcp/state/doc-disk.js +0 -550
  121. package/runtime/scripts/amalgm-mcp/tests/code-project-stream.test.js +0 -399
  122. package/runtime/scripts/amalgm-mcp/tests/fixtures/code-project-stream-v2.json +0 -1
  123. package/runtime/scripts/amalgm-mcp/tests/workspace-durable.test.js +0 -24
  124. package/runtime/scripts/amalgm-mcp/tests/workspace-local-intent.test.js +0 -1999
  125. package/runtime/scripts/amalgm-mcp/tests/workspace-native-file-transaction.test.js +0 -364
  126. package/runtime/scripts/amalgm-mcp/tests/workspace-provenance.test.js +0 -185
  127. package/runtime/scripts/amalgm-mcp/tests/workspace-reducer-liveness.test.js +0 -26
  128. package/runtime/scripts/amalgm-mcp/tests/workspace-sync-stats.test.js +0 -119
  129. package/runtime/scripts/amalgm-mcp/tests/workspace-transition.test.js +0 -1446
  130. package/runtime/scripts/amalgm-mcp/workspace/content.js +0 -32
  131. package/runtime/scripts/amalgm-mcp/workspace/durable.js +0 -45
  132. package/runtime/scripts/amalgm-mcp/workspace/intent.js +0 -535
  133. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/BUILD.md +0 -31
  134. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/bin/darwin-arm64/amalgm-file-transaction +0 -0
  135. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/bin/linux-x64/amalgm-file-transaction +0 -0
  136. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/build.mjs +0 -72
  137. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/client.js +0 -165
  138. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/go.mod +0 -5
  139. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/go.sum +0 -2
  140. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/main.go +0 -2201
  141. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/manifest.json +0 -19
  142. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/move_darwin.go +0 -18
  143. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/move_linux.go +0 -18
  144. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/process_darwin.go +0 -33
  145. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/process_linux.go +0 -47
  146. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/verify.mjs +0 -43
  147. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/writers_darwin.go +0 -114
  148. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/writers_linux.go +0 -84
  149. package/runtime/scripts/amalgm-mcp/workspace/project-stream.js +0 -771
  150. package/runtime/scripts/amalgm-mcp/workspace/provenance.js +0 -240
  151. package/runtime/scripts/amalgm-mcp/workspace/sync-stats.js +0 -240
  152. package/runtime/scripts/amalgm-mcp/workspace/tree/floor.js +0 -100
  153. package/runtime/scripts/amalgm-mcp/workspace/tree/observation-holds.js +0 -127
  154. package/runtime/scripts/amalgm-mcp/workspace/tree/path-state.js +0 -12
  155. package/runtime/scripts/amalgm-mcp/workspace/tree/root-binding.js +0 -125
  156. package/runtime/scripts/amalgm-mcp/workspace/tree/symlinks.js +0 -76
  157. package/runtime/scripts/amalgm-mcp/workspace/tree-materialization.js +0 -3766
@@ -6,7 +6,6 @@ const assert = require('node:assert/strict');
6
6
  const { can, resolveEffectiveRole } = require('../workspace/tree/access');
7
7
  const { isUuidV7, uuidV7, uuidV7Timestamp } = require('../workspace/tree/identity');
8
8
  const { applyTreeOperation } = require('../workspace/tree/reducer');
9
- const { normalizeTreeSnapshot } = require('../workspace/tree/snapshot');
10
9
 
11
10
  test('UUIDv7 identity is standard, timestamped, and independent of path', () => {
12
11
  const now = 1_782_000_123_456;
@@ -71,82 +70,6 @@ test('tree operations preserve identity across rename and reject cycles', () =>
71
70
  }), /destination folder does not exist|inside itself/);
72
71
  });
73
72
 
74
- test('symlink legality is a portable invariant of the complete live tree', () => {
75
- const workspaceId = uuidV7();
76
- const folderId = uuidV7();
77
- const nestedId = uuidV7();
78
- const linkId = uuidV7();
79
- const root = {
80
- id: workspaceId,
81
- workspaceId,
82
- parentId: null,
83
- kind: 'folder',
84
- name: 'Workspace',
85
- };
86
- let nodes = new Map([[workspaceId, root]]);
87
- nodes = applyTreeOperation(nodes, {
88
- kind: 'tree.create',
89
- workspaceId,
90
- nodeId: folderId,
91
- parentId: workspaceId,
92
- nodeKind: 'folder',
93
- name: 'folder',
94
- });
95
- nodes = applyTreeOperation(nodes, {
96
- kind: 'tree.create',
97
- workspaceId,
98
- nodeId: nestedId,
99
- parentId: folderId,
100
- nodeKind: 'folder',
101
- name: 'nested',
102
- });
103
- nodes = applyTreeOperation(nodes, {
104
- kind: 'tree.create',
105
- workspaceId,
106
- nodeId: linkId,
107
- parentId: nestedId,
108
- nodeKind: 'symlink',
109
- name: 'entry',
110
- symlinkTarget: '../../folder/file.txt',
111
- });
112
-
113
- assert.throws(() => applyTreeOperation(nodes, {
114
- kind: 'tree.move',
115
- workspaceId,
116
- nodeId: nestedId,
117
- parentId: workspaceId,
118
- }), /escapes its workspace/);
119
- for (const [index, target] of [
120
- '../../../outside',
121
- '/tmp/outside',
122
- '\\\\server\\share',
123
- 'C:\\outside',
124
- 'C:outside',
125
- ].entries()) {
126
- assert.throws(() => applyTreeOperation(nodes, {
127
- kind: 'tree.create',
128
- workspaceId,
129
- nodeId: uuidV7(Date.now() + index),
130
- parentId: workspaceId,
131
- nodeKind: 'symlink',
132
- name: `unsafe-${index}`,
133
- symlinkTarget: target,
134
- }), /relative|escapes its workspace/);
135
- }
136
-
137
- const snapshot = {
138
- schemaVersion: 1,
139
- workspaceId,
140
- version: 0,
141
- nodes: Array.from(nodes.values()).map((node) => ({ ...node })),
142
- };
143
- snapshot.nodes.find((node) => node.id === linkId).symlinkTarget = '../../../outside';
144
- assert.throws(
145
- () => normalizeTreeSnapshot(snapshot),
146
- /escapes its workspace/,
147
- );
148
- });
149
-
150
73
  test('trash cascades preserve independently trashed children', () => {
151
74
  const workspaceId = uuidV7();
152
75
  const folderId = uuidV7();
@@ -176,11 +99,9 @@ test('trash cascades preserve independently trashed children', () => {
176
99
  kind: 'tree.trash', workspaceId, nodeId: fileId, trashedAt: '2026-07-21T00:01:00.000Z',
177
100
  });
178
101
  nodes = applyTreeOperation(nodes, {
179
- kind: 'tree.trash', workspaceId, nodeId: folderId, trashedAt: '2026-07-21T00:01:00.000Z',
102
+ kind: 'tree.trash', workspaceId, nodeId: folderId, trashedAt: '2026-07-21T00:02:00.000Z',
180
103
  });
181
104
  assert.equal(nodes.get(fileId).trashedAt, '2026-07-21T00:01:00.000Z');
182
- assert.equal(nodes.get(fileId).trashComponentId, fileId);
183
- assert.equal(nodes.get(folderId).trashComponentId, folderId);
184
105
 
185
106
  nodes = applyTreeOperation(nodes, {
186
107
  kind: 'tree.restore', workspaceId, nodeId: folderId,
@@ -190,115 +111,4 @@ test('trash cascades preserve independently trashed children', () => {
190
111
  assert.throws(() => applyTreeOperation(nodes, {
191
112
  kind: 'tree.restore', workspaceId, nodeId: folderId,
192
113
  }), /must be trashed/);
193
-
194
- nodes = applyTreeOperation(nodes, {
195
- kind: 'tree.purge', workspaceId, nodeId: fileId,
196
- });
197
- assert.ok(nodes.get(fileId).purgedAt);
198
- assert.equal(nodes.get(fileId).trashComponentId, null);
199
- });
200
-
201
- test('snapshots require active trash provenance and retire it on purge', () => {
202
- const workspaceId = uuidV7();
203
- const fileId = uuidV7();
204
- const base = {
205
- schemaVersion: 1,
206
- workspaceId,
207
- version: 1,
208
- nodes: [
209
- {
210
- id: workspaceId,
211
- workspaceId,
212
- parentId: null,
213
- kind: 'folder',
214
- name: 'Workspace',
215
- },
216
- {
217
- id: fileId,
218
- workspaceId,
219
- parentId: workspaceId,
220
- kind: 'file',
221
- name: 'note.txt',
222
- trashedAt: '2026-07-21T00:01:00.000Z',
223
- },
224
- ],
225
- };
226
- assert.throws(
227
- () => normalizeTreeSnapshot(base),
228
- /requires explicit trash provenance/,
229
- );
230
- const cyclic = structuredClone(base);
231
- cyclic.nodes[1].trashedAt = null;
232
- cyclic.nodes[1].parentId = fileId;
233
- assert.throws(() => normalizeTreeSnapshot(cyclic), /contains a cycle/);
234
-
235
- const siblingId = uuidV7();
236
- const nonAncestor = structuredClone(base);
237
- nonAncestor.nodes.push({
238
- id: siblingId,
239
- workspaceId,
240
- parentId: workspaceId,
241
- kind: 'folder',
242
- name: 'other-trash',
243
- trashedAt: '2026-07-21T00:01:00.000Z',
244
- trashComponentId: siblingId,
245
- });
246
- nonAncestor.nodes[1].trashComponentId = siblingId;
247
- assert.throws(() => normalizeTreeSnapshot(nonAncestor), /is not an ancestor/);
248
-
249
- const purged = structuredClone(base);
250
- purged.nodes[1].purgedAt = '2026-07-21T00:02:00.000Z';
251
- const normalized = normalizeTreeSnapshot(purged);
252
- assert.equal(normalized.nodes.get(fileId).trashComponentId, null);
253
- });
254
-
255
- test('snapshot ancestry validation stays bounded on a deep tree', { timeout: 10_000 }, () => {
256
- const workspaceId = uuidV7();
257
- const componentId = uuidV7();
258
- const changedAt = '2026-07-21T00:01:00.000Z';
259
- const nodes = [{
260
- id: workspaceId,
261
- workspaceId,
262
- parentId: null,
263
- kind: 'folder',
264
- name: 'Workspace',
265
- }, {
266
- id: componentId,
267
- workspaceId,
268
- parentId: workspaceId,
269
- kind: 'folder',
270
- name: 'trash-root',
271
- }];
272
- let parentId = componentId;
273
- for (let index = 0; index < 20_000; index += 1) {
274
- const id = uuidV7();
275
- nodes.push({
276
- id,
277
- workspaceId,
278
- parentId,
279
- kind: 'folder',
280
- name: `level-${index}`,
281
- });
282
- parentId = id;
283
- }
284
- const live = normalizeTreeSnapshot({
285
- schemaVersion: 1,
286
- workspaceId,
287
- version: 1,
288
- nodes,
289
- });
290
- const trashed = applyTreeOperation(live.nodes, {
291
- kind: 'tree.trash',
292
- workspaceId,
293
- nodeId: componentId,
294
- trashedAt: changedAt,
295
- });
296
- const normalized = normalizeTreeSnapshot({
297
- schemaVersion: 1,
298
- workspaceId,
299
- version: 2,
300
- nodes: Array.from(trashed.values()),
301
- });
302
- assert.equal(normalized.nodes.size, nodes.length);
303
- assert.equal(normalized.nodes.get(parentId).trashComponentId, componentId);
304
114
  });