anygate 0.5.11 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/{chunk-6AFYEDSU.js → chunk-4N4RDHGZ.js} +21 -6
  2. package/dist/{chunk-6AFYEDSU.js.map → chunk-4N4RDHGZ.js.map} +1 -1
  3. package/dist/{chunk-55RHVPE4.js → chunk-BY4AKT2X.js} +1540 -829
  4. package/dist/chunk-BY4AKT2X.js.map +1 -0
  5. package/dist/{chunk-5UF4TVCM.js → chunk-UE2I2ETX.js} +25 -3
  6. package/dist/chunk-UE2I2ETX.js.map +1 -0
  7. package/dist/{chunk-72WNE2IK.js → chunk-UT3JLF3M.js} +2 -13
  8. package/dist/cli.js +1728 -680
  9. package/dist/cli.js.map +1 -1
  10. package/dist/{command-7AI36ICY.js → command-XIDZGWNR.js} +417 -108
  11. package/dist/command-XIDZGWNR.js.map +1 -0
  12. package/dist/{constants-HE3EOSMH.js → constants-WLMOLKEO.js} +9 -3
  13. package/dist/{provider-templates-MNJZTG3Z.js → provider-templates-336QE7ZV.js} +3 -3
  14. package/dist/registry/data/templates/agentrouter.json +19 -0
  15. package/dist/registry/data/templates/cohere.json +5 -2
  16. package/dist/registry/data/templates/fireworks.json +1 -1
  17. package/dist/registry/data/templates/sambanova.json +8 -7
  18. package/dist/ui/dist/assets/index-Bnth1xGD.js +7 -0
  19. package/dist/ui/dist/assets/index-bNoUNC_v.css +1 -0
  20. package/dist/ui/dist/index.html +2 -2
  21. package/package.json +110 -94
  22. package/dist/chunk-55RHVPE4.js.map +0 -1
  23. package/dist/chunk-5UF4TVCM.js.map +0 -1
  24. package/dist/command-7AI36ICY.js.map +0 -1
  25. package/dist/ui/dist/assets/index-DWAOH_B3.css +0 -1
  26. package/dist/ui/dist/assets/index-qxVU3kMy.js +0 -6
  27. /package/dist/{chunk-72WNE2IK.js.map → chunk-UT3JLF3M.js.map} +0 -0
  28. /package/dist/{constants-HE3EOSMH.js.map → constants-WLMOLKEO.js.map} +0 -0
  29. /package/dist/{provider-templates-MNJZTG3Z.js.map → provider-templates-336QE7ZV.js.map} +0 -0
package/dist/cli.js CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  buildClaudeCodeBillingSystemLine,
20
20
  buildCodexAppRootConfig,
21
21
  buildImportProviderList,
22
+ buildProviderAllModelRoutes,
22
23
  buildVertexRuntimeConfig,
23
24
  cachedModelToLocal,
24
25
  catalogEntryFromModel,
@@ -69,8 +70,6 @@ import {
69
70
  getValidationStatus,
70
71
  grabRoundTripSignature,
71
72
  hasApplicationDefaultCredentials,
72
- init_config,
73
- init_paths,
74
73
  injectClaudeIdentity,
75
74
  isClaudeAppRunning,
76
75
  isCodexAppRunning,
@@ -173,7 +172,7 @@ import {
173
172
  validateModels,
174
173
  writeSecureLogLine,
175
174
  zenRegistryStub
176
- } from "./chunk-55RHVPE4.js";
175
+ } from "./chunk-BY4AKT2X.js";
177
176
  import {
178
177
  BACKENDS,
179
178
  CONFLICTING_ENV_VARS,
@@ -181,15 +180,15 @@ import {
181
180
  MAX_MODEL_CATALOG,
182
181
  VERSION,
183
182
  VERTEX_ANTHROPIC_NPM
184
- } from "./chunk-5UF4TVCM.js";
183
+ } from "./chunk-UE2I2ETX.js";
185
184
  import {
186
185
  filterTemplates,
187
186
  getTemplateById,
188
187
  listAddableTemplates,
189
188
  listSupportedTemplates,
190
189
  listVisibleOAuthTemplates
191
- } from "./chunk-6AFYEDSU.js";
192
- import "./chunk-72WNE2IK.js";
190
+ } from "./chunk-4N4RDHGZ.js";
191
+ import "./chunk-UT3JLF3M.js";
193
192
 
194
193
  // src/cli.ts
195
194
  import pc18 from "picocolors";
@@ -200,8 +199,6 @@ import { fileURLToPath } from "url";
200
199
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
201
200
  import { homedir } from "os";
202
201
  import { join } from "path";
203
- init_config();
204
- init_paths();
205
202
  var SKILL_DIR_NAME = "anygate-cli";
206
203
  var SKILL_INSTALL_DIRS = [
207
204
  join(getAppHome(), "skills"),
@@ -242,7 +239,8 @@ function skillInstallTargets() {
242
239
  }
243
240
  function formatProviderModels(provider) {
244
241
  const models = provider.modelsCache?.models ?? [];
245
- if (models.length === 0) return ` (no cached models \u2014 run: anygate providers refresh-models ${provider.id})`;
242
+ if (models.length === 0)
243
+ return ` (no cached models \u2014 run: anygate providers refresh-models ${provider.id})`;
246
244
  const lines = models.slice(0, 40).map((m) => ` ${m.id}${m.name !== m.id ? ` (${m.name})` : ""}`);
247
245
  if (models.length > 40) lines.push(` ... and ${models.length - 40} more`);
248
246
  return lines.join("\n");
@@ -253,13 +251,19 @@ function buildLiveStateSection() {
253
251
  const enabled = registry.providers.filter((p18) => p18.enabled);
254
252
  const prefLines = [];
255
253
  if (prefs.lastProvider || prefs.lastModel) {
256
- prefLines.push(` Claude last launch: provider=${prefs.lastProvider ?? "(none)"} model=${prefs.lastModel ?? "(none)"}`);
254
+ prefLines.push(
255
+ ` Claude last launch: provider=${prefs.lastProvider ?? "(none)"} model=${prefs.lastModel ?? "(none)"}`
256
+ );
257
257
  }
258
258
  if (prefs.lastCodexProvider || prefs.lastCodexModel) {
259
- prefLines.push(` Codex last launch: provider=${prefs.lastCodexProvider ?? "(none)"} model=${prefs.lastCodexModel ?? "(none)"}`);
259
+ prefLines.push(
260
+ ` Codex last launch: provider=${prefs.lastCodexProvider ?? "(none)"} model=${prefs.lastCodexModel ?? "(none)"}`
261
+ );
260
262
  }
261
263
  if (prefs.lastGeminiProvider || prefs.lastGeminiModel) {
262
- prefLines.push(` Gemini last launch: provider=${prefs.lastGeminiProvider ?? "(none)"} model=${prefs.lastGeminiModel ?? "(none)"}`);
264
+ prefLines.push(
265
+ ` Gemini last launch: provider=${prefs.lastGeminiProvider ?? "(none)"} model=${prefs.lastGeminiModel ?? "(none)"}`
266
+ );
263
267
  }
264
268
  if (prefs.favoriteModels?.length) {
265
269
  prefLines.push(` Favorites (${prefs.favoriteModels.length}/${MAX_MODEL_CATALOG}):`);
@@ -267,10 +271,12 @@ function buildLiveStateSection() {
267
271
  prefLines.push(` ${f.providerId} / ${f.modelId}`);
268
272
  }
269
273
  }
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)
273
- ].join("\n"));
274
+ const providerBlocks = enabled.length === 0 ? [" No registry providers configured. Built-in cloud: zen, go (OpenCode Zen/Go)."] : enabled.map(
275
+ (p18) => [
276
+ ` ${p18.name} (${p18.id}) \u2014 ${p18.modelsCache?.models.length ?? 0} cached model(s)`,
277
+ formatProviderModels(p18)
278
+ ].join("\n")
279
+ );
274
280
  return `
275
281
  ================================================================================
276
282
  CURRENT LOCAL STATE (from disk \u2014 no network)
@@ -770,7 +776,9 @@ import * as p from "@clack/prompts";
770
776
  import open from "open";
771
777
  var ONBOARDING_TEMPLATES = ["kilo", "nvidia", "groq", "mistral", "cerebras"];
772
778
  function categorizeOnboardingProviders() {
773
- const templates = ONBOARDING_TEMPLATES.map((id) => getTemplateById(id)).filter((t) => t !== void 0 && t.supported);
779
+ const templates = ONBOARDING_TEMPLATES.map((id) => getTemplateById(id)).filter(
780
+ (t) => t !== void 0 && t.supported
781
+ );
774
782
  const keyless = [];
775
783
  const apiKeyRequired = [];
776
784
  for (const t of templates) {
@@ -800,7 +808,7 @@ async function handleKeylessProvider(template) {
800
808
  }
801
809
  async function handleApiKeyProvider(template) {
802
810
  const signupUrl = template.signupUrl ?? "https://opencode.ai/auth";
803
- printApiKeyProviderPanel(template.name, signupUrl);
811
+ printApiKeyProviderPanel(template.name, signupUrl, template.signupNote);
804
812
  let choice = await p.select({
805
813
  message: `How would you like to set up ${template.name}?`,
806
814
  options: [
@@ -812,7 +820,7 @@ async function handleApiKeyProvider(template) {
812
820
  {
813
821
  value: "signup",
814
822
  label: pc.cyan("Open signup page in browser"),
815
- hint: `Free tier at ${signupUrl}`
823
+ hint: template.signupNote ?? `Free tier at ${signupUrl}`
816
824
  },
817
825
  {
818
826
  value: "skip",
@@ -1032,28 +1040,27 @@ async function runMainMenu() {
1032
1040
  switch (choice) {
1033
1041
  case "claude":
1034
1042
  gateOutro("Launching Claude Code...");
1035
- return 0;
1036
- // The actual launch is handled by the claude command
1043
+ return dispatchCommand({ command: "claude", claudeArgs: [] });
1037
1044
  case "codex":
1038
1045
  gateOutro("Launching Codex...");
1039
- return 0;
1046
+ return dispatchCommand({ command: "codex", claudeArgs: [] });
1040
1047
  case "providers":
1041
1048
  gateOutro("Opening provider manager...");
1042
- return 0;
1049
+ return dispatchCommand({ command: "providers", claudeArgs: [] });
1043
1050
  case "onboarding":
1044
1051
  return runOnboardingFlow();
1045
1052
  case "doctor":
1046
1053
  gateOutro("Running diagnostics...");
1047
- return 0;
1054
+ return dispatchCommand({ command: "doctor", claudeArgs: [] });
1048
1055
  case "server":
1049
1056
  gateOutro("Starting server...");
1050
- return 0;
1057
+ return dispatchCommand({ command: "server", claudeArgs: [] });
1051
1058
  case "ui":
1052
1059
  gateOutro("Opening dashboard...");
1053
- return 0;
1060
+ return dispatchCommand({ command: "ui", claudeArgs: [] });
1054
1061
  case "settings":
1055
1062
  gateOutro("Opening settings...");
1056
- return 0;
1063
+ return dispatchCommand({ command: "providers", claudeArgs: [] });
1057
1064
  default:
1058
1065
  return 0;
1059
1066
  }
@@ -1122,7 +1129,10 @@ async function validateImportKey(lp, entry) {
1122
1129
  allowInsecureLocal: catalogTemplate?.apiKeyOptional === true
1123
1130
  });
1124
1131
  if (!urlCheck.ok || !urlCheck.normalizedUrl) {
1125
- return reject("invalid-key", `${urlCheck.error ?? "Invalid API base URL."} ${urlCheck.hint ?? ""}`.trim());
1132
+ return reject(
1133
+ "invalid-key",
1134
+ `${urlCheck.error ?? "Invalid API base URL."} ${urlCheck.hint ?? ""}`.trim()
1135
+ );
1126
1136
  }
1127
1137
  safeBaseUrl = urlCheck.normalizedUrl;
1128
1138
  }
@@ -1200,7 +1210,10 @@ async function importFromOpencode(options = {}) {
1200
1210
  continue;
1201
1211
  }
1202
1212
  const isOAuth = isOAuthImportProvider(lp.id, oauth);
1203
- const entry = localProviderToRegistry(lp, isOAuth ? { authType: "oauth", authRef: oauthAuthRef(lp.id) } : void 0);
1213
+ const entry = localProviderToRegistry(
1214
+ lp,
1215
+ isOAuth ? { authType: "oauth", authRef: oauthAuthRef(lp.id) } : void 0
1216
+ );
1204
1217
  if (!entry) {
1205
1218
  skipped.push({
1206
1219
  id: lp.id,
@@ -1233,7 +1246,9 @@ async function importFromOpencode(options = {}) {
1233
1246
  existing,
1234
1247
  incoming: entry,
1235
1248
  incomingProvider: lp,
1236
- existingKeyHint: await keyHint(existing.id, existing.authRef, { oauth: existing.authType === "oauth" }),
1249
+ existingKeyHint: await keyHint(existing.id, existing.authRef, {
1250
+ oauth: existing.authType === "oauth"
1251
+ }),
1237
1252
  incomingKeyHint: await keyHint(entry.id, entry.authRef, {
1238
1253
  fallbackKey: lp.apiKey,
1239
1254
  oauth: isOAuth
@@ -1254,7 +1269,10 @@ async function importFromOpencode(options = {}) {
1254
1269
  continue;
1255
1270
  }
1256
1271
  if (existingIdx >= 0) {
1257
- registry.providers[existingIdx] = { ...entry, addedAt: registry.providers[existingIdx].addedAt };
1272
+ registry.providers[existingIdx] = {
1273
+ ...entry,
1274
+ addedAt: registry.providers[existingIdx].addedAt
1275
+ };
1258
1276
  } else {
1259
1277
  registry.providers.push(entry);
1260
1278
  }
@@ -1295,7 +1313,8 @@ function detectShellProfile() {
1295
1313
  const shell = process.env["SHELL"] ?? "";
1296
1314
  if (process.platform === "darwin") {
1297
1315
  if (shell.includes("zsh")) return { display: "~/.zshrc", path: `${homedir2()}/.zshrc` };
1298
- if (shell.includes("bash")) return { display: "~/.bash_profile", path: `${homedir2()}/.bash_profile` };
1316
+ if (shell.includes("bash"))
1317
+ return { display: "~/.bash_profile", path: `${homedir2()}/.bash_profile` };
1299
1318
  return { display: "~/.profile", path: `${homedir2()}/.profile` };
1300
1319
  }
1301
1320
  if (process.platform === "linux") {
@@ -1350,28 +1369,70 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1350
1369
  const saveOptions = (() => {
1351
1370
  if (isMac) {
1352
1371
  return [
1353
- { value: "keychain", label: "Keychain only", hint: "Key stored encrypted in Keychain; anygate reads it automatically next time" },
1354
- { value: "keychain-autoload", label: `Keychain + ${display} auto-load`, hint: `Key in Keychain; ${display} also exports it so all terminal tools can see it` },
1355
- { value: "profile", label: `${display} only (plaintext)`, hint: "Key written directly to your shell profile \u2014 simpler but less secure" },
1356
- { value: "session", label: "This session only", hint: "Not saved anywhere \u2014 you'll be asked again next time" }
1372
+ {
1373
+ value: "keychain",
1374
+ label: "Keychain only",
1375
+ hint: "Key stored encrypted in Keychain; anygate reads it automatically next time"
1376
+ },
1377
+ {
1378
+ value: "keychain-autoload",
1379
+ label: `Keychain + ${display} auto-load`,
1380
+ hint: `Key in Keychain; ${display} also exports it so all terminal tools can see it`
1381
+ },
1382
+ {
1383
+ value: "profile",
1384
+ label: `${display} only (plaintext)`,
1385
+ hint: "Key written directly to your shell profile \u2014 simpler but less secure"
1386
+ },
1387
+ {
1388
+ value: "session",
1389
+ label: "This session only",
1390
+ hint: "Not saved anywhere \u2014 you'll be asked again next time"
1391
+ }
1357
1392
  ];
1358
1393
  }
1359
1394
  if (isWindows4) {
1360
1395
  return [
1361
- { value: "credential-manager", label: "Windows Credential Manager", hint: "Key stored securely; anygate reads it automatically next time" },
1362
- { value: "setx", label: "Persistent environment variable (plaintext)", hint: "Runs setx \u2014 key visible in System Properties \u2192 Environment Variables" },
1363
- { value: "session", label: "This session only", hint: "Not saved anywhere \u2014 you'll be asked again next time" }
1396
+ {
1397
+ value: "credential-manager",
1398
+ label: "Windows Credential Manager",
1399
+ hint: "Key stored securely; anygate reads it automatically next time"
1400
+ },
1401
+ {
1402
+ value: "setx",
1403
+ label: "Persistent environment variable (plaintext)",
1404
+ hint: "Runs setx \u2014 key visible in System Properties \u2192 Environment Variables"
1405
+ },
1406
+ {
1407
+ value: "session",
1408
+ label: "This session only",
1409
+ hint: "Not saved anywhere \u2014 you'll be asked again next time"
1410
+ }
1364
1411
  ];
1365
1412
  }
1366
1413
  const opts = [];
1367
1414
  if (secretServiceAvailable) {
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" });
1415
+ opts.push({
1416
+ value: "secret-service",
1417
+ label: "Secret Service (GNOME Keyring / KWallet)",
1418
+ hint: "Key stored securely in your desktop keyring; anygate reads it automatically next time"
1419
+ });
1369
1420
  } else if (!simulate) {
1370
- p2.log.info("No keyring daemon detected \u2014 secure storage requires GNOME Keyring or KWallet running.");
1421
+ p2.log.info(
1422
+ "No keyring daemon detected \u2014 secure storage requires GNOME Keyring or KWallet running."
1423
+ );
1371
1424
  }
1372
1425
  opts.push(
1373
- { value: "profile", label: `${display} (plaintext)`, hint: "Key written directly to your shell profile" },
1374
- { value: "session", label: "This session only", hint: "Not saved anywhere \u2014 you'll be asked again next time" }
1426
+ {
1427
+ value: "profile",
1428
+ label: `${display} (plaintext)`,
1429
+ hint: "Key written directly to your shell profile"
1430
+ },
1431
+ {
1432
+ value: "session",
1433
+ label: "This session only",
1434
+ hint: "Not saved anywhere \u2014 you'll be asked again next time"
1435
+ }
1375
1436
  );
1376
1437
  return opts;
1377
1438
  })();
@@ -1412,7 +1473,9 @@ async function resolveOrCollectApiKey(simulate = false, trace = false) {
1412
1473
  ${autoLoadLine}
1413
1474
  `);
1414
1475
  }
1415
- p2.log.success(`Key saved to Keychain and auto-load added to ${display} \u2014 active now and in all future terminals.`);
1476
+ p2.log.success(
1477
+ `Key saved to Keychain and auto-load added to ${display} \u2014 active now and in all future terminals.`
1478
+ );
1416
1479
  } catch {
1417
1480
  p2.log.success("Key saved to Keychain \u2014 active now and automatically loaded next time.");
1418
1481
  p2.log.warn(`Could not write auto-load line to ${display}`);
@@ -1422,15 +1485,21 @@ ${autoLoadLine}
1422
1485
  }
