@lmzhen/dsh-evolution-merge 0.30.15 → 0.30.17
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/lib/index.js +23 -6
- package/lib/types/domain/ledger.js +3 -0
- package/lib/types/read-commands.js +10 -4
- package/lib/types/scan-run.js +2 -0
- package/lib/types/state.js +3 -1
- package/package.json +3 -3
package/lib/index.js
CHANGED
|
@@ -246,6 +246,14 @@ function parseLedger(raw) {
|
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
248
|
const body = parsed;
|
|
249
|
+
if (typeof body.schemaVersion === "number" && body.schemaVersion > 2) return {
|
|
250
|
+
ok: false,
|
|
251
|
+
ledger: {
|
|
252
|
+
schemaVersion: 2,
|
|
253
|
+
rows: []
|
|
254
|
+
},
|
|
255
|
+
note: "merge-state-forward-only"
|
|
256
|
+
};
|
|
249
257
|
if (!Array.isArray(body.rows)) return {
|
|
250
258
|
ok: false,
|
|
251
259
|
ledger: {
|
|
@@ -300,7 +308,8 @@ function parseState(raw) {
|
|
|
300
308
|
const parsed = parseLedger(raw);
|
|
301
309
|
if (!parsed.ok) return {
|
|
302
310
|
ok: false,
|
|
303
|
-
rows: []
|
|
311
|
+
rows: [],
|
|
312
|
+
...parsed.note === void 0 ? {} : { note: parsed.note }
|
|
304
313
|
};
|
|
305
314
|
return {
|
|
306
315
|
ok: true,
|
|
@@ -336,7 +345,9 @@ async function loadMergeState(io, home) {
|
|
|
336
345
|
async function mutateMergeState(io, home, now, fn) {
|
|
337
346
|
let result;
|
|
338
347
|
await transactIo(io, mergeStatePath(home), (current) => {
|
|
339
|
-
const
|
|
348
|
+
const parsed = parseState(current);
|
|
349
|
+
if (!parsed.ok || parsed.note === "merge-state-forward-only") throw new Error(parsed.note ?? "merge-state-invalid");
|
|
350
|
+
const out = fn(parsed.rows);
|
|
340
351
|
result = out.result;
|
|
341
352
|
return JSON.stringify({
|
|
342
353
|
schemaVersion: 2,
|
|
@@ -1551,8 +1562,13 @@ function mergeUsage() {
|
|
|
1551
1562
|
//#region lib/types/read-commands.js
|
|
1552
1563
|
async function handleReadOnlyMergeCommand(command, io, home, cards) {
|
|
1553
1564
|
const withNote = (text, note) => note === void 0 ? text : "note: " + note + "\n" + text;
|
|
1565
|
+
const load = async () => {
|
|
1566
|
+
const result = await loadMergeState(io, home);
|
|
1567
|
+
if (result.note === "merge-state-forward-only") throw new Error("merge-state-forward-only");
|
|
1568
|
+
return result;
|
|
1569
|
+
};
|
|
1554
1570
|
if (command.verb === "status") {
|
|
1555
|
-
const loaded = await
|
|
1571
|
+
const loaded = await load();
|
|
1556
1572
|
if (command.id !== void 0) {
|
|
1557
1573
|
const row = loaded.state.rows.find((item) => item.id === command.id);
|
|
1558
1574
|
return withNote(row === void 0 ? "merge row not found: " + command.id : formatStatus([row]), loaded.note);
|
|
@@ -1560,17 +1576,17 @@ async function handleReadOnlyMergeCommand(command, io, home, cards) {
|
|
|
1560
1576
|
return withNote(formatStatus(loaded.state.rows), loaded.note);
|
|
1561
1577
|
}
|
|
1562
1578
|
if (command.verb === "pending") {
|
|
1563
|
-
const loaded = await
|
|
1579
|
+
const loaded = await load();
|
|
1564
1580
|
const rows = command.expired === true ? loaded.state.rows.filter((row) => row.expired !== void 0) : loaded.state.rows;
|
|
1565
1581
|
const live = cards === void 0 ? rows : rows.filter((row) => cards.some((card) => card.name === row.a) && cards.some((card) => card.name === row.b));
|
|
1566
1582
|
return withNote(command.expired === true ? formatStatus(live) : formatQueue(live, "pending"), loaded.note);
|
|
1567
1583
|
}
|
|
1568
1584
|
if (command.verb === "candidates") {
|
|
1569
|
-
const loaded = await
|
|
1585
|
+
const loaded = await load();
|
|
1570
1586
|
return withNote(formatQueue(command.retry === true ? loaded.state.rows.filter((row) => row.state === "approved") : loaded.state.rows, command.retry === true ? "fuse" : "verify"), loaded.note);
|
|
1571
1587
|
}
|
|
1572
1588
|
if (command.verb === "skipped") {
|
|
1573
|
-
const loaded = await
|
|
1589
|
+
const loaded = await load();
|
|
1574
1590
|
return withNote(formatQueue(loaded.state.rows, "skipped"), loaded.note);
|
|
1575
1591
|
}
|
|
1576
1592
|
return null;
|
|
@@ -1747,6 +1763,7 @@ async function runScan(options) {
|
|
|
1747
1763
|
const stage = options.stage ?? (async () => {});
|
|
1748
1764
|
const candidates = await options.ports.screening(options.signal);
|
|
1749
1765
|
const before = await loadMergeState(options.io, options.home);
|
|
1766
|
+
if (!before.ok) throw new Error(before.note ?? "merge-state-invalid");
|
|
1750
1767
|
const queueBefore = {
|
|
1751
1768
|
verify: 0,
|
|
1752
1769
|
pending: 0,
|
|
@@ -17,6 +17,9 @@ export function parseLedger(raw) {
|
|
|
17
17
|
return { ok: false, ledger: { schemaVersion: 2, rows: [] }, note: 'invalid json' };
|
|
18
18
|
}
|
|
19
19
|
const body = parsed;
|
|
20
|
+
if (typeof body.schemaVersion === 'number' && body.schemaVersion > 2) {
|
|
21
|
+
return { ok: false, ledger: { schemaVersion: 2, rows: [] }, note: 'merge-state-forward-only' };
|
|
22
|
+
}
|
|
20
23
|
if (!Array.isArray(body.rows))
|
|
21
24
|
return { ok: false, ledger: { schemaVersion: 2, rows: [] }, note: 'rows missing' };
|
|
22
25
|
const rows = [];
|
|
@@ -3,8 +3,14 @@ import { formatQueue, formatStatus } from "./status.js";
|
|
|
3
3
|
import { mergeUsage } from "./commands.js";
|
|
4
4
|
export async function handleReadOnlyMergeCommand(command, io, home, cards) {
|
|
5
5
|
const withNote = (text, note) => note === undefined ? text : 'note: ' + note + '\n' + text;
|
|
6
|
+
const load = async () => {
|
|
7
|
+
const result = await loadMergeState(io, home);
|
|
8
|
+
if (result.note === 'merge-state-forward-only')
|
|
9
|
+
throw new Error('merge-state-forward-only');
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
6
12
|
if (command.verb === 'status') {
|
|
7
|
-
const loaded = await
|
|
13
|
+
const loaded = await load();
|
|
8
14
|
if (command.id !== undefined) {
|
|
9
15
|
const row = loaded.state.rows.find(item => item.id === command.id);
|
|
10
16
|
return withNote(row === undefined ? 'merge row not found: ' + command.id : formatStatus([row]), loaded.note);
|
|
@@ -12,18 +18,18 @@ export async function handleReadOnlyMergeCommand(command, io, home, cards) {
|
|
|
12
18
|
return withNote(formatStatus(loaded.state.rows), loaded.note);
|
|
13
19
|
}
|
|
14
20
|
if (command.verb === 'pending') {
|
|
15
|
-
const loaded = await
|
|
21
|
+
const loaded = await load();
|
|
16
22
|
const rows = command.expired === true ? loaded.state.rows.filter(row => row.expired !== undefined) : loaded.state.rows;
|
|
17
23
|
const live = cards === undefined ? rows : rows.filter(row => cards.some(card => card.name === row.a) && cards.some(card => card.name === row.b));
|
|
18
24
|
return withNote(command.expired === true ? formatStatus(live) : formatQueue(live, 'pending'), loaded.note);
|
|
19
25
|
}
|
|
20
26
|
if (command.verb === 'candidates') {
|
|
21
|
-
const loaded = await
|
|
27
|
+
const loaded = await load();
|
|
22
28
|
const rows = command.retry === true ? loaded.state.rows.filter(row => row.state === 'approved') : loaded.state.rows;
|
|
23
29
|
return withNote(formatQueue(rows, command.retry === true ? 'fuse' : 'verify'), loaded.note);
|
|
24
30
|
}
|
|
25
31
|
if (command.verb === 'skipped') {
|
|
26
|
-
const loaded = await
|
|
32
|
+
const loaded = await load();
|
|
27
33
|
return withNote(formatQueue(loaded.state.rows, 'skipped'), loaded.note);
|
|
28
34
|
}
|
|
29
35
|
return null;
|
package/lib/types/scan-run.js
CHANGED
|
@@ -37,6 +37,8 @@ export async function runScan(options) {
|
|
|
37
37
|
const stage = options.stage ?? (async () => { });
|
|
38
38
|
const candidates = await options.ports.screening(options.signal);
|
|
39
39
|
const before = await loadMergeState(options.io, options.home);
|
|
40
|
+
if (!before.ok)
|
|
41
|
+
throw new Error(before.note ?? 'merge-state-invalid');
|
|
40
42
|
const queueBefore = { verify: 0, pending: 0, fuse: 0, skipped: 0 };
|
|
41
43
|
for (const row of before.state.rows)
|
|
42
44
|
queueBefore[row.queue] += 1;
|
package/lib/types/state.js
CHANGED
|
@@ -16,7 +16,7 @@ export function mergeStatePath(home) {
|
|
|
16
16
|
function parseState(raw) {
|
|
17
17
|
const parsed = parseLedger(raw);
|
|
18
18
|
if (!parsed.ok)
|
|
19
|
-
return { ok: false, rows: [] };
|
|
19
|
+
return { ok: false, rows: [], ...(parsed.note === undefined ? {} : { note: parsed.note }) };
|
|
20
20
|
return {
|
|
21
21
|
ok: true,
|
|
22
22
|
rows: parsed.ledger.rows,
|
|
@@ -46,6 +46,8 @@ export async function mutateMergeState(io, home, now, fn) {
|
|
|
46
46
|
await transactIo(io, mergeStatePath(home), (current) => {
|
|
47
47
|
ran = true;
|
|
48
48
|
const parsed = parseState(current);
|
|
49
|
+
if (!parsed.ok || parsed.note === 'merge-state-forward-only')
|
|
50
|
+
throw new Error(parsed.note ?? 'merge-state-invalid');
|
|
49
51
|
const out = fn(parsed.rows);
|
|
50
52
|
result = out.result;
|
|
51
53
|
return JSON.stringify({ schemaVersion: MERGE_STATE_VERSION, rows: out.rows }, null, 2);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-merge",
|
|
3
3
|
"description": "Skill auto-merge domain: screening, two-round authoring, queues and commit orchestration (community build)",
|
|
4
|
-
"version": "0.30.
|
|
4
|
+
"version": "0.30.17",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.5",
|
|
30
|
-
"@lmzhen/dsh-evolution-core": "^0.30.
|
|
31
|
-
"@lmzhen/dsh-evolution-merge-engine": "^0.30.
|
|
30
|
+
"@lmzhen/dsh-evolution-core": "^0.30.17",
|
|
31
|
+
"@lmzhen/dsh-evolution-merge-engine": "^0.30.17"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@deepseek-ai/cordis": "^4.0.5"
|