@dealdeploy/skl 1.3.0 → 1.4.0
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.test.ts +62 -0
- package/lib.ts +15 -1
- package/package.json +1 -1
- package/tui.ts +9 -1
package/lib.test.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
findSkillEntries,
|
|
17
17
|
parseRepoArg,
|
|
18
18
|
buildAddArgs,
|
|
19
|
+
readSkillFrontmatterName,
|
|
19
20
|
detectProjectAgents,
|
|
20
21
|
parseSkillsListOutput,
|
|
21
22
|
planUpdates,
|
|
@@ -326,6 +327,67 @@ describe("buildAddArgs", () => {
|
|
|
326
327
|
const args = buildAddArgs("/my/catalog", "custom-skill", true);
|
|
327
328
|
expect(args).toEqual(["add", "/my/catalog/custom-skill", "-y", "-g"]);
|
|
328
329
|
});
|
|
330
|
+
|
|
331
|
+
test("uses SKILL.md frontmatter name for --skill flag when it differs from dir name", () => {
|
|
332
|
+
const catalog = catalogDir();
|
|
333
|
+
mkdirSync(join(catalog, "code-review"), { recursive: true });
|
|
334
|
+
writeFileSync(
|
|
335
|
+
join(catalog, "code-review", "SKILL.md"),
|
|
336
|
+
"---\nname: code-review:code-review\ndescription: Review PRs\n---\n# Code Review"
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
const entry: LockEntry = {
|
|
340
|
+
source: "owner/repo",
|
|
341
|
+
sourceUrl: "https://github.com/owner/repo",
|
|
342
|
+
skillPath: "skills/code-review",
|
|
343
|
+
treeSHA: "abc",
|
|
344
|
+
addedAt: "2026-01-01",
|
|
345
|
+
};
|
|
346
|
+
addToLock("code-review", entry);
|
|
347
|
+
|
|
348
|
+
const args = buildAddArgs(catalog, "code-review", true);
|
|
349
|
+
expect(args).toContain("--skill");
|
|
350
|
+
expect(args).toContain("code-review:code-review");
|
|
351
|
+
expect(args).not.toContain("--agent");
|
|
352
|
+
expect(args).toContain("-g");
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// ── readSkillFrontmatterName ────────────────────────────────────────
|
|
357
|
+
|
|
358
|
+
describe("readSkillFrontmatterName", () => {
|
|
359
|
+
test("reads name from valid frontmatter", () => {
|
|
360
|
+
const catalog = catalogDir();
|
|
361
|
+
mkdirSync(join(catalog, "my-skill"), { recursive: true });
|
|
362
|
+
writeFileSync(
|
|
363
|
+
join(catalog, "my-skill", "SKILL.md"),
|
|
364
|
+
"---\nname: my-skill:variant\ndescription: test\n---\n# Content"
|
|
365
|
+
);
|
|
366
|
+
expect(readSkillFrontmatterName(catalog, "my-skill")).toBe("my-skill:variant");
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
test("returns null when no frontmatter", () => {
|
|
370
|
+
const catalog = catalogDir();
|
|
371
|
+
mkdirSync(join(catalog, "no-fm"), { recursive: true });
|
|
372
|
+
writeFileSync(join(catalog, "no-fm", "SKILL.md"), "# Just markdown");
|
|
373
|
+
expect(readSkillFrontmatterName(catalog, "no-fm")).toBeNull();
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
test("returns null when SKILL.md missing", () => {
|
|
377
|
+
const catalog = catalogDir();
|
|
378
|
+
mkdirSync(join(catalog, "empty"), { recursive: true });
|
|
379
|
+
expect(readSkillFrontmatterName(catalog, "empty")).toBeNull();
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
test("returns null when name field missing from frontmatter", () => {
|
|
383
|
+
const catalog = catalogDir();
|
|
384
|
+
mkdirSync(join(catalog, "no-name"), { recursive: true });
|
|
385
|
+
writeFileSync(
|
|
386
|
+
join(catalog, "no-name", "SKILL.md"),
|
|
387
|
+
"---\ndescription: has no name\n---\n# Content"
|
|
388
|
+
);
|
|
389
|
+
expect(readSkillFrontmatterName(catalog, "no-name")).toBeNull();
|
|
390
|
+
});
|
|
329
391
|
});
|
|
330
392
|
|
|
331
393
|
// ── detectProjectAgents ─────────────────────────────────────────────
|
package/lib.ts
CHANGED
|
@@ -160,6 +160,19 @@ export function detectProjectAgents(cwd: string): string[] {
|
|
|
160
160
|
return agents;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
/** Read the frontmatter `name` from a skill's SKILL.md in the catalog. */
|
|
164
|
+
export function readSkillFrontmatterName(catalogPath: string, dirName: string): string | null {
|
|
165
|
+
try {
|
|
166
|
+
const content = readFileSync(join(catalogPath, dirName, "SKILL.md"), "utf-8");
|
|
167
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
168
|
+
if (!match) return null;
|
|
169
|
+
const nameMatch = match[1]!.match(/^name:\s*(.+)$/m);
|
|
170
|
+
return nameMatch ? nameMatch[1]!.trim() : null;
|
|
171
|
+
} catch {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
163
176
|
/** Build npx skills add args for a skill. */
|
|
164
177
|
export function buildAddArgs(
|
|
165
178
|
catalogPath: string,
|
|
@@ -172,7 +185,8 @@ export function buildAddArgs(
|
|
|
172
185
|
? ["--agent", ...projectAgents]
|
|
173
186
|
: [];
|
|
174
187
|
if (lockEntry) {
|
|
175
|
-
const
|
|
188
|
+
const skillName = readSkillFrontmatterName(catalogPath, name) ?? name;
|
|
189
|
+
const args = ["add", lockEntry.sourceUrl, "--skill", skillName, "-y", ...agentArgs];
|
|
176
190
|
if (isGlobal) args.push("-g");
|
|
177
191
|
return args;
|
|
178
192
|
}
|
package/package.json
CHANGED
package/tui.ts
CHANGED
|
@@ -239,6 +239,14 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
|
|
|
239
239
|
const rows: RowRefs[] = new Array(allSkills.length);
|
|
240
240
|
|
|
241
241
|
scrollBox.add(searchRow);
|
|
242
|
+
scrollBox.add(
|
|
243
|
+
new BoxRenderable(renderer, {
|
|
244
|
+
id: "spacer-search",
|
|
245
|
+
height: 1,
|
|
246
|
+
width: "100%",
|
|
247
|
+
backgroundColor: C.rowBg,
|
|
248
|
+
})
|
|
249
|
+
);
|
|
242
250
|
|
|
243
251
|
for (let di = 0; di < displayItems.length; di++) {
|
|
244
252
|
const item = displayItems[di]!;
|
|
@@ -490,7 +498,7 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
|
|
|
490
498
|
if (rows[item.skillIndex]!.row.visible) visibleBefore++;
|
|
491
499
|
}
|
|
492
500
|
}
|
|
493
|
-
scrollBox.scrollTo(Math.max(0, visibleBefore +
|
|
501
|
+
scrollBox.scrollTo(Math.max(0, visibleBefore + 2 - 2));
|
|
494
502
|
}
|
|
495
503
|
}
|
|
496
504
|
|