install-agent-skill 1.2.4 → 1.2.6

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.
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * install-agent-skill
4
+ * Vercel-Style CLI - Modular Entry Point v2.1
5
+ */
6
+
7
+ import { c, step, fatal, intro, outro } from "./lib/ui.js";
8
+ import { command, params, flags, VERSION } from "./lib/config.js";
9
+
10
+ // --- MAIN ---
11
+ async function main() {
12
+ // Basic command routing
13
+ let cmdModule;
14
+
15
+ try {
16
+ switch (command) {
17
+ case "list":
18
+ case "ls":
19
+ cmdModule = await import("./lib/commands/list.js");
20
+ await cmdModule.run();
21
+ break;
22
+ case "init":
23
+ cmdModule = await import("./lib/commands/init.js");
24
+ await cmdModule.run();
25
+ break;
26
+ case "install":
27
+ case "add":
28
+ case "i":
29
+ cmdModule = await import("./lib/commands/install.js");
30
+ await cmdModule.run(params[0]);
31
+ break;
32
+ case "uninstall":
33
+ case "remove":
34
+ case "rm":
35
+ cmdModule = await import("./lib/commands/uninstall.js");
36
+ await cmdModule.run(params[0]);
37
+ break;
38
+ case "update":
39
+ cmdModule = await import("./lib/commands/update.js");
40
+ await cmdModule.run(params[0]);
41
+ break;
42
+ case "lock":
43
+ cmdModule = await import("./lib/commands/lock.js");
44
+ await cmdModule.run();
45
+ break;
46
+ case "verify":
47
+ cmdModule = await import("./lib/commands/verify.js");
48
+ await cmdModule.run();
49
+ break;
50
+ case "doctor":
51
+ cmdModule = await import("./lib/commands/doctor.js");
52
+ await cmdModule.run();
53
+ break;
54
+ case "cache":
55
+ cmdModule = await import("./lib/commands/cache.js");
56
+ await cmdModule.run(params[0]);
57
+ break;
58
+ case "validate":
59
+ case "check":
60
+ cmdModule = await import("./lib/commands/validate.js");
61
+ await cmdModule.run(params[0]);
62
+ break;
63
+ case "analyze":
64
+ cmdModule = await import("./lib/commands/analyze.js");
65
+ await cmdModule.run(params[0]);
66
+ break;
67
+ case "info":
68
+ case "show":
69
+ cmdModule = await import("./lib/commands/info.js");
70
+ await cmdModule.run(params[0]);
71
+ break;
72
+ case "help":
73
+ case "--help":
74
+ case "-h":
75
+ cmdModule = await import("./lib/commands/help.js");
76
+ await cmdModule.run();
77
+ break;
78
+ case "--version":
79
+ case "-V":
80
+ console.log(VERSION);
81
+ break;
82
+ default:
83
+ // Handle direct install via org/repo syntax
84
+ if (command.includes("/")) {
85
+ cmdModule = await import("./lib/commands/install.js");
86
+ await cmdModule.run(command);
87
+ } else {
88
+ console.log(`Unknown command: ${command}`);
89
+ cmdModule = await import("./lib/commands/help.js");
90
+ await cmdModule.run();
91
+ }
92
+ }
93
+ } catch (err) {
94
+ console.error(c.red("\nError: " + err.message));
95
+ if (process.env.DEBUG) console.error(err.stack);
96
+ process.exit(1);
97
+ }
98
+ }
99
+
100
+ main().catch(err => {
101
+ console.error(c.red("\nFatal Error: " + err.message));
102
+ process.exit(1);
103
+ });
@@ -10,7 +10,7 @@ import os from "os";
10
10
  import { execSync } from "child_process";
11
11
  import crypto from "crypto";
12
12
  import prompts from "prompts";
13
- import { multiselect, isCancel, cancel, intro, outro, select, confirm } from "@clack/prompts";
13
+ import { multiselect, isCancel, cancel, intro, outro, select, confirm, log, spinner } from "@clack/prompts";
14
14
  import kleur from "kleur";
