amalgm 0.1.179 → 0.1.180
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 +20 -1
- package/runtime/scripts/amalgm-mcp/tests/workspace-reducer.test.js +25 -1
- package/runtime/scripts/amalgm-mcp/workspace/checkpoint.js +28 -14
- package/runtime/scripts/amalgm-mcp/workspace/reducer.js +2 -0
package/package.json
CHANGED
|
@@ -26,7 +26,12 @@ const { closeLocalDb } = require('../state/db');
|
|
|
26
26
|
const { captureCheckpoint, captureWorktreeDiff } = require('../workspace/git');
|
|
27
27
|
const merge = require('../workspace/merge');
|
|
28
28
|
const { applyPatch } = require('../workspace/transition');
|
|
29
|
-
const {
|
|
29
|
+
const {
|
|
30
|
+
checkpointFile,
|
|
31
|
+
checkpointValueReady,
|
|
32
|
+
readCheckpointValue,
|
|
33
|
+
revisionOf,
|
|
34
|
+
} = require('../workspace/checkpoint');
|
|
30
35
|
|
|
31
36
|
test.after(() => {
|
|
32
37
|
closeLocalDb();
|
|
@@ -161,3 +166,17 @@ test('checkpoint captures are local cache; their operations travel on the one wa
|
|
|
161
166
|
assert.notEqual(first, checkpointFile('m1', 'https://github.com/a/c'));
|
|
162
167
|
assert.match(first, /repo-checkpoints-v5/);
|
|
163
168
|
});
|
|
169
|
+
|
|
170
|
+
test('an uploading checkpoint payload is not published as a transition', () => {
|
|
171
|
+
const pending = {
|
|
172
|
+
revision: 'a'.repeat(64),
|
|
173
|
+
payload: {
|
|
174
|
+
kind: 'pending',
|
|
175
|
+
contract: 'opaque-chunks@1',
|
|
176
|
+
checksum: 'b'.repeat(64),
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
assert.equal(checkpointValueReady(pending), false);
|
|
180
|
+
assert.equal(readCheckpointValue('c'.repeat(40), pending).state, 'payload-pending');
|
|
181
|
+
assert.equal(checkpointValueReady({ revision: null, indexDiff: '', worktreeDiff: '' }), true);
|
|
182
|
+
});
|
|
@@ -22,7 +22,13 @@ fs.writeFileSync(
|
|
|
22
22
|
|
|
23
23
|
const { closeLocalDb } = require('../state/db');
|
|
24
24
|
const { revisionOf } = require('../workspace/checkpoint');
|
|
25
|
-
const {
|
|
25
|
+
const {
|
|
26
|
+
hydrateRepo,
|
|
27
|
+
materializeRepo,
|
|
28
|
+
readRepoState,
|
|
29
|
+
reduceCheckpoint,
|
|
30
|
+
reduceWall,
|
|
31
|
+
} = require('../workspace/reducer');
|
|
26
32
|
|
|
27
33
|
test.after(() => {
|
|
28
34
|
closeLocalDb();
|
|
@@ -123,6 +129,24 @@ test('a stale lower rail card cannot roll back a newer branch and commit', () =>
|
|
|
123
129
|
assert.equal(plan.card.positionVersion, 12);
|
|
124
130
|
});
|
|
125
131
|
|
|
132
|
+
test('an old pending payload does not block the later complete checkpoint transition', async () => {
|
|
133
|
+
const { repo, oid } = await makeRepo('pending-payload');
|
|
134
|
+
const diff = await patchFor(repo, { 'a.txt': 'a1\n' });
|
|
135
|
+
const pending = transition('machine-a', 2, oid, '', '');
|
|
136
|
+
pending.from = {
|
|
137
|
+
revision: 'a'.repeat(64),
|
|
138
|
+
payload: { kind: 'pending', contract: 'opaque-chunks@1', checksum: 'b'.repeat(64) },
|
|
139
|
+
};
|
|
140
|
+
pending.to = pending.from;
|
|
141
|
+
const complete = transition('machine-a', 3, oid, '', diff);
|
|
142
|
+
const reduced = await reduceCheckpoint(
|
|
143
|
+
{ path: repo },
|
|
144
|
+
{ card: card(repo, oid, 1), transitions: [pending, complete] },
|
|
145
|
+
);
|
|
146
|
+
assert.equal(reduced.state, 'ready');
|
|
147
|
+
assert.match(reduced.indexDiff, /a1/);
|
|
148
|
+
});
|
|
149
|
+
|
|
126
150
|
test('an empty project folder hydrates from the winning card bundle without cloning', async () => {
|
|
127
151
|
const sourceRepo = await makeRepo('hydrate-source');
|
|
128
152
|
const source = sourceRepo.repo;
|
|
@@ -119,10 +119,17 @@ function checkpointValue(machine, repoKey, baseOid, indexDiff, worktreeDiff) {
|
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
function checkpointValueReady(value) {
|
|
123
|
+
return !value?.payload || value.payload.kind === 'chunks';
|
|
124
|
+
}
|
|
125
|
+
|
|
122
126
|
function readCheckpointValue(baseOid, value) {
|
|
123
127
|
let indexDiff = typeof value?.indexDiff === 'string' ? value.indexDiff : '';
|
|
124
128
|
let worktreeDiff = typeof value?.worktreeDiff === 'string' ? value.worktreeDiff : '';
|
|
125
129
|
if (value?.payload) {
|
|
130
|
+
if (value.payload.kind === 'pending') {
|
|
131
|
+
return { state: 'payload-pending', indexDiff: null, worktreeDiff: null };
|
|
132
|
+
}
|
|
126
133
|
const payload = require('./objects').readPayload(value.payload);
|
|
127
134
|
if (payload.state !== 'ready') {
|
|
128
135
|
return { state: payload.state, indexDiff: null, worktreeDiff: null };
|
|
@@ -203,26 +210,32 @@ async function publishPass(replicaId = null) {
|
|
|
203
210
|
continue;
|
|
204
211
|
}
|
|
205
212
|
|
|
213
|
+
const from = checkpointValue(
|
|
214
|
+
machine,
|
|
215
|
+
repoKey,
|
|
216
|
+
card.head.oid,
|
|
217
|
+
reduced.indexDiff,
|
|
218
|
+
reduced.worktreeDiff,
|
|
219
|
+
);
|
|
220
|
+
const to = checkpointValue(
|
|
221
|
+
machine,
|
|
222
|
+
repoKey,
|
|
223
|
+
card.head.oid,
|
|
224
|
+
captured.indexDiff,
|
|
225
|
+
captured.worktreeDiff,
|
|
226
|
+
);
|
|
227
|
+
if (!checkpointValueReady(from) || !checkpointValueReady(to)) {
|
|
228
|
+
run.waiting += 1;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
206
231
|
const envelope = {
|
|
207
232
|
checkpoint: CHECKPOINT_CONTRACT,
|
|
208
233
|
machine,
|
|
209
234
|
repoKey,
|
|
210
235
|
branch: card.head.branch,
|
|
211
236
|
baseOid: card.head.oid,
|
|
212
|
-
from
|
|
213
|
-
|
|
214
|
-
repoKey,
|
|
215
|
-
card.head.oid,
|
|
216
|
-
reduced.indexDiff,
|
|
217
|
-
reduced.worktreeDiff,
|
|
218
|
-
),
|
|
219
|
-
to: checkpointValue(
|
|
220
|
-
machine,
|
|
221
|
-
repoKey,
|
|
222
|
-
card.head.oid,
|
|
223
|
-
captured.indexDiff,
|
|
224
|
-
captured.worktreeDiff,
|
|
225
|
-
),
|
|
237
|
+
from,
|
|
238
|
+
to,
|
|
226
239
|
parked,
|
|
227
240
|
capturedAt: new Date().toISOString(),
|
|
228
241
|
};
|
|
@@ -322,6 +335,7 @@ module.exports = {
|
|
|
322
335
|
MAX_INLINE_DIFF_BYTES,
|
|
323
336
|
checkpointFile,
|
|
324
337
|
checkpointStats,
|
|
338
|
+
checkpointValueReady,
|
|
325
339
|
parseCheckpoint,
|
|
326
340
|
publishCheckpoints,
|
|
327
341
|
readCheckpoint,
|
|
@@ -378,6 +378,7 @@ async function reduceCheckpoint(localCard, plan) {
|
|
|
378
378
|
for (const operation of plan.transitions) {
|
|
379
379
|
const from = readCheckpointValue(baseOid, operation.from);
|
|
380
380
|
const to = readCheckpointValue(baseOid, operation.to);
|
|
381
|
+
if (from.state === 'payload-pending' || to.state === 'payload-pending') continue;
|
|
381
382
|
if (from.state !== 'ready' || to.state !== 'ready') {
|
|
382
383
|
return { state: 'waiting', reason: `checkpoint-${from.state !== 'ready' ? from.state : to.state}` };
|
|
383
384
|
}
|
|
@@ -644,6 +645,7 @@ module.exports = {
|
|
|
644
645
|
hydrateRepo,
|
|
645
646
|
materializeRepo,
|
|
646
647
|
readRepoState,
|
|
648
|
+
reduceCheckpoint,
|
|
647
649
|
reduceNow,
|
|
648
650
|
reduceWall,
|
|
649
651
|
reducerStats,
|