skills 1.4.1 → 1.4.2
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 +1 -2
- package/dist/_chunks/libs/@clack/prompts.mjs +60 -1
- package/dist/cli.mjs +203 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -214,7 +214,7 @@ Skills can be installed to any of these agents:
|
|
|
214
214
|
| Augment | `augment` | `.augment/skills/` | `~/.augment/skills/` |
|
|
215
215
|
| Claude Code | `claude-code` | `.claude/skills/` | `~/.claude/skills/` |
|
|
216
216
|
| OpenClaw | `openclaw` | `skills/` | `~/.openclaw/skills/` |
|
|
217
|
-
| Cline | `cline` | `.
|
|
217
|
+
| Cline | `cline` | `.agents/skills/` | `~/.agents/skills/` |
|
|
218
218
|
| CodeBuddy | `codebuddy` | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
|
|
219
219
|
| Codex | `codex` | `.agents/skills/` | `~/.codex/skills/` |
|
|
220
220
|
| Command Code | `command-code` | `.commandcode/skills/` | `~/.commandcode/skills/` |
|
|
@@ -321,7 +321,6 @@ The CLI searches for skills in these locations within a repository:
|
|
|
321
321
|
- `.augment/skills/`
|
|
322
322
|
- `.claude/skills/`
|
|
323
323
|
- `./skills/`
|
|
324
|
-
- `.cline/skills/`
|
|
325
324
|
- `.codebuddy/skills/`
|
|
326
325
|
- `.commandcode/skills/`
|
|
327
326
|
- `.continue/skills/`
|
|
@@ -129,6 +129,65 @@ ${s}
|
|
|
129
129
|
}).join(`
|
|
130
130
|
${import_picocolors.default.cyan(o)} `)}
|
|
131
131
|
${import_picocolors.default.cyan(d)}
|
|
132
|
+
`;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}).prompt();
|
|
136
|
+
}, be = (t) => {
|
|
137
|
+
const { selectableGroups: n = !0 } = t, r = (i, s, c = []) => {
|
|
138
|
+
const a = i.label ?? String(i.value), l = typeof i.group == "string", $ = l && (c[c.indexOf(i) + 1] ?? { group: !0 }), g = l && $.group === !0, p = l ? n ? `${g ? d : o} ` : " " : "";
|
|
139
|
+
if (s === "active") return `${import_picocolors.default.dim(p)}${import_picocolors.default.cyan(A)} ${a} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}`;
|
|
140
|
+
if (s === "group-active") return `${p}${import_picocolors.default.cyan(A)} ${import_picocolors.default.dim(a)}`;
|
|
141
|
+
if (s === "group-active-selected") return `${p}${import_picocolors.default.green(T)} ${import_picocolors.default.dim(a)}`;
|
|
142
|
+
if (s === "selected") {
|
|
143
|
+
const f = l || n ? import_picocolors.default.green(T) : "";
|
|
144
|
+
return `${import_picocolors.default.dim(p)}${f} ${import_picocolors.default.dim(a)} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}`;
|
|
145
|
+
}
|
|
146
|
+
if (s === "cancelled") return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(a))}`;
|
|
147
|
+
if (s === "active-selected") return `${import_picocolors.default.dim(p)}${import_picocolors.default.green(T)} ${a} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}`;
|
|
148
|
+
if (s === "submitted") return `${import_picocolors.default.dim(a)}`;
|
|
149
|
+
const v = l || n ? import_picocolors.default.dim(F) : "";
|
|
150
|
+
return `${import_picocolors.default.dim(p)}${v} ${import_picocolors.default.dim(a)}`;
|
|
151
|
+
};
|
|
152
|
+
return new _D({
|
|
153
|
+
options: t.options,
|
|
154
|
+
initialValues: t.initialValues,
|
|
155
|
+
required: t.required ?? !0,
|
|
156
|
+
cursorAt: t.cursorAt,
|
|
157
|
+
selectableGroups: n,
|
|
158
|
+
validate(i) {
|
|
159
|
+
if (this.required && i.length === 0) return `Please select at least one option.
|
|
160
|
+
${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
|
|
161
|
+
},
|
|
162
|
+
render() {
|
|
163
|
+
const i = `${import_picocolors.default.gray(o)}
|
|
164
|
+
${b(this.state)} ${t.message}
|
|
165
|
+
`;
|
|
166
|
+
switch (this.state) {
|
|
167
|
+
case "submit": return `${i}${import_picocolors.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => r(s, "submitted")).join(import_picocolors.default.dim(", "))}`;
|
|
168
|
+
case "cancel": {
|
|
169
|
+
const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => r(c, "cancelled")).join(import_picocolors.default.dim(", "));
|
|
170
|
+
return `${i}${import_picocolors.default.gray(o)} ${s.trim() ? `${s}
|
|
171
|
+
${import_picocolors.default.gray(o)}` : ""}`;
|
|
172
|
+
}
|
|
173
|
+
case "error": {
|
|
174
|
+
const s = this.error.split(`
|
|
175
|
+
`).map((c, a) => a === 0 ? `${import_picocolors.default.yellow(d)} ${import_picocolors.default.yellow(c)}` : ` ${c}`).join(`
|
|
176
|
+
`);
|
|
177
|
+
return `${i}${import_picocolors.default.yellow(o)} ${this.options.map((c, a, l) => {
|
|
178
|
+
const $ = this.value.includes(c.value) || c.group === !0 && this.isGroupSelected(`${c.value}`), g = a === this.cursor;
|
|
179
|
+
return !g && typeof c.group == "string" && this.options[this.cursor].value === c.group ? r(c, $ ? "group-active-selected" : "group-active", l) : g && $ ? r(c, "active-selected", l) : $ ? r(c, "selected", l) : r(c, g ? "active" : "inactive", l);
|
|
180
|
+
}).join(`
|
|
181
|
+
${import_picocolors.default.yellow(o)} `)}
|
|
182
|
+
${s}
|
|
183
|
+
`;
|
|
184
|
+
}
|
|
185
|
+
default: return `${i}${import_picocolors.default.cyan(o)} ${this.options.map((s, c, a) => {
|
|
186
|
+
const l = this.value.includes(s.value) || s.group === !0 && this.isGroupSelected(`${s.value}`), $ = c === this.cursor;
|
|
187
|
+
return !$ && typeof s.group == "string" && this.options[this.cursor].value === s.group ? r(s, l ? "group-active-selected" : "group-active", a) : $ && l ? r(s, "active-selected", a) : l ? r(s, "selected", a) : r(s, $ ? "active" : "inactive", a);
|
|
188
|
+
}).join(`
|
|
189
|
+
${import_picocolors.default.cyan(o)} `)}
|
|
190
|
+
${import_picocolors.default.cyan(d)}
|
|
132
191
|
`;
|
|
133
192
|
}
|
|
134
193
|
}
|
|
@@ -272,4 +331,4 @@ ${J}${i.trimStart()}`), r = 3 + stripVTControlCharacters(i.trimStart()).length);
|
|
|
272
331
|
}
|
|
273
332
|
};
|
|
274
333
|
};
|
|
275
|
-
export { Y as a,
|
|
334
|
+
export { Y as a, ve as c, Se as i, xe as l, M as n, be as o, Me as r, fe as s, Ie as t, ye as u };
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { r as __toESM } from "./_chunks/rolldown-runtime.mjs";
|
|
3
3
|
import { l as pD, u as require_picocolors } from "./_chunks/libs/@clack/core.mjs";
|
|
4
|
-
import { a as Y, c as
|
|
4
|
+
import { a as Y, c as ve, i as Se, l as xe, n as M, o as be, r as Me, s as fe, t as Ie, u as ye } from "./_chunks/libs/@clack/prompts.mjs";
|
|
5
5
|
import "./_chunks/libs/@kwsites/file-exists.mjs";
|
|
6
6
|
import "./_chunks/libs/@kwsites/promise-deferred.mjs";
|
|
7
7
|
import { t as esm_default } from "./_chunks/libs/simple-git.mjs";
|
|
@@ -424,6 +424,36 @@ async function getPluginSkillPaths(basePath) {
|
|
|
424
424
|
} catch {}
|
|
425
425
|
return searchDirs;
|
|
426
426
|
}
|
|
427
|
+
async function getPluginGroupings(basePath) {
|
|
428
|
+
const groupings = /* @__PURE__ */ new Map();
|
|
429
|
+
try {
|
|
430
|
+
const content = await readFile(join(basePath, ".claude-plugin/marketplace.json"), "utf-8");
|
|
431
|
+
const manifest = JSON.parse(content);
|
|
432
|
+
const pluginRoot = manifest.metadata?.pluginRoot;
|
|
433
|
+
if (pluginRoot === void 0 || isValidRelativePath(pluginRoot)) for (const plugin of manifest.plugins ?? []) {
|
|
434
|
+
if (!plugin.name) continue;
|
|
435
|
+
if (typeof plugin.source !== "string" && plugin.source !== void 0) continue;
|
|
436
|
+
if (plugin.source !== void 0 && !isValidRelativePath(plugin.source)) continue;
|
|
437
|
+
const pluginBase = join(basePath, pluginRoot ?? "", plugin.source ?? "");
|
|
438
|
+
if (!isContainedIn(pluginBase, basePath)) continue;
|
|
439
|
+
if (plugin.skills && plugin.skills.length > 0) for (const skillPath of plugin.skills) {
|
|
440
|
+
if (!isValidRelativePath(skillPath)) continue;
|
|
441
|
+
const skillDir = join(pluginBase, skillPath);
|
|
442
|
+
if (isContainedIn(skillDir, basePath)) groupings.set(resolve(skillDir), plugin.name);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
} catch {}
|
|
446
|
+
try {
|
|
447
|
+
const content = await readFile(join(basePath, ".claude-plugin/plugin.json"), "utf-8");
|
|
448
|
+
const manifest = JSON.parse(content);
|
|
449
|
+
if (manifest.name && manifest.skills && manifest.skills.length > 0) for (const skillPath of manifest.skills) {
|
|
450
|
+
if (!isValidRelativePath(skillPath)) continue;
|
|
451
|
+
const skillDir = join(basePath, skillPath);
|
|
452
|
+
if (isContainedIn(skillDir, basePath)) groupings.set(resolve(skillDir), manifest.name);
|
|
453
|
+
}
|
|
454
|
+
} catch {}
|
|
455
|
+
return groupings;
|
|
456
|
+
}
|
|
427
457
|
const SKIP_DIRS = [
|
|
428
458
|
"node_modules",
|
|
429
459
|
".git",
|
|
@@ -475,9 +505,16 @@ async function discoverSkills(basePath, subpath, options) {
|
|
|
475
505
|
const skills = [];
|
|
476
506
|
const seenNames = /* @__PURE__ */ new Set();
|
|
477
507
|
const searchPath = subpath ? join(basePath, subpath) : basePath;
|
|
508
|
+
const pluginGroupings = await getPluginGroupings(searchPath);
|
|
509
|
+
const enhanceSkill = (skill) => {
|
|
510
|
+
const resolvedPath = resolve(skill.path);
|
|
511
|
+
if (pluginGroupings.has(resolvedPath)) skill.pluginName = pluginGroupings.get(resolvedPath);
|
|
512
|
+
return skill;
|
|
513
|
+
};
|
|
478
514
|
if (await hasSkillMd(searchPath)) {
|
|
479
|
-
|
|
515
|
+
let skill = await parseSkillMd(join(searchPath, "SKILL.md"), options);
|
|
480
516
|
if (skill) {
|
|
517
|
+
skill = enhanceSkill(skill);
|
|
481
518
|
skills.push(skill);
|
|
482
519
|
seenNames.add(skill.name);
|
|
483
520
|
if (!options?.fullDepth) return skills;
|
|
@@ -520,8 +557,9 @@ async function discoverSkills(basePath, subpath, options) {
|
|
|
520
557
|
for (const entry of entries) if (entry.isDirectory()) {
|
|
521
558
|
const skillDir = join(dir, entry.name);
|
|
522
559
|
if (await hasSkillMd(skillDir)) {
|
|
523
|
-
|
|
560
|
+
let skill = await parseSkillMd(join(skillDir, "SKILL.md"), options);
|
|
524
561
|
if (skill && !seenNames.has(skill.name)) {
|
|
562
|
+
skill = enhanceSkill(skill);
|
|
525
563
|
skills.push(skill);
|
|
526
564
|
seenNames.add(skill.name);
|
|
527
565
|
}
|
|
@@ -531,8 +569,9 @@ async function discoverSkills(basePath, subpath, options) {
|
|
|
531
569
|
if (skills.length === 0 || options?.fullDepth) {
|
|
532
570
|
const allSkillDirs = await findSkillDirs(searchPath);
|
|
533
571
|
for (const skillDir of allSkillDirs) {
|
|
534
|
-
|
|
572
|
+
let skill = await parseSkillMd(join(skillDir, "SKILL.md"), options);
|
|
535
573
|
if (skill && !seenNames.has(skill.name)) {
|
|
574
|
+
skill = enhanceSkill(skill);
|
|
536
575
|
skills.push(skill);
|
|
537
576
|
seenNames.add(skill.name);
|
|
538
577
|
}
|
|
@@ -610,8 +649,8 @@ const agents = {
|
|
|
610
649
|
cline: {
|
|
611
650
|
name: "cline",
|
|
612
651
|
displayName: "Cline",
|
|
613
|
-
skillsDir: ".
|
|
614
|
-
globalSkillsDir: join(home, ".
|
|
652
|
+
skillsDir: ".agents/skills",
|
|
653
|
+
globalSkillsDir: join(home, ".agents", "skills"),
|
|
615
654
|
detectInstalled: async () => {
|
|
616
655
|
return existsSync(join(home, ".cline"));
|
|
617
656
|
}
|
|
@@ -1835,6 +1874,9 @@ async function removeSkillFromLock(skillName) {
|
|
|
1835
1874
|
async function getSkillFromLock(skillName) {
|
|
1836
1875
|
return (await readSkillLock$1()).skills[skillName] ?? null;
|
|
1837
1876
|
}
|
|
1877
|
+
async function getAllLockedSkills() {
|
|
1878
|
+
return (await readSkillLock$1()).skills;
|
|
1879
|
+
}
|
|
1838
1880
|
function createEmptyLockFile() {
|
|
1839
1881
|
return {
|
|
1840
1882
|
version: CURRENT_VERSION$1,
|
|
@@ -1925,7 +1967,7 @@ function createEmptyLocalLock() {
|
|
|
1925
1967
|
skills: {}
|
|
1926
1968
|
};
|
|
1927
1969
|
}
|
|
1928
|
-
var version$1 = "1.4.
|
|
1970
|
+
var version$1 = "1.4.2";
|
|
1929
1971
|
const isCancelled$1 = (value) => typeof value === "symbol";
|
|
1930
1972
|
async function isSourcePrivate(source) {
|
|
1931
1973
|
const ownerRepo = parseOwnerRepo(source);
|
|
@@ -2355,7 +2397,6 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
2355
2397
|
for (const s of skills) M.message(` - ${s.installName}`);
|
|
2356
2398
|
process.exit(1);
|
|
2357
2399
|
}
|
|
2358
|
-
M.info(`Selected ${selectedSkills.length} skill${selectedSkills.length !== 1 ? "s" : ""}: ${selectedSkills.map((s) => import_picocolors.default.cyan(s.installName)).join(", ")}`);
|
|
2359
2400
|
} else if (skills.length === 1) {
|
|
2360
2401
|
selectedSkills = skills;
|
|
2361
2402
|
const firstSkill = skills[0];
|
|
@@ -2858,9 +2899,29 @@ async function runAdd(args, options = {}) {
|
|
|
2858
2899
|
if (options.list) {
|
|
2859
2900
|
console.log();
|
|
2860
2901
|
M.step(import_picocolors.default.bold("Available Skills"));
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2902
|
+
const groupedSkills = {};
|
|
2903
|
+
const ungroupedSkills = [];
|
|
2904
|
+
for (const skill of skills) if (skill.pluginName) {
|
|
2905
|
+
const group = skill.pluginName;
|
|
2906
|
+
if (!groupedSkills[group]) groupedSkills[group] = [];
|
|
2907
|
+
groupedSkills[group].push(skill);
|
|
2908
|
+
} else ungroupedSkills.push(skill);
|
|
2909
|
+
const sortedGroups = Object.keys(groupedSkills).sort();
|
|
2910
|
+
for (const group of sortedGroups) {
|
|
2911
|
+
const title = group.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
2912
|
+
console.log(import_picocolors.default.bold(title));
|
|
2913
|
+
for (const skill of groupedSkills[group]) {
|
|
2914
|
+
M.message(` ${import_picocolors.default.cyan(getSkillDisplayName(skill))}`);
|
|
2915
|
+
M.message(` ${import_picocolors.default.dim(skill.description)}`);
|
|
2916
|
+
}
|
|
2917
|
+
console.log();
|
|
2918
|
+
}
|
|
2919
|
+
if (ungroupedSkills.length > 0) {
|
|
2920
|
+
if (sortedGroups.length > 0) console.log(import_picocolors.default.bold("General"));
|
|
2921
|
+
for (const skill of ungroupedSkills) {
|
|
2922
|
+
M.message(` ${import_picocolors.default.cyan(getSkillDisplayName(skill))}`);
|
|
2923
|
+
M.message(` ${import_picocolors.default.dim(skill.description)}`);
|
|
2924
|
+
}
|
|
2864
2925
|
}
|
|
2865
2926
|
console.log();
|
|
2866
2927
|
Se("Use --skill <name> to install specific skills");
|
|
@@ -2890,9 +2951,34 @@ async function runAdd(args, options = {}) {
|
|
|
2890
2951
|
selectedSkills = skills;
|
|
2891
2952
|
M.info(`Installing all ${skills.length} skills`);
|
|
2892
2953
|
} else {
|
|
2893
|
-
const
|
|
2954
|
+
const sortedSkills = [...skills].sort((a, b) => {
|
|
2955
|
+
if (a.pluginName && !b.pluginName) return -1;
|
|
2956
|
+
if (!a.pluginName && b.pluginName) return 1;
|
|
2957
|
+
if (a.pluginName && b.pluginName && a.pluginName !== b.pluginName) return a.pluginName.localeCompare(b.pluginName);
|
|
2958
|
+
return getSkillDisplayName(a).localeCompare(getSkillDisplayName(b));
|
|
2959
|
+
});
|
|
2960
|
+
const hasGroups = sortedSkills.some((s) => s.pluginName);
|
|
2961
|
+
let selected;
|
|
2962
|
+
if (hasGroups) {
|
|
2963
|
+
const kebabToTitle = (s) => s.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
2964
|
+
const grouped = {};
|
|
2965
|
+
for (const s of sortedSkills) {
|
|
2966
|
+
const groupName = s.pluginName ? kebabToTitle(s.pluginName) : "Other";
|
|
2967
|
+
if (!grouped[groupName]) grouped[groupName] = [];
|
|
2968
|
+
grouped[groupName].push({
|
|
2969
|
+
value: s,
|
|
2970
|
+
label: getSkillDisplayName(s),
|
|
2971
|
+
hint: s.description.length > 60 ? s.description.slice(0, 57) + "..." : s.description
|
|
2972
|
+
});
|
|
2973
|
+
}
|
|
2974
|
+
selected = await be({
|
|
2975
|
+
message: `Select skills to install ${import_picocolors.default.dim("(space to toggle)")}`,
|
|
2976
|
+
options: grouped,
|
|
2977
|
+
required: true
|
|
2978
|
+
});
|
|
2979
|
+
} else selected = await multiselect({
|
|
2894
2980
|
message: "Select skills to install",
|
|
2895
|
-
options:
|
|
2981
|
+
options: sortedSkills.map((s) => ({
|
|
2896
2982
|
value: s,
|
|
2897
2983
|
label: getSkillDisplayName(s),
|
|
2898
2984
|
hint: s.description.length > 60 ? s.description.slice(0, 57) + "..." : s.description
|
|
@@ -3015,14 +3101,37 @@ async function runAdd(args, options = {}) {
|
|
|
3015
3101
|
if (!overwriteStatus.has(skillName)) overwriteStatus.set(skillName, /* @__PURE__ */ new Map());
|
|
3016
3102
|
overwriteStatus.get(skillName).set(agent, installed);
|
|
3017
3103
|
}
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3104
|
+
const groupedSummary = {};
|
|
3105
|
+
const ungroupedSummary = [];
|
|
3106
|
+
for (const skill of selectedSkills) if (skill.pluginName) {
|
|
3107
|
+
const group = skill.pluginName;
|
|
3108
|
+
if (!groupedSummary[group]) groupedSummary[group] = [];
|
|
3109
|
+
groupedSummary[group].push(skill);
|
|
3110
|
+
} else ungroupedSummary.push(skill);
|
|
3111
|
+
const printSkillSummary = (skills) => {
|
|
3112
|
+
for (const skill of skills) {
|
|
3113
|
+
if (summaryLines.length > 0) summaryLines.push("");
|
|
3114
|
+
const shortCanonical = shortenPath$2(getCanonicalPath(skill.name, { global: installGlobally }), cwd);
|
|
3115
|
+
summaryLines.push(`${import_picocolors.default.cyan(shortCanonical)}`);
|
|
3116
|
+
summaryLines.push(...buildAgentSummaryLines(targetAgents, installMode));
|
|
3117
|
+
const skillOverwrites = overwriteStatus.get(skill.name);
|
|
3118
|
+
const overwriteAgents = targetAgents.filter((a) => skillOverwrites?.get(a)).map((a) => agents[a].displayName);
|
|
3119
|
+
if (overwriteAgents.length > 0) summaryLines.push(` ${import_picocolors.default.yellow("overwrites:")} ${formatList$1(overwriteAgents)}`);
|
|
3120
|
+
}
|
|
3121
|
+
};
|
|
3122
|
+
const sortedGroups = Object.keys(groupedSummary).sort();
|
|
3123
|
+
for (const group of sortedGroups) {
|
|
3124
|
+
const title = group.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3125
|
+
summaryLines.push("");
|
|
3126
|
+
summaryLines.push(import_picocolors.default.bold(title));
|
|
3127
|
+
printSkillSummary(groupedSummary[group]);
|
|
3128
|
+
}
|
|
3129
|
+
if (ungroupedSummary.length > 0) {
|
|
3130
|
+
if (sortedGroups.length > 0) {
|
|
3131
|
+
summaryLines.push("");
|
|
3132
|
+
summaryLines.push(import_picocolors.default.bold("General"));
|
|
3133
|
+
}
|
|
3134
|
+
printSkillSummary(ungroupedSummary);
|
|
3026
3135
|
}
|
|
3027
3136
|
console.log();
|
|
3028
3137
|
Me(summaryLines.join("\n"), "Installation Summary");
|
|
@@ -3054,6 +3163,7 @@ async function runAdd(args, options = {}) {
|
|
|
3054
3163
|
results.push({
|
|
3055
3164
|
skill: getSkillDisplayName(skill),
|
|
3056
3165
|
agent: agents[agent].displayName,
|
|
3166
|
+
pluginName: skill.pluginName,
|
|
3057
3167
|
...result
|
|
3058
3168
|
});
|
|
3059
3169
|
}
|
|
@@ -3106,7 +3216,8 @@ async function runAdd(args, options = {}) {
|
|
|
3106
3216
|
sourceType: parsed.type,
|
|
3107
3217
|
sourceUrl: parsed.url,
|
|
3108
3218
|
skillPath: skillPathValue,
|
|
3109
|
-
skillFolderHash
|
|
3219
|
+
skillFolderHash,
|
|
3220
|
+
pluginName: skill.pluginName
|
|
3110
3221
|
});
|
|
3111
3222
|
} catch {}
|
|
3112
3223
|
}
|
|
@@ -3127,30 +3238,54 @@ async function runAdd(args, options = {}) {
|
|
|
3127
3238
|
}
|
|
3128
3239
|
if (successful.length > 0) {
|
|
3129
3240
|
const bySkill = /* @__PURE__ */ new Map();
|
|
3241
|
+
const groupedResults = {};
|
|
3242
|
+
const ungroupedResults = [];
|
|
3130
3243
|
for (const r of successful) {
|
|
3131
3244
|
const skillResults = bySkill.get(r.skill) || [];
|
|
3132
3245
|
skillResults.push(r);
|
|
3133
3246
|
bySkill.set(r.skill, skillResults);
|
|
3247
|
+
if (skillResults.length === 1) if (r.pluginName) {
|
|
3248
|
+
const group = r.pluginName;
|
|
3249
|
+
if (!groupedResults[group]) groupedResults[group] = [];
|
|
3250
|
+
groupedResults[group].push(r);
|
|
3251
|
+
} else ungroupedResults.push(r);
|
|
3134
3252
|
}
|
|
3135
3253
|
const skillCount = bySkill.size;
|
|
3136
3254
|
const symlinkFailures = successful.filter((r) => r.mode === "symlink" && r.symlinkFailed);
|
|
3137
3255
|
const copiedAgents = symlinkFailures.map((r) => r.agent);
|
|
3138
3256
|
const resultLines = [];
|
|
3139
|
-
|
|
3140
|
-
const
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3257
|
+
const printSkillResults = (entries) => {
|
|
3258
|
+
for (const entry of entries) {
|
|
3259
|
+
const skillResults = bySkill.get(entry.skill) || [];
|
|
3260
|
+
const firstResult = skillResults[0];
|
|
3261
|
+
if (firstResult.mode === "copy") {
|
|
3262
|
+
resultLines.push(`${import_picocolors.default.green("✓")} ${entry.skill} ${import_picocolors.default.dim("(copied)")}`);
|
|
3263
|
+
for (const r of skillResults) {
|
|
3264
|
+
const shortPath = shortenPath$2(r.path, cwd);
|
|
3265
|
+
resultLines.push(` ${import_picocolors.default.dim("→")} ${shortPath}`);
|
|
3266
|
+
}
|
|
3267
|
+
} else {
|
|
3268
|
+
if (firstResult.canonicalPath) {
|
|
3269
|
+
const shortPath = shortenPath$2(firstResult.canonicalPath, cwd);
|
|
3270
|
+
resultLines.push(`${import_picocolors.default.green("✓")} ${shortPath}`);
|
|
3271
|
+
} else resultLines.push(`${import_picocolors.default.green("✓")} ${entry.skill}`);
|
|
3272
|
+
resultLines.push(...buildResultLines(skillResults, targetAgents));
|
|
3146
3273
|
}
|
|
3147
|
-
} else {
|
|
3148
|
-
if (firstResult.canonicalPath) {
|
|
3149
|
-
const shortPath = shortenPath$2(firstResult.canonicalPath, cwd);
|
|
3150
|
-
resultLines.push(`${import_picocolors.default.green("✓")} ${shortPath}`);
|
|
3151
|
-
} else resultLines.push(`${import_picocolors.default.green("✓")} ${skillName}`);
|
|
3152
|
-
resultLines.push(...buildResultLines(skillResults, targetAgents));
|
|
3153
3274
|
}
|
|
3275
|
+
};
|
|
3276
|
+
const sortedResultGroups = Object.keys(groupedResults).sort();
|
|
3277
|
+
for (const group of sortedResultGroups) {
|
|
3278
|
+
const title = group.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3279
|
+
resultLines.push("");
|
|
3280
|
+
resultLines.push(import_picocolors.default.bold(title));
|
|
3281
|
+
printSkillResults(groupedResults[group]);
|
|
3282
|
+
}
|
|
3283
|
+
if (ungroupedResults.length > 0) {
|
|
3284
|
+
if (sortedResultGroups.length > 0) {
|
|
3285
|
+
resultLines.push("");
|
|
3286
|
+
resultLines.push(import_picocolors.default.bold("General"));
|
|
3287
|
+
}
|
|
3288
|
+
printSkillResults(ungroupedResults);
|
|
3154
3289
|
}
|
|
3155
3290
|
const title = import_picocolors.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
|
|
3156
3291
|
Me(resultLines.join("\n"), title);
|
|
@@ -3864,6 +3999,7 @@ async function runList(args) {
|
|
|
3864
3999
|
global: scope,
|
|
3865
4000
|
agentFilter
|
|
3866
4001
|
});
|
|
4002
|
+
const lockedSkills = await getAllLockedSkills();
|
|
3867
4003
|
const cwd = process.cwd();
|
|
3868
4004
|
const scopeLabel = scope ? "Global" : "Project";
|
|
3869
4005
|
if (installedSkills.length === 0) {
|
|
@@ -3872,17 +4008,44 @@ async function runList(args) {
|
|
|
3872
4008
|
else console.log(`${DIM$1}Try listing global skills with -g${RESET$1}`);
|
|
3873
4009
|
return;
|
|
3874
4010
|
}
|
|
3875
|
-
function printSkill(skill) {
|
|
4011
|
+
function printSkill(skill, indent = false) {
|
|
4012
|
+
const prefix = indent ? " " : "";
|
|
3876
4013
|
const shortPath = shortenPath(skill.canonicalPath, cwd);
|
|
3877
4014
|
const agentNames = skill.agents.map((a) => agents[a].displayName);
|
|
3878
4015
|
const agentInfo = skill.agents.length > 0 ? formatList(agentNames) : `${YELLOW}not linked${RESET$1}`;
|
|
3879
|
-
console.log(`${CYAN}${skill.name}${RESET$1} ${DIM$1}${shortPath}${RESET$1}`);
|
|
3880
|
-
console.log(
|
|
4016
|
+
console.log(`${prefix}${CYAN}${skill.name}${RESET$1} ${DIM$1}${shortPath}${RESET$1}`);
|
|
4017
|
+
console.log(`${prefix} ${DIM$1}Agents:${RESET$1} ${agentInfo}`);
|
|
3881
4018
|
}
|
|
3882
4019
|
console.log(`${BOLD$1}${scopeLabel} Skills${RESET$1}`);
|
|
3883
4020
|
console.log();
|
|
3884
|
-
|
|
3885
|
-
|
|
4021
|
+
const groupedSkills = {};
|
|
4022
|
+
const ungroupedSkills = [];
|
|
4023
|
+
for (const skill of installedSkills) {
|
|
4024
|
+
const lockEntry = lockedSkills[skill.name];
|
|
4025
|
+
if (lockEntry?.pluginName) {
|
|
4026
|
+
const group = lockEntry.pluginName;
|
|
4027
|
+
if (!groupedSkills[group]) groupedSkills[group] = [];
|
|
4028
|
+
groupedSkills[group].push(skill);
|
|
4029
|
+
} else ungroupedSkills.push(skill);
|
|
4030
|
+
}
|
|
4031
|
+
if (Object.keys(groupedSkills).length > 0) {
|
|
4032
|
+
const sortedGroups = Object.keys(groupedSkills).sort();
|
|
4033
|
+
for (const group of sortedGroups) {
|
|
4034
|
+
const title = group.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
4035
|
+
console.log(`${BOLD$1}${title}${RESET$1}`);
|
|
4036
|
+
const skills = groupedSkills[group];
|
|
4037
|
+
if (skills) for (const skill of skills) printSkill(skill, true);
|
|
4038
|
+
console.log();
|
|
4039
|
+
}
|
|
4040
|
+
if (ungroupedSkills.length > 0) {
|
|
4041
|
+
console.log(`${BOLD$1}General${RESET$1}`);
|
|
4042
|
+
for (const skill of ungroupedSkills) printSkill(skill, true);
|
|
4043
|
+
console.log();
|
|
4044
|
+
}
|
|
4045
|
+
} else {
|
|
4046
|
+
for (const skill of installedSkills) printSkill(skill);
|
|
4047
|
+
console.log();
|
|
4048
|
+
}
|
|
3886
4049
|
}
|
|
3887
4050
|
async function removeCommand(skillNames, options) {
|
|
3888
4051
|
const isGlobal = options.global ?? false;
|