apiblaze 0.20.17 → 0.20.20

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 +65 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1024,7 +1024,7 @@ var import_commander = require("commander");
1024
1024
  var import_chalk53 = __toESM(require("chalk"));
1025
1025
 
1026
1026
  // package.json
1027
- var version = "0.20.17";
1027
+ var version = "0.20.20";
1028
1028
 
1029
1029
  // src/index.ts
1030
1030
  init_types();
@@ -2390,11 +2390,34 @@ function installIntoClaude(spec2) {
2390
2390
  if (r.status === 0) return { ok: true };
2391
2391
  return { ok: false, error: (r.stderr || r.stdout || `exit ${r.status}`).trim().slice(0, 400) };
2392
2392
  }
2393
+ function claudeServerStatus(name) {
2394
+ const r = run("claude", ["mcp", "get", name]);
2395
+ const out = `${r.stdout || ""}${r.stderr || ""}`;
2396
+ const line = out.split("\n").find((l) => l.includes("Status:")) ?? "";
2397
+ if (/connected/i.test(line)) return "connected";
2398
+ if (/needs auth/i.test(line)) return "needs-auth";
2399
+ if (/failed|error|unreachable/i.test(line)) return "failed";
2400
+ return "unknown";
2401
+ }
2402
+ function waitForClaudeConnection(name, timeoutMs = 12e3) {
2403
+ const deadline = Date.now() + timeoutMs;
2404
+ let last = "unknown";
2405
+ for (; ; ) {
2406
+ last = claudeServerStatus(name);
2407
+ if (last === "connected" || Date.now() >= deadline) return last;
2408
+ (0, import_child_process.spawnSync)(process.execPath, ["-e", "setTimeout(()=>{},1200)"], { timeout: 3e3 });
2409
+ }
2410
+ }
2393
2411
  function claudeOneShot(spec2, prompt) {
2394
2412
  const argv = ["claude", "-p", prompt, "--allowedTools", `mcp__${spec2.name}__*`];
2395
2413
  const r = run(argv[0], argv.slice(1), { inherit: true });
2396
2414
  return { argv, status: r.status };
2397
2415
  }
2416
+ function claudeInteractive(spec2, prompt) {
2417
+ const argv = ["claude", prompt, "--allowedTools", `mcp__${spec2.name}__*`];
2418
+ const r = run(argv[0], argv.slice(1), { interactive: true });
2419
+ return { argv, status: r.status };
2420
+ }
2398
2421
  function codexConfigPath() {
2399
2422
  return path4.join(process.env.CODEX_HOME || path4.join(os3.homedir(), ".codex"), "config.toml");
2400
2423
  }
@@ -2474,6 +2497,11 @@ function codexOneShot(_spec, prompt) {
2474
2497
  const r = run(argv[0], argv.slice(1), { inherit: true });
2475
2498
  return { argv, status: r.status };
2476
2499
  }
2500
+ function codexInteractive(_spec, prompt) {
2501
+ const argv = ["codex", prompt];
2502
+ const r = run(argv[0], argv.slice(1), { interactive: true });
2503
+ return { argv, status: r.status };
2504
+ }
2477
2505
  var shellQuote = (s) => `"${s.replace(/(["\\$`])/g, "\\$1")}"`;
2478
2506
  function renderCommand(argv) {
2479
2507
  return argv.map((a, i) => i === 0 || /^[A-Za-z0-9_@%+=:,./-]+$/.test(a) ? a : shellQuote(a)).join(" ");
@@ -2508,10 +2536,25 @@ async function installAndDemo(cli, spec2, getQuestion, log = console.log) {
2508
2536
  log(` ${import_chalk12.default.dim("$")} ${renderCommand(loginArgv)}`);
2509
2537
  const r = run(loginArgv[0], loginArgv.slice(1), { interactive: true });
2510
2538
  if (r.status !== 0) {
2511
- log(import_chalk12.default.yellow(` Sign-in didn't complete (exit ${r.status ?? "?"}). Run \`${renderCommand(loginArgv)}\` yourself, then chat away.`));
2512
- return true;
2539
+ log(import_chalk12.default.yellow(` Sign-in didn't complete (exit ${r.status ?? "?"}). Run \`${renderCommand(loginArgv)}\` yourself to finish it.`));
2540
+ } else {
2541
+ log(` ${import_chalk12.default.green("\u2714")} Signed in.`);
2513
2542
  }
2514
- log(` ${import_chalk12.default.green("\u2714")} Signed in.`);
2543
+ }
2544
+ if (cli.kind === "claude") {
2545
+ const status = waitForClaudeConnection(spec2.name);
2546
+ if (status !== "connected") {
2547
+ log(import_chalk12.default.yellow(`
2548
+ ${cli.label} has the MCP configured, but reports: ${status === "needs-auth" ? "needs authentication" : status === "failed" ? "failed to connect" : "unknown status"}.`));
2549
+ if (status === "needs-auth") {
2550
+ log(import_chalk12.default.dim(` Finish the sign-in with: claude mcp login ${spec2.name}`));
2551
+ } else {
2552
+ log(import_chalk12.default.dim(` Check it with: claude mcp get ${spec2.name} (or /mcp inside Claude Code)`));
2553
+ }
2554
+ log(import_chalk12.default.dim(" Chatting here instead so you still get an answer."));
2555
+ return false;
2556
+ }
2557
+ log(` ${import_chalk12.default.green("\u2714")} ${cli.label} reports the server connected.`);
2515
2558
  }
2516
2559
  const oneShot = cli.kind === "claude" ? claudeOneShot : codexOneShot;
2517
2560
  const abilities = `What are the tool abilities of the MCP server "${spec2.name}"? List them briefly.`;
@@ -2528,14 +2571,16 @@ async function installAndDemo(cli, spec2, getQuestion, log = console.log) {
2528
2571
  }
2529
2572
  const question = await getQuestion();
2530
2573
  if (question) {
2574
+ const handoff = !!process.stdin.isTTY;
2575
+ const ask = handoff ? cli.kind === "claude" ? claudeInteractive : codexInteractive : oneShot;
2531
2576
  log(`
2532
- ${import_chalk12.default.dim("Your question, through " + cli.label + ":")}`);
2533
- const shown = cli.kind === "claude" ? ["claude", "-p", question, "--allowedTools", `mcp__${spec2.name}__*`] : ["codex", "exec", question];
2577
+ ${import_chalk12.default.dim(handoff ? `Opening ${cli.label} with your question \u2014 you'll stay in that session:` : `Your question, through ${cli.label}:`)}`);
2578
+ const shown = cli.kind === "claude" ? handoff ? ["claude", question, "--allowedTools", `mcp__${spec2.name}__*`] : ["claude", "-p", question, "--allowedTools", `mcp__${spec2.name}__*`] : handoff ? ["codex", question] : ["codex", "exec", question];
2534
2579
  log(` ${import_chalk12.default.dim("$")} ${renderCommand(shown)}
2535
2580
  `);
2536
- const ans = oneShot(spec2, question);
2581
+ const ans = ask(spec2, question);
2537
2582
  if (ans.status !== 0) log(import_chalk12.default.yellow(`
2538
- ${cli.label} exited with ${ans.status ?? "no status"} on that one \u2014 the MCP stays installed.`));
2583
+ ${cli.label} exited with ${ans.status ?? "no status"} \u2014 the MCP stays installed.`));
2539
2584
  }
2540
2585
  log(`
2541
2586
  ${import_chalk12.default.bold(`Your ${cli.label} is now able to talk to the ${spec2.projectLabel} API.`)}`);
@@ -4015,22 +4060,27 @@ async function maybeInstallExternalCli(p, opts) {
4015
4060
  refreshInstall(c.kind, buildInstallSpec(p));
4016
4061
  }
4017
4062
  }
4018
- const fresh = clis.filter((c) => !offer[c.kind]);
4019
- if (fresh.length === 0) return false;
4063
+ const pending = clis.filter((c) => !offer[c.kind]);
4064
+ if (pending.length === 0) return false;
4020
4065
  const { default: inquirer3 } = await import("inquirer");
4021
- const names = fresh.map((c) => c.label).join(" and ");
4022
- const targetName = fresh.length > 1 ? "one of them" : fresh[0].label;
4066
+ const names = clis.map((c) => c.label).join(" and ");
4067
+ const targetName = clis.length > 1 ? "one of them" : clis[0].label;
4023
4068
  const { pick: pick2 } = await inquirer3.prompt([{
4024
4069
  type: "list",
4025
4070
  name: "pick",
4026
- message: `I see ${names} ${fresh.length > 1 ? "are" : "is"} installed on this computer. Do you want to add the MCP for this proxy to ${targetName} so you can chat with your API from there directly, or chat here directly?`,
4071
+ message: `I see ${names} ${clis.length > 1 ? "are" : "is"} installed on this computer. Do you want to add the MCP for this proxy to ${targetName} so you can chat with your API from there directly, or chat here directly?`,
4027
4072
  choices: [
4028
- ...fresh.map((c) => ({ name: c.label, value: c })),
4073
+ ...clis.map((c) => ({
4074
+ // An already-wired client stays selectable: picking it re-installs
4075
+ // (fresh key, moved host) and re-runs the check.
4076
+ name: offer[c.kind] === "installed" ? `${c.label} ${import_chalk13.default.dim("(already added \u2014 re-add)")}` : c.label,
4077
+ value: c
4078
+ })),
4029
4079
  { name: "Chat here directly", value: "here" }
4030
4080
  ]
4031
4081
  }]);
4032
4082
  if (pick2 === "here") {
4033
- for (const c of fresh) rememberCliOffer(p, c.kind, "declined");
4083
+ for (const c of pending) rememberCliOffer(p, c.kind, "declined");
4034
4084
  if (p.consumerAuth && p.teamId && p.tenant) {
4035
4085
  try {
4036
4086
  await ensureConsumerLogin(p.teamId, p.tenant, p.version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apiblaze",
3
- "version": "0.20.17",
3
+ "version": "0.20.20",
4
4
  "description": "APIblaze CLI — Chat with your APIs, Manage your API keys, users and groups with the APIblaze serverless proxy",
5
5
  "keywords": [
6
6
  "apiblaze",