@lmzhen/dsh-evolution-commands 0.3.79 → 0.3.80
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 +57 -7
- package/package.json +5 -5
package/lib/index.js
CHANGED
|
@@ -119,6 +119,9 @@ function resolveAgentPresetAsset(asset) {
|
|
|
119
119
|
}
|
|
120
120
|
/** The base rows of bases.json: the comparison iterates the same table the
|
|
121
121
|
* installer reads, so doctor cannot check a different set of variants.
|
|
122
|
+
* S1-F1: rows also carry the optional `unsupported` note — the layered-form
|
|
123
|
+
* detection below must not treat a base that carries NO family model rows
|
|
124
|
+
* (minimal) as a double-mount participant.
|
|
122
125
|
* @param path - resolved bases.json.
|
|
123
126
|
* @returns the rows, or null when the table is unreadable or malformed. */
|
|
124
127
|
function readAgentPresetBases$1(path) {
|
|
@@ -131,7 +134,8 @@ function readAgentPresetBases$1(path) {
|
|
|
131
134
|
if (typeof entry.name !== "string" || typeof entry.id !== "string") return null;
|
|
132
135
|
rows.push({
|
|
133
136
|
name: entry.name,
|
|
134
|
-
id: entry.id
|
|
137
|
+
id: entry.id,
|
|
138
|
+
...typeof entry.unsupported === "string" ? { unsupported: entry.unsupported } : {}
|
|
135
139
|
});
|
|
136
140
|
}
|
|
137
141
|
return rows.length > 0 ? rows : null;
|
|
@@ -155,6 +159,38 @@ function installedPresetIds(root) {
|
|
|
155
159
|
return ids;
|
|
156
160
|
}
|
|
157
161
|
/**
|
|
162
|
+
* S1-F1: ids of the family's DELIVERED layered presets — every
|
|
163
|
+
* `.agent-presets/<id>/agent.cordis.yml` artifact that can actually carry the
|
|
164
|
+
* family model rows. The detection used to probe ONLY the default base id
|
|
165
|
+
* (`evolution`), so a `--base ptc|cordis` layered install was invisible:
|
|
166
|
+
* installForm degraded to `none`/`host` and the action ladder recommended
|
|
167
|
+
* installing `evolution-all` on top — the exact double-mount the doctor exists
|
|
168
|
+
* to prevent (V27 G6.4 closed it for the default id only).
|
|
169
|
+
*
|
|
170
|
+
* A directory counts only when the base table names it as a SUPPORTED family
|
|
171
|
+
* base (the `unsupported` minimal base carries no model rows and cannot
|
|
172
|
+
* double-mount anything). When the table itself cannot be read, every
|
|
173
|
+
* delivered artifact counts — the visible-by-directory posture of
|
|
174
|
+
* {@link probePresetFreshness}: flag rather than stay silent.
|
|
175
|
+
* @param root - the `.agent-presets` home directory.
|
|
176
|
+
* @returns installed family base ids whose `agent.cordis.yml` is on disk.
|
|
177
|
+
*/
|
|
178
|
+
function installedLayeredPresetIds(root) {
|
|
179
|
+
const delivered = installedPresetIds(root).filter((id) => existsSync(join(root, id, "agent.cordis.yml")));
|
|
180
|
+
if (delivered.length === 0) return [];
|
|
181
|
+
const basesPath = resolveAgentPresetAsset("bases.json");
|
|
182
|
+
const bases = basesPath === null ? null : readAgentPresetBases$1(basesPath);
|
|
183
|
+
if (bases === null) return delivered.filter((id) => {
|
|
184
|
+
try {
|
|
185
|
+
return readFileSync(join(root, id, "agent.cordis.yml"), "utf8").includes("@deepseek-ai/dsh-");
|
|
186
|
+
} catch {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
const supported = new Set(bases.filter((row) => row.unsupported === void 0).map((row) => row.id));
|
|
191
|
+
return delivered.filter((id) => supported.has(id));
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
158
194
|
* G3-② (B2): recompute what a fresh generation would write for every
|
|
159
195
|
* installed variant and compare it byte-for-byte with the file on disk.
|
|
160
196
|
*
|
|
@@ -278,13 +314,15 @@ async function diagnose(ctx, options = {}) {
|
|
|
278
314
|
const full = bundles.some((name) => tailOf(name) === "dsh-evolution-all");
|
|
279
315
|
const host = bundles.some((name) => tailOf(name) === "dsh-evolution-host");
|
|
280
316
|
const preset = bundles.some((name) => tailOf(name) === "dsh-evolution-preset");
|
|
281
|
-
const
|
|
317
|
+
const layeredIds = installedLayeredPresetIds(join(home, ".agent-presets"));
|
|
318
|
+
const presetDirInstalled = layeredIds.length > 0;
|
|
319
|
+
const layeredArtifactLabel = presetDirInstalled ? layeredIds.join(", ") : "evolution";
|
|
282
320
|
const layered = host && presetDirInstalled;
|
|
283
321
|
if (full && host) conflicts.push("evolution-all and evolution-host are installed together — the infra rows double-mount and startup fails loud. Keep ONE: remove the other bundle.");
|
|
284
322
|
if (full && preset) conflicts.push("evolution-all and evolution-preset are installed together — the infra rows double-mount. Keep ONE.");
|
|
285
323
|
if (host && preset) conflicts.push("evolution-host and evolution-preset are installed together — the infra rows double-mount. Keep ONE.");
|
|
286
|
-
if (full && presetDirInstalled) conflicts.push(
|
|
287
|
-
if (preset && presetDirInstalled) conflicts.push(
|
|
324
|
+
if (full && presetDirInstalled) conflicts.push(`evolution-all and the layered Evolution preset (${layeredArtifactLabel}) are both present — the model rows double-mount. Keep ONE (use layered without all, or drop the preset).`);
|
|
325
|
+
if (preset && presetDirInstalled) conflicts.push(`evolution-preset and the layered Evolution preset (${layeredArtifactLabel}) are both present — the model rows double-mount (the preset bundle carries the same model rows as all). Keep ONE (drop the preset bundle, or remove the layered preset).`);
|
|
288
326
|
const services = {
|
|
289
327
|
review: full || host || preset,
|
|
290
328
|
curator: has("evolutionCurator"),
|
|
@@ -312,7 +350,7 @@ async function diagnose(ctx, options = {}) {
|
|
|
312
350
|
if (mountConflicts.length > 0) actions.push("Resolve the conflict first: keep exactly one of evolution-all / evolution-host / evolution-preset / layered.");
|
|
313
351
|
else if (undecidable) actions.push("The install form is UNDECIDABLE (see the DEGRADED row above): an unreadable profiles directory or profile manifest hides whatever is installed, so this report must not add or remove a bundle. Fix the reported read failure, then re-run /evolution doctor.");
|
|
314
352
|
else if (installForm === "none") actions.push("Install the default full bundle: dsh plugin --profile web add @lmzhen/dsh-evolution-all");
|
|
315
|
-
else if (installForm === "preset-only") actions.push(
|
|
353
|
+
else if (installForm === "preset-only") actions.push(`The Evolution preset is delivered but no profile mounts an evolution bundle — re-add @lmzhen/dsh-evolution-host for the layered layout (do NOT add all on top of the preset: that double-mounts the model rows), or remove .agent-presets/${layeredArtifactLabel} if the layered layout is no longer wanted.`);
|
|
316
354
|
else if (installForm === "layered") actions.push("Variant form (session opt-in): model tools follow the Evolution preset, and a session on a platform original preset carries no family rows; add @lmzhen/dsh-evolution-all instead if every session should have them.");
|
|
317
355
|
const env = envIssues();
|
|
318
356
|
if (env.length > 0) actions.push("Fix the DSH_EVOLUTION_* variable listed above.");
|
|
@@ -320,7 +358,7 @@ async function diagnose(ctx, options = {}) {
|
|
|
320
358
|
if (pendingCount === null && services.approval) actions.push("Approval service is mounted but pending listing failed — check the evolution state service.");
|
|
321
359
|
const memoryIssues = memoryInterpolationIssues(home);
|
|
322
360
|
if (memoryIssues.length > 0) actions.push("Rewrite the memory entries listed above (or run a build with the render-time neutralization) — they broke prompt assembly on older builds.");
|
|
323
|
-
if ((executingCount ?? 0) > 0) actions.push(`${executingCount} staged write(s) are EXECUTING (an approve crashed mid-run — or one is still in flight). Inspect with /evolution pending: if you started the approve, verify the landed write and do not reject it; only reject after verifying no write is intended.`);
|
|
361
|
+
if ((executingCount ?? 0) > 0) actions.push(`${executingCount} staged write(s) are EXECUTING (an approve crashed mid-run — or one is still in flight). Inspect with /evolution pending: if you started the approve, verify the landed write and do not reject it; only reject after verifying no write is intended. For a verified orphan (this build: S2-P2-22), /evolution release <id> returns it to the pending window instead.`);
|
|
324
362
|
for (const row of presetFreshness) {
|
|
325
363
|
if (row.status !== "differs") continue;
|
|
326
364
|
actions.push(`Preset variant ${row.destination} DIFFERS from a fresh generation — it is an install-time snapshot; re-run the installer (/evolution preset install) to regenerate`);
|
|
@@ -373,6 +411,10 @@ const COMMAND_ENTRIES = [
|
|
|
373
411
|
usage: "reject <id>",
|
|
374
412
|
summary: "drop a staged write without running it"
|
|
375
413
|
},
|
|
414
|
+
{
|
|
415
|
+
usage: "release <id>",
|
|
416
|
+
summary: "return an orphaned EXECUTING write to the pending window (verify the effect first, then approve or reject)"
|
|
417
|
+
},
|
|
376
418
|
{
|
|
377
419
|
usage: "doctor [--json]",
|
|
378
420
|
summary: "read-only self-check: install form, conflicts, env, services (--json feeds scripts)"
|
|
@@ -477,7 +519,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
477
519
|
const approval = ctx.get("evolutionApproval");
|
|
478
520
|
const pendingMatch = /^pending(?: --detail)?$/.exec(input);
|
|
479
521
|
if (pendingMatch) {
|
|
480
|
-
|
|
522
|
+
if (!approval) return err("E-301: approval service not mounted — pending writes cannot be listed or replayed. Next: the evolution-approval row ships with evolution-host/evolution-all — run /evolution doctor to see which services are mounted.");
|
|
523
|
+
const listed = [...await approval.list("pending"), ...await approval.list("executing")];
|
|
481
524
|
const pending = [...new Map(listed.map((row) => [row.id, row])).values()];
|
|
482
525
|
if (pending.length === 0) return ok("No pending evolution writes.");
|
|
483
526
|
const detailed = pendingMatch[0] === "pending --detail";
|
|
@@ -504,6 +547,13 @@ function apply(ctx, rawConfig = {}) {
|
|
|
504
547
|
};
|
|
505
548
|
return result.ok ? ok(result.message) : err(result.message);
|
|
506
549
|
}
|
|
550
|
+
if (input.startsWith("release ")) {
|
|
551
|
+
const id = input.slice(8).trim();
|
|
552
|
+
if (!approval) return err("E-301: approval service not mounted. Next: the evolution-approval row ships with evolution-host/evolution-all — run /evolution doctor to see which services are mounted.");
|
|
553
|
+
if (!approval.release) return err("E-304: the mounted approval service predates the release capability — reject the record instead.");
|
|
554
|
+
const result = await approval.release(id);
|
|
555
|
+
return result.ok ? ok(result.message) : err(result.message);
|
|
556
|
+
}
|
|
507
557
|
if (input === "curator run") {
|
|
508
558
|
const curator = ctx.get("evolutionCurator");
|
|
509
559
|
if (!curator) return err("E-302: curator service not mounted. Next: mount the evolution-curator row (evolution-host/evolution-all) and run /evolution doctor.");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-commands",
|
|
3
3
|
"description": "Human commands for the evolution family (/evolution pending|curator|maintain|doctor) (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.80",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
30
|
-
"@lmzhen/dsh-evolution-approval": "^0.3.
|
|
31
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
32
|
-
"@lmzhen/dsh-evolution-maintenance": "^0.3.
|
|
30
|
+
"@lmzhen/dsh-evolution-approval": "^0.3.80",
|
|
31
|
+
"@lmzhen/dsh-evolution-core": "^0.3.80",
|
|
32
|
+
"@lmzhen/dsh-evolution-maintenance": "^0.3.80"
|
|
33
33
|
},
|
|
34
34
|
"optionalDependencies": {
|
|
35
|
-
"@lmzhen/dsh-evolution-agent-preset": "^0.3.
|
|
35
|
+
"@lmzhen/dsh-evolution-agent-preset": "^0.3.80"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.1",
|