@lmzhen/dsh-tool-skill-manage 0.12.0 → 0.13.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
@@ -130,7 +130,7 @@ const GATES = [
130
130
  {
131
131
  id: "human-confirm",
132
132
  appliesTo: ["admission"],
133
- run: async ({ view, origin, confirm, warn, confirmMode, confirmTimeoutSeconds }) => {
133
+ run: async ({ view, origin, confirm, warn, confirmMode, confirmTimeoutSeconds, describeTarget }) => {
134
134
  const action = view.action;
135
135
  if (action === void 0 || origin !== "foreground" || view.name === "") return null;
136
136
  if (!(action === "create" || action === "delete" && view.absorbedInto === void 0)) return null;
@@ -151,6 +151,9 @@ const GATES = [
151
151
  }, seconds * 1e3);
152
152
  timer.unref();
153
153
  }) : void 0;
154
+ const context = await describeTarget?.();
155
+ const details = [context?.description === void 0 || context.description === "" ? null : "What it does: " + context.description, context?.versions === void 0 ? null : "Content versions recorded: " + String(context.versions)].filter((line) => line !== null);
156
+ const consequence = action === "create" ? `Create skill "${view.name}"? A new skill directory is written into the family tree.` : `Delete skill "${view.name}"? It is archived under .archive and leaves the catalog.`;
154
157
  const asked = confirm({
155
158
  action,
156
159
  name: view.name,
@@ -158,7 +161,7 @@ const GATES = [
158
161
  question: {
159
162
  id: CONFIRM_QUESTION_ID,
160
163
  header: "Confirm",
161
- question: action === "create" ? `Create skill "${view.name}"? A new skill directory is written into the family tree.` : `Delete skill "${view.name}"? It is archived under .archive and leaves the catalog.`,
164
+ question: details.length === 0 ? consequence : consequence + " " + details.join(" · "),
162
165
  options: [{ label: confirmLabel }, { label: CANCEL_LABEL }]
163
166
  },
164
167
  ...mode === "timeout" ? { signal: cancel.signal } : {}
@@ -813,6 +816,17 @@ function apply(ctx, rawConfig = {}) {
813
816
  confirm: async (request) => confirmSkillWrite(request, exec),
814
817
  confirmMode: settings().skillWriteConfirm,
815
818
  confirmTimeoutSeconds: settings().skillWriteConfirmTimeoutSeconds,
819
+ describeTarget: async () => {
820
+ const versions = typeof args.name === "string" && args.name !== "" ? (await library.listVersions(args.name).catch(() => [])).length : 0;
821
+ const body = typeof args.content === "string" && args.content !== "" ? args.content : typeof args.name === "string" && args.name !== "" ? await library.read(args.name).catch(() => null) : null;
822
+ const frontmatter = body === null ? null : parseFrontmatter(body)?.frontmatter ?? null;
823
+ const parsedDescription = frontmatter === null ? void 0 : frontmatter.description;
824
+ const description = typeof parsedDescription === "string" ? parsedDescription : "";
825
+ return {
826
+ ...description === "" ? {} : { description },
827
+ ...versions === 0 ? {} : { versions }
828
+ };
829
+ },
816
830
  warn: warnWriteGateOnce
817
831
  });
818
832
  if (refusal !== null) return {
@@ -851,7 +865,7 @@ function apply(ctx, rawConfig = {}) {
851
865
  });
852
866
  if (decision.action === "staged") return {
853
867
  ok: true,
854
- message: decision.message,
868
+ message: decision.pendingId === void 0 ? decision.message : decision.message + " (staged id: " + decision.pendingId + " — /evolution pending lists it)",
855
869
  skills: [],
856
870
  ...decision.pendingId !== void 0 ? { pending_id: decision.pendingId } : {}
857
871
  };
@@ -38,6 +38,12 @@ export type WriteConfirmMode = 'auto' | 'ask' | 'timeout';
38
38
  export declare const DEFAULT_WRITE_CONFIRM_MODE: WriteConfirmMode;
39
39
  /** Seconds a `timeout`-mode prompt waits before the write is cancelled. */
40
40
  export declare const DEFAULT_WRITE_CONFIRM_TIMEOUT_SECONDS = 120;
41
+ /** What the operator is told about the target before answering. Every field is optional: a target
42
+ * with no frontmatter, or one the library cannot read, simply carries less. */
43
+ export interface ConfirmContext {
44
+ readonly description?: string | undefined;
45
+ readonly versions?: number | undefined;
46
+ }
41
47
  /** One confirm question, as the gate writes it and the seam asks it. */
42
48
  export interface WriteConfirmRequest {
43
49
  /** The action being confirmed (`create` or `delete`). */
@@ -88,6 +94,9 @@ export interface WriteGateContext {
88
94
  readonly confirmMode?: WriteConfirmMode;
89
95
  /** The registry's `skillWriteConfirmTimeoutSeconds`, read only in `timeout` mode. */
90
96
  readonly confirmTimeoutSeconds?: number;
97
+ /** Read the target's own words for the confirmation card. LAZY on purpose: a write that is not
98
+ * asked about must not pay a read for a question nobody sees. Absent means "say nothing extra". */
99
+ readonly describeTarget?: (() => Promise<ConfirmContext | undefined>) | undefined;
91
100
  /** Report a degraded gate; must not throw. The implementation decides how often it speaks — the
92
101
  * shipped seam latches once per PROCESS, because the conditions it reports (no question service,
93
102
  * an unreadable session log) belong to the deployment, not to one write. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-tool-skill-manage",
3
3
  "description": "Model-facing skill_manage tool (community build)",
4
- "version": "0.12.0",
4
+ "version": "0.13.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,24 +27,24 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@deepseek-ai/schemastery": "^3.18.1",
30
- "@lmzhen/dsh-evolution-approval": "^0.12.0",
31
- "@lmzhen/dsh-evolution-core": "^0.12.0"
30
+ "@lmzhen/dsh-evolution-approval": "^0.13.1",
31
+ "@lmzhen/dsh-evolution-core": "^0.13.1"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@deepseek-ai/cordis": "^4.0.1",
35
35
  "@deepseek-ai/dsh-skill": "^0.1.5-rc.2",
36
36
  "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
37
37
  "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
38
- "@lmzhen/dsh-evolution-io": "^0.12.0",
39
- "@lmzhen/dsh-skill-usage": "^0.12.0"
38
+ "@lmzhen/dsh-evolution-io": "^0.13.1",
39
+ "@lmzhen/dsh-skill-usage": "^0.13.1"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.5-rc.2",
43
43
  "@deepseek-ai/dsh-skill": "^0.1.5-rc.2",
44
44
  "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
45
45
  "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
46
- "@lmzhen/dsh-evolution-core": "^0.12.0",
47
- "@lmzhen/dsh-evolution-io": "^0.12.0",
48
- "@lmzhen/dsh-skill-usage": "^0.12.0"
46
+ "@lmzhen/dsh-evolution-core": "^0.13.1",
47
+ "@lmzhen/dsh-evolution-io": "^0.13.1",
48
+ "@lmzhen/dsh-skill-usage": "^0.13.1"
49
49
  }
50
50
  }