skild 0.4.2 → 0.4.3
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/index.js +284 -48
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -128,16 +128,6 @@ async function promptPassword(question) {
|
|
|
128
128
|
stdin.on("keypress", onKeypress);
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
|
-
async function promptConfirm(question, options = {}) {
|
|
132
|
-
const defaultValue = options.defaultValue ?? false;
|
|
133
|
-
const suffix = defaultValue ? " (Y/n)" : " (y/N)";
|
|
134
|
-
const answer = await promptLine(`${question}${suffix}`);
|
|
135
|
-
const v = answer.trim().toLowerCase();
|
|
136
|
-
if (!v) return defaultValue;
|
|
137
|
-
if (v === "y" || v === "yes") return true;
|
|
138
|
-
if (v === "n" || v === "no") return false;
|
|
139
|
-
return defaultValue;
|
|
140
|
-
}
|
|
141
131
|
|
|
142
132
|
// src/commands/install-discovery.ts
|
|
143
133
|
import fs from "fs";
|
|
@@ -233,10 +223,6 @@ function printJson(value) {
|
|
|
233
223
|
process.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
234
224
|
`);
|
|
235
225
|
}
|
|
236
|
-
function previewDiscovered(found, limit = 12) {
|
|
237
|
-
const preview = found.slice(0, limit).map((s) => ` - ${s.relPath}`).join("\n");
|
|
238
|
-
return `${preview}${found.length > limit ? "\n ..." : ""}`;
|
|
239
|
-
}
|
|
240
226
|
function asDiscoveredSkills(discovered, toSuggestedSource, toMaterializedDir) {
|
|
241
227
|
return discovered.map((d) => ({
|
|
242
228
|
relPath: d.relPath,
|
|
@@ -244,24 +230,258 @@ function asDiscoveredSkills(discovered, toSuggestedSource, toMaterializedDir) {
|
|
|
244
230
|
materializedDir: toMaterializedDir ? toMaterializedDir(d) : void 0
|
|
245
231
|
}));
|
|
246
232
|
}
|
|
233
|
+
function buildSkillTree(found) {
|
|
234
|
+
const root = { id: "", name: ".", children: [], leafIndices: [] };
|
|
235
|
+
const byId = /* @__PURE__ */ new Map([["", root]]);
|
|
236
|
+
for (let i = 0; i < found.length; i += 1) {
|
|
237
|
+
const relPath = found[i].relPath;
|
|
238
|
+
const parts = relPath === "." ? ["."] : relPath.split("/").filter(Boolean);
|
|
239
|
+
let currentId = "";
|
|
240
|
+
let current = root;
|
|
241
|
+
current.leafIndices.push(i);
|
|
242
|
+
for (const part of parts) {
|
|
243
|
+
const nextId = currentId ? `${currentId}/${part}` : part;
|
|
244
|
+
let node = byId.get(nextId);
|
|
245
|
+
if (!node) {
|
|
246
|
+
node = { id: nextId, name: part, children: [], leafIndices: [] };
|
|
247
|
+
byId.set(nextId, node);
|
|
248
|
+
current.children.push(node);
|
|
249
|
+
}
|
|
250
|
+
node.leafIndices.push(i);
|
|
251
|
+
current = node;
|
|
252
|
+
currentId = nextId;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return root;
|
|
256
|
+
}
|
|
257
|
+
function getNodeState(node, selected) {
|
|
258
|
+
const total = node.leafIndices.length;
|
|
259
|
+
if (total === 0) return "none";
|
|
260
|
+
let selectedCount = 0;
|
|
261
|
+
for (const idx of node.leafIndices) {
|
|
262
|
+
if (selected.has(idx)) selectedCount += 1;
|
|
263
|
+
}
|
|
264
|
+
if (selectedCount === 0) return "none";
|
|
265
|
+
if (selectedCount === total) return "all";
|
|
266
|
+
return "partial";
|
|
267
|
+
}
|
|
268
|
+
function renderSkillTree(root, selected) {
|
|
269
|
+
const items = [];
|
|
270
|
+
const stack = [];
|
|
271
|
+
for (let i = root.children.length - 1; i >= 0; i -= 1) {
|
|
272
|
+
stack.push({ node: root.children[i], depth: 0 });
|
|
273
|
+
}
|
|
274
|
+
while (stack.length) {
|
|
275
|
+
const current = stack.pop();
|
|
276
|
+
items.push(current);
|
|
277
|
+
const children = current.node.children;
|
|
278
|
+
for (let i = children.length - 1; i >= 0; i -= 1) {
|
|
279
|
+
stack.push({ node: children[i], depth: current.depth + 1 });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return items;
|
|
283
|
+
}
|
|
284
|
+
function parseSelectionInput(input, maxIndex) {
|
|
285
|
+
const trimmed = input.trim().toLowerCase();
|
|
286
|
+
if (!trimmed) return { command: "done" };
|
|
287
|
+
if (["q", "quit", "exit", "cancel"].includes(trimmed)) return { command: "cancel" };
|
|
288
|
+
if (["a", "all"].includes(trimmed)) return { command: "all" };
|
|
289
|
+
if (["n", "none"].includes(trimmed)) return { command: "none" };
|
|
290
|
+
if (["i", "invert"].includes(trimmed)) return { command: "invert" };
|
|
291
|
+
const tokens = trimmed.split(/[,\s]+/).filter(Boolean);
|
|
292
|
+
const indices = [];
|
|
293
|
+
for (const token of tokens) {
|
|
294
|
+
if (/^\d+$/.test(token)) {
|
|
295
|
+
const value = Number(token);
|
|
296
|
+
if (value < 1 || value > maxIndex) return null;
|
|
297
|
+
indices.push(value);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (/^\d+-\d+$/.test(token)) {
|
|
301
|
+
const [startRaw, endRaw] = token.split("-");
|
|
302
|
+
const start = Number(startRaw);
|
|
303
|
+
const end = Number(endRaw);
|
|
304
|
+
if (!Number.isFinite(start) || !Number.isFinite(end) || start < 1 || end < 1 || start > maxIndex || end > maxIndex) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
const from = Math.min(start, end);
|
|
308
|
+
const to = Math.max(start, end);
|
|
309
|
+
for (let i = from; i <= to; i += 1) indices.push(i);
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
return { indices };
|
|
315
|
+
}
|
|
316
|
+
async function promptSkillSelection(found, options) {
|
|
317
|
+
const root = buildSkillTree(found);
|
|
318
|
+
const selected = /* @__PURE__ */ new Set();
|
|
319
|
+
if (options.defaultAll) {
|
|
320
|
+
for (let i = 0; i < found.length; i += 1) selected.add(i);
|
|
321
|
+
}
|
|
322
|
+
while (true) {
|
|
323
|
+
console.log(chalk2.cyan("\nSelect skills to install"));
|
|
324
|
+
console.log(chalk2.dim("Toggle by number. Commands: a=all, n=none, i=invert, enter=continue, q=cancel."));
|
|
325
|
+
const display = renderSkillTree(root, selected);
|
|
326
|
+
for (let i = 0; i < display.length; i += 1) {
|
|
327
|
+
const item = display[i];
|
|
328
|
+
const state = getNodeState(item.node, selected);
|
|
329
|
+
const box = state === "all" ? "[x]" : state === "partial" ? "[-]" : "[ ]";
|
|
330
|
+
const indent = " ".repeat(item.depth);
|
|
331
|
+
const idx = String(i + 1).padStart(2, " ");
|
|
332
|
+
console.log(`${idx} ${box} ${indent}${item.node.name}`);
|
|
333
|
+
}
|
|
334
|
+
const answer = await promptLine("Selection");
|
|
335
|
+
const parsed = parseSelectionInput(answer, display.length);
|
|
336
|
+
if (!parsed) {
|
|
337
|
+
console.log(chalk2.yellow('Invalid selection. Use numbers like "1,3-5" or a/n/i.'));
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (parsed.command === "done") break;
|
|
341
|
+
if (parsed.command === "cancel") return null;
|
|
342
|
+
if (parsed.command === "all") {
|
|
343
|
+
selected.clear();
|
|
344
|
+
for (let i = 0; i < found.length; i += 1) selected.add(i);
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (parsed.command === "none") {
|
|
348
|
+
selected.clear();
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (parsed.command === "invert") {
|
|
352
|
+
const next = /* @__PURE__ */ new Set();
|
|
353
|
+
for (let i = 0; i < found.length; i += 1) {
|
|
354
|
+
if (!selected.has(i)) next.add(i);
|
|
355
|
+
}
|
|
356
|
+
selected.clear();
|
|
357
|
+
for (const idx of next) selected.add(idx);
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (parsed.indices) {
|
|
361
|
+
for (const index of parsed.indices) {
|
|
362
|
+
const item = display[index - 1];
|
|
363
|
+
if (!item) continue;
|
|
364
|
+
const state = getNodeState(item.node, selected);
|
|
365
|
+
if (state === "all") {
|
|
366
|
+
for (const leaf of item.node.leafIndices) selected.delete(leaf);
|
|
367
|
+
} else {
|
|
368
|
+
for (const leaf of item.node.leafIndices) selected.add(leaf);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (selected.size === 0) return null;
|
|
374
|
+
const selectedFound = [];
|
|
375
|
+
for (let i = 0; i < found.length; i += 1) {
|
|
376
|
+
if (selected.has(i)) selectedFound.push(found[i]);
|
|
377
|
+
}
|
|
378
|
+
return selectedFound;
|
|
379
|
+
}
|
|
380
|
+
async function promptPlatformSelection(defaultAll) {
|
|
381
|
+
const selected = /* @__PURE__ */ new Set();
|
|
382
|
+
if (defaultAll) {
|
|
383
|
+
for (let i = 0; i < PLATFORMS.length; i += 1) selected.add(i);
|
|
384
|
+
}
|
|
385
|
+
while (true) {
|
|
386
|
+
console.log(chalk2.cyan("\nSelect platforms to install to"));
|
|
387
|
+
console.log(chalk2.dim("Toggle by number. Commands: a=all, n=none, i=invert, enter=continue, q=cancel."));
|
|
388
|
+
for (let i = 0; i < PLATFORMS.length; i += 1) {
|
|
389
|
+
const label = PLATFORMS[i];
|
|
390
|
+
const box = selected.has(i) ? "[x]" : "[ ]";
|
|
391
|
+
const idx = String(i + 1).padStart(2, " ");
|
|
392
|
+
console.log(`${idx} ${box} ${label}`);
|
|
393
|
+
}
|
|
394
|
+
const answer = await promptLine("Selection");
|
|
395
|
+
const parsed = parseSelectionInput(answer, PLATFORMS.length);
|
|
396
|
+
if (!parsed) {
|
|
397
|
+
console.log(chalk2.yellow('Invalid selection. Use numbers like "1,3-5" or a/n/i.'));
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
if (parsed.command === "done") break;
|
|
401
|
+
if (parsed.command === "cancel") return null;
|
|
402
|
+
if (parsed.command === "all") {
|
|
403
|
+
selected.clear();
|
|
404
|
+
for (let i = 0; i < PLATFORMS.length; i += 1) selected.add(i);
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (parsed.command === "none") {
|
|
408
|
+
selected.clear();
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (parsed.command === "invert") {
|
|
412
|
+
const next = /* @__PURE__ */ new Set();
|
|
413
|
+
for (let i = 0; i < PLATFORMS.length; i += 1) {
|
|
414
|
+
if (!selected.has(i)) next.add(i);
|
|
415
|
+
}
|
|
416
|
+
selected.clear();
|
|
417
|
+
for (const idx of next) selected.add(idx);
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
if (parsed.indices) {
|
|
421
|
+
for (const index of parsed.indices) {
|
|
422
|
+
const idx = index - 1;
|
|
423
|
+
if (idx < 0 || idx >= PLATFORMS.length) continue;
|
|
424
|
+
if (selected.has(idx)) selected.delete(idx);
|
|
425
|
+
else selected.add(idx);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (selected.size === 0) return null;
|
|
430
|
+
const chosen = [];
|
|
431
|
+
for (let i = 0; i < PLATFORMS.length; i += 1) {
|
|
432
|
+
if (selected.has(i)) chosen.push(PLATFORMS[i]);
|
|
433
|
+
}
|
|
434
|
+
return chosen;
|
|
435
|
+
}
|
|
436
|
+
function printSelectedSkills(found) {
|
|
437
|
+
const names = found.map((skill) => skill.relPath);
|
|
438
|
+
if (names.length === 0) return;
|
|
439
|
+
const preview = names.slice(0, 20).map((name) => ` - ${name}`).join("\n");
|
|
440
|
+
console.log(chalk2.dim(`
|
|
441
|
+
Selected skills (${names.length}):`));
|
|
442
|
+
console.log(preview);
|
|
443
|
+
if (names.length > 20) {
|
|
444
|
+
console.log(chalk2.dim(` ... and ${names.length - 20} more`));
|
|
445
|
+
}
|
|
446
|
+
}
|
|
247
447
|
async function install(source, options = {}) {
|
|
248
448
|
const scope = options.local ? "project" : "global";
|
|
249
449
|
const auth = loadRegistryAuth();
|
|
250
450
|
const registryUrlForDeps = options.registry || auth?.registryUrl;
|
|
251
|
-
const all = Boolean(options.all);
|
|
252
451
|
const jsonOnly = Boolean(options.json);
|
|
253
452
|
const recursive = Boolean(options.recursive);
|
|
254
453
|
const yes = Boolean(options.yes);
|
|
255
454
|
const maxDepth = parsePositiveInt(options.depth, 6);
|
|
256
455
|
const maxSkills = parsePositiveInt(options.maxSkills, 200);
|
|
257
|
-
const
|
|
258
|
-
|
|
456
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !jsonOnly;
|
|
457
|
+
const requestedAll = Boolean(options.all);
|
|
458
|
+
const requestedTarget = options.target;
|
|
459
|
+
if (requestedAll && options.target) {
|
|
259
460
|
const message = "Invalid options: use either --all or --target, not both.";
|
|
260
461
|
if (jsonOnly) printJson({ ok: false, error: message });
|
|
261
462
|
else console.error(chalk2.red(message));
|
|
262
463
|
process.exitCode = 1;
|
|
263
464
|
return;
|
|
264
465
|
}
|
|
466
|
+
let targets = [];
|
|
467
|
+
if (requestedAll) {
|
|
468
|
+
targets = [...PLATFORMS];
|
|
469
|
+
} else if (requestedTarget) {
|
|
470
|
+
targets = [requestedTarget];
|
|
471
|
+
} else if (yes) {
|
|
472
|
+
targets = [...PLATFORMS];
|
|
473
|
+
} else if (interactive) {
|
|
474
|
+
const selectedTargets = await promptPlatformSelection(true);
|
|
475
|
+
if (!selectedTargets) {
|
|
476
|
+
console.error(chalk2.red("No platforms selected."));
|
|
477
|
+
process.exitCode = 1;
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
targets = selectedTargets;
|
|
481
|
+
} else {
|
|
482
|
+
targets = ["claude"];
|
|
483
|
+
}
|
|
484
|
+
const allPlatformsSelected = targets.length === PLATFORMS.length;
|
|
265
485
|
let resolvedSource = source.trim();
|
|
266
486
|
try {
|
|
267
487
|
if (looksLikeAlias(resolvedSource)) {
|
|
@@ -277,12 +497,10 @@ async function install(source, options = {}) {
|
|
|
277
497
|
process.exitCode = 1;
|
|
278
498
|
return;
|
|
279
499
|
}
|
|
280
|
-
const targets = all ? [...PLATFORMS] : [platform];
|
|
281
500
|
const results = [];
|
|
282
501
|
const errors = [];
|
|
283
502
|
let effectiveRecursive = recursive;
|
|
284
503
|
let recursiveSkillCount = null;
|
|
285
|
-
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !jsonOnly;
|
|
286
504
|
async function installOne(inputSource, materializedDir) {
|
|
287
505
|
for (const targetPlatform of targets) {
|
|
288
506
|
try {
|
|
@@ -301,14 +519,14 @@ async function install(source, options = {}) {
|
|
|
301
519
|
}
|
|
302
520
|
}
|
|
303
521
|
}
|
|
304
|
-
async function
|
|
305
|
-
if (found.length === 0) return
|
|
522
|
+
async function resolveDiscoveredSelection(found, spinner) {
|
|
523
|
+
if (found.length === 0) return null;
|
|
306
524
|
if (found.length > maxSkills) {
|
|
307
525
|
const message = `Found more than ${maxSkills} skills. Increase --max-skills to proceed.`;
|
|
308
526
|
if (jsonOnly) printJson({ ok: false, error: "TOO_MANY_SKILLS", message, source, resolvedSource, maxSkills });
|
|
309
527
|
else console.error(chalk2.red(message));
|
|
310
528
|
process.exitCode = 1;
|
|
311
|
-
return
|
|
529
|
+
return null;
|
|
312
530
|
}
|
|
313
531
|
if (!effectiveRecursive) {
|
|
314
532
|
if (jsonOnly) {
|
|
@@ -322,31 +540,39 @@ async function install(source, options = {}) {
|
|
|
322
540
|
found: foundOutput
|
|
323
541
|
});
|
|
324
542
|
process.exitCode = 1;
|
|
325
|
-
return
|
|
543
|
+
return null;
|
|
326
544
|
}
|
|
327
545
|
if (spinner) spinner.stop();
|
|
328
|
-
const headline = found.length === 1 ? `No SKILL.md found at root. Found 1 skill
|
|
329
|
-
${
|
|
330
|
-
` : `No SKILL.md found at root. Found ${found.length} skills:
|
|
331
|
-
${previewDiscovered(found)}
|
|
546
|
+
const headline = found.length === 1 ? `No SKILL.md found at root. Found 1 skill.
|
|
547
|
+
` : `No SKILL.md found at root. Found ${found.length} skills.
|
|
332
548
|
`;
|
|
333
549
|
console.log(chalk2.yellow(headline));
|
|
334
|
-
|
|
335
|
-
const confirm = yes || interactive && await promptConfirm(question, { defaultValue: found.length === 1 });
|
|
336
|
-
if (!confirm) {
|
|
550
|
+
if (!interactive && !yes) {
|
|
337
551
|
console.log(chalk2.dim(`Tip: rerun with ${chalk2.cyan("skild install <source> --recursive")} to install all.`));
|
|
338
552
|
process.exitCode = 1;
|
|
339
|
-
return
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
if (!yes) {
|
|
556
|
+
const selected = await promptSkillSelection(found, { defaultAll: true });
|
|
557
|
+
if (!selected) {
|
|
558
|
+
console.log(chalk2.red("No skills selected."));
|
|
559
|
+
process.exitCode = 1;
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
printSelectedSkills(selected);
|
|
563
|
+
effectiveRecursive = true;
|
|
564
|
+
if (spinner) spinner.start();
|
|
565
|
+
recursiveSkillCount = selected.length;
|
|
566
|
+
return selected;
|
|
340
567
|
}
|
|
341
568
|
effectiveRecursive = true;
|
|
342
|
-
if (spinner) spinner.start();
|
|
343
569
|
}
|
|
344
570
|
recursiveSkillCount = found.length;
|
|
345
|
-
return
|
|
571
|
+
return found;
|
|
346
572
|
}
|
|
347
573
|
try {
|
|
348
574
|
const spinner = jsonOnly ? null : createSpinner(
|
|
349
|
-
|
|
575
|
+
allPlatformsSelected ? `Installing ${chalk2.cyan(source)} to ${chalk2.dim("all platforms")} (${scope})...` : targets.length > 1 ? `Installing ${chalk2.cyan(source)} to ${chalk2.dim(`${targets.length} platforms`)} (${scope})...` : `Installing ${chalk2.cyan(source)} to ${chalk2.dim(targets[0])} (${scope})...`
|
|
350
576
|
);
|
|
351
577
|
let cleanupMaterialized = null;
|
|
352
578
|
let materializedRoot = null;
|
|
@@ -374,10 +600,10 @@ ${previewDiscovered(found)}
|
|
|
374
600
|
return;
|
|
375
601
|
}
|
|
376
602
|
const found = asDiscoveredSkills(discovered, (d) => path2.join(maybeLocalRoot, d.relPath));
|
|
377
|
-
const
|
|
378
|
-
if (
|
|
379
|
-
if (spinner) spinner.text = `Installing ${chalk2.cyan(source)} \u2014 discovered ${
|
|
380
|
-
for (const skill of
|
|
603
|
+
const selected = await resolveDiscoveredSelection(found, spinner);
|
|
604
|
+
if (!selected) return;
|
|
605
|
+
if (spinner) spinner.text = `Installing ${chalk2.cyan(source)} \u2014 discovered ${selected.length} skills...`;
|
|
606
|
+
for (const skill of selected) {
|
|
381
607
|
if (spinner) spinner.text = `Installing ${chalk2.cyan(skill.relPath)} (${scope})...`;
|
|
382
608
|
await installOne(skill.suggestedSource, skill.materializedDir);
|
|
383
609
|
}
|
|
@@ -407,10 +633,10 @@ ${previewDiscovered(found)}
|
|
|
407
633
|
(d) => deriveChildSource(resolvedSource, d.relPath),
|
|
408
634
|
(d) => d.absDir
|
|
409
635
|
);
|
|
410
|
-
const
|
|
411
|
-
if (
|
|
412
|
-
if (spinner) spinner.text = `Installing ${chalk2.cyan(source)} \u2014 discovered ${
|
|
413
|
-
for (const skill of
|
|
636
|
+
const selected = await resolveDiscoveredSelection(found, spinner);
|
|
637
|
+
if (!selected) return;
|
|
638
|
+
if (spinner) spinner.text = `Installing ${chalk2.cyan(source)} \u2014 discovered ${selected.length} skills...`;
|
|
639
|
+
for (const skill of selected) {
|
|
414
640
|
if (spinner) spinner.text = `Installing ${chalk2.cyan(skill.relPath)} (${scope})...`;
|
|
415
641
|
await installOne(skill.suggestedSource, skill.materializedDir);
|
|
416
642
|
}
|
|
@@ -421,11 +647,21 @@ ${previewDiscovered(found)}
|
|
|
421
647
|
if (cleanupMaterialized) cleanupMaterialized();
|
|
422
648
|
}
|
|
423
649
|
if (jsonOnly) {
|
|
424
|
-
if (!
|
|
650
|
+
if (!effectiveRecursive && targets.length === 1) {
|
|
425
651
|
if (errors.length) printJson({ ok: false, error: errors[0]?.error || "Install failed." });
|
|
426
652
|
else printJson(results[0] ?? null);
|
|
427
653
|
} else {
|
|
428
|
-
printJson({
|
|
654
|
+
printJson({
|
|
655
|
+
ok: errors.length === 0,
|
|
656
|
+
source,
|
|
657
|
+
resolvedSource,
|
|
658
|
+
scope,
|
|
659
|
+
recursive: effectiveRecursive,
|
|
660
|
+
all: allPlatformsSelected,
|
|
661
|
+
recursiveSkillCount,
|
|
662
|
+
results,
|
|
663
|
+
errors
|
|
664
|
+
});
|
|
429
665
|
}
|
|
430
666
|
process.exitCode = errors.length ? 1 : 0;
|
|
431
667
|
return;
|
|
@@ -433,7 +669,7 @@ ${previewDiscovered(found)}
|
|
|
433
669
|
if (errors.length === 0) {
|
|
434
670
|
const displayName = results[0]?.canonicalName || results[0]?.name || source;
|
|
435
671
|
spinner.succeed(
|
|
436
|
-
effectiveRecursive ? `Installed ${chalk2.green(String(recursiveSkillCount ?? results.length))}${chalk2.dim(" skills")} to ${chalk2.dim(`${targets.length} platforms`)}` :
|
|
672
|
+
effectiveRecursive ? `Installed ${chalk2.green(String(recursiveSkillCount ?? results.length))}${chalk2.dim(" skills")} to ${chalk2.dim(`${targets.length} platforms`)}` : targets.length > 1 ? `Installed ${chalk2.green(displayName)} to ${chalk2.dim(`${results.length} platforms`)}` : `Installed ${chalk2.green(displayName)} to ${chalk2.dim(results[0]?.installDir || "")}`
|
|
437
673
|
);
|
|
438
674
|
} else {
|
|
439
675
|
const attempted = results.length + errors.length;
|
|
@@ -441,9 +677,9 @@ ${previewDiscovered(found)}
|
|
|
441
677
|
effectiveRecursive ? `Install had failures (${errors.length}/${attempted} installs failed)` : `Failed to install ${chalk2.red(source)} to ${errors.length}/${targets.length} platforms`
|
|
442
678
|
);
|
|
443
679
|
process.exitCode = 1;
|
|
444
|
-
if (!
|
|
680
|
+
if (!effectiveRecursive && targets.length === 1 && errors[0]) console.error(chalk2.red(errors[0].error));
|
|
445
681
|
}
|
|
446
|
-
if (!effectiveRecursive &&
|
|
682
|
+
if (!effectiveRecursive && targets.length === 1 && results[0]) {
|
|
447
683
|
const record = results[0];
|
|
448
684
|
if (record.hasSkillMd) logger.installDetail("SKILL.md found \u2713");
|
|
449
685
|
else logger.installDetail("Warning: No SKILL.md found", true);
|
|
@@ -452,7 +688,7 @@ ${previewDiscovered(found)}
|
|
|
452
688
|
} else if (record.skill?.validation?.ok) {
|
|
453
689
|
logger.installDetail(`Validation: ${chalk2.green("ok")}`);
|
|
454
690
|
}
|
|
455
|
-
} else if (effectiveRecursive ||
|
|
691
|
+
} else if (effectiveRecursive || targets.length > 1) {
|
|
456
692
|
for (const r of results.slice(0, 60)) {
|
|
457
693
|
const displayName = r.canonicalName || r.name;
|
|
458
694
|
const suffix = r.hasSkillMd ? chalk2.green("\u2713") : chalk2.yellow("\u26A0");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skild",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "The npm for Agent Skills — Discover, install, manage, and publish AI Agent Skills with ease.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"commander": "^12.1.0",
|
|
38
38
|
"ora": "^8.0.1",
|
|
39
39
|
"tar": "^7.4.3",
|
|
40
|
-
"@skild/core": "^0.4.
|
|
40
|
+
"@skild/core": "^0.4.3"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^20.10.0",
|