@lmzhen/dsh-evolution-skill-catalog 0.3.17 → 0.3.18

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/README.md CHANGED
@@ -22,5 +22,6 @@ Independent of request-prefix construction. This package does not alter the asse
22
22
  ## Known Limitations and Deferred Work
23
23
 
24
24
 
25
- - - Read-only native `ctx.skills` catalog. Skill mutations still happen through `tool-skill-manage`.
25
+ - Read-only native `ctx.skills` catalog. Skill mutations still happen through `tool-skill-manage`.
26
+ - **Out-of-band edits need a refresh (0.3.18, E-71).** The catalog invalidates on the in-band `evolution/skill-mutated` event (all writes through SkillLibrary). Edits made outside the family — manual file edit, a git pull, another process — bypass that event and cannot be auto-detected (decision C: no filesystem watcher). A root-mtime probe re-stamps the summaries cache when the provider is re-queried after a structural change (directory add/remove/rename), but any out-of-band change is only guaranteed to be visible after `/evolution skills refresh` runs (or the process restarts).
26
27
 
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
- import { SkillLibrary, evolutionIoAdapter } from "@lmzhen/dsh-evolution-core";
2
+ import { SkillLibrary, evolutionIoAdapter, resolveSkillsRoot } from "@lmzhen/dsh-evolution-core";
3
3
  import { join } from "node:path";
4
4
  //#region lib/types/index.js
5
5
  /**
@@ -28,15 +28,29 @@ function apply(ctx, rawConfig = {}) {
28
28
  userInvocable: rawConfig.userInvocable ?? true
29
29
  };
30
30
  const io = evolutionIoAdapter(() => ctx.evolutionIo.provider());
31
- const library = new SkillLibrary(rawConfig.root || void 0, io);
31
+ const library = new SkillLibrary(resolveSkillsRoot(rawConfig), io);
32
32
  const included = new Set(rawConfig.includeSkillNames ?? []);
33
33
  const excluded = new Set(rawConfig.excludeSkillNames ?? []);
34
34
  const visible = (name) => (included.size === 0 || included.has(name)) && !excluded.has(name);
35
35
  let control;
36
+ let summariesCache = null;
37
+ let summariesStamp = null;
38
+ async function summaries() {
39
+ const stamp = await io.mtime?.(library.root) ?? null;
40
+ if (summariesCache !== null && (stamp === null || summariesStamp === stamp)) return summariesCache;
41
+ if (summariesCache !== null && stamp !== null) control?.invalidate();
42
+ summariesCache = await library.list();
43
+ summariesStamp = stamp;
44
+ return summariesCache;
45
+ }
46
+ const dropSummariesCache = () => {
47
+ summariesCache = null;
48
+ control?.invalidate();
49
+ };
36
50
  const provider = {
37
51
  name: "dsh-evolution",
38
52
  async list(_options) {
39
- return (await library.list()).filter((summary) => visible(summary.name)).map((summary) => ({
53
+ return (await summaries()).filter((summary) => visible(summary.name)).map((summary) => ({
40
54
  name: summary.name,
41
55
  description: summary.description,
42
56
  invocation,
@@ -54,7 +68,7 @@ function apply(ctx, rawConfig = {}) {
54
68
  async get(candidate) {
55
69
  const name = candidate.name;
56
70
  if (!visible(name)) return void 0;
57
- const summary = (await library.list()).find((item) => item.name === name);
71
+ const summary = (await summaries()).find((item) => item.name === name);
58
72
  if (!summary) return void 0;
59
73
  const content = await library.read(name);
60
74
  if (content === null) return void 0;
@@ -79,9 +93,13 @@ function apply(ctx, rawConfig = {}) {
79
93
  return provider;
80
94
  });
81
95
  const disposeEvent = ctx.on("evolution/skill-mutated", () => {
82
- control?.invalidate();
96
+ dropSummariesCache();
97
+ });
98
+ const disposeRefresh = ctx.on("evolution/skills-refresh", () => {
99
+ dropSummariesCache();
83
100
  });
84
101
  return () => {
102
+ disposeRefresh();
85
103
  disposeEvent();
86
104
  unregister();
87
105
  control = void 0;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-skill-catalog",
3
3
  "description": "Native ctx.skills provider for the evolution-managed skill tree (community build)",
4
- "version": "0.3.17",
4
+ "version": "0.3.18",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -33,18 +33,18 @@
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
35
  "@deepseek-ai/schemastery": "^3.18.1",
36
- "@lmzhen/dsh-evolution-core": "^0.3.17"
36
+ "@lmzhen/dsh-evolution-core": "^0.3.18"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@deepseek-ai/cordis": "^4.0.1",
40
40
  "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
41
41
  "@deepseek-ai/dsh-skill": "^0.1.1-rc.2",
42
- "@lmzhen/dsh-evolution-io": "^0.3.17"
42
+ "@lmzhen/dsh-evolution-io": "^0.3.18"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
46
46
  "@deepseek-ai/dsh-skill": "^0.1.1-rc.2",
47
- "@lmzhen/dsh-evolution-core": "^0.3.17",
48
- "@lmzhen/dsh-evolution-io": "^0.3.17"
47
+ "@lmzhen/dsh-evolution-core": "^0.3.18",
48
+ "@lmzhen/dsh-evolution-io": "^0.3.18"
49
49
  }
50
50
  }