skills 1.5.17 → 1.5.19
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/dist/_chunks/libs/@clack/core.mjs +1 -55
- package/dist/_chunks/libs/@clack/prompts.mjs +2 -96
- package/dist/cli.mjs +260 -135
- package/package.json +3 -3
|
@@ -627,60 +627,6 @@ var r = class extends V {
|
|
|
627
627
|
});
|
|
628
628
|
}
|
|
629
629
|
};
|
|
630
|
-
let u$2 = class u extends V {
|
|
631
|
-
options;
|
|
632
|
-
cursor = 0;
|
|
633
|
-
#t;
|
|
634
|
-
getGroupItems(t) {
|
|
635
|
-
return this.options.filter((r) => r.group === t);
|
|
636
|
-
}
|
|
637
|
-
isGroupSelected(t) {
|
|
638
|
-
const r = this.getGroupItems(t), e = this.value;
|
|
639
|
-
return e === void 0 ? false : r.every((s) => e.includes(s.value));
|
|
640
|
-
}
|
|
641
|
-
toggleValue() {
|
|
642
|
-
const t = this.options[this.cursor];
|
|
643
|
-
if (t !== void 0) if (this.value === void 0 && (this.value = []), t.group === true) {
|
|
644
|
-
const r = t.value, e = this.getGroupItems(r);
|
|
645
|
-
this.isGroupSelected(r) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
|
|
646
|
-
} else {
|
|
647
|
-
const r = this.value.includes(t.value);
|
|
648
|
-
this.value = r ? this.value.filter((e) => e !== t.value) : [...this.value, t.value];
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
constructor(t) {
|
|
652
|
-
super(t, false);
|
|
653
|
-
const { options: r } = t;
|
|
654
|
-
this.#t = t.selectableGroups !== false, this.options = Object.entries(r).flatMap(([e, s]) => [{
|
|
655
|
-
value: e,
|
|
656
|
-
group: true,
|
|
657
|
-
label: e
|
|
658
|
-
}, ...s.map((i) => ({
|
|
659
|
-
...i,
|
|
660
|
-
group: e
|
|
661
|
-
}))]), this.value = [...t.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
|
|
662
|
-
switch (e) {
|
|
663
|
-
case "left":
|
|
664
|
-
case "up": {
|
|
665
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
666
|
-
const s = this.options[this.cursor]?.group === true;
|
|
667
|
-
!this.#t && s && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
668
|
-
break;
|
|
669
|
-
}
|
|
670
|
-
case "down":
|
|
671
|
-
case "right": {
|
|
672
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
673
|
-
const s = this.options[this.cursor]?.group === true;
|
|
674
|
-
!this.#t && s && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
675
|
-
break;
|
|
676
|
-
}
|
|
677
|
-
case "space":
|
|
678
|
-
this.toggleValue();
|
|
679
|
-
break;
|
|
680
|
-
}
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
};
|
|
684
630
|
var a = class extends V {
|
|
685
631
|
options;
|
|
686
632
|
cursor = 0;
|
|
@@ -755,4 +701,4 @@ let n$1 = class n extends V {
|
|
|
755
701
|
});
|
|
756
702
|
}
|
|
757
703
|
};
|
|
758
|
-
export { a, block, fastStringWidth, getColumns, getRows, isCancel, n$1, r, require_src, settings,
|
|
704
|
+
export { a, block, fastStringWidth, getColumns, getRows, isCancel, n$1, r, require_src, settings, wrapAnsi, wrapTextWithPrefix };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a, block, fastStringWidth, getColumns, getRows, n$1, r, require_src, settings,
|
|
1
|
+
import { a, block, fastStringWidth, getColumns, getRows, n$1, r, require_src, settings, wrapAnsi, wrapTextWithPrefix } from "./core.mjs";
|
|
2
2
|
import { styleText } from "node:util";
|
|
3
3
|
import process$1 from "node:process";
|
|
4
4
|
var import_src = require_src();
|
|
@@ -213,100 +213,6 @@ ${h}
|
|
|
213
213
|
}
|
|
214
214
|
}).prompt();
|
|
215
215
|
};
|
|
216
|
-
const groupMultiselect = (o) => {
|
|
217
|
-
const { selectableGroups: h = true, groupSpacing: x = 0 } = o, m = (n, l, g = []) => {
|
|
218
|
-
const a = n.label ?? String(n.value), t = typeof n.group == "string", s = t && (g[g.indexOf(n) + 1] ?? { group: true }), u = t && s && s.group === true;
|
|
219
|
-
let r = "", c = "";
|
|
220
|
-
t && (h ? (r = u ? `${S_BAR_END} ` : `${S_BAR} `, c = u ? " " : `${S_BAR} `) : r = " ");
|
|
221
|
-
let i = "";
|
|
222
|
-
if (x > 0 && !t && (i = `
|
|
223
|
-
`.repeat(x)), l === "active") return wrapTextWithPrefix(o.output, `${a}${n.hint ? ` ${styleText("dim", `(${n.hint})`)}` : ""}`, `${i}${styleText("dim", r)} `, `${i}${styleText("dim", r)}${styleText("cyan", S_CHECKBOX_ACTIVE)} `, `${i}${styleText("dim", c)} `);
|
|
224
|
-
if (l === "group-active") return wrapTextWithPrefix(o.output, a, `${i}${r} `, `${i}${r}${styleText("cyan", S_CHECKBOX_ACTIVE)} `, `${i}${c} `, (d) => styleText("dim", d));
|
|
225
|
-
if (l === "group-active-selected") return wrapTextWithPrefix(o.output, a, `${i}${r} `, `${i}${r}${styleText("green", S_CHECKBOX_SELECTED)} `, `${i}${c} `, (d) => styleText("dim", d));
|
|
226
|
-
if (l === "selected") {
|
|
227
|
-
const d = t || h ? styleText("green", S_CHECKBOX_SELECTED) : "";
|
|
228
|
-
return wrapTextWithPrefix(o.output, `${a}${n.hint ? ` (${n.hint})` : ""}`, `${i}${styleText("dim", r)} `, `${i}${styleText("dim", r)}${d} `, `${i}${styleText("dim", c)} `, (S) => styleText("dim", S));
|
|
229
|
-
}
|
|
230
|
-
if (l === "cancelled") return `${styleText(["strikethrough", "dim"], a)}`;
|
|
231
|
-
if (l === "active-selected") return wrapTextWithPrefix(o.output, `${a}${n.hint ? ` ${styleText("dim", `(${n.hint})`)}` : ""}`, `${i}${styleText("dim", r)} `, `${i}${styleText("dim", r)}${styleText("green", S_CHECKBOX_SELECTED)} `, `${i}${styleText("dim", c)} `);
|
|
232
|
-
if (l === "submitted") return `${styleText("dim", a)}`;
|
|
233
|
-
const f = t || h ? styleText("dim", S_CHECKBOX_INACTIVE) : "";
|
|
234
|
-
return wrapTextWithPrefix(o.output, a, `${i}${styleText("dim", r)} `, `${i}${styleText("dim", r)}${f} `, `${i}${styleText("dim", c)} `, (d) => styleText("dim", d));
|
|
235
|
-
}, y = o.required ?? true, I = o.showInstructions ?? true;
|
|
236
|
-
return new u$2({
|
|
237
|
-
options: o.options,
|
|
238
|
-
signal: o.signal,
|
|
239
|
-
input: o.input,
|
|
240
|
-
output: o.output,
|
|
241
|
-
initialValues: o.initialValues,
|
|
242
|
-
required: y,
|
|
243
|
-
cursorAt: o.cursorAt,
|
|
244
|
-
selectableGroups: h,
|
|
245
|
-
validate(n) {
|
|
246
|
-
if (y && (n === void 0 || n.length === 0)) return `Please select at least one option.
|
|
247
|
-
${styleText("reset", styleText("dim", `Press ${styleText([
|
|
248
|
-
"gray",
|
|
249
|
-
"bgWhite",
|
|
250
|
-
"inverse"
|
|
251
|
-
], " space ")} to select, ${styleText("gray", styleText(["bgWhite", "inverse"], " enter "))} to submit`))}`;
|
|
252
|
-
},
|
|
253
|
-
render() {
|
|
254
|
-
const n = o.withGuide ?? settings.withGuide, l = `${n ? `${styleText("gray", S_BAR)}
|
|
255
|
-
` : ""}${symbol(this.state)} ${o.message}
|
|
256
|
-
`, g = this.value ?? [], a = (t, s) => {
|
|
257
|
-
const u = this.options, r = g.includes(t.value) || t.group === true && this.isGroupSelected(`${t.value}`);
|
|
258
|
-
return !s && typeof t.group == "string" && this.options[this.cursor]?.value === t.group ? m(t, r ? "group-active-selected" : "group-active", u) : s && r ? m(t, "active-selected", u) : r ? m(t, "selected", u) : m(t, s ? "active" : "inactive", u);
|
|
259
|
-
};
|
|
260
|
-
switch (this.state) {
|
|
261
|
-
case "submit": {
|
|
262
|
-
const t = this.options.filter(({ value: u }) => g.includes(u)).map((u) => m(u, "submitted")), s = t.length === 0 ? "" : ` ${t.join(styleText("dim", ", "))}`;
|
|
263
|
-
return `${l}${n ? styleText("gray", S_BAR) : ""}${s}`;
|
|
264
|
-
}
|
|
265
|
-
case "cancel": {
|
|
266
|
-
const t = this.options.filter(({ value: s }) => g.includes(s)).map((s) => m(s, "cancelled")).join(styleText("dim", ", "));
|
|
267
|
-
return `${l}${n ? `${styleText("gray", S_BAR)} ` : ""}${t.trim() ? `${t}${n ? `
|
|
268
|
-
${styleText("gray", S_BAR)}` : ""}` : ""}`;
|
|
269
|
-
}
|
|
270
|
-
case "error": {
|
|
271
|
-
const t = n ? `${styleText("yellow", S_BAR)} ` : "", s = this.error.split(`
|
|
272
|
-
`).map((i, f) => f === 0 ? `${n ? `${styleText("yellow", S_BAR_END)} ` : ""}${styleText("yellow", i)}` : ` ${i}`).join(`
|
|
273
|
-
`), u = l.split(`
|
|
274
|
-
`).length, r = s.split(`
|
|
275
|
-
`).length + 1;
|
|
276
|
-
return `${l}${t}${limitOptions({
|
|
277
|
-
output: o.output,
|
|
278
|
-
options: this.options,
|
|
279
|
-
cursor: this.cursor,
|
|
280
|
-
maxItems: o.maxItems,
|
|
281
|
-
columnPadding: t.length,
|
|
282
|
-
rowPadding: u + r,
|
|
283
|
-
style: a
|
|
284
|
-
}).join(`
|
|
285
|
-
${t}`)}
|
|
286
|
-
${s}
|
|
287
|
-
`;
|
|
288
|
-
}
|
|
289
|
-
default: {
|
|
290
|
-
const t = n ? `${styleText("cyan", S_BAR)} ` : "", s = l.split(`
|
|
291
|
-
`).length, u = I ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS, n) : n ? [styleText("cyan", S_BAR_END)] : [], r = u.join(`
|
|
292
|
-
`), c = u.length + 1;
|
|
293
|
-
return `${l}${t}${limitOptions({
|
|
294
|
-
output: o.output,
|
|
295
|
-
options: this.options,
|
|
296
|
-
cursor: this.cursor,
|
|
297
|
-
maxItems: o.maxItems,
|
|
298
|
-
columnPadding: t.length,
|
|
299
|
-
rowPadding: s + c,
|
|
300
|
-
style: a
|
|
301
|
-
}).join(`
|
|
302
|
-
${t}`)}
|
|
303
|
-
${r}
|
|
304
|
-
`;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}).prompt();
|
|
309
|
-
};
|
|
310
216
|
const log = {
|
|
311
217
|
message: (s = [], { symbol: e = styleText("gray", S_BAR), secondarySymbol: r = styleText("gray", S_BAR), output: m = process.stdout, spacing: l = 1, withGuide: c } = {}) => {
|
|
312
218
|
const t = [], o = c ?? settings.withGuide, f = o ? r : "", O = o ? `${e} ` : "", u = o ? `${r} ` : "";
|
|
@@ -536,4 +442,4 @@ ${b}
|
|
|
536
442
|
}).prompt();
|
|
537
443
|
};
|
|
538
444
|
`${styleText("gray", S_BAR)}`;
|
|
539
|
-
export { cancel, confirm,
|
|
445
|
+
export { cancel, confirm, intro, log, multiselect, note, outro, select, spinner };
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { __toESM } from "./_chunks/rolldown-runtime.mjs";
|
|
3
3
|
import { isCancel } from "./_chunks/libs/@clack/core.mjs";
|
|
4
|
-
import { cancel, confirm,
|
|
4
|
+
import { cancel, confirm, intro, log, multiselect as multiselect$1, note, outro, select, spinner } from "./_chunks/libs/@clack/prompts.mjs";
|
|
5
5
|
import { require_picocolors } from "./_chunks/libs/picocolors.mjs";
|
|
6
6
|
import { esm_default } from "./_chunks/libs/simple-git.mjs";
|
|
7
7
|
import { xdgConfig } from "./_chunks/libs/xdg-basedir.mjs";
|
|
@@ -9,7 +9,6 @@ import { require_dist } from "./_chunks/libs/@vercel/detect-agent.mjs";
|
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "fs";
|
|
10
10
|
import { basename, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "path";
|
|
11
11
|
import { fileURLToPath } from "url";
|
|
12
|
-
import { createHash } from "node:crypto";
|
|
13
12
|
import { stripVTControlCharacters } from "node:util";
|
|
14
13
|
import { homedir, platform, tmpdir } from "os";
|
|
15
14
|
import * as readline from "readline";
|
|
@@ -18,7 +17,8 @@ import { promisify } from "util";
|
|
|
18
17
|
import { execFile, execSync, spawn, spawnSync } from "child_process";
|
|
19
18
|
import { access, chmod, cp, lstat, mkdir, mkdtemp, readFile, readdir, readlink, realpath, rm, stat, symlink, writeFile } from "fs/promises";
|
|
20
19
|
import { parse } from "yaml";
|
|
21
|
-
import { createHash
|
|
20
|
+
import { createHash } from "crypto";
|
|
21
|
+
import { createHash as createHash$1 } from "node:crypto";
|
|
22
22
|
import { gunzipSync, inflateRawSync } from "node:zlib";
|
|
23
23
|
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
24
24
|
function getOwnerRepo(parsed) {
|
|
@@ -71,7 +71,10 @@ function sanitizeSubpath(subpath) {
|
|
|
71
71
|
function isLocalPath(input) {
|
|
72
72
|
return isAbsolute(input) || input.startsWith("./") || input.startsWith("../") || input === "." || input === ".." || /^[a-zA-Z]:[/\\]/.test(input);
|
|
73
73
|
}
|
|
74
|
-
const SOURCE_ALIASES = {
|
|
74
|
+
const SOURCE_ALIASES = {
|
|
75
|
+
"coinbase/agentWallet": "coinbase/agentic-wallet-skills",
|
|
76
|
+
"vercel-labs/vercel-skills": "vercel-labs/agent-skills"
|
|
77
|
+
};
|
|
75
78
|
function decodeFragmentValue(value) {
|
|
76
79
|
try {
|
|
77
80
|
return decodeURIComponent(value);
|
|
@@ -277,8 +280,88 @@ function countVisualRowsForLines(lines, columns) {
|
|
|
277
280
|
const cols = columns !== void 0 && columns > 0 ? columns : process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 80;
|
|
278
281
|
return lines.reduce((sum, line) => sum + visualRowsForLine(line, cols), 0);
|
|
279
282
|
}
|
|
283
|
+
function truncateToWidth(text, width) {
|
|
284
|
+
let truncated = "";
|
|
285
|
+
for (const char of text) {
|
|
286
|
+
if (approxStringWidth(truncated + char) > width) break;
|
|
287
|
+
truncated += char;
|
|
288
|
+
}
|
|
289
|
+
return truncated;
|
|
290
|
+
}
|
|
291
|
+
function formatDetailLines(detail, width, maxLines) {
|
|
292
|
+
const safeWidth = Math.max(1, width);
|
|
293
|
+
const normalized = detail?.replace(/\s+/g, " ").trim() ?? "";
|
|
294
|
+
const lines = [];
|
|
295
|
+
let remaining = normalized;
|
|
296
|
+
while (remaining && lines.length < maxLines) {
|
|
297
|
+
if (approxStringWidth(remaining) <= safeWidth) {
|
|
298
|
+
lines.push(remaining);
|
|
299
|
+
remaining = "";
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
const candidate = truncateToWidth(remaining, safeWidth);
|
|
303
|
+
const breakAt = candidate.lastIndexOf(" ");
|
|
304
|
+
if (breakAt > 0) {
|
|
305
|
+
lines.push(candidate.slice(0, breakAt).trimEnd());
|
|
306
|
+
remaining = remaining.slice(breakAt).trimStart();
|
|
307
|
+
} else {
|
|
308
|
+
lines.push(candidate);
|
|
309
|
+
remaining = remaining.slice(candidate.length).trimStart();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (remaining && lines.length > 0) {
|
|
313
|
+
const last = lines.length - 1;
|
|
314
|
+
lines[last] = `${truncateToWidth(lines[last], Math.max(0, safeWidth - 1)).trimEnd()}…`;
|
|
315
|
+
}
|
|
316
|
+
while (lines.length < maxLines) lines.push("");
|
|
317
|
+
return lines;
|
|
318
|
+
}
|
|
319
|
+
function buildSearchEntries(items, selectGroups, collapsedGroups = /* @__PURE__ */ new Set()) {
|
|
320
|
+
if (!selectGroups) return items.map((item) => ({
|
|
321
|
+
type: "item",
|
|
322
|
+
item
|
|
323
|
+
}));
|
|
324
|
+
const entries = [];
|
|
325
|
+
let index = 0;
|
|
326
|
+
while (index < items.length) {
|
|
327
|
+
const item = items[index];
|
|
328
|
+
if (!item.group) {
|
|
329
|
+
entries.push({
|
|
330
|
+
type: "item",
|
|
331
|
+
item
|
|
332
|
+
});
|
|
333
|
+
index += 1;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const groupItems = [];
|
|
337
|
+
while (index < items.length && items[index].group === item.group) {
|
|
338
|
+
groupItems.push(items[index]);
|
|
339
|
+
index += 1;
|
|
340
|
+
}
|
|
341
|
+
const collapsed = collapsedGroups.has(item.group);
|
|
342
|
+
entries.push({
|
|
343
|
+
type: "group",
|
|
344
|
+
group: item.group,
|
|
345
|
+
items: groupItems,
|
|
346
|
+
collapsed
|
|
347
|
+
});
|
|
348
|
+
if (!collapsed) entries.push(...groupItems.map((groupItem) => ({
|
|
349
|
+
type: "item",
|
|
350
|
+
item: groupItem
|
|
351
|
+
})));
|
|
352
|
+
}
|
|
353
|
+
return entries;
|
|
354
|
+
}
|
|
355
|
+
function toggleSearchEntry(selected, entry) {
|
|
356
|
+
if (entry?.type === "group") {
|
|
357
|
+
const allSelected = entry.items.every((item) => selected.has(item.value));
|
|
358
|
+
for (const item of entry.items) if (allSelected) selected.delete(item.value);
|
|
359
|
+
else selected.add(item.value);
|
|
360
|
+
} else if (entry?.type === "item") if (selected.has(entry.item.value)) selected.delete(entry.item.value);
|
|
361
|
+
else selected.add(entry.item.value);
|
|
362
|
+
}
|
|
280
363
|
async function searchMultiselect(options) {
|
|
281
|
-
const { message, items, maxVisible = 8, initialSelected = [], required = false, lockedSection } = options;
|
|
364
|
+
const { message, items, maxVisible = 8, initialSelected = [], required = false, lockedSection, searchable = true, showDetail = false, detailLines = 2, showSelectedSummary = true, selectGroups = false } = options;
|
|
282
365
|
return new Promise((resolve) => {
|
|
283
366
|
const rl = readline.createInterface({
|
|
284
367
|
input: process.stdin,
|
|
@@ -290,6 +373,7 @@ async function searchMultiselect(options) {
|
|
|
290
373
|
let query = "";
|
|
291
374
|
let cursor = 0;
|
|
292
375
|
const selected = new Set(initialSelected);
|
|
376
|
+
const collapsedGroups = /* @__PURE__ */ new Set();
|
|
293
377
|
let lastRenderHeight = 0;
|
|
294
378
|
const lockedValues = lockedSection ? lockedSection.items.map((i) => i.value) : [];
|
|
295
379
|
const filter = (item, q) => {
|
|
@@ -300,17 +384,10 @@ async function searchMultiselect(options) {
|
|
|
300
384
|
const getFiltered = () => {
|
|
301
385
|
return items.filter((item) => filter(item, query));
|
|
302
386
|
};
|
|
303
|
-
const clearRender = () => {
|
|
304
|
-
if (lastRenderHeight > 0) {
|
|
305
|
-
process.stdout.write(`\x1b[${lastRenderHeight}A`);
|
|
306
|
-
for (let i = 0; i < lastRenderHeight; i++) process.stdout.write("\x1B[2K\x1B[1B");
|
|
307
|
-
process.stdout.write(`\x1b[${lastRenderHeight}A`);
|
|
308
|
-
}
|
|
309
|
-
};
|
|
310
387
|
const render = (state = "active") => {
|
|
311
|
-
clearRender();
|
|
312
388
|
const lines = [];
|
|
313
389
|
const filtered = getFiltered();
|
|
390
|
+
const entries = buildSearchEntries(filtered, selectGroups, collapsedGroups);
|
|
314
391
|
const icon = state === "active" ? S_STEP_ACTIVE : state === "cancel" ? S_STEP_CANCEL : S_STEP_SUBMIT;
|
|
315
392
|
lines.push(`${icon} ${import_picocolors.default.bold(message)}`);
|
|
316
393
|
if (state === "active") {
|
|
@@ -319,32 +396,45 @@ async function searchMultiselect(options) {
|
|
|
319
396
|
const lockedTitle = `${import_picocolors.default.bold(lockedSection.title)} ${import_picocolors.default.dim("── always included")}`;
|
|
320
397
|
lines.push(`${S_BAR} ${S_BAR_H}${S_BAR_H} ${lockedTitle} ${S_BAR_H.repeat(12)}`);
|
|
321
398
|
for (const item of lockedSection.items) lines.push(`${S_BAR} ${S_BULLET} ${import_picocolors.default.bold(item.label)}`);
|
|
322
|
-
if (lockedSection.hiddenCount && lockedSection.hiddenCount > 0) lines.push(`${S_BAR} ${import_picocolors.default.dim(
|
|
399
|
+
if (lockedSection.hiddenCount && lockedSection.hiddenCount > 0) lines.push(`${S_BAR} ${import_picocolors.default.dim(`…and ${lockedSection.hiddenCount} more`)}`);
|
|
323
400
|
lines.push(`${S_BAR}`);
|
|
324
401
|
lines.push(`${S_BAR} ${S_BAR_H}${S_BAR_H} ${import_picocolors.default.bold("Additional agents")} ${S_BAR_H.repeat(29)}`);
|
|
325
402
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const
|
|
403
|
+
if (searchable) {
|
|
404
|
+
const searchLine = `${S_BAR} ${import_picocolors.default.dim("Search:")} ${query}${import_picocolors.default.inverse(" ")}`;
|
|
405
|
+
lines.push(searchLine);
|
|
406
|
+
lines.push(`${S_BAR} ${import_picocolors.default.dim("↑↓ move, space select, enter confirm")}`);
|
|
407
|
+
lines.push(`${S_BAR}`);
|
|
408
|
+
}
|
|
409
|
+
const visibleStart = Math.max(0, Math.min(cursor - Math.floor(maxVisible / 2), entries.length - maxVisible));
|
|
410
|
+
const visibleEnd = Math.min(entries.length, visibleStart + maxVisible);
|
|
411
|
+
const visibleEntries = entries.slice(visibleStart, visibleEnd);
|
|
333
412
|
if (filtered.length === 0) lines.push(`${S_BAR} ${import_picocolors.default.dim("No matches found")}`);
|
|
334
413
|
else {
|
|
335
|
-
for (let i = 0; i <
|
|
336
|
-
const
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
414
|
+
for (let i = 0; i < visibleEntries.length; i++) {
|
|
415
|
+
const entry = visibleEntries[i];
|
|
416
|
+
const isCursor = visibleStart + i === cursor;
|
|
417
|
+
if (entry.type === "group") {
|
|
418
|
+
const selectedCount = entry.items.filter((item) => selected.has(item.value)).length;
|
|
419
|
+
const radio = selectedCount === entry.items.length ? S_RADIO_ACTIVE : selectedCount > 0 ? import_picocolors.default.yellow("◐") : S_RADIO_INACTIVE;
|
|
420
|
+
const label = isCursor ? import_picocolors.default.underline(import_picocolors.default.bold(entry.group)) : import_picocolors.default.bold(entry.group);
|
|
421
|
+
const prefix = isCursor ? import_picocolors.default.cyan("❯") : " ";
|
|
422
|
+
const disclosure = import_picocolors.default.dim(entry.collapsed ? "▸" : "▾");
|
|
423
|
+
lines.push(`${S_BAR} ${prefix} ${disclosure} ${radio} ${label}`);
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
const item = entry.item;
|
|
427
|
+
const radio = selected.has(item.value) ? S_RADIO_ACTIVE : S_RADIO_INACTIVE;
|
|
341
428
|
const label = isCursor ? import_picocolors.default.underline(item.label) : item.label;
|
|
342
429
|
const hint = item.hint ? import_picocolors.default.dim(` (${item.hint})`) : "";
|
|
343
430
|
const prefix = isCursor ? import_picocolors.default.cyan("❯") : " ";
|
|
344
|
-
|
|
431
|
+
const groupItems = selectGroups && item.group ? filtered.filter((i) => i.group === item.group) : [];
|
|
432
|
+
const isLastInGroup = groupItems.at(-1) === item;
|
|
433
|
+
const tree = groupItems.length > 0 ? `${import_picocolors.default.dim(isLastInGroup ? "└─" : "├─")} ` : "";
|
|
434
|
+
lines.push(`${S_BAR} ${prefix} ${tree}${radio} ${label}${hint}`);
|
|
345
435
|
}
|
|
346
436
|
const hiddenBefore = visibleStart;
|
|
347
|
-
const hiddenAfter =
|
|
437
|
+
const hiddenAfter = entries.length - visibleEnd;
|
|
348
438
|
if (hiddenBefore > 0 || hiddenAfter > 0) {
|
|
349
439
|
const parts = [];
|
|
350
440
|
if (hiddenBefore > 0) parts.push(`↑ ${hiddenBefore} more`);
|
|
@@ -352,19 +442,35 @@ async function searchMultiselect(options) {
|
|
|
352
442
|
lines.push(`${S_BAR} ${import_picocolors.default.dim(parts.join(" "))}`);
|
|
353
443
|
}
|
|
354
444
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const
|
|
360
|
-
lines.push(`${S_BAR}
|
|
445
|
+
if (showDetail) {
|
|
446
|
+
const entry = entries[cursor];
|
|
447
|
+
const detail = entry?.type === "group" ? `Select all ${entry.items.length} skills in ${entry.group}.` : entry?.item.detail;
|
|
448
|
+
const columns = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 80;
|
|
449
|
+
const detailWidth = Math.max(1, columns - 5);
|
|
450
|
+
lines.push(`${S_BAR}`);
|
|
451
|
+
lines.push(`${S_BAR} ${import_picocolors.default.dim("Description")}`);
|
|
452
|
+
for (const line of formatDetailLines(detail, detailWidth, detailLines)) lines.push(`${S_BAR} ${import_picocolors.default.dim(line)}`);
|
|
453
|
+
}
|
|
454
|
+
if (showSelectedSummary) {
|
|
455
|
+
lines.push(`${S_BAR}`);
|
|
456
|
+
const allSelectedLabels = [...lockedSection ? lockedSection.items.map((i) => i.label) : [], ...items.filter((item) => selected.has(item.value)).map((item) => item.label)];
|
|
457
|
+
if (allSelectedLabels.length === 0) lines.push(`${S_BAR} ${import_picocolors.default.dim("Selected: (none)")}`);
|
|
458
|
+
else {
|
|
459
|
+
const summary = allSelectedLabels.length <= 3 ? allSelectedLabels.join(", ") : `${allSelectedLabels.slice(0, 3).join(", ")} +${allSelectedLabels.length - 3} more`;
|
|
460
|
+
lines.push(`${S_BAR} ${import_picocolors.default.green("Selected:")} ${summary}`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (!searchable) {
|
|
464
|
+
lines.push(`${S_BAR}`);
|
|
465
|
+
lines.push(`${S_BAR} ${import_picocolors.default.dim("↑↓ move, ←→ collapse/expand, space select, enter confirm")}`);
|
|
361
466
|
}
|
|
362
467
|
lines.push(`${import_picocolors.default.dim("└")}`);
|
|
363
468
|
} else if (state === "submit") {
|
|
364
469
|
const allSelectedLabels = [...lockedSection ? lockedSection.items.map((i) => i.label) : [], ...items.filter((item) => selected.has(item.value)).map((item) => item.label)];
|
|
365
470
|
lines.push(`${S_BAR} ${import_picocolors.default.dim(allSelectedLabels.join(", "))}`);
|
|
366
471
|
} else if (state === "cancel") lines.push(`${S_BAR} ${import_picocolors.default.strikethrough(import_picocolors.default.dim("Cancelled"))}`);
|
|
367
|
-
|
|
472
|
+
const clearPreviousFrame = lastRenderHeight > 0 ? `\x1b[${lastRenderHeight}A\x1b[J` : "";
|
|
473
|
+
process.stdout.write(clearPreviousFrame + lines.join("\n") + "\n");
|
|
368
474
|
lastRenderHeight = countVisualRowsForLines(lines, process.stdout.columns);
|
|
369
475
|
};
|
|
370
476
|
const cleanup = () => {
|
|
@@ -385,7 +491,7 @@ async function searchMultiselect(options) {
|
|
|
385
491
|
};
|
|
386
492
|
const keypressHandler = (_str, key) => {
|
|
387
493
|
if (!key) return;
|
|
388
|
-
const
|
|
494
|
+
const entries = buildSearchEntries(getFiltered(), selectGroups, collapsedGroups);
|
|
389
495
|
if (key.name === "return") {
|
|
390
496
|
submit();
|
|
391
497
|
return;
|
|
@@ -400,14 +506,31 @@ async function searchMultiselect(options) {
|
|
|
400
506
|
return;
|
|
401
507
|
}
|
|
402
508
|
if (key.name === "down") {
|
|
403
|
-
cursor = Math.min(
|
|
509
|
+
cursor = Math.min(entries.length - 1, cursor + 1);
|
|
404
510
|
render();
|
|
405
511
|
return;
|
|
406
512
|
}
|
|
513
|
+
if (selectGroups && key.name === "right") {
|
|
514
|
+
const entry = entries[cursor];
|
|
515
|
+
if (entry?.type === "group" && entry.collapsed) {
|
|
516
|
+
collapsedGroups.delete(entry.group);
|
|
517
|
+
render();
|
|
518
|
+
}
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
if (selectGroups && key.name === "left") {
|
|
522
|
+
const entry = entries[cursor];
|
|
523
|
+
const group = entry?.type === "group" ? entry.group : entry?.item.group;
|
|
524
|
+
if (group) {
|
|
525
|
+
collapsedGroups.add(group);
|
|
526
|
+
cursor = buildSearchEntries(getFiltered(), selectGroups, collapsedGroups).findIndex((collapsedEntry) => collapsedEntry.type === "group" && collapsedEntry.group === group);
|
|
527
|
+
render();
|
|
528
|
+
}
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
407
531
|
if (key.name === "space") {
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
else selected.add(item.value);
|
|
532
|
+
const entry = entries[cursor];
|
|
533
|
+
toggleSearchEntry(selected, entry);
|
|
411
534
|
render();
|
|
412
535
|
return;
|
|
413
536
|
}
|
|
@@ -417,7 +540,7 @@ async function searchMultiselect(options) {
|
|
|
417
540
|
render();
|
|
418
541
|
return;
|
|
419
542
|
}
|
|
420
|
-
if (key.sequence && !key.ctrl && !key.meta && key.sequence.length === 1) {
|
|
543
|
+
if (searchable && key.sequence && !key.ctrl && !key.meta && key.sequence.length === 1) {
|
|
421
544
|
query += key.sequence;
|
|
422
545
|
cursor = 0;
|
|
423
546
|
render();
|
|
@@ -429,6 +552,7 @@ async function searchMultiselect(options) {
|
|
|
429
552
|
});
|
|
430
553
|
}
|
|
431
554
|
const DEFAULT_CLONE_TIMEOUT_MS = 3e5;
|
|
555
|
+
const ALLOWED_GIT_PROTOCOLS = "https:http:ssh:git:file";
|
|
432
556
|
const CLONE_TIMEOUT_MS = (() => {
|
|
433
557
|
const raw = process.env.SKILLS_CLONE_TIMEOUT_MS;
|
|
434
558
|
if (!raw) return DEFAULT_CLONE_TIMEOUT_MS;
|
|
@@ -492,23 +616,45 @@ function isGitHubSsoAuthError(message) {
|
|
|
492
616
|
function isAuthFailure(message) {
|
|
493
617
|
return message.includes("Authentication failed") || message.includes("could not read Username") || message.includes("Permission denied") || message.includes("Repository not found") || message.includes("requested URL returned error: 403") || isGitHubSsoAuthError(message);
|
|
494
618
|
}
|
|
495
|
-
function createGitClient(
|
|
496
|
-
|
|
619
|
+
function createGitClient(sshCommand) {
|
|
620
|
+
const git = esm_default({
|
|
497
621
|
timeout: { block: CLONE_TIMEOUT_MS },
|
|
498
|
-
env: {
|
|
499
|
-
...process.env,
|
|
500
|
-
GIT_TERMINAL_PROMPT: "0",
|
|
501
|
-
GIT_LFS_SKIP_SMUDGE: "1",
|
|
502
|
-
...extraEnv
|
|
503
|
-
},
|
|
504
622
|
config: [
|
|
505
623
|
"filter.lfs.required=false",
|
|
506
624
|
"filter.lfs.smudge=",
|
|
507
625
|
"filter.lfs.clean=",
|
|
508
626
|
"filter.lfs.process="
|
|
509
627
|
],
|
|
510
|
-
unsafe: {
|
|
628
|
+
unsafe: {
|
|
629
|
+
allowUnsafeAlias: true,
|
|
630
|
+
allowUnsafeAskPass: true,
|
|
631
|
+
allowUnsafeConfigEnvCount: true,
|
|
632
|
+
allowUnsafeConfigPaths: true,
|
|
633
|
+
allowUnsafeCredentialHelper: true,
|
|
634
|
+
allowUnsafeDiffExternal: true,
|
|
635
|
+
allowUnsafeDiffTextConv: true,
|
|
636
|
+
allowUnsafeEditor: true,
|
|
637
|
+
allowUnsafeFilter: true,
|
|
638
|
+
allowUnsafeFsMonitor: true,
|
|
639
|
+
allowUnsafeGpgProgram: true,
|
|
640
|
+
allowUnsafeGitProxy: true,
|
|
641
|
+
allowUnsafeHooksPath: true,
|
|
642
|
+
allowUnsafeMergeDriver: true,
|
|
643
|
+
allowUnsafePack: true,
|
|
644
|
+
allowUnsafePager: true,
|
|
645
|
+
allowUnsafeProtocolOverride: true,
|
|
646
|
+
allowUnsafeSshCommand: true,
|
|
647
|
+
allowUnsafeTemplateDir: true
|
|
648
|
+
}
|
|
511
649
|
});
|
|
650
|
+
git.env({
|
|
651
|
+
...process.env,
|
|
652
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
653
|
+
GIT_ALLOW_PROTOCOL: ALLOWED_GIT_PROTOCOLS,
|
|
654
|
+
GIT_LFS_SKIP_SMUDGE: "1",
|
|
655
|
+
...sshCommand ? { GIT_SSH_COMMAND: sshCommand } : {}
|
|
656
|
+
});
|
|
657
|
+
return git;
|
|
512
658
|
}
|
|
513
659
|
async function resetTempDir(dir) {
|
|
514
660
|
await rm(dir, {
|
|
@@ -552,7 +698,8 @@ async function tryGhClone(repo, tempDir, ref) {
|
|
|
552
698
|
timeout: CLONE_TIMEOUT_MS,
|
|
553
699
|
env: {
|
|
554
700
|
...process.env,
|
|
555
|
-
GIT_TERMINAL_PROMPT: "0"
|
|
701
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
702
|
+
GIT_ALLOW_PROTOCOL: ALLOWED_GIT_PROTOCOLS
|
|
556
703
|
}
|
|
557
704
|
});
|
|
558
705
|
return true;
|
|
@@ -593,7 +740,7 @@ async function cloneRepo(url, ref) {
|
|
|
593
740
|
} catch {}
|
|
594
741
|
try {
|
|
595
742
|
await resetTempDir(tempDir);
|
|
596
|
-
await createGitClient(
|
|
743
|
+
await createGitClient(process.env.GIT_SSH_COMMAND ?? "ssh -o BatchMode=yes").clone(repo.sshUrl, tempDir, cloneOptions);
|
|
597
744
|
return tempDir;
|
|
598
745
|
} catch {}
|
|
599
746
|
}
|
|
@@ -721,7 +868,7 @@ async function computeSkillFolderHash(skillDir) {
|
|
|
721
868
|
const files = [];
|
|
722
869
|
await collectFiles(skillDir, skillDir, files);
|
|
723
870
|
files.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
724
|
-
const hash = createHash
|
|
871
|
+
const hash = createHash("sha256");
|
|
725
872
|
for (const file of files) {
|
|
726
873
|
hash.update(file.relativePath);
|
|
727
874
|
hash.update(file.content);
|
|
@@ -795,6 +942,9 @@ function normalizeSkillName(name) {
|
|
|
795
942
|
function normalizeRelativePath(path) {
|
|
796
943
|
return path.split(sep).join("/").replace(/\/+/g, "/");
|
|
797
944
|
}
|
|
945
|
+
function isRecord(value) {
|
|
946
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
947
|
+
}
|
|
798
948
|
function shouldInstallInternalSkills() {
|
|
799
949
|
const envValue = process.env.INSTALL_INTERNAL_SKILLS;
|
|
800
950
|
return envValue === "1" || envValue === "true";
|
|
@@ -812,13 +962,14 @@ async function parseSkillMd(skillMdPath, options) {
|
|
|
812
962
|
const { data } = parseFrontmatter(content);
|
|
813
963
|
if (!data.name || !data.description) return null;
|
|
814
964
|
if (typeof data.name !== "string" || typeof data.description !== "string") return null;
|
|
815
|
-
|
|
965
|
+
const metadata = isRecord(data.metadata) ? data.metadata : void 0;
|
|
966
|
+
if (metadata?.internal === true && !shouldInstallInternalSkills() && !options?.includeInternal) return null;
|
|
816
967
|
return {
|
|
817
968
|
name: sanitizeMetadata(data.name),
|
|
818
969
|
description: sanitizeMetadata(data.description),
|
|
819
970
|
path: dirname(skillMdPath),
|
|
820
971
|
rawContent: content,
|
|
821
|
-
metadata
|
|
972
|
+
metadata
|
|
822
973
|
};
|
|
823
974
|
} catch {
|
|
824
975
|
return null;
|
|
@@ -2680,7 +2831,7 @@ var WellKnownProvider = class {
|
|
|
2680
2831
|
}
|
|
2681
2832
|
}
|
|
2682
2833
|
computeDigest(bytes) {
|
|
2683
|
-
return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
2834
|
+
return `sha256:${createHash$1("sha256").update(bytes).digest("hex")}`;
|
|
2684
2835
|
}
|
|
2685
2836
|
extractArchive(bytes, artifactUrl, contentType) {
|
|
2686
2837
|
if (this.isZipArchive(bytes, artifactUrl, contentType)) return this.extractZip(bytes);
|
|
@@ -2849,7 +3000,7 @@ function getGitHubToken() {
|
|
|
2849
3000
|
if (process.env.GITHUB_TOKEN) return process.env.GITHUB_TOKEN;
|
|
2850
3001
|
if (process.env.GH_TOKEN) return process.env.GH_TOKEN;
|
|
2851
3002
|
if (!_ghWarningShown) {
|
|
2852
|
-
process.stderr.write(`${import_picocolors.default.
|
|
3003
|
+
process.stderr.write(`${import_picocolors.default.dim("│ GitHub API request limit reached; checking existing ")}${import_picocolors.default.cyan("gh")}${import_picocolors.default.dim(" authentication…\n")}`);
|
|
2853
3004
|
_ghWarningShown = true;
|
|
2854
3005
|
}
|
|
2855
3006
|
try {
|
|
@@ -3103,7 +3254,7 @@ async function fetchSkillDownload(source, slug) {
|
|
|
3103
3254
|
}
|
|
3104
3255
|
}
|
|
3105
3256
|
function computeSnapshotHash(files) {
|
|
3106
|
-
const hash = createHash("sha256");
|
|
3257
|
+
const hash = createHash$1("sha256");
|
|
3107
3258
|
for (const file of [...files].sort((a, b) => a.path.localeCompare(b.path))) {
|
|
3108
3259
|
hash.update(file.path);
|
|
3109
3260
|
hash.update(file.contents);
|
|
@@ -3183,7 +3334,7 @@ async function tryBlobInstall(ownerRepo, options = {}) {
|
|
|
3183
3334
|
tree
|
|
3184
3335
|
};
|
|
3185
3336
|
}
|
|
3186
|
-
var version$1 = "1.5.
|
|
3337
|
+
var version$1 = "1.5.19";
|
|
3187
3338
|
const isCancelled$1 = (value) => typeof value === "symbol";
|
|
3188
3339
|
const EVE_AGENT_LABEL = "eve agent";
|
|
3189
3340
|
async function isSourcePrivate(source) {
|
|
@@ -3254,12 +3405,6 @@ function shortenPath$2(fullPath, cwd) {
|
|
|
3254
3405
|
if (fullPath === cwd || fullPath.startsWith(cwd + sep)) return "." + fullPath.slice(cwd.length);
|
|
3255
3406
|
return fullPath;
|
|
3256
3407
|
}
|
|
3257
|
-
function computeSingleFileSkillHash(contents) {
|
|
3258
|
-
const hash = createHash("sha256");
|
|
3259
|
-
hash.update("SKILL.md");
|
|
3260
|
-
hash.update(contents);
|
|
3261
|
-
return hash.digest("hex");
|
|
3262
|
-
}
|
|
3263
3408
|
function formatList$1(items, maxShow = 5) {
|
|
3264
3409
|
if (items.length <= maxShow) return items.join(", ");
|
|
3265
3410
|
const shown = items.slice(0, maxShow);
|
|
@@ -3409,7 +3554,7 @@ async function selectAgentsInteractive(options) {
|
|
|
3409
3554
|
}
|
|
3410
3555
|
setVersion(version$1);
|
|
3411
3556
|
async function handleWellKnownSkills(source, url, options, spinner) {
|
|
3412
|
-
spinner.start("Discovering skills from well-known endpoint
|
|
3557
|
+
spinner.start("Discovering skills from well-known endpoint…");
|
|
3413
3558
|
const skills = await wellKnownProvider.fetchAllSkills(url);
|
|
3414
3559
|
if (skills.length === 0) {
|
|
3415
3560
|
spinner.stop(import_picocolors.default.red("No skills found"));
|
|
@@ -3459,7 +3604,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
3459
3604
|
options: skills.map((s) => ({
|
|
3460
3605
|
value: s,
|
|
3461
3606
|
label: s.installName,
|
|
3462
|
-
hint: s.description.length > 60 ? s.description.slice(0, 57) + "
|
|
3607
|
+
hint: s.description.length > 60 ? s.description.slice(0, 57) + "…" : s.description
|
|
3463
3608
|
})),
|
|
3464
3609
|
required: true
|
|
3465
3610
|
});
|
|
@@ -3483,7 +3628,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
3483
3628
|
}
|
|
3484
3629
|
targetAgents = options.agent;
|
|
3485
3630
|
} else {
|
|
3486
|
-
spinner.start("Loading agents
|
|
3631
|
+
spinner.start("Loading agents…");
|
|
3487
3632
|
const installedAgents = await detectInstalledAgents();
|
|
3488
3633
|
const totalAgents = Object.keys(agents).length;
|
|
3489
3634
|
spinner.stop(`${totalAgents} agents`);
|
|
@@ -3593,7 +3738,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
3593
3738
|
}
|
|
3594
3739
|
const sourceIdentifier = wellKnownProvider.getSourceIdentifier(url);
|
|
3595
3740
|
const wellKnownPrivacyPromise = isSourcePrivate(sourceIdentifier).catch(() => null);
|
|
3596
|
-
spinner.start("Installing skills
|
|
3741
|
+
spinner.start("Installing skills…");
|
|
3597
3742
|
const results = [];
|
|
3598
3743
|
for (const skill of selectedSkills) for (const agent of targetAgents) {
|
|
3599
3744
|
const result = await installWellKnownSkillForAgent(skill, agent, {
|
|
@@ -3735,7 +3880,7 @@ async function runAdd(args, options = {}) {
|
|
|
3735
3880
|
let tempDir = null;
|
|
3736
3881
|
try {
|
|
3737
3882
|
const spinner$3 = spinner();
|
|
3738
|
-
spinner$3.start("Parsing source
|
|
3883
|
+
spinner$3.start("Parsing source…");
|
|
3739
3884
|
const parsed = parseSource(source);
|
|
3740
3885
|
spinner$3.stop(`Source: ${parsed.type === "local" ? parsed.localPath : parsed.url}${parsed.ref ? ` @ ${import_picocolors.default.yellow(parsed.ref)}` : ""}${parsed.subpath ? ` (${parsed.subpath})` : ""}${parsed.skillFilter ? ` ${import_picocolors.default.dim("@")}${import_picocolors.default.cyan(parsed.skillFilter)}` : ""}`);
|
|
3741
3886
|
const ownerRepoRaw = getOwnerRepo(parsed);
|
|
@@ -3757,14 +3902,14 @@ async function runAdd(args, options = {}) {
|
|
|
3757
3902
|
let skills;
|
|
3758
3903
|
let blobResult = null;
|
|
3759
3904
|
if (parsed.type === "local") {
|
|
3760
|
-
spinner$3.start("Validating local path
|
|
3905
|
+
spinner$3.start("Validating local path…");
|
|
3761
3906
|
if (!existsSync(parsed.localPath)) {
|
|
3762
3907
|
spinner$3.stop(import_picocolors.default.red("Path not found"));
|
|
3763
3908
|
outro(import_picocolors.default.red(`Local path does not exist: ${parsed.localPath}`));
|
|
3764
3909
|
process.exit(1);
|
|
3765
3910
|
}
|
|
3766
3911
|
spinner$3.stop("Local path validated");
|
|
3767
|
-
spinner$3.start("Discovering skills
|
|
3912
|
+
spinner$3.start("Discovering skills…");
|
|
3768
3913
|
skills = await discoverSkills(parsed.localPath, parsed.subpath, {
|
|
3769
3914
|
includeInternal,
|
|
3770
3915
|
fullDepth: options.fullDepth
|
|
@@ -3779,7 +3924,7 @@ async function runAdd(args, options = {}) {
|
|
|
3779
3924
|
const owner = ownerRepo?.split("/")[0]?.toLowerCase();
|
|
3780
3925
|
const isSelfHostedRepo = !!ownerRepo && Object.hasOwn(BLOB_ALLOWED_REPOS, ownerRepo.toLowerCase());
|
|
3781
3926
|
if (ownerRepo && owner && (isSelfHostedRepo || BLOB_ALLOWED_OWNERS.includes(owner))) {
|
|
3782
|
-
spinner$3.start("Fetching skills
|
|
3927
|
+
spinner$3.start("Fetching skills…");
|
|
3783
3928
|
blobResult = await tryBlobInstall(ownerRepo, {
|
|
3784
3929
|
subpath: parsed.subpath,
|
|
3785
3930
|
skillFilter: parsed.skillFilter,
|
|
@@ -3787,26 +3932,26 @@ async function runAdd(args, options = {}) {
|
|
|
3787
3932
|
getToken: getGitHubToken,
|
|
3788
3933
|
includeInternal
|
|
3789
3934
|
});
|
|
3790
|
-
if (!blobResult) spinner$3.stop(import_picocolors.default.dim("Falling back to clone
|
|
3935
|
+
if (!blobResult) spinner$3.stop(import_picocolors.default.dim("Falling back to clone…"));
|
|
3791
3936
|
}
|
|
3792
3937
|
if (blobResult) {
|
|
3793
3938
|
skills = blobResult.skills;
|
|
3794
3939
|
spinner$3.stop(`Found ${import_picocolors.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
|
|
3795
3940
|
} else {
|
|
3796
|
-
spinner$3.start("Cloning repository
|
|
3941
|
+
spinner$3.start("Cloning repository…");
|
|
3797
3942
|
tempDir = await cloneRepo(parsed.url, parsed.ref);
|
|
3798
3943
|
spinner$3.stop("Repository cloned");
|
|
3799
|
-
spinner$3.start("Discovering skills
|
|
3944
|
+
spinner$3.start("Discovering skills…");
|
|
3800
3945
|
skills = await discoverSkills(tempDir, parsed.subpath, {
|
|
3801
3946
|
includeInternal,
|
|
3802
3947
|
fullDepth: options.fullDepth
|
|
3803
3948
|
});
|
|
3804
3949
|
}
|
|
3805
3950
|
} else {
|
|
3806
|
-
spinner$3.start("Cloning repository
|
|
3951
|
+
spinner$3.start("Cloning repository…");
|
|
3807
3952
|
tempDir = await cloneRepo(parsed.url, parsed.ref);
|
|
3808
3953
|
spinner$3.stop("Repository cloned");
|
|
3809
|
-
spinner$3.start("Discovering skills
|
|
3954
|
+
spinner$3.start("Discovering skills…");
|
|
3810
3955
|
skills = await discoverSkills(tempDir, parsed.subpath, {
|
|
3811
3956
|
includeInternal,
|
|
3812
3957
|
fullDepth: options.fullDepth
|
|
@@ -3881,34 +4026,24 @@ async function runAdd(args, options = {}) {
|
|
|
3881
4026
|
return getSkillDisplayName(a).localeCompare(getSkillDisplayName(b));
|
|
3882
4027
|
});
|
|
3883
4028
|
const hasGroups = sortedSkills.some((s) => s.pluginName);
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
required: true
|
|
3901
|
-
});
|
|
3902
|
-
} else selected = await multiselect({
|
|
3903
|
-
message: "Select skills to install",
|
|
3904
|
-
options: sortedSkills.map((s) => ({
|
|
3905
|
-
value: s,
|
|
3906
|
-
label: getSkillDisplayName(s),
|
|
3907
|
-
hint: s.description.length > 60 ? s.description.slice(0, 57) + "..." : s.description
|
|
3908
|
-
})),
|
|
3909
|
-
required: true
|
|
4029
|
+
const kebabToTitle = (s) => s.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
4030
|
+
const skillChoices = sortedSkills.map((s) => ({
|
|
4031
|
+
value: s,
|
|
4032
|
+
label: getSkillDisplayName(s),
|
|
4033
|
+
group: hasGroups ? s.pluginName ? kebabToTitle(s.pluginName) : "Other" : void 0,
|
|
4034
|
+
detail: s.description
|
|
4035
|
+
}));
|
|
4036
|
+
const selected = await searchMultiselect({
|
|
4037
|
+
message: hasGroups ? `Select skills to install ${import_picocolors.default.dim("(space to toggle)")}` : "Select skills to install",
|
|
4038
|
+
items: skillChoices,
|
|
4039
|
+
required: true,
|
|
4040
|
+
maxVisible: 20,
|
|
4041
|
+
searchable: !hasGroups,
|
|
4042
|
+
showDetail: true,
|
|
4043
|
+
showSelectedSummary: false,
|
|
4044
|
+
selectGroups: hasGroups
|
|
3910
4045
|
});
|
|
3911
|
-
if (
|
|
4046
|
+
if (isCancelled$1(selected)) {
|
|
3912
4047
|
cancel("Installation cancelled");
|
|
3913
4048
|
await cleanup(tempDir);
|
|
3914
4049
|
process.exit(0);
|
|
@@ -3932,7 +4067,7 @@ async function runAdd(args, options = {}) {
|
|
|
3932
4067
|
}
|
|
3933
4068
|
targetAgents = options.agent;
|
|
3934
4069
|
} else {
|
|
3935
|
-
spinner$3.start("Loading agents
|
|
4070
|
+
spinner$3.start("Loading agents…");
|
|
3936
4071
|
const installedAgents = await detectInstalledAgents();
|
|
3937
4072
|
const totalAgents = Object.keys(agents).length;
|
|
3938
4073
|
spinner$3.stop(`${totalAgents} agents`);
|
|
@@ -4135,7 +4270,7 @@ async function runAdd(args, options = {}) {
|
|
|
4135
4270
|
process.exit(0);
|
|
4136
4271
|
}
|
|
4137
4272
|
}
|
|
4138
|
-
spinner$3.start("Installing skills
|
|
4273
|
+
spinner$3.start("Installing skills…");
|
|
4139
4274
|
const results = [];
|
|
4140
4275
|
for (const skill of selectedSkills) for (const target of installTargets) {
|
|
4141
4276
|
const { agent, subagent } = target;
|
|
@@ -4150,17 +4285,7 @@ async function runAdd(args, options = {}) {
|
|
|
4150
4285
|
mode: installMode,
|
|
4151
4286
|
eveSubagent: subagent
|
|
4152
4287
|
});
|
|
4153
|
-
} else
|
|
4154
|
-
installName: skill.name,
|
|
4155
|
-
files: [{
|
|
4156
|
-
path: "SKILL.md",
|
|
4157
|
-
contents: skill.rawContent
|
|
4158
|
-
}]
|
|
4159
|
-
}, agent, {
|
|
4160
|
-
global: installGlobally,
|
|
4161
|
-
mode: installMode
|
|
4162
|
-
});
|
|
4163
|
-
else result = await installSkillForAgent(skill, agent, {
|
|
4288
|
+
} else result = await installSkillForAgent(skill, agent, {
|
|
4164
4289
|
global: installGlobally,
|
|
4165
4290
|
mode: installMode,
|
|
4166
4291
|
eveSubagent: subagent
|
|
@@ -4241,7 +4366,7 @@ async function runAdd(args, options = {}) {
|
|
|
4241
4366
|
for (const skill of selectedSkills) {
|
|
4242
4367
|
const skillDisplayName = getSkillDisplayName(skill);
|
|
4243
4368
|
if (successfulSkillNames.has(skillDisplayName)) try {
|
|
4244
|
-
const computedHash = blobResult && "snapshotHash" in skill ? skill.snapshotHash :
|
|
4369
|
+
const computedHash = blobResult && "snapshotHash" in skill ? skill.snapshotHash : await computeSkillFolderHash(skill.path);
|
|
4245
4370
|
const skillPathValue = skillFiles[skill.name];
|
|
4246
4371
|
await addSkillToLocalLock(skill.name, {
|
|
4247
4372
|
source: lockSource || parsed.url,
|
|
@@ -4363,7 +4488,7 @@ async function promptForFindSkills(options, targetAgents) {
|
|
|
4363
4488
|
const findSkillsAgents = targetAgents?.filter((a) => a !== "replit");
|
|
4364
4489
|
if (!findSkillsAgents || findSkillsAgents.length === 0) return;
|
|
4365
4490
|
console.log();
|
|
4366
|
-
log.step("Installing find-skills skill
|
|
4491
|
+
log.step("Installing find-skills skill…");
|
|
4367
4492
|
try {
|
|
4368
4493
|
await runAdd(["vercel-labs/skills"], {
|
|
4369
4494
|
skill: ["find-skills"],
|
|
@@ -4536,7 +4661,7 @@ async function runSearchPrompt(initialQuery = "", owner) {
|
|
|
4536
4661
|
lines.push(`${TEXT$2}Search skills:${RESET$3} ${query}${cursor}`);
|
|
4537
4662
|
lines.push("");
|
|
4538
4663
|
if (!query || query.length < 2) lines.push(`${DIM$3}Start typing to search (min 2 chars)${RESET$3}`);
|
|
4539
|
-
else if (results.length === 0 && loading) lines.push(`${DIM$3}Searching
|
|
4664
|
+
else if (results.length === 0 && loading) lines.push(`${DIM$3}Searching…${RESET$3}`);
|
|
4540
4665
|
else if (results.length === 0) lines.push(`${DIM$3}No skills found${RESET$3}`);
|
|
4541
4666
|
else {
|
|
4542
4667
|
const visible = results.slice(0, 8);
|
|
@@ -4548,7 +4673,7 @@ async function runSearchPrompt(initialQuery = "", owner) {
|
|
|
4548
4673
|
const source = skill.source ? ` ${DIM$3}${skill.source}${RESET$3}` : "";
|
|
4549
4674
|
const installs = formatInstalls(skill.installs);
|
|
4550
4675
|
const installsBadge = installs ? ` ${CYAN$1}${installs}${RESET$3}` : "";
|
|
4551
|
-
const loadingIndicator = loading && i === 0 ? ` ${DIM$3}
|
|
4676
|
+
const loadingIndicator = loading && i === 0 ? ` ${DIM$3}…${RESET$3}` : "";
|
|
4552
4677
|
lines.push(` ${arrow} ${name}${source}${installsBadge}${loadingIndicator}`);
|
|
4553
4678
|
}
|
|
4554
4679
|
}
|
|
@@ -4702,7 +4827,7 @@ ${DIM$3} 2) npx skills add <owner/repo@skill>${RESET$3}`;
|
|
|
4702
4827
|
const pkg = selected.source || selected.slug;
|
|
4703
4828
|
const skillName = selected.name;
|
|
4704
4829
|
console.log();
|
|
4705
|
-
console.log(`${TEXT$2}Installing ${BOLD$3}${skillName}${RESET$3} from ${DIM$3}${pkg}${RESET$3}
|
|
4830
|
+
console.log(`${TEXT$2}Installing ${BOLD$3}${skillName}${RESET$3} from ${DIM$3}${pkg}${RESET$3}…`);
|
|
4706
4831
|
console.log();
|
|
4707
4832
|
const { source, options: addOptions } = parseAddOptions([
|
|
4708
4833
|
pkg,
|
|
@@ -4805,7 +4930,7 @@ async function runSync(args, options = {}) {
|
|
|
4805
4930
|
if (!agentResult.isAgent) intro(import_picocolors.default.bgCyan(import_picocolors.default.black(" skills experimental_sync ")));
|
|
4806
4931
|
if (agentResult.isAgent) log.info(import_picocolors.default.bgCyan(import_picocolors.default.black(import_picocolors.default.bold(` ${agentResult.agent.name} `))) + " Agent detected — installing non-interactively");
|
|
4807
4932
|
const spinner$2 = spinner();
|
|
4808
|
-
spinner$2.start("Scanning node_modules for skills
|
|
4933
|
+
spinner$2.start("Scanning node_modules for skills…");
|
|
4809
4934
|
const discoveredSkills = await discoverNodeModuleSkills(cwd);
|
|
4810
4935
|
if (discoveredSkills.length === 0) {
|
|
4811
4936
|
spinner$2.stop(import_picocolors.default.yellow("No skills found"));
|
|
@@ -4858,7 +4983,7 @@ async function runSync(args, options = {}) {
|
|
|
4858
4983
|
}
|
|
4859
4984
|
targetAgents = options.agent;
|
|
4860
4985
|
} else {
|
|
4861
|
-
spinner$2.start("Loading agents
|
|
4986
|
+
spinner$2.start("Loading agents…");
|
|
4862
4987
|
const installedAgents = await detectInstalledAgents();
|
|
4863
4988
|
const totalAgents = Object.keys(agents).length;
|
|
4864
4989
|
spinner$2.stop(`${totalAgents} agents`);
|
|
@@ -4932,7 +5057,7 @@ async function runSync(args, options = {}) {
|
|
|
4932
5057
|
process.exit(0);
|
|
4933
5058
|
}
|
|
4934
5059
|
}
|
|
4935
|
-
spinner$2.start("Syncing skills
|
|
5060
|
+
spinner$2.start("Syncing skills…");
|
|
4936
5061
|
const results = [];
|
|
4937
5062
|
for (const skill of toInstall) for (const agent of targetAgents) {
|
|
4938
5063
|
const result = await installSkillForAgent(skill, agent, {
|
|
@@ -5269,7 +5394,7 @@ async function removeCommand(skillNames, options) {
|
|
|
5269
5394
|
const isGlobal = options.global ?? false;
|
|
5270
5395
|
const cwd = process.cwd();
|
|
5271
5396
|
const spinner$1 = spinner();
|
|
5272
|
-
spinner$1.start("Scanning for installed skills
|
|
5397
|
+
spinner$1.start("Scanning for installed skills…");
|
|
5273
5398
|
const skillNamesSet = /* @__PURE__ */ new Set();
|
|
5274
5399
|
const scanDir = async (dir) => {
|
|
5275
5400
|
try {
|
|
@@ -5343,7 +5468,7 @@ async function removeCommand(skillNames, options) {
|
|
|
5343
5468
|
process.exit(0);
|
|
5344
5469
|
}
|
|
5345
5470
|
}
|
|
5346
|
-
spinner$1.start("Removing skills
|
|
5471
|
+
spinner$1.start("Removing skills…");
|
|
5347
5472
|
const results = [];
|
|
5348
5473
|
for (const skillName of selectedSkills) try {
|
|
5349
5474
|
const canonicalPath = getCanonicalPath(skillName, {
|
|
@@ -5594,7 +5719,7 @@ async function checkAndPromptForDeletions(source, allLockedForSource, lockSkills
|
|
|
5594
5719
|
else {
|
|
5595
5720
|
const confirmed = await confirm({ message: `Would you like to remove the local copies of these deleted skills?` });
|
|
5596
5721
|
if (confirmed && !isCancel(confirmed)) for (const s of deletedSkills) {
|
|
5597
|
-
console.log(`${DIM$1}Removing${RESET$1} ${s}
|
|
5722
|
+
console.log(`${DIM$1}Removing${RESET$1} ${s}…`);
|
|
5598
5723
|
await removeCommand([s], {
|
|
5599
5724
|
yes: true,
|
|
5600
5725
|
global: isGlobal
|
|
@@ -5728,7 +5853,7 @@ async function updateGlobalSkills(options = {}) {
|
|
|
5728
5853
|
console.log();
|
|
5729
5854
|
for (const update of updates) {
|
|
5730
5855
|
const safeName = sanitizeMetadata(update.name);
|
|
5731
|
-
console.log(`${TEXT$1}Updating ${safeName}
|
|
5856
|
+
console.log(`${TEXT$1}Updating ${safeName}…${RESET$1}`);
|
|
5732
5857
|
const installUrl = buildUpdateInstallSource(update.entry);
|
|
5733
5858
|
if (!installUrl) {
|
|
5734
5859
|
failCount++;
|
|
@@ -5809,7 +5934,7 @@ async function updateProjectSkills(options = {}) {
|
|
|
5809
5934
|
if (hasUniversal) targetParts.push("Universal");
|
|
5810
5935
|
targetParts.push(...targetAgentNames);
|
|
5811
5936
|
if (targetParts.length > 0) console.log(`${TEXT$1}Updating for: ${targetParts.join(", ")}${RESET$1}`);
|
|
5812
|
-
console.log(`${TEXT$1}Refreshing ${updatable.length} skill(s)
|
|
5937
|
+
console.log(`${TEXT$1}Refreshing ${updatable.length} skill(s)…${RESET$1}`);
|
|
5813
5938
|
console.log();
|
|
5814
5939
|
const bySource = /* @__PURE__ */ new Map();
|
|
5815
5940
|
for (const skill of updatable) {
|
|
@@ -5854,7 +5979,7 @@ async function updateProjectSkills(options = {}) {
|
|
|
5854
5979
|
const remainingSkills = skillsForSource.filter((s) => !deletedSkills.includes(s.name));
|
|
5855
5980
|
for (const skill of remainingSkills) {
|
|
5856
5981
|
const safeName = sanitizeMetadata(skill.name);
|
|
5857
|
-
console.log(`${TEXT$1}Updating ${safeName}
|
|
5982
|
+
console.log(`${TEXT$1}Updating ${safeName}…${RESET$1}`);
|
|
5858
5983
|
const installUrl = buildLocalUpdateSource(skill.entry);
|
|
5859
5984
|
if (!installUrl) {
|
|
5860
5985
|
failCount++;
|
|
@@ -5908,8 +6033,8 @@ function printLegacyProjectSkills(legacy) {
|
|
|
5908
6033
|
async function runUpdate(args = []) {
|
|
5909
6034
|
const options = parseUpdateOptions(args);
|
|
5910
6035
|
const scope = await resolveUpdateScope(options);
|
|
5911
|
-
if (options.skills) console.log(`${TEXT$1}Updating ${options.skills.join(", ")}
|
|
5912
|
-
else console.log(`${TEXT$1}Checking for skill updates
|
|
6036
|
+
if (options.skills) console.log(`${TEXT$1}Updating ${options.skills.join(", ")}…${RESET$1}`);
|
|
6037
|
+
else console.log(`${TEXT$1}Checking for skill updates…${RESET$1}`);
|
|
5913
6038
|
console.log();
|
|
5914
6039
|
let totalSuccess = 0;
|
|
5915
6040
|
let totalFail = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skills",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.19",
|
|
4
4
|
"description": "The open agent skills ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -130,13 +130,13 @@
|
|
|
130
130
|
"obuild": "^0.4.22",
|
|
131
131
|
"picocolors": "^1.1.1",
|
|
132
132
|
"prettier": "^3.8.1",
|
|
133
|
-
"simple-git": "^3.
|
|
133
|
+
"simple-git": "^3.36.0",
|
|
134
134
|
"typescript": "^5.9.3",
|
|
135
135
|
"vitest": "^4.0.17",
|
|
136
136
|
"xdg-basedir": "^5.1.0"
|
|
137
137
|
},
|
|
138
138
|
"engines": {
|
|
139
|
-
"node": ">=
|
|
139
|
+
"node": ">=22.20.0"
|
|
140
140
|
},
|
|
141
141
|
"packageManager": "pnpm@10.17.1",
|
|
142
142
|
"dependencies": {
|