@lmzhen/dsh-evolution-curator 0.1.0-rc.44 → 0.1.0-rc.46

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, computeScopeView, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, parseCuratorNominations, relatedSkillNames, 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, EvolutionGateSet, SkillLibrary, buildCuratorRunReport, computeLifecycleTransitions, computeQualityScores, computeScopeView, emptyRecord, evolutionHome, evolutionIoAdapter, loadSuppressedNames, loadUsage, parseCuratorNominations, relatedSkillNames, 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.
@@ -18,8 +18,8 @@ const DEFAULT_QUALITY_WARN_STALE_AFTER_DAYS = 7;
18
18
  * plane's `consolidate()` guard; automatic nominations must pass the same gate.
19
19
  */
20
20
  function gateConsolidations(consolidations, gates) {
21
- const blocked = (name) => gates.exclude?.has(name) === true || gates.referenced?.has(name) === true || gates.suppressed?.has(name) === true;
22
- return consolidations.filter((n) => !blocked(n.from) && !blocked(n.into));
21
+ const gateSet = gates instanceof EvolutionGateSet ? gates : new EvolutionGateSet(gates);
22
+ return consolidations.filter((n) => !gateSet.isBlocked(n.from) && !gateSet.isBlocked(n.into));
23
23
  }
24
24
  var EvolutionCurator = class extends Service {
25
25
  static inject = ["evolutionIo"];
@@ -326,6 +326,11 @@ var EvolutionCurator = class extends Service {
326
326
  const usage = dryRun ? new Map([...rawUsage].map(([name, record]) => [name, { ...record }])) : rawUsage;
327
327
  const snapshotPath = dryRun ? void 0 : await this.snapshotFull("pre-curator-run");
328
328
  const suppressedNames = new Set(await loadSuppressedNames(root, this.io));
329
+ const gates = new EvolutionGateSet({
330
+ exclude: this.excludeSkillNames,
331
+ referenced: this.referencedSkillNames,
332
+ suppressed: suppressedNames
333
+ });
329
334
  const { bundledNames, treeNames } = await this.seedBaseline(usage);
330
335
  await this.scoreTree(usage, treeNames);
331
336
  const result = computeLifecycleTransitions(usage, {
@@ -338,18 +343,14 @@ var EvolutionCurator = class extends Service {
338
343
  bundledNames,
339
344
  suppressedNames,
340
345
  referencedSkillNames: this.referencedSkillNames
341
- });
346
+ }, /* @__PURE__ */ new Date(), gates);
342
347
  const nominations = this.llmReview ? await this.recommend(result.markStale, { dryRun }) : {
343
348
  prunings: [],
344
349
  consolidations: []
345
350
  };
346
351
  const gatedNominations = {
347
352
  ...nominations,
348
- consolidations: gateConsolidations(nominations.consolidations, {
349
- exclude: this.excludeSkillNames,
350
- referenced: this.referencedSkillNames,
351
- suppressed: suppressedNames
352
- })
353
+ consolidations: gateConsolidations(nominations.consolidations, gates)
353
354
  };
354
355
  const llmNominations = gatedNominations.prunings;
355
356
  const archiveCandidates = [...new Set([...result.archive, ...llmNominations])];
@@ -391,12 +392,13 @@ var EvolutionCurator = class extends Service {
391
392
  }
392
393
  const llmHint = !this.llmReview && result.markStale.length > 0 ? " (llmReview: off - deterministic archive only; set llmReview: true for the LLM merge channel)" : "";
393
394
  const summary = `${dryRun ? "dry-run" : "auto"}: stale:${result.markStale.length} archived:${archivedSkills.length} consolidated:${gatedNominations.consolidations.length}${llmHint}`;
395
+ const pausedNow = (await stateService?.loadCuratorState())?.paused ?? false;
394
396
  await stateService?.saveCuratorState({
395
397
  schemaVersion: 1,
396
398
  lastRunAt: dryRun ? persisted?.lastRunAt ?? this.lastRun : this.lastRun,
397
399
  runCount: dryRun ? persisted?.runCount ?? 0 : (persisted?.runCount ?? 0) + 1,
398
400
  lastSummary: summary,
399
- paused: false
401
+ paused: pausedNow
400
402
  });
401
403
  return {
402
404
  stale: result.markStale,
@@ -580,16 +582,21 @@ var EvolutionCurator = class extends Service {
580
582
  const root = this.skills.root;
581
583
  const usage = await loadUsage(root, this.io);
582
584
  const { bundledNames } = await this.seedBaseline(usage);
585
+ const gates = new EvolutionGateSet({
586
+ exclude: this.excludeSkillNames,
587
+ referenced: this.referencedSkillNames,
588
+ suppressed: new Set(await loadSuppressedNames(root, this.io))
589
+ });
583
590
  return computeScopeView(usage, {
584
591
  staleAfterDays: this.lifecycle().staleAfterDays,
585
592
  archiveAfterDays: this.lifecycle().archiveAfterDays,
586
593
  excludeSkillNames: this.excludeSkillNames,
587
594
  referencedSkillNames: this.referencedSkillNames,
588
- suppressedNames: new Set(await loadSuppressedNames(root, this.io)),
595
+ suppressedNames: new Set(gates.suppressed),
589
596
  manageUnmanaged: this.manageUnmanaged,
590
597
  pruneBuiltins: this.pruneBuiltins,
591
598
  bundledNames
592
- }, await this.protectedNameMap());
599
+ }, await this.protectedNameMap(), gates);
593
600
  }
