@lmzhen/dsh-evolution-maintenance 0.3.7 → 0.3.9
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/{probe-CrVeRJ6b.js → enrichment-DxCdaJaQ.js} +67 -2
- package/lib/index.js +16 -40
- package/lib/tools.js +7 -12
- package/lib/types/enrichment.d.ts +18 -0
- package/lib/types/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -1,4 +1,35 @@
|
|
|
1
|
-
import { HEALTH_STAMP_RE, computeDedupGroups, computePrefixClusters, duplicateHeadings, missingSupportPointers, narrowNameMatches, overlongLines } from "@lmzhen/dsh-evolution-core";
|
|
1
|
+
import { HEALTH_STAMP_RE, computeDedupGroups, computePrefixClusters, duplicateHeadings, missingSupportPointers, narrowNameMatches, overlongLines, parseFrontmatter, usageObserved } from "@lmzhen/dsh-evolution-core";
|
|
2
|
+
//#region lib/types/drift-scan.js
|
|
3
|
+
/**
|
|
4
|
+
* Skill-library snapshot assembly for drift scanning.
|
|
5
|
+
*
|
|
6
|
+
* `computeDriftSignals` (evolution-core) is a pure function over a plain
|
|
7
|
+
* snapshot; this module converts a SkillLibrary-like reader into that
|
|
8
|
+
* snapshot. Quality score and usage-window status are caller-provided —
|
|
9
|
+
* when absent they stay `undefined`, which the signal layer reports as
|
|
10
|
+
* `unknown` (never a fabricated verdict).
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Assemble drift snapshots from a library reader and optional enrichment.
|
|
14
|
+
* Missing enrichment stays `undefined` → signal layer reports `unknown`.
|
|
15
|
+
*/
|
|
16
|
+
async function snapshotFromLibrary(library, options = {}) {
|
|
17
|
+
const entries = await library.list();
|
|
18
|
+
const snapshots = [];
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
const body = await library.read(entry.name);
|
|
21
|
+
if (body === void 0 || body === null) continue;
|
|
22
|
+
snapshots.push({
|
|
23
|
+
name: entry.name,
|
|
24
|
+
body,
|
|
25
|
+
description: options.descriptions?.get(entry.name),
|
|
26
|
+
supportFiles: options.supportFiles?.get(entry.name),
|
|
27
|
+
quality: options.quality?.get(entry.name)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return snapshots;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
2
33
|
//#region lib/types/probe.js
|
|
3
34
|
/**
|
|
4
35
|
* Probe detail computation (011 Phase 3).
|
|
@@ -68,4 +99,38 @@ function computeProbe(signal, target, snapshots) {
|
|
|
68
99
|
}
|
|
69
100
|
}
|
|
70
101
|
//#endregion
|
|
71
|
-
|
|
102
|
+
//#region lib/types/enrichment.js
|
|
103
|
+
/**
|
|
104
|
+
* Enrichment maps shared by the full maintain scan and the `--facts` preview
|
|
105
|
+
* (v12) AND the maintenance_probe tool (0.3.9): one construction = the probe
|
|
106
|
+
* and the facts block can never disagree about descriptions, support files,
|
|
107
|
+
* or quality (the 0.3.8 review found the probe answering "description=missing"
|
|
108
|
+
* while the facts block measured real lengths — probe snapshots carried no
|
|
109
|
+
* enrichment at all).
|
|
110
|
+
*/
|
|
111
|
+
async function buildEnrichment(ctx, library) {
|
|
112
|
+
const skillUsage = ctx.get("skillUsage");
|
|
113
|
+
const usageMap = skillUsage?.report ? await skillUsage.report() : void 0;
|
|
114
|
+
const usageObservedValue = usageMap ? usageObserved(usageMap) : void 0;
|
|
115
|
+
const descriptions = /* @__PURE__ */ new Map();
|
|
116
|
+
const supportFiles = /* @__PURE__ */ new Map();
|
|
117
|
+
const quality = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const entry of await library.list()) {
|
|
119
|
+
const body = await library.read(entry.name);
|
|
120
|
+
if (body === null) continue;
|
|
121
|
+
const description = parseFrontmatter(body)?.frontmatter.description;
|
|
122
|
+
if (typeof description === "string" && description.trim().length > 0) descriptions.set(entry.name, description);
|
|
123
|
+
const files = await library.listSupportFiles(entry.name);
|
|
124
|
+
if (files.length > 0) supportFiles.set(entry.name, files);
|
|
125
|
+
const record = usageMap?.get(entry.name);
|
|
126
|
+
if (typeof record?.quality_score === "number") quality.set(entry.name, record.quality_score);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
descriptions,
|
|
130
|
+
supportFiles,
|
|
131
|
+
quality,
|
|
132
|
+
usageObservedValue
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { snapshotFromLibrary as i, PROBE_SIGNALS as n, computeProbe as r, buildEnrichment as t };
|
package/lib/index.js
CHANGED
|
@@ -1,37 +1,6 @@
|
|
|
1
|
-
import { n as computeProbe, t as
|
|
1
|
+
import { i as snapshotFromLibrary, n as PROBE_SIGNALS, r as computeProbe, t as buildEnrichment } from "./enrichment-DxCdaJaQ.js";
|
|
2
2
|
import { AUTHORING_DESCRIPTION_BAR, DEFAULT_HEALTH_THRESHOLDS, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, LOW_QUALITY_THRESHOLD, MAINTAIN_PROMPT, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, computeDriftSignals, findDriftSignal, redactSecrets, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
|
-
//#region lib/types/drift-scan.js
|
|
5
|
-
/**
|
|
6
|
-
* Skill-library snapshot assembly for drift scanning.
|
|
7
|
-
*
|
|
8
|
-
* `computeDriftSignals` (evolution-core) is a pure function over a plain
|
|
9
|
-
* snapshot; this module converts a SkillLibrary-like reader into that
|
|
10
|
-
* snapshot. Quality score and usage-window status are caller-provided —
|
|
11
|
-
* when absent they stay `undefined`, which the signal layer reports as
|
|
12
|
-
* `unknown` (never a fabricated verdict).
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Assemble drift snapshots from a library reader and optional enrichment.
|
|
16
|
-
* Missing enrichment stays `undefined` → signal layer reports `unknown`.
|
|
17
|
-
*/
|
|
18
|
-
async function snapshotFromLibrary(library, options = {}) {
|
|
19
|
-
const entries = await library.list();
|
|
20
|
-
const snapshots = [];
|
|
21
|
-
for (const entry of entries) {
|
|
22
|
-
const body = await library.read(entry.name);
|
|
23
|
-
if (body === void 0 || body === null) continue;
|
|
24
|
-
snapshots.push({
|
|
25
|
-
name: entry.name,
|
|
26
|
-
body,
|
|
27
|
-
description: options.descriptions?.get(entry.name),
|
|
28
|
-
supportFiles: options.supportFiles?.get(entry.name),
|
|
29
|
-
quality: options.quality?.get(entry.name)
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
return snapshots;
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
4
|
//#region lib/types/render-facts.js
|
|
36
5
|
/**
|
|
37
6
|
* Mechanical-facts rendering for the maintenance subagent (011 §6).
|
|
@@ -363,7 +332,7 @@ async function runMaintain(runtime, options = {}) {
|
|
|
363
332
|
const timeoutMs = options.timeoutMs ?? 12e4;
|
|
364
333
|
const agentOptions = { model: options.model ?? "deepseek-v4-pro" };
|
|
365
334
|
if (options.provider) agentOptions.provider = options.provider;
|
|
366
|
-
const
|
|
335
|
+
const runResult = await (await runtime.subagents.start("spawn", {
|
|
367
336
|
label: "dsh-evolution-maintain",
|
|
368
337
|
prompt: [{
|
|
369
338
|
type: "text",
|
|
@@ -423,11 +392,18 @@ async function runMaintain(runtime, options = {}) {
|
|
|
423
392
|
}
|
|
424
393
|
}
|
|
425
394
|
}
|
|
426
|
-
})).result
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
395
|
+
})).result;
|
|
396
|
+
const raw = runResult?.structured;
|
|
397
|
+
if (raw === void 0) {
|
|
398
|
+
if (runResult?.stopReason === "aborted") return {
|
|
399
|
+
ok: false,
|
|
400
|
+
error: "Maintenance scan was aborted (the run was cancelled before the subagent produced a plan) — retry when the session is idle; concurrent re-submission cancels the previous scan."
|
|
401
|
+
};
|
|
402
|
+
return {
|
|
403
|
+
ok: false,
|
|
404
|
+
error: "Maintain subagent returned no structured plan (the model did not emit the structured plan, or the run ended without one) — retry; if it repeats, raise --timeout or check the model output shape."
|
|
405
|
+
};
|
|
406
|
+
}
|
|
431
407
|
const validated = validateAndNormalizeMaintainPlan(raw, report, existingSignalIds(report));
|
|
432
408
|
if (!validated.ok) return {
|
|
433
409
|
ok: false,
|
|
@@ -446,9 +422,9 @@ async function runMaintain(runtime, options = {}) {
|
|
|
446
422
|
const message = error instanceof Error ? error.message : String(error);
|
|
447
423
|
return {
|
|
448
424
|
ok: false,
|
|
449
|
-
error: name === "AbortError" ? "Maintenance scan was aborted (
|
|
425
|
+
error: name === "AbortError" || /abort/i.test(`${String(name)} ${message}`) ? "Maintenance scan was aborted (cancellation or timeout) before a plan was produced — retry, or raise the timeout (evolution-commands maintainTimeoutMs) on a slow/large library." : `Maintenance scan failed: ${message}`
|
|
450
426
|
};
|
|
451
427
|
}
|
|
452
428
|
}
|
|
453
429
|
//#endregion
|
|
454
|
-
export { PROBE_SIGNALS, buildMaintainFacts, computeProbe, renderFacts, renderMaintainTemplate, runMaintain, snapshotFromLibrary, summarizeAssessment, validateAndNormalizeMaintainPlan };
|
|
430
|
+
export { PROBE_SIGNALS, buildEnrichment, buildMaintainFacts, computeProbe, renderFacts, renderMaintainTemplate, runMaintain, snapshotFromLibrary, summarizeAssessment, validateAndNormalizeMaintainPlan };
|
package/lib/tools.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as computeProbe, t as
|
|
1
|
+
import { i as snapshotFromLibrary, n as PROBE_SIGNALS, r as computeProbe, t as buildEnrichment } from "./enrichment-DxCdaJaQ.js";
|
|
2
2
|
import { SkillLibrary, redactSecrets } from "@lmzhen/dsh-evolution-core";
|
|
3
3
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
4
4
|
//#region lib/types/tools.js
|
|
@@ -59,17 +59,12 @@ function apply(ctx, rawConfig = {}) {
|
|
|
59
59
|
...target ? { target } : {}
|
|
60
60
|
};
|
|
61
61
|
const library = new SkillLibrary(config.skillsRoot, ioRegistry.provider());
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
name: entry.name,
|
|
69
|
-
body
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
const probe = computeProbe(signal, target, snapshots);
|
|
62
|
+
const enrichment = await buildEnrichment(ctx, library);
|
|
63
|
+
const probe = computeProbe(signal, target, await snapshotFromLibrary(library, {
|
|
64
|
+
descriptions: enrichment.descriptions,
|
|
65
|
+
supportFiles: enrichment.supportFiles,
|
|
66
|
+
quality: enrichment.quality
|
|
67
|
+
}));
|
|
73
68
|
const redacted = redactSecrets(probe.detail.join("\n"));
|
|
74
69
|
return {
|
|
75
70
|
...probe,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enrichment maps shared by the full maintain scan and the `--facts` preview
|
|
3
|
+
* (v12) AND the maintenance_probe tool (0.3.9): one construction = the probe
|
|
4
|
+
* and the facts block can never disagree about descriptions, support files,
|
|
5
|
+
* or quality (the 0.3.8 review found the probe answering "description=missing"
|
|
6
|
+
* while the facts block measured real lengths — probe snapshots carried no
|
|
7
|
+
* enrichment at all).
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
10
|
+
import { type SkillLibrary } from '@deepseek-ai/dsh-evolution-core';
|
|
11
|
+
export interface Enrichment {
|
|
12
|
+
descriptions: ReadonlyMap<string, string>;
|
|
13
|
+
supportFiles: ReadonlyMap<string, readonly string[]>;
|
|
14
|
+
quality: ReadonlyMap<string, number>;
|
|
15
|
+
usageObservedValue: boolean | undefined;
|
|
16
|
+
}
|
|
17
|
+
export declare function buildEnrichment(ctx: Context, library: SkillLibrary): Promise<Enrichment>;
|
|
18
|
+
//# sourceMappingURL=enrichment.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-maintenance",
|
|
3
3
|
"description": "Deterministic maintenance-scan surface: skill-library snapshot assembly, drift signals and mechanical-facts rendering (design 011) (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.9",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
37
|
+
"@lmzhen/dsh-evolution-core": "^0.3.9"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|