@lmzhen/dsh-evolution-commands 0.27.0 → 0.27.1

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 CHANGED
@@ -1602,40 +1602,53 @@ function legacyLine(row) {
1602
1602
  const more = row.pending.length > 6 ? ` (+${row.pending.length - 6} more)` : "";
1603
1603
  return `legacy settings: ${row.pending.length} family value(s) still on ${row.source ?? "(unknown)"}: ${shown}${more} — /evolution migrate moves them`;
1604
1604
  }
1605
+ /**
1606
+ * W8-S7: the doctor's text face, VIEW-FIRST.
1607
+ *
1608
+ * The frozen DiagnosticsView (7 facts + 8 runtime rows) is the single text source for everything
1609
+ * it carries — install form, platform services, runs, channel/preset/host/pairing. The legacy
1610
+ * report now contributes only the facts the view does not represent yet: cross-profile bundles,
1611
+ * the family service inference, capability absence, the scoped-row probe, the legacy settings
1612
+ * document, pending/executing audit records, preset freshness, and the conflict/env/budget/
1613
+ * parameter/session-search findings + next steps. This is the W8-S7 rewrite branch: the text face
1614
+ * has real consumers (the `/evolution doctor` command, README/INSTALL, doctor.spec), so the legacy
1615
+ * rendering was rewritten instead of deleted — but every fact the view owns renders from the view
1616
+ * exactly once (the legacy install-form line is gone).
1617
+ * @param report - the assembled report (view + legacy findings).
1618
+ * @returns the text face.
1619
+ */
1605
1620
  function renderDoctorText(report) {
1606
- const lines = [
1607
- `Evolution doctor — install form: ${report.installForm} (deployment: ${report.deploymentForm}; from ${report.formSource === "platform" ? "this runtime's bundle surface" : "the cross-profile aggregate"})`,
1608
- report.runtimeBundles === null ? "runtime bundles: unknown — the platform bundle surface (pluginManager.listBundles) is not mounted here" : `runtime bundles (this profile): ${report.runtimeBundles.length > 0 ? report.runtimeBundles.join(", ") : "(none)"}`,
1609
- report.dormantBundles.length === 0 ? null : `installed but not selected: ${report.dormantBundles.join(", ")} — the Plugins page lists them; this runtime mounts neither`,
1610
- `bundles (all profiles): ${report.bundles.length > 0 ? report.bundles.join(", ") : "(none)"}`,
1611
- `services: review=${report.services.review} (${report.serviceSource === "platform" ? "the live row, this runtime" : "inferred from bundles, all profiles"}) curator=${report.services.curator} approval=${report.services.approval} skillUsage=${report.services.skillUsage} io=${report.services.io}`,
1612
- report.capabilityAbsence.length === 0 ? null : `capability absence (${report.capabilityAbsence.length}): ${report.capabilityAbsence.map((entry) => `${entry.service} — ${entry.feature}`).join("; ")}`,
1613
- scopedProbeLine(report.scopedProbe),
1614
- legacyLine(report.legacy),
1615
- `pending: ${report.pendingCount === null ? "unknown" : report.pendingCount}`,
1616
- `executing: ${report.executingCount === null ? "unknown" : report.executingCount}`
1617
- ];
1621
+ const extras = [];
1622
+ extras.push(report.runtimeBundles === null ? "runtime bundles: unknown — the platform bundle surface (pluginManager.listBundles) is not mounted here" : `runtime bundles (this profile): ${report.runtimeBundles.length > 0 ? report.runtimeBundles.join(", ") : "(none)"}`);
1623
+ if (report.dormantBundles.length > 0) extras.push(`installed but not selected: ${report.dormantBundles.join(", ")} — the Plugins page lists them; this runtime mounts neither`);
1624
+ extras.push(`bundles (all profiles): ${report.bundles.length > 0 ? report.bundles.join(", ") : "(none)"}`);
1625
+ extras.push(`services: review=${report.services.review} (${report.serviceSource === "platform" ? "the live row, this runtime" : "inferred from bundles, all profiles"}) curator=${report.services.curator} approval=${report.services.approval} skillUsage=${report.services.skillUsage} io=${report.services.io}`);
1626
+ if (report.capabilityAbsence.length > 0) extras.push(`capability absence (${report.capabilityAbsence.length}): ${report.capabilityAbsence.map((entry) => `${entry.service} — ${entry.feature}`).join("; ")}`);
1627
+ extras.push(scopedProbeLine(report.scopedProbe));
1628
+ extras.push(legacyLine(report.legacy));
1629
+ extras.push(`pending: ${report.pendingCount === null ? "unknown" : report.pendingCount}`);
1630
+ extras.push(`executing: ${report.executingCount === null ? "unknown" : report.executingCount}`);
1618
1631
  for (const row of report.presetFreshness) {
1619
1632
  if (row.status === "absent") continue;
1620
1633
  const verdict = row.status === "fresh" ? "fresh — a fresh generation matches this file byte-for-byte" : row.status === "differs" ? "DIFFERS from a fresh generation — it is an install-time snapshot; re-run the installer (/evolution preset install) to regenerate" : `unknown — a fresh generation could not be recomputed (${row.detail ?? "reason not recorded"})`;
1621
- lines.push(`preset: ${row.base} → ${row.destination} ${verdict}`);
1634
+ extras.push(`preset: ${row.base} → ${row.destination} ${verdict}`);
1622
1635
  }
1623
- if (report.presetIssues.length > 0) lines.push("agent presets:", ...report.presetIssues.map((line) => ` ! ${line}`));
1624
- if (report.foreignProfiles.length > 0) lines.push("profiles-foreign: " + report.foreignProfiles.join(", ") + " — not part of this plane: /evolution preset install ignores them, while the bundles (all profiles) line above counts them");
1625
- if (report.conflicts.length > 0) lines.push("conflicts:", ...report.conflicts.map((line) => ` ! ${line}`));
1626
- if (report.envIssues.length > 0) lines.push("env:", ...report.envIssues.map((line) => ` ! ${line}`));
1627
- if (report.budgetIssues.length > 0) lines.push("memory budget:", ...report.budgetIssues.map((line) => ` ! ${line}`));
1628
- if (report.paramIssues.length > 0) lines.push("parameters:", ...report.paramIssues.map((line) => ` ! ${line}`));
1629
- if (report.queryIssues.length > 0) lines.push("session search:", ...report.queryIssues.map((line) => ` ! ${line}`));
1630
- if (report.actions.length > 0) lines.push("next steps:", ...report.actions.map((line) => ` → ${line}`));
1631
- return lines.filter((line) => line !== null).join("\n");
1636
+ if (report.presetIssues.length > 0) extras.push("agent presets:", ...report.presetIssues.map((line) => ` ! ${line}`));
1637
+ if (report.foreignProfiles.length > 0) extras.push("profiles-foreign: " + report.foreignProfiles.join(", ") + " — not part of this plane: /evolution preset install ignores them, while the bundles (all profiles) line above counts them");
1638
+ if (report.conflicts.length > 0) extras.push("conflicts:", ...report.conflicts.map((line) => ` ! ${line}`));
1639
+ if (report.envIssues.length > 0) extras.push("env:", ...report.envIssues.map((line) => ` ! ${line}`));
1640
+ if (report.budgetIssues.length > 0) extras.push("memory budget:", ...report.budgetIssues.map((line) => ` ! ${line}`));
1641
+ if (report.paramIssues.length > 0) extras.push("parameters:", ...report.paramIssues.map((line) => ` ! ${line}`));
1642
+ if (report.queryIssues.length > 0) extras.push("session search:", ...report.queryIssues.map((line) => ` ! ${line}`));
1643
+ if (report.actions.length > 0) extras.push("next steps:", ...report.actions.map((line) => ` → ${line}`));
1644
+ return renderDiagnosticsText(report.view).trimEnd() + "\n\n补充检查(view 未覆盖的运行时事实):\n" + extras.join("\n");
1632
1645
  }
