ai-builder 0.1.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.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,545 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import chalk5 from "chalk";
5
+ import { Command } from "commander";
6
+
7
+ // src/commands/add.ts
8
+ import * as readline from "readline";
9
+ import chalk from "chalk";
10
+ import ora from "ora";
11
+
12
+ // src/services/api.ts
13
+ var API_BASE = process.env.AI_BUILDER_API_URL || "https://aibuilder.sh/api";
14
+ async function resolveArtifact(type, slug) {
15
+ const url = `${API_BASE}/resolve?type=${encodeURIComponent(type)}&slug=${encodeURIComponent(slug)}`;
16
+ const response = await fetch(url);
17
+ if (!response.ok) {
18
+ const errorBody = await response.json().catch(() => ({ error: "Unknown error" }));
19
+ throw new Error(errorBody.error || `Failed to resolve artifact: ${response.status}`);
20
+ }
21
+ return response.json();
22
+ }
23
+ async function searchArtifacts(options) {
24
+ const params = new URLSearchParams();
25
+ if (options.query) params.set("q", options.query);
26
+ if (options.type) params.set("type", options.type);
27
+ if (options.task) params.set("task", options.task);
28
+ if (options.limit) params.set("limit", options.limit.toString());
29
+ const url = `${API_BASE}/artifacts?${params.toString()}`;
30
+ const response = await fetch(url);
31
+ if (!response.ok) {
32
+ throw new Error(`Failed to search artifacts: ${response.status}`);
33
+ }
34
+ return response.json();
35
+ }
36
+ async function trackInstall(type, slug, cliVersion) {
37
+ try {
38
+ await fetch(`${API_BASE}/install-events`, {
39
+ method: "POST",
40
+ headers: { "Content-Type": "application/json" },
41
+ body: JSON.stringify({ type, slug, cliVersion })
42
+ });
43
+ } catch {
44
+ }
45
+ }
46
+ async function resolveStack(slug) {
47
+ const url = `${API_BASE}/stacks/${encodeURIComponent(slug)}`;
48
+ const response = await fetch(url);
49
+ if (!response.ok) {
50
+ const errorBody = await response.json().catch(() => ({ error: "Unknown error" }));
51
+ throw new Error(errorBody.error || `Failed to resolve stack: ${response.status}`);
52
+ }
53
+ return response.json();
54
+ }
55
+
56
+ // src/services/installer.ts
57
+ import * as fs2 from "fs";
58
+ import * as path2 from "path";
59
+
60
+ // src/services/lock-file.ts
61
+ import * as fs from "fs";
62
+ import * as path from "path";
63
+ var LOCK_FILE_NAME = "ai-builder.lock.json";
64
+ function getLockFilePath() {
65
+ return path.join(process.cwd(), ".claude", LOCK_FILE_NAME);
66
+ }
67
+ function readLockFile() {
68
+ const lockPath = getLockFilePath();
69
+ if (!fs.existsSync(lockPath)) {
70
+ return { version: 1, artifacts: {} };
71
+ }
72
+ try {
73
+ const content = fs.readFileSync(lockPath, "utf-8");
74
+ return JSON.parse(content);
75
+ } catch {
76
+ return { version: 1, artifacts: {} };
77
+ }
78
+ }
79
+ function writeLockFile(lockFile) {
80
+ const lockPath = getLockFilePath();
81
+ const lockDir = path.dirname(lockPath);
82
+ if (!fs.existsSync(lockDir)) {
83
+ fs.mkdirSync(lockDir, { recursive: true });
84
+ }
85
+ fs.writeFileSync(lockPath, `${JSON.stringify(lockFile, null, 2)}
86
+ `);
87
+ }
88
+ function addToLockFile(entry) {
89
+ const lockFile = readLockFile();
90
+ const key = `${entry.type}:${entry.author}/${entry.slug}`;
91
+ lockFile.artifacts[key] = entry;
92
+ writeLockFile(lockFile);
93
+ }
94
+ function removeFromLockFile(type, author, slug) {
95
+ const lockFile = readLockFile();
96
+ const key = `${type}:${author}/${slug}`;
97
+ delete lockFile.artifacts[key];
98
+ writeLockFile(lockFile);
99
+ }
100
+ function getInstalledArtifacts() {
101
+ const lockFile = readLockFile();
102
+ return Object.values(lockFile.artifacts);
103
+ }
104
+ function isInstalled(type, author, slug) {
105
+ const lockFile = readLockFile();
106
+ const key = `${type}:${author}/${slug}`;
107
+ return key in lockFile.artifacts;
108
+ }
109
+
110
+ // src/services/installer.ts
111
+ function getInstallPath(type, artifactName) {
112
+ const basePath = path2.join(process.cwd(), ".claude");
113
+ switch (type) {
114
+ case "skill":
115
+ return path2.join(basePath, "skills", artifactName);
116
+ case "agent":
117
+ return path2.join(basePath, "agents", `${artifactName}.md`);
118
+ case "command":
119
+ return path2.join(basePath, "commands", `${artifactName}.md`);
120
+ default:
121
+ throw new Error(`Unknown artifact type: ${type}`);
122
+ }
123
+ }
124
+ function installArtifact(artifact, options = {}) {
125
+ const [, artifactName] = artifact.installPath.includes("/") ? artifact.installPath.split("/").filter(Boolean) : [null, artifact.installPath.replace(".claude/", "").replace(".md", "").split("/").pop()];
126
+ const installPath = getInstallPath(artifact.type, artifactName || artifact.name);
127
+ const files = [];
128
+ if (!options.force && isInstalled(artifact.type, artifact.author, artifactName || artifact.name)) {
129
+ return { installed: false, files: [] };
130
+ }
131
+ const dir = artifact.type === "skill" ? installPath : path2.dirname(installPath);
132
+ if (!fs2.existsSync(dir)) {
133
+ fs2.mkdirSync(dir, { recursive: true });
134
+ }
135
+ if (artifact.type === "skill") {
136
+ const skillMdPath = path2.join(installPath, "SKILL.md");
137
+ fs2.writeFileSync(skillMdPath, artifact.content);
138
+ files.push(skillMdPath);
139
+ if (artifact.bundleFiles) {
140
+ for (const [filename, content] of Object.entries(artifact.bundleFiles)) {
141
+ const filePath = path2.join(installPath, filename);
142
+ fs2.mkdirSync(path2.dirname(filePath), { recursive: true });
143
+ fs2.writeFileSync(filePath, content);
144
+ files.push(filePath);
145
+ }
146
+ }
147
+ } else {
148
+ fs2.writeFileSync(installPath, artifact.content);
149
+ files.push(installPath);
150
+ }
151
+ addToLockFile({
152
+ type: artifact.type,
153
+ slug: artifactName || artifact.name,
154
+ author: artifact.author,
155
+ name: artifact.name,
156
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
157
+ files: files.map((f) => path2.relative(process.cwd(), f))
158
+ });
159
+ return { installed: true, files };
160
+ }
161
+ function uninstallArtifact(type, author, slug) {
162
+ const installPath = getInstallPath(type, slug);
163
+ if (!fs2.existsSync(installPath)) {
164
+ return false;
165
+ }
166
+ if (type === "skill") {
167
+ fs2.rmSync(installPath, { recursive: true, force: true });
168
+ } else {
169
+ fs2.unlinkSync(installPath);
170
+ }
171
+ removeFromLockFile(type, author, slug);
172
+ return true;
173
+ }
174
+
175
+ // src/commands/add.ts
176
+ var VALID_TYPES = ["skill", "agent", "command", "stack"];
177
+ var CLI_VERSION = "0.1.0";
178
+ async function addCommand(type, slug, options) {
179
+ if (!type) {
180
+ console.log(chalk.red("Error: Missing artifact type."));
181
+ console.log("Usage: ai-builder add <type> <author/slug>");
182
+ console.log("Types: skill, agent, command, stack");
183
+ process.exit(1);
184
+ }
185
+ if (!VALID_TYPES.includes(type)) {
186
+ console.log(chalk.red(`Error: Invalid type "${type}".`));
187
+ console.log("Valid types: skill, agent, command, stack");
188
+ process.exit(1);
189
+ }
190
+ if (!slug) {
191
+ console.log(chalk.red("Error: Missing artifact slug."));
192
+ console.log("Usage: ai-builder add <type> <author/slug>");
193
+ console.log("Example: ai-builder add agent anthropic/frontend-tester");
194
+ process.exit(1);
195
+ }
196
+ if (type !== "stack" && !slug.includes("/")) {
197
+ console.log(chalk.red("Error: Invalid slug format."));
198
+ console.log("Expected format: author/artifact-name");
199
+ console.log("Example: anthropic/frontend-tester");
200
+ process.exit(1);
201
+ }
202
+ if (type === "stack") {
203
+ await installStack(slug, options);
204
+ return;
205
+ }
206
+ const [author, artifactSlug] = slug.split("/");
207
+ if (!options.force && isInstalled(type, author, artifactSlug)) {
208
+ console.log(chalk.yellow(`${type} ${chalk.bold(slug)} is already installed.`));
209
+ console.log("Use --force to reinstall.");
210
+ return;
211
+ }
212
+ const spinner = ora(`Resolving ${type} ${chalk.cyan(slug)}...`).start();
213
+ try {
214
+ const artifact = await resolveArtifact(type, slug);
215
+ spinner.text = `Installing ${artifact.name}...`;
216
+ const { installed } = installArtifact(artifact, { force: options.force });
217
+ if (!installed) {
218
+ spinner.warn(`${artifact.name} is already installed. Use --force to reinstall.`);
219
+ return;
220
+ }
221
+ trackInstall(type, slug, CLI_VERSION);
222
+ spinner.succeed(
223
+ `Installed ${chalk.green(artifact.name)} to ${chalk.dim(artifact.installPath)}`
224
+ );
225
+ console.log();
226
+ printUsageHint(type, artifactSlug);
227
+ } catch (error) {
228
+ const message = error instanceof Error ? error.message : "Unknown error";
229
+ spinner.fail(chalk.red(`Failed to install: ${message}`));
230
+ process.exit(1);
231
+ }
232
+ }
233
+ function printUsageHint(type, slug) {
234
+ switch (type) {
235
+ case "agent":
236
+ console.log(chalk.dim(" Try it:"));
237
+ console.log(` ${chalk.green(`@${slug}`)} write tests for my auth module`);
238
+ break;
239
+ case "command":
240
+ console.log(chalk.dim(" Try it:"));
241
+ console.log(` ${chalk.green(`/${slug}`)}`);
242
+ break;
243
+ case "skill":
244
+ console.log(chalk.dim(" This skill will be available in Claude Code automatically."));
245
+ break;
246
+ }
247
+ }
248
+ async function installStack(stackSlug, options) {
249
+ const spinner = ora(`Resolving stack ${chalk.cyan(stackSlug)}...`).start();
250
+ try {
251
+ const stack = await resolveStack(stackSlug);
252
+ spinner.stop();
253
+ console.log();
254
+ console.log(chalk.bold(`Stack: ${stack.title}`));
255
+ if (stack.summary) {
256
+ console.log(chalk.dim(stack.summary));
257
+ }
258
+ console.log();
259
+ console.log(`This will install ${chalk.cyan(stack.artifactCount)} artifacts:`);
260
+ console.log();
261
+ for (const artifact of stack.artifacts) {
262
+ const typeColor = artifact.type === "skill" ? chalk.blue : artifact.type === "agent" ? chalk.magenta : chalk.green;
263
+ console.log(` ${typeColor(`[${artifact.type}]`)} ${artifact.name}`);
264
+ console.log(` ${chalk.dim(artifact.slug)}`);
265
+ if (artifact.installNotes) {
266
+ console.log(` ${chalk.yellow(`Note: ${artifact.installNotes}`)}`);
267
+ }
268
+ }
269
+ console.log();
270
+ if (!options.yes) {
271
+ const confirmed = await confirm("Proceed with installation?");
272
+ if (!confirmed) {
273
+ console.log("Cancelled.");
274
+ return;
275
+ }
276
+ }
277
+ console.log();
278
+ let installed = 0;
279
+ let skipped = 0;
280
+ for (const artifact of stack.artifacts) {
281
+ const artifactSpinner = ora(`Installing ${artifact.name}...`).start();
282
+ try {
283
+ const resolved = await resolveArtifact(artifact.type, artifact.slug);
284
+ const result = installArtifact(resolved, { force: options.force });
285
+ if (result.installed) {
286
+ artifactSpinner.succeed(`Installed ${chalk.green(artifact.name)}`);
287
+ trackInstall(artifact.type, artifact.slug, CLI_VERSION);
288
+ installed++;
289
+ } else {
290
+ artifactSpinner.info(`${artifact.name} already installed`);
291
+ skipped++;
292
+ }
293
+ } catch (error) {
294
+ const message = error instanceof Error ? error.message : "Unknown error";
295
+ artifactSpinner.fail(`Failed to install ${artifact.name}: ${chalk.dim(message)}`);
296
+ }
297
+ }
298
+ console.log();
299
+ console.log(
300
+ `${chalk.green("Done!")} Installed ${installed} artifact${installed === 1 ? "" : "s"}${skipped > 0 ? `, skipped ${skipped}` : ""}`
301
+ );
302
+ console.log();
303
+ console.log(chalk.dim(`Learn more: https://aibuilder.sh/stacks/${stackSlug}`));
304
+ } catch (error) {
305
+ const message = error instanceof Error ? error.message : "Unknown error";
306
+ spinner.fail(chalk.red(`Failed to resolve stack: ${message}`));
307
+ process.exit(1);
308
+ }
309
+ }
310
+ async function confirm(question) {
311
+ const rl = readline.createInterface({
312
+ input: process.stdin,
313
+ output: process.stdout
314
+ });
315
+ return new Promise((resolve) => {
316
+ rl.question(`${question} ${chalk.dim("[y/N]")} `, (answer) => {
317
+ rl.close();
318
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
319
+ });
320
+ });
321
+ }
322
+
323
+ // src/commands/list.ts
324
+ import chalk2 from "chalk";
325
+ var TYPE_COLORS = {
326
+ skill: chalk2.blue,
327
+ agent: chalk2.magenta,
328
+ command: chalk2.green
329
+ };
330
+ async function listCommand(options) {
331
+ let artifacts = getInstalledArtifacts();
332
+ if (options.type) {
333
+ artifacts = artifacts.filter((a) => a.type === options.type);
334
+ }
335
+ if (artifacts.length === 0) {
336
+ if (options.type) {
337
+ console.log(chalk2.dim(`No ${options.type}s installed.`));
338
+ } else {
339
+ console.log(chalk2.dim("No artifacts installed."));
340
+ }
341
+ console.log();
342
+ console.log("Install artifacts with:");
343
+ console.log(`${chalk2.green(" $ ")}ai-builder add agent anthropic/frontend-tester`);
344
+ return;
345
+ }
346
+ console.log();
347
+ console.log(chalk2.bold("Installed Artifacts"));
348
+ console.log();
349
+ console.log(
350
+ `${chalk2.dim(" ") + padEnd("TYPE", 10) + padEnd("NAME", 30) + padEnd("AUTHOR", 15)}INSTALLED`
351
+ );
352
+ console.log(chalk2.dim(` ${"-".repeat(70)}`));
353
+ for (const artifact of artifacts) {
354
+ const typeColor = TYPE_COLORS[artifact.type] || chalk2.white;
355
+ const typeLabel = typeColor(padEnd(artifact.type, 10));
356
+ const name = padEnd(artifact.name, 30);
357
+ const author = chalk2.dim(padEnd(artifact.author, 15));
358
+ const date = chalk2.dim(formatDate(artifact.installedAt));
359
+ console.log(` ${typeLabel}${name}${author}${date}`);
360
+ }
361
+ console.log();
362
+ console.log(
363
+ chalk2.dim(` ${artifacts.length} artifact${artifacts.length === 1 ? "" : "s"} installed`)
364
+ );
365
+ console.log();
366
+ }
367
+ function padEnd(str, length) {
368
+ return str.length >= length ? str : str + " ".repeat(length - str.length);
369
+ }
370
+ function formatDate(isoDate) {
371
+ const date = new Date(isoDate);
372
+ const now = /* @__PURE__ */ new Date();
373
+ const diffMs = now.getTime() - date.getTime();
374
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
375
+ if (diffDays === 0) {
376
+ return "today";
377
+ }
378
+ if (diffDays === 1) {
379
+ return "yesterday";
380
+ }
381
+ if (diffDays < 7) {
382
+ return `${diffDays} days ago`;
383
+ }
384
+ if (diffDays < 30) {
385
+ const weeks = Math.floor(diffDays / 7);
386
+ return `${weeks} week${weeks === 1 ? "" : "s"} ago`;
387
+ }
388
+ return date.toLocaleDateString();
389
+ }
390
+
391
+ // src/commands/remove.ts
392
+ import * as readline2 from "readline";
393
+ import chalk3 from "chalk";
394
+ var VALID_TYPES2 = ["skill", "agent", "command"];
395
+ async function removeCommand(type, slug, options) {
396
+ if (!type) {
397
+ console.log(chalk3.red("Error: Missing artifact type."));
398
+ console.log("Usage: ai-builder remove <type> <author/slug>");
399
+ console.log("Types: skill, agent, command");
400
+ process.exit(1);
401
+ }
402
+ if (!VALID_TYPES2.includes(type)) {
403
+ console.log(chalk3.red(`Error: Invalid type "${type}".`));
404
+ console.log("Valid types: skill, agent, command");
405
+ process.exit(1);
406
+ }
407
+ if (!slug) {
408
+ console.log(chalk3.red("Error: Missing artifact slug."));
409
+ console.log("Usage: ai-builder remove <type> <author/slug>");
410
+ console.log("Example: ai-builder remove agent anthropic/frontend-tester");
411
+ process.exit(1);
412
+ }
413
+ if (!slug.includes("/")) {
414
+ console.log(chalk3.red("Error: Invalid slug format."));
415
+ console.log("Expected format: author/artifact-name");
416
+ console.log("Example: anthropic/frontend-tester");
417
+ process.exit(1);
418
+ }
419
+ const [author, artifactSlug] = slug.split("/");
420
+ if (!isInstalled(type, author, artifactSlug)) {
421
+ console.log(chalk3.yellow(`${type} ${chalk3.bold(slug)} is not installed.`));
422
+ return;
423
+ }
424
+ if (!options.yes) {
425
+ const confirmed = await confirm2(`Remove ${type} ${chalk3.cyan(slug)}?`);
426
+ if (!confirmed) {
427
+ console.log("Cancelled.");
428
+ return;
429
+ }
430
+ }
431
+ const removed = uninstallArtifact(type, author, artifactSlug);
432
+ if (removed) {
433
+ console.log(chalk3.green(`Removed ${type} ${chalk3.bold(slug)}`));
434
+ } else {
435
+ console.log(chalk3.red(`Failed to remove ${type} ${slug}`));
436
+ process.exit(1);
437
+ }
438
+ }
439
+ async function confirm2(question) {
440
+ const rl = readline2.createInterface({
441
+ input: process.stdin,
442
+ output: process.stdout
443
+ });
444
+ return new Promise((resolve) => {
445
+ rl.question(`${question} ${chalk3.dim("[y/N]")} `, (answer) => {
446
+ rl.close();
447
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
448
+ });
449
+ });
450
+ }
451
+
452
+ // src/commands/search.ts
453
+ import chalk4 from "chalk";
454
+ import ora2 from "ora";
455
+ var TYPE_COLORS2 = {
456
+ skill: chalk4.blue,
457
+ agent: chalk4.magenta,
458
+ command: chalk4.green
459
+ };
460
+ async function searchCommand(query, options) {
461
+ const limit = Number.parseInt(options.limit || "10", 10);
462
+ const spinner = ora2(`Searching for "${query}"...`).start();
463
+ try {
464
+ const { artifacts, total } = await searchArtifacts({
465
+ query,
466
+ type: options.type,
467
+ task: options.task,
468
+ limit
469
+ });
470
+ spinner.stop();
471
+ if (artifacts.length === 0) {
472
+ console.log(chalk4.dim(`No results found for "${query}"`));
473
+ return;
474
+ }
475
+ console.log();
476
+ console.log(chalk4.bold(`Found ${total} result${total === 1 ? "" : "s"}`));
477
+ console.log();
478
+ for (const artifact of artifacts) {
479
+ const typeColor = TYPE_COLORS2[artifact.type] || chalk4.white;
480
+ const typeLabel = typeColor(`[${artifact.type}]`);
481
+ const fullSlug = `${artifact.author}/${artifact.slug}`;
482
+ console.log(` ${typeLabel} ${chalk4.bold(artifact.name)}`);
483
+ console.log(` ${chalk4.cyan(fullSlug)}`);
484
+ if (artifact.summary) {
485
+ console.log(` ${chalk4.dim(truncate(artifact.summary, 60))}`);
486
+ }
487
+ console.log(` ${chalk4.dim(`${formatNumber(artifact.installCount)} installs`)}`);
488
+ console.log();
489
+ }
490
+ if (total > artifacts.length) {
491
+ console.log(chalk4.dim(` ... and ${total - artifacts.length} more results`));
492
+ console.log(chalk4.dim(" Use --limit to see more results"));
493
+ console.log();
494
+ }
495
+ console.log("Install with:");
496
+ if (artifacts.length > 0) {
497
+ const first = artifacts[0];
498
+ console.log(
499
+ `${chalk4.green(" $ ")}ai-builder add ${first.type} ${first.author}/${first.slug}`
500
+ );
501
+ }
502
+ console.log();
503
+ } catch (error) {
504
+ const message = error instanceof Error ? error.message : "Unknown error";
505
+ spinner.fail(chalk4.red(`Search failed: ${message}`));
506
+ process.exit(1);
507
+ }
508
+ }
509
+ function truncate(str, length) {
510
+ if (str.length <= length) return str;
511
+ return `${str.slice(0, length - 3)}...`;
512
+ }
513
+ function formatNumber(num) {
514
+ if (num >= 1e6) {
515
+ return `${(num / 1e6).toFixed(1)}M`;
516
+ }
517
+ if (num >= 1e3) {
518
+ return `${(num / 1e3).toFixed(1)}K`;
519
+ }
520
+ return num.toString();
521
+ }
522
+
523
+ // src/index.ts
524
+ var program = new Command();
525
+ program.name("ai-builder").description("CLI for installing Claude Code artifacts from aibuilder.sh").version("0.1.0");
526
+ program.command("add").description("Install an artifact or stack").argument("[type]", "Artifact type: skill, agent, command, or stack").argument("[slug]", "Artifact slug in author/name format").option("-f, --force", "Overwrite existing artifacts").option("-y, --yes", "Skip confirmation for stacks").action(addCommand);
527
+ 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);
528
+ program.command("list").alias("ls").description("List installed artifacts").option("-t, --type <type>", "Filter by type: skill, agent, or command").action(listCommand);
529
+ 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);
530
+ program.action(() => {
531
+ console.log(chalk5.cyan.bold("\n ai-builder") + chalk5.dim(" - Claude Code artifact registry\n"));
532
+ console.log(" Usage:");
533
+ console.log(" ai-builder add <type> <author/slug> Install an artifact");
534
+ console.log(" ai-builder remove <type> <slug> Remove an artifact");
535
+ console.log(" ai-builder list List installed");
536
+ console.log(" ai-builder search <query> Search registry");
537
+ console.log("\n Examples:");
538
+ console.log(`${chalk5.green(" $ ")}ai-builder add agent anthropic/frontend-tester`);
539
+ console.log(`${chalk5.green(" $ ")}ai-builder add stack nextjs-fullstack`);
540
+ console.log(`${chalk5.green(" $ ")}ai-builder search "test generator"`);
541
+ console.log(`
542
+ Learn more at ${chalk5.cyan("https://aibuilder.sh")}
543
+ `);
544
+ });
545
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "ai-builder",
3
+ "version": "0.1.0",
4
+ "description": "CLI for installing Claude Code artifacts from aibuilder.sh",
5
+ "type": "module",
6
+ "bin": {
7
+ "ai-builder": "./dist/index.js"
8
+ },
9
+ "files": ["dist"],
10
+ "scripts": {
11
+ "build": "tsup src/index.ts --format esm --dts --clean",
12
+ "dev": "tsx src/index.ts",
13
+ "type-check": "tsc --noEmit",
14
+ "prepublishOnly": "pnpm run build",
15
+ "preversion": "pnpm run type-check",
16
+ "release:patch": "npm version patch -m 'chore(cli): release v%s'",
17
+ "release:minor": "npm version minor -m 'chore(cli): release v%s'",
18
+ "release:major": "npm version major -m 'chore(cli): release v%s'"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "dependencies": {
24
+ "chalk": "^5.3.0",
25
+ "commander": "^12.1.0",
26
+ "ora": "^8.1.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.10.5",
30
+ "tsup": "^8.3.6",
31
+ "tsx": "^4.19.2",
32
+ "typescript": "^5.7.3"
33
+ },
34
+ "engines": {
35
+ "node": ">=18"
36
+ },
37
+ "keywords": ["claude", "claude-code", "ai", "cli", "artifacts", "skills", "agents", "commands"],
38
+ "author": "",
39
+ "license": "MIT",
40
+ "homepage": "https://aibuilder.sh",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/BrainGridAI/ai-builder"
44
+ }
45
+ }