@lmzhen/dsh-tool-skill-manage 0.3.73 → 0.3.76

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
@@ -32,3 +32,5 @@ Mutations (create/edit/update/patch/delete/write_file/remove_file/restructure) p
32
32
 
33
33
 
34
34
  - No known durable consumer gaps at this time. Runtime contracts are covered by package and boundary tests.
35
+
36
+ **Runtime invariant:** No companion is published. The platform auto-assembles nothing and the family mounts no `<pkg>/invariant` cordis row, so a companion here would never execute (v37 S2.1 / I-3).
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { effectiveSessionPolicy } from "@lmzhen/dsh-evolution-approval";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { defineTool } from "@deepseek-ai/dsh-tools";
4
- import { DEFAULT_SKILL_LIMITS, DSH_AUTHORING_STANDARDS, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SkillLibrary, authoringFeedback, clampedNumber, computeDedupGroups, contentHash, evolutionIoAdapter, parseFrontmatter, resolveOrigins, resolveSkillsRoot } from "@lmzhen/dsh-evolution-core";
4
+ import { DEFAULT_SKILL_LIMITS, DSH_AUTHORING_STANDARDS, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, authoringFeedback, callingScope, clampedNumber, computeDedupGroups, contentHash, evolutionIoAdapter, isPresent, isReviewChannelSession, isUnknown, newSkillLibrary, parseFrontmatter, probePresent, probeUnknown, resolveOrigins } from "@lmzhen/dsh-evolution-core";
5
5
  //#region lib/types/index.js
6
6
  /**
7
7
  * Model-facing skill_manage tool over ctx.evolutionIo + ctx.skillUsage.
@@ -58,23 +58,30 @@ function apply(ctx, rawConfig = {}) {
58
58
  if (value !== void 0 && result !== value) numericClamped.push(name);
59
59
  return result;
60
60
  };
61
- const libraryOptions = {
62
- maxNameLength: limit("maxSkillNameLength", rawConfig.maxSkillNameLength, DEFAULT_SKILL_LIMITS.maxNameLength),
63
- maxDescriptionLength: limit("maxDescriptionLength", rawConfig.maxDescriptionLength, DEFAULT_SKILL_LIMITS.maxDescriptionLength),
64
- maxSkillContentChars: limit("maxSkillContentChars", rawConfig.maxSkillContentChars, DEFAULT_SKILL_LIMITS.maxSkillContentChars),
65
- maxSkillFileBytes: limit("maxSkillFileBytes", rawConfig.maxSkillFileBytes, DEFAULT_SKILL_LIMITS.maxSkillFileBytes)
66
- };
67
- const library = new SkillLibrary(resolveSkillsRoot(rawConfig), io, libraryOptions, (event) => {
68
- ctx.emit("evolution/skill-mutated", event);
69
- }, void 0, [...rawConfig.threatExemptLabels ?? []]);
61
+ const library = newSkillLibrary({
62
+ config: rawConfig,
63
+ io,
64
+ limits: {
65
+ maxNameLength: limit("maxSkillNameLength", rawConfig.maxSkillNameLength, DEFAULT_SKILL_LIMITS.maxNameLength),
66
+ maxDescriptionLength: limit("maxDescriptionLength", rawConfig.maxDescriptionLength, DEFAULT_SKILL_LIMITS.maxDescriptionLength),
67
+ maxSkillContentChars: limit("maxSkillContentChars", rawConfig.maxSkillContentChars, DEFAULT_SKILL_LIMITS.maxSkillContentChars),
68
+ maxSkillFileBytes: limit("maxSkillFileBytes", rawConfig.maxSkillFileBytes, DEFAULT_SKILL_LIMITS.maxSkillFileBytes)
69
+ },
70
+ ctx,
71
+ threatExemptLabels: rawConfig.threatExemptLabels
72
+ });
70
73
  if (numericClamped.length > 0) ctx.logger.warn(`tool-skill-manage: ${numericClamped.join(", ")} provided an invalid value; falling back to the default`);
74
+ let crossSourceViewWarned = false;
71
75
  const catalogWinner = async (name) => {
72
76
  const catalog = ctx.get("skills");
73
- if (catalog === void 0) return void 0;
77
+ if (catalog === void 0) return probeUnknown("the skills service is not mounted");
78
+ const scope = callingScope(ctx);
74
79
  try {
75
- return (await catalog.list()).find((summary) => summary.name === name);
76
- } catch {
77
- return;
80
+ const summaries = await catalog.list(scope === void 0 ? void 0 : { scope });
81
+ if (summaries.length === 0) return probeUnknown(`the catalog view is empty in the ${scope === void 0 ? "global" : "calling"} scope`);
82
+ return probePresent(summaries.find((summary) => summary.name === name));
83
+ } catch (error) {
84
+ return probeUnknown(`the catalog lookup failed (${error instanceof Error ? error.message : String(error)})`);
78
85
  }
79
86
  };
80
87
  async function executeCore(args, origin = "foreground") {
@@ -298,13 +305,24 @@ function apply(ctx, rawConfig = {}) {
298
305
  isConcurrencySafe: () => false,
299
306
  async execute(args, exec) {
300
307
  let operation = args;
301
- const origins = resolveOrigins(exec.agent?.session?.header.origin);
308
+ const origins = resolveOrigins(exec.agent?.session?.header.origin, isReviewChannelSession(exec.agent?.session?.id));
302
309
  const reviewOrigin = origins.approval;
303
310
  const libraryOrigin = origins.library;
304
311
  const sessionPolicy = effectiveSessionPolicy(ctx, exec.agent?.session);
305
312
  if (typeof args.name === "string" && args.name !== "" && args.action !== "list" && args.action !== "review" && args.action !== "pin" && args.action !== "unpin") {
306
- const winner = await catalogWinner(args.name);
307
- if (winner !== void 0 && winner.provider !== "dsh-evolution") {
313
+ const probe = await catalogWinner(args.name);
314
+ if (isUnknown(probe)) {
315
+ if (rawConfig.strictCrossSource === true) return {
316
+ ok: false,
317
+ message: `Refused: the cross-source check could not be performed — ${probe.reason}. Fix the catalog view (or drop strictCrossSource) before writing "${args.name}".`,
318
+ skills: []
319
+ };
320
+ if (!crossSourceViewWarned) {
321
+ crossSourceViewWarned = true;
322
+ ctx.logger.warn(`skill_manage: cross-source check skipped for this session — ${probe.reason}`);
323
+ }
324
+ } else if (isPresent(probe) && probe.value !== void 0 && probe.value.provider !== "dsh-evolution") {
325
+ const winner = probe.value;
308
326
  const message = `skill "${args.name}" resolves to a higher-priority "${winner.source}" skill (provider "${winner.provider}"); this write lands on the family copy, which the catalog does NOT serve — edit the "${winner.source}" copy or rename.`;
309
327
  if (rawConfig.strictCrossSource === true) return {
310
328
  ok: false,
@@ -317,10 +335,10 @@ function apply(ctx, rawConfig = {}) {
317
335
  const approval = ctx.get("evolutionApproval");
318
336
  if (approval && args.action !== "list" && args.action !== "review" && args.action !== "pin" && args.action !== "unpin") {
319
337
  if ((args.action === "update" || args.action === "edit") && typeof args.name === "string" && args.name !== "") {
320
- const stageCurrent = await library.read(args.name).catch(() => null);
321
- if (stageCurrent !== null) operation = {
338
+ const stageCurrent = await library.read(args.name).catch(() => void 0);
339
+ if (stageCurrent !== void 0) operation = {
322
340
  ...args,
323
- staged_from_sha256: contentHash(stageCurrent)
341
+ staged_from_sha256: stageCurrent === null ? "absent" : contentHash(stageCurrent)
324
342
  };
325
343
  }
326
344
  if ((args.action === "write_file" || args.action === "remove_file") && typeof args.name === "string" && args.name !== "" && typeof args.file_path === "string" && args.file_path !== "") {
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.3.73",
4
+ "version": "0.3.76",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -18,10 +18,6 @@
18
18
  "types": "./lib/types/index.d.ts",
19
19
  "default": "./lib/index.js"
20
20
  },
21
- "./invariant": {
22
- "types": "./lib/types/invariant.d.ts",
23
- "default": "./lib/invariant.js"
24
- },
25
21
  "./package.json": "./package.json"
26
22
  },
27
23
  "files": [
@@ -31,26 +27,24 @@
31
27
  "license": "MIT",
32
28
  "dependencies": {
33
29
  "@deepseek-ai/schemastery": "^3.18.1",
34
- "@lmzhen/dsh-evolution-approval": "^0.3.73",
35
- "@lmzhen/dsh-evolution-core": "^0.3.73"
30
+ "@lmzhen/dsh-evolution-approval": "^0.3.76",
31
+ "@lmzhen/dsh-evolution-core": "^0.3.76"
36
32
  },
37
33
  "peerDependencies": {
38
34
  "@deepseek-ai/cordis": "^4.0.1",
39
- "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2",
40
35
  "@deepseek-ai/dsh-skill": "^0.1.5-rc.2",
41
36
  "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
42
37
  "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
43
- "@lmzhen/dsh-evolution-io": "^0.3.73",
44
- "@lmzhen/dsh-skill-usage": "^0.3.73"
38
+ "@lmzhen/dsh-evolution-io": "^0.3.76",
39
+ "@lmzhen/dsh-skill-usage": "^0.3.76"
45
40
  },
46
41
  "devDependencies": {
47
42
  "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.5-rc.2",
48
- "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2",
49
43
  "@deepseek-ai/dsh-skill": "^0.1.5-rc.2",
50
44
  "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2",
51
45
  "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
52
- "@lmzhen/dsh-evolution-core": "^0.3.73",
53
- "@lmzhen/dsh-evolution-io": "^0.3.73",
54
- "@lmzhen/dsh-skill-usage": "^0.3.73"
46
+ "@lmzhen/dsh-evolution-core": "^0.3.76",
47
+ "@lmzhen/dsh-evolution-io": "^0.3.76",
48
+ "@lmzhen/dsh-skill-usage": "^0.3.76"
55
49
  }
56
50
  }
package/lib/invariant.js DELETED
@@ -1,8 +0,0 @@
1
- //#region lib/types/invariant.js
2
- const PACKAGE_NAME = "@lmzhen/dsh-tool-skill-manage";
3
- const name = "tool-skill-manage-invariant";
4
- const inject = ["invariants"];
5
- const install = () => {};
6
- const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
7
- //#endregion
8
- export { apply, inject, name };
@@ -1,5 +0,0 @@
1
- import type { Context } from '@deepseek-ai/cordis';
2
- export declare const name = "tool-skill-manage-invariant";
3
- export declare const inject: string[];
4
- export declare const apply: (ctx: Context) => Promise<() => void>;
5
- //# sourceMappingURL=invariant.d.ts.map