1633
1646
  /**
1634
1647
  * G6/W8 tail: render the frozen DiagnosticsView as the doctor's diagnostics section.
1635
1648
  *
1636
1649
  * This is the ONE text face of the 7+8 rows: the same object `--json` and the diagnostics route
1637
- * answer, so the three readers cannot disagree. Legacy install/conflict sections keep their own
1638
- * renderer until the remaining W8-S7 rewrite lands.
1650
+ * answer, so the three readers cannot disagree. The legacy report only adds the facts this frozen
1651
+ * view does not carry yet (see renderDoctorText).
1639
1652
  * @param view - the assembled view.
1640
1653
  * @returns the section text (ends with a newline).
1641
1654
  */
@@ -3174,7 +3187,7 @@ function apply(ctx, rawConfig = {}) {
3174
3187
  ...mounted
3175
3188
  });
3176
3189
  if (input === "doctor --json") return ok(JSON.stringify(report.view, null, 2));
3177
- return ok(renderDoctorText(report) + "\n" + renderDiagnosticsText(report.view));
3190
+ return ok(renderDoctorText(report));
3178
3191
  }
3179
3192
  if (input === "" || input === "help") return ok(`自进化:记忆、技能、会话回顾、技能整理——状态、待批准写入与维护。\n${renderHelpText()}`);