15
15
  import ora from "ora";
16
16
  import boxen from "boxen";
@@ -250,20 +250,50 @@ async function runInstall(spec) {
250
250
  if (!spec) { fatal("Missing skill spec. Usage: add-skill <org/repo>"); return; }
251
251
  const { org, repo, skill: singleSkill, ref } = parseSkillSpec(spec);
252
252
  if (!org || !repo) { fatal("Invalid spec. Format: org/repo or org/repo#skill"); return; }
253
+
254
+ // Start Clack UI session
255
+ intro(c.bgCyan(c.black(" add-skill ")));
256
+
253
257
  const url = `https://github.com/${org}/${repo}.git`;
254
- stepLine();
255
- console.log(` ${c.gray(S.branch)} ${c.bgCyan().black(" skills ")}`);
256
- stepLine();
257
- step(`Source: ${c.cyan(url)}`, S.diamond, "green");
258
- stepLine();
259
- const spinner = ora({ text: "Cloning repository", prefixText: ` ${c.gray(S.branch)} ${c.cyan(S.diamondFilled)} `, color: "cyan" }).start();
258
+ log.info(`Source: ${c.cyan(url)}`);
259
+
260
+ const s = spinner();
261
+ s.start("Cloning repository");
262
+
260
263
  const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "add-skill-"));
261
- try { execSync(`git clone --depth=1 ${url} "${tmp}"`, { stdio: "pipe" }); if (ref) execSync(`git -C "${tmp}" checkout ${ref}`, { stdio: "pipe" }); } catch { spinner.stop(); console.log(` ${c.gray(S.branch)} ${c.red(S.cross)} ${c.red("Failed to clone")}`); fs.rmSync(tmp, { recursive: true, force: true }); return; }
262
- spinner.stop(); step("Repository cloned", S.check, "green");
264
+ try {
265
+ execSync(`git clone --depth=1 ${url} "${tmp}"`, { stdio: "pipe" });
266
+ if (ref) execSync(`git -C "${tmp}" checkout ${ref}`, { stdio: "pipe" });
267
+ } catch {
268
+ s.stop("Failed to clone", 1);
269
+ log.error("Failed to clone repository");
270
+ fs.rmSync(tmp, { recursive: true, force: true });
271
+ cancel("Operation cancelled");
272
+ return;
273
+ }
274
+ s.stop("Repository cloned");
275
+
263
276
  const skillsInRepo = [];
264
- for (const e of fs.readdirSync(tmp)) { const sp = path.join(tmp, e); if (fs.statSync(sp).isDirectory() && fs.existsSync(path.join(sp, "SKILL.md"))) { const m = parseSkillMdFrontmatter(path.join(sp, "SKILL.md")); skillsInRepo.push({ title: e + (m.description ? c.dim(` (${m.description.substring(0, 40)}...)`) : ""), value: e, selected: singleSkill ? e === singleSkill : true }); } }
265
- if (skillsInRepo.length === 0) { step(c.yellow("No valid skills found"), S.diamond, "yellow"); fs.rmSync(tmp, { recursive: true, force: true }); return; }
266
- stepLine(); step(`Found ${skillsInRepo.length} skills`, S.diamond); stepLine();
277
+ for (const e of fs.readdirSync(tmp)) {
278
+ const sp = path.join(tmp, e);
279
+ if (fs.statSync(sp).isDirectory() && fs.existsSync(path.join(sp, "SKILL.md"))) {
280
+ const m = parseSkillMdFrontmatter(path.join(sp, "SKILL.md"));
281
+ skillsInRepo.push({
282
+ title: e + (m.description ? c.dim(` (${m.description.substring(0, 40)}...)`) : ""),
283
+ value: e,
284
+ selected: singleSkill ? e === singleSkill : true
285
+ });
286
+ }
287
+ }
288
+
289
+ if (skillsInRepo.length === 0) {
290
+ log.warn("No valid skills found in repository");
291
+ fs.rmSync(tmp, { recursive: true, force: true });
292
+ cancel("Operation cancelled");
293
+ return;
294
+ }
295
+
296
+ log.info(`Found ${skillsInRepo.length} skills`);
267
297
 
