@lmzhen/dsh-evolution-curator 0.1.0-rc.25 → 0.1.0-rc.26

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 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, 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;
@@ -284,7 +300,8 @@ var EvolutionCurator = class extends Service {
284
300
  for (const name of treeNames) supportDirs.set(name, await this.skills.countSupportDirs(name));
285
301
  const quality = computeQualityScores({
286
302
  usage,
287
- supportDirs
303
+ supportDirs,
304
+ referenceCounts: await this.referenceCounts(treeNames)
288
305
  });
289
306
  for (const [name, score] of quality) {
290
307
  const record = usage.get(name);
@@ -295,6 +312,28 @@ var EvolutionCurator = class extends Service {
295
312
  }
296
313
  }
297
314
  /**
315
+ * In-degree over explicit `related_skills` frontmatter references (the DSH
316
+ * equivalent of the graph-in-degree references factor): a skill listing
317
+ * other skill names counts as one reference to each of them, so hub skills
318
+ * that are explicitly named by peers get a non-zero references factor.
319
+ */
320
+ async referenceCounts(treeNames) {
321
+ const counts = /* @__PURE__ */ new Map();
322
+ for (const name of treeNames) {
323
+ const content = await this.skills.read(name);
324
+ if (!content) continue;
325
+ const parsed = parseFrontmatter(content);
326
+ if (!parsed) continue;
327
+ const raw = parsed.frontmatter["related_skills"];
328
+ if (typeof raw !== "string") continue;
329
+ for (const match of Array.from(raw.matchAll(/[a-z0-9][a-z0-9-]*/g))) {
330
+ const target = match[0];
331
+ if (target && SKILL_NAME_RE.test(target) && target !== name) counts.set(target, (counts.get(target) ?? 0) + 1);
332
+ }
333
+ }
334
+ return counts;
335
+ }
336
+ /**
298
337
  * Execute lifecycle archives and consolidation nominations, then persist the
299
338
  * suppression and usage sidecars best-effort. A dry-run short-circuits: no
300
339
  * file moves and no state persistence — the caller still writes the report.
@@ -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
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.25",
4
+ "version": "0.1.0-rc.26",
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.25"
36
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.26"
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.25",
43
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.25"
42
+ "@lmzhen/dsh-evolution-io": "^0.1.0-rc.26",
43
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.26"
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.25",
49
- "@lmzhen/dsh-evolution-io": "^0.1.0-rc.25",
50
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.25"
48
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.26",
49
+ "@lmzhen/dsh-evolution-io": "^0.1.0-rc.26",
50
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.26"
51
51
  }
52
52
  }