install-agent-skill 1.2.8 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/add-skill.v2.js +30 -30
- package/bin/lib/commands/install.js +1 -2
- package/bin/lib/commands/update.js +3 -3
- package/bin/lib/ui.js +39 -2
- package/package.json +1 -1
package/bin/add-skill.v2.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* install-agent-skill
|
|
4
4
|
* Vercel-Style CLI - Full Port v2.0
|
|
@@ -70,11 +70,11 @@ const c = {
|
|
|
70
70
|
|
|
71
71
|
// --- UI Helpers ---
|
|
72
72
|
function step(text, icon = S.diamond, color = "gray") {
|
|
73
|
-
console.log(
|
|
73
|
+
console.log(`${c.gray(S.branch)} ${c[color](icon)} ${text}`);
|
|
74
74
|
}
|
|
75
|
-
function stepLine() { console.log(
|
|
76
|
-
function fatal(msg) { console.log(
|
|
77
|
-
function success(msg) { console.log(
|
|
75
|
+
function stepLine() { console.log(`${c.gray(S.branch)}`); }
|
|
76
|
+
function fatal(msg) { console.log(`${c.gray(S.branch)} ${c.red(S.cross)} ${c.red(msg)}`); process.exit(1); }
|
|
77
|
+
function success(msg) { console.log(`${c.gray(S.branch)} ${c.green(S.check)} ${c.green(msg)}`); }
|
|
78
78
|
function outputJSON(data) { if (JSON_OUTPUT) console.log(JSON.stringify(data, null, 2)); }
|
|
79
79
|
|
|
80
80
|
// --- Core Helpers ---
|
|
@@ -231,18 +231,18 @@ async function runInit() {
|
|
|
231
231
|
async function runList() {
|
|
232
232
|
stepLine();
|
|
233
233
|
step(c.bold("Installed Skills"), S.diamondFilled, "cyan");
|
|
234
|
-
console.log(
|
|
234
|
+
console.log(`${c.gray(S.branch)} ${c.dim("Location: " + resolveScope())}`);
|
|
235
235
|
stepLine();
|
|
236
236
|
const skills = getInstalledSkills();
|
|
237
237
|
if (skills.length === 0) { step(c.dim("No skills installed."), S.diamond); stepLine(); return; }
|
|
238
238
|
if (JSON_OUTPUT) { outputJSON({ skills }); return; }
|
|
239
239
|
for (const s of skills) {
|
|
240
240
|
const icon = s.hasSkillMd ? c.green(S.check) : c.yellow(S.diamond);
|
|
241
|
-
console.log(
|
|
242
|
-
if (s.description && VERBOSE) console.log(
|
|
241
|
+
console.log(`${c.gray(S.branch)} ${icon} ${c.bold(s.name)} ${c.dim("v" + s.version)} ${c.dim("(" + formatBytes(s.size) + ")")}`);
|
|
242
|
+
if (s.description && VERBOSE) console.log(`${c.gray(S.branch)} ${c.dim(s.description.substring(0, 60))}`);
|
|
243
243
|
}
|
|
244
244
|
stepLine();
|
|
245
|
-
console.log(
|
|
245
|
+
console.log(`${c.gray(S.branch)} ${c.dim("Total: " + skills.length + " skill(s)")}`);
|
|
246
246
|
stepLine();
|
|
247
247
|
}
|
|
248
248
|
|
|
@@ -361,7 +361,7 @@ async function runInstall(spec) {
|
|
|
361
361
|
for (const sn of selectedSkills) {
|
|
362
362
|
const src = path.join(tmp, sn), dest = path.join(targetScope, sn);
|
|
363
363
|
if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });
|
|
364
|
-
fs.
|
|
364
|
+
await fs.promises.cp(src, dest, { recursive: true });
|
|
365
365
|
const hash = merkleHash(dest);
|
|
366
366
|
fs.writeFileSync(path.join(dest, ".skill-source.json"), JSON.stringify({ repo: `${org}/${repo}`, skill: sn, ref: ref || null, checksum: hash, installedAt: new Date().toISOString() }, null, 2));
|
|
367
367
|
}
|
|
@@ -441,7 +441,7 @@ function runVerify() {
|
|
|
441
441
|
if (actual !== m.checksum) { step(`${name}: ${c.red("checksum mismatch")}`, S.cross, "red"); issues++; }
|
|
442
442
|
else step(`${name}: ${c.green("OK")}`, S.check, "green");
|
|
443
443
|
}
|
|
444
|
-
stepLine(); console.log(
|
|
444
|
+
stepLine(); console.log(`${c.gray(S.branch)} ${issues ? c.red(issues + " issue(s)") : c.green("All verified")}`); stepLine();
|
|
445
445
|
if (issues && STRICT) process.exit(1);
|
|
446
446
|
}
|
|
447
447
|
|
|
@@ -464,7 +464,7 @@ function runDoctor() {
|
|
|
464
464
|
} else if (lock && !lock.skills[name]) { step(`${name}: ${c.yellow("not in lock")}`, S.diamond, "yellow"); STRICT ? errors++ : warnings++; }
|
|
465
465
|
else step(`${name}: ${c.green("healthy")}`, S.check, "green");
|
|
466
466
|
}
|
|
467
|
-
stepLine(); console.log(
|
|
467
|
+
stepLine(); console.log(`${c.gray(S.branch)} Errors: ${errors}, Warnings: ${warnings}`); stepLine();
|
|
468
468
|
if (STRICT && errors) process.exit(1);
|
|
469
469
|
}
|
|
470
470
|
|
|
@@ -481,17 +481,17 @@ function runCache(sub) {
|
|
|
481
481
|
const rs = fs.existsSync(REGISTRY_CACHE) ? getDirSize(REGISTRY_CACHE) : 0;
|
|
482
482
|
const bs = fs.existsSync(BACKUP_DIR) ? getDirSize(BACKUP_DIR) : 0;
|
|
483
483
|
step(c.bold("Cache Info"), S.diamondFilled, "cyan");
|
|
484
|
-
console.log(
|
|
485
|
-
console.log(
|
|
486
|
-
console.log(
|
|
487
|
-
console.log(
|
|
484
|
+
console.log(`${c.gray(S.branch)} Location: ${CACHE_ROOT}`);
|
|
485
|
+
console.log(`${c.gray(S.branch)} Registries: ${formatBytes(rs)}`);
|
|
486
|
+
console.log(`${c.gray(S.branch)} Backups: ${formatBytes(bs)}`);
|
|
487
|
+
console.log(`${c.gray(S.branch)} Total: ${formatBytes(getDirSize(CACHE_ROOT))}`);
|
|
488
488
|
stepLine(); return;
|
|
489
489
|
}
|
|
490
490
|
if (sub === "backups") {
|
|
491
491
|
const backups = listBackups();
|
|
492
492
|
if (backups.length === 0) { step("No backups found", S.diamond); return; }
|
|
493
493
|
step(c.bold("Backups"), S.diamondFilled, "cyan"); stepLine();
|
|
494
|
-
backups.forEach(b => console.log(
|
|
494
|
+
backups.forEach(b => console.log(`${c.gray(S.branch)} ${b.name} (${formatBytes(b.size)})`));
|
|
495
495
|
stepLine(); return;
|
|
496
496
|
}
|
|
497
497
|
fatal(`Unknown cache subcommand: ${sub}`);
|
|
@@ -511,11 +511,11 @@ function runValidate(skillName) {
|
|
|
511
511
|
if (!fs.existsSync(smp)) errors.push("Missing SKILL.md");
|
|
512
512
|
else { const m = parseSkillMdFrontmatter(smp); if (!m.description) errors.push("Missing description"); else if (m.description.length < 50) warnings.push("Description too short"); }
|
|
513
513
|
const status = errors.length > 0 ? c.red("FAIL") : warnings.length > 0 ? c.yellow("WARN") : c.green("PASS");
|
|
514
|
-
console.log(
|
|
515
|
-
if (VERBOSE || errors.length || warnings.length) { errors.forEach(e => console.log(
|
|
514
|
+
console.log(`${c.gray(S.branch)} ${status} ${c.bold(skill.name)}`);
|
|
515
|
+
if (VERBOSE || errors.length || warnings.length) { errors.forEach(e => console.log(`${c.gray(S.branch)} ${c.red("ERROR: " + e)}`)); warnings.forEach(w => console.log(`${c.gray(S.branch)} ${c.yellow("WARN: " + w)}`)); }
|
|
516
516
|
totalErrors += errors.length; totalWarnings += warnings.length;
|
|
517
517
|
}
|
|
518
|
-
stepLine(); console.log(
|
|
518
|
+
stepLine(); console.log(`${c.gray(S.branch)} Total: ${skillsToValidate.length}, Errors: ${totalErrors}, Warnings: ${totalWarnings}`); stepLine();
|
|
519
519
|
if (STRICT && totalErrors > 0) process.exit(1);
|
|
520
520
|
}
|
|
521
521
|
|
|
@@ -524,20 +524,20 @@ function runAnalyze(skillName) {
|
|
|
524
524
|
const scope = resolveScope(), skillDir = path.join(scope, skillName);
|
|
525
525
|
if (!fs.existsSync(skillDir)) fatal(`Skill not found: ${skillName}`);
|
|
526
526
|
stepLine(); step(c.bold(`Skill Analysis: ${skillName}`), S.diamondFilled, "cyan");
|
|
527
|
-
console.log(
|
|
527
|
+
console.log(`${c.gray(S.branch)} ${c.dim("Path: " + skillDir)}`); stepLine();
|
|
528
528
|
const smp = path.join(skillDir, "SKILL.md");
|
|
529
529
|
if (fs.existsSync(smp)) {
|
|
530
530
|
const m = parseSkillMdFrontmatter(smp);
|
|
531
|
-
console.log(
|
|
532
|
-
console.log(
|
|
533
|
-
console.log(
|
|
534
|
-
if (m.tags) console.log(
|
|
531
|
+
console.log(`${c.gray(S.branch)} ${c.cyan("SKILL.md Frontmatter:")}`);
|
|
532
|
+
console.log(`${c.gray(S.branch)} Name: ${m.name || c.dim("(not set)")}`);
|
|
533
|
+
console.log(`${c.gray(S.branch)} Description: ${m.description ? m.description.substring(0, 60) : c.red("(MISSING)")}`);
|
|
534
|
+
if (m.tags) console.log(`${c.gray(S.branch)} Tags: ${m.tags.join(", ")}`);
|
|
535
535
|
stepLine();
|
|
536
536
|
}
|
|
537
537
|
const structure = detectSkillStructure(skillDir);
|
|
538
|
-
console.log(
|
|
538
|
+
console.log(`${c.gray(S.branch)} ${c.cyan("Structure:")}`);
|
|
539
539
|
const items = [["resources", structure.hasResources], ["examples", structure.hasExamples], ["scripts", structure.hasScripts], ["constitution", structure.hasConstitution], ["doctrines", structure.hasDoctrines]];
|
|
540
|
-
items.forEach(([n, has]) => console.log(
|
|
540
|
+
items.forEach(([n, has]) => console.log(`${c.gray(S.branch)} ${has ? c.green(S.check) : c.dim("○")} ${has ? c.bold(n) : c.dim(n)}`));
|
|
541
541
|
stepLine();
|
|
542
542
|
let score = 0;
|
|
543
543
|
if (fs.existsSync(smp)) score += 20;
|
|
@@ -548,7 +548,7 @@ function runAnalyze(skillName) {
|
|
|
548
548
|
if (fs.existsSync(path.join(skillDir, ".skill-source.json"))) score += 10;
|
|
549
549
|
if (structure.hasConstitution || structure.hasDoctrines) score += 15;
|
|
550
550
|
const scoreColor = score >= 80 ? c.green : score >= 50 ? c.yellow : c.red;
|
|
551
|
-
console.log(
|
|
551
|
+
console.log(`${c.gray(S.branch)} ${c.cyan("Antigravity Score:")} ${scoreColor(score + "/100")}`);
|
|
552
552
|
stepLine();
|
|
553
553
|
}
|
|
554
554
|
|
|
@@ -558,9 +558,9 @@ function runInfo(name) {
|
|
|
558
558
|
stepLine();
|
|
559
559
|
if (fs.existsSync(localDir)) {
|
|
560
560
|
step(`${c.bold(name)} ${c.green("(installed)")}`, S.diamondFilled, "cyan");
|
|
561
|
-
console.log(
|
|
561
|
+
console.log(`${c.gray(S.branch)} ${c.dim("Path: " + localDir)}`);
|
|
562
562
|
const mf = path.join(localDir, ".skill-source.json");
|
|
563
|
-
if (fs.existsSync(mf)) { const m = JSON.parse(fs.readFileSync(mf, "utf-8")); console.log(
|
|
563
|
+
if (fs.existsSync(mf)) { const m = JSON.parse(fs.readFileSync(mf, "utf-8")); console.log(`${c.gray(S.branch)} Repo: ${m.repo || "local"}`); console.log(`${c.gray(S.branch)} Installed: ${formatDate(m.installedAt)}`); }
|
|
564
564
|
stepLine(); return;
|
|
565
565
|
}
|
|
566
566
|
step(`Skill not installed: ${name}`, S.diamond, "yellow"); stepLine();
|
|
@@ -47,8 +47,7 @@ export async function run(spec) {
|
|
|
47
47
|
await execAsync(`git clone --depth=1 ${url} "${tmp}"`);
|
|
48
48
|
if (ref) await execAsync(`git -C "${tmp}" checkout ${ref}`);
|
|
49
49
|
} catch {
|
|
50
|
-
s.
|
|
51
|
-
step(c.red("Failed to clone"), S.cross, "red");
|
|
50
|
+
s.fail("Failed to clone");
|
|
52
51
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
53
52
|
return;
|
|
54
53
|
}
|
|
@@ -41,15 +41,15 @@ export async function run(skillName) {
|
|
|
41
41
|
const spec = `${meta.repo}#${meta.skill}${meta.ref ? "@" + meta.ref : ""}`;
|
|
42
42
|
|
|
43
43
|
if (DRY) {
|
|
44
|
-
s.stop();
|
|
44
|
+
s.stop("Dry run analysis complete");
|
|
45
45
|
step(`Would update: ${skillName}`);
|
|
46
46
|
} else {
|
|
47
|
+
s.stop("Preparing update...");
|
|
47
48
|
// Dynamically import install command
|
|
48
49
|
const { run: install } = await import("./install.js");
|
|
49
50
|
await install(spec);
|
|
50
|
-
s.stop();
|
|
51
51
|
}
|
|
52
52
|
} catch (err) {
|
|
53
|
-
s.
|
|
53
|
+
s.fail(`Failed: ${err.message}`);
|
|
54
54
|
}
|
|
55
55
|
}
|
package/bin/lib/ui.js
CHANGED
|
@@ -3,9 +3,46 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import kleur from "kleur";
|
|
6
|
-
import { intro, outro,
|
|
6
|
+
import { intro, outro, multiselect, select, confirm, isCancel, cancel, text } from "@clack/prompts";
|
|
7
|
+
import ora from "ora";
|
|
7
8
|
|
|
8
|
-
export { intro, outro,
|
|
9
|
+
export { intro, outro, multiselect, select, confirm, isCancel, cancel, text };
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create a spinner
|
|
13
|
+
*/
|
|
14
|
+
export function spinner() {
|
|
15
|
+
return {
|
|
16
|
+
_s: null,
|
|
17
|
+
start(msg) {
|
|
18
|
+
this._s = ora({
|
|
19
|
+
text: msg,
|
|
20
|
+
prefixText: ` ${c.gray(S.branch)} `,
|
|
21
|
+
color: "magenta",
|
|
22
|
+
spinner: "dots"
|
|
23
|
+
}).start();
|
|
24
|
+
},
|
|
25
|
+
stop(msg) {
|
|
26
|
+
if (this._s) {
|
|
27
|
+
this._s.stopAndPersist({
|
|
28
|
+
symbol: c.green(S.check),
|
|
29
|
+
text: msg
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
fail(msg) {
|
|
34
|
+
if (this._s) {
|
|
35
|
+
this._s.stopAndPersist({
|
|
36
|
+
symbol: c.red(S.cross),
|
|
37
|
+
text: msg
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
message(msg) {
|
|
42
|
+
if (this._s) this._s.text = msg;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
9
46
|
|
|
10
47
|
// --- Symbols ---
|
|
11
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "install-agent-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Enterprise-grade Agent Skill Manager with Antigravity Skills support, Progressive Disclosure detection, and semantic routing validation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "DataGuruIn <contact@dataguruin.com>",
|