@lmzhen/dsh-evolution-commands 0.6.1 → 0.8.0
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 +49 -33
- package/package.json +5 -5
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { effectiveSessionPolicy } from "@lmzhen/dsh-evolution-approval";
|
|
4
4
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
5
|
-
import { DEFAULT_SKILL_LIMITS, MAX_TIMER_DELAY_MS, PARAM_EXPOSURE, PARAM_NAMESPACES, appendEvolutionEvent, assertSkillsRootAliasRetired, buildLearnPrompt, canonicalWriteId, clampedNumber, composePresetComposition, eventsFile, evolutionRoot, isDeprecatedParamId, isMissingPath, newSkillLibrary, policyStageLimits, resolveParamId, resolveRootConfig, scopedProbeReport } from "@lmzhen/dsh-evolution-core";
|
|
5
|
+
import { DEFAULT_SKILL_LIMITS, MAX_TIMER_DELAY_MS, PARAM_EXPOSURE, PARAM_NAMESPACES, appendEvolutionEvent, assertSkillsRootAliasRetired, buildLearnPrompt, canonicalWriteId, clampedNumber, composePresetComposition, errorText, eventsFile, evolutionRoot, isDeprecatedParamId, isMissingPath, newSkillLibrary, policyStageLimits, resolveParamId, resolveRootConfig, scopedProbeReport } from "@lmzhen/dsh-evolution-core";
|
|
6
6
|
import { buildEnrichment, buildMaintainFacts, runMaintain, snapshotFromLibrary } from "@lmzhen/dsh-evolution-maintenance";
|
|
7
7
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
@@ -833,18 +833,18 @@ function apply(ctx, rawConfig = {}) {
|
|
|
833
833
|
text
|
|
834
834
|
});
|
|
835
835
|
const invocationAgent = invocation.agent;
|
|
836
|
-
const agentMissing = (need) => invocationAgent === void 0 ? err(
|
|
836
|
+
const agentMissing = (need) => invocationAgent === void 0 ? err(errorText("e-305-this-invocation-carries-no", { a1: need })) : void 0;
|
|
837
837
|
const unreplayableWriteRefusal = (what) => {
|
|
838
838
|
if (approval === void 0) return void 0;
|
|
839
839
|
const session = invocationAgent?.session;
|
|
840
840
|
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
841
841
|
if (!(approval.isEnabled !== false && sessionPolicy !== "never" && approval.stageForeground !== false)) return void 0;
|
|
842
|
-
return err(
|
|
842
|
+
return err(errorText("e-306-this-deployment-stages-foreground", { a1: what }));
|
|
843
843
|
};
|
|
844
844
|
const approval = ctx.get("evolutionApproval");
|
|
845
845
|
const pendingMatch = /^pending(?: --detail)?$/.exec(input);
|
|
846
846
|
if (pendingMatch) {
|
|
847
|
-
if (!approval) return err("
|
|
847
|
+
if (!approval) return err(errorText("e-301-approval-service-not-mounted"));
|
|
848
848
|
const listed = [...await approval.list("pending"), ...await approval.list("executing")];
|
|
849
849
|
const pending = [...new Map(listed.map((row) => [row.id, row])).values()];
|
|
850
850
|
if (pending.length === 0) return ok("No pending evolution writes.");
|
|
@@ -860,7 +860,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
860
860
|
const id = input.slice(8).trim();
|
|
861
861
|
const result = approval ? await approval.approve(id) : {
|
|
862
862
|
ok: false,
|
|
863
|
-
message: "
|
|
863
|
+
message: errorText("e-301-approval-service-not-mounted-2")
|
|
864
864
|
};
|
|
865
865
|
return result.ok ? ok(result.message) : err(result.message);
|
|
866
866
|
}
|
|
@@ -868,27 +868,27 @@ function apply(ctx, rawConfig = {}) {
|
|
|
868
868
|
const id = input.slice(7).trim();
|
|
869
869
|
const result = approval ? await approval.reject(id) : {
|
|
870
870
|
ok: false,
|
|
871
|
-
message: "
|
|
871
|
+
message: errorText("e-301-approval-service-not-mounted-2")
|
|
872
872
|
};
|
|
873
873
|
return result.ok ? ok(result.message) : err(result.message);
|
|
874
874
|
}
|
|
875
875
|
if (input.startsWith("release ")) {
|
|
876
876
|
const id = input.slice(8).trim();
|
|
877
|
-
if (!approval) return err("
|
|
878
|
-
if (!approval.release) return err("
|
|
877
|
+
if (!approval) return err(errorText("e-301-approval-service-not-mounted-2"));
|
|
878
|
+
if (!approval.release) return err(errorText("e-304-the-mounted-approval-service"));
|
|
879
879
|
const result = await approval.release(id);
|
|
880
880
|
return result.ok ? ok(result.message) : err(result.message);
|
|
881
881
|
}
|
|
882
882
|
if (input === "curator run") {
|
|
883
883
|
const curator = ctx.get("evolutionCurator");
|
|
884
|
-
if (!curator) return err("
|
|
884
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
885
885
|
const result = await curator.run({ ignoreGates: true });
|
|
886
886
|
if (result.skipped !== void 0) return ok(`Curator run skipped (${result.skipped}): no curation pass was executed.\nrunId=${result.report.runId}`);
|
|
887
887
|
return ok(`Curator run complete: ${result.stale.length} stale, ${result.archived.length} archived, ${result.errors.length} failed.\nrunId=${result.report.runId}${result.report.snapshotPath ? `\nsnapshot=${result.report.snapshotPath}` : ""}`);
|
|
888
888
|
}
|
|
889
889
|
if (input === "curator pause" || input === "curator resume") {
|
|
890
890
|
const curator = ctx.get("evolutionCurator");
|
|
891
|
-
if (!curator) return err("
|
|
891
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
892
892
|
const paused = input === "curator pause";
|
|
893
893
|
await curator.setPaused(paused);
|
|
894
894
|
const notPersisted = ctx.get("evolutionState") !== void 0 ? "" : "\nNOTE: no evolution state service is mounted — this setting is NOT persisted and will not survive this process.";
|
|
@@ -896,7 +896,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
896
896
|
}
|
|
897
897
|
if (input === "curator status") {
|
|
898
898
|
const curator = ctx.get("evolutionCurator");
|
|
899
|
-
if (!curator) return err("
|
|
899
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
900
900
|
const state = await curator.status();
|
|
901
901
|
if (!state) return ok("No curator state yet: the first automatic pass is deferred until the interval elapses.");
|
|
902
902
|
const lastRun = typeof state.lastRunAt === "number" && Number.isFinite(state.lastRunAt) && state.lastRunAt > 0 ? new Date(state.lastRunAt).toISOString() : "unknown";
|
|
@@ -909,7 +909,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
909
909
|
}
|
|
910
910
|
if (input === "mutations") {
|
|
911
911
|
const curator = ctx.get("evolutionCurator");
|
|
912
|
-
if (!curator) return err("
|
|
912
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
913
913
|
const records = await curator.skills.listMutations();
|
|
914
914
|
const usable = Array.isArray(records) ? records.filter((row) => typeof row === "object" && row !== null && typeof row.at === "string" && typeof row.skillName === "string" && typeof row.action === "string" && typeof row.summary === "string") : [];
|
|
915
915
|
if (usable.length === 0) return ok("No mutation records yet.");
|
|
@@ -918,7 +918,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
918
918
|
}
|
|
919
919
|
if (input === "curator scope") {
|
|
920
920
|
const curator = ctx.get("evolutionCurator");
|
|
921
|
-
if (!curator) return err("
|
|
921
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
922
922
|
const view = await curator.scopeView();
|
|
923
923
|
const line = (label, names) => `${label}: ${names.length}${names.length === 0 ? "" : `\n ${names.join(", ")}`}`;
|
|
924
924
|
return ok([
|
|
@@ -932,7 +932,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
932
932
|
}
|
|
933
933
|
if (input === "curator report") {
|
|
934
934
|
const curator = ctx.get("evolutionCurator");
|
|
935
|
-
if (!curator) return err("
|
|
935
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
936
936
|
const report = await curator.latestReport();
|
|
937
937
|
if (!report) return ok("No curator report available.");
|
|
938
938
|
if (typeof report !== "object" || typeof report.runId !== "string" || typeof report.startedAt !== "string" || !Array.isArray(report.archived) || !Array.isArray(report.failed)) return err("Report file unreadable.");
|
|
@@ -958,7 +958,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
958
958
|
const curator = ctx.get("evolutionCurator");
|
|
959
959
|
const result = curator ? await curator.restoreSnapshot() : {
|
|
960
960
|
ok: false,
|
|
961
|
-
message: "
|
|
961
|
+
message: errorText("e-302-curator-service-not-mounted")
|
|
962
962
|
};
|
|
963
963
|
return result.ok ? ok(result.message) : err(result.message);
|
|
964
964
|
}
|
|
@@ -972,7 +972,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
972
972
|
const curator = ctx.get("evolutionCurator");
|
|
973
973
|
const result = curator ? await curator.consolidate(target, sources) : {
|
|
974
974
|
ok: false,
|
|
975
|
-
message: "
|
|
975
|
+
message: errorText("e-302-curator-service-not-mounted")
|
|
976
976
|
};
|
|
977
977
|
if (!result.ok) return err(result.message);
|
|
978
978
|
return ok(planRunId ? `${result.message}\n[audit] plan=${planRunId}` : result.message);
|
|
@@ -985,13 +985,13 @@ function apply(ctx, rawConfig = {}) {
|
|
|
985
985
|
const curator = ctx.get("evolutionCurator");
|
|
986
986
|
const result = curator ? await curator.restore(name) : {
|
|
987
987
|
ok: false,
|
|
988
|
-
message: "
|
|
988
|
+
message: errorText("e-302-curator-service-not-mounted")
|
|
989
989
|
};
|
|
990
990
|
return result.ok ? ok(result.message) : err(result.message);
|
|
991
991
|
}
|
|
992
992
|
if (input === "skills health") {
|
|
993
993
|
const curator = ctx.get("evolutionCurator");
|
|
994
|
-
if (!curator) return err("
|
|
994
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
995
995
|
const [rows, observed] = await Promise.all([curator.healthView(), curator.usageObserved()]);
|
|
996
996
|
const banner = observed ? "" : "Usage observation not yet established — churn (write-ghost) rows are suppressed.";
|
|
997
997
|
const line = (row) => `${row.verdict.padEnd(18)} ${row.name}${row.reasons.length > 0 ? ` — ${row.reasons.join("; ")}` : ""}`;
|
|
@@ -1024,7 +1024,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1024
1024
|
agent.followup(message);
|
|
1025
1025
|
woke = true;
|
|
1026
1026
|
} else if (typeof agent.inject === "function") agent.inject(message);
|
|
1027
|
-
else return err("
|
|
1027
|
+
else return err(errorText("e-305-the-invocation-agent-exposes"));
|
|
1028
1028
|
const eventIo = ctx.get("evolutionIo")?.provider();
|
|
1029
1029
|
if (eventIo) appendEvolutionEvent(eventIo, eventsFile(evolutionRoot()), {
|
|
1030
1030
|
type: "learn",
|
|
@@ -1203,7 +1203,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1203
1203
|
const session = invocationAgent?.session;
|
|
1204
1204
|
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
1205
1205
|
const stagesForeground = approval.isEnabled !== false && sessionPolicy !== "never" && approval.stageForeground !== false;
|
|
1206
|
-
if (stagesForeground && session === void 0) return err("
|
|
1206
|
+
if (stagesForeground && session === void 0) return err(errorText("e-306-this-deployment-stages-foreground-2"));
|
|
1207
1207
|
if (stagesForeground && !approval.hasRunner("skill")) return err("Restructure cannot be staged: no skill replay runner is registered — mount the tool-skill-manage row (evolution-agent preset, or evolution-all) or disable evolution-approval.");
|
|
1208
1208
|
const decision = await approval.request({
|
|
1209
1209
|
kind: "skill",
|
|
@@ -1248,7 +1248,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1248
1248
|
}
|
|
1249
1249
|
if (input === "replay") {
|
|
1250
1250
|
const replay = ctx.get("evolutionReplay");
|
|
1251
|
-
if (!replay) return err("
|
|
1251
|
+
if (!replay) return err(errorText("e-303-replay-service-not-mounted"));
|
|
1252
1252
|
return ok(replay.compare().report);
|
|
1253
1253
|
}
|
|
1254
1254
|
const paramsMatch = /^params(?: --group ([a-z-]+))?(?: --json)?$/.exec(input);
|
|
@@ -1264,52 +1264,68 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1264
1264
|
sections.set(descriptor.ns, section);
|
|
1265
1265
|
}
|
|
1266
1266
|
} catch (error) {
|
|
1267
|
-
return err(
|
|
1267
|
+
return err(errorText("e-307-the-settings-service-could", { a1: error instanceof Error ? error.message : String(error) }));
|
|
1268
1268
|
}
|
|
1269
1269
|
const rows = paramSurfaceRows(sections, PARAM_EXPOSURE);
|
|
1270
1270
|
const group = paramsMatch[1];
|
|
1271
1271
|
const selected = group === void 0 ? rows : rows.filter((row) => row.group === group);
|
|
1272
|
-
if (group !== void 0 && selected.length === 0) return err(
|
|
1272
|
+
if (group !== void 0 && selected.length === 0) return err(errorText("e-308-unknown-parameter-group-group", {
|
|
1273
|
+
a1: group,
|
|
1274
|
+
a2: paramGroups(PARAM_EXPOSURE).join(", ")
|
|
1275
|
+
}));
|
|
1273
1276
|
if (input.endsWith("--json")) return ok(renderParamJson(selected));
|
|
1274
1277
|
return ok(renderParamRows(selected, { providerMounted: provider !== void 0 }));
|
|
1275
1278
|
}
|
|
1276
1279
|
const policySetMatch = /^policy set ([A-Za-z][A-Za-z0-9.-]*) (.+?)(?: --expect (\d+))?$/.exec(input);
|
|
1277
1280
|
if (policySetMatch) {
|
|
1278
1281
|
const provider = ctx.get("settings");
|
|
1279
|
-
if (provider?.update === void 0 || provider.describe === void 0) return err("
|
|
1282
|
+
if (provider?.update === void 0 || provider.describe === void 0) return err(errorText("e-311-no-settings-service-is"));
|
|
1280
1283
|
const rawId = policySetMatch[1] ?? "";
|
|
1281
1284
|
const rawValue = policySetMatch[2] ?? "";
|
|
1282
1285
|
let id;
|
|
1283
1286
|
try {
|
|
1284
1287
|
id = canonicalWriteId(rawId);
|
|
1285
1288
|
} catch (error) {
|
|
1286
|
-
return err(
|
|
1289
|
+
return err(errorText("e-312-error-instanceof-Error-error", { a1: error instanceof Error ? error.message : String(error) }));
|
|
1287
1290
|
}
|
|
1288
1291
|
const entry = PARAM_EXPOSURE.find((candidate) => candidate.id === id);
|
|
1289
|
-
if (entry === void 0) return err(
|
|
1290
|
-
if (entry.tier !== "E3") return err(
|
|
1292
|
+
if (entry === void 0) return err(errorText("e-313-unknown-parameter-id-evolution", { a1: id }));
|
|
1293
|
+
if (entry.tier !== "E3") return err(errorText("e-314-id-is-a-deployment", {
|
|
1294
|
+
a1: id,
|
|
1295
|
+
a2: entry.tier,
|
|
1296
|
+
a3: entry.owner
|
|
1297
|
+
}));
|
|
1291
1298
|
const namespace = PARAM_NAMESPACES[entry.owner];
|
|
1292
|
-
if (namespace === void 0) return err(
|
|
1299
|
+
if (namespace === void 0) return err(errorText("e-315-id-has-no-user", {
|
|
1300
|
+
a1: id,
|
|
1301
|
+
a2: entry.owner
|
|
1302
|
+
}));
|
|
1293
1303
|
let descriptor;
|
|
1294
1304
|
try {
|
|
1295
1305
|
descriptor = provider.describe({ redactSecrets: false }).find((candidate) => candidate.ns === namespace);
|
|
1296
1306
|
} catch (error) {
|
|
1297
|
-
return err(
|
|
1307
|
+
return err(errorText("e-307-the-settings-service-could-2", { a1: error instanceof Error ? error.message : String(error) }));
|
|
1298
1308
|
}
|
|
1299
|
-
if (descriptor === void 0) return err(
|
|
1309
|
+
if (descriptor === void 0) return err(errorText("e-316-namespace-namespace-is-not", {
|
|
1310
|
+
a1: namespace,
|
|
1311
|
+
a2: entry.owner
|
|
1312
|
+
}));
|
|
1300
1313
|
const current = descriptor.value;
|
|
1301
1314
|
const resolved = typeof current === "object" && current !== null ? current : void 0;
|
|
1302
1315
|
const expectedRaw = policySetMatch[3];
|
|
1303
1316
|
const expected = expectedRaw === void 0 ? descriptor.revision : Number(expectedRaw);
|
|
1304
|
-
if (expectedRaw !== void 0 && descriptor.revision !== void 0 && Number(expectedRaw) !== descriptor.revision) return err(
|
|
1317
|
+
if (expectedRaw !== void 0 && descriptor.revision !== void 0 && Number(expectedRaw) !== descriptor.revision) return err(errorText("e-309-revision-conflict-you-sent", {
|
|
1318
|
+
a1: expectedRaw,
|
|
1319
|
+
a2: descriptor.revision
|
|
1320
|
+
}));
|
|
1305
1321
|
const value = parseParamValue(rawValue);
|
|
1306
1322
|
try {
|
|
1307
1323
|
await provider.update(namespace, { [id]: value }, expected);
|
|
1308
1324
|
} catch (error) {
|
|
1309
1325
|
const code = error?.code;
|
|
1310
1326
|
const message = error instanceof Error ? error.message : String(error);
|
|
1311
|
-
if (code === "SETTINGS_CONFLICT") return err(
|
|
1312
|
-
return err(
|
|
1327
|
+
if (code === "SETTINGS_CONFLICT") return err(errorText("e-309-revision-conflict-message-Re", { a1: message }));
|
|
1328
|
+
return err(errorText("e-310-the-settings-service-refused", { a1: message }));
|
|
1313
1329
|
}
|
|
1314
1330
|
return ok(renderPolicySet({
|
|
1315
1331
|
id,
|
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.
|
|
4
|
+
"version": "0.8.0",
|
|
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.
|
|
31
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
32
|
-
"@lmzhen/dsh-evolution-maintenance": "^0.
|
|
30
|
+
"@lmzhen/dsh-evolution-approval": "^0.8.0",
|
|
31
|
+
"@lmzhen/dsh-evolution-core": "^0.8.0",
|
|
32
|
+
"@lmzhen/dsh-evolution-maintenance": "^0.8.0"
|
|
33
33
|
},
|
|
34
34
|
"optionalDependencies": {
|
|
35
|
-
"@lmzhen/dsh-evolution-agent-preset": "^0.
|
|
35
|
+
"@lmzhen/dsh-evolution-agent-preset": "^0.8.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.1",
|