3180
3193
  return err(`/evolution ${input} 不是本构建能应答的子命令(已知子命令但缺参数也会落到这里)。\n${renderHint()}`);
@@ -159,13 +159,28 @@ export declare function diagnose(ctx: {
159
159
  home?: string;
160
160
  mounted?: MountedProfile;
161
161
  }): Promise<DoctorReport>;
162
+ /**
163
+ * W8-S7: the doctor's text face, VIEW-FIRST.
164
+ *
165
+ * The frozen DiagnosticsView (7 facts + 8 runtime rows) is the single text source for everything
166
+ * it carries — install form, platform services, runs, channel/preset/host/pairing. The legacy
167
+ * report now contributes only the facts the view does not represent yet: cross-profile bundles,
168
+ * the family service inference, capability absence, the scoped-row probe, the legacy settings
169
+ * document, pending/executing audit records, preset freshness, and the conflict/env/budget/
170
+ * parameter/session-search findings + next steps. This is the W8-S7 rewrite branch: the text face
171
+ * has real consumers (the `/evolution doctor` command, README/INSTALL, doctor.spec), so the legacy
172
+ * rendering was rewritten instead of deleted — but every fact the view owns renders from the view
173
+ * exactly once (the legacy install-form line is gone).
174
+ * @param report - the assembled report (view + legacy findings).
175
+ * @returns the text face.
176
+ */
162
177
  export declare function renderDoctorText(report: DoctorReport): string;
163
178
  /**
164
179
  * G6/W8 tail: render the frozen DiagnosticsView as the doctor's diagnostics section.
165
180
  *
166
181
  * This is the ONE text face of the 7+8 rows: the same object `--json` and the diagnostics route
167
- * answer, so the three readers cannot disagree. Legacy install/conflict sections keep their own
168
- * renderer until the remaining W8-S7 rewrite lands.
182
+ * answer, so the three readers cannot disagree. The legacy report only adds the facts this frozen
183
+ * view does not carry yet (see renderDoctorText).
169
184
  * @param view - the assembled view.
170
185
  * @returns the section text (ends with a newline).
171
186
  */
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.27.0",
4
+ "version": "0.27.1",
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.5",
30
- "@lmzhen/dsh-evolution-approval": "^0.27.0",
31
- "@lmzhen/dsh-evolution-core": "^0.27.0",
32
- "@lmzhen/dsh-evolution-maintenance": "^0.27.0"
30
+ "@lmzhen/dsh-evolution-approval": "^0.27.1",
31
+ "@lmzhen/dsh-evolution-core": "^0.27.1",
32
+ "@lmzhen/dsh-evolution-maintenance": "^0.27.1"
33
33
  },
34
34
  "optionalDependencies": {
35
- "@lmzhen/dsh-evolution-agent-preset": "^0.27.0"
35
+ "@lmzhen/dsh-evolution-agent-preset": "^0.27.1"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@deepseek-ai/cordis": "^4.0.5",