268
298
  // Use @clack/prompts for multiselect
269
299
  const skillsR = await multiselect({
@@ -284,12 +314,12 @@ async function runInstall(spec) {
284
314
  }
285
315
 
286
316
  const selectedSkills = skillsR;
287
- if (selectedSkills.length === 0) { console.log(`\n ${c.yellow("Cancelled.")}`); fs.rmSync(tmp, { recursive: true, force: true }); return; }
288
-
289
- stepLine();
290
- // Re-use standard prompts for scope for now, or could switch to clack select too,
291
- // but focusing on the requested "green square" UI which is multiselect.
292
- // To match style, let's use clack select for scope too.
317
+ if (selectedSkills.length === 0) {
318
+ log.warn("No skills selected");
319
+ fs.rmSync(tmp, { recursive: true, force: true });
320
+ cancel("Operation cancelled");
321
+ return;
322
+ }
293
323
 
294
324
  const scopeR = await select({
295
325
  message: 'Installation scope',
@@ -308,22 +338,29 @@ async function runInstall(spec) {
308
338
 
309
339
  const targetScope = scopeR === "global" ? GLOBAL_DIR : WORKSPACE;
310
340
 
311
- stepLine(); step("Installation Summary", S.diamond); stepLine();
312
- let boxContent = ""; for (const sn of selectedSkills) boxContent += `${c.cyan(sn)}\n ${c.dim(targetScope)}\n\n`;
313
- const box = boxen(boxContent.trim(), { padding: 1, borderStyle: "round", borderColor: "gray", dimBorder: true });
314
- box.split("\n").forEach(l => console.log(` ${c.gray(S.branch)} ${l}`));
341
+ log.info("Installing skills...");
342
+ fs.mkdirSync(targetScope, { recursive: true });
343
+
344
+ // Install loop
345
+ const sInstall = spinner();
346
+ sInstall.start("Copying files");
315
347
 
316
- stepLine(); fs.mkdirSync(targetScope, { recursive: true });
317
348
  for (const sn of selectedSkills) {
318
349
  const src = path.join(tmp, sn), dest = path.join(targetScope, sn);
319
350
  if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });
320
351
  fs.cpSync(src, dest, { recursive: true });
321
352
  const hash = merkleHash(dest);
322
353
  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));
323
- step(`Installed: ${c.bold(sn)}`, S.check, "green");
324
354
  }
355
+ sInstall.stop("Files copied");
356
+
357
+ for (const sn of selectedSkills) {
358
+ log.success(`Installed ${c.bold(sn)}`);
359
+ }
360
+
325
361
  fs.rmSync(tmp, { recursive: true, force: true });
326
- stepLine(); console.log(` ${c.cyan("Done!")}`); console.log();
362
+
363
+ outro("Done!");
327
364
  }
328
365
 
329
366
  async function runUninstall(skillName) {
package/bin/lib/ui.js CHANGED
@@ -3,6 +3,9 @@
3
3
  */
4
4
 
5
5
  import kleur from "kleur";
6
+ import { intro, outro, spinner, multiselect, select, confirm, isCancel, cancel, text } from "@clack/prompts";
7
+
8
+ export { intro, outro, spinner, multiselect, select, confirm, isCancel, cancel, text };
6
9
 
7
10
  // --- Symbols ---
8
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "install-agent-skill",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
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>",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "type": "module",
16
16
  "bin": {
17
- "add-skill": "./bin/add-skill.v2.js"
17
+ "add-skill": "./bin/add-skill.modular.js"
18
18
  },
19
19
  "files": [
20
20
  "bin/",