api2cli 0.3.5 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +234 -114
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2292,39 +2292,227 @@ ${import_picocolors.default.bold("Next steps:")}`);
2292
2292
  });
2293
2293
 
2294
2294
  // src/commands/install.ts
2295
+ var import_picocolors3 = __toESM(require_picocolors(), 1);
2296
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync2 } from "fs";
2297
+ import { join as join5 } from "path";
2298
+ import { homedir as homedir3 } from "os";
2299
+
2300
+ // src/lib/shell.ts
2295
2301
  var import_picocolors2 = __toESM(require_picocolors(), 1);
2296
- import { existsSync as existsSync3 } from "fs";
2297
- var installCommand = new Command("install").description("Install a pre-built CLI from the registry").argument("<app>", "CLI to install (e.g. typefully, dub)").option("--force", "Overwrite existing CLI", false).addHelpText("after", `
2302
+ import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2, appendFileSync, symlinkSync, unlinkSync, chmodSync } from "fs";
2303
+ import { homedir as homedir2 } from "os";
2304
+ import { join as join4 } from "path";
2305
+ var BIN_DIR = join4(homedir2(), ".local", "bin");
2306
+ var MARKER_START = "# >>> api2cli >>>";
2307
+ var MARKER_END = "# <<< api2cli <<<";
2308
+ function getShellRc() {
2309
+ const shell = process.env.SHELL ?? "";
2310
+ if (shell.includes("zsh"))
2311
+ return join4(homedir2(), ".zshrc");
2312
+ if (shell.includes("fish"))
2313
+ return join4(homedir2(), ".config", "fish", "config.fish");
2314
+ const zshrc = join4(homedir2(), ".zshrc");
2315
+ if (existsSync3(zshrc))
2316
+ return zshrc;
2317
+ return join4(homedir2(), ".bashrc");
2318
+ }
2319
+ function ensureBinInPath() {
2320
+ const rcFile = getShellRc();
2321
+ const content = existsSync3(rcFile) ? readFileSync2(rcFile, "utf-8") : "";
2322
+ const exportLine = `export PATH="${BIN_DIR}:$PATH"`;
2323
+ if (content.includes(BIN_DIR))
2324
+ return;
2325
+ if (content.includes(MARKER_START)) {
2326
+ const updated = content.replace(MARKER_END, `${exportLine}
2327
+ ${MARKER_END}`);
2328
+ writeFileSync2(rcFile, updated);
2329
+ } else {
2330
+ appendFileSync(rcFile, `
2331
+ ${MARKER_START}
2332
+ ${exportLine}
2333
+ ${MARKER_END}
2334
+ `);
2335
+ }
2336
+ }
2337
+ function addToPath(app, distDir) {
2338
+ const { mkdirSync: mkdirSync2 } = __require("fs");
2339
+ mkdirSync2(BIN_DIR, { recursive: true });
2340
+ const target = join4(distDir, `${app}-cli.js`);
2341
+ const linkPath = join4(BIN_DIR, `${app}-cli`);
2342
+ if (!existsSync3(target)) {
2343
+ console.error(`${import_picocolors2.default.red("\u2717")} Built file not found: ${target}`);
2344
+ console.error(` Run: ${import_picocolors2.default.cyan(`npx api2cli bundle ${app}`)}`);
2345
+ process.exit(1);
2346
+ }
2347
+ chmodSync(target, 493);
2348
+ if (existsSync3(linkPath)) {
2349
+ unlinkSync(linkPath);
2350
+ }
2351
+ symlinkSync(target, linkPath);
2352
+ ensureBinInPath();
2353
+ console.log(`${import_picocolors2.default.green("+")} Linked ${import_picocolors2.default.bold(`${app}-cli`)} -> ${import_picocolors2.default.dim(linkPath)}`);
2354
+ console.log(` ${import_picocolors2.default.dim("PATH updated in")} ${import_picocolors2.default.dim(getShellRc())}`);
2355
+ }
2356
+ function removeFromPath(app, _distDir) {
2357
+ const linkPath = join4(BIN_DIR, `${app}-cli`);
2358
+ if (!existsSync3(linkPath)) {
2359
+ console.log(`${import_picocolors2.default.dim(app)} not linked`);
2360
+ return;
2361
+ }
2362
+ unlinkSync(linkPath);
2363
+ console.log(`${import_picocolors2.default.red("-")} Unlinked ${import_picocolors2.default.bold(`${app}-cli`)}`);
2364
+ }
2365
+
2366
+ // src/commands/install.ts
2367
+ var REGISTRY_API = "https://api2cli.dev/api";
2368
+ function parseGithubInput(input) {
2369
+ const cleaned = input.trim().replace(/\.git$/, "").replace(/\/$/, "");
2370
+ const shortMatch = cleaned.match(/^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)$/);
2371
+ if (shortMatch)
2372
+ return { owner: shortMatch[1], repo: shortMatch[2] };
2373
+ const urlMatch = cleaned.match(/(?:https?:\/\/)?github\.com\/([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)/);
2374
+ if (urlMatch)
2375
+ return { owner: urlMatch[1], repo: urlMatch[2] };
2376
+ return null;
2377
+ }
2378
+ function getAppName(repo) {
2379
+ return repo.replace(/-cli$/, "");
2380
+ }
2381
+ function symlinkSkill(cliDir, appCli) {
2382
+ const skillSource = join5(cliDir, "skills", appCli, "SKILL.md");
2383
+ if (!existsSync4(skillSource))
2384
+ return;
2385
+ const agentDirs = [
2386
+ { name: "Claude Code", path: join5(homedir3(), ".claude", "skills") },
2387
+ { name: "Cursor", path: join5(homedir3(), ".cursor", "skills") },
2388
+ { name: "OpenClaw", path: join5(homedir3(), ".openclaw", "workspace", "skills") }
2389
+ ];
2390
+ for (const agent of agentDirs) {
2391
+ if (!existsSync4(join5(agent.path, "..")))
2392
+ continue;
2393
+ const skillDir = join5(agent.path, appCli);
2394
+ mkdirSync2(skillDir, { recursive: true });
2395
+ const target = join5(skillDir, "SKILL.md");
2396
+ if (existsSync4(target))
2397
+ unlinkSync2(target);
2398
+ symlinkSync2(skillSource, target);
2399
+ console.log(` ${import_picocolors3.default.green("+")} Skill symlinked for ${import_picocolors3.default.dim(agent.name)}`);
2400
+ }
2401
+ }
2402
+ var installCommand = new Command("install").description("Install a CLI from GitHub repo").argument("<source>", "GitHub repo (owner/repo) or app name from registry").option("--force", "Overwrite existing CLI", false).addHelpText("after", `
2298
2403
  Examples:
2299
- api2cli install typefully
2300
- api2cli install dub --force`).action(async (app, opts) => {
2404
+ api2cli install Melvynx/typefully-cli
2405
+ api2cli install https://github.com/Melvynx/typefully-cli
2406
+ api2cli install typefully`).action(async (source, opts) => {
2407
+ let owner;
2408
+ let repo;
2409
+ const parsed = parseGithubInput(source);
2410
+ if (parsed) {
2411
+ owner = parsed.owner;
2412
+ repo = parsed.repo;
2413
+ } else {
2414
+ console.log(`Looking up ${import_picocolors3.default.bold(source)} in registry...`);
2415
+ try {
2416
+ const res = await fetch(`${REGISTRY_API}/skills/${source}`);
2417
+ if (!res.ok) {
2418
+ console.error(`${import_picocolors3.default.red("\u2717")} ${source} not found in registry.`);
2419
+ console.error(` Try: ${import_picocolors3.default.cyan(`api2cli install owner/repo`)}`);
2420
+ process.exit(1);
2421
+ }
2422
+ const data = await res.json();
2423
+ const githubUrl = data.githubRepo || data.skill?.githubRepo;
2424
+ if (!githubUrl) {
2425
+ console.error(`${import_picocolors3.default.red("\u2717")} No GitHub repo found for ${source}.`);
2426
+ process.exit(1);
2427
+ }
2428
+ const repoParsed = parseGithubInput(githubUrl);
2429
+ if (!repoParsed) {
2430
+ console.error(`${import_picocolors3.default.red("\u2717")} Invalid repo URL from registry: ${githubUrl}`);
2431
+ process.exit(1);
2432
+ }
2433
+ owner = repoParsed.owner;
2434
+ repo = repoParsed.repo;
2435
+ } catch {
2436
+ console.error(`${import_picocolors3.default.red("\u2717")} Could not reach registry. Use ${import_picocolors3.default.cyan("owner/repo")} format instead.`);
2437
+ process.exit(1);
2438
+ }
2439
+ }
2440
+ const app = getAppName(repo);
2441
+ const appCli = `${app}-cli`;
2301
2442
  const cliDir = getCliDir(app);
2302
- if (existsSync3(cliDir) && !opts.force) {
2303
- console.error(`${import_picocolors2.default.red("\u2717")} ${app}-cli already installed. Use ${import_picocolors2.default.cyan("--force")} to reinstall.`);
2443
+ if (existsSync4(cliDir) && !opts.force) {
2444
+ console.error(`${import_picocolors3.default.red("\u2717")} ${appCli} already installed at ${cliDir}`);
2445
+ console.error(` Use ${import_picocolors3.default.cyan("--force")} to reinstall.`);
2446
+ process.exit(1);
2447
+ }
2448
+ console.log(`
2449
+ ${import_picocolors3.default.bold("Installing")} ${import_picocolors3.default.cyan(appCli)} from ${import_picocolors3.default.dim(`${owner}/${repo}`)}...
2450
+ `);
2451
+ mkdirSync2(cliDir, { recursive: true });
2452
+ const clone = Bun.spawn(["git", "clone", "--depth", "1", `https://github.com/${owner}/${repo}.git`, cliDir], { stdout: "ignore", stderr: "pipe" });
2453
+ const cloneCode = await clone.exited;
2454
+ if (cloneCode !== 0) {
2455
+ const stderr = await new Response(clone.stderr).text();
2456
+ if (opts.force) {
2457
+ Bun.spawn(["rm", "-rf", cliDir], { stdout: "ignore", stderr: "ignore" });
2458
+ await Bun.spawn(["rm", "-rf", cliDir]).exited;
2459
+ const retry = Bun.spawn(["git", "clone", "--depth", "1", `https://github.com/${owner}/${repo}.git`, cliDir], { stdout: "ignore", stderr: "pipe" });
2460
+ const retryCode = await retry.exited;
2461
+ if (retryCode !== 0) {
2462
+ const retryErr = await new Response(retry.stderr).text();
2463
+ console.error(`${import_picocolors3.default.red("\u2717")} Clone failed: ${retryErr}`);
2464
+ process.exit(1);
2465
+ }
2466
+ } else {
2467
+ console.error(`${import_picocolors3.default.red("\u2717")} Clone failed: ${stderr}`);
2468
+ process.exit(1);
2469
+ }
2470
+ }
2471
+ console.log(` ${import_picocolors3.default.green("+")} Cloned ${import_picocolors3.default.dim(`${owner}/${repo}`)}`);
2472
+ console.log(` ${import_picocolors3.default.dim("Installing dependencies...")}`);
2473
+ const install = Bun.spawn(["bun", "install"], {
2474
+ cwd: cliDir,
2475
+ stdout: "ignore",
2476
+ stderr: "pipe"
2477
+ });
2478
+ await install.exited;
2479
+ console.log(` ${import_picocolors3.default.green("+")} Dependencies installed`);
2480
+ const entry = join5(cliDir, "src", "index.ts");
2481
+ const distDir = getDistDir(app);
2482
+ mkdirSync2(distDir, { recursive: true });
2483
+ const outfile = join5(distDir, `${appCli}.js`);
2484
+ const build = Bun.spawn(["bun", "build", entry, "--outfile", outfile, "--target", "bun"], { cwd: cliDir, stdout: "ignore", stderr: "pipe" });
2485
+ const buildCode = await build.exited;
2486
+ if (buildCode !== 0) {
2487
+ const stderr = await new Response(build.stderr).text();
2488
+ console.error(`${import_picocolors3.default.red("\u2717")} Build failed: ${stderr}`);
2304
2489
  process.exit(1);
2305
2490
  }
2306
- console.log(`Installing ${import_picocolors2.default.bold(`${app}-cli`)} from registry...`);
2491
+ console.log(` ${import_picocolors3.default.green("+")} Built`);
2492
+ addToPath(app, distDir);
2493
+ symlinkSkill(cliDir, appCli);
2307
2494
  console.log(`
2308
- ${import_picocolors2.default.yellow("\uD83D\uDEA7")} Registry not yet available.`);
2495
+ ${import_picocolors3.default.green("\u2713")} Installed ${import_picocolors3.default.bold(appCli)}`);
2309
2496
  console.log(`
2310
- Create it manually instead:`);
2311
- console.log(` ${import_picocolors2.default.cyan(`api2cli create ${app} --docs <api-docs-url>`)}`);
2497
+ ${import_picocolors3.default.bold("Next:")}`);
2498
+ console.log(` ${import_picocolors3.default.cyan(`${appCli} auth set "your-token"`)}`);
2499
+ console.log(` ${import_picocolors3.default.cyan(`${appCli} --help`)}`);
2312
2500
  });
