amalgm 0.1.175 → 0.1.176

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 (34) hide show
  1. package/lib/shared-realtime-tunnel.js +28 -12
  2. package/package.json +1 -1
  3. package/runtime/scripts/amalgm-mcp/index.js +1 -1
  4. package/runtime/scripts/amalgm-mcp/server/routes/state.js +5 -1
  5. package/runtime/scripts/amalgm-mcp/server/routes/workspace.js +4 -0
  6. package/runtime/scripts/amalgm-mcp/state/docs.js +13 -6
  7. package/runtime/scripts/amalgm-mcp/state/migrations.js +0 -4
  8. package/runtime/scripts/amalgm-mcp/state/mutations.js +13 -1
  9. package/runtime/scripts/amalgm-mcp/state/shared-rest.js +25 -1
  10. package/runtime/scripts/amalgm-mcp/tests/state-mutations.test.js +9 -0
  11. package/runtime/scripts/amalgm-mcp/tests/state-promotion-ownership.test.js +30 -3
  12. package/runtime/scripts/amalgm-mcp/tests/workspace-cards-store.test.js +4 -5
  13. package/runtime/scripts/amalgm-mcp/tests/workspace-checkpoint-reducer.test.js +91 -0
  14. package/runtime/scripts/amalgm-mcp/tests/workspace-checkpoint.test.js +37 -11
  15. package/runtime/scripts/amalgm-mcp/tests/workspace-object-tunnel.test.js +10 -2
  16. package/runtime/scripts/amalgm-mcp/tests/workspace-objects.test.js +14 -6
  17. package/runtime/scripts/amalgm-mcp/tests/workspace-reducer.test.js +324 -0
  18. package/runtime/scripts/amalgm-mcp/tests/workspace-store.test.js +36 -1
  19. package/runtime/scripts/amalgm-mcp/tests/workspace-wall.test.js +81 -48
  20. package/runtime/scripts/amalgm-mcp/workspace/card.js +11 -1
  21. package/runtime/scripts/amalgm-mcp/workspace/cards.js +9 -21
  22. package/runtime/scripts/amalgm-mcp/workspace/checkpoint.js +187 -122
  23. package/runtime/scripts/amalgm-mcp/workspace/git.js +71 -0
  24. package/runtime/scripts/amalgm-mcp/workspace/merge.js +119 -2
  25. package/runtime/scripts/amalgm-mcp/workspace/objects.js +49 -17
  26. package/runtime/scripts/amalgm-mcp/workspace/reducer.js +582 -0
  27. package/runtime/scripts/amalgm-mcp/workspace/rest.js +15 -1
  28. package/runtime/scripts/amalgm-mcp/workspace/store.js +8 -18
  29. package/runtime/scripts/amalgm-mcp/workspace/transition.js +67 -0
  30. package/runtime/scripts/amalgm-mcp/workspace/tree/local-state.js +3 -4
  31. package/runtime/scripts/amalgm-mcp/workspace/wall.js +331 -180
  32. package/runtime/scripts/amalgm-mcp/tests/workspace-reconcile.test.js +0 -359
  33. package/runtime/scripts/amalgm-mcp/workspace/ledger.js +0 -96
  34. package/runtime/scripts/amalgm-mcp/workspace/reconcile.js +0 -452
@@ -166,6 +166,61 @@ async function moveToCard(worktreeRoot, {
166
166
  }
167
167
  }
168
168
 
169
+ /** Keep a commit reachable under one content-derived internal ref. */
170
+ function parkCommit(worktreeRoot, oid) {
171
+ const ref = `refs/amalgm/parked/${oid}`;
172
+ return run('park-commit', worktreeRoot, [
173
+ '-C', worktreeRoot, 'update-ref', ref, oid,
174
+ ]).then(() => ref);
175
+ }
176
+
177
+ function setBranchRef(worktreeRoot, branch, oid) {
178
+ return run('set-branch-ref', worktreeRoot, [
179
+ '-C', worktreeRoot, 'update-ref', `refs/heads/${branch}`, oid,
180
+ ]);
181
+ }
182
+
183
+ function deleteBranchRef(worktreeRoot, branch) {
184
+ return run('delete-branch-ref', worktreeRoot, [
185
+ '-C', worktreeRoot, 'update-ref', '-d', `refs/heads/${branch}`,
186
+ ]);
187
+ }
188
+
189
+ /**
190
+ * Exact card movement after the caller has durably parked the old commit
191
+ * and captured the working tree. This deliberately discards the local
192
+ * checkout copy; the caller immediately pours the preserved work back as
193
+ * the checkpoint layer.
194
+ */
195
+ async function forceMoveToCard(worktreeRoot, {
196
+ expectedBranch,
197
+ expectedOid,
198
+ targetBranch,
199
+ targetOid,
200
+ }) {
201
+ const before = await currentHead(worktreeRoot);
202
+ if (before.branch !== expectedBranch || before.oid !== expectedOid) {
203
+ throw new TransitionError('force-move-to-card', worktreeRoot, 'local card changed before movement');
204
+ }
205
+ if (targetBranch) {
206
+ await run('force-move-to-card', worktreeRoot, [
207
+ '-C', worktreeRoot, 'checkout', '--force', '-B', targetBranch, targetOid,
208
+ ], { timeoutMs: 60_000 });
209
+ } else {
210
+ await run('force-move-to-card', worktreeRoot, [
211
+ '-C', worktreeRoot, 'checkout', '--force', '--detach', targetOid,
212
+ ], { timeoutMs: 60_000 });
213
+ }
214
+ const after = await currentHead(worktreeRoot);
215
+ if (after.branch !== (targetBranch || null) || after.oid !== targetOid) {
216
+ throw new TransitionError(
217
+ 'force-move-to-card',
218
+ worktreeRoot,
219
+ `expected ${targetBranch || '(detached)'}@${targetOid}, observed ${after.branch || '(detached)'}@${after.oid}`,
220
+ );
221
+ }
222
+ }
223
+
169
224
  /**
170
225
  * Apply a captured worktree patch — or reverse one — from a file on disk.
171
226
  * The patch file lives outside the repo (in the state dir), so what was
@@ -177,6 +232,13 @@ function applyPatch(worktreeRoot, patchFile, { reverse = false } = {}) {
177
232
  ], { timeoutMs: 60_000 });
178
233
  }
179
234
 
235
+ /** Set only Git's index; working files are left exactly as they are. */
236
+ function setIndexTree(worktreeRoot, treeOid) {
237
+ return run('set-index-tree', worktreeRoot, [
238
+ '-C', worktreeRoot, 'read-tree', treeOid,
239
+ ]);
240
+ }
241
+
180
242
  /**
181
243
  * Land a merged write set in a working tree — the coexistence engine's
182
244
  * only mutation path. Each entry is { path, content, mode } (content a
@@ -224,8 +286,13 @@ module.exports = {
224
286
  applyMergedFiles,
225
287
  applyPatch,
226
288
  createBundle,
289
+ deleteBranchRef,
227
290
  fastForwardTo,
228
291
  fetchBranch,
292
+ forceMoveToCard,
229
293
  importBundle,
230
294
  moveToCard,
295
+ parkCommit,
296
+ setBranchRef,
297
+ setIndexTree,
231
298
  };
@@ -32,12 +32,11 @@ function rowToNode(row) {
32
32
 
33
33
  function workspaceRow(identifier, database = openLocalDb()) {
34
34
  return database.prepare(`
35
- SELECT workspaces.*
35
+ SELECT *
36
36
  FROM workspaces
37
- LEFT JOIN workspace_id_aliases ON workspace_id_aliases.workspace_id = workspaces.id
38
- WHERE workspaces.id = ? OR workspaces.path = ? OR workspace_id_aliases.alias_id = ?
37
+ WHERE id = ? OR path = ?
39
38
  LIMIT 1
40
- `).get(identifier, identifier, identifier) || null;
39
+ `).get(identifier, identifier) || null;
41
40
  }
42
41
 
43
42
  function relativePathForNode(nodes, nodeId, memo = new Map()) {