@lmzhen/dsh-evolution-curator 0.1.0-rc.25 → 0.1.0-rc.27
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 +64 -2
- package/lib/types/index.d.ts +15 -1
- package/package.json +7 -7
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { BlockAssembler, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
6
|
-
import { CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_STALE_AFTER_DAYS, SkillLibrary, buildCuratorRunReport, computeLifecycleTransitions, computeQualityScores, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, parseCuratorNominations, saveSuppressedNames, saveUsage } from "@lmzhen/dsh-evolution-core";
|
|
6
|
+
import { CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_STALE_AFTER_DAYS, SKILL_NAME_RE, SkillLibrary, buildCuratorRunReport, computeLifecycleTransitions, computeQualityScores, computeScopeView, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, parseCuratorNominations, parseFrontmatter, saveSuppressedNames, saveUsage } from "@lmzhen/dsh-evolution-core";
|
|
7
7
|
//#region lib/types/index.js
|
|
8
8
|
/**
|
|
9
9
|
* Deterministic skill lifecycle curator with interval gate and archive.
|
|
@@ -181,6 +181,22 @@ var EvolutionCurator = class extends Service {
|
|
|
181
181
|
report: this.skippedReport(runId, startedAt),
|
|
182
182
|
skipped: "active-session"
|
|
183
183
|
};
|
|
184
|
+
if (!ignoreGates && persisted === null) {
|
|
185
|
+
await stateService?.saveCuratorState({
|
|
186
|
+
schemaVersion: 1,
|
|
187
|
+
lastRunAt: Date.now(),
|
|
188
|
+
runCount: 0,
|
|
189
|
+
lastSummary: "first-run-deferred",
|
|
190
|
+
paused: false
|
|
191
|
+
});
|
|
192
|
+
return {
|
|
193
|
+
stale: [],
|
|
194
|
+
archived: [],
|
|
195
|
+
errors: [],
|
|
196
|
+
report: this.skippedReport(runId, startedAt),
|
|
197
|
+
skipped: "first-run-deferred"
|
|
198
|
+
};
|
|
199
|
+
}
|
|
184
200
|
const root = this.skills.root;
|
|
185
201
|
const rawUsage = await loadUsage(root, this.io);
|
|
186
202
|
const usage = dryRun ? new Map([...rawUsage].map(([name, record]) => [name, { ...record }])) : rawUsage;
|
|
@@ -270,6 +286,8 @@ var EvolutionCurator = class extends Service {
|
|
|
270
286
|
treeNames.add(summary.name);
|
|
271
287
|
if (!usage.has(summary.name)) usage.set(summary.name, emptyRecord());
|
|
272
288
|
if (await this.skills.isBundled(summary.name)) bundledNames.add(summary.name);
|
|
289
|
+
const record = usage.get(summary.name);
|
|
290
|
+
if (record) record.pinned = await this.skills.isPinned(summary.name);
|
|
273
291
|
}
|
|
274
292
|
return {
|
|
275
293
|
bundledNames,
|
|
@@ -284,7 +302,8 @@ var EvolutionCurator = class extends Service {
|
|
|
284
302
|
for (const name of treeNames) supportDirs.set(name, await this.skills.countSupportDirs(name));
|
|
285
303
|
const quality = computeQualityScores({
|
|
286
304
|
usage,
|
|
287
|
-
supportDirs
|
|
305
|
+
supportDirs,
|
|
306
|
+
referenceCounts: await this.referenceCounts(treeNames)
|
|
288
307
|
});
|
|
289
308
|
for (const [name, score] of quality) {
|
|
290
309
|
const record = usage.get(name);
|
|
@@ -295,6 +314,28 @@ var EvolutionCurator = class extends Service {
|
|
|
295
314
|
}
|
|
296
315
|
}
|
|
297
316
|
/**
|
|
317
|
+
* In-degree over explicit `related_skills` frontmatter references (the DSH
|
|
318
|
+
* equivalent of the graph-in-degree references factor): a skill listing
|
|
319
|
+
* other skill names counts as one reference to each of them, so hub skills
|
|
320
|
+
* that are explicitly named by peers get a non-zero references factor.
|
|
321
|
+
*/
|
|
322
|
+
async referenceCounts(treeNames) {
|
|
323
|
+
const counts = /* @__PURE__ */ new Map();
|
|
324
|
+
for (const name of treeNames) {
|
|
325
|
+
const content = await this.skills.read(name);
|
|
326
|
+
if (!content) continue;
|
|
327
|
+
const parsed = parseFrontmatter(content);
|
|
328
|
+
if (!parsed) continue;
|
|
329
|
+
const raw = parsed.frontmatter["related_skills"];
|
|
330
|
+
if (typeof raw !== "string") continue;
|
|
331
|
+
for (const match of Array.from(raw.matchAll(/[a-z0-9][a-z0-9-]*/g))) {
|
|
332
|
+
const target = match[0];
|
|
333
|
+
if (target && SKILL_NAME_RE.test(target) && target !== name) counts.set(target, (counts.get(target) ?? 0) + 1);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return counts;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
298
339
|
* Execute lifecycle archives and consolidation nominations, then persist the
|
|
299
340
|
* suppression and usage sidecars best-effort. A dry-run short-circuits: no
|
|
300
341
|
* file moves and no state persistence — the caller still writes the report.
|
|
@@ -394,6 +435,27 @@ var EvolutionCurator = class extends Service {
|
|
|
394
435
|
}
|
|
395
436
|
}
|
|
396
437
|
/**
|
|
438
|
+
* Read-only lifecycle scope classification: which skills are in scope,
|
|
439
|
+
* watched (stale/quality-warned), exempted, or protected. Uses the same
|
|
440
|
+
* candidate gate as `run()` (`computeScopeView` / `lifecycleCandidate`),
|
|
441
|
+
* so the view always predicts what a curator pass may touch.
|
|
442
|
+
*/
|
|
443
|
+
async scopeView() {
|
|
444
|
+
const root = this.skills.root;
|
|
445
|
+
const usage = await loadUsage(root, this.io);
|
|
446
|
+
const { bundledNames } = await this.seedBaseline(usage);
|
|
447
|
+
return computeScopeView(usage, {
|
|
448
|
+
staleAfterDays: this.lifecycle().staleAfterDays,
|
|
449
|
+
archiveAfterDays: this.lifecycle().archiveAfterDays,
|
|
450
|
+
excludeSkillNames: this.excludeSkillNames,
|
|
451
|
+
referencedSkillNames: this.referencedSkillNames,
|
|
452
|
+
suppressedNames: new Set(await loadSuppressedNames(root, this.io)),
|
|
453
|
+
manageUnmanaged: this.manageUnmanaged,
|
|
454
|
+
pruneBuiltins: this.pruneBuiltins,
|
|
455
|
+
bundledNames
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
397
459
|
* Control-plane consolidation: merge source skill bodies into `target`,
|
|
398
460
|
* archive the sources with an absorbed-into marker, and fold their usage
|
|
399
461
|
* records into `archived` state. Snapshot-then-mutate, never a hard delete.
|
package/lib/types/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
6
6
|
import type Schema from '@deepseek-ai/schemastery';
|
|
7
7
|
import { SkillLibrary } from '@deepseek-ai/dsh-evolution-core';
|
|
8
|
-
import { type CuratorNominations, type CuratorRunReport, type SkillActionResult } from '@deepseek-ai/dsh-evolution-core';
|
|
8
|
+
import { type CuratorNominations, type CuratorRunReport, type ScopeView, type SkillActionResult } from '@deepseek-ai/dsh-evolution-core';
|
|
9
9
|
declare module '@deepseek-ai/cordis' {
|
|
10
10
|
interface Context {
|
|
11
11
|
evolutionCurator: EvolutionCurator;
|
|
@@ -109,6 +109,13 @@ export declare class EvolutionCurator extends Service {
|
|
|
109
109
|
* F13 six-factor quality scoring, persisted onto the usage records.
|
|
110
110
|
*/
|
|
111
111
|
private scoreTree;
|
|
112
|
+
/**
|
|
113
|
+
* In-degree over explicit `related_skills` frontmatter references (the DSH
|
|
114
|
+
* equivalent of the graph-in-degree references factor): a skill listing
|
|
115
|
+
* other skill names counts as one reference to each of them, so hub skills
|
|
116
|
+
* that are explicitly named by peers get a non-zero references factor.
|
|
117
|
+
*/
|
|
118
|
+
private referenceCounts;
|
|
112
119
|
/**
|
|
113
120
|
* Execute lifecycle archives and consolidation nominations, then persist the
|
|
114
121
|
* suppression and usage sidecars best-effort. A dry-run short-circuits: no
|
|
@@ -117,6 +124,13 @@ export declare class EvolutionCurator extends Service {
|
|
|
117
124
|
private applyMutations;
|
|
118
125
|
private recentSessionActive;
|
|
119
126
|
latestReport(): Promise<CuratorRunReport | null>;
|
|
127
|
+
/**
|
|
128
|
+
* Read-only lifecycle scope classification: which skills are in scope,
|
|
129
|
+
* watched (stale/quality-warned), exempted, or protected. Uses the same
|
|
130
|
+
* candidate gate as `run()` (`computeScopeView` / `lifecycleCandidate`),
|
|
131
|
+
* so the view always predicts what a curator pass may touch.
|
|
132
|
+
*/
|
|
133
|
+
scopeView(): Promise<ScopeView>;
|
|
120
134
|
/**
|
|
121
135
|
* Control-plane consolidation: merge source skill bodies into `target`,
|
|
122
136
|
* archive the sources with an absorbed-into marker, and fold their usage
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-curator",
|
|
3
3
|
"description": "Deterministic skill lifecycle and recovery (community build)",
|
|
4
|
-
"version": "0.1.0-rc.
|
|
4
|
+
"version": "0.1.0-rc.27",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
36
|
-
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.
|
|
36
|
+
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.27"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
40
40
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
41
41
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
|
|
42
|
-
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.
|
|
43
|
-
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.
|
|
42
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.27",
|
|
43
|
+
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.27"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
47
47
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
|
|
48
|
-
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.
|
|
49
|
-
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.
|
|
50
|
-
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.
|
|
48
|
+
"@lmzhen/dsh-evolution-core": "^0.1.0-rc.27",
|
|
49
|
+
"@lmzhen/dsh-evolution-io": "^0.1.0-rc.27",
|
|
50
|
+
"@lmzhen/dsh-evolution-state": "^0.1.0-rc.27"
|
|
51
51
|
}
|
|
52
52
|
}
|