594
601
  /** marker info (pinned/bundled/hub-installed) per skill, from the library list. */
595
602
  async protectedNameMap() {
@@ -603,10 +610,16 @@ var EvolutionCurator = class extends Service {
603
610
  * records into `archived` state. Snapshot-then-mutate, never a hard delete.
604
611
  */
605
612
  async consolidate(target, sources) {
606
- const blocked = [...this.excludeSkillNames].filter((name) => name === target || sources.includes(name));
613
+ const suppressedNames = new Set(await loadSuppressedNames(this.skills.root, this.io));
614
+ const gates = new EvolutionGateSet({
615
+ exclude: this.excludeSkillNames,
616
+ referenced: this.referencedSkillNames,
617
+ suppressed: suppressedNames
618
+ });
619
+ const blocked = [...new Set([target, ...sources])].filter((name) => gates.isBlocked(name));
607
620
  if (blocked.length > 0) return {
608
621
  ok: false,
609
- message: `Skill(s) excluded from lifecycle management: ${blocked.join(", ")}`
622
+ message: `Skill(s) protected from consolidation (excluded / referenced / suppressed / protected builtin): ${blocked.join(", ")}`
610
623
  };
611
624
  await this.snapshotFull("pre-consolidate");
612
625
  const result = await this.skills.consolidate(target, sources);
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { Context, Service } from '@deepseek-ai/cordis';
6
6
  import type Schema from '@deepseek-ai/schemastery';
7
- import { SkillLibrary } from '@deepseek-ai/dsh-evolution-core';
7
+ import { EvolutionGateSet, SkillLibrary } from '@deepseek-ai/dsh-evolution-core';
8
8
  import { type CuratorConsolidation, 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 {
@@ -62,7 +62,7 @@ export interface CuratorStateRecordShape {
62
62
  * source being archived nor as the umbrella being edited). Mirrors the control
63
63
  * plane's `consolidate()` guard; automatic nominations must pass the same gate.
64
64
  */
65
- export declare function gateConsolidations(consolidations: CuratorConsolidation[], gates: {
65
+ export declare function gateConsolidations(consolidations: CuratorConsolidation[], gates: EvolutionGateSet | {
66
66
  exclude?: ReadonlySet<string>;
67
67
  referenced?: ReadonlySet<string>;
68
68
  suppressed?: ReadonlySet<string>;
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.44",
4
+ "version": "0.1.0-rc.46",
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.44"
36
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.46"
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.44",
43
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.44"
42
+ "@lmzhen/dsh-evolution-io": "^0.1.0-rc.46",
43
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.46"
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.44",
49
- "@lmzhen/dsh-evolution-io": "^0.1.0-rc.44",
50
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.44"
48
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.46",
49
+ "@lmzhen/dsh-evolution-io": "^0.1.0-rc.46",
50
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.46"
51
51
  }
52
52
  }