@lmzhen/dsh-evolution-commands 0.30.31 → 0.30.36
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 +120 -2
- package/package.json +5 -5
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { DEFAULT_SKILL_LIMITS, DIAGNOSTICS_FACT_KEYS, DIAGNOSTICS_RUNTIME_KEYS, DIAGNOSTICS_VIEW_SCHEMA_VERSION, EVOLUTION_PRESET_IDS, MAINTAINER_PRESET_ID, MAX_TIMER_DELAY_MS, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PLATFORM_LINE, REVIEWER_PRESET_ID, absentHostServices, appendEvolutionEvent, applyNamespaceMigration, asRecord, assertSkillsRootAliasRetired, atomicWriteFiles, authorityFrom, buildLearnPrompt, canonicalWriteId, clampedNumber, classifyNamespaceMigration, classifySessionEvent, createSubagentChannel, elapsedSince, errorText, eventsFile, evolutionHome, evolutionRoot, hostSurface, isDeprecatedParamId, isPresent, isRecord, isUnknown, liveBool, newRunRegistry, newSkillLibrary, paramSettingsId, partitionVersions, planNamespaceMigration, policyStageLimits, probeMtime, probeText, reportsSweepLockTarget, resolveParamId, resolveRootConfig, scopedPackageName, scopedProbeReport, sweepReports, transactIo } from "@lmzhen/dsh-evolution-core";
|
|
2
|
+
import { DEFAULT_SKILL_LIMITS, DIAGNOSTICS_FACT_KEYS, DIAGNOSTICS_RUNTIME_KEYS, DIAGNOSTICS_VIEW_SCHEMA_VERSION, EVOLUTION_PRESET_IDS, MAINTAINER_PRESET_ID, MAX_TIMER_DELAY_MS, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PLATFORM_LINE, REVIEWER_PRESET_ID, absentHostServices, appendEvolutionEvent, applyNamespaceMigration, asRecord, assertSkillsRootAliasRetired, atomicWriteFiles, authorityFrom, buildLearnPrompt, canonicalWriteId, clampedNumber, classifyNamespaceMigration, classifySessionEvent, contentHash, createSubagentChannel, elapsedSince, errorText, eventsFile, evolutionHome, evolutionRoot, findOwnerCandidate, hostSurface, isDeprecatedParamId, isPresent, isRecord, isUnknown, liveBool, newRunRegistry, newSkillLibrary, ownerCandidatesFromSummaries, paramSettingsId, parseFrontmatter, partitionVersions, planExtract, planNamespaceMigration, policyStageLimits, probeMtime, probeText, proposalFromPlan, readExternalSupport, reportsSweepLockTarget, resolveParamId, resolveRootConfig, scopedPackageName, scopedProbeReport, sweepReports, transactIo, writeProposalReport } from "@lmzhen/dsh-evolution-core";
|
|
3
3
|
import { HOST_ROUTES, json, methodNotAllowed, registerHostRoutes } from "@lmzhen/dsh-evolution-core/http-routes";
|
|
4
4
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
@@ -2061,6 +2061,11 @@ const COMMAND_ENTRIES = [
|
|
|
2061
2061
|
usage: "restructure <name> \"<heading>\" <to_file> [--plan <runId>]",
|
|
2062
2062
|
summary: "把技能正文的一节移到 references 文件"
|
|
2063
2063
|
},
|
|
2064
|
+
{
|
|
2065
|
+
readonly: false,
|
|
2066
|
+
usage: "extract <source> <target> \"<heading>\" [--start <line>] [--end <line>] [--plan <runId>]",
|
|
2067
|
+
summary: "把源技能的可复用部分提取到已有类级 owner(多根一次事务)"
|
|
2068
|
+
},
|
|
2064
2069
|
{
|
|
2065
2070
|
readonly: true,
|
|
2066
2071
|
usage: "replay",
|
|
@@ -2107,7 +2112,9 @@ const VALUE_FLAGS = [
|
|
|
2107
2112
|
"base",
|
|
2108
2113
|
"to",
|
|
2109
2114
|
"timeout",
|
|
2110
|
-
"plan"
|
|
2115
|
+
"plan",
|
|
2116
|
+
"start",
|
|
2117
|
+
"end"
|
|
2111
2118
|
];
|
|
2112
2119
|
/**
|
|
2113
2120
|
* Narrow a parse result: true when it is the syntax failure rather than a command.
|
|
@@ -3152,6 +3159,117 @@ function apply(ctx, rawConfig = {}) {
|
|
|
3152
3159
|
return err(`预设安装失败:${error instanceof Error ? error.message : String(error)}`);
|
|
3153
3160
|
}
|
|
3154
3161
|
}
|
|
3162
|
+
if (input.startsWith("extract ")) {
|
|
3163
|
+
const extractParsed = parseSubcommand(rawInputTrimmed);
|
|
3164
|
+
if (isParseFailure(extractParsed) || extractParsed.name !== "extract") return err("用法:/evolution extract <source> <target> \"<## heading>\" [--start <line>] [--end <line>]");
|
|
3165
|
+
const source = extractParsed.positionals[0] ?? "";
|
|
3166
|
+
const target = extractParsed.positionals[1] ?? "";
|
|
3167
|
+
const heading = extractParsed.positionals[2] ?? "";
|
|
3168
|
+
if (source === "" || target === "" || heading === "") return err("用法:/evolution extract <source> <target> \"<## heading>\" [--start <line>] [--end <line>]");
|
|
3169
|
+
const startFlag = extractParsed.flags.get("start");
|
|
3170
|
+
const endFlag = extractParsed.flags.get("end");
|
|
3171
|
+
const start = typeof startFlag === "string" ? startFlag : void 0;
|
|
3172
|
+
const end = typeof endFlag === "string" ? endFlag : void 0;
|
|
3173
|
+
const ioRegistry = ctx.get("evolutionIo");
|
|
3174
|
+
if (!ioRegistry) return err("未挂载 evolution-io 注册表:无法执行 extract。");
|
|
3175
|
+
const library = newSkillLibrary({
|
|
3176
|
+
authority: authorityFrom({ origin: "foreground" }),
|
|
3177
|
+
config: { root: skillsRootValue },
|
|
3178
|
+
io: ioRegistry.provider(),
|
|
3179
|
+
ctx,
|
|
3180
|
+
threatExemptLabels: config.threatExemptLabels,
|
|
3181
|
+
limits: {
|
|
3182
|
+
...DEFAULT_SKILL_LIMITS,
|
|
3183
|
+
...policyStageLimits(ctx.get("evolutionPolicy")?.get?.())
|
|
3184
|
+
}
|
|
3185
|
+
});
|
|
3186
|
+
const sourceMd = await library.read(source);
|
|
3187
|
+
const targetMd = await library.read(target);
|
|
3188
|
+
if (sourceMd === null) return err("技能「" + source + "」不存在。");
|
|
3189
|
+
if (targetMd === null) return err("目标技能「" + target + "」不存在;owner-gap 不自动 create。");
|
|
3190
|
+
if (source === target) return err("source 与 target 不能相同。");
|
|
3191
|
+
const candidate = findOwnerCandidate(ownerCandidatesFromSummaries(source, await library.list({
|
|
3192
|
+
withContent: true,
|
|
3193
|
+
withFrontmatter: true
|
|
3194
|
+
})), target);
|
|
3195
|
+
if (candidate === void 0) return err("目标「" + target + "」不是可用的 owner candidate(描述为空或已排除);owner-gap,不自动 create。");
|
|
3196
|
+
if (candidate.protectionUnknown || candidate.protectedBy !== null) return err("目标「" + target + "」受保护(" + (candidate.protectedBy ?? "未知") + "),拒绝提取。");
|
|
3197
|
+
const sourceParsed = parseFrontmatter(sourceMd);
|
|
3198
|
+
if (sourceParsed === null) return err("技能「" + source + "」没有可读取的正文。");
|
|
3199
|
+
const sourceFiles = await library.listSupportFiles(source);
|
|
3200
|
+
const targetFiles = await library.listSupportFiles(target);
|
|
3201
|
+
if (!isPresent(sourceFiles) || !isPresent(targetFiles)) return err("支撑文件列表不可读;拒绝在不确定的闭包上提取。");
|
|
3202
|
+
const external = await readExternalSupport(sourceParsed.body, join(library.root, source), dirname(library.root), targetFiles.value);
|
|
3203
|
+
if (!external.ok) return err(external.message);
|
|
3204
|
+
const plan = planExtract({
|
|
3205
|
+
body: sourceParsed.body,
|
|
3206
|
+
sourceName: source,
|
|
3207
|
+
targetName: target,
|
|
3208
|
+
targetExists: true,
|
|
3209
|
+
outcome: start !== void 0 || end !== void 0 ? "mixed" : "extract",
|
|
3210
|
+
owner: {
|
|
3211
|
+
mode: "covered",
|
|
3212
|
+
name: target,
|
|
3213
|
+
triggerCovers: true,
|
|
3214
|
+
outcomeCovers: true,
|
|
3215
|
+
reason: "explicit target"
|
|
3216
|
+
},
|
|
3217
|
+
requests: [{
|
|
3218
|
+
heading,
|
|
3219
|
+
...start === void 0 ? {} : { start },
|
|
3220
|
+
...end === void 0 ? {} : { end }
|
|
3221
|
+
}],
|
|
3222
|
+
sourceFiles: sourceFiles.value,
|
|
3223
|
+
targetFiles: targetFiles.value,
|
|
3224
|
+
external: external.files,
|
|
3225
|
+
anchors: {
|
|
3226
|
+
sourceMdSha256: contentHash(sourceMd),
|
|
3227
|
+
targetMdSha256: contentHash(targetMd)
|
|
3228
|
+
}
|
|
3229
|
+
});
|
|
3230
|
+
if (!plan.ok) return err(plan.message);
|
|
3231
|
+
if (extractParsed.flags.has("plan")) {
|
|
3232
|
+
const proposal = proposalFromPlan(plan.plan, { runId: "cli-" + Date.now().toString(36) });
|
|
3233
|
+
const io = ctx.get("evolutionIo")?.provider();
|
|
3234
|
+
if (io !== void 0) await writeProposalReport(io, proposal).catch(() => {});
|
|
3235
|
+
return ok("提取计划(未写入):" + plan.plan.parts.map((part) => "## " + part.heading).join(", ") + " -> " + target);
|
|
3236
|
+
}
|
|
3237
|
+
if (approval) {
|
|
3238
|
+
const session = invocationAgent?.session;
|
|
3239
|
+
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
3240
|
+
const stagesForeground = approval.isEnabled !== false && sessionPolicy !== "never" && approval.stageForeground !== false;
|
|
3241
|
+
if (stagesForeground && session === void 0) return err(errorText("e-306-this-deployment-stages-foreground-2"));
|
|
3242
|
+
if (stagesForeground && !approval.hasRunner("skill")) return err("无法暂存提取:没有注册技能回放运行器:请挂载 tool-skill-manage 行,或禁用 evolution-approval。");
|
|
3243
|
+
const decision = await approval.request({
|
|
3244
|
+
kind: "skill",
|
|
3245
|
+
summary: "/evolution extract " + source + " -> " + target + " " + heading,
|
|
3246
|
+
args: {
|
|
3247
|
+
operation: {
|
|
3248
|
+
action: "extract",
|
|
3249
|
+
name: source,
|
|
3250
|
+
extract: [{
|
|
3251
|
+
heading,
|
|
3252
|
+
...start === void 0 ? {} : { start },
|
|
3253
|
+
...end === void 0 ? {} : { end },
|
|
3254
|
+
to_skill: target
|
|
3255
|
+
}]
|
|
3256
|
+
},
|
|
3257
|
+
origin: "foreground",
|
|
3258
|
+
libraryOrigin: "foreground"
|
|
3259
|
+
},
|
|
3260
|
+
origin: "foreground",
|
|
3261
|
+
...session !== void 0 ? {
|
|
3262
|
+
sessionId: session.id,
|
|
3263
|
+
session
|
|
3264
|
+
} : {},
|
|
3265
|
+
...sessionPolicy !== void 0 ? { sessionPolicy } : {}
|
|
3266
|
+
});
|
|
3267
|
+
if (decision.action === "staged") return ok(decision.message);
|
|
3268
|
+
}
|
|
3269
|
+
const result = await library.extract(plan.plan, "foreground");
|
|
3270
|
+
if (!result.ok) return err(result.message);
|
|
3271
|
+
return ok(result.message);
|
|
3272
|
+
}
|
|
3155
3273
|
if (input.startsWith("restructure ")) {
|
|
3156
3274
|
const restParsed = parseSubcommand(rawInputTrimmed);
|
|
3157
3275
|
if (isParseFailure(restParsed) || restParsed.name !== "restructure") return err("用法:/evolution restructure <name> \"<## heading>\" <to_file>");
|
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.30.
|
|
4
|
+
"version": "0.30.36",
|
|
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.30.
|
|
31
|
-
"@lmzhen/dsh-evolution-core": "^0.30.
|
|
32
|
-
"@lmzhen/dsh-evolution-maintenance": "^0.30.
|
|
30
|
+
"@lmzhen/dsh-evolution-approval": "^0.30.36",
|
|
31
|
+
"@lmzhen/dsh-evolution-core": "^0.30.36",
|
|
32
|
+
"@lmzhen/dsh-evolution-maintenance": "^0.30.36"
|
|
33
33
|
},
|
|
34
34
|
"optionalDependencies": {
|
|
35
|
-
"@lmzhen/dsh-evolution-agent-preset": "^0.30.
|
|
35
|
+
"@lmzhen/dsh-evolution-agent-preset": "^0.30.36"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.5",
|