bridgerapi 1.0.0 → 1.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.
Files changed (2) hide show
  1. package/dist/cli.js +122 -53
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -532,35 +532,71 @@ function serviceStatus() {
532
532
  var import_fs3 = require("fs");
533
533
  var import_os3 = require("os");
534
534
  var import_path2 = require("path");
535
+ var import_readline = require("readline");
535
536
  var PORT = parseInt(process.env.BRIDGERAPI_PORT ?? "8082");
536
537
  var LOG_DIR = (0, import_path2.join)((0, import_os3.homedir)(), ".bridgerapi");
537
- var USAGE = `
538
- bridgerapi \u2014 OpenAI-compatible API bridge for AI CLI tools
539
-
540
- Commands:
541
- start [--port <n>] Start server in the foreground (default port: 8082)
542
- install [--port <n>] Install as a background service (auto-starts on login)
543
- uninstall Remove background service
544
- status Show whether the service is running
545
- backends List detected CLI backends and their status
546
-
547
- Examples:
548
- bridgerapi start
549
- bridgerapi start --port 9000
550
- bridgerapi install
551
- bridgerapi backends
552
-
553
- Supported backends (auto-detected):
554
- claude-* \u2192 Claude Code CLI (oauth via Claude Code login)
555
- gemini-* \u2192 Gemini CLI (run: gemini auth)
556
- gpt-*, o3 \u2192 Codex CLI (run: codex auth)
557
- copilot \u2192 GitHub Copilot (run: gh auth login)
558
-
559
- Logs: ${LOG_DIR}/server.log
560
- `.trim();
538
+ function ask(question) {
539
+ const rl = (0, import_readline.createInterface)({ input: process.stdin, output: process.stdout });
540
+ return new Promise((resolve) => {
541
+ rl.question(question, (answer) => {
542
+ rl.close();
543
+ resolve(answer.trim());
544
+ });
545
+ });
546
+ }
547
+ var INSTALL_HINTS = {
548
+ claude: "Install Claude Code: https://claude.ai/download \u2192 then sign in with: claude login",
549
+ gemini: "Install Gemini CLI: npm install -g @google/gemini-cli \u2192 then: gemini auth",
550
+ codex: "Install Codex CLI: npm install -g @openai/codex \u2192 then: codex auth",
551
+ copilot: "Install Copilot: gh extension install github/gh-copilot \u2192 then: gh auth login"
552
+ };
553
+ async function cmdSetup() {
554
+ console.log();
555
+ console.log(" bridgerapi \u2014 OpenAI-compatible API bridge for AI CLI tools");
556
+ console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
557
+ console.log();
558
+ console.log(" Checking installed backends\u2026");
559
+ console.log();
560
+ const available = BACKENDS.filter((b) => b.available());
561
+ const missing = BACKENDS.filter((b) => !b.available());
562
+ for (const b of BACKENDS) {
563
+ const ok = b.available();
564
+ const icon = ok ? "\u2713" : "\u2717";
565
+ const note = ok ? b.models.join(", ") : "not found";
566
+ console.log(` ${icon} ${b.name.padEnd(10)} ${note}`);
567
+ }
568
+ console.log();
569
+ if (available.length === 0) {
570
+ console.log(" No CLI backends found. Install at least one:\n");
571
+ for (const b of missing) console.log(` ${INSTALL_HINTS[b.name]}`);
572
+ console.log();
573
+ console.log(" Then re-run: bridgerapi");
574
+ process.exit(1);
575
+ }
576
+ if (missing.length) {
577
+ console.log(" Optional \u2014 to enable missing backends:");
578
+ for (const b of missing) console.log(` ${INSTALL_HINTS[b.name]}`);
579
+ console.log();
580
+ }
581
+ const portAnswer = await ask(` Port [${PORT}]: `);
582
+ const port2 = portAnswer ? parseInt(portAnswer) || PORT : PORT;
583
+ console.log();
584
+ console.log(" How do you want to run bridgerapi?");
585
+ console.log(" 1 Start now in the foreground (stops when you close terminal)");
586
+ console.log(" 2 Install as a background service (auto-starts on login)");
587
+ console.log();
588
+ const modeAnswer = await ask(" Choose [1/2]: ");
589
+ const mode = modeAnswer === "2" ? "install" : "start";
590
+ console.log();
591
+ if (mode === "install") {
592
+ cmdInstall(port2);
593
+ } else {
594
+ cmdStart(port2);
595
+ }
596
+ }
561
597
  function parseArgs() {
562
598
  const args = process.argv.slice(2);
563
- const cmd2 = args[0] ?? "help";
599
+ const cmd2 = args[0] ?? "";
564
600
  let port2 = PORT;
565
601
  for (let i = 1; i < args.length; i++) {
566
602
  if ((args[i] === "--port" || args[i] === "-p") && args[i + 1]) {
@@ -573,33 +609,35 @@ function cmdStart(port2) {
573
609
  (0, import_fs3.mkdirSync)(LOG_DIR, { recursive: true });
574
610
  const available = BACKENDS.filter((b) => b.available());
575
611
  const unavailable = BACKENDS.filter((b) => !b.available());
576
- console.log(`bridgerapi http://127.0.0.1:${port2}`);
577
- console.log(` backends ready : ${available.map((b) => b.name).join(", ") || "none!"}`);
612
+ console.log(` bridgerapi \u2192 http://127.0.0.1:${port2}`);
613
+ console.log(` backends : ${available.map((b) => b.name).join(", ") || "none!"}`);
578
614
  if (unavailable.length) {
579
- console.log(` backends missing : ${unavailable.map((b) => b.name).join(", ")}`);
615
+ console.log(` missing : ${unavailable.map((b) => b.name).join(", ")}`);
580
616
  }
581
- console.log(` logs : ${LOG_DIR}/server.log`);
617
+ console.log(` logs : ${LOG_DIR}/server.log`);
582
618
  console.log();
583
619
  if (available.length === 0) {
584
- console.error("Error: no CLI backends found. Install claude / gemini / codex first.");
620
+ console.error(" Error: no CLI backends found. Run: bridgerapi to see setup instructions.");
585
621
  process.exit(1);
586
622
  }
587
623
  const server = createBridgeServer(port2);
588
624
  server.listen(port2, "127.0.0.1", () => {
589
625
  console.log(` GET /v1/models`);
590
- console.log(` POST /v1/chat/completions (stream + blocking)`);
626
+ console.log(` POST /v1/chat/completions (streaming + blocking)`);
591
627
  console.log(` GET /health`);
592
628
  console.log();
593
- console.log(` Goose provider config:`);
629
+ console.log(" OpenAI-compatible config:");
594
630
  console.log(` Base URL : http://127.0.0.1:${port2}/v1`);
595
631
  console.log(` API Key : local`);
596
- console.log(` Model : claude-sonnet-4-6`);
632
+ console.log(` Model : ${available[0].models[0]}`);
633
+ console.log();
634
+ console.log(" Ctrl+C to stop.");
597
635
  });
598
636
  server.on("error", (err) => {
599
637
  if (err.code === "EADDRINUSE") {
600
- console.error(`Port ${port2} is already in use. Try: bridgerapi start --port 9000`);
638
+ console.error(` Port ${port2} is already in use. Try: bridgerapi start --port 9000`);
601
639
  } else {
602
- console.error("Server error:", err.message);
640
+ console.error(" Server error:", err.message);
603
641
  }
604
642
  process.exit(1);
605
643
  });
@@ -617,14 +655,13 @@ function cmdInstall(port2) {
617
655
  http.get(`http://127.0.0.1:${port2}/health`, (res) => {
618
656
  if (res.statusCode === 200) {
619
657
  clearInterval(poll);
620
- console.log(`
621
- \u2713 bridgerapi running on http://127.0.0.1:${port2}`);
622
658
  console.log();
623
- console.log(" Goose config:");
624
- console.log(` Provider : OpenAI Compatible`);
659
+ console.log(` \u2713 bridgerapi is running on http://127.0.0.1:${port2}`);
660
+ console.log();
661
+ console.log(" OpenAI-compatible config:");
625
662
  console.log(` Base URL : http://127.0.0.1:${port2}/v1`);
626
663
  console.log(` API Key : local`);
627
- console.log(` Model : claude-sonnet-4-6`);
664
+ console.log(` Model : ${allModels()[0] ?? "claude-sonnet-4-6"}`);
628
665
  console.log();
629
666
  console.log(` Logs : tail -f ${LOG_DIR}/server.log`);
630
667
  console.log(` Stop : bridgerapi uninstall`);
@@ -634,15 +671,15 @@ function cmdInstall(port2) {
634
671
  });
635
672
  } catch {
636
673
  }
637
- if (attempts >= 10) {
674
+ if (attempts >= 15) {
638
675
  clearInterval(poll);
639
676
  console.log(`
640
- Server did not start. Check: tail -f ${LOG_DIR}/server.log`);
677
+ Server did not respond. Check: tail -f ${LOG_DIR}/server.log`);
641
678
  process.exit(1);
642
679
  }
643
680
  }, 600);
644
681
  } catch (err) {
645
- console.error("Install failed:", err.message);
682
+ console.error(" Install failed:", err.message);
646
683
  process.exit(1);
647
684
  }
648
685
  }
@@ -650,36 +687,63 @@ function cmdUninstall() {
650
687
  try {
651
688
  uninstallService();
652
689
  } catch (err) {
653
- console.error("Uninstall failed:", err.message);
690
+ console.error(" Uninstall failed:", err.message);
654
691
  process.exit(1);
655
692
  }
656
693
  }
657
694
  function cmdStatus(port2) {
658
695
  const { running, pid } = serviceStatus();
659
696
  if (running) {
660
- console.log(`\u2713 bridgerapi is running${pid ? ` (pid ${pid})` : ""} on port ${port2}`);
697
+ console.log(` \u2713 bridgerapi is running${pid ? ` (pid ${pid})` : ""} on port ${port2}`);
661
698
  } else {
662
- console.log(" bridgerapi is not running");
663
- console.log(" Start with: bridgerapi start or bridgerapi install");
699
+ console.log(" bridgerapi is not running.");
700
+ console.log(" Run: bridgerapi \u2192 interactive setup");
701
+ console.log(" Run: bridgerapi start \u2192 start in foreground");
702
+ console.log(" Run: bridgerapi install \u2192 install background service");
664
703
  }
665
704
  }
666
705
  function cmdBackends() {
667
- console.log("CLI backends:\n");
706
+ console.log("\n CLI backends:\n");
668
707
  for (const b of BACKENDS) {
669
708
  const ok = b.available();
670
709
  const icon = ok ? "\u2713" : "\u2717";
671
710
  const models = ok ? b.models.join(", ") : "(not installed)";
672
- console.log(` ${icon} ${b.name.padEnd(10)} ${models}`);
711
+ console.log(` ${icon} ${b.name.padEnd(10)} ${models}`);
712
+ if (!ok) console.log(` ${INSTALL_HINTS[b.name]}`);
673
713
  }
674
714
  console.log();
675
715
  const available = BACKENDS.filter((b) => b.available());
676
716
  if (available.length) {
677
- console.log(`All available models:
678
- ${allModels().join(", ")}`);
717
+ console.log(` All available models:
718
+ ${allModels().join(", ")}
719
+ `);
679
720
  }
680
721
  }
722
+ function showHelp() {
723
+ console.log(`
724
+ bridgerapi \u2014 OpenAI-compatible API bridge for AI CLI tools
725
+
726
+ Usage:
727
+ bridgerapi Interactive setup wizard
728
+ bridgerapi start [--port n] Start server in the foreground
729
+ bridgerapi install [--port n] Install as a background service
730
+ bridgerapi uninstall Remove background service
731
+ bridgerapi status Show service status
732
+ bridgerapi backends List detected backends
733
+
734
+ Supported backends (auto-detected):
735
+ claude-* \u2192 Claude Code CLI (claude login)
736
+ gemini-* \u2192 Gemini CLI (gemini auth)
737
+ gpt-*, o3 \u2192 Codex CLI (codex auth)
738
+ copilot \u2192 GitHub Copilot (gh auth login)
739
+ `.trim());
740
+ }
681
741
  var { cmd, port } = parseArgs();
682
742
  switch (cmd) {
743
+ case "":
744
+ case "setup":
745
+ cmdSetup();
746
+ break;
683
747
  case "start":
684
748
  cmdStart(port);
685
749
  break;
@@ -695,7 +759,12 @@ switch (cmd) {
695
759
  case "backends":
696
760
  cmdBackends();
697
761
  break;
762
+ case "help":
763
+ case "--help":
764
+ case "-h":
765
+ showHelp();
766
+ break;
698
767
  default:
699
- console.log(USAGE);
700
- if (cmd !== "help") process.exit(1);
768
+ showHelp();
769
+ process.exit(1);
701
770
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bridgerapi",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Turn any AI CLI (Claude Code, Gemini, Codex, GitHub Copilot) into an OpenAI-compatible API — no API keys needed",
5
5
  "keywords": [
6
6
  "claude",
@@ -21,7 +21,7 @@
21
21
  "author": "teodorwaltervido",
22
22
  "main": "dist/cli.js",
23
23
  "bin": {
24
- "bridgerapi": "./dist/cli.js"
24
+ "bridgerapi": "dist/cli.js"
25
25
  },
26
26
  "files": [
27
27
  "dist"