@lythos/skill-deck 0.1.3 → 0.1.5

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/link.ts +14 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lythos/skill-deck",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Declarative skill deck governance — cold pool, working set, deny-by-default",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/link.ts CHANGED
@@ -119,12 +119,13 @@ function findSource(name: string, coldPool: string, projectDir: string): string
119
119
  if (existsSync(join(local, "SKILL.md"))) return local;
120
120
 
121
121
  // 4. 扁平扫描: cold_pool/<any-repo>/<name> 或 <any-repo>/skills/<name>
122
- // 跳过 agent/working-set 相关目录,避免把 symlink 误判为有效源
123
- const skipDirs = new Set(['.claude', '.kimi', '.git', 'node_modules', '.lythos-curator']);
122
+ // 跳过隐藏目录(agent working set、git、配置等)和 node_modules,
123
+ // 避免把 .claude/skills/ 里的 symlink 误判为有效 cold-pool 源
124
124
  try {
125
125
  for (const entry of readdirSync(coldPool, { withFileTypes: true })) {
126
126
  if (!entry.isDirectory()) continue;
127
- if (skipDirs.has(entry.name)) continue;
127
+ if (entry.name.startsWith('.')) continue;
128
+ if (entry.name === 'node_modules') continue;
128
129
  const base = join(coldPool, entry.name);
129
130
  for (const sub of [join(base, name), join(base, "skills", name)]) {
130
131
  if (existsSync(join(sub, "SKILL.md"))) return sub;
@@ -168,7 +169,8 @@ const MAX_CARDS = Number(deck.deck?.max_cards || 10);
168
169
  // ── 收集声明 ────────────────────────────────────────────────
169
170
 
170
171
  interface DeclaredSkill {
171
- name: string;
172
+ name: string; // 完整声明名(如 github.com/.../lythoskill-deck)
173
+ baseName: string; // working set 中的目录名(如 lythoskill-deck)
172
174
  type: "innate" | "tool" | "combo" | "transient";
173
175
  sourcePath: string;
174
176
  expires?: string;
@@ -185,7 +187,8 @@ for (const section of ["innate", "tool", "combo"] as const) {
185
187
  errors.push(`skill 未找到: ${name}`);
186
188
  continue;
187
189
  }
188
- declared.push({ name, type: section, sourcePath: src });
190
+ const baseName = name.split("/").pop() || name;
191
+ declared.push({ name, baseName, type: section, sourcePath: src });
189
192
  }
190
193
  }
191
194
 
@@ -198,7 +201,7 @@ for (const [key, value] of Object.entries(deck.transient || {})) {
198
201
  errors.push(`transient 路径不存在: ${key} → ${src}`);
199
202
  continue;
200
203
  }
201
- declared.push({ name: key, type: "transient", sourcePath: src, expires: t.expires });
204
+ declared.push({ name: key, baseName: key, type: "transient", sourcePath: src, expires: t.expires });
202
205
  }
203
206
 
204
207
  if (errors.length > 0) {
@@ -219,11 +222,11 @@ if (declared.length > MAX_CARDS) {
219
222
  mkdirSync(WORKING_SET, { recursive: true });
220
223
 
221
224
  // 清理未声明的条目
222
- const declaredNames = new Set(declared.map(d => d.name.split("/")[0]));
225
+ const declaredBaseNames = new Set(declared.map(d => d.baseName));
223
226
  try {
224
227
  for (const entry of readdirSync(WORKING_SET)) {
225
228
  if (entry.startsWith("_")) continue;
226
- if (!declaredNames.has(entry)) {
229
+ if (!declaredBaseNames.has(entry)) {
227
230
  rmSync(join(WORKING_SET, entry), { recursive: true, force: true });
228
231
  console.log(` 🗑️ 移除: ${entry}`);
229
232
  }
@@ -234,7 +237,7 @@ try {
234
237
  const linkedSkills: LinkedSkill[] = [];
235
238
 
236
239
  for (const item of declared) {
237
- const dest = join(WORKING_SET, item.name);
240
+ const dest = join(WORKING_SET, item.baseName);
238
241
 
239
242
  // 幂等:已存在则删除重建(lstat 不跟随 symlink,能处理断链/自引用 symlink)
240
243
  try {
@@ -243,10 +246,9 @@ for (const item of declared) {
243
246
  } catch {}
244
247
 
245
248
  try {
246
- mkdirSync(dirname(dest), { recursive: true });
247
249
  symlinkSync(item.sourcePath, dest);
248
250
  } catch (err: any) {
249
- console.error(`❌ 链接失败: ${item.name}: ${err.message}`);
251
+ console.error(`❌ 链接失败: ${item.baseName}: ${err.message}`);
250
252
  continue;
251
253
  }
252
254
 
@@ -272,7 +274,7 @@ for (const item of declared) {
272
274
  deck_managed_dirs: managedDirs,
273
275
  });
274
276
 
275
- console.log(` 🔗 ${item.name}`);
277
+ console.log(` 🔗 ${item.baseName}`);
276
278
  }
277
279
 
278
280
  // ── Transient 过期检查 ──────────────────────────────────────