@lmzhen/dsh-evolution-commands 0.3.67 → 0.3.68
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 +18 -13
- package/lib/types/index.d.ts +3 -2
- package/package.json +7 -5
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { effectiveSessionPolicy } from "@lmzhen/dsh-evolution-approval";
|
|
4
4
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
5
|
-
import { SkillLibrary, appendEvolutionEvent, buildLearnPrompt, clampedNumber, composePresetComposition, eventsFile, evolutionRoot, resolveRootConfig, resolveSkillsRoot } from "@lmzhen/dsh-evolution-core";
|
|
5
|
+
import { MAX_TIMER_DELAY_MS, SkillLibrary, appendEvolutionEvent, assertSkillsRootAliasRetired, buildLearnPrompt, clampedNumber, composePresetComposition, eventsFile, evolutionRoot, resolveRootConfig, resolveSkillsRoot } from "@lmzhen/dsh-evolution-core";
|
|
6
6
|
import { buildEnrichment, buildMaintainFacts, runMaintain, snapshotFromLibrary } from "@lmzhen/dsh-evolution-maintenance";
|
|
7
7
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
@@ -69,7 +69,7 @@ async function diagnose(ctx, options = {}) {
|
|
|
69
69
|
if (full && host) conflicts.push("evolution-all and evolution-host are installed together — the infra rows double-mount and startup fails loud. Keep ONE: remove the other bundle.");
|
|
70
70
|
if (full && preset) conflicts.push("evolution-all and evolution-preset are installed together — the infra rows double-mount. Keep ONE.");
|
|
71
71
|
if (host && preset) conflicts.push("evolution-host and evolution-preset are installed together — the infra rows double-mount. Keep ONE.");
|
|
72
|
-
if (full &&
|
|
72
|
+
if (full && presetDirInstalled) conflicts.push("evolution-all and the layered Evolution preset are both present — the model rows double-mount. Keep ONE (use layered without all, or drop the preset).");
|
|
73
73
|
if (preset && presetDirInstalled) conflicts.push("evolution-preset and the layered Evolution preset are both present — the model rows double-mount (the preset bundle carries the same model rows as all). Keep ONE (drop the preset bundle, or remove the layered preset).");
|
|
74
74
|
const services = {
|
|
75
75
|
review: full || host || preset,
|
|
@@ -217,9 +217,8 @@ const Config = z.object({
|
|
|
217
217
|
});
|
|
218
218
|
function apply(ctx, rawConfig = {}) {
|
|
219
219
|
const config = rawConfig;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const skillsRootValue = rootConfig.root;
|
|
220
|
+
assertSkillsRootAliasRetired(rawConfig);
|
|
221
|
+
const skillsRootValue = resolveRootConfig(rawConfig).root;
|
|
223
222
|
let lastMaintainAt = 0;
|
|
224
223
|
let lastMaintainRunId = "";
|
|
225
224
|
let maintainInFlightSince = 0;
|
|
@@ -231,7 +230,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
231
230
|
recordInput: false,
|
|
232
231
|
input: { hint: renderHint() },
|
|
233
232
|
async handler(invocation) {
|
|
234
|
-
const rawInputTrimmed = invocation.rawInput
|
|
233
|
+
const rawInputTrimmed = invocation.rawInput.trim();
|
|
235
234
|
const input = rawInputTrimmed.replace(/\s+/g, " ");
|
|
236
235
|
const ok = (text) => ({
|
|
237
236
|
kind: "success",
|
|
@@ -385,7 +384,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
385
384
|
}
|
|
386
385
|
if (input === "learn" || input.startsWith("learn ")) {
|
|
387
386
|
const request = rawInputTrimmed === "learn" ? "" : rawInputTrimmed.slice(6).trim();
|
|
388
|
-
|
|
387
|
+
const message = createUserMessage({
|
|
389
388
|
content: [{
|
|
390
389
|
type: "text",
|
|
391
390
|
text: buildLearnPrompt(request)
|
|
@@ -396,7 +395,11 @@ function apply(ctx, rawConfig = {}) {
|
|
|
396
395
|
form: "notice",
|
|
397
396
|
summary: "learn request"
|
|
398
397
|
}
|
|
399
|
-
})
|
|
398
|
+
});
|
|
399
|
+
const followup = invocation.agent.followup;
|
|
400
|
+
const woke = typeof followup === "function";
|
|
401
|
+
if (woke) followup(message);
|
|
402
|
+
else invocation.agent.inject(message);
|
|
400
403
|
const eventIo = ctx.get("evolutionIo")?.provider();
|
|
401
404
|
if (eventIo) appendEvolutionEvent(eventIo, eventsFile(evolutionRoot()), {
|
|
402
405
|
type: "learn",
|
|
@@ -405,7 +408,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
405
408
|
}).catch((error) => {
|
|
406
409
|
ctx.logger.warn(`evolution-commands: failed to record learn event: ${String(error)}`);
|
|
407
410
|
});
|
|
408
|
-
return ok("Learning request sent to this session. Follow it now.");
|
|
411
|
+
return woke ? ok("Learning request sent to this session. Follow it now.") : ok("Learning request queued for this session — this host exposes no wake-up channel, so it is read on your next message.");
|
|
409
412
|
}
|
|
410
413
|
if (input === "maintain --facts") {
|
|
411
414
|
const ioRegistry = ctx.get("evolutionIo");
|
|
@@ -424,7 +427,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
424
427
|
const maintainArgs = /^maintain(?:\s+--timeout[ =](\d+))?\s*$/.exec(input);
|
|
425
428
|
if (maintainArgs) {
|
|
426
429
|
const runTimeoutMs = maintainArgs[1] ? Number(maintainArgs[1]) : config.maintainTimeoutMs ?? 6e5;
|
|
427
|
-
if (!Number.isSafeInteger(runTimeoutMs) || runTimeoutMs <= 0 || runTimeoutMs >
|
|
430
|
+
if (!Number.isSafeInteger(runTimeoutMs) || runTimeoutMs <= 0 || runTimeoutMs > MAX_TIMER_DELAY_MS) return err(maintainArgs[1] ? `Invalid --timeout value: expected a positive integer number of milliseconds up to ${MAX_TIMER_DELAY_MS} (e.g. /evolution maintain --timeout 600000).` : `The maintainTimeoutMs config is invalid: expected a positive integer number of milliseconds up to ${MAX_TIMER_DELAY_MS}. Fix the evolution-commands row config (maintainTimeoutMs), then retry.`);
|
|
428
431
|
if (maintainInFlightSince > 0) return err(`Maintenance scan is already running (since ~${Math.max(1, Math.round((Date.now() - maintainInFlightSince) / 1e3))}s ago) — re-submitting now would cancel it. Wait for it to settle; the result appears when it finishes.`);
|
|
429
432
|
const cooldownMs = clampedNumber(config.maintainCooldownMs, 3e4, { min: 0 });
|
|
430
433
|
const sinceLast = Date.now() - lastMaintainAt;
|
|
@@ -445,7 +448,9 @@ function apply(ctx, rawConfig = {}) {
|
|
|
445
448
|
tools: { get: (name) => ctx.get("tools")?.get(name) },
|
|
446
449
|
logger: { warn: (message) => {
|
|
447
450
|
ctx.logger.warn(message);
|
|
448
|
-
} }
|
|
451
|
+
} },
|
|
452
|
+
rootExists: () => ioRegistry.provider().exists(skillsRootValue),
|
|
453
|
+
skillRoot: skillsRootValue
|
|
449
454
|
}, {
|
|
450
455
|
timeoutMs: runTimeoutMs,
|
|
451
456
|
signal: invocation.signal,
|
|
@@ -533,8 +538,8 @@ function apply(ctx, rawConfig = {}) {
|
|
|
533
538
|
libraryOrigin: "foreground"
|
|
534
539
|
},
|
|
535
540
|
origin: "foreground",
|
|
536
|
-
...session
|
|
537
|
-
|
|
541
|
+
...session.id ? { sessionId: session.id } : {},
|
|
542
|
+
session,
|
|
538
543
|
...sessionPolicy !== void 0 ? { sessionPolicy } : {}
|
|
539
544
|
});
|
|
540
545
|
if (decision.action === "staged") return ok(`${decision.message}${planRunId ? `\n[audit] plan=${planRunId}` : ""}`);
|
package/lib/types/index.d.ts
CHANGED
|
@@ -11,8 +11,9 @@ export interface Config {
|
|
|
11
11
|
* resolved through resolveSkillsRoot() so an empty/whitespace value falls
|
|
12
12
|
* back to the default instead of a CWD-relative root. */
|
|
13
13
|
root?: string | undefined;
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
14
|
+
/** V27 G2.4 (M-08): RETIRED alias of `root`. The field stays declared so the
|
|
15
|
+
* loader can hand it to the load-time gate (which rejects it loudly) instead
|
|
16
|
+
* of dropping it silently; the plugin never reads it as a root. */
|
|
16
17
|
skillsRoot?: string | undefined;
|
|
17
18
|
/** Cooldown window for scan commands (ms) — misclick/rapid-trigger guard;
|
|
18
19
|
* secondary calls inside the window return the previous runId instead of
|
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.3.
|
|
4
|
+
"version": "0.3.68",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,19 +31,21 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
34
|
-
"@lmzhen/dsh-evolution-approval": "^0.3.
|
|
35
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
36
|
-
"@lmzhen/dsh-evolution-maintenance": "^0.3.
|
|
34
|
+
"@lmzhen/dsh-evolution-approval": "^0.3.68",
|
|
35
|
+
"@lmzhen/dsh-evolution-core": "^0.3.68",
|
|
36
|
+
"@lmzhen/dsh-evolution-maintenance": "^0.3.68"
|
|
37
37
|
},
|
|
38
38
|
"optionalDependencies": {
|
|
39
|
-
"@lmzhen/dsh-evolution-agent-preset": "^0.3.
|
|
39
|
+
"@lmzhen/dsh-evolution-agent-preset": "^0.3.68"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
43
|
+
"@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
|
|
43
44
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
44
45
|
"@deepseek-ai/dsh-llm": "^0.1.1-rc.2"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
48
|
+
"@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
|
|
47
49
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2"
|
|
48
50
|
}
|
|
49
51
|
}
|