ai-builder 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -13
- package/dist/index.js +16 -124
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
21
|
- **Install artifacts** - Add skills, agents, and commands from the registry
|
|
22
|
-
- **Install stacks** - Bundle multiple artifacts together for specific workflows
|
|
23
22
|
- **Search the registry** - Find artifacts by name, description, or task category
|
|
24
23
|
- **Manage installed artifacts** - List and remove artifacts from your project
|
|
25
24
|
- **Self-update** - Keep the CLI up to date with a single command
|
|
@@ -72,7 +71,7 @@ Install an artifact from the registry:
|
|
|
72
71
|
npx ai-builder add <type> <author/slug>
|
|
73
72
|
```
|
|
74
73
|
|
|
75
|
-
**Types:** `skill`, `agent`, `command
|
|
74
|
+
**Types:** `skill`, `agent`, `command`
|
|
76
75
|
|
|
77
76
|
**Examples:**
|
|
78
77
|
|
|
@@ -90,16 +89,6 @@ npx ai-builder add skill anthropic/mcp-builder
|
|
|
90
89
|
npx ai-builder add agent git-town/code_reviewer --force
|
|
91
90
|
```
|
|
92
91
|
|
|
93
|
-
**Stacks** bundle multiple artifacts together:
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
# Install a stack (prompts for confirmation)
|
|
97
|
-
npx ai-builder add stack my-stack
|
|
98
|
-
|
|
99
|
-
# Skip confirmation
|
|
100
|
-
npx ai-builder add stack my-stack --yes
|
|
101
|
-
```
|
|
102
|
-
|
|
103
92
|
### Remove
|
|
104
93
|
|
|
105
94
|
Remove an installed artifact:
|
|
@@ -219,7 +208,6 @@ ai-builder completion zsh >> ~/.zshrc
|
|
|
219
208
|
| **skill** | Background capabilities that enhance Claude's abilities | `.claude/skills/{name}/` |
|
|
220
209
|
| **agent** | Specialized agents invoked with `@agent-name` | `.claude/agents/{name}.md` |
|
|
221
210
|
| **command** | Slash commands invoked with `/command-name` | `.claude/commands/{name}.md` |
|
|
222
|
-
| **stack** | Bundles of artifacts for specific workflows | Various locations |
|
|
223
211
|
|
|
224
212
|
---
|
|
225
213
|
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,6 @@ import chalk8 from "chalk";
|
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/commands/add.ts
|
|
8
|
-
import * as readline from "readline";
|
|
9
8
|
import chalk from "chalk";
|
|
10
9
|
import ora from "ora";
|
|
11
10
|
|
|
@@ -165,19 +164,6 @@ async function trackInstall(type, slug, cliVersion) {
|
|
|
165
164
|
logger.debug({ err: error, type, slug }, "Install tracking failed (non-critical)");
|
|
166
165
|
}
|
|
167
166
|
}
|
|
168
|
-
async function resolveStack(slug) {
|
|
169
|
-
const url = `${API_BASE}/stacks/${encodeURIComponent(slug)}`;
|
|
170
|
-
const timer = logger.startTimer("api-resolve-stack");
|
|
171
|
-
const response = await fetch(url);
|
|
172
|
-
if (!response.ok) {
|
|
173
|
-
const errorBody = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
174
|
-
timer.done({ slug, status: response.status, success: false });
|
|
175
|
-
throw new Error(errorBody.error || `Failed to resolve stack: ${response.status}`);
|
|
176
|
-
}
|
|
177
|
-
const result = await response.json();
|
|
178
|
-
timer.done({ slug, artifactCount: result.artifactCount, status: response.status, success: true });
|
|
179
|
-
return result;
|
|
180
|
-
}
|
|
181
167
|
|
|
182
168
|
// src/services/installer.ts
|
|
183
169
|
import * as fs3 from "fs";
|
|
@@ -248,7 +234,7 @@ function getInstallPath(type, artifactName) {
|
|
|
248
234
|
}
|
|
249
235
|
}
|
|
250
236
|
function installArtifact(artifact, options = {}) {
|
|
251
|
-
const artifactName = artifact.
|
|
237
|
+
const artifactName = artifact.name;
|
|
252
238
|
const installPath = getInstallPath(artifact.type, artifactName);
|
|
253
239
|
const files = [];
|
|
254
240
|
if (!options.force && isInstalled(artifact.type, artifact.author, artifactName || artifact.name)) {
|
|
@@ -276,7 +262,7 @@ function installArtifact(artifact, options = {}) {
|
|
|
276
262
|
}
|
|
277
263
|
addToLockFile({
|
|
278
264
|
type: artifact.type,
|
|
279
|
-
slug:
|
|
265
|
+
slug: artifact.name,
|
|
280
266
|
author: artifact.author,
|
|
281
267
|
name: artifact.name,
|
|
282
268
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -299,18 +285,18 @@ function uninstallArtifact(type, author, slug) {
|
|
|
299
285
|
}
|
|
300
286
|
|
|
301
287
|
// src/commands/add.ts
|
|
302
|
-
var VALID_TYPES = ["skill", "agent", "command"
|
|
288
|
+
var VALID_TYPES = ["skill", "agent", "command"];
|
|
303
289
|
var CLI_VERSION = "0.1.0";
|
|
304
290
|
async function addCommand(type, slug, options) {
|
|
305
291
|
if (!type) {
|
|
306
292
|
console.log(chalk.red("Error: Missing artifact type."));
|
|
307
293
|
console.log("Usage: ai-builder add <type> <author/slug>");
|
|
308
|
-
console.log("Types: skill, agent, command
|
|
294
|
+
console.log("Types: skill, agent, command");
|
|
309
295
|
process.exit(1);
|
|
310
296
|
}
|
|
311
297
|
if (!VALID_TYPES.includes(type)) {
|
|
312
298
|
console.log(chalk.red(`Error: Invalid type "${type}".`));
|
|
313
|
-
console.log("Valid types: skill, agent, command
|
|
299
|
+
console.log("Valid types: skill, agent, command");
|
|
314
300
|
process.exit(1);
|
|
315
301
|
}
|
|
316
302
|
if (!slug) {
|
|
@@ -319,16 +305,12 @@ async function addCommand(type, slug, options) {
|
|
|
319
305
|
console.log("Example: ai-builder add agent anthropic/frontend-tester");
|
|
320
306
|
process.exit(1);
|
|
321
307
|
}
|
|
322
|
-
if (
|
|
308
|
+
if (!slug.includes("/")) {
|
|
323
309
|
console.log(chalk.red("Error: Invalid slug format."));
|
|
324
310
|
console.log("Expected format: author/artifact-name");
|
|
325
311
|
console.log("Example: anthropic/frontend-tester");
|
|
326
312
|
process.exit(1);
|
|
327
313
|
}
|
|
328
|
-
if (type === "stack") {
|
|
329
|
-
await installStack(slug, options);
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
314
|
const [author, artifactSlug] = slug.split("/");
|
|
333
315
|
const isUpdate = isInstalled(type, author, artifactSlug);
|
|
334
316
|
const actionVerb = isUpdate ? "Updating" : "Resolving";
|
|
@@ -370,95 +352,6 @@ function printUsageHint(type, slug) {
|
|
|
370
352
|
break;
|
|
371
353
|
}
|
|
372
354
|
}
|
|
373
|
-
async function installStack(stackSlug, options) {
|
|
374
|
-
const spinner = ora(`Resolving stack ${chalk.cyan(stackSlug)}...`).start();
|
|
375
|
-
try {
|
|
376
|
-
const stack = await resolveStack(stackSlug);
|
|
377
|
-
spinner.stop();
|
|
378
|
-
console.log();
|
|
379
|
-
console.log(chalk.bold(`Stack: ${stack.title}`));
|
|
380
|
-
if (stack.summary) {
|
|
381
|
-
console.log(chalk.dim(stack.summary));
|
|
382
|
-
}
|
|
383
|
-
console.log();
|
|
384
|
-
console.log(`This will install ${chalk.cyan(stack.artifactCount)} artifacts:`);
|
|
385
|
-
console.log();
|
|
386
|
-
for (const artifact of stack.artifacts) {
|
|
387
|
-
const typeColor = artifact.type === "skill" ? chalk.blue : artifact.type === "agent" ? chalk.magenta : chalk.green;
|
|
388
|
-
console.log(` ${typeColor(`[${artifact.type}]`)} ${artifact.name}`);
|
|
389
|
-
console.log(` ${chalk.dim(artifact.slug)}`);
|
|
390
|
-
if (artifact.installNotes) {
|
|
391
|
-
console.log(` ${chalk.yellow(`Note: ${artifact.installNotes}`)}`);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
console.log();
|
|
395
|
-
if (!options.yes) {
|
|
396
|
-
const confirmed = await confirm("Proceed with installation?");
|
|
397
|
-
if (!confirmed) {
|
|
398
|
-
console.log("Cancelled.");
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
console.log();
|
|
403
|
-
let installed = 0;
|
|
404
|
-
let updated = 0;
|
|
405
|
-
for (const artifact of stack.artifacts) {
|
|
406
|
-
const [artifactAuthor, artifactSlug] = artifact.slug.split("/");
|
|
407
|
-
const isArtifactUpdate = isInstalled(artifact.type, artifactAuthor, artifactSlug);
|
|
408
|
-
const actionVerb = isArtifactUpdate ? "Updating" : "Installing";
|
|
409
|
-
const artifactSpinner = ora(`${actionVerb} ${artifact.name}...`).start();
|
|
410
|
-
try {
|
|
411
|
-
const resolved = await resolveArtifact(artifact.type, artifact.slug);
|
|
412
|
-
const result = installArtifact(resolved, { force: isArtifactUpdate || options.force });
|
|
413
|
-
if (result.installed) {
|
|
414
|
-
if (isArtifactUpdate) {
|
|
415
|
-
artifactSpinner.succeed(`Updated ${chalk.green(artifact.name)}`);
|
|
416
|
-
updated++;
|
|
417
|
-
} else {
|
|
418
|
-
artifactSpinner.succeed(`Installed ${chalk.green(artifact.name)}`);
|
|
419
|
-
installed++;
|
|
420
|
-
}
|
|
421
|
-
await trackInstall(artifact.type, artifact.slug, CLI_VERSION);
|
|
422
|
-
} else {
|
|
423
|
-
artifactSpinner.warn(`${artifact.name} could not be installed`);
|
|
424
|
-
}
|
|
425
|
-
} catch (error) {
|
|
426
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
427
|
-
artifactSpinner.fail(`Failed to install ${artifact.name}: ${chalk.dim(message)}`);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
console.log();
|
|
431
|
-
const parts = [];
|
|
432
|
-
if (installed > 0) {
|
|
433
|
-
parts.push(`installed ${installed}`);
|
|
434
|
-
}
|
|
435
|
-
if (updated > 0) {
|
|
436
|
-
parts.push(`updated ${updated}`);
|
|
437
|
-
}
|
|
438
|
-
const summary = parts.length > 0 ? parts.join(", ") : "no changes";
|
|
439
|
-
console.log(
|
|
440
|
-
`${chalk.green("Done!")} ${summary.charAt(0).toUpperCase() + summary.slice(1)} artifact${installed + updated === 1 ? "" : "s"}`
|
|
441
|
-
);
|
|
442
|
-
console.log();
|
|
443
|
-
console.log(chalk.dim(`Learn more: https://aibuilder.sh/stacks/${stackSlug}`));
|
|
444
|
-
} catch (error) {
|
|
445
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
446
|
-
spinner.fail(chalk.red(`Failed to resolve stack: ${message}`));
|
|
447
|
-
process.exit(1);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
async function confirm(question) {
|
|
451
|
-
const rl = readline.createInterface({
|
|
452
|
-
input: process.stdin,
|
|
453
|
-
output: process.stdout
|
|
454
|
-
});
|
|
455
|
-
return new Promise((resolve) => {
|
|
456
|
-
rl.question(`${question} ${chalk.dim("[y/N]")} `, (answer) => {
|
|
457
|
-
rl.close();
|
|
458
|
-
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
355
|
|
|
463
356
|
// src/commands/completion.ts
|
|
464
357
|
import * as fs4 from "fs";
|
|
@@ -472,7 +365,7 @@ _ai_builder_completions() {
|
|
|
472
365
|
_get_comp_words_by_ref -n : cur prev words cword
|
|
473
366
|
|
|
474
367
|
local commands="add remove rm list ls search status update completion"
|
|
475
|
-
local types="skill agent command
|
|
368
|
+
local types="skill agent command"
|
|
476
369
|
|
|
477
370
|
case "\${prev}" in
|
|
478
371
|
ai-builder)
|
|
@@ -526,7 +419,7 @@ _ai_builder() {
|
|
|
526
419
|
local -a commands types
|
|
527
420
|
|
|
528
421
|
commands=(
|
|
529
|
-
'add:Install an artifact
|
|
422
|
+
'add:Install an artifact'
|
|
530
423
|
'remove:Remove an installed artifact'
|
|
531
424
|
'rm:Remove an installed artifact'
|
|
532
425
|
'list:List installed artifacts'
|
|
@@ -537,7 +430,7 @@ _ai_builder() {
|
|
|
537
430
|
'completion:Generate shell completions'
|
|
538
431
|
)
|
|
539
432
|
|
|
540
|
-
types=(skill agent command
|
|
433
|
+
types=(skill agent command)
|
|
541
434
|
|
|
542
435
|
_arguments -C \\
|
|
543
436
|
'1:command:->command' \\
|
|
@@ -551,10 +444,9 @@ _ai_builder() {
|
|
|
551
444
|
case "$words[1]" in
|
|
552
445
|
add|remove|rm)
|
|
553
446
|
_arguments \\
|
|
554
|
-
'1:type:(skill agent command
|
|
447
|
+
'1:type:(skill agent command)' \\
|
|
555
448
|
'2:slug:' \\
|
|
556
449
|
'--force[Overwrite existing artifacts]' \\
|
|
557
|
-
'--yes[Skip confirmation]' \\
|
|
558
450
|
'--help[Show help]'
|
|
559
451
|
;;
|
|
560
452
|
list|ls)
|
|
@@ -735,7 +627,7 @@ function formatDate(isoDate) {
|
|
|
735
627
|
}
|
|
736
628
|
|
|
737
629
|
// src/commands/remove.ts
|
|
738
|
-
import * as
|
|
630
|
+
import * as readline from "readline";
|
|
739
631
|
import chalk4 from "chalk";
|
|
740
632
|
var VALID_TYPES2 = ["skill", "agent", "command"];
|
|
741
633
|
async function removeCommand(type, slug, options) {
|
|
@@ -768,7 +660,7 @@ async function removeCommand(type, slug, options) {
|
|
|
768
660
|
return;
|
|
769
661
|
}
|
|
770
662
|
if (!options.yes) {
|
|
771
|
-
const confirmed = await
|
|
663
|
+
const confirmed = await confirm(`Remove ${type} ${chalk4.cyan(slug)}?`);
|
|
772
664
|
if (!confirmed) {
|
|
773
665
|
console.log("Cancelled.");
|
|
774
666
|
return;
|
|
@@ -782,8 +674,8 @@ async function removeCommand(type, slug, options) {
|
|
|
782
674
|
process.exit(1);
|
|
783
675
|
}
|
|
784
676
|
}
|
|
785
|
-
async function
|
|
786
|
-
const rl =
|
|
677
|
+
async function confirm(question) {
|
|
678
|
+
const rl = readline.createInterface({
|
|
787
679
|
input: process.stdin,
|
|
788
680
|
output: process.stdout
|
|
789
681
|
});
|
|
@@ -984,7 +876,7 @@ async function updateCommand(options) {
|
|
|
984
876
|
// src/index.ts
|
|
985
877
|
var program = new Command();
|
|
986
878
|
program.name("ai-builder").description("CLI for installing Claude Code artifacts from aibuilder.sh").version(version);
|
|
987
|
-
program.command("add").description("Install an artifact
|
|
879
|
+
program.command("add").description("Install an artifact").argument("[type]", "Artifact type: skill, agent, or command").argument("[slug]", "Artifact slug in author/name format").option("-f, --force", "Overwrite existing artifacts").action(addCommand);
|
|
988
880
|
program.command("remove").alias("rm").description("Remove an installed artifact").argument("[type]", "Artifact type: skill, agent, or command").argument("[slug]", "Artifact slug in author/name format").option("-y, --yes", "Skip confirmation").action(removeCommand);
|
|
989
881
|
program.command("list").alias("ls").description("List installed artifacts").option("-t, --type <type>", "Filter by type: skill, agent, or command").action(listCommand);
|
|
990
882
|
program.command("search").description("Search the registry for artifacts").argument("<query>", "Search query").option("-t, --type <type>", "Filter by type: skill, agent, or command").option("--task <task>", "Filter by task category").option("-l, --limit <number>", "Number of results", "10").action(searchCommand);
|
|
@@ -1005,7 +897,7 @@ program.action(() => {
|
|
|
1005
897
|
console.log(" ai-builder update Update CLI");
|
|
1006
898
|
console.log("\n Examples:");
|
|
1007
899
|
console.log(`${chalk8.green(" $ ")}ai-builder add agent anthropic/frontend-tester`);
|
|
1008
|
-
console.log(`${chalk8.green(" $ ")}ai-builder add
|
|
900
|
+
console.log(`${chalk8.green(" $ ")}ai-builder add skill anthropic/code-reviewer`);
|
|
1009
901
|
console.log(`${chalk8.green(" $ ")}ai-builder search "test generator"`);
|
|
1010
902
|
console.log(`
|
|
1011
903
|
Learn more at ${chalk8.cyan("https://aibuilder.sh")}
|