anygate 0.5.9 → 0.5.11

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.
package/dist/cli.js CHANGED
@@ -66,6 +66,7 @@ import {
66
66
  getProvidersPath,
67
67
  getProxyDebugLogPath,
68
68
  getReasoningCapabilities,
69
+ getValidationStatus,
69
70
  grabRoundTripSignature,
70
71
  hasApplicationDefaultCredentials,
71
72
  init_config,
@@ -101,13 +102,18 @@ import {
101
102
  parseToolArguments,
102
103
  prepareClaudeTraceLog,
103
104
  printApiKeyPanel,
105
+ printApiKeyProviderPanel,
104
106
  printAsciiBanner,
105
107
  printCloudProviderPanel,
106
108
  printDryRunPanel,
107
109
  printEnvConflictPanel,
108
110
  printImportConflictPanel,
111
+ printMainMenuPanel,
112
+ printOnboardingPanel,
109
113
  printPanel,
114
+ printProviderCategoryPanel,
110
115
  printProviderDetailPanel,
116
+ printSetupSummaryPanel,
111
117
  printTraceLog,
112
118
  printWelcomePanel,
113
119
  providerAuthHelpText,
@@ -115,6 +121,8 @@ import {
115
121
  providersForPicker,
116
122
  providersForPickerWithTemplates,
117
123
  providersForTarget,
124
+ pruneValidationCache,
125
+ quickValidateModel,
118
126
  quitClaudeAppGracefully,
119
127
  quitCodexAppGracefully,
120
128
  readBody,
@@ -162,9 +170,10 @@ import {
162
170
  upgradeLegacyCloudProviders,
163
171
  upstreamHttpStatus,
164
172
  validateCustomEndpointUrl,
173
+ validateModels,
165
174
  writeSecureLogLine,
166
175
  zenRegistryStub
167
- } from "./chunk-PJ3L2TW7.js";
176
+ } from "./chunk-55RHVPE4.js";
168
177
  import {
169
178
  BACKENDS,
170
179
  CONFLICTING_ENV_VARS,
@@ -172,7 +181,7 @@ import {
172
181
  MAX_MODEL_CATALOG,
173
182
  VERSION,
174
183
  VERTEX_ANTHROPIC_NPM
175
- } from "./chunk-P36O5B7N.js";
184
+ } from "./chunk-5UF4TVCM.js";
176
185
  import {
177
186
  filterTemplates,
178
187
  getTemplateById,
@@ -183,7 +192,7 @@ import {
183
192
  import "./chunk-72WNE2IK.js";
184
193
 
185
194
  // src/cli.ts
186
- import pc17 from "picocolors";
195
+ import pc18 from "picocolors";
187
196
  import { realpathSync } from "fs";
188
197
  import { fileURLToPath } from "url";
189
198
 
@@ -241,7 +250,7 @@ function formatProviderModels(provider) {
241
250
  function buildLiveStateSection() {
242
251
  const prefs = loadPreferences();
243
252
  const registry = loadRegistry();
244
- const enabled = registry.providers.filter((p17) => p17.enabled);
253
+ const enabled = registry.providers.filter((p18) => p18.enabled);
245
254
  const prefLines = [];
246
255
  if (prefs.lastProvider || prefs.lastModel) {
247
256
  prefLines.push(` Claude last launch: provider=${prefs.lastProvider ?? "(none)"} model=${prefs.lastModel ?? "(none)"}`);
@@ -258,9 +267,9 @@ function buildLiveStateSection() {
258
267
  prefLines.push(` ${f.providerId} / ${f.modelId}`);
259
268
  }
260
269
  }
261
- const providerBlocks = enabled.length === 0 ? [" No registry providers configured. Built-in cloud: zen, go (OpenCode Zen/Go)."] : enabled.map((p17) => [
262
- ` ${p17.name} (${p17.id}) \u2014 ${p17.modelsCache?.models.length ?? 0} cached model(s)`,
263
- formatProviderModels(p17)
270
+ const providerBlocks = enabled.length === 0 ? [" No registry providers configured. Built-in cloud: zen, go (OpenCode Zen/Go)."] : enabled.map((p18) => [
271
+ ` ${p18.name} (${p18.id}) \u2014 ${p18.modelsCache?.models.length ?? 0} cached model(s)`,
272
+ formatProviderModels(p18)
264
273
  ].join("\n"));
265
274
  return `
266
275
  ================================================================================
@@ -755,13 +764,320 @@ function printAiInstallResult(result) {
755
764
  return result.failed.length > 0 ? 1 : 0;
756
765
  }
757
766
 
767
+ // src/cli/root.ts
768
+ import pc from "picocolors";
769
+ import * as p from "@clack/prompts";
770
+ import open from "open";
771
+ var ONBOARDING_TEMPLATES = ["kilo", "nvidia", "groq", "mistral", "cerebras"];
772
+ function categorizeOnboardingProviders() {
773
+ const templates = ONBOARDING_TEMPLATES.map((id) => getTemplateById(id)).filter((t) => t !== void 0 && t.supported);
774
+ const keyless = [];
775
+ const apiKeyRequired = [];
776
+ for (const t of templates) {
777
+ if (t.apiKeyOptional || t.anonymousFreeModels) {
778
+ keyless.push(t);
779
+ } else {
780
+ apiKeyRequired.push(t);
781
+ }
782
+ }
783
+ return { keyless, apiKeyRequired };
784
+ }
785
+ function hasConfiguredProviders() {
786
+ const registry = loadRegistry();
787
+ return registry.providers.length > 0;
788
+ }
789
+ async function handleKeylessProvider(template) {
790
+ p.log.info(`Adding ${template.name}...`);
791
+ const result = await addProviderFromTemplate(template, "");
792
+ if (result.added) {
793
+ p.log.success(`${template.name} enabled (no key needed)`);
794
+ return true;
795
+ }
796
+ if (result.error) {
797
+ p.log.error(`${template.name}: ${result.error}`);
798
+ }
799
+ return false;
800
+ }
801
+ async function handleApiKeyProvider(template) {
802
+ const signupUrl = template.signupUrl ?? "https://opencode.ai/auth";
803
+ printApiKeyProviderPanel(template.name, signupUrl);
804
+ let choice = await p.select({
805
+ message: `How would you like to set up ${template.name}?`,
806
+ options: [
807
+ {
808
+ value: "paste",
809
+ label: pc.cyan("I have a key \u2014 paste it now"),
810
+ hint: "Key stored securely in your system keychain"
811
+ },
812
+ {
813
+ value: "signup",
814
+ label: pc.cyan("Open signup page in browser"),
815
+ hint: `Free tier at ${signupUrl}`
816
+ },
817
+ {
818
+ value: "skip",
819
+ label: pc.dim("Skip for now"),
820
+ hint: "You can add this later with anygate providers add"
821
+ }
822
+ ]
823
+ });
824
+ if (p.isCancel(choice)) return null;
825
+ if (choice === "signup") {
826
+ try {
827
+ await open(signupUrl);
828
+ p.log.info(`Opened ${signupUrl} in your browser.`);
829
+ } catch {
830
+ p.log.warn(`Could not open browser. Visit: ${signupUrl}`);
831
+ }
832
+ const retry = await p.confirm({
833
+ message: "Did you get your API key?",
834
+ initialValue: false
835
+ });
836
+ if (p.isCancel(retry) || !retry) return false;
837
+ choice = "paste";
838
+ }
839
+ if (choice === "paste") {
840
+ const apiKey = await p.password({
841
+ message: `Paste your ${template.name} API key:`,
842
+ validate: (val) => val.trim() ? void 0 : "Key cannot be empty"
843
+ });
844
+ if (p.isCancel(apiKey)) return null;
845
+ p.log.info(`Adding ${template.name}...`);
846
+ const result = await addProviderFromTemplate(template, String(apiKey).trim());
847
+ if (result.added) {
848
+ p.log.success(`${template.name} configured`);
849
+ return true;
850
+ }
851
+ if (result.error) {
852
+ p.log.error(`${template.name}: ${result.error}`);
853
+ }
854
+ return false;
855
+ }
856
+ return false;
857
+ }
858
+ async function step1CategorizeProviders(keyless, apiKeyRequired) {
859
+ printProviderCategoryPanel();
860
+ const options = [];
861
+ if (keyless.length > 0) {
862
+ options.push({
863
+ value: "__keyless_header__",
864
+ label: pc.dim("\u2500\u2500 Keyless (works instantly) \u2500\u2500"),
865
+ hint: ""
866
+ });
867
+ for (const t of keyless) {
868
+ options.push({
869
+ value: `keyless:${t.id}`,
870
+ label: `${pc.green("\u2713")} ${t.name}`,
871
+ hint: "no key needed"
872
+ });
873
+ }
874
+ }
875
+ if (apiKeyRequired.length > 0) {
876
+ options.push({
877
+ value: "__apikey_header__",
878
+ label: pc.dim("\u2500\u2500 API Key Required (free tier) \u2500\u2500"),
879
+ hint: ""
880
+ });
881
+ for (const t of apiKeyRequired) {
882
+ options.push({
883
+ value: `apikey:${t.id}`,
884
+ label: t.name,
885
+ hint: `free at ${t.signupUrl ?? "console.groq.com"}`
886
+ });
887
+ }
888
+ }
889
+ options.push({
890
+ value: "__continue__",
891
+ label: pc.cyan("Continue"),
892
+ hint: "configure selected providers"
893
+ });
894
+ const selected = /* @__PURE__ */ new Set();
895
+ let selectedKeyless = [];
896
+ let selectedApiKey = [];
897
+ while (true) {
898
+ const currentOptions = options.map((opt) => ({
899
+ ...opt,
900
+ label: selected.has(opt.value) && !opt.value.startsWith("__") && opt.value !== "__continue__" ? `${pc.green("\u2713")} ${opt.label.replace(/^[✓●]\s*/, "")}` : opt.label
901
+ }));
902
+ const choice = await p.select({
903
+ message: "Select providers to configure (Space to toggle, Enter to continue):",
904
+ options: currentOptions
905
+ });
906
+ if (p.isCancel(choice)) return null;
907
+ if (choice === "__continue__") break;
908
+ if (selected.has(choice)) {
909
+ selected.delete(choice);
910
+ } else {
911
+ selected.add(choice);
912
+ }
913
+ selectedKeyless = [];
914
+ selectedApiKey = [];
915
+ for (const val of selected) {
916
+ if (val.startsWith("keyless:")) {
917
+ const t = keyless.find((k) => k.id === val.slice("keyless:".length));
918
+ if (t) selectedKeyless.push(t);
919
+ } else if (val.startsWith("apikey:")) {
920
+ const t = apiKeyRequired.find((k) => k.id === val.slice("apikey:".length));
921
+ if (t) selectedApiKey.push(t);
922
+ }
923
+ }
924
+ }
925
+ if (selectedKeyless.length === 0 && selectedApiKey.length === 0) {
926
+ selectedKeyless = [...keyless];
927
+ selectedApiKey = [...apiKeyRequired];
928
+ }
929
+ return { selectedKeyless, selectedApiKey };
930
+ }
931
+ async function step2HandleSelections(keyless, apiKeyRequired) {
932
+ const configured = [];
933
+ const skipped = [];
934
+ for (const t of keyless) {
935
+ const result = await handleKeylessProvider(t);
936
+ if (result) {
937
+ configured.push({ name: t.name, keyless: true });
938
+ } else {
939
+ skipped.push(t.name);
940
+ }
941
+ }
942
+ for (const t of apiKeyRequired) {
943
+ const result = await handleApiKeyProvider(t);
944
+ if (result === true) {
945
+ configured.push({ name: t.name, keyless: false });
946
+ } else if (result === false) {
947
+ skipped.push(t.name);
948
+ }
949
+ }
950
+ return { configured, skipped };
951
+ }
952
+ function step3Summary(configured, skipped) {
953
+ printSetupSummaryPanel(configured, skipped);
954
+ }
955
+ async function runOnboardingFlow() {
956
+ printOnboardingPanel();
957
+ const { keyless, apiKeyRequired } = categorizeOnboardingProviders();
958
+ if (keyless.length === 0 && apiKeyRequired.length === 0) {
959
+ p.log.warn("No providers available for onboarding.");
960
+ return 0;
961
+ }
962
+ const selection = await step1CategorizeProviders(keyless, apiKeyRequired);
963
+ if (!selection) return 0;
964
+ const { configured, skipped } = await step2HandleSelections(
965
+ selection.selectedKeyless,
966
+ selection.selectedApiKey
967
+ );
968
+ step3Summary(configured, skipped);
969
+ return 0;
970
+ }
971
+ async function runMainMenu() {
972
+ const entries = await resolveProvidersForDisplay();
973
+ const providerCount = entries.length;
974
+ const onboardingEntries = entries.filter((e) => ONBOARDING_TEMPLATES.includes(e.id));
975
+ const freeHint = onboardingEntries.length > 0 ? `free: ${onboardingEntries.map((e) => e.name).join(", ")}` : providerCount > 0 ? `${providerCount} provider${providerCount === 1 ? "" : "s"} configured` : "no providers configured";
976
+ printMainMenuPanel(VERSION, providerCount);
977
+ const options = [
978
+ {
979
+ value: "claude",
980
+ label: pc.cyan("Launch Claude"),
981
+ hint: freeHint
982
+ },
983
+ {
984
+ value: "codex",
985
+ label: pc.cyan("Launch Codex"),
986
+ hint: "OpenAI Codex CLI with registry providers"
987
+ },
988
+ {
989
+ value: "providers",
990
+ label: pc.cyan("Configure Providers"),
991
+ hint: "Add, import, or manage AI providers"
992
+ },
993
+ {
994
+ value: "onboarding",
995
+ label: pc.cyan("Free Setup"),
996
+ hint: "Re-run the provider onboarding flow"
997
+ },
998
+ {
999
+ value: "doctor",
1000
+ label: pc.cyan("Doctor"),
1001
+ hint: "Run environment diagnostics"
1002
+ },
1003
+ {
1004
+ value: "server",
1005
+ label: pc.cyan("Server"),
1006
+ hint: "Start a foreground API gateway"
1007
+ },
1008
+ {
1009
+ value: "ui",
1010
+ label: pc.cyan("Dashboard"),
1011
+ hint: "Open the web dashboard"
1012
+ },
1013
+ {
1014
+ value: "settings",
1015
+ label: pc.cyan("Settings"),
1016
+ hint: "Configure preferences and paths"
1017
+ },
1018
+ {
1019
+ value: "quit",
1020
+ label: pc.dim("Quit"),
1021
+ hint: ""
1022
+ }
1023
+ ];
1024
+ const choice = await p.select({
1025
+ message: "What would you like to do?",
1026
+ options
1027
+ });
1028
+ if (p.isCancel(choice) || choice === "quit") {
1029
+ gateOutro("Goodbye!");
1030
+ return 0;
1031
+ }
1032
+ switch (choice) {
1033
+ case "claude":
1034
+ gateOutro("Launching Claude Code...");
1035
+ return 0;
1036
+ // The actual launch is handled by the claude command
1037
+ case "codex":
1038
+ gateOutro("Launching Codex...");
1039
+ return 0;
1040
+ case "providers":
1041
+ gateOutro("Opening provider manager...");
1042
+ return 0;
1043
+ case "onboarding":
1044
+ return runOnboardingFlow();
1045
+ case "doctor":
1046
+ gateOutro("Running diagnostics...");
1047
+ return 0;
1048
+ case "server":
1049
+ gateOutro("Starting server...");
1050
+ return 0;
1051
+ case "ui":
1052
+ gateOutro("Opening dashboard...");
1053
+ return 0;
1054
+ case "settings":
1055
+ gateOutro("Opening settings...");
1056
+ return 0;
1057
+ default:
1058
+ return 0;
1059
+ }
1060
+ }
1061
+ async function handleRootCommand(_parsed) {
1062
+ if (!process.stdin.isTTY) {
1063
+ const { printHelp: printHelp2, rootHelpText: rootHelpText2 } = await import("./cli.js");
1064
+ printHelp2(rootHelpText2());
1065
+ return 0;
1066
+ }
1067
+ gateIntro("anygate");
1068
+ if (!hasConfiguredProviders()) {
1069
+ return runOnboardingFlow();
1070
+ }
1071
+ return runMainMenu();
1072
+ }
1073
+
758
1074
  // src/cli/claude.ts
759
- import pc4 from "picocolors";
760
- import * as p5 from "@clack/prompts";
1075
+ import pc5 from "picocolors";
1076
+ import * as p6 from "@clack/prompts";
761
1077
 
762
1078
  // src/apps/shared/first-run.ts
763
- import pc from "picocolors";
764
- import * as p2 from "@clack/prompts";
1079
+ import pc2 from "picocolors";
1080
+ import * as p3 from "@clack/prompts";
765
1081
 
766
1082
  // src/registry/validation/validate-import-key.ts
767
1083
  function reject(reason, detail) {
@@ -910,7 +1226,7 @@ async function importFromOpencode(options = {}) {
910
1226
  }
911
1227
  continue;
912
1228
  }
913
- const existingIdx = registry.providers.findIndex((p17) => p17.id === entry.id);
1229
+ const existingIdx = registry.providers.findIndex((p18) => p18.id === entry.id);
914
1230
  const existing = existingIdx >= 0 ? registry.providers[existingIdx] : void 0;
915
1231
  if (existing && options.resolveConflict) {
916
1232
  const choice = await options.resolveConflict({
@@ -948,7 +1264,7 @@ async function importFromOpencode(options = {}) {
948
1264
  if (isOAuth) oauthImported += 1;
949
1265
  }
950
1266
  const alreadyReportedIds = new Set(skipped.map((s) => s.id));
951
- const registryProviderIds = new Set(registry.providers.map((p17) => p17.id));
1267
+ const registryProviderIds = new Set(registry.providers.map((p18) => p18.id));
952
1268
  for (const provider of listCredentialSkippedProviders(
953
1269
  raw,
954
1270
  authEntries,
@@ -971,7 +1287,7 @@ async function importFromOpencode(options = {}) {
971
1287
  }
972
1288
 
973
1289
  // src/apps/shared/key-setup.ts
974
- import * as p from "@clack/prompts";
1290
+ import * as p2 from "@clack/prompts";
975
1291
  import { appendFileSync, readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
976
1292
  import { homedir as homedir2 } from "os";
977
1293
  import { spawnSync } from "child_process";
@@ -1003,7 +1319,7 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1003
1319
  }
1004
1320
  if (!simulate) {
1005
1321
  const keyDiag = (reason) => {
1006
- p.log.warn(`Credential store unavailable \u2014 ${reason}`);
1322
+ p2.log.warn(`Credential store unavailable \u2014 ${reason}`);
1007
1323
  if (trace) {
1008
1324
  writeSecureLogLine(getClaudeDebugLogPath(), `keyring: ${reason}`);
1009
1325
  }
@@ -1011,18 +1327,18 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1011
1327
  const storedKey = await readFromCredentialStore(keyDiag);
1012
1328
  if (storedKey) {
1013
1329
  const storeName = isMac ? "macOS Keychain" : isWindows4 ? "Windows Credential Manager" : "Secret Service";
1014
- p.log.success(`Found key in ${storeName}`);
1330
+ p2.log.success(`Found key in ${storeName}`);
1015
1331
  process.env["OPENCODE_API_KEY"] = storedKey;
1016
1332
  return storedKey;
1017
1333
  }
1018
1334
  }
1019
1335
  printApiKeyPanel("https://opencode.ai/auth");
1020
- const key = await p.password({
1336
+ const key = await p2.password({
1021
1337
  message: "Paste your OPENCODE_API_KEY:",
1022
1338
  validate: (val) => val.trim() ? void 0 : "Key cannot be empty"
1023
1339
  });
1024
- if (p.isCancel(key)) {
1025
- p.cancel("Cancelled.");
1340
+ if (p2.isCancel(key)) {
1341
+ p2.cancel("Cancelled.");
1026
1342
  return null;
1027
1343
  }
1028
1344
  const trimmedKey = key.trim();
@@ -1051,7 +1367,7 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1051
1367
  if (secretServiceAvailable) {
1052
1368
  opts.push({ value: "secret-service", label: "Secret Service (GNOME Keyring / KWallet)", hint: "Key stored securely in your desktop keyring; anygate reads it automatically next time" });
1053
1369
  } else if (!simulate) {
1054
- p.log.info("No keyring daemon detected \u2014 secure storage requires GNOME Keyring or KWallet running.");
1370
+ p2.log.info("No keyring daemon detected \u2014 secure storage requires GNOME Keyring or KWallet running.");
1055
1371
  }
1056
1372
  opts.push(
1057
1373
  { value: "profile", label: `${display} (plaintext)`, hint: "Key written directly to your shell profile" },
@@ -1059,13 +1375,13 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1059
1375
  );
1060
1376
  return opts;
1061
1377
  })();
1062
- const saveChoice = await p.select({
1378
+ const saveChoice = await p2.select({
1063
1379
  message: "Where should we save the key?",
1064
1380
  options: saveOptions,
1065
1381
  initialValue: isMac ? "keychain" : isWindows4 ? "credential-manager" : secretServiceAvailable ? "secret-service" : "profile"
1066
1382
  });
1067
- if (p.isCancel(saveChoice)) {
1068
- p.cancel("Cancelled.");
1383
+ if (p2.isCancel(saveChoice)) {
1384
+ p2.cancel("Cancelled.");
1069
1385
  return null;
1070
1386
  }
1071
1387
  if (simulate) {
@@ -1078,12 +1394,12 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1078
1394
  profile: `Would append OPENCODE_API_KEY export to ${display}`,
1079
1395
  session: "Would use key for this session only"
1080
1396
  };
1081
- p.log.info(`[dry-run] ${dryRunMessages[saveChoice]}`);
1397
+ p2.log.info(`[dry-run] ${dryRunMessages[saveChoice]}`);
1082
1398
  } else if (saveChoice === "keychain") {
1083
1399
  if (await saveToCredentialStore(trimmedKey)) {
1084
- p.log.success("Key saved to macOS Keychain \u2014 active now and automatically loaded next time.");
1400
+ p2.log.success("Key saved to macOS Keychain \u2014 active now and automatically loaded next time.");
1085
1401
  } else {
1086
- p.log.warn("Could not write to Keychain \u2014 key will be used for this session only");
1402
+ p2.log.warn("Could not write to Keychain \u2014 key will be used for this session only");
1087
1403
  }
1088
1404
  } else if (saveChoice === "keychain-autoload") {
1089
1405
  if (await saveToCredentialStore(trimmedKey)) {
@@ -1096,33 +1412,33 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1096
1412
  ${autoLoadLine}
1097
1413
  `);
1098
1414
  }
1099
- p.log.success(`Key saved to Keychain and auto-load added to ${display} \u2014 active now and in all future terminals.`);
1415
+ p2.log.success(`Key saved to Keychain and auto-load added to ${display} \u2014 active now and in all future terminals.`);
1100
1416
  } catch {
1101
- p.log.success("Key saved to Keychain \u2014 active now and automatically loaded next time.");
1102
- p.log.warn(`Could not write auto-load line to ${display}`);
1417
+ p2.log.success("Key saved to Keychain \u2014 active now and automatically loaded next time.");
1418
+ p2.log.warn(`Could not write auto-load line to ${display}`);
1103
1419
  }
1104
1420
  } else {
1105
- p.log.warn("Could not write to Keychain \u2014 key will be used for this session only");
1421
+ p2.log.warn("Could not write to Keychain \u2014 key will be used for this session only");
1106
1422
  }
1107
1423
  } else if (saveChoice === "credential-manager") {
1108
1424
  if (await saveToCredentialStore(trimmedKey)) {
1109
- p.log.success("Key saved to Windows Credential Manager \u2014 active now and automatically loaded next time.");
1425
+ p2.log.success("Key saved to Windows Credential Manager \u2014 active now and automatically loaded next time.");
1110
1426
  } else {
1111
- p.log.warn("Could not write to Credential Manager \u2014 key will be used for this session only");
1427
+ p2.log.warn("Could not write to Credential Manager \u2014 key will be used for this session only");
1112
1428
  }
1113
1429
  } else if (saveChoice === "setx") {
1114
1430
  try {
1115
1431
  const result = spawnSync("setx", ["OPENCODE_API_KEY", trimmedKey], { stdio: ["pipe", "pipe", "pipe"] });
1116
1432
  if (result.status !== 0) throw new Error("setx exited with non-zero status");
1117
- p.log.success("Key saved as a user environment variable \u2014 active now and in all future terminals.");
1433
+ p2.log.success("Key saved as a user environment variable \u2014 active now and in all future terminals.");
1118
1434
  } catch {
1119
- p.log.warn("Could not run setx \u2014 key will be used for this session only");
1435
+ p2.log.warn("Could not run setx \u2014 key will be used for this session only");
1120
1436
  }
1121
1437
  } else if (saveChoice === "secret-service") {
1122
1438
  if (await saveToCredentialStore(trimmedKey)) {
1123
- p.log.success("Key saved to Secret Service \u2014 active now and automatically loaded next time.");
1439
+ p2.log.success("Key saved to Secret Service \u2014 active now and automatically loaded next time.");
1124
1440
  } else {
1125
- p.log.warn("Could not write to Secret Service \u2014 key will be used for this session only");
1441
+ p2.log.warn("Could not write to Secret Service \u2014 key will be used for this session only");
1126
1442
  }
1127
1443
  } else if (saveChoice === "profile") {
1128
1444
  try {
@@ -1131,9 +1447,9 @@ ${autoLoadLine}
1131
1447
  appendFileSync(path2, `
1132
1448
  export OPENCODE_API_KEY='${escapedKey}'
1133
1449
  `);
1134
- p.log.success(`Key saved to ${display} \u2014 active now and in all future terminals.`);
1450
+ p2.log.success(`Key saved to ${display} \u2014 active now and in all future terminals.`);
1135
1451
  } catch {
1136
- p.log.warn(`Could not write to ${display} \u2014 key will be used for this session only`);
1452
+ p2.log.warn(`Could not write to ${display} \u2014 key will be used for this session only`);
1137
1453
  }
1138
1454
  }
1139
1455
  if (!simulate) process.env["OPENCODE_API_KEY"] = trimmedKey;
@@ -1159,28 +1475,28 @@ async function runFirstRunWizard(trace = false) {
1159
1475
  const options = [
1160
1476
  {
1161
1477
  value: "zen",
1162
- label: pc.cyan("Quick start with OpenCode Zen (free)"),
1478
+ label: pc2.cyan("Quick start with OpenCode Zen (free)"),
1163
1479
  hint: "Enter your API key and pick a model \u2014 launches Claude Code"
1164
1480
  },
1165
1481
  {
1166
1482
  value: "providers",
1167
- label: pc.cyan("Set up your own AI provider"),
1483
+ label: pc2.cyan("Set up your own AI provider"),
1168
1484
  hint: hasOpencode ? "Import providers you configured in OpenCode" : "Import from OpenCode or add providers via anygate providers"
1169
1485
  }
1170
1486
  ];
1171
1487
  if (hasOpencode) {
1172
1488
  options.push({
1173
1489
  value: "import",
1174
- label: pc.cyan("Bring settings from OpenCode"),
1490
+ label: pc2.cyan("Bring settings from OpenCode"),
1175
1491
  hint: "One-time import of your OpenCode provider config"
1176
1492
  });
1177
1493
  }
1178
- const choice = await p2.select({
1494
+ const choice = await p3.select({
1179
1495
  message: "How do you want to get started?",
1180
1496
  options
1181
1497
  });
1182
- if (p2.isCancel(choice)) {
1183
- p2.cancel("Cancelled.");
1498
+ if (p3.isCancel(choice)) {
1499
+ p3.cancel("Cancelled.");
1184
1500
  return "cancel";
1185
1501
  }
1186
1502
  if (choice === "zen") {
@@ -1188,40 +1504,40 @@ async function runFirstRunWizard(trace = false) {
1188
1504
  if (!apiKey) return "cancel";
1189
1505
  await upgradeGlobalOpencodeCredential();
1190
1506
  ensureZenRegistryStub();
1191
- p2.log.success("OpenCode Zen ready \u2014 picking a model next.");
1507
+ p3.log.success("OpenCode Zen ready \u2014 picking a model next.");
1192
1508
  return "continue";
1193
1509
  }
1194
1510
  if (choice === "import" || choice === "providers") {
1195
1511
  if (!hasOpencode && choice === "import") {
1196
- p2.log.error("OpenCode CLI not found. Install from https://opencode.ai");
1512
+ p3.log.error("OpenCode CLI not found. Install from https://opencode.ai");
1197
1513
  return runFirstRunWizard(trace);
1198
1514
  }
1199
1515
  if (!hasOpencode) {
1200
- p2.log.info("Run anygate providers to add providers, then anygate claude again.");
1201
- p2.log.info("Quick start with Zen is the fastest path if you have an OpenCode API key.");
1202
- const retry = await p2.select({
1516
+ p3.log.info("Run anygate providers to add providers, then anygate claude again.");
1517
+ p3.log.info("Quick start with Zen is the fastest path if you have an OpenCode API key.");
1518
+ const retry = await p3.select({
1203
1519
  message: "What next?",
1204
1520
  options: [
1205
1521
  { value: "zen", label: "Quick start with OpenCode Zen", hint: "" },
1206
1522
  { value: "cancel", label: "Cancel", hint: "" }
1207
1523
  ]
1208
1524
  });
1209
- if (p2.isCancel(retry) || retry === "cancel") return "cancel";
1525
+ if (p3.isCancel(retry) || retry === "cancel") return "cancel";
1210
1526
  return runFirstRunWizard(trace);
1211
1527
  }
1212
- const spinner10 = p2.spinner();
1528
+ const spinner10 = p3.spinner();
1213
1529
  spinner10.start("Importing from OpenCode...");
1214
1530
  const result = await importFromOpencode();
1215
1531
  spinner10.stop("");
1216
1532
  if (result.error) {
1217
- p2.log.error(result.error);
1533
+ p3.log.error(result.error);
1218
1534
  return runFirstRunWizard(trace);
1219
1535
  }
1220
1536
  if (result.imported.length === 0) {
1221
- p2.log.warn("No providers imported. Configure providers in OpenCode first, or use Quick start with Zen.");
1537
+ p3.log.warn("No providers imported. Configure providers in OpenCode first, or use Quick start with Zen.");
1222
1538
  return runFirstRunWizard(trace);
1223
1539
  }
1224
- p2.log.success(
1540
+ p3.log.success(
1225
1541
  `Imported ${result.imported.length} provider${result.imported.length === 1 ? "" : "s"}.`
1226
1542
  );
1227
1543
  return "continue";
@@ -1233,8 +1549,8 @@ async function runFirstRunWizard(trace = false) {
1233
1549
  init_config();
1234
1550
 
1235
1551
  // src/apps/shared/prompts.ts
1236
- import * as p3 from "@clack/prompts";
1237
- import pc2 from "picocolors";
1552
+ import * as p4 from "@clack/prompts";
1553
+ import pc3 from "picocolors";
1238
1554
 
1239
1555
  // src/apps/shared/model-search.ts
1240
1556
  function normalizeModelSearchText(value) {
@@ -1342,12 +1658,12 @@ async function pickModelFromPagedList(list, toOption, messagePrefix, initialMode
1342
1658
  options.push(navOption(SWITCH_SEARCH, "\u2190 New search", ""));
1343
1659
  }
1344
1660
  const initialValue = (initialModelId && pageItems.some((m) => m.id === initialModelId) ? initialModelId : pageItems[0]?.id) ?? options[0]?.value;
1345
- const picked = await p3.select({
1661
+ const picked = await p4.select({
1346
1662
  message: `${messagePrefix} (page ${currentPage + 1} of ${totalPages})`,
1347
1663
  options,
1348
1664
  initialValue
1349
1665
  });
1350
- if (p3.isCancel(picked)) return "menu";
1666
+ if (p4.isCancel(picked)) return "menu";
1351
1667
  const choice = String(picked);
1352
1668
  if (choice === PAGE_PREV) {
1353
1669
  page = currentPage - 1;
@@ -1368,19 +1684,19 @@ async function selectLargeCatalog(models, browseList, toOption, message, initial
1368
1684
  let mode = "choose";
1369
1685
  while (true) {
1370
1686
  if (mode === "choose") {
1371
- const method = await p3.select({
1687
+ const method = await p4.select({
1372
1688
  message: `${message} (${models.length} available)`,
1373
1689
  options: [
1374
- { value: MODE_SEARCH, label: pc2.cyan("Search models"), hint: "Filter by name, id, or brand" },
1690
+ { value: MODE_SEARCH, label: pc3.cyan("Search models"), hint: "Filter by name, id, or brand" },
1375
1691
  {
1376
1692
  value: MODE_BROWSE,
1377
- label: pc2.cyan("Browse all models"),
1693
+ label: pc3.cyan("Browse all models"),
1378
1694
  hint: `${MODEL_PAGE_SIZE} per page \xB7 ${Math.ceil(browseList.length / MODEL_PAGE_SIZE)} pages`
1379
1695
  },
1380
1696
  navOption("__back__", "\u2190 Go back", "Select a different provider")
1381
1697
  ]
1382
1698
  });
1383
- if (p3.isCancel(method) || String(method) === "__back__") {
1699
+ if (p4.isCancel(method) || String(method) === "__back__") {
1384
1700
  return "back";
1385
1701
  }
1386
1702
  mode = method === MODE_BROWSE ? "browse" : "search";
@@ -1405,17 +1721,17 @@ async function selectLargeCatalog(models, browseList, toOption, message, initial
1405
1721
  if (isSelectedModel(picked)) return picked;
1406
1722
  continue;
1407
1723
  }
1408
- const searchInput = await p3.text({
1724
+ const searchInput = await p4.text({
1409
1725
  message: `Search models (${models.length} available):`,
1410
1726
  placeholder: "e.g. claude, sonnet, llama"
1411
1727
  });
1412
- if (p3.isCancel(searchInput)) {
1728
+ if (p4.isCancel(searchInput)) {
1413
1729
  mode = "choose";
1414
1730
  continue;
1415
1731
  }
1416
1732
  const matched = filterModelsBySearch(browseList, String(searchInput));
1417
1733
  if (matched.length === 0) {
1418
- p3.log.warn("No models match \u2014 try a different search");
1734
+ p4.log.warn("No models match \u2014 try a different search");
1419
1735
  continue;
1420
1736
  }
1421
1737
  const result = await pickModelFromPagedList(
@@ -1446,12 +1762,12 @@ async function selectModelWithSearch(models, toOption, message, initialModelId,
1446
1762
  navOption("__back__", "\u2190 Go back", "")
1447
1763
  ];
1448
1764
  const initialValue = initialModelId && options.some((o) => o.value === initialModelId) ? initialModelId : options[0]?.value;
1449
- const picked = await p3.select({
1765
+ const picked = await p4.select({
1450
1766
  message,
1451
1767
  options,
1452
1768
  initialValue
1453
1769
  });
1454
- if (p3.isCancel(picked) || String(picked) === "__back__") {
1770
+ if (p4.isCancel(picked) || String(picked) === "__back__") {
1455
1771
  return "back";
1456
1772
  }
1457
1773
  const selected = models.find((m) => m.id === String(picked));
@@ -1485,12 +1801,12 @@ async function pickLocalModel(provider, conflicts, prefs) {
1485
1801
  navOption(BROWSE_ALL, "Browse all models \u2192", `${provider.models.length} available`),
1486
1802
  navOption("__back__", "\u2190 Go back", "Select a different provider")
1487
1803
  ];
1488
- const picked = await p3.select({
1804
+ const picked = await p4.select({
1489
1805
  message: "Which model?",
1490
1806
  options,
1491
1807
  initialValue: recentModels[0].id
1492
1808
  });
1493
- if (p3.isCancel(picked) || String(picked) === "__back__") {
1809
+ if (p4.isCancel(picked) || String(picked) === "__back__") {
1494
1810
  return "back";
1495
1811
  }
1496
1812
  if (String(picked) === BROWSE_ALL) {
@@ -1517,12 +1833,12 @@ async function pickLocalModel(provider, conflicts, prefs) {
1517
1833
  }
1518
1834
  noteEnvConflicts(conflicts);
1519
1835
  const modelLabel = formatCodexModelLabel(selectedModel);
1520
- const confirmed = await p3.confirm({
1836
+ const confirmed = await p4.confirm({
1521
1837
  message: confirmLaunchMessage("Claude Code", modelLabel, selectedModel.id, provider.name),
1522
1838
  initialValue: true
1523
1839
  });
1524
- if (p3.isCancel(confirmed) || !confirmed) {
1525
- p3.cancel("Cancelled.");
1840
+ if (p4.isCancel(confirmed) || !confirmed) {
1841
+ p4.cancel("Cancelled.");
1526
1842
  return null;
1527
1843
  }
1528
1844
  gateOutro("Launching", fmtModel(modelLabel, selectedModel.id));
@@ -1538,7 +1854,7 @@ async function resolveLocalProviderApiKey(provider) {
1538
1854
  if (template?.apiKeyOptional || template?.anonymousFreeModels) {
1539
1855
  return "anonymous";
1540
1856
  }
1541
- const reg = loadRegistry().providers.find((p17) => p17.id === provider.id);
1857
+ const reg = loadRegistry().providers.find((p18) => p18.id === provider.id);
1542
1858
  const authRef = reg?.authRef ?? (provider.id === "zen" || provider.id === "go" ? "keyring:global:opencode" : oauthAuthRef(provider.id));
1543
1859
  return resolveProviderCredential(provider.id, authRef);
1544
1860
  }
@@ -1645,7 +1961,7 @@ function resolveLaunchTarget(explicit, prefs, agent) {
1645
1961
  }
1646
1962
  function findProviderAndModel(providers, target) {
1647
1963
  if (!target.providerId || !target.modelId) return null;
1648
- const provider = providers.find((p17) => p17.id === target.providerId);
1964
+ const provider = providers.find((p18) => p18.id === target.providerId);
1649
1965
  if (!provider) return null;
1650
1966
  const model = provider.models.find((m) => m.id === target.modelId);
1651
1967
  if (!model) return null;
@@ -1709,8 +2025,8 @@ function isAntigravityNonInteractive(args) {
1709
2025
  }
1710
2026
 
1711
2027
  // src/cli/providers-command.ts
1712
- import pc3 from "picocolors";
1713
- import * as p4 from "@clack/prompts";
2028
+ import pc4 from "picocolors";
2029
+ import * as p5 from "@clack/prompts";
1714
2030
  init_config();
1715
2031
  function providerHubChoiceValue(entry) {
1716
2032
  return `provider:${entry.id}`;
@@ -1720,54 +2036,54 @@ async function runProvidersImport() {
1720
2036
  const hasExisting = registry.providers.length > 0;
1721
2037
  const resolveConflict = hasExisting ? async (ctx) => {
1722
2038
  printImportConflictPanel(ctx.existing.name, ctx.existingKeyHint, ctx.incomingKeyHint);
1723
- const choice = await p4.select({
2039
+ const choice = await p5.select({
1724
2040
  message: "Which configuration should we keep?",
1725
2041
  options: [
1726
- { value: "keep", label: pc3.cyan("Keep mine"), hint: "Leave your current anygate config unchanged" },
1727
- { value: "import", label: pc3.cyan("Use imported"), hint: "Replace with OpenCode settings and refresh models" },
1728
- { value: "skip", label: pc3.dim("Skip this provider"), hint: "" }
2042
+ { value: "keep", label: pc4.cyan("Keep mine"), hint: "Leave your current anygate config unchanged" },
2043
+ { value: "import", label: pc4.cyan("Use imported"), hint: "Replace with OpenCode settings and refresh models" },
2044
+ { value: "skip", label: pc4.dim("Skip this provider"), hint: "" }
1729
2045
  ]
1730
2046
  });
1731
- if (p4.isCancel(choice)) return "skip";
2047
+ if (p5.isCancel(choice)) return "skip";
1732
2048
  return choice;
1733
2049
  } : void 0;
1734
- const spinner10 = p4.spinner();
2050
+ const spinner10 = p5.spinner();
1735
2051
  spinner10.start("Importing from OpenCode...");
1736
2052
  const result = await importFromOpencode({ resolveConflict });
1737
2053
  spinner10.stop("");
1738
2054
  if (result.error) {
1739
- p4.log.error(result.error);
2055
+ p5.log.error(result.error);
1740
2056
  return 1;
1741
2057
  }
1742
2058
  if (result.imported.length === 0 && result.skipped.length === 0) {
1743
- p4.log.warn("No configured providers found in OpenCode.");
1744
- p4.log.info("Add providers in OpenCode first, or use anygate providers add.");
2059
+ p5.log.warn("No configured providers found in OpenCode.");
2060
+ p5.log.info("Add providers in OpenCode first, or use anygate providers add.");
1745
2061
  return 0;
1746
2062
  }
1747
2063
  if (result.authFileWarning) {
1748
- p4.log.warn(result.authFileWarning);
2064
+ p5.log.warn(result.authFileWarning);
1749
2065
  }
1750
2066
  const importedNames = result.imported.map((pr) => pr.name).join(", ");
1751
2067
  const modelTotal = result.imported.reduce((n, pr) => n + (pr.modelsCache?.models.length ?? 0), 0);
1752
2068
  const credNote = result.oauthImported > 0 ? ` (${result.oauthImported} via OAuth)` : "";
1753
- p4.log.success(
2069
+ p5.log.success(
1754
2070
  `Imported ${importedNames} \u2014 ${modelTotal} model${modelTotal === 1 ? "" : "s"}, ${result.keysSaved} credential${result.keysSaved === 1 ? "" : "s"} saved to Keychain${credNote}.`
1755
2071
  );
1756
2072
  if (result.skipped.length > 0) {
1757
2073
  for (const s of result.skipped) {
1758
2074
  const reason = s.reason === "user-skipped" ? "skipped by you" : s.reason === "conflict-kept" ? "kept your existing config" : s.reason === "oauth-no-token" ? "OAuth provider in OpenCode but not signed in \u2014 run anygate providers auth" : s.reason === "no-api-key" ? "no API key in OpenCode \u2014 add key there or use anygate providers add" : s.reason === "manual-only" ? "uses gcloud/AWS credentials \u2014 not importable via API key" : s.reason === "placeholder-key" ? "placeholder API key \u2014 provider not imported" : s.reason === "invalid-key" ? "API key failed verification \u2014 provider not imported" : s.reason === "credential-save-failed" ? "could not save credential \u2014 provider not imported" : s.reason;
1759
- p4.log.warn(`Skipped ${s.name} (${s.id}): ${reason}`);
2075
+ p5.log.warn(`Skipped ${s.name} (${s.id}): ${reason}`);
1760
2076
  }
1761
2077
  }
1762
2078
  if (result.keysSkipped.length > 0) {
1763
2079
  for (const k of result.keysSkipped) {
1764
2080
  if (k.detail) {
1765
- p4.log.info(`${k.name} (${k.id}): ${k.detail}`);
2081
+ p5.log.info(`${k.name} (${k.id}): ${k.detail}`);
1766
2082
  }
1767
2083
  }
1768
2084
  }
1769
2085
  if (result.imported.length > 0) {
1770
- const refreshSpinner = p4.spinner();
2086
+ const refreshSpinner = p5.spinner();
1771
2087
  refreshSpinner.start("Fetching model capabilities from providers...");
1772
2088
  const currentReg = loadRegistry();
1773
2089
  for (const provider of result.imported) {
@@ -1784,14 +2100,14 @@ async function runProvidersImport() {
1784
2100
  async function runProvidersAuth(providerId, method) {
1785
2101
  try {
1786
2102
  const result = await authenticateProvider(providerId, { method });
1787
- p4.log.success(`Signed in to ${result.registryProvider.name} \u2014 credential saved to Keychain.`);
2103
+ p5.log.success(`Signed in to ${result.registryProvider.name} \u2014 credential saved to Keychain.`);
1788
2104
  return 0;
1789
2105
  } catch (err) {
1790
2106
  if (err instanceof Error && err.message === "Cancelled") {
1791
- p4.cancel("Cancelled.");
2107
+ p5.cancel("Cancelled.");
1792
2108
  return 0;
1793
2109
  }
1794
- p4.log.error(err instanceof Error ? err.message : String(err));
2110
+ p5.log.error(err instanceof Error ? err.message : String(err));
1795
2111
  return 1;
1796
2112
  }
1797
2113
  }
@@ -1799,41 +2115,41 @@ async function runProvidersRemove(id, interactive = false) {
1799
2115
  const registry = loadRegistry();
1800
2116
  const provider = registry.providers.find((pr) => pr.id === id);
1801
2117
  if (!provider) {
1802
- p4.log.error(`Provider not found: ${id}`);
2118
+ p5.log.error(`Provider not found: ${id}`);
1803
2119
  return 1;
1804
2120
  }
1805
2121
  if (interactive) {
1806
- const confirm10 = await p4.confirm({
2122
+ const confirm11 = await p5.confirm({
1807
2123
  message: `Remove ${provider.name} (${id})?`,
1808
2124
  initialValue: false
1809
2125
  });
1810
- if (p4.isCancel(confirm10) || !confirm10) {
1811
- p4.cancel("Cancelled.");
2126
+ if (p5.isCancel(confirm11) || !confirm11) {
2127
+ p5.cancel("Cancelled.");
1812
2128
  return 0;
1813
2129
  }
1814
2130
  }
1815
2131
  const result = await removeProviderFromRegistry(id);
1816
2132
  if (!result.removed) {
1817
- p4.log.error(result.error ?? `Could not remove ${id}`);
2133
+ p5.log.error(result.error ?? `Could not remove ${id}`);
1818
2134
  return 1;
1819
2135
  }
1820
- p4.log.success(`Removed ${result.name ?? id}.`);
2136
+ p5.log.success(`Removed ${result.name ?? id}.`);
1821
2137
  if (result.credentialDeleted) {
1822
- p4.log.info("Provider API key removed from Keychain.");
2138
+ p5.log.info("Provider API key removed from Keychain.");
1823
2139
  }
1824
2140
  return 0;
1825
2141
  }
1826
2142
  async function runProvidersList() {
1827
2143
  const entries = await resolveProvidersForDisplay();
1828
2144
  if (entries.length === 0) {
1829
- p4.log.info("No providers configured. Run anygate providers add or import.");
2145
+ p5.log.info("No providers configured. Run anygate providers add or import.");
1830
2146
  return 0;
1831
2147
  }
1832
2148
  console.log("");
1833
2149
  for (const entry of entries) {
1834
- const status = entry.enabled ? pc3.green("\u25CF") : pc3.dim("\u25CB");
2150
+ const status = entry.enabled ? pc4.green("\u25CF") : pc4.dim("\u25CB");
1835
2151
  console.log(
1836
- ` ${status} ${pc3.bold(entry.name)} ${pc3.dim(`(${entry.id})`)} \u2014 ${entry.modelCount} model${entry.modelCount === 1 ? "" : "s"}, auth: ${entry.authLabel}`
2152
+ ` ${status} ${pc4.bold(entry.name)} ${pc4.dim(`(${entry.id})`)} \u2014 ${entry.modelCount} model${entry.modelCount === 1 ? "" : "s"}, auth: ${entry.authLabel}`
1837
2153
  );
1838
2154
  }
1839
2155
  console.log("");
@@ -1845,10 +2161,10 @@ async function runProvidersRefreshModels(providerId) {
1845
2161
  const registry = loadRegistry();
1846
2162
  const provider = registry.providers.find((pItem) => pItem.id === providerId);
1847
2163
  if (!provider) {
1848
- p4.log.error(`Provider not found: ${providerId}`);
2164
+ p5.log.error(`Provider not found: ${providerId}`);
1849
2165
  return 1;
1850
2166
  }
1851
- const spinner11 = p4.spinner();
2167
+ const spinner11 = p5.spinner();
1852
2168
  spinner11.start(`Refreshing ${provider.name}...`);
1853
2169
  const key = await resolveRefreshCredential(
1854
2170
  provider,
@@ -1858,22 +2174,22 @@ async function runProvidersRefreshModels(providerId) {
1858
2174
  spinner11.stop("");
1859
2175
  if (result.skipped) {
1860
2176
  const countNote = result.modelCount ? ` (${result.modelCount} cached models kept)` : "";
1861
- p4.log.warn(`${result.name}: ${result.reason}${countNote}`);
2177
+ p5.log.warn(`${result.name}: ${result.reason}${countNote}`);
1862
2178
  return 0;
1863
2179
  }
1864
2180
  if (!result.ok) {
1865
- p4.log.error(`${result.name}: ${result.reason ?? "Refresh failed."}`);
2181
+ p5.log.error(`${result.name}: ${result.reason ?? "Refresh failed."}`);
1866
2182
  return 1;
1867
2183
  }
1868
2184
  const diff = result.previousModelCount === void 0 ? 0 : (result.modelCount ?? 0) - result.previousModelCount;
1869
2185
  const diffStr = result.previousModelCount === void 0 ? "" : diff > 0 ? ` (+${diff})` : diff < 0 ? ` (${diff})` : "";
1870
- p4.log.success(`${result.name}: ${result.modelCount} model${result.modelCount === 1 ? "" : "s"} updated${diffStr}.`);
2186
+ p5.log.success(`${result.name}: ${result.modelCount} model${result.modelCount === 1 ? "" : "s"} updated${diffStr}.`);
1871
2187
  if (result.reason) {
1872
- p4.log.warn(result.reason);
2188
+ p5.log.warn(result.reason);
1873
2189
  }
1874
2190
  return 0;
1875
2191
  }
1876
- const spinner10 = p4.spinner();
2192
+ const spinner10 = p5.spinner();
1877
2193
  spinner10.start("Refreshing model lists...");
1878
2194
  const { refreshed } = await refreshAllProviderModels(resolveKey);
1879
2195
  spinner10.stop("");
@@ -1881,22 +2197,22 @@ async function runProvidersRefreshModels(providerId) {
1881
2197
  const skipped = refreshed.filter((r) => r.skipped);
1882
2198
  const failed = refreshed.filter((r) => !r.ok);
1883
2199
  if (ok.length > 0) {
1884
- p4.log.success(`Updated ${ok.length} provider${ok.length === 1 ? "" : "s"}.`);
2200
+ p5.log.success(`Updated ${ok.length} provider${ok.length === 1 ? "" : "s"}.`);
1885
2201
  for (const r of ok) {
1886
2202
  const diff = r.previousModelCount === void 0 ? 0 : (r.modelCount ?? 0) - r.previousModelCount;
1887
2203
  const diffStr = r.previousModelCount === void 0 ? "" : diff > 0 ? ` (+${diff})` : diff < 0 ? ` (${diff})` : "";
1888
- p4.log.info(` ${r.name}: ${r.modelCount} model${r.modelCount === 1 ? "" : "s"}${diffStr}`);
2204
+ p5.log.info(` ${r.name}: ${r.modelCount} model${r.modelCount === 1 ? "" : "s"}${diffStr}`);
1889
2205
  if (r.reason) {
1890
- p4.log.warn(` ${r.reason}`);
2206
+ p5.log.warn(` ${r.reason}`);
1891
2207
  }
1892
2208
  }
1893
2209
  }
1894
2210
  for (const r of skipped) {
1895
2211
  const countNote = r.modelCount ? ` (${r.modelCount} cached models kept)` : "";
1896
- p4.log.warn(`Skipped ${r.name}: ${r.reason}${countNote}`);
2212
+ p5.log.warn(`Skipped ${r.name}: ${r.reason}${countNote}`);
1897
2213
  }
1898
2214
  for (const r of failed) {
1899
- p4.log.error(`${r.name}: ${r.reason ?? "Refresh failed."}`);
2215
+ p5.log.error(`${r.name}: ${r.reason ?? "Refresh failed."}`);
1900
2216
  }
1901
2217
  return failed.length > 0 ? 1 : 0;
1902
2218
  }
@@ -1906,7 +2222,7 @@ async function pickTemplateFromCatalog() {
1906
2222
  const configuredIds = new Set(registry.providers.map((pItem) => pItem.id));
1907
2223
  const templates = listAddableTemplates(configuredIds);
1908
2224
  if (templates.length === 0) return null;
1909
- const method = await p4.select({
2225
+ const method = await p5.select({
1910
2226
  message: `Choose a provider (${templates.length} available)`,
1911
2227
  options: [
1912
2228
  { value: "search", label: "Search providers", hint: "e.g. gro, mistral, together" },
@@ -1914,32 +2230,32 @@ async function pickTemplateFromCatalog() {
1914
2230
  { value: "back", label: "Back", hint: "" }
1915
2231
  ]
1916
2232
  });
1917
- if (p4.isCancel(method) || method === "back") return null;
2233
+ if (p5.isCancel(method) || method === "back") return null;
1918
2234
  if (method === "browse") {
1919
2235
  const options2 = templates.map((t) => ({
1920
2236
  value: t.id,
1921
2237
  label: t.name,
1922
2238
  hint: t.npm
1923
2239
  }));
1924
- const picked2 = await p4.select({ message: "Select a provider", options: options2 });
1925
- if (p4.isCancel(picked2)) continue;
2240
+ const picked2 = await p5.select({ message: "Select a provider", options: options2 });
2241
+ if (p5.isCancel(picked2)) continue;
1926
2242
  const template2 = templates.find((t) => t.id === picked2);
1927
2243
  if (template2) return template2;
1928
2244
  continue;
1929
2245
  }
1930
- const searchInput = await p4.text({
2246
+ const searchInput = await p5.text({
1931
2247
  message: "Search providers:",
1932
2248
  placeholder: "e.g. groq, mistral, openrouter"
1933
2249
  });
1934
- if (p4.isCancel(searchInput)) continue;
2250
+ if (p5.isCancel(searchInput)) continue;
1935
2251
  const query = String(searchInput);
1936
2252
  const matched = filterTemplates(templates, query);
1937
2253
  if (matched.length === 0) {
1938
2254
  const alreadyAdded = filterTemplates(listSupportedTemplates(), query).filter((t) => configuredIds.has(t.id));
1939
2255
  if (alreadyAdded.length > 0) {
1940
- p4.log.info(`Already configured: ${alreadyAdded.map((t) => t.name).join(", ")}`);
2256
+ p5.log.info(`Already configured: ${alreadyAdded.map((t) => t.name).join(", ")}`);
1941
2257
  } else {
1942
- p4.log.warn("No providers match \u2014 try a different search");
2258
+ p5.log.warn("No providers match \u2014 try a different search");
1943
2259
  }
1944
2260
  continue;
1945
2261
  }
@@ -1948,11 +2264,11 @@ async function pickTemplateFromCatalog() {
1948
2264
  label: t.name,
1949
2265
  hint: t.npm
1950
2266
  }));
1951
- const picked = await p4.select({
2267
+ const picked = await p5.select({
1952
2268
  message: matched.length === 1 ? "Match found" : `Select provider (${matched.length} matches)`,
1953
2269
  options
1954
2270
  });
1955
- if (p4.isCancel(picked)) continue;
2271
+ if (p5.isCancel(picked)) continue;
1956
2272
  const template = matched.find((t) => t.id === picked);
1957
2273
  if (template) return template;
1958
2274
  }
@@ -1962,7 +2278,7 @@ async function runOpenCodeCloudDetail() {
1962
2278
  const routes = registry.providers.filter((provider) => provider.id === "zen" || provider.id === "go");
1963
2279
  printCloudProviderPanel("OpenCode Zen / Go");
1964
2280
  if (routes.length === 0) return "back";
1965
- const choice = await p4.select({
2281
+ const choice = await p5.select({
1966
2282
  message: "Manage an OpenCode catalog",
1967
2283
  options: [
1968
2284
  ...routes.map((provider) => ({
@@ -1973,7 +2289,7 @@ async function runOpenCodeCloudDetail() {
1973
2289
  { value: "back", label: "Back", hint: "" }
1974
2290
  ]
1975
2291
  });
1976
- if (!p4.isCancel(choice) && choice !== "back") {
2292
+ if (!p5.isCancel(choice) && choice !== "back") {
1977
2293
  await runProviderDetail(String(choice));
1978
2294
  }
1979
2295
  return "back";
@@ -2014,11 +2330,11 @@ async function runProviderDetail(id) {
2014
2330
  { value: "remove", label: "Remove provider", hint: "Delete from registry and Keychain when safe" },
2015
2331
  { value: "back", label: "Back", hint: "" }
2016
2332
  );
2017
- const action = await p4.select({
2333
+ const action = await p5.select({
2018
2334
  message: "What would you like to do?",
2019
2335
  options: detailOptions
2020
2336
  });
2021
- if (p4.isCancel(action) || action === "back") return "back";
2337
+ if (p5.isCancel(action) || action === "back") return "back";
2022
2338
  if (action === "browse") {
2023
2339
  const cachedModels = provider.modelsCache?.models ?? [];
2024
2340
  const localModels = cachedModels.map((m) => cachedModelToLocal(m, provider)).filter((m) => m !== null);
@@ -2042,7 +2358,7 @@ async function runProviderDetail(id) {
2042
2358
  if (action === "toggle") {
2043
2359
  const result = toggleProviderEnabled(id);
2044
2360
  if (result.toggled) {
2045
- p4.log.success(`${provider.name} ${result.enabled ? "enabled" : "disabled"}.`);
2361
+ p5.log.success(`${provider.name} ${result.enabled ? "enabled" : "disabled"}.`);
2046
2362
  }
2047
2363
  return "back";
2048
2364
  }
@@ -2050,7 +2366,7 @@ async function runProviderDetail(id) {
2050
2366
  return code === 0 ? "removed" : "back";
2051
2367
  }
2052
2368
  function providerLabel(name, modelCount, enabled) {
2053
- const status = enabled ? pc3.green("\u25CF") : pc3.dim("\u25CB");
2369
+ const status = enabled ? pc4.green("\u25CF") : pc4.dim("\u25CB");
2054
2370
  return `${status} ${name} (${modelCount} model${modelCount === 1 ? "" : "s"})`;
2055
2371
  }
2056
2372
  function parseProvidersArgs(args) {
@@ -2081,9 +2397,9 @@ function parseProvidersArgs(args) {
2081
2397
  return { subcommand: "hub", showHelp: false };
2082
2398
  }
2083
2399
  function providersHelpText() {
2084
- return `${pc3.bold("anygate providers")} \u2014 manage AI providers & model catalogs (Phase 1.1)
2400
+ return `${pc4.bold("anygate providers")} \u2014 manage AI providers & model catalogs (Phase 1.1)
2085
2401
 
2086
- ${pc3.bold("Usage:")}
2402
+ ${pc4.bold("Usage:")}
2087
2403
  anygate providers Open interactive provider manager
2088
2404
  anygate providers add Add a provider (template, custom, or import)
2089
2405
  anygate providers import Import providers from OpenCode CLI
@@ -2095,21 +2411,21 @@ ${pc3.bold("Usage:")}
2095
2411
  async function runTemplateAddFlow(t) {
2096
2412
  const template = t ?? await pickTemplateFromCatalog();
2097
2413
  if (!template) return 0;
2098
- const inputKey = await p4.password({
2414
+ const inputKey = await p5.password({
2099
2415
  message: `API key for ${template.name}${template.apiKeyOptional ? " (optional)" : ""}:`
2100
2416
  });
2101
- if (p4.isCancel(inputKey)) return 0;
2417
+ if (p5.isCancel(inputKey)) return 0;
2102
2418
  const apiKey = String(inputKey ?? "").trim();
2103
2419
  const result = await addProviderFromTemplate(template, apiKey);
2104
2420
  if (!result.added) {
2105
- if (result.error) p4.log.error(result.error);
2421
+ if (result.error) p5.log.error(result.error);
2106
2422
  return 1;
2107
2423
  }
2108
2424
  logConnected(template.name, result.modelCount ?? 0);
2109
2425
  return 0;
2110
2426
  }
2111
2427
  async function runCustomEndpointAddFlow() {
2112
- const kindChoice = await p4.select({
2428
+ const kindChoice = await p5.select({
2113
2429
  message: "Custom server type",
2114
2430
  options: [
2115
2431
  {
@@ -2125,52 +2441,52 @@ async function runCustomEndpointAddFlow() {
2125
2441
  { value: "back", label: "Back", hint: "" }
2126
2442
  ]
2127
2443
  });
2128
- if (p4.isCancel(kindChoice) || kindChoice === "back") return 0;
2129
- const displayName = await p4.text({
2444
+ if (p5.isCancel(kindChoice) || kindChoice === "back") return 0;
2445
+ const displayName = await p5.text({
2130
2446
  message: "Display name:",
2131
2447
  placeholder: "My Work LLM",
2132
2448
  validate: (v) => v.trim() ? void 0 : "Name is required"
2133
2449
  });
2134
- if (p4.isCancel(displayName)) return 0;
2135
- const baseUrl = await p4.text({
2450
+ if (p5.isCancel(displayName)) return 0;
2451
+ const baseUrl = await p5.text({
2136
2452
  message: "Base URL:",
2137
2453
  placeholder: kindChoice === "openai" ? "https://api.together.xyz/v1" : "https://api.anthropic.com",
2138
2454
  validate: (v) => v.trim() ? void 0 : "URL is required"
2139
2455
  });
2140
- if (p4.isCancel(baseUrl)) return 0;
2456
+ if (p5.isCancel(baseUrl)) return 0;
2141
2457
  const usesHttp = /^http:\/\//i.test(String(baseUrl).trim());
2142
2458
  let allowInsecureHttp = false;
2143
2459
  if (usesHttp) {
2144
- p4.log.warn("HTTP is not encrypted. Only use it for a trusted local or LAN server, like Ollama on your own network.");
2145
- const allowLocal = await p4.confirm({
2460
+ p5.log.warn("HTTP is not encrypted. Only use it for a trusted local or LAN server, like Ollama on your own network.");
2461
+ const allowLocal = await p5.confirm({
2146
2462
  message: "Allow insecure HTTP for this local/LAN server?",
2147
2463
  initialValue: true
2148
2464
  });
2149
- if (p4.isCancel(allowLocal)) return 0;
2465
+ if (p5.isCancel(allowLocal)) return 0;
2150
2466
  allowInsecureHttp = allowLocal === true;
2151
2467
  }
2152
- const apiKey = await p4.password({
2468
+ const apiKey = await p5.password({
2153
2469
  message: "API key (leave empty for local servers without auth):"
2154
2470
  });
2155
- if (p4.isCancel(apiKey)) return 0;
2156
- const wantsHeaders = await p4.confirm({
2471
+ if (p5.isCancel(apiKey)) return 0;
2472
+ const wantsHeaders = await p5.confirm({
2157
2473
  message: "Does this endpoint need extra custom headers? (e.g. a plan/auth-tracking header)",
2158
2474
  initialValue: false
2159
2475
  });
2160
- if (p4.isCancel(wantsHeaders)) return 0;
2476
+ if (p5.isCancel(wantsHeaders)) return 0;
2161
2477
  const headers = {};
2162
2478
  if (wantsHeaders) {
2163
2479
  for (; ; ) {
2164
- const headerLine = await p4.text({
2480
+ const headerLine = await p5.text({
2165
2481
  message: "Header (leave empty when done):",
2166
2482
  placeholder: "X-Plan: coding"
2167
2483
  });
2168
- if (p4.isCancel(headerLine)) return 0;
2484
+ if (p5.isCancel(headerLine)) return 0;
2169
2485
  const trimmed = String(headerLine).trim();
2170
2486
  if (!trimmed) break;
2171
2487
  const idx = trimmed.indexOf(":");
2172
2488
  if (idx < 1) {
2173
- p4.log.warn('Use the format "Name: Value" \u2014 skipped.');
2489
+ p5.log.warn('Use the format "Name: Value" \u2014 skipped.');
2174
2490
  continue;
2175
2491
  }
2176
2492
  const name = trimmed.slice(0, idx).trim();
@@ -2178,7 +2494,7 @@ async function runCustomEndpointAddFlow() {
2178
2494
  if (name) headers[name] = value;
2179
2495
  }
2180
2496
  }
2181
- const spinner10 = p4.spinner();
2497
+ const spinner10 = p5.spinner();
2182
2498
  spinner10.start("Testing connection...");
2183
2499
  const result = await addCustomEndpointProvider({
2184
2500
  displayName: String(displayName).trim(),
@@ -2190,8 +2506,8 @@ async function runCustomEndpointAddFlow() {
2190
2506
  });
2191
2507
  spinner10.stop("");
2192
2508
  if (!result.added) {
2193
- p4.log.error(result.error ?? "Could not add custom provider.");
2194
- if (result.hint) p4.log.info(result.hint);
2509
+ p5.log.error(result.error ?? "Could not add custom provider.");
2510
+ if (result.hint) p5.log.info(result.hint);
2195
2511
  return 1;
2196
2512
  }
2197
2513
  logConnected(result.provider?.name ?? "Provider", result.modelCount ?? 0);
@@ -2219,14 +2535,14 @@ async function runProvidersAdd() {
2219
2535
  label: "Import providers from OpenCode CLI",
2220
2536
  hint: hasOpencode ? "Import Groq, OpenAI, etc. from your OpenCode config" : "Requires OpenCode CLI"
2221
2537
  });
2222
- const choice = await p4.select({ message: "Add a provider", options });
2223
- if (p4.isCancel(choice)) {
2224
- p4.cancel("Cancelled.");
2538
+ const choice = await p5.select({ message: "Add a provider", options });
2539
+ if (p5.isCancel(choice)) {
2540
+ p5.cancel("Cancelled.");
2225
2541
  return 0;
2226
2542
  }
2227
2543
  if (choice === "import") {
2228
2544
  if (!hasOpencode) {
2229
- p4.log.error("OpenCode CLI not found. Install from https://opencode.ai");
2545
+ p5.log.error("OpenCode CLI not found. Install from https://opencode.ai");
2230
2546
  return 1;
2231
2547
  }
2232
2548
  return runProvidersImport();
@@ -2240,7 +2556,7 @@ async function runProvidersHub() {
2240
2556
  while (true) {
2241
2557
  const entries = await resolveProvidersForDisplay();
2242
2558
  const options = [
2243
- { value: "add", label: pc3.bold("+ Add a provider"), hint: "" }
2559
+ { value: "add", label: pc4.bold("+ Add a provider"), hint: "" }
2244
2560
  ];
2245
2561
  for (const entry of entries) {
2246
2562
  const hint = entry.id;
@@ -2259,11 +2575,11 @@ async function runProvidersHub() {
2259
2575
  options.push({ value: "import", label: "\u2192 Import providers from OpenCode CLI", hint: "One-time import" });
2260
2576
  }
2261
2577
  options.push({ value: "done", label: "Done", hint: "" });
2262
- const choice = await p4.select({
2578
+ const choice = await p5.select({
2263
2579
  message: entries.length > 0 ? "Your AI providers" : "Get started",
2264
2580
  options
2265
2581
  });
2266
- if (p4.isCancel(choice) || choice === "done") {
2582
+ if (p5.isCancel(choice) || choice === "done") {
2267
2583
  return 0;
2268
2584
  }
2269
2585
  if (choice === "add") {
@@ -2282,10 +2598,10 @@ async function runProvidersHub() {
2282
2598
  const configuredIds = loadRegistry().providers.map((provider) => provider.id);
2283
2599
  const oauthTemplates = listVisibleOAuthTemplates(configuredIds);
2284
2600
  if (oauthTemplates.length === 0) {
2285
- p4.log.info("All visible OAuth providers are already configured.");
2601
+ p5.log.info("All visible OAuth providers are already configured.");
2286
2602
  continue;
2287
2603
  }
2288
- const providerId = await p4.select({
2604
+ const providerId = await p5.select({
2289
2605
  message: "Which provider?",
2290
2606
  options: oauthTemplates.map((template) => ({
2291
2607
  value: template.id,
@@ -2293,7 +2609,7 @@ async function runProvidersHub() {
2293
2609
  hint: "device code"
2294
2610
  }))
2295
2611
  });
2296
- if (!p4.isCancel(providerId)) await runProvidersAuth(providerId);
2612
+ if (!p5.isCancel(providerId)) await runProvidersAuth(providerId);
2297
2613
  continue;
2298
2614
  }
2299
2615
  if (typeof choice === "string" && choice.startsWith("cloud:")) {
@@ -2311,7 +2627,7 @@ async function runProvidersHub() {
2311
2627
  async function runProvidersCommand(args) {
2312
2628
  const parsed = parseProvidersArgs(args);
2313
2629
  if (parsed.error) {
2314
- p4.log.error(parsed.error);
2630
+ p5.log.error(parsed.error);
2315
2631
  return 1;
2316
2632
  }
2317
2633
  if (parsed.showHelp) {
@@ -2341,7 +2657,7 @@ async function handleClaudeCommand(parsed) {
2341
2657
  setAgentStdoutMode(agentStdout);
2342
2658
  const claudePath = findClaudeBinary();
2343
2659
  if (!claudePath) {
2344
- console.error(pc4.red("\nError: claude binary not found on PATH.\n"));
2660
+ console.error(pc5.red("\nError: claude binary not found on PATH.\n"));
2345
2661
  console.error("Install Claude Code:");
2346
2662
  console.error(" npm install -g @anthropic-ai/claude-code\n");
2347
2663
  return 1;
@@ -2356,7 +2672,7 @@ async function handleClaudeCommand(parsed) {
2356
2672
  prefs
2357
2673
  });
2358
2674
  if (launchPlan.error) {
2359
- console.error(pc4.red(`
2675
+ console.error(pc5.red(`
2360
2676
  Error: ${launchPlan.error}
2361
2677
  `));
2362
2678
  return 1;
@@ -2364,7 +2680,7 @@ Error: ${launchPlan.error}
2364
2680
  const switchMenuActive = favorites.length > 0 && !launchPlan.skip;
2365
2681
  if (!agentStdout) gateIntro("Claude Code");
2366
2682
  if (setup && !dryRun && !agentStdout) {
2367
- p5.log.info("Provider setup now lives in anygate providers \u2014 opening that next is recommended.");
2683
+ p6.log.info("Provider setup now lives in anygate providers \u2014 opening that next is recommended.");
2368
2684
  }
2369
2685
  if (!dryRun && await needsFirstRunSetup()) {
2370
2686
  const firstRun = await runFirstRunWizard(trace);
@@ -2375,17 +2691,17 @@ Error: ${launchPlan.error}
2375
2691
  try {
2376
2692
  catalog = await fetchProviderCatalog();
2377
2693
  } catch (err) {
2378
- console.error(pc4.red(String(err instanceof Error ? err.message : err)));
2694
+ console.error(pc5.red(String(err instanceof Error ? err.message : err)));
2379
2695
  return 1;
2380
2696
  }
2381
2697
  } else {
2382
- const catalogSpinner = p5.spinner();
2698
+ const catalogSpinner = p6.spinner();
2383
2699
  catalogSpinner.start("Loading your providers...");
2384
2700
  try {
2385
2701
  catalog = await fetchProviderCatalog();
2386
2702
  } catch (err) {
2387
2703
  catalogSpinner.stop("");
2388
- console.error(pc4.red(String(err instanceof Error ? err.message : err)));
2704
+ console.error(pc5.red(String(err instanceof Error ? err.message : err)));
2389
2705
  return 1;
2390
2706
  }
2391
2707
  catalogSpinner.stop("");
@@ -2393,12 +2709,12 @@ Error: ${launchPlan.error}
2393
2709
  const allProvidersWithTemplates = await providersForPickerWithTemplates("claude");
2394
2710
  const allProviders = providersForTarget(allProvidersWithTemplates, "claude");
2395
2711
  if (allProviders.length === 0) {
2396
- p5.log.warn("No providers available.");
2397
- p5.log.info(pc4.dim("Run anygate providers add or import to get started."));
2712
+ p6.log.warn("No providers available.");
2713
+ p6.log.info(pc5.dim("Run anygate providers add or import to get started."));
2398
2714
  return 0;
2399
2715
  }
2400
- const configuredProviders = allProviders.filter((p17) => p17.inRegistry);
2401
- const templateProviders = allProviders.filter((p17) => !p17.inRegistry);
2716
+ const configuredProviders = allProviders.filter((p18) => p18.inRegistry);
2717
+ const templateProviders = allProviders.filter((p18) => !p18.inRegistry);
2402
2718
  const providerOptions = allProviders.map((lp) => {
2403
2719
  const baseOption = providerSelectOption(lp);
2404
2720
  if (!lp.inRegistry) {
@@ -2424,7 +2740,7 @@ Error: ${launchPlan.error}
2424
2740
  if (launchPlan.skip && launchPlan.target) {
2425
2741
  const resolved = findProviderAndModel(allProviders, launchPlan.target);
2426
2742
  if (!resolved) {
2427
- p5.log.error(
2743
+ p6.log.error(
2428
2744
  `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
2429
2745
  );
2430
2746
  return 1;
@@ -2432,19 +2748,19 @@ Error: ${launchPlan.error}
2432
2748
  activeProvider = resolved.provider;
2433
2749
  selectedModel = resolved.model;
2434
2750
  if (!agentStdout) {
2435
- p5.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
2751
+ p6.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
2436
2752
  }
2437
2753
  if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
2438
2754
  } else {
2439
2755
  let currentInitialProvider = initialProvider;
2440
2756
  while (true) {
2441
- const chosen = await p5.select({
2757
+ const chosen = await p6.select({
2442
2758
  message: "Which provider?",
2443
2759
  options: providerOptions,
2444
2760
  initialValue: currentInitialProvider
2445
2761
  });
2446
- if (p5.isCancel(chosen)) {
2447
- p5.cancel("Cancelled.");
2762
+ if (p6.isCancel(chosen)) {
2763
+ p6.cancel("Cancelled.");
2448
2764
  return 0;
2449
2765
  }
2450
2766
  const providerChoice = chosen;
@@ -2456,7 +2772,7 @@ Error: ${launchPlan.error}
2456
2772
  if (prov && mod) available.push({ provider: prov, model: mod });
2457
2773
  }
2458
2774
  if (available.length === 0) {
2459
- p5.log.warn("No saved favorites are currently available.");
2775
+ p6.log.warn("No saved favorites are currently available.");
2460
2776
  return 0;
2461
2777
  }
2462
2778
  const favOptions = available.map((f, i) => ({
@@ -2464,13 +2780,13 @@ Error: ${launchPlan.error}
2464
2780
  label: `${f.model.name || f.model.id} \u2014 ${f.provider.name}`,
2465
2781
  hint: f.model.id
2466
2782
  }));
2467
- const pickedIdx = await p5.select({
2783
+ const pickedIdx = await p6.select({
2468
2784
  message: "Starting model?",
2469
2785
  options: favOptions,
2470
2786
  initialValue: "0"
2471
2787
  });
2472
- if (p5.isCancel(pickedIdx)) {
2473
- p5.cancel("Cancelled.");
2788
+ if (p6.isCancel(pickedIdx)) {
2789
+ p6.cancel("Cancelled.");
2474
2790
  return 0;
2475
2791
  }
2476
2792
  const sel = available[Number(pickedIdx)];
@@ -2481,10 +2797,10 @@ Error: ${launchPlan.error}
2481
2797
  } else {
2482
2798
  const selectedProvider = allProviders.find((lp) => lp.id === providerChoice);
2483
2799
  if (!selectedProvider.inRegistry) {
2484
- p5.log.info(`Adding ${selectedProvider.name}...`);
2800
+ p6.log.info(`Adding ${selectedProvider.name}...`);
2485
2801
  const template = getTemplateById(selectedProvider.id);
2486
2802
  if (!template) {
2487
- p5.log.error(`Template not found for ${selectedProvider.id}`);
2803
+ p6.log.error(`Template not found for ${selectedProvider.id}`);
2488
2804
  continue;
2489
2805
  }
2490
2806
  const addResult = await runTemplateAddFlow(template);
@@ -2493,11 +2809,11 @@ Error: ${launchPlan.error}
2493
2809
  await providersForPickerWithTemplates("claude"),
2494
2810
  "claude"
2495
2811
  );
2496
- const newProvider = refreshedProviders.find((p17) => p17.id === selectedProvider.id);
2812
+ const newProvider = refreshedProviders.find((p18) => p18.id === selectedProvider.id);
2497
2813
  if (newProvider) {
2498
2814
  activeProvider = newProvider;
2499
2815
  } else {
2500
- p5.log.error(`Failed to reload provider after adding`);
2816
+ p6.log.error(`Failed to reload provider after adding`);
2501
2817
  continue;
2502
2818
  }
2503
2819
  } else {
@@ -2525,30 +2841,39 @@ Error: ${launchPlan.error}
2525
2841
  );
2526
2842
  const startingRoute = resolveRoute(activeProvider.id, selectedModel.id) ?? null;
2527
2843
  if (!startingRoute) {
2528
- p5.log.error("Could not resolve a proxy route for the selected model.");
2844
+ p6.log.error("Could not resolve a proxy route for the selected model.");
2529
2845
  return 1;
2530
2846
  }
2531
2847
  const { routes: catalogRoutes, droppedFavorites } = buildCatalogRoutes(startingRoute, favorites, resolveRoute);
2532
2848
  if (droppedFavorites.length > 0) {
2533
- p5.log.warn(
2849
+ p6.log.warn(
2534
2850
  `Skipping ${droppedFavorites.length} favorite${droppedFavorites.length === 1 ? "" : "s"} that are no longer available in /model`
2535
2851
  );
2536
2852
  }
2537
2853
  if (dryRun) {
2538
2854
  const endpoint = selectedModel.baseUrl ?? selectedModel.completionsUrl ?? "(unknown)";
2539
2855
  console.log("");
2540
- console.log(pc4.bold(pc4.cyan(" DRY RUN \u2014 would execute (switch-menu mode):")));
2856
+ console.log(pc5.bold(pc5.cyan(" DRY RUN \u2014 would execute (switch-menu mode):")));
2541
2857
  console.log("");
2542
- console.log(` ${pc4.bold("Provider:")} ${activeProvider.name}`);
2543
- console.log(` ${pc4.bold("Starting model:")} ${selectedModel.id}`);
2544
- console.log(` ${pc4.bold("Endpoint:")} ${endpoint}`);
2545
- console.log(` ${pc4.bold("/model catalog:")} ${catalogRoutes.length} model(s)`);
2546
- catalogRoutes.forEach((r) => console.log(` ${pc4.dim(r.displayName)}`));
2858
+ console.log(` ${pc5.bold("Provider:")} ${activeProvider.name}`);
2859
+ console.log(` ${pc5.bold("Starting model:")} ${selectedModel.id}`);
2860
+ console.log(` ${pc5.bold("Endpoint:")} ${endpoint}`);
2861
+ console.log(` ${pc5.bold("/model catalog:")} ${catalogRoutes.length} model(s)`);
2862
+ catalogRoutes.forEach((r) => console.log(` ${pc5.dim(r.displayName)}`));
2547
2863
  console.log("");
2548
- console.log(pc4.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
2864
+ console.log(pc5.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
2549
2865
  console.log("");
2550
2866
  return 0;
2551
2867
  }
2868
+ const isAvailable2 = await quickValidateModel(activeProvider.id, selectedModel.id);
2869
+ if (!isAvailable2) {
2870
+ const cached = getValidationStatus(activeProvider.id, selectedModel.id);
2871
+ p6.log.error(
2872
+ `Model ${selectedModel.id} (${activeProvider.name}) has been marked as deprecated: ${cached?.error ?? "unknown"}.`
2873
+ );
2874
+ p6.log.info(`Run ${pc5.cyan("anygate providers refresh-models")} to re-check.`);
2875
+ return 1;
2876
+ }
2552
2877
  return launchClaudeViaCatalog(
2553
2878
  catalogRoutes,
2554
2879
  startingRoute,
@@ -2561,25 +2886,34 @@ Error: ${launchPlan.error}
2561
2886
  const formatDesc = selectedModel.modelFormat === "anthropic" ? "direct passthrough" : "via SDK adapter proxy";
2562
2887
  const endpoint = selectedModel.modelFormat === "anthropic" ? selectedModel.baseUrl ?? "(unknown)" : selectedModel.npm ?? "SDK";
2563
2888
  console.log("");
2564
- console.log(pc4.bold(pc4.cyan(" DRY RUN \u2014 would execute:")));
2889
+ console.log(pc5.bold(pc5.cyan(" DRY RUN \u2014 would execute:")));
2565
2890
  console.log("");
2566
- console.log(` ${pc4.bold("Provider:")} ${activeProvider.name}`);
2567
- console.log(` ${pc4.bold("Model:")} ${selectedModel.id}`);
2568
- console.log(` ${pc4.bold("Format:")} ${selectedModel.modelFormat} (${formatDesc})`);
2569
- console.log(` ${pc4.bold(selectedModel.modelFormat === "anthropic" ? "Endpoint:" : "SDK npm:")} ${endpoint}`);
2570
- console.log(` ${pc4.bold("Key:")} ${activeProvider.name} provider key`);
2891
+ console.log(` ${pc5.bold("Provider:")} ${activeProvider.name}`);
2892
+ console.log(` ${pc5.bold("Model:")} ${selectedModel.id}`);
2893
+ console.log(` ${pc5.bold("Format:")} ${selectedModel.modelFormat} (${formatDesc})`);
2894
+ console.log(` ${pc5.bold(selectedModel.modelFormat === "anthropic" ? "Endpoint:" : "SDK npm:")} ${endpoint}`);
2895
+ console.log(` ${pc5.bold("Key:")} ${activeProvider.name} provider key`);
2571
2896
  console.log("");
2572
- console.log(pc4.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
2897
+ console.log(pc5.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
2573
2898
  console.log("");
2574
2899
  return 0;
2575
2900
  }
2576
2901
  const launchApiKey = await resolveLocalProviderApiKey(activeProvider);
2577
2902
  if (!launchApiKey?.trim()) {
2578
- p5.log.error(
2903
+ p6.log.error(
2579
2904
  new CredentialUnavailableError(activeProvider.id).userMessage
2580
2905
  );
2581
2906
  return 1;
2582
2907
  }
2908
+ const isAvailable = await quickValidateModel(activeProvider.id, selectedModel.id);
2909
+ if (!isAvailable) {
2910
+ const cached = getValidationStatus(activeProvider.id, selectedModel.id);
2911
+ p6.log.error(
2912
+ `Model ${selectedModel.id} (${activeProvider.name}) has been marked as deprecated: ${cached?.error ?? "unknown"}.`
2913
+ );
2914
+ p6.log.info(`Run ${pc5.cyan("anygate providers refresh-models")} to re-check.`);
2915
+ return 1;
2916
+ }
2583
2917
  let proxyHandle = null;
2584
2918
  let childEnv;
2585
2919
  const isAntigravityOAuth = activeProvider.id === "antigravity" && activeProvider.authType === "oauth";
@@ -2600,9 +2934,9 @@ Error: ${launchPlan.error}
2600
2934
  },
2601
2935
  launchApiKey
2602
2936
  );
2603
- if (!isAgentStdoutMode()) p5.log.info(`Cloud Code proxy started on port ${proxyHandle.port}`);
2937
+ if (!isAgentStdoutMode()) p6.log.info(`Cloud Code proxy started on port ${proxyHandle.port}`);
2604
2938
  } catch (err) {
2605
- p5.log.error(`Failed to start Cloud Code proxy: ${err instanceof Error ? err.message : String(err)}`);
2939
+ p6.log.error(`Failed to start Cloud Code proxy: ${err instanceof Error ? err.message : String(err)}`);
2606
2940
  return 1;
2607
2941
  }
2608
2942
  childEnv = buildChildEnv(
@@ -2629,9 +2963,9 @@ Error: ${launchPlan.error}
2629
2963
  },
2630
2964
  launchApiKey
2631
2965
  );
2632
- if (!isAgentStdoutMode()) p5.log.info(`OAuth proxy started on port ${proxyHandle.port}`);
2966
+ if (!isAgentStdoutMode()) p6.log.info(`OAuth proxy started on port ${proxyHandle.port}`);
2633
2967
  } catch (err) {
2634
- p5.log.error(`Failed to start OAuth proxy: ${err instanceof Error ? err.message : String(err)}`);
2968
+ p6.log.error(`Failed to start OAuth proxy: ${err instanceof Error ? err.message : String(err)}`);
2635
2969
  return 1;
2636
2970
  }
2637
2971
  childEnv = buildChildEnv(
@@ -2673,12 +3007,12 @@ Error: ${launchPlan.error}
2673
3007
  launchApiKey
2674
3008
  );
2675
3009
  if (!isAgentStdoutMode()) {
2676
- p5.log.info(
2677
- `SDK adapter proxy started on port ${proxyHandle.port}` + (selectedModel.npm ? pc4.dim(` (${selectedModel.npm})`) : "")
3010
+ p6.log.info(
3011
+ `SDK adapter proxy started on port ${proxyHandle.port}` + (selectedModel.npm ? pc5.dim(` (${selectedModel.npm})`) : "")
2678
3012
  );
2679
3013
  }
2680
3014
  } catch (err) {
2681
- p5.log.error(`Failed to start SDK adapter proxy: ${err instanceof Error ? err.message : String(err)}`);
3015
+ p6.log.error(`Failed to start SDK adapter proxy: ${err instanceof Error ? err.message : String(err)}`);
2682
3016
  return 1;
2683
3017
  }
2684
3018
  childEnv = buildChildEnv(
@@ -2694,7 +3028,7 @@ Error: ${launchPlan.error}
2694
3028
  }
2695
3029
  const debugLogPath = prepareClaudeTraceLog();
2696
3030
  const traceArgs = trace ? ["--debug-file", debugLogPath] : [];
2697
- if (trace) p5.log.info(`Debug log: ${debugLogPath}`);
3031
+ if (trace) p6.log.info(`Debug log: ${debugLogPath}`);
2698
3032
  const exitCode = await launchClaude(
2699
3033
  childEnv,
2700
3034
  claudeCodeClientModelId(selectedModel.id, selectedModel.contextWindow),
@@ -2708,11 +3042,11 @@ async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindo
2708
3042
  let proxyHandle;
2709
3043
  try {
2710
3044
  proxyHandle = await startProxyCatalog(catalogRoutes, startingRoute.aliasId, trace);
2711
- p5.log.info(
2712
- `Switch menu active \u2014 proxy on port ${proxyHandle.port} ` + pc4.dim(`(${catalogRoutes.length} model${catalogRoutes.length !== 1 ? "s" : ""} in /model)`)
3045
+ p6.log.info(
3046
+ `Switch menu active \u2014 proxy on port ${proxyHandle.port} ` + pc5.dim(`(${catalogRoutes.length} model${catalogRoutes.length !== 1 ? "s" : ""} in /model)`)
2713
3047
  );
2714
3048
  } catch (err) {
2715
- p5.log.error(`Failed to start proxy: ${err instanceof Error ? err.message : String(err)}`);
3049
+ p6.log.error(`Failed to start proxy: ${err instanceof Error ? err.message : String(err)}`);
2716
3050
  return 1;
2717
3051
  }
2718
3052
  const childEnv = buildChildEnv(
@@ -2725,7 +3059,7 @@ async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindo
2725
3059
  );
2726
3060
  const debugLogPath = prepareClaudeTraceLog();
2727
3061
  const traceArgs = trace ? ["--debug-file", debugLogPath] : [];
2728
- if (trace) p5.log.info(`Debug log: ${debugLogPath}`);
3062
+ if (trace) p6.log.info(`Debug log: ${debugLogPath}`);
2729
3063
  const exitCode = await launchClaude(
2730
3064
  childEnv,
2731
3065
  claudeCodeClientModelId(startingRoute.aliasId, contextWindow),
@@ -2737,8 +3071,8 @@ async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindo
2737
3071
  }
2738
3072
 
2739
3073
  // src/apps/codex/cli.ts
2740
- import pc7 from "picocolors";
2741
- import * as p8 from "@clack/prompts";
3074
+ import pc8 from "picocolors";
3075
+ import * as p9 from "@clack/prompts";
2742
3076
  init_config();
2743
3077
 
2744
3078
  // src/apps/codex/proxy.ts
@@ -2796,7 +3130,7 @@ function applyClaudeCodeOAuthIdentity(input, sdkParams) {
2796
3130
  import { streamText, generateText, tool, jsonSchema } from "ai";
2797
3131
  function messageText(content) {
2798
3132
  if (typeof content === "string") return content;
2799
- return (content ?? []).map((p17) => p17.type === "output_text" || p17.type === "input_text" || p17.type === "text" ? p17.text ?? "" : "").join("");
3133
+ return (content ?? []).map((p18) => p18.type === "output_text" || p18.type === "input_text" || p18.type === "text" ? p18.text ?? "" : "").join("");
2800
3134
  }
2801
3135
  function extractDeveloperAndInstructions(items, instructions) {
2802
3136
  const developerParts = [];
@@ -3705,9 +4039,9 @@ function estimateCodexRequestChars(params) {
3705
4039
  if (Array.isArray(msg.content)) {
3706
4040
  for (const part of msg.content) {
3707
4041
  if (!part || typeof part !== "object") continue;
3708
- const p17 = part;
3709
- if (typeof p17["text"] === "string") {
3710
- chars += p17["text"].length;
4042
+ const p18 = part;
4043
+ if (typeof p18["text"] === "string") {
4044
+ chars += p18["text"].length;
3711
4045
  } else {
3712
4046
  chars += JSON.stringify(part).length;
3713
4047
  }
@@ -3738,9 +4072,9 @@ function clipLargeTextParts(params, maxCharsPerPart) {
3738
4072
  ...msg,
3739
4073
  content: msg.content.map((part) => {
3740
4074
  if (!part || typeof part !== "object") return part;
3741
- const p17 = part;
3742
- if (typeof p17.text !== "string") return part;
3743
- return { ...p17, text: clipTextForContext(p17.text, maxCharsPerPart) };
4075
+ const p18 = part;
4076
+ if (typeof p18.text !== "string") return part;
4077
+ return { ...p18, text: clipTextForContext(p18.text, maxCharsPerPart) };
3744
4078
  })
3745
4079
  };
3746
4080
  });
@@ -3774,7 +4108,7 @@ var COMPACTION_PROMPT_MARKER = "You are performing a CONTEXT CHECKPOINT COMPACTI
3774
4108
  function inputItemText(content) {
3775
4109
  if (typeof content === "string") return content;
3776
4110
  if (!Array.isArray(content)) return "";
3777
- return content.map((p17) => p17 && typeof p17 === "object" && typeof p17.text === "string" ? p17.text : "").join("");
4111
+ return content.map((p18) => p18 && typeof p18 === "object" && typeof p18.text === "string" ? p18.text : "").join("");
3778
4112
  }
3779
4113
  function isLikelyCodexCompactionRequest(body) {
3780
4114
  if (!Array.isArray(body.input)) return false;
@@ -3860,16 +4194,16 @@ async function startCodexProxy(routes, options = {}) {
3860
4194
  }));
3861
4195
  }
3862
4196
  return new Promise((resolve, reject2) => {
3863
- const log16 = debug ? makeTraceLogger(getCodexProxyDebugLogPath()) : () => {
4197
+ const log17 = debug ? makeTraceLogger(getCodexProxyDebugLogPath()) : () => {
3864
4198
  };
3865
4199
  const onRejection = (reason) => {
3866
- if (debug) log16(`unhandled-rejection: ${formatUpstreamError(reason)}`);
4200
+ if (debug) log17(`unhandled-rejection: ${formatUpstreamError(reason)}`);
3867
4201
  };
3868
4202
  process.on("unhandledRejection", onRejection);
3869
4203
  const server = createServer(async (req, res) => {
3870
4204
  const url = req.url ?? "/";
3871
4205
  if (debug) {
3872
- log16(`-> ${req.method} ${url} content-type=${req.headers["content-type"] ?? "(none)"} content-encoding=${req.headers["content-encoding"] ?? "(none)"} content-length=${req.headers["content-length"] ?? "(none)"}`);
4206
+ log17(`-> ${req.method} ${url} content-type=${req.headers["content-type"] ?? "(none)"} content-encoding=${req.headers["content-encoding"] ?? "(none)"} content-length=${req.headers["content-length"] ?? "(none)"}`);
3873
4207
  }
3874
4208
  if (!requireAuth && req.method === "POST") {
3875
4209
  const origin = req.headers.origin;
@@ -3947,7 +4281,7 @@ async function startCodexProxy(routes, options = {}) {
3947
4281
  rawBody = await readBody(req);
3948
4282
  } catch (err) {
3949
4283
  if (debug) {
3950
- log16(`Error: failed to read/decode request body on POST ${url}: ${formatUpstreamError(err)} content-encoding=${req.headers["content-encoding"] ?? "(none)"}`);
4284
+ log17(`Error: failed to read/decode request body on POST ${url}: ${formatUpstreamError(err)} content-encoding=${req.headers["content-encoding"] ?? "(none)"}`);
3951
4285
  }
3952
4286
  sendJson(res, 400, { error: { message: "Invalid request body", type: "invalid_request_error" } });
3953
4287
  return;
@@ -3958,7 +4292,7 @@ async function startCodexProxy(routes, options = {}) {
3958
4292
  } catch (err) {
3959
4293
  if (debug) {
3960
4294
  const headers = JSON.stringify(req.headers);
3961
- log16(`Error: Invalid JSON body on POST ${url}: ${formatUpstreamError(err)} headers=${headers} rawBody=${JSON.stringify(rawBody.slice(0, 2e3))}`);
4295
+ log17(`Error: Invalid JSON body on POST ${url}: ${formatUpstreamError(err)} headers=${headers} rawBody=${JSON.stringify(rawBody.slice(0, 2e3))}`);
3962
4296
  }
3963
4297
  sendJson(res, 400, { error: { message: "Invalid JSON body", type: "invalid_request_error" } });
3964
4298
  return;
@@ -3968,12 +4302,12 @@ async function startCodexProxy(routes, options = {}) {
3968
4302
  const inputItems = Array.isArray(body.input) ? body.input.length : typeof body.input === "string" ? 1 : 0;
3969
4303
  const tools = Array.isArray(body.tools) ? body.tools : [];
3970
4304
  const toolNames = tools.map((t) => t && typeof t === "object" && "name" in t ? t.name : "?").join(",");
3971
- log16(`request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${rawBody.length} tools=[${toolNames || "none"}]`);
4305
+ log17(`request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${rawBody.length} tools=[${toolNames || "none"}]`);
3972
4306
  const mcpTools = tools.filter((t) => t && typeof t === "object" && "name" in t && String(t.name).startsWith("mcp__"));
3973
4307
  for (const t of mcpTools) {
3974
4308
  const mt = t;
3975
4309
  const subTools = mt.type === "namespace" && Array.isArray(mt.tools) ? ` subTools=[${mt.tools.length}]` : "";
3976
- log16(` mcp-tool: name=${mt.name} type=${mt.type} desc=${JSON.stringify(String(mt.description ?? "")).slice(0, 120)}${subTools}`);
4310
+ log17(` mcp-tool: name=${mt.name} type=${mt.type} desc=${JSON.stringify(String(mt.description ?? "")).slice(0, 120)}${subTools}`);
3977
4311
  }
3978
4312
  }
3979
4313
  const modelId = String(body.model ?? "");
@@ -3983,12 +4317,12 @@ async function startCodexProxy(routes, options = {}) {
3983
4317
  const fallbackLm = fallbackRoute ? models.get(fallbackRoute.modelId) : void 0;
3984
4318
  if (fallbackRoute && fallbackLm) {
3985
4319
  if (debug) {
3986
- log16(`resolveModel fallback: requested="${modelId}" \u2192 ${fallbackRoute.modelId}`);
4320
+ log17(`resolveModel fallback: requested="${modelId}" \u2192 ${fallbackRoute.modelId}`);
3987
4321
  }
3988
4322
  resolved = { route: fallbackRoute, languageModel: fallbackLm };
3989
4323
  } else {
3990
4324
  if (debug) {
3991
- log16(`resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
4325
+ log17(`resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
3992
4326
  }
3993
4327
  sendJson(res, 404, { error: { message: `Unknown model: ${modelId}`, type: "invalid_request_error" } });
3994
4328
  return;
@@ -4013,16 +4347,16 @@ async function startCodexProxy(routes, options = {}) {
4013
4347
  const before = params.messages.length;
4014
4348
  const estimatedChars = estimateCodexRequestChars(params);
4015
4349
  const compaction = isLikelyCodexCompactionRequest(body);
4016
- if (debug) log16(`context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before}`);
4350
+ if (debug) log17(`context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before}`);
4017
4351
  params = protectCodexCompactionParams(body, params, route.contextWindow);
4018
4352
  params.isCompaction = compaction;
4019
4353
  if (debug && params.messages.length < before) {
4020
- log16(`context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages`);
4354
+ log17(`context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages`);
4021
4355
  }
4022
4356
  }
4023
4357
  if (debug) {
4024
4358
  const effort = body.reasoning?.effort;
4025
- log16(`model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
4359
+ log17(`model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
4026
4360
  }
4027
4361
  if (body.stream) {
4028
4362
  res.writeHead(200, {
@@ -4035,17 +4369,17 @@ async function startCodexProxy(routes, options = {}) {
4035
4369
  await streamResponsesResponse(languageModel, params, modelId, write, (summary) => {
4036
4370
  if (debug) {
4037
4371
  const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
4038
- log16(`response done: model=${route.modelId} reasoningChars=${summary.reasoningChars} textChars=${summary.textChars} toolCalls=${summary.toolCallCount} toolNames=[${summary.toolNames.join(",")}] loopDetected=${summary.loopDetected ?? "no"} dsmlRecovered=${summary.dsmlToolCallsRecovered ?? 0}${failure} reasoningPreview=${JSON.stringify(summary.reasoningPreview)}`);
4372
+ log17(`response done: model=${route.modelId} reasoningChars=${summary.reasoningChars} textChars=${summary.textChars} toolCalls=${summary.toolCallCount} toolNames=[${summary.toolNames.join(",")}] loopDetected=${summary.loopDetected ?? "no"} dsmlRecovered=${summary.dsmlToolCallsRecovered ?? 0}${failure} reasoningPreview=${JSON.stringify(summary.reasoningPreview)}`);
4039
4373
  }
4040
4374
  }, (progress) => {
4041
4375
  if (debug) {
4042
- log16(`response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
4376
+ log17(`response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
4043
4377
  }
4044
4378
  });
4045
4379
  } catch (err) {
4046
4380
  const msg = formatUpstreamError(err);
4047
4381
  const status = upstreamHttpStatus(err);
4048
- if (debug) log16(`sdk error: ${route.modelId}: ${msg}`);
4382
+ if (debug) log17(`sdk error: ${route.modelId}: ${msg}`);
4049
4383
  if (status === 429) {
4050
4384
  writeResponsesRateLimitStream(modelId, msg, write);
4051
4385
  } else {
@@ -4060,7 +4394,7 @@ async function startCodexProxy(routes, options = {}) {
4060
4394
  } catch (err) {
4061
4395
  const msg = formatUpstreamError(err);
4062
4396
  const status = upstreamHttpStatus(err);
4063
- if (debug) log16(`sdk error: ${route.modelId}: ${msg}`);
4397
+ if (debug) log17(`sdk error: ${route.modelId}: ${msg}`);
4064
4398
  if (status === 429) {
4065
4399
  sendJson(res, 200, responsesRateLimitBody(modelId, msg));
4066
4400
  } else {
@@ -4070,7 +4404,7 @@ async function startCodexProxy(routes, options = {}) {
4070
4404
  }
4071
4405
  } catch (err) {
4072
4406
  const msg = formatUpstreamError(err);
4073
- log16(`handler error: ${msg}`);
4407
+ log17(`handler error: ${msg}`);
4074
4408
  sendJson(res, 500, { error: { message: msg, type: "api_error" } });
4075
4409
  }
4076
4410
  return;
@@ -4188,7 +4522,7 @@ Sec-WebSocket-Accept: ${wsAcceptKey(clientKey)}\r
4188
4522
  try {
4189
4523
  body = JSON.parse(frame.text);
4190
4524
  } catch {
4191
- if (debug) log16(`WS Error: Invalid JSON body: rawBody=${JSON.stringify(frame.text.slice(0, 2e3))}`);
4525
+ if (debug) log17(`WS Error: Invalid JSON body: rawBody=${JSON.stringify(frame.text.slice(0, 2e3))}`);
4192
4526
  sendWsEvent(`event: error
4193
4527
  data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_request_error" } })}
4194
4528
 
@@ -4201,7 +4535,7 @@ data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_reques
4201
4535
  const inputItems = Array.isArray(body.input) ? body.input.length : typeof body.input === "string" ? 1 : 0;
4202
4536
  const tools = Array.isArray(body.tools) ? body.tools : [];
4203
4537
  const toolNames = tools.map((t) => t && typeof t === "object" && "name" in t ? t.name : "?").join(",");
4204
- log16(`WS request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${frame.text.length} tools=[${toolNames || "none"}]`);
4538
+ log17(`WS request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${frame.text.length} tools=[${toolNames || "none"}]`);
4205
4539
  }
4206
4540
  const modelId = String(body.model ?? "");
4207
4541
  let resolved = resolveModel(routes, models, modelId);
@@ -4209,10 +4543,10 @@ data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_reques
4209
4543
  const fb = routes[0];
4210
4544
  const fbLm = fb ? models.get(fb.modelId) : void 0;
4211
4545
  if (fb && fbLm) {
4212
- if (debug) log16(`WS resolveModel fallback: requested="${modelId}" \u2192 ${fb.modelId}`);
4546
+ if (debug) log17(`WS resolveModel fallback: requested="${modelId}" \u2192 ${fb.modelId}`);
4213
4547
  resolved = { route: fb, languageModel: fbLm };
4214
4548
  } else {
4215
- if (debug) log16(`WS resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
4549
+ if (debug) log17(`WS resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
4216
4550
  sendWsEvent(`event: error
4217
4551
  data: ${JSON.stringify({ error: { message: `Unknown model: ${modelId}` } })}
4218
4552
 
@@ -4240,31 +4574,31 @@ data: ${JSON.stringify({ error: { message: `Unknown model: ${modelId}` } })}
4240
4574
  const before = params.messages.length;
4241
4575
  const estimatedChars = estimateCodexRequestChars(params);
4242
4576
  const compaction = isLikelyCodexCompactionRequest(body);
4243
- if (debug) log16(`WS context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before} tools=${params.tools ? Object.keys(params.tools).length : 0}`);
4577
+ if (debug) log17(`WS context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before} tools=${params.tools ? Object.keys(params.tools).length : 0}`);
4244
4578
  params = protectCodexCompactionParams(body, params, route.contextWindow);
4245
4579
  params.isCompaction = compaction;
4246
4580
  if (debug && params.messages.length < before) {
4247
- log16(`WS context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages tools=${params.tools ? Object.keys(params.tools).length : 0}`);
4581
+ log17(`WS context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages tools=${params.tools ? Object.keys(params.tools).length : 0}`);
4248
4582
  }
4249
4583
  }
4250
4584
  if (debug) {
4251
4585
  const effort = body.reasoning?.effort;
4252
- log16(`WS model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
4586
+ log17(`WS model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
4253
4587
  }
4254
4588
  await streamResponsesResponse(languageModel, params, modelId, sendWsEvent, (summary) => {
4255
4589
  if (debug) {
4256
4590
  const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
4257
- log16(`WS response done: model=${route.modelId} reasoningChars=${summary.reasoningChars} textChars=${summary.textChars} toolCalls=${summary.toolCallCount} toolNames=[${summary.toolNames.join(",")}] loopDetected=${summary.loopDetected ?? "no"} dsmlRecovered=${summary.dsmlToolCallsRecovered ?? 0}${failure} reasoningPreview=${JSON.stringify(summary.reasoningPreview)}`);
4591
+ log17(`WS response done: model=${route.modelId} reasoningChars=${summary.reasoningChars} textChars=${summary.textChars} toolCalls=${summary.toolCallCount} toolNames=[${summary.toolNames.join(",")}] loopDetected=${summary.loopDetected ?? "no"} dsmlRecovered=${summary.dsmlToolCallsRecovered ?? 0}${failure} reasoningPreview=${JSON.stringify(summary.reasoningPreview)}`);
4258
4592
  }
4259
4593
  }, (progress) => {
4260
4594
  if (debug) {
4261
- log16(`WS response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
4595
+ log17(`WS response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
4262
4596
  }
4263
4597
  });
4264
4598
  } catch (err) {
4265
4599
  const msg = formatUpstreamError(err);
4266
4600
  const status = upstreamHttpStatus(err);
4267
- if (debug) log16(`WS sdk error: ${route.modelId}: ${msg}`);
4601
+ if (debug) log17(`WS sdk error: ${route.modelId}: ${msg}`);
4268
4602
  if (status === 429) {
4269
4603
  writeResponsesRateLimitStream(modelId, msg, sendWsEvent);
4270
4604
  } else {
@@ -4487,7 +4821,7 @@ function restoreCodexOverlay(env = process.env) {
4487
4821
  return removed;
4488
4822
  }
4489
4823
  function remainingOverlayPaths(env = process.env) {
4490
- return ownedOverlayPaths(env).filter((p17) => existsSync3(p17));
4824
+ return ownedOverlayPaths(env).filter((p18) => existsSync3(p18));
4491
4825
  }
4492
4826
  function recoverInterruptedCodexSession(env = process.env) {
4493
4827
  const before = remainingOverlayPaths(env);
@@ -4691,8 +5025,8 @@ function launchCodex(modelId, env, extraArgs) {
4691
5025
  }
4692
5026
 
4693
5027
  // src/apps/codex/prompts.ts
4694
- import pc5 from "picocolors";
4695
- import * as p6 from "@clack/prompts";
5028
+ import pc6 from "picocolors";
5029
+ import * as p7 from "@clack/prompts";
4696
5030
  async function pickCodexProvider(providers, prefs, hasFavorites = false, initialProviderId, agentLabel = "Codex") {
4697
5031
  if (providers.length === 0 && !hasFavorites) return null;
4698
5032
  const options = providers.map((lp) => providerSelectOption(lp));
@@ -4704,13 +5038,13 @@ async function pickCodexProvider(providers, prefs, hasFavorites = false, initial
4704
5038
  });
4705
5039
  }
4706
5040
  const initial = initialProviderId && options.some((o) => o.value === initialProviderId) ? initialProviderId : hasFavorites ? "__favorites__" : prefs.lastCodexProvider && options.some((o) => o.value === prefs.lastCodexProvider) ? prefs.lastCodexProvider : options[0].value;
4707
- const chosen = await p6.select({
5041
+ const chosen = await p7.select({
4708
5042
  message: `Which provider for ${agentLabel}?`,
4709
5043
  options,
4710
5044
  initialValue: initial
4711
5045
  });
4712
- if (p6.isCancel(chosen)) {
4713
- p6.cancel("Cancelled.");
5046
+ if (p7.isCancel(chosen)) {
5047
+ p7.cancel("Cancelled.");
4714
5048
  return null;
4715
5049
  }
4716
5050
  if (chosen === "__favorites__") return "__favorites__";
@@ -4727,12 +5061,12 @@ async function pickCodexModel(provider, prefs) {
4727
5061
  navOption("__browse_all__", "Browse all models \u2192", `${provider.models.length} available`),
4728
5062
  navOption("__back__", "\u2190 Go back", "Select a different provider")
4729
5063
  ];
4730
- const picked = await p6.select({
5064
+ const picked = await p7.select({
4731
5065
  message: `Model for ${provider.name}?`,
4732
5066
  options,
4733
5067
  initialValue: recentModels[0].id
4734
5068
  });
4735
- if (p6.isCancel(picked) || String(picked) === "__back__") {
5069
+ if (p7.isCancel(picked) || String(picked) === "__back__") {
4736
5070
  return "back";
4737
5071
  }
4738
5072
  if (String(picked) === "__browse_all__") {
@@ -4760,13 +5094,13 @@ async function pickCodexModel(provider, prefs) {
4760
5094
  return selectedModel;
4761
5095
  }
4762
5096
  function confirmCodexLaunch(providerName, modelLabel, modelId, route) {
4763
- const via = route.tier === "direct" ? pc5.green("direct") : `${pc5.dim("via")} ${pc5.yellow("anygate proxy")}`;
4764
- return p6.confirm({
4765
- message: `${confirmLaunchMessage("Codex", modelLabel, modelId, providerName)} ${pc5.dim("(")}${via}${pc5.dim(")")}`,
5097
+ const via = route.tier === "direct" ? pc6.green("direct") : `${pc6.dim("via")} ${pc6.yellow("anygate proxy")}`;
5098
+ return p7.confirm({
5099
+ message: `${confirmLaunchMessage("Codex", modelLabel, modelId, providerName)} ${pc6.dim("(")}${via}${pc6.dim(")")}`,
4766
5100
  initialValue: true
4767
5101
  }).then((answer) => {
4768
- if (p6.isCancel(answer)) {
4769
- p6.cancel("Cancelled.");
5102
+ if (p7.isCancel(answer)) {
5103
+ p7.cancel("Cancelled.");
4770
5104
  return false;
4771
5105
  }
4772
5106
  return answer;
@@ -4789,7 +5123,7 @@ function rejectManagedFlags(codexArgs) {
4789
5123
  }
4790
5124
 
4791
5125
  // src/apps/codex/ui.ts
4792
- import pc6 from "picocolors";
5126
+ import pc7 from "picocolors";
4793
5127
  function codexAppIntro() {
4794
5128
  gateIntro("Codex App");
4795
5129
  }
@@ -4797,22 +5131,22 @@ function codexCliIntro() {
4797
5131
  gateIntro("Codex");
4798
5132
  }
4799
5133
  function printCodexAppSessionPanel(opts) {
4800
- printPanel(pc6.cyan("Foreground session"), [
4801
- `${pc6.bold("Model")} ${fmtModel(opts.modelLabel, opts.modelId)}`,
4802
- `${pc6.bold("Provider")} ${fmtProvider(opts.providerName)}`,
5134
+ printPanel(pc7.cyan("Foreground session"), [
5135
+ `${pc7.bold("Model")} ${fmtModel(opts.modelLabel, opts.modelId)}`,
5136
+ `${pc7.bold("Provider")} ${fmtProvider(opts.providerName)}`,
4803
5137
  "",
4804
- `${pc6.yellow(pc6.bold("Keep this terminal open"))}${pc6.white(" while you use Codex.")}`,
4805
- `${pc6.white("Press ")}${pc6.bold(pc6.red("Ctrl+C"))}${pc6.white(" to stop the proxy and restore ")}${fmtCommand("~/.codex/config.toml")}${pc6.white(".")}`,
4806
- `${pc6.dim("Codex may show ")}${pc6.yellow('"Custom"')}${pc6.dim(" if the desktop picker cannot resolve registry models \u2014 check the terminal line above. After restart, pick your model from the picker if it appears.")}`,
4807
- `${pc6.dim("If Codex asks you to sign in after restart: choose API key and enter any character \u2014 that unlocks the model picker for registry providers.")}`,
4808
- `${pc6.dim("Stuck? Run ")}${fmtCommand(opts.restoreCommand)}${pc6.dim(".")}`
5138
+ `${pc7.yellow(pc7.bold("Keep this terminal open"))}${pc7.white(" while you use Codex.")}`,
5139
+ `${pc7.white("Press ")}${pc7.bold(pc7.red("Ctrl+C"))}${pc7.white(" to stop the proxy and restore ")}${fmtCommand("~/.codex/config.toml")}${pc7.white(".")}`,
5140
+ `${pc7.dim("Codex may show ")}${pc7.yellow('"Custom"')}${pc7.dim(" if the desktop picker cannot resolve registry models \u2014 check the terminal line above. After restart, pick your model from the picker if it appears.")}`,
5141
+ `${pc7.dim("If Codex asks you to sign in after restart: choose API key and enter any character \u2014 that unlocks the model picker for registry providers.")}`,
5142
+ `${pc7.dim("Stuck? Run ")}${fmtCommand(opts.restoreCommand)}${pc7.dim(".")}`
4809
5143
  ]);
4810
5144
  }
4811
5145
  function printCodexCliCleanupPanel(restoreCommand) {
4812
- printPanel(pc6.cyan("While Codex runs"), [
4813
- `${pc6.white("Temporary profile: ")}${fmtCommand("~/.codex/anygate-launch.config.toml")}`,
4814
- `${pc6.white("Removed automatically when Codex exits.")}`,
4815
- `${pc6.dim("After a crash: ")}${fmtCommand(restoreCommand)}${pc6.dim(".")}`
5146
+ printPanel(pc7.cyan("While Codex runs"), [
5147
+ `${pc7.white("Temporary profile: ")}${fmtCommand("~/.codex/anygate-launch.config.toml")}`,
5148
+ `${pc7.white("Removed automatically when Codex exits.")}`,
5149
+ `${pc7.dim("After a crash: ")}${fmtCommand(restoreCommand)}${pc7.dim(".")}`
4816
5150
  ]);
4817
5151
  }
4818
5152
  function codexAppOutro(modelLabel) {
@@ -4821,7 +5155,7 @@ function codexAppOutro(modelLabel) {
4821
5155
  function codexCliOutro(providerName, modelLabel, modelId) {
4822
5156
  gateOutro(
4823
5157
  "Launching Codex",
4824
- `${fmtProvider(providerName)} ${pc6.dim("/")} ${fmtModel(modelLabel, modelId)}`
5158
+ `${fmtProvider(providerName)} ${pc7.dim("/")} ${fmtModel(modelLabel, modelId)}`
4825
5159
  );
4826
5160
  }
4827
5161
 
@@ -4876,7 +5210,7 @@ function buildFavoritesAppCatalog(resolved) {
4876
5210
  }
4877
5211
 
4878
5212
  // src/apps/codex/favorites-launch.ts
4879
- import * as p7 from "@clack/prompts";
5213
+ import * as p8 from "@clack/prompts";
4880
5214
 
4881
5215
  // src/apps/shared/favorites-resolver.ts
4882
5216
  async function resolveFavorite(fav, ctx) {
@@ -4951,7 +5285,7 @@ async function pickFavoriteStartingModel(compatible, favorites, agent, productLa
4951
5285
  if (provider && model) available.push({ provider, model });
4952
5286
  }
4953
5287
  if (available.length === 0) {
4954
- p7.log.warn(`No saved ${productLabel} favorites are currently available.`);
5288
+ p8.log.warn(`No saved ${productLabel} favorites are currently available.`);
4955
5289
  return "unavailable";
4956
5290
  }
4957
5291
  const favOptions = available.map((f, i) => ({
@@ -4959,13 +5293,13 @@ async function pickFavoriteStartingModel(compatible, favorites, agent, productLa
4959
5293
  label: `${f.model.name || f.model.id} \u2014 ${f.provider.name}`,
4960
5294
  hint: f.model.id
4961
5295
  }));
4962
- const pickedIdx = await p7.select({
5296
+ const pickedIdx = await p8.select({
4963
5297
  message: "Starting model?",
4964
5298
  options: favOptions,
4965
5299
  initialValue: "0"
4966
5300
  });
4967
- if (p7.isCancel(pickedIdx)) {
4968
- p7.cancel("Cancelled.");
5301
+ if (p8.isCancel(pickedIdx)) {
5302
+ p8.cancel("Cancelled.");
4969
5303
  return "cancelled";
4970
5304
  }
4971
5305
  return available[Number(pickedIdx)] ?? "unavailable";
@@ -5008,7 +5342,7 @@ function buildCodexProxyRoutesFromResolved(resolved, providersById) {
5008
5342
  };
5009
5343
  }).filter((r) => r !== void 0);
5010
5344
  if (skippedOAuth.length > 0) {
5011
- p7.log.warn(
5345
+ p8.log.warn(
5012
5346
  `Skipped ${skippedOAuth.length} OAuth favorite(s) (OAuth auth not supported in favorites catalog): ${skippedOAuth.join(", ")}`
5013
5347
  );
5014
5348
  }
@@ -5034,7 +5368,7 @@ async function resolveCodexFavorites(activeProvider, selectedModel, compatible,
5034
5368
  ctx
5035
5369
  );
5036
5370
  if (droppedFavorites.length > 0) {
5037
- p7.log.warn(
5371
+ p8.log.warn(
5038
5372
  `Skipped ${droppedFavorites.length} stale/unauthorized favorite(s): ${droppedFavorites.map((f) => `${f.providerId}:${f.modelId}`).join(", ")}`
5039
5373
  );
5040
5374
  }
@@ -5111,9 +5445,9 @@ async function startCloudCodeCatalogBackend(routes, startingAliasId, trace) {
5111
5445
 
5112
5446
  // src/apps/codex/cli.ts
5113
5447
  function codexHelpText() {
5114
- return `${pc7.bold("anygate codex")} \u2014 launch OpenAI Codex CLI with your registry providers
5448
+ return `${pc8.bold("anygate codex")} \u2014 launch OpenAI Codex CLI with your registry providers
5115
5449
 
5116
- ${pc7.bold("Usage:")}
5450
+ ${pc8.bold("Usage:")}
5117
5451
  anygate codex [options] [codex-flags]
5118
5452
  anygate codex --vertex
5119
5453
  anygate codex --restore
@@ -5121,7 +5455,7 @@ ${pc7.bold("Usage:")}
5121
5455
  anygate codex --help
5122
5456
  anygate codex --version
5123
5457
 
5124
- ${pc7.bold("Options:")}
5458
+ ${pc8.bold("Options:")}
5125
5459
  --trace Write proxy debug logs to ~/.anygate/logs/ and show errors on exit
5126
5460
  --provider Boot provider id (skip wizard when paired with --model or non-interactive)
5127
5461
  --model Boot model id (skip wizard when paired with --provider or non-interactive)
@@ -5131,30 +5465,30 @@ ${pc7.bold("Options:")}
5131
5465
  --help Show this command help
5132
5466
  --version Show version
5133
5467
 
5134
- ${pc7.bold("Description:")}
5468
+ ${pc8.bold("Description:")}
5135
5469
  Picks a provider and model from ~/.anygate/providers.json, writes a temporary
5136
5470
  anygate-launch profile (never touches ~/.codex/config.toml), and launches Codex.
5137
5471
  Overlay files are removed automatically when Codex exits; use --restore after a crash.
5138
5472
  Anthropic and other registry models route through a local Responses API proxy.
5139
5473
 
5140
- ${pc7.bold("Prerequisites:")}
5474
+ ${pc8.bold("Prerequisites:")}
5141
5475
  npm install -g @openai/codex
5142
5476
 
5143
- ${pc7.bold("Cleanup:")}
5477
+ ${pc8.bold("Cleanup:")}
5144
5478
  Temporary files: ~/.codex/anygate-launch.config.toml and ~/.anygate/codex/*
5145
5479
  Auto-removed on normal exit. After crash or force-quit: anygate codex --restore
5146
5480
 
5147
- ${pc7.bold("Passing flags to Codex:")}
5481
+ ${pc8.bold("Passing flags to Codex:")}
5148
5482
  Add Codex flags directly \u2014 no "--" separator needed.
5149
5483
  anygate launches with sandbox disabled (danger-full-access) by default so shell
5150
5484
  tools can reach the network. Override with your own -s flag if you want a tighter sandbox.
5151
5485
  anygate manages --profile, -m, -p (profile), --provider, and --model; other flags go to Codex.
5152
5486
  See docs/CODEX.md for sandbox, network, and troubleshooting.
5153
5487
 
5154
- ${pc7.bold("OAuth:")}
5488
+ ${pc8.bold("OAuth:")}
5155
5489
  For ChatGPT Plus/Pro, run anygate providers auth openai first.
5156
5490
 
5157
- ${pc7.bold("Examples:")}
5491
+ ${pc8.bold("Examples:")}
5158
5492
  anygate codex
5159
5493
  anygate codex --trace
5160
5494
  anygate codex --provider zen --model deepseek-v4-flash-free
@@ -5162,8 +5496,8 @@ ${pc7.bold("Examples:")}
5162
5496
  anygate codex -s workspace-write
5163
5497
  anygate codex --restore
5164
5498
  anygate codex --help
5165
- ${pc7.bold("Favorites:")}
5166
- When you have saved favorites via ${pc7.cyan("anygate models")}, the Codex
5499
+ ${pc8.bold("Favorites:")}
5500
+ When you have saved favorites via ${pc8.cyan("anygate models")}, the Codex
5167
5501
  picker will show your starting model + favorites for mid-session switching.
5168
5502
  Zen/Go favorites are included when an OpenCode API key is available.`;
5169
5503
  }
@@ -5213,14 +5547,14 @@ function printCodexCleanupReminder(hadProxy) {
5213
5547
  if (isAgentStdoutMode()) return;
5214
5548
  const left = remainingOverlayPaths();
5215
5549
  if (left.length > 0) {
5216
- p8.log.warn("Temporary Codex overlay files may still be on disk.");
5217
- p8.log.info("Run: anygate codex --restore");
5550
+ p9.log.warn("Temporary Codex overlay files may still be on disk.");
5551
+ p9.log.info("Run: anygate codex --restore");
5218
5552
  return;
5219
5553
  }
5220
5554
  const parts = ["Temporary Codex profile removed."];
5221
5555
  if (hadProxy) parts.push("Local Responses proxy stopped.");
5222
5556
  parts.push("If a future session acts stuck: anygate codex --restore");
5223
- p8.log.info(parts.join(" "));
5557
+ p9.log.info(parts.join(" "));
5224
5558
  }
5225
5559
  function vertexEntryToLocalModel(entry) {
5226
5560
  return {
@@ -5237,26 +5571,26 @@ function vertexEntryToLocalModel(entry) {
5237
5571
  }
5238
5572
  async function runCodexVertexLaunch(passthroughArgs, trace) {
5239
5573
  if (!hasApplicationDefaultCredentials()) {
5240
- p8.log.error("Google Application Default Credentials not found.");
5241
- p8.log.info("Run: gcloud auth application-default login");
5574
+ p9.log.error("Google Application Default Credentials not found.");
5575
+ p9.log.info("Run: gcloud auth application-default login");
5242
5576
  return 1;
5243
5577
  }
5244
5578
  const config = buildVertexRuntimeConfig();
5245
5579
  if (!config) {
5246
- p8.log.error("ANTHROPIC_VERTEX_PROJECT_ID (or GOOGLE_CLOUD_PROJECT) is not set.");
5247
- p8.log.info("Set your project: export ANTHROPIC_VERTEX_PROJECT_ID=your-project-id");
5580
+ p9.log.error("ANTHROPIC_VERTEX_PROJECT_ID (or GOOGLE_CLOUD_PROJECT) is not set.");
5581
+ p9.log.info("Set your project: export ANTHROPIC_VERTEX_PROJECT_ID=your-project-id");
5248
5582
  return 1;
5249
5583
  }
5250
5584
  let selectedEntry;
5251
5585
  if (config.models.length === 1) {
5252
5586
  selectedEntry = config.models[0];
5253
5587
  } else {
5254
- const choice = await p8.select({
5588
+ const choice = await p9.select({
5255
5589
  message: "Select a Vertex AI model:",
5256
5590
  options: config.models.map((m) => ({ value: m, label: m.display_name, hint: m.id }))
5257
5591
  });
5258
- if (p8.isCancel(choice)) {
5259
- p8.cancel("Cancelled.");
5592
+ if (p9.isCancel(choice)) {
5593
+ p9.cancel("Cancelled.");
5260
5594
  return 0;
5261
5595
  }
5262
5596
  selectedEntry = choice;
@@ -5284,7 +5618,7 @@ async function runCodexVertexLaunch(passthroughArgs, trace) {
5284
5618
  const debugLogPath = getCodexProxyDebugLogPath();
5285
5619
  let proxyHandle = null;
5286
5620
  try {
5287
- p8.log.info(`Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`);
5621
+ p9.log.info(`Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`);
5288
5622
  proxyHandle = await startCodexProxy(allRoutes, { debug: trace });
5289
5623
  const proxyPort = proxyHandle.port;
5290
5624
  const catalogPath = getCatalogOutputPath("vertex");
@@ -5335,7 +5669,7 @@ async function runCodexCommand(codexArgs, trace = false, launch = {}) {
5335
5669
  }
5336
5670
  const codexPath = findCodexBinary();
5337
5671
  if (!codexPath) {
5338
- console.error(pc7.red("\nError: codex binary not found on PATH.\n"));
5672
+ console.error(pc8.red("\nError: codex binary not found on PATH.\n"));
5339
5673
  console.error("Install OpenAI Codex CLI:");
5340
5674
  console.error(" npm install -g @openai/codex\n");
5341
5675
  return 1;
@@ -5347,7 +5681,7 @@ async function runCodexCommand(codexArgs, trace = false, launch = {}) {
5347
5681
  setAgentStdoutMode(agentStdout);
5348
5682
  const debugLogPath = getCodexProxyDebugLogPath();
5349
5683
  if (trace && !configOnly) {
5350
- p8.log.info(`Debug log: ${debugLogPath}`);
5684
+ p9.log.info(`Debug log: ${debugLogPath}`);
5351
5685
  }
5352
5686
  const isTty = Boolean(process.stdin.isTTY);
5353
5687
  if (launch.vertex) {
@@ -5355,10 +5689,10 @@ async function runCodexCommand(codexArgs, trace = false, launch = {}) {
5355
5689
  const sessionCheck = checkSessionLock(isTty);
5356
5690
  if (!sessionCheck.ok) {
5357
5691
  if (sessionCheck.reason === "non_tty") {
5358
- console.error(pc7.red("anygate codex --vertex requires an interactive terminal."));
5692
+ console.error(pc8.red("anygate codex --vertex requires an interactive terminal."));
5359
5693
  return 1;
5360
5694
  }
5361
- console.error(pc7.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`));
5695
+ console.error(pc8.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`));
5362
5696
  console.error("Run anygate codex --restore to clean up, or wait for it to finish.");
5363
5697
  return 1;
5364
5698
  }
@@ -5373,7 +5707,7 @@ async function runCodexCommand(codexArgs, trace = false, launch = {}) {
5373
5707
  prefs
5374
5708
  });
5375
5709
  if (launchPlan.error) {
5376
- console.error(pc7.red(`
5710
+ console.error(pc8.red(`
5377
5711
  Error: ${launchPlan.error}
5378
5712
  `));
5379
5713
  return 1;
@@ -5383,12 +5717,12 @@ Error: ${launchPlan.error}
5383
5717
  const sessionCheck = checkSessionLock(isTty || allowNonTty);
5384
5718
  if (!sessionCheck.ok) {
5385
5719
  if (sessionCheck.reason === "non_tty") {
5386
- console.error(pc7.red(
5720
+ console.error(pc8.red(
5387
5721
  "anygate codex requires an interactive terminal (or use --provider and --model for non-interactive launch)."
5388
5722
  ));
5389
5723
  return 1;
5390
5724
  }
5391
- console.error(pc7.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`));
5725
+ console.error(pc8.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`));
5392
5726
  console.error("Run anygate codex --restore to clean up, or wait for it to finish.");
5393
5727
  return 1;
5394
5728
  }
@@ -5396,10 +5730,10 @@ Error: ${launchPlan.error}
5396
5730
  if (!configOnly) {
5397
5731
  if (!agentStdout) codexCliIntro();
5398
5732
  if (interrupted.recovered && !agentStdout) {
5399
- p8.log.warn(
5733
+ p9.log.warn(
5400
5734
  "Found leftover Codex files from an interrupted session (closed terminal, crash, or force-quit)."
5401
5735
  );
5402
- p8.log.info(
5736
+ p9.log.info(
5403
5737
  `Removed ${interrupted.removedCount ?? "those"} file(s) automatically. If anything still looks wrong: anygate codex --restore`
5404
5738
  );
5405
5739
  }
@@ -5409,17 +5743,17 @@ Error: ${launchPlan.error}
5409
5743
  try {
5410
5744
  catalog = await fetchProviderCatalog({ agent: "codex" });
5411
5745
  } catch (err) {
5412
- console.error(pc7.red(String(err instanceof Error ? err.message : err)));
5746
+ console.error(pc8.red(String(err instanceof Error ? err.message : err)));
5413
5747
  return 1;
5414
5748
  }
5415
5749
  } else {
5416
- const catalogSpinner = p8.spinner();
5750
+ const catalogSpinner = p9.spinner();
5417
5751
  catalogSpinner.start("Loading your providers...");
5418
5752
  try {
5419
5753
  catalog = await fetchProviderCatalog({ agent: "codex" });
5420
5754
  } catch (err) {
5421
5755
  catalogSpinner.stop("");
5422
- console.error(pc7.red(String(err instanceof Error ? err.message : err)));
5756
+ console.error(pc8.red(String(err instanceof Error ? err.message : err)));
5423
5757
  return 1;
5424
5758
  }
5425
5759
  catalogSpinner.stop("");
@@ -5427,25 +5761,25 @@ Error: ${launchPlan.error}
5427
5761
  const compatible = codexCompatibleProviders(providersForPicker(catalog), "codex");
5428
5762
  if (compatible.length === 0) {
5429
5763
  if (!configOnly) {
5430
- p8.log.warn("No Codex-compatible providers in your registry.");
5431
- p8.log.info("Add a provider with anygate providers add, or sign in with anygate providers auth openai.");
5764
+ p9.log.warn("No Codex-compatible providers in your registry.");
5765
+ p9.log.info("Add a provider with anygate providers add, or sign in with anygate providers auth openai.");
5432
5766
  }
5433
5767
  return 0;
5434
5768
  }
5435
5769
  const favorites = prefs.favoriteModels ?? [];
5436
5770
  const favoritesActive = favorites.length > 0 && !launchPlan.skip;
5437
5771
  if (favoritesActive && !configOnly) {
5438
- p8.log.info(
5772
+ p9.log.info(
5439
5773
  `Favorites mode active \u2014 Codex picker will show ${favorites.length + 1} models (1 starting + ${favorites.length} favorites).`
5440
5774
  );
5441
- p8.log.info("Edit with `anygate models`.");
5775
+ p9.log.info("Edit with `anygate models`.");
5442
5776
  }
5443
5777
  let activeProvider = compatible.find((lp) => lp.id === prefs.lastCodexProvider) ?? compatible[0];
5444
5778
  let selectedModel = activeProvider.models.find((m) => m.id === prefs.lastCodexModel) ?? activeProvider.models[0];
5445
5779
  if (!configOnly && launchPlan.skip && launchPlan.target) {
5446
5780
  const resolved = findProviderAndModel(compatible, launchPlan.target);
5447
5781
  if (!resolved) {
5448
- p8.log.error(
5782
+ p9.log.error(
5449
5783
  `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
5450
5784
  );
5451
5785
  return 1;
@@ -5453,7 +5787,7 @@ Error: ${launchPlan.error}
5453
5787
  activeProvider = resolved.provider;
5454
5788
  selectedModel = resolved.model;
5455
5789
  if (!agentStdout) {
5456
- p8.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
5790
+ p9.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
5457
5791
  }
5458
5792
  } else if (!configOnly) {
5459
5793
  let currentInitialProvider = prefs.lastCodexProvider && compatible.some((o) => o.id === prefs.lastCodexProvider) ? prefs.lastCodexProvider : compatible[0].id;
@@ -5501,7 +5835,7 @@ Error: ${launchPlan.error}
5501
5835
  const apiKey = await resolveLocalProviderApiKey(activeProvider);
5502
5836
  if (!apiKey) {
5503
5837
  if (!configOnly) {
5504
- p8.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
5838
+ p9.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
5505
5839
  }
5506
5840
  return 1;
5507
5841
  }
@@ -5646,29 +5980,29 @@ Error: ${launchPlan.error}
5646
5980
  });
5647
5981
  if (configOnly) {
5648
5982
  const home = process.env["HOME"] ?? "";
5649
- const shortenPath = (p17) => home ? p17.replace(home, "~") : p17;
5983
+ const shortenPath = (p18) => home ? p18.replace(home, "~") : p18;
5650
5984
  console.log("");
5651
- console.log(pc7.bold(pc7.cyan(" CONFIG PREVIEW \u2014 anygate codex")));
5985
+ console.log(pc8.bold(pc8.cyan(" CONFIG PREVIEW \u2014 anygate codex")));
5652
5986
  console.log("");
5653
5987
  if (favoritesActive && resolvedFavorites.length > 0) {
5654
- console.log(` ${pc7.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`);
5988
+ console.log(` ${pc8.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`);
5655
5989
  console.log("");
5656
- console.log(` ${pc7.bold("Models:")}`);
5990
+ console.log(` ${pc8.bold("Models:")}`);
5657
5991
  for (const r of resolvedFavorites) {
5658
- console.log(` ${pc7.cyan(r.model.id)} ${pc7.dim(`(${r.providerName})`)}`);
5992
+ console.log(` ${pc8.cyan(r.model.id)} ${pc8.dim(`(${r.providerName})`)}`);
5659
5993
  }
5660
5994
  } else {
5661
- console.log(` ${pc7.bold("Mode:")} Single model`);
5662
- console.log(` ${pc7.bold("Provider:")} ${activeProvider.name}`);
5663
- console.log(` ${pc7.bold("Model:")} ${selectedModel.id}`);
5995
+ console.log(` ${pc8.bold("Mode:")} Single model`);
5996
+ console.log(` ${pc8.bold("Provider:")} ${activeProvider.name}`);
5997
+ console.log(` ${pc8.bold("Model:")} ${selectedModel.id}`);
5664
5998
  }
5665
5999
  console.log("");
5666
- console.log(` ${pc7.bold("Files written:")}`);
5667
- console.log(` ${pc7.dim(shortenPath(profilePath))}`);
5668
- console.log(` ${pc7.dim(shortenPath(catalogPath))}`);
6000
+ console.log(` ${pc8.bold("Files written:")}`);
6001
+ console.log(` ${pc8.dim(shortenPath(profilePath))}`);
6002
+ console.log(` ${pc8.dim(shortenPath(catalogPath))}`);
5669
6003
  console.log("");
5670
- console.log(pc7.dim(" No Codex process was started."));
5671
- console.log(pc7.dim(" Run ") + pc7.cyan("anygate codex") + pc7.dim(" to launch."));
6004
+ console.log(pc8.dim(" No Codex process was started."));
6005
+ console.log(pc8.dim(" Run ") + pc8.cyan("anygate codex") + pc8.dim(" to launch."));
5672
6006
  console.log("");
5673
6007
  restoreCodexOverlay();
5674
6008
  return 0;
@@ -5719,7 +6053,7 @@ Error: ${launchPlan.error}
5719
6053
  // src/cli/codex.ts
5720
6054
  async function handleCodexCommand(parsed) {
5721
6055
  if (parsed.showVersion) {
5722
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
6056
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
5723
6057
  console.log(VERSION2);
5724
6058
  return 0;
5725
6059
  }
@@ -5735,8 +6069,8 @@ async function handleCodexCommand(parsed) {
5735
6069
  }
5736
6070
 
5737
6071
  // src/apps/codex/app.ts
5738
- import pc8 from "picocolors";
5739
- import * as p9 from "@clack/prompts";
6072
+ import pc9 from "picocolors";
6073
+ import * as p10 from "@clack/prompts";
5740
6074
  init_config();
5741
6075
 
5742
6076
  // src/apps/codex/app-provider-routes.ts
@@ -6230,29 +6564,29 @@ async function waitForShutdownWithConfirm() {
6230
6564
  const signal = await waitForShutdown();
6231
6565
  if (signal !== "sigint") break;
6232
6566
  console.log("");
6233
- const choice = await p9.select({
6567
+ const choice = await p10.select({
6234
6568
  message: "Close ChatGPT Desktop and restore your Codex config?",
6235
6569
  options: [
6236
6570
  { value: "yes", label: "Yes, close ChatGPT Desktop and restore config" },
6237
6571
  { value: "no", label: "No, keep session running" }
6238
6572
  ]
6239
6573
  });
6240
- if (p9.isCancel(choice) || choice === "yes") break;
6574
+ if (p10.isCancel(choice) || choice === "yes") break;
6241
6575
  }
6242
6576
  }
6243
6577
  async function maybeCloseRunningCodexApp() {
6244
6578
  if (!isCodexAppRunning()) return;
6245
- const shouldClose = await p9.confirm({ message: "ChatGPT Desktop is still running. Close it?" });
6246
- if (shouldClose && !p9.isCancel(shouldClose)) {
6247
- p9.log.step("Stopping ChatGPT Desktop...");
6579
+ const shouldClose = await p10.confirm({ message: "ChatGPT Desktop is still running. Close it?" });
6580
+ if (shouldClose && !p10.isCancel(shouldClose)) {
6581
+ p10.log.step("Stopping ChatGPT Desktop...");
6248
6582
  quitCodexAppGracefully();
6249
6583
  }
6250
6584
  }
6251
6585
  function codexAppHelpText() {
6252
- return `${pc8.bold("anygate codex-app")} \u2014 launch the ChatGPT desktop app (Codex mode) with your registry providers
6253
- ${pc8.dim('(OpenAI merged the Codex app into ChatGPT desktop on 2026-07-09; "chatgpt" is an alias for this command)')}
6586
+ return `${pc9.bold("anygate codex-app")} \u2014 launch the ChatGPT desktop app (Codex mode) with your registry providers
6587
+ ${pc9.dim('(OpenAI merged the Codex app into ChatGPT desktop on 2026-07-09; "chatgpt" is an alias for this command)')}
6254
6588
 
6255
- ${pc8.bold("Usage:")}
6589
+ ${pc9.bold("Usage:")}
6256
6590
  anygate codex-app [options]
6257
6591
  anygate chatgpt [options]
6258
6592
  anygate codex-app --vertex
@@ -6261,7 +6595,7 @@ ${pc8.bold("Usage:")}
6261
6595
  anygate codex-app --help
6262
6596
  anygate codex-app --version
6263
6597
 
6264
- ${pc8.bold("Options:")}
6598
+ ${pc9.bold("Options:")}
6265
6599
  --vertex Use Claude models through Google Vertex AI
6266
6600
  --restore Restore Codex config after an interrupted app session
6267
6601
  --config Preview the generated Codex app configuration without launching
@@ -6269,31 +6603,31 @@ ${pc8.bold("Options:")}
6269
6603
  --help Show this command help
6270
6604
  --version Show version
6271
6605
 
6272
- ${pc8.bold("Description:")}
6606
+ ${pc9.bold("Description:")}
6273
6607
  Picks a provider and model from ~/.anygate/providers.json, patches ~/.codex/config.toml
6274
6608
  (with backup + restore on Ctrl+C), starts a local Responses proxy, and opens the
6275
6609
  ChatGPT desktop app in Codex mode. Keep this terminal open while using Codex.
6276
6610
 
6277
- ${pc8.bold("Platforms:")}
6611
+ ${pc9.bold("Platforms:")}
6278
6612
  macOS and Windows. Linux is not supported (no ChatGPT desktop app).
6279
6613
 
6280
- ${pc8.bold("Cleanup:")}
6614
+ ${pc9.bold("Cleanup:")}
6281
6615
  Ctrl+C stops the proxy and restores your previous Codex config.
6282
6616
  After crash: anygate codex-app --restore
6283
6617
 
6284
- ${pc8.bold("Preview (no writes):")}
6618
+ ${pc9.bold("Preview (no writes):")}
6285
6619
  anygate codex-app --config
6286
6620
 
6287
6621
  See docs/CODEX.md for CLI vs app, files touched, and restore.
6288
6622
 
6289
- ${pc8.bold("Examples:")}
6623
+ ${pc9.bold("Examples:")}
6290
6624
  anygate codex-app
6291
6625
  anygate codex-app --vertex
6292
6626
  anygate codex-app --config
6293
6627
  anygate codex-app --restore
6294
6628
 
6295
- ${pc8.bold("Favorites:")}
6296
- When you have saved favorites via ${pc8.cyan("anygate models")}, the Codex App
6629
+ ${pc9.bold("Favorites:")}
6630
+ When you have saved favorites via ${pc9.cyan("anygate models")}, the Codex App
6297
6631
  picker will show your starting model + favorites for mid-session switching.
6298
6632
  Zen/Go favorites are included when an OpenCode API key is available.`;
6299
6633
  }
@@ -6315,26 +6649,26 @@ function vertexEntryToLocalModel2(entry) {
6315
6649
  }
6316
6650
  async function runCodexAppVertexLaunch(configOnly, trace = false) {
6317
6651
  if (!hasApplicationDefaultCredentials()) {
6318
- p9.log.error("Google Application Default Credentials not found.");
6319
- p9.log.info("Run: gcloud auth application-default login");
6652
+ p10.log.error("Google Application Default Credentials not found.");
6653
+ p10.log.info("Run: gcloud auth application-default login");
6320
6654
  return 1;
6321
6655
  }
6322
6656
  const config = buildVertexRuntimeConfig();
6323
6657
  if (!config) {
6324
- p9.log.error("ANTHROPIC_VERTEX_PROJECT_ID (or GOOGLE_CLOUD_PROJECT) is not set.");
6325
- p9.log.info("Set your project: export ANTHROPIC_VERTEX_PROJECT_ID=your-project-id");
6658
+ p10.log.error("ANTHROPIC_VERTEX_PROJECT_ID (or GOOGLE_CLOUD_PROJECT) is not set.");
6659
+ p10.log.info("Set your project: export ANTHROPIC_VERTEX_PROJECT_ID=your-project-id");
6326
6660
  return 1;
6327
6661
  }
6328
6662
  let selectedEntry;
6329
6663
  if (config.models.length === 1) {
6330
6664
  selectedEntry = config.models[0];
6331
6665
  } else {
6332
- const choice = await p9.select({
6666
+ const choice = await p10.select({
6333
6667
  message: "Select a starting Vertex AI model:",
6334
6668
  options: config.models.map((m) => ({ value: m, label: m.display_name, hint: m.id }))
6335
6669
  });
6336
- if (p9.isCancel(choice)) {
6337
- p9.cancel("Cancelled.");
6670
+ if (p10.isCancel(choice)) {
6671
+ p10.cancel("Cancelled.");
6338
6672
  return 0;
6339
6673
  }
6340
6674
  selectedEntry = choice;
@@ -6357,19 +6691,19 @@ async function runCodexAppVertexLaunch(configOnly, trace = false) {
6357
6691
  const home = process.env["HOME"] ?? "";
6358
6692
  const shortenPath = (fp) => home ? fp.replace(home, "~") : fp;
6359
6693
  console.log("");
6360
- console.log(pc8.bold(pc8.cyan(" CONFIG PREVIEW \u2014 anygate codex-app --vertex")));
6694
+ console.log(pc9.bold(pc9.cyan(" CONFIG PREVIEW \u2014 anygate codex-app --vertex")));
6361
6695
  console.log("");
6362
- console.log(` ${pc8.bold("Mode:")} Vertex AI`);
6363
- console.log(` ${pc8.bold("Project:")} ${config.project}`);
6364
- console.log(` ${pc8.bold("Location:")} ${config.location}`);
6365
- console.log(` ${pc8.bold("Model:")} ${selectedEntry.display_name}`);
6366
- console.log(` ${pc8.bold("Catalog:")} ${vertexModels.length} model${vertexModels.length !== 1 ? "s" : ""} available`);
6696
+ console.log(` ${pc9.bold("Mode:")} Vertex AI`);
6697
+ console.log(` ${pc9.bold("Project:")} ${config.project}`);
6698
+ console.log(` ${pc9.bold("Location:")} ${config.location}`);
6699
+ console.log(` ${pc9.bold("Model:")} ${selectedEntry.display_name}`);
6700
+ console.log(` ${pc9.bold("Catalog:")} ${vertexModels.length} model${vertexModels.length !== 1 ? "s" : ""} available`);
6367
6701
  console.log("");
6368
- console.log(` ${pc8.bold("Catalog file:")}`);
6369
- console.log(` ${pc8.dim(shortenPath(catalogPath))}`);
6702
+ console.log(` ${pc9.bold("Catalog file:")}`);
6703
+ console.log(` ${pc9.dim(shortenPath(catalogPath))}`);
6370
6704
  console.log("");
6371
- console.log(pc8.dim(" No app was launched."));
6372
- console.log(pc8.dim(" Run ") + pc8.cyan("anygate codex-app --vertex") + pc8.dim(" to launch."));
6705
+ console.log(pc9.dim(" No app was launched."));
6706
+ console.log(pc9.dim(" Run ") + pc9.cyan("anygate codex-app --vertex") + pc9.dim(" to launch."));
6373
6707
  console.log("");
6374
6708
  return 0;
6375
6709
  }
@@ -6409,14 +6743,14 @@ async function runCodexAppVertexLaunch(configOnly, trace = false) {
6409
6743
  proxyPort
6410
6744
  });
6411
6745
  sessionActive = true;
6412
- p9.log.info(`Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`);
6746
+ p10.log.info(`Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`);
6413
6747
  logProxy(proxyPort);
6414
6748
  logActiveModel(selectedEntry.display_name, selectedEntry.id);
6415
6749
  try {
6416
6750
  await launchOrRestartCodexApp();
6417
6751
  } catch (err) {
6418
- p9.log.warn(String(err instanceof Error ? err.message : err));
6419
- p9.log.info(codexAppInstallHint());
6752
+ p10.log.warn(String(err instanceof Error ? err.message : err));
6753
+ p10.log.info(codexAppInstallHint());
6420
6754
  }
6421
6755
  printCodexAppSessionPanel({
6422
6756
  modelLabel: selectedEntry.display_name,
@@ -6451,7 +6785,7 @@ async function runCodexAppCommand(args, opts = {}) {
6451
6785
  try {
6452
6786
  codexAppSupported();
6453
6787
  } catch (err) {
6454
- console.error(pc8.red(String(err instanceof Error ? err.message : err)));
6788
+ console.error(pc9.red(String(err instanceof Error ? err.message : err)));
6455
6789
  return 1;
6456
6790
  }
6457
6791
  const interrupted = recoverInterruptedCodexAppSession();
@@ -6459,17 +6793,17 @@ async function runCodexAppCommand(args, opts = {}) {
6459
6793
  const trace = args.includes("--trace");
6460
6794
  const debugLogPath = getCodexProxyDebugLogPath();
6461
6795
  if (trace && !configOnly) {
6462
- p9.log.info(`Debug log: ${debugLogPath}`);
6796
+ p10.log.info(`Debug log: ${debugLogPath}`);
6463
6797
  }
6464
6798
  const isTty = Boolean(process.stdin.isTTY);
6465
6799
  if (!configOnly) {
6466
6800
  const sessionCheck = checkAppSessionLock(isTty);
6467
6801
  if (!sessionCheck.ok) {
6468
6802
  if (sessionCheck.reason === "non_tty") {
6469
- console.error(pc8.red("anygate codex-app requires an interactive terminal."));
6803
+ console.error(pc9.red("anygate codex-app requires an interactive terminal."));
6470
6804
  return 1;
6471
6805
  }
6472
- console.error(pc8.yellow(`Another anygate codex-app session may be running (pid ${sessionCheck.lock.pid}).`));
6806
+ console.error(pc9.yellow(`Another anygate codex-app session may be running (pid ${sessionCheck.lock.pid}).`));
6473
6807
  console.error("Stop it with Ctrl+C in that terminal, or run anygate codex-app --restore after it exits.");
6474
6808
  return 1;
6475
6809
  }
@@ -6477,28 +6811,28 @@ async function runCodexAppCommand(args, opts = {}) {
6477
6811
  if (!configOnly) {
6478
6812
  codexAppIntro();
6479
6813
  if (interrupted.recovered) {
6480
- p9.log.warn("Recovered from an interrupted codex-app session (restored Codex config).");
6814
+ p10.log.warn("Recovered from an interrupted codex-app session (restored Codex config).");
6481
6815
  }
6482
6816
  }
6483
6817
  if (opts.vertex) {
6484
6818
  return runCodexAppVertexLaunch(configOnly, trace);
6485
6819
  }
6486
- const catalogSpinner = p9.spinner();
6820
+ const catalogSpinner = p10.spinner();
6487
6821
  catalogSpinner.start("Loading your providers...");
6488
6822
  let catalog;
6489
6823
  try {
6490
6824
  catalog = await fetchProviderCatalog({ agent: "codex-app" });
6491
6825
  } catch (err) {
6492
6826
  catalogSpinner.stop("");
6493
- console.error(pc8.red(String(err instanceof Error ? err.message : err)));
6827
+ console.error(pc9.red(String(err instanceof Error ? err.message : err)));
6494
6828
  return 1;
6495
6829
  }
6496
6830
  catalogSpinner.stop("");
6497
6831
  const compatible = codexCompatibleProviders(providersForPicker(catalog), "codex-app");
6498
6832
  if (compatible.length === 0) {
6499
6833
  if (!configOnly) {
6500
- p9.log.warn("No Codex-compatible providers in your registry.");
6501
- p9.log.info("Add a provider with anygate providers add.");
6834
+ p10.log.warn("No Codex-compatible providers in your registry.");
6835
+ p10.log.info("Add a provider with anygate providers add.");
6502
6836
  }
6503
6837
  return 0;
6504
6838
  }
@@ -6507,10 +6841,10 @@ async function runCodexAppCommand(args, opts = {}) {
6507
6841
  const favoritesActive = favorites.length > 0;
6508
6842
  const useFavoritesCatalog = args.includes("--favorites");
6509
6843
  if (favoritesActive && !configOnly) {
6510
- p9.log.info(
6844
+ p10.log.info(
6511
6845
  `Favorites mode active \u2014 Codex App picker will show ${favorites.length + 1} models (1 starting + ${favorites.length} favorites).`
6512
6846
  );
6513
- p9.log.info("Edit with `anygate models`.");
6847
+ p10.log.info("Edit with `anygate models`.");
6514
6848
  }
6515
6849
  let activeProvider = providerForCodexPicker(
6516
6850
  compatible.find((lp) => lp.id === prefs.lastCodexProvider) ?? compatible[0]
@@ -6524,7 +6858,7 @@ async function runCodexAppCommand(args, opts = {}) {
6524
6858
  providerForCodexPicker
6525
6859
  );
6526
6860
  if ("error" in bootSelection) {
6527
- p9.log.error(bootSelection.error);
6861
+ p10.log.error(bootSelection.error);
6528
6862
  return 1;
6529
6863
  }
6530
6864
  activeProvider = bootSelection.provider;
@@ -6536,7 +6870,7 @@ async function runCodexAppCommand(args, opts = {}) {
6536
6870
  compatible.map(providerForCodexPicker)
6537
6871
  );
6538
6872
  if (!firstFavorite) {
6539
- p9.log.warn("No saved favorites are currently available.");
6873
+ p10.log.warn("No saved favorites are currently available.");
6540
6874
  return 0;
6541
6875
  }
6542
6876
  activeProvider = providerForCodexPicker(firstFavorite.provider);
@@ -6575,7 +6909,7 @@ async function runCodexAppCommand(args, opts = {}) {
6575
6909
  const apiKey = await resolveLocalProviderApiKey(activeProvider);
6576
6910
  if (!apiKey) {
6577
6911
  if (!configOnly) {
6578
- p9.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
6912
+ p10.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
6579
6913
  }
6580
6914
  return 1;
6581
6915
  }
@@ -6626,36 +6960,36 @@ async function runCodexAppCommand(args, opts = {}) {
6626
6960
  const home = process.env["HOME"] ?? "";
6627
6961
  const shortenPath = (fp) => home ? fp.replace(home, "~") : fp;
6628
6962
  console.log("");
6629
- console.log(pc8.bold(pc8.cyan(" CONFIG PREVIEW \u2014 anygate codex-app")));
6963
+ console.log(pc9.bold(pc9.cyan(" CONFIG PREVIEW \u2014 anygate codex-app")));
6630
6964
  console.log("");
6631
6965
  if (favoritesActive) {
6632
- console.log(` ${pc8.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`);
6966
+ console.log(` ${pc9.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`);
6633
6967
  console.log("");
6634
- console.log(` ${pc8.bold("Models:")}`);
6968
+ console.log(` ${pc9.bold("Models:")}`);
6635
6969
  for (const r of resolvedFavorites) {
6636
- console.log(` ${pc8.cyan(r.model.id)} ${pc8.dim(`(${r.providerName})`)}`);
6970
+ console.log(` ${pc9.cyan(r.model.id)} ${pc9.dim(`(${r.providerName})`)}`);
6637
6971
  }
6638
6972
  } else {
6639
- console.log(` ${pc8.bold("Mode:")} Single model`);
6640
- console.log(` ${pc8.bold("Provider:")} ${activeProvider.name}`);
6641
- console.log(` ${pc8.bold("Model:")} ${formatCodexModelLabel(selectedModel)}`);
6642
- console.log(` ${pc8.bold("Catalog:")} ${routable.length} model${routable.length !== 1 ? "s" : ""} available`);
6973
+ console.log(` ${pc9.bold("Mode:")} Single model`);
6974
+ console.log(` ${pc9.bold("Provider:")} ${activeProvider.name}`);
6975
+ console.log(` ${pc9.bold("Model:")} ${formatCodexModelLabel(selectedModel)}`);
6976
+ console.log(` ${pc9.bold("Catalog:")} ${routable.length} model${routable.length !== 1 ? "s" : ""} available`);
6643
6977
  }
6644
6978
  console.log("");
6645
- console.log(` ${pc8.bold("config.toml patch preview:")}`);
6979
+ console.log(` ${pc9.bold("config.toml patch preview:")}`);
6646
6980
  const tomlPreview = previewAppConfigToml({
6647
6981
  ...specBase,
6648
6982
  proxyPort: PREVIEW_PROXY_PORT
6649
6983
  });
6650
6984
  for (const line2 of tomlPreview.split("\n")) {
6651
- console.log(` ${pc8.dim(line2)}`);
6985
+ console.log(` ${pc9.dim(line2)}`);
6652
6986
  }
6653
6987
  console.log("");
6654
- console.log(` ${pc8.bold("Catalog file:")}`);
6655
- console.log(` ${pc8.dim(shortenPath(catalogPath))}`);
6988
+ console.log(` ${pc9.bold("Catalog file:")}`);
6989
+ console.log(` ${pc9.dim(shortenPath(catalogPath))}`);
6656
6990
  console.log("");
6657
- console.log(pc8.dim(" No app was launched."));
6658
- console.log(pc8.dim(" Run ") + pc8.cyan("anygate codex-app") + pc8.dim(" to launch."));
6991
+ console.log(pc9.dim(" No app was launched."));
6992
+ console.log(pc9.dim(" Run ") + pc9.cyan("anygate codex-app") + pc9.dim(" to launch."));
6659
6993
  console.log("");
6660
6994
  return 0;
6661
6995
  }
@@ -6741,8 +7075,8 @@ async function runCodexAppCommand(args, opts = {}) {
6741
7075
  try {
6742
7076
  await launchOrRestartCodexApp();
6743
7077
  } catch (err) {
6744
- p9.log.warn(String(err instanceof Error ? err.message : err));
6745
- p9.log.info(codexAppInstallHint());
7078
+ p10.log.warn(String(err instanceof Error ? err.message : err));
7079
+ p10.log.info(codexAppInstallHint());
6746
7080
  }
6747
7081
  printCodexAppSessionPanel({
6748
7082
  modelLabel,
@@ -6775,7 +7109,7 @@ async function runCodexAppCommand(args, opts = {}) {
6775
7109
  // src/cli/codex-app.ts
6776
7110
  async function handleCodexAppCommand(parsed) {
6777
7111
  if (parsed.showVersion) {
6778
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
7112
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
6779
7113
  console.log(VERSION2);
6780
7114
  return 0;
6781
7115
  }
@@ -6807,8 +7141,8 @@ This command launches the ChatGPT Desktop app with anygate's provider registry.
6807
7141
  }
6808
7142
 
6809
7143
  // src/apps/claude/desktop.ts
6810
- import pc9 from "picocolors";
6811
- import * as p10 from "@clack/prompts";
7144
+ import pc10 from "picocolors";
7145
+ import * as p11 from "@clack/prompts";
6812
7146
  init_config();
6813
7147
 
6814
7148
  // src/apps/claude/desktop-app.ts
@@ -6980,30 +7314,30 @@ function setupExitCleanup(uuid) {
6980
7314
 
6981
7315
  // src/apps/claude/desktop.ts
6982
7316
  function claudeAppHelpText() {
6983
- return `${pc9.bold("anygate claude-app")} \u2014 launch Claude Desktop app in 3P mode with your registry providers
7317
+ return `${pc10.bold("anygate claude-app")} \u2014 launch Claude Desktop app in 3P mode with your registry providers
6984
7318
 
6985
- ${pc9.bold("Usage:")}
7319
+ ${pc10.bold("Usage:")}
6986
7320
  anygate claude-app [options]
6987
7321
  anygate claude-app --trace
6988
7322
  anygate claude-app --restore
6989
7323
  anygate claude-app --help
6990
7324
  anygate claude-app --version
6991
7325
 
6992
- ${pc9.bold("Options:")}
7326
+ ${pc10.bold("Options:")}
6993
7327
  --trace Write proxy debug logs to ~/.anygate/logs/
6994
7328
  --restore Restore Claude Desktop config after an interrupted app session
6995
7329
  --help Show this command help
6996
7330
  --version Show version
6997
7331
 
6998
- ${pc9.bold("Description:")}
7332
+ ${pc10.bold("Description:")}
6999
7333
  Picks a provider and model from ~/.anygate/providers.json, patches Claude Desktop config
7000
7334
  (with backup + restore on Ctrl+C), starts a local Responses proxy, and opens
7001
7335
  the Claude Desktop app. Keep this terminal open while using Claude.
7002
7336
 
7003
- ${pc9.bold("Platforms:")}
7337
+ ${pc10.bold("Platforms:")}
7004
7338
  macOS and Windows. Linux is not supported.
7005
7339
 
7006
- ${pc9.bold("Cleanup:")}
7340
+ ${pc10.bold("Cleanup:")}
7007
7341
  Ctrl+C stops the proxy and restores your previous Claude config.
7008
7342
  After a crash: anygate claude-app --restore
7009
7343
  `;
@@ -7055,37 +7389,37 @@ async function runClaudeAppCommand(args, boot) {
7055
7389
  try {
7056
7390
  claudeAppSupported();
7057
7391
  } catch (err) {
7058
- console.error(pc9.red(String(err instanceof Error ? err.message : err)));
7392
+ console.error(pc10.red(String(err instanceof Error ? err.message : err)));
7059
7393
  return 1;
7060
7394
  }
7061
7395
  const isTty = Boolean(process.stdin.isTTY);
7062
7396
  if (!isTty) {
7063
- console.error(pc9.red("anygate claude-app requires an interactive terminal."));
7397
+ console.error(pc10.red("anygate claude-app requires an interactive terminal."));
7064
7398
  return 1;
7065
7399
  }
7066
7400
  if (isConcurrentLiveSession()) {
7067
- console.error(pc9.yellow(`Another anygate claude-app session may be running.`));
7401
+ console.error(pc10.yellow(`Another anygate claude-app session may be running.`));
7068
7402
  console.error("Stop it with Ctrl+C in that terminal.");
7069
7403
  return 1;
7070
7404
  }
7071
7405
  if (hasStaleSession()) {
7072
- p10.log.warn("Recovered from an interrupted claude-app session.");
7406
+ p11.log.warn("Recovered from an interrupted claude-app session.");
7073
7407
  recoverSession();
7074
7408
  }
7075
- const catalogSpinner = p10.spinner();
7409
+ const catalogSpinner = p11.spinner();
7076
7410
  catalogSpinner.start("Loading your providers...");
7077
7411
  let catalog;
7078
7412
  try {
7079
7413
  catalog = await fetchProviderCatalog({ agent: "codex-app" });
7080
7414
  } catch (err) {
7081
7415
  catalogSpinner.stop("");
7082
- console.error(pc9.red(String(err instanceof Error ? err.message : err)));
7416
+ console.error(pc10.red(String(err instanceof Error ? err.message : err)));
7083
7417
  return 1;
7084
7418
  }
7085
7419
  catalogSpinner.stop("");
7086
7420
  const compatible = codexCompatibleProviders(providersForPicker(catalog), "claude-app");
7087
7421
  if (compatible.length === 0) {
7088
- p10.log.warn("No compatible providers in your registry.");
7422
+ p11.log.warn("No compatible providers in your registry.");
7089
7423
  return 0;
7090
7424
  }
7091
7425
  const prefs = loadPreferences();
@@ -7102,7 +7436,7 @@ async function runClaudeAppCommand(args, boot) {
7102
7436
  providerForClaudePicker
7103
7437
  );
7104
7438
  if ("error" in bootSelection) {
7105
- p10.log.error(bootSelection.error);
7439
+ p11.log.error(bootSelection.error);
7106
7440
  return 1;
7107
7441
  }
7108
7442
  activeProvider = bootSelection.provider;
@@ -7124,7 +7458,7 @@ async function runClaudeAppCommand(args, boot) {
7124
7458
  if (activeProvider) {
7125
7459
  const apiKey = await resolveLocalProviderApiKey(activeProvider);
7126
7460
  if (!apiKey) {
7127
- p10.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
7461
+ p11.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
7128
7462
  return 1;
7129
7463
  }
7130
7464
  activeProvider.apiKey = apiKey;
@@ -7236,21 +7570,21 @@ async function runClaudeAppCommand(args, boot) {
7236
7570
  });
7237
7571
  }
7238
7572
  console.log(`
7239
- ${pc9.green("\u2714")} Proxy started on port ${proxyHandle.port}`);
7573
+ ${pc10.green("\u2714")} Proxy started on port ${proxyHandle.port}`);
7240
7574
  try {
7241
7575
  await launchOrRestartClaudeApp();
7242
7576
  } catch (err) {
7243
- p10.log.warn(String(err instanceof Error ? err.message : err));
7577
+ p11.log.warn(String(err instanceof Error ? err.message : err));
7244
7578
  }
7245
7579
  console.log(`
7246
- ${pc9.bold("Claude Desktop 3P Mode Active")}`);
7580
+ ${pc10.bold("Claude Desktop 3P Mode Active")}`);
7247
7581
  if (useFavorites) {
7248
- console.log(`${pc9.dim("Catalog:")} Favorite models only`);
7582
+ console.log(`${pc10.dim("Catalog:")} Favorite models only`);
7249
7583
  } else {
7250
- console.log(`${pc9.dim("Model:")} ${selectedModel.id}`);
7251
- console.log(`${pc9.dim("Provider:")} ${activeProvider.name}`);
7584
+ console.log(`${pc10.dim("Model:")} ${selectedModel.id}`);
7585
+ console.log(`${pc10.dim("Provider:")} ${activeProvider.name}`);
7252
7586
  }
7253
- console.log(`${pc9.cyan("Press Ctrl+C to stop and restore config.")}`);
7587
+ console.log(`${pc10.cyan("Press Ctrl+C to stop and restore config.")}`);
7254
7588
  await waitForShutdown2();
7255
7589
  console.log("");
7256
7590
  cleanupSession(uuid);
@@ -7258,8 +7592,8 @@ ${pc9.bold("Claude Desktop 3P Mode Active")}`);
7258
7592
  if (cloudCodeBackend) cloudCodeBackend.handle.close();
7259
7593
  if (cloudCodeFavBackend) cloudCodeFavBackend.handle.close();
7260
7594
  if (isClaudeAppRunning()) {
7261
- const shouldClose = await p10.confirm({ message: "Claude Desktop is still running. Close it?" });
7262
- if (shouldClose && !p10.isCancel(shouldClose)) {
7595
+ const shouldClose = await p11.confirm({ message: "Claude Desktop is still running. Close it?" });
7596
+ if (shouldClose && !p11.isCancel(shouldClose)) {
7263
7597
  quitClaudeAppGracefully();
7264
7598
  }
7265
7599
  }
@@ -7278,7 +7612,7 @@ ${pc9.bold("Claude Desktop 3P Mode Active")}`);
7278
7612
  // src/cli/claude-app.ts
7279
7613
  async function handleClaudeAppCommand(parsed) {
7280
7614
  if (parsed.showVersion) {
7281
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
7615
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
7282
7616
  console.log(VERSION2);
7283
7617
  return 0;
7284
7618
  }
@@ -7308,8 +7642,8 @@ This command launches the Claude Desktop app with anygate's provider registry.
7308
7642
  }
7309
7643
 
7310
7644
  // src/apps/gemini/cli.ts
7311
- import pc10 from "picocolors";
7312
- import * as p12 from "@clack/prompts";
7645
+ import pc11 from "picocolors";
7646
+ import * as p13 from "@clack/prompts";
7313
7647
  init_config();
7314
7648
 
7315
7649
  // src/apps/gemini/launch.ts
@@ -7400,7 +7734,7 @@ function launchGemini(geminiPath, modelId, env, extraArgs) {
7400
7734
  }
7401
7735
 
7402
7736
  // src/apps/gemini/prompts.ts
7403
- import * as p11 from "@clack/prompts";
7737
+ import * as p12 from "@clack/prompts";
7404
7738
  async function pickGeminiProvider(providers, prefs, hasFavorites = false, initialProviderId) {
7405
7739
  if (providers.length === 0 && !hasFavorites) return null;
7406
7740
  const options = providers.map((lp) => providerSelectOption(lp));
@@ -7412,13 +7746,13 @@ async function pickGeminiProvider(providers, prefs, hasFavorites = false, initia
7412
7746
  });
7413
7747
  }
7414
7748
  const initial = initialProviderId && options.some((o) => o.value === initialProviderId) ? initialProviderId : prefs.lastGeminiProvider && options.some((o) => o.value === prefs.lastGeminiProvider) ? prefs.lastGeminiProvider : options[0].value;
7415
- const chosen = await p11.select({
7749
+ const chosen = await p12.select({
7416
7750
  message: "Which provider for Gemini CLI?",
7417
7751
  options,
7418
7752
  initialValue: initial
7419
7753
  });
7420
- if (p11.isCancel(chosen)) {
7421
- p11.cancel("Cancelled.");
7754
+ if (p12.isCancel(chosen)) {
7755
+ p12.cancel("Cancelled.");
7422
7756
  return null;
7423
7757
  }
7424
7758
  if (chosen === "__favorites__") return "__favorites__";
@@ -7435,12 +7769,12 @@ async function pickGeminiModel(provider, prefs) {
7435
7769
  navOption("__browse_all__", "Browse all models \u2192", `${provider.models.length} available`),
7436
7770
  navOption("__back__", "\u2190 Go back", "Select a different provider")
7437
7771
  ];
7438
- const picked = await p11.select({
7772
+ const picked = await p12.select({
7439
7773
  message: `Model for ${provider.name}?`,
7440
7774
  options,
7441
7775
  initialValue: recentModels[0].id
7442
7776
  });
7443
- if (p11.isCancel(picked) || String(picked) === "__back__") {
7777
+ if (p12.isCancel(picked) || String(picked) === "__back__") {
7444
7778
  return "back";
7445
7779
  }
7446
7780
  if (String(picked) === "__browse_all__") {
@@ -7468,12 +7802,12 @@ async function pickGeminiModel(provider, prefs) {
7468
7802
  return selectedModel;
7469
7803
  }
7470
7804
  function confirmGeminiLaunch(providerName, modelLabel, modelId) {
7471
- return p11.confirm({
7805
+ return p12.confirm({
7472
7806
  message: confirmLaunchMessage("Gemini CLI", modelLabel, modelId, providerName),
7473
7807
  initialValue: true
7474
7808
  }).then((answer) => {
7475
- if (p11.isCancel(answer)) {
7476
- p11.cancel("Cancelled.");
7809
+ if (p12.isCancel(answer)) {
7810
+ p12.cancel("Cancelled.");
7477
7811
  return false;
7478
7812
  }
7479
7813
  return answer;
@@ -7487,7 +7821,7 @@ async function pickGeminiFavoriteModel(providers, favorites) {
7487
7821
  if (provider2 && model2) favList.push({ provider: provider2, model: model2 });
7488
7822
  }
7489
7823
  if (favList.length === 0) {
7490
- p11.log.warn("None of your saved favorites are available in the current registry.");
7824
+ p12.log.warn("None of your saved favorites are available in the current registry.");
7491
7825
  return null;
7492
7826
  }
7493
7827
  const options = [
@@ -7498,12 +7832,12 @@ async function pickGeminiFavoriteModel(providers, favorites) {
7498
7832
  })),
7499
7833
  { value: "__back__", label: "\u2190 Go back", hint: "Select a different provider" }
7500
7834
  ];
7501
- const picked = await p11.select({
7835
+ const picked = await p12.select({
7502
7836
  message: "Pick a favorite model for Gemini CLI:",
7503
7837
  options,
7504
7838
  initialValue: options[0].value
7505
7839
  });
7506
- if (p11.isCancel(picked) || String(picked) === "__back__") return "back";
7840
+ if (p12.isCancel(picked) || String(picked) === "__back__") return "back";
7507
7841
  const [pickedProviderId, pickedModelId] = picked.split("::");
7508
7842
  const provider = providers.find((lp) => lp.id === pickedProviderId);
7509
7843
  const model = provider?.models.find((m) => m.id === pickedModelId);
@@ -7583,7 +7917,7 @@ function stripGeminiIdentity(text4) {
7583
7917
  function translateGeminiRequest(body, options = {}) {
7584
7918
  let system;
7585
7919
  if (body.systemInstruction?.parts) {
7586
- const rawSystem = body.systemInstruction.parts.map((p17) => p17.text || "").join("\n");
7920
+ const rawSystem = body.systemInstruction.parts.map((p18) => p18.text || "").join("\n");
7587
7921
  system = stripGeminiIdentity(rawSystem).trim();
7588
7922
  }
7589
7923
  const messages = [];
@@ -7594,9 +7928,9 @@ function translateGeminiRequest(body, options = {}) {
7594
7928
  const parts = [];
7595
7929
  const toolResults = [];
7596
7930
  const turnParts = turn.parts || [];
7597
- for (const p17 of turnParts) {
7598
- if (p17.text !== void 0) {
7599
- const text4 = stripGeminiIdentity(p17.text);
7931
+ for (const p18 of turnParts) {
7932
+ if (p18.text !== void 0) {
7933
+ const text4 = stripGeminiIdentity(p18.text);
7600
7934
  if (text4.includes("<thinking>")) {
7601
7935
  const tokens = text4.split(/<thinking>([\s\S]*?)<\/thinking>/);
7602
7936
  for (let i = 0; i < tokens.length; i++) {
@@ -7607,25 +7941,25 @@ function translateGeminiRequest(body, options = {}) {
7607
7941
  } else {
7608
7942
  parts.push({ type: "text", text: text4 });
7609
7943
  }
7610
- } else if (p17.inlineData) {
7944
+ } else if (p18.inlineData) {
7611
7945
  parts.push({
7612
7946
  type: "image",
7613
- image: Buffer.from(p17.inlineData.data, "base64"),
7614
- mediaType: p17.inlineData.mimeType
7947
+ image: Buffer.from(p18.inlineData.data, "base64"),
7948
+ mediaType: p18.inlineData.mimeType
7615
7949
  });
7616
- } else if (p17.functionCall) {
7950
+ } else if (p18.functionCall) {
7617
7951
  const id = "call_" + randomUUID2().replace(/-/g, "");
7618
- const name = p17.functionCall.name;
7952
+ const name = p18.functionCall.name;
7619
7953
  if (!nameToIdList.has(name)) nameToIdList.set(name, []);
7620
7954
  nameToIdList.get(name).push(id);
7621
7955
  parts.push({
7622
7956
  type: "tool-call",
7623
7957
  toolCallId: id,
7624
7958
  toolName: name,
7625
- input: p17.functionCall.args || {}
7959
+ input: p18.functionCall.args || {}
7626
7960
  });
7627
- } else if (p17.functionResponse) {
7628
- const name = p17.functionResponse.name;
7961
+ } else if (p18.functionResponse) {
7962
+ const name = p18.functionResponse.name;
7629
7963
  const idList = nameToIdList.get(name) || [];
7630
7964
  const id = idList.shift() || "call_" + randomUUID2().replace(/-/g, "");
7631
7965
  toolResults.push({
@@ -7634,7 +7968,7 @@ function translateGeminiRequest(body, options = {}) {
7634
7968
  toolName: name,
7635
7969
  output: {
7636
7970
  type: "text",
7637
- value: typeof p17.functionResponse.response === "string" ? p17.functionResponse.response : JSON.stringify(p17.functionResponse.response || {})
7971
+ value: typeof p18.functionResponse.response === "string" ? p18.functionResponse.response : JSON.stringify(p18.functionResponse.response || {})
7638
7972
  }
7639
7973
  });
7640
7974
  }
@@ -7840,9 +8174,9 @@ ${JSON.stringify(params, null, 2)}`);
7840
8174
  const toolCallBuffers = /* @__PURE__ */ new Map();
7841
8175
  let isThinking = false;
7842
8176
  for await (const part of fullStream) {
7843
- const p17 = part;
7844
- plog(`Stream chunk type: ${p17.type}`);
7845
- if (isThinking && (p17.type === "tool-input-start" || p17.type === "tool-call" || p17.type === "finish")) {
8177
+ const p18 = part;
8178
+ plog(`Stream chunk type: ${p18.type}`);
8179
+ if (isThinking && (p18.type === "tool-input-start" || p18.type === "tool-call" || p18.type === "finish")) {
7846
8180
  isThinking = false;
7847
8181
  const chunk = {
7848
8182
  candidates: [{ content: { role: "model", parts: [{ text: `
@@ -7855,8 +8189,8 @@ ${JSON.stringify(params, null, 2)}`);
7855
8189
 
7856
8190
  `);
7857
8191
  }
7858
- if (p17.type === "reasoning") {
7859
- let text4 = p17.textDelta ?? p17.text ?? "";
8192
+ if (p18.type === "reasoning") {
8193
+ let text4 = p18.textDelta ?? p18.text ?? "";
7860
8194
  if (!isThinking) {
7861
8195
  isThinking = true;
7862
8196
  text4 = `<thinking>
@@ -7869,8 +8203,8 @@ ${JSON.stringify(params, null, 2)}`);
7869
8203
  res.write(`data: ${JSON.stringify(chunk)}
7870
8204
 
7871
8205
  `);
7872
- } else if (p17.type === "text-delta") {
7873
- let text4 = p17.textDelta ?? p17.text ?? "";
8206
+ } else if (p18.type === "text-delta") {
8207
+ let text4 = p18.textDelta ?? p18.text ?? "";
7874
8208
  if (isThinking) {
7875
8209
  isThinking = false;
7876
8210
  text4 = `
@@ -7890,17 +8224,17 @@ ${JSON.stringify(params, null, 2)}`);
7890
8224
  const data = `data: ${JSON.stringify(chunk)}
7891
8225
 
7892
8226
  `;
7893
- plog(`Streaming text delta: ${p17.textDelta}`);
8227
+ plog(`Streaming text delta: ${p18.textDelta}`);
7894
8228
  res.write(data);
7895
- } else if (p17.type === "tool-input-start") {
7896
- toolCallBuffers.set(p17.toolCallId, { name: p17.toolName, json: "" });
7897
- } else if (p17.type === "tool-input-delta") {
7898
- const buf = toolCallBuffers.get(p17.toolCallId);
7899
- if (buf) buf.json += p17.delta;
7900
- } else if (p17.type === "tool-call") {
7901
- const buf = toolCallBuffers.get(p17.toolCallId);
7902
- const args = buf ? JSON.parse(buf.json || "{}") : p17.input || {};
7903
- const name = buf ? buf.name : p17.toolName;
8229
+ } else if (p18.type === "tool-input-start") {
8230
+ toolCallBuffers.set(p18.toolCallId, { name: p18.toolName, json: "" });
8231
+ } else if (p18.type === "tool-input-delta") {
8232
+ const buf = toolCallBuffers.get(p18.toolCallId);
8233
+ if (buf) buf.json += p18.delta;
8234
+ } else if (p18.type === "tool-call") {
8235
+ const buf = toolCallBuffers.get(p18.toolCallId);
8236
+ const args = buf ? JSON.parse(buf.json || "{}") : p18.input || {};
8237
+ const name = buf ? buf.name : p18.toolName;
7904
8238
  plog(`Streaming tool call: ${name} with args: ${JSON.stringify(args)}`);
7905
8239
  const chunk = {
7906
8240
  candidates: [{
@@ -7916,18 +8250,18 @@ ${JSON.stringify(params, null, 2)}`);
7916
8250
  res.write(`data: ${JSON.stringify(chunk)}
7917
8251
 
7918
8252
  `);
7919
- } else if (p17.type === "finish") {
8253
+ } else if (p18.type === "finish") {
7920
8254
  const chunk = {
7921
8255
  candidates: [{
7922
- finishReason: mapFinishReason(p17.finishReason ?? "")
8256
+ finishReason: mapFinishReason(p18.finishReason ?? "")
7923
8257
  }],
7924
8258
  usageMetadata: {
7925
- promptTokenCount: p17.totalUsage?.inputTokens || 0,
7926
- candidatesTokenCount: p17.totalUsage?.outputTokens || 0
8259
+ promptTokenCount: p18.totalUsage?.inputTokens || 0,
8260
+ candidatesTokenCount: p18.totalUsage?.outputTokens || 0
7927
8261
  },
7928
8262
  modelVersion: route.aliasId
7929
8263
  };
7930
- plog(`Stream finish. Reason: ${p17.finishReason}`);
8264
+ plog(`Stream finish. Reason: ${p18.finishReason}`);
7931
8265
  res.write(`data: ${JSON.stringify(chunk)}
7932
8266
 
7933
8267
  `);
@@ -8184,34 +8518,34 @@ async function rewriteGeminiBackendRoutes(routes, launchModelId, trace) {
8184
8518
 
8185
8519
  // src/apps/gemini/cli.ts
8186
8520
  function geminiHelpText() {
8187
- return `${pc10.bold("anygate gemini")} v${VERSION}
8521
+ return `${pc11.bold("anygate gemini")} v${VERSION}
8188
8522
  Launch Google Gemini CLI with OpenCode Zen / Go or local registry providers.
8189
8523
 
8190
- ${pc10.bold("Usage:")}
8524
+ ${pc11.bold("Usage:")}
8191
8525
  anygate gemini [options] [gemini-flags]
8192
8526
  anygate gemini --help
8193
8527
  anygate gemini --version
8194
8528
 
8195
- ${pc10.bold("Options:")}
8529
+ ${pc11.bold("Options:")}
8196
8530
  --trace Write proxy debug logs to ~/.anygate/logs/ and show errors on exit
8197
8531
  --provider Boot provider id (skip wizard when paired with --model or non-interactive)
8198
8532
  --model Boot model id (skip wizard when paired with --provider or non-interactive)
8199
8533
  --help Show this command help
8200
8534
  --version Show version
8201
8535
 
8202
- ${pc10.bold("Description:")}
8536
+ ${pc11.bold("Description:")}
8203
8537
  Picks a provider and model from ~/.anygate/providers.json, starts a local Gemini-to-SDK translation
8204
8538
  proxy, and launches the Gemini CLI.
8205
8539
  All registry models (Anthropic, OpenAI, custom endpoints, etc.) route through the local translation proxy.
8206
8540
 
8207
- ${pc10.bold("Prerequisites:")}
8541
+ ${pc11.bold("Prerequisites:")}
8208
8542
  npm install -g @google/gemini-cli
8209
8543
 
8210
- ${pc10.bold("Passing flags to Gemini CLI:")}
8544
+ ${pc11.bold("Passing flags to Gemini CLI:")}
8211
8545
  Add Gemini flags directly \u2014 no "--" separator needed.
8212
8546
  anygate manages -m / --model and -p / --prompt; other flags go to Gemini CLI.
8213
8547
 
8214
- ${pc10.bold("Examples:")}
8548
+ ${pc11.bold("Examples:")}
8215
8549
  anygate gemini
8216
8550
  anygate gemini --trace
8217
8551
  anygate gemini --provider zen --model gemini-2.5-flash
@@ -8224,7 +8558,7 @@ async function runGeminiCommand(geminiArgs, trace = false, launch = {}) {
8224
8558
  }
8225
8559
  const geminiPath = findGeminiBinary();
8226
8560
  if (!geminiPath) {
8227
- console.error(pc10.red("\nError: gemini binary not found on PATH.\n"));
8561
+ console.error(pc11.red("\nError: gemini binary not found on PATH.\n"));
8228
8562
  console.error("Install Google Gemini CLI:");
8229
8563
  console.error(" npm install -g @google/gemini-cli\n");
8230
8564
  return 1;
@@ -8240,7 +8574,7 @@ async function runGeminiCommand(geminiArgs, trace = false, launch = {}) {
8240
8574
  prefs
8241
8575
  });
8242
8576
  if (launchPlan.error) {
8243
- console.error(pc10.red(`
8577
+ console.error(pc11.red(`
8244
8578
  Error: ${launchPlan.error}
8245
8579
  `));
8246
8580
  return 1;
@@ -8250,38 +8584,38 @@ Error: ${launchPlan.error}
8250
8584
  try {
8251
8585
  catalog = await fetchProviderCatalog({ agent: "gemini" });
8252
8586
  } catch (err) {
8253
- console.error(pc10.red(String(err instanceof Error ? err.message : err)));
8587
+ console.error(pc11.red(String(err instanceof Error ? err.message : err)));
8254
8588
  return 1;
8255
8589
  }
8256
8590
  } else {
8257
- const catalogSpinner = p12.spinner();
8591
+ const catalogSpinner = p13.spinner();
8258
8592
  catalogSpinner.start("Loading your providers...");
8259
8593
  try {
8260
8594
  catalog = await fetchProviderCatalog({ agent: "gemini" });
8261
8595
  } catch (err) {
8262
8596
  catalogSpinner.stop("");
8263
- console.error(pc10.red(String(err instanceof Error ? err.message : err)));
8597
+ console.error(pc11.red(String(err instanceof Error ? err.message : err)));
8264
8598
  return 1;
8265
8599
  }
8266
8600
  catalogSpinner.stop("");
8267
8601
  }
8268
8602
  const compatible = providersForTarget(providersForPicker(catalog), "gemini");
8269
8603
  if (compatible.length === 0) {
8270
- p12.log.warn("No Gemini-compatible providers in your registry.");
8271
- p12.log.info("Add a provider with anygate providers add, or sign in with anygate providers auth openai.");
8604
+ p13.log.warn("No Gemini-compatible providers in your registry.");
8605
+ p13.log.info("Add a provider with anygate providers add, or sign in with anygate providers auth openai.");
8272
8606
  return 0;
8273
8607
  }
8274
8608
  let activeProvider = compatible.find((lp) => lp.id === prefs.lastGeminiProvider) ?? compatible[0];
8275
8609
  let selectedModel = activeProvider.models.find((m) => m.id === prefs.lastGeminiModel) ?? activeProvider.models[0];
8276
8610
  if (!selectedModel) {
8277
- p12.log.error(`Provider "${activeProvider.name}" has no models available.`);
8611
+ p13.log.error(`Provider "${activeProvider.name}" has no models available.`);
8278
8612
  return 1;
8279
8613
  }
8280
8614
  ;
8281
8615
  if (launchPlan.skip && launchPlan.target) {
8282
8616
  const resolved = findProviderAndModel(compatible, launchPlan.target);
8283
8617
  if (!resolved) {
8284
- p12.log.error(
8618
+ p13.log.error(
8285
8619
  `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
8286
8620
  );
8287
8621
  return 1;
@@ -8289,12 +8623,12 @@ Error: ${launchPlan.error}
8289
8623
  activeProvider = resolved.provider;
8290
8624
  selectedModel = resolved.model;
8291
8625
  if (!agentStdout) {
8292
- p12.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
8626
+ p13.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
8293
8627
  }
8294
8628
  } else {
8295
8629
  if (!agentStdout) {
8296
8630
  console.log("");
8297
- p12.log.info(`Launching ${pc10.bold("Gemini CLI")} with anygate`);
8631
+ p13.log.info(`Launching ${pc11.bold("Gemini CLI")} with anygate`);
8298
8632
  }
8299
8633
  const chosenProvider = await pickGeminiProvider(
8300
8634
  compatible,
@@ -8326,7 +8660,7 @@ Error: ${launchPlan.error}
8326
8660
  recordLaunchSelection("gemini", activeProvider.id, selectedModel.id, prefs);
8327
8661
  const launchApiKey = await resolveLocalProviderApiKey(activeProvider);
8328
8662
  if (!launchApiKey?.trim()) {
8329
- p12.log.error(
8663
+ p13.log.error(
8330
8664
  new CredentialUnavailableError(activeProvider.id).userMessage
8331
8665
  );
8332
8666
  return 1;
@@ -8422,14 +8756,14 @@ Error: ${launchPlan.error}
8422
8756
  oauthBackend = backendRoutes.backend;
8423
8757
  proxyHandle = await startGeminiProxy(finalRoutes, trace);
8424
8758
  } catch (err) {
8425
- p12.log.error(`Failed to start Gemini proxy: ${err instanceof Error ? err.message : String(err)}`);
8759
+ p13.log.error(`Failed to start Gemini proxy: ${err instanceof Error ? err.message : String(err)}`);
8426
8760
  oauthBackend?.handle.close();
8427
8761
  return 1;
8428
8762
  }
8429
8763
  const childEnv = prepareGeminiChildEnv(proxyHandle.port, proxyHandle.token);
8430
8764
  if (!agentStdout) {
8431
- p12.log.info(`Gemini proxy started on port ${proxyHandle.port}`);
8432
- p12.log.info(`\u{1F4A1} Type ${pc10.bold(".model <id>")} in the chat to switch models mid-session.`);
8765
+ p13.log.info(`Gemini proxy started on port ${proxyHandle.port}`);
8766
+ p13.log.info(`\u{1F4A1} Type ${pc11.bold(".model <id>")} in the chat to switch models mid-session.`);
8433
8767
  }
8434
8768
  let exitCode = 1;
8435
8769
  try {
@@ -8440,7 +8774,7 @@ Error: ${launchPlan.error}
8440
8774
  oauthBackend?.handle.close();
8441
8775
  }
8442
8776
  if (!agentStdout) {
8443
- p12.log.info("Gemini proxy stopped.");
8777
+ p13.log.info("Gemini proxy stopped.");
8444
8778
  }
8445
8779
  if (trace) {
8446
8780
  printTraceLog(getGeminiProxyDebugLogPath());
@@ -8451,7 +8785,7 @@ Error: ${launchPlan.error}
8451
8785
  // src/cli/gemini.ts
8452
8786
  async function handleGeminiCommand(parsed) {
8453
8787
  if (parsed.showVersion) {
8454
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
8788
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
8455
8789
  console.log(VERSION2);
8456
8790
  return 0;
8457
8791
  }
@@ -8467,8 +8801,8 @@ async function handleGeminiCommand(parsed) {
8467
8801
 
8468
8802
  // src/apps/gemini/antigravity.ts
8469
8803
  init_config();
8470
- import pc11 from "picocolors";
8471
- import * as p13 from "@clack/prompts";
8804
+ import pc12 from "picocolors";
8805
+ import * as p14 from "@clack/prompts";
8472
8806
  import { appendFileSync as appendFileSync2 } from "fs";
8473
8807
 
8474
8808
  // src/gateway/antigravity/cloud-code-gateway.ts
@@ -10171,7 +10505,7 @@ async function startCloudCodeGateway(routes, opts = {}) {
10171
10505
  const templateKey = opts.templateKey ?? "gemini-3.5-flash-low";
10172
10506
  const trace = opts.trace ?? false;
10173
10507
  const trackActiveRoute = opts.trackActiveRoute ?? false;
10174
- const log16 = opts.logFn ?? (() => {
10508
+ const log17 = opts.logFn ?? (() => {
10175
10509
  });
10176
10510
  const catalogFixture = fetchAvailableModels_default;
10177
10511
  const injectedCatalog = injectGatewayModels(catalogFixture, routes, templateKey);
@@ -10221,12 +10555,12 @@ async function startCloudCodeGateway(routes, opts = {}) {
10221
10555
  const contentType = (req.headers["content-type"] ?? "").toLowerCase();
10222
10556
  const lowerUrl = url.toLowerCase();
10223
10557
  if (trace) {
10224
- log16(`[gateway] ${method} ${url}`);
10225
- log16(`[gateway] content-type: ${contentType}`);
10226
- log16(`[gateway] body-size: ${bodyStr.length}`);
10558
+ log17(`[gateway] ${method} ${url}`);
10559
+ log17(`[gateway] content-type: ${contentType}`);
10560
+ log17(`[gateway] body-size: ${bodyStr.length}`);
10227
10561
  }
10228
10562
  if (contentType.includes("proto") || contentType.includes("grpc") && !contentType.includes("json")) {
10229
- log16(`[gateway] UNSUPPORTED content-type: ${contentType}`);
10563
+ log17(`[gateway] UNSUPPORTED content-type: ${contentType}`);
10230
10564
  respondJson(res, 415, {
10231
10565
  error: {
10232
10566
  code: 415,
@@ -10242,35 +10576,35 @@ async function startCloudCodeGateway(routes, opts = {}) {
10242
10576
  }
10243
10577
  if (trace && parsed) {
10244
10578
  const preview = JSON.stringify(parsed).slice(0, 500);
10245
- log16(`[gateway] body-preview: ${preview}`);
10579
+ log17(`[gateway] body-preview: ${preview}`);
10246
10580
  }
10247
10581
  if (lowerUrl.includes("loadcodeassist")) {
10248
- if (trace) log16("[gateway] \u2192 loadCodeAssist");
10582
+ if (trace) log17("[gateway] \u2192 loadCodeAssist");
10249
10583
  respondJson(res, 200, loadCodeAssist_default);
10250
10584
  return;
10251
10585
  }
10252
10586
  if (lowerUrl.includes("fetchavailablemodels") || lowerUrl.includes("getavailablemodels")) {
10253
- if (trace) log16("[gateway] \u2192 fetchAvailableModels");
10587
+ if (trace) log17("[gateway] \u2192 fetchAvailableModels");
10254
10588
  respondJson(res, 200, injectedCatalog);
10255
10589
  return;
10256
10590
  }
10257
10591
  if (lowerUrl.includes("modelconfigs")) {
10258
- if (trace) log16("[gateway] \u2192 listModelConfigs");
10592
+ if (trace) log17("[gateway] \u2192 listModelConfigs");
10259
10593
  respondJson(res, 200, modelConfigsResponse);
10260
10594
  return;
10261
10595
  }
10262
10596
  if (lowerUrl.includes("generatecontent") || lowerUrl.includes("generatechat")) {
10263
10597
  const model = parsed?.model;
10264
- if (trace) log16(`[gateway] extracted model: ${model ?? "N/A"}`);
10598
+ if (trace) log17(`[gateway] extracted model: ${model ?? "N/A"}`);
10265
10599
  const route = resolveRouteForModel(model);
10266
10600
  if (route) {
10267
10601
  if (trackActiveRoute && selectedSlotIds.has(model ?? "") && isUserTurnRequest(parsed)) {
10268
10602
  activeRoute = route;
10269
- if (trace) log16(`[gateway] active route: ${route.catalogId} via ${model}`);
10603
+ if (trace) log17(`[gateway] active route: ${route.catalogId} via ${model}`);
10270
10604
  }
10271
10605
  if (isCloudCodeOAuthRoute(route)) {
10272
- handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log16).catch((err) => {
10273
- log16(`[gateway] cloud-code forward error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
10606
+ handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log17).catch((err) => {
10607
+ log17(`[gateway] cloud-code forward error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
10274
10608
  if (!res.headersSent) {
10275
10609
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
10276
10610
  } else if (!res.writableEnded) {
@@ -10288,11 +10622,11 @@ async function startCloudCodeGateway(routes, opts = {}) {
10288
10622
  rememberReasoningEcho(reasoningEchoesByConversation, conversationKey, reasoning);
10289
10623
  };
10290
10624
  if (isStream) {
10291
- handleStreamingRequest(res, route, baseProviderOptions, parsed, log16, {
10625
+ handleStreamingRequest(res, route, baseProviderOptions, parsed, log17, {
10292
10626
  requestOptions,
10293
10627
  onReasoningWithToolCall: rememberReasoning
10294
10628
  }).catch((err) => {
10295
- log16(`[gateway] stream error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
10629
+ log17(`[gateway] stream error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
10296
10630
  if (!res.headersSent) {
10297
10631
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
10298
10632
  } else if (!res.writableEnded) {
@@ -10300,11 +10634,11 @@ async function startCloudCodeGateway(routes, opts = {}) {
10300
10634
  }
10301
10635
  });
10302
10636
  } else {
10303
- handleUnaryRequest(res, route, baseProviderOptions, parsed, log16, {
10637
+ handleUnaryRequest(res, route, baseProviderOptions, parsed, log17, {
10304
10638
  requestOptions,
10305
10639
  onReasoningWithToolCall: rememberReasoning
10306
10640
  }).catch((err) => {
10307
- log16(`[gateway] unary error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
10641
+ log17(`[gateway] unary error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
10308
10642
  if (!res.headersSent) {
10309
10643
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
10310
10644
  }
@@ -10400,7 +10734,7 @@ async function startCloudCodeGateway(routes, opts = {}) {
10400
10734
  return;
10401
10735
  }
10402
10736
  if (trace) {
10403
- log16(`[gateway] unknown endpoint: ${url}`);
10737
+ log17(`[gateway] unknown endpoint: ${url}`);
10404
10738
  }
10405
10739
  respondJson(res, 200, {});
10406
10740
  }).catch((err) => {
@@ -10486,7 +10820,7 @@ function rememberReasoningEcho(cache, key, reasoning) {
10486
10820
  existing.push(normalized);
10487
10821
  cache.set(key, existing.slice(-MAX_REASONING_ECHOES_PER_CONVERSATION));
10488
10822
  }
10489
- async function handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log16) {
10823
+ async function handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log17) {
10490
10824
  const projectId = typeof route.providerData?.projectId === "string" ? route.providerData.projectId : "";
10491
10825
  if (!projectId) {
10492
10826
  respondJson(res, 500, {
@@ -10515,7 +10849,7 @@ async function handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log16
10515
10849
  });
10516
10850
  if (!upstream.ok) {
10517
10851
  const errBody = await upstream.text();
10518
- log16(`[gateway] cloud-code upstream error ${upstream.status}: ${errBody}`);
10852
+ log17(`[gateway] cloud-code upstream error ${upstream.status}: ${errBody}`);
10519
10853
  respondJson(res, upstream.status >= 500 ? 502 : upstream.status, {
10520
10854
  error: { code: upstream.status, message: errBody || upstream.statusText }
10521
10855
  });
@@ -10677,7 +11011,7 @@ function respondJson(res, status, data) {
10677
11011
  });
10678
11012
  res.end(body);
10679
11013
  }
10680
- async function handleStreamingRequest(res, route, providerOptions, parsed, log16, options = {}) {
11014
+ async function handleStreamingRequest(res, route, providerOptions, parsed, log17, options = {}) {
10681
11015
  const sdkParams = applyClaudeCodeOAuthIdentity(route, translateRequest(parsed, {
10682
11016
  ...options.requestOptions,
10683
11017
  maxTools: maxToolsForNpm(route.npm)
@@ -10718,21 +11052,21 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log16
10718
11052
  let responseReasoning = "";
10719
11053
  let sawToolCall = false;
10720
11054
  for await (const part of fullStream) {
10721
- const p17 = part;
10722
- if (p17.type === "reasoning-delta" || p17.type === "reasoning") {
10723
- const reasoning = reasoningDeltaText(p17);
11055
+ const p18 = part;
11056
+ if (p18.type === "reasoning-delta" || p18.type === "reasoning") {
11057
+ const reasoning = reasoningDeltaText(p18);
10724
11058
  responseReasoning += reasoning;
10725
11059
  emitThinkingDelta(res, route, responseId, reasoning, startSse);
10726
11060
  continue;
10727
11061
  }
10728
- if (p17.type === "text-delta") {
10729
- const { thought, text: text4 } = thinkFilter(reasoningDeltaText(p17));
11062
+ if (p18.type === "text-delta") {
11063
+ const { thought, text: text4 } = thinkFilter(reasoningDeltaText(p18));
10730
11064
  if (thought) {
10731
11065
  responseReasoning += thought;
10732
11066
  emitThinkingDelta(res, route, responseId, thought, startSse);
10733
11067
  }
10734
11068
  if (text4) {
10735
- log16(`[gateway] text-delta: ${JSON.stringify(text4.slice(0, 500))}`);
11069
+ log17(`[gateway] text-delta: ${JSON.stringify(text4.slice(0, 500))}`);
10736
11070
  startSse();
10737
11071
  const chunk = formatCloudCodeChunk({
10738
11072
  text: text4,
@@ -10743,25 +11077,25 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log16
10743
11077
 
10744
11078
  `);
10745
11079
  }
10746
- } else if (p17.type === "tool-input-start") {
10747
- const id = p17.id ?? p17.toolCallId;
10748
- toolCallBuffers.set(id, { name: p17.toolName, json: "" });
10749
- } else if (p17.type === "tool-input-delta") {
10750
- const id = p17.id ?? p17.toolCallId;
11080
+ } else if (p18.type === "tool-input-start") {
11081
+ const id = p18.id ?? p18.toolCallId;
11082
+ toolCallBuffers.set(id, { name: p18.toolName, json: "" });
11083
+ } else if (p18.type === "tool-input-delta") {
11084
+ const id = p18.id ?? p18.toolCallId;
10751
11085
  const buf = toolCallBuffers.get(id);
10752
- if (buf) buf.json += p17.delta;
10753
- } else if (p17.type === "tool-call") {
11086
+ if (buf) buf.json += p18.delta;
11087
+ } else if (p18.type === "tool-call") {
10754
11088
  sawToolCall = true;
10755
- const id = p17.toolCallId ?? p17.id;
11089
+ const id = p18.toolCallId ?? p18.id;
10756
11090
  const buf = toolCallBuffers.get(id);
10757
11091
  let args = {};
10758
11092
  try {
10759
- args = buf ? JSON.parse(buf.json || "{}") : p17.input || {};
11093
+ args = buf ? JSON.parse(buf.json || "{}") : p18.input || {};
10760
11094
  } catch {
10761
- args = p17.input || {};
11095
+ args = p18.input || {};
10762
11096
  }
10763
- const name = buf ? buf.name : p17.toolName;
10764
- log16(`[gateway] tool-call: ${name}`);
11097
+ const name = buf ? buf.name : p18.toolName;
11098
+ log17(`[gateway] tool-call: ${name}`);
10765
11099
  startSse();
10766
11100
  const chunk = formatCloudCodeChunk({
10767
11101
  functionCall: { name, args: normalizeFunctionCallArgs(args) },
@@ -10771,17 +11105,17 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log16
10771
11105
  res.write(`data: ${JSON.stringify(chunk)}
10772
11106
 
10773
11107
  `);
10774
- } else if (p17.type === "finish") {
10775
- log16(`[gateway] finish: ${p17.finishReason ?? "unknown"}`);
11108
+ } else if (p18.type === "finish") {
11109
+ log17(`[gateway] finish: ${p18.finishReason ?? "unknown"}`);
10776
11110
  startSse();
10777
- const reason = mapFinishReason2(p17.finishReason ?? "");
11111
+ const reason = mapFinishReason2(p18.finishReason ?? "");
10778
11112
  const chunk = formatCloudCodeChunk({
10779
11113
  modelVersion: route.catalogId,
10780
11114
  responseId,
10781
11115
  finishReason: reason,
10782
11116
  usage: {
10783
- promptTokens: p17.totalUsage?.inputTokens || 0,
10784
- completionTokens: p17.totalUsage?.outputTokens || 0
11117
+ promptTokens: p18.totalUsage?.inputTokens || 0,
11118
+ completionTokens: p18.totalUsage?.outputTokens || 0
10785
11119
  }
10786
11120
  });
10787
11121
  res.write(`data: ${JSON.stringify(chunk)}
@@ -10793,16 +11127,16 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log16
10793
11127
  npm: route.npm,
10794
11128
  providerId: route.providerId,
10795
11129
  app: "Antigravity",
10796
- inputTokens: p17.totalUsage?.inputTokens ?? 0,
10797
- outputTokens: p17.totalUsage?.outputTokens ?? 0
11130
+ inputTokens: p18.totalUsage?.inputTokens ?? 0,
11131
+ outputTokens: p18.totalUsage?.outputTokens ?? 0
10798
11132
  });
10799
- } else if (p17.type === "error") {
10800
- const message = formatUpstreamError(p17.error);
10801
- log16(`[gateway] stream provider error: ${message}`);
11133
+ } else if (p18.type === "error") {
11134
+ const message = formatUpstreamError(p18.error);
11135
+ log17(`[gateway] stream provider error: ${message}`);
10802
11136
  emitStreamError(res, route, responseId, message, startSse);
10803
11137
  break;
10804
- } else if (p17.type === "reasoning-start" || p17.type === "reasoning-end") {
10805
- log16(`[gateway] ${p17.type}`);
11138
+ } else if (p18.type === "reasoning-start" || p18.type === "reasoning-end") {
11139
+ log17(`[gateway] ${p18.type}`);
10806
11140
  }
10807
11141
  }
10808
11142
  if (!res.headersSent) {
@@ -11370,11 +11704,11 @@ function resolveAntigravityBootModel(provider, modelSelector) {
11370
11704
  async function pickAntigravityCliFavoriteLaunchModel(favorites, allProviders) {
11371
11705
  const resolved = favorites.map((favorite) => resolveFavoriteModel(favorite, allProviders)).filter((entry) => entry !== null);
11372
11706
  if (resolved.length === 0) {
11373
- p13.log.warn("No Antigravity CLI favorites are available.");
11374
- p13.log.info(pc11.dim("Manage them with `anygate favorites --agy`."));
11707
+ p14.log.warn("No Antigravity CLI favorites are available.");
11708
+ p14.log.info(pc12.dim("Manage them with `anygate favorites --agy`."));
11375
11709
  return null;
11376
11710
  }
11377
- const picked = await p13.select({
11711
+ const picked = await p14.select({
11378
11712
  message: "Launch from Antigravity CLI favorites",
11379
11713
  options: resolved.map(({ provider, model }) => ({
11380
11714
  value: `${provider.id}:${model.id}`,
@@ -11383,8 +11717,8 @@ async function pickAntigravityCliFavoriteLaunchModel(favorites, allProviders) {
11383
11717
  })),
11384
11718
  initialValue: `${resolved[0].provider.id}:${resolved[0].model.id}`
11385
11719
  });
11386
- if (p13.isCancel(picked)) {
11387
- p13.cancel("Cancelled.");
11720
+ if (p14.isCancel(picked)) {
11721
+ p14.cancel("Cancelled.");
11388
11722
  return null;
11389
11723
  }
11390
11724
  const [providerId, ...modelParts] = picked.split(":");
@@ -11393,31 +11727,31 @@ async function pickAntigravityCliFavoriteLaunchModel(favorites, allProviders) {
11393
11727
  }
11394
11728
  async function resolveAntigravityLaunch(prefs, boot) {
11395
11729
  let catalog;
11396
- const catalogSpinner = p13.spinner();
11730
+ const catalogSpinner = p14.spinner();
11397
11731
  catalogSpinner.start("Loading providers...");
11398
11732
  try {
11399
11733
  catalog = await fetchProviderCatalog();
11400
11734
  } catch (err) {
11401
11735
  catalogSpinner.stop("");
11402
- p13.log.error(String(err instanceof Error ? err.message : err));
11736
+ p14.log.error(String(err instanceof Error ? err.message : err));
11403
11737
  return null;
11404
11738
  }
11405
11739
  catalogSpinner.stop("");
11406
11740
  const allProviders = providersForTarget(providersForPicker(catalog), "antigravity");
11407
11741
  if (allProviders.length === 0) {
11408
- p13.log.warn("No providers available.");
11409
- p13.log.info(pc11.dim("Run anygate providers add or import to get started."));
11742
+ p14.log.warn("No providers available.");
11743
+ p14.log.info(pc12.dim("Run anygate providers add or import to get started."));
11410
11744
  return null;
11411
11745
  }
11412
11746
  if (boot?.launchProvider && boot?.launchModel) {
11413
- const provider = allProviders.find((p17) => p17.id === boot.launchProvider);
11747
+ const provider = allProviders.find((p18) => p18.id === boot.launchProvider);
11414
11748
  if (!provider) {
11415
- p13.log.error(`Provider not found: ${boot.launchProvider}`);
11749
+ p14.log.error(`Provider not found: ${boot.launchProvider}`);
11416
11750
  return null;
11417
11751
  }
11418
11752
  const { model, error } = resolveAntigravityBootModel(provider, boot.launchModel);
11419
11753
  if (!model) {
11420
- p13.log.error(error ?? `Model not found: ${boot.launchModel} on provider ${provider.name}`);
11754
+ p14.log.error(error ?? `Model not found: ${boot.launchModel} on provider ${provider.name}`);
11421
11755
  return null;
11422
11756
  }
11423
11757
  return { provider, model, allProviders };
@@ -11425,7 +11759,7 @@ async function resolveAntigravityLaunch(prefs, boot) {
11425
11759
  const providerOptions = [
11426
11760
  {
11427
11761
  value: AGY_FAVORITES_PROVIDER_ID,
11428
- label: pc11.cyan(AGY_FAVORITES_PROVIDER_LABEL),
11762
+ label: pc12.cyan(AGY_FAVORITES_PROVIDER_LABEL),
11429
11763
  hint: `${prefs.antigravityCliFavoriteModels?.length ?? 0}/6 saved \xB7 manage with anygate favorites --agy`
11430
11764
  },
11431
11765
  ...allProviders.map((lp) => providerSelectOption(lp))
@@ -11434,13 +11768,13 @@ async function resolveAntigravityLaunch(prefs, boot) {
11434
11768
  const conflicts = detectConflicts();
11435
11769
  let currentInitialProvider = initialProvider;
11436
11770
  while (true) {
11437
- const chosen = await p13.select({
11771
+ const chosen = await p14.select({
11438
11772
  message: "Which provider?",
11439
11773
  options: providerOptions,
11440
11774
  initialValue: currentInitialProvider
11441
11775
  });
11442
- if (p13.isCancel(chosen)) {
11443
- p13.cancel("Cancelled.");
11776
+ if (p14.isCancel(chosen)) {
11777
+ p14.cancel("Cancelled.");
11444
11778
  return null;
11445
11779
  }
11446
11780
  if (chosen === AGY_FAVORITES_PROVIDER_ID) {
@@ -11473,32 +11807,32 @@ async function resolveAndBuildRoutes(provider, model, allProviders, prefs, opts)
11473
11807
  maxRoutes: opts.maxRoutes
11474
11808
  });
11475
11809
  if (!result) {
11476
- p13.log.error(new CredentialUnavailableError(provider.id).userMessage);
11810
+ p14.log.error(new CredentialUnavailableError(provider.id).userMessage);
11477
11811
  return null;
11478
11812
  }
11479
11813
  if (result.routes.length > 1) {
11480
- p13.log.info(
11814
+ p14.log.info(
11481
11815
  `Favorites mode active \u2014 Antigravity picker will show ${result.routes.length} models.`
11482
11816
  );
11483
- p13.log.info("Edit with `anygate favorites --agy`.");
11817
+ p14.log.info("Edit with `anygate favorites --agy`.");
11484
11818
  }
11485
11819
  if (result.droppedFavorites.length > 0) {
11486
- p13.log.warn(
11820
+ p14.log.warn(
11487
11821
  `Skipped ${result.droppedFavorites.length} stale/unauthorized favorite(s): ` + result.droppedFavorites.map((fav) => `${fav.providerId}:${fav.modelId}`).join(", ")
11488
11822
  );
11489
11823
  }
11490
11824
  if (result.capacitySkippedFavorites.length > 0) {
11491
- p13.log.warn(formatAgyCapacityWarning(opts.validatedSlotCount, result.capacitySkippedFavorites.length));
11492
- p13.log.warn(
11825
+ p14.log.warn(formatAgyCapacityWarning(opts.validatedSlotCount, result.capacitySkippedFavorites.length));
11826
+ p14.log.warn(
11493
11827
  "Not exposed: " + result.capacitySkippedFavorites.map((fav) => `${fav.providerId}:${fav.modelId}`).join(", ")
11494
11828
  );
11495
11829
  if (opts.pauseForCapacityWarning && isInteractiveTerminal() && !agyArgsAreNonInteractive(opts.childArgs)) {
11496
- const proceed = await p13.confirm({
11830
+ const proceed = await p14.confirm({
11497
11831
  message: "Continue with the validated AGY switch catalog?",
11498
11832
  initialValue: true
11499
11833
  });
11500
- if (p13.isCancel(proceed) || !proceed) {
11501
- p13.cancel("Cancelled.");
11834
+ if (p14.isCancel(proceed) || !proceed) {
11835
+ p14.cancel("Cancelled.");
11502
11836
  return null;
11503
11837
  }
11504
11838
  }
@@ -11533,27 +11867,27 @@ async function runAntigravityCommand(intro, tracePrefix, trace, boot, launch, op
11533
11867
  const prefs = loadPreferences();
11534
11868
  gateIntro(intro);
11535
11869
  if (tracePrefix === "agy" && (prefs.favoriteModels?.length ?? 0) > 0 && (prefs.antigravityCliFavoriteModels?.length ?? 0) === 0 && !prefs.antigravityCliFavoritesHintShown) {
11536
- p13.log.info("Tip: AGY uses its own favorites list. Run `anygate favorites --agy` to set up switching.");
11870
+ p14.log.info("Tip: AGY uses its own favorites list. Run `anygate favorites --agy` to set up switching.");
11537
11871
  savePreferences({ antigravityCliFavoritesHintShown: true });
11538
11872
  }
11539
11873
  const agyFavorites = prefs.antigravityCliFavoriteModels ?? [];
11540
11874
  if (opts.useFavoritesCatalog && agyFavorites.length > 0) {
11541
- const catalogSpinner = p13.spinner();
11875
+ const catalogSpinner = p14.spinner();
11542
11876
  catalogSpinner.start("Loading providers...");
11543
11877
  let catalog;
11544
11878
  try {
11545
11879
  catalog = await fetchProviderCatalog();
11546
11880
  } catch (err) {
11547
11881
  catalogSpinner.stop("");
11548
- p13.log.error(String(err instanceof Error ? err.message : err));
11882
+ p14.log.error(String(err instanceof Error ? err.message : err));
11549
11883
  return 1;
11550
11884
  }
11551
11885
  catalogSpinner.stop("");
11552
11886
  const allProviders = providersForTarget(providersForPicker(catalog), "antigravity");
11553
11887
  const firstFavorite = resolveFirstAvailableFavorite(agyFavorites, allProviders);
11554
11888
  if (!firstFavorite) {
11555
- p13.log.warn("No Antigravity CLI favorites are currently available.");
11556
- p13.log.info(pc11.dim("Manage them with `anygate favorites --agy`."));
11889
+ p14.log.warn("No Antigravity CLI favorites are currently available.");
11890
+ p14.log.info(pc12.dim("Manage them with `anygate favorites --agy`."));
11557
11891
  return 1;
11558
11892
  }
11559
11893
  const selection2 = { provider: firstFavorite.provider, model: firstFavorite.model, allProviders };
@@ -11572,7 +11906,7 @@ async function launchWithSelection(selection, prefs, opts, trace, tracePrefix, b
11572
11906
  fixture: fetchAvailableModels_default
11573
11907
  });
11574
11908
  for (const warning of compatibility.warnings) {
11575
- p13.log.warn(warning);
11909
+ p14.log.warn(warning);
11576
11910
  }
11577
11911
  const routeLimit = compatibility.mode === "multi-model" ? compatibility.validatedSwitchSlotCount : 1;
11578
11912
  const routeResult = await resolveAndBuildRoutes(provider, model, allProviders, prefs, {
@@ -11598,12 +11932,12 @@ async function launchWithSelection(selection, prefs, opts, trace, tracePrefix, b
11598
11932
  try {
11599
11933
  gatewayHandle = await startCloudCodeGateway(routeResult.routes, { trace, logFn });
11600
11934
  } catch (err) {
11601
- p13.log.error(`Failed to start Cloud Code gateway: ${err}`);
11935
+ p14.log.error(`Failed to start Cloud Code gateway: ${err}`);
11602
11936
  return 1;
11603
11937
  }
11604
- p13.log.info(`Cloud Code gateway on ${pc11.cyan(`127.0.0.1:${gatewayHandle.port}`)}`);
11605
- p13.log.success(`Active model: ${formatCodexModelLabel(model)} ${pc11.dim("via")} ${provider.name}`);
11606
- if (trace) p13.log.info(`Gateway trace \u2192 ${pc11.dim(traceLogPath)}`);
11938
+ p14.log.info(`Cloud Code gateway on ${pc12.cyan(`127.0.0.1:${gatewayHandle.port}`)}`);
11939
+ p14.log.success(`Active model: ${formatCodexModelLabel(model)} ${pc12.dim("via")} ${provider.name}`);
11940
+ if (trace) p14.log.info(`Gateway trace \u2192 ${pc12.dim(traceLogPath)}`);
11607
11941
  gateOutro("Launching", `${formatCodexModelLabel(model)} (${provider.name})`);
11608
11942
  try {
11609
11943
  const cleanEnv = buildAntigravityChildEnv(gatewayHandle.url);
@@ -11631,12 +11965,12 @@ async function runAntigravityAppCommand(childArgs, trace = false, boot) {
11631
11965
  async (env, _routes, gatewayHandle) => {
11632
11966
  const profileDir = join12(homedir10(), ".anygate", "antigravity", "app-profile");
11633
11967
  if (isAntigravityAppRunning(profileDir)) {
11634
- const restart = await p13.confirm({
11968
+ const restart = await p14.confirm({
11635
11969
  message: "Restart Antigravity to apply this Gateway gateway?",
11636
11970
  initialValue: true
11637
11971
  });
11638
- if (p13.isCancel(restart) || !restart) {
11639
- p13.log.info("Quit and reopen Antigravity when you are ready for the new gateway to take effect.");
11972
+ if (p14.isCancel(restart) || !restart) {
11973
+ p14.log.info("Quit and reopen Antigravity when you are ready for the new gateway to take effect.");
11640
11974
  return 0;
11641
11975
  }
11642
11976
  quitAntigravityAppGracefully();
@@ -11647,18 +11981,18 @@ async function runAntigravityAppCommand(childArgs, trace = false, boot) {
11647
11981
  }
11648
11982
  const launchCode = await launchAntigravityApp(env, profileDir, gatewayHandle.url, childArgs);
11649
11983
  if (launchCode !== 0) return launchCode;
11650
- p13.log.info("Antigravity is using the Gateway Cloud Code gateway.");
11651
- p13.log.info(pc11.cyan("Press Ctrl+C to stop the gateway."));
11984
+ p14.log.info("Antigravity is using the Gateway Cloud Code gateway.");
11985
+ p14.log.info(pc12.cyan("Press Ctrl+C to stop the gateway."));
11652
11986
  await waitForShutdown3();
11653
11987
  await new Promise((r) => setTimeout(r, SHUTDOWN_DRAIN_MS));
11654
11988
  console.log("");
11655
- p13.log.step("Gateway stopped.");
11656
- const shouldClose = await p13.confirm({
11989
+ p14.log.step("Gateway stopped.");
11990
+ const shouldClose = await p14.confirm({
11657
11991
  message: "Close Antigravity?",
11658
11992
  initialValue: true
11659
11993
  });
11660
- if (!p13.isCancel(shouldClose) && shouldClose) {
11661
- p13.log.step("Stopping Antigravity...");
11994
+ if (!p14.isCancel(shouldClose) && shouldClose) {
11995
+ p14.log.step("Stopping Antigravity...");
11662
11996
  quitAntigravityAppGracefully();
11663
11997
  if (!await waitForAntigravityAppQuit(profileDir)) {
11664
11998
  forceQuitAntigravityApp(profileDir);
@@ -11679,12 +12013,12 @@ async function runAntigravityIdeCommand(childArgs, trace = false, boot) {
11679
12013
  async (env, _routes, gatewayHandle) => {
11680
12014
  const profileDir = join12(homedir10(), ".anygate", "antigravity", "profile");
11681
12015
  if (isAntigravityIdeRunning(profileDir)) {
11682
- const restart = await p13.confirm({
12016
+ const restart = await p14.confirm({
11683
12017
  message: "Restart Antigravity IDE to apply this Gateway gateway?",
11684
12018
  initialValue: true
11685
12019
  });
11686
- if (p13.isCancel(restart) || !restart) {
11687
- p13.log.info("Quit and reopen Antigravity IDE when you are ready for the new gateway to take effect.");
12020
+ if (p14.isCancel(restart) || !restart) {
12021
+ p14.log.info("Quit and reopen Antigravity IDE when you are ready for the new gateway to take effect.");
11688
12022
  return 0;
11689
12023
  }
11690
12024
  quitAntigravityIdeGracefully();
@@ -11695,18 +12029,18 @@ async function runAntigravityIdeCommand(childArgs, trace = false, boot) {
11695
12029
  }
11696
12030
  const launchCode = await launchAntigravityIde(env, profileDir, gatewayHandle.url, childArgs);
11697
12031
  if (launchCode !== 0) return launchCode;
11698
- p13.log.info("Antigravity IDE is using the Gateway Cloud Code gateway.");
11699
- p13.log.info(pc11.cyan("Press Ctrl+C to stop the gateway."));
12032
+ p14.log.info("Antigravity IDE is using the Gateway Cloud Code gateway.");
12033
+ p14.log.info(pc12.cyan("Press Ctrl+C to stop the gateway."));
11700
12034
  await waitForShutdown3();
11701
12035
  await new Promise((r) => setTimeout(r, SHUTDOWN_DRAIN_MS));
11702
12036
  console.log("");
11703
- p13.log.step("Gateway stopped.");
11704
- const shouldClose = await p13.confirm({
12037
+ p14.log.step("Gateway stopped.");
12038
+ const shouldClose = await p14.confirm({
11705
12039
  message: "Close Antigravity IDE?",
11706
12040
  initialValue: true
11707
12041
  });
11708
- if (!p13.isCancel(shouldClose) && shouldClose) {
11709
- p13.log.step("Stopping Antigravity IDE...");
12042
+ if (!p14.isCancel(shouldClose) && shouldClose) {
12043
+ p14.log.step("Stopping Antigravity IDE...");
11710
12044
  quitAntigravityIdeGracefully();
11711
12045
  if (!await waitForAntigravityIdeQuit(profileDir)) {
11712
12046
  forceQuitAntigravityIde(profileDir);
@@ -11805,7 +12139,7 @@ Examples:
11805
12139
  `;
11806
12140
  async function handleAgyCommand(parsed) {
11807
12141
  if (parsed.showVersion) {
11808
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
12142
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
11809
12143
  console.log(VERSION2);
11810
12144
  return 0;
11811
12145
  }
@@ -11820,7 +12154,7 @@ async function handleAgyCommand(parsed) {
11820
12154
  }
11821
12155
  async function handleAntigravityAppCommand(parsed) {
11822
12156
  if (parsed.showVersion) {
11823
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
12157
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
11824
12158
  console.log(VERSION2);
11825
12159
  return 0;
11826
12160
  }
@@ -11835,7 +12169,7 @@ async function handleAntigravityAppCommand(parsed) {
11835
12169
  }
11836
12170
  async function handleAntigravityIdeCommand(parsed) {
11837
12171
  if (parsed.showVersion) {
11838
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
12172
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
11839
12173
  console.log(VERSION2);
11840
12174
  return 0;
11841
12175
  }
@@ -11940,18 +12274,18 @@ Options:
11940
12274
  `);
11941
12275
  return 0;
11942
12276
  }
11943
- const { runUiCommand } = await import("./command-5BWYQP5G.js");
12277
+ const { runUiCommand } = await import("./command-7AI36ICY.js");
11944
12278
  return runUiCommand({ trace: parsed.trace });
11945
12279
  }
11946
12280
 
11947
12281
  // src/cli/models.ts
11948
12282
  init_config();
11949
- import pc13 from "picocolors";
11950
- import * as p15 from "@clack/prompts";
12283
+ import pc14 from "picocolors";
12284
+ import * as p16 from "@clack/prompts";
11951
12285
 
11952
12286
  // src/apps/claude/favorites-picker.ts
11953
- import * as p14 from "@clack/prompts";
11954
- import pc12 from "picocolors";
12287
+ import * as p15 from "@clack/prompts";
12288
+ import pc13 from "picocolors";
11955
12289
 
11956
12290
  // src/apps/claude/favorites.ts
11957
12291
  function isFavorite(list, fav) {
@@ -12017,7 +12351,7 @@ function globalFavoriteSelectOption(entry, favorites) {
12017
12351
  return {
12018
12352
  value: globalFavoritePickKey(entry),
12019
12353
  label: `${fmtModel(label, entry.model.id)} ${providerTag}`,
12020
- hint: favorited ? pc12.dim("already in favorites") : ""
12354
+ hint: favorited ? pc13.dim("already in favorites") : ""
12021
12355
  };
12022
12356
  }
12023
12357
  function parseGlobalFavoritePickKey(key, index) {
@@ -12028,25 +12362,25 @@ async function pickGlobalFavoriteModel(providers, favorites, opts) {
12028
12362
  if (index.length === 0) return null;
12029
12363
  const freeOnly = opts?.freeOnly === true;
12030
12364
  while (true) {
12031
- const searchInput = await p14.text({
12365
+ const searchInput = await p15.text({
12032
12366
  message: freeOnly ? `Search free models (${filterGlobalFavoriteIndex(index, "", { freeOnly: true }).length} models):` : `Search all providers (${index.length} models):`,
12033
12367
  placeholder: "e.g. deepseek, claude, sonnet"
12034
12368
  });
12035
- if (p14.isCancel(searchInput)) {
12036
- const fallback = await p14.select({
12369
+ if (p15.isCancel(searchInput)) {
12370
+ const fallback = await p15.select({
12037
12371
  message: "Add a favorite",
12038
12372
  options: [
12039
- { value: "back", label: pc12.cyan("\u2190 Back to favorites"), hint: "" },
12040
- { value: ADD_BY_PROVIDER, label: pc12.cyan("Browse by provider \u2192"), hint: "Pick one provider first" }
12373
+ { value: "back", label: pc13.cyan("\u2190 Back to favorites"), hint: "" },
12374
+ { value: ADD_BY_PROVIDER, label: pc13.cyan("Browse by provider \u2192"), hint: "Pick one provider first" }
12041
12375
  ]
12042
12376
  });
12043
- if (p14.isCancel(fallback) || fallback === "back") return null;
12377
+ if (p15.isCancel(fallback) || fallback === "back") return null;
12044
12378
  if (fallback === ADD_BY_PROVIDER) return ADD_BY_PROVIDER;
12045
12379
  continue;
12046
12380
  }
12047
12381
  const matched = filterGlobalFavoriteIndex(index, String(searchInput), { freeOnly });
12048
12382
  if (matched.length === 0) {
12049
- p14.log.warn("No models match \u2014 try a different search");
12383
+ p15.log.warn("No models match \u2014 try a different search");
12050
12384
  continue;
12051
12385
  }
12052
12386
  const result = await pickModelFromPagedList(
@@ -12064,7 +12398,7 @@ async function pickGlobalFavoriteModel(providers, favorites, opts) {
12064
12398
  const picked = parseGlobalFavoritePickKey(result.id, matched);
12065
12399
  if (!picked) continue;
12066
12400
  if (isFavorite(favorites, { providerId: picked.providerId, modelId: picked.model.id })) {
12067
- p14.log.warn(`${picked.model.name || picked.model.id} (${picked.providerName}) is already in your favorites.`);
12401
+ p15.log.warn(`${picked.model.name || picked.model.id} (${picked.providerName}) is already in your favorites.`);
12068
12402
  continue;
12069
12403
  }
12070
12404
  return picked;
@@ -12074,12 +12408,15 @@ async function pickGlobalFavoriteModel(providers, favorites, opts) {
12074
12408
  // src/cli/models.ts
12075
12409
  var AGY_CLI_FAVORITES_CAP = 6;
12076
12410
  async function runModelsCommand(parsed) {
12411
+ if (parsed.validateSubcommand) {
12412
+ return runValidateSubcommand(parsed);
12413
+ }
12077
12414
  const scope = parsed.favoritesAgy ? "agy" : "global";
12078
12415
  const maxFavorites = scope === "agy" ? AGY_CLI_FAVORITES_CAP : 20;
12079
12416
  const scopeName = scope === "agy" ? "Antigravity CLI Favorites" : "Favorite Models";
12080
12417
  const configKey = scope === "agy" ? "antigravityCliFavoriteModels" : "favoriteModels";
12081
12418
  gateIntro(scopeName);
12082
- const spinner10 = p15.spinner();
12419
+ const spinner10 = p16.spinner();
12083
12420
  spinner10.start("Loading providers...");
12084
12421
  const catalog = await fetchProviderCatalog();
12085
12422
  spinner10.stop("");
@@ -12089,8 +12426,8 @@ async function runModelsCommand(parsed) {
12089
12426
  name: favoriteProviderDisplayName(provider)
12090
12427
  }));
12091
12428
  if (favoriteProviders.length === 0) {
12092
- p15.log.warn("No providers found.");
12093
- p15.log.info(`OpenCode Zen/Go is always available. Add providers with ${pc13.cyan("anygate providers")}.`);
12429
+ p16.log.warn("No providers found.");
12430
+ p16.log.info(`OpenCode Zen/Go is always available. Add providers with ${pc14.cyan("anygate providers")}.`);
12094
12431
  gateOutro("Done");
12095
12432
  return 0;
12096
12433
  }
@@ -12108,50 +12445,50 @@ async function runModelsCommand(parsed) {
12108
12445
  for (let i = 0; i < favorites.length; i++) {
12109
12446
  const fav = favorites[i];
12110
12447
  const entry = modelLookup.get(`${fav.providerId}:${fav.modelId}`);
12111
- const label = entry ? `${fmtEnabledStar(true)} ${fmtModel(entry.modelName)} ${pc13.dim(`(${entry.providerName})`)}` : pc13.dim(`\u2605 ${fav.modelId} \u2014 provider gone`);
12448
+ const label = entry ? `${fmtEnabledStar(true)} ${fmtModel(entry.modelName)} ${pc14.dim(`(${entry.providerName})`)}` : pc14.dim(`\u2605 ${fav.modelId} \u2014 provider gone`);
12112
12449
  options.push({ value: `fav-${i}`, label, hint: "select to remove" });
12113
12450
  }
12114
12451
  const atCap = favorites.length >= 20;
12115
12452
  options.push({
12116
12453
  value: "__add__",
12117
- label: atCap ? pc13.dim(`+ Add a model \u2192 (limit of 20 reached)`) : pc13.cyan("+ Add a model \u2192"),
12454
+ label: atCap ? pc14.dim(`+ Add a model \u2192 (limit of 20 reached)`) : pc14.cyan("+ Add a model \u2192"),
12118
12455
  hint: atCap ? "Remove a favorite first to make room" : `${favoriteProviders.length} provider${favoriteProviders.length !== 1 ? "s" : ""} available`
12119
12456
  });
12120
12457
  options.push({ value: "__done__", label: "Done", hint: "" });
12121
12458
  const header = favorites.length === 0 ? `${scopeName} (0/20)` : `${scopeName} (${favorites.length}/20) \u2014 select to remove`;
12122
- const choice = await p15.select({
12459
+ const choice = await p16.select({
12123
12460
  message: header,
12124
12461
  options,
12125
12462
  initialValue: "__done__"
12126
12463
  });
12127
- if (p15.isCancel(choice) || choice === "__done__") break;
12464
+ if (p16.isCancel(choice) || choice === "__done__") break;
12128
12465
  if (choice === "__add__") {
12129
12466
  if (atCap) {
12130
- p15.log.warn("Limit of 20 favorites reached \u2014 remove one first.");
12467
+ p16.log.warn("Limit of 20 favorites reached \u2014 remove one first.");
12131
12468
  continue;
12132
12469
  }
12133
12470
  const globalCount = buildGlobalFavoriteIndex(favoriteProviders).length;
12134
- const addPath = await p15.select({
12471
+ const addPath = await p16.select({
12135
12472
  message: "Add a favorite",
12136
12473
  options: [
12137
12474
  {
12138
12475
  value: "global",
12139
- label: pc13.cyan("Search all providers"),
12476
+ label: pc14.cyan("Search all providers"),
12140
12477
  hint: `${globalCount} models \xB7 ${favoriteProviders.length} provider${favoriteProviders.length !== 1 ? "s" : ""}`
12141
12478
  },
12142
12479
  {
12143
12480
  value: "free",
12144
- label: pc13.cyan("Search free models"),
12481
+ label: pc14.cyan("Search free models"),
12145
12482
  hint: `${buildGlobalFavoriteIndex(favoriteProviders).filter((e) => e.model.isFree || e.model.freeStatus === "verified_free" || e.model.freeStatus === "free_provider").length} free/free-access models`
12146
12483
  },
12147
12484
  {
12148
12485
  value: "provider",
12149
- label: pc13.cyan("Browse by provider \u2192"),
12486
+ label: pc14.cyan("Browse by provider \u2192"),
12150
12487
  hint: "Pick one provider first"
12151
12488
  }
12152
12489
  ]
12153
12490
  });
12154
- if (p15.isCancel(addPath)) continue;
12491
+ if (p16.isCancel(addPath)) continue;
12155
12492
  let provider;
12156
12493
  let browsedMultiple = [];
12157
12494
  if (addPath === "global") {
@@ -12178,12 +12515,12 @@ async function runModelsCommand(parsed) {
12178
12515
  label: ap.name,
12179
12516
  hint: `${ap.models.length} models`
12180
12517
  }));
12181
- const pickedProviderId = await p15.select({
12518
+ const pickedProviderId = await p16.select({
12182
12519
  message: "Which provider?",
12183
12520
  options: providerOptions,
12184
12521
  initialValue: currentInitialProvider
12185
12522
  });
12186
- if (p15.isCancel(pickedProviderId)) break;
12523
+ if (p16.isCancel(pickedProviderId)) break;
12187
12524
  provider = favoriteProviders.find((ap) => ap.id === pickedProviderId);
12188
12525
  const options2 = provider.models.map((m) => {
12189
12526
  const favorited = isFavorite(favorites, { providerId: provider.id, modelId: m.id });
@@ -12191,15 +12528,15 @@ async function runModelsCommand(parsed) {
12191
12528
  return {
12192
12529
  value: m.id,
12193
12530
  label: `${favorited ? "\u2605 " : ""}${fmtModel(label, m.id)}`,
12194
- hint: favorited ? pc13.yellow("\u2605 already favorite") : ""
12531
+ hint: favorited ? pc14.yellow("\u2605 already favorite") : ""
12195
12532
  };
12196
12533
  });
12197
- const pickedModelIds = await p15.multiselect({
12198
- message: `Select models to add from ${provider.name} ${pc13.dim("(Space to select, Enter to confirm)")}`,
12534
+ const pickedModelIds = await p16.multiselect({
12535
+ message: `Select models to add from ${provider.name} ${pc14.dim("(Space to select, Enter to confirm)")}`,
12199
12536
  options: options2,
12200
12537
  required: false
12201
12538
  });
12202
- if (p15.isCancel(pickedModelIds)) {
12539
+ if (p16.isCancel(pickedModelIds)) {
12203
12540
  currentInitialProvider = provider.id;
12204
12541
  continue;
12205
12542
  }
@@ -12234,27 +12571,27 @@ async function runModelsCommand(parsed) {
12234
12571
  if (addedModels.length > 0) {
12235
12572
  if (addedModels.length === 1) {
12236
12573
  const modelName = addedModels[0].name || addedModels[0].id;
12237
- p15.log.success(`Added ${modelName} (${provider.name}) to favorites.`);
12574
+ p16.log.success(`Added ${modelName} (${provider.name}) to favorites.`);
12238
12575
  } else {
12239
- p15.log.success(`Added ${addedModels.length} models from ${provider.name} to favorites.`);
12576
+ p16.log.success(`Added ${addedModels.length} models from ${provider.name} to favorites.`);
12240
12577
  }
12241
12578
  }
12242
12579
  if (duplicateCount > 0) {
12243
- p15.log.warn(`${duplicateCount} selected model(s) were already in your favorites.`);
12580
+ p16.log.warn(`${duplicateCount} selected model(s) were already in your favorites.`);
12244
12581
  }
12245
12582
  if (limitReached) {
12246
- p15.log.warn(`Limit of 20 favorites reached \u2014 some selected models could not be added.`);
12583
+ p16.log.warn(`Limit of 20 favorites reached \u2014 some selected models could not be added.`);
12247
12584
  }
12248
12585
  } else if (choice.startsWith("fav-")) {
12249
12586
  const idx = parseInt(choice.slice(4), 10);
12250
12587
  const fav = favorites[idx];
12251
12588
  const entry = modelLookup.get(`${fav.providerId}:${fav.modelId}`);
12252
12589
  const label = entry ? `${entry.modelName} (${entry.providerName})` : fav.modelId;
12253
- const confirmed = await p15.confirm({ message: `Remove ${label} from favorites?` });
12254
- if (p15.isCancel(confirmed) || !confirmed) continue;
12590
+ const confirmed = await p16.confirm({ message: `Remove ${label} from favorites?` });
12591
+ if (p16.isCancel(confirmed) || !confirmed) continue;
12255
12592
  favorites = removeFavorite(favorites, fav);
12256
12593
  favoritesDirty = true;
12257
- p15.log.success(`Removed ${label} from favorites.`);
12594
+ p16.log.success(`Removed ${label} from favorites.`);
12258
12595
  }
12259
12596
  }
12260
12597
  if (favoritesDirty) {
@@ -12263,15 +12600,101 @@ async function runModelsCommand(parsed) {
12263
12600
  const favLabel = scope === "agy" ? "Antigravity CLI " : "";
12264
12601
  gateOutro(
12265
12602
  favorites.length === 0 ? `No ${favLabel}favorites saved` : `${favorites.length} ${favLabel}favorite${favorites.length !== 1 ? "s" : ""} saved`,
12266
- favorites.length === 0 ? pc13.dim("Launch uses single-model mode") : pc13.cyan("/model menu ready on next launch")
12603
+ favorites.length === 0 ? pc14.dim("Launch uses single-model mode") : pc14.cyan("/model menu ready on next launch")
12267
12604
  );
12268
12605
  return 0;
12269
12606
  }
12607
+ async function runValidateSubcommand(parsed) {
12608
+ gateIntro("Model Validation");
12609
+ const providerId = parsed.validateProvider;
12610
+ const force = parsed.force ?? false;
12611
+ const ttlMs = force ? 0 : void 0;
12612
+ const catalog = await fetchProviderCatalog();
12613
+ const registry = loadRegistry();
12614
+ let providersToValidate = catalog;
12615
+ if (providerId) {
12616
+ const found = catalog.find((p18) => p18.id === providerId);
12617
+ if (!found) {
12618
+ p16.log.error(`Provider not found: ${providerId}`);
12619
+ return 1;
12620
+ }
12621
+ providersToValidate = [found];
12622
+ }
12623
+ if (providersToValidate.length === 0) {
12624
+ p16.log.warn("No providers configured.");
12625
+ return 0;
12626
+ }
12627
+ const allParams = [];
12628
+ for (const provider of providersToValidate) {
12629
+ const regProvider = registry.providers.find((p18) => p18.id === provider.id);
12630
+ if (!regProvider) continue;
12631
+ const apiKey = provider.apiKey || await resolveProviderCredential(provider.id, regProvider.authRef).catch(() => "");
12632
+ if (!apiKey?.trim()) {
12633
+ p16.log.warn(`Skipping ${provider.name} \u2014 no API key available.`);
12634
+ continue;
12635
+ }
12636
+ const baseUrl = provider.models[0]?.apiBaseUrl || provider.models[0]?.completionsUrl || "";
12637
+ if (!baseUrl) {
12638
+ p16.log.warn(`Skipping ${provider.name} \u2014 no base URL available.`);
12639
+ continue;
12640
+ }
12641
+ for (const model of provider.models) {
12642
+ const completionsUrl = model.completionsUrl || model.apiBaseUrl || "";
12643
+ if (!completionsUrl) continue;
12644
+ allParams.push({
12645
+ modelId: model.id,
12646
+ providerId: provider.id,
12647
+ baseUrl: completionsUrl.replace(/\/chat\/completions$/, "").replace(/\/v1\/?$/, ""),
12648
+ apiKey,
12649
+ modelFormat: model.modelFormat === "anthropic" ? "anthropic" : "openai",
12650
+ headers: provider.headers
12651
+ });
12652
+ }
12653
+ }
12654
+ if (allParams.length === 0) {
12655
+ p16.log.warn("No models to validate.");
12656
+ return 0;
12657
+ }
12658
+ const spinner10 = p16.spinner();
12659
+ spinner10.start(`Validating ${allParams.length} model${allParams.length === 1 ? "" : "s"}...`);
12660
+ const results = await validateModels(allParams, { ttlMs });
12661
+ spinner10.stop("");
12662
+ const available = results.filter((r) => r.status === "available").length;
12663
+ const deprecated = results.filter((r) => r.status === "deprecated").length;
12664
+ const errors = results.filter((r) => r.status === "error").length;
12665
+ const unverified = results.filter((r) => r.status === "unverified").length;
12666
+ if (deprecated > 0) {
12667
+ p16.log.error(`${deprecated} model${deprecated === 1 ? "" : "s"} marked as deprecated:`);
12668
+ for (const r of results.filter((r2) => r2.status === "deprecated")) {
12669
+ p16.log.error(` ${r.modelId} (${r.providerId}): ${r.error ?? "unknown"}`);
12670
+ }
12671
+ }
12672
+ if (errors > 0) {
12673
+ p16.log.warn(`${errors} model${errors === 1 ? "" : "s"} with errors:`);
12674
+ for (const r of results.filter((r2) => r2.status === "error")) {
12675
+ p16.log.warn(` ${r.modelId} (${r.providerId}): ${r.error ?? "unknown"}`);
12676
+ }
12677
+ }
12678
+ if (unverified > 0) {
12679
+ p16.log.warn(`${unverified} model${unverified === 1 ? "" : "s"} unverified (will retry later):`);
12680
+ for (const r of results.filter((r2) => r2.status === "unverified")) {
12681
+ p16.log.warn(` ${r.modelId} (${r.providerId}): ${r.error ?? "unknown"}`);
12682
+ }
12683
+ }
12684
+ p16.log.success(
12685
+ `${available} available, ${deprecated} deprecated, ${errors} error${errors === 1 ? "" : "s"}, ${unverified} unverified`
12686
+ );
12687
+ const pruned = pruneValidationCache();
12688
+ if (pruned > 0) {
12689
+ p16.log.info(`Pruned ${pruned} stale cache entr${pruned === 1 ? "y" : "ies"}.`);
12690
+ }
12691
+ return deprecated > 0 ? 1 : 0;
12692
+ }
12270
12693
 
12271
12694
  // src/cli/providers.ts
12272
12695
  async function handleProvidersCommand(parsed) {
12273
12696
  if (parsed.showVersion) {
12274
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
12697
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
12275
12698
  console.log(VERSION2);
12276
12699
  return 0;
12277
12700
  }
@@ -12286,7 +12709,7 @@ async function handleProvidersCommand(parsed) {
12286
12709
  }
12287
12710
 
12288
12711
  // src/apps/shared/doctor.ts
12289
- import pc14 from "picocolors";
12712
+ import pc15 from "picocolors";
12290
12713
  import { createServer as createServer3 } from "net";
12291
12714
  function nodeMajor() {
12292
12715
  const raw = process.versions.node.split(".")[0] ?? "0";
@@ -12304,8 +12727,8 @@ function checkPortFree(port) {
12304
12727
  });
12305
12728
  }
12306
12729
  function line(ok, label, detail = "") {
12307
- const mark = ok ? pc14.green("\u2713") : pc14.red("\u2717");
12308
- const text4 = detail ? `${label} ${pc14.dim(`\u2014 ${detail}`)}` : label;
12730
+ const mark = ok ? pc15.green("\u2713") : pc15.red("\u2717");
12731
+ const text4 = detail ? `${label} ${pc15.dim(`\u2014 ${detail}`)}` : label;
12309
12732
  return ` ${mark} ${text4}`;
12310
12733
  }
12311
12734
  async function runDoctorCommand(_dryRun) {
@@ -12366,15 +12789,15 @@ async function runDoctorCommand(_dryRun) {
12366
12789
  const reportLines = checks.map((c) => line(c.ok, c.label, c.detail));
12367
12790
  reportLines.push("");
12368
12791
  reportLines.push(
12369
- pc14.dim("Antigravity note: macOS-only today. Windows/Linux app launches are") + pc14.dim(" best-effort \u2014 see help for each agy/antigravity command.")
12792
+ pc15.dim("Antigravity note: macOS-only today. Windows/Linux app launches are") + pc15.dim(" best-effort \u2014 see help for each agy/antigravity command.")
12370
12793
  );
12371
12794
  printPanel("Environment check", reportLines);
12372
12795
  if (failedCritical.length > 0) {
12373
- gateOutro("Problems found", pc14.red(`${failedCritical.length} critical check(s) failed`));
12796
+ gateOutro("Problems found", pc15.red(`${failedCritical.length} critical check(s) failed`));
12374
12797
  return 1;
12375
12798
  }
12376
12799
  if (failedNonCritical.length > 0) {
12377
- gateOutro("Mostly OK", pc14.yellow(`${failedNonCritical.length} non-critical warning(s)`));
12800
+ gateOutro("Mostly OK", pc15.yellow(`${failedNonCritical.length} non-critical warning(s)`));
12378
12801
  return 0;
12379
12802
  }
12380
12803
  gateOutro("All checks passed");
@@ -12384,7 +12807,7 @@ async function runDoctorCommand(_dryRun) {
12384
12807
  // src/cli/doctor.ts
12385
12808
  async function handleDoctorCommand(parsed) {
12386
12809
  if (parsed.showVersion) {
12387
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
12810
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
12388
12811
  console.log(VERSION2);
12389
12812
  return 0;
12390
12813
  }
@@ -12413,7 +12836,7 @@ Checks:
12413
12836
  }
12414
12837
 
12415
12838
  // src/apps/shared/completions.ts
12416
- import pc15 from "picocolors";
12839
+ import pc16 from "picocolors";
12417
12840
  var SUBCOMMANDS = [
12418
12841
  "claude",
12419
12842
  "claude-app",
@@ -12510,7 +12933,7 @@ var SCRIPTS = {
12510
12933
  function runCompletionsCommand(shellArg) {
12511
12934
  const shell = normalizeShell(shellArg) ?? detectShell();
12512
12935
  if (!shell) {
12513
- console.error(pc15.red("\\nError: could not detect your shell.\\n"));
12936
+ console.error(pc16.red("\\nError: could not detect your shell.\\n"));
12514
12937
  console.error("Pass one explicitly: anygate completions <bash|zsh|fish|powershell>\\n");
12515
12938
  return Promise.resolve(1);
12516
12939
  }
@@ -12521,7 +12944,7 @@ function runCompletionsCommand(shellArg) {
12521
12944
  // src/cli/completions.ts
12522
12945
  async function handleCompletionsCommand(parsed) {
12523
12946
  if (parsed.showVersion) {
12524
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
12947
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
12525
12948
  console.log(VERSION2);
12526
12949
  return 0;
12527
12950
  }
@@ -12547,9 +12970,9 @@ Examples:
12547
12970
  }
12548
12971
 
12549
12972
  // src/apps/shared/self-update.ts
12550
- import pc16 from "picocolors";
12973
+ import pc17 from "picocolors";
12551
12974
  import { spawn as spawn5, execFileSync as execFileSync4 } from "child_process";
12552
- import * as p16 from "@clack/prompts";
12975
+ import * as p17 from "@clack/prompts";
12553
12976
  function resolveNpmBin() {
12554
12977
  if (process.platform === "win32") {
12555
12978
  try {
@@ -12564,41 +12987,41 @@ function resolveNpmBin() {
12564
12987
  async function runUpdateCommand(dryRun) {
12565
12988
  const update = await checkForUpdates();
12566
12989
  if (!update.updateAvailable || !update.latestVersion) {
12567
- p16.log.success(`anygate is up to date (v${VERSION}).`);
12990
+ p17.log.success(`anygate is up to date (v${VERSION}).`);
12568
12991
  return 0;
12569
12992
  }
12570
- p16.log.info(
12571
- `Update available: ${pc16.cyan(`v${update.currentVersion}`)} \u2192 ${pc16.green(`v${update.latestVersion}`)}`
12993
+ p17.log.info(
12994
+ `Update available: ${pc17.cyan(`v${update.currentVersion}`)} \u2192 ${pc17.green(`v${update.latestVersion}`)}`
12572
12995
  );
12573
12996
  const npmBin = resolveNpmBin();
12574
12997
  if (dryRun) {
12575
- p16.log.step(`Would run: ${pc16.bold(`${npmBin} install -g anygate@latest`)}`);
12576
- p16.log.warn("Dry run \u2014 no changes made.");
12998
+ p17.log.step(`Would run: ${pc17.bold(`${npmBin} install -g anygate@latest`)}`);
12999
+ p17.log.warn("Dry run \u2014 no changes made.");
12577
13000
  return 0;
12578
13001
  }
12579
- const confirmed = await p16.confirm({
13002
+ const confirmed = await p17.confirm({
12580
13003
  message: `Install anygate@${update.latestVersion} now?`,
12581
13004
  initialValue: false
12582
13005
  });
12583
- if (p16.isCancel(confirmed) || !confirmed) {
12584
- p16.log.info(`Update skipped. Run ${pc16.cyan(UPDATE_COMMAND)} later if you change your mind.`);
13006
+ if (p17.isCancel(confirmed) || !confirmed) {
13007
+ p17.log.info(`Update skipped. Run ${pc17.cyan(UPDATE_COMMAND)} later if you change your mind.`);
12585
13008
  return 0;
12586
13009
  }
12587
- p16.log.info(`Running ${pc16.cyan(`${npmBin} install -g anygate@latest`)}...`);
13010
+ p17.log.info(`Running ${pc17.cyan(`${npmBin} install -g anygate@latest`)}...`);
12588
13011
  const child = spawn5(npmBin, ["install", "-g", "anygate@latest"], {
12589
13012
  stdio: "inherit",
12590
13013
  windowsHide: true
12591
13014
  });
12592
13015
  return new Promise((resolve) => {
12593
13016
  child.on("error", (err) => {
12594
- p16.log.error(`Failed to start npm: ${err instanceof Error ? err.message : String(err)}`);
13017
+ p17.log.error(`Failed to start npm: ${err instanceof Error ? err.message : String(err)}`);
12595
13018
  resolve(1);
12596
13019
  });
12597
13020
  child.on("close", (code) => {
12598
13021
  if (code === 0) {
12599
- p16.log.success("anygate updated. Restart your shell or re-run anygate to use the new version.");
13022
+ p17.log.success("anygate updated. Restart your shell or re-run anygate to use the new version.");
12600
13023
  } else {
12601
- p16.log.error(`Update failed (exit ${code}). Try ${pc16.cyan(UPDATE_COMMAND)} manually.`);
13024
+ p17.log.error(`Update failed (exit ${code}). Try ${pc17.cyan(UPDATE_COMMAND)} manually.`);
12602
13025
  }
12603
13026
  resolve(code ?? 1);
12604
13027
  });
@@ -12608,7 +13031,7 @@ async function runUpdateCommand(dryRun) {
12608
13031
  // src/cli/update.ts
12609
13032
  async function handleUpdateCommand(parsed) {
12610
13033
  if (parsed.showVersion) {
12611
- const { VERSION: VERSION2 } = await import("./constants-5RN2WJSS.js");
13034
+ const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
12612
13035
  console.log(VERSION2);
12613
13036
  return 0;
12614
13037
  }
@@ -12643,6 +13066,7 @@ async function dispatchCommand(parsed) {
12643
13066
  }
12644
13067
  return handler(parsed);
12645
13068
  }
13069
+ registerCommand("root", handleRootCommand);
12646
13070
  registerCommand("claude", handleClaudeCommand);
12647
13071
  registerCommand("codex", handleCodexCommand);
12648
13072
  registerCommand("codex-app", handleCodexAppCommand);
@@ -12746,7 +13170,7 @@ function parseArgs(args) {
12746
13170
  aiInstallForce: args.includes("--force")
12747
13171
  };
12748
13172
  }
12749
- if (args.length === 0) return { ...emptyParsed("root"), showHelp: true };
13173
+ if (args.length === 0) return { ...emptyParsed("root"), showHelp: false };
12750
13174
  const [first, ...rest] = args;
12751
13175
  if (first === "--help" || first === "-h") {
12752
13176
  return { ...emptyParsed("root"), showHelp: true };
@@ -12792,10 +13216,21 @@ function parseArgs(args) {
12792
13216
  }
12793
13217
  if (first === "models" || first === "favorites") {
12794
13218
  const parsed2 = emptyParsed("models");
12795
- for (const arg of rest) {
13219
+ for (let i = 0; i < rest.length; i += 1) {
13220
+ const arg = rest[i];
12796
13221
  if (arg === "--help" || arg === "-h") parsed2.showHelp = true;
12797
13222
  else if (arg === "--version" || arg === "-v") parsed2.showVersion = true;
12798
13223
  else if (arg === "--agy") parsed2.favoritesAgy = true;
13224
+ else if (arg === "--force") parsed2.force = true;
13225
+ else if (arg === "--provider" || arg.startsWith("--provider=")) {
13226
+ const value = arg.startsWith("--provider=") ? arg.slice("--provider=".length) : rest[i + 1];
13227
+ if (!value || value.startsWith("-")) {
13228
+ parsed2.error = "Missing value for --provider";
13229
+ return parsed2;
13230
+ }
13231
+ if (!arg.startsWith("--provider=")) i += 1;
13232
+ parsed2.validateProvider = value;
13233
+ } else if (arg === "validate") parsed2.validateSubcommand = true;
12799
13234
  else if (!parsed2.error) parsed2.error = `Unknown models option: ${arg}`;
12800
13235
  }
12801
13236
  return parsed2;
@@ -13071,11 +13506,11 @@ ${text4}
13071
13506
  `);
13072
13507
  }
13073
13508
  function rootHelpText() {
13074
- return `${pc17.bold("anygate")} v${VERSION}
13509
+ return `${pc18.bold("anygate")} v${VERSION}
13075
13510
  Launch AI coding tools with OpenCode Zen / Go or local providers (Groq, Mistral,
13076
13511
  OpenAI, Gemini, Ollama, and more).
13077
13512
 
13078
- ${pc17.bold("Usage:")}
13513
+ ${pc18.bold("Usage:")}
13079
13514
  anygate claude [options] [claude-flags]
13080
13515
  anygate claude-app [options]
13081
13516
  anygate codex [options] [codex-flags]
@@ -13088,6 +13523,7 @@ ${pc17.bold("Usage:")}
13088
13523
  anygate server [options]
13089
13524
  anygate ui
13090
13525
  anygate models
13526
+ anygate models validate [--provider <id>] [--force]
13091
13527
  anygate favorites
13092
13528
  anygate providers
13093
13529
  anygate doctor
@@ -13099,14 +13535,14 @@ ${pc17.bold("Usage:")}
13099
13535
  anygate --ai --install Install or upgrade agent skill when version changed
13100
13536
  anygate --ai --install --force Reinstall skill even if already current
13101
13537
 
13102
- ${pc17.bold("Root options:")}
13538
+ ${pc18.bold("Root options:")}
13103
13539
  -h, --help Show this help
13104
13540
  -v, --version Show version
13105
13541
  --ai Print the full reference for AI agents
13106
13542
  --ai --install Install or upgrade the anygate agent skill
13107
13543
  --force Reinstall the agent skill when used with --ai --install
13108
13544
 
13109
- ${pc17.bold("Commands:")}
13545
+ ${pc18.bold("Commands:")}
13110
13546
  claude Launch Claude Code \u2014 pick a provider from your registry
13111
13547
  models Manage favorite models for mid-session /model switching (max ${MAX_MODEL_CATALOG})
13112
13548
  favorites Alias for models
@@ -13124,15 +13560,17 @@ ${pc17.bold("Commands:")}
13124
13560
  completions Print a shell completion script for anygate
13125
13561
  update Interactively upgrade anygate to the latest published version
13126
13562
 
13127
- ${pc17.bold("Antigravity favorites:")}
13563
+ ${pc18.bold("Antigravity favorites:")}
13128
13564
  agy, antigravity, and antigravity-ide share up to six Antigravity favorites
13129
13565
  from anygate favorites --agy, plus the selected launch model.
13130
13566
 
13131
- ${pc17.bold("Upgradeion:")}
13132
- Bare anygate prints this help instead of launching Claude Code.
13133
- Use anygate claude for the wizard and launcher.
13567
+ ${pc18.bold("Bare command:")}
13568
+ anygate (no subcommand) runs the onboarding flow on first run, or
13569
+ shows a main menu on subsequent runs. Use anygate claude for the
13570
+ Claude Code wizard and launcher.
13134
13571
 
13135
- ${pc17.bold("Examples:")}
13572
+ ${pc18.bold("Examples:")}
13573
+ anygate
13136
13574
  anygate claude
13137
13575
  anygate models
13138
13576
  anygate providers
@@ -13149,15 +13587,15 @@ ${pc17.bold("Examples:")}
13149
13587
  anygate claude -- --print "hello"`;
13150
13588
  }
13151
13589
  function claudeHelpText() {
13152
- return `${pc17.bold("anygate claude")} v${VERSION}
13590
+ return `${pc18.bold("anygate claude")} v${VERSION}
13153
13591
  Launch Claude Code with OpenCode Zen, Go, or local providers as the API backend.
13154
13592
 
13155
- ${pc17.bold("Usage:")}
13593
+ ${pc18.bold("Usage:")}
13156
13594
  anygate claude [options] [claude-flags]
13157
13595
  anygate claude --help
13158
13596
  anygate claude --version
13159
13597
 
13160
- ${pc17.bold("Options:")}
13598
+ ${pc18.bold("Options:")}
13161
13599
  --dry-run Run the wizard but show a preview instead of launching Claude Code
13162
13600
  --setup Hint: use anygate providers to add or manage providers
13163
13601
  --trace Write debug logs to ~/.anygate/logs/ and show errors on exit
@@ -13166,22 +13604,22 @@ ${pc17.bold("Options:")}
13166
13604
  --help Show this command help
13167
13605
  --version Show version
13168
13606
 
13169
- ${pc17.bold("Providers:")}
13607
+ ${pc18.bold("Providers:")}
13170
13608
  Cloud (Zen/Go) Requires OPENCODE_API_KEY \u2014 get one at https://opencode.ai/auth
13171
13609
  Registry Configure with anygate providers add or import (Groq, Mistral,
13172
13610
  Nvidia, DeepSeek, OpenAI, custom endpoints, etc.).
13173
13611
 
13174
- ${pc17.bold("Model switching:")}
13612
+ ${pc18.bold("Model switching:")}
13175
13613
  Run anygate models to save favorites (max ${MAX_MODEL_CATALOG}).
13176
13614
  When favorites exist, launch starts a multi-route proxy and Claude Code /model
13177
13615
  lists your starting model plus favorites for live switching.
13178
13616
  With no favorites, launch uses a single model as before.
13179
13617
 
13180
- ${pc17.bold("Note:")}
13618
+ ${pc18.bold("Note:")}
13181
13619
  Claude Code may save the launched model to ~/.claude/settings.json.
13182
13620
  Bare claude later can still show that model \u2014 reset with claude --model sonnet.
13183
13621
 
13184
- ${pc17.bold("Examples:")}
13622
+ ${pc18.bold("Examples:")}
13185
13623
  anygate claude
13186
13624
  anygate claude -c
13187
13625
  anygate claude --resume abc-123
@@ -13195,10 +13633,10 @@ ${pc17.bold("Examples:")}
13195
13633
  anygate claude -- --dangerously-skip-permissions`;
13196
13634
  }
13197
13635
  function serverHelpText() {
13198
- return `${pc17.bold("anygate server")} v${VERSION}
13636
+ return `${pc18.bold("anygate server")} v${VERSION}
13199
13637
  Run a foreground API gateway for registry providers, Zen/Go, or Vertex AI.
13200
13638
 
13201
- ${pc17.bold("Usage:")}
13639
+ ${pc18.bold("Usage:")}
13202
13640
  anygate server
13203
13641
  anygate server --quick
13204
13642
  anygate server --listen network --password <password>
@@ -13206,7 +13644,7 @@ ${pc17.bold("Usage:")}
13206
13644
  anygate server --help
13207
13645
  anygate server --version
13208
13646
 
13209
- ${pc17.bold("Options:")}
13647
+ ${pc18.bold("Options:")}
13210
13648
  --quick, --saved Start immediately from saved/default settings
13211
13649
  --listen local|network One-run listen mode override
13212
13650
  --providers all|favorites|id1,id2
@@ -13217,7 +13655,7 @@ ${pc17.bold("Options:")}
13217
13655
  --password <value> One-run network-mode server password
13218
13656
  --vertex Use Claude on Google Vertex AI
13219
13657
 
13220
- ${pc17.bold("Behavior:")}
13658
+ ${pc18.bold("Behavior:")}
13221
13659
  Default: interactive wizard for exposed providers, discovery id masking (for
13222
13660
  Claude Desktop / Cowork), optional favorites-only catalog, then listen mode.
13223
13661
  Quick mode skips prompts and uses saved settings. Any one-run option also
@@ -13227,129 +13665,129 @@ ${pc17.bold("Behavior:")}
13227
13665
  local gcloud Application Default Credentials (no OpenCode API key).
13228
13666
  Binds to port 17645. Network mode asks for a server password.
13229
13667
 
13230
- ${pc17.bold("Vertex env:")}
13668
+ ${pc18.bold("Vertex env:")}
13231
13669
  ANTHROPIC_VERTEX_PROJECT_ID or GOOGLE_CLOUD_PROJECT \u2014 your GCP project
13232
13670
  GOOGLE_CLOUD_LOCATION or CLOUD_ML_REGION \u2014 region (default: global)
13233
13671
  Optional catalog: ~/.anygate/vertex-models.json (see assets/vertex-models.example.json)
13234
13672
 
13235
- ${pc17.bold("Endpoints:")}
13673
+ ${pc18.bold("Endpoints:")}
13236
13674
  Anthropic-compatible: ANTHROPIC_BASE_URL=http://127.0.0.1:17645/anthropic
13237
13675
  OpenAI-compatible: OPENAI_BASE_URL=http://127.0.0.1:17645/openai/v1
13238
13676
  API key: use anything locally; use the server password in network mode.`;
13239
13677
  }
13240
13678
  function modelsHelpText() {
13241
- return `${pc17.bold("anygate favorites")} v${VERSION}
13679
+ return `${pc18.bold("anygate favorites")} v${VERSION}
13242
13680
  Manage favorite models for mid-session switching.
13243
13681
 
13244
- ${pc17.bold("Usage:")}
13682
+ ${pc18.bold("Usage:")}
13245
13683
  anygate favorites
13246
13684
  anygate favorites --agy
13247
13685
  anygate models
13248
13686
  anygate favorites --help
13249
13687
  anygate favorites --version
13250
13688
 
13251
- ${pc17.bold("Behavior:")}
13689
+ ${pc18.bold("Behavior:")}
13252
13690
  Opens an interactive manager to add or remove favorites.
13253
13691
  Search all providers at once (paginated results) or browse one provider at a time.
13254
13692
  Pick from Zen, Go, or any provider in your registry.
13255
13693
  Global favorites are saved to ~/.anygate/config.json (max ${MAX_MODEL_CATALOG}).
13256
13694
  --agy manages Antigravity CLI favorites only (max 6).
13257
13695
 
13258
- ${pc17.bold("How it works:")}
13696
+ ${pc18.bold("How it works:")}
13259
13697
  Claude/Codex/Gemini/server use the global favorites list.
13260
13698
  Favorites appear in supported /model switch menus.
13261
13699
  anygate agy, antigravity, and antigravity-ide use the Antigravity favorites
13262
13700
  list so the limited native switch slots stay predictable: one selected launch
13263
13701
  model plus up to six Antigravity favorites.
13264
13702
 
13265
- ${pc17.bold("Examples:")}
13703
+ ${pc18.bold("Examples:")}
13266
13704
  anygate favorites
13267
13705
  anygate favorites --agy
13268
13706
  anygate claude # switch menu active when favorites are set`;
13269
13707
  }
13270
13708
  function antigravityCliHelpText() {
13271
- return `${pc17.bold("anygate agy")} v${VERSION}
13709
+ return `${pc18.bold("anygate agy")} v${VERSION}
13272
13710
  Launch Antigravity CLI with anygate provider registry.
13273
13711
 
13274
- ${pc17.bold("Usage:")}
13712
+ ${pc18.bold("Usage:")}
13275
13713
  anygate agy [options] [agy-flags]
13276
13714
  anygate agy --help
13277
13715
  anygate agy --version
13278
13716
 
13279
- ${pc17.bold("Options:")}
13717
+ ${pc18.bold("Options:")}
13280
13718
  --provider <id> Use a specific provider (skip picker)
13281
13719
  --model <id> Use a specific model (skip picker)
13282
13720
  --trace Write debug log to /tmp/anygate-debug.log
13283
13721
  -h, --help Show this help
13284
13722
  -v, --version Show version
13285
13723
 
13286
- ${pc17.bold("How it works:")}
13724
+ ${pc18.bold("How it works:")}
13287
13725
  Starts a local Cloud Code gateway, points agy at it via CLOUD_CODE_URL,
13288
13726
  and injects anygate models into Antigravity's native model picker.
13289
13727
  All Cloud Code traffic routes through anygate \u2014 no Google Cloud Code upstream.
13290
13728
 
13291
- ${pc17.bold("Examples:")}
13729
+ ${pc18.bold("Examples:")}
13292
13730
  anygate agy
13293
13731
  anygate agy --provider zen --model deepseek-v4-flash-free
13294
13732
  anygate agy -p "fix this bug"`;
13295
13733
  }
13296
13734
  function antigravityIdeHelpText() {
13297
- return `${pc17.bold("anygate antigravity-ide")} v${VERSION}
13735
+ return `${pc18.bold("anygate antigravity-ide")} v${VERSION}
13298
13736
  Launch Antigravity IDE with anygate provider registry.
13299
13737
 
13300
- ${pc17.bold("Usage:")}
13738
+ ${pc18.bold("Usage:")}
13301
13739
  anygate antigravity-ide [options]
13302
13740
  anygate antigravity-ide --help
13303
13741
  anygate antigravity-ide --version
13304
13742
 
13305
- ${pc17.bold("Options:")}
13743
+ ${pc18.bold("Options:")}
13306
13744
  --provider <id> Use a specific provider (skip picker)
13307
13745
  --model <id> Use a specific model (skip picker)
13308
13746
  --trace Write debug log to /tmp/anygate-debug.log
13309
13747
  -h, --help Show this help
13310
13748
  -v, --version Show version
13311
13749
 
13312
- ${pc17.bold("How it works:")}
13750
+ ${pc18.bold("How it works:")}
13313
13751
  Creates an isolated anygate-managed IDE profile, starts a local Cloud Code
13314
13752
  gateway, and injects anygate models into Antigravity's native picker.
13315
13753
  The normal IDE profile is never modified.
13316
13754
 
13317
- ${pc17.bold("Platform:")}
13755
+ ${pc18.bold("Platform:")}
13318
13756
  macOS (Apple Silicon) \u2014 other platforms coming after testing.
13319
13757
 
13320
- ${pc17.bold("Examples:")}
13758
+ ${pc18.bold("Examples:")}
13321
13759
  anygate antigravity-ide
13322
13760
  anygate antigravity-ide --provider zen --model deepseek-v4-flash-free`;
13323
13761
  }
13324
13762
  function antigravityAppHelpText() {
13325
- return `${pc17.bold("anygate antigravity")} v${VERSION}
13763
+ return `${pc18.bold("anygate antigravity")} v${VERSION}
13326
13764
  Launch Antigravity with anygate provider registry.
13327
13765
 
13328
- ${pc17.bold("Usage:")}
13766
+ ${pc18.bold("Usage:")}
13329
13767
  anygate antigravity [options]
13330
13768
  anygate antigravity --help
13331
13769
  anygate antigravity --version
13332
13770
 
13333
- ${pc17.bold("Options:")}
13771
+ ${pc18.bold("Options:")}
13334
13772
  --provider <id> Use a specific provider (skip picker)
13335
13773
  --model <id> Use a specific model (skip picker)
13336
13774
  --trace Write debug log to /tmp/anygate-debug.log
13337
13775
  -h, --help Show this help
13338
13776
  -v, --version Show version
13339
13777
 
13340
- ${pc17.bold("How it works:")}
13778
+ ${pc18.bold("How it works:")}
13341
13779
  Creates an isolated anygate-managed Antigravity profile, starts a local Cloud
13342
13780
  Code gateway, and injects anygate models into Antigravity's native picker.
13343
13781
  The normal Antigravity profile is never modified.
13344
13782
 
13345
- ${pc17.bold("Favorites:")}
13783
+ ${pc18.bold("Favorites:")}
13346
13784
  Uses the same Antigravity favorites list as anygate favorites --agy:
13347
13785
  up to six saved favorites plus the selected launch model.
13348
13786
 
13349
- ${pc17.bold("Platform:")}
13787
+ ${pc18.bold("Platform:")}
13350
13788
  macOS (Apple Silicon) \u2014 other platforms coming after testing.
13351
13789
 
13352
- ${pc17.bold("Examples:")}
13790
+ ${pc18.bold("Examples:")}
13353
13791
  anygate antigravity
13354
13792
  anygate antigravity --provider zen --model deepseek-v4-flash-free`;
13355
13793
  }
@@ -13367,7 +13805,7 @@ ${formatUpdateNotification(update.currentVersion, update.latestVersion)}
13367
13805
  else console.error(notice);
13368
13806
  }
13369
13807
  if (parsed.error) {
13370
- console.error(pc17.red(`
13808
+ console.error(pc18.red(`
13371
13809
  Error: ${parsed.error}
13372
13810
  `));
13373
13811
  printHelp(rootHelpText());
@@ -13386,10 +13824,13 @@ Error: ${parsed.error}
13386
13824
  }
13387
13825
  if (parsed.showVersion) {
13388
13826
  console.log(VERSION);
13389
- } else {
13827
+ return 0;
13828
+ }
13829
+ if (parsed.showHelp) {
13390
13830
  printHelp(rootHelpText());
13831
+ return 0;
13391
13832
  }
13392
- return 0;
13833
+ return dispatchCommand(parsed);
13393
13834
  }
13394
13835
  if (parsed.showVersion) {
13395
13836
  console.log(VERSION);
@@ -13436,7 +13877,7 @@ if (isCliEntryPoint()) {
13436
13877
  if (err === /* @__PURE__ */ Symbol.for("clack:cancel")) {
13437
13878
  process.exit(0);
13438
13879
  }
13439
- console.error(pc17.red("\nUnexpected error:"), err);
13880
+ console.error(pc18.red("\nUnexpected error:"), err);
13440
13881
  process.exit(1);
13441
13882
  });
13442
13883
  }