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
@@ -0,0 +1,178 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Structural registration for `amalgm register`.
5
+ *
6
+ * Purpose: give every enrolled thing a durable UUID before realtime work
7
+ * begins. This is deliberately a filesystem-shape walk: names, nesting,
8
+ * directories, links, ordinary files, and repository boundaries. It never
9
+ * reads a file's bytes or a link's target. A repository boundary adds one
10
+ * required semantic fact: its initial Card + Checkpoint baseline. Detect
11
+ * owns all later changing facts after Watch has started.
12
+ *
13
+ * Axioms:
14
+ * 1. Registration records the complete enrolled shape, never content.
15
+ * 2. One registration walk commits the tree and its root witness together.
16
+ * 3. A repository is a boundary for realtime semantics, never a hole in
17
+ * the entity tree: `.git` is excluded, its allowed worktree children
18
+ * are registered beneath the repo.git entity.
19
+ * 4. Every repo.git record is born with a persisted Card + Checkpoint;
20
+ * Watch resumes from that baseline rather than inventing one later.
21
+ *
22
+ * The existing public alphabet still distinguishes file.text/file.binary,
23
+ * although they have identical behavior today. A structural walk therefore
24
+ * uses file.text as the content-free ordinary-file placeholder. The first
25
+ * Detect pass immediately attests the actual bytes and corrects that
26
+ * representation through the normal one-observation transition.
27
+ */
28
+
29
+ const fs = require('fs');
30
+ const path = require('path');
31
+
32
+ function rootType(rootPath, kind) {
33
+ if (kind === 'repo') return 'repo.git';
34
+ if (kind !== 'file') return 'workspace';
35
+ return fs.lstatSync(rootPath).isSymbolicLink() ? 'link' : 'file.text';
36
+ }
37
+
38
+ function isRepository(dirPath) {
39
+ try {
40
+ fs.lstatSync(path.join(dirPath, '.git'));
41
+ return true;
42
+ } catch (error) {
43
+ // A failed look cannot prove a repo boundary. Register the readable
44
+ // shape below it; observer territory detection retries the boundary
45
+ // look and performs the UUID-preserving folder → repo.git transition
46
+ // once Git becomes knowable.
47
+ if (error.code === 'ENOENT' || error.code === 'ENOTDIR'
48
+ || error.code === 'EACCES' || error.code === 'EPERM') return false;
49
+ throw error;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Create the root record, its witness, and every entity below ordinary
55
+ * directory ground. The caller supplies a root that is already known to the
56
+ * observer but is not yet watched or scanned.
57
+ */
58
+ function registerTree({ root, registry, memory, shouldEnroll, captureRepo, repoStates, identityAt = null }) {
59
+ if (!root || !registry || !memory || typeof shouldEnroll !== 'function'
60
+ || typeof captureRepo !== 'function' || !repoStates) {
61
+ throw new Error('registerTree requires { root, registry, memory, shouldEnroll, captureRepo, repoStates }');
62
+ }
63
+
64
+ if (identityAt !== null && typeof identityAt !== 'function') {
65
+ throw new Error('registerTree identityAt must be a function when supplied');
66
+ }
67
+
68
+ function seeded(relativePath, { type, parentUUID, name, root: isRoot }) {
69
+ const identity = identityAt?.(relativePath) || null;
70
+ if (!identity) return { type, uuid: undefined };
71
+ if (identity.name !== name || identity.parentUUID !== parentUUID || identity.status !== 'active') {
72
+ throw new Error(`cloud identity at ${relativePath || '.'} does not match the local declared tree`);
73
+ }
74
+ // The structural walk intentionally does not read file bytes. A seeded
75
+ // file may therefore retain either physical file subtype until Detect
76
+ // observes its local bytes; directories and links must already agree.
77
+ const compatibleFile = type === 'file.text'
78
+ && (identity.type === 'file.text' || identity.type === 'file.binary');
79
+ if (identity.type !== type && !compatibleFile) {
80
+ throw new Error(`cloud identity at ${relativePath || '.'} is ${identity.type}, local declared tree is ${type}`);
81
+ }
82
+ if (isRoot && !['workspace', 'repo.git', 'file.text', 'file.binary', 'link'].includes(identity.type)) {
83
+ throw new Error(`cloud identity at ${relativePath || '.'} is not a valid tree root`);
84
+ }
85
+ return { type: identity.type, uuid: identity.uuid };
86
+ }
87
+
88
+ return registry.transaction(() => {
89
+ const initialState = root.kind === 'repo' ? captureInitialRepo(root.path, captureRepo) : null;
90
+ const rootIdentity = seeded('', {
91
+ type: rootType(root.path, root.kind), parentUUID: null, name: path.basename(root.path), root: true,
92
+ });
93
+ const record = registry.enrollRoot({
94
+ type: rootIdentity.type,
95
+ name: path.basename(root.path),
96
+ payloadVersion: initialState?.stateId ?? null,
97
+ uuid: rootIdentity.uuid,
98
+ });
99
+ memory.bind(root.rootId, root.rootId, record.uuid);
100
+ if (initialState) repoStates.put(record.uuid, initialState);
101
+
102
+ if (root.kind === 'files' || root.kind === 'repo') {
103
+ registerDirectory(root.path, record.uuid, {
104
+ registry, shouldEnroll, captureRepo, repoStates, identityAt, seeded, relativePath: '',
105
+ });
106
+ }
107
+ return record;
108
+ });
109
+ }
110
+
111
+ function captureInitialRepo(repoPath, captureRepo) {
112
+ const state = captureRepo(repoPath);
113
+ if (state?.busy) {
114
+ throw new Error(`cannot register ${repoPath}: Git is unsettled (${state.busy})`);
115
+ }
116
+ if (!state?.stateId || !state.cardId || !state.checkpointId) {
117
+ throw new Error(`cannot register ${repoPath}: Git did not produce a Card + Checkpoint state`);
118
+ }
119
+ return state;
120
+ }
121
+
122
+ function registerDirectory(dirPath, parentUUID, {
123
+ registry, shouldEnroll, captureRepo, repoStates, identityAt, seeded, relativePath,
124
+ }) {
125
+ let entries;
126
+ try {
127
+ entries = fs.readdirSync(dirPath, { withFileTypes: true })
128
+ .sort((a, b) => a.name.localeCompare(b.name));
129
+ } catch (error) {
130
+ // Structural registration names every readable child. An unreadable
131
+ // directory is not proof that it is empty; leave its already-created
132
+ // folder record childless and let Detect retry when ground settles.
133
+ if (error.code === 'EACCES' || error.code === 'EPERM') return;
134
+ throw error;
135
+ }
136
+
137
+ for (const entry of entries) {
138
+ const entryPath = path.join(dirPath, entry.name);
139
+ const entryRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
140
+ if (!shouldEnroll(entryPath)) continue;
141
+ const stat = fs.lstatSync(entryPath);
142
+
143
+ if (stat.isSymbolicLink()) {
144
+ const identity = seeded(entryRelativePath, {
145
+ type: 'link', parentUUID, name: entry.name, root: false,
146
+ });
147
+ registry.create({ type: identity.type, parentUUID, name: entry.name, uuid: identity.uuid });
148
+ continue;
149
+ }
150
+ if (stat.isDirectory()) {
151
+ const type = isRepository(entryPath) ? 'repo.git' : 'folder';
152
+ const state = type === 'repo.git' ? captureInitialRepo(entryPath, captureRepo) : null;
153
+ const identity = seeded(entryRelativePath, {
154
+ type, parentUUID, name: entry.name, root: false,
155
+ });
156
+ const record = registry.create({
157
+ type: identity.type,
158
+ parentUUID,
159
+ name: entry.name,
160
+ payloadVersion: state?.stateId ?? null,
161
+ uuid: identity.uuid,
162
+ });
163
+ if (state) repoStates.put(record.uuid, state);
164
+ registerDirectory(entryPath, record.uuid, {
165
+ registry, shouldEnroll, captureRepo, repoStates, identityAt, seeded, relativePath: entryRelativePath,
166
+ });
167
+ continue;
168
+ }
169
+ if (stat.isFile()) {
170
+ const identity = seeded(entryRelativePath, {
171
+ type: 'file.text', parentUUID, name: entry.name, root: false,
172
+ });
173
+ registry.create({ type: identity.type, parentUUID, name: entry.name, uuid: identity.uuid });
174
+ }
175
+ }
176
+ }
177
+
178
+ module.exports = { registerTree };