@lmzhen/dsh-evolution-commands 0.3.82 → 0.3.83

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/README.md CHANGED
@@ -1,14 +1,26 @@
1
- # @deepseek-ai/dsh-evolution-commands
1
+ # @lmzhen/dsh-evolution-commands
2
2
 
3
3
  Human commands for the evolution family
4
4
 
5
+ ## Command reference
6
+
7
+ The full `/evolution` subcommand table is single-sourced in the family
8
+ README's **Command reference** section (`packages/README.md` in the source
9
+ repository; it is named here instead of linked because a repo-relative
10
+ markdown link out of this package would be dead inside the npm published
11
+ tree). It is rendered from the subcommand registry (`src/registry.ts`, the same
12
+ single source as the `/evolution` input-declaration hint and the
13
+ bare-command help output), and `tests/registry.spec.ts` (T-WD2) pins that
14
+ rendered table byte-for-byte. This package README cites that home instead
15
+ of restating the table (doc-facts rule N19: never copy a fact across docs).
16
+
5
17
  ## Model Experience
6
18
 
7
19
  ### Indirect model surface
8
20
 
9
21
  #### What the model sees
10
22
 
11
- `@deepseek-ai/dsh-evolution-commands` registers no direct prompt or tool schema itself. Model-visible effects are owned by the packages that consume this service.
23
+ `@lmzhen/dsh-evolution-commands` registers no direct prompt or tool schema itself. Model-visible effects are owned by the packages that consume this service.
12
24
 
13
25
  #### Token effect
14
26
 
package/lib/index.js CHANGED
@@ -321,8 +321,8 @@ async function diagnose(ctx, options = {}) {
321
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.");
322
322
  if (full && preset) conflicts.push("evolution-all and evolution-preset are installed together — the infra rows double-mount. Keep ONE.");
323
323
  if (host && preset) conflicts.push("evolution-host and evolution-preset are installed together — the infra rows double-mount. Keep ONE.");
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).`);
324
+ if (full && presetDirInstalled) conflicts.push(`evolution-all and the layered Evolution preset (${layeredArtifactLabel}) are both present — the four model rows AND the systemPrompt sections double-instance across the profile and preset layers; the preset loader does not fail on it, shadowing semantics take the nearest layer, so an Evolution-preset session silently runs the preset's copies of everything. 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 preset bundle carries the same model rows as all, so the four model rows AND the systemPrompt sections double-instance and shadowing semantics take the nearest layer (the preset loader does not fail on it). Keep ONE (drop the preset bundle, or remove the layered preset).`);
326
326
  const reviewMounted = full || host || preset;
327
327
  const services = {
328
328
  review: reviewMounted,
@@ -850,13 +850,22 @@ function apply(ctx, rawConfig = {}) {
850
850
  io: ioRegistry.provider()
851
851
  });
852
852
  const enrichment = await buildEnrichment(ctx, library);
853
- const { facts } = buildMaintainFacts(await snapshotFromLibrary(library, {
853
+ const readFailures = [];
854
+ const snapshots = await snapshotFromLibrary(library, {
854
855
  descriptions: enrichment.descriptions,
855
856
  supportFiles: enrichment.supportFiles,
856
857
  quality: enrichment.quality,
857
858
  protected: enrichment.protected,
858
- catalogInvalid: enrichment.catalogInvalid
859
- }), enrichment.usageObservedValue, void 0);
859
+ catalogInvalid: enrichment.catalogInvalid,
860
+ onReadError: (name, error) => {
861
+ readFailures.push(name);
862
+ ctx.logger.warn(`evolution-maintenance: skipping unreadable skill "${name}": ${error instanceof Error ? error.message : String(error)}`);
863
+ }
864
+ });
865
+ if (snapshots.length === 0 && readFailures.length > 0) return err(`maintenance scan could not read ${readFailures.length} listed skill(s) (${readFailures.slice(0, 10).join(", ")}${readFailures.length > 10 ? ", …" : ""}) and read no skill at all — the library was NOT audited; fix the unreadable skills (or their directory names) and run the scan again`);
866
+ if (snapshots.length === 0 && skillsRootValue !== "" && !await ioRegistry.provider().exists(skillsRootValue)) return err(`maintenance scan found an empty skill library, but the configured skill root does not exist (${skillsRootValue}) — point the skillsRoot config at a real directory (a literal \`~\` is not expanded) and run the scan again`);
867
+ if (snapshots.length === 0) return ok("Maintenance scan: empty skill library. Nothing to do.");
868
+ const { facts } = buildMaintainFacts(snapshots, enrichment.usageObservedValue, void 0);
860
869
  return ok(`Maintenance facts (0-token preview):\n${facts}`);
861
870
  }
862
871
  const maintainArgs = /^maintain(?:\s+--timeout[ =](\d+))?\s*$/.exec(input);
@@ -994,7 +1003,9 @@ function apply(ctx, rawConfig = {}) {
994
1003
  if (approval) {
995
1004
  const session = invocationAgent?.session;
996
1005
  const sessionPolicy = effectiveSessionPolicy(ctx, session);
997
- if (session !== void 0 && approval.isEnabled !== false && sessionPolicy !== "never" && approval.stageForeground !== false && !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.");
1006
+ const stagesForeground = approval.isEnabled !== false && sessionPolicy !== "never" && approval.stageForeground !== false;
1007
+ if (stagesForeground && session === void 0) return err("E-306: this deployment stages foreground writes, but this invocation carries no agent session — `/evolution restructure` would stage a record with no session attribution. Run it from a session in the GUI or the CLI, or set `stageForeground: false` on the evolution-approval row, then repeat the command.");
1008
+ 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.");
998
1009
  const decision = await approval.request({
999
1010
  kind: "skill",
1000
1011
  summary: `/evolution restructure ${name}${planRunId ? ` (plan ${planRunId})` : ""}`,
@@ -4,6 +4,9 @@
4
4
  * 0.3.55 (WD1): the input-declaration hint, the bare `/evolution` help output
5
5
  * and the README command table all render FROM this table; a hand-written
6
6
  * copy anywhere is drift waiting to happen (v10 R-13 proved it once).
7
+ * PLAN S5.3 (2026-09-16): "the README command table" means the FAMILY README
8
+ * (`packages/README.md` — the T-WD2 anchor). Package-level READMEs cite that
9
+ * home instead of restating the table (doc-facts rule N19).
7
10
  * Keep `usage` in the exact shape a user can type after `/evolution`.
8
11
  */
9
12
  export interface CommandEntry {
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.82",
4
+ "version": "0.3.83",
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.82",
31
- "@lmzhen/dsh-evolution-core": "^0.3.82",
32
- "@lmzhen/dsh-evolution-maintenance": "^0.3.82"
30
+ "@lmzhen/dsh-evolution-approval": "^0.3.83",
31
+ "@lmzhen/dsh-evolution-core": "^0.3.83",
32
+ "@lmzhen/dsh-evolution-maintenance": "^0.3.83"
33
33
  },
34
34
  "optionalDependencies": {
35
- "@lmzhen/dsh-evolution-agent-preset": "^0.3.82"
35
+ "@lmzhen/dsh-evolution-agent-preset": "^0.3.83"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@deepseek-ai/cordis": "^4.0.1",