2313
2501
 
2314
2502
  // src/commands/list.ts
2315
- var import_picocolors3 = __toESM(require_picocolors(), 1);
2316
- import { existsSync as existsSync4, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
2317
- import { join as join4 } from "path";
2503
+ var import_picocolors4 = __toESM(require_picocolors(), 1);
2504
+ import { existsSync as existsSync5, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
2505
+ import { join as join6 } from "path";
2318
2506
  var listCommand = new Command("list").description("List all installed CLIs").option("--json", "Output as JSON").addHelpText("after", `
2319
2507
  Examples:
2320
2508
  api2cli list
2321
2509
  api2cli list --json`).action((opts) => {
2322
- if (!existsSync4(CLI_ROOT)) {
2510
+ if (!existsSync5(CLI_ROOT)) {
2323
2511
  console.log("No CLIs installed. Run: api2cli create <app>");
2324
2512
  return;
2325
2513
  }
2326
- const dirs = readdirSync2(CLI_ROOT).filter((d) => {
2327
- return statSync2(join4(CLI_ROOT, d)).isDirectory() && d.endsWith("-cli");
2514
+ const dirs = readdirSync3(CLI_ROOT).filter((d) => {
2515
+ return statSync2(join6(CLI_ROOT, d)).isDirectory() && d.endsWith("-cli");
2328
2516
  });
2329
2517
  if (dirs.length === 0) {
2330
2518
  console.log("No CLIs installed.");
@@ -2335,46 +2523,46 @@ Examples:
2335
2523
  const name = d.replace(/-cli$/, "");
2336
2524
  return {
2337
2525
  name,
2338
- built: existsSync4(join4(CLI_ROOT, d, "dist")),
2339
- hasToken: existsSync4(join4(TOKENS_DIR, `${d}.txt`)),
2340
- path: join4(CLI_ROOT, d)
2526
+ built: existsSync5(join6(CLI_ROOT, d, "dist")),
2527
+ hasToken: existsSync5(join6(TOKENS_DIR, `${d}.txt`)),
2528
+ path: join6(CLI_ROOT, d)
2341
2529
  };
2342
2530
  });
2343
2531
  console.log(JSON.stringify({ ok: true, data }, null, 2));
2344
2532
  return;
2345
2533
  }
2346
2534
  console.log(`
2347
- ${import_picocolors3.default.bold("Installed CLIs:")}
2535
+ ${import_picocolors4.default.bold("Installed CLIs:")}
2348
2536
  `);
2349
2537
  for (const d of dirs) {
2350
2538
  const name = d.replace(/-cli$/, "");
2351
- const built = existsSync4(join4(CLI_ROOT, d, "dist"));
2352
- const hasToken = existsSync4(join4(TOKENS_DIR, `${d}.txt`));
2539
+ const built = existsSync5(join6(CLI_ROOT, d, "dist"));
2540
+ const hasToken = existsSync5(join6(TOKENS_DIR, `${d}.txt`));
2353
2541
  const status = [
2354
- built ? import_picocolors3.default.green("built") : import_picocolors3.default.yellow("not built"),
2355
- hasToken ? import_picocolors3.default.green("auth") : import_picocolors3.default.dim("no auth")
2356
- ].join(import_picocolors3.default.dim(" | "));
2357
- console.log(` ${import_picocolors3.default.bold(name.padEnd(20))} ${status}`);
2542
+ built ? import_picocolors4.default.green("built") : import_picocolors4.default.yellow("not built"),
2543
+ hasToken ? import_picocolors4.default.green("auth") : import_picocolors4.default.dim("no auth")
2544
+ ].join(import_picocolors4.default.dim(" | "));
2545
+ console.log(` ${import_picocolors4.default.bold(name.padEnd(20))} ${status}`);
2358
2546
  }
2359
2547
  console.log();
2360
2548
  });
2361
2549
 
2362
2550
  // src/commands/bundle.ts
2363
- var import_picocolors4 = __toESM(require_picocolors(), 1);
2364
- import { existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
2365
- import { join as join5 } from "path";
2366
- import { readdirSync as readdirSync3 } from "fs";
2551
+ var import_picocolors5 = __toESM(require_picocolors(), 1);
2552
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
2553
+ import { join as join7 } from "path";
2554
+ import { readdirSync as readdirSync4 } from "fs";
2367
2555
  var bundleCommand = new Command("bundle").description("Build/rebuild a CLI from source").argument("[app]", "CLI to build (omit with --all)").option("--compile", "Create standalone binary (~50MB, no runtime needed)").option("--all", "Build all installed CLIs").addHelpText("after", `
2368
2556
  Examples:
2369
2557
  api2cli bundle typefully
2370
2558
  api2cli bundle typefully --compile
2371
2559
  api2cli bundle --all`).action(async (app, opts) => {
2372
2560
  if (opts.all) {
2373
- if (!existsSync5(CLI_ROOT)) {
2561
+ if (!existsSync6(CLI_ROOT)) {
2374
2562
  console.log("No CLIs installed.");
2375
2563
  return;
2376
2564
  }
2377
- const dirs = readdirSync3(CLI_ROOT).filter((d) => d.endsWith("-cli"));
2565
+ const dirs = readdirSync4(CLI_ROOT).filter((d) => d.endsWith("-cli"));
2378
2566
  for (const d of dirs) {
2379
2567
  await buildCli(d.replace(/-cli$/, ""), opts.compile);
2380
2568
  }
@@ -2388,15 +2576,15 @@ Examples:
2388
2576
  });
2389
2577
  async function buildCli(app, compile) {
2390
2578
  const cliDir = getCliDir(app);
2391
- if (!existsSync5(cliDir)) {
2392
- console.error(`${import_picocolors4.default.red("\u2717")} ${app}-cli not found. Run: ${import_picocolors4.default.cyan(`api2cli create ${app}`)}`);
2579
+ if (!existsSync6(cliDir)) {
2580
+ console.error(`${import_picocolors5.default.red("\u2717")} ${app}-cli not found. Run: ${import_picocolors5.default.cyan(`api2cli create ${app}`)}`);
2393
2581
  return;
2394
2582
  }
2395
2583
  const distDir = getDistDir(app);
2396
- mkdirSync2(distDir, { recursive: true });
2397
- console.log(`Building ${import_picocolors4.default.bold(`${app}-cli`)}...`);
2398
- const entry = join5(cliDir, "src", "index.ts");
2399
- const outfile = join5(distDir, compile ? `${app}-cli` : `${app}-cli.js`);
2584
+ mkdirSync3(distDir, { recursive: true });
2585
+ console.log(`Building ${import_picocolors5.default.bold(`${app}-cli`)}...`);
2586
+ const entry = join7(cliDir, "src", "index.ts");
2587
+ const outfile = join7(distDir, compile ? `${app}-cli` : `${app}-cli.js`);
2400
2588
  const args = ["bun", "build", entry, "--outfile", outfile, "--target", "bun"];
2401
2589
  if (compile)
2402
2590
  args.push("--compile");
@@ -2405,84 +2593,16 @@ async function buildCli(app, compile) {
2405
2593
  if (code === 0) {
2406
2594
  const size = Bun.file(outfile).size;
2407
2595
  const sizeStr = size > 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(1)}MB` : `${(size / 1024).toFixed(1)}KB`;
2408
- console.log(`${import_picocolors4.default.green("\u2713")} Built ${import_picocolors4.default.bold(`${app}-cli`)} (${sizeStr})`);
2596
+ console.log(`${import_picocolors5.default.green("\u2713")} Built ${import_picocolors5.default.bold(`${app}-cli`)} (${sizeStr})`);
2409
2597
  } else {
2410
2598
  const stderr = await new Response(proc.stderr).text();
2411
- console.error(`${import_picocolors4.default.red("\u2717")} Build failed: ${stderr}`);
2599
+ console.error(`${import_picocolors5.default.red("\u2717")} Build failed: ${stderr}`);
2412
2600
  }
2413
2601
  }
2414
2602
 
2415
2603
  // src/commands/link.ts
2416
2604
  var import_picocolors6 = __toESM(require_picocolors(), 1);
2417
- import { existsSync as existsSync7, readdirSync as readdirSync4 } from "fs";
2418
-
2419
- // src/lib/shell.ts
2420
- var import_picocolors5 = __toESM(require_picocolors(), 1);
2421
- import { existsSync as existsSync6, readFileSync as readFileSync2, writeFileSync as writeFileSync2, appendFileSync, symlinkSync, unlinkSync, chmodSync } from "fs";
2422
- import { homedir as homedir2 } from "os";
2423
- import { join as join6 } from "path";
2424
- var BIN_DIR = join6(homedir2(), ".local", "bin");
2425
- var MARKER_START = "# >>> api2cli >>>";
2426
- var MARKER_END = "# <<< api2cli <<<";
2427
- function getShellRc() {
2428
- const shell = process.env.SHELL ?? "";
2429
- if (shell.includes("zsh"))
2430
- return join6(homedir2(), ".zshrc");
2431
- if (shell.includes("fish"))
2432
- return join6(homedir2(), ".config", "fish", "config.fish");
2433
- const zshrc = join6(homedir2(), ".zshrc");
2434
- if (existsSync6(zshrc))
2435
- return zshrc;
2436
- return join6(homedir2(), ".bashrc");
2437
- }
2438
- function ensureBinInPath() {
2439
- const rcFile = getShellRc();
2440
- const content = existsSync6(rcFile) ? readFileSync2(rcFile, "utf-8") : "";
2441
- const exportLine = `export PATH="${BIN_DIR}:$PATH"`;
2442
- if (content.includes(BIN_DIR))
2443
- return;
2444
- if (content.includes(MARKER_START)) {
2445
- const updated = content.replace(MARKER_END, `${exportLine}
2446
- ${MARKER_END}`);
2447
- writeFileSync2(rcFile, updated);
2448
- } else {
2449
- appendFileSync(rcFile, `
2450
- ${MARKER_START}
2451
- ${exportLine}
2452
- ${MARKER_END}
2453
- `);
2454
- }
2455
- }
2456
- function addToPath(app, distDir) {
2457
- const { mkdirSync: mkdirSync3 } = __require("fs");
2458
- mkdirSync3(BIN_DIR, { recursive: true });
2459
- const target = join6(distDir, `${app}-cli.js`);
2460
- const linkPath = join6(BIN_DIR, `${app}-cli`);
2461
- if (!existsSync6(target)) {
2462
- console.error(`${import_picocolors5.default.red("\u2717")} Built file not found: ${target}`);
2463
- console.error(` Run: ${import_picocolors5.default.cyan(`npx api2cli bundle ${app}`)}`);
2464
- process.exit(1);
2465
- }
2466
- chmodSync(target, 493);
2467
- if (existsSync6(linkPath)) {
2468
- unlinkSync(linkPath);
2469
- }
2470
- symlinkSync(target, linkPath);
2471
- ensureBinInPath();
2472
- console.log(`${import_picocolors5.default.green("+")} Linked ${import_picocolors5.default.bold(`${app}-cli`)} -> ${import_picocolors5.default.dim(linkPath)}`);
2473
- console.log(` ${import_picocolors5.default.dim("PATH updated in")} ${import_picocolors5.default.dim(getShellRc())}`);
2474
- }
2475
- function removeFromPath(app, _distDir) {
2476
- const linkPath = join6(BIN_DIR, `${app}-cli`);
2477
- if (!existsSync6(linkPath)) {
2478
- console.log(`${import_picocolors5.default.dim(app)} not linked`);
2479
- return;
2480
- }
2481
- unlinkSync(linkPath);
2482
- console.log(`${import_picocolors5.default.red("-")} Unlinked ${import_picocolors5.default.bold(`${app}-cli`)}`);
2483
- }
2484
-
2485
- // src/commands/link.ts
2605
+ import { existsSync as existsSync7, readdirSync as readdirSync5 } from "fs";
2486
2606
  var linkCommand = new Command("link").description("Add a CLI to your PATH").argument("[app]", "CLI to link (omit with --all)").option("--all", "Link all installed CLIs").addHelpText("after", `
2487
2607
  Examples:
2488
2608
  api2cli link typefully
@@ -2492,7 +2612,7 @@ Examples:
2492
2612
  console.log("No CLIs installed.");
2493
2613
  return;
2494
2614
  }
2495
- const dirs = readdirSync4(CLI_ROOT).filter((d) => d.endsWith("-cli"));
2615
+ const dirs = readdirSync5(CLI_ROOT).filter((d) => d.endsWith("-cli"));
2496
2616
  for (const d of dirs) {
2497
2617
  const name = d.replace(/-cli$/, "");
2498
2618
  addToPath(name, getDistDir(name));
@@ -2515,8 +2635,8 @@ Example:
2515
2635
 
2516
2636
  // src/commands/tokens.ts
2517
2637
  var import_picocolors7 = __toESM(require_picocolors(), 1);
2518
- import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync3 } from "fs";
2519
- import { join as join7 } from "path";
2638
+ import { existsSync as existsSync8, readdirSync as readdirSync6, readFileSync as readFileSync3 } from "fs";
2639
+ import { join as join8 } from "path";
2520
2640
  var tokensCommand = new Command("tokens").description("List all configured API tokens").option("--show", "Show full unmasked tokens").addHelpText("after", `
2521
2641
  Examples:
2522
2642
  api2cli tokens
@@ -2525,7 +2645,7 @@ Examples:
2525
2645
  console.log("No tokens configured yet.");
2526
2646
  return;
2527
2647
  }
2528
- const files = readdirSync5(TOKENS_DIR).filter((f) => f.endsWith(".txt"));
2648
+ const files = readdirSync6(TOKENS_DIR).filter((f) => f.endsWith(".txt"));
2529
2649
  if (files.length === 0) {
2530
2650
  console.log("No tokens configured yet.");
2531
2651
  return;
@@ -2535,7 +2655,7 @@ ${import_picocolors7.default.bold("Configured tokens:")}
2535
2655
  `);
2536
2656
  for (const f of files) {
2537
2657
  const name = f.replace(".txt", "");
2538
- const token = readFileSync3(join7(TOKENS_DIR, f), "utf-8").trim();
2658
+ const token = readFileSync3(join8(TOKENS_DIR, f), "utf-8").trim();
2539
2659
  const display = opts.show ? token : token.length > 8 ? `${token.slice(0, 4)}${import_picocolors7.default.dim("...")}${token.slice(-4)}` : import_picocolors7.default.dim("****");
2540
2660
  console.log(` ${import_picocolors7.default.bold(name.padEnd(25))} ${display}`);
2541
2661
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api2cli",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Turn any REST API into a standardized, agent-ready CLI",
5
5
  "type": "module",
6
6
  "bin": {