1423
1486
  } else if (saveChoice === "credential-manager") {
1424
1487
  if (await saveToCredentialStore(trimmedKey)) {
1425
- p2.log.success("Key saved to Windows Credential Manager \u2014 active now and automatically loaded next time.");
1488
+ p2.log.success(
1489
+ "Key saved to Windows Credential Manager \u2014 active now and automatically loaded next time."
1490
+ );
1426
1491
  } else {
1427
1492
  p2.log.warn("Could not write to Credential Manager \u2014 key will be used for this session only");
1428
1493
  }
1429
1494
  } else if (saveChoice === "setx") {
1430
1495
  try {
1431
- const result = spawnSync("setx", ["OPENCODE_API_KEY", trimmedKey], { stdio: ["pipe", "pipe", "pipe"] });
1496
+ const result = spawnSync("setx", ["OPENCODE_API_KEY", trimmedKey], {
1497
+ stdio: ["pipe", "pipe", "pipe"]
1498
+ });
1432
1499
  if (result.status !== 0) throw new Error("setx exited with non-zero status");
1433
- p2.log.success("Key saved as a user environment variable \u2014 active now and in all future terminals.");
1500
+ p2.log.success(
1501
+ "Key saved as a user environment variable \u2014 active now and in all future terminals."
1502
+ );
1434
1503
  } catch {
1435
1504
  p2.log.warn("Could not run setx \u2014 key will be used for this session only");
1436
1505
  }
@@ -1534,7 +1603,9 @@ async function runFirstRunWizard(trace = false) {
1534
1603
  return runFirstRunWizard(trace);
1535
1604
  }
1536
1605
  if (result.imported.length === 0) {
1537
- p3.log.warn("No providers imported. Configure providers in OpenCode first, or use Quick start with Zen.");
1606
+ p3.log.warn(
1607
+ "No providers imported. Configure providers in OpenCode first, or use Quick start with Zen."
1608
+ );
1538
1609
  return runFirstRunWizard(trace);
1539
1610
  }
1540
1611
  p3.log.success(
@@ -1545,9 +1616,6 @@ async function runFirstRunWizard(trace = false) {
1545
1616
  return "continue";
1546
1617
  }
1547
1618
 
1548
- // src/cli/claude.ts
1549
- init_config();
1550
-
1551
1619
  // src/apps/shared/prompts.ts
1552
1620
  import * as p4 from "@clack/prompts";
1553
1621
  import pc3 from "picocolors";
@@ -1565,23 +1633,32 @@ function scoreModelSearch(query, fields) {
1565
1633
  return { normalized, compact: normalized.replace(/\s+/g, ""), weight: field.weight };
1566
1634
  });
1567
1635
  const tokens = normalizedQuery.split(" ").filter(Boolean);
1568
- if (!tokens.every((token) => searchableFields.some((field) => field.normalized.includes(token) || field.compact.includes(token)))) {
1636
+ if (!tokens.every(
1637
+ (token) => searchableFields.some(
1638
+ (field) => field.normalized.includes(token) || field.compact.includes(token)
1639
+ )
1640
+ )) {
1569
1641
  return 0;
1570
1642
  }
1571
1643
  let score = 1;
1572
1644
  for (const field of searchableFields) {
1573
1645
  if (field.normalized === normalizedQuery) score = Math.max(score, field.weight + 300);
1574
1646
  else if (field.compact === compactQuery) score = Math.max(score, field.weight + 260);
1575
- else if (field.normalized.startsWith(normalizedQuery)) score = Math.max(score, field.weight + 180);
1647
+ else if (field.normalized.startsWith(normalizedQuery))
1648
+ score = Math.max(score, field.weight + 180);
1576
1649
  else if (field.compact.startsWith(compactQuery)) score = Math.max(score, field.weight + 150);
1577
1650
  else if (field.normalized.includes(normalizedQuery)) score = Math.max(score, field.weight + 90);
1578
1651
  else if (field.compact.includes(compactQuery)) score = Math.max(score, field.weight + 70);
1579
1652
  }
1580
- return score + tokens.reduce((sum, token) => sum + searchableFields.reduce((best, field) => {
1581
- if (field.normalized.split(" ").includes(token)) return Math.max(best, 30);
1582
- if (field.normalized.includes(token) || field.compact.includes(token)) return Math.max(best, 12);
1583
- return best;
1584
- }, 0), 0);
1653
+ return score + tokens.reduce(
1654
+ (sum, token) => sum + searchableFields.reduce((best, field) => {
1655
+ if (field.normalized.split(" ").includes(token)) return Math.max(best, 30);
1656
+ if (field.normalized.includes(token) || field.compact.includes(token))
1657
+ return Math.max(best, 12);
1658
+ return best;
1659
+ }, 0),
1660
+ 0
1661
+ );
1585
1662
  }
1586
1663
 
1587
1664
  // src/apps/shared/prompts.ts
@@ -1687,7 +1764,11 @@ async function selectLargeCatalog(models, browseList, toOption, message, initial
1687
1764
  const method = await p4.select({
1688
1765
  message: `${message} (${models.length} available)`,
1689
1766
  options: [
1690
- { value: MODE_SEARCH, label: pc3.cyan("Search models"), hint: "Filter by name, id, or brand" },
1767
+ {
1768
+ value: MODE_SEARCH,
1769
+ label: pc3.cyan("Search models"),
1770
+ hint: "Filter by name, id, or brand"
1771
+ },
1691
1772
  {
1692
1773
  value: MODE_BROWSE,
1693
1774
  label: pc3.cyan("Browse all models"),
@@ -1703,13 +1784,9 @@ async function selectLargeCatalog(models, browseList, toOption, message, initial
1703
1784
  continue;
1704
1785
  }
1705
1786
  if (mode === "browse") {
1706
- const picked = await pickModelFromPagedList(
1707
- browseList,
1708
- toOption,
1709
- message,
1710
- initialModelId,
1711
- { search: true }
1712
- );
1787
+ const picked = await pickModelFromPagedList(browseList, toOption, message, initialModelId, {
1788
+ search: true
1789
+ });
1713
1790
  if (picked === "search") {
1714
1791
  mode = "search";
1715
1792
  continue;
@@ -1757,10 +1834,7 @@ async function selectModelWithSearch(models, toOption, message, initialModelId,
1757
1834
  if (models.length === 0) return null;
1758
1835
  const orderedBrowse = browseList ?? sortModelsByBrand(models);
1759
1836
  if (models.length <= MODEL_SEARCH_THRESHOLD) {
1760
- const options = [
1761
- ...models.map(toOption),
1762
- navOption("__back__", "\u2190 Go back", "")
1763
- ];
1837
+ const options = [...models.map(toOption), navOption("__back__", "\u2190 Go back", "")];
1764
1838
  const initialValue = initialModelId && options.some((o) => o.value === initialModelId) ? initialModelId : options[0]?.value;
1765
1839
  const picked = await p4.select({
1766
1840
  message,
@@ -1908,7 +1982,8 @@ function isGeminiNonInteractive(args) {
1908
1982
  for (let i = 0; i < args.length; i++) {
1909
1983
  const arg = args[i];
1910
1984
  if (arg === "--") return false;
1911
- if (arg === "-p" || arg === "--prompt" || arg === "-i" || arg === "--prompt-interactive") return true;
1985
+ if (arg === "-p" || arg === "--prompt" || arg === "-i" || arg === "--prompt-interactive")
1986
+ return true;
1912
1987
  if (arg.startsWith("-")) {
1913
1988
  i = skipAttachedFlagValue(args, i);
1914
1989
  continue;
@@ -1956,6 +2031,10 @@ function resolveLaunchTarget(explicit, prefs, agent) {
1956
2031
  const slug = explicit.modelId ? parseModelSlug(explicit.modelId) : null;
1957
2032
  const providerId = explicit.providerId ?? slug?.providerId ?? (agent === "claude" ? prefs.lastProvider : agent === "codex" ? prefs.lastCodexProvider : agent === "antigravity" ? prefs.lastAntigravityProvider : prefs.lastGeminiProvider);
1958
2033
  const modelId = slug?.modelId ?? explicit.modelId ?? (agent === "claude" ? prefs.lastModel : agent === "codex" ? prefs.lastCodexModel : agent === "antigravity" ? prefs.lastAntigravityModel : prefs.lastGeminiModel);
2034
+ if (explicit.allModels) {
2035
+ if (!providerId) return null;
2036
+ return { providerId, allModels: true };
2037
+ }
1959
2038
  if (!providerId || !modelId) return null;
1960
2039
  return { providerId, modelId };
1961
2040
  }
@@ -1968,6 +2047,7 @@ function findProviderAndModel(providers, target) {
1968
2047
  return { provider, model };
1969
2048
  }
1970
2049
  function hasCompleteExplicitLaunch(explicit) {
2050
+ if (explicit.allModels && explicit.providerId) return true;
1971
2051
  if (explicit.providerId && explicit.modelId) return true;
1972
2052
  if (explicit.modelId) {
1973
2053
  const slug = parseModelSlug(explicit.modelId);
@@ -1985,16 +2065,16 @@ function planLaunchWizard(opts) {
1985
2065
  return {
1986
2066
  skip: false,
1987
2067
  target: null,
1988
- error: "Both --provider and --model are required (or use provider__model slug with --model)."
2068
+ error: "A provider is required \u2014 use --provider, --all-models, or a saved preference."
1989
2069
  };
1990
2070
  }
1991
2071
  return { skip: true, target };
1992
2072
  }
1993
- if (explicit.providerId || explicit.modelId) {
2073
+ if (explicit.providerId || explicit.modelId || explicit.allModels) {
1994
2074
  return {
1995
2075
  skip: false,
1996
2076
  target: null,
1997
- error: "Both --provider and --model are required (or use provider__model slug with --model)."
2077
+ error: explicit.allModels ? "Use --all-models with --provider to launch every model from a provider." : "Both --provider and --model are required (or use provider__model slug with --model)."
1998
2078
  };
1999
2079
  }
2000
2080
  if (nonInteractive) {
@@ -2011,9 +2091,12 @@ function planLaunchWizard(opts) {
2011
2091
  return { skip: false, target: null };
2012
2092
  }
2013
2093
  function nonInteractiveLaunchError(agent) {
2014
- if (agent === "claude") return "Print mode requires --provider and --model, or saved preferences from a prior launch.";
2015
- if (agent === "codex") return "Non-interactive Codex launch requires --provider and --model, or saved preferences from a prior launch.";
2016
- if (agent === "antigravity") return "Non-interactive Antigravity launch requires --provider and --model, or saved preferences from a prior launch.";
2094
+ if (agent === "claude")
2095
+ return "Print mode requires --provider and --model, or saved preferences from a prior launch.";
2096
+ if (agent === "codex")
2097
+ return "Non-interactive Codex launch requires --provider and --model, or saved preferences from a prior launch.";
2098
+ if (agent === "antigravity")
2099
+ return "Non-interactive Antigravity launch requires --provider and --model, or saved preferences from a prior launch.";
2017
2100
  return "Non-interactive Gemini launch requires --provider and --model, or saved preferences from a prior launch.";
2018
2101
  }
2019
2102
  function isAntigravityNonInteractive(args) {
@@ -2027,7 +2110,6 @@ function isAntigravityNonInteractive(args) {
2027
2110
  // src/cli/providers-command.ts
2028
2111
  import pc4 from "picocolors";
2029
2112
  import * as p5 from "@clack/prompts";
2030
- init_config();
2031
2113
  function providerHubChoiceValue(entry) {
2032
2114
  return `provider:${entry.id}`;
2033
2115
  }
@@ -2039,8 +2121,16 @@ async function runProvidersImport() {
2039
2121
  const choice = await p5.select({
2040
2122
  message: "Which configuration should we keep?",
2041
2123
  options: [
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" },
2124
+ {
2125
+ value: "keep",
2126
+ label: pc4.cyan("Keep mine"),
2127
+ hint: "Leave your current anygate config unchanged"
2128
+ },
2129
+ {
2130
+ value: "import",
2131
+ label: pc4.cyan("Use imported"),
2132
+ hint: "Replace with OpenCode settings and refresh models"
2133
+ },
2044
2134
  { value: "skip", label: pc4.dim("Skip this provider"), hint: "" }
2045
2135
  ]
2046
2136
  });
@@ -2183,7 +2273,9 @@ async function runProvidersRefreshModels(providerId) {
2183
2273
  }
2184
2274
  const diff = result.previousModelCount === void 0 ? 0 : (result.modelCount ?? 0) - result.previousModelCount;
2185
2275
  const diffStr = result.previousModelCount === void 0 ? "" : diff > 0 ? ` (+${diff})` : diff < 0 ? ` (${diff})` : "";
2186
- p5.log.success(`${result.name}: ${result.modelCount} model${result.modelCount === 1 ? "" : "s"} updated${diffStr}.`);
2276
+ p5.log.success(
2277
+ `${result.name}: ${result.modelCount} model${result.modelCount === 1 ? "" : "s"} updated${diffStr}.`
2278
+ );
2187
2279
  if (result.reason) {
2188
2280
  p5.log.warn(result.reason);
2189
2281
  }
@@ -2251,7 +2343,9 @@ async function pickTemplateFromCatalog() {
2251
2343
  const query = String(searchInput);
2252
2344
  const matched = filterTemplates(templates, query);
2253
2345
  if (matched.length === 0) {
2254
- const alreadyAdded = filterTemplates(listSupportedTemplates(), query).filter((t) => configuredIds.has(t.id));
2346
+ const alreadyAdded = filterTemplates(listSupportedTemplates(), query).filter(
2347
+ (t) => configuredIds.has(t.id)
2348
+ );
2255
2349
  if (alreadyAdded.length > 0) {
2256
2350
  p5.log.info(`Already configured: ${alreadyAdded.map((t) => t.name).join(", ")}`);
2257
2351
  } else {
@@ -2275,7 +2369,9 @@ async function pickTemplateFromCatalog() {
2275
2369
  }
2276
2370
  async function runOpenCodeCloudDetail() {
2277
2371
  const registry = loadRegistry();
2278
- const routes = registry.providers.filter((provider) => provider.id === "zen" || provider.id === "go");
2372
+ const routes = registry.providers.filter(
2373
+ (provider) => provider.id === "zen" || provider.id === "go"
2374
+ );
2279
2375
  printCloudProviderPanel("OpenCode Zen / Go");
2280
2376
  if (routes.length === 0) return "back";
2281
2377
  const choice = await p5.select({
@@ -2327,7 +2423,11 @@ async function runProviderDetail(id) {
2327
2423
  label: provider.enabled ? "Disable provider" : "Enable provider",
2328
2424
  hint: provider.enabled ? "Hide from anygate claude picker" : "Show in anygate claude picker"
2329
2425
  },
2330
- { value: "remove", label: "Remove provider", hint: "Delete from registry and Keychain when safe" },
2426
+ {
2427
+ value: "remove",
2428
+ label: "Remove provider",
2429
+ hint: "Delete from registry and Keychain when safe"
2430
+ },
2331
2431
  { value: "back", label: "Back", hint: "" }
2332
2432
  );
2333
2433
  const action = await p5.select({
@@ -2380,7 +2480,8 @@ function parseProvidersArgs(args) {
2380
2480
  if (first === "list") return { subcommand: "list", showHelp: false };
2381
2481
  if (first === "remove" || first === "rm") {
2382
2482
  const targetId = args[1];
2383
- if (!targetId) return { subcommand: "remove", showHelp: true, error: "Usage: anygate providers remove <id>" };
2483
+ if (!targetId)
2484
+ return { subcommand: "remove", showHelp: true, error: "Usage: anygate providers remove <id>" };
2384
2485
  return { subcommand: "remove", showHelp: false, removeId: targetId };
2385
2486
  }
2386
2487
  if (first === "refresh-models") {
@@ -2408,6 +2509,36 @@ ${pc4.bold("Usage:")}
2408
2509
  anygate providers refresh-models Refresh model catalog for all/specific provider
2409
2510
  anygate providers auth <id> Sign in with OAuth (xAI, OpenAI, GitHub Copilot, \u2026)`;
2410
2511
  }
2512
+ async function promptTemplateBaseUrl(template) {
2513
+ const entered = await p5.text({
2514
+ message: template.urlPrompt ?? "API Base URL:",
2515
+ placeholder: template.urlPlaceholder ?? template.defaultBaseUrl,
2516
+ defaultValue: template.defaultBaseUrl ?? "",
2517
+ validate: (v) => v.trim() || template.defaultBaseUrl ? void 0 : "URL is required"
2518
+ });
2519
+ if (p5.isCancel(entered)) return null;
2520
+ const baseUrl = String(entered ?? "").trim() || (template.defaultBaseUrl ?? "");
2521
+ if (!baseUrl) return null;
2522
+ let allowInsecureLocal = false;
2523
+ if (/^http:\/\//i.test(baseUrl)) {
2524
+ p5.log.warn(
2525
+ "HTTP is not encrypted. Only use it for a trusted local or LAN server, like Ollama on your own network."
2526
+ );
2527
+ const allowLocal = await p5.confirm({
2528
+ message: "Allow insecure HTTP for this local/LAN server?",
2529
+ initialValue: true
2530
+ });
2531
+ if (p5.isCancel(allowLocal)) return null;
2532
+ allowInsecureLocal = allowLocal === true;
2533
+ }
2534
+ const valid = await validateCustomEndpointUrl(baseUrl, { allowInsecureLocal });
2535
+ if (!valid.ok || !valid.normalizedUrl) {
2536
+ p5.log.error(valid.error ?? "Invalid URL.");
2537
+ if (valid.hint) p5.log.info(valid.hint);
2538
+ return null;
2539
+ }
2540
+ return valid.normalizedUrl;
2541
+ }
2411
2542
  async function runTemplateAddFlow(t) {
2412
2543
  const template = t ?? await pickTemplateFromCatalog();
2413
2544
  if (!template) return 0;
@@ -2416,9 +2547,16 @@ async function runTemplateAddFlow(t) {
2416
2547
  });
2417
2548
  if (p5.isCancel(inputKey)) return 0;
2418
2549
  const apiKey = String(inputKey ?? "").trim();
2419
- const result = await addProviderFromTemplate(template, apiKey);
2550
+ let baseUrl;
2551
+ if (template.urlPrompt) {
2552
+ const collected = await promptTemplateBaseUrl(template);
2553
+ if (!collected) return 1;
2554
+ baseUrl = collected;
2555
+ }
2556
+ const result = await addProviderFromTemplate(template, apiKey, { baseUrl });
2420
2557
  if (!result.added) {
2421
2558
  if (result.error) p5.log.error(result.error);
2559
+ if (result.hint) p5.log.info(result.hint);
2422
2560
  return 1;
2423
2561
  }
2424
2562
  logConnected(template.name, result.modelCount ?? 0);
@@ -2457,7 +2595,9 @@ async function runCustomEndpointAddFlow() {
2457
2595
  const usesHttp = /^http:\/\//i.test(String(baseUrl).trim());
2458
2596
  let allowInsecureHttp = false;
2459
2597
  if (usesHttp) {
2460
- p5.log.warn("HTTP is not encrypted. Only use it for a trusted local or LAN server, like Ollama on your own network.");
2598
+ p5.log.warn(
2599
+ "HTTP is not encrypted. Only use it for a trusted local or LAN server, like Ollama on your own network."
2600
+ );
2461
2601
  const allowLocal = await p5.confirm({
2462
2602
  message: "Allow insecure HTTP for this local/LAN server?",
2463
2603
  initialValue: true
@@ -2567,12 +2707,24 @@ async function runProvidersHub() {
2567
2707
  hint
2568
2708
  });
2569
2709
  }
2570
- options.push({ value: "auth-menu", label: "\u2192 Sign in with OAuth", hint: "GitHub Copilot \xB7 xAI \xB7 OpenAI" });
2710
+ options.push({
2711
+ value: "auth-menu",
2712
+ label: "\u2192 Sign in with OAuth",
2713
+ hint: "GitHub Copilot \xB7 xAI \xB7 OpenAI"
2714
+ });
2571
2715
  if (entries.length > 0) {
2572
- options.push({ value: "refresh-all", label: "\u21BA Refresh all models", hint: "Update model lists for all providers" });
2716
+ options.push({
2717
+ value: "refresh-all",
2718
+ label: "\u21BA Refresh all models",
2719
+ hint: "Update model lists for all providers"
2720
+ });
2573
2721
  }
2574
2722
  if (hasOpencode) {
2575
- options.push({ value: "import", label: "\u2192 Import providers from OpenCode CLI", hint: "One-time import" });
2723
+ options.push({
2724
+ value: "import",
2725
+ label: "\u2192 Import providers from OpenCode CLI",
2726
+ hint: "One-time import"
2727
+ });
2576
2728
  }
2577
2729
  options.push({ value: "done", label: "Done", hint: "" });
2578
2730
  const choice = await p5.select({
@@ -2651,7 +2803,9 @@ async function runProvidersCommand(args) {
2651
2803
 
2652
2804
  // src/cli/claude.ts
2653
2805
  async function handleClaudeCommand(parsed) {
2654
- const { dryRun, setup, trace, launchProvider, launchModel } = parsed;
2806
+ const { dryRun, setup, trace, launchProvider } = parsed;
2807
+ const launchAllModels = parsed.launchAllModels || parsed.launchModel === "All";
2808
+ const launchModel = launchAllModels && !parsed.launchModel ? "All" : parsed.launchModel;
2655
2809
  const claudeArgs = normalizeClaudeAgentArgs(parsed.claudeArgs);
2656
2810
  const agentStdout = wantsCleanAgentStdout("claude", claudeArgs);
2657
2811
  setAgentStdoutMode(agentStdout);
@@ -2666,7 +2820,7 @@ async function handleClaudeCommand(parsed) {
2666
2820
  const conflicts = detectConflicts();
2667
2821
  const favorites = dryRun ? [] : prefs.favoriteModels ?? [];
2668
2822
  const launchPlan = planLaunchWizard({
2669
- explicit: { providerId: launchProvider, modelId: launchModel },
2823
+ explicit: launchAllModels ? { providerId: launchProvider, allModels: true } : { providerId: launchProvider, modelId: launchModel },
2670
2824
  childArgs: claudeArgs,
2671
2825
  agent: "claude",
2672
2826
  prefs
@@ -2677,7 +2831,13 @@ Error: ${launchPlan.error}
2677
2831
  `));
2678
2832
  return 1;
2679
2833
  }
2680
- const switchMenuActive = favorites.length > 0 && !launchPlan.skip;
2834
+ let catalogMode = false;
2835
+ const hasFavorites = favorites.length > 0;
2836
+ if (launchPlan.skip && launchPlan.target) {
2837
+ if (launchPlan.target.allModels) {
2838
+ catalogMode = "provider-all";
2839
+ }
2840
+ }
2681
2841
  if (!agentStdout) gateIntro("Claude Code");
2682
2842
  if (setup && !dryRun && !agentStdout) {
2683
2843
  p6.log.info("Provider setup now lives in anygate providers \u2014 opening that next is recommended.");
@@ -2727,7 +2887,7 @@ Error: ${launchPlan.error}
2727
2887
  }
2728
2888
  return baseOption;
2729
2889
  });
2730
- if (switchMenuActive) {
2890
+ if (hasFavorites) {
2731
2891
  providerOptions.unshift({
2732
2892
  value: "__favorites__",
2733
2893
  label: "\u2B50 Favorites Catalog",
@@ -2738,19 +2898,35 @@ Error: ${launchPlan.error}
2738
2898
  let activeProvider;
2739
2899
  let selectedModel;
2740
2900
  if (launchPlan.skip && launchPlan.target) {
2741
- const resolved = findProviderAndModel(allProviders, launchPlan.target);
2742
- if (!resolved) {
2743
- p6.log.error(
2744
- `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
2745
- );
2746
- return 1;
2747
- }
2748
- activeProvider = resolved.provider;
2749
- selectedModel = resolved.model;
2750
- if (!agentStdout) {
2751
- p6.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
2901
+ if (launchPlan.target.allModels) {
2902
+ const resolvedProvider = allProviders.find((lp) => lp.id === launchPlan.target.providerId);
2903
+ if (!resolvedProvider) {
2904
+ p6.log.error(`Provider not found: ${launchPlan.target.providerId}`);
2905
+ return 1;
2906
+ }
2907
+ activeProvider = resolvedProvider;
2908
+ selectedModel = activeProvider.models[0];
2909
+ catalogMode = "provider-all";
2910
+ if (!agentStdout) {
2911
+ p6.log.step(`Using all ${activeProvider.models.length} models from ${activeProvider.name}`);
2912
+ }
2913
+ if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
2914
+ } else {
2915
+ const resolved = findProviderAndModel(allProviders, launchPlan.target);
2916
+ if (!resolved) {
2917
+ p6.log.error(
2918
+ `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
2919
+ );
2920
+ return 1;
2921
+ }
2922
+ activeProvider = resolved.provider;
2923
+ selectedModel = resolved.model;
2924
+ catalogMode = false;
2925
+ if (!agentStdout) {
2926
+ p6.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
2927
+ }
2928
+ if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
2752
2929
  }
2753
- if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
2754
2930
  } else {
2755
2931
  let currentInitialProvider = initialProvider;
2756
2932
  while (true) {
@@ -2792,6 +2968,7 @@ Error: ${launchPlan.error}
2792
2968
  const sel = available[Number(pickedIdx)];
2793
2969
  activeProvider = sel.provider;
2794
2970
  selectedModel = sel.model;
2971
+ catalogMode = "favorites";
2795
2972
  if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
2796
2973
  break;
2797
2974
  } else {
@@ -2822,6 +2999,32 @@ Error: ${launchPlan.error}
2822
2999
  } else {
2823
3000
  activeProvider = selectedProvider;
2824
3001
  }
3002
+ const modelModeChoice = await p6.select({
3003
+ message: `Launch mode for ${activeProvider.name}?`,
3004
+ options: [
3005
+ {
3006
+ value: "specific",
3007
+ label: "One model",
3008
+ hint: "Pick a specific model from this provider"
3009
+ },
3010
+ {
3011
+ value: "all",
3012
+ label: `All models (${activeProvider.models.length})`,
3013
+ hint: "Every model from this provider in the /model switcher"
3014
+ },
3015
+ navOption("__back__", "\u2190 Back", "Choose a different provider")
3016
+ ]
3017
+ });
3018
+ if (p6.isCancel(modelModeChoice) || modelModeChoice === "__back__") {
3019
+ currentInitialProvider = activeProvider.id;
3020
+ continue;
3021
+ }
3022
+ if (modelModeChoice === "all") {
3023
+ catalogMode = "provider-all";
3024
+ selectedModel = activeProvider.models[0];
3025
+ if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
3026
+ break;
3027
+ }
2825
3028
  const pickedModelResult = await pickLocalModel(activeProvider, conflicts, prefs);
2826
3029
  if (pickedModelResult === "back") {
2827
3030
  currentInitialProvider = activeProvider.id;
@@ -2829,22 +3032,25 @@ Error: ${launchPlan.error}
2829
3032
  }
2830
3033
  if (!pickedModelResult) return 0;
2831
3034
  selectedModel = pickedModelResult;
3035
+ catalogMode = false;
2832
3036
  if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
2833
3037
  break;
2834
3038
  }
2835
3039
  }
2836
3040
  }
2837
3041
  const localProviders = catalog.length > 0 ? catalog : null;
2838
- if (switchMenuActive) {
2839
- const resolveRoute = makeRouteResolver(
2840
- localProviders
2841
- );
3042
+ if (catalogMode === "favorites") {
3043
+ const resolveRoute = makeRouteResolver(localProviders);
2842
3044
  const startingRoute = resolveRoute(activeProvider.id, selectedModel.id) ?? null;
2843
3045
  if (!startingRoute) {
2844
3046
  p6.log.error("Could not resolve a proxy route for the selected model.");
2845
3047
  return 1;
2846
3048
  }
2847
- const { routes: catalogRoutes, droppedFavorites } = buildCatalogRoutes(startingRoute, favorites, resolveRoute);
3049
+ const { routes: catalogRoutes, droppedFavorites } = buildCatalogRoutes(
3050
+ startingRoute,
3051
+ favorites,
3052
+ resolveRoute
3053
+ );
2848
3054
  if (droppedFavorites.length > 0) {
2849
3055
  p6.log.warn(
2850
3056
  `Skipping ${droppedFavorites.length} favorite${droppedFavorites.length === 1 ? "" : "s"} that are no longer available in /model`
@@ -2882,6 +3088,35 @@ Error: ${launchPlan.error}
2882
3088
  claudeArgs
2883
3089
  );
2884
3090
  }
3091
+ if (catalogMode === "provider-all") {
3092
+ const resolveRoute = makeRouteResolver(localProviders);
3093
+ const startingRoute = resolveRoute(activeProvider.id, selectedModel.id) ?? null;
3094
+ if (!startingRoute) {
3095
+ p6.log.error("Could not resolve a proxy route for the starting model.");
3096
+ return 1;
3097
+ }
3098
+ const catalogRoutes = buildProviderAllModelRoutes(activeProvider, startingRoute, resolveRoute);
3099
+ if (dryRun) {
3100
+ console.log("");
3101
+ console.log(pc5.bold(pc5.cyan(" DRY RUN \u2014 would execute (provider catalog mode):")));
3102
+ console.log("");
3103
+ console.log(` ${pc5.bold("Provider:")} ${activeProvider.name}`);
3104
+ console.log(` ${pc5.bold("Starting model:")} ${selectedModel.id}`);
3105
+ console.log(` ${pc5.bold("/model catalog:")} ${catalogRoutes.length} model(s)`);
3106
+ catalogRoutes.forEach((r) => console.log(` ${pc5.dim(r.displayName)}`));
3107
+ console.log("");
3108
+ console.log(pc5.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
3109
+ console.log("");
3110
+ return 0;
3111
+ }
3112
+ return launchClaudeViaCatalog(
3113
+ catalogRoutes,
3114
+ startingRoute,
3115
+ selectedModel.contextWindow,
3116
+ trace ?? false,
3117
+ claudeArgs
3118
+ );
3119
+ }
2885
3120
  if (dryRun) {
2886
3121
  const formatDesc = selectedModel.modelFormat === "anthropic" ? "direct passthrough" : "via SDK adapter proxy";
2887
3122
  const endpoint = selectedModel.modelFormat === "anthropic" ? selectedModel.baseUrl ?? "(unknown)" : selectedModel.npm ?? "SDK";
@@ -2891,7 +3126,9 @@ Error: ${launchPlan.error}
2891
3126
  console.log(` ${pc5.bold("Provider:")} ${activeProvider.name}`);
2892
3127
  console.log(` ${pc5.bold("Model:")} ${selectedModel.id}`);
2893
3128
  console.log(` ${pc5.bold("Format:")} ${selectedModel.modelFormat} (${formatDesc})`);
2894
- console.log(` ${pc5.bold(selectedModel.modelFormat === "anthropic" ? "Endpoint:" : "SDK npm:")} ${endpoint}`);
3129
+ console.log(
3130
+ ` ${pc5.bold(selectedModel.modelFormat === "anthropic" ? "Endpoint:" : "SDK npm:")} ${endpoint}`
3131
+ );
2895
3132
  console.log(` ${pc5.bold("Key:")} ${activeProvider.name} provider key`);
2896
3133
  console.log("");
2897
3134
  console.log(pc5.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
@@ -2900,9 +3137,7 @@ Error: ${launchPlan.error}
2900
3137
  }
2901
3138
  const launchApiKey = await resolveLocalProviderApiKey(activeProvider);
2902
3139
  if (!launchApiKey?.trim()) {
2903
- p6.log.error(
2904
- new CredentialUnavailableError(activeProvider.id).userMessage
2905
- );
3140
+ p6.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
2906
3141
  return 1;
2907
3142
  }
2908
3143
  const isAvailable = await quickValidateModel(activeProvider.id, selectedModel.id);
@@ -2936,7 +3171,9 @@ Error: ${launchPlan.error}
2936
3171
  );
2937
3172
  if (!isAgentStdoutMode()) p6.log.info(`Cloud Code proxy started on port ${proxyHandle.port}`);
2938
3173
  } catch (err) {
2939
- p6.log.error(`Failed to start Cloud Code proxy: ${err instanceof Error ? err.message : String(err)}`);
3174
+ p6.log.error(
3175
+ `Failed to start Cloud Code proxy: ${err instanceof Error ? err.message : String(err)}`
3176
+ );
2940
3177
  return 1;
2941
3178
  }
2942
3179
  childEnv = buildChildEnv(
@@ -2965,7 +3202,9 @@ Error: ${launchPlan.error}
2965
3202
  );
2966
3203
  if (!isAgentStdoutMode()) p6.log.info(`OAuth proxy started on port ${proxyHandle.port}`);
2967
3204
  } catch (err) {
2968
- p6.log.error(`Failed to start OAuth proxy: ${err instanceof Error ? err.message : String(err)}`);
3205
+ p6.log.error(
3206
+ `Failed to start OAuth proxy: ${err instanceof Error ? err.message : String(err)}`
3207
+ );
2969
3208
  return 1;
2970
3209
  }
2971
3210
  childEnv = buildChildEnv(
@@ -3012,7 +3251,9 @@ Error: ${launchPlan.error}
3012
3251
  );
3013
3252
  }
3014
3253
  } catch (err) {
3015
- p6.log.error(`Failed to start SDK adapter proxy: ${err instanceof Error ? err.message : String(err)}`);
3254
+ p6.log.error(
3255
+ `Failed to start SDK adapter proxy: ${err instanceof Error ? err.message : String(err)}`
3256
+ );
3016
3257
  return 1;
3017
3258
  }
3018
3259
  childEnv = buildChildEnv(
@@ -3041,7 +3282,9 @@ Error: ${launchPlan.error}
3041
3282
  async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindow, trace, claudeArgs) {
3042
3283
  let proxyHandle;
3043
3284
  try {
3044
- proxyHandle = await startProxyCatalog(catalogRoutes, startingRoute.aliasId, trace);
3285
+ proxyHandle = await startProxyCatalog(catalogRoutes, startingRoute.aliasId, trace, {
3286
+ app: "Claude"
3287
+ });
3045
3288
  p6.log.info(
3046
3289
  `Switch menu active \u2014 proxy on port ${proxyHandle.port} ` + pc5.dim(`(${catalogRoutes.length} model${catalogRoutes.length !== 1 ? "s" : ""} in /model)`)
3047
3290
  );
@@ -3073,7 +3316,6 @@ async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindo
3073
3316
  // src/apps/codex/cli.ts
3074
3317
  import pc8 from "picocolors";
3075
3318
  import * as p9 from "@clack/prompts";
3076
- init_config();
3077
3319
 
3078
3320
  // src/apps/codex/proxy.ts
3079
3321
  import { createHash } from "crypto";
@@ -3130,7 +3372,9 @@ function applyClaudeCodeOAuthIdentity(input, sdkParams) {
3130
3372
  import { streamText, generateText, tool, jsonSchema } from "ai";
3131
3373
  function messageText(content) {
3132
3374
  if (typeof content === "string") return content;
3133
- return (content ?? []).map((p18) => p18.type === "output_text" || p18.type === "input_text" || p18.type === "text" ? p18.text ?? "" : "").join("");
3375
+ return (content ?? []).map(
3376
+ (p18) => p18.type === "output_text" || p18.type === "input_text" || p18.type === "text" ? p18.text ?? "" : ""
3377
+ ).join("");
3134
3378
  }
3135
3379
  function extractDeveloperAndInstructions(items, instructions) {
3136
3380
  const developerParts = [];
@@ -3174,9 +3418,16 @@ function mergeConsecutiveMessages(messages) {
3174
3418
  return out;
3175
3419
  }
3176
3420
  function ensureUserFirst(messages) {
3177
- if (messages.length === 0) return [{ role: "user", content: [{ type: "text", text: "(empty input)" }] }];
3421
+ if (messages.length === 0)
3422
+ return [{ role: "user", content: [{ type: "text", text: "(empty input)" }] }];
3178
3423
  if (messages[0].role === "assistant") {
3179
- return [{ role: "user", content: [{ type: "text", text: "(conversation continued)" }] }, ...messages];
3424
+ return [
3425
+ {
3426
+ role: "user",
3427
+ content: [{ type: "text", text: "(conversation continued)" }]
3428
+ },
3429
+ ...messages
3430
+ ];
3180
3431
  }
3181
3432
  return messages;
3182
3433
  }
@@ -3256,12 +3507,14 @@ function translateResponsesInput(input, instructions, npm) {
3256
3507
  const { rawId } = splitToolUseId(item.call_id);
3257
3508
  messages.push({
3258
3509
  role: "tool",
3259
- content: [{
3260
- type: "tool-result",
3261
- toolCallId: rawId,
3262
- toolName: toolNames.get(rawId) ?? "unknown",
3263
- output: { type: "text", value: serializeToolResultContent(item.output) }
3264
- }]
3510
+ content: [
3511
+ {
3512
+ type: "tool-result",
3513
+ toolCallId: rawId,
3514
+ toolName: toolNames.get(rawId) ?? "unknown",
3515
+ output: { type: "text", value: serializeToolResultContent(item.output) }
3516
+ }
3517
+ ]
3265
3518
  });
3266
3519
  } else if ("role" in item) {
3267
3520
  const role = item.role === "assistant" ? "assistant" : "user";
@@ -3283,8 +3536,14 @@ var TOOL_SEARCH_FLAT = {
3283
3536
  parameters: {
3284
3537
  type: "object",
3285
3538
  properties: {
3286
- query: { type: "string", description: "Search query describing the tool or capability needed." },
3287
- limit: { type: "number", description: "Maximum number of matching tools to return. Defaults to 8." }
3539
+ query: {
3540
+ type: "string",
3541
+ description: "Search query describing the tool or capability needed."
3542
+ },
3543
+ limit: {
3544
+ type: "number",
3545
+ description: "Maximum number of matching tools to return. Defaults to 8."
3546
+ }
3288
3547
  },
3289
3548
  required: ["query"],
3290
3549
  additionalProperties: false
@@ -3367,7 +3626,12 @@ function translateResponsesTools(tools, options = {}) {
3367
3626
  continue;
3368
3627
  }
3369
3628
  if (t.type === "custom") {
3370
- addTool(t.name, { type: "function", name: t.name, description: t.description ?? "", parameters: { type: "object", properties: {} } });
3629
+ addTool(t.name, {
3630
+ type: "function",
3631
+ name: t.name,
3632
+ description: t.description ?? "",
3633
+ parameters: { type: "object", properties: {} }
3634
+ });
3371
3635
  continue;
3372
3636
  }
3373
3637
  if (t.type !== "function" || !t.name) continue;
@@ -3469,7 +3733,13 @@ async function writeResponsesStream(fullStream, modelId, write, onDone, onProgre
3469
3733
  emit("response.output_item.added", {
3470
3734
  type: "response.output_item.added",
3471
3735
  output_index: textOutputIndex,
3472
- item: { id: textItemId, type: "message", role: "assistant", status: "in_progress", content: [] }
3736
+ item: {
3737
+ id: textItemId,
3738
+ type: "message",
3739
+ role: "assistant",
3740
+ status: "in_progress",
3741
+ content: []
3742
+ }
3473
3743
  });
3474
3744
  emit("response.content_part.added", {
3475
3745
  type: "response.content_part.added",
@@ -3723,7 +3993,14 @@ async function writeResponsesStream(fullStream, modelId, write, onDone, onProgre
3723
3993
  emit("response.output_item.added", {
3724
3994
  type: "response.output_item.added",
3725
3995
  output_index: idx,
3726
- item: { type: "function_call", id: itemId, call_id: callId, name: call.name, arguments: "", status: "in_progress" }
3996
+ item: {
3997
+ type: "function_call",
3998
+ id: itemId,
3999
+ call_id: callId,
4000
+ name: call.name,
4001
+ arguments: "",
4002
+ status: "in_progress"
4003
+ }
3727
4004
  });
3728
4005
  emit("response.function_call_arguments.done", {
3729
4006
  type: "response.function_call_arguments.done",
@@ -3731,9 +4008,20 @@ async function writeResponsesStream(fullStream, modelId, write, onDone, onProgre
3731
4008
  output_index: idx,
3732
4009
  arguments: args
3733
4010
  });
3734
- const fcItem = { type: "function_call", id: itemId, call_id: callId, name: call.name, arguments: args, status: "completed" };
4011
+ const fcItem = {
4012
+ type: "function_call",
4013
+ id: itemId,
4014
+ call_id: callId,
4015
+ name: call.name,
4016
+ arguments: args,
4017
+ status: "completed"
4018
+ };
3735
4019
  const fcSplit = splitBackFunctionCall(fcItem, namespaceMap, customToolNames);
3736
- emit("response.output_item.done", { type: "response.output_item.done", output_index: idx, item: fcSplit });
4020
+ emit("response.output_item.done", {
4021
+ type: "response.output_item.done",
4022
+ output_index: idx,
4023
+ item: fcSplit
4024
+ });
3737
4025
  outputItems.push(fcSplit);
3738
4026
  }
3739
4027
  } else if (textItemId) {
@@ -3797,7 +4085,13 @@ async function writeResponsesStream(fullStream, modelId, write, onDone, onProgre
3797
4085
  outputItems.push(fcItem);
3798
4086
  }
3799
4087
  if (outputItems.length === 0) {
3800
- outputItems.push({ id: newItemId("msg"), type: "message", role: "assistant", status: "completed", content: [{ type: "output_text", text: "(conversation context was too large to summarize)" }] });
4088
+ outputItems.push({
4089
+ id: newItemId("msg"),
4090
+ type: "message",
4091
+ role: "assistant",
4092
+ status: "completed",
4093
+ content: [{ type: "output_text", text: "(conversation context was too large to summarize)" }]
4094
+ });
3801
4095
  }
3802
4096
  let finalOutput = outputItems;
3803
4097
  if (isCompaction) {
@@ -3811,7 +4105,9 @@ async function writeResponsesStream(fullStream, modelId, write, onDone, onProgre
3811
4105
  toolCallCount: toolStates.length,
3812
4106
  toolNames: toolStates.map((t) => t.name),
3813
4107
  loopDetected,
3814
- dsmlToolCallsRecovered: dsml?.calls.length
4108
+ dsmlToolCallsRecovered: dsml?.calls.length,
4109
+ inputTokens: usage.input_tokens,
4110
+ outputTokens: usage.output_tokens
3815
4111
  });
3816
4112
  emit("response.completed", {
3817
4113
  type: "response.completed",
@@ -3831,11 +4127,18 @@ async function streamResponsesResponse(model, params, modelId, write, onDone, on
3831
4127
  const idleTimeoutMs = options?.idleTimeoutMs ?? STREAM_IDLE_TIMEOUT_MS;
3832
4128
  const abort = new AbortController();
3833
4129
  let idleTimer = setTimeout(
3834
- () => abort.abort(new Error(`no data received from provider for ${Math.round(idleTimeoutMs / 1e3)}s`)),
4130
+ () => abort.abort(
4131
+ new Error(`no data received from provider for ${Math.round(idleTimeoutMs / 1e3)}s`)
4132
+ ),
3835
4133
  idleTimeoutMs
3836
4134
  );
3837
- const result = streamText({ model, ...params, abortSignal: abort.signal, onError: () => {
3838
- } });
4135
+ const result = streamText({
4136
+ model,
4137
+ ...params,
4138
+ abortSignal: abort.signal,
4139
+ onError: () => {
4140
+ }
4141
+ });
3839
4142
  Promise.resolve(result.text).catch(() => {
3840
4143
  });
3841
4144
  Promise.resolve(result.toolCalls).catch(() => {
@@ -3853,7 +4156,9 @@ async function streamResponsesResponse(model, params, modelId, write, onDone, on
3853
4156
  for await (const part of result.fullStream) {
3854
4157
  clearTimeout(idleTimer);
3855
4158
  idleTimer = setTimeout(
3856
- () => abort.abort(new Error(`no data received from provider for ${Math.round(idleTimeoutMs / 1e3)}s`)),
4159
+ () => abort.abort(
4160
+ new Error(`no data received from provider for ${Math.round(idleTimeoutMs / 1e3)}s`)
4161
+ ),
3857
4162
  idleTimeoutMs
3858
4163
  );
3859
4164
  yield part;
@@ -3906,7 +4211,13 @@ async function generateResponsesResponse(model, params, modelId) {
3906
4211
  arguments: typeof argsRaw === "string" ? argsRaw : JSON.stringify(argsRaw ?? {}),
3907
4212
  status: "completed"
3908
4213
  };
3909
- output.push(splitBackFunctionCall(fcItem, params.namespaceMap, params.customToolNames));
4214
+ output.push(
4215
+ splitBackFunctionCall(
4216
+ fcItem,
4217
+ params.namespaceMap,
4218
+ params.customToolNames
4219
+ )
4220
+ );
3910
4221
  }
3911
4222
  if (r.text !== null && r.text !== void 0) {
3912
4223
  output.push({
@@ -3918,7 +4229,13 @@ async function generateResponsesResponse(model, params, modelId) {
3918
4229
  });
3919
4230
  }
3920
4231
  if (output.length === 0) {
3921
- output.push({ id: newItemId("msg"), type: "message", role: "assistant", status: "completed", content: [{ type: "output_text", text: "(conversation context was too large to summarize)" }] });
4232
+ output.push({
4233
+ id: newItemId("msg"),
4234
+ type: "message",
4235
+ role: "assistant",
4236
+ status: "completed",
4237
+ content: [{ type: "output_text", text: "(conversation context was too large to summarize)" }]
4238
+ });
3922
4239
  }
3923
4240
  const inputTokens = r.usage?.inputTokens ?? 0;
3924
4241
  const outputTokens = r.usage?.outputTokens ?? 0;
@@ -3944,80 +4261,102 @@ function responsesErrorBody(modelId, message, statusCode = 401) {
3944
4261
  created_at: Math.floor(Date.now() / 1e3),
3945
4262
  status: "failed",
3946
4263
  output: [],
3947
- error: { message, type: statusCode === 429 ? "rate_limit_error" : "api_error", code: String(statusCode) }
4264
+ error: {
4265
+ message,
4266
+ type: statusCode === 429 ? "rate_limit_error" : "api_error",
4267
+ code: String(statusCode)
4268
+ }
3948
4269
  };
3949
4270
  }
3950
4271
  function writeResponsesErrorStream(modelId, message, write, statusCode = 401) {
3951
- write(sseChunk("response.completed", {
3952
- type: "response.completed",
3953
- response: responsesErrorBody(modelId, message, statusCode)
3954
- }));
4272
+ write(
4273
+ sseChunk("response.completed", {
4274
+ type: "response.completed",
4275
+ response: responsesErrorBody(modelId, message, statusCode)
4276
+ })
4277
+ );
3955
4278
  }
3956
4279
  function writeResponsesRateLimitStream(modelId, message, write) {
3957
4280
  const responseId = newResponseId();
3958
4281
  const itemId = newItemId("msg");
3959
4282
  const createdAt = Math.floor(Date.now() / 1e3);
3960
4283
  const content = [{ type: "output_text", text: message }];
3961
- write(sseChunk("response.created", {
3962
- type: "response.created",
3963
- response: {
3964
- id: responseId,
3965
- object: "response",
3966
- model: modelId,
3967
- created_at: createdAt,
3968
- status: "in_progress",
3969
- output: []
3970
- }
3971
- }));
3972
- write(sseChunk("response.output_item.added", {
3973
- type: "response.output_item.added",
3974
- output_index: 0,
3975
- item: { id: itemId, type: "message", role: "assistant", status: "in_progress", content: [] }
3976
- }));
3977
- write(sseChunk("response.content_part.added", {
3978
- type: "response.content_part.added",
3979
- item_id: itemId,
3980
- output_index: 0,
3981
- content_index: 0,
3982
- part: { type: "output_text", text: "" }
3983
- }));
3984
- write(sseChunk("response.output_text.delta", {
3985
- type: "response.output_text.delta",
3986
- item_id: itemId,
3987
- output_index: 0,
3988
- content_index: 0,
3989
- delta: message
3990
- }));
3991
- write(sseChunk("response.output_text.done", {
3992
- type: "response.output_text.done",
3993
- item_id: itemId,
3994
- output_index: 0,
3995
- content_index: 0,
3996
- text: message
3997
- }));
3998
- write(sseChunk("response.content_part.done", {
3999
- type: "response.content_part.done",
4000
- item_id: itemId,
4001
- output_index: 0,
4002
- content_index: 0,
4003
- part: { type: "output_text", text: message }
4004
- }));
4005
- write(sseChunk("response.output_item.done", {
4006
- type: "response.output_item.done",
4007
- output_index: 0,
4008
- item: { id: itemId, type: "message", role: "assistant", status: "completed", content }
4009
- }));
4010
- write(sseChunk("response.completed", {
4011
- type: "response.completed",
4012
- response: {
4013
- id: responseId,
4014
- object: "response",
4015
- model: modelId,
4016
- created_at: createdAt,
4017
- status: "completed",
4018
- output: [{ id: itemId, type: "message", role: "assistant", status: "completed", content }]
4019
- }
4020
- }));
4284
+ write(
4285
+ sseChunk("response.created", {
4286
+ type: "response.created",
4287
+ response: {
4288
+ id: responseId,
4289
+ object: "response",
4290
+ model: modelId,
4291
+ created_at: createdAt,
4292
+ status: "in_progress",
4293
+ output: []
4294
+ }
4295
+ })
4296
+ );
4297
+ write(
4298
+ sseChunk("response.output_item.added", {
4299
+ type: "response.output_item.added",
4300
+ output_index: 0,
4301
+ item: { id: itemId, type: "message", role: "assistant", status: "in_progress", content: [] }
4302
+ })
4303
+ );
4304
+ write(
4305
+ sseChunk("response.content_part.added", {
4306
+ type: "response.content_part.added",
4307
+ item_id: itemId,
4308
+ output_index: 0,
4309
+ content_index: 0,
4310
+ part: { type: "output_text", text: "" }
4311
+ })
4312
+ );
4313
+ write(
4314
+ sseChunk("response.output_text.delta", {
4315
+ type: "response.output_text.delta",
4316
+ item_id: itemId,
4317
+ output_index: 0,
4318
+ content_index: 0,
4319
+ delta: message
4320
+ })
4321
+ );
4322
+ write(
4323
+ sseChunk("response.output_text.done", {
4324
+ type: "response.output_text.done",
4325
+ item_id: itemId,
4326
+ output_index: 0,
4327
+ content_index: 0,
4328
+ text: message
4329
+ })
4330
+ );
4331
+ write(
4332
+ sseChunk("response.content_part.done", {
4333
+ type: "response.content_part.done",
4334
+ item_id: itemId,
4335
+ output_index: 0,
4336
+ content_index: 0,
4337
+ part: { type: "output_text", text: message }
4338
+ })
4339
+ );
4340
+ write(
4341
+ sseChunk("response.output_item.done", {
4342
+ type: "response.output_item.done",
4343
+ output_index: 0,
4344
+ item: { id: itemId, type: "message", role: "assistant", status: "completed", content }
4345
+ })
4346
+ );
4347
+ write(
4348
+ sseChunk("response.completed", {
4349
+ type: "response.completed",
4350
+ response: {
4351
+ id: responseId,
4352
+ object: "response",
4353
+ model: modelId,
4354
+ created_at: createdAt,
4355
+ status: "completed",
4356
+ output: [{ id: itemId, type: "message", role: "assistant", status: "completed", content }]
4357
+ }
4358
+ })
4359
+ );
4021
4360
  }
4022
4361
  function responsesRateLimitBody(modelId, message) {
4023
4362
  const itemId = newItemId("msg");
@@ -4108,7 +4447,9 @@ var COMPACTION_PROMPT_MARKER = "You are performing a CONTEXT CHECKPOINT COMPACTI
4108
4447
  function inputItemText(content) {
4109
4448
  if (typeof content === "string") return content;
4110
4449
  if (!Array.isArray(content)) return "";
4111
- return content.map((p18) => p18 && typeof p18 === "object" && typeof p18.text === "string" ? p18.text : "").join("");
4450
+ return content.map(
4451
+ (p18) => p18 && typeof p18 === "object" && typeof p18.text === "string" ? p18.text : ""
4452
+ ).join("");
4112
4453
  }
4113
4454
  function isLikelyCodexCompactionRequest(body) {
4114
4455
  if (!Array.isArray(body.input)) return false;
@@ -4159,9 +4500,7 @@ function codexRouteLookupIds(requestedModel) {
4159
4500
  function findCodexProxyRoute(routes, requestedModel) {
4160
4501
  const ids = codexRouteLookupIds(requestedModel);
4161
4502
  for (const id of ids) {
4162
- const route = routes.find(
4163
- (r) => r.modelId === id || codexAppModelSlug(r.modelId) === id
4164
- );
4503
+ const route = routes.find((r) => r.modelId === id || codexAppModelSlug(r.modelId) === id);
4165
4504
  if (route) return route;
4166
4505
  }
4167
4506
  return void 0;
@@ -4177,21 +4516,42 @@ async function startCodexProxy(routes, options = {}) {
4177
4516
  const opts = typeof options === "boolean" ? { debug: options } : options;
4178
4517
  const debug = opts.debug ?? false;
4179
4518
  const requireAuth = opts.requireAuth ?? true;
4519
+ const analyticsApp = opts.app ?? "codex";
4520
+ const routeByModelId = new Map(routes.map((r) => [r.modelId, r]));
4521
+ const trackUsage = (modelId, inputTokens, outputTokens) => {
4522
+ if (inputTokens <= 0 && outputTokens <= 0) return;
4523
+ try {
4524
+ const route = routeByModelId.get(modelId);
4525
+ recordUsage({
4526
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
4527
+ modelId: route?.upstreamModelId ?? modelId,
4528
+ npm: route?.npm,
4529
+ providerId: route?.providerId,
4530
+ app: analyticsApp,
4531
+ inputTokens,
4532
+ outputTokens
4533
+ });
4534
+ } catch {
4535
+ }
4536
+ };
4180
4537
  silenceSdkWarnings();
4181
4538
  const models = /* @__PURE__ */ new Map();
4182
4539
  for (const route of routes) {
4183
- models.set(route.modelId, await createLanguageModel({
4184
- npm: route.npm,
4185
- modelId: route.upstreamModelId,
4186
- apiKey: route.apiKey,
4187
- baseURL: route.baseURL,
4188
- providerId: route.providerId ?? route.modelId,
4189
- authType: route.authType,
4190
- oauthAccountId: route.oauthAccountId,
4191
- providerData: route.providerData,
4192
- vertex: route.vertex,
4193
- headers: route.headers
4194
- }));
4540
+ models.set(
4541
+ route.modelId,
4542
+ await createLanguageModel({
4543
+ npm: route.npm,
4544
+ modelId: route.upstreamModelId,
4545
+ apiKey: route.apiKey,
4546
+ baseURL: route.baseURL,
4547
+ providerId: route.providerId ?? route.modelId,
4548
+ authType: route.authType,
4549
+ oauthAccountId: route.oauthAccountId,
4550
+ providerData: route.providerData,
4551
+ vertex: route.vertex,
4552
+ headers: route.headers
4553
+ })
4554
+ );
4195
4555
  }
4196
4556
  return new Promise((resolve, reject2) => {
4197
4557
  const log17 = debug ? makeTraceLogger(getCodexProxyDebugLogPath()) : () => {
@@ -4203,7 +4563,9 @@ async function startCodexProxy(routes, options = {}) {
4203
4563
  const server = createServer(async (req, res) => {
4204
4564
  const url = req.url ?? "/";
4205
4565
  if (debug) {
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)"}`);
4566
+ log17(
4567
+ `-> ${req.method} ${url} content-type=${req.headers["content-type"] ?? "(none)"} content-encoding=${req.headers["content-encoding"] ?? "(none)"} content-length=${req.headers["content-length"] ?? "(none)"}`
4568
+ );
4207
4569
  }
4208
4570
  if (!requireAuth && req.method === "POST") {
4209
4571
  const origin = req.headers.origin;
@@ -4219,7 +4581,9 @@ async function startCodexProxy(routes, options = {}) {
4219
4581
  }
4220
4582
  };
4221
4583
  if (!isValidLoopback(origin) || !isValidLoopback(referer)) {
4222
- sendJson(res, 403, { error: { message: "Forbidden origin", type: "invalid_request_error" } });
4584
+ sendJson(res, 403, {
4585
+ error: { message: "Forbidden origin", type: "invalid_request_error" }
4586
+ });
4223
4587
  return;
4224
4588
  }
4225
4589
  }
@@ -4257,7 +4621,9 @@ async function startCodexProxy(routes, options = {}) {
4257
4621
  const id = url.slice("/v1/models/".length);
4258
4622
  const route = findCodexProxyRoute(routes, id);
4259
4623
  if (!route) {
4260
- sendJson(res, 404, { error: { message: `Model not found: ${id}`, type: "invalid_request_error" } });
4624
+ sendJson(res, 404, {
4625
+ error: { message: `Model not found: ${id}`, type: "invalid_request_error" }
4626
+ });
4261
4627
  return;
4262
4628
  }
4263
4629
  sendJson(res, 200, {
@@ -4281,9 +4647,13 @@ async function startCodexProxy(routes, options = {}) {
4281
4647
  rawBody = await readBody(req);
4282
4648
  } catch (err) {
4283
4649
  if (debug) {
4284
- log17(`Error: failed to read/decode request body on POST ${url}: ${formatUpstreamError(err)} content-encoding=${req.headers["content-encoding"] ?? "(none)"}`);
4650
+ log17(
4651
+ `Error: failed to read/decode request body on POST ${url}: ${formatUpstreamError(err)} content-encoding=${req.headers["content-encoding"] ?? "(none)"}`
4652
+ );
4285
4653
  }
4286
- sendJson(res, 400, { error: { message: "Invalid request body", type: "invalid_request_error" } });
4654
+ sendJson(res, 400, {
4655
+ error: { message: "Invalid request body", type: "invalid_request_error" }
4656
+ });
4287
4657
  return;
4288
4658
  }
4289
4659
  let body;
@@ -4292,22 +4662,34 @@ async function startCodexProxy(routes, options = {}) {
4292
4662
  } catch (err) {
4293
4663
  if (debug) {
4294
4664
  const headers = JSON.stringify(req.headers);
4295
- log17(`Error: Invalid JSON body on POST ${url}: ${formatUpstreamError(err)} headers=${headers} rawBody=${JSON.stringify(rawBody.slice(0, 2e3))}`);
4665
+ log17(
4666
+ `Error: Invalid JSON body on POST ${url}: ${formatUpstreamError(err)} headers=${headers} rawBody=${JSON.stringify(rawBody.slice(0, 2e3))}`
4667
+ );
4296
4668
  }
4297
- sendJson(res, 400, { error: { message: "Invalid JSON body", type: "invalid_request_error" } });
4669
+ sendJson(res, 400, {
4670
+ error: { message: "Invalid JSON body", type: "invalid_request_error" }
4671
+ });
4298
4672
  return;
4299
4673
  }
4300
4674
  if (debug) {
4301
4675
  const prevId = body.previous_response_id ?? null;
4302
4676
  const inputItems = Array.isArray(body.input) ? body.input.length : typeof body.input === "string" ? 1 : 0;
4303
4677
  const tools = Array.isArray(body.tools) ? body.tools : [];
4304
- const toolNames = tools.map((t) => t && typeof t === "object" && "name" in t ? t.name : "?").join(",");
4305
- log17(`request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${rawBody.length} tools=[${toolNames || "none"}]`);
4306
- const mcpTools = tools.filter((t) => t && typeof t === "object" && "name" in t && String(t.name).startsWith("mcp__"));
4678
+ const toolNames = tools.map(
4679
+ (t) => t && typeof t === "object" && "name" in t ? t.name : "?"
4680
+ ).join(",");
4681
+ log17(
4682
+ `request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${rawBody.length} tools=[${toolNames || "none"}]`
4683
+ );
4684
+ const mcpTools = tools.filter(
4685
+ (t) => t && typeof t === "object" && "name" in t && String(t.name).startsWith("mcp__")
4686
+ );
4307
4687
  for (const t of mcpTools) {
4308
4688
  const mt = t;
4309
4689
  const subTools = mt.type === "namespace" && Array.isArray(mt.tools) ? ` subTools=[${mt.tools.length}]` : "";
4310
- log17(` mcp-tool: name=${mt.name} type=${mt.type} desc=${JSON.stringify(String(mt.description ?? "")).slice(0, 120)}${subTools}`);
4690
+ log17(
4691
+ ` mcp-tool: name=${mt.name} type=${mt.type} desc=${JSON.stringify(String(mt.description ?? "")).slice(0, 120)}${subTools}`
4692
+ );
4311
4693
  }
4312
4694
  }
4313
4695
  const modelId = String(body.model ?? "");
@@ -4322,41 +4704,55 @@ async function startCodexProxy(routes, options = {}) {
4322
4704
  resolved = { route: fallbackRoute, languageModel: fallbackLm };
4323
4705
  } else {
4324
4706
  if (debug) {
4325
- log17(`resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
4707
+ log17(
4708
+ `resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`
4709
+ );
4326
4710
  }
4327
- sendJson(res, 404, { error: { message: `Unknown model: ${modelId}`, type: "invalid_request_error" } });
4711
+ sendJson(res, 404, {
4712
+ error: { message: `Unknown model: ${modelId}`, type: "invalid_request_error" }
4713
+ });
4328
4714
  return;
4329
4715
  }
4330
4716
  }
4331
4717
  const { route, languageModel } = resolved;
4332
4718
  try {
4333
- let params = applyClaudeCodeOAuthIdentity(route, translateResponsesRequest(
4334
- body,
4335
- route.npm,
4336
- {
4337
- providerId: route.providerId,
4338
- apiBaseUrl: route.baseURL,
4339
- supportedParameters: route.supportedParameters,
4340
- reasoning: route.reasoning,
4341
- interleavedReasoningField: route.interleavedReasoningField,
4342
- upstreamModelId: route.upstreamModelId
4343
- },
4344
- { maxTools: maxToolsForNpm(route.npm) }
4345
- ));
4719
+ let params = applyClaudeCodeOAuthIdentity(
4720
+ route,
4721
+ translateResponsesRequest(
4722
+ body,
4723
+ route.npm,
4724
+ {
4725
+ providerId: route.providerId,
4726
+ apiBaseUrl: route.baseURL,
4727
+ supportedParameters: route.supportedParameters,
4728
+ reasoning: route.reasoning,
4729
+ interleavedReasoningField: route.interleavedReasoningField,
4730
+ upstreamModelId: route.upstreamModelId
4731
+ },
4732
+ { maxTools: maxToolsForNpm(route.npm) }
4733
+ )
4734
+ );
4346
4735
  if (route.contextWindow && route.contextWindow > 0) {
4347
4736
  const before = params.messages.length;
4348
4737
  const estimatedChars = estimateCodexRequestChars(params);
4349
4738
  const compaction = isLikelyCodexCompactionRequest(body);
4350
- if (debug) log17(`context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before}`);
4739
+ if (debug)
4740
+ log17(
4741
+ `context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before}`
4742
+ );
4351
4743
  params = protectCodexCompactionParams(body, params, route.contextWindow);
4352
4744
  params.isCompaction = compaction;
4353
4745
  if (debug && params.messages.length < before) {
4354
- log17(`context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages`);
4746
+ log17(
4747
+ `context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages`
4748
+ );
4355
4749
  }
4356
4750
  }
4357
4751
  if (debug) {
4358
4752
  const effort = body.reasoning?.effort;
4359
- log17(`model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
4753
+ log17(
4754
+ `model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`
4755
+ );
4360
4756
  }
4361
4757
  if (body.stream) {
4362
4758
  res.writeHead(200, {
@@ -4366,16 +4762,28 @@ async function startCodexProxy(routes, options = {}) {
4366
4762
  });
4367
4763
  const write = (chunk) => res.write(chunk);
4368
4764
  try {
4369
- await streamResponsesResponse(languageModel, params, modelId, write, (summary) => {
4370
- if (debug) {
4371
- const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
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)}`);
4373
- }
4374
- }, (progress) => {
4375
- if (debug) {
4376
- log17(`response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
4765
+ await streamResponsesResponse(
4766
+ languageModel,
4767
+ params,
4768
+ modelId,
4769
+ write,
4770
+ (summary) => {
4771
+ trackUsage(modelId, summary.inputTokens ?? 0, summary.outputTokens ?? 0);
4772
+ if (debug) {
4773
+ const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
4774
+ log17(
4775
+ `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)}`
4776
+ );
4777
+ }
4778
+ },
4779
+ (progress) => {
4780
+ if (debug) {
4781
+ log17(
4782
+ `response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`
4783
+ );
4784
+ }
4377
4785
  }
4378
- });
4786
+ );
4379
4787
  } catch (err) {
4380
4788
  const msg = formatUpstreamError(err);
4381
4789
  const status = upstreamHttpStatus(err);
@@ -4390,6 +4798,8 @@ async function startCodexProxy(routes, options = {}) {
4390
4798
  } else {
4391
4799
  try {
4392
4800
  const response = await generateResponsesResponse(languageModel, params, modelId);
4801
+ const u = response["usage"];
4802
+ trackUsage(modelId, u?.input_tokens ?? 0, u?.output_tokens ?? 0);
4393
4803
  sendJson(res, 200, response);
4394
4804
  } catch (err) {
4395
4805
  const msg = formatUpstreamError(err);
@@ -4475,7 +4885,9 @@ async function startCodexProxy(routes, options = {}) {
4475
4885
  if (requireAuth) {
4476
4886
  const inboundKey = extractApiKey(req);
4477
4887
  if (!inboundKey || inboundKey !== PROXY_PLACEHOLDER_KEY) {
4478
- socket.write("HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n");
4888
+ socket.write(
4889
+ "HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"
4890
+ );
4479
4891
  socket.destroy();
4480
4892
  return;
4481
4893
  }
@@ -4522,11 +4934,16 @@ Sec-WebSocket-Accept: ${wsAcceptKey(clientKey)}\r
4522
4934
  try {
4523
4935
  body = JSON.parse(frame.text);
4524
4936
  } catch {
4525
- if (debug) log17(`WS Error: Invalid JSON body: rawBody=${JSON.stringify(frame.text.slice(0, 2e3))}`);
4526
- sendWsEvent(`event: error
4937
+ if (debug)
4938
+ log17(
4939
+ `WS Error: Invalid JSON body: rawBody=${JSON.stringify(frame.text.slice(0, 2e3))}`
4940
+ );
4941
+ sendWsEvent(
4942
+ `event: error
4527
4943
  data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_request_error" } })}
4528
4944
 
4529
- `);
4945
+ `
4946
+ );
4530
4947
  closeSocket();
4531
4948
  return;
4532
4949
  }
@@ -4534,8 +4951,12 @@ data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_reques
4534
4951
  const prevId = body.previous_response_id ?? null;
4535
4952
  const inputItems = Array.isArray(body.input) ? body.input.length : typeof body.input === "string" ? 1 : 0;
4536
4953
  const tools = Array.isArray(body.tools) ? body.tools : [];
4537
- const toolNames = tools.map((t) => t && typeof t === "object" && "name" in t ? t.name : "?").join(",");
4538
- log17(`WS request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${frame.text.length} tools=[${toolNames || "none"}]`);
4954
+ const toolNames = tools.map(
4955
+ (t) => t && typeof t === "object" && "name" in t ? t.name : "?"
4956
+ ).join(",");
4957
+ log17(
4958
+ `WS request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${frame.text.length} tools=[${toolNames || "none"}]`
4959
+ );
4539
4960
  }
4540
4961
  const modelId = String(body.model ?? "");
4541
4962
  let resolved = resolveModel(routes, models, modelId);
@@ -4546,55 +4967,82 @@ data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_reques
4546
4967
  if (debug) log17(`WS resolveModel fallback: requested="${modelId}" \u2192 ${fb.modelId}`);
4547
4968
  resolved = { route: fb, languageModel: fbLm };
4548
4969
  } else {
4549
- if (debug) log17(`WS resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
4550
- sendWsEvent(`event: error
4970
+ if (debug)
4971
+ log17(
4972
+ `WS resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`
4973
+ );
4974
+ sendWsEvent(
4975
+ `event: error
4551
4976
  data: ${JSON.stringify({ error: { message: `Unknown model: ${modelId}` } })}
4552
4977
 
4553
- `);
4978
+ `
4979
+ );
4554
4980
  closeSocket();
4555
4981
  return;
4556
4982
  }
4557
4983
  }
4558
4984
  const { route, languageModel } = resolved;
4559
4985
  try {
4560
- let params = applyClaudeCodeOAuthIdentity(route, translateResponsesRequest(
4561
- body,
4562
- route.npm,
4563
- {
4564
- providerId: route.providerId,
4565
- apiBaseUrl: route.baseURL,
4566
- supportedParameters: route.supportedParameters,
4567
- reasoning: route.reasoning,
4568
- interleavedReasoningField: route.interleavedReasoningField,
4569
- upstreamModelId: route.upstreamModelId
4570
- },
4571
- { maxTools: maxToolsForNpm(route.npm) }
4572
- ));
4986
+ let params = applyClaudeCodeOAuthIdentity(
4987
+ route,
4988
+ translateResponsesRequest(
4989
+ body,
4990
+ route.npm,
4991
+ {
4992
+ providerId: route.providerId,
4993
+ apiBaseUrl: route.baseURL,
4994
+ supportedParameters: route.supportedParameters,
4995
+ reasoning: route.reasoning,
4996
+ interleavedReasoningField: route.interleavedReasoningField,
4997
+ upstreamModelId: route.upstreamModelId
4998
+ },
4999
+ { maxTools: maxToolsForNpm(route.npm) }
5000
+ )
5001
+ );
4573
5002
  if (route.contextWindow && route.contextWindow > 0) {
4574
5003
  const before = params.messages.length;
4575
5004
  const estimatedChars = estimateCodexRequestChars(params);
4576
5005
  const compaction = isLikelyCodexCompactionRequest(body);
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}`);
5006
+ if (debug)
5007
+ log17(
5008
+ `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}`
5009
+ );
4578
5010
  params = protectCodexCompactionParams(body, params, route.contextWindow);
4579
5011
  params.isCompaction = compaction;
4580
5012
  if (debug && params.messages.length < before) {
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}`);
5013
+ log17(
5014
+ `WS context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages tools=${params.tools ? Object.keys(params.tools).length : 0}`
5015
+ );
4582
5016
  }
4583
5017
  }
4584
5018
  if (debug) {
4585
5019
  const effort = body.reasoning?.effort;
4586
- log17(`WS model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
5020
+ log17(
5021
+ `WS model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`
5022
+ );
4587
5023
  }
4588
- await streamResponsesResponse(languageModel, params, modelId, sendWsEvent, (summary) => {
4589
- if (debug) {
4590
- const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
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)}`);
4592
- }
4593
- }, (progress) => {
4594
- if (debug) {
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)}`);
5024
+ await streamResponsesResponse(
5025
+ languageModel,
5026
+ params,
5027
+ modelId,
5028
+ sendWsEvent,
5029
+ (summary) => {
5030
+ trackUsage(modelId, summary.inputTokens ?? 0, summary.outputTokens ?? 0);
5031
+ if (debug) {
5032
+ const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
5033
+ log17(
5034
+ `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)}`
5035
+ );
5036
+ }
5037
+ },
5038
+ (progress) => {
5039
+ if (debug) {
5040
+ log17(
5041
+ `WS response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`
5042
+ );
5043
+ }
4596
5044
  }
4597
- });
5045
+ );
4598
5046
  } catch (err) {
4599
5047
  const msg = formatUpstreamError(err);
4600
5048
  const status = upstreamHttpStatus(err);
@@ -4706,7 +5154,6 @@ function codexProviderEnvKey(providerId) {
4706
5154
  }
4707
5155
 
4708
5156
  // src/apps/codex/session.ts
4709
- init_paths();
4710
5157
  import {
4711
5158
  copyFileSync,
4712
5159
  existsSync as existsSync3,
@@ -4912,7 +5359,6 @@ import { execFileSync, execSync, spawn } from "child_process";
4912
5359
  import { existsSync as existsSync4 } from "fs";
4913
5360
  import { homedir as homedir4 } from "os";
4914
5361
  import { join as join4 } from "path";
4915
- init_config();
4916
5362
  var isWindows = process.platform === "win32";
4917
5363
  var CODEX_CI_ENV_VARS = [
4918
5364
  "CI",
@@ -5029,7 +5475,9 @@ import pc6 from "picocolors";
5029
5475
  import * as p7 from "@clack/prompts";
5030
5476
  async function pickCodexProvider(providers, prefs, hasFavorites = false, initialProviderId, agentLabel = "Codex") {
5031
5477
  if (providers.length === 0 && !hasFavorites) return null;
5032
- const options = providers.map((lp) => providerSelectOption(lp));
5478
+ const options = providers.map(
5479
+ (lp) => providerSelectOption(lp)
5480
+ );
5033
5481
  if (hasFavorites) {
5034
5482
  options.unshift({
5035
5483
  value: "__favorites__",
@@ -5037,7 +5485,13 @@ async function pickCodexProvider(providers, prefs, hasFavorites = false, initial
5037
5485
  hint: `${prefs.favoriteModels?.length ?? 0} saved favorites`
5038
5486
  });
5039
5487
  }
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;
5488
+ const initial = initialProviderId && options.some((o) => o.value === initialProviderId) ? initialProviderId : (
5489
+ // When favorites exist, default to the Favorites Catalog so the gateway
5490
+ // exposes ALL saved models to the client picker — not just the last
5491
+ // single-provider selection (remembered via lastCodexProvider), which
5492
+ // would otherwise collapse the catalog to a single model.
5493
+ hasFavorites ? "__favorites__" : prefs.lastCodexProvider && options.some((o) => o.value === prefs.lastCodexProvider) ? prefs.lastCodexProvider : options[0].value
5494
+ );
5041
5495
  const chosen = await p7.select({
5042
5496
  message: `Which provider for ${agentLabel}?`,
5043
5497
  options,
@@ -5116,7 +5570,8 @@ function rejectManagedFlags(codexArgs) {
5116
5570
  if (takesValue.has(arg)) i++;
5117
5571
  continue;
5118
5572
  }
5119
- if (arg.startsWith("--profile=") || arg.startsWith("--model=") || arg.startsWith("--provider=") || arg.startsWith("-m=")) continue;
5573
+ if (arg.startsWith("--profile=") || arg.startsWith("--model=") || arg.startsWith("--provider=") || arg.startsWith("-m="))
5574
+ continue;
5120
5575
  out.push(arg);
5121
5576
  }
5122
5577
  return out;
@@ -5227,14 +5682,15 @@ async function resolveFavorite(fav, ctx) {
5227
5682
  apiKey: await resolveLocalProviderApiKey(found.provider) ?? "",
5228
5683
  authType: found.provider.authType,
5229
5684
  oauthAccountId: found.provider.oauthAccountId,
5230
- providerData: found.provider.providerData
5685
+ providerData: found.provider.providerData,
5686
+ headers: found.provider.headers
5231
5687
  };
5232
5688
  }
5233
5689
  return void 0;
5234
5690
  }
5235
5691
  async function buildFavoritesList(starting, favorites, ctx, max = 20, options = {}) {
5236
- const seen = /* @__PURE__ */ new Set();
5237
5692
  const out = [];
5693
+ const seen = /* @__PURE__ */ new Set();
5238
5694
  if (starting) {
5239
5695
  seen.add(`${starting.providerId}::${starting.model.id}`);
5240
5696
  out.push(starting);
@@ -5362,11 +5818,7 @@ async function resolveCodexFavorites(activeProvider, selectedModel, compatible,
5362
5818
  { providerId: activeProvider.id, modelId: selectedModel.id },
5363
5819
  ctx
5364
5820
  );
5365
- const { resolved, droppedFavorites } = await buildFavoritesList(
5366
- startingResolved,
5367
- favorites,
5368
- ctx
5369
- );
5821
+ const { resolved, droppedFavorites } = await buildFavoritesList(startingResolved, favorites, ctx);
5370
5822
  if (droppedFavorites.length > 0) {
5371
5823
  p8.log.warn(
5372
5824
  `Skipped ${droppedFavorites.length} stale/unauthorized favorite(s): ${droppedFavorites.map((f) => `${f.providerId}:${f.modelId}`).join(", ")}`
@@ -5403,10 +5855,7 @@ function buildCloudCodeProxyRoute(model, apiKey, providerData) {
5403
5855
  };
5404
5856
  }
5405
5857
  function buildOAuthAnthropicProxyRoute(model, apiKey, providerId, providerData) {
5406
- const aliasId = claudeCodeClientModelId(
5407
- aliasModelId(model.id, providerId),
5408
- model.contextWindow
5409
- );
5858
+ const aliasId = claudeCodeClientModelId(aliasModelId(model.id, providerId), model.contextWindow);
5410
5859
  return {
5411
5860
  aliasId,
5412
5861
  realModelId: model.upstreamModelId || model.id,
@@ -5422,15 +5871,28 @@ function buildOAuthAnthropicProxyRoute(model, apiKey, providerId, providerData)
5422
5871
  refreshToken: () => resolveProviderCredential(providerId, oauthAuthRef(providerId))
5423
5872
  };
5424
5873
  }
5425
- async function partitionAndStartCloudCodeBackend(items, toOutput, trace) {
5874
+ async function partitionAndStartCloudCodeBackend(items, toOutput, trace, app) {
5426
5875
  if (items.length === 0) return { backendItems: [], backend: null };
5427
5876
  const proxyRoutes = items.map(
5428
- (item) => item.model.modelFormat === "cloud-code" ? buildCloudCodeProxyRoute(item.model, item.apiKey, item.providerData ?? {}) : buildOAuthAnthropicProxyRoute(item.model, item.apiKey, item.providerId, item.providerData ?? {})
5877
+ (item) => item.model.modelFormat === "cloud-code" ? buildCloudCodeProxyRoute(item.model, item.apiKey, item.providerData ?? {}) : buildOAuthAnthropicProxyRoute(
5878
+ item.model,
5879
+ item.apiKey,
5880
+ item.providerId,
5881
+ item.providerData ?? {}
5882
+ )
5883
+ );
5884
+ if (app) for (const route of proxyRoutes) route.app = app;
5885
+ const backend = await startCloudCodeCatalogBackend(
5886
+ proxyRoutes,
5887
+ proxyRoutes[0].aliasId,
5888
+ trace,
5889
+ app
5429
5890
  );
5430
- const backend = await startCloudCodeCatalogBackend(proxyRoutes, proxyRoutes[0].aliasId, trace);
5431
5891
  return {
5432
5892
  backend,
5433
- backendItems: proxyRoutes.map((proxyRoute, index) => toOutput(proxyRoute, backend, items[index]))
5893
+ backendItems: proxyRoutes.map(
5894
+ (proxyRoute, index) => toOutput(proxyRoute, backend, items[index])
5895
+ )
5434
5896
  };
5435
5897
  }
5436
5898
  async function buildSingleModelCloudCodeRoute(model, apiKey, providerId, providerData, trace) {
@@ -5438,8 +5900,8 @@ async function buildSingleModelCloudCodeRoute(model, apiKey, providerId, provide
5438
5900
  const backend = await startCloudCodeCatalogBackend([proxyRoute], proxyRoute.aliasId, trace);
5439
5901
  return { proxyRoute, backend };
5440
5902
  }
5441
- async function startCloudCodeCatalogBackend(routes, startingAliasId, trace) {
5442
- const handle = await startProxyCatalog(routes, startingAliasId, trace ?? false);
5903
+ async function startCloudCodeCatalogBackend(routes, startingAliasId, trace, app) {
5904
+ const handle = await startProxyCatalog(routes, startingAliasId, trace ?? false, { app });
5443
5905
  return { port: handle.port, token: handle.token, handle };
5444
5906
  }
5445
5907
 
@@ -5513,12 +5975,15 @@ async function writeLaunchArtifacts(route, selectedModel, providerName, proxyPor
5513
5975
  reasoning: route.reasoning,
5514
5976
  interleavedReasoningField: route.interleavedReasoningField
5515
5977
  });
5516
- writeOverlayFile(profilePath, buildCodexProfileToml({
5517
- route,
5518
- proxyPort,
5519
- catalogPath,
5520
- modelReasoningEffort: caps.defaultLevel || void 0
5521
- }));
5978
+ writeOverlayFile(
5979
+ profilePath,
5980
+ buildCodexProfileToml({
5981
+ route,
5982
+ proxyPort,
5983
+ catalogPath,
5984
+ modelReasoningEffort: caps.defaultLevel || void 0
5985
+ })
5986
+ );
5522
5987
  return { profilePath, catalogPath };
5523
5988
  }
5524
5989
  async function writeFavoritesLaunchArtifacts(resolved, starting, proxyPort) {
@@ -5535,12 +6000,38 @@ async function writeFavoritesLaunchArtifacts(resolved, starting, proxyPort) {
5535
6000
  upstreamModelId: model.upstreamModelId || model.id,
5536
6001
  apiKey: ""
5537
6002
  };
5538
- writeOverlayFile(profilePath, buildCodexProfileToml({
5539
- route: dummyRoute,
5540
- proxyPort,
5541
- catalogPath,
5542
- modelReasoningEffort: defaultReasoningEffortForFavorite(starting)
5543
- }));
6003
+ writeOverlayFile(
6004
+ profilePath,
6005
+ buildCodexProfileToml({
6006
+ route: dummyRoute,
6007
+ proxyPort,
6008
+ catalogPath,
6009
+ modelReasoningEffort: defaultReasoningEffortForFavorite(starting)
6010
+ })
6011
+ );
6012
+ return { profilePath, catalogPath };
6013
+ }
6014
+ async function writeAllModelsLaunchArtifacts(activeProvider, selectedModel, routable, proxyPort) {
6015
+ const catalogPath = getCatalogOutputPath(activeProvider.id);
6016
+ const catalog = buildCatalogFile(routable, activeProvider.name);
6017
+ writeOverlayFile(catalogPath, serializeCatalog(catalog));
6018
+ const profilePath = getProfileOutputPath();
6019
+ const dummyRoute = {
6020
+ tier: "proxy",
6021
+ modelId: selectedModel.id,
6022
+ providerId: "anygate-proxy",
6023
+ npm: selectedModel.npm ?? "@ai-sdk/openai-compatible",
6024
+ upstreamModelId: selectedModel.upstreamModelId || selectedModel.id,
6025
+ apiKey: ""
6026
+ };
6027
+ writeOverlayFile(
6028
+ profilePath,
6029
+ buildCodexProfileToml({
6030
+ route: dummyRoute,
6031
+ proxyPort,
6032
+ catalogPath
6033
+ })
6034
+ );
5544
6035
  return { profilePath, catalogPath };
5545
6036
  }
5546
6037
  function printCodexCleanupReminder(hadProxy) {
@@ -5618,19 +6109,24 @@ async function runCodexVertexLaunch(passthroughArgs, trace) {
5618
6109
  const debugLogPath = getCodexProxyDebugLogPath();
5619
6110
  let proxyHandle = null;
5620
6111
  try {
5621
- p9.log.info(`Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`);
6112
+ p9.log.info(
6113
+ `Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`
6114
+ );
5622
6115
  proxyHandle = await startCodexProxy(allRoutes, { debug: trace });
5623
6116
  const proxyPort = proxyHandle.port;
5624
6117
  const catalogPath = getCatalogOutputPath("vertex");
5625
6118
  writeOverlayFile(catalogPath, serializeCatalog(buildCatalogFile(allModels, "Vertex AI")));
5626
6119
  const profilePath = getProfileOutputPath();
5627
6120
  const caps = getReasoningCapabilities(VERTEX_ANTHROPIC_NPM, selectedEntry.id);
5628
- writeOverlayFile(profilePath, buildCodexProfileToml({
5629
- route: startingRoute,
5630
- proxyPort,
5631
- catalogPath,
5632
- modelReasoningEffort: caps.defaultLevel || void 0
5633
- }));
6121
+ writeOverlayFile(
6122
+ profilePath,
6123
+ buildCodexProfileToml({
6124
+ route: startingRoute,
6125
+ proxyPort,
6126
+ catalogPath,
6127
+ modelReasoningEffort: caps.defaultLevel || void 0
6128
+ })
6129
+ );
5634
6130
  writeSessionLock({
5635
6131
  pid: process.pid,
5636
6132
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -5692,7 +6188,9 @@ async function runCodexCommand(codexArgs, trace = false, launch = {}) {
5692
6188
  console.error(pc8.red("anygate codex --vertex requires an interactive terminal."));
5693
6189
  return 1;
5694
6190
  }
5695
- console.error(pc8.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`));
6191
+ console.error(
6192
+ pc8.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`)
6193
+ );
5696
6194
  console.error("Run anygate codex --restore to clean up, or wait for it to finish.");
5697
6195
  return 1;
5698
6196
  }
@@ -5700,8 +6198,9 @@ async function runCodexCommand(codexArgs, trace = false, launch = {}) {
5700
6198
  return runCodexVertexLaunch(passthroughArgs, trace);
5701
6199
  }
5702
6200
  const prefs = loadPreferences();
6201
+ const launchAllModels = Boolean(launch.launchAllModels || launch.launchModel === "All");
5703
6202
  const launchPlan = planLaunchWizard({
5704
- explicit: { providerId: launch.launchProvider, modelId: launch.launchModel },
6203
+ explicit: launchAllModels ? { providerId: launch.launchProvider, allModels: true } : { providerId: launch.launchProvider, modelId: launch.launchModel },
5705
6204
  childArgs: passthroughArgs,
5706
6205
  agent: "codex",
5707
6206
  prefs
@@ -5717,12 +6216,16 @@ Error: ${launchPlan.error}
5717
6216
  const sessionCheck = checkSessionLock(isTty || allowNonTty);
5718
6217
  if (!sessionCheck.ok) {
5719
6218
  if (sessionCheck.reason === "non_tty") {
5720
- console.error(pc8.red(
5721
- "anygate codex requires an interactive terminal (or use --provider and --model for non-interactive launch)."
5722
- ));
6219
+ console.error(
6220
+ pc8.red(
6221
+ "anygate codex requires an interactive terminal (or use --provider and --model for non-interactive launch)."
6222
+ )
6223
+ );
5723
6224
  return 1;
5724
6225
  }
5725
- console.error(pc8.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`));
6226
+ console.error(
6227
+ pc8.yellow(`Another anygate codex session may be running (pid ${sessionCheck.lock.pid}).`)
6228
+ );
5726
6229
  console.error("Run anygate codex --restore to clean up, or wait for it to finish.");
5727
6230
  return 1;
5728
6231
  }
@@ -5762,13 +6265,23 @@ Error: ${launchPlan.error}
5762
6265
  if (compatible.length === 0) {
5763
6266
  if (!configOnly) {
5764
6267
  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.");
6268
+ p9.log.info(
6269
+ "Add a provider with anygate providers add, or sign in with anygate providers auth openai."
6270
+ );
5766
6271
  }
5767
6272
  return 0;
5768
6273
  }
5769
6274
  const favorites = prefs.favoriteModels ?? [];
5770
- const favoritesActive = favorites.length > 0 && !launchPlan.skip;
5771
- if (favoritesActive && !configOnly) {
6275
+ const hasFavorites = favorites.length > 0;
6276
+ let catalogMode = false;
6277
+ if (launchPlan.skip && launchPlan.target && launchPlan.target.allModels) {
6278
+ catalogMode = "provider-all";
6279
+ }
6280
+ let favoritesActive = false;
6281
+ if (configOnly && hasFavorites && !launchPlan.skip) {
6282
+ favoritesActive = true;
6283
+ }
6284
+ if (hasFavorites && !configOnly && !launchPlan.skip) {
5772
6285
  p9.log.info(
5773
6286
  `Favorites mode active \u2014 Codex picker will show ${favorites.length + 1} models (1 starting + ${favorites.length} favorites).`
5774
6287
  );
@@ -5777,22 +6290,41 @@ Error: ${launchPlan.error}
5777
6290
  let activeProvider = compatible.find((lp) => lp.id === prefs.lastCodexProvider) ?? compatible[0];
5778
6291
  let selectedModel = activeProvider.models.find((m) => m.id === prefs.lastCodexModel) ?? activeProvider.models[0];
5779
6292
  if (!configOnly && launchPlan.skip && launchPlan.target) {
5780
- const resolved = findProviderAndModel(compatible, launchPlan.target);
5781
- if (!resolved) {
5782
- p9.log.error(
5783
- `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
5784
- );
5785
- return 1;
5786
- }
5787
- activeProvider = resolved.provider;
5788
- selectedModel = resolved.model;
5789
- if (!agentStdout) {
5790
- p9.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
6293
+ if (launchPlan.target.allModels) {
6294
+ const foundProvider = compatible.find((lp) => lp.id === launchPlan.target.providerId);
6295
+ if (!foundProvider) {
6296
+ p9.log.error(`Provider not found: ${launchPlan.target.providerId}`);
6297
+ return 1;
6298
+ }
6299
+ activeProvider = foundProvider;
6300
+ selectedModel = activeProvider.models[0];
6301
+ catalogMode = "provider-all";
6302
+ if (!agentStdout) {
6303
+ p9.log.step(`Using all ${activeProvider.models.length} models from ${activeProvider.name}`);
6304
+ }
6305
+ } else {
6306
+ const resolved = findProviderAndModel(compatible, launchPlan.target);
6307
+ if (!resolved) {
6308
+ p9.log.error(
6309
+ `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
6310
+ );
6311
+ return 1;
6312
+ }
6313
+ activeProvider = resolved.provider;
6314
+ selectedModel = resolved.model;
6315
+ if (!agentStdout) {
6316
+ p9.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
6317
+ }
5791
6318
  }
5792
6319
  } else if (!configOnly) {
5793
6320
  let currentInitialProvider = prefs.lastCodexProvider && compatible.some((o) => o.id === prefs.lastCodexProvider) ? prefs.lastCodexProvider : compatible[0].id;
5794
6321
  while (true) {
5795
- const pickedProvider = await pickCodexProvider(compatible, prefs, favoritesActive, currentInitialProvider);
6322
+ const pickedProvider = await pickCodexProvider(
6323
+ compatible,
6324
+ prefs,
6325
+ hasFavorites,
6326
+ currentInitialProvider
6327
+ );
5796
6328
  if (!pickedProvider) return 0;
5797
6329
  if (pickedProvider === "__favorites__") {
5798
6330
  const favoritePick = await pickFavoriteStartingModel(
@@ -5805,9 +6337,36 @@ Error: ${launchPlan.error}
5805
6337
  if (favoritePick === "cancelled" || favoritePick === "unavailable") return 0;
5806
6338
  activeProvider = favoritePick.provider;
5807
6339
  selectedModel = favoritePick.model;
6340
+ catalogMode = "favorites";
6341
+ favoritesActive = true;
5808
6342
  break;
5809
6343
  } else {
5810
6344
  activeProvider = pickedProvider;
6345
+ const modelModeChoice = await p9.select({
6346
+ message: `Launch mode for ${activeProvider.name}?`,
6347
+ options: [
6348
+ {
6349
+ value: "specific",
6350
+ label: "One model",
6351
+ hint: "Pick a specific model"
6352
+ },
6353
+ {
6354
+ value: "all",
6355
+ label: `All models (${activeProvider.models.length})`,
6356
+ hint: "Every model from this provider in the picker"
6357
+ },
6358
+ navOption("__back__", "\u2190 Back", "Choose a different provider")
6359
+ ]
6360
+ });
6361
+ if (p9.isCancel(modelModeChoice) || modelModeChoice === "__back__") {
6362
+ currentInitialProvider = activeProvider.id;
6363
+ continue;
6364
+ }
6365
+ if (modelModeChoice === "all") {
6366
+ catalogMode = "provider-all";
6367
+ selectedModel = activeProvider.models[0];
6368
+ break;
6369
+ }
5811
6370
  const pickedModelResult = await pickCodexModel(activeProvider, prefs);
5812
6371
  if (pickedModelResult === "back") {
5813
6372
  currentInitialProvider = activeProvider.id;
@@ -5855,7 +6414,64 @@ Error: ${launchPlan.error}
5855
6414
  let cloudCodeBackendFav = null;
5856
6415
  try {
5857
6416
  let proxyPort;
5858
- if (favoritesActive && resolvedFavorites.length > 0) {
6417
+ if (catalogMode === "provider-all") {
6418
+ const routable = routableModelsForProvider(activeProvider, "codex");
6419
+ const backendModels = routable.filter((m) => needsCloudCodeBackend(m, activeProvider.authType));
6420
+ const regularModels = routable.filter((m) => !needsCloudCodeBackend(m, activeProvider.authType));
6421
+ let backendCodexRoutes = [];
6422
+ if (backendModels.length > 0) {
6423
+ const partitioned = await partitionAndStartCloudCodeBackend(
6424
+ backendModels.map((model) => ({
6425
+ providerId: activeProvider.id,
6426
+ model,
6427
+ apiKey,
6428
+ oauthAccountId: activeProvider.oauthAccountId,
6429
+ providerData: activeProvider.providerData ?? {}
6430
+ })),
6431
+ (cr, backend) => ({
6432
+ modelId: cr.aliasId,
6433
+ npm: "@ai-sdk/anthropic",
6434
+ apiKey: backend.token,
6435
+ baseURL: `http://127.0.0.1:${backend.port}`,
6436
+ upstreamModelId: cr.aliasId,
6437
+ providerId: cr.providerId ?? activeProvider.id,
6438
+ authType: "oauth",
6439
+ oauthAccountId: activeProvider.oauthAccountId,
6440
+ providerData: activeProvider.providerData ?? {},
6441
+ contextWindow: cr.contextWindow,
6442
+ supportedParameters: cr.supportedParameters,
6443
+ reasoning: cr.reasoning,
6444
+ interleavedReasoningField: cr.interleavedReasoningField
6445
+ }),
6446
+ trace,
6447
+ "codex"
6448
+ );
6449
+ cloudCodeBackendFav = partitioned.backend;
6450
+ backendCodexRoutes = partitioned.backendItems;
6451
+ }
6452
+ const regularRoutes = regularModels.map((model) => {
6453
+ const r = resolveCodexRoute(activeProvider, model, apiKey);
6454
+ return {
6455
+ modelId: r.modelId,
6456
+ npm: r.npm,
6457
+ apiKey: r.apiKey,
6458
+ baseURL: r.baseURL,
6459
+ upstreamModelId: r.upstreamModelId,
6460
+ providerId: r.providerId,
6461
+ authType: r.authType,
6462
+ oauthAccountId: r.oauthAccountId,
6463
+ providerData: r.providerData,
6464
+ contextWindow: r.contextWindow,
6465
+ supportedParameters: r.supportedParameters,
6466
+ reasoning: r.reasoning,
6467
+ interleavedReasoningField: r.interleavedReasoningField,
6468
+ headers: r.headers
6469
+ };
6470
+ });
6471
+ const allRoutes = [...backendCodexRoutes, ...regularRoutes];
6472
+ proxyHandle = await startCodexProxy(allRoutes, { requireAuth: true, debug: trace });
6473
+ proxyPort = proxyHandle.port;
6474
+ } else if (favoritesActive && resolvedFavorites.length > 0) {
5859
6475
  const needsBackend = (r) => {
5860
6476
  const m = r.model;
5861
6477
  const prov = providersById.get(r.providerId);
@@ -5888,7 +6504,8 @@ Error: ${launchPlan.error}
5888
6504
  providerData: original.providerData,
5889
6505
  contextWindow: cr.contextWindow
5890
6506
  }),
5891
- trace
6507
+ trace,
6508
+ "codex"
5892
6509
  );
5893
6510
  cloudCodeBackendFav = partitioned.backend;
5894
6511
  backendCodexRoutes = partitioned.backendItems;
@@ -5907,21 +6524,26 @@ Error: ${launchPlan.error}
5907
6524
  trace
5908
6525
  );
5909
6526
  cloudCodeBackend = backend;
5910
- proxyHandle = await startCodexProxy([{
5911
- modelId: cloudRoute.aliasId,
5912
- npm: "@ai-sdk/anthropic",
5913
- apiKey: cloudCodeBackend.token,
5914
- baseURL: `http://127.0.0.1:${cloudCodeBackend.port}`,
5915
- upstreamModelId: cloudRoute.aliasId,
5916
- providerId: route.providerId,
5917
- authType: route.authType,
5918
- oauthAccountId: route.oauthAccountId,
5919
- providerData,
5920
- contextWindow: route.contextWindow,
5921
- supportedParameters: route.supportedParameters,
5922
- reasoning: route.reasoning,
5923
- interleavedReasoningField: route.interleavedReasoningField
5924
- }], { debug: trace });
6527
+ proxyHandle = await startCodexProxy(
6528
+ [
6529
+ {
6530
+ modelId: cloudRoute.aliasId,
6531
+ npm: "@ai-sdk/anthropic",
6532
+ apiKey: cloudCodeBackend.token,
6533
+ baseURL: `http://127.0.0.1:${cloudCodeBackend.port}`,
6534
+ upstreamModelId: cloudRoute.aliasId,
6535
+ providerId: route.providerId,
6536
+ authType: route.authType,
6537
+ oauthAccountId: route.oauthAccountId,
6538
+ providerData,
6539
+ contextWindow: route.contextWindow,
6540
+ supportedParameters: route.supportedParameters,
6541
+ reasoning: route.reasoning,
6542
+ interleavedReasoningField: route.interleavedReasoningField
6543
+ }
6544
+ ],
6545
+ { debug: trace }
6546
+ );
5925
6547
  proxyPort = proxyHandle.port;
5926
6548
  } else if (route.authType === "oauth" && selectedModel.modelFormat === "anthropic") {
5927
6549
  const providerData = activeProvider.providerData ?? {};
@@ -5933,44 +6555,59 @@ Error: ${launchPlan.error}
5933
6555
  trace
5934
6556
  );
5935
6557
  cloudCodeBackend = backend;
5936
- proxyHandle = await startCodexProxy([{
5937
- modelId: oauthRoute.aliasId,
5938
- npm: "@ai-sdk/anthropic",
5939
- apiKey: cloudCodeBackend.token,
5940
- baseURL: `http://127.0.0.1:${cloudCodeBackend.port}`,
5941
- upstreamModelId: oauthRoute.aliasId,
5942
- providerId: route.providerId,
5943
- authType: route.authType,
5944
- oauthAccountId: route.oauthAccountId,
5945
- providerData,
5946
- contextWindow: route.contextWindow,
5947
- supportedParameters: route.supportedParameters,
5948
- reasoning: route.reasoning,
5949
- interleavedReasoningField: route.interleavedReasoningField
5950
- }], { debug: trace });
6558
+ proxyHandle = await startCodexProxy(
6559
+ [
6560
+ {
6561
+ modelId: oauthRoute.aliasId,
6562
+ npm: "@ai-sdk/anthropic",
6563
+ apiKey: cloudCodeBackend.token,
6564
+ baseURL: `http://127.0.0.1:${cloudCodeBackend.port}`,
6565
+ upstreamModelId: oauthRoute.aliasId,
6566
+ providerId: route.providerId,
6567
+ authType: route.authType,
6568
+ oauthAccountId: route.oauthAccountId,
6569
+ providerData,
6570
+ contextWindow: route.contextWindow,
6571
+ supportedParameters: route.supportedParameters,
6572
+ reasoning: route.reasoning,
6573
+ interleavedReasoningField: route.interleavedReasoningField
6574
+ }
6575
+ ],
6576
+ { debug: trace }
6577
+ );
5951
6578
  proxyPort = proxyHandle.port;
5952
6579
  } else if (route.tier === "proxy") {
5953
- proxyHandle = await startCodexProxy([{
5954
- modelId: route.modelId,
5955
- npm: route.npm,
5956
- apiKey: route.apiKey,
5957
- baseURL: route.baseURL,
5958
- upstreamModelId: route.upstreamModelId,
5959
- providerId: route.providerId,
5960
- authType: route.authType,
5961
- oauthAccountId: route.oauthAccountId,
5962
- providerData: route.providerData,
5963
- supportedParameters: route.supportedParameters,
5964
- reasoning: route.reasoning,
5965
- interleavedReasoningField: route.interleavedReasoningField,
5966
- headers: route.headers
5967
- }], { debug: trace });
6580
+ proxyHandle = await startCodexProxy(
6581
+ [
6582
+ {
6583
+ modelId: route.modelId,
6584
+ npm: route.npm,
6585
+ apiKey: route.apiKey,
6586
+ baseURL: route.baseURL,
6587
+ upstreamModelId: route.upstreamModelId,
6588
+ providerId: route.providerId,
6589
+ authType: route.authType,
6590
+ oauthAccountId: route.oauthAccountId,
6591
+ providerData: route.providerData,
6592
+ supportedParameters: route.supportedParameters,
6593
+ reasoning: route.reasoning,
6594
+ interleavedReasoningField: route.interleavedReasoningField,
6595
+ headers: route.headers
6596
+ }
6597
+ ],
6598
+ { debug: trace }
6599
+ );
5968
6600
  proxyPort = proxyHandle.port;
5969
6601
  }
5970
6602
  const startingFavorite = resolvedFavorites.find(
5971
6603
  (r) => r.providerId === activeProvider.id && r.model.id === selectedModel.id
5972
6604
  ) ?? resolvedFavorites[0];
5973
- const { profilePath, catalogPath } = favoritesActive && resolvedFavorites.length > 0 && proxyPort && startingFavorite ? await writeFavoritesLaunchArtifacts(resolvedFavorites, startingFavorite, proxyPort) : await writeLaunchArtifacts(route, selectedModel, activeProvider.name, proxyPort);
6605
+ const { profilePath, catalogPath } = catalogMode === "provider-all" && proxyPort ? await writeAllModelsLaunchArtifacts(
6606
+ activeProvider,
6607
+ selectedModel,
6608
+ routableModelsForProvider(activeProvider, "codex"),
6609
+ proxyPort
6610
+ ) : favoritesActive && resolvedFavorites.length > 0 && proxyPort && startingFavorite ? await writeFavoritesLaunchArtifacts(resolvedFavorites, startingFavorite, proxyPort) : await writeLaunchArtifacts(route, selectedModel, activeProvider.name, proxyPort);
5974
6611
  writeSessionLock({
5975
6612
  pid: process.pid,
5976
6613
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -5984,8 +6621,22 @@ Error: ${launchPlan.error}
5984
6621
  console.log("");
5985
6622
  console.log(pc8.bold(pc8.cyan(" CONFIG PREVIEW \u2014 anygate codex")));
5986
6623
  console.log("");
5987
- if (favoritesActive && resolvedFavorites.length > 0) {
5988
- console.log(` ${pc8.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`);
6624
+ if (catalogMode === "provider-all") {
6625
+ const allModels = routableModelsForProvider(activeProvider, "codex");
6626
+ console.log(
6627
+ ` ${pc8.bold("Mode:")} Provider Catalog (${allModels.length} model${allModels.length !== 1 ? "s" : ""})`
6628
+ );
6629
+ console.log(` ${pc8.bold("Provider:")} ${activeProvider.name}`);
6630
+ console.log(` ${pc8.bold("Starting model:")} ${selectedModel.id}`);
6631
+ console.log("");
6632
+ console.log(` ${pc8.bold("Models:")}`);
6633
+ for (const m of allModels) {
6634
+ console.log(` ${pc8.cyan(m.id)}`);
6635
+ }
6636
+ } else if (favoritesActive && resolvedFavorites.length > 0) {
6637
+ console.log(
6638
+ ` ${pc8.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`
6639
+ );
5989
6640
  console.log("");
5990
6641
  console.log(` ${pc8.bold("Models:")}`);
5991
6642
  for (const r of resolvedFavorites) {
@@ -6015,6 +6666,7 @@ Error: ${launchPlan.error}
6015
6666
  }
6016
6667
  }
6017
6668
  const favoritesLaunch = favoritesActive && resolvedFavorites.length > 0;
6669
+ const providerAllLaunch = catalogMode === "provider-all";
6018
6670
  const launchModelId = favoritesLaunch ? codexCliFavoritesSlug(activeProvider.id, selectedModel.id) : selectedModel.id;
6019
6671
  if (!agentStdout) {
6020
6672
  logActiveModel(modelLabel, launchModelId);
@@ -6029,11 +6681,9 @@ Error: ${launchPlan.error}
6029
6681
  upstreamModelId: selectedModel.upstreamModelId || selectedModel.id,
6030
6682
  apiKey: ""
6031
6683
  };
6032
- const childEnv = buildCodexChildEnv(
6033
- favoritesLaunch || route.tier === "cloud-code" ? dummyRoute : route,
6034
- proxyPort
6035
- );
6036
- const hadProxy = (route.tier === "proxy" || route.tier === "cloud-code" || favoritesLaunch) && !!proxyPort;
6684
+ const useProxyRoute = favoritesLaunch || providerAllLaunch || route.tier === "cloud-code";
6685
+ const childEnv = buildCodexChildEnv(useProxyRoute ? dummyRoute : route, proxyPort);
6686
+ const hadProxy = (route.tier === "proxy" || route.tier === "cloud-code" || favoritesLaunch || providerAllLaunch) && !!proxyPort;
6037
6687
  const exitCode = await launchCodex(launchModelId, childEnv, passthroughArgs);
6038
6688
  if (trace) printTraceLog(debugLogPath);
6039
6689
  printCodexCleanupReminder(hadProxy);
@@ -6053,7 +6703,7 @@ Error: ${launchPlan.error}
6053
6703
  // src/cli/codex.ts
6054
6704
  async function handleCodexCommand(parsed) {
6055
6705
  if (parsed.showVersion) {
6056
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
6706
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
6057
6707
  console.log(VERSION2);
6058
6708
  return 0;
6059
6709
  }
@@ -6064,6 +6714,7 @@ async function handleCodexCommand(parsed) {
6064
6714
  return runCodexCommand(parsed.claudeArgs ?? [], parsed.trace ?? false, {
6065
6715
  launchProvider: parsed.launchProvider,
6066
6716
  launchModel: parsed.launchModel,
6717
+ launchAllModels: parsed.launchAllModels || parsed.launchModel === "All",
6067
6718
  vertex: parsed.vertex
6068
6719
  });
6069
6720
  }
@@ -6071,7 +6722,6 @@ async function handleCodexCommand(parsed) {
6071
6722
  // src/apps/codex/app.ts
6072
6723
  import pc9 from "picocolors";
6073
6724
  import * as p10 from "@clack/prompts";
6074
- init_config();
6075
6725
 
6076
6726
  // src/apps/codex/app-provider-routes.ts
6077
6727
  function codexRouteToProxyRoute(provider, model, apiKey) {
@@ -6130,7 +6780,8 @@ async function buildCodexAppProviderCatalogRoutes(provider, apiKey, selectedMode
6130
6780
  interleavedReasoningField: original.model.interleavedReasoningField,
6131
6781
  headers: provider.headers
6132
6782
  }),
6133
- trace
6783
+ trace,
6784
+ "codex-app"
6134
6785
  );
6135
6786
  for (let index = 0; index < backendModels.length; index++) {
6136
6787
  const model = backendModels[index];
@@ -6312,7 +6963,9 @@ function applyAppConfigPatch(spec, configPath = getCodexConfigPath()) {
6312
6963
  try {
6313
6964
  existing = parseCodexConfig(existingText);
6314
6965
  } catch (err) {
6315
- throw new Error(`Invalid existing Codex config at ${configPath}: ${err instanceof Error ? err.message : err}`);
6966
+ throw new Error(
6967
+ `Invalid existing Codex config at ${configPath}: ${err instanceof Error ? err.message : err}`
6968
+ );
6316
6969
  }
6317
6970
  const merged = mergeAppConfig(existing, spec);
6318
6971
  const text4 = `${stringify(merged)}
@@ -6350,9 +7003,24 @@ function restoreConfigFromState(state, configPath = getCodexConfigPath()) {
6350
7003
  if ("hadOpenAIBaseUrl" in state) {
6351
7004
  applyRestoreKey(config, "openai_base_url", Boolean(state.hadOpenAIBaseUrl), state.openAIBaseUrl);
6352
7005
  }
6353
- applyRestoreKey(config, "model_reasoning_effort", state.hadModelReasoningEffort, state.modelReasoningEffort);
6354
- applyRestoreNumber(config, "model_context_window", state.hadModelContextWindow ?? false, state.modelContextWindow);
6355
- applyRestoreNumber(config, "model_auto_compact_token_limit", state.hadModelAutoCompactTokenLimit ?? false, state.modelAutoCompactTokenLimit);
7006
+ applyRestoreKey(
7007
+ config,
7008
+ "model_reasoning_effort",
7009
+ state.hadModelReasoningEffort,
7010
+ state.modelReasoningEffort
7011
+ );
7012
+ applyRestoreNumber(
7013
+ config,
7014
+ "model_context_window",
7015
+ state.hadModelContextWindow ?? false,
7016
+ state.modelContextWindow
7017
+ );
7018
+ applyRestoreNumber(
7019
+ config,
7020
+ "model_auto_compact_token_limit",
7021
+ state.hadModelAutoCompactTokenLimit ?? false,
7022
+ state.modelAutoCompactTokenLimit
7023
+ );
6356
7024
  const sidecar = getCodexAppSidecarProfilePath();
6357
7025
  if (existsSync5(sidecar)) {
6358
7026
  try {
@@ -6379,14 +7047,7 @@ function previewAppConfigToml(spec) {
6379
7047
  }
6380
7048
 
6381
7049
  // src/apps/codex/app-session.ts
6382
- import {
6383
- copyFileSync as copyFileSync2,
6384
- existsSync as existsSync6,
6385
- mkdirSync as mkdirSync4,
6386
- readdirSync as readdirSync2,
6387
- readFileSync as readFileSync5,
6388
- rmSync as rmSync3
6389
- } from "fs";
7050
+ import { copyFileSync as copyFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync5, rmSync as rmSync3 } from "fs";
6390
7051
  import { basename as basename2, join as join6 } from "path";
6391
7052
  function getAppSessionLockPath(env = process.env) {
6392
7053
  return join6(getAnygateICodexDir(env), "session-app.json");
@@ -6697,7 +7358,9 @@ async function runCodexAppVertexLaunch(configOnly, trace = false) {
6697
7358
  console.log(` ${pc9.bold("Project:")} ${config.project}`);
6698
7359
  console.log(` ${pc9.bold("Location:")} ${config.location}`);
6699
7360
  console.log(` ${pc9.bold("Model:")} ${selectedEntry.display_name}`);
6700
- console.log(` ${pc9.bold("Catalog:")} ${vertexModels.length} model${vertexModels.length !== 1 ? "s" : ""} available`);
7361
+ console.log(
7362
+ ` ${pc9.bold("Catalog:")} ${vertexModels.length} model${vertexModels.length !== 1 ? "s" : ""} available`
7363
+ );
6701
7364
  console.log("");
6702
7365
  console.log(` ${pc9.bold("Catalog file:")}`);
6703
7366
  console.log(` ${pc9.dim(shortenPath(catalogPath))}`);
@@ -6720,7 +7383,7 @@ async function runCodexAppVertexLaunch(configOnly, trace = false) {
6720
7383
  vertex: vertexConfig,
6721
7384
  contextWindow: m.contextWindow
6722
7385
  })),
6723
- { requireAuth: false, debug: trace }
7386
+ { requireAuth: false, debug: trace, app: "codex-app" }
6724
7387
  );
6725
7388
  const proxyPort = proxyHandle.port;
6726
7389
  const catalogFile = buildAppCatalogFile(vertexModels, "Vertex AI", selectedEntry.id);
@@ -6743,7 +7406,9 @@ async function runCodexAppVertexLaunch(configOnly, trace = false) {
6743
7406
  proxyPort
6744
7407
  });
6745
7408
  sessionActive = true;
6746
- p10.log.info(`Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`);
7409
+ p10.log.info(
7410
+ `Vertex AI \xB7 ${selectedEntry.display_name} \u2014 project: ${config.project} / location: ${config.location}`
7411
+ );
6747
7412
  logProxy(proxyPort);
6748
7413
  logActiveModel(selectedEntry.display_name, selectedEntry.id);
6749
7414
  try {
@@ -6803,8 +7468,14 @@ async function runCodexAppCommand(args, opts = {}) {
6803
7468
  console.error(pc9.red("anygate codex-app requires an interactive terminal."));
6804
7469
  return 1;
6805
7470
  }
6806
- console.error(pc9.yellow(`Another anygate codex-app session may be running (pid ${sessionCheck.lock.pid}).`));
6807
- console.error("Stop it with Ctrl+C in that terminal, or run anygate codex-app --restore after it exits.");
7471
+ console.error(
7472
+ pc9.yellow(
7473
+ `Another anygate codex-app session may be running (pid ${sessionCheck.lock.pid}).`
7474
+ )
7475
+ );
7476
+ console.error(
7477
+ "Stop it with Ctrl+C in that terminal, or run anygate codex-app --restore after it exits."
7478
+ );
6808
7479
  return 1;
6809
7480
  }
6810
7481
  }
@@ -6838,33 +7509,43 @@ async function runCodexAppCommand(args, opts = {}) {
6838
7509
  }
6839
7510
  const prefs = loadPreferences();
6840
7511
  const favorites = prefs.favoriteModels ?? [];
6841
- const favoritesActive = favorites.length > 0;
7512
+ const hasFavorites = favorites.length > 0;
7513
+ let favoritesMode = false;
7514
+ let useProviderAll = false;
6842
7515
  const useFavoritesCatalog = args.includes("--favorites");
6843
- if (favoritesActive && !configOnly) {
6844
- p10.log.info(
6845
- `Favorites mode active \u2014 Codex App picker will show ${favorites.length + 1} models (1 starting + ${favorites.length} favorites).`
6846
- );
6847
- p10.log.info("Edit with `anygate models`.");
6848
- }
6849
7516
  let activeProvider = providerForCodexPicker(
6850
7517
  compatible.find((lp) => lp.id === prefs.lastCodexProvider) ?? compatible[0]
6851
7518
  );
6852
7519
  let selectedModel = activeProvider.models.find((m) => m.id === prefs.lastCodexModel) ?? activeProvider.models[0];
6853
- if (!configOnly && opts.launchProvider && opts.launchModel) {
6854
- const bootSelection = resolveBootSelection(
6855
- compatible,
6856
- opts.launchProvider,
6857
- opts.launchModel,
6858
- providerForCodexPicker
6859
- );
6860
- if ("error" in bootSelection) {
6861
- p10.log.error(bootSelection.error);
6862
- return 1;
7520
+ if (!configOnly && opts.launchProvider && opts.launchModel || opts.launchProvider && (opts.launchAllModels || opts.launchModel === "All")) {
7521
+ if (opts.launchAllModels || opts.launchModel === "All") {
7522
+ const foundProvider = compatible.find((lp) => lp.id === opts.launchProvider);
7523
+ if (!foundProvider) {
7524
+ p10.log.error(`Provider not found: ${opts.launchProvider}`);
7525
+ return 1;
7526
+ }
7527
+ activeProvider = providerForCodexPicker(foundProvider);
7528
+ selectedModel = activeProvider.models[0];
7529
+ useProviderAll = true;
7530
+ if (!configOnly) {
7531
+ p10.log.step(`Using all ${activeProvider.models.length} models from ${activeProvider.name}`);
7532
+ }
7533
+ } else {
7534
+ const bootSelection = resolveBootSelection(
7535
+ compatible,
7536
+ opts.launchProvider,
7537
+ opts.launchModel,
7538
+ providerForCodexPicker
7539
+ );
7540
+ if ("error" in bootSelection) {
7541
+ p10.log.error(bootSelection.error);
7542
+ return 1;
7543
+ }
7544
+ activeProvider = bootSelection.provider;
7545
+ selectedModel = bootSelection.model;
6863
7546
  }
6864
- activeProvider = bootSelection.provider;
6865
- selectedModel = bootSelection.model;
6866
7547
  } else if (!configOnly) {
6867
- if (useFavoritesCatalog && favoritesActive) {
7548
+ if (useFavoritesCatalog && hasFavorites) {
6868
7549
  const firstFavorite = resolveFirstAvailableFavorite(
6869
7550
  favorites,
6870
7551
  compatible.map(providerForCodexPicker)
@@ -6875,10 +7556,16 @@ async function runCodexAppCommand(args, opts = {}) {
6875
7556
  }
6876
7557
  activeProvider = providerForCodexPicker(firstFavorite.provider);
6877
7558
  selectedModel = firstFavorite.model;
7559
+ favoritesMode = true;
6878
7560
  } else {
6879
7561
  let currentInitialProvider = prefs.lastCodexProvider && compatible.some((o) => o.id === prefs.lastCodexProvider) ? prefs.lastCodexProvider : compatible[0].id;
6880
7562
  while (true) {
6881
- const pickedProvider = await pickCodexProvider(compatible, prefs, favoritesActive, currentInitialProvider);
7563
+ const pickedProvider = await pickCodexProvider(
7564
+ compatible,
7565
+ prefs,
7566
+ hasFavorites,
7567
+ currentInitialProvider
7568
+ );
6882
7569
  if (!pickedProvider) return 0;
6883
7570
  if (pickedProvider === "__favorites__") {
6884
7571
  const favoritePick = await pickFavoriteStartingModel(
@@ -6891,9 +7578,35 @@ async function runCodexAppCommand(args, opts = {}) {
6891
7578
  if (favoritePick === "cancelled" || favoritePick === "unavailable") return 0;
6892
7579
  activeProvider = favoritePick.provider;
6893
7580
  selectedModel = favoritePick.model;
7581
+ favoritesMode = true;
6894
7582
  break;
6895
7583
  } else {
6896
7584
  activeProvider = providerForCodexPicker(pickedProvider);
7585
+ const modelModeChoice = await p10.select({
7586
+ message: `Launch mode for ${activeProvider.name}?`,
7587
+ options: [
7588
+ {
7589
+ value: "specific",
7590
+ label: "One model",
7591
+ hint: "Pick a specific model"
7592
+ },
7593
+ {
7594
+ value: "all",
7595
+ label: `All models (${activeProvider.models.length})`,
7596
+ hint: "Every model from this provider in the model switcher"
7597
+ },
7598
+ navOption("__back__", "\u2190 Back", "Choose a different provider")
7599
+ ]
7600
+ });
7601
+ if (p10.isCancel(modelModeChoice) || modelModeChoice === "__back__") {
7602
+ currentInitialProvider = activeProvider.id;
7603
+ continue;
7604
+ }
7605
+ if (modelModeChoice === "all") {
7606
+ useProviderAll = true;
7607
+ selectedModel = activeProvider.models[0];
7608
+ break;
7609
+ }
6897
7610
  const pickedModelResult = await pickCodexModel(activeProvider, prefs);
6898
7611
  if (pickedModelResult === "back") {
6899
7612
  currentInitialProvider = activeProvider.id;
@@ -6914,9 +7627,15 @@ async function runCodexAppCommand(args, opts = {}) {
6914
7627
  return 1;
6915
7628
  }
6916
7629
  activeProvider.apiKey = apiKey;
7630
+ if (hasFavorites && !configOnly && !useProviderAll) {
7631
+ p10.log.info(
7632
+ `Favorites mode active \u2014 Codex App picker will show ${favorites.length + 1} models (1 starting + ${favorites.length} favorites).`
7633
+ );
7634
+ p10.log.info("Edit with `anygate models`.");
7635
+ }
6917
7636
  let cloudCodeBackend = null;
6918
7637
  let cloudCodeBackendFav = null;
6919
- const appProviderRoutes = favoritesActive ? null : await buildCodexAppProviderCatalogRoutes(activeProvider, apiKey, selectedModel.id, trace);
7638
+ const appProviderRoutes = !favoritesMode ? await buildCodexAppProviderCatalogRoutes(activeProvider, apiKey, selectedModel.id, trace) : null;
6920
7639
  cloudCodeBackend = appProviderRoutes?.backend ?? null;
6921
7640
  const route = appProviderRoutes ? codexProxyRouteToCodexRoute(appProviderRoutes.selectedRoute, activeProvider.id) : resolveCodexRoute(activeProvider, selectedModel, apiKey);
6922
7641
  const appRoute = { ...route, tier: "proxy" };
@@ -6924,19 +7643,21 @@ async function runCodexAppCommand(args, opts = {}) {
6924
7643
  const catalogModels = appProviderRoutes?.catalogModels ?? routable;
6925
7644
  let resolvedFavorites = [];
6926
7645
  let providersById = /* @__PURE__ */ new Map();
6927
- if (favoritesActive) {
6928
- const res = await resolveCodexFavorites(activeProvider, selectedModel, compatible, favorites, "codex-app");
7646
+ if (favoritesMode) {
7647
+ const res = await resolveCodexFavorites(
7648
+ activeProvider,
7649
+ selectedModel,
7650
+ compatible,
7651
+ favorites,
7652
+ "codex-app"
7653
+ );
6929
7654
  resolvedFavorites = res.resolvedFavorites;
6930
7655
  providersById = res.providersById;
6931
7656
  }
6932
7657
  if (!configOnly) {
6933
7658
  const modelLabel = formatCodexModelLabel(selectedModel);
6934
- const confirmed = useFavoritesCatalog || await confirmCodexLaunch(
6935
- activeProvider.name,
6936
- modelLabel,
6937
- selectedModel.id,
6938
- appRoute
6939
- );
7659
+ const isExplicitLaunch = Boolean(opts.launchProvider) && Boolean(opts.launchModel || opts.launchAllModels);
7660
+ const confirmed = useFavoritesCatalog || isExplicitLaunch || await confirmCodexLaunch(activeProvider.name, modelLabel, selectedModel.id, appRoute);
6940
7661
  if (!confirmed) {
6941
7662
  cloudCodeBackend?.handle.close();
6942
7663
  return 0;
@@ -6945,8 +7666,8 @@ async function runCodexAppCommand(args, opts = {}) {
6945
7666
  let proxyHandle = null;
6946
7667
  let sessionActive = false;
6947
7668
  try {
6948
- const catalogPath = favoritesActive && resolvedFavorites.length > 0 ? getFavoritesAppCatalogPath() : getAppCatalogPath(route.providerId);
6949
- const activeRoute = favoritesActive && resolvedFavorites.length > 0 ? {
7669
+ const catalogPath = favoritesMode && resolvedFavorites.length > 0 ? getFavoritesAppCatalogPath() : getAppCatalogPath(route.providerId);
7670
+ const activeRoute = favoritesMode && resolvedFavorites.length > 0 ? {
6950
7671
  tier: "proxy",
6951
7672
  modelId: codexCliFavoritesSlug(activeProvider.id, selectedModel.id),
6952
7673
  providerId: activeProvider.id,
@@ -6962,8 +7683,10 @@ async function runCodexAppCommand(args, opts = {}) {
6962
7683
  console.log("");
6963
7684
  console.log(pc9.bold(pc9.cyan(" CONFIG PREVIEW \u2014 anygate codex-app")));
6964
7685
  console.log("");
6965
- if (favoritesActive) {
6966
- console.log(` ${pc9.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`);
7686
+ if (favoritesMode) {
7687
+ console.log(
7688
+ ` ${pc9.bold("Mode:")} Favorites Catalog (${resolvedFavorites.length} model${resolvedFavorites.length !== 1 ? "s" : ""})`
7689
+ );
6967
7690
  console.log("");
6968
7691
  console.log(` ${pc9.bold("Models:")}`);
6969
7692
  for (const r of resolvedFavorites) {
@@ -6973,7 +7696,9 @@ async function runCodexAppCommand(args, opts = {}) {
6973
7696
  console.log(` ${pc9.bold("Mode:")} Single model`);
6974
7697
  console.log(` ${pc9.bold("Provider:")} ${activeProvider.name}`);
6975
7698
  console.log(` ${pc9.bold("Model:")} ${formatCodexModelLabel(selectedModel)}`);
6976
- console.log(` ${pc9.bold("Catalog:")} ${routable.length} model${routable.length !== 1 ? "s" : ""} available`);
7699
+ console.log(
7700
+ ` ${pc9.bold("Catalog:")} ${routable.length} model${routable.length !== 1 ? "s" : ""} available`
7701
+ );
6977
7702
  }
6978
7703
  console.log("");
6979
7704
  console.log(` ${pc9.bold("config.toml patch preview:")}`);
@@ -6994,7 +7719,7 @@ async function runCodexAppCommand(args, opts = {}) {
6994
7719
  return 0;
6995
7720
  }
6996
7721
  let proxyPort;
6997
- if (favoritesActive && resolvedFavorites.length > 0) {
7722
+ if (favoritesMode && resolvedFavorites.length > 0) {
6998
7723
  const needsBackend = (r) => {
6999
7724
  const m = r.model;
7000
7725
  const prov = providersById.get(r.providerId);
@@ -7012,7 +7737,11 @@ async function runCodexAppCommand(args, opts = {}) {
7012
7737
  return { ...route2, oauthAccountId: provider?.oauthAccountId, providerData };
7013
7738
  });
7014
7739
  const startingAlias = backendRoutes[0].aliasId;
7015
- cloudCodeBackendFav = await startCloudCodeCatalogBackend(backendRoutes, startingAlias, trace);
7740
+ cloudCodeBackendFav = await startCloudCodeCatalogBackend(
7741
+ backendRoutes,
7742
+ startingAlias,
7743
+ trace
7744
+ );
7016
7745
  backendCodexRoutes = backendRoutes.map((cr) => ({
7017
7746
  modelId: cr.aliasId,
7018
7747
  npm: "@ai-sdk/anthropic",
@@ -7027,23 +7756,25 @@ async function runCodexAppCommand(args, opts = {}) {
7027
7756
  }));
7028
7757
  }
7029
7758
  const regularRoutes = buildCodexProxyRoutesFromResolved(regularResolved, providersById);
7030
- proxyHandle = await startCodexProxy(
7031
- [...backendCodexRoutes, ...regularRoutes],
7032
- { requireAuth: false, debug: trace }
7033
- );
7759
+ proxyHandle = await startCodexProxy([...backendCodexRoutes, ...regularRoutes], {
7760
+ requireAuth: false,
7761
+ debug: trace,
7762
+ app: "codex-app"
7763
+ });
7034
7764
  proxyPort = proxyHandle.port;
7035
7765
  } else {
7036
7766
  if (!appProviderRoutes) {
7037
7767
  throw new Error("Codex App provider routes were not initialized");
7038
7768
  }
7039
- proxyHandle = await startCodexProxy(
7040
- appProviderRoutes.routes,
7041
- { requireAuth: false, debug: trace }
7042
- );
7769
+ proxyHandle = await startCodexProxy(appProviderRoutes.routes, {
7770
+ requireAuth: false,
7771
+ debug: trace,
7772
+ app: "codex-app"
7773
+ });
7043
7774
  proxyPort = proxyHandle.port;
7044
7775
  }
7045
7776
  const modelLabel = formatCodexModelLabel(selectedModel);
7046
- const catalogFile = favoritesActive && resolvedFavorites.length > 0 ? buildFavoritesAppCatalog(resolvedFavorites) : buildAppCatalogFile(catalogModels, activeProvider.name, appRoute.modelId);
7777
+ const catalogFile = favoritesMode && resolvedFavorites.length > 0 ? buildFavoritesAppCatalog(resolvedFavorites) : buildAppCatalogFile(catalogModels, activeProvider.name, appRoute.modelId);
7047
7778
  writeOverlayFile(catalogPath, serializeCatalog(catalogFile));
7048
7779
  const spec = {
7049
7780
  route: activeRoute,
@@ -7064,11 +7795,17 @@ async function runCodexAppCommand(args, opts = {}) {
7064
7795
  });
7065
7796
  sessionActive = true;
7066
7797
  const prevRecent = prefs.recentModelsByProvider?.[activeProvider.id] ?? [];
7067
- const updatedRecent = [selectedModel.id, ...prevRecent.filter((id) => id !== selectedModel.id)].slice(0, 3);
7798
+ const updatedRecent = [
7799
+ selectedModel.id,
7800
+ ...prevRecent.filter((id) => id !== selectedModel.id)
7801
+ ].slice(0, 3);
7068
7802
  savePreferences({
7069
7803
  lastCodexProvider: activeProvider.id,
7070
7804
  lastCodexModel: selectedModel.id,
7071
- recentModelsByProvider: { ...prefs.recentModelsByProvider, [activeProvider.id]: updatedRecent }
7805
+ recentModelsByProvider: {
7806
+ ...prefs.recentModelsByProvider,
7807
+ [activeProvider.id]: updatedRecent
7808
+ }
7072
7809
  });
7073
7810
  logProxy(proxyPort);
7074
7811
  logActiveModel(modelLabel, selectedModel.id);
@@ -7109,7 +7846,7 @@ async function runCodexAppCommand(args, opts = {}) {
7109
7846
  // src/cli/codex-app.ts
7110
7847
  async function handleCodexAppCommand(parsed) {
7111
7848
  if (parsed.showVersion) {
7112
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
7849
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
7113
7850
  console.log(VERSION2);
7114
7851
  return 0;
7115
7852
  }
@@ -7136,14 +7873,14 @@ This command launches the ChatGPT Desktop app with anygate's provider registry.
7136
7873
  return runCodexAppCommand(parsed.claudeArgs ?? [], {
7137
7874
  vertex: parsed.vertex,
7138
7875
  launchProvider: parsed.launchProvider,
7139
- launchModel: parsed.launchModel
7876
+ launchModel: parsed.launchModel,
7877
+ launchAllModels: parsed.launchAllModels || parsed.launchModel === "All"
7140
7878
  });
7141
7879
  }
7142
7880
 
7143
7881
  // src/apps/claude/desktop.ts
7144
7882
  import pc10 from "picocolors";
7145
7883
  import * as p11 from "@clack/prompts";
7146
- init_config();
7147
7884
 
7148
7885
  // src/apps/claude/desktop-app.ts
7149
7886
  import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "fs";
@@ -7425,10 +8162,21 @@ async function runClaudeAppCommand(args, boot) {
7425
8162
  const prefs = loadPreferences();
7426
8163
  const favorites = prefs.favoriteModels ?? [];
7427
8164
  const hasFavorites = favorites.length > 0;
8165
+ const launchAllModels = Boolean(boot?.launchAllModels || boot?.launchModel === "All");
7428
8166
  let activeProvider = null;
7429
8167
  let selectedModel = null;
7430
8168
  let useFavorites = false;
7431
- if (boot?.launchProvider && boot?.launchModel) {
8169
+ let useProviderAll = false;
8170
+ if (boot?.launchProvider && launchAllModels) {
8171
+ const foundProvider = compatible.find((lp) => lp.id === boot.launchProvider);
8172
+ if (!foundProvider) {
8173
+ p11.log.error(`Provider not found: ${boot.launchProvider}`);
8174
+ return 1;
8175
+ }
8176
+ activeProvider = foundProvider;
8177
+ selectedModel = activeProvider.models[0];
8178
+ useProviderAll = true;
8179
+ } else if (boot?.launchProvider && boot?.launchModel) {
7432
8180
  const bootSelection = resolveBootSelection(
7433
8181
  compatible,
7434
8182
  boot.launchProvider,
@@ -7444,15 +8192,59 @@ async function runClaudeAppCommand(args, boot) {
7444
8192
  } else if (useFavoritesCatalog && hasFavorites) {
7445
8193
  useFavorites = true;
7446
8194
  } else {
7447
- const pickedProvider = await pickCodexProvider(compatible, prefs, hasFavorites, void 0, "Claude");
8195
+ const pickedProvider = await pickCodexProvider(
8196
+ compatible,
8197
+ prefs,
8198
+ hasFavorites,
8199
+ void 0,
8200
+ "Claude"
8201
+ );
7448
8202
  if (!pickedProvider) return 0;
7449
8203
  if (pickedProvider === "__favorites__") {
7450
8204
  useFavorites = true;
7451
8205
  } else {
7452
- activeProvider = providerForClaudePicker(pickedProvider);
7453
- const pickedModel = await pickCodexModel(activeProvider, prefs);
7454
- if (!pickedModel) return 0;
7455
- selectedModel = pickedModel;
8206
+ while (true) {
8207
+ const pickedProvider2 = await pickCodexProvider(
8208
+ compatible,
8209
+ prefs,
8210
+ hasFavorites,
8211
+ void 0,
8212
+ "Claude"
8213
+ );
8214
+ if (!pickedProvider2) return 0;
8215
+ if (pickedProvider2 === "__favorites__") {
8216
+ useFavorites = true;
8217
+ break;
8218
+ } else {
8219
+ activeProvider = providerForClaudePicker(pickedProvider2);
8220
+ const modelModeChoice = await p11.select({
8221
+ message: `Launch mode for ${activeProvider.name}?`,
8222
+ options: [
8223
+ {
8224
+ value: "specific",
8225
+ label: "One model",
8226
+ hint: "Pick a specific model"
8227
+ },
8228
+ {
8229
+ value: "all",
8230
+ label: `All models (${activeProvider.models.length})`,
8231
+ hint: "Every model from this provider in the model picker"
8232
+ },
8233
+ navOption("__back__", "\u2190 Back", "Choose a different provider")
8234
+ ]
8235
+ });
8236
+ if (p11.isCancel(modelModeChoice) || modelModeChoice === "__back__") continue;
8237
+ if (modelModeChoice === "all") {
8238
+ useProviderAll = true;
8239
+ selectedModel = activeProvider.models[0];
8240
+ break;
8241
+ }
8242
+ const pickedModel = await pickCodexModel(activeProvider, prefs);
8243
+ if (!pickedModel) return 0;
8244
+ selectedModel = pickedModel;
8245
+ break;
8246
+ }
8247
+ }
7456
8248
  }
7457
8249
  }
7458
8250
  if (activeProvider) {
@@ -7470,7 +8262,9 @@ async function runClaudeAppCommand(args, boot) {
7470
8262
  const antigravityProvider = catalog.find((lp) => lp.id === "antigravity");
7471
8263
  const cloudCodeFavoriteModels = favorites.map((fav) => {
7472
8264
  if (fav.providerId !== "antigravity") return null;
7473
- const model = antigravityProvider?.models.find((m) => m.id === fav.modelId);
8265
+ const model = antigravityProvider?.models.find(
8266
+ (m) => m.id === fav.modelId
8267
+ );
7474
8268
  return model?.modelFormat === "cloud-code" ? model : null;
7475
8269
  }).filter((m) => m !== null);
7476
8270
  const regularFavorites = favorites.filter(
@@ -7488,21 +8282,23 @@ async function runClaudeAppCommand(args, boot) {
7488
8282
  const startingAlias = cloudRoutes[0].aliasId;
7489
8283
  cloudCodeFavBackend = await startCloudCodeCatalogBackend(cloudRoutes, startingAlias, trace);
7490
8284
  const favBackend = cloudCodeFavBackend;
7491
- cloudCodeServerModels = cloudCodeFavoriteModels.map((model) => modelToServerModelInfo(model, antigravityProvider, {
7492
- isFree: false,
7493
- providerId: "antigravity",
7494
- sourceBackend: "antigravity",
7495
- modelFormat: "anthropic",
7496
- cost: void 0,
7497
- baseUrl: `http://127.0.0.1:${favBackend.port}`,
7498
- completionsUrl: void 0,
7499
- npm: void 0,
7500
- apiBaseUrl: void 0,
7501
- apiKey: favBackend.token,
7502
- authType: void 0,
7503
- oauthAccountId: void 0,
7504
- headers: void 0
7505
- }));
8285
+ cloudCodeServerModels = cloudCodeFavoriteModels.map(
8286
+ (model) => modelToServerModelInfo(model, antigravityProvider, {
8287
+ isFree: false,
8288
+ providerId: "antigravity",
8289
+ sourceBackend: "antigravity",
8290
+ modelFormat: "anthropic",
8291
+ cost: void 0,
8292
+ baseUrl: `http://127.0.0.1:${favBackend.port}`,
8293
+ completionsUrl: void 0,
8294
+ npm: void 0,
8295
+ apiBaseUrl: void 0,
8296
+ apiKey: favBackend.token,
8297
+ authType: void 0,
8298
+ oauthAccountId: void 0,
8299
+ headers: void 0
8300
+ })
8301
+ );
7506
8302
  }
7507
8303
  const regularLocalProviders = providersForTarget(catalog, "claude-app");
7508
8304
  const regularAllModels = regularLocalProviders.flatMap(
@@ -7517,21 +8313,71 @@ async function runClaudeAppCommand(args, boot) {
7517
8313
  seen.add(key);
7518
8314
  return true;
7519
8315
  });
8316
+ } else if (useProviderAll) {
8317
+ const routableProvider = providersForTarget(catalog, "claude-app").find(
8318
+ (lp) => lp.id === activeProvider.id
8319
+ );
8320
+ const allServerModels = localProvidersToServerModels(
8321
+ routableProvider ? [routableProvider] : [activeProvider]
8322
+ );
8323
+ const cloudCodeIndices = allServerModels.map((m, i) => m.modelFormat === "cloud-code" ? i : -1).filter((i) => i >= 0);
8324
+ if (cloudCodeIndices.length > 0 && activeProvider.apiKey) {
8325
+ const providerData = activeProvider.providerData ?? {};
8326
+ const cloudCodeModels = cloudCodeIndices.map((i) => allServerModels[i]);
8327
+ const cloudRoutes = cloudCodeModels.map(
8328
+ (model) => buildCloudCodeProxyRoute(
8329
+ { id: model.id, name: model.name, modelFormat: "cloud-code" },
8330
+ activeProvider.apiKey,
8331
+ providerData
8332
+ )
8333
+ );
8334
+ const startingAlias = cloudRoutes[0].aliasId;
8335
+ cloudCodeBackend = await startCloudCodeCatalogBackend(
8336
+ cloudRoutes,
8337
+ startingAlias,
8338
+ trace,
8339
+ "claude-desktop"
8340
+ );
8341
+ const backend = cloudCodeBackend;
8342
+ for (let idx of cloudCodeIndices) {
8343
+ const m = allServerModels[idx];
8344
+ allServerModels[idx] = {
8345
+ ...m,
8346
+ modelFormat: "anthropic",
8347
+ baseUrl: `http://127.0.0.1:${backend.port}`,
8348
+ apiBaseUrl: void 0,
8349
+ apiKey: backend.token,
8350
+ completionsUrl: void 0,
8351
+ authType: void 0,
8352
+ oauthAccountId: void 0,
8353
+ headers: void 0
8354
+ };
8355
+ }
8356
+ }
8357
+ const seen = /* @__PURE__ */ new Set();
8358
+ serverModels = allServerModels.filter((m) => {
8359
+ const key = `${m.providerId}:${m.id}`;
8360
+ if (seen.has(key)) return false;
8361
+ seen.add(key);
8362
+ return true;
8363
+ });
7520
8364
  } else if (selectedModel.modelFormat === "cloud-code") {
7521
8365
  const providerData = activeProvider.providerData ?? {};
7522
8366
  const cloudRoute = buildCloudCodeProxyRoute(selectedModel, activeProvider.apiKey, providerData);
7523
8367
  cloudCodeBackend = await startCloudCodeCatalogBackend([cloudRoute], cloudRoute.aliasId, trace);
7524
- serverModels = [modelToServerModelInfo(selectedModel, activeProvider, {
7525
- modelFormat: "anthropic",
7526
- baseUrl: `http://127.0.0.1:${cloudCodeBackend.port}`,
7527
- completionsUrl: void 0,
7528
- npm: void 0,
7529
- apiBaseUrl: void 0,
7530
- apiKey: cloudCodeBackend.token,
7531
- authType: void 0,
7532
- oauthAccountId: void 0,
7533
- headers: void 0
7534
- })];
8368
+ serverModels = [
8369
+ modelToServerModelInfo(selectedModel, activeProvider, {
8370
+ modelFormat: "anthropic",
8371
+ baseUrl: `http://127.0.0.1:${cloudCodeBackend.port}`,
8372
+ completionsUrl: void 0,
8373
+ npm: void 0,
8374
+ apiBaseUrl: void 0,
8375
+ apiKey: cloudCodeBackend.token,
8376
+ authType: void 0,
8377
+ oauthAccountId: void 0,
8378
+ headers: void 0
8379
+ })
8380
+ ];
7535
8381
  } else {
7536
8382
  serverModels = [modelToServerModelInfo(selectedModel, activeProvider)];
7537
8383
  }
@@ -7549,7 +8395,10 @@ async function runClaudeAppCommand(args, boot) {
7549
8395
  catalog: createGatewayModelCatalog(serverModels, { maskGatewayIds: true }),
7550
8396
  backends: BACKENDS,
7551
8397
  gateway: { maskGatewayIds: true },
7552
- debugLogPath
8398
+ debugLogPath,
8399
+ // Claude Desktop embeds the gateway router rather than running
8400
+ // `anygate server`, so attribute its traffic to the app, not 'gateway'.
8401
+ app: "claude-desktop"
7553
8402
  });
7554
8403
  uuid = writeAnygateIConfig(proxyHandle.port);
7555
8404
  writeSessionLock2({
@@ -7562,11 +8411,17 @@ async function runClaudeAppCommand(args, boot) {
7562
8411
  setupExitCleanup(uuid);
7563
8412
  if (!useFavorites) {
7564
8413
  const prevRecent = prefs.recentModelsByProvider?.[activeProvider.id] ?? [];
7565
- const updatedRecent = [selectedModel.id, ...prevRecent.filter((id) => id !== selectedModel.id)].slice(0, 3);
8414
+ const updatedRecent = [
8415
+ selectedModel.id,
8416
+ ...prevRecent.filter((id) => id !== selectedModel.id)
8417
+ ].slice(0, 3);
7566
8418
  savePreferences({
7567
8419
  lastCodexProvider: activeProvider.id,
7568
8420
  lastCodexModel: selectedModel.id,
7569
- recentModelsByProvider: { ...prefs.recentModelsByProvider, [activeProvider.id]: updatedRecent }
8421
+ recentModelsByProvider: {
8422
+ ...prefs.recentModelsByProvider,
8423
+ [activeProvider.id]: updatedRecent
8424
+ }
7570
8425
  });
7571
8426
  }
7572
8427
  console.log(`
@@ -7580,6 +8435,10 @@ ${pc10.green("\u2714")} Proxy started on port ${proxyHandle.port}`);
7580
8435
  ${pc10.bold("Claude Desktop 3P Mode Active")}`);
7581
8436
  if (useFavorites) {
7582
8437
  console.log(`${pc10.dim("Catalog:")} Favorite models only`);
8438
+ } else if (useProviderAll) {
8439
+ console.log(
8440
+ `${pc10.dim("Catalog:")} All ${activeProvider.name} models (${serverModels.length})`
8441
+ );
7583
8442
  } else {
7584
8443
  console.log(`${pc10.dim("Model:")} ${selectedModel.id}`);
7585
8444
  console.log(`${pc10.dim("Provider:")} ${activeProvider.name}`);
@@ -7612,7 +8471,7 @@ ${pc10.bold("Claude Desktop 3P Mode Active")}`);
7612
8471
  // src/cli/claude-app.ts
7613
8472
  async function handleClaudeAppCommand(parsed) {
7614
8473
  if (parsed.showVersion) {
7615
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
8474
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
7616
8475
  console.log(VERSION2);
7617
8476
  return 0;
7618
8477
  }
@@ -7637,17 +8496,16 @@ This command launches the Claude Desktop app with anygate's provider registry.
7637
8496
  }
7638
8497
  return runClaudeAppCommand(parsed.claudeArgs ?? [], {
7639
8498
  launchProvider: parsed.launchProvider,
7640
- launchModel: parsed.launchModel
8499
+ launchModel: parsed.launchModel,
8500
+ launchAllModels: parsed.launchAllModels || parsed.launchModel === "All"
7641
8501
  });
7642
8502
  }
7643
8503
 
7644
8504
  // src/apps/gemini/cli.ts
7645
8505
  import pc11 from "picocolors";
7646
8506
  import * as p13 from "@clack/prompts";
7647
- init_config();
7648
8507
 
7649
8508
  // src/apps/gemini/launch.ts
7650
- init_config();
7651
8509
  import { spawn as spawn2 } from "child_process";
7652
8510
  import { existsSync as existsSync9, mkdirSync as mkdirSync6, mkdtempSync, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
7653
8511
  import { homedir as homedir6, tmpdir } from "os";
@@ -7737,7 +8595,9 @@ function launchGemini(geminiPath, modelId, env, extraArgs) {
7737
8595
  import * as p12 from "@clack/prompts";
7738
8596
  async function pickGeminiProvider(providers, prefs, hasFavorites = false, initialProviderId) {
7739
8597
  if (providers.length === 0 && !hasFavorites) return null;
7740
- const options = providers.map((lp) => providerSelectOption(lp));
8598
+ const options = providers.map(
8599
+ (lp) => providerSelectOption(lp)
8600
+ );
7741
8601
  if (hasFavorites) {
7742
8602
  options.unshift({
7743
8603
  value: "__favorites__",
@@ -7854,7 +8714,8 @@ function rejectGeminiManagedFlags(geminiArgs) {
7854
8714
  if (takesValue.has(arg)) i++;
7855
8715
  continue;
7856
8716
  }
7857
- if (arg.startsWith("--model=") || arg.startsWith("--provider=") || arg.startsWith("-m=")) continue;
8717
+ if (arg.startsWith("--model=") || arg.startsWith("--provider=") || arg.startsWith("-m="))
8718
+ continue;
7858
8719
  out.push(arg);
7859
8720
  }
7860
8721
  return out;
@@ -7889,7 +8750,9 @@ function lookupGeminiRoute(routes, requestedModel, defaultRoute) {
7889
8750
  }
7890
8751
  const fallback = defaultRoute ?? routes[0];
7891
8752
  if (requestedModel !== fallback.aliasId) {
7892
- console.error(`[gemini-proxy] model '${requestedModel}' not in catalog \u2014 remapping to default route '${fallback.aliasId}' (upstream: ${fallback.realModelId})`);
8753
+ console.error(
8754
+ `[gemini-proxy] model '${requestedModel}' not in catalog \u2014 remapping to default route '${fallback.aliasId}' (upstream: ${fallback.realModelId})`
8755
+ );
7893
8756
  }
7894
8757
  return fallback;
7895
8758
  }
@@ -8037,7 +8900,9 @@ async function startGeminiProxy(routes, debug = false) {
8037
8900
  const plog = debug ? makeTraceLogger(getGeminiProxyDebugLogPath()) : () => {
8038
8901
  };
8039
8902
  const onRejection = (reason) => {
8040
- plog(`Unhandled Rejection: ${reason instanceof Error ? reason.stack || reason.message : String(reason)}`);
8903
+ plog(
8904
+ `Unhandled Rejection: ${reason instanceof Error ? reason.stack || reason.message : String(reason)}`
8905
+ );
8041
8906
  };
8042
8907
  const onException = (error) => {
8043
8908
  plog(`Uncaught Exception: ${error.stack || error.message}`);
@@ -8117,7 +8982,7 @@ ${rawBody}`);
8117
8982
  const modelCommand = parseModelCommand(lastUserTurn);
8118
8983
  if (modelCommand !== null) {
8119
8984
  if (modelCommand === "") {
8120
- const current = sessionRouteOverride ?? (lookupGeminiRoute(routes, requestedModel) ?? defaultRoute);
8985
+ const current = sessionRouteOverride ?? lookupGeminiRoute(routes, requestedModel) ?? defaultRoute;
8121
8986
  const availableList = routes.map((r) => ` - ${r.aliasId} (${r.displayName})`).join("\n");
8122
8987
  const exampleId = routes.length > 1 ? routes[1].aliasId : routes[0]?.aliasId ?? "deepseek-v4";
8123
8988
  const text4 = `Current model: ${current.displayName} (${current.aliasId})
@@ -8134,16 +8999,25 @@ Example: .model ${exampleId}`;
8134
8999
  if (targetRoute) {
8135
9000
  sessionRouteOverride = targetRoute;
8136
9001
  plog(`.model switch: ${targetRoute.aliasId} (${targetRoute.realModelId})`);
8137
- sendMockGeminiResponse(res, `\u2705 Switched model to ${targetRoute.displayName} (${targetRoute.aliasId})`, isStream, targetRoute.aliasId);
9002
+ sendMockGeminiResponse(
9003
+ res,
9004
+ `\u2705 Switched model to ${targetRoute.displayName} (${targetRoute.aliasId})`,
9005
+ isStream,
9006
+ targetRoute.aliasId
9007
+ );
8138
9008
  } else {
8139
9009
  const available = routes.map((r) => r.aliasId).join(", ");
8140
- sendMockGeminiResponse(res, `\u274C Model '${modelCommand}' not found.
9010
+ sendMockGeminiResponse(
9011
+ res,
9012
+ `\u274C Model '${modelCommand}' not found.
8141
9013
 
8142
- Available: ${available}`, isStream);
9014
+ Available: ${available}`,
9015
+ isStream
9016
+ );
8143
9017
  }
8144
9018
  return;
8145
9019
  }
8146
- const route = sessionRouteOverride ?? (lookupGeminiRoute(routes, requestedModel) ?? defaultRoute);
9020
+ const route = sessionRouteOverride ?? lookupGeminiRoute(routes, requestedModel) ?? defaultRoute;
8147
9021
  plog(`Route selected: ${route.aliasId} (upstream model: ${route.realModelId})`);
8148
9022
  body.contents = sanitizeModelSwitchTurns(body.contents || []);
8149
9023
  const languageModel = await getOrInitModel(route);
@@ -8155,7 +9029,12 @@ Available: ${available}`, isStream);
8155
9029
  params.providerOptions,
8156
9030
  deepMergeProviderOptions(
8157
9031
  thinkingProviderOptions(route.npm || "@ai-sdk/openai-compatible"),
8158
- effortProviderOptions(route.npm || "@ai-sdk/openai-compatible", "high", route.realModelId, route)
9032
+ effortProviderOptions(
9033
+ route.npm || "@ai-sdk/openai-compatible",
9034
+ "high",
9035
+ route.realModelId,
9036
+ route
9037
+ )
8159
9038
  )
8160
9039
  );
8161
9040
  plog(`Translated SDK params:
@@ -8164,7 +9043,7 @@ ${JSON.stringify(params, null, 2)}`);
8164
9043
  res.writeHead(200, {
8165
9044
  "Content-Type": "text/event-stream",
8166
9045
  "Cache-Control": "no-cache",
8167
- "Connection": "keep-alive"
9046
+ Connection: "keep-alive"
8168
9047
  });
8169
9048
  plog("Starting streamText...");
8170
9049
  const { fullStream } = streamText2({
@@ -8179,10 +9058,12 @@ ${JSON.stringify(params, null, 2)}`);
8179
9058
  if (isThinking && (p18.type === "tool-input-start" || p18.type === "tool-call" || p18.type === "finish")) {
8180
9059
  isThinking = false;
8181
9060
  const chunk = {
8182
- candidates: [{ content: { role: "model", parts: [{ text: `
9061
+ candidates: [
9062
+ { content: { role: "model", parts: [{ text: `
8183
9063
  </thinking>
8184
9064
 
8185
- ` }] } }],
9065
+ ` }] } }
9066
+ ],
8186
9067
  modelVersion: route.aliasId
8187
9068
  };
8188
9069
  res.write(`data: ${JSON.stringify(chunk)}
@@ -8213,12 +9094,14 @@ ${JSON.stringify(params, null, 2)}`);
8213
9094
  ` + text4;
8214
9095
  }
8215
9096
  const chunk = {
8216
- candidates: [{
8217
- content: {
8218
- role: "model",
8219
- parts: [{ text: text4 }]
9097
+ candidates: [
9098
+ {
9099
+ content: {
9100
+ role: "model",
9101
+ parts: [{ text: text4 }]
9102
+ }
8220
9103
  }
8221
- }],
9104
+ ],
8222
9105
  modelVersion: route.aliasId
8223
9106
  };
8224
9107
  const data = `data: ${JSON.stringify(chunk)}
@@ -8237,14 +9120,18 @@ ${JSON.stringify(params, null, 2)}`);
8237
9120
  const name = buf ? buf.name : p18.toolName;
8238
9121
  plog(`Streaming tool call: ${name} with args: ${JSON.stringify(args)}`);
8239
9122
  const chunk = {
8240
- candidates: [{
8241
- content: {
8242
- role: "model",
8243
- parts: [{
8244
- functionCall: { name, args }
8245
- }]
9123
+ candidates: [
9124
+ {
9125
+ content: {
9126
+ role: "model",
9127
+ parts: [
9128
+ {
9129
+ functionCall: { name, args }
9130
+ }
9131
+ ]
9132
+ }
8246
9133
  }
8247
- }],
9134
+ ],
8248
9135
  modelVersion: route.aliasId
8249
9136
  };
8250
9137
  res.write(`data: ${JSON.stringify(chunk)}
@@ -8252,9 +9139,11 @@ ${JSON.stringify(params, null, 2)}`);
8252
9139
  `);
8253
9140
  } else if (p18.type === "finish") {
8254
9141
  const chunk = {
8255
- candidates: [{
8256
- finishReason: mapFinishReason(p18.finishReason ?? "")
8257
- }],
9142
+ candidates: [
9143
+ {
9144
+ finishReason: mapFinishReason(p18.finishReason ?? "")
9145
+ }
9146
+ ],
8258
9147
  usageMetadata: {
8259
9148
  promptTokenCount: p18.totalUsage?.inputTokens || 0,
8260
9149
  candidatesTokenCount: p18.totalUsage?.outputTokens || 0
@@ -8295,13 +9184,15 @@ ${result.reasoning}
8295
9184
  }
8296
9185
  }
8297
9186
  const response = {
8298
- candidates: [{
8299
- content: {
8300
- role: "model",
8301
- parts
8302
- },
8303
- finishReason: mapFinishReason(result.finishReason ?? "")
8304
- }],
9187
+ candidates: [
9188
+ {
9189
+ content: {
9190
+ role: "model",
9191
+ parts
9192
+ },
9193
+ finishReason: mapFinishReason(result.finishReason ?? "")
9194
+ }
9195
+ ],
8305
9196
  usageMetadata: {
8306
9197
  promptTokenCount: result.usage?.inputTokens || 0,
8307
9198
  candidatesTokenCount: result.usage?.outputTokens || 0
@@ -8319,13 +9210,19 @@ ${JSON.stringify(response, null, 2)}`);
8319
9210
  res.writeHead(404);
8320
9211
  res.end("Not Found");
8321
9212
  } catch (err) {
8322
- plog(`Error handling request: ${err instanceof Error ? err.stack || err.message : String(err)}`);
9213
+ plog(
9214
+ `Error handling request: ${err instanceof Error ? err.stack || err.message : String(err)}`
9215
+ );
8323
9216
  const errMsg = formatUpstreamError(err);
8324
9217
  if (debug) {
8325
9218
  console.error(`[Gemini Proxy] ${errMsg}`);
8326
9219
  }
8327
9220
  if (!res.headersSent) {
8328
- sendMockGeminiResponse(res, `\u26A0 ${errMsg}`, req.url?.includes("streamGenerateContent") ?? false);
9221
+ sendMockGeminiResponse(
9222
+ res,
9223
+ `\u26A0 ${errMsg}`,
9224
+ req.url?.includes("streamGenerateContent") ?? false
9225
+ );
8329
9226
  } else {
8330
9227
  try {
8331
9228
  writeGeminiStreamText(res, `\u26A0 ${errMsg}`);
@@ -8412,28 +9309,34 @@ function sendMockGeminiResponse(res, text4, isStream, modelVersion) {
8412
9309
  res.writeHead(200, {
8413
9310
  "Content-Type": "text/event-stream",
8414
9311
  "Cache-Control": "no-cache",
8415
- "Connection": "keep-alive"
9312
+ Connection: "keep-alive"
8416
9313
  });
8417
9314
  writeGeminiStreamText(res, text4, modelVersion);
8418
9315
  res.end();
8419
9316
  } else {
8420
9317
  res.writeHead(200, { "Content-Type": "application/json" });
8421
- res.end(JSON.stringify({
8422
- candidates: [{
8423
- content: { role: "model", parts: [{ text: text4 }] },
8424
- finishReason: "STOP"
8425
- }],
8426
- usageMetadata: { promptTokenCount: 0, candidatesTokenCount: 0 },
8427
- ...modelVersion ? { modelVersion } : {}
8428
- }));
9318
+ res.end(
9319
+ JSON.stringify({
9320
+ candidates: [
9321
+ {
9322
+ content: { role: "model", parts: [{ text: text4 }] },
9323
+ finishReason: "STOP"
9324
+ }
9325
+ ],
9326
+ usageMetadata: { promptTokenCount: 0, candidatesTokenCount: 0 },
9327
+ ...modelVersion ? { modelVersion } : {}
9328
+ })
9329
+ );
8429
9330
  }
8430
9331
  }
8431
9332
  function writeGeminiStreamText(res, text4, modelVersion) {
8432
9333
  const chunk = {
8433
- candidates: [{
8434
- content: { role: "model", parts: [{ text: text4 }] },
8435
- finishReason: "STOP"
8436
- }],
9334
+ candidates: [
9335
+ {
9336
+ content: { role: "model", parts: [{ text: text4 }] },
9337
+ finishReason: "STOP"
9338
+ }
9339
+ ],
8437
9340
  usageMetadata: { promptTokenCount: 0, candidatesTokenCount: 0 },
8438
9341
  ...modelVersion ? { modelVersion } : {}
8439
9342
  };
@@ -8487,7 +9390,8 @@ async function rewriteGeminiBackendRoutes(routes, launchModelId, trace) {
8487
9390
  backendUrl: `http://127.0.0.1:${backend.port}`,
8488
9391
  apiKey: backend.token
8489
9392
  }),
8490
- trace
9393
+ trace,
9394
+ "gemini"
8491
9395
  );
8492
9396
  if (!partitioned.backend) {
8493
9397
  return { routes, launchModelId, backend: null };
@@ -8567,8 +9471,9 @@ async function runGeminiCommand(geminiArgs, trace = false, launch = {}) {
8567
9471
  const agentStdout = wantsCleanAgentStdout("gemini", passthroughArgs);
8568
9472
  setAgentStdoutMode(agentStdout);
8569
9473
  const prefs = loadPreferences();
9474
+ const launchAllModels = Boolean(launch.launchAllModels || launch.launchModel === "All");
8570
9475
  const launchPlan = planLaunchWizard({
8571
- explicit: { providerId: launch.launchProvider, modelId: launch.launchModel },
9476
+ explicit: launchAllModels ? { providerId: launch.launchProvider, allModels: true } : { providerId: launch.launchProvider, modelId: launch.launchModel },
8572
9477
  childArgs: passthroughArgs,
8573
9478
  agent: "gemini",
8574
9479
  prefs
@@ -8602,7 +9507,9 @@ Error: ${launchPlan.error}
8602
9507
  const compatible = providersForTarget(providersForPicker(catalog), "gemini");
8603
9508
  if (compatible.length === 0) {
8604
9509
  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.");
9510
+ p13.log.info(
9511
+ "Add a provider with anygate providers add, or sign in with anygate providers auth openai."
9512
+ );
8606
9513
  return 0;
8607
9514
  }
8608
9515
  let activeProvider = compatible.find((lp) => lp.id === prefs.lastGeminiProvider) ?? compatible[0];
@@ -8611,7 +9518,6 @@ Error: ${launchPlan.error}
8611
9518
  p13.log.error(`Provider "${activeProvider.name}" has no models available.`);
8612
9519
  return 1;
8613
9520
  }
8614
- ;
8615
9521
  if (launchPlan.skip && launchPlan.target) {
8616
9522
  const resolved = findProviderAndModel(compatible, launchPlan.target);
8617
9523
  if (!resolved) {
@@ -8660,9 +9566,7 @@ Error: ${launchPlan.error}
8660
9566
  recordLaunchSelection("gemini", activeProvider.id, selectedModel.id, prefs);
8661
9567
  const launchApiKey = await resolveLocalProviderApiKey(activeProvider);
8662
9568
  if (!launchApiKey?.trim()) {
8663
- p13.log.error(
8664
- new CredentialUnavailableError(activeProvider.id).userMessage
8665
- );
9569
+ p13.log.error(new CredentialUnavailableError(activeProvider.id).userMessage);
8666
9570
  return 1;
8667
9571
  }
8668
9572
  const providerRoutes = activeProvider.models.map((m) => ({
@@ -8764,6 +9668,13 @@ Error: ${launchPlan.error}
8764
9668
  if (!agentStdout) {
8765
9669
  p13.log.info(`Gemini proxy started on port ${proxyHandle.port}`);
8766
9670
  p13.log.info(`\u{1F4A1} Type ${pc11.bold(".model <id>")} in the chat to switch models mid-session.`);
9671
+ if (launchAllModels) {
9672
+ p13.log.info(
9673
+ pc11.dim(
9674
+ `All ${activeProvider.models.length} ${activeProvider.name} models are available \u2014 type .model <id> to switch.`
9675
+ )
9676
+ );
9677
+ }
8767
9678
  }
8768
9679
  let exitCode = 1;
8769
9680
  try {
@@ -8785,7 +9696,7 @@ Error: ${launchPlan.error}
8785
9696
  // src/cli/gemini.ts
8786
9697
  async function handleGeminiCommand(parsed) {
8787
9698
  if (parsed.showVersion) {
8788
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
9699
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
8789
9700
  console.log(VERSION2);
8790
9701
  return 0;
8791
9702
  }
@@ -8795,12 +9706,12 @@ async function handleGeminiCommand(parsed) {
8795
9706
  }
8796
9707
  return runGeminiCommand(parsed.claudeArgs ?? [], parsed.trace ?? false, {
8797
9708
  launchProvider: parsed.launchProvider,
8798
- launchModel: parsed.launchModel
9709
+ launchModel: parsed.launchModel,
9710
+ launchAllModels: parsed.launchAllModels || parsed.launchModel === "All"
8799
9711
  });
8800
9712
  }
8801
9713
 
8802
9714
  // src/apps/gemini/antigravity.ts
8803
- init_config();
8804
9715
  import pc12 from "picocolors";
8805
9716
  import * as p14 from "@clack/prompts";
8806
9717
  import { appendFileSync as appendFileSync2 } from "fs";
@@ -9085,7 +9996,9 @@ function evaluateAgySwitchCompatibility(opts) {
9085
9996
  const shapeMatches = validation.warnings.length === 0 && validation.switchSlots.length > 0;
9086
9997
  const warnings = [];
9087
9998
  if (opts.versionReadError) {
9088
- warnings.push(`Could not read agy --version (${opts.versionReadError}); validating AGY fixture shape instead.`);
9999
+ warnings.push(
10000
+ `Could not read agy --version (${opts.versionReadError}); validating AGY fixture shape instead.`
10001
+ );
9089
10002
  }
9090
10003
  if (opts.version && KNOWN_INCOMPATIBLE_AGY_VERSIONS.has(opts.version)) {
9091
10004
  return {
@@ -9109,9 +10022,13 @@ function evaluateAgySwitchCompatibility(opts) {
9109
10022
  };
9110
10023
  }
9111
10024
  if (opts.version && !KNOWN_COMPATIBLE_AGY_VERSIONS.has(opts.version)) {
9112
- warnings.push(`Unvalidated AGY version ${opts.version}; fixture shape matches, so multi-model switching remains enabled.`);
10025
+ warnings.push(
10026
+ `Unvalidated AGY version ${opts.version}; fixture shape matches, so multi-model switching remains enabled.`
10027
+ );
9113
10028
  } else if (!opts.version && !opts.versionReadError) {
9114
- warnings.push("AGY version is unknown; fixture shape matches, so multi-model switching remains enabled.");
10029
+ warnings.push(
10030
+ "AGY version is unknown; fixture shape matches, so multi-model switching remains enabled."
10031
+ );
9115
10032
  }
9116
10033
  return {
9117
10034
  mode: "multi-model",
@@ -9169,10 +10086,7 @@ function withCascadeCheckpointer(entry, maxTokenLimit = 128e3) {
9169
10086
  function applyRouteContextBounds(entry, route) {
9170
10087
  const maxTokenLimit = route.contextWindow ?? 128e3;
9171
10088
  const maxOutputTokens = Math.min(entry.maxOutputTokens ?? 65536, maxTokenLimit);
9172
- const checkpointTokenLimit = Math.min(
9173
- 128e3,
9174
- Math.max(1, maxTokenLimit - maxOutputTokens)
9175
- );
10089
+ const checkpointTokenLimit = Math.min(128e3, Math.max(1, maxTokenLimit - maxOutputTokens));
9176
10090
  entry.maxTokens = maxTokenLimit;
9177
10091
  entry.maxOutputTokens = maxOutputTokens;
9178
10092
  entry.supportsImages = route.inputTypes?.includes("image") ?? false;
@@ -9255,7 +10169,9 @@ function injectGatewayModels(fixture, routes, templateKey) {
9255
10169
  if (routes.length > 0) {
9256
10170
  result.models[GATEWAY_CASCADE_ANCHOR_ID] ??= structuredClone(template);
9257
10171
  result.models[GATEWAY_CASCADE_FALLBACK_ID] ??= structuredClone(GATEWAY_CASCADE_FALLBACK_ENTRY);
9258
- result.models[GATEWAY_CASCADE_INTENT_MODEL_ID] ??= structuredClone(GATEWAY_CASCADE_INTENT_MODEL_ENTRY);
10172
+ result.models[GATEWAY_CASCADE_INTENT_MODEL_ID] ??= structuredClone(
10173
+ GATEWAY_CASCADE_INTENT_MODEL_ENTRY
10174
+ );
9259
10175
  if (!result.models[GATEWAY_CASCADE_PLAN_ANCHOR_ID]) {
9260
10176
  const planAnchor = withCascadeCheckpointer(structuredClone(template));
9261
10177
  planAnchor.model = GATEWAY_CASCADE_PLAN_MODEL;
@@ -9274,9 +10190,11 @@ function injectGatewayModels(fixture, routes, templateKey) {
9274
10190
  result.agentModelSorts = [
9275
10191
  {
9276
10192
  displayName: "Recommended",
9277
- groups: [{
9278
- modelIds: slots.map((slot) => slot.slotId)
9279
- }]
10193
+ groups: [
10194
+ {
10195
+ modelIds: slots.map((slot) => slot.slotId)
10196
+ }
10197
+ ]
9280
10198
  }
9281
10199
  ];
9282
10200
  return result;
@@ -9321,6 +10239,7 @@ function buildAntigravityRoutes(resolvedFavorites, maxRoutes = MAX_MODEL_CATALOG
9321
10239
  ...fav.authType ? { authType: fav.authType } : {},
9322
10240
  ...fav.oauthAccountId ? { oauthAccountId: fav.oauthAccountId } : {},
9323
10241
  ...fav.providerData ? { providerData: fav.providerData } : {},
10242
+ ...fav.headers ? { headers: fav.headers } : {},
9324
10243
  baseURL,
9325
10244
  contextWindow,
9326
10245
  inputTypes
@@ -10603,8 +11522,16 @@ async function startCloudCodeGateway(routes, opts = {}) {
10603
11522
  if (trace) log17(`[gateway] active route: ${route.catalogId} via ${model}`);
10604
11523
  }
10605
11524
  if (isCloudCodeOAuthRoute(route)) {
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)}`);
11525
+ handleCloudCodeForwardRequest(
11526
+ res,
11527
+ route,
11528
+ parsed,
11529
+ lowerUrl,
11530
+ log17
11531
+ ).catch((err) => {
11532
+ log17(
11533
+ `[gateway] cloud-code forward error: ${err instanceof Error ? err.stack || err.message : String(err)}`
11534
+ );
10608
11535
  if (!res.headersSent) {
10609
11536
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
10610
11537
  } else if (!res.writableEnded) {
@@ -10616,7 +11543,11 @@ async function startCloudCodeGateway(routes, opts = {}) {
10616
11543
  const baseProviderOptions = providerOptionsCache.get(route.catalogId);
10617
11544
  const isStream = lowerUrl.includes("stream");
10618
11545
  const conversationKey = conversationKeyFromRequest(parsed);
10619
- const requestOptions = reasoningEchoOptionsForRoute(route, parsed, reasoningEchoesByConversation);
11546
+ const requestOptions = reasoningEchoOptionsForRoute(
11547
+ route,
11548
+ parsed,
11549
+ reasoningEchoesByConversation
11550
+ );
10620
11551
  const rememberReasoning = (reasoning) => {
10621
11552
  if (!shouldEchoReasoningForRoute(route)) return;
10622
11553
  rememberReasoningEcho(reasoningEchoesByConversation, conversationKey, reasoning);
@@ -10626,7 +11557,9 @@ async function startCloudCodeGateway(routes, opts = {}) {
10626
11557
  requestOptions,
10627
11558
  onReasoningWithToolCall: rememberReasoning
10628
11559
  }).catch((err) => {
10629
- log17(`[gateway] stream error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
11560
+ log17(
11561
+ `[gateway] stream error: ${err instanceof Error ? err.stack || err.message : String(err)}`
11562
+ );
10630
11563
  if (!res.headersSent) {
10631
11564
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
10632
11565
  } else if (!res.writableEnded) {
@@ -10638,7 +11571,9 @@ async function startCloudCodeGateway(routes, opts = {}) {
10638
11571
  requestOptions,
10639
11572
  onReasoningWithToolCall: rememberReasoning
10640
11573
  }).catch((err) => {
10641
- log17(`[gateway] unary error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
11574
+ log17(
11575
+ `[gateway] unary error: ${err instanceof Error ? err.stack || err.message : String(err)}`
11576
+ );
10642
11577
  if (!res.headersSent) {
10643
11578
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
10644
11579
  }
@@ -10659,7 +11594,13 @@ async function startCloudCodeGateway(routes, opts = {}) {
10659
11594
  return;
10660
11595
  }
10661
11596
  if (lowerUrl.includes("userquota")) {
10662
- respondJson(res, 200, { quotaSummary: { remainingQueries: 9999, totalQueries: 9999, quotaType: "GATEWAY_UNLIMITED" } });
11597
+ respondJson(res, 200, {
11598
+ quotaSummary: {
11599
+ remainingQueries: 9999,
11600
+ totalQueries: 9999,
11601
+ quotaType: "GATEWAY_UNLIMITED"
11602
+ }
11603
+ });
10663
11604
  return;
10664
11605
  }
10665
11606
  if (lowerUrl.includes("userinfo")) {
@@ -10738,7 +11679,12 @@ async function startCloudCodeGateway(routes, opts = {}) {
10738
11679
  }
10739
11680
  respondJson(res, 200, {});
10740
11681
  }).catch((err) => {
10741
- respondJson(res, 400, { error: { code: 400, message: `Failed to read request: ${err instanceof Error ? err.message : String(err)}` } });
11682
+ respondJson(res, 400, {
11683
+ error: {
11684
+ code: 400,
11685
+ message: `Failed to read request: ${err instanceof Error ? err.message : String(err)}`
11686
+ }
11687
+ });
10742
11688
  });
10743
11689
  });
10744
11690
  return new Promise((resolve, reject2) => {
@@ -11012,10 +11958,13 @@ function respondJson(res, status, data) {
11012
11958
  res.end(body);
11013
11959
  }
11014
11960
  async function handleStreamingRequest(res, route, providerOptions, parsed, log17, options = {}) {
11015
- const sdkParams = applyClaudeCodeOAuthIdentity(route, translateRequest(parsed, {
11016
- ...options.requestOptions,
11017
- maxTools: maxToolsForNpm(route.npm)
11018
- }));
11961
+ const sdkParams = applyClaudeCodeOAuthIdentity(
11962
+ route,
11963
+ translateRequest(parsed, {
11964
+ ...options.requestOptions,
11965
+ maxTools: maxToolsForNpm(route.npm)
11966
+ })
11967
+ );
11019
11968
  const effectiveProviderOptions = deepMergeProviderOptions(
11020
11969
  providerOptions,
11021
11970
  sdkParams.providerOptions
@@ -11028,7 +11977,8 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log17
11028
11977
  providerId: route.providerId,
11029
11978
  authType: route.authType,
11030
11979
  oauthAccountId: route.oauthAccountId,
11031
- providerData: route.providerData
11980
+ providerData: route.providerData,
11981
+ headers: route.headers
11032
11982
  });
11033
11983
  const responseId = `gateway-${Date.now()}`;
11034
11984
  const { fullStream } = streamText3({
@@ -11148,10 +12098,13 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log17
11148
12098
  res.end();
11149
12099
  }
11150
12100
  async function handleUnaryRequest(res, route, providerOptions, parsed, _log, options = {}) {
11151
- const sdkParams = applyClaudeCodeOAuthIdentity(route, translateRequest(parsed, {
11152
- ...options.requestOptions,
11153
- maxTools: maxToolsForNpm(route.npm)
11154
- }));
12101
+ const sdkParams = applyClaudeCodeOAuthIdentity(
12102
+ route,
12103
+ translateRequest(parsed, {
12104
+ ...options.requestOptions,
12105
+ maxTools: maxToolsForNpm(route.npm)
12106
+ })
12107
+ );
11155
12108
  const effectiveProviderOptions = deepMergeProviderOptions(
11156
12109
  providerOptions,
11157
12110
  sdkParams.providerOptions
@@ -11164,7 +12117,8 @@ async function handleUnaryRequest(res, route, providerOptions, parsed, _log, opt
11164
12117
  providerId: route.providerId,
11165
12118
  authType: route.authType,
11166
12119
  oauthAccountId: route.oauthAccountId,
11167
- providerData: route.providerData
12120
+ providerData: route.providerData,
12121
+ headers: route.headers
11168
12122
  });
11169
12123
  const responseId = `gateway-${Date.now()}`;
11170
12124
  const result = await generateText3({
@@ -11186,7 +12140,10 @@ async function handleUnaryRequest(res, route, providerOptions, parsed, _log, opt
11186
12140
  if (result.toolCalls?.length) {
11187
12141
  for (const tc of result.toolCalls) {
11188
12142
  parts.push({
11189
- functionCall: { name: tc.toolName, args: normalizeFunctionCallArgs(tc.input) }
12143
+ functionCall: {
12144
+ name: tc.toolName,
12145
+ args: normalizeFunctionCallArgs(tc.input)
12146
+ }
11190
12147
  });
11191
12148
  }
11192
12149
  }
@@ -11197,10 +12154,12 @@ async function handleUnaryRequest(res, route, providerOptions, parsed, _log, opt
11197
12154
  parts.push({ text: "" });
11198
12155
  }
11199
12156
  const response = {
11200
- candidates: [{
11201
- content: { role: "model", parts },
11202
- finishReason: mapFinishReason2(result.finishReason ?? "")
11203
- }],
12157
+ candidates: [
12158
+ {
12159
+ content: { role: "model", parts },
12160
+ finishReason: mapFinishReason2(result.finishReason ?? "")
12161
+ }
12162
+ ],
11204
12163
  usageMetadata: {
11205
12164
  promptTokenCount: result.usage?.inputTokens || 0,
11206
12165
  candidatesTokenCount: result.usage?.outputTokens || 0,
@@ -11233,7 +12192,8 @@ async function resolveAntigravityLaunchRoutes(opts) {
11233
12192
  apiKey,
11234
12193
  authType: opts.provider.authType,
11235
12194
  oauthAccountId: opts.provider.oauthAccountId,
11236
- providerData: opts.provider.providerData
12195
+ providerData: opts.provider.providerData,
12196
+ headers: opts.provider.headers
11237
12197
  };
11238
12198
  const ctx = {
11239
12199
  agent: "antigravity",
@@ -11260,7 +12220,6 @@ async function resolveAntigravityLaunchRoutes(opts) {
11260
12220
  }
11261
12221
 
11262
12222
  // src/gateway/antigravity/launch-cli.ts
11263
- init_config();
11264
12223
  import { execFileSync as execFileSync2, execSync as execSync2, spawn as spawn3 } from "child_process";
11265
12224
  import { existsSync as existsSync10 } from "fs";
11266
12225
  import { homedir as homedir7 } from "os";
@@ -11435,7 +12394,6 @@ function prepareIdeProfile(profileDir, gatewayUrl, isIDE) {
11435
12394
  }
11436
12395
 
11437
12396
  // src/gateway/antigravity/launch-ide.ts
11438
- init_config();
11439
12397
  function sleep(ms) {
11440
12398
  return new Promise((resolve) => setTimeout(resolve, ms));
11441
12399
  }
@@ -11486,14 +12444,20 @@ function defaultProcessList() {
11486
12444
  }
11487
12445
  }
11488
12446
  function isAntigravityIdeRunning(profileDir, processList = defaultProcessList) {
11489
- if (process.platform === "win32") return winIsProcessRunningForProfile("Antigravity IDE.exe", profileDir);
12447
+ if (process.platform === "win32")
12448
+ return winIsProcessRunningForProfile("Antigravity IDE.exe", profileDir);
11490
12449
  const output = processList();
11491
- return output.split("\n").some((line2) => line2.includes("Antigravity IDE.app") && line2.includes(`--user-data-dir=${profileDir}`));
12450
+ return output.split("\n").some(
12451
+ (line2) => line2.includes("Antigravity IDE.app") && line2.includes(`--user-data-dir=${profileDir}`)
12452
+ );
11492
12453
  }
11493
12454
  function isAntigravityAppRunning(profileDir, processList = defaultProcessList) {
11494
- if (process.platform === "win32") return winIsProcessRunningForProfile("Antigravity.exe", profileDir);
12455
+ if (process.platform === "win32")
12456
+ return winIsProcessRunningForProfile("Antigravity.exe", profileDir);
11495
12457
  const output = processList();
11496
- return output.split("\n").some((line2) => line2.includes("Antigravity.app") && line2.includes(`--user-data-dir=${profileDir}`));
12458
+ return output.split("\n").some(
12459
+ (line2) => line2.includes("Antigravity.app") && line2.includes(`--user-data-dir=${profileDir}`)
12460
+ );
11497
12461
  }
11498
12462
  async function waitForAntigravityIdeQuit(profileDir, options = {}) {
11499
12463
  const processList = options.processList ?? defaultProcessList;
@@ -11564,7 +12528,14 @@ function findAntigravityAppBinary() {
11564
12528
  if (process.platform !== "darwin") return null;
11565
12529
  const defaultPath = "/Applications/Antigravity.app/Contents/MacOS/Antigravity";
11566
12530
  if (existsSync11(defaultPath)) return defaultPath;
11567
- const homePath = join11(homedir9(), "Applications", "Antigravity.app", "Contents", "MacOS", "Antigravity");
12531
+ const homePath = join11(
12532
+ homedir9(),
12533
+ "Applications",
12534
+ "Antigravity.app",
12535
+ "Contents",
12536
+ "MacOS",
12537
+ "Antigravity"
12538
+ );
11568
12539
  if (existsSync11(homePath)) return homePath;
11569
12540
  return null;
11570
12541
  }
@@ -11579,7 +12550,16 @@ function findAntigravityIdeBinary() {
11579
12550
  if (process.platform !== "darwin") return null;
11580
12551
  const defaultPath = "/Applications/Antigravity IDE.app/Contents/Resources/app/bin/antigravity-ide";
11581
12552
  if (existsSync11(defaultPath)) return defaultPath;
11582
- const homePath = join11(homedir9(), "Applications", "Antigravity IDE.app", "Contents", "Resources", "app", "bin", "antigravity-ide");
12553
+ const homePath = join11(
12554
+ homedir9(),
12555
+ "Applications",
12556
+ "Antigravity IDE.app",
12557
+ "Contents",
12558
+ "Resources",
12559
+ "app",
12560
+ "bin",
12561
+ "antigravity-ide"
12562
+ );
11583
12563
  if (existsSync11(homePath)) return homePath;
11584
12564
  return null;
11585
12565
  }
@@ -11599,10 +12579,7 @@ function launchAntigravityApp(env, profileDir, gatewayUrl, extraArgs) {
11599
12579
  return;
11600
12580
  }
11601
12581
  prepareIdeProfile(profileDir, gatewayUrl, false);
11602
- const args = [
11603
- `--user-data-dir=${profileDir}`,
11604
- ...extraArgs
11605
- ];
12582
+ const args = [`--user-data-dir=${profileDir}`, ...extraArgs];
11606
12583
  const child = spawn4(binaryPath, args, {
11607
12584
  stdio: "inherit",
11608
12585
  env
@@ -11702,7 +12679,9 @@ function resolveAntigravityBootModel(provider, modelSelector) {
11702
12679
  };
11703
12680
  }
11704
12681
  async function pickAntigravityCliFavoriteLaunchModel(favorites, allProviders) {
11705
- const resolved = favorites.map((favorite) => resolveFavoriteModel(favorite, allProviders)).filter((entry) => entry !== null);
12682
+ const resolved = favorites.map((favorite) => resolveFavoriteModel(favorite, allProviders)).filter(
12683
+ (entry) => entry !== null
12684
+ );
11706
12685
  if (resolved.length === 0) {
11707
12686
  p14.log.warn("No Antigravity CLI favorites are available.");
11708
12687
  p14.log.info(pc12.dim("Manage them with `anygate favorites --agy`."));
@@ -11743,6 +12722,15 @@ async function resolveAntigravityLaunch(prefs, boot) {
11743
12722
  p14.log.info(pc12.dim("Run anygate providers add or import to get started."));
11744
12723
  return null;
11745
12724
  }
12725
+ if (boot?.launchProvider && boot?.launchAllModels) {
12726
+ const provider = allProviders.find((p18) => p18.id === boot.launchProvider);
12727
+ if (!provider) {
12728
+ p14.log.error(`Provider not found: ${boot.launchProvider}`);
12729
+ return null;
12730
+ }
12731
+ const model = provider.models[0];
12732
+ return { provider, model, allProviders, allModels: true };
12733
+ }
11746
12734
  if (boot?.launchProvider && boot?.launchModel) {
11747
12735
  const provider = allProviders.find((p18) => p18.id === boot.launchProvider);
11748
12736
  if (!provider) {
@@ -11799,11 +12787,15 @@ async function resolveAntigravityLaunch(prefs, boot) {
11799
12787
  }
11800
12788
  }
11801
12789
  async function resolveAndBuildRoutes(provider, model, allProviders, prefs, opts) {
12790
+ const allModelsFavorites = opts.allModels ? provider.models.map((m) => ({
12791
+ providerId: provider.id,
12792
+ modelId: m.id
12793
+ })) : [];
11802
12794
  const result = await resolveAntigravityLaunchRoutes({
11803
12795
  provider,
11804
12796
  model,
11805
12797
  allProviders,
11806
- favorites: prefs.antigravityCliFavoriteModels ?? [],
12798
+ favorites: opts.allModels ? allModelsFavorites : prefs.antigravityCliFavoriteModels ?? [],
11807
12799
  maxRoutes: opts.maxRoutes
11808
12800
  });
11809
12801
  if (!result) {
@@ -11822,7 +12814,9 @@ async function resolveAndBuildRoutes(provider, model, allProviders, prefs, opts)
11822
12814
  );
11823
12815
  }
11824
12816
  if (result.capacitySkippedFavorites.length > 0) {
11825
- p14.log.warn(formatAgyCapacityWarning(opts.validatedSlotCount, result.capacitySkippedFavorites.length));
12817
+ p14.log.warn(
12818
+ formatAgyCapacityWarning(opts.validatedSlotCount, result.capacitySkippedFavorites.length)
12819
+ );
11826
12820
  p14.log.warn(
11827
12821
  "Not exposed: " + result.capacitySkippedFavorites.map((fav) => `${fav.providerId}:${fav.modelId}`).join(", ")
11828
12822
  );
@@ -11867,7 +12861,9 @@ async function runAntigravityCommand(intro, tracePrefix, trace, boot, launch, op
11867
12861
  const prefs = loadPreferences();
11868
12862
  gateIntro(intro);
11869
12863
  if (tracePrefix === "agy" && (prefs.favoriteModels?.length ?? 0) > 0 && (prefs.antigravityCliFavoriteModels?.length ?? 0) === 0 && !prefs.antigravityCliFavoritesHintShown) {
11870
- p14.log.info("Tip: AGY uses its own favorites list. Run `anygate favorites --agy` to set up switching.");
12864
+ p14.log.info(
12865
+ "Tip: AGY uses its own favorites list. Run `anygate favorites --agy` to set up switching."
12866
+ );
11871
12867
  savePreferences({ antigravityCliFavoritesHintShown: true });
11872
12868
  }
11873
12869
  const agyFavorites = prefs.antigravityCliFavoriteModels ?? [];
@@ -11913,7 +12909,8 @@ async function launchWithSelection(selection, prefs, opts, trace, tracePrefix, b
11913
12909
  maxRoutes: routeLimit,
11914
12910
  validatedSlotCount: routeLimit,
11915
12911
  pauseForCapacityWarning: opts.pauseForCapacityWarning ?? false,
11916
- childArgs: opts.childArgs ?? []
12912
+ childArgs: opts.childArgs ?? [],
12913
+ allModels: selection.allModels
11917
12914
  });
11918
12915
  if (!routeResult) return 1;
11919
12916
  savePreferences({
@@ -11953,7 +12950,12 @@ async function runAgyCommand(childArgs, trace = false, boot) {
11953
12950
  trace,
11954
12951
  boot,
11955
12952
  (env, routes) => launchAntigravityCli(env, buildAgyLaunchArgs(routes[0].displayName, childArgs)),
11956
- { childArgs, versionGuard: true, pauseForCapacityWarning: true, useFavoritesCatalog: agyArgsIncludeFavoritesFlag(childArgs) }
12953
+ {
12954
+ childArgs,
12955
+ versionGuard: true,
12956
+ pauseForCapacityWarning: true,
12957
+ useFavoritesCatalog: agyArgsIncludeFavoritesFlag(childArgs)
12958
+ }
11957
12959
  );
11958
12960
  }
11959
12961
  async function runAntigravityAppCommand(childArgs, trace = false, boot) {
@@ -11970,7 +12972,9 @@ async function runAntigravityAppCommand(childArgs, trace = false, boot) {
11970
12972
  initialValue: true
11971
12973
  });
11972
12974
  if (p14.isCancel(restart) || !restart) {
11973
- p14.log.info("Quit and reopen Antigravity when you are ready for the new gateway to take effect.");
12975
+ p14.log.info(
12976
+ "Quit and reopen Antigravity when you are ready for the new gateway to take effect."
12977
+ );
11974
12978
  return 0;
11975
12979
  }
11976
12980
  quitAntigravityAppGracefully();
@@ -12001,7 +13005,12 @@ async function runAntigravityAppCommand(childArgs, trace = false, boot) {
12001
13005
  }
12002
13006
  return 0;
12003
13007
  },
12004
- { childArgs, versionGuard: false, pauseForCapacityWarning: false, useFavoritesCatalog: agyArgsIncludeFavoritesFlag(childArgs) }
13008
+ {
13009
+ childArgs,
13010
+ versionGuard: false,
13011
+ pauseForCapacityWarning: false,
13012
+ useFavoritesCatalog: agyArgsIncludeFavoritesFlag(childArgs)
13013
+ }
12005
13014
  );
12006
13015
  }
12007
13016
  async function runAntigravityIdeCommand(childArgs, trace = false, boot) {
@@ -12018,7 +13027,9 @@ async function runAntigravityIdeCommand(childArgs, trace = false, boot) {
12018
13027
  initialValue: true
12019
13028
  });
12020
13029
  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.");
13030
+ p14.log.info(
13031
+ "Quit and reopen Antigravity IDE when you are ready for the new gateway to take effect."
13032
+ );
12022
13033
  return 0;
12023
13034
  }
12024
13035
  quitAntigravityIdeGracefully();
@@ -12049,7 +13060,12 @@ async function runAntigravityIdeCommand(childArgs, trace = false, boot) {
12049
13060
  }
12050
13061
  return 0;
12051
13062
  },
12052
- { childArgs, versionGuard: false, pauseForCapacityWarning: false, useFavoritesCatalog: agyArgsIncludeFavoritesFlag(childArgs) }
13063
+ {
13064
+ childArgs,
13065
+ versionGuard: false,
13066
+ pauseForCapacityWarning: false,
13067
+ useFavoritesCatalog: agyArgsIncludeFavoritesFlag(childArgs)
13068
+ }
12053
13069
  );
12054
13070
  }
12055
13071
 
@@ -12139,7 +13155,7 @@ Examples:
12139
13155
  `;
12140
13156
  async function handleAgyCommand(parsed) {
12141
13157
  if (parsed.showVersion) {
12142
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
13158
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
12143
13159
  console.log(VERSION2);
12144
13160
  return 0;
12145
13161
  }
@@ -12149,12 +13165,13 @@ async function handleAgyCommand(parsed) {
12149
13165
  }
12150
13166
  return runAgyCommand(parsed.claudeArgs ?? [], parsed.trace ?? false, {
12151
13167
  launchProvider: parsed.launchProvider,
12152
- launchModel: parsed.launchModel
13168
+ launchModel: parsed.launchModel,
13169
+ launchAllModels: parsed.launchAllModels || parsed.launchModel === "All"
12153
13170
  });
12154
13171
  }
12155
13172
  async function handleAntigravityAppCommand(parsed) {
12156
13173
  if (parsed.showVersion) {
12157
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
13174
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
12158
13175
  console.log(VERSION2);
12159
13176
  return 0;
12160
13177
  }
@@ -12164,12 +13181,13 @@ async function handleAntigravityAppCommand(parsed) {
12164
13181
  }
12165
13182
  return runAntigravityAppCommand(parsed.claudeArgs ?? [], parsed.trace ?? false, {
12166
13183
  launchProvider: parsed.launchProvider,
12167
- launchModel: parsed.launchModel
13184
+ launchModel: parsed.launchModel,
13185
+ launchAllModels: parsed.launchAllModels || parsed.launchModel === "All"
12168
13186
  });
12169
13187
  }
12170
13188
  async function handleAntigravityIdeCommand(parsed) {
12171
13189
  if (parsed.showVersion) {
12172
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
13190
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
12173
13191
  console.log(VERSION2);
12174
13192
  return 0;
12175
13193
  }
@@ -12179,7 +13197,8 @@ async function handleAntigravityIdeCommand(parsed) {
12179
13197
  }
12180
13198
  return runAntigravityIdeCommand(parsed.claudeArgs ?? [], parsed.trace ?? false, {
12181
13199
  launchProvider: parsed.launchProvider,
12182
- launchModel: parsed.launchModel
13200
+ launchModel: parsed.launchModel,
13201
+ launchAllModels: parsed.launchAllModels || parsed.launchModel === "All"
12183
13202
  });
12184
13203
  }
12185
13204
 
@@ -12274,12 +13293,11 @@ Options:
12274
13293
  `);
12275
13294
  return 0;
12276
13295
  }
12277
- const { runUiCommand } = await import("./command-7AI36ICY.js");
13296
+ const { runUiCommand } = await import("./command-XIDZGWNR.js");
12278
13297
  return runUiCommand({ trace: parsed.trace });
12279
13298
  }
12280
13299
 
12281
13300
  // src/cli/models.ts
12282
- init_config();
12283
13301
  import pc14 from "picocolors";
12284
13302
  import * as p16 from "@clack/prompts";
12285
13303
 
@@ -12287,7 +13305,7 @@ import * as p16 from "@clack/prompts";
12287
13305
  import * as p15 from "@clack/prompts";
12288
13306
  import pc13 from "picocolors";
12289
13307
 
12290
- // src/apps/claude/favorites.ts
13308
+ // src/apps/shared/favorites.ts
12291
13309
  function isFavorite(list, fav) {
12292
13310
  return list.some((f) => f.providerId === fav.providerId && f.modelId === fav.modelId);
12293
13311
  }
@@ -12371,7 +13389,11 @@ async function pickGlobalFavoriteModel(providers, favorites, opts) {
12371
13389
  message: "Add a favorite",
12372
13390
  options: [
12373
13391
  { 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" }
13392
+ {
13393
+ value: ADD_BY_PROVIDER,
13394
+ label: pc13.cyan("Browse by provider \u2192"),
13395
+ hint: "Pick one provider first"
13396
+ }
12375
13397
  ]
12376
13398
  });
12377
13399
  if (p15.isCancel(fallback) || fallback === "back") return null;
@@ -12398,7 +13420,9 @@ async function pickGlobalFavoriteModel(providers, favorites, opts) {
12398
13420
  const picked = parseGlobalFavoritePickKey(result.id, matched);
12399
13421
  if (!picked) continue;
12400
13422
  if (isFavorite(favorites, { providerId: picked.providerId, modelId: picked.model.id })) {
12401
- p15.log.warn(`${picked.model.name || picked.model.id} (${picked.providerName}) is already in your favorites.`);
13423
+ p15.log.warn(
13424
+ `${picked.model.name || picked.model.id} (${picked.providerName}) is already in your favorites.`
13425
+ );
12402
13426
  continue;
12403
13427
  }
12404
13428
  return picked;
@@ -12427,7 +13451,9 @@ async function runModelsCommand(parsed) {
12427
13451
  }));
12428
13452
  if (favoriteProviders.length === 0) {
12429
13453
  p16.log.warn("No providers found.");
12430
- p16.log.info(`OpenCode Zen/Go is always available. Add providers with ${pc14.cyan("anygate providers")}.`);
13454
+ p16.log.info(
13455
+ `OpenCode Zen/Go is always available. Add providers with ${pc14.cyan("anygate providers")}.`
13456
+ );
12431
13457
  gateOutro("Done");
12432
13458
  return 0;
12433
13459
  }
@@ -12500,7 +13526,9 @@ async function runModelsCommand(parsed) {
12500
13526
  }
12501
13527
  }
12502
13528
  if (addPath === "free") {
12503
- const globalPick = await pickGlobalFavoriteModel(favoriteProviders, favorites, { freeOnly: true });
13529
+ const globalPick = await pickGlobalFavoriteModel(favoriteProviders, favorites, {
13530
+ freeOnly: true
13531
+ });
12504
13532
  if (globalPick === null) continue;
12505
13533
  if (globalPick !== ADD_BY_PROVIDER) {
12506
13534
  provider = favoriteProviders.find((ap) => ap.id === globalPick.providerId);
@@ -12694,7 +13722,7 @@ async function runValidateSubcommand(parsed) {
12694
13722
  // src/cli/providers.ts
12695
13723
  async function handleProvidersCommand(parsed) {
12696
13724
  if (parsed.showVersion) {
12697
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
13725
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
12698
13726
  console.log(VERSION2);
12699
13727
  return 0;
12700
13728
  }
@@ -12807,7 +13835,7 @@ async function runDoctorCommand(_dryRun) {
12807
13835
  // src/cli/doctor.ts
12808
13836
  async function handleDoctorCommand(parsed) {
12809
13837
  if (parsed.showVersion) {
12810
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
13838
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
12811
13839
  console.log(VERSION2);
12812
13840
  return 0;
12813
13841
  }
@@ -12862,7 +13890,8 @@ function detectShell() {
12862
13890
  if (shell.includes("zsh")) return "zsh";
12863
13891
  if (shell.includes("bash")) return "bash";
12864
13892
  if (shell.includes("fish")) return "fish";
12865
- if (process.env["PSModulePath"] || process.env["POWERSHELL_DISTRIBUTION_CHANNEL"]) return "powershell";
13893
+ if (process.env["PSModulePath"] || process.env["POWERSHELL_DISTRIBUTION_CHANNEL"])
13894
+ return "powershell";
12866
13895
  return void 0;
12867
13896
  }
12868
13897
  function normalizeShell(input) {
@@ -12905,7 +13934,9 @@ _anygate "$@"
12905
13934
  `;
12906
13935
  }
12907
13936
  function fishScript() {
12908
- const lines = SUBCOMMANDS.map((c) => `complete -c anygate -n "not __fish_seen_subcommand_from ${SUBCOMMANDS.join(" ")}" -a ${c} -d 'anygate ${c}'`);
13937
+ const lines = SUBCOMMANDS.map(
13938
+ (c) => `complete -c anygate -n "not __fish_seen_subcommand_from ${SUBCOMMANDS.join(" ")}" -a ${c} -d 'anygate ${c}'`
13939
+ );
12909
13940
  lines.push(`complete -c anygate -s h -l help -d 'Show help'`);
12910
13941
  lines.push(`complete -c anygate -s v -l version -d 'Show version'`);
12911
13942
  return `# anygate fish completion
@@ -12944,7 +13975,7 @@ function runCompletionsCommand(shellArg) {
12944
13975
  // src/cli/completions.ts
12945
13976
  async function handleCompletionsCommand(parsed) {
12946
13977
  if (parsed.showVersion) {
12947
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
13978
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
12948
13979
  console.log(VERSION2);
12949
13980
  return 0;
12950
13981
  }
@@ -12971,18 +14002,11 @@ Examples:
12971
14002
 
12972
14003
  // src/apps/shared/self-update.ts
12973
14004
  import pc17 from "picocolors";
12974
- import { spawn as spawn5, execFileSync as execFileSync4 } from "child_process";
14005
+ import { spawn as spawn5 } from "child_process";
12975
14006
  import * as p17 from "@clack/prompts";
12976
- function resolveNpmBin() {
12977
- if (process.platform === "win32") {
12978
- try {
12979
- const found = execFileSync4("where", ["npm"], { stdio: ["ignore", "pipe", "ignore"] }).toString().split(/\r?\n/).map((s) => s.trim()).find((s) => s.toLowerCase().endsWith(".cmd") || s.toLowerCase().endsWith("npm"));
12980
- if (found) return found;
12981
- } catch {
12982
- }
12983
- return "npm.cmd";
12984
- }
12985
- return "npm";
14007
+ var INSTALL_ARGS = ["install", "-g", "anygate@latest"];
14008
+ function resolveNpmSpawn() {
14009
+ return { bin: "npm", shell: process.platform === "win32" };
12986
14010
  }
12987
14011
  async function runUpdateCommand(dryRun) {
12988
14012
  const update = await checkForUpdates();
@@ -12993,9 +14017,9 @@ async function runUpdateCommand(dryRun) {
12993
14017
  p17.log.info(
12994
14018
  `Update available: ${pc17.cyan(`v${update.currentVersion}`)} \u2192 ${pc17.green(`v${update.latestVersion}`)}`
12995
14019
  );
12996
- const npmBin = resolveNpmBin();
14020
+ const { bin: npmBin, shell } = resolveNpmSpawn();
12997
14021
  if (dryRun) {
12998
- p17.log.step(`Would run: ${pc17.bold(`${npmBin} install -g anygate@latest`)}`);
14022
+ p17.log.step(`Would run: ${pc17.bold(`${npmBin} ${INSTALL_ARGS.join(" ")}`)}`);
12999
14023
  p17.log.warn("Dry run \u2014 no changes made.");
13000
14024
  return 0;
13001
14025
  }
@@ -13007,23 +14031,35 @@ async function runUpdateCommand(dryRun) {
13007
14031
  p17.log.info(`Update skipped. Run ${pc17.cyan(UPDATE_COMMAND)} later if you change your mind.`);
13008
14032
  return 0;
13009
14033
  }
13010
- p17.log.info(`Running ${pc17.cyan(`${npmBin} install -g anygate@latest`)}...`);
13011
- const child = spawn5(npmBin, ["install", "-g", "anygate@latest"], {
14034
+ p17.log.info(`Running ${pc17.cyan(`${npmBin} ${INSTALL_ARGS.join(" ")}`)}...`);
14035
+ const child = spawn5(npmBin, [...INSTALL_ARGS], {
13012
14036
  stdio: "inherit",
14037
+ shell,
13013
14038
  windowsHide: true
13014
14039
  });
13015
14040
  return new Promise((resolve) => {
14041
+ let settled = false;
14042
+ const settle = (code) => {
14043
+ settled = true;
14044
+ resolve(code);
14045
+ };
13016
14046
  child.on("error", (err) => {
13017
- p17.log.error(`Failed to start npm: ${err instanceof Error ? err.message : String(err)}`);
13018
- resolve(1);
14047
+ if (settled) return;
14048
+ const msg = err instanceof Error ? err.message : String(err);
14049
+ p17.log.error(`Could not start npm: ${msg}`);
14050
+ p17.log.info(`Update anygate manually with: ${pc17.cyan(UPDATE_COMMAND)}`);
14051
+ settle(1);
13019
14052
  });
13020
14053
  child.on("close", (code) => {
14054
+ if (settled) return;
13021
14055
  if (code === 0) {
13022
- p17.log.success("anygate updated. Restart your shell or re-run anygate to use the new version.");
14056
+ p17.log.success(
14057
+ "anygate updated. Restart your shell or re-run anygate to use the new version."
14058
+ );
13023
14059
  } else {
13024
14060
  p17.log.error(`Update failed (exit ${code}). Try ${pc17.cyan(UPDATE_COMMAND)} manually.`);
13025
14061
  }
13026
- resolve(code ?? 1);
14062
+ settle(code ?? 1);
13027
14063
  });
13028
14064
  });
13029
14065
  }
@@ -13031,7 +14067,7 @@ async function runUpdateCommand(dryRun) {
13031
14067
  // src/cli/update.ts
13032
14068
  async function handleUpdateCommand(parsed) {
13033
14069
  if (parsed.showVersion) {
13034
- const { VERSION: VERSION2 } = await import("./constants-HE3EOSMH.js");
14070
+ const { VERSION: VERSION2 } = await import("./constants-WLMOLKEO.js");
13035
14071
  console.log(VERSION2);
13036
14072
  return 0;
13037
14073
  }
@@ -13086,9 +14122,21 @@ registerCommand("completions", handleCompletionsCommand);
13086
14122
  registerCommand("update", handleUpdateCommand);
13087
14123
 
13088
14124
  // src/cli.ts
13089
- var STARTER_CLAUDE_FLAGS = /* @__PURE__ */ new Set(["--dry-run", "--setup", "--trace", "--help", "-h", "--version", "-v"]);
14125
+ var STARTER_CLAUDE_FLAGS = /* @__PURE__ */ new Set([
14126
+ "--dry-run",
14127
+ "--setup",
14128
+ "--trace",
14129
+ "--help",
14130
+ "-h",
14131
+ "--version",
14132
+ "-v"
14133
+ ]);
13090
14134
  var GATEWAY_LAUNCH_FLAGS = /* @__PURE__ */ new Set(["--provider", "--model"]);
13091
14135
  function parseGatewayLaunchFlag(arg, rest, index, parsed) {
14136
+ if (arg === "--all-models") {
14137
+ parsed.launchAllModels = true;
14138
+ return index;
14139
+ }
13092
14140
  if (arg === "--provider" || arg === "--model") {
13093
14141
  const value = rest[index + 1];
13094
14142
  if (!value || value.startsWith("-")) {