apiblaze 0.19.25 → 0.19.28

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 +668 -583
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -476,7 +476,7 @@ var init_admin = __esm({
476
476
  function requireAuth() {
477
477
  const creds = loadCredentials();
478
478
  if (!creds) {
479
- console.error(import_chalk8.default.red("Not logged in. Run `apiblaze login` first."));
479
+ console.error(import_chalk9.default.red("Not logged in. Run `apiblaze login` first."));
480
480
  process.exit(1);
481
481
  }
482
482
  return creds;
@@ -485,7 +485,7 @@ async function resolveTeam(opt) {
485
485
  const creds = requireAuth();
486
486
  if (!opt) {
487
487
  if (!creds.teamId) {
488
- console.error(import_chalk8.default.red("No active team. Run `apiblaze login` or pass --team."));
488
+ console.error(import_chalk9.default.red("No active team. Run `apiblaze login` or pass --team."));
489
489
  process.exit(1);
490
490
  }
491
491
  return { teamId: creds.teamId, teamName: creds.teamName };
@@ -494,7 +494,7 @@ async function resolveTeam(opt) {
494
494
  const teams = await getTeams().catch(() => []);
495
495
  const match = teams.find((t) => t.name === opt || t.teamId === opt);
496
496
  if (!match) {
497
- console.error(import_chalk8.default.red(`Team "${opt}" not found.${teams.length ? " Available: " + teams.map((t) => t.name).join(", ") : ""}`));
497
+ console.error(import_chalk9.default.red(`Team "${opt}" not found.${teams.length ? " Available: " + teams.map((t) => t.name).join(", ") : ""}`));
498
498
  process.exit(1);
499
499
  }
500
500
  return { teamId: match.teamId, teamName: match.name };
@@ -505,13 +505,13 @@ async function resolveProject(teamId, nameOrId, version2) {
505
505
  (p) => p.projectId === nameOrId || p.projectName === nameOrId
506
506
  );
507
507
  if (candidates.length === 0) {
508
- console.error(import_chalk8.default.red(`Project "${nameOrId}" not found in this team.`));
509
- if (projects.length) console.error(import_chalk8.default.dim(" Known: " + projects.map((p) => p.projectName).join(", ")));
508
+ console.error(import_chalk9.default.red(`Project "${nameOrId}" not found in this team.`));
509
+ if (projects.length) console.error(import_chalk9.default.dim(" Known: " + projects.map((p) => p.projectName).join(", ")));
510
510
  process.exit(1);
511
511
  }
512
512
  const chosen = version2 ? candidates.find((p) => p.apiVersion === version2) : candidates[0];
513
513
  if (!chosen) {
514
- console.error(import_chalk8.default.red(`Project "${nameOrId}" has no version ${version2}. Versions: ${candidates.map((p) => p.apiVersion).join(", ")}`));
514
+ console.error(import_chalk9.default.red(`Project "${nameOrId}" has no version ${version2}. Versions: ${candidates.map((p) => p.apiVersion).join(", ")}`));
515
515
  process.exit(1);
516
516
  }
517
517
  return {
@@ -522,11 +522,11 @@ async function resolveProject(teamId, nameOrId, version2) {
522
522
  tenant: chosen.tenant
523
523
  };
524
524
  }
525
- var import_chalk8;
525
+ var import_chalk9;
526
526
  var init_resolve = __esm({
527
527
  "src/lib/resolve.ts"() {
528
528
  "use strict";
529
- import_chalk8 = __toESM(require("chalk"));
529
+ import_chalk9 = __toESM(require("chalk"));
530
530
  init_auth();
531
531
  init_api();
532
532
  }
@@ -635,12 +635,12 @@ async function runIamToggle(project, state, opts) {
635
635
  summary: `IAM ${state} for tenant ${tenant2}`
636
636
  });
637
637
  if (opts.quiet) return;
638
- spinner?.succeed(`IAM is ${import_chalk9.default.bold(state)} for tenant ${tenant2}.`);
638
+ spinner?.succeed(`IAM is ${import_chalk10.default.bold(state)} for tenant ${tenant2}.`);
639
639
  if (opts.json) console.log(JSON.stringify(out ?? { iam_enabled: enabled }));
640
640
  else if (enabled) {
641
- console.log(import_chalk9.default.dim(" Groups now apply to identified calls. Identify callers with"));
642
- console.log(import_chalk9.default.dim(" X-End-User-Id, a login token, or per-user keys \u2014 and consider"));
643
- console.log(import_chalk9.default.dim(` \`apiblaze identified ${project} require\` to reject unattributed traffic.`));
641
+ console.log(import_chalk10.default.dim(" Groups now apply to identified calls. Identify callers with"));
642
+ console.log(import_chalk10.default.dim(" X-End-User-Id, a login token, or per-user keys \u2014 and consider"));
643
+ console.log(import_chalk10.default.dim(` \`apiblaze identified ${project} require\` to reject unattributed traffic.`));
644
644
  }
645
645
  } catch (err) {
646
646
  spinner?.fail(`IAM ${state} failed.`);
@@ -692,11 +692,11 @@ async function runIdentifiedToggle(project, mode, opts) {
692
692
  throw err;
693
693
  }
694
694
  }
695
- var import_chalk9, import_ora4;
695
+ var import_chalk10, import_ora4;
696
696
  var init_iam = __esm({
697
697
  "src/commands/iam.ts"() {
698
698
  "use strict";
699
- import_chalk9 = __toESM(require("chalk"));
699
+ import_chalk10 = __toESM(require("chalk"));
700
700
  import_ora4 = __toESM(require("ora"));
701
701
  init_caller();
702
702
  }
@@ -714,7 +714,7 @@ async function createTenantRow(teamId) {
714
714
  const { name } = await inquirer3.prompt([{
715
715
  type: "input",
716
716
  name: "name",
717
- message: `Tenant name ${import_chalk26.default.dim("(lowercase letters/numbers; globally unique \u2014 becomes {name}.portal.apiblaze.com)")}:`,
717
+ message: `Tenant name ${import_chalk27.default.dim("(lowercase letters/numbers; globally unique \u2014 becomes {name}.portal.apiblaze.com)")}:`,
718
718
  validate: (s) => /^[a-z0-9]+$/.test(s.trim()) ? true : "lowercase letters and numbers only"
719
719
  }]);
720
720
  const slug = name.trim();
@@ -729,7 +729,7 @@ async function createTenantRow(teamId) {
729
729
  } catch (err) {
730
730
  const msg = err instanceof Error ? err.message : String(err);
731
731
  if (/taken|unique|exists|reserved|conflict/i.test(msg)) {
732
- console.log(import_chalk26.default.yellow(` "${slug}" is not available (tenant names are global): ${msg}`));
732
+ console.log(import_chalk27.default.yellow(` "${slug}" is not available (tenant names are global): ${msg}`));
733
733
  continue;
734
734
  }
735
735
  throw err;
@@ -746,11 +746,11 @@ async function addApiblazeHostedLogin(teamId, tenant2, opts = {}) {
746
746
  pageSize: 10,
747
747
  choices: [
748
748
  ...PROVIDERS.map((p) => ({ name: p.label, value: p.id })),
749
- ...opts.allowSkip ? [new inquirer3.Separator(), { name: import_chalk26.default.dim("Skip for now \u2014 set up a login method later"), value: null }] : []
749
+ ...opts.allowSkip ? [new inquirer3.Separator(), { name: import_chalk27.default.dim("Skip for now \u2014 set up a login method later"), value: null }] : []
750
750
  ]
751
751
  }]);
752
752
  if (!provider) {
753
- console.log(import_chalk26.default.dim(" No login method yet \u2014 add one later under Login methods."));
753
+ console.log(import_chalk27.default.dim(" No login method yet \u2014 add one later under Login methods."));
754
754
  return false;
755
755
  }
756
756
  const opt = PROVIDERS.find((p) => p.id === provider);
@@ -796,26 +796,26 @@ async function addApiblazeHostedLogin(teamId, tenant2, opts = {}) {
796
796
  async function createTenantInteractive(teamId) {
797
797
  const { default: inquirer3 } = await import("inquirer");
798
798
  const tenant2 = await createTenantRow(teamId);
799
- console.log(import_chalk26.default.green(` Tenant ${import_chalk26.default.bold(tenant2)} created.`));
799
+ console.log(import_chalk27.default.green(` Tenant ${import_chalk27.default.bold(tenant2)} created.`));
800
800
  const { users } = await inquirer3.prompt([{
801
801
  type: "confirm",
802
802
  name: "users",
803
803
  default: false,
804
- message: `Enable Users & groups? ${import_chalk26.default.dim(`(identity/key management at iam.apiblaze.com)`)}`
804
+ message: `Enable Users & groups? ${import_chalk27.default.dim(`(identity/key management at iam.apiblaze.com)`)}`
805
805
  }]);
806
806
  if (users) {
807
807
  await admin({ method: "PATCH", path: `/teams/${encodeURIComponent(teamId)}/tenants/${encodeURIComponent(tenant2)}/iam`, body: { enabled: true }, summary: "Enable Users & groups" }).catch(() => {
808
808
  });
809
- console.log(import_chalk26.default.green(" Users & groups enabled."));
809
+ console.log(import_chalk27.default.green(" Users & groups enabled."));
810
810
  }
811
811
  await addApiblazeHostedLogin(teamId, tenant2, { allowSkip: true });
812
812
  return tenant2;
813
813
  }
814
- var import_chalk26, import_ora10, PROVIDERS, DEFAULT_SCOPES;
814
+ var import_chalk27, import_ora10, PROVIDERS, DEFAULT_SCOPES;
815
815
  var init_tenant_create = __esm({
816
816
  "src/lib/tenant-create.ts"() {
817
817
  "use strict";
818
- import_chalk26 = __toESM(require("chalk"));
818
+ import_chalk27 = __toESM(require("chalk"));
819
819
  import_ora10 = __toESM(require("ora"));
820
820
  init_admin();
821
821
  PROVIDERS = [
@@ -854,10 +854,10 @@ async function fetchPage(teamId, q) {
854
854
  }
855
855
  function label(t, defaultTenant, active) {
856
856
  const tags = [
857
- t.tenant_name === active ? import_chalk27.default.cyan("active scope") : "",
858
- t.tenant_name === defaultTenant ? import_chalk27.default.dim("team default") : ""
857
+ t.tenant_name === active ? import_chalk28.default.cyan("active scope") : "",
858
+ t.tenant_name === defaultTenant ? import_chalk28.default.dim("team default") : ""
859
859
  ].filter(Boolean).join(", ");
860
- const disp = t.display_name && t.display_name !== t.tenant_name ? import_chalk27.default.dim(` ${t.display_name}`) : "";
860
+ const disp = t.display_name && t.display_name !== t.tenant_name ? import_chalk28.default.dim(` ${t.display_name}`) : "";
861
861
  return `${t.tenant_name}${disp}${tags ? ` (${tags})` : ""}`;
862
862
  }
863
863
  async function pickTenant(teamId, opts = {}) {
@@ -872,7 +872,7 @@ async function pickTenant(teamId, opts = {}) {
872
872
  const { make } = await inquirer3.prompt([{ type: "confirm", name: "make", message: "No tenants yet \u2014 create one?", default: true }]);
873
873
  if (make) return await createTenantInline(teamId);
874
874
  }
875
- console.error(import_chalk27.default.red("This team has no tenants. Create one with `apiblaze tenant create`."));
875
+ console.error(import_chalk28.default.red("This team has no tenants. Create one with `apiblaze tenant create`."));
876
876
  return null;
877
877
  }
878
878
  const truncated = page.total > page.rows.length;
@@ -881,7 +881,7 @@ async function pickTenant(teamId, opts = {}) {
881
881
  value: t.tenant_name
882
882
  }));
883
883
  if (truncated || q) {
884
- choices.push(new inquirer3.Separator(import_chalk27.default.dim(
884
+ choices.push(new inquirer3.Separator(import_chalk28.default.dim(
885
885
  truncated ? `showing ${page.rows.length} of ${page.total}${q ? ` matching "${q}"` : ""} \u2014 search to narrow` : `matches for "${q}"`
886
886
  )));
887
887
  choices.push({ name: `\u{1F50D} Search${q ? " again" : ""}\u2026`, value: "\0search" });
@@ -915,11 +915,11 @@ async function createTenantInline(teamId) {
915
915
  const { createTenantInteractive: createTenantInteractive2 } = await Promise.resolve().then(() => (init_tenant_create(), tenant_create_exports));
916
916
  return createTenantInteractive2(teamId);
917
917
  }
918
- var import_chalk27, import_ora11, PAGE;
918
+ var import_chalk28, import_ora11, PAGE;
919
919
  var init_tenant_pick = __esm({
920
920
  "src/lib/tenant-pick.ts"() {
921
921
  "use strict";
922
- import_chalk27 = __toESM(require("chalk"));
922
+ import_chalk28 = __toESM(require("chalk"));
923
923
  import_ora11 = __toESM(require("ora"));
924
924
  init_admin();
925
925
  init_auth();
@@ -929,10 +929,10 @@ var init_tenant_pick = __esm({
929
929
 
930
930
  // src/index.ts
931
931
  var import_commander = require("commander");
932
- var import_chalk44 = __toESM(require("chalk"));
932
+ var import_chalk45 = __toESM(require("chalk"));
933
933
 
934
934
  // package.json
935
- var version = "0.19.25";
935
+ var version = "0.19.28";
936
936
 
937
937
  // src/index.ts
938
938
  init_types();
@@ -1936,8 +1936,79 @@ ${projects.length} project${projects.length === 1 ? "" : "s"}`));
1936
1936
 
1937
1937
  // src/commands/create.ts
1938
1938
  var import_fs2 = __toESM(require("fs"));
1939
+
1940
+ // src/lib/tenant-choice.ts
1941
+ var import_chalk8 = __toESM(require("chalk"));
1942
+ init_admin();
1943
+ function decideTenant(input) {
1944
+ if (input.tenant) {
1945
+ const slug = input.tenant.toLowerCase().replace(/[^a-z0-9]/g, "");
1946
+ return slug ? { kind: "use", tenant: slug } : { kind: "server-default" };
1947
+ }
1948
+ if (input.existing.length === 0) return { kind: "server-default" };
1949
+ const suggested = suggestTenantName(input.projectSlug, input.existing);
1950
+ if (input.existing.length === 1) return { kind: "use", tenant: input.existing[0] };
1951
+ if (!input.interactive) return { kind: "use", tenant: suggested };
1952
+ return { kind: "ask", existing: input.existing, suggested };
1953
+ }
1954
+ async function chooseTenantForCreate(teamId, projectSlug, opts) {
1955
+ if (opts.tenant) return opts.tenant.toLowerCase().replace(/[^a-z0-9]/g, "");
1956
+ if (!teamId) return void 0;
1957
+ let existing = [];
1958
+ try {
1959
+ const rows = await admin({
1960
+ method: "GET",
1961
+ path: `/teams/${encodeURIComponent(teamId)}/tenants`,
1962
+ summary: "List tenants to place the new proxy"
1963
+ });
1964
+ const list = Array.isArray(rows) ? rows : rows?.tenants ?? [];
1965
+ existing = list.map((t) => t?.tenant_name ?? t?.name).filter((n) => typeof n === "string" && n.length > 0);
1966
+ } catch {
1967
+ return void 0;
1968
+ }
1969
+ const decision = decideTenant({
1970
+ existing,
1971
+ projectSlug,
1972
+ tenant: opts.tenant,
1973
+ yes: opts.yes,
1974
+ json: opts.json,
1975
+ interactive: !opts.yes && !opts.json && !!process.stdin.isTTY
1976
+ });
1977
+ if (decision.kind === "server-default") return void 0;
1978
+ if (decision.kind === "use") {
1979
+ if (!opts.json && !existing.includes(decision.tenant)) {
1980
+ console.log(import_chalk8.default.dim(` Placing this proxy in a new tenant "${decision.tenant}" (pass --tenant to choose another).`));
1981
+ }
1982
+ return decision.tenant;
1983
+ }
1984
+ const { existing: choices, suggested } = decision;
1985
+ const { default: inquirer3 } = await import("inquirer");
1986
+ const { pick: pick2 } = await inquirer3.prompt([
1987
+ {
1988
+ type: "list",
1989
+ name: "pick",
1990
+ message: "Which tenant should this proxy's consumers live in?",
1991
+ choices: [
1992
+ { name: `${import_chalk8.default.green("\uFF0B")} New tenant "${suggested}" ${import_chalk8.default.dim("(its own portal, login and users)")}`, value: "\0new" },
1993
+ ...choices.map((t) => ({ name: `${t} ${import_chalk8.default.dim("(share its portal, login app and users)")}`, value: t }))
1994
+ ]
1995
+ }
1996
+ ]);
1997
+ return pick2 === "\0new" ? suggested : pick2;
1998
+ }
1999
+ function suggestTenantName(projectSlug, taken) {
2000
+ const base2 = (projectSlug || "tenant").toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 24) || "tenant";
2001
+ if (!taken.includes(base2)) return base2;
2002
+ for (let i = 2; i < 100; i++) {
2003
+ const candidate = `${base2}${i}`;
2004
+ if (!taken.includes(candidate)) return candidate;
2005
+ }
2006
+ return `${base2}${Math.random().toString(36).slice(2, 7)}`;
2007
+ }
2008
+
2009
+ // src/commands/create.ts
1939
2010
  var import_yaml = require("yaml");
1940
- var import_chalk10 = __toESM(require("chalk"));
2011
+ var import_chalk11 = __toESM(require("chalk"));
1941
2012
  var import_ora5 = __toESM(require("ora"));
1942
2013
  init_auth();
1943
2014
  init_api();
@@ -2000,7 +2071,7 @@ function stripTenantFromPortal(devPortal) {
2000
2071
  }
2001
2072
  }
2002
2073
  function fail(message) {
2003
- console.error(import_chalk10.default.red(`Error: ${message}`));
2074
+ console.error(import_chalk11.default.red(`Error: ${message}`));
2004
2075
  process.exit(1);
2005
2076
  }
2006
2077
  function buildTryItCurl(url, authType, apiKey) {
@@ -2015,11 +2086,11 @@ function printCurlExample(url, authType, apiKey, devPortal) {
2015
2086
  const curl = buildTryItCurl(url, authType, apiKey);
2016
2087
  console.log();
2017
2088
  if (curl) {
2018
- console.log(` ${import_chalk10.default.dim("Try it \u2014 copy/paste:")}`);
2019
- console.log(` ${import_chalk10.default.cyan(curl)}`);
2089
+ console.log(` ${import_chalk11.default.dim("Try it \u2014 copy/paste:")}`);
2090
+ console.log(` ${import_chalk11.default.cyan(curl)}`);
2020
2091
  } else if (authType === "oauth") {
2021
- console.log(` ${import_chalk10.default.dim("Try it:")} this proxy uses OAuth \u2014 sign in at ${import_chalk10.default.bold(devPortal ?? "the dev portal")} to get a token,`);
2022
- console.log(` ${import_chalk10.default.dim(`then call ${url} with`)} ${import_chalk10.default.cyan('-H "Authorization: Bearer <token>"')}`);
2092
+ console.log(` ${import_chalk11.default.dim("Try it:")} this proxy uses OAuth \u2014 sign in at ${import_chalk11.default.bold(devPortal ?? "the dev portal")} to get a token,`);
2093
+ console.log(` ${import_chalk11.default.dim(`then call ${url} with`)} ${import_chalk11.default.cyan('-H "Authorization: Bearer <token>"')}`);
2023
2094
  }
2024
2095
  }
2025
2096
  var VALID_AUTH = ["api_key", "none", "oauth"];
@@ -2049,7 +2120,7 @@ async function runCreate(opts = {}) {
2049
2120
  teamId = match.teamId;
2050
2121
  }
2051
2122
  }
2052
- if (!opts.json) console.log(import_chalk10.default.bold("\nCreate an API proxy\n"));
2123
+ if (!opts.json) console.log(import_chalk11.default.bold("\nCreate an API proxy\n"));
2053
2124
  let name = "";
2054
2125
  if (opts.name !== void 0) {
2055
2126
  name = normalizeName(opts.name);
@@ -2069,7 +2140,7 @@ async function runCreate(opts = {}) {
2069
2140
  }]);
2070
2141
  name = normalizeName(rawName);
2071
2142
  if (name.length < 3) {
2072
- console.log(import_chalk10.default.yellow(" Name must be at least 3 characters (letters and digits only).\n"));
2143
+ console.log(import_chalk11.default.yellow(" Name must be at least 3 characters (letters and digits only).\n"));
2073
2144
  continue;
2074
2145
  }
2075
2146
  const spinner2 = (0, import_ora5.default)("Checking availability...").start();
@@ -2077,15 +2148,15 @@ async function runCreate(opts = {}) {
2077
2148
  const check = await checkProxyName(name, teamId, opts.apiversion);
2078
2149
  spinner2.stop();
2079
2150
  if (!check.canUseProjectName || !check.canUseApiVersion) {
2080
- console.log(import_chalk10.default.yellow(` "${name}" is not available${check.message ? ` \u2014 ${check.message}` : ""}. Try another.
2151
+ console.log(import_chalk11.default.yellow(` "${name}" is not available${check.message ? ` \u2014 ${check.message}` : ""}. Try another.
2081
2152
  `));
2082
2153
  continue;
2083
2154
  }
2084
2155
  } catch {
2085
2156
  spinner2.stop();
2086
- console.log(import_chalk10.default.dim(" (could not verify availability; continuing)"));
2157
+ console.log(import_chalk11.default.dim(" (could not verify availability; continuing)"));
2087
2158
  }
2088
- console.log(`${import_chalk10.default.cyan("\u2192")} Your API will live at ${import_chalk10.default.bold(`https://${name}.abz.run`)}
2159
+ console.log(`${import_chalk11.default.cyan("\u2192")} Your API will live at ${import_chalk11.default.bold(`https://${name}.abz.run`)}
2089
2160
  `);
2090
2161
  break;
2091
2162
  }
@@ -2111,7 +2182,7 @@ async function runCreate(opts = {}) {
2111
2182
  message: "Target URL to forward requests to (e.g. https://httpbin.org):"
2112
2183
  }]);
2113
2184
  if (!isHttpUrl(url)) {
2114
- console.log(import_chalk10.default.yellow(" Enter a valid http(s) URL.\n"));
2185
+ console.log(import_chalk11.default.yellow(" Enter a valid http(s) URL.\n"));
2115
2186
  continue;
2116
2187
  }
2117
2188
  targetUrl = url.trim();
@@ -2122,7 +2193,7 @@ async function runCreate(opts = {}) {
2122
2193
  }
2123
2194
  if (interactive && !opts.yes) {
2124
2195
  const { default: inquirer3 } = await import("inquirer");
2125
- console.log(`${import_chalk10.default.cyan("\u2192")} Auth: ${import_chalk10.default.bold(auth)}${auth === "api_key" ? " \u2014 consumers send an X-API-Key header" : ""}`);
2196
+ console.log(`${import_chalk11.default.cyan("\u2192")} Auth: ${import_chalk11.default.bold(auth)}${auth === "api_key" ? " \u2014 consumers send an X-API-Key header" : ""}`);
2126
2197
  const { ok } = await inquirer3.prompt([{
2127
2198
  type: "confirm",
2128
2199
  name: "ok",
@@ -2130,10 +2201,15 @@ async function runCreate(opts = {}) {
2130
2201
  default: true
2131
2202
  }]);
2132
2203
  if (!ok) {
2133
- console.log(import_chalk10.default.yellow("Cancelled."));
2204
+ console.log(import_chalk11.default.yellow("Cancelled."));
2134
2205
  return;
2135
2206
  }
2136
2207
  }
2208
+ const chosenTenant = await chooseTenantForCreate(teamId, name, {
2209
+ tenant: opts.tenant,
2210
+ yes: opts.yes,
2211
+ json: opts.json
2212
+ });
2137
2213
  const spinner = !opts.json ? (0, import_ora5.default)("Creating proxy (tenant, keys, dev portal)...").start() : null;
2138
2214
  let result;
2139
2215
  try {
@@ -2142,10 +2218,10 @@ async function runCreate(opts = {}) {
2142
2218
  ...openapiContent ? { openapi: openapiContent } : { target_url: targetUrl },
2143
2219
  auth_type: auth,
2144
2220
  team_id: teamId,
2145
- ...opts.tenant ? { tenant: normalizeName(opts.tenant) } : {},
2221
+ ...chosenTenant ? { tenant: chosenTenant } : {},
2146
2222
  ...opts.apiversion ? { api_version: opts.apiversion } : {}
2147
2223
  });
2148
- spinner?.succeed(import_chalk10.default.green("Proxy created!"));
2224
+ spinner?.succeed(import_chalk11.default.green("Proxy created!"));
2149
2225
  } catch (err) {
2150
2226
  spinner?.fail("Failed to create proxy.");
2151
2227
  throw err;
@@ -2170,16 +2246,16 @@ async function runCreate(opts = {}) {
2170
2246
  return;
2171
2247
  }
2172
2248
  console.log();
2173
- console.log(` ${import_chalk10.default.dim("Proxy URL: ")} ${import_chalk10.default.bold(proxyUrl)}`);
2174
- if (devPortal) console.log(` ${import_chalk10.default.dim("Dev portal:")} ${import_chalk10.default.bold(devPortal)}`);
2249
+ console.log(` ${import_chalk11.default.dim("Proxy URL: ")} ${import_chalk11.default.bold(proxyUrl)}`);
2250
+ if (devPortal) console.log(` ${import_chalk11.default.dim("Dev portal:")} ${import_chalk11.default.bold(devPortal)}`);
2175
2251
  if (adminKey) {
2176
2252
  console.log();
2177
- console.log(` ${import_chalk10.default.dim("Consumer admin API key (dev):")}`);
2178
- console.log(` ${import_chalk10.default.bold.green(adminKey)}`);
2179
- console.log(import_chalk10.default.dim("\n Save this now \u2014 send it as the X-API-Key header. It may not be shown again."));
2253
+ console.log(` ${import_chalk11.default.dim("Consumer admin API key (dev):")}`);
2254
+ console.log(` ${import_chalk11.default.bold.green(adminKey)}`);
2255
+ console.log(import_chalk11.default.dim("\n Save this now \u2014 send it as the X-API-Key header. It may not be shown again."));
2180
2256
  const otherEnvs = Object.keys(keys).filter((e) => e !== "dev");
2181
2257
  if (otherEnvs.length) {
2182
- console.log(import_chalk10.default.dim(` (Separate keys were also created for: ${otherEnvs.join(", ")}.)`));
2258
+ console.log(import_chalk11.default.dim(` (Separate keys were also created for: ${otherEnvs.join(", ")}.)`));
2183
2259
  }
2184
2260
  }
2185
2261
  printCurlExample(proxyUrl, auth, adminKey, devPortal);
@@ -2195,8 +2271,8 @@ async function applyCreateToggles(name, opts) {
2195
2271
  async function runAnonymousCreate(opts) {
2196
2272
  const interactive = !!process.stdin.isTTY && !opts.json;
2197
2273
  if (!opts.json) {
2198
- console.log(import_chalk10.default.bold("\nCreate an API proxy"));
2199
- console.log(import_chalk10.default.dim("Not logged in \u2014 creating an anonymous proxy. You can claim it to your account within 30 days.\n"));
2274
+ console.log(import_chalk11.default.bold("\nCreate an API proxy"));
2275
+ console.log(import_chalk11.default.dim("Not logged in \u2014 creating an anonymous proxy. You can claim it to your account within 30 days.\n"));
2200
2276
  }
2201
2277
  let body = {};
2202
2278
  if (opts.config) {
@@ -2245,7 +2321,7 @@ async function runAnonymousCreate(opts) {
2245
2321
  message: "Target URL to forward requests to (e.g. https://httpbin.org):"
2246
2322
  }]);
2247
2323
  if (!isHttpUrl(url)) {
2248
- console.log(import_chalk10.default.yellow(" Enter a valid http(s) URL.\n"));
2324
+ console.log(import_chalk11.default.yellow(" Enter a valid http(s) URL.\n"));
2249
2325
  continue;
2250
2326
  }
2251
2327
  target = url.trim();
@@ -2286,7 +2362,7 @@ async function runAnonymousCreate(opts) {
2286
2362
  saveAnonCred2(result.cp_key, result.team_id, result.claim_code);
2287
2363
  }
2288
2364
  }
2289
- spinner?.succeed(import_chalk10.default.green("Proxy created!"));
2365
+ spinner?.succeed(import_chalk11.default.green("Proxy created!"));
2290
2366
  } catch (err) {
2291
2367
  spinner?.fail("Failed to create proxy.");
2292
2368
  throw err;
@@ -2309,36 +2385,36 @@ async function runAnonymousCreate(opts) {
2309
2385
  return;
2310
2386
  }
2311
2387
  console.log();
2312
- if (prodEndpoint) console.log(` ${import_chalk10.default.dim("Proxy URL: ")} ${import_chalk10.default.bold(prodEndpoint)}`);
2313
- if (result.portal) console.log(` ${import_chalk10.default.dim("Dev portal:")} ${import_chalk10.default.bold(result.portal)}`);
2388
+ if (prodEndpoint) console.log(` ${import_chalk11.default.dim("Proxy URL: ")} ${import_chalk11.default.bold(prodEndpoint)}`);
2389
+ if (result.portal) console.log(` ${import_chalk11.default.dim("Dev portal:")} ${import_chalk11.default.bold(result.portal)}`);
2314
2390
  if (apiKey) {
2315
2391
  console.log();
2316
- console.log(` ${import_chalk10.default.dim("API key:")}`);
2317
- console.log(` ${import_chalk10.default.bold.green(apiKey)}`);
2318
- console.log(import_chalk10.default.dim("\n Save this now \u2014 send it as the X-API-Key header. It may not be shown again."));
2392
+ console.log(` ${import_chalk11.default.dim("API key:")}`);
2393
+ console.log(` ${import_chalk11.default.bold.green(apiKey)}`);
2394
+ console.log(import_chalk11.default.dim("\n Save this now \u2014 send it as the X-API-Key header. It may not be shown again."));
2319
2395
  }
2320
2396
  if (prodEndpoint) printCurlExample(prodEndpoint, opts.auth || "api_key", apiKey, result.portal);
2321
2397
  const claimCode = result.claim_code || cred?.claim_code;
2322
2398
  if (claimCode) {
2323
2399
  console.log();
2324
- console.log(` ${import_chalk10.default.yellow("\u26A0 Anonymous \u2014 claim within 30 days or it expires.")} To claim these proxies:`);
2325
- console.log(` ${import_chalk10.default.cyan(`npx apiblaze login && npx apiblaze claim ${claimCode}`)}`);
2400
+ console.log(` ${import_chalk11.default.yellow("\u26A0 Anonymous \u2014 claim within 30 days or it expires.")} To claim these proxies:`);
2401
+ console.log(` ${import_chalk11.default.cyan(`npx apiblaze login && npx apiblaze claim ${claimCode}`)}`);
2326
2402
  } else if (result.claim_url) {
2327
2403
  console.log();
2328
- console.log(` ${import_chalk10.default.yellow("\u26A0 Anonymous proxy \u2014 claim it to your account within 30 days or it expires:")}`);
2329
- console.log(` ${import_chalk10.default.bold(result.claim_url)}`);
2404
+ console.log(` ${import_chalk11.default.yellow("\u26A0 Anonymous proxy \u2014 claim it to your account within 30 days or it expires:")}`);
2405
+ console.log(` ${import_chalk11.default.bold(result.claim_url)}`);
2330
2406
  }
2331
2407
  console.log();
2332
2408
  }
2333
2409
 
2334
2410
  // src/commands/claim.ts
2335
- var import_chalk11 = __toESM(require("chalk"));
2411
+ var import_chalk12 = __toESM(require("chalk"));
2336
2412
  init_auth();
2337
2413
  init_anon_cred();
2338
2414
  init_api();
2339
2415
  init_types();
2340
2416
  function fail2(message) {
2341
- console.error(import_chalk11.default.red(`Error: ${message}`));
2417
+ console.error(import_chalk12.default.red(`Error: ${message}`));
2342
2418
  process.exit(1);
2343
2419
  }
2344
2420
  async function runClaim(claimCodeArg, opts) {
@@ -2374,9 +2450,9 @@ async function runClaim(claimCodeArg, opts) {
2374
2450
  const c = typeof err.body === "object" && err.body ? err.body.error : void 0;
2375
2451
  if (c === "already_claimed" || c === "not_claimable") {
2376
2452
  if (fromLocal) clearAnonCred();
2377
- console.log(import_chalk11.default.yellow("\nThis workspace was already claimed (e.g. on dashboard.apiblaze.com)."));
2378
- if (fromLocal) console.log(import_chalk11.default.dim(" Cleared the local anonymous key."));
2379
- console.log(import_chalk11.default.dim(" Your proxies are safe under your account \u2014 manage them with `apiblaze login`."));
2453
+ console.log(import_chalk12.default.yellow("\nThis workspace was already claimed (e.g. on dashboard.apiblaze.com)."));
2454
+ if (fromLocal) console.log(import_chalk12.default.dim(" Cleared the local anonymous key."));
2455
+ console.log(import_chalk12.default.dim(" Your proxies are safe under your account \u2014 manage them with `apiblaze login`."));
2380
2456
  return;
2381
2457
  }
2382
2458
  if (c === "expired") {
@@ -2394,20 +2470,20 @@ async function runClaim(claimCodeArg, opts) {
2394
2470
  console.log(JSON.stringify(res, null, 2));
2395
2471
  return;
2396
2472
  }
2397
- console.log(import_chalk11.default.green("\n\u2714 Claimed your anonymous workspace into your account."));
2473
+ console.log(import_chalk12.default.green("\n\u2714 Claimed your anonymous workspace into your account."));
2398
2474
  if (res.merged) {
2399
- console.log(` Merged ${import_chalk11.default.bold(String(res.proxy_count ?? ""))} prox${res.proxy_count === 1 ? "y" : "ies"} into team ${import_chalk11.default.bold(res.team_id)}.`);
2475
+ console.log(` Merged ${import_chalk12.default.bold(String(res.proxy_count ?? ""))} prox${res.proxy_count === 1 ? "y" : "ies"} into team ${import_chalk12.default.bold(res.team_id)}.`);
2400
2476
  } else {
2401
2477
  const label3 = res.team_name ? `\u201C${res.team_name}\u201D` : res.team_id;
2402
- console.log(` It's now your team ${import_chalk11.default.bold(label3)}. Switch to it with ${import_chalk11.default.cyan(`apiblaze team ${res.team_id}`)}.`);
2403
- console.log(import_chalk11.default.dim(` (Tip: name it with --name, or --team <name> to merge into an existing team instead.)`));
2478
+ console.log(` It's now your team ${import_chalk12.default.bold(label3)}. Switch to it with ${import_chalk12.default.cyan(`apiblaze team ${res.team_id}`)}.`);
2479
+ console.log(import_chalk12.default.dim(` (Tip: name it with --name, or --team <name> to merge into an existing team instead.)`));
2404
2480
  }
2405
2481
  console.log(`
2406
- Manage it at ${import_chalk11.default.cyan("https://dashboard.apiblaze.com/dashboard")}`);
2482
+ Manage it at ${import_chalk12.default.cyan("https://dashboard.apiblaze.com/dashboard")}`);
2407
2483
  }
2408
2484
 
2409
2485
  // src/commands/logout.ts
2410
- var import_chalk12 = __toESM(require("chalk"));
2486
+ var import_chalk13 = __toESM(require("chalk"));
2411
2487
  init_auth();
2412
2488
 
2413
2489
  // src/lib/consumer-auth.ts
@@ -2539,7 +2615,7 @@ async function runLogout(opts = {}) {
2539
2615
  const creds = loadCredentials();
2540
2616
  const consumer2 = loadConsumer();
2541
2617
  if (!creds && !consumer2) {
2542
- console.log(import_chalk12.default.yellow("You were not logged in."));
2618
+ console.log(import_chalk13.default.yellow("You were not logged in."));
2543
2619
  return;
2544
2620
  }
2545
2621
  let target;
@@ -2566,16 +2642,16 @@ async function runLogout(opts = {}) {
2566
2642
  }
2567
2643
  if (target === "producer" || target === "all") {
2568
2644
  clearCredentials();
2569
- console.log(import_chalk12.default.green(`\u2714 Logged out of API Producer${creds?.githubHandle ? ` (${creds.githubHandle})` : ""}.`));
2645
+ console.log(import_chalk13.default.green(`\u2714 Logged out of API Producer${creds?.githubHandle ? ` (${creds.githubHandle})` : ""}.`));
2570
2646
  }
2571
2647
  if (target === "consumer" || target === "all") {
2572
2648
  clearConsumer();
2573
- console.log(import_chalk12.default.green(`\u2714 Logged out of API Consumer${consumer2?.tenant ? ` (${consumer2.tenant})` : ""}.`));
2649
+ console.log(import_chalk13.default.green(`\u2714 Logged out of API Consumer${consumer2?.tenant ? ` (${consumer2.tenant})` : ""}.`));
2574
2650
  }
2575
2651
  }
2576
2652
 
2577
2653
  // src/commands/flush.ts
2578
- var import_chalk13 = __toESM(require("chalk"));
2654
+ var import_chalk14 = __toESM(require("chalk"));
2579
2655
  var fs6 = __toESM(require("fs"));
2580
2656
  var path4 = __toESM(require("path"));
2581
2657
  init_auth();
@@ -2583,22 +2659,22 @@ async function runFlush(opts) {
2583
2659
  const dir = getApiblazeDir();
2584
2660
  const entries2 = fs6.existsSync(dir) ? fs6.readdirSync(dir) : [];
2585
2661
  if (!entries2.length) {
2586
- console.log(import_chalk13.default.dim("Nothing to flush \u2014 no local apiblaze config found."));
2662
+ console.log(import_chalk14.default.dim("Nothing to flush \u2014 no local apiblaze config found."));
2587
2663
  return;
2588
2664
  }
2589
- console.log(import_chalk13.default.yellow("This removes ALL local apiblaze state from this machine:"));
2590
- console.log(import_chalk13.default.dim(" \u2022 login credentials & anonymous-workspace keys"));
2591
- console.log(import_chalk13.default.dim(" \u2022 saved apichats \u2014 their DP API keys and transcripts"));
2592
- console.log(import_chalk13.default.dim(" \u2022 your BYO LLM key and any cached secrets"));
2593
- console.log(import_chalk13.default.dim(` (${entries2.length} item(s) in ${dir})`));
2594
- console.log(import_chalk13.default.dim(" It does NOT delete server-side proxies/keys \u2014 those GC or are revoked separately."));
2665
+ console.log(import_chalk14.default.yellow("This removes ALL local apiblaze state from this machine:"));
2666
+ console.log(import_chalk14.default.dim(" \u2022 login credentials & anonymous-workspace keys"));
2667
+ console.log(import_chalk14.default.dim(" \u2022 saved apichats \u2014 their DP API keys and transcripts"));
2668
+ console.log(import_chalk14.default.dim(" \u2022 your BYO LLM key and any cached secrets"));
2669
+ console.log(import_chalk14.default.dim(` (${entries2.length} item(s) in ${dir})`));
2670
+ console.log(import_chalk14.default.dim(" It does NOT delete server-side proxies/keys \u2014 those GC or are revoked separately."));
2595
2671
  if (!opts.yes) {
2596
2672
  const { default: inquirer3 } = await import("inquirer");
2597
2673
  const { ok } = await inquirer3.prompt([
2598
2674
  { type: "confirm", name: "ok", message: "Delete all local state?", default: false }
2599
2675
  ]);
2600
2676
  if (!ok) {
2601
- console.log(import_chalk13.default.dim("Cancelled \u2014 nothing removed."));
2677
+ console.log(import_chalk14.default.dim("Cancelled \u2014 nothing removed."));
2602
2678
  return;
2603
2679
  }
2604
2680
  }
@@ -2608,14 +2684,14 @@ async function runFlush(opts) {
2608
2684
  fs6.rmSync(path4.join(dir, e), { recursive: true, force: true });
2609
2685
  removed++;
2610
2686
  } catch (err) {
2611
- console.log(import_chalk13.default.red(` \u2717 could not remove ${e}: ${err instanceof Error ? err.message : "error"}`));
2687
+ console.log(import_chalk14.default.red(` \u2717 could not remove ${e}: ${err instanceof Error ? err.message : "error"}`));
2612
2688
  }
2613
2689
  }
2614
- console.log(`${import_chalk13.default.green("\u2714")} Flushed \u2014 removed ${removed} item(s). You're fully logged out and clean.`);
2690
+ console.log(`${import_chalk14.default.green("\u2714")} Flushed \u2014 removed ${removed} item(s). You're fully logged out and clean.`);
2615
2691
  }
2616
2692
 
2617
2693
  // src/commands/whoami.ts
2618
- var import_chalk14 = __toESM(require("chalk"));
2694
+ var import_chalk15 = __toESM(require("chalk"));
2619
2695
  init_auth();
2620
2696
  init_anon_cred();
2621
2697
  async function runWhoami(opts = {}) {
@@ -2638,43 +2714,43 @@ async function runWhoami(opts = {}) {
2638
2714
  }, null, 2));
2639
2715
  return;
2640
2716
  }
2641
- console.log(import_chalk14.default.bold("API Producer"));
2717
+ console.log(import_chalk15.default.bold("API Producer"));
2642
2718
  if (!creds) {
2643
- console.log(import_chalk14.default.dim(" Not logged in. Run `apiblaze login`."));
2719
+ console.log(import_chalk15.default.dim(" Not logged in. Run `apiblaze login`."));
2644
2720
  } else {
2645
2721
  const who = creds.githubHandle ?? creds.email ?? creds.apiblazeUserId ?? "unknown";
2646
- console.log(` ${import_chalk14.default.cyan("Signed in as")} ${import_chalk14.default.bold(who)}`);
2722
+ console.log(` ${import_chalk15.default.cyan("Signed in as")} ${import_chalk15.default.bold(who)}`);
2647
2723
  if (creds.email && creds.email !== who) console.log(` Email: ${creds.email}`);
2648
- if (creds.teamName || creds.teamId) console.log(` Team: ${import_chalk14.default.bold(creds.teamName ?? creds.teamId)}`);
2649
- if (creds.activeTenant) console.log(` Tenant scope: ${import_chalk14.default.bold(creds.activeTenant)} ${import_chalk14.default.dim("(clear: `apiblaze tenant use --clear`)")}`);
2650
- if (Date.now() >= creds.expiresAt) console.log(import_chalk14.default.yellow(" \u26A0 Session expired \u2014 run `apiblaze login`."));
2724
+ if (creds.teamName || creds.teamId) console.log(` Team: ${import_chalk15.default.bold(creds.teamName ?? creds.teamId)}`);
2725
+ if (creds.activeTenant) console.log(` Tenant scope: ${import_chalk15.default.bold(creds.activeTenant)} ${import_chalk15.default.dim("(clear: `apiblaze tenant use --clear`)")}`);
2726
+ if (Date.now() >= creds.expiresAt) console.log(import_chalk15.default.yellow(" \u26A0 Session expired \u2014 run `apiblaze login`."));
2651
2727
  }
2652
2728
  if (anon) {
2653
2729
  const masked = `${anon.cp_key.slice(0, 11)}\u2026${anon.cp_key.slice(-4)}`;
2654
- console.log(import_chalk14.default.bold("\nAnonymous workspace") + import_chalk14.default.dim(" (created without an account \u2014 unclaimed)"));
2655
- console.log(` Team: ${import_chalk14.default.bold(anon.team_id)}`);
2656
- console.log(` CP key: ${import_chalk14.default.bold(masked)} ${import_chalk14.default.dim("controls the proxies you created anonymously")}`);
2730
+ console.log(import_chalk15.default.bold("\nAnonymous workspace") + import_chalk15.default.dim(" (created without an account \u2014 unclaimed)"));
2731
+ console.log(` Team: ${import_chalk15.default.bold(anon.team_id)}`);
2732
+ console.log(` CP key: ${import_chalk15.default.bold(masked)} ${import_chalk15.default.dim("controls the proxies you created anonymously")}`);
2657
2733
  console.log(
2658
- import_chalk14.default.dim(` Keep it: ${import_chalk14.default.cyan("apiblaze login")} then ${import_chalk14.default.cyan("apiblaze claim")}`) + (anon.claim_code ? import_chalk14.default.dim(` \xB7 from another machine: ${import_chalk14.default.cyan(`apiblaze claim ${anon.claim_code}`)}`) : "")
2734
+ import_chalk15.default.dim(` Keep it: ${import_chalk15.default.cyan("apiblaze login")} then ${import_chalk15.default.cyan("apiblaze claim")}`) + (anon.claim_code ? import_chalk15.default.dim(` \xB7 from another machine: ${import_chalk15.default.cyan(`apiblaze claim ${anon.claim_code}`)}`) : "")
2659
2735
  );
2660
- if (creds) console.log(import_chalk14.default.dim(" (you're logged in \u2014 `apiblaze claim` folds this workspace into your account)"));
2736
+ if (creds) console.log(import_chalk15.default.dim(" (you're logged in \u2014 `apiblaze claim` folds this workspace into your account)"));
2661
2737
  }
2662
- console.log(import_chalk14.default.bold("\nAPI Consumer"));
2738
+ console.log(import_chalk15.default.bold("\nAPI Consumer"));
2663
2739
  if (!consumer2) {
2664
- console.log(import_chalk14.default.dim(" Not logged in. Run `apiblaze consumer login`."));
2740
+ console.log(import_chalk15.default.dim(" Not logged in. Run `apiblaze consumer login`."));
2665
2741
  } else {
2666
- console.log(` ${import_chalk14.default.cyan("Signed in as")} ${import_chalk14.default.bold(consumer2.email ?? consumer2.tenant)}`);
2667
- console.log(` Tenant: ${import_chalk14.default.bold(consumer2.tenant)}`);
2668
- if (Date.now() >= consumer2.expiresAt) console.log(import_chalk14.default.yellow(" \u26A0 Token expired \u2014 it will refresh on next use, or re-run `apiblaze consumer login`."));
2742
+ console.log(` ${import_chalk15.default.cyan("Signed in as")} ${import_chalk15.default.bold(consumer2.email ?? consumer2.tenant)}`);
2743
+ console.log(` Tenant: ${import_chalk15.default.bold(consumer2.tenant)}`);
2744
+ if (Date.now() >= consumer2.expiresAt) console.log(import_chalk15.default.yellow(" \u26A0 Token expired \u2014 it will refresh on next use, or re-run `apiblaze consumer login`."));
2669
2745
  }
2670
2746
  }
2671
2747
 
2672
2748
  // src/commands/team.ts
2673
- var import_chalk15 = __toESM(require("chalk"));
2749
+ var import_chalk16 = __toESM(require("chalk"));
2674
2750
  init_auth();
2675
2751
  init_api();
2676
2752
  function fail3(message) {
2677
- console.error(import_chalk15.default.red(`Error: ${message}`));
2753
+ console.error(import_chalk16.default.red(`Error: ${message}`));
2678
2754
  process.exit(1);
2679
2755
  }
2680
2756
  async function runTeam(arg) {
@@ -2696,7 +2772,7 @@ async function runTeam(arg) {
2696
2772
  }
2697
2773
  } else if (teams.length === 1) {
2698
2774
  chosen = teams[0];
2699
- console.log(`${import_chalk15.default.cyan("\u2192")} You only have one team: ${import_chalk15.default.bold(chosen.name)}`);
2775
+ console.log(`${import_chalk16.default.cyan("\u2192")} You only have one team: ${import_chalk16.default.bold(chosen.name)}`);
2700
2776
  } else if (process.stdin.isTTY) {
2701
2777
  const { default: inquirer3 } = await import("inquirer");
2702
2778
  const { picked } = await inquirer3.prompt([{
@@ -2711,48 +2787,48 @@ async function runTeam(arg) {
2711
2787
  fail3(`Specify a team: \`apiblaze team <name|id>\`. Available: ${teams.map((t) => t.name).join(", ")}.`);
2712
2788
  }
2713
2789
  saveCredentials({ ...creds, teamId: chosen.teamId, teamName: chosen.name });
2714
- console.log(import_chalk15.default.green(`
2715
- \u2714 Active team: ${import_chalk15.default.bold(chosen.name)}`));
2790
+ console.log(import_chalk16.default.green(`
2791
+ \u2714 Active team: ${import_chalk16.default.bold(chosen.name)}`));
2716
2792
  }
2717
2793
 
2718
2794
  // src/commands/authz.ts
2719
- var import_chalk18 = __toESM(require("chalk"));
2795
+ var import_chalk19 = __toESM(require("chalk"));
2720
2796
  init_auth();
2721
2797
  init_api();
2722
2798
 
2723
2799
  // src/lib/agent-chat.ts
2724
2800
  var import_readline = __toESM(require("readline"));
2725
- var import_chalk16 = __toESM(require("chalk"));
2801
+ var import_chalk17 = __toESM(require("chalk"));
2726
2802
  init_api();
2727
2803
  init_admin();
2728
2804
  async function runAgentChatRepl(opts) {
2729
2805
  const { title, subtitle, endpoint, buildBody, seedPrompt, summarizeProposal, commands } = opts;
2730
- console.log("\n" + import_chalk16.default.cyan.bold(title));
2731
- if (subtitle) console.log(import_chalk16.default.dim(subtitle));
2806
+ console.log("\n" + import_chalk17.default.cyan.bold(title));
2807
+ if (subtitle) console.log(import_chalk17.default.dim(subtitle));
2732
2808
  const messages = [];
2733
2809
  const ctx = { proposal: null, lastData: null, log: (s) => console.log(s) };
2734
2810
  const cmdByName = new Map(commands.map((c) => [c.name, c]));
2735
2811
  const footer = () => {
2736
2812
  const parts = [
2737
- import_chalk16.default.dim("type to chat/refine"),
2738
- ...commands.map((c) => import_chalk16.default.dim(`/${c.name} ${c.describe}`)),
2739
- import_chalk16.default.dim("/show"),
2740
- import_chalk16.default.dim("/exit when done"),
2741
- import_chalk16.default.dim("/drop discard changes")
2813
+ import_chalk17.default.dim("type to chat/refine"),
2814
+ ...commands.map((c) => import_chalk17.default.dim(`/${c.name} ${c.describe}`)),
2815
+ import_chalk17.default.dim("/show"),
2816
+ import_chalk17.default.dim("/exit when done"),
2817
+ import_chalk17.default.dim("/drop discard changes")
2742
2818
  ];
2743
- return " " + import_chalk16.default.dim("[ ") + parts.join(import_chalk16.default.dim(" \xB7 ")) + import_chalk16.default.dim(" ]");
2819
+ return " " + import_chalk17.default.dim("[ ") + parts.join(import_chalk17.default.dim(" \xB7 ")) + import_chalk17.default.dim(" ]");
2744
2820
  };
2745
2821
  async function turn(content) {
2746
2822
  messages.push({ role: "user", content });
2747
- process.stdout.write(import_chalk16.default.dim(" \u2026thinking\n"));
2823
+ process.stdout.write(import_chalk17.default.dim(" \u2026thinking\n"));
2748
2824
  const { status, data } = await agentCall(endpoint, "POST", { messages, ...buildBody(messages) });
2749
2825
  if (status === 402) {
2750
- console.log(import_chalk16.default.red(" Insufficient credits \u2014 top up to keep using the agents.\n"));
2826
+ console.log(import_chalk17.default.red(" Insufficient credits \u2014 top up to keep using the agents.\n"));
2751
2827
  messages.pop();
2752
2828
  return;
2753
2829
  }
2754
2830
  if (status >= 400 || !data) {
2755
- console.log(import_chalk16.default.red(` Error (${status}): ${(data && data.error) ?? "request failed"}
2831
+ console.log(import_chalk17.default.red(` Error (${status}): ${(data && data.error) ?? "request failed"}
2756
2832
  `));
2757
2833
  messages.pop();
2758
2834
  return;
@@ -2760,24 +2836,24 @@ async function runAgentChatRepl(opts) {
2760
2836
  ctx.lastData = data;
2761
2837
  const reply = data.reply ?? data.message ?? "(no reply)";
2762
2838
  messages.push({ role: "assistant", content: reply });
2763
- console.log("\n" + import_chalk16.default.cyan("agent \u203A ") + reply + "\n");
2839
+ console.log("\n" + import_chalk17.default.cyan("agent \u203A ") + reply + "\n");
2764
2840
  if (data.proposal) {
2765
2841
  ctx.proposal = data.proposal;
2766
2842
  const summary = summarizeProposal?.(data);
2767
- if (summary) console.log(import_chalk16.default.yellow(" " + summary));
2843
+ if (summary) console.log(import_chalk17.default.yellow(" " + summary));
2768
2844
  const applies = commands.filter((c) => c.needsProposal);
2769
2845
  const primary = applies[applies.length - 1];
2770
2846
  if (primary) {
2771
- console.log(import_chalk16.default.bold.green(" \u279C Next: type ") + import_chalk16.default.bold.cyan(`/${primary.name}`) + import_chalk16.default.bold.green(" to apply this, then ") + import_chalk16.default.bold.cyan("/exit") + import_chalk16.default.bold.green(" to leave."));
2847
+ console.log(import_chalk17.default.bold.green(" \u279C Next: type ") + import_chalk17.default.bold.cyan(`/${primary.name}`) + import_chalk17.default.bold.green(" to apply this, then ") + import_chalk17.default.bold.cyan("/exit") + import_chalk17.default.bold.green(" to leave."));
2772
2848
  const rest = applies.slice(0, -1).map((c) => `/${c.name} = ${c.describe}`).join(" \xB7 ");
2773
- console.log(import_chalk16.default.dim(` (or keep chatting to refine${rest ? ` \xB7 ${rest}` : ""} \xB7 /show = inspect)`));
2849
+ console.log(import_chalk17.default.dim(` (or keep chatting to refine${rest ? ` \xB7 ${rest}` : ""} \xB7 /show = inspect)`));
2774
2850
  }
2775
2851
  console.log();
2776
2852
  }
2777
2853
  const line = formatBilling(data.billing);
2778
2854
  if (line) {
2779
2855
  const llm2 = data.llm;
2780
- console.log(import_chalk16.default.dim(` ${line}${llm2?.model ? ` \xB7 ${llm2.model}` : ""}`));
2856
+ console.log(import_chalk17.default.dim(` ${line}${llm2?.model ? ` \xB7 ${llm2.model}` : ""}`));
2781
2857
  }
2782
2858
  }
2783
2859
  const rl = import_readline.default.createInterface({ input: process.stdin, output: process.stdout });
@@ -2785,31 +2861,31 @@ async function runAgentChatRepl(opts) {
2785
2861
  await turn(seedPrompt);
2786
2862
  for (; ; ) {
2787
2863
  console.log(footer());
2788
- const line = (await ask(import_chalk16.default.green("you \u203A "))).trim();
2864
+ const line = (await ask(import_chalk17.default.green("you \u203A "))).trim();
2789
2865
  if (!line) continue;
2790
2866
  const lower = line.toLowerCase();
2791
2867
  if (line === "/exit" || line === "/quit" || lower === "exit" || lower === "quit" || lower === "q") {
2792
- console.log(import_chalk16.default.dim(" Bye \u2014 anything you enabled or published stays in place.\n"));
2868
+ console.log(import_chalk17.default.dim(" Bye \u2014 anything you enabled or published stays in place.\n"));
2793
2869
  break;
2794
2870
  }
2795
2871
  if (line === "/drop") {
2796
- console.log(import_chalk16.default.dim(" Dropped the pending proposal \u2014 rules you already enabled/published are untouched.\n"));
2872
+ console.log(import_chalk17.default.dim(" Dropped the pending proposal \u2014 rules you already enabled/published are untouched.\n"));
2797
2873
  break;
2798
2874
  }
2799
2875
  if (line === "/show") {
2800
- if (!ctx.proposal) console.log(import_chalk16.default.dim(" No proposal yet \u2014 keep chatting until the agent proposes one.\n"));
2876
+ if (!ctx.proposal) console.log(import_chalk17.default.dim(" No proposal yet \u2014 keep chatting until the agent proposes one.\n"));
2801
2877
  else console.log("\n" + JSON.stringify(ctx.proposal, null, 2) + "\n");
2802
2878
  continue;
2803
2879
  }
2804
2880
  if (line.startsWith("/")) {
2805
2881
  const cmd = cmdByName.get(line.slice(1));
2806
2882
  if (!cmd) {
2807
- console.log(import_chalk16.default.red(` Unknown command "${line}". Try one of: ${commands.map((c) => "/" + c.name).join(", ")}, /show, /drop
2883
+ console.log(import_chalk17.default.red(` Unknown command "${line}". Try one of: ${commands.map((c) => "/" + c.name).join(", ")}, /show, /drop
2808
2884
  `));
2809
2885
  continue;
2810
2886
  }
2811
2887
  if (cmd.needsProposal && !ctx.proposal) {
2812
- console.log(import_chalk16.default.yellow(" No proposal yet \u2014 keep chatting until the agent generates one, then try again.\n"));
2888
+ console.log(import_chalk17.default.yellow(" No proposal yet \u2014 keep chatting until the agent generates one, then try again.\n"));
2813
2889
  continue;
2814
2890
  }
2815
2891
  await cmd.run(ctx);
@@ -2821,7 +2897,7 @@ async function runAgentChatRepl(opts) {
2821
2897
  }
2822
2898
 
2823
2899
  // src/lib/authz-apply.ts
2824
- var import_chalk17 = __toESM(require("chalk"));
2900
+ var import_chalk18 = __toESM(require("chalk"));
2825
2901
  init_api();
2826
2902
  async function gatherSampleIds(projectId, apiVersion, cap = 50) {
2827
2903
  try {
@@ -2846,10 +2922,10 @@ async function gatherSampleIds(projectId, apiVersion, cap = 50) {
2846
2922
  }
2847
2923
  function maybeWarnNoTraffic(total, projectArg) {
2848
2924
  if (total >= 3) return;
2849
- console.log(import_chalk17.default.yellow(total === 0 ? " \u26A0 No captured traffic for this API yet." : ` \u26A0 Only ${total} captured request(s) so far.`));
2850
- console.log(import_chalk17.default.dim(" The authorization agent designs much better models & rules from REAL requests"));
2851
- console.log(import_chalk17.default.dim(" (it sees who is allowed vs denied). Send some through your proxy first \u2014"));
2852
- console.log(import_chalk17.default.dim(` curl a few endpoints, or `) + import_chalk17.default.cyan("npx apiblaze dev") + import_chalk17.default.dim(` \u2014 then re-run.
2925
+ console.log(import_chalk18.default.yellow(total === 0 ? " \u26A0 No captured traffic for this API yet." : ` \u26A0 Only ${total} captured request(s) so far.`));
2926
+ console.log(import_chalk18.default.dim(" The authorization agent designs much better models & rules from REAL requests"));
2927
+ console.log(import_chalk18.default.dim(" (it sees who is allowed vs denied). Send some through your proxy first \u2014"));
2928
+ console.log(import_chalk18.default.dim(` curl a few endpoints, or `) + import_chalk18.default.cyan("npx apiblaze dev") + import_chalk18.default.dim(` \u2014 then re-run.
2853
2929
  `));
2854
2930
  }
2855
2931
  async function applyProposal(opts) {
@@ -2858,11 +2934,11 @@ async function applyProposal(opts) {
2858
2934
  {
2859
2935
  const m = await agentCall(`/projects/${projectId}/${apiVersion}/policies/model?tenantId=${encodeURIComponent(tenant2)}`, "POST", proposal.model);
2860
2936
  if (m.status === 404) {
2861
- log(import_chalk17.default.red(" Authorization store not provisioned yet. Open the dashboard Authorization tab for this project once (it auto-provisions the store), then re-run.\n"));
2937
+ log(import_chalk18.default.red(" Authorization store not provisioned yet. Open the dashboard Authorization tab for this project once (it auto-provisions the store), then re-run.\n"));
2862
2938
  return { ok: 0, fail: 0, enabled: false, storeMissing: true };
2863
2939
  }
2864
2940
  if (m.status >= 400) {
2865
- log(import_chalk17.default.red(` Model save failed (${m.status}): ${m.data?.error ?? ""}
2941
+ log(import_chalk18.default.red(` Model save failed (${m.status}): ${m.data?.error ?? ""}
2866
2942
  `));
2867
2943
  return { ok: 0, fail: 0, enabled: false };
2868
2944
  }
@@ -2891,7 +2967,7 @@ async function applyProposal(opts) {
2891
2967
  if (enable) {
2892
2968
  const e = await agentCall(`/projects/${projectId}/${apiVersion}`, "PATCH", { authorization: { enforce_authorization: true }, tenant: tenant2 });
2893
2969
  if (e.status >= 400) {
2894
- log(import_chalk17.default.red(` Enforced ${ok} route(s) but turning on the project-level switch failed (${e.status}). Toggle "Enforce Authorization" on in the dashboard.
2970
+ log(import_chalk18.default.red(` Enforced ${ok} route(s) but turning on the project-level switch failed (${e.status}). Toggle "Enforce Authorization" on in the dashboard.
2895
2971
  `));
2896
2972
  return { ok, fail: fail5, enabled: false };
2897
2973
  }
@@ -2917,10 +2993,10 @@ async function runAuthz(projectArg, apiVersionArg) {
2917
2993
  const r = await applyProposal({ projectId, apiVersion, tenant: tenant2, proposal, enable, log: ctx.log });
2918
2994
  if (r.storeMissing) return;
2919
2995
  if (enable && r.enabled) {
2920
- ctx.log(import_chalk18.default.green(` \u2713 Enforcement ON \u2014 ${r.ok} route(s) + project switch on${r.fail ? `, ${r.fail} failed` : ""}.`));
2921
- ctx.log(import_chalk18.default.dim(" Done here? Type /exit to leave the chat (your rule stays on).\n"));
2996
+ ctx.log(import_chalk19.default.green(` \u2713 Enforcement ON \u2014 ${r.ok} route(s) + project switch on${r.fail ? `, ${r.fail} failed` : ""}.`));
2997
+ ctx.log(import_chalk19.default.dim(" Done here? Type /exit to leave the chat (your rule stays on).\n"));
2922
2998
  } else if (!enable) {
2923
- ctx.log(import_chalk18.default.green(` \u2713 Published (shadow): model + ${r.ok} route(s)${r.fail ? `, ${r.fail} failed` : ""}. Review, then /enable.
2999
+ ctx.log(import_chalk19.default.green(` \u2713 Published (shadow): model + ${r.ok} route(s)${r.fail ? `, ${r.fail} failed` : ""}. Review, then /enable.
2924
3000
  `));
2925
3001
  }
2926
3002
  }
@@ -2947,7 +3023,7 @@ async function runAuthz(projectArg, apiVersionArg) {
2947
3023
  }
2948
3024
 
2949
3025
  // src/commands/rule.ts
2950
- var import_chalk19 = __toESM(require("chalk"));
3026
+ var import_chalk20 = __toESM(require("chalk"));
2951
3027
  var import_ora6 = __toESM(require("ora"));
2952
3028
  init_auth();
2953
3029
  init_api();
@@ -2984,27 +3060,27 @@ async function runRule(ruleText, projectArg, opts) {
2984
3060
  const proposal = data?.proposal;
2985
3061
  if (!proposal || !Array.isArray(proposal.routes) || proposal.routes.length === 0) {
2986
3062
  spinner.fail("The agent couldn\u2019t turn that into a rule in one shot.");
2987
- if (data?.reply) console.log(import_chalk19.default.dim("\n " + String(data.reply).slice(0, 500) + "\n"));
2988
- console.log(import_chalk19.default.dim(" Try an interactive session for anything nuanced: ") + import_chalk19.default.cyan(`apiblaze agent authz ${projectArg}`));
3063
+ if (data?.reply) console.log(import_chalk20.default.dim("\n " + String(data.reply).slice(0, 500) + "\n"));
3064
+ console.log(import_chalk20.default.dim(" Try an interactive session for anything nuanced: ") + import_chalk20.default.cyan(`apiblaze agent authz ${projectArg}`));
2989
3065
  return;
2990
3066
  }
2991
3067
  spinner.succeed(`Rule designed \u2014 ${proposal.routes.length} route(s) affected.`);
2992
- if (data?.reply) console.log(import_chalk19.default.dim(" " + String(data.reply).slice(0, 240)));
3068
+ if (data?.reply) console.log(import_chalk20.default.dim(" " + String(data.reply).slice(0, 240)));
2993
3069
  const pub = await applyProposal({ projectId, apiVersion, tenant: tenant2, proposal, enable: false });
2994
3070
  if (pub.storeMissing) return;
2995
- console.log(import_chalk19.default.green(` \u2713 Published in shadow mode \u2014 model + ${pub.ok} route(s)${pub.fail ? `, ${pub.fail} failed` : ""}.`));
3071
+ console.log(import_chalk20.default.green(` \u2713 Published in shadow mode \u2014 model + ${pub.ok} route(s)${pub.fail ? `, ${pub.fail} failed` : ""}.`));
2996
3072
  if (opts.enforce) {
2997
3073
  const enf = await applyProposal({ projectId, apiVersion, tenant: tenant2, proposal, enable: true });
2998
3074
  if (enf.enabled) {
2999
- console.log(import_chalk19.default.green(` \u2713 Enforcement ON \u2014 ${enf.ok} route(s) + project switch on${enf.fail ? `, ${enf.fail} failed` : ""}.`));
3075
+ console.log(import_chalk20.default.green(` \u2713 Enforcement ON \u2014 ${enf.ok} route(s) + project switch on${enf.fail ? `, ${enf.fail} failed` : ""}.`));
3000
3076
  }
3001
3077
  } else {
3002
- console.log(import_chalk19.default.dim(` Review it (shadow logs), then enforce: `) + import_chalk19.default.cyan(`apiblaze rule "${rule}" ${projectArg} --enforce`));
3078
+ console.log(import_chalk20.default.dim(` Review it (shadow logs), then enforce: `) + import_chalk20.default.cyan(`apiblaze rule "${rule}" ${projectArg} --enforce`));
3003
3079
  }
3004
3080
  }
3005
3081
 
3006
3082
  // src/commands/openapi.ts
3007
- var import_chalk20 = __toESM(require("chalk"));
3083
+ var import_chalk21 = __toESM(require("chalk"));
3008
3084
  init_auth();
3009
3085
  init_api();
3010
3086
  async function runOpenapi(projectArg, apiVersionArg) {
@@ -3015,10 +3091,10 @@ async function runOpenapi(projectArg, apiVersionArg) {
3015
3091
  if (!match) throw new Error(`Project "${projectArg}" not found in your active team. Run \`apiblaze projects\`.`);
3016
3092
  const projectId = match.projectId;
3017
3093
  const apiVersion = apiVersionArg || match.apiVersion;
3018
- console.log(import_chalk20.default.dim("Gathering captured traffic samples\u2026"));
3094
+ console.log(import_chalk21.default.dim("Gathering captured traffic samples\u2026"));
3019
3095
  const routesRes = await agentCall(`/projects/${projectId}/${apiVersion}/samples/routes`, "GET");
3020
3096
  if (routesRes.status >= 400) {
3021
- console.log(import_chalk20.default.red(`Could not list traffic (${routesRes.status}): ${routesRes.data?.error ?? ""}`));
3097
+ console.log(import_chalk21.default.red(`Could not list traffic (${routesRes.status}): ${routesRes.data?.error ?? ""}`));
3022
3098
  return;
3023
3099
  }
3024
3100
  const routes = routesRes.data?.routes ?? (Array.isArray(routesRes.data) ? routesRes.data : []);
@@ -3031,25 +3107,25 @@ async function runOpenapi(projectArg, apiVersionArg) {
3031
3107
  }
3032
3108
  const sampleIds = [...ids];
3033
3109
  if (sampleIds.length === 0) {
3034
- console.log(import_chalk20.default.yellow("No captured traffic samples found. Hit the dev environment of this proxy to capture some traces, then retry."));
3110
+ console.log(import_chalk21.default.yellow("No captured traffic samples found. Hit the dev environment of this proxy to capture some traces, then retry."));
3035
3111
  return;
3036
3112
  }
3037
3113
  async function publish(ctx) {
3038
3114
  const patch = ctx.proposal.patch;
3039
3115
  if (!Array.isArray(patch) || patch.length === 0) {
3040
- ctx.log(import_chalk20.default.green(" Nothing to publish \u2014 the spec already covers the observed traffic.\n"));
3116
+ ctx.log(import_chalk21.default.green(" Nothing to publish \u2014 the spec already covers the observed traffic.\n"));
3041
3117
  return;
3042
3118
  }
3043
3119
  const specSource = ctx.lastData?.spec_source ?? "unknown";
3044
3120
  const endpoint = specSource === "github" ? "open-pr" : "publish-openapi";
3045
3121
  const pub = await agentCall(`/projects/${projectId}/${apiVersion}/samples/${endpoint}`, "POST", { patch, sample_ids_used: sampleIds });
3046
3122
  if (pub.status >= 400) {
3047
- ctx.log(import_chalk20.default.red(` Publish failed (${pub.status}): ${pub.data?.error ?? ""}
3123
+ ctx.log(import_chalk21.default.red(` Publish failed (${pub.status}): ${pub.data?.error ?? ""}
3048
3124
  `));
3049
3125
  return;
3050
3126
  }
3051
3127
  const prUrl = pub.data?.pr_url;
3052
- ctx.log(import_chalk20.default.green(prUrl ? ` \u2713 Pull request opened: ${prUrl}
3128
+ ctx.log(import_chalk21.default.green(prUrl ? ` \u2713 Pull request opened: ${prUrl}
3053
3129
  ` : " \u2713 Published updated OpenAPI spec.\n"));
3054
3130
  }
3055
3131
  await runAgentChatRepl({
@@ -3070,7 +3146,7 @@ async function runOpenapi(projectArg, apiVersionArg) {
3070
3146
  }
3071
3147
 
3072
3148
  // src/commands/mcp.ts
3073
- var import_chalk21 = __toESM(require("chalk"));
3149
+ var import_chalk22 = __toESM(require("chalk"));
3074
3150
  init_auth();
3075
3151
  init_api();
3076
3152
  async function runMcp(projectArg, apiVersionArg, opts) {
@@ -3087,11 +3163,11 @@ async function runMcp(projectArg, apiVersionArg, opts) {
3087
3163
  const spec2 = ctx.proposal;
3088
3164
  const pub = await agentCall(`/projects/${projectId}/${apiVersion}/mcp/spec`, "PUT", { environment, spec: spec2 });
3089
3165
  if (pub.status >= 400) {
3090
- ctx.log(import_chalk21.default.red(` Publish failed (${pub.status}): ${pub.data?.error ?? ""}
3166
+ ctx.log(import_chalk22.default.red(` Publish failed (${pub.status}): ${pub.data?.error ?? ""}
3091
3167
  `));
3092
3168
  return;
3093
3169
  }
3094
- ctx.log(import_chalk21.default.green(` \u2713 Published MCP server \u2014 ${mcpHost}.mcp.apiblaze.com/${apiVersion}/${environment}.
3170
+ ctx.log(import_chalk22.default.green(` \u2713 Published MCP server \u2014 ${mcpHost}.mcp.apiblaze.com/${apiVersion}/${environment}.
3095
3171
  `));
3096
3172
  }
3097
3173
  await runAgentChatRepl({
@@ -3113,7 +3189,7 @@ async function runMcp(projectArg, apiVersionArg, opts) {
3113
3189
  }
3114
3190
 
3115
3191
  // src/commands/delete.ts
3116
- var import_chalk22 = __toESM(require("chalk"));
3192
+ var import_chalk23 = __toESM(require("chalk"));
3117
3193
  var import_ora7 = __toESM(require("ora"));
3118
3194
  init_admin();
3119
3195
  init_resolve();
@@ -3139,10 +3215,10 @@ async function runDelete(project, version2, opts) {
3139
3215
  return;
3140
3216
  }
3141
3217
  } else {
3142
- console.log(`${import_chalk22.default.red.bold("Delete")} ${import_chalk22.default.bold(proj2.projectName)} ${import_chalk22.default.dim("v" + proj2.apiVersion)} ${import_chalk22.default.dim("(" + proj2.projectId + ")")}`);
3218
+ console.log(`${import_chalk23.default.red.bold("Delete")} ${import_chalk23.default.bold(proj2.projectName)} ${import_chalk23.default.dim("v" + proj2.apiVersion)} ${import_chalk23.default.dim("(" + proj2.projectId + ")")}`);
3143
3219
  if (impact && typeof impact === "object") {
3144
3220
  const counts = impact.counts ?? impact.impact ?? impact;
3145
- console.log(import_chalk22.default.dim(" This removes (cascade): ") + import_chalk22.default.yellow(JSON.stringify(counts)));
3221
+ console.log(import_chalk23.default.dim(" This removes (cascade): ") + import_chalk23.default.yellow(JSON.stringify(counts)));
3146
3222
  }
3147
3223
  if (!opts.yes) {
3148
3224
  const { default: inquirer3 } = await import("inquirer");
@@ -3150,7 +3226,7 @@ async function runDelete(project, version2, opts) {
3150
3226
  { type: "confirm", name: "confirm", message: `Permanently delete ${proj2.projectName} v${proj2.apiVersion}? This cannot be undone.`, default: false }
3151
3227
  ]);
3152
3228
  if (!confirm) {
3153
- console.log(import_chalk22.default.dim("Aborted."));
3229
+ console.log(import_chalk23.default.dim("Aborted."));
3154
3230
  return;
3155
3231
  }
3156
3232
  }
@@ -3171,7 +3247,7 @@ async function runDelete(project, version2, opts) {
3171
3247
  }
3172
3248
 
3173
3249
  // src/commands/export.ts
3174
- var import_chalk23 = __toESM(require("chalk"));
3250
+ var import_chalk24 = __toESM(require("chalk"));
3175
3251
  var import_fs3 = require("fs");
3176
3252
  init_admin();
3177
3253
  init_auth();
@@ -3190,7 +3266,7 @@ async function runExport(projectArg, versionArg, opts) {
3190
3266
  if (opts.noConsumers) q.set("include_consumers", "0");
3191
3267
  if (opts.keys) q.set("keys", opts.keys);
3192
3268
  const qs = q.toString() ? `?${q.toString()}` : "";
3193
- console.log(import_chalk23.default.dim(`Queuing ${target} export of ${projectId}@${version2}\u2026`));
3269
+ console.log(import_chalk24.default.dim(`Queuing ${target} export of ${projectId}@${version2}\u2026`));
3194
3270
  const job = await admin({
3195
3271
  path: `/projects/${projectId}/${version2}/export/${target}${qs}`,
3196
3272
  method: "GET",
@@ -3200,11 +3276,11 @@ async function runExport(projectArg, versionArg, opts) {
3200
3276
  const statusPath = `/projects/${projectId}/${version2}/export/jobs/${job.job_id}`;
3201
3277
  let status = "queued";
3202
3278
  const started = Date.now();
3203
- process.stdout.write(import_chalk23.default.dim("Building bundle"));
3279
+ process.stdout.write(import_chalk24.default.dim("Building bundle"));
3204
3280
  while (status !== "ready" && status !== "failed") {
3205
3281
  if (Date.now() - started > 10 * 6e4) throw new Error("Export timed out after 10 minutes.");
3206
3282
  await new Promise((r) => setTimeout(r, 3e3));
3207
- process.stdout.write(import_chalk23.default.dim("."));
3283
+ process.stdout.write(import_chalk24.default.dim("."));
3208
3284
  const st = await admin({ path: statusPath, method: "GET", summary: "poll export" });
3209
3285
  status = st?.status ?? "queued";
3210
3286
  if (status === "failed") {
@@ -3222,14 +3298,14 @@ async function runExport(projectArg, versionArg, opts) {
3222
3298
  if (!res.ok) throw new Error(`Download failed (${res.status}): ${await res.text().catch(() => "")}`);
3223
3299
  const buf = Buffer.from(await res.arrayBuffer());
3224
3300
  (0, import_fs3.writeFileSync)(outFile, buf);
3225
- console.log(import_chalk23.default.green(`\u2713 Saved ${outFile} (${(buf.length / 1024).toFixed(0)} KB)`));
3226
- if (job.decryption_key) console.log(import_chalk23.default.yellow(`Decryption key (shown once): ${job.decryption_key}`));
3227
- console.log(import_chalk23.default.dim("Read MIGRATION-REPORT.json inside the zip for the full fidelity ledger."));
3228
- if (target === "kong") console.log(import_chalk23.default.dim("Kong: unzip, then `cd kong && docker compose up` (see kong/README.md)."));
3301
+ console.log(import_chalk24.default.green(`\u2713 Saved ${outFile} (${(buf.length / 1024).toFixed(0)} KB)`));
3302
+ if (job.decryption_key) console.log(import_chalk24.default.yellow(`Decryption key (shown once): ${job.decryption_key}`));
3303
+ console.log(import_chalk24.default.dim("Read MIGRATION-REPORT.json inside the zip for the full fidelity ledger."));
3304
+ if (target === "kong") console.log(import_chalk24.default.dim("Kong: unzip, then `cd kong && docker compose up` (see kong/README.md)."));
3229
3305
  }
3230
3306
 
3231
3307
  // src/commands/config.ts
3232
- var import_chalk24 = __toESM(require("chalk"));
3308
+ var import_chalk25 = __toESM(require("chalk"));
3233
3309
  var import_ora8 = __toESM(require("ora"));
3234
3310
  init_admin();
3235
3311
  init_resolve();
@@ -3253,7 +3329,7 @@ async function patchConfig(project, opts, body, summary) {
3253
3329
  }
3254
3330
  async function runTargetSet(project, opts) {
3255
3331
  if (!opts.url) {
3256
- console.error(import_chalk24.default.red("--url is required."));
3332
+ console.error(import_chalk25.default.red("--url is required."));
3257
3333
  process.exit(1);
3258
3334
  }
3259
3335
  const body = opts.env ? { environments: { [opts.env]: { target: opts.url } } } : { target_url: opts.url };
@@ -3266,40 +3342,40 @@ async function runThrottleSet(project, opts) {
3266
3342
  if (opts.quota !== void 0) throttling.proxyQuota = Number(opts.quota);
3267
3343
  if (opts.period !== void 0) {
3268
3344
  if (!["daily", "weekly", "monthly"].includes(opts.period)) {
3269
- console.error(import_chalk24.default.red("--period must be daily, weekly, or monthly."));
3345
+ console.error(import_chalk25.default.red("--period must be daily, weekly, or monthly."));
3270
3346
  process.exit(1);
3271
3347
  }
3272
3348
  throttling.quotaPeriod = opts.period;
3273
3349
  }
3274
3350
  if (Object.keys(throttling).length === 0) {
3275
- console.error(import_chalk24.default.red("Nothing to set. Pass at least one of --rate, --end-user-rate, --quota, --period."));
3351
+ console.error(import_chalk25.default.red("Nothing to set. Pass at least one of --rate, --end-user-rate, --quota, --period."));
3276
3352
  process.exit(1);
3277
3353
  }
3278
3354
  await patchConfig(project, opts, { throttling }, `Update throttling ${JSON.stringify(throttling)}`);
3279
3355
  }
3280
3356
  async function runRename(project, opts) {
3281
3357
  if (!opts.displayName) {
3282
- console.error(import_chalk24.default.red("--display-name is required."));
3358
+ console.error(import_chalk25.default.red("--display-name is required."));
3283
3359
  process.exit(1);
3284
3360
  }
3285
3361
  await patchConfig(project, opts, { display_name: opts.displayName }, `Rename \u2192 "${opts.displayName}"`);
3286
3362
  }
3287
3363
 
3288
3364
  // src/commands/config-browse.ts
3289
- var import_chalk33 = __toESM(require("chalk"));
3365
+ var import_chalk34 = __toESM(require("chalk"));
3290
3366
  var import_ora16 = __toESM(require("ora"));
3291
3367
  init_admin();
3292
3368
  init_auth();
3293
3369
  init_resolve();
3294
3370
 
3295
3371
  // src/commands/domain.ts
3296
- var import_chalk25 = __toESM(require("chalk"));
3372
+ var import_chalk26 = __toESM(require("chalk"));
3297
3373
  var import_ora9 = __toESM(require("ora"));
3298
3374
  init_admin();
3299
3375
  init_resolve();
3300
3376
  async function runDomainAdd(project, opts) {
3301
3377
  if (!opts.domain) {
3302
- console.error(import_chalk25.default.red("--domain is required."));
3378
+ console.error(import_chalk26.default.red("--domain is required."));
3303
3379
  process.exit(1);
3304
3380
  }
3305
3381
  const { teamId } = await resolveTeam(opts.team);
@@ -3318,9 +3394,9 @@ async function runDomainAdd(project, opts) {
3318
3394
  console.log(JSON.stringify(out));
3319
3395
  return;
3320
3396
  }
3321
- if (out?.cnameRecord) console.log(` ${import_chalk25.default.cyan("CNAME")} ${out.cnameRecord.name ?? opts.domain} \u2192 ${out.cnameRecord.value ?? out.cnameRecord.target}`);
3322
- if (out?.dcv) console.log(` ${import_chalk25.default.cyan("TXT")} ${out.dcv.name} = ${out.dcv.value}`);
3323
- if (out?.id) console.log(import_chalk25.default.dim(` domain id: ${out.id}`));
3397
+ if (out?.cnameRecord) console.log(` ${import_chalk26.default.cyan("CNAME")} ${out.cnameRecord.name ?? opts.domain} \u2192 ${out.cnameRecord.value ?? out.cnameRecord.target}`);
3398
+ if (out?.dcv) console.log(` ${import_chalk26.default.cyan("TXT")} ${out.dcv.name} = ${out.dcv.value}`);
3399
+ if (out?.id) console.log(import_chalk26.default.dim(` domain id: ${out.id}`));
3324
3400
  } catch (err) {
3325
3401
  spinner.fail("Domain registration failed.");
3326
3402
  throw err;
@@ -3340,14 +3416,14 @@ async function runDomainList(project, opts) {
3340
3416
  return;
3341
3417
  }
3342
3418
  if (!domains.length) {
3343
- console.log(import_chalk25.default.yellow("No custom domains."));
3419
+ console.log(import_chalk26.default.yellow("No custom domains."));
3344
3420
  return;
3345
3421
  }
3346
- for (const d of domains) console.log(` ${import_chalk25.default.bold(d.hostname)} ${import_chalk25.default.dim(d.status ?? "")} ${import_chalk25.default.dim(d.id ?? "")}`);
3422
+ for (const d of domains) console.log(` ${import_chalk26.default.bold(d.hostname)} ${import_chalk26.default.dim(d.status ?? "")} ${import_chalk26.default.dim(d.id ?? "")}`);
3347
3423
  }
3348
3424
  async function runDomainStatus(project, opts) {
3349
3425
  if (!opts.id) {
3350
- console.error(import_chalk25.default.red("--id <domainId> is required (see `apiblaze domain list`)."));
3426
+ console.error(import_chalk26.default.red("--id <domainId> is required (see `apiblaze domain list`)."));
3351
3427
  process.exit(1);
3352
3428
  }
3353
3429
  const { teamId } = await resolveTeam(opts.team);
@@ -3357,11 +3433,11 @@ async function runDomainStatus(project, opts) {
3357
3433
  path: `/projects/${proj2.projectId}/domains/${encodeURIComponent(opts.id)}/status`,
3358
3434
  summary: `Check custom-domain status`
3359
3435
  });
3360
- console.log(opts.json ? JSON.stringify(out) : ` ${import_chalk25.default.bold(out?.hostname ?? opts.id)}: ${import_chalk25.default.cyan(out?.status ?? "unknown")}`);
3436
+ console.log(opts.json ? JSON.stringify(out) : ` ${import_chalk26.default.bold(out?.hostname ?? opts.id)}: ${import_chalk26.default.cyan(out?.status ?? "unknown")}`);
3361
3437
  }
3362
3438
  async function runDomainRemove(project, opts) {
3363
3439
  if (!opts.id) {
3364
- console.error(import_chalk25.default.red("--id <domainId> is required (see `apiblaze domain list`)."));
3440
+ console.error(import_chalk26.default.red("--id <domainId> is required (see `apiblaze domain list`)."));
3365
3441
  process.exit(1);
3366
3442
  }
3367
3443
  const { teamId } = await resolveTeam(opts.team);
@@ -3399,7 +3475,7 @@ async function runDomainSetBase(project, opts) {
3399
3475
  }
3400
3476
 
3401
3477
  // src/commands/tenant.ts
3402
- var import_chalk28 = __toESM(require("chalk"));
3478
+ var import_chalk29 = __toESM(require("chalk"));
3403
3479
  var import_ora12 = __toESM(require("ora"));
3404
3480
  init_admin();
3405
3481
  init_resolve();
@@ -3408,20 +3484,20 @@ init_tenant_pick();
3408
3484
  async function runTenantUse(query, opts) {
3409
3485
  const creds = loadCredentials();
3410
3486
  if (!creds) {
3411
- console.error(import_chalk28.default.red("Not logged in. Run `apiblaze login` first."));
3487
+ console.error(import_chalk29.default.red("Not logged in. Run `apiblaze login` first."));
3412
3488
  process.exit(1);
3413
3489
  }
3414
3490
  if (opts.clear) {
3415
3491
  delete creds.activeTenant;
3416
3492
  saveCredentials(creds);
3417
- console.log(import_chalk28.default.green("Tenant scope cleared."));
3493
+ console.log(import_chalk29.default.green("Tenant scope cleared."));
3418
3494
  return;
3419
3495
  }
3420
3496
  const { teamId } = await resolveTeam(opts.team);
3421
3497
  const slug = await pickTenant(teamId, { message: "Scope future commands to which tenant?", initialQuery: query });
3422
3498
  if (!slug) process.exit(1);
3423
3499
  saveCredentials({ ...creds, activeTenant: slug });
3424
- console.log(import_chalk28.default.green(`Tenant scope set to ${import_chalk28.default.bold(slug)}.`) + import_chalk28.default.dim(" (clear with `apiblaze tenant use --clear`)"));
3500
+ console.log(import_chalk29.default.green(`Tenant scope set to ${import_chalk29.default.bold(slug)}.`) + import_chalk29.default.dim(" (clear with `apiblaze tenant use --clear`)"));
3425
3501
  }
3426
3502
  async function runTenantList(opts) {
3427
3503
  const { teamId, teamName } = await resolveTeam(opts.team);
@@ -3438,22 +3514,22 @@ async function runTenantList(opts) {
3438
3514
  return;
3439
3515
  }
3440
3516
  if (!tenants.length) {
3441
- console.log(import_chalk28.default.yellow(opts.q ? `No tenants matching "${opts.q}".` : "No tenants."));
3517
+ console.log(import_chalk29.default.yellow(opts.q ? `No tenants matching "${opts.q}".` : "No tenants."));
3442
3518
  return;
3443
3519
  }
3444
3520
  for (const t of tenants) {
3445
3521
  const name = typeof t === "string" ? t : t.tenant_name;
3446
- const display = typeof t === "string" ? "" : import_chalk28.default.dim(` ${t.display_name ?? ""}`);
3447
- console.log(` ${import_chalk28.default.bold(name)}${display}`);
3522
+ const display = typeof t === "string" ? "" : import_chalk29.default.dim(` ${t.display_name ?? ""}`);
3523
+ console.log(` ${import_chalk29.default.bold(name)}${display}`);
3448
3524
  }
3449
3525
  const total = out?.total ?? tenants.length;
3450
3526
  if (total > tenants.length) {
3451
- console.log(import_chalk28.default.dim(` \u2026 showing ${tenants.length} of ${total} \u2014 narrow with --q <search>`));
3527
+ console.log(import_chalk29.default.dim(` \u2026 showing ${tenants.length} of ${total} \u2014 narrow with --q <search>`));
3452
3528
  }
3453
3529
  }
3454
3530
  async function runTenantCreate(opts) {
3455
3531
  if (!opts.name) {
3456
- console.error(import_chalk28.default.red("--name (display name) is required."));
3532
+ console.error(import_chalk29.default.red("--name (display name) is required."));
3457
3533
  process.exit(1);
3458
3534
  }
3459
3535
  const { teamId } = await resolveTeam(opts.team);
@@ -3465,7 +3541,7 @@ async function runTenantCreate(opts) {
3465
3541
  body: { display_name: opts.name, ...opts.slug ? { tenant_name: opts.slug } : {} },
3466
3542
  summary: `Create tenant "${opts.name}"`
3467
3543
  });
3468
- spinner.succeed(`Created tenant ${import_chalk28.default.bold(out?.tenant_name ?? opts.name)}.`);
3544
+ spinner.succeed(`Created tenant ${import_chalk29.default.bold(out?.tenant_name ?? opts.name)}.`);
3469
3545
  if (opts.json) console.log(JSON.stringify(out));
3470
3546
  } catch (err) {
3471
3547
  spinner.fail("Tenant create failed.");
@@ -3474,7 +3550,7 @@ async function runTenantCreate(opts) {
3474
3550
  }
3475
3551
  async function runTenantAttach(project, opts) {
3476
3552
  if (!opts.tenant) {
3477
- console.error(import_chalk28.default.red("--tenant <slug> is required."));
3553
+ console.error(import_chalk29.default.red("--tenant <slug> is required."));
3478
3554
  process.exit(1);
3479
3555
  }
3480
3556
  const { teamId } = await resolveTeam(opts.team);
@@ -3502,7 +3578,7 @@ async function runTenantDelete(slug, opts) {
3502
3578
  { type: "confirm", name: "confirm", message: `Permanently delete tenant "${slug}" and everything under it? This cannot be undone.`, default: false }
3503
3579
  ]);
3504
3580
  if (!confirm) {
3505
- console.log(import_chalk28.default.dim("Aborted."));
3581
+ console.log(import_chalk29.default.dim("Aborted."));
3506
3582
  return;
3507
3583
  }
3508
3584
  }
@@ -3521,7 +3597,7 @@ async function runTenantDelete(slug, opts) {
3521
3597
  }
3522
3598
  async function runTenantCors(opts) {
3523
3599
  if (!opts.tenant) {
3524
- console.error(import_chalk28.default.red("--tenant <slug> is required."));
3600
+ console.error(import_chalk29.default.red("--tenant <slug> is required."));
3525
3601
  process.exit(1);
3526
3602
  }
3527
3603
  const { teamId } = await resolveTeam(opts.team);
@@ -3543,7 +3619,7 @@ async function runTenantCors(opts) {
3543
3619
  }
3544
3620
 
3545
3621
  // src/commands/tenant-drill.ts
3546
- var import_chalk29 = __toESM(require("chalk"));
3622
+ var import_chalk30 = __toESM(require("chalk"));
3547
3623
  var import_ora13 = __toESM(require("ora"));
3548
3624
  var import_crypto = require("crypto");
3549
3625
  init_admin();
@@ -3574,15 +3650,15 @@ async function validScopedTenant(teamId, query) {
3574
3650
  const next = { ...creds };
3575
3651
  delete next.activeTenant;
3576
3652
  saveCredentials2(next);
3577
- console.log(import_chalk29.default.yellow(`Tenant scope "${scoped}" no longer exists in this team \u2014 cleared.`));
3653
+ console.log(import_chalk30.default.yellow(`Tenant scope "${scoped}" no longer exists in this team \u2014 cleared.`));
3578
3654
  return void 0;
3579
3655
  }
3580
3656
  async function tenantHome(teamId, tenant2) {
3581
3657
  const { default: inquirer3 } = await import("inquirer");
3582
3658
  const base2 = `/teams/${encodeURIComponent(teamId)}/tenants/${encodeURIComponent(tenant2)}`;
3583
- console.log(import_chalk29.default.bold(`
3659
+ console.log(import_chalk30.default.bold(`
3584
3660
  Tenant ${tenant2}`));
3585
- console.log(import_chalk29.default.dim("Tenant auth/settings are SHARED: changes apply to every proxy this tenant serves.\n"));
3661
+ console.log(import_chalk30.default.dim("Tenant auth/settings are SHARED: changes apply to every proxy this tenant serves.\n"));
3586
3662
  for (; ; ) {
3587
3663
  const spinner = (0, import_ora13.default)("Reading tenant state...").start();
3588
3664
  const [iam, cors, emails, issuers, opaque, clients] = await Promise.all([
@@ -3598,18 +3674,18 @@ Tenant ${tenant2}`));
3598
3674
  const nClients = Array.isArray(clients) ? clients.length : 0;
3599
3675
  const nOpaque = opaque?.opaque?.endpoint ? 1 : 0;
3600
3676
  const nLogin = nClients + nIssuers + nOpaque;
3601
- const onOff = (b) => b ? import_chalk29.default.green("on") : import_chalk29.default.dim("off");
3677
+ const onOff = (b) => b ? import_chalk30.default.green("on") : import_chalk30.default.dim("off");
3602
3678
  const { pick: pick2 } = await inquirer3.prompt([{
3603
3679
  type: "list",
3604
3680
  name: "pick",
3605
3681
  message: `Tenant ${tenant2}:`,
3606
3682
  pageSize: 12,
3607
3683
  choices: [
3608
- { name: `Login methods (${nLogin}) ${import_chalk29.default.dim("how your consumers sign in")}`, value: "login" },
3609
- { name: `Users & groups: ${onOff(iam?.iam_enabled)} ${import_chalk29.default.dim(`identity & key management (iam.apiblaze.com)`)}`, value: "iam" },
3610
- { name: `Portal admins (${nEmails}) ${import_chalk29.default.dim("emails allowed to administer this tenant's portal")}`, value: "emails" },
3611
- new inquirer3.Separator(import_chalk29.default.dim(" Settings")),
3612
- { name: `CORS: ${cors?.cors ? import_chalk29.default.cyan(JSON.stringify(cors.cors)) : import_chalk29.default.dim("(unset)")} ${import_chalk29.default.dim("browser origins allowed to call this tenant")}`, value: "cors" },
3684
+ { name: `Login methods (${nLogin}) ${import_chalk30.default.dim("how your consumers sign in")}`, value: "login" },
3685
+ { name: `Users & groups: ${onOff(iam?.iam_enabled)} ${import_chalk30.default.dim(`identity & key management (iam.apiblaze.com)`)}`, value: "iam" },
3686
+ { name: `Portal admins (${nEmails}) ${import_chalk30.default.dim("emails allowed to administer this tenant's portal")}`, value: "emails" },
3687
+ new inquirer3.Separator(import_chalk30.default.dim(" Settings")),
3688
+ { name: `CORS: ${cors?.cors ? import_chalk30.default.cyan(JSON.stringify(cors.cors)) : import_chalk30.default.dim("(unset)")} ${import_chalk30.default.dim("browser origins allowed to call this tenant")}`, value: "cors" },
3613
3689
  { name: "\u2190 Back", value: "back" }
3614
3690
  ]
3615
3691
  }]);
@@ -3622,7 +3698,7 @@ Tenant ${tenant2}`));
3622
3698
  case "iam": {
3623
3699
  const { v } = await inquirer3.prompt([{ type: "confirm", name: "v", message: "Enable Users & groups?", default: !!iam?.iam_enabled }]);
3624
3700
  await admin({ method: "PATCH", path: `${base2}/iam`, body: { enabled: v }, summary: `IAM enforcement \u2192 ${v ? "on" : "off"}` });
3625
- console.log(import_chalk29.default.green(` Users & groups ${v ? "enabled" : "disabled"}.`));
3701
+ console.log(import_chalk30.default.green(` Users & groups ${v ? "enabled" : "disabled"}.`));
3626
3702
  break;
3627
3703
  }
3628
3704
  case "cors": {
@@ -3635,11 +3711,11 @@ Tenant ${tenant2}`));
3635
3711
  if (v === "") break;
3636
3712
  const parsed = v === "null" ? null : safeJson(v);
3637
3713
  if (parsed === void 0) {
3638
- console.log(import_chalk29.default.yellow(" Not valid JSON \u2014 unchanged."));
3714
+ console.log(import_chalk30.default.yellow(" Not valid JSON \u2014 unchanged."));
3639
3715
  break;
3640
3716
  }
3641
3717
  await admin({ method: "PUT", path: `${base2}/cors`, body: { cors: parsed }, summary: "Set tenant CORS" });
3642
- console.log(import_chalk29.default.green(" CORS updated."));
3718
+ console.log(import_chalk30.default.green(" CORS updated."));
3643
3719
  break;
3644
3720
  }
3645
3721
  case "emails":
@@ -3663,15 +3739,15 @@ async function loginMethodsMenu(teamId, tenant2, base2) {
3663
3739
  const choices = [];
3664
3740
  for (const c of appClients) {
3665
3741
  const nP = (c.providers ?? []).length || c.providers_count || 0;
3666
- choices.push({ name: `${import_chalk29.default.cyan("APIblaze-hosted")} ${import_chalk29.default.bold(c.name ?? c.clientId)} ${import_chalk29.default.dim(`${c.clientId}${nP ? ` \xB7 ${nP} provider${nP === 1 ? "" : "s"}` : import_chalk29.default.yellow(" \xB7 needs a provider")}`)}`, value: { kind: "client", item: c } });
3742
+ choices.push({ name: `${import_chalk30.default.cyan("APIblaze-hosted")} ${import_chalk30.default.bold(c.name ?? c.clientId)} ${import_chalk30.default.dim(`${c.clientId}${nP ? ` \xB7 ${nP} provider${nP === 1 ? "" : "s"}` : import_chalk30.default.yellow(" \xB7 needs a provider")}`)}`, value: { kind: "client", item: c } });
3667
3743
  }
3668
3744
  for (const i of issuers) {
3669
- choices.push({ name: `${import_chalk29.default.cyan("Your own \u2014 JWT ")} ${import_chalk29.default.bold(i.iss)} ${import_chalk29.default.dim(`aud=${i.aud}`)}`, value: { kind: "issuer", item: i } });
3745
+ choices.push({ name: `${import_chalk30.default.cyan("Your own \u2014 JWT ")} ${import_chalk30.default.bold(i.iss)} ${import_chalk30.default.dim(`aud=${i.aud}`)}`, value: { kind: "issuer", item: i } });
3670
3746
  }
3671
3747
  if (opaque?.endpoint) {
3672
- choices.push({ name: `${import_chalk29.default.cyan("Your own \u2014 opaque")} ${import_chalk29.default.bold(opaque.endpoint)}`, value: { kind: "opaque", item: opaque } });
3748
+ choices.push({ name: `${import_chalk30.default.cyan("Your own \u2014 opaque")} ${import_chalk30.default.bold(opaque.endpoint)}`, value: { kind: "opaque", item: opaque } });
3673
3749
  }
3674
- if (!choices.length) console.log(import_chalk29.default.dim("\n No login methods yet \u2014 consumers cannot sign in until you add one."));
3750
+ if (!choices.length) console.log(import_chalk30.default.dim("\n No login methods yet \u2014 consumers cannot sign in until you add one."));
3675
3751
  const { pick: pick2 } = await inquirer3.prompt([{
3676
3752
  type: "list",
3677
3753
  name: "pick",
@@ -3711,9 +3787,9 @@ async function addLoginMethod(teamId, tenant2, base2) {
3711
3787
  message: "How do people log in?",
3712
3788
  pageSize: 8,
3713
3789
  choices: [
3714
- { name: `APIblaze hosted login page ${import_chalk29.default.dim("we host login; pick a provider (GitHub/Google/\u2026) \u2014 easiest")}`, value: "apiblaze" },
3715
- { name: `Your own hosted login \u2014 JWT ${import_chalk29.default.dim("your identity provider issues JWTs; we trust them")}`, value: "jwt" },
3716
- { name: `Your own login \u2014 opaque token ${import_chalk29.default.dim("we validate your opaque tokens via an introspection endpoint")}`, value: "opaque" },
3790
+ { name: `APIblaze hosted login page ${import_chalk30.default.dim("we host login; pick a provider (GitHub/Google/\u2026) \u2014 easiest")}`, value: "apiblaze" },
3791
+ { name: `Your own hosted login \u2014 JWT ${import_chalk30.default.dim("your identity provider issues JWTs; we trust them")}`, value: "jwt" },
3792
+ { name: `Your own login \u2014 opaque token ${import_chalk30.default.dim("we validate your opaque tokens via an introspection endpoint")}`, value: "opaque" },
3717
3793
  { name: "\u2190 Back", value: null }
3718
3794
  ]
3719
3795
  }]);
@@ -3737,8 +3813,8 @@ function safeJson(s) {
3737
3813
  async function emailsMenu(base2, emails) {
3738
3814
  const { default: inquirer3 } = await import("inquirer");
3739
3815
  console.log();
3740
- if (!emails.length) console.log(import_chalk29.default.dim(" No consumer-admin emails."));
3741
- for (const e of emails) console.log(` ${import_chalk29.default.bold(e.email ?? e)} ${import_chalk29.default.dim(e.status ?? "")}`);
3816
+ if (!emails.length) console.log(import_chalk30.default.dim(" No consumer-admin emails."));
3817
+ for (const e of emails) console.log(` ${import_chalk30.default.bold(e.email ?? e)} ${import_chalk30.default.dim(e.status ?? "")}`);
3742
3818
  const { act } = await inquirer3.prompt([{
3743
3819
  type: "list",
3744
3820
  name: "act",
@@ -3753,7 +3829,7 @@ async function emailsMenu(base2, emails) {
3753
3829
  if (act === "add") {
3754
3830
  const { email } = await inquirer3.prompt([{ type: "input", name: "email", message: "Email:", validate: (s) => /.+@.+\..+/.test(s) || "not an email" }]);
3755
3831
  await admin({ method: "POST", path: `${base2}/admin-emails`, body: { email }, summary: `Add consumer-admin ${email}` });
3756
- console.log(import_chalk29.default.green(` ${email} added.`));
3832
+ console.log(import_chalk30.default.green(` ${email} added.`));
3757
3833
  } else {
3758
3834
  const { e } = await inquirer3.prompt([{
3759
3835
  type: "list",
@@ -3763,7 +3839,7 @@ async function emailsMenu(base2, emails) {
3763
3839
  }]);
3764
3840
  if (!e) return;
3765
3841
  await admin({ method: "DELETE", path: `${base2}/admin-emails/${encodeURIComponent(e)}`, summary: `Remove consumer-admin ${e}` });
3766
- console.log(import_chalk29.default.green(` ${e} removed.`));
3842
+ console.log(import_chalk30.default.green(` ${e} removed.`));
3767
3843
  }
3768
3844
  }
3769
3845
  async function addIssuer(base2) {
@@ -3784,19 +3860,19 @@ async function addIssuer(base2) {
3784
3860
  body: { iss: a.iss.trim(), aud: a.aud.trim(), jwks_url: a.jwks.trim() || null, sub_semantics: a.sem, ...claim ? { claim_name: claim } : {} },
3785
3861
  summary: `Add external issuer ${a.iss.trim()}`
3786
3862
  });
3787
- console.log(import_chalk29.default.green(" JWT login method saved."));
3863
+ console.log(import_chalk30.default.green(" JWT login method saved."));
3788
3864
  }
3789
3865
  async function issuerHome(base2, issuer) {
3790
3866
  const { default: inquirer3 } = await import("inquirer");
3791
3867
  console.log(`
3792
- ${import_chalk29.default.bold(issuer.iss)} ${import_chalk29.default.dim(`aud=${issuer.aud} \xB7 ${issuer.sub_semantics ?? ""}`)}`);
3868
+ ${import_chalk30.default.bold(issuer.iss)} ${import_chalk30.default.dim(`aud=${issuer.aud} \xB7 ${issuer.sub_semantics ?? ""}`)}`);
3793
3869
  const { act } = await inquirer3.prompt([{
3794
3870
  type: "list",
3795
3871
  name: "act",
3796
3872
  message: "This JWT login method:",
3797
3873
  choices: [
3798
3874
  { name: "Replace it (re-enter details)", value: "edit" },
3799
- { name: import_chalk29.default.red("Delete it"), value: "rm" },
3875
+ { name: import_chalk30.default.red("Delete it"), value: "rm" },
3800
3876
  { name: "\u2190 Back", value: "back" }
3801
3877
  ]
3802
3878
  }]);
@@ -3812,7 +3888,7 @@ async function issuerHome(base2, issuer) {
3812
3888
  path: `${base2}/external-issuers?iss=${encodeURIComponent(issuer.iss)}&aud=${encodeURIComponent(issuer.aud)}`,
3813
3889
  summary: `Delete issuer ${issuer.iss}`
3814
3890
  });
3815
- console.log(import_chalk29.default.green(" Deleted."));
3891
+ console.log(import_chalk30.default.green(" Deleted."));
3816
3892
  }
3817
3893
  async function setOpaque(base2, cur) {
3818
3894
  const { default: inquirer3 } = await import("inquirer");
@@ -3821,19 +3897,19 @@ async function setOpaque(base2, cur) {
3821
3897
  { type: "list", name: "method", message: "HTTP method:", choices: ["GET", "POST"], default: cur?.method ?? "GET" }
3822
3898
  ]);
3823
3899
  await admin({ method: "PUT", path: `${base2}/opaque`, body: { opaque: { endpoint: a.endpoint, method: a.method } }, summary: "Set opaque validator" });
3824
- console.log(import_chalk29.default.green(" Opaque login method set."));
3900
+ console.log(import_chalk30.default.green(" Opaque login method set."));
3825
3901
  }
3826
3902
  async function opaqueHome(base2, cur) {
3827
3903
  const { default: inquirer3 } = await import("inquirer");
3828
3904
  console.log(`
3829
- ${import_chalk29.default.bold(cur.endpoint)} ${import_chalk29.default.dim(cur.method ?? "GET")}`);
3905
+ ${import_chalk30.default.bold(cur.endpoint)} ${import_chalk30.default.dim(cur.method ?? "GET")}`);
3830
3906
  const { act } = await inquirer3.prompt([{
3831
3907
  type: "list",
3832
3908
  name: "act",
3833
3909
  message: "This opaque login method:",
3834
3910
  choices: [
3835
3911
  { name: "Replace it", value: "edit" },
3836
- { name: import_chalk29.default.red("Delete it"), value: "rm" },
3912
+ { name: import_chalk30.default.red("Delete it"), value: "rm" },
3837
3913
  { name: "\u2190 Back", value: "back" }
3838
3914
  ]
3839
3915
  }]);
@@ -3843,7 +3919,7 @@ async function opaqueHome(base2, cur) {
3843
3919
  return;
3844
3920
  }
3845
3921
  await admin({ method: "PUT", path: `${base2}/opaque`, body: { opaque: null }, summary: "Clear opaque validator" });
3846
- console.log(import_chalk29.default.green(" Deleted."));
3922
+ console.log(import_chalk30.default.green(" Deleted."));
3847
3923
  }
3848
3924
  async function clientHome(base2, summary) {
3849
3925
  const { default: inquirer3 } = await import("inquirer");
@@ -3862,13 +3938,13 @@ async function clientHome(base2, summary) {
3862
3938
  message: `${c.name ?? id}:`,
3863
3939
  pageSize: 12,
3864
3940
  choices: [
3865
- { name: `Login providers${nProviders ? ` (${nProviders})` : ""} ${import_chalk29.default.dim("google/github/microsoft/\u2026 \u2014 how consumers sign in")}`, value: "providers" },
3866
- { name: `Callback URLs: ${cb.length ? import_chalk29.default.cyan(cb.join(", ")) : import_chalk29.default.dim("(none)")}`, value: "callbacks" },
3867
- { name: `Scopes: ${scopes.length ? import_chalk29.default.cyan(scopes.join(" ")) : import_chalk29.default.dim("(defaults)")}`, value: "scopes" },
3941
+ { name: `Login providers${nProviders ? ` (${nProviders})` : ""} ${import_chalk30.default.dim("google/github/microsoft/\u2026 \u2014 how consumers sign in")}`, value: "providers" },
3942
+ { name: `Callback URLs: ${cb.length ? import_chalk30.default.cyan(cb.join(", ")) : import_chalk30.default.dim("(none)")}`, value: "callbacks" },
3943
+ { name: `Scopes: ${scopes.length ? import_chalk30.default.cyan(scopes.join(" ")) : import_chalk30.default.dim("(defaults)")}`, value: "scopes" },
3868
3944
  { name: `Token expiries: access ${c.accessTokenExpiry ?? 3600}s \xB7 id ${c.idTokenExpiry ?? 3600}s \xB7 refresh ${c.refreshTokenExpiry ?? 2592e3}s`, value: "expiries" },
3869
3945
  { name: "Reveal client secret", value: "secret" },
3870
3946
  { name: "Rotate client secret", value: "rotate" },
3871
- { name: import_chalk29.default.red("Delete this app client"), value: "delete" },
3947
+ { name: import_chalk30.default.red("Delete this app client"), value: "delete" },
3872
3948
  { name: "\u2190 Back", value: "back" }
3873
3949
  ]
3874
3950
  }]);
@@ -3881,13 +3957,13 @@ async function clientHome(base2, summary) {
3881
3957
  case "callbacks": {
3882
3958
  const { v } = await inquirer3.prompt([{ type: "input", name: "v", message: "Callback URLs (comma-separated):", default: cb.join(", ") }]);
3883
3959
  await admin({ method: "PATCH", path: cBase, body: { authorizedCallbackUrls: parseList(v) }, summary: "Update callback URLs" });
3884
- console.log(import_chalk29.default.green(" Callbacks updated."));
3960
+ console.log(import_chalk30.default.green(" Callbacks updated."));
3885
3961
  break;
3886
3962
  }
3887
3963
  case "scopes": {
3888
3964
  const { v } = await inquirer3.prompt([{ type: "input", name: "v", message: "Scopes (space/comma-separated):", default: scopes.join(" ") }]);
3889
3965
  await admin({ method: "PATCH", path: cBase, body: { scopes: v.split(/[\s,]+/).filter(Boolean) }, summary: "Update scopes" });
3890
- console.log(import_chalk29.default.green(" Scopes updated."));
3966
+ console.log(import_chalk30.default.green(" Scopes updated."));
3891
3967
  break;
3892
3968
  }
3893
3969
  case "expiries": {
@@ -3902,14 +3978,14 @@ async function clientHome(base2, summary) {
3902
3978
  body: { accessTokenExpiry: Number(a.access), idTokenExpiry: Number(a.id), refreshTokenExpiry: Number(a.refresh) },
3903
3979
  summary: "Update token expiries"
3904
3980
  });
3905
- console.log(import_chalk29.default.green(" Expiries updated."));
3981
+ console.log(import_chalk30.default.green(" Expiries updated."));
3906
3982
  break;
3907
3983
  }
3908
3984
  case "secret": {
3909
3985
  const { sure } = await inquirer3.prompt([{ type: "confirm", name: "sure", message: "Print the client secret to this terminal?", default: false }]);
3910
3986
  if (!sure) break;
3911
3987
  const s = await admin({ method: "GET", path: `${cBase}/secret`, summary: "Reveal client secret" });
3912
- console.log(` ${import_chalk29.default.bold("client_secret")}: ${import_chalk29.default.green(s?.clientSecret ?? s?.client_secret ?? JSON.stringify(s))}`);
3988
+ console.log(` ${import_chalk30.default.bold("client_secret")}: ${import_chalk30.default.green(s?.clientSecret ?? s?.client_secret ?? JSON.stringify(s))}`);
3913
3989
  break;
3914
3990
  }
3915
3991
  case "rotate": {
@@ -3917,14 +3993,14 @@ async function clientHome(base2, summary) {
3917
3993
  if (!sure) break;
3918
3994
  const fresh = randomSecret();
3919
3995
  await admin({ method: "PATCH", path: cBase, body: { clientSecret: fresh }, summary: "Rotate client secret" });
3920
- console.log(` New ${import_chalk29.default.bold("client_secret")}: ${import_chalk29.default.green(fresh)} ${import_chalk29.default.dim("(store it now)")}`);
3996
+ console.log(` New ${import_chalk30.default.bold("client_secret")}: ${import_chalk30.default.green(fresh)} ${import_chalk30.default.dim("(store it now)")}`);
3921
3997
  break;
3922
3998
  }
3923
3999
  case "delete": {
3924
4000
  const { sure } = await inquirer3.prompt([{ type: "confirm", name: "sure", message: `Delete app client "${c.name ?? id}"? Consumers logged in through it will lose access.`, default: false }]);
3925
4001
  if (!sure) break;
3926
4002
  await admin({ method: "DELETE", path: cBase, summary: `Delete app client ${id}` });
3927
- console.log(import_chalk29.default.green(" App client deleted."));
4003
+ console.log(import_chalk30.default.green(" App client deleted."));
3928
4004
  return;
3929
4005
  }
3930
4006
  }
@@ -3951,9 +4027,9 @@ async function providersMenu(cBase, clientLabel) {
3951
4027
  const providers = Array.isArray(raw) ? raw : [];
3952
4028
  console.log();
3953
4029
  for (const p of providers) {
3954
- console.log(` ${import_chalk29.default.bold(p.type)} ${import_chalk29.default.dim(`${p.clientId || "(managed)"} \xB7 identity=${p.tokenType ?? "apiblaze"} \xB7 to-upstream=${p.targetServerToken ?? "apiblaze"}${p.isApiblazeDefault ? " \xB7 apiblaze-managed" : ""}`)}`);
4030
+ console.log(` ${import_chalk30.default.bold(p.type)} ${import_chalk30.default.dim(`${p.clientId || "(managed)"} \xB7 identity=${p.tokenType ?? "apiblaze"} \xB7 to-upstream=${p.targetServerToken ?? "apiblaze"}${p.isApiblazeDefault ? " \xB7 apiblaze-managed" : ""}`)}`);
3955
4031
  }
3956
- if (!providers.length) console.log(import_chalk29.default.dim(" No login providers \u2014 consumers cannot sign in to this client yet."));
4032
+ if (!providers.length) console.log(import_chalk30.default.dim(" No login providers \u2014 consumers cannot sign in to this client yet."));
3957
4033
  const { act } = await inquirer3.prompt([{
3958
4034
  type: "list",
3959
4035
  name: "act",
@@ -4011,23 +4087,23 @@ async function providersMenu(cBase, clientLabel) {
4011
4087
  body.targetServerToken = routing;
4012
4088
  }
4013
4089
  await admin({ method: "POST", path: `${cBase}/providers`, body, summary: `Add ${type} login provider` });
4014
- console.log(import_chalk29.default.green(` ${type} provider added.`));
4090
+ console.log(import_chalk30.default.green(` ${type} provider added.`));
4015
4091
  } else {
4016
4092
  const { p } = await inquirer3.prompt([{
4017
4093
  type: "list",
4018
4094
  name: "p",
4019
4095
  message: act === "rm" ? "Remove which provider?" : "Reveal which secret?",
4020
- choices: [...providers.map((x) => ({ name: `${x.type} ${import_chalk29.default.dim(x.clientId || "(managed)")}`, value: x })), { name: "\u2190 Back", value: null }]
4096
+ choices: [...providers.map((x) => ({ name: `${x.type} ${import_chalk30.default.dim(x.clientId || "(managed)")}`, value: x })), { name: "\u2190 Back", value: null }]
4021
4097
  }]);
4022
4098
  if (!p) continue;
4023
4099
  if (act === "rm") {
4024
4100
  const { sure } = await inquirer3.prompt([{ type: "confirm", name: "sure", message: `Remove the ${p.type} provider? Consumers using it can no longer sign in.`, default: false }]);
4025
4101
  if (!sure) continue;
4026
4102
  await admin({ method: "DELETE", path: `${cBase}/providers/${encodeURIComponent(p.id)}`, summary: `Remove ${p.type} provider` });
4027
- console.log(import_chalk29.default.green(` ${p.type} removed.`));
4103
+ console.log(import_chalk30.default.green(` ${p.type} removed.`));
4028
4104
  } else {
4029
4105
  const s = await admin({ method: "GET", path: `${cBase}/providers/${encodeURIComponent(p.id)}/secret`, summary: `Reveal ${p.type} provider secret` });
4030
- console.log(` ${import_chalk29.default.bold("client_secret")}: ${import_chalk29.default.green(s?.clientSecret ?? s?.client_secret ?? JSON.stringify(s))}`);
4106
+ console.log(` ${import_chalk30.default.bold("client_secret")}: ${import_chalk30.default.green(s?.clientSecret ?? s?.client_secret ?? JSON.stringify(s))}`);
4031
4107
  }
4032
4108
  }
4033
4109
  }
@@ -4035,7 +4111,7 @@ async function providersMenu(cBase, clientLabel) {
4035
4111
 
4036
4112
  // src/commands/spec.ts
4037
4113
  var fs7 = __toESM(require("fs"));
4038
- var import_chalk30 = __toESM(require("chalk"));
4114
+ var import_chalk31 = __toESM(require("chalk"));
4039
4115
  var import_ora14 = __toESM(require("ora"));
4040
4116
  init_admin();
4041
4117
  init_api();
@@ -4052,14 +4128,14 @@ async function runSpecGet(project, opts) {
4052
4128
  }
4053
4129
  async function runSpecSet(project, opts) {
4054
4130
  if (!opts.file) {
4055
- console.error(import_chalk30.default.red("--file <path> is required (OpenAPI JSON or YAML)."));
4131
+ console.error(import_chalk31.default.red("--file <path> is required (OpenAPI JSON or YAML)."));
4056
4132
  process.exit(1);
4057
4133
  }
4058
4134
  let specContent;
4059
4135
  try {
4060
4136
  specContent = fs7.readFileSync(opts.file, "utf-8");
4061
4137
  } catch {
4062
- console.error(import_chalk30.default.red(`Cannot read file: ${opts.file}`));
4138
+ console.error(import_chalk31.default.red(`Cannot read file: ${opts.file}`));
4063
4139
  process.exit(1);
4064
4140
  }
4065
4141
  const { teamId } = await resolveTeam(opts.team);
@@ -4088,23 +4164,23 @@ async function runSpecSet(project, opts) {
4088
4164
  function printSpecChangeReport(report, projectName) {
4089
4165
  const r = report.routes;
4090
4166
  if (r) {
4091
- for (const a of r.added) console.log(import_chalk30.default.green(` + ${a}`));
4092
- for (const d of r.removed) console.log(import_chalk30.default.red(` \u2212 ${d}`));
4093
- for (const rn of r.renamed ?? []) console.log(import_chalk30.default.yellow(` ~ ${rn.from} \u2192 ${rn.to}`));
4094
- for (const m of r.modified ?? []) console.log(import_chalk30.default.dim(` \xB1 ${m} (params/schema changed)`));
4167
+ for (const a of r.added) console.log(import_chalk31.default.green(` + ${a}`));
4168
+ for (const d of r.removed) console.log(import_chalk31.default.red(` \u2212 ${d}`));
4169
+ for (const rn of r.renamed ?? []) console.log(import_chalk31.default.yellow(` ~ ${rn.from} \u2192 ${rn.to}`));
4170
+ for (const m of r.modified ?? []) console.log(import_chalk31.default.dim(` \xB1 ${m} (params/schema changed)`));
4095
4171
  }
4096
- if (report.applied?.mcp_regenerated) console.log(import_chalk30.default.dim(" MCP catalogue regenerated."));
4097
- if (report.applied?.candidates_cleared) console.log(import_chalk30.default.dim(` ${report.applied.candidates_cleared} route candidate(s) now documented \u2014 cleared.`));
4172
+ if (report.applied?.mcp_regenerated) console.log(import_chalk31.default.dim(" MCP catalogue regenerated."));
4173
+ if (report.applied?.candidates_cleared) console.log(import_chalk31.default.dim(` ${report.applied.candidates_cleared} route candidate(s) now documented \u2014 cleared.`));
4098
4174
  for (const item of report.attention ?? []) {
4099
- console.log(import_chalk30.default.yellow(` \u26A0 ${item.detail}`));
4175
+ console.log(import_chalk31.default.yellow(` \u26A0 ${item.detail}`));
4100
4176
  if (item.suggestion?.carry_from && item.suggestion.carry_to) {
4101
- console.log(import_chalk30.default.dim(` Fix: apiblaze spec carry ${projectName} --method ${item.suggestion.method} --from "${item.suggestion.carry_from}" --to "${item.suggestion.carry_to}"`));
4177
+ console.log(import_chalk31.default.dim(` Fix: apiblaze spec carry ${projectName} --method ${item.suggestion.method} --from "${item.suggestion.carry_from}" --to "${item.suggestion.carry_to}"`));
4102
4178
  }
4103
4179
  }
4104
4180
  }
4105
4181
  async function runSpecCarry(project, opts) {
4106
4182
  if (!opts.method || !opts.from || !opts.to) {
4107
- console.error(import_chalk30.default.red("--method, --from and --to are required."));
4183
+ console.error(import_chalk31.default.red("--method, --from and --to are required."));
4108
4184
  process.exit(1);
4109
4185
  }
4110
4186
  const { teamId } = await resolveTeam(opts.team);
@@ -4126,7 +4202,7 @@ async function runSpecCarry(project, opts) {
4126
4202
  }
4127
4203
  async function runSpecDeleteRule(project, opts) {
4128
4204
  if (!opts.method || !opts.route) {
4129
- console.error(import_chalk30.default.red("--method and --route are required."));
4205
+ console.error(import_chalk31.default.red("--method and --route are required."));
4130
4206
  process.exit(1);
4131
4207
  }
4132
4208
  const { teamId } = await resolveTeam(opts.team);
@@ -4146,14 +4222,14 @@ async function runSpecDeleteRule(project, opts) {
4146
4222
  }
4147
4223
 
4148
4224
  // src/commands/agent.ts
4149
- var import_chalk32 = __toESM(require("chalk"));
4225
+ var import_chalk33 = __toESM(require("chalk"));
4150
4226
  var import_ora15 = __toESM(require("ora"));
4151
4227
  init_auth();
4152
4228
  init_admin();
4153
4229
  init_resolve();
4154
4230
 
4155
4231
  // src/lib/tools.ts
4156
- var import_chalk31 = __toESM(require("chalk"));
4232
+ var import_chalk32 = __toESM(require("chalk"));
4157
4233
  init_admin();
4158
4234
  init_api();
4159
4235
  init_resolve();
@@ -4173,15 +4249,15 @@ var TOOLS = [
4173
4249
  const key = keys.dev ?? Object.values(keys)[0];
4174
4250
  const url = `https://${a.name}.abz.run/${version2}/dev`;
4175
4251
  const tryIt = buildTryItCurl(url, auth, key);
4176
- const lines = [` ${import_chalk31.default.dim("Proxy URL:")} ${import_chalk31.default.bold(url)}`];
4177
- if (res.devPortal) lines.push(` ${import_chalk31.default.dim("Dev portal:")} ${res.devPortal}`);
4252
+ const lines = [` ${import_chalk32.default.dim("Proxy URL:")} ${import_chalk32.default.bold(url)}`];
4253
+ if (res.devPortal) lines.push(` ${import_chalk32.default.dim("Dev portal:")} ${res.devPortal}`);
4178
4254
  const envs = Object.keys(keys);
4179
4255
  if (envs.length) {
4180
- lines.push("", ` ${import_chalk31.default.bold("API keys")} ${import_chalk31.default.dim("(bootstrapped \u2014 send as the X-API-Key header; shown once):")}`);
4256
+ lines.push("", ` ${import_chalk32.default.bold("API keys")} ${import_chalk32.default.dim("(bootstrapped \u2014 send as the X-API-Key header; shown once):")}`);
4181
4257
  const w = Math.max(...envs.map((e) => e.length));
4182
- for (const env of envs) lines.push(` ${import_chalk31.default.cyan(env.padEnd(w))} ${import_chalk31.default.green(keys[env])}`);
4258
+ for (const env of envs) lines.push(` ${import_chalk32.default.cyan(env.padEnd(w))} ${import_chalk32.default.green(keys[env])}`);
4183
4259
  }
4184
- if (tryIt) lines.push("", ` ${import_chalk31.default.dim("Try it:")}`, ` ${import_chalk31.default.cyan(tryIt)}`);
4260
+ if (tryIt) lines.push("", ` ${import_chalk32.default.dim("Try it:")}`, ` ${import_chalk32.default.cyan(tryIt)}`);
4185
4261
  return { ...res, proxy_url: url, keys, ...tryIt ? { try_it: tryIt } : {}, display: lines.join("\n") };
4186
4262
  }
4187
4263
  },
@@ -4337,17 +4413,17 @@ function truncate(value, max = 1500) {
4337
4413
  }
4338
4414
  function printCost(resp) {
4339
4415
  const line = formatBilling(resp.billing);
4340
- if (line) console.log(import_chalk32.default.magenta(` ${line}`) + import_chalk32.default.dim(` (${resp.llm.model}, ${resp.llm.total_tokens} tok)`));
4416
+ if (line) console.log(import_chalk33.default.magenta(` ${line}`) + import_chalk33.default.dim(` (${resp.llm.model}, ${resp.llm.total_tokens} tok)`));
4341
4417
  }
4342
4418
  async function runAgent(opts) {
4343
4419
  requireAuth();
4344
4420
  const { teamId, teamName } = await resolveTeam(opts.team);
4345
4421
  const { default: inquirer3 } = await import("inquirer");
4346
- console.log(import_chalk32.default.bold("APIblaze agent") + import_chalk32.default.dim(` \xB7 team ${teamName ?? teamId}`));
4347
- console.log(import_chalk32.default.dim('Ask me to create/delete/configure proxies, tenants, keys, domains, specs. Type "exit" to quit.\n'));
4422
+ console.log(import_chalk33.default.bold("APIblaze agent") + import_chalk33.default.dim(` \xB7 team ${teamName ?? teamId}`));
4423
+ console.log(import_chalk33.default.dim('Ask me to create/delete/configure proxies, tenants, keys, domains, specs. Type "exit" to quit.\n'));
4348
4424
  const history = [];
4349
4425
  while (true) {
4350
- const { input } = await inquirer3.prompt([{ type: "input", name: "input", message: import_chalk32.default.cyan("you") + " \u203A" }]);
4426
+ const { input } = await inquirer3.prompt([{ type: "input", name: "input", message: import_chalk33.default.cyan("you") + " \u203A" }]);
4351
4427
  const text = (input ?? "").trim();
4352
4428
  if (!text) continue;
4353
4429
  if (["exit", "quit", ":q"].includes(text.toLowerCase())) break;
@@ -4361,14 +4437,14 @@ async function runAgent(opts) {
4361
4437
  } catch (err) {
4362
4438
  spinner.stop();
4363
4439
  if (err instanceof ApiError && err.status === 402) {
4364
- console.log(import_chalk32.default.yellow(" Insufficient credits \u2014 top up to keep using the agent."));
4440
+ console.log(import_chalk33.default.yellow(" Insufficient credits \u2014 top up to keep using the agent."));
4365
4441
  break;
4366
4442
  }
4367
4443
  throw err;
4368
4444
  }
4369
4445
  history.push({ role: "assistant", content: resp.raw });
4370
4446
  printCost(resp);
4371
- if (resp.reply) console.log(import_chalk32.default.green("agent") + " \u203A " + resp.reply);
4447
+ if (resp.reply) console.log(import_chalk33.default.green("agent") + " \u203A " + resp.reply);
4372
4448
  if (!resp.action) break;
4373
4449
  const tool = findTool(resp.action.tool);
4374
4450
  if (!tool) {
@@ -4393,11 +4469,11 @@ async function runAgent(opts) {
4393
4469
  }
4394
4470
  renderTrace();
4395
4471
  if (step === MAX_TOOL_STEPS - 1) {
4396
- console.log(import_chalk32.default.dim(" (paused after several steps \u2014 tell me how to continue)"));
4472
+ console.log(import_chalk33.default.dim(" (paused after several steps \u2014 tell me how to continue)"));
4397
4473
  }
4398
4474
  }
4399
4475
  }
4400
- console.log(import_chalk32.default.dim("\nBye."));
4476
+ console.log(import_chalk33.default.dim("\nBye."));
4401
4477
  }
4402
4478
 
4403
4479
  // src/commands/config-browse.ts
@@ -4636,11 +4712,11 @@ function dig(blob, dotted) {
4636
4712
  }
4637
4713
  var readSetting = (s, cfg) => s.read ? s.read(cfg) : dig(cfg, s.key);
4638
4714
  function show(v) {
4639
- if (v === void 0) return import_chalk33.default.dim("(unset)");
4640
- if (v === null) return import_chalk33.default.dim("null");
4641
- if (typeof v === "object") return import_chalk33.default.cyan(JSON.stringify(v));
4642
- if (typeof v === "boolean") return v ? import_chalk33.default.green("on") : import_chalk33.default.red("off");
4643
- return import_chalk33.default.cyan(String(v));
4715
+ if (v === void 0) return import_chalk34.default.dim("(unset)");
4716
+ if (v === null) return import_chalk34.default.dim("null");
4717
+ if (typeof v === "object") return import_chalk34.default.cyan(JSON.stringify(v));
4718
+ if (typeof v === "boolean") return v ? import_chalk34.default.green("on") : import_chalk34.default.red("off");
4719
+ return import_chalk34.default.cyan(String(v));
4644
4720
  }
4645
4721
  function parseValue(raw) {
4646
4722
  if (raw === "true") return true;
@@ -4682,10 +4758,10 @@ async function patchSetting(proj2, s, value, cfg) {
4682
4758
  }
4683
4759
  }
4684
4760
  var loginFirst = (what) => {
4685
- console.log(import_chalk33.default.yellow(`
4761
+ console.log(import_chalk34.default.yellow(`
4686
4762
  Log in first to ${what}.`));
4687
- console.log(import_chalk33.default.dim(" Run `npx apiblaze login` \u2014 or `npx apiblaze claim` if you created this proxy"));
4688
- console.log(import_chalk33.default.dim(" anonymously and want to bring it into your account.\n"));
4763
+ console.log(import_chalk34.default.dim(" Run `npx apiblaze login` \u2014 or `npx apiblaze claim` if you created this proxy"));
4764
+ console.log(import_chalk34.default.dim(" anonymously and want to bring it into your account.\n"));
4689
4765
  };
4690
4766
  async function runConfig(project, key, value, opts) {
4691
4767
  const creds = loadCredentials();
@@ -4702,9 +4778,9 @@ async function runConfig(project, key, value, opts) {
4702
4778
  }
4703
4779
  const setting = SETTINGS.find((s) => s.key === key);
4704
4780
  if (!setting) {
4705
- console.error(import_chalk33.default.red(`Unknown setting "${key}".`));
4706
- console.error(import_chalk33.default.dim(" Known: " + SETTINGS.map((s) => s.key).join(", ")));
4707
- console.error(import_chalk33.default.dim(" (Features like transforms/domains/tenants live in the menu: `apiblaze config <project>`.)"));
4781
+ console.error(import_chalk34.default.red(`Unknown setting "${key}".`));
4782
+ console.error(import_chalk34.default.dim(" Known: " + SETTINGS.map((s) => s.key).join(", ")));
4783
+ console.error(import_chalk34.default.dim(" (Features like transforms/domains/tenants live in the menu: `apiblaze config <project>`.)"));
4708
4784
  process.exit(1);
4709
4785
  }
4710
4786
  if (value === void 0) {
@@ -4719,7 +4795,7 @@ async function pickProject(teamId) {
4719
4795
  const { getProjects: getProjects2 } = await Promise.resolve().then(() => (init_api(), api_exports));
4720
4796
  const projects = await getProjects2(teamId).catch(() => []);
4721
4797
  if (!projects.length) {
4722
- console.error(import_chalk33.default.red("No projects in this team. Create one: `npx apiblaze create`."));
4798
+ console.error(import_chalk34.default.red("No projects in this team. Create one: `npx apiblaze create`."));
4723
4799
  process.exit(1);
4724
4800
  }
4725
4801
  const { default: inquirer3 } = await import("inquirer");
@@ -4727,7 +4803,7 @@ async function pickProject(teamId) {
4727
4803
  type: "list",
4728
4804
  name: "picked",
4729
4805
  message: "Which project?",
4730
- choices: projects.map((p) => ({ name: `${p.projectName} ${import_chalk33.default.dim("v" + p.apiVersion)}`, value: p }))
4806
+ choices: projects.map((p) => ({ name: `${p.projectName} ${import_chalk34.default.dim("v" + p.apiVersion)}`, value: p }))
4731
4807
  }]);
4732
4808
  return { projectId: picked.projectId, projectName: picked.projectName, apiVersion: picked.apiVersion, teamId, tenant: picked.tenant };
4733
4809
  }
@@ -4738,25 +4814,25 @@ function printAll(proj2, cfg, json) {
4738
4814
  console.log(JSON.stringify(out, null, 2));
4739
4815
  return;
4740
4816
  }
4741
- console.log(import_chalk33.default.bold(`
4817
+ console.log(import_chalk34.default.bold(`
4742
4818
  ${proj2.projectName} v${proj2.apiVersion} \u2014 settings
4743
4819
  `));
4744
4820
  for (const group2 of SETTING_GROUPS) {
4745
- console.log(import_chalk33.default.bold(group2));
4821
+ console.log(import_chalk34.default.bold(group2));
4746
4822
  for (const s of SETTINGS.filter((x) => x.group === group2)) {
4747
- console.log(` ${s.key.padEnd(32)} ${show(readSetting(s, cfg))} ${import_chalk33.default.dim(s.desc)}`);
4823
+ console.log(` ${s.key.padEnd(32)} ${show(readSetting(s, cfg))} ${import_chalk34.default.dim(s.desc)}`);
4748
4824
  }
4749
4825
  console.log();
4750
4826
  }
4751
- console.log(import_chalk33.default.dim("Change one: apiblaze config " + proj2.projectName + " <key> <value> (add --verbose for the API call)"));
4827
+ console.log(import_chalk34.default.dim("Change one: apiblaze config " + proj2.projectName + " <key> <value> (add --verbose for the API call)"));
4752
4828
  }
4753
4829
  async function discoveryMenu(project) {
4754
4830
  const { default: inquirer3 } = await import("inquirer");
4755
- console.log(import_chalk33.default.bold(`
4831
+ console.log(import_chalk34.default.bold(`
4756
4832
  APIblaze proxy configuration${project ? ` \u2014 ${project}` : ""}
4757
4833
  `));
4758
- console.log(import_chalk33.default.dim("You are not logged in \u2014 browsing what's configurable. Everything below works"));
4759
- console.log(import_chalk33.default.dim("from this menu once you log in (`npx apiblaze login`).\n"));
4834
+ console.log(import_chalk34.default.dim("You are not logged in \u2014 browsing what's configurable. Everything below works"));
4835
+ console.log(import_chalk34.default.dim("from this menu once you log in (`npx apiblaze login`).\n"));
4760
4836
  for (; ; ) {
4761
4837
  const { pick: pick2 } = await inquirer3.prompt([{
4762
4838
  type: "list",
@@ -4764,13 +4840,13 @@ APIblaze proxy configuration${project ? ` \u2014 ${project}` : ""}
4764
4840
  message: "Explore:",
4765
4841
  pageSize: 20,
4766
4842
  choices: [
4767
- new inquirer3.Separator(import_chalk33.default.bold("\u2014 Settings \u2014")),
4843
+ new inquirer3.Separator(import_chalk34.default.bold("\u2014 Settings \u2014")),
4768
4844
  ...SETTING_GROUPS.map((g) => ({
4769
- name: `${g} ${import_chalk33.default.dim(SETTINGS.filter((s) => s.group === g).map((s) => s.label).join(", "))}`,
4845
+ name: `${g} ${import_chalk34.default.dim(SETTINGS.filter((s) => s.group === g).map((s) => s.label).join(", "))}`,
4770
4846
  value: { kind: "settings", g }
4771
4847
  })),
4772
- new inquirer3.Separator(import_chalk33.default.bold("\u2014 Features \u2014")),
4773
- ...FEATURES.map((f) => ({ name: `${f.label} ${import_chalk33.default.dim(f.desc)}`, value: { kind: "feature", f } })),
4848
+ new inquirer3.Separator(import_chalk34.default.bold("\u2014 Features \u2014")),
4849
+ ...FEATURES.map((f) => ({ name: `${f.label} ${import_chalk34.default.dim(f.desc)}`, value: { kind: "feature", f } })),
4774
4850
  new inquirer3.Separator(),
4775
4851
  { name: "Exit", value: { kind: "exit" } }
4776
4852
  ]
@@ -4779,24 +4855,24 @@ APIblaze proxy configuration${project ? ` \u2014 ${project}` : ""}
4779
4855
  if (pick2.kind === "settings") {
4780
4856
  console.log();
4781
4857
  for (const s of SETTINGS.filter((x) => x.group === pick2.g)) {
4782
- console.log(` ${import_chalk33.default.bold(s.label.padEnd(28))} ${import_chalk33.default.dim(s.desc)}`);
4783
- console.log(` ${import_chalk33.default.dim(" key: " + s.key)}`);
4858
+ console.log(` ${import_chalk34.default.bold(s.label.padEnd(28))} ${import_chalk34.default.dim(s.desc)}`);
4859
+ console.log(` ${import_chalk34.default.dim(" key: " + s.key)}`);
4784
4860
  }
4785
4861
  loginFirst("view or change these settings");
4786
4862
  } else {
4787
4863
  const f = pick2.f;
4788
4864
  console.log(`
4789
- ${import_chalk33.default.bold(f.label)} \u2014 ${f.desc}`);
4865
+ ${import_chalk34.default.bold(f.label)} \u2014 ${f.desc}`);
4790
4866
  loginFirst(`use ${f.label.toLowerCase()}`);
4791
4867
  }
4792
4868
  }
4793
4869
  }
4794
4870
  async function navigator(proj2, cfg, opts) {
4795
4871
  const { default: inquirer3 } = await import("inquirer");
4796
- console.log(import_chalk33.default.bold(`
4872
+ console.log(import_chalk34.default.bold(`
4797
4873
  ${proj2.projectName} v${proj2.apiVersion} \u2014 configuration
4798
4874
  `));
4799
- console.log(import_chalk33.default.dim("Tip: every change is one API call \u2014 add --verbose to see the curl equivalent.\n"));
4875
+ console.log(import_chalk34.default.dim("Tip: every change is one API call \u2014 add --verbose to see the curl equivalent.\n"));
4800
4876
  let blob = cfg;
4801
4877
  for (; ; ) {
4802
4878
  const { pick: pick2 } = await inquirer3.prompt([{
@@ -4805,10 +4881,10 @@ ${proj2.projectName} v${proj2.apiVersion} \u2014 configuration
4805
4881
  message: "Where to?",
4806
4882
  pageSize: 20,
4807
4883
  choices: [
4808
- new inquirer3.Separator(import_chalk33.default.bold("\u2014 Settings \u2014")),
4884
+ new inquirer3.Separator(import_chalk34.default.bold("\u2014 Settings \u2014")),
4809
4885
  ...SETTING_GROUPS.map((g) => ({ name: g, value: { kind: "settings", g } })),
4810
- new inquirer3.Separator(import_chalk33.default.bold("\u2014 Features \u2014")),
4811
- ...FEATURES.map((f) => ({ name: `${f.label} ${import_chalk33.default.dim(f.desc)}`, value: { kind: f.go } })),
4886
+ new inquirer3.Separator(import_chalk34.default.bold("\u2014 Features \u2014")),
4887
+ ...FEATURES.map((f) => ({ name: `${f.label} ${import_chalk34.default.dim(f.desc)}`, value: { kind: f.go } })),
4812
4888
  new inquirer3.Separator(),
4813
4889
  { name: "Show all settings", value: { kind: "list" } },
4814
4890
  { name: "Exit", value: { kind: "exit" } }
@@ -4848,7 +4924,7 @@ ${proj2.projectName} v${proj2.apiVersion} \u2014 configuration
4848
4924
  }
4849
4925
  }
4850
4926
  } catch (err) {
4851
- console.error(import_chalk33.default.red(` ${err instanceof Error ? err.message : String(err)}`));
4927
+ console.error(import_chalk34.default.red(` ${err instanceof Error ? err.message : String(err)}`));
4852
4928
  }
4853
4929
  }
4854
4930
  }
@@ -4862,7 +4938,7 @@ async function settingsGroup(proj2, cfg, group2) {
4862
4938
  message: group2 + ":",
4863
4939
  pageSize: 16,
4864
4940
  choices: [
4865
- ...items.map((s2) => ({ name: `${s2.label.padEnd(30)} ${show(readSetting(s2, cfg))} ${import_chalk33.default.dim(s2.desc)}`, value: s2 })),
4941
+ ...items.map((s2) => ({ name: `${s2.label.padEnd(30)} ${show(readSetting(s2, cfg))} ${import_chalk34.default.dim(s2.desc)}`, value: s2 })),
4866
4942
  new inquirer3.Separator(),
4867
4943
  { name: "\u2190 Back", value: null }
4868
4944
  ]
@@ -4880,7 +4956,7 @@ async function settingsGroup(proj2, cfg, group2) {
4880
4956
  } else if (s.type === "number") {
4881
4957
  const { v } = await inquirer3.prompt([{ type: "input", name: "v", message: `${s.label} (number):`, default: readSetting(s, cfg) }]);
4882
4958
  if (v === "" || Number.isNaN(Number(v))) {
4883
- console.log(import_chalk33.default.yellow(" Not a number \u2014 unchanged."));
4959
+ console.log(import_chalk34.default.yellow(" Not a number \u2014 unchanged."));
4884
4960
  continue;
4885
4961
  }
4886
4962
  value = Number(v);
@@ -4961,7 +5037,7 @@ async function buildCondition(phase) {
4961
5037
  const items = [];
4962
5038
  for (; ; ) {
4963
5039
  const a = await inquirer3.prompt([
4964
- { type: "input", name: "source", message: `Condition field ${import_chalk33.default.dim(srcHint)}:`, validate: (s) => !!s || "required" },
5040
+ { type: "input", name: "source", message: `Condition field ${import_chalk34.default.dim(srcHint)}:`, validate: (s) => !!s || "required" },
4965
5041
  { type: "list", name: "operator", message: "Operator:", choices: [
4966
5042
  "eq",
4967
5043
  "neq",
@@ -4992,7 +5068,7 @@ async function buildCondition(phase) {
4992
5068
  function showCondition(cond) {
4993
5069
  if (!Array.isArray(cond) || !cond.length) return "";
4994
5070
  const s = cond.map((c) => `${c.source} ${c.operator}${c.value !== void 0 ? ` "${c.value}"` : ""}${c.logicOp ? ` ${c.logicOp}` : ""}`).join(" ");
4995
- return import_chalk33.default.dim(` when ${s}`);
5071
+ return import_chalk34.default.dim(` when ${s}`);
4996
5072
  }
4997
5073
  async function transformsMenu(proj2) {
4998
5074
  const { default: inquirer3 } = await import("inquirer");
@@ -5001,12 +5077,12 @@ async function transformsMenu(proj2) {
5001
5077
  const out = await admin({ method: "GET", path: base2, summary: "List transform rules" });
5002
5078
  const rules = out?.rules ?? [];
5003
5079
  console.log();
5004
- if (!rules.length) console.log(import_chalk33.default.dim(" No transform rules yet."));
5080
+ if (!rules.length) console.log(import_chalk34.default.dim(" No transform rules yet."));
5005
5081
  for (const r of rules) {
5006
5082
  const a = r.action ?? {};
5007
5083
  const fns = [...a.source_fns ?? [], ...a.dest_fns ?? []].map((f) => f.fn);
5008
- const what = a.type === "hardcode" ? `${a.destination} = "${a.value}"` : a.type === "remove" ? `remove ${a.field}` : `${a.source} \u2192 ${a.destination}${a.lookup ? " (mapped)" : ""}${fns.length ? import_chalk33.default.dim(` via ${fns.join("\u2192")}`) : ""}`;
5009
- console.log(` ${r.enabled ? import_chalk33.default.green("\u25CF") : import_chalk33.default.dim("\u25CB")} ${import_chalk33.default.bold(r.name)} ${import_chalk33.default.dim(`[${r.phase ?? "request"}]`)} ${what}${showCondition(r.condition)}`);
5084
+ const what = a.type === "hardcode" ? `${a.destination} = "${a.value}"` : a.type === "remove" ? `remove ${a.field}` : `${a.source} \u2192 ${a.destination}${a.lookup ? " (mapped)" : ""}${fns.length ? import_chalk34.default.dim(` via ${fns.join("\u2192")}`) : ""}`;
5085
+ console.log(` ${r.enabled ? import_chalk34.default.green("\u25CF") : import_chalk34.default.dim("\u25CB")} ${import_chalk34.default.bold(r.name)} ${import_chalk34.default.dim(`[${r.phase ?? "request"}]`)} ${what}${showCondition(r.condition)}`);
5010
5086
  }
5011
5087
  const { act } = await inquirer3.prompt([{
5012
5088
  type: "list",
@@ -5018,7 +5094,7 @@ async function transformsMenu(proj2) {
5018
5094
  { name: "Enable/disable a rule", value: "toggle" },
5019
5095
  { name: "Delete a rule", value: "delete" }
5020
5096
  ] : [],
5021
- { name: import_chalk33.default.dim("Add from raw JSON (grouped conditions, lookup tables, \u2026)"), value: "raw" },
5097
+ { name: import_chalk34.default.dim("Add from raw JSON (grouped conditions, lookup tables, \u2026)"), value: "raw" },
5022
5098
  { name: "\u2190 Back", value: "back" }
5023
5099
  ]
5024
5100
  }]);
@@ -5031,11 +5107,11 @@ async function transformsMenu(proj2) {
5031
5107
  }]);
5032
5108
  const body = parseValue(raw);
5033
5109
  if (!body || typeof body !== "object" || Array.isArray(body)) {
5034
- console.log(import_chalk33.default.yellow(" Not a JSON object \u2014 skipped."));
5110
+ console.log(import_chalk34.default.yellow(" Not a JSON object \u2014 skipped."));
5035
5111
  continue;
5036
5112
  }
5037
5113
  await admin({ method: "POST", path: base2, body, summary: "Create transform rule (raw JSON)" });
5038
- console.log(import_chalk33.default.green(" Rule created."));
5114
+ console.log(import_chalk34.default.green(" Rule created."));
5039
5115
  continue;
5040
5116
  }
5041
5117
  if (act === "add") {
@@ -5051,7 +5127,7 @@ async function transformsMenu(proj2) {
5051
5127
  { name: "Remove a field", value: "remove" }
5052
5128
  ] }
5053
5129
  ]);
5054
- const fieldHint = import_chalk33.default.dim("(e.g. header:x-api-version, param:limit, bodyvar:user.id)");
5130
+ const fieldHint = import_chalk34.default.dim("(e.g. header:x-api-version, param:limit, bodyvar:user.id)");
5055
5131
  let action2;
5056
5132
  if (ans.kind === "hardcode") {
5057
5133
  const a = await inquirer3.prompt([
@@ -5098,16 +5174,16 @@ async function transformsMenu(proj2) {
5098
5174
  type: "list",
5099
5175
  name: "rule",
5100
5176
  message: act === "toggle" ? "Which rule?" : "Delete which rule?",
5101
- choices: [...rules.map((r) => ({ name: `${r.name} ${import_chalk33.default.dim(`[${r.phase ?? "request"}]`)}`, value: r })), { name: "\u2190 Back", value: null }]
5177
+ choices: [...rules.map((r) => ({ name: `${r.name} ${import_chalk34.default.dim(`[${r.phase ?? "request"}]`)}`, value: r })), { name: "\u2190 Back", value: null }]
5102
5178
  }]);
5103
5179
  if (!rule) continue;
5104
5180
  if (act === "toggle") {
5105
5181
  const flipped = { ...rule, enabled: rule.enabled === false };
5106
5182
  await admin({ method: "PUT", path: `${base2}/${rule.id}`, body: flipped, summary: `${flipped.enabled ? "Enable" : "Disable"} transform "${rule.name}"` });
5107
- console.log(import_chalk33.default.green(` ${rule.name} \u2192 ${flipped.enabled ? "enabled" : "disabled"}`));
5183
+ console.log(import_chalk34.default.green(` ${rule.name} \u2192 ${flipped.enabled ? "enabled" : "disabled"}`));
5108
5184
  } else {
5109
5185
  await admin({ method: "DELETE", path: `${base2}/${rule.id}`, summary: `Delete transform "${rule.name}"` });
5110
- console.log(import_chalk33.default.green(` ${rule.name} deleted.`));
5186
+ console.log(import_chalk34.default.green(` ${rule.name} deleted.`));
5111
5187
  }
5112
5188
  }
5113
5189
  }
@@ -5119,9 +5195,9 @@ async function mappingsMenu(proj2) {
5119
5195
  const out = await admin({ method: "GET", path: base2, summary: "List mapping tables" });
5120
5196
  const tables = out?.mappings ?? out?.tables ?? [];
5121
5197
  console.log();
5122
- if (!tables.length) console.log(import_chalk33.default.dim(" No mapping tables yet."));
5198
+ if (!tables.length) console.log(import_chalk34.default.dim(" No mapping tables yet."));
5123
5199
  for (const t of tables) {
5124
- console.log(` ${import_chalk33.default.bold(t.name)} ${import_chalk33.default.dim(`${t.entries?.length ?? "?"} entries${t.hide_map_values ? ", hidden" : ""}${t.encrypt_values ? ", encrypted" : ""}`)}`);
5200
+ console.log(` ${import_chalk34.default.bold(t.name)} ${import_chalk34.default.dim(`${t.entries?.length ?? "?"} entries${t.hide_map_values ? ", hidden" : ""}${t.encrypt_values ? ", encrypted" : ""}`)}`);
5125
5201
  }
5126
5202
  const { act } = await inquirer3.prompt([{
5127
5203
  type: "list",
@@ -5141,11 +5217,11 @@ async function mappingsMenu(proj2) {
5141
5217
  ]);
5142
5218
  const entries2 = parseValue(a.entries);
5143
5219
  if (!Array.isArray(entries2)) {
5144
- console.log(import_chalk33.default.yellow(" Entries must be a JSON array \u2014 not created."));
5220
+ console.log(import_chalk34.default.yellow(" Entries must be a JSON array \u2014 not created."));
5145
5221
  continue;
5146
5222
  }
5147
5223
  await admin({ method: "POST", path: base2, body: { name: a.name, entries: entries2 }, summary: `Create mapping table "${a.name}"` });
5148
- console.log(import_chalk33.default.green(` Table "${a.name}" created.`));
5224
+ console.log(import_chalk34.default.green(` Table "${a.name}" created.`));
5149
5225
  } else {
5150
5226
  const { table } = await inquirer3.prompt([{
5151
5227
  type: "list",
@@ -5155,7 +5231,7 @@ async function mappingsMenu(proj2) {
5155
5231
  }]);
5156
5232
  if (!table) continue;
5157
5233
  await admin({ method: "DELETE", path: `${base2}/${table.id}`, summary: `Delete mapping table "${table.name}"` });
5158
- console.log(import_chalk33.default.green(` ${table.name} deleted.`));
5234
+ console.log(import_chalk34.default.green(` ${table.name} deleted.`));
5159
5235
  }
5160
5236
  }
5161
5237
  }
@@ -5166,14 +5242,14 @@ async function tenantsMenu(proj2, opts) {
5166
5242
  const out = await admin({ method: "GET", path: base2, summary: "List attached tenants" });
5167
5243
  const tenants = out?.tenants ?? [];
5168
5244
  console.log();
5169
- if (!tenants.length) console.log(import_chalk33.default.dim(" No tenants attached (consumers use the default tenant)."));
5170
- for (const t of tenants) console.log(` ${import_chalk33.default.bold(t.tenant_name ?? t.name)} ${import_chalk33.default.dim(t.display_name ?? "")}`);
5245
+ if (!tenants.length) console.log(import_chalk34.default.dim(" No tenants attached (consumers use the default tenant)."));
5246
+ for (const t of tenants) console.log(` ${import_chalk34.default.bold(t.tenant_name ?? t.name)} ${import_chalk34.default.dim(t.display_name ?? "")}`);
5171
5247
  const { act } = await inquirer3.prompt([{
5172
5248
  type: "list",
5173
5249
  name: "act",
5174
5250
  message: "Tenants:",
5175
5251
  choices: [
5176
- { name: `Manage a tenant\u2026 ${import_chalk33.default.dim("settings, login app clients, providers, issuers \u2014 affects EVERY proxy the tenant serves")}`, value: "manage" },
5252
+ { name: `Manage a tenant\u2026 ${import_chalk34.default.dim("settings, login app clients, providers, issuers \u2014 affects EVERY proxy the tenant serves")}`, value: "manage" },
5177
5253
  { name: "Attach a tenant to this project", value: "attach" },
5178
5254
  ...tenants.length ? [{ name: "Detach a tenant from this project", value: "detach" }] : [],
5179
5255
  { name: "\u2190 Back", value: "back" }
@@ -5196,7 +5272,7 @@ async function tenantsMenu(proj2, opts) {
5196
5272
  }]);
5197
5273
  if (!t) continue;
5198
5274
  await admin({ method: "DELETE", path: `${base2}/${encodeURIComponent(t.tenant_name ?? t.name)}`, summary: `Detach tenant ${t.tenant_name ?? t.name}` });
5199
- console.log(import_chalk33.default.green(` Detached ${t.tenant_name ?? t.name}.`));
5275
+ console.log(import_chalk34.default.green(` Detached ${t.tenant_name ?? t.name}.`));
5200
5276
  }
5201
5277
  }
5202
5278
  }
@@ -5239,7 +5315,7 @@ async function specMenu(proj2, opts) {
5239
5315
  choices: [
5240
5316
  { name: "Print the stored spec", value: "get" },
5241
5317
  { name: "Refresh the spec from its source", value: "refresh" },
5242
- { name: import_chalk33.default.dim("Build the spec by chatting over real traffic \u2192 agent"), value: "agent" },
5318
+ { name: import_chalk34.default.dim("Build the spec by chatting over real traffic \u2192 agent"), value: "agent" },
5243
5319
  { name: "\u2190 Back", value: "back" }
5244
5320
  ]
5245
5321
  }]);
@@ -5247,7 +5323,7 @@ async function specMenu(proj2, opts) {
5247
5323
  if (act === "get") await runSpecGet(proj2.projectName, { team: opts.team, apiversion: proj2.apiVersion });
5248
5324
  else if (act === "refresh") {
5249
5325
  await admin({ method: "POST", path: `/projects/${proj2.projectId}/${proj2.apiVersion}/refresh-spec`, summary: "Refresh spec from source" });
5250
- console.log(import_chalk33.default.green(" Spec refresh triggered."));
5326
+ console.log(import_chalk34.default.green(" Spec refresh triggered."));
5251
5327
  } else await runOpenapi(proj2.projectName, proj2.apiVersion);
5252
5328
  }
5253
5329
  async function agentsMenu(proj2, opts) {
@@ -5272,7 +5348,7 @@ async function agentsMenu(proj2, opts) {
5272
5348
  }
5273
5349
 
5274
5350
  // src/commands/group.ts
5275
- var import_chalk34 = __toESM(require("chalk"));
5351
+ var import_chalk35 = __toESM(require("chalk"));
5276
5352
  var import_ora17 = __toESM(require("ora"));
5277
5353
  init_auth();
5278
5354
  init_admin();
@@ -5366,7 +5442,7 @@ async function userByRefOrCreate(t, ref) {
5366
5442
  if (!ref.includes("@")) throw e;
5367
5443
  const created = await t.call("/v1/admin/users", "POST", { email: ref.trim().toLowerCase() });
5368
5444
  if (!created?.abz_sub) throw e;
5369
- console.log(import_chalk34.default.dim(` ${ref} wasn't a user yet \u2014 created.`));
5445
+ console.log(import_chalk35.default.dim(` ${ref} wasn't a user yet \u2014 created.`));
5370
5446
  return { abz_sub: created.abz_sub, email: created.email ?? ref, display_name: null };
5371
5447
  }
5372
5448
  }
@@ -5374,11 +5450,11 @@ async function runGroupList(opts) {
5374
5450
  const t = await resolveTransport(opts);
5375
5451
  const groups = await listGroups(t);
5376
5452
  if (opts.json) return void console.log(JSON.stringify(groups));
5377
- if (!groups.length) return void console.log(import_chalk34.default.yellow(`No groups in ${t.tenant}. Create one: apiblaze group create <name>`));
5378
- console.log(import_chalk34.default.dim(`Tenant ${t.tenant}:`));
5453
+ if (!groups.length) return void console.log(import_chalk35.default.yellow(`No groups in ${t.tenant}. Create one: apiblaze group create <name>`));
5454
+ console.log(import_chalk35.default.dim(`Tenant ${t.tenant}:`));
5379
5455
  for (const g of groups) {
5380
- const sealed = g.name === "apiblaze_admins" ? import_chalk34.default.dim(" (admins \u2014 managed by allowlist)") : "";
5381
- console.log(` ${import_chalk34.default.bold(g.name)} ${import_chalk34.default.dim(`${g.member_count ?? 0} member(s)`)}${sealed}`);
5456
+ const sealed = g.name === "apiblaze_admins" ? import_chalk35.default.dim(" (admins \u2014 managed by allowlist)") : "";
5457
+ console.log(` ${import_chalk35.default.bold(g.name)} ${import_chalk35.default.dim(`${g.member_count ?? 0} member(s)`)}${sealed}`);
5382
5458
  }
5383
5459
  }
5384
5460
  async function runGroupCreate(name, opts) {
@@ -5406,7 +5482,7 @@ async function runGroupCreate(name, opts) {
5406
5482
  const spinner = (0, import_ora17.default)(`Creating group ${name}...`).start();
5407
5483
  try {
5408
5484
  await t.call("/v1/admin/groups", "POST", { name, admins: [adminSub] });
5409
- spinner.succeed(`Group ${import_chalk34.default.bold(name)} created in ${t.tenant}.`);
5485
+ spinner.succeed(`Group ${import_chalk35.default.bold(name)} created in ${t.tenant}.`);
5410
5486
  } catch (e) {
5411
5487
  spinner.fail("Create failed.");
5412
5488
  throw e;
@@ -5418,7 +5494,7 @@ async function runGroupDelete(name, opts) {
5418
5494
  const spinner = (0, import_ora17.default)(`Deleting group ${name}...`).start();
5419
5495
  try {
5420
5496
  await t.call(`/v1/admin/groups/${encodeURIComponent(g.id)}`, "DELETE");
5421
- spinner.succeed(`Group ${import_chalk34.default.bold(name)} deleted.`);
5497
+ spinner.succeed(`Group ${import_chalk35.default.bold(name)} deleted.`);
5422
5498
  } catch (e) {
5423
5499
  spinner.fail("Delete failed.");
5424
5500
  throw e;
@@ -5431,11 +5507,11 @@ async function runGroupMembers(name, opts) {
5431
5507
  const subs = await t.call(`/v1/admin/groups/${encodeURIComponent(g.id)}/subgroups`);
5432
5508
  if (opts.json) return void console.log(JSON.stringify({ ...detail, subgroups: subs?.subgroups ?? [] }));
5433
5509
  const members = detail?.members ?? [];
5434
- console.log(import_chalk34.default.bold(`${g.name}`) + import_chalk34.default.dim(` (${t.tenant})`));
5435
- for (const m of members) console.log(` ${label2(m)} ${m.role === "admin" ? import_chalk34.default.cyan("group-admin") : import_chalk34.default.dim("member")}`);
5436
- if (!members.length) console.log(import_chalk34.default.dim(" no members"));
5510
+ console.log(import_chalk35.default.bold(`${g.name}`) + import_chalk35.default.dim(` (${t.tenant})`));
5511
+ for (const m of members) console.log(` ${label2(m)} ${m.role === "admin" ? import_chalk35.default.cyan("group-admin") : import_chalk35.default.dim("member")}`);
5512
+ if (!members.length) console.log(import_chalk35.default.dim(" no members"));
5437
5513
  const sg = subs?.subgroups ?? [];
5438
- if (sg.length) console.log(import_chalk34.default.dim(` subgroups: ${sg.map((s) => s.name).join(", ")}`));
5514
+ if (sg.length) console.log(import_chalk35.default.dim(` subgroups: ${sg.map((s) => s.name).join(", ")}`));
5439
5515
  }
5440
5516
  async function runGroupAddUser(userRef, groupName, opts) {
5441
5517
  const t = await resolveTransport(opts);
@@ -5445,7 +5521,7 @@ async function runGroupAddUser(userRef, groupName, opts) {
5445
5521
  const spinner = (0, import_ora17.default)(`Adding ${label2(u)} to ${g.name}...`).start();
5446
5522
  try {
5447
5523
  await t.call(`/v1/admin/groups/${encodeURIComponent(g.id)}/members`, "POST", { abz_sub: u.abz_sub, role });
5448
- spinner.succeed(`${import_chalk34.default.bold(label2(u))} added to ${import_chalk34.default.bold(g.name)} as ${role}.`);
5524
+ spinner.succeed(`${import_chalk35.default.bold(label2(u))} added to ${import_chalk35.default.bold(g.name)} as ${role}.`);
5449
5525
  } catch (e) {
5450
5526
  spinner.fail("Add failed.");
5451
5527
  throw e;
@@ -5457,7 +5533,7 @@ async function runGroupRemoveUser(userRef, groupName, opts) {
5457
5533
  const spinner = (0, import_ora17.default)(`Removing ${label2(u)} from ${g.name}...`).start();
5458
5534
  try {
5459
5535
  await t.call(`/v1/admin/groups/${encodeURIComponent(g.id)}/members/_?abz_sub=${encodeURIComponent(u.abz_sub)}`, "DELETE");
5460
- spinner.succeed(`${import_chalk34.default.bold(label2(u))} removed from ${import_chalk34.default.bold(g.name)}.`);
5536
+ spinner.succeed(`${import_chalk35.default.bold(label2(u))} removed from ${import_chalk35.default.bold(g.name)}.`);
5461
5537
  } catch (e) {
5462
5538
  spinner.fail("Remove failed.");
5463
5539
  throw e;
@@ -5469,7 +5545,7 @@ async function runGroupAddGroup(childName, parentName, opts) {
5469
5545
  const spinner = (0, import_ora17.default)(`Nesting ${child.name} under ${parent.name}...`).start();
5470
5546
  try {
5471
5547
  await t.call(`/v1/admin/groups/${encodeURIComponent(parent.id)}/subgroups`, "POST", { child_group_id: child.id });
5472
- spinner.succeed(`${import_chalk34.default.bold(child.name)} is now a subgroup of ${import_chalk34.default.bold(parent.name)}.`);
5548
+ spinner.succeed(`${import_chalk35.default.bold(child.name)} is now a subgroup of ${import_chalk35.default.bold(parent.name)}.`);
5473
5549
  } catch (e) {
5474
5550
  spinner.fail("Nest failed.");
5475
5551
  throw e;
@@ -5481,7 +5557,7 @@ async function runGroupRemoveGroup(childName, parentName, opts) {
5481
5557
  const spinner = (0, import_ora17.default)(`Un-nesting ${child.name} from ${parent.name}...`).start();
5482
5558
  try {
5483
5559
  await t.call(`/v1/admin/groups/${encodeURIComponent(parent.id)}/subgroups/${encodeURIComponent(child.id)}`, "DELETE");
5484
- spinner.succeed(`${import_chalk34.default.bold(child.name)} un-nested from ${import_chalk34.default.bold(parent.name)}.`);
5560
+ spinner.succeed(`${import_chalk35.default.bold(child.name)} un-nested from ${import_chalk35.default.bold(parent.name)}.`);
5485
5561
  } catch (e) {
5486
5562
  spinner.fail("Un-nest failed.");
5487
5563
  throw e;
@@ -5492,18 +5568,18 @@ async function runGroupUsers(opts) {
5492
5568
  const users = await listUsers(t);
5493
5569
  const observed = await t.call("/v1/admin/observed-identities").catch(() => ({ identities: [] }));
5494
5570
  if (opts.json) return void console.log(JSON.stringify({ users, observed: observed?.identities ?? [] }));
5495
- console.log(import_chalk34.default.dim(`Tenant ${t.tenant} \u2014 user directory:`));
5496
- for (const u of users) console.log(` ${label2(u)} ${import_chalk34.default.dim(u.abz_sub)}`);
5497
- if (!users.length) console.log(import_chalk34.default.dim(" no users yet"));
5571
+ console.log(import_chalk35.default.dim(`Tenant ${t.tenant} \u2014 user directory:`));
5572
+ for (const u of users) console.log(` ${label2(u)} ${import_chalk35.default.dim(u.abz_sub)}`);
5573
+ if (!users.length) console.log(import_chalk35.default.dim(" no users yet"));
5498
5574
  const fresh = (observed?.identities ?? []).filter((o) => !o.provisioned);
5499
5575
  if (fresh.length) {
5500
- console.log(import_chalk34.default.dim("Seen in traffic (not yet users):"));
5501
- for (const o of fresh) console.log(` ${o.email || o.abz_sub} ${import_chalk34.default.dim(o.source_label ?? "")}`);
5576
+ console.log(import_chalk35.default.dim("Seen in traffic (not yet users):"));
5577
+ for (const o of fresh) console.log(` ${o.email || o.abz_sub} ${import_chalk35.default.dim(o.source_label ?? "")}`);
5502
5578
  }
5503
5579
  }
5504
5580
 
5505
5581
  // src/commands/key.ts
5506
- var import_chalk35 = __toESM(require("chalk"));
5582
+ var import_chalk36 = __toESM(require("chalk"));
5507
5583
  var import_ora18 = __toESM(require("ora"));
5508
5584
  init_caller();
5509
5585
  async function runApikeysMenu(opts) {
@@ -5533,11 +5609,11 @@ async function runKeyList(opts) {
5533
5609
  return;
5534
5610
  }
5535
5611
  if (!keys.length) {
5536
- console.log(import_chalk35.default.yellow("No developer keys."));
5612
+ console.log(import_chalk36.default.yellow("No developer keys."));
5537
5613
  return;
5538
5614
  }
5539
5615
  for (const k of keys) {
5540
- console.log(` ${import_chalk35.default.bold(k.key_id ?? k.id)} ${import_chalk35.default.dim(k.description ?? "")} ${import_chalk35.default.dim(k.expires_at ?? "no expiry")}`);
5616
+ console.log(` ${import_chalk36.default.bold(k.key_id ?? k.id)} ${import_chalk36.default.dim(k.description ?? "")} ${import_chalk36.default.dim(k.expires_at ?? "no expiry")}`);
5541
5617
  }
5542
5618
  }
5543
5619
  async function runKeyMint(opts) {
@@ -5559,9 +5635,9 @@ async function runKeyMint(opts) {
5559
5635
  console.log(JSON.stringify(out));
5560
5636
  return;
5561
5637
  }
5562
- console.log(` ${import_chalk35.default.bold("key_id")}: ${out?.key_id}`);
5563
- console.log(` ${import_chalk35.default.bold("key")}: ${import_chalk35.default.green(out?.key)} ${import_chalk35.default.dim("(shown once \u2014 store it now)")}`);
5564
- if (out?.expires_at) console.log(` ${import_chalk35.default.dim("expires:")} ${out.expires_at}`);
5638
+ console.log(` ${import_chalk36.default.bold("key_id")}: ${out?.key_id}`);
5639
+ console.log(` ${import_chalk36.default.bold("key")}: ${import_chalk36.default.green(out?.key)} ${import_chalk36.default.dim("(shown once \u2014 store it now)")}`);
5640
+ if (out?.expires_at) console.log(` ${import_chalk36.default.dim("expires:")} ${out.expires_at}`);
5565
5641
  } catch (err) {
5566
5642
  spinner.fail("Mint failed.");
5567
5643
  throw err;
@@ -5588,7 +5664,7 @@ async function runKeyRevoke(keyId, opts) {
5588
5664
  init_iam();
5589
5665
 
5590
5666
  // src/commands/admins.ts
5591
- var import_chalk36 = __toESM(require("chalk"));
5667
+ var import_chalk37 = __toESM(require("chalk"));
5592
5668
  var import_ora19 = __toESM(require("ora"));
5593
5669
  init_caller();
5594
5670
  function requireTenant(opts) {
@@ -5616,13 +5692,13 @@ async function runAdminsList(opts) {
5616
5692
  return;
5617
5693
  }
5618
5694
  if (!admins2.length) {
5619
- console.log(import_chalk36.default.yellow(`No tenant admins for ${tenant2} yet.`));
5695
+ console.log(import_chalk37.default.yellow(`No tenant admins for ${tenant2} yet.`));
5620
5696
  return;
5621
5697
  }
5622
5698
  for (const a of admins2) {
5623
5699
  const email = typeof a === "string" ? a : a.email;
5624
5700
  const flags = [a.active === false ? "pending" : null, a.pinned ? "pinned" : null].filter(Boolean).join(", ");
5625
- console.log(` ${import_chalk36.default.bold(email)}${flags ? import_chalk36.default.dim(` (${flags})`) : ""}`);
5701
+ console.log(` ${import_chalk37.default.bold(email)}${flags ? import_chalk37.default.dim(` (${flags})`) : ""}`);
5626
5702
  }
5627
5703
  }
5628
5704
  async function runAdminsAdd(email, opts) {
@@ -5637,9 +5713,9 @@ async function runAdminsAdd(email, opts) {
5637
5713
  body: { email },
5638
5714
  summary: `Add ${email} to tenant ${tenant2} admins`
5639
5715
  });
5640
- spinner?.succeed(`${import_chalk36.default.bold(email)} is now a tenant admin of ${import_chalk36.default.bold(tenant2)}.`);
5716
+ spinner?.succeed(`${import_chalk37.default.bold(email)} is now a tenant admin of ${import_chalk37.default.bold(tenant2)}.`);
5641
5717
  if (opts.json) console.log(JSON.stringify(out ?? { ok: true }));
5642
- else console.log(import_chalk36.default.dim(" Reload the Users & Groups widget \u2014 access flips from \u201Cpending\u201D to ready."));
5718
+ else console.log(import_chalk37.default.dim(" Reload the Users & Groups widget \u2014 access flips from \u201Cpending\u201D to ready."));
5643
5719
  } catch (err) {
5644
5720
  spinner?.fail("Add failed.");
5645
5721
  throw err;
@@ -5656,7 +5732,7 @@ async function runAdminsRemove(email, opts) {
5656
5732
  path: `${base(teamId, tenant2)}/${encodeURIComponent(email)}`,
5657
5733
  summary: `Remove ${email} from tenant ${tenant2} admins`
5658
5734
  });
5659
- spinner?.succeed(`Removed ${import_chalk36.default.bold(email)} from the tenant admins of ${import_chalk36.default.bold(tenant2)}.`);
5735
+ spinner?.succeed(`Removed ${import_chalk37.default.bold(email)} from the tenant admins of ${import_chalk37.default.bold(tenant2)}.`);
5660
5736
  } catch (err) {
5661
5737
  spinner?.fail("Remove failed.");
5662
5738
  throw err;
@@ -5664,7 +5740,7 @@ async function runAdminsRemove(email, opts) {
5664
5740
  }
5665
5741
 
5666
5742
  // src/commands/preapprove.ts
5667
- var import_chalk37 = __toESM(require("chalk"));
5743
+ var import_chalk38 = __toESM(require("chalk"));
5668
5744
  var import_ora20 = __toESM(require("ora"));
5669
5745
 
5670
5746
  // src/lib/preapproval.ts
@@ -5729,14 +5805,14 @@ async function runPreapprove(who, opts) {
5729
5805
  const rules = await listPreapprovalRules(tenant2);
5730
5806
  if (opts.json) return void console.log(JSON.stringify(rules, null, 2));
5731
5807
  if (!rules.length) {
5732
- console.log(import_chalk37.default.dim(`No pre-approval rules in ${tenant2}. Anyone who signs in can access (unless access is restricted).`));
5733
- console.log(import_chalk37.default.dim(`Add one: apiblaze preapprove someone@acme.com`));
5808
+ console.log(import_chalk38.default.dim(`No pre-approval rules in ${tenant2}. Anyone who signs in can access (unless access is restricted).`));
5809
+ console.log(import_chalk38.default.dim(`Add one: apiblaze preapprove someone@acme.com`));
5734
5810
  return;
5735
5811
  }
5736
- console.log(import_chalk37.default.dim(`Pre-approved for ${import_chalk37.default.bold(tenant2)}:`));
5812
+ console.log(import_chalk38.default.dim(`Pre-approved for ${import_chalk38.default.bold(tenant2)}:`));
5737
5813
  for (const r of rules) {
5738
- const tag = r.kind === "domain" ? import_chalk37.default.cyan("@" + r.value + " (whole domain)") : r.value;
5739
- const grp = r.groups?.length ? import_chalk37.default.dim(` \u2192 groups: ${r.groups.join(", ")}`) : "";
5814
+ const tag = r.kind === "domain" ? import_chalk38.default.cyan("@" + r.value + " (whole domain)") : r.value;
5815
+ const grp = r.groups?.length ? import_chalk38.default.dim(` \u2192 groups: ${r.groups.join(", ")}`) : "";
5740
5816
  console.log(` ${tag}${grp}`);
5741
5817
  }
5742
5818
  return;
@@ -5747,17 +5823,17 @@ async function runPreapprove(who, opts) {
5747
5823
  if (opts.remove) {
5748
5824
  const spinner2 = (0, import_ora20.default)(`Removing ${who} from ${tenant2}\u2026`).start();
5749
5825
  const { removed, value } = await removePreapprovalRule(tenant2, who);
5750
- if (removed) spinner2.succeed(`${import_chalk37.default.bold(value)} is no longer pre-approved for ${tenant2}.`);
5751
- else spinner2.warn(`No pre-approval rule for ${import_chalk37.default.bold(value)} in ${tenant2} \u2014 nothing to remove.`);
5826
+ if (removed) spinner2.succeed(`${import_chalk38.default.bold(value)} is no longer pre-approved for ${tenant2}.`);
5827
+ else spinner2.warn(`No pre-approval rule for ${import_chalk38.default.bold(value)} in ${tenant2} \u2014 nothing to remove.`);
5752
5828
  return;
5753
5829
  }
5754
5830
  const spinner = (0, import_ora20.default)(`Pre-approving ${who} for ${tenant2}\u2026`).start();
5755
5831
  try {
5756
5832
  const { kind, value } = await addPreapprovalRule(tenant2, who, opts.group);
5757
5833
  const what = kind === "domain" ? `Anyone @${value}` : value;
5758
- spinner.succeed(`${import_chalk37.default.bold(what)} can now sign in to ${import_chalk37.default.bold(tenant2)}.`);
5759
- if (opts.group?.length) console.log(import_chalk37.default.dim(` They'll join group(s) ${opts.group.join(", ")} on first sign-in.`));
5760
- console.log(import_chalk37.default.dim(` See the full list: apiblaze preapprove --list`));
5834
+ spinner.succeed(`${import_chalk38.default.bold(what)} can now sign in to ${import_chalk38.default.bold(tenant2)}.`);
5835
+ if (opts.group?.length) console.log(import_chalk38.default.dim(` They'll join group(s) ${opts.group.join(", ")} on first sign-in.`));
5836
+ console.log(import_chalk38.default.dim(` See the full list: apiblaze preapprove --list`));
5761
5837
  } catch (err) {
5762
5838
  spinner.fail("Could not add the rule.");
5763
5839
  throw err;
@@ -5768,7 +5844,7 @@ async function runPreapprove(who, opts) {
5768
5844
  var fs9 = __toESM(require("fs"));
5769
5845
  var path6 = __toESM(require("path"));
5770
5846
  var crypto2 = __toESM(require("crypto"));
5771
- var import_chalk39 = __toESM(require("chalk"));
5847
+ var import_chalk40 = __toESM(require("chalk"));
5772
5848
  var import_ora21 = __toESM(require("ora"));
5773
5849
  var import_yaml2 = require("yaml");
5774
5850
  init_auth();
@@ -5779,7 +5855,7 @@ init_admin();
5779
5855
  // src/commands/llm.ts
5780
5856
  var fs8 = __toESM(require("fs"));
5781
5857
  var path5 = __toESM(require("path"));
5782
- var import_chalk38 = __toESM(require("chalk"));
5858
+ var import_chalk39 = __toESM(require("chalk"));
5783
5859
  var import_inquirer2 = __toESM(require("inquirer"));
5784
5860
  init_auth();
5785
5861
  var LLM_PATH = path5.join(getApiblazeDir(), "llm.json");
@@ -5823,27 +5899,27 @@ async function runLlmSetKey(keyArg, opts) {
5823
5899
  }
5824
5900
  const existing = loadLlmConfig();
5825
5901
  saveLlmConfig({ key, provider, model: opts.model ?? existing?.model });
5826
- console.log(`${import_chalk38.default.green("\u2713")} Saved ${import_chalk38.default.bold(provider)} key ${maskSecret(key)}`);
5827
- console.log(import_chalk38.default.gray(` Stored locally at ${LLM_PATH} (0600) \u2014 never sent to APIblaze except per chat turn.`));
5828
- if (opts.model) console.log(import_chalk38.default.gray(` Model: ${opts.model}`));
5902
+ console.log(`${import_chalk39.default.green("\u2713")} Saved ${import_chalk39.default.bold(provider)} key ${maskSecret(key)}`);
5903
+ console.log(import_chalk39.default.gray(` Stored locally at ${LLM_PATH} (0600) \u2014 never sent to APIblaze except per chat turn.`));
5904
+ if (opts.model) console.log(import_chalk39.default.gray(` Model: ${opts.model}`));
5829
5905
  }
5830
5906
  async function runLlmShow() {
5831
5907
  const cfg = loadLlmConfig();
5832
5908
  if (!cfg) {
5833
- console.log(import_chalk38.default.gray("No LLM key set. `apiblaze llm set-key sk-...` to add one (optional \u2014 chat works without it)."));
5909
+ console.log(import_chalk39.default.gray("No LLM key set. `apiblaze llm set-key sk-...` to add one (optional \u2014 chat works without it)."));
5834
5910
  return;
5835
5911
  }
5836
- console.log(`Provider: ${import_chalk38.default.bold(cfg.provider)}`);
5912
+ console.log(`Provider: ${import_chalk39.default.bold(cfg.provider)}`);
5837
5913
  console.log(`Key: ${maskSecret(cfg.key)}`);
5838
5914
  if (cfg.model) console.log(`Model: ${cfg.model}`);
5839
- console.log(import_chalk38.default.gray(`Stored at ${LLM_PATH}`));
5915
+ console.log(import_chalk39.default.gray(`Stored at ${LLM_PATH}`));
5840
5916
  }
5841
5917
  async function runLlmClearKey() {
5842
5918
  try {
5843
5919
  fs8.unlinkSync(LLM_PATH);
5844
- console.log(`${import_chalk38.default.green("\u2713")} Removed local LLM key.`);
5920
+ console.log(`${import_chalk39.default.green("\u2713")} Removed local LLM key.`);
5845
5921
  } catch {
5846
- console.log(import_chalk38.default.gray("No LLM key was set."));
5922
+ console.log(import_chalk39.default.gray("No LLM key was set."));
5847
5923
  }
5848
5924
  }
5849
5925
 
@@ -5851,9 +5927,9 @@ async function runLlmClearKey() {
5851
5927
  init_trace();
5852
5928
  init_types();
5853
5929
  function fail4(message, hint) {
5854
- console.error(import_chalk39.default.red(`
5930
+ console.error(import_chalk40.default.red(`
5855
5931
  Error: ${message}`));
5856
- if (hint) console.error(import_chalk39.default.dim(hint));
5932
+ if (hint) console.error(import_chalk40.default.dim(hint));
5857
5933
  process.exit(1);
5858
5934
  }
5859
5935
  function normalizeName2(raw) {
@@ -6001,7 +6077,7 @@ async function resolveTargetAuth(spec2, opts) {
6001
6077
  "Re-run with --force to provision anyway (configure target auth later with `apiblaze config`),\nor use an api_key / bearer / basic scheme."
6002
6078
  );
6003
6079
  }
6004
- if (sawOAuth) console.log(import_chalk39.default.yellow(" --force: skipping OAuth target auth \u2014 configure it later with `apiblaze config`."));
6080
+ if (sawOAuth) console.log(import_chalk40.default.yellow(" --force: skipping OAuth target auth \u2014 configure it later with `apiblaze config`."));
6005
6081
  return null;
6006
6082
  }
6007
6083
  if (candidates.length === 1 && !noneAllowed) return candidates[0];
@@ -6074,7 +6150,7 @@ async function ensureConsumerLogin(teamId, tenant2, version2) {
6074
6150
  const fresh = await validConsumerToken(existing);
6075
6151
  if (fresh) {
6076
6152
  if (fresh.accessToken !== existing.accessToken) saveConsumer({ ...fresh, resource });
6077
- console.log(import_chalk39.default.dim(` Using your consumer session on ${import_chalk39.default.bold(tenant2)}${fresh.email ? ` (${fresh.email})` : ""}.`));
6153
+ console.log(import_chalk40.default.dim(` Using your consumer session on ${import_chalk40.default.bold(tenant2)}${fresh.email ? ` (${fresh.email})` : ""}.`));
6078
6154
  return fresh;
6079
6155
  }
6080
6156
  }
@@ -6093,13 +6169,13 @@ async function ensureConsumerLogin(teamId, tenant2, version2) {
6093
6169
  );
6094
6170
  }
6095
6171
  const clientId = pick2.client_id ?? pick2.clientId;
6096
- console.log(`${import_chalk39.default.cyan("\u2192")} This proxy signs consumers in with OAuth \u2014 logging you in to ${import_chalk39.default.bold(tenant2)}...`);
6172
+ console.log(`${import_chalk40.default.cyan("\u2192")} This proxy signs consumers in with OAuth \u2014 logging you in to ${import_chalk40.default.bold(tenant2)}...`);
6097
6173
  const result = await deviceLogin(clientId, "openid email profile offline_access", ({ verificationUri, userCode }) => {
6098
6174
  console.log(`
6099
- Open: ${import_chalk39.default.underline(verificationUri)}`);
6100
- console.log(` Code: ${import_chalk39.default.bold(userCode)}
6175
+ Open: ${import_chalk40.default.underline(verificationUri)}`);
6176
+ console.log(` Code: ${import_chalk40.default.bold(userCode)}
6101
6177
  `);
6102
- console.log(import_chalk39.default.dim(" (opening your browser\u2026 waiting for you to finish)"));
6178
+ console.log(import_chalk40.default.dim(" (opening your browser\u2026 waiting for you to finish)"));
6103
6179
  }, resource);
6104
6180
  const claims = result.idToken && decodeJwt2(result.idToken) || (decodeJwt2(result.accessToken) ?? {});
6105
6181
  const creds = {
@@ -6115,7 +6191,7 @@ async function ensureConsumerLogin(teamId, tenant2, version2) {
6115
6191
  resource
6116
6192
  };
6117
6193
  saveConsumer(creds);
6118
- console.log(` ${import_chalk39.default.green("\u2714")} Signed in as${creds.email ? ` ${import_chalk39.default.bold(creds.email)}` : " a consumer"} on ${tenant2}.`);
6194
+ console.log(` ${import_chalk40.default.green("\u2714")} Signed in as${creds.email ? ` ${import_chalk40.default.bold(creds.email)}` : " a consumer"} on ${tenant2}.`);
6119
6195
  return creds;
6120
6196
  }
6121
6197
  async function cpPost(anon, path8, body, summary) {
@@ -6144,13 +6220,18 @@ async function provision(spec2, target, opts) {
6144
6220
  let name = opts.name ? base2 : `${base2}${salt()}`;
6145
6221
  const access = anon ? "open" : opts.access === "open" ? "open" : "invite";
6146
6222
  if (anon && opts.access === "invite") {
6147
- console.log(import_chalk39.default.dim(" Note: --access invite needs an account to pre-approve people. Staying open for this anonymous proxy \u2014 run `apiblaze login`, then `apiblaze apichat --access invite`."));
6223
+ console.log(import_chalk40.default.dim(" Note: --access invite needs an account to pre-approve people. Staying open for this anonymous proxy \u2014 run `apiblaze login`, then `apiblaze apichat --access invite`."));
6148
6224
  }
6149
6225
  const DUAL_AUTH = {
6150
6226
  mode: "authenticate",
6151
6227
  methods: ["api_key", "jwt"],
6152
6228
  ...access === "invite" ? { preapproved_users_only: true } : {}
6153
6229
  };
6230
+ const chosenTenant = loggedIn ? await chooseTenantForCreate(loadCredentials()?.teamId, name, {
6231
+ tenant: opts.tenant,
6232
+ yes: opts.yes,
6233
+ json: opts.json
6234
+ }) : void 0;
6154
6235
  const spinner = (0, import_ora21.default)("Provisioning an api_key proxy...").start();
6155
6236
  let result;
6156
6237
  for (let attempt = 0; attempt < 4; attempt++) {
@@ -6163,6 +6244,7 @@ async function provision(spec2, target, opts) {
6163
6244
  auth_type: "api_key",
6164
6245
  requests_auth: DUAL_AUTH,
6165
6246
  team_id: creds.teamId,
6247
+ ...chosenTenant ? { tenant: chosenTenant } : {},
6166
6248
  ...opts.apiversion ? { api_version: opts.apiversion } : {}
6167
6249
  });
6168
6250
  } else {
@@ -6237,7 +6319,7 @@ async function provision(spec2, target, opts) {
6237
6319
  try {
6238
6320
  await addPreapprovalRule(tenant2, email);
6239
6321
  } catch {
6240
- console.log(import_chalk39.default.dim(` (Could not auto-approve your email for sign-in \u2014 add it later: apiblaze preapprove ${email})`));
6322
+ console.log(import_chalk40.default.dim(` (Could not auto-approve your email for sign-in \u2014 add it later: apiblaze preapprove ${email})`));
6241
6323
  }
6242
6324
  }
6243
6325
  }
@@ -6281,7 +6363,7 @@ async function uploadSpec(p, specText, opts) {
6281
6363
  throw err;
6282
6364
  }
6283
6365
  if (out && out.reused === true) {
6284
- console.log(import_chalk39.default.dim(" Spec unchanged since the last provision \u2014 reusing the existing configuration."));
6366
+ console.log(import_chalk40.default.dim(" Spec unchanged since the last provision \u2014 reusing the existing configuration."));
6285
6367
  } else if (out && out.changed === true && out.previous_spec_hash) {
6286
6368
  const interactive = !!process.stdin.isTTY && !opts.yes;
6287
6369
  if (interactive) {
@@ -6289,7 +6371,7 @@ async function uploadSpec(p, specText, opts) {
6289
6371
  const { go } = await inquirer3.prompt([
6290
6372
  { type: "confirm", name: "go", message: "The spec changed since the last provision \u2014 re-publish the MCP catalogue?", default: true }
6291
6373
  ]);
6292
- if (!go) console.log(import_chalk39.default.dim(" Keeping the existing MCP catalogue."));
6374
+ if (!go) console.log(import_chalk40.default.dim(" Keeping the existing MCP catalogue."));
6293
6375
  }
6294
6376
  }
6295
6377
  }
@@ -6330,22 +6412,23 @@ var revealAuth = false;
6330
6412
  function renderToolEvents(events, cred) {
6331
6413
  for (const e of events ?? []) {
6332
6414
  const ok = typeof e.status === "number" ? e.status < 400 : String(e.status).toLowerCase() === "ok";
6333
- const mark = ok ? import_chalk39.default.green("\u2713") : import_chalk39.default.red("\u2717");
6334
- console.log(` ${mark} ${import_chalk39.default.cyan(e.name)} ${import_chalk39.default.dim(`(${e.status}, ${e.ms}ms)`)}`);
6415
+ const mark = ok ? import_chalk40.default.green("\u2713") : import_chalk40.default.red("\u2717");
6416
+ console.log(` ${mark} ${import_chalk40.default.cyan(e.name)} ${import_chalk40.default.dim(`(${e.status}, ${e.ms}ms)`)}`);
6335
6417
  if (isVerbose() && e.method && e.url) {
6336
- console.log(import_chalk39.default.dim(` curl -sS -X ${e.method} '${e.url}'${cred ? " \\" : ""}`));
6418
+ console.log(import_chalk40.default.dim(` curl -sS -X ${e.method} '${e.url}'${cred ? " \\" : ""}`));
6337
6419
  if (cred) {
6338
6420
  const shown = revealAuth ? cred.value : maskKey(cred.value);
6339
6421
  const keyLine = ` -H '${cred.header}: ${shown}'`;
6340
- const hint = revealAuth ? "" : import_chalk39.default.yellow(" \u2190 /showauth will reveal this");
6341
- console.log(import_chalk39.default.dim(keyLine) + hint);
6422
+ const hint = revealAuth ? "" : import_chalk40.default.yellow(" \u2190 /showauth will reveal this");
6423
+ console.log(import_chalk40.default.dim(keyLine) + hint);
6342
6424
  }
6343
6425
  }
6344
6426
  }
6345
6427
  }
6346
- function renderFailedToolResults(delta, events) {
6347
- const failed = new Set((events ?? []).filter((e) => e.status === "error").map((e) => e.name));
6348
- if (failed.size === 0) return;
6428
+ function renderToolResults(delta, events) {
6429
+ const anyFailed = (events ?? []).some((e) => e.status === "error");
6430
+ if (!anyFailed && !isVerbose()) return;
6431
+ const cap = anyFailed ? 24 : 12;
6349
6432
  for (const m of delta ?? []) {
6350
6433
  if (!m || m.role !== "tool" || typeof m.content !== "string") continue;
6351
6434
  const body = m.content.trim();
@@ -6357,19 +6440,21 @@ function renderFailedToolResults(delta, events) {
6357
6440
  return body;
6358
6441
  }
6359
6442
  })();
6360
- console.log(import_chalk39.default.dim(" response:"));
6361
- for (const line of pretty.split("\n").slice(0, 24)) {
6362
- console.log(import_chalk39.default.dim(` ${line}`));
6443
+ const lines = pretty.split("\n");
6444
+ console.log(import_chalk40.default.dim(" response:"));
6445
+ for (const line of lines.slice(0, cap)) {
6446
+ console.log(import_chalk40.default.dim(` ${line}`));
6363
6447
  }
6448
+ if (lines.length > cap) console.log(import_chalk40.default.dim(` \u2026${lines.length - cap} more lines`));
6364
6449
  }
6365
6450
  }
6366
6451
  function billingLine(billing) {
6367
6452
  if (!billing || typeof billing.cents !== "number") return null;
6368
6453
  if (typeof billing.free_turns_remaining === "number") return null;
6369
6454
  const usd = (billing.cents / 100).toFixed(Math.abs(billing.cents - Math.round(billing.cents)) < 1e-9 ? 2 : 4);
6370
- let line = import_chalk39.default.magenta(` \u{1F4B3} $${usd}`) + import_chalk39.default.dim(billing.model ? ` \xB7 ${billing.model}` : "");
6455
+ let line = import_chalk40.default.magenta(` \u{1F4B3} $${usd}`) + import_chalk40.default.dim(billing.model ? ` \xB7 ${billing.model}` : "");
6371
6456
  if (typeof billing.credits_remaining === "number") {
6372
- line += import_chalk39.default.dim(` \xB7 balance $${(billing.credits_remaining / 100).toFixed(2)}`);
6457
+ line += import_chalk40.default.dim(` \xB7 balance $${(billing.credits_remaining / 100).toFixed(2)}`);
6373
6458
  }
6374
6459
  return line;
6375
6460
  }
@@ -6377,21 +6462,21 @@ function freeBudgetWarning(billing, anon) {
6377
6462
  if (!anon || !billing) return null;
6378
6463
  if (typeof billing.free_turns_remaining === "number") {
6379
6464
  const left2 = billing.free_turns_remaining;
6380
- if (left2 <= 0) return import_chalk39.default.yellow(" Free chats used up \u2014 `npx apiblaze login` (free) to keep going.");
6381
- return import_chalk39.default.dim(` ${left2} free chat${left2 === 1 ? "" : "s"} left \xB7 /login to get more`);
6465
+ if (left2 <= 0) return import_chalk40.default.yellow(" Free chats used up \u2014 `npx apiblaze login` (free) to keep going.");
6466
+ return import_chalk40.default.dim(` ${left2} free chat${left2 === 1 ? "" : "s"} left \xB7 /login to get more`);
6382
6467
  }
6383
6468
  if (typeof billing.free_remaining_cents !== "number") return null;
6384
6469
  const perTurn = Math.max(billing.cents || 0, 0.02);
6385
6470
  const left = Math.floor(billing.free_remaining_cents / perTurn);
6386
6471
  if (left > 8) return null;
6387
- if (left <= 0) return import_chalk39.default.yellow(" Free messages used up \u2014 `npx apiblaze login` (free) to keep chatting.");
6388
- return import_chalk39.default.yellow(` \u26A0 About ${left} free message${left === 1 ? "" : "s"} left \u2014 \`npx apiblaze login\` (free) for more.`);
6472
+ if (left <= 0) return import_chalk40.default.yellow(" Free messages used up \u2014 `npx apiblaze login` (free) to keep chatting.");
6473
+ return import_chalk40.default.yellow(` \u26A0 About ${left} free message${left === 1 ? "" : "s"} left \u2014 \`npx apiblaze login\` (free) for more.`);
6389
6474
  }
6390
6475
  function printAssistant(delta) {
6391
6476
  for (let i = delta.length - 1; i >= 0; i--) {
6392
6477
  const m = delta[i];
6393
6478
  if (m && m.role === "assistant" && typeof m.content === "string" && m.content.trim()) {
6394
- console.log("\n" + import_chalk39.default.green("assistant \u203A ") + m.content + "\n");
6479
+ console.log("\n" + import_chalk40.default.green("assistant \u203A ") + m.content + "\n");
6395
6480
  return;
6396
6481
  }
6397
6482
  }
@@ -6417,7 +6502,7 @@ async function replTurn(p, messages, userText) {
6417
6502
  });
6418
6503
  } catch (err) {
6419
6504
  spinner.fail("Network error.");
6420
- console.log(import_chalk39.default.red(` Could not reach ${p.mcpHost}: ${err instanceof Error ? err.message : String(err)}`));
6505
+ console.log(import_chalk40.default.red(` Could not reach ${p.mcpHost}: ${err instanceof Error ? err.message : String(err)}`));
6421
6506
  return;
6422
6507
  }
6423
6508
  let data = null;
@@ -6437,9 +6522,9 @@ async function replTurn(p, messages, userText) {
6437
6522
  if (res.status === 401) {
6438
6523
  const reason = data && (data.error || data.message) || null;
6439
6524
  const usingKey = !p.consumerAuth;
6440
- console.log(import_chalk39.default.red(` The proxy rejected the request (401)${reason ? `: ${reason}` : "."}`));
6525
+ console.log(import_chalk40.default.red(` The proxy rejected the request (401)${reason ? `: ${reason}` : "."}`));
6441
6526
  console.log(
6442
- import_chalk39.default.dim(
6527
+ import_chalk40.default.dim(
6443
6528
  usingKey ? " Sent an API key. If the key was revoked, re-run `apiblaze apichat` to re-provision." : " Sent your consumer OAuth token. Re-run `apiblaze apichat` to sign in again."
6444
6529
  )
6445
6530
  );
@@ -6447,7 +6532,7 @@ async function replTurn(p, messages, userText) {
6447
6532
  }
6448
6533
  if (!res.ok || !data) {
6449
6534
  const err = data && data.error || `HTTP ${res.status}`;
6450
- console.log(import_chalk39.default.red(` Chat error: ${err}`));
6535
+ console.log(import_chalk40.default.red(` Chat error: ${err}`));
6451
6536
  return;
6452
6537
  }
6453
6538
  if (Array.isArray(data.delta)) {
@@ -6458,7 +6543,7 @@ async function replTurn(p, messages, userText) {
6458
6543
  return t ? { header: "Authorization", value: `Bearer ${t}` } : void 0;
6459
6544
  })() : p.dpKey ? { header: "X-API-Key", value: p.dpKey } : void 0
6460
6545
  );
6461
- renderFailedToolResults(data.delta, data.tool_events);
6546
+ renderToolResults(data.delta, data.tool_events);
6462
6547
  for (const m of data.delta) messages.push(m);
6463
6548
  printAssistant(data.delta);
6464
6549
  }
@@ -6468,25 +6553,25 @@ async function replTurn(p, messages, userText) {
6468
6553
  if (warn) console.log(warn);
6469
6554
  if (!data.continue) return;
6470
6555
  }
6471
- console.log(import_chalk39.default.dim(" (stopped after several tool rounds \u2014 ask again to continue)"));
6556
+ console.log(import_chalk40.default.dim(" (stopped after several tool rounds \u2014 ask again to continue)"));
6472
6557
  }
6473
6558
  function renderUpsell(p, upsell) {
6474
6559
  const loggedIn = !!loadCredentials();
6475
6560
  if (upsell.reason === "CAPPED" && !loggedIn) {
6476
- console.log("\n" + import_chalk39.default.yellow(" Type `npx apiblaze login` to claim the rest of your balance."));
6477
- console.log(import_chalk39.default.dim(" (or `/login` right here \u2014 your chat is preserved \u2014 or `apiblaze llm set-key` for your own model key.)"));
6561
+ console.log("\n" + import_chalk40.default.yellow(" Type `npx apiblaze login` to claim the rest of your balance."));
6562
+ console.log(import_chalk40.default.dim(" (or `/login` right here \u2014 your chat is preserved \u2014 or `apiblaze llm set-key` for your own model key.)"));
6478
6563
  console.log();
6479
6564
  return;
6480
6565
  }
6481
- console.log("\n" + import_chalk39.default.yellow(` ${upsell.message || "This turn is not available right now."}`));
6566
+ console.log("\n" + import_chalk40.default.yellow(` ${upsell.message || "This turn is not available right now."}`));
6482
6567
  if (upsell.reason === "INSUFFICIENT" || upsell.reason === "BREAKER" || upsell.reason === "CAPPED" || upsell.reason === "PAUSED") {
6483
6568
  if (!loggedIn) {
6484
- console.log(import_chalk39.default.dim(" Options: `/login` for more free chats and requests, or `apiblaze llm set-key` to bring your own model key."));
6569
+ console.log(import_chalk40.default.dim(" Options: `/login` for more free chats and requests, or `apiblaze llm set-key` to bring your own model key."));
6485
6570
  } else {
6486
- console.log(import_chalk39.default.dim(" Options: top up your wallet, or `apiblaze llm set-key` to bring your own model key (bypasses platform limits)."));
6571
+ console.log(import_chalk40.default.dim(" Options: top up your wallet, or `apiblaze llm set-key` to bring your own model key (bypasses platform limits)."));
6487
6572
  }
6488
6573
  } else if (upsell.reason === "INFLIGHT") {
6489
- console.log(import_chalk39.default.dim(" Another turn is still in flight \u2014 wait a moment and try again."));
6574
+ console.log(import_chalk40.default.dim(" Another turn is still in flight \u2014 wait a moment and try again."));
6490
6575
  }
6491
6576
  console.log();
6492
6577
  }
@@ -6579,9 +6664,9 @@ async function openServerProxy(project) {
6579
6664
  let consumerAuth = false;
6580
6665
  if (acceptsApiKey) {
6581
6666
  if (!dpKey) {
6582
- console.log(import_chalk39.default.dim(` Minting an API key for tenant ${import_chalk39.default.bold(tenant2)} to query project ${import_chalk39.default.bold(project.projectName)}\u2026`));
6667
+ console.log(import_chalk40.default.dim(` Minting an API key for tenant ${import_chalk40.default.bold(tenant2)} to query project ${import_chalk40.default.bold(project.projectName)}\u2026`));
6583
6668
  dpKey = await mintDurableProxyKey(project.teamId, tenant2);
6584
- console.log(` ${import_chalk39.default.green("\u2714")} API key: ${import_chalk39.default.dim(maskKey(dpKey))}`);
6669
+ console.log(` ${import_chalk40.default.green("\u2714")} API key: ${import_chalk40.default.dim(maskKey(dpKey))}`);
6585
6670
  }
6586
6671
  } else {
6587
6672
  consumerAuth = true;
@@ -6610,9 +6695,9 @@ async function openServerProxy(project) {
6610
6695
  const spec2 = raw && (raw.spec ?? raw);
6611
6696
  spinner.stop();
6612
6697
  if (!spec2 || !(spec2.paths || spec2.openapi)) {
6613
- console.log(import_chalk39.default.yellow(" This proxy has no OpenAPI spec yet \u2014 chat will have no tools. Build one with `apiblaze agent openapi`."));
6698
+ console.log(import_chalk40.default.yellow(" This proxy has no OpenAPI spec yet \u2014 chat will have no tools. Build one with `apiblaze agent openapi`."));
6614
6699
  } else {
6615
- console.log(import_chalk39.default.dim(" Using the proxy's existing MCP catalogue (`apiblaze mcp` to rebuild it)."));
6700
+ console.log(import_chalk40.default.dim(" Using the proxy's existing MCP catalogue (`apiblaze mcp` to rebuild it)."));
6616
6701
  }
6617
6702
  } catch (err) {
6618
6703
  spinner.fail("Could not open the proxy.");
@@ -6668,7 +6753,7 @@ async function noArgsMenu(opts) {
6668
6753
  const me = loadCredentials()?.apiblazeUserId;
6669
6754
  const saved = loadApichats().filter((a) => a.anon ? true : a.ownerUserId !== void 0 && a.ownerUserId === me);
6670
6755
  const choices = saved.map((a) => ({
6671
- name: `Chat with ${import_chalk39.default.bold(a.name)} ${import_chalk39.default.dim(`(${a.target})${a.messages && a.messages.length ? ` \xB7 ${a.messages.length} msgs` : ""}`)}`,
6756
+ name: `Chat with ${import_chalk40.default.bold(a.name)} ${import_chalk40.default.dim(`(${a.target})${a.messages && a.messages.length ? ` \xB7 ${a.messages.length} msgs` : ""}`)}`,
6672
6757
  value: { type: "existing", a }
6673
6758
  }));
6674
6759
  const creds = loadCredentials();
@@ -6678,14 +6763,14 @@ async function noArgsMenu(opts) {
6678
6763
  const proxies = (await getProjects(creds.teamId)).filter((pr) => !savedIds.has(pr.projectId));
6679
6764
  for (const pr of proxies) {
6680
6765
  choices.push({
6681
- name: `Chat with ${import_chalk39.default.bold(pr.projectName)} ${import_chalk39.default.dim(`(v${pr.apiVersion}) \xB7 your proxy`)}`,
6766
+ name: `Chat with ${import_chalk40.default.bold(pr.projectName)} ${import_chalk40.default.dim(`(v${pr.apiVersion}) \xB7 your proxy`)}`,
6682
6767
  value: { type: "server", project: pr }
6683
6768
  });
6684
6769
  }
6685
6770
  } catch {
6686
6771
  }
6687
6772
  }
6688
- choices.push({ name: import_chalk39.default.green("\uFF0B Create a new apichat"), value: { type: "new" } });
6773
+ choices.push({ name: import_chalk40.default.green("\uFF0B Create a new apichat"), value: { type: "new" } });
6689
6774
  const { pick: pick2 } = await inquirer3.prompt([
6690
6775
  { type: "list", name: "pick", message: "What would you like to do?", choices }
6691
6776
  ]);
@@ -6788,36 +6873,36 @@ async function noArgsMenu(opts) {
6788
6873
  async function runRepl(p, initialMessages) {
6789
6874
  const { default: inquirer3 } = await import("inquirer");
6790
6875
  const messages = initialMessages && initialMessages.length ? initialMessages.slice() : [];
6791
- console.log("\n" + import_chalk39.default.cyan.bold("Chat with your API") + import_chalk39.default.dim(` \xB7 ${p.mcpHost}`));
6792
- if (messages.length) console.log(import_chalk39.default.dim(` Resumed \u2014 ${messages.length} prior messages.`));
6876
+ console.log("\n" + import_chalk40.default.cyan.bold("Chat with your API") + import_chalk40.default.dim(` \xB7 ${p.mcpHost}`));
6877
+ if (messages.length) console.log(import_chalk40.default.dim(` Resumed \u2014 ${messages.length} prior messages.`));
6793
6878
  const llm2 = loadLlmConfig();
6794
6879
  console.log(
6795
- import_chalk39.default.dim(
6880
+ import_chalk40.default.dim(
6796
6881
  llm2 ? `Using your local ${llm2.provider} key for the model. Type a question, or /exit. /login /claim manage your workspace.` : "Ask a question in plain English. /exit to quit \xB7 /login for more free chats \xB7 /claim to keep this workspace \xB7 `apiblaze llm set-key` for BYO models."
6797
6882
  )
6798
6883
  );
6799
6884
  for (; ; ) {
6800
- const { input } = await inquirer3.prompt([{ type: "input", name: "input", message: import_chalk39.default.green("you \u203A") }]);
6885
+ const { input } = await inquirer3.prompt([{ type: "input", name: "input", message: import_chalk40.default.green("you \u203A") }]);
6801
6886
  const text = (input ?? "").trim();
6802
6887
  if (!text) continue;
6803
6888
  if (["/exit", "/quit", "exit", "quit", ":q"].includes(text.toLowerCase())) break;
6804
6889
  if (text === "/login") {
6805
6890
  try {
6806
6891
  await runLogin();
6807
- console.log(import_chalk39.default.dim(" Logged in \u2014 history preserved. Keep chatting."));
6892
+ console.log(import_chalk40.default.dim(" Logged in \u2014 history preserved. Keep chatting."));
6808
6893
  } catch (err) {
6809
- console.log(import_chalk39.default.red(` Login failed: ${err instanceof Error ? err.message : String(err)}`));
6894
+ console.log(import_chalk40.default.red(` Login failed: ${err instanceof Error ? err.message : String(err)}`));
6810
6895
  }
6811
6896
  continue;
6812
6897
  }
6813
6898
  if (text === "/claim") {
6814
6899
  const justLoggedIn = !loadCredentials();
6815
6900
  if (justLoggedIn) {
6816
- console.log(import_chalk39.default.dim(" Logging in to claim your workspace\u2026"));
6901
+ console.log(import_chalk40.default.dim(" Logging in to claim your workspace\u2026"));
6817
6902
  try {
6818
6903
  await runLogin();
6819
6904
  } catch (err) {
6820
- console.log(import_chalk39.default.red(` Login failed: ${err instanceof Error ? err.message : String(err)}`));
6905
+ console.log(import_chalk40.default.red(` Login failed: ${err instanceof Error ? err.message : String(err)}`));
6821
6906
  continue;
6822
6907
  }
6823
6908
  if (!loadCredentials()) continue;
@@ -6828,30 +6913,30 @@ async function runRepl(p, initialMessages) {
6828
6913
  p.mcpHost = p.mcpHost.replace(".mcp.tryabz.run", ".mcp.abz.run");
6829
6914
  p.anon = false;
6830
6915
  claimApichat(p, loadCredentials()?.apiblazeUserId);
6831
- console.log(import_chalk39.default.dim(` Workspace claimed \u2014 chat now routes on ${p.mcpHost}. History preserved.`));
6916
+ console.log(import_chalk40.default.dim(` Workspace claimed \u2014 chat now routes on ${p.mcpHost}. History preserved.`));
6832
6917
  }
6833
6918
  } catch (err) {
6834
- console.log(import_chalk39.default.red(` Claim failed: ${err instanceof Error ? err.message : String(err)}`));
6919
+ console.log(import_chalk40.default.red(` Claim failed: ${err instanceof Error ? err.message : String(err)}`));
6835
6920
  }
6836
6921
  continue;
6837
6922
  }
6838
6923
  if (text === "/showauth") {
6839
6924
  revealAuth = !revealAuth;
6840
- console.log(import_chalk39.default.dim(revealAuth ? " The real API key will be shown in the next call's curl. /showauth again to re-mask." : " API key re-masked."));
6925
+ console.log(import_chalk40.default.dim(revealAuth ? " The real API key will be shown in the next call's curl. /showauth again to re-mask." : " API key re-masked."));
6841
6926
  continue;
6842
6927
  }
6843
6928
  if (text.startsWith("/")) {
6844
- console.log(import_chalk39.default.dim(" Commands: /login /claim /showauth /exit"));
6929
+ console.log(import_chalk40.default.dim(" Commands: /login /claim /showauth /exit"));
6845
6930
  continue;
6846
6931
  }
6847
6932
  await replTurn(p, messages, text);
6848
6933
  saveTranscript(p, messages);
6849
6934
  }
6850
- console.log(import_chalk39.default.dim("\nBye."));
6935
+ console.log(import_chalk40.default.dim("\nBye."));
6851
6936
  }
6852
6937
  async function runApichat(opts) {
6853
6938
  setVerbose(opts.verbose !== false);
6854
- console.log(import_chalk39.default.bold("\napichat \u2014 turn any API into a chat\n"));
6939
+ console.log(import_chalk40.default.bold("\napichat \u2014 turn any API into a chat\n"));
6855
6940
  if (!opts.openapispec && !opts.target) {
6856
6941
  if (!process.stdin.isTTY) {
6857
6942
  fail4("No spec source. Pass --openapispec <file|url> or --target <url>.", GENERATOR_HINT);
@@ -6864,7 +6949,7 @@ async function runApichat(opts) {
6864
6949
  }
6865
6950
  const { spec: spec2, sourceUrl } = await loadSpec(opts);
6866
6951
  const target = resolveTarget(spec2, opts, sourceUrl);
6867
- console.log(` ${import_chalk39.default.dim("Target:")} ${import_chalk39.default.bold(target)}`);
6952
+ console.log(` ${import_chalk40.default.dim("Target:")} ${import_chalk40.default.bold(target)}`);
6868
6953
  const auth = await resolveTargetAuth(spec2, opts);
6869
6954
  if (auth && !process.stdin.isTTY && !opts.targetAuthEnv) {
6870
6955
  fail4(
@@ -6873,7 +6958,7 @@ async function runApichat(opts) {
6873
6958
  );
6874
6959
  }
6875
6960
  const p = await provision(spec2, target, opts);
6876
- console.log(` ${import_chalk39.default.dim("Proxy: ")} ${import_chalk39.default.bold(p.proxyUrl || `${p.projectId} v${p.version}`)}`);
6961
+ console.log(` ${import_chalk40.default.dim("Proxy: ")} ${import_chalk40.default.bold(p.proxyUrl || `${p.projectId} v${p.version}`)}`);
6877
6962
  upsertApichat({
6878
6963
  name: p.projectId,
6879
6964
  target,
@@ -6893,30 +6978,30 @@ async function runApichat(opts) {
6893
6978
  const secret = await captureTargetSecret(auth, opts);
6894
6979
  if (secret) await writeTargetAuth(p, auth, secret);
6895
6980
  } else {
6896
- console.log(import_chalk39.default.dim(" Target auth: none required."));
6981
+ console.log(import_chalk40.default.dim(" Target auth: none required."));
6897
6982
  }
6898
6983
  const specText = JSON.stringify(spec2);
6899
6984
  await uploadSpec(p, specText, opts);
6900
6985
  const mcpUrl = await publishMcp(p, spec2);
6901
6986
  console.log();
6902
- if (p.proxyUrl) console.log(` ${import_chalk39.default.green("\u2713")} proxy ${import_chalk39.default.bold(p.proxyUrl)}`);
6987
+ if (p.proxyUrl) console.log(` ${import_chalk40.default.green("\u2713")} proxy ${import_chalk40.default.bold(p.proxyUrl)}`);
6903
6988
  if (mcpUrl) {
6904
- console.log(` ${import_chalk39.default.green("\u2713")} mcp ${import_chalk39.default.bold(mcpUrl)}`);
6989
+ console.log(` ${import_chalk40.default.green("\u2713")} mcp ${import_chalk40.default.bold(mcpUrl)}`);
6905
6990
  if (p.access === "invite") {
6906
- console.log(import_chalk39.default.dim(" Claude/ChatGPT-connectable (GitHub sign-in) \xB7 access: invite \u2014 only you + emails you pre-approve"));
6907
- console.log(import_chalk39.default.dim(` Let others in: apiblaze preapprove someone@company.com${p.tenant ? ` --tenant ${p.tenant}` : ""} (or re-run with --access open)`));
6991
+ console.log(import_chalk40.default.dim(" Claude/ChatGPT-connectable (GitHub sign-in) \xB7 access: invite \u2014 only you + emails you pre-approve"));
6992
+ console.log(import_chalk40.default.dim(` Let others in: apiblaze preapprove someone@company.com${p.tenant ? ` --tenant ${p.tenant}` : ""} (or re-run with --access open)`));
6908
6993
  } else {
6909
- console.log(import_chalk39.default.dim(" Claude/ChatGPT-connectable (GitHub sign-in) \xB7 access: open \u2014 anyone who signs in can call this API"));
6994
+ console.log(import_chalk40.default.dim(" Claude/ChatGPT-connectable (GitHub sign-in) \xB7 access: open \u2014 anyone who signs in can call this API"));
6910
6995
  }
6911
6996
  }
6912
6997
  if (p.anon) {
6913
- console.log(import_chalk39.default.dim("\n Anonymous workspace \u2014 /claim inside the chat to log in and keep it beyond 30 days."));
6998
+ console.log(import_chalk40.default.dim("\n Anonymous workspace \u2014 /claim inside the chat to log in and keep it beyond 30 days."));
6914
6999
  }
6915
7000
  await runRepl(p);
6916
7001
  }
6917
7002
 
6918
7003
  // src/commands/consumer.ts
6919
- var import_chalk40 = __toESM(require("chalk"));
7004
+ var import_chalk41 = __toESM(require("chalk"));
6920
7005
  var import_ora22 = __toESM(require("ora"));
6921
7006
  init_admin();
6922
7007
  init_resolve();
@@ -6938,7 +7023,7 @@ async function consumerFetch(creds, suffix, init) {
6938
7023
  function requireConsumer() {
6939
7024
  const c = loadConsumer();
6940
7025
  if (!c) {
6941
- console.error(import_chalk40.default.red("Not logged in as a consumer. Run `apiblaze consumer login` first."));
7026
+ console.error(import_chalk41.default.red("Not logged in as a consumer. Run `apiblaze consumer login` first."));
6942
7027
  process.exit(1);
6943
7028
  }
6944
7029
  return c;
@@ -6949,7 +7034,7 @@ async function runConsumerLogin(opts) {
6949
7034
  let clientId = opts.client;
6950
7035
  if (clientId) {
6951
7036
  if (!tenant2) {
6952
- console.error(import_chalk40.default.red("When using --client, also pass --tenant <slug> (it sets which portal/keys host to use)."));
7037
+ console.error(import_chalk41.default.red("When using --client, also pass --tenant <slug> (it sets which portal/keys host to use)."));
6953
7038
  process.exit(1);
6954
7039
  }
6955
7040
  } else {
@@ -6967,19 +7052,19 @@ async function runConsumerLogin(opts) {
6967
7052
  const usable = (Array.isArray(clients) ? clients : []).filter((c) => c && (c.client_id || c.clientId));
6968
7053
  const pick2 = usable.find((c) => c.is_default || c.default) ?? usable.find((c) => c.verified !== false) ?? usable[0];
6969
7054
  if (!pick2) {
6970
- console.error(import_chalk40.default.red(`Tenant "${tenant2}" has no login app configured. Set one up in the dashboard (or \`apiblaze create\` with auth).`));
7055
+ console.error(import_chalk41.default.red(`Tenant "${tenant2}" has no login app configured. Set one up in the dashboard (or \`apiblaze create\` with auth).`));
6971
7056
  process.exit(1);
6972
7057
  }
6973
7058
  clientId = pick2.client_id ?? pick2.clientId;
6974
7059
  }
6975
7060
  const portalResource = `https://${tenant2}.portal.apiblaze.com/1.0.0`;
6976
- console.log(`${import_chalk40.default.cyan("\u2192")} Logging in to ${import_chalk40.default.bold(tenant2)} as a consumer...`);
7061
+ console.log(`${import_chalk41.default.cyan("\u2192")} Logging in to ${import_chalk41.default.bold(tenant2)} as a consumer...`);
6977
7062
  const result = await deviceLogin(clientId, DEFAULT_SCOPE, ({ verificationUri, userCode }) => {
6978
7063
  console.log(`
6979
- Open: ${import_chalk40.default.underline(verificationUri)}`);
6980
- console.log(` Code: ${import_chalk40.default.bold(userCode)}
7064
+ Open: ${import_chalk41.default.underline(verificationUri)}`);
7065
+ console.log(` Code: ${import_chalk41.default.bold(userCode)}
6981
7066
  `);
6982
- console.log(import_chalk40.default.dim(" (opening your browser\u2026 waiting for you to finish)"));
7067
+ console.log(import_chalk41.default.dim(" (opening your browser\u2026 waiting for you to finish)"));
6983
7068
  }, portalResource);
6984
7069
  const claims = result.idToken && decodeJwt2(result.idToken) || (decodeJwt2(result.accessToken) ?? {});
6985
7070
  const creds = {
@@ -6994,7 +7079,7 @@ async function runConsumerLogin(opts) {
6994
7079
  obtainedAt: Date.now()
6995
7080
  };
6996
7081
  saveConsumer(creds);
6997
- console.log(import_chalk40.default.green(`\u2714 Logged in as consumer${creds.email ? ` ${creds.email}` : ""} on ${tenant2}.`));
7082
+ console.log(import_chalk41.default.green(`\u2714 Logged in as consumer${creds.email ? ` ${creds.email}` : ""} on ${tenant2}.`));
6998
7083
  }
6999
7084
  async function runConsumerTokens(opts) {
7000
7085
  const creds = requireConsumer();
@@ -7007,18 +7092,18 @@ async function runConsumerTokens(opts) {
7007
7092
  console.log(JSON.stringify({ tenant: fresh.tenant, access_token: fresh.accessToken, refresh_token: fresh.refreshToken, id_token: fresh.idToken, expires_at: new Date(fresh.expiresAt).toISOString() }, null, 2));
7008
7093
  return;
7009
7094
  }
7010
- console.log(`${import_chalk40.default.cyan("Consumer")} ${import_chalk40.default.bold(fresh.email ?? fresh.tenant)} on ${import_chalk40.default.bold(fresh.tenant)}
7095
+ console.log(`${import_chalk41.default.cyan("Consumer")} ${import_chalk41.default.bold(fresh.email ?? fresh.tenant)} on ${import_chalk41.default.bold(fresh.tenant)}
7011
7096
  `);
7012
- console.log(`${import_chalk40.default.bold("access_token")} ${import_chalk40.default.dim("exp " + (exp(fresh.accessToken) ?? "?"))}
7097
+ console.log(`${import_chalk41.default.bold("access_token")} ${import_chalk41.default.dim("exp " + (exp(fresh.accessToken) ?? "?"))}
7013
7098
  ${fresh.accessToken}
7014
7099
  `);
7015
- if (fresh.idToken) console.log(`${import_chalk40.default.bold("id_token")} ${import_chalk40.default.dim("exp " + (exp(fresh.idToken) ?? "?"))}
7100
+ if (fresh.idToken) console.log(`${import_chalk41.default.bold("id_token")} ${import_chalk41.default.dim("exp " + (exp(fresh.idToken) ?? "?"))}
7016
7101
  ${fresh.idToken}
7017
7102
  `);
7018
- if (fresh.refreshToken) console.log(`${import_chalk40.default.bold("refresh_token")}
7103
+ if (fresh.refreshToken) console.log(`${import_chalk41.default.bold("refresh_token")}
7019
7104
  ${fresh.refreshToken}
7020
7105
  `);
7021
- console.log(import_chalk40.default.dim("These are your own tokens \u2014 keep them secret."));
7106
+ console.log(import_chalk41.default.dim("These are your own tokens \u2014 keep them secret."));
7022
7107
  }
7023
7108
  async function runConsumerApikeys(opts) {
7024
7109
  const creds = requireConsumer();
@@ -7028,8 +7113,8 @@ async function runConsumerApikeys(opts) {
7028
7113
  const revealed = await consumerFetch(list.creds, "/apikeys/reveal").catch(() => ({ status: 0, data: null, creds: list.creds }));
7029
7114
  spinner.stop();
7030
7115
  if (list.status >= 400) {
7031
- console.error(import_chalk40.default.red(`Failed to list keys (${list.status}): ${list.data?.error ?? ""}`));
7032
- if (list.status === 401) console.error(import_chalk40.default.dim("Your consumer session may have expired \u2014 run `apiblaze consumer login` again."));
7116
+ console.error(import_chalk41.default.red(`Failed to list keys (${list.status}): ${list.data?.error ?? ""}`));
7117
+ if (list.status === 401) console.error(import_chalk41.default.dim("Your consumer session may have expired \u2014 run `apiblaze consumer login` again."));
7033
7118
  process.exit(1);
7034
7119
  }
7035
7120
  const keys = list.data?.keys ?? [];
@@ -7037,16 +7122,16 @@ async function runConsumerApikeys(opts) {
7037
7122
  if (opts.json) {
7038
7123
  console.log(JSON.stringify({ keys, revealed: revealMap }, null, 2));
7039
7124
  } else if (!keys.length) {
7040
- console.log(import_chalk40.default.yellow("No API keys yet."));
7125
+ console.log(import_chalk41.default.yellow("No API keys yet."));
7041
7126
  } else {
7042
7127
  for (const k of keys) {
7043
7128
  const clear = revealMap[k.environment]?.key;
7044
- const shown = clear ? import_chalk40.default.green(clear) : import_chalk40.default.dim(`${k.key_prefix ?? ""}\u2026${k.key_suffix ?? ""}`);
7045
- const exp = k.expires_at ? import_chalk40.default.dim(`exp ${k.expires_at}`) : import_chalk40.default.dim("no expiry");
7046
- console.log(` ${import_chalk40.default.bold(k.environment ?? "")} ${shown} ${exp} ${import_chalk40.default.dim(k.description ?? "")}`);
7129
+ const shown = clear ? import_chalk41.default.green(clear) : import_chalk41.default.dim(`${k.key_prefix ?? ""}\u2026${k.key_suffix ?? ""}`);
7130
+ const exp = k.expires_at ? import_chalk41.default.dim(`exp ${k.expires_at}`) : import_chalk41.default.dim("no expiry");
7131
+ console.log(` ${import_chalk41.default.bold(k.environment ?? "")} ${shown} ${exp} ${import_chalk41.default.dim(k.description ?? "")}`);
7047
7132
  }
7048
7133
  if (Object.keys(revealMap).length === 0 && keys.some((k) => !k.expires_at)) {
7049
- console.log(import_chalk40.default.dim("\n(Only expiring keys can be shown in clear; non-expiring keys show a prefix only.)"));
7134
+ console.log(import_chalk41.default.dim("\n(Only expiring keys can be shown in clear; non-expiring keys show a prefix only.)"));
7050
7135
  }
7051
7136
  }
7052
7137
  if (opts.json) return;
@@ -7068,12 +7153,12 @@ async function runConsumerApikeys(opts) {
7068
7153
  }
7069
7154
  s2.succeed("Key created.");
7070
7155
  const key = created.data?.key ?? created.data?.fullKey;
7071
- if (key) console.log(` ${import_chalk40.default.green(key)} ${import_chalk40.default.dim("(shown once \u2014 store it now)")}`);
7072
- else console.log(import_chalk40.default.dim(" Key created; run `apiblaze consumer apikeys` to reveal it if it expires."));
7156
+ if (key) console.log(` ${import_chalk41.default.green(key)} ${import_chalk41.default.dim("(shown once \u2014 store it now)")}`);
7157
+ else console.log(import_chalk41.default.dim(" Key created; run `apiblaze consumer apikeys` to reveal it if it expires."));
7073
7158
  }
7074
7159
 
7075
7160
  // src/commands/sidecar.ts
7076
- var import_chalk41 = __toESM(require("chalk"));
7161
+ var import_chalk42 = __toESM(require("chalk"));
7077
7162
  var import_ora23 = __toESM(require("ora"));
7078
7163
  var fs10 = __toESM(require("fs"));
7079
7164
  var path7 = __toESM(require("path"));
@@ -7116,7 +7201,7 @@ function upsertEnvLocal(root, token) {
7116
7201
  }
7117
7202
  function installSidecarPackage(root) {
7118
7203
  if (fs10.existsSync(path7.join(root, "node_modules", "apiblaze", "package.json"))) {
7119
- console.log(` ${import_chalk41.default.green("\u2713")} apiblaze package already installed`);
7204
+ console.log(` ${import_chalk42.default.green("\u2713")} apiblaze package already installed`);
7120
7205
  return;
7121
7206
  }
7122
7207
  const has = (f) => fs10.existsSync(path7.join(root, f));
@@ -7127,7 +7212,7 @@ function installSidecarPackage(root) {
7127
7212
  execSync(`${pm.cmd} ${pm.add} apiblaze`, { cwd: root, stdio: "ignore" });
7128
7213
  spinner.succeed("Installed apiblaze (the sidecar runtime).");
7129
7214
  } catch {
7130
- spinner.warn(`Couldn't auto-install \u2014 run ${import_chalk41.default.cyan(`${pm.cmd} ${pm.add} apiblaze`)} yourself before ${import_chalk41.default.cyan("npm run dev")}.`);
7215
+ spinner.warn(`Couldn't auto-install \u2014 run ${import_chalk42.default.cyan(`${pm.cmd} ${pm.add} apiblaze`)} yourself before ${import_chalk42.default.cyan("npm run dev")}.`);
7131
7216
  }
7132
7217
  }
7133
7218
  function readEnvKey(root) {
@@ -7278,29 +7363,29 @@ async function runAnonymousInit(root, router, opts) {
7278
7363
  if (out.cp_key && out.team_id) saveAnonCred2(out.cp_key, out.team_id, out.claim_code);
7279
7364
  const envState = upsertEnvLocal(root, out.token);
7280
7365
  ensureGitignored(root);
7281
- console.log(` ${import_chalk41.default.green("\u2713")} .env.local ${envState} (APIBLAZE_API_KEY) \u2014 gitignored`);
7282
- console.log(` ${import_chalk41.default.green("\u2713")} instrumentation.ts ${wireInstrumentation(root)}`);
7366
+ console.log(` ${import_chalk42.default.green("\u2713")} .env.local ${envState} (APIBLAZE_API_KEY) \u2014 gitignored`);
7367
+ console.log(` ${import_chalk42.default.green("\u2713")} instrumentation.ts ${wireInstrumentation(root)}`);
7283
7368
  installSidecarPackage(root);
7284
7369
  let inspectorPath = null;
7285
7370
  if (!opts.noInspector) {
7286
7371
  inspectorPath = generateInspector(root, router);
7287
- if (inspectorPath) console.log(` ${import_chalk41.default.green("\u2713")} inspector at ${inspectorPath}`);
7372
+ if (inspectorPath) console.log(` ${import_chalk42.default.green("\u2713")} inspector at ${inspectorPath}`);
7288
7373
  }
7289
7374
  console.log("");
7290
- console.log(import_chalk41.default.bold("Done (no account needed). What happens next:"));
7291
- console.log(` 1. ${import_chalk41.default.cyan("npm run dev")} and use your app.`);
7375
+ console.log(import_chalk42.default.bold("Done (no account needed). What happens next:"));
7376
+ console.log(` 1. ${import_chalk42.default.cyan("npm run dev")} and use your app.`);
7292
7377
  console.log(` 2. Each external origin your app calls is logged in the console \u2014 approve one with:`);
7293
- console.log(` ${import_chalk41.default.cyan("apiblaze sidecar approve api.stripe.com")} (no login needed)`);
7378
+ console.log(` ${import_chalk42.default.cyan("apiblaze sidecar approve api.stripe.com")} (no login needed)`);
7294
7379
  console.log("");
7295
- console.log(import_chalk41.default.bold(" \u{1F511} Keep your setup \u2014 claim it into an account:"));
7296
- console.log(` ${import_chalk41.default.cyan("apiblaze login")} then ${import_chalk41.default.cyan("apiblaze claim")} ${import_chalk41.default.dim("(no code needed here)")}`);
7297
- console.log(import_chalk41.default.dim(` From another machine: apiblaze claim ${out.claim_code} \xB7 expires in 30 days`));
7380
+ console.log(import_chalk42.default.bold(" \u{1F511} Keep your setup \u2014 claim it into an account:"));
7381
+ console.log(` ${import_chalk42.default.cyan("apiblaze login")} then ${import_chalk42.default.cyan("apiblaze claim")} ${import_chalk42.default.dim("(no code needed here)")}`);
7382
+ console.log(import_chalk42.default.dim(` From another machine: apiblaze claim ${out.claim_code} \xB7 expires in 30 days`));
7298
7383
  }
7299
7384
  async function runSidecar(opts) {
7300
7385
  const root = path7.resolve(opts.dir ?? process.cwd());
7301
7386
  const detected = detectNextProject(root);
7302
7387
  if (!detected.found) {
7303
- console.log(import_chalk41.default.yellow(`No Next.js project detected in ${root}.`));
7388
+ console.log(import_chalk42.default.yellow(`No Next.js project detected in ${root}.`));
7304
7389
  console.log("Create one (e.g. `npx create-next-app`) and re-run `apiblaze init` inside it.");
7305
7390
  return;
7306
7391
  }
@@ -7311,10 +7396,10 @@ async function runSidecar(opts) {
7311
7396
  if (!loadCredentials()) {
7312
7397
  upsertEnvLocal(root, readEnvKey(root));
7313
7398
  ensureGitignored(root);
7314
- console.log(` ${import_chalk41.default.green("\u2713")} .env.local present (APIBLAZE_API_KEY) \u2014 reusing`);
7315
- console.log(` ${import_chalk41.default.green("\u2713")} instrumentation.ts ${wireInstrumentation(root)}`);
7399
+ console.log(` ${import_chalk42.default.green("\u2713")} .env.local present (APIBLAZE_API_KEY) \u2014 reusing`);
7400
+ console.log(` ${import_chalk42.default.green("\u2713")} instrumentation.ts ${wireInstrumentation(root)}`);
7316
7401
  installSidecarPackage(root);
7317
- console.log(import_chalk41.default.dim(" Log in and run `apiblaze claim <code>` to keep this setup, or `apiblaze login` to manage it."));
7402
+ console.log(import_chalk42.default.dim(" Log in and run `apiblaze claim <code>` to keep this setup, or `apiblaze login` to manage it."));
7318
7403
  return;
7319
7404
  }
7320
7405
  const { teamId, teamName } = await resolveTeam(opts.team);
@@ -7337,38 +7422,38 @@ async function runSidecar(opts) {
7337
7422
  throw err;
7338
7423
  }
7339
7424
  } else {
7340
- console.log(import_chalk41.default.dim(` Reusing the existing APIBLAZE_API_KEY (run with --rotate to mint a fresh one, or --team <name> to switch teams).`));
7425
+ console.log(import_chalk42.default.dim(` Reusing the existing APIBLAZE_API_KEY (run with --rotate to mint a fresh one, or --team <name> to switch teams).`));
7341
7426
  }
7342
7427
  const envState = upsertEnvLocal(root, token);
7343
7428
  ensureGitignored(root);
7344
- console.log(` ${import_chalk41.default.green("\u2713")} .env.local ${envState} (APIBLAZE_API_KEY) \u2014 gitignored`);
7429
+ console.log(` ${import_chalk42.default.green("\u2713")} .env.local ${envState} (APIBLAZE_API_KEY) \u2014 gitignored`);
7345
7430
  const wireState = wireInstrumentation(root);
7346
- console.log(` ${import_chalk41.default.green("\u2713")} instrumentation.ts ${wireState}`);
7431
+ console.log(` ${import_chalk42.default.green("\u2713")} instrumentation.ts ${wireState}`);
7347
7432
  installSidecarPackage(root);
7348
7433
  let inspectorPath = null;
7349
7434
  if (!opts.noInspector) {
7350
7435
  inspectorPath = generateInspector(root, detected.router);
7351
- if (inspectorPath) console.log(` ${import_chalk41.default.green("\u2713")} inspector at ${inspectorPath}`);
7436
+ if (inspectorPath) console.log(` ${import_chalk42.default.green("\u2713")} inspector at ${inspectorPath}`);
7352
7437
  }
7353
7438
  console.log("");
7354
- console.log(import_chalk41.default.bold("Done. What happens next:"));
7355
- console.log(` 1. ${import_chalk41.default.cyan("npm run dev")} and use your app \u2014 it works exactly as before (all calls go direct).`);
7356
- console.log(` 2. The origins your app calls appear as ${import_chalk41.default.bold("candidates")} \u2014 list them: ${import_chalk41.default.cyan("apiblaze sidecar")}`);
7357
- console.log(` 3. Approve the ones to route: ${import_chalk41.default.cyan("apiblaze sidecar approve api.stripe.com")} (or in the dashboard)`);
7439
+ console.log(import_chalk42.default.bold("Done. What happens next:"));
7440
+ console.log(` 1. ${import_chalk42.default.cyan("npm run dev")} and use your app \u2014 it works exactly as before (all calls go direct).`);
7441
+ console.log(` 2. The origins your app calls appear as ${import_chalk42.default.bold("candidates")} \u2014 list them: ${import_chalk42.default.cyan("apiblaze sidecar")}`);
7442
+ console.log(` 3. Approve the ones to route: ${import_chalk42.default.cyan("apiblaze sidecar approve api.stripe.com")} (or in the dashboard)`);
7358
7443
  console.log(` \u2026within ~5 min your app starts routing that origin through APIblaze.`);
7359
- if (inspectorPath) console.log(` \u2022 Try it now: open ${import_chalk41.default.underline("http://localhost:3000/abz-inspector")} (dev only; rm ${path7.dirname(inspectorPath)} before shipping)`);
7360
- if (switchingTeam) console.log(import_chalk41.default.dim(` \u2022 Approved origins are per-team \u2014 re-approve them on ${teamName ?? teamId} with \`apiblaze sidecar approve <origin>\`.`));
7444
+ if (inspectorPath) console.log(` \u2022 Try it now: open ${import_chalk42.default.underline("http://localhost:3000/abz-inspector")} (dev only; rm ${path7.dirname(inspectorPath)} before shipping)`);
7445
+ if (switchingTeam) console.log(import_chalk42.default.dim(` \u2022 Approved origins are per-team \u2014 re-approve them on ${teamName ?? teamId} with \`apiblaze sidecar approve <origin>\`.`));
7361
7446
  console.log("");
7362
- console.log(import_chalk41.default.dim(" Manage: apiblaze sidecar (list/approve/deny/remove)"));
7363
- console.log(import_chalk41.default.dim(" Rotate: apiblaze init --rotate \xB7 Switch team: apiblaze init --team <name>"));
7364
- console.log(import_chalk41.default.dim(" Turn off: set APIBLAZE_SIDECAR=off in .env.local (flip back to on anytime; key stays put)."));
7447
+ console.log(import_chalk42.default.dim(" Manage: apiblaze sidecar (list/approve/deny/remove)"));
7448
+ console.log(import_chalk42.default.dim(" Rotate: apiblaze init --rotate \xB7 Switch team: apiblaze init --team <name>"));
7449
+ console.log(import_chalk42.default.dim(" Turn off: set APIBLAZE_SIDECAR=off in .env.local (flip back to on anytime; key stays put)."));
7365
7450
  console.log("");
7366
- console.log(import_chalk41.default.yellow(" \u26A0 APIBLAZE_API_KEY is long-lived and lets a holder call your team's proxies. Never commit it."));
7367
- console.log(import_chalk41.default.dim(" Your control-plane login stays in ~/.apiblaze \u2014 it never entered this project."));
7451
+ console.log(import_chalk42.default.yellow(" \u26A0 APIBLAZE_API_KEY is long-lived and lets a holder call your team's proxies. Never commit it."));
7452
+ console.log(import_chalk42.default.dim(" Your control-plane login stays in ~/.apiblaze \u2014 it never entered this project."));
7368
7453
  }
7369
7454
 
7370
7455
  // src/commands/origins.ts
7371
- var import_chalk42 = __toESM(require("chalk"));
7456
+ var import_chalk43 = __toESM(require("chalk"));
7372
7457
  var import_ora24 = __toESM(require("ora"));
7373
7458
  init_admin();
7374
7459
  init_resolve();
@@ -7379,7 +7464,7 @@ async function runOriginsList(opts) {
7379
7464
  if (!loadCredentials()) {
7380
7465
  const cred = loadAnonCred();
7381
7466
  if (!cred) {
7382
- console.log(import_chalk42.default.yellow("No anonymous workspace here. Run `apiblaze init` first."));
7467
+ console.log(import_chalk43.default.yellow("No anonymous workspace here. Run `apiblaze init` first."));
7383
7468
  return;
7384
7469
  }
7385
7470
  out = await cpFetch(cred.cp_key, `/teams/${encodeURIComponent(cred.team_id)}/sidecar/candidates`, { method: "GET" });
@@ -7397,27 +7482,27 @@ async function runOriginsList(opts) {
7397
7482
  }
7398
7483
  const routed = out.routed ?? [];
7399
7484
  const candidates = out.candidates ?? [];
7400
- console.log(import_chalk42.default.bold(`
7485
+ console.log(import_chalk43.default.bold(`
7401
7486
  Routed through APIblaze (${routed.length})`));
7402
- if (!routed.length) console.log(import_chalk42.default.dim(" none yet"));
7403
- for (const r of routed) console.log(` ${import_chalk42.default.green("\u25CF")} ${r.sidecar_origin} ${import_chalk42.default.dim(`\u2192 ${r.project_id}`)}`);
7404
- console.log(import_chalk42.default.bold(`
7487
+ if (!routed.length) console.log(import_chalk43.default.dim(" none yet"));
7488
+ for (const r of routed) console.log(` ${import_chalk43.default.green("\u25CF")} ${r.sidecar_origin} ${import_chalk43.default.dim(`\u2192 ${r.project_id}`)}`);
7489
+ console.log(import_chalk43.default.bold(`
7405
7490
  Candidates \u2014 going direct, not yet approved (${candidates.length})`));
7406
- if (!candidates.length) console.log(import_chalk42.default.dim(" none \u2014 run your app to discover the origins it calls"));
7491
+ if (!candidates.length) console.log(import_chalk43.default.dim(" none \u2014 run your app to discover the origins it calls"));
7407
7492
  for (const c of candidates) {
7408
- console.log(` ${import_chalk42.default.yellow("\u25CB")} ${c.origin} ${import_chalk42.default.dim(`seen ${c.request_count}\xD7, last ${c.last_seen}`)}`);
7493
+ console.log(` ${import_chalk43.default.yellow("\u25CB")} ${c.origin} ${import_chalk43.default.dim(`seen ${c.request_count}\xD7, last ${c.last_seen}`)}`);
7409
7494
  }
7410
7495
  if (candidates.length) {
7411
- console.log(import_chalk42.default.dim(`
7496
+ console.log(import_chalk43.default.dim(`
7412
7497
  Approve: apiblaze sidecar approve ${candidates[0].origin.replace("https://", "")}`));
7413
- console.log(import_chalk42.default.dim(` Dismiss: apiblaze sidecar deny ${candidates[0].origin.replace("https://", "")}`));
7498
+ console.log(import_chalk43.default.dim(` Dismiss: apiblaze sidecar deny ${candidates[0].origin.replace("https://", "")}`));
7414
7499
  }
7415
7500
  }
7416
7501
  async function runOriginsApprove(origin, opts) {
7417
7502
  if (!loadCredentials()) {
7418
7503
  const cred = loadAnonCred();
7419
7504
  if (!cred) {
7420
- console.error(import_chalk42.default.red("Not logged in and no anonymous workspace. Run `apiblaze init` first."));
7505
+ console.error(import_chalk43.default.red("Not logged in and no anonymous workspace. Run `apiblaze init` first."));
7421
7506
  process.exit(1);
7422
7507
  }
7423
7508
  const spinner2 = (0, import_ora24.default)(`Approving ${origin} (anonymous)...`).start();
@@ -7470,7 +7555,7 @@ async function runOriginsRemove(origin, opts) {
7470
7555
  }
7471
7556
 
7472
7557
  // src/commands/op.ts
7473
- var import_chalk43 = __toESM(require("chalk"));
7558
+ var import_chalk44 = __toESM(require("chalk"));
7474
7559
  init_auth();
7475
7560
  init_trace();
7476
7561
  init_types();
@@ -7503,82 +7588,82 @@ function printResidue(report, applied) {
7503
7588
  const up = report?.upstash ?? {};
7504
7589
  const fga = report?.fga ?? {};
7505
7590
  const ghosts = report?.ghosts ?? {};
7506
- console.log(import_chalk43.default.bold(applied ? "\nExternal-residue sweep" : "\nExternal residue (dry-run \u2014 nothing deleted)"));
7507
- console.log(import_chalk43.default.bold("\n Upstash"));
7591
+ console.log(import_chalk44.default.bold(applied ? "\nExternal-residue sweep" : "\nExternal residue (dry-run \u2014 nothing deleted)"));
7592
+ console.log(import_chalk44.default.bold("\n Upstash"));
7508
7593
  const orphans = up.orphans ?? [];
7509
- if (orphans.length === 0) console.log(import_chalk43.default.green(" no orphaned keys"));
7510
- for (const o of orphans) console.log(` ${import_chalk43.default.yellow(o.key)} ${import_chalk43.default.dim(`\u2014 ${o.reason}`)}`);
7511
- console.log(import_chalk43.default.dim(` kept (live principals): ${up.kept ?? 0} \xB7 anon wallets (untouched): ${up.anon_wallets ?? 0}`));
7594
+ if (orphans.length === 0) console.log(import_chalk44.default.green(" no orphaned keys"));
7595
+ for (const o of orphans) console.log(` ${import_chalk44.default.yellow(o.key)} ${import_chalk44.default.dim(`\u2014 ${o.reason}`)}`);
7596
+ console.log(import_chalk44.default.dim(` kept (live principals): ${up.kept ?? 0} \xB7 anon wallets (untouched): ${up.anon_wallets ?? 0}`));
7512
7597
  if (up.anon_wallet_detail) {
7513
7598
  const d = up.anon_wallet_detail;
7514
- console.log(import_chalk43.default.dim(` anon wallets: ${d.count} ($${(d.total_cents / 100).toFixed(2)}), ${d.no_ttl} with NO TTL${d.no_ttl ? " \u26A0" : " (all self-expire)"}`));
7599
+ console.log(import_chalk44.default.dim(` anon wallets: ${d.count} ($${(d.total_cents / 100).toFixed(2)}), ${d.no_ttl} with NO TTL${d.no_ttl ? " \u26A0" : " (all self-expire)"}`));
7515
7600
  }
7516
7601
  if (up.keyspace_census) {
7517
7602
  const census = Object.entries(up.keyspace_census).map(([k, v]) => `${k}=${v}`).join(" \xB7 ");
7518
- console.log(import_chalk43.default.dim(` keyspace: ${census}`));
7603
+ console.log(import_chalk44.default.dim(` keyspace: ${census}`));
7519
7604
  }
7520
- if (up.unknown?.length) console.log(import_chalk43.default.dim(` unknown (never deleted): ${up.unknown.join(", ")}`));
7521
- if (applied) console.log(` ${import_chalk43.default.bold(String(up.deleted ?? 0))} key(s) deleted`);
7522
- for (const e of up.errors ?? []) console.log(import_chalk43.default.red(` error: ${e}`));
7523
- console.log(import_chalk43.default.bold("\n OpenFGA / Neon \u2014 orphan stores"));
7605
+ if (up.unknown?.length) console.log(import_chalk44.default.dim(` unknown (never deleted): ${up.unknown.join(", ")}`));
7606
+ if (applied) console.log(` ${import_chalk44.default.bold(String(up.deleted ?? 0))} key(s) deleted`);
7607
+ for (const e of up.errors ?? []) console.log(import_chalk44.default.red(` error: ${e}`));
7608
+ console.log(import_chalk44.default.bold("\n OpenFGA / Neon \u2014 orphan stores"));
7524
7609
  if (applied) {
7525
7610
  const swept = fga?.swept ?? [];
7526
- if (swept.length === 0) console.log(import_chalk43.default.green(" no orphaned stores"));
7611
+ if (swept.length === 0) console.log(import_chalk44.default.green(" no orphaned stores"));
7527
7612
  for (const s of swept) {
7528
7613
  console.log(
7529
- ` ${import_chalk43.default.yellow(s.store_id)} ${import_chalk43.default.dim(`\u2014 store ${s.openfga_deleted ? "deleted" : "DEFERRED"}, ${s.neon_deleted} Neon tuple(s) purged`)}`
7614
+ ` ${import_chalk44.default.yellow(s.store_id)} ${import_chalk44.default.dim(`\u2014 store ${s.openfga_deleted ? "deleted" : "DEFERRED"}, ${s.neon_deleted} Neon tuple(s) purged`)}`
7530
7615
  );
7531
7616
  }
7532
- if (fga?.remaining) console.log(import_chalk43.default.yellow(` ${fga.remaining} more orphan store(s) \u2014 re-run to drain`));
7617
+ if (fga?.remaining) console.log(import_chalk44.default.yellow(` ${fga.remaining} more orphan store(s) \u2014 re-run to drain`));
7533
7618
  const st = fga?.side_tables;
7534
- if (st) console.log(import_chalk43.default.dim(` Neon side-tables purged: ${st.soft_deleted_stores} store records, ${st.orphan_models} models, ${st.orphan_changelog} changelog rows${st.error ? ` (${st.error})` : ""}`));
7619
+ if (st) console.log(import_chalk44.default.dim(` Neon side-tables purged: ${st.soft_deleted_stores} store records, ${st.orphan_models} models, ${st.orphan_changelog} changelog rows${st.error ? ` (${st.error})` : ""}`));
7535
7620
  } else {
7536
7621
  const fgaOrphans = fga?.orphans ?? [];
7537
- if (fgaOrphans.length === 0) console.log(import_chalk43.default.green(" no orphaned stores"));
7622
+ if (fgaOrphans.length === 0) console.log(import_chalk44.default.green(" no orphaned stores"));
7538
7623
  for (const s of fgaOrphans) {
7539
7624
  const src = s.in_openfga ? "live in OpenFGA" : "Neon tuples only";
7540
- console.log(` ${import_chalk43.default.yellow(s.store_id)} ${import_chalk43.default.dim(`\u2014 ${src}${s.name ? ` (${s.name})` : ""}, ${s.neon_tuples} Neon tuple(s)`)}`);
7625
+ console.log(` ${import_chalk44.default.yellow(s.store_id)} ${import_chalk44.default.dim(`\u2014 ${src}${s.name ? ` (${s.name})` : ""}, ${s.neon_tuples} Neon tuple(s)`)}`);
7541
7626
  }
7542
- console.log(import_chalk43.default.dim(` kept stores: ${(fga?.kept_store_ids ?? []).length}`));
7627
+ console.log(import_chalk44.default.dim(` kept stores: ${(fga?.kept_store_ids ?? []).length}`));
7543
7628
  const st = fga?.side_tables;
7544
- if (st) console.log(import_chalk43.default.dim(` Neon side-table residue: ${st.soft_deleted_stores} soft-deleted store records, ${st.orphan_models} orphan models, ${st.orphan_changelog} orphan changelog rows`));
7629
+ if (st) console.log(import_chalk44.default.dim(` Neon side-table residue: ${st.soft_deleted_stores} soft-deleted store records, ${st.orphan_models} orphan models, ${st.orphan_changelog} orphan changelog rows`));
7545
7630
  }
7546
- for (const e of fga?.errors ?? []) console.log(import_chalk43.default.red(` error: ${e}`));
7547
- console.log(import_chalk43.default.bold("\n OpenFGA \u2014 ghost tuples in surviving stores"));
7631
+ for (const e of fga?.errors ?? []) console.log(import_chalk44.default.red(` error: ${e}`));
7632
+ console.log(import_chalk44.default.bold("\n OpenFGA \u2014 ghost tuples in surviving stores"));
7548
7633
  if (applied) {
7549
- if ((ghosts?.ghost_count ?? 0) === 0) console.log(import_chalk43.default.green(" no ghost tuples"));
7550
- else console.log(` ${import_chalk43.default.bold(String(ghosts.deleted ?? 0))} ghost tuple(s) deleted ${import_chalk43.default.dim(`(of ${ghosts.ghost_count} found, ${ghosts.scanned_tuples} scanned across ${ghosts.live_stores} live stores)`)}`);
7634
+ if ((ghosts?.ghost_count ?? 0) === 0) console.log(import_chalk44.default.green(" no ghost tuples"));
7635
+ else console.log(` ${import_chalk44.default.bold(String(ghosts.deleted ?? 0))} ghost tuple(s) deleted ${import_chalk44.default.dim(`(of ${ghosts.ghost_count} found, ${ghosts.scanned_tuples} scanned across ${ghosts.live_stores} live stores)`)}`);
7551
7636
  } else {
7552
7637
  const n = ghosts?.ghost_count ?? 0;
7553
- if (n === 0) console.log(import_chalk43.default.green(` no ghost tuples ${import_chalk43.default.dim(`(${ghosts.scanned_tuples ?? 0} scanned across ${ghosts.live_stores ?? 0} live stores)`)}`));
7638
+ if (n === 0) console.log(import_chalk44.default.green(` no ghost tuples ${import_chalk44.default.dim(`(${ghosts.scanned_tuples ?? 0} scanned across ${ghosts.live_stores ?? 0} live stores)`)}`));
7554
7639
  else {
7555
- console.log(import_chalk43.default.yellow(` ${n} ghost tuple(s) referencing entities absent from D1:`));
7640
+ console.log(import_chalk44.default.yellow(` ${n} ghost tuple(s) referencing entities absent from D1:`));
7556
7641
  for (const g of (ghosts.ghosts ?? []).slice(0, 20)) {
7557
- console.log(import_chalk43.default.dim(` ${g.object_type}:${g.object_id} ${g.relation} ${g._user}`));
7642
+ console.log(import_chalk44.default.dim(` ${g.object_type}:${g.object_id} ${g.relation} ${g._user}`));
7558
7643
  }
7559
- if (n > 20) console.log(import_chalk43.default.dim(` \u2026 and ${n - 20} more`));
7644
+ if (n > 20) console.log(import_chalk44.default.dim(` \u2026 and ${n - 20} more`));
7560
7645
  }
7561
7646
  }
7562
- for (const e of ghosts?.errors ?? []) console.log(import_chalk43.default.red(` error: ${e}`));
7647
+ for (const e of ghosts?.errors ?? []) console.log(import_chalk44.default.red(` error: ${e}`));
7563
7648
  console.log();
7564
7649
  }
7565
7650
  async function runOp(sub, opts = {}) {
7566
7651
  if (!loadCredentials()) {
7567
- console.log(import_chalk43.default.dim("Not logged in. Run `apiblaze login`."));
7652
+ console.log(import_chalk44.default.dim("Not logged in. Run `apiblaze login`."));
7568
7653
  return;
7569
7654
  }
7570
7655
  if (!isOperatorLogin()) {
7571
- console.log(import_chalk43.default.dim("`apiblaze op` is only available to platform operators."));
7656
+ console.log(import_chalk44.default.dim("`apiblaze op` is only available to platform operators."));
7572
7657
  return;
7573
7658
  }
7574
7659
  switch (sub) {
7575
7660
  case void 0:
7576
7661
  case "menu": {
7577
- console.log(import_chalk43.default.bold("\nOperator menu"));
7578
- console.log(` ${import_chalk43.default.cyan("apiblaze op residue")} external-store residue report (Upstash + Neon/OpenFGA, dry-run)`);
7579
- console.log(` ${import_chalk43.default.cyan("apiblaze op sweep")} delete the orphans the report shows (asks first; ${import_chalk43.default.dim("-y to skip")})`);
7580
- console.log(` ${import_chalk43.default.cyan("apiblaze op credits")} list credit wallets`);
7581
- console.log(import_chalk43.default.dim(` (to prune all non-CP data: run scripts/nuke-but-cp.sh --apply --sweep in the repo)
7662
+ console.log(import_chalk44.default.bold("\nOperator menu"));
7663
+ console.log(` ${import_chalk44.default.cyan("apiblaze op residue")} external-store residue report (Upstash + Neon/OpenFGA, dry-run)`);
7664
+ console.log(` ${import_chalk44.default.cyan("apiblaze op sweep")} delete the orphans the report shows (asks first; ${import_chalk44.default.dim("-y to skip")})`);
7665
+ console.log(` ${import_chalk44.default.cyan("apiblaze op credits")} list credit wallets`);
7666
+ console.log(import_chalk44.default.dim(` (to prune all non-CP data: run scripts/nuke-but-cp.sh --apply --sweep in the repo)
7582
7667
  `));
7583
7668
  return;
7584
7669
  }
@@ -7597,17 +7682,17 @@ async function runOp(sub, opts = {}) {
7597
7682
  const nSide = (st.soft_deleted_stores ?? 0) + (st.orphan_models ?? 0) + (st.orphan_changelog ?? 0);
7598
7683
  printResidue(report, false);
7599
7684
  if (nUp + nFga + nGhost + nSide === 0) {
7600
- console.log(import_chalk43.default.green("Nothing to sweep."));
7685
+ console.log(import_chalk44.default.green("Nothing to sweep."));
7601
7686
  return;
7602
7687
  }
7603
7688
  if (!opts.yes) {
7604
7689
  const readline2 = await import("readline/promises");
7605
7690
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
7606
7691
  const answer = await rl.question(
7607
- import_chalk43.default.red(`Delete ${nUp} Upstash key(s) + ${nFga} OpenFGA store(s) + ${nGhost} ghost tuple(s) + ${nSide} Neon side-table row(s)? Type 'sweep' to confirm: `)
7692
+ import_chalk44.default.red(`Delete ${nUp} Upstash key(s) + ${nFga} OpenFGA store(s) + ${nGhost} ghost tuple(s) + ${nSide} Neon side-table row(s)? Type 'sweep' to confirm: `)
7608
7693
  );
7609
7694
  rl.close();
7610
- if (answer.trim() !== "sweep") return void console.log(import_chalk43.default.dim("Aborted."));
7695
+ if (answer.trim() !== "sweep") return void console.log(import_chalk44.default.dim("Aborted."));
7611
7696
  }
7612
7697
  const result = await opCall({ method: "POST", path: "/operator/external-residue/sweep", summary: "external residue sweep" });
7613
7698
  if (opts.json) return void console.log(JSON.stringify(result, null, 2));
@@ -7618,15 +7703,15 @@ async function runOp(sub, opts = {}) {
7618
7703
  const data = await opCall({ method: "GET", path: "/operator/credits", summary: "list credit wallets" });
7619
7704
  if (opts.json) return void console.log(JSON.stringify(data, null, 2));
7620
7705
  const accounts = data?.accounts ?? [];
7621
- if (accounts.length === 0) return void console.log(import_chalk43.default.dim("No credit wallets."));
7706
+ if (accounts.length === 0) return void console.log(import_chalk44.default.dim("No credit wallets."));
7622
7707
  for (const a of accounts) {
7623
7708
  const bal = typeof a.balance_cents === "number" ? `$${(a.balance_cents / 100).toFixed(2)}` : "?";
7624
- console.log(` ${import_chalk43.default.bold(bal.padStart(9))} ${a.walletId}${a.owner_email ? import_chalk43.default.dim(` \u2014 ${a.owner_email}`) : a.anon ? import_chalk43.default.dim(" \u2014 anon") : ""}`);
7709
+ console.log(` ${import_chalk44.default.bold(bal.padStart(9))} ${a.walletId}${a.owner_email ? import_chalk44.default.dim(` \u2014 ${a.owner_email}`) : a.anon ? import_chalk44.default.dim(" \u2014 anon") : ""}`);
7625
7710
  }
7626
7711
  return;
7627
7712
  }
7628
7713
  default:
7629
- console.log(import_chalk43.default.red(`Unknown op subcommand '${sub}'. Run \`apiblaze op\` for the menu.`));
7714
+ console.log(import_chalk44.default.red(`Unknown op subcommand '${sub}'. Run \`apiblaze op\` for the menu.`));
7630
7715
  }
7631
7716
  }
7632
7717
 
@@ -7672,7 +7757,7 @@ agent.command("authz").description("Chat to design and turn on access rules for
7672
7757
  program.command("rule").description("Author an object-level access rule in plain English, in one shot (billed per turn)").argument("<rule>", 'The rule in plain English, e.g. "users see only their own rows"').argument("<project>", "Project name or id").option("--enforce", "Turn enforcement on immediately (default: shadow-publish only)").option("--apiversion <version>", "API version (defaults to the project's)").action(action((rule, project, opts) => runRule(rule, project, opts)));
7673
7758
  agent.command("openapi").description("Chat to build your API spec from real traffic").argument("<project>", "Project name or id").argument("[apiVersion]", "API version (defaults to the project's)").action(action((project, apiVersion) => runOpenapi(project, apiVersion)));
7674
7759
  agent.command("mcp").description("Chat to build an MCP server for an API").argument("<project>", "Project name or id").argument("[apiVersion]", "API version (defaults to the project's)").option("--environment <env>", "Environment to publish (default: prod)").action(action((project, apiVersion, opts) => runMcp(project, apiVersion, opts)));
7675
- program.command("apichat").description("Turn any API into a chat: point at an OpenAPI spec and start asking questions (no login needed)").option("--openapi <file|url>", "OpenAPI/Swagger spec to build from (JSON or YAML; file path or URL)").option("--openapispec <file|url>", "Alias for --openapi").option("--target <url>", "Upstream base URL (overrides servers[0].url; enables spec discovery when --openapi is omitted)").option("--name <name>", "Proxy name (defaults to the target host)").option("--apiversion <version>", "API version to create (e.g. 1.0.0)").option("--environment <env>", "Environment to chat against (default: prod anonymous / dev logged-in)").option("--access <mode>", 'Who can call this API once connected (e.g. via Claude): "open" = anyone who signs in, "invite" = only you + emails you pre-approve. Default: invite when logged in, open when anonymous.').option("--target-auth-env <ENV_VAR>", "Read the upstream credential from this env var (CI-safe; required when there is no TTY and the API needs auth)").option("--force", "Proceed even if the API uses oauth2/openIdConnect target auth (you configure target auth yourself later)").option("-y, --yes", "Skip confirmation prompts").option("--no-verbose", "Hide the per-turn proxy curl trace (shown by default for apichat)").action(action((opts) => runApichat({ ...opts, openapispec: opts.openapispec ?? opts.openapi })));
7760
+ program.command("apichat").description("Turn any API into a chat: point at an OpenAPI spec and start asking questions (no login needed)").option("--openapi <file|url>", "OpenAPI/Swagger spec to build from (JSON or YAML; file path or URL)").option("--openapispec <file|url>", "Alias for --openapi").option("--target <url>", "Upstream base URL (overrides servers[0].url; enables spec discovery when --openapi is omitted)").option("--name <name>", "Proxy name (defaults to the target host)").option("--apiversion <version>", "API version to create (e.g. 1.0.0)").option("--environment <env>", "Environment to chat against (default: prod anonymous / dev logged-in)").option("--access <mode>", 'Who can call this API once connected (e.g. via Claude): "open" = anyone who signs in, "invite" = only you + emails you pre-approve. Default: invite when logged in, open when anonymous.').option("--target-auth-env <ENV_VAR>", "Read the upstream credential from this env var (CI-safe; required when there is no TTY and the API needs auth)").option("--force", "Proceed even if the API uses oauth2/openIdConnect target auth (you configure target auth yourself later)").option("-y, --yes", "Skip confirmation prompts").option("--tenant <slug>", "Tenant (consumer namespace: portal, login, users) for the new proxy; omit to be asked").option("--no-verbose", "Hide the per-turn proxy curl trace (shown by default for apichat)").action(action((opts) => runApichat({ ...opts, openapispec: opts.openapispec ?? opts.openapi })));
7676
7761
  var llm = program.command("llm").description("Manage a local LLM provider key for chat (optional \u2014 lifts model quality, bills your key)");
7677
7762
  llm.command("set-key").description("Store an LLM provider key locally (OpenRouter/Anthropic/DeepSeek/OpenAI)").argument("[key]", "The API key (omit to enter it hidden at a prompt)").option("--model <id>", "Model id to use with this key (e.g. anthropic/claude-haiku-4.5)").action(action((key, opts) => runLlmSetKey(key, opts)));
7678
7763
  llm.command("show").description("Show the locally stored LLM key (masked)").action(action(() => runLlmShow()));
@@ -7689,7 +7774,7 @@ program.command("dev").description("Put your localhost behind a public URL (dev
7689
7774
  try {
7690
7775
  const resolved = parseInt(port ?? opts.port, 10);
7691
7776
  if (Number.isNaN(resolved)) {
7692
- console.error(import_chalk44.default.red(`Invalid port: ${port ?? opts.port}`));
7777
+ console.error(import_chalk45.default.red(`Invalid port: ${port ?? opts.port}`));
7693
7778
  process.exit(1);
7694
7779
  }
7695
7780
  await runDev({ port: resolved, project: opts.project, yes: opts.yes, captureFile: opts.captureFile, newSession: opts.newSession });
@@ -7808,7 +7893,7 @@ function groupedCommandHelp() {
7808
7893
  const sub = byName.get(e.parent)?.commands.find((s) => s.name() === e.sub);
7809
7894
  return sub ? ` ${helpLabel(e).padEnd(width)}${sub.description()}` : "";
7810
7895
  }).filter(Boolean).join("\n");
7811
- return `${import_chalk44.default.bold(g.title)}
7896
+ return `${import_chalk45.default.bold(g.title)}
7812
7897
  ${rows}`;
7813
7898
  }).join("\n\n");
7814
7899
  }
@@ -7843,14 +7928,14 @@ async function recoverStaleTeam() {
7843
7928
  const { resolveLinkedTeam: resolveLinkedTeam2 } = await Promise.resolve().then(() => (init_team(), team_exports));
7844
7929
  const linked = await resolveLinkedTeam2({ preferredId: creds.teamId, interactive: !!process.stdin.isTTY });
7845
7930
  if (!linked) {
7846
- console.error(import_chalk44.default.yellow("Your account has no teams anymore (deleted?). Run `apiblaze login` or `apiblaze create` to get a workspace."));
7931
+ console.error(import_chalk45.default.yellow("Your account has no teams anymore (deleted?). Run `apiblaze login` or `apiblaze create` to get a workspace."));
7847
7932
  return;
7848
7933
  }
7849
7934
  if (linked.teamId === creds.teamId) return;
7850
7935
  const next = { ...creds, teamId: linked.teamId, teamName: linked.teamName };
7851
7936
  delete next.activeTenant;
7852
7937
  saveCredentials(next);
7853
- console.error(import_chalk44.default.yellow(`Your previous team no longer exists \u2014 relinked to ${import_chalk44.default.bold(linked.teamName ?? linked.teamId)}. Re-run your command.`));
7938
+ console.error(import_chalk45.default.yellow(`Your previous team no longer exists \u2014 relinked to ${import_chalk45.default.bold(linked.teamName ?? linked.teamId)}. Re-run your command.`));
7854
7939
  } catch {
7855
7940
  }
7856
7941
  }
@@ -7858,16 +7943,16 @@ async function printError(err) {
7858
7943
  if (err instanceof ApiError) {
7859
7944
  const data = err.body;
7860
7945
  const extra = [data?.body?.reason, data?.body?.details, data?.details, data?.body?.error].find((x) => typeof x === "string" && x && x !== err.message);
7861
- console.error(import_chalk44.default.red(`
7946
+ console.error(import_chalk45.default.red(`
7862
7947
  API error (${err.status}): ${err.message}${extra ? ` \u2014 ${extra}` : ""}`));
7863
7948
  if (err.status === 403 || err.status === 404) {
7864
7949
  await recoverStaleTeam();
7865
7950
  }
7866
7951
  } else if (err instanceof Error) {
7867
- console.error(import_chalk44.default.red(`
7952
+ console.error(import_chalk45.default.red(`
7868
7953
  Error: ${err.message}`));
7869
7954
  } else {
7870
- console.error(import_chalk44.default.red("\nUnknown error"));
7955
+ console.error(import_chalk45.default.red("\nUnknown error"));
7871
7956
  }
7872
7957
  }
7873
7958
  program.parse(process.argv);