@lmzhen/dsh-tool-skill-manage 0.15.2 → 0.16.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 +88 -3
- package/package.json +8 -8
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_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DSH_AUTHORING_STANDARDS, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, authoringFeedback, callingScope, clampedNumber, computeDedupGroups, contentHash, errorText, evolutionIoAdapter, installParamSection, isPresent, isUnknown, isUnreadWrite, nearDuplicateSummaries, newSkillLibrary, paramNamespace, parseFrontmatter, policyStageLimits, probePresent, probeUnknown, readNumberParam, resolveExecOrigins, sessionReadSkillNames } from "@lmzhen/dsh-evolution-core";
|
|
4
|
+
import { DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DSH_AUTHORING_STANDARDS, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, anchorVerdict, authoringFeedback, callingScope, clampedNumber, computeDedupGroups, contentHash, errorText, evolutionIoAdapter, fuzzyPatch, installParamSection, isPresent, isUnknown, isUnreadWrite, nearDuplicateSummaries, newSkillLibrary, normalizeFrontmatter, paramNamespace, parseFrontmatter, policyStageLimits, probePresent, probeUnknown, readNumberParam, resolveExecOrigins, sessionReadSkillNames } from "@lmzhen/dsh-evolution-core";
|
|
5
5
|
//#region lib/types/write-gates.js
|
|
6
6
|
/**
|
|
7
7
|
* The write-admission sequence: ONE ordered table of the reasons a skill write is refused.
|
|
@@ -295,6 +295,89 @@ const SKILL_SETTINGS_CAPS = [
|
|
|
295
295
|
function validateSkillSettings(value, ceilings) {
|
|
296
296
|
for (const key of SKILL_SETTINGS_CAPS) if (value[key] > ceilings[key]) throw new Error(`${key} may only be tightened: ${value[key]} exceeds the deployment value ${ceilings[key]}`);
|
|
297
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* What the staged skill write WOULD store, resolved WITHOUT writing.
|
|
300
|
+
*
|
|
301
|
+
* It lives here because this module owns what a skill operation MEANS: the bytes come from the same
|
|
302
|
+
* helpers the write path uses (`normalizeFrontmatter`, `fuzzyPatch`, the `trimEnd() + '\n'` trailing
|
|
303
|
+
* rule the library commits with), and the stage-time anchor is judged by core's own `anchorVerdict`, so
|
|
304
|
+
* the preview cannot advertise bytes the approve path then refuses. Everything it cannot resolve is an
|
|
305
|
+
* answer with a reason — never a guess and never a partial diff.
|
|
306
|
+
* @param library - the family skill library (reads only).
|
|
307
|
+
* @param args - the staged record's args: `{ operation }`.
|
|
308
|
+
* @returns the before/after pair, or why there is none to show.
|
|
309
|
+
*/
|
|
310
|
+
async function previewSkillWrite(library, args) {
|
|
311
|
+
const operation = (args ?? {}).operation ?? {};
|
|
312
|
+
const name = typeof operation.name === "string" ? operation.name.trim() : "";
|
|
313
|
+
if (name === "") return {
|
|
314
|
+
available: false,
|
|
315
|
+
reason: "the staged write names no skill"
|
|
316
|
+
};
|
|
317
|
+
const filePath = typeof operation.file_path === "string" && operation.file_path !== "" ? operation.file_path : null;
|
|
318
|
+
const path = filePath ?? "SKILL.md";
|
|
319
|
+
const before = await (filePath === null ? library.read(name) : library.readSupportFile(name, filePath)).catch(() => null);
|
|
320
|
+
const staged = operation.staged_from_sha256;
|
|
321
|
+
if (anchorVerdict(typeof staged === "string" && staged !== "" ? staged === "absent" ? { absent: true } : { sha256: staged } : void 0, before) !== "match") return {
|
|
322
|
+
available: false,
|
|
323
|
+
reason: "the target changed after this write was staged — approving it would be refused"
|
|
324
|
+
};
|
|
325
|
+
const action = typeof operation.action === "string" ? operation.action : "";
|
|
326
|
+
/** The bytes the write path commits for a body: frontmatter normalized, one trailing newline. */
|
|
327
|
+
const bodyOnDisk = (content) => {
|
|
328
|
+
const norm = normalizeFrontmatter(content);
|
|
329
|
+
if (norm.issues.length > 0) return {
|
|
330
|
+
available: false,
|
|
331
|
+
reason: "frontmatter cannot be auto-fixed: " + norm.issues.join("; ")
|
|
332
|
+
};
|
|
333
|
+
return {
|
|
334
|
+
available: true,
|
|
335
|
+
path,
|
|
336
|
+
before,
|
|
337
|
+
after: (norm.changed ? norm.content : content).trimEnd() + "\n"
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
if (action === "create" || action === "update") return typeof operation.content === "string" ? bodyOnDisk(operation.content) : {
|
|
341
|
+
available: false,
|
|
342
|
+
reason: "\"" + action + "\" carries no content"
|
|
343
|
+
};
|
|
344
|
+
if (action === "patch") {
|
|
345
|
+
if (before === null) return {
|
|
346
|
+
available: false,
|
|
347
|
+
reason: "the skill has no body to patch"
|
|
348
|
+
};
|
|
349
|
+
const patched = fuzzyPatch(before, operation.old_string ?? "", operation.new_string ?? "", operation.replace_all === true);
|
|
350
|
+
return patched === null ? {
|
|
351
|
+
available: false,
|
|
352
|
+
reason: "the staged old text is not in the current body — approving it would be refused"
|
|
353
|
+
} : bodyOnDisk(patched);
|
|
354
|
+
}
|
|
355
|
+
if (action === "write_file") {
|
|
356
|
+
if (typeof operation.file_content !== "string") return {
|
|
357
|
+
available: false,
|
|
358
|
+
reason: "\"write_file\" carries no content"
|
|
359
|
+
};
|
|
360
|
+
return {
|
|
361
|
+
available: true,
|
|
362
|
+
path,
|
|
363
|
+
before,
|
|
364
|
+
after: operation.file_content
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
if (action === "remove_file") return before === null ? {
|
|
368
|
+
available: false,
|
|
369
|
+
reason: "that support file is not there to remove"
|
|
370
|
+
} : {
|
|
371
|
+
available: true,
|
|
372
|
+
path,
|
|
373
|
+
before,
|
|
374
|
+
after: null
|
|
375
|
+
};
|
|
376
|
+
return {
|
|
377
|
+
available: false,
|
|
378
|
+
reason: "\"" + action + "\" has no byte-level preview"
|
|
379
|
+
};
|
|
380
|
+
}
|
|
298
381
|
/** One abort signal that carries BOTH cancellations: the call's own (the operator cancelled the
|
|
299
382
|
* turn) and the gate's deadline (`skillWriteConfirm: 'timeout'`). `undefined` when neither exists —
|
|
300
383
|
* the platform's `ask()` then waits without a signal, which is the `ask` mode.
|
|
@@ -874,7 +957,9 @@ function apply(ctx, rawConfig = {}) {
|
|
|
874
957
|
}
|
|
875
958
|
}));
|
|
876
959
|
ctx.inject(["evolutionApproval"], (approvalCtx) => {
|
|
877
|
-
const
|
|
960
|
+
const approval = approvalCtx.evolutionApproval;
|
|
961
|
+
const preview = async (args) => await previewSkillWrite(library, args);
|
|
962
|
+
const dispose = approval.registerRunner("skill", (args) => {
|
|
878
963
|
const wrapped = args ?? {};
|
|
879
964
|
const operation = wrapped.operation ?? {};
|
|
880
965
|
const replayAction = operation.action;
|
|
@@ -887,7 +972,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
887
972
|
return executeCore(operation, wrapped.libraryOrigin ?? wrapped.origin ?? "background_review");
|
|
888
973
|
});
|
|
889
974
|
return executeCore(operation, wrapped.libraryOrigin ?? wrapped.origin ?? "background_review");
|
|
890
|
-
});
|
|
975
|
+
}, preview);
|
|
891
976
|
approvalCtx.effect(() => dispose, "tool-skill-manage.approval-runner");
|
|
892
977
|
});
|
|
893
978
|
}
|
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.
|
|
4
|
+
"version": "0.16.0",
|
|
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.
|
|
31
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
30
|
+
"@lmzhen/dsh-evolution-approval": "^0.16.0",
|
|
31
|
+
"@lmzhen/dsh-evolution-core": "^0.16.0"
|
|
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.
|
|
39
|
-
"@lmzhen/dsh-skill-usage": "^0.
|
|
38
|
+
"@lmzhen/dsh-evolution-io": "^0.16.0",
|
|
39
|
+
"@lmzhen/dsh-skill-usage": "^0.16.0"
|
|
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.
|
|
47
|
-
"@lmzhen/dsh-evolution-io": "^0.
|
|
48
|
-
"@lmzhen/dsh-skill-usage": "^0.
|
|
46
|
+
"@lmzhen/dsh-evolution-core": "^0.16.0",
|
|
47
|
+
"@lmzhen/dsh-evolution-io": "^0.16.0",
|
|
48
|
+
"@lmzhen/dsh-skill-usage": "^0.16.0"
|
|
49
49
|
}
|
|
50
50
|
}
|