amalgm 0.1.212 → 0.1.214
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.
- package/package.json +1 -1
- package/runtime/scripts/amalgm-mcp/tests/workspace-checkpoint.test.js +29 -0
- package/runtime/scripts/amalgm-mcp/tests/workspace-reducer.test.js +15 -0
- package/runtime/scripts/amalgm-mcp/tests/workspace-wall.test.js +9 -0
- package/runtime/scripts/amalgm-mcp/workspace/checkpoint.js +10 -1
- package/runtime/scripts/amalgm-mcp/workspace/reducer.js +0 -1
- package/runtime/scripts/amalgm-mcp/workspace/wall.js +5 -15
package/package.json
CHANGED
|
@@ -33,6 +33,7 @@ const {
|
|
|
33
33
|
checkpointValueReady,
|
|
34
34
|
readCheckpointValue,
|
|
35
35
|
revisionOf,
|
|
36
|
+
sameTransition,
|
|
36
37
|
} = require('../workspace/checkpoint');
|
|
37
38
|
|
|
38
39
|
test.after(() => {
|
|
@@ -241,3 +242,31 @@ test('a clean losing commit travels as parked metadata on a no-op checkpoint', (
|
|
|
241
242
|
assert.deepEqual(checkpoint.to, sharedValue);
|
|
242
243
|
assert.deepEqual(checkpoint.parked, parked);
|
|
243
244
|
});
|
|
245
|
+
|
|
246
|
+
test('a server rail number does not turn the same parked checkpoint into new work', () => {
|
|
247
|
+
const value = { revision: null, indexDiff: '', worktreeDiff: '' };
|
|
248
|
+
const checkpoint = {
|
|
249
|
+
branch: 'main',
|
|
250
|
+
baseOid: 'a'.repeat(40),
|
|
251
|
+
from: value,
|
|
252
|
+
to: value,
|
|
253
|
+
parked: [{
|
|
254
|
+
oid: 'b'.repeat(40),
|
|
255
|
+
ref: `refs/amalgm/parked/${'b'.repeat(40)}`,
|
|
256
|
+
objects: { kind: 'bundle', checksum: 'c'.repeat(64) },
|
|
257
|
+
version: 12,
|
|
258
|
+
}],
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
assert.equal(sameTransition(checkpoint, {
|
|
262
|
+
...checkpoint,
|
|
263
|
+
parked: checkpoint.parked.map((entry) => ({ ...entry, version: 37 })),
|
|
264
|
+
}), true);
|
|
265
|
+
assert.equal(sameTransition(checkpoint, {
|
|
266
|
+
...checkpoint,
|
|
267
|
+
parked: checkpoint.parked.map((entry) => ({
|
|
268
|
+
...entry,
|
|
269
|
+
objects: { ...entry.objects, checksum: 'd'.repeat(64) },
|
|
270
|
+
})),
|
|
271
|
+
}), false);
|
|
272
|
+
});
|
|
@@ -507,6 +507,21 @@ test('a losing commit is parked, the winning card lands exactly, and losing work
|
|
|
507
507
|
assert.equal(fs.readFileSync(path.join(repo, 'local-dirty.txt'), 'utf8'), 'also uncommitted\n');
|
|
508
508
|
assert.equal((await git(repo, 'status', '--porcelain')).trim().length > 0, true);
|
|
509
509
|
assert.deepEqual(readRepoState('root:test').parked.map((entry) => entry.oid), [losingOid]);
|
|
510
|
+
|
|
511
|
+
await git(repo, 'add', '.');
|
|
512
|
+
await git(repo, 'commit', '-m', 'fold parked work');
|
|
513
|
+
const foldedOid = (await git(repo, 'rev-parse', 'HEAD')).trim();
|
|
514
|
+
const foldedCard = card(repo, foldedOid, 3);
|
|
515
|
+
const folded = await materializeRepo(foldedCard, {
|
|
516
|
+
repoKey: 'root:test',
|
|
517
|
+
card: foldedCard,
|
|
518
|
+
transitions: [],
|
|
519
|
+
parked: [],
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
assert.equal(folded.state, 'in-sync');
|
|
523
|
+
assert.deepEqual(readRepoState('root:test').parked, []);
|
|
524
|
+
assert.equal((await git(repo, 'rev-parse', `refs/amalgm/parked/${losingOid}`)).trim(), losingOid);
|
|
510
525
|
});
|
|
511
526
|
|
|
512
527
|
test('rail-parked peer commits become one staged checkpoint on every machine', async () => {
|
|
@@ -120,6 +120,15 @@ test('only a value different from both the materialized baseline and the rail is
|
|
|
120
120
|
branches: [{ name: 'main', oid: oidC }],
|
|
121
121
|
};
|
|
122
122
|
assert.equal(hasLocalContribution(local, remoteAdvance, baseline), false);
|
|
123
|
+
assert.equal(hasLocalContribution(local, remoteAdvance, baseline, {
|
|
124
|
+
checkpoint: 'repo-checkpoint@7',
|
|
125
|
+
machine: 'machine-a',
|
|
126
|
+
branch: 'main',
|
|
127
|
+
baseOid: oidA,
|
|
128
|
+
from: { revision: null, indexDiff: '', worktreeDiff: '' },
|
|
129
|
+
to: { revision: 'old-work', indexDiff: '', worktreeDiff: 'patch' },
|
|
130
|
+
parked: [],
|
|
131
|
+
}), false);
|
|
123
132
|
assert.equal(hasLocalContribution(
|
|
124
133
|
{
|
|
125
134
|
head: { branch: 'main', oid: oidB, detached: false },
|
|
@@ -96,13 +96,21 @@ function valueIdentity(value) {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
function parkedIdentity(parked) {
|
|
100
|
+
return JSON.stringify((parked || []).map((entry) => {
|
|
101
|
+
const stable = { ...entry };
|
|
102
|
+
delete stable.version;
|
|
103
|
+
return stable;
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
|
|
99
107
|
function sameTransition(left, right) {
|
|
100
108
|
return left
|
|
101
109
|
&& left.baseOid === right.baseOid
|
|
102
110
|
&& left.branch === right.branch
|
|
103
111
|
&& valueIdentity(left.from) === valueIdentity(right.from)
|
|
104
112
|
&& valueIdentity(left.to) === valueIdentity(right.to)
|
|
105
|
-
&&
|
|
113
|
+
&& parkedIdentity(left.parked) === parkedIdentity(right.parked);
|
|
106
114
|
}
|
|
107
115
|
|
|
108
116
|
function checkpointValue(machine, repoKey, baseOid, indexDiff, worktreeDiff) {
|
|
@@ -397,6 +405,7 @@ module.exports = {
|
|
|
397
405
|
readCheckpointValue,
|
|
398
406
|
repoKeyOfCard,
|
|
399
407
|
revisionOf,
|
|
408
|
+
sameTransition,
|
|
400
409
|
startCheckpointService,
|
|
401
410
|
stopCheckpointService,
|
|
402
411
|
};
|
|
@@ -513,7 +513,6 @@ async function materializeRepo(localCardInput, plan) {
|
|
|
513
513
|
: refreshed;
|
|
514
514
|
const previous = readRepoState(plan.repoKey);
|
|
515
515
|
const parked = uniqueParked([
|
|
516
|
-
...(previous?.parked || []),
|
|
517
516
|
...(plan.parked || []),
|
|
518
517
|
...(cardResult.parked || []),
|
|
519
518
|
]);
|
|
@@ -17,7 +17,7 @@ const { AMALGM_DIR } = require('../config');
|
|
|
17
17
|
const { subscribeStateEvents } = require('../state/events');
|
|
18
18
|
const { machineId, userId } = require('./identity');
|
|
19
19
|
const { listRepoCards } = require('./cards');
|
|
20
|
-
const { readCheckpoint, repoKeyOfCard } = require('./checkpoint');
|
|
20
|
+
const { readCheckpoint, repoKeyOfCard, sameTransition } = require('./checkpoint');
|
|
21
21
|
|
|
22
22
|
const WALL_CONTRACT = 'code-project@3';
|
|
23
23
|
const PROJECT_DIR = path.join(AMALGM_DIR, 'state', 'code-projects');
|
|
@@ -209,17 +209,6 @@ function samePosition(left, right) {
|
|
|
209
209
|
&& Boolean(left?.head?.detached) === Boolean(right?.head?.detached);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
function checkpointIdentity(checkpoint) {
|
|
213
|
-
if (!checkpoint) return null;
|
|
214
|
-
return JSON.stringify({
|
|
215
|
-
baseOid: checkpoint.baseOid,
|
|
216
|
-
branch: checkpoint.branch,
|
|
217
|
-
from: checkpoint.from,
|
|
218
|
-
to: checkpoint.to,
|
|
219
|
-
parked: checkpoint.parked || [],
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
212
|
function oidMap(refs) {
|
|
224
213
|
return new Map((refs || []).map((ref) => [ref.name, ref.oid ?? null]));
|
|
225
214
|
}
|
|
@@ -271,14 +260,15 @@ function hasLocalContribution(card, plan, baseline, checkpoint = null, previousC
|
|
|
271
260
|
}
|
|
272
261
|
|
|
273
262
|
if (
|
|
274
|
-
|
|
263
|
+
onRail
|
|
264
|
+
&& checkpoint
|
|
275
265
|
&& checkpoint.baseOid === card.head?.oid
|
|
276
266
|
&& checkpoint.branch === card.head?.branch
|
|
277
267
|
) {
|
|
278
268
|
const latest = [...(plan.transitions || [])]
|
|
279
269
|
.reverse()
|
|
280
270
|
.find((entry) => entry.machine === checkpoint.machine);
|
|
281
|
-
if (
|
|
271
|
+
if (!sameTransition(latest, checkpoint)) return true;
|
|
282
272
|
}
|
|
283
273
|
return false;
|
|
284
274
|
}
|
|
@@ -444,7 +434,7 @@ function stampCards(cards, previousCards, sharedPlan, baseline, mutationId, proj
|
|
|
444
434
|
: [];
|
|
445
435
|
const last = history.at(-1);
|
|
446
436
|
const checkpoints = currentCheckpoint
|
|
447
|
-
? (
|
|
437
|
+
? (sameTransition(last, currentCheckpoint)
|
|
448
438
|
? history
|
|
449
439
|
: [...history, { ...currentCheckpoint, mutationId }])
|
|
450
440
|
: history;
|