anygate 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -4,9 +4,12 @@ import {
4
4
  BACKENDS,
5
5
  CODEX_APP_AUTO_COMPACT_RATIO,
6
6
  CODEX_APP_PROVIDER_ID,
7
+ CONFLICTING_ENV_VARS,
8
+ GATEWAY_PORT,
7
9
  GLOBAL_OPENCODE_KEYRING_ACCOUNT,
8
10
  MAX_MODEL_CATALOG,
9
11
  PREVIEW_PROXY_PORT,
12
+ UPDATE_COMMAND,
10
13
  VERSION,
11
14
  VERTEX_ANTHROPIC_NPM,
12
15
  addCustomEndpointProvider,
@@ -165,18 +168,18 @@ import {
165
168
  validateCustomEndpointUrl,
166
169
  writeSecureLogLine,
167
170
  zenRegistryStub
168
- } from "./chunk-6GVUN4JO.js";
171
+ } from "./chunk-E2MV3GDX.js";
169
172
  import {
170
173
  filterTemplates,
171
174
  getTemplateById,
172
175
  listAddableTemplates,
173
176
  listSupportedTemplates,
174
177
  listVisibleOAuthTemplates
175
- } from "./chunk-YYSUTRMV.js";
178
+ } from "./chunk-VKROC37K.js";
176
179
 
177
180
  // src/cli.ts
178
- import pc12 from "picocolors";
179
- import * as p14 from "@clack/prompts";
181
+ import pc15 from "picocolors";
182
+ import * as p15 from "@clack/prompts";
180
183
  import { realpathSync } from "fs";
181
184
  import { fileURLToPath } from "url";
182
185
 
@@ -331,7 +334,7 @@ async function importFromOpencode(options = {}) {
331
334
  }
332
335
  continue;
333
336
  }
334
- const existingIdx = registry.providers.findIndex((p15) => p15.id === entry.id);
337
+ const existingIdx = registry.providers.findIndex((p16) => p16.id === entry.id);
335
338
  const existing = existingIdx >= 0 ? registry.providers[existingIdx] : void 0;
336
339
  if (existing && options.resolveConflict) {
337
340
  const choice = await options.resolveConflict({
@@ -369,7 +372,7 @@ async function importFromOpencode(options = {}) {
369
372
  if (isOAuth) oauthImported += 1;
370
373
  }
371
374
  const alreadyReportedIds = new Set(skipped.map((s) => s.id));
372
- const registryProviderIds = new Set(registry.providers.map((p15) => p15.id));
375
+ const registryProviderIds = new Set(registry.providers.map((p16) => p16.id));
373
376
  for (const provider of listCredentialSkippedProviders(
374
377
  raw,
375
378
  authEntries,
@@ -956,7 +959,7 @@ async function resolveLocalProviderApiKey(provider) {
956
959
  if (template?.apiKeyOptional || template?.anonymousFreeModels) {
957
960
  return "anonymous";
958
961
  }
959
- const reg = loadRegistry().providers.find((p15) => p15.id === provider.id);
962
+ const reg = loadRegistry().providers.find((p16) => p16.id === provider.id);
960
963
  const authRef = reg?.authRef ?? (provider.id === "zen" || provider.id === "go" ? "keyring:global:opencode" : oauthAuthRef(provider.id));
961
964
  return resolveProviderCredential(provider.id, authRef);
962
965
  }
@@ -1238,7 +1241,7 @@ async function runProvidersRefreshModels(providerId) {
1238
1241
  const resolveKey = async (provider) => resolveProviderCredential(provider.id, provider.authRef);
1239
1242
  if (providerId) {
1240
1243
  const registry = loadRegistry();
1241
- const provider = registry.providers.find((p15) => p15.id === providerId);
1244
+ const provider = registry.providers.find((p16) => p16.id === providerId);
1242
1245
  if (!provider) {
1243
1246
  p5.log.error(`Provider not found: ${providerId}`);
1244
1247
  return 1;
@@ -1247,7 +1250,7 @@ async function runProvidersRefreshModels(providerId) {
1247
1250
  spinner10.start(`Refreshing ${provider.name}...`);
1248
1251
  const key = await resolveRefreshCredential(
1249
1252
  provider,
1250
- async (p15) => resolveProviderCredential(p15.id, p15.authRef)
1253
+ async (p16) => resolveProviderCredential(p16.id, p16.authRef)
1251
1254
  );
1252
1255
  const result = await refreshProviderModels(providerId, key);
1253
1256
  spinner10.stop("");
@@ -1314,7 +1317,7 @@ async function runProvidersList() {
1314
1317
  async function pickTemplateFromCatalog() {
1315
1318
  while (true) {
1316
1319
  const registry = loadRegistry();
1317
- const configuredIds = new Set(registry.providers.map((p15) => p15.id));
1320
+ const configuredIds = new Set(registry.providers.map((p16) => p16.id));
1318
1321
  const templates = listAddableTemplates(configuredIds);
1319
1322
  if (templates.length === 0) return null;
1320
1323
  const method = await p5.select({
@@ -1369,7 +1372,7 @@ async function pickTemplateFromCatalog() {
1369
1372
  }
1370
1373
  }
1371
1374
  async function runTemplateAddFlow() {
1372
- if (listAddableTemplates(loadRegistry().providers.map((p15) => p15.id)).length === 0) {
1375
+ if (listAddableTemplates(loadRegistry().providers.map((p16) => p16.id)).length === 0) {
1373
1376
  p5.log.info("All catalog providers are already configured.");
1374
1377
  return 0;
1375
1378
  }
@@ -1556,7 +1559,7 @@ async function runProvidersAdd() {
1556
1559
  const registry = loadRegistry();
1557
1560
  const hasOpencode = findOpencodeBinary() !== null;
1558
1561
  const options = [];
1559
- const addableTemplates = listAddableTemplates(registry.providers.map((p15) => p15.id));
1562
+ const addableTemplates = listAddableTemplates(registry.providers.map((p16) => p16.id));
1560
1563
  if (addableTemplates.length > 0) {
1561
1564
  options.push({
1562
1565
  value: "templates",
@@ -1598,11 +1601,11 @@ async function runProvidersRemove(id, interactive = false) {
1598
1601
  return 1;
1599
1602
  }
1600
1603
  if (interactive) {
1601
- const confirm9 = await p5.confirm({
1604
+ const confirm10 = await p5.confirm({
1602
1605
  message: `Remove ${provider.name} (${id})?`,
1603
1606
  initialValue: false
1604
1607
  });
1605
- if (p5.isCancel(confirm9) || !confirm9) {
1608
+ if (p5.isCancel(confirm10) || !confirm10) {
1606
1609
  p5.cancel("Cancelled.");
1607
1610
  return 0;
1608
1611
  }
@@ -1825,10 +1828,10 @@ function isClaudeCodeOAuthRoute(input) {
1825
1828
  return input.providerId === "claude-code" && input.authType === "oauth";
1826
1829
  }
1827
1830
  function prependClaudeCodeBillingLine(system) {
1828
- const line = buildClaudeCodeBillingSystemLine();
1829
- if (!system?.trim()) return line;
1830
- if (system.startsWith(line)) return system;
1831
- return `${line}
1831
+ const line2 = buildClaudeCodeBillingSystemLine();
1832
+ if (!system?.trim()) return line2;
1833
+ if (system.startsWith(line2)) return system;
1834
+ return `${line2}
1832
1835
 
1833
1836
  ${system}`;
1834
1837
  }
@@ -1871,7 +1874,7 @@ function applyClaudeCodeOAuthIdentity(input, sdkParams) {
1871
1874
  import { streamText, generateText, tool, jsonSchema } from "ai";
1872
1875
  function messageText(content) {
1873
1876
  if (typeof content === "string") return content;
1874
- return (content ?? []).map((p15) => p15.type === "output_text" || p15.type === "input_text" || p15.type === "text" ? p15.text ?? "" : "").join("");
1877
+ return (content ?? []).map((p16) => p16.type === "output_text" || p16.type === "input_text" || p16.type === "text" ? p16.text ?? "" : "").join("");
1875
1878
  }
1876
1879
  function extractDeveloperAndInstructions(items, instructions) {
1877
1880
  const developerParts = [];
@@ -2780,9 +2783,9 @@ function estimateCodexRequestChars(params) {
2780
2783
  if (Array.isArray(msg.content)) {
2781
2784
  for (const part of msg.content) {
2782
2785
  if (!part || typeof part !== "object") continue;
2783
- const p15 = part;
2784
- if (typeof p15["text"] === "string") {
2785
- chars += p15["text"].length;
2786
+ const p16 = part;
2787
+ if (typeof p16["text"] === "string") {
2788
+ chars += p16["text"].length;
2786
2789
  } else {
2787
2790
  chars += JSON.stringify(part).length;
2788
2791
  }
@@ -2813,9 +2816,9 @@ function clipLargeTextParts(params, maxCharsPerPart) {
2813
2816
  ...msg,
2814
2817
  content: msg.content.map((part) => {
2815
2818
  if (!part || typeof part !== "object") return part;
2816
- const p15 = part;
2817
- if (typeof p15.text !== "string") return part;
2818
- return { ...p15, text: clipTextForContext(p15.text, maxCharsPerPart) };
2819
+ const p16 = part;
2820
+ if (typeof p16.text !== "string") return part;
2821
+ return { ...p16, text: clipTextForContext(p16.text, maxCharsPerPart) };
2819
2822
  })
2820
2823
  };
2821
2824
  });
@@ -2849,7 +2852,7 @@ var COMPACTION_PROMPT_MARKER = "You are performing a CONTEXT CHECKPOINT COMPACTI
2849
2852
  function inputItemText(content) {
2850
2853
  if (typeof content === "string") return content;
2851
2854
  if (!Array.isArray(content)) return "";
2852
- return content.map((p15) => p15 && typeof p15 === "object" && typeof p15.text === "string" ? p15.text : "").join("");
2855
+ return content.map((p16) => p16 && typeof p16 === "object" && typeof p16.text === "string" ? p16.text : "").join("");
2853
2856
  }
2854
2857
  function isLikelyCodexCompactionRequest(body) {
2855
2858
  if (!Array.isArray(body.input)) return false;
@@ -2935,16 +2938,16 @@ async function startCodexProxy(routes, options = {}) {
2935
2938
  }));
2936
2939
  }
2937
2940
  return new Promise((resolve, reject2) => {
2938
- const log14 = debug ? makeTraceLogger(getCodexProxyDebugLogPath()) : () => {
2941
+ const log15 = debug ? makeTraceLogger(getCodexProxyDebugLogPath()) : () => {
2939
2942
  };
2940
2943
  const onRejection = (reason) => {
2941
- if (debug) log14(`unhandled-rejection: ${formatUpstreamError(reason)}`);
2944
+ if (debug) log15(`unhandled-rejection: ${formatUpstreamError(reason)}`);
2942
2945
  };
2943
2946
  process.on("unhandledRejection", onRejection);
2944
2947
  const server = createServer(async (req, res) => {
2945
2948
  const url = req.url ?? "/";
2946
2949
  if (debug) {
2947
- log14(`-> ${req.method} ${url} content-type=${req.headers["content-type"] ?? "(none)"} content-encoding=${req.headers["content-encoding"] ?? "(none)"} content-length=${req.headers["content-length"] ?? "(none)"}`);
2950
+ log15(`-> ${req.method} ${url} content-type=${req.headers["content-type"] ?? "(none)"} content-encoding=${req.headers["content-encoding"] ?? "(none)"} content-length=${req.headers["content-length"] ?? "(none)"}`);
2948
2951
  }
2949
2952
  if (!requireAuth && req.method === "POST") {
2950
2953
  const origin = req.headers.origin;
@@ -3022,7 +3025,7 @@ async function startCodexProxy(routes, options = {}) {
3022
3025
  rawBody = await readBody(req);
3023
3026
  } catch (err) {
3024
3027
  if (debug) {
3025
- log14(`Error: failed to read/decode request body on POST ${url}: ${formatUpstreamError(err)} content-encoding=${req.headers["content-encoding"] ?? "(none)"}`);
3028
+ log15(`Error: failed to read/decode request body on POST ${url}: ${formatUpstreamError(err)} content-encoding=${req.headers["content-encoding"] ?? "(none)"}`);
3026
3029
  }
3027
3030
  sendJson(res, 400, { error: { message: "Invalid request body", type: "invalid_request_error" } });
3028
3031
  return;
@@ -3033,7 +3036,7 @@ async function startCodexProxy(routes, options = {}) {
3033
3036
  } catch (err) {
3034
3037
  if (debug) {
3035
3038
  const headers = JSON.stringify(req.headers);
3036
- log14(`Error: Invalid JSON body on POST ${url}: ${formatUpstreamError(err)} headers=${headers} rawBody=${JSON.stringify(rawBody.slice(0, 2e3))}`);
3039
+ log15(`Error: Invalid JSON body on POST ${url}: ${formatUpstreamError(err)} headers=${headers} rawBody=${JSON.stringify(rawBody.slice(0, 2e3))}`);
3037
3040
  }
3038
3041
  sendJson(res, 400, { error: { message: "Invalid JSON body", type: "invalid_request_error" } });
3039
3042
  return;
@@ -3043,12 +3046,12 @@ async function startCodexProxy(routes, options = {}) {
3043
3046
  const inputItems = Array.isArray(body.input) ? body.input.length : typeof body.input === "string" ? 1 : 0;
3044
3047
  const tools = Array.isArray(body.tools) ? body.tools : [];
3045
3048
  const toolNames = tools.map((t) => t && typeof t === "object" && "name" in t ? t.name : "?").join(",");
3046
- log14(`request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${rawBody.length} tools=[${toolNames || "none"}]`);
3049
+ log15(`request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${rawBody.length} tools=[${toolNames || "none"}]`);
3047
3050
  const mcpTools = tools.filter((t) => t && typeof t === "object" && "name" in t && String(t.name).startsWith("mcp__"));
3048
3051
  for (const t of mcpTools) {
3049
3052
  const mt = t;
3050
3053
  const subTools = mt.type === "namespace" && Array.isArray(mt.tools) ? ` subTools=[${mt.tools.length}]` : "";
3051
- log14(` mcp-tool: name=${mt.name} type=${mt.type} desc=${JSON.stringify(String(mt.description ?? "")).slice(0, 120)}${subTools}`);
3054
+ log15(` mcp-tool: name=${mt.name} type=${mt.type} desc=${JSON.stringify(String(mt.description ?? "")).slice(0, 120)}${subTools}`);
3052
3055
  }
3053
3056
  }
3054
3057
  const modelId = String(body.model ?? "");
@@ -3058,12 +3061,12 @@ async function startCodexProxy(routes, options = {}) {
3058
3061
  const fallbackLm = fallbackRoute ? models.get(fallbackRoute.modelId) : void 0;
3059
3062
  if (fallbackRoute && fallbackLm) {
3060
3063
  if (debug) {
3061
- log14(`resolveModel fallback: requested="${modelId}" \u2192 ${fallbackRoute.modelId}`);
3064
+ log15(`resolveModel fallback: requested="${modelId}" \u2192 ${fallbackRoute.modelId}`);
3062
3065
  }
3063
3066
  resolved = { route: fallbackRoute, languageModel: fallbackLm };
3064
3067
  } else {
3065
3068
  if (debug) {
3066
- log14(`resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
3069
+ log15(`resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
3067
3070
  }
3068
3071
  sendJson(res, 404, { error: { message: `Unknown model: ${modelId}`, type: "invalid_request_error" } });
3069
3072
  return;
@@ -3088,16 +3091,16 @@ async function startCodexProxy(routes, options = {}) {
3088
3091
  const before = params.messages.length;
3089
3092
  const estimatedChars = estimateCodexRequestChars(params);
3090
3093
  const compaction = isLikelyCodexCompactionRequest(body);
3091
- if (debug) log14(`context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before}`);
3094
+ if (debug) log15(`context check: model=${route.modelId} window=${route.contextWindow} chars=${estimatedChars} compaction=${compaction ? "yes" : "no"} messages=${before}`);
3092
3095
  params = protectCodexCompactionParams(body, params, route.contextWindow);
3093
3096
  params.isCompaction = compaction;
3094
3097
  if (debug && params.messages.length < before) {
3095
- log14(`context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages`);
3098
+ log15(`context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages`);
3096
3099
  }
3097
3100
  }
3098
3101
  if (debug) {
3099
3102
  const effort = body.reasoning?.effort;
3100
- log14(`model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
3103
+ log15(`model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
3101
3104
  }
3102
3105
  if (body.stream) {
3103
3106
  res.writeHead(200, {
@@ -3110,17 +3113,17 @@ async function startCodexProxy(routes, options = {}) {
3110
3113
  await streamResponsesResponse(languageModel, params, modelId, write, (summary) => {
3111
3114
  if (debug) {
3112
3115
  const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
3113
- log14(`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)}`);
3116
+ log15(`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)}`);
3114
3117
  }
3115
3118
  }, (progress) => {
3116
3119
  if (debug) {
3117
- log14(`response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
3120
+ log15(`response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
3118
3121
  }
3119
3122
  });
3120
3123
  } catch (err) {
3121
3124
  const msg = formatUpstreamError(err);
3122
3125
  const status = upstreamHttpStatus(err);
3123
- if (debug) log14(`sdk error: ${route.modelId}: ${msg}`);
3126
+ if (debug) log15(`sdk error: ${route.modelId}: ${msg}`);
3124
3127
  if (status === 429) {
3125
3128
  writeResponsesRateLimitStream(modelId, msg, write);
3126
3129
  } else {
@@ -3135,7 +3138,7 @@ async function startCodexProxy(routes, options = {}) {
3135
3138
  } catch (err) {
3136
3139
  const msg = formatUpstreamError(err);
3137
3140
  const status = upstreamHttpStatus(err);
3138
- if (debug) log14(`sdk error: ${route.modelId}: ${msg}`);
3141
+ if (debug) log15(`sdk error: ${route.modelId}: ${msg}`);
3139
3142
  if (status === 429) {
3140
3143
  sendJson(res, 200, responsesRateLimitBody(modelId, msg));
3141
3144
  } else {
@@ -3145,7 +3148,7 @@ async function startCodexProxy(routes, options = {}) {
3145
3148
  }
3146
3149
  } catch (err) {
3147
3150
  const msg = formatUpstreamError(err);
3148
- log14(`handler error: ${msg}`);
3151
+ log15(`handler error: ${msg}`);
3149
3152
  sendJson(res, 500, { error: { message: msg, type: "api_error" } });
3150
3153
  }
3151
3154
  return;
@@ -3245,9 +3248,9 @@ Sec-WebSocket-Accept: ${wsAcceptKey(clientKey)}\r
3245
3248
  };
3246
3249
  const sendWsEvent = (sseChunk2) => {
3247
3250
  if (socket.destroyed) return;
3248
- for (const line of sseChunk2.split("\n")) {
3249
- if (line.startsWith("data: ")) {
3250
- socket.write(wsEncodeTextFrame(line.slice(6)));
3251
+ for (const line2 of sseChunk2.split("\n")) {
3252
+ if (line2.startsWith("data: ")) {
3253
+ socket.write(wsEncodeTextFrame(line2.slice(6)));
3251
3254
  }
3252
3255
  }
3253
3256
  };
@@ -3263,7 +3266,7 @@ Sec-WebSocket-Accept: ${wsAcceptKey(clientKey)}\r
3263
3266
  try {
3264
3267
  body = JSON.parse(frame.text);
3265
3268
  } catch {
3266
- if (debug) log14(`WS Error: Invalid JSON body: rawBody=${JSON.stringify(frame.text.slice(0, 2e3))}`);
3269
+ if (debug) log15(`WS Error: Invalid JSON body: rawBody=${JSON.stringify(frame.text.slice(0, 2e3))}`);
3267
3270
  sendWsEvent(`event: error
3268
3271
  data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_request_error" } })}
3269
3272
 
@@ -3276,7 +3279,7 @@ data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_reques
3276
3279
  const inputItems = Array.isArray(body.input) ? body.input.length : typeof body.input === "string" ? 1 : 0;
3277
3280
  const tools = Array.isArray(body.tools) ? body.tools : [];
3278
3281
  const toolNames = tools.map((t) => t && typeof t === "object" && "name" in t ? t.name : "?").join(",");
3279
- log14(`WS request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${frame.text.length} tools=[${toolNames || "none"}]`);
3282
+ log15(`WS request: model=${String(body.model ?? "")} previous_response_id=${prevId ?? "(none)"} input_items=${inputItems} body_bytes=${frame.text.length} tools=[${toolNames || "none"}]`);
3280
3283
  }
3281
3284
  const modelId = String(body.model ?? "");
3282
3285
  let resolved = resolveModel(routes, models, modelId);
@@ -3284,10 +3287,10 @@ data: ${JSON.stringify({ error: { message: "Invalid JSON", type: "invalid_reques
3284
3287
  const fb = routes[0];
3285
3288
  const fbLm = fb ? models.get(fb.modelId) : void 0;
3286
3289
  if (fb && fbLm) {
3287
- if (debug) log14(`WS resolveModel fallback: requested="${modelId}" \u2192 ${fb.modelId}`);
3290
+ if (debug) log15(`WS resolveModel fallback: requested="${modelId}" \u2192 ${fb.modelId}`);
3288
3291
  resolved = { route: fb, languageModel: fbLm };
3289
3292
  } else {
3290
- if (debug) log14(`WS resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
3293
+ if (debug) log15(`WS resolveModel failed: requested="${modelId}" known=[${routes.map((r) => r.modelId).join(", ")}]`);
3291
3294
  sendWsEvent(`event: error
3292
3295
  data: ${JSON.stringify({ error: { message: `Unknown model: ${modelId}` } })}
3293
3296
 
@@ -3315,31 +3318,31 @@ data: ${JSON.stringify({ error: { message: `Unknown model: ${modelId}` } })}
3315
3318
  const before = params.messages.length;
3316
3319
  const estimatedChars = estimateCodexRequestChars(params);
3317
3320
  const compaction = isLikelyCodexCompactionRequest(body);
3318
- if (debug) log14(`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}`);
3321
+ if (debug) log15(`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}`);
3319
3322
  params = protectCodexCompactionParams(body, params, route.contextWindow);
3320
3323
  params.isCompaction = compaction;
3321
3324
  if (debug && params.messages.length < before) {
3322
- log14(`WS context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages tools=${params.tools ? Object.keys(params.tools).length : 0}`);
3325
+ log15(`WS context trim: model=${route.modelId} window=${route.contextWindow} kept=${params.messages.length}/${before} messages tools=${params.tools ? Object.keys(params.tools).length : 0}`);
3323
3326
  }
3324
3327
  }
3325
3328
  if (debug) {
3326
3329
  const effort = body.reasoning?.effort;
3327
- log14(`WS model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
3330
+ log15(`WS model=${route.modelId} effort=${effort ?? "(none)"} providerOptions=${JSON.stringify(params.providerOptions)}`);
3328
3331
  }
3329
3332
  await streamResponsesResponse(languageModel, params, modelId, sendWsEvent, (summary) => {
3330
3333
  if (debug) {
3331
3334
  const failure = `${summary.aborted ? " aborted=yes" : ""}${summary.errorMessage ? ` error=${JSON.stringify(summary.errorMessage)}` : ""}`;
3332
- log14(`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)}`);
3335
+ log15(`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)}`);
3333
3336
  }
3334
3337
  }, (progress) => {
3335
3338
  if (debug) {
3336
- log14(`WS response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
3339
+ log15(`WS response progress: model=${route.modelId} elapsedMs=${progress.elapsedMs} reasoningChars=${progress.reasoningChars} textChars=${progress.textChars} toolCalls=${progress.toolCallCount} reasoningTail=${JSON.stringify(progress.reasoningTail)}`);
3337
3340
  }
3338
3341
  });
3339
3342
  } catch (err) {
3340
3343
  const msg = formatUpstreamError(err);
3341
3344
  const status = upstreamHttpStatus(err);
3342
- if (debug) log14(`WS sdk error: ${route.modelId}: ${msg}`);
3345
+ if (debug) log15(`WS sdk error: ${route.modelId}: ${msg}`);
3343
3346
  if (status === 429) {
3344
3347
  writeResponsesRateLimitStream(modelId, msg, sendWsEvent);
3345
3348
  } else {
@@ -3561,7 +3564,7 @@ function restoreCodexOverlay(env = process.env) {
3561
3564
  return removed;
3562
3565
  }
3563
3566
  function remainingOverlayPaths(env = process.env) {
3564
- return ownedOverlayPaths(env).filter((p15) => existsSync2(p15));
3567
+ return ownedOverlayPaths(env).filter((p16) => existsSync2(p16));
3565
3568
  }
3566
3569
  function recoverInterruptedCodexSession(env = process.env) {
3567
3570
  const before = remainingOverlayPaths(env);
@@ -4128,6 +4131,7 @@ function buildCloudCodeProxyRoute(model, apiKey, providerData) {
4128
4131
  contextWindow: model.contextWindow,
4129
4132
  providerId: "antigravity",
4130
4133
  authType: "oauth",
4134
+ app: "Antigravity",
4131
4135
  providerData,
4132
4136
  refreshToken: () => resolveProviderCredential("antigravity", oauthAuthRef("antigravity"))
4133
4137
  };
@@ -4147,6 +4151,7 @@ function buildOAuthAnthropicProxyRoute(model, apiKey, providerId, providerData)
4147
4151
  contextWindow: model.contextWindow,
4148
4152
  providerId,
4149
4153
  authType: "oauth",
4154
+ app: "Claude",
4150
4155
  providerData,
4151
4156
  refreshToken: () => resolveProviderCredential(providerId, oauthAuthRef(providerId))
4152
4157
  };
@@ -4274,7 +4279,7 @@ function resolveLaunchTarget(explicit, prefs, agent) {
4274
4279
  }
4275
4280
  function findProviderAndModel(providers, target) {
4276
4281
  if (!target.providerId || !target.modelId) return null;
4277
- const provider = providers.find((p15) => p15.id === target.providerId);
4282
+ const provider = providers.find((p16) => p16.id === target.providerId);
4278
4283
  if (!provider) return null;
4279
4284
  const model = provider.models.find((m) => m.id === target.modelId);
4280
4285
  if (!model) return null;
@@ -4874,7 +4879,7 @@ Error: ${launchPlan.error}
4874
4879
  });
4875
4880
  if (configOnly) {
4876
4881
  const home = process.env["HOME"] ?? "";
4877
- const shortenPath = (p15) => home ? p15.replace(home, "~") : p15;
4882
+ const shortenPath = (p16) => home ? p16.replace(home, "~") : p16;
4878
4883
  console.log("");
4879
4884
  console.log(pc7.bold(pc7.cyan(" CONFIG PREVIEW \u2014 anygate codex")));
4880
4885
  console.log("");
@@ -5214,7 +5219,7 @@ function stripGeminiIdentity(text4) {
5214
5219
  function translateGeminiRequest(body, options = {}) {
5215
5220
  let system;
5216
5221
  if (body.systemInstruction?.parts) {
5217
- const rawSystem = body.systemInstruction.parts.map((p15) => p15.text || "").join("\n");
5222
+ const rawSystem = body.systemInstruction.parts.map((p16) => p16.text || "").join("\n");
5218
5223
  system = stripGeminiIdentity(rawSystem).trim();
5219
5224
  }
5220
5225
  const messages = [];
@@ -5225,9 +5230,9 @@ function translateGeminiRequest(body, options = {}) {
5225
5230
  const parts = [];
5226
5231
  const toolResults = [];
5227
5232
  const turnParts = turn.parts || [];
5228
- for (const p15 of turnParts) {
5229
- if (p15.text !== void 0) {
5230
- const text4 = stripGeminiIdentity(p15.text);
5233
+ for (const p16 of turnParts) {
5234
+ if (p16.text !== void 0) {
5235
+ const text4 = stripGeminiIdentity(p16.text);
5231
5236
  if (text4.includes("<thinking>")) {
5232
5237
  const tokens = text4.split(/<thinking>([\s\S]*?)<\/thinking>/);
5233
5238
  for (let i = 0; i < tokens.length; i++) {
@@ -5238,25 +5243,25 @@ function translateGeminiRequest(body, options = {}) {
5238
5243
  } else {
5239
5244
  parts.push({ type: "text", text: text4 });
5240
5245
  }
5241
- } else if (p15.inlineData) {
5246
+ } else if (p16.inlineData) {
5242
5247
  parts.push({
5243
5248
  type: "image",
5244
- image: Buffer.from(p15.inlineData.data, "base64"),
5245
- mediaType: p15.inlineData.mimeType
5249
+ image: Buffer.from(p16.inlineData.data, "base64"),
5250
+ mediaType: p16.inlineData.mimeType
5246
5251
  });
5247
- } else if (p15.functionCall) {
5252
+ } else if (p16.functionCall) {
5248
5253
  const id = "call_" + randomUUID().replace(/-/g, "");
5249
- const name = p15.functionCall.name;
5254
+ const name = p16.functionCall.name;
5250
5255
  if (!nameToIdList.has(name)) nameToIdList.set(name, []);
5251
5256
  nameToIdList.get(name).push(id);
5252
5257
  parts.push({
5253
5258
  type: "tool-call",
5254
5259
  toolCallId: id,
5255
5260
  toolName: name,
5256
- input: p15.functionCall.args || {}
5261
+ input: p16.functionCall.args || {}
5257
5262
  });
5258
- } else if (p15.functionResponse) {
5259
- const name = p15.functionResponse.name;
5263
+ } else if (p16.functionResponse) {
5264
+ const name = p16.functionResponse.name;
5260
5265
  const idList = nameToIdList.get(name) || [];
5261
5266
  const id = idList.shift() || "call_" + randomUUID().replace(/-/g, "");
5262
5267
  toolResults.push({
@@ -5265,7 +5270,7 @@ function translateGeminiRequest(body, options = {}) {
5265
5270
  toolName: name,
5266
5271
  output: {
5267
5272
  type: "text",
5268
- value: typeof p15.functionResponse.response === "string" ? p15.functionResponse.response : JSON.stringify(p15.functionResponse.response || {})
5273
+ value: typeof p16.functionResponse.response === "string" ? p16.functionResponse.response : JSON.stringify(p16.functionResponse.response || {})
5269
5274
  }
5270
5275
  });
5271
5276
  }
@@ -5471,9 +5476,9 @@ ${JSON.stringify(params, null, 2)}`);
5471
5476
  const toolCallBuffers = /* @__PURE__ */ new Map();
5472
5477
  let isThinking = false;
5473
5478
  for await (const part of fullStream) {
5474
- const p15 = part;
5475
- plog(`Stream chunk type: ${p15.type}`);
5476
- if (isThinking && (p15.type === "tool-input-start" || p15.type === "tool-call" || p15.type === "finish")) {
5479
+ const p16 = part;
5480
+ plog(`Stream chunk type: ${p16.type}`);
5481
+ if (isThinking && (p16.type === "tool-input-start" || p16.type === "tool-call" || p16.type === "finish")) {
5477
5482
  isThinking = false;
5478
5483
  const chunk = {
5479
5484
  candidates: [{ content: { role: "model", parts: [{ text: `
@@ -5486,8 +5491,8 @@ ${JSON.stringify(params, null, 2)}`);
5486
5491
 
5487
5492
  `);
5488
5493
  }
5489
- if (p15.type === "reasoning") {
5490
- let text4 = p15.textDelta ?? p15.text ?? "";
5494
+ if (p16.type === "reasoning") {
5495
+ let text4 = p16.textDelta ?? p16.text ?? "";
5491
5496
  if (!isThinking) {
5492
5497
  isThinking = true;
5493
5498
  text4 = `<thinking>
@@ -5500,8 +5505,8 @@ ${JSON.stringify(params, null, 2)}`);
5500
5505
  res.write(`data: ${JSON.stringify(chunk)}
5501
5506
 
5502
5507
  `);
5503
- } else if (p15.type === "text-delta") {
5504
- let text4 = p15.textDelta ?? p15.text ?? "";
5508
+ } else if (p16.type === "text-delta") {
5509
+ let text4 = p16.textDelta ?? p16.text ?? "";
5505
5510
  if (isThinking) {
5506
5511
  isThinking = false;
5507
5512
  text4 = `
@@ -5521,17 +5526,17 @@ ${JSON.stringify(params, null, 2)}`);
5521
5526
  const data = `data: ${JSON.stringify(chunk)}
5522
5527
 
5523
5528
  `;
5524
- plog(`Streaming text delta: ${p15.textDelta}`);
5529
+ plog(`Streaming text delta: ${p16.textDelta}`);
5525
5530
  res.write(data);
5526
- } else if (p15.type === "tool-input-start") {
5527
- toolCallBuffers.set(p15.toolCallId, { name: p15.toolName, json: "" });
5528
- } else if (p15.type === "tool-input-delta") {
5529
- const buf = toolCallBuffers.get(p15.toolCallId);
5530
- if (buf) buf.json += p15.delta;
5531
- } else if (p15.type === "tool-call") {
5532
- const buf = toolCallBuffers.get(p15.toolCallId);
5533
- const args = buf ? JSON.parse(buf.json || "{}") : p15.input || {};
5534
- const name = buf ? buf.name : p15.toolName;
5531
+ } else if (p16.type === "tool-input-start") {
5532
+ toolCallBuffers.set(p16.toolCallId, { name: p16.toolName, json: "" });
5533
+ } else if (p16.type === "tool-input-delta") {
5534
+ const buf = toolCallBuffers.get(p16.toolCallId);
5535
+ if (buf) buf.json += p16.delta;
5536
+ } else if (p16.type === "tool-call") {
5537
+ const buf = toolCallBuffers.get(p16.toolCallId);
5538
+ const args = buf ? JSON.parse(buf.json || "{}") : p16.input || {};
5539
+ const name = buf ? buf.name : p16.toolName;
5535
5540
  plog(`Streaming tool call: ${name} with args: ${JSON.stringify(args)}`);
5536
5541
  const chunk = {
5537
5542
  candidates: [{
@@ -5547,18 +5552,18 @@ ${JSON.stringify(params, null, 2)}`);
5547
5552
  res.write(`data: ${JSON.stringify(chunk)}
5548
5553
 
5549
5554
  `);
5550
- } else if (p15.type === "finish") {
5555
+ } else if (p16.type === "finish") {
5551
5556
  const chunk = {
5552
5557
  candidates: [{
5553
- finishReason: mapFinishReason(p15.finishReason ?? "")
5558
+ finishReason: mapFinishReason(p16.finishReason ?? "")
5554
5559
  }],
5555
5560
  usageMetadata: {
5556
- promptTokenCount: p15.totalUsage?.inputTokens || 0,
5557
- candidatesTokenCount: p15.totalUsage?.outputTokens || 0
5561
+ promptTokenCount: p16.totalUsage?.inputTokens || 0,
5562
+ candidatesTokenCount: p16.totalUsage?.outputTokens || 0
5558
5563
  },
5559
5564
  modelVersion: route.aliasId
5560
5565
  };
5561
- plog(`Stream finish. Reason: ${p15.finishReason}`);
5566
+ plog(`Stream finish. Reason: ${p16.finishReason}`);
5562
5567
  res.write(`data: ${JSON.stringify(chunk)}
5563
5568
 
5564
5569
  `);
@@ -7780,7 +7785,7 @@ async function startCloudCodeGateway(routes, opts = {}) {
7780
7785
  const templateKey = opts.templateKey ?? "gemini-3.5-flash-low";
7781
7786
  const trace = opts.trace ?? false;
7782
7787
  const trackActiveRoute = opts.trackActiveRoute ?? false;
7783
- const log14 = opts.logFn ?? (() => {
7788
+ const log15 = opts.logFn ?? (() => {
7784
7789
  });
7785
7790
  const catalogFixture = fetchAvailableModels_default;
7786
7791
  const injectedCatalog = injectGatewayModels(catalogFixture, routes, templateKey);
@@ -7830,12 +7835,12 @@ async function startCloudCodeGateway(routes, opts = {}) {
7830
7835
  const contentType = (req.headers["content-type"] ?? "").toLowerCase();
7831
7836
  const lowerUrl = url.toLowerCase();
7832
7837
  if (trace) {
7833
- log14(`[gateway] ${method} ${url}`);
7834
- log14(`[gateway] content-type: ${contentType}`);
7835
- log14(`[gateway] body-size: ${bodyStr.length}`);
7838
+ log15(`[gateway] ${method} ${url}`);
7839
+ log15(`[gateway] content-type: ${contentType}`);
7840
+ log15(`[gateway] body-size: ${bodyStr.length}`);
7836
7841
  }
7837
7842
  if (contentType.includes("proto") || contentType.includes("grpc") && !contentType.includes("json")) {
7838
- log14(`[gateway] UNSUPPORTED content-type: ${contentType}`);
7843
+ log15(`[gateway] UNSUPPORTED content-type: ${contentType}`);
7839
7844
  respondJson(res, 415, {
7840
7845
  error: {
7841
7846
  code: 415,
@@ -7851,35 +7856,35 @@ async function startCloudCodeGateway(routes, opts = {}) {
7851
7856
  }
7852
7857
  if (trace && parsed) {
7853
7858
  const preview = JSON.stringify(parsed).slice(0, 500);
7854
- log14(`[gateway] body-preview: ${preview}`);
7859
+ log15(`[gateway] body-preview: ${preview}`);
7855
7860
  }
7856
7861
  if (lowerUrl.includes("loadcodeassist")) {
7857
- if (trace) log14("[gateway] \u2192 loadCodeAssist");
7862
+ if (trace) log15("[gateway] \u2192 loadCodeAssist");
7858
7863
  respondJson(res, 200, loadCodeAssist_default);
7859
7864
  return;
7860
7865
  }
7861
7866
  if (lowerUrl.includes("fetchavailablemodels") || lowerUrl.includes("getavailablemodels")) {
7862
- if (trace) log14("[gateway] \u2192 fetchAvailableModels");
7867
+ if (trace) log15("[gateway] \u2192 fetchAvailableModels");
7863
7868
  respondJson(res, 200, injectedCatalog);
7864
7869
  return;
7865
7870
  }
7866
7871
  if (lowerUrl.includes("modelconfigs")) {
7867
- if (trace) log14("[gateway] \u2192 listModelConfigs");
7872
+ if (trace) log15("[gateway] \u2192 listModelConfigs");
7868
7873
  respondJson(res, 200, modelConfigsResponse);
7869
7874
  return;
7870
7875
  }
7871
7876
  if (lowerUrl.includes("generatecontent") || lowerUrl.includes("generatechat")) {
7872
7877
  const model = parsed?.model;
7873
- if (trace) log14(`[gateway] extracted model: ${model ?? "N/A"}`);
7878
+ if (trace) log15(`[gateway] extracted model: ${model ?? "N/A"}`);
7874
7879
  const route = resolveRouteForModel(model);
7875
7880
  if (route) {
7876
7881
  if (trackActiveRoute && selectedSlotIds.has(model ?? "") && isUserTurnRequest(parsed)) {
7877
7882
  activeRoute = route;
7878
- if (trace) log14(`[gateway] active route: ${route.catalogId} via ${model}`);
7883
+ if (trace) log15(`[gateway] active route: ${route.catalogId} via ${model}`);
7879
7884
  }
7880
7885
  if (isCloudCodeOAuthRoute(route)) {
7881
- handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log14).catch((err) => {
7882
- log14(`[gateway] cloud-code forward error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7886
+ handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log15).catch((err) => {
7887
+ log15(`[gateway] cloud-code forward error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7883
7888
  if (!res.headersSent) {
7884
7889
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
7885
7890
  } else if (!res.writableEnded) {
@@ -7897,11 +7902,11 @@ async function startCloudCodeGateway(routes, opts = {}) {
7897
7902
  rememberReasoningEcho(reasoningEchoesByConversation, conversationKey, reasoning);
7898
7903
  };
7899
7904
  if (isStream) {
7900
- handleStreamingRequest(res, route, baseProviderOptions, parsed, log14, {
7905
+ handleStreamingRequest(res, route, baseProviderOptions, parsed, log15, {
7901
7906
  requestOptions,
7902
7907
  onReasoningWithToolCall: rememberReasoning
7903
7908
  }).catch((err) => {
7904
- log14(`[gateway] stream error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7909
+ log15(`[gateway] stream error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7905
7910
  if (!res.headersSent) {
7906
7911
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
7907
7912
  } else if (!res.writableEnded) {
@@ -7909,11 +7914,11 @@ async function startCloudCodeGateway(routes, opts = {}) {
7909
7914
  }
7910
7915
  });
7911
7916
  } else {
7912
- handleUnaryRequest(res, route, baseProviderOptions, parsed, log14, {
7917
+ handleUnaryRequest(res, route, baseProviderOptions, parsed, log15, {
7913
7918
  requestOptions,
7914
7919
  onReasoningWithToolCall: rememberReasoning
7915
7920
  }).catch((err) => {
7916
- log14(`[gateway] unary error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7921
+ log15(`[gateway] unary error: ${err instanceof Error ? err.stack || err.message : String(err)}`);
7917
7922
  if (!res.headersSent) {
7918
7923
  respondJson(res, 500, { error: { code: 500, message: formatUpstreamError(err) } });
7919
7924
  }
@@ -8009,7 +8014,7 @@ async function startCloudCodeGateway(routes, opts = {}) {
8009
8014
  return;
8010
8015
  }
8011
8016
  if (trace) {
8012
- log14(`[gateway] unknown endpoint: ${url}`);
8017
+ log15(`[gateway] unknown endpoint: ${url}`);
8013
8018
  }
8014
8019
  respondJson(res, 200, {});
8015
8020
  }).catch((err) => {
@@ -8095,7 +8100,7 @@ function rememberReasoningEcho(cache, key, reasoning) {
8095
8100
  existing.push(normalized);
8096
8101
  cache.set(key, existing.slice(-MAX_REASONING_ECHOES_PER_CONVERSATION));
8097
8102
  }
8098
- async function handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log14) {
8103
+ async function handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log15) {
8099
8104
  const projectId = typeof route.providerData?.projectId === "string" ? route.providerData.projectId : "";
8100
8105
  if (!projectId) {
8101
8106
  respondJson(res, 500, {
@@ -8124,7 +8129,7 @@ async function handleCloudCodeForwardRequest(res, route, parsed, lowerUrl, log14
8124
8129
  });
8125
8130
  if (!upstream.ok) {
8126
8131
  const errBody = await upstream.text();
8127
- log14(`[gateway] cloud-code upstream error ${upstream.status}: ${errBody}`);
8132
+ log15(`[gateway] cloud-code upstream error ${upstream.status}: ${errBody}`);
8128
8133
  respondJson(res, upstream.status >= 500 ? 502 : upstream.status, {
8129
8134
  error: { code: upstream.status, message: errBody || upstream.statusText }
8130
8135
  });
@@ -8238,7 +8243,7 @@ function respondJson(res, status, data) {
8238
8243
  });
8239
8244
  res.end(body);
8240
8245
  }
8241
- async function handleStreamingRequest(res, route, providerOptions, parsed, log14, options = {}) {
8246
+ async function handleStreamingRequest(res, route, providerOptions, parsed, log15, options = {}) {
8242
8247
  const sdkParams = applyClaudeCodeOAuthIdentity(route, translateRequest(parsed, {
8243
8248
  ...options.requestOptions,
8244
8249
  maxTools: maxToolsForNpm(route.npm)
@@ -8279,21 +8284,21 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
8279
8284
  let responseReasoning = "";
8280
8285
  let sawToolCall = false;
8281
8286
  for await (const part of fullStream) {
8282
- const p15 = part;
8283
- if (p15.type === "reasoning-delta" || p15.type === "reasoning") {
8284
- const reasoning = reasoningDeltaText(p15);
8287
+ const p16 = part;
8288
+ if (p16.type === "reasoning-delta" || p16.type === "reasoning") {
8289
+ const reasoning = reasoningDeltaText(p16);
8285
8290
  responseReasoning += reasoning;
8286
8291
  emitThinkingDelta(res, route, responseId, reasoning, startSse);
8287
8292
  continue;
8288
8293
  }
8289
- if (p15.type === "text-delta") {
8290
- const { thought, text: text4 } = thinkFilter(reasoningDeltaText(p15));
8294
+ if (p16.type === "text-delta") {
8295
+ const { thought, text: text4 } = thinkFilter(reasoningDeltaText(p16));
8291
8296
  if (thought) {
8292
8297
  responseReasoning += thought;
8293
8298
  emitThinkingDelta(res, route, responseId, thought, startSse);
8294
8299
  }
8295
8300
  if (text4) {
8296
- log14(`[gateway] text-delta: ${JSON.stringify(text4.slice(0, 500))}`);
8301
+ log15(`[gateway] text-delta: ${JSON.stringify(text4.slice(0, 500))}`);
8297
8302
  startSse();
8298
8303
  const chunk = formatCloudCodeChunk({
8299
8304
  text: text4,
@@ -8304,25 +8309,25 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
8304
8309
 
8305
8310
  `);
8306
8311
  }
8307
- } else if (p15.type === "tool-input-start") {
8308
- const id = p15.id ?? p15.toolCallId;
8309
- toolCallBuffers.set(id, { name: p15.toolName, json: "" });
8310
- } else if (p15.type === "tool-input-delta") {
8311
- const id = p15.id ?? p15.toolCallId;
8312
+ } else if (p16.type === "tool-input-start") {
8313
+ const id = p16.id ?? p16.toolCallId;
8314
+ toolCallBuffers.set(id, { name: p16.toolName, json: "" });
8315
+ } else if (p16.type === "tool-input-delta") {
8316
+ const id = p16.id ?? p16.toolCallId;
8312
8317
  const buf = toolCallBuffers.get(id);
8313
- if (buf) buf.json += p15.delta;
8314
- } else if (p15.type === "tool-call") {
8318
+ if (buf) buf.json += p16.delta;
8319
+ } else if (p16.type === "tool-call") {
8315
8320
  sawToolCall = true;
8316
- const id = p15.toolCallId ?? p15.id;
8321
+ const id = p16.toolCallId ?? p16.id;
8317
8322
  const buf = toolCallBuffers.get(id);
8318
8323
  let args = {};
8319
8324
  try {
8320
- args = buf ? JSON.parse(buf.json || "{}") : p15.input || {};
8325
+ args = buf ? JSON.parse(buf.json || "{}") : p16.input || {};
8321
8326
  } catch {
8322
- args = p15.input || {};
8327
+ args = p16.input || {};
8323
8328
  }
8324
- const name = buf ? buf.name : p15.toolName;
8325
- log14(`[gateway] tool-call: ${name}`);
8329
+ const name = buf ? buf.name : p16.toolName;
8330
+ log15(`[gateway] tool-call: ${name}`);
8326
8331
  startSse();
8327
8332
  const chunk = formatCloudCodeChunk({
8328
8333
  functionCall: { name, args: normalizeFunctionCallArgs(args) },
@@ -8332,29 +8337,29 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
8332
8337
  res.write(`data: ${JSON.stringify(chunk)}
8333
8338
 
8334
8339
  `);
8335
- } else if (p15.type === "finish") {
8336
- log14(`[gateway] finish: ${p15.finishReason ?? "unknown"}`);
8340
+ } else if (p16.type === "finish") {
8341
+ log15(`[gateway] finish: ${p16.finishReason ?? "unknown"}`);
8337
8342
  startSse();
8338
- const reason = mapFinishReason2(p15.finishReason ?? "");
8343
+ const reason = mapFinishReason2(p16.finishReason ?? "");
8339
8344
  const chunk = formatCloudCodeChunk({
8340
8345
  modelVersion: route.catalogId,
8341
8346
  responseId,
8342
8347
  finishReason: reason,
8343
8348
  usage: {
8344
- promptTokens: p15.totalUsage?.inputTokens || 0,
8345
- completionTokens: p15.totalUsage?.outputTokens || 0
8349
+ promptTokens: p16.totalUsage?.inputTokens || 0,
8350
+ completionTokens: p16.totalUsage?.outputTokens || 0
8346
8351
  }
8347
8352
  });
8348
8353
  res.write(`data: ${JSON.stringify(chunk)}
8349
8354
 
8350
8355
  `);
8351
- } else if (p15.type === "error") {
8352
- const message = formatUpstreamError(p15.error);
8353
- log14(`[gateway] stream provider error: ${message}`);
8356
+ } else if (p16.type === "error") {
8357
+ const message = formatUpstreamError(p16.error);
8358
+ log15(`[gateway] stream provider error: ${message}`);
8354
8359
  emitStreamError(res, route, responseId, message, startSse);
8355
8360
  break;
8356
- } else if (p15.type === "reasoning-start" || p15.type === "reasoning-end") {
8357
- log14(`[gateway] ${p15.type}`);
8361
+ } else if (p16.type === "reasoning-start" || p16.type === "reasoning-end") {
8362
+ log15(`[gateway] ${p16.type}`);
8358
8363
  }
8359
8364
  }
8360
8365
  if (!res.headersSent) {
@@ -8645,12 +8650,12 @@ function defaultProcessList() {
8645
8650
  function isAntigravityIdeRunning(profileDir, processList = defaultProcessList) {
8646
8651
  if (process.platform === "win32") return winIsProcessRunningForProfile("Antigravity IDE.exe", profileDir);
8647
8652
  const output = processList();
8648
- return output.split("\n").some((line) => line.includes("Antigravity IDE.app") && line.includes(`--user-data-dir=${profileDir}`));
8653
+ return output.split("\n").some((line2) => line2.includes("Antigravity IDE.app") && line2.includes(`--user-data-dir=${profileDir}`));
8649
8654
  }
8650
8655
  function isAntigravityAppRunning(profileDir, processList = defaultProcessList) {
8651
8656
  if (process.platform === "win32") return winIsProcessRunningForProfile("Antigravity.exe", profileDir);
8652
8657
  const output = processList();
8653
- return output.split("\n").some((line) => line.includes("Antigravity.app") && line.includes(`--user-data-dir=${profileDir}`));
8658
+ return output.split("\n").some((line2) => line2.includes("Antigravity.app") && line2.includes(`--user-data-dir=${profileDir}`));
8654
8659
  }
8655
8660
  async function waitForAntigravityIdeQuit(profileDir, options = {}) {
8656
8661
  const processList = options.processList ?? defaultProcessList;
@@ -8898,7 +8903,7 @@ async function resolveAntigravityLaunch(prefs, boot) {
8898
8903
  return null;
8899
8904
  }
8900
8905
  if (boot?.launchProvider && boot?.launchModel) {
8901
- const provider = allProviders.find((p15) => p15.id === boot.launchProvider);
8906
+ const provider = allProviders.find((p16) => p16.id === boot.launchProvider);
8902
8907
  if (!provider) {
8903
8908
  p11.log.error(`Provider not found: ${boot.launchProvider}`);
8904
8909
  return null;
@@ -10079,8 +10084,8 @@ async function runCodexAppCommand(args, opts = {}) {
10079
10084
  ...specBase,
10080
10085
  proxyPort: PREVIEW_PROXY_PORT
10081
10086
  });
10082
- for (const line of tomlPreview.split("\n")) {
10083
- console.log(` ${pc10.dim(line)}`);
10087
+ for (const line2 of tomlPreview.split("\n")) {
10088
+ console.log(` ${pc10.dim(line2)}`);
10084
10089
  }
10085
10090
  console.log("");
10086
10091
  console.log(` ${pc10.bold("Catalog file:")}`);
@@ -10675,8 +10680,8 @@ var SKILL_INSTALL_DIRS = [
10675
10680
  function parseSkillVersion(content) {
10676
10681
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
10677
10682
  if (!match) return null;
10678
- for (const line of match[1].split("\n")) {
10679
- const trimmed = line.trim();
10683
+ for (const line2 of match[1].split("\n")) {
10684
+ const trimmed = line2.trim();
10680
10685
  if (!trimmed.startsWith("version:")) continue;
10681
10686
  const raw = trimmed.slice("version:".length).trim();
10682
10687
  return raw.replace(/^["']|["']$/g, "");
@@ -10711,7 +10716,7 @@ function formatProviderModels(provider) {
10711
10716
  function buildLiveStateSection() {
10712
10717
  const prefs = loadPreferences();
10713
10718
  const registry = loadRegistry();
10714
- const enabled = registry.providers.filter((p15) => p15.enabled);
10719
+ const enabled = registry.providers.filter((p16) => p16.enabled);
10715
10720
  const prefLines = [];
10716
10721
  if (prefs.lastProvider || prefs.lastModel) {
10717
10722
  prefLines.push(` Claude last launch: provider=${prefs.lastProvider ?? "(none)"} model=${prefs.lastModel ?? "(none)"}`);
@@ -10728,9 +10733,9 @@ function buildLiveStateSection() {
10728
10733
  prefLines.push(` ${f.providerId} / ${f.modelId}`);
10729
10734
  }
10730
10735
  }
10731
- const providerBlocks = enabled.length === 0 ? [" No registry providers configured. Built-in cloud: zen, go (OpenCode Zen/Go)."] : enabled.map((p15) => [
10732
- ` ${p15.name} (${p15.id}) \u2014 ${p15.modelsCache?.models.length ?? 0} cached model(s)`,
10733
- formatProviderModels(p15)
10736
+ const providerBlocks = enabled.length === 0 ? [" No registry providers configured. Built-in cloud: zen, go (OpenCode Zen/Go)."] : enabled.map((p16) => [
10737
+ ` ${p16.name} (${p16.id}) \u2014 ${p16.modelsCache?.models.length ?? 0} cached model(s)`,
10738
+ formatProviderModels(p16)
10734
10739
  ].join("\n"));
10735
10740
  return `
10736
10741
  ================================================================================
@@ -11225,6 +11230,267 @@ function printAiInstallResult(result) {
11225
11230
  return result.failed.length > 0 ? 1 : 0;
11226
11231
  }
11227
11232
 
11233
+ // src/agents/shared/doctor.ts
11234
+ import pc12 from "picocolors";
11235
+ import { createServer as createServer3 } from "net";
11236
+ function nodeMajor() {
11237
+ const raw = process.versions.node.split(".")[0] ?? "0";
11238
+ return Number.parseInt(raw, 10) || 0;
11239
+ }
11240
+ function checkPortFree(port) {
11241
+ return new Promise((resolve) => {
11242
+ const server = createServer3();
11243
+ server.once("error", () => resolve(false));
11244
+ server.listen(port, () => {
11245
+ server.close(() => resolve(true));
11246
+ });
11247
+ const timer = setTimeout(() => resolve(true), 1500);
11248
+ if (typeof timer.unref === "function") timer.unref();
11249
+ });
11250
+ }
11251
+ function line(ok, label, detail = "") {
11252
+ const mark = ok ? pc12.green("\u2713") : pc12.red("\u2717");
11253
+ const text4 = detail ? `${label} ${pc12.dim(`\u2014 ${detail}`)}` : label;
11254
+ return ` ${mark} ${text4}`;
11255
+ }
11256
+ async function runDoctorCommand(_dryRun) {
11257
+ gateIntro("Doctor");
11258
+ const checks = [];
11259
+ const major = nodeMajor();
11260
+ checks.push({
11261
+ label: "Node.js version",
11262
+ ok: major >= 18,
11263
+ detail: `v${process.versions.node} (requires \u2265 18)`,
11264
+ critical: true
11265
+ });
11266
+ let keyringOk = false;
11267
+ let keyringDetail = "";
11268
+ try {
11269
+ keyringOk = await isSecretServiceAvailable();
11270
+ keyringDetail = keyringOk ? "credential store reachable" : "not available on this system";
11271
+ } catch (err) {
11272
+ keyringDetail = err instanceof Error ? err.message : String(err);
11273
+ }
11274
+ checks.push({
11275
+ label: "Secure credential store",
11276
+ ok: keyringOk,
11277
+ detail: keyringDetail,
11278
+ critical: false
11279
+ });
11280
+ let keyPresent = false;
11281
+ let keyDetail = "";
11282
+ try {
11283
+ const key = await readFromCredentialStore();
11284
+ keyPresent = Boolean(key?.trim());
11285
+ keyDetail = keyPresent ? "OPENCODE_API_KEY found" : "not set (get one at https://opencode.ai/auth)";
11286
+ } catch (err) {
11287
+ keyDetail = err instanceof Error ? err.message : String(err);
11288
+ }
11289
+ checks.push({
11290
+ label: "OpenCode API key",
11291
+ ok: keyPresent,
11292
+ detail: keyDetail,
11293
+ critical: false
11294
+ });
11295
+ const portFree = await checkPortFree(GATEWAY_PORT);
11296
+ checks.push({
11297
+ label: `Gateway port ${GATEWAY_PORT}`,
11298
+ ok: portFree,
11299
+ detail: portFree ? "available" : "in use \u2014 `anygate server` will fail to bind",
11300
+ critical: false
11301
+ });
11302
+ const conflicts = detectConflicts();
11303
+ checks.push({
11304
+ label: "Conflicting env vars",
11305
+ ok: conflicts.length === 0,
11306
+ detail: conflicts.length === 0 ? `none of the ${CONFLICTING_ENV_VARS.length} known conflicts set` : `${conflicts.length} set: ${conflicts.map((c) => c.name).join(", ")}`,
11307
+ critical: false
11308
+ });
11309
+ const failedCritical = checks.filter((c) => !c.ok && c.critical);
11310
+ const failedNonCritical = checks.filter((c) => !c.ok && !c.critical);
11311
+ const reportLines = checks.map((c) => line(c.ok, c.label, c.detail));
11312
+ reportLines.push("");
11313
+ reportLines.push(
11314
+ pc12.dim("Antigravity note: macOS-only today. Windows/Linux app launches are") + pc12.dim(" best-effort \u2014 see help for each agy/antigravity command.")
11315
+ );
11316
+ printPanel("Environment check", reportLines);
11317
+ if (failedCritical.length > 0) {
11318
+ gateOutro("Problems found", pc12.red(`${failedCritical.length} critical check(s) failed`));
11319
+ return 1;
11320
+ }
11321
+ if (failedNonCritical.length > 0) {
11322
+ gateOutro("Mostly OK", pc12.yellow(`${failedNonCritical.length} non-critical warning(s)`));
11323
+ return 0;
11324
+ }
11325
+ gateOutro("All checks passed");
11326
+ return 0;
11327
+ }
11328
+
11329
+ // src/agents/shared/completions.ts
11330
+ import pc13 from "picocolors";
11331
+ var SUBCOMMANDS = [
11332
+ "claude",
11333
+ "claude-app",
11334
+ "codex",
11335
+ "codex-app",
11336
+ "chatgpt",
11337
+ "gemini",
11338
+ "agy",
11339
+ "antigravity",
11340
+ "antigravity-ide",
11341
+ "server",
11342
+ "ui",
11343
+ "models",
11344
+ "favorites",
11345
+ "providers",
11346
+ "doctor",
11347
+ "completions",
11348
+ "update"
11349
+ ];
11350
+ var ROOT_FLAGS = ["--help", "--version", "--ai", "--ai --install", "--force"];
11351
+ function detectShell() {
11352
+ const shell = process.env["SHELL"]?.toLowerCase() ?? "";
11353
+ if (shell.includes("zsh")) return "zsh";
11354
+ if (shell.includes("bash")) return "bash";
11355
+ if (shell.includes("fish")) return "fish";
11356
+ if (process.env["PSModulePath"] || process.env["POWERSHELL_DISTRIBUTION_CHANNEL"]) return "powershell";
11357
+ return void 0;
11358
+ }
11359
+ function normalizeShell(input) {
11360
+ const s = input?.toLowerCase().trim();
11361
+ if (s === "bash" || s === "zsh" || s === "fish" || s === "powershell" || s === "pwsh" || s === "ps") {
11362
+ return s === "pwsh" || s === "ps" ? "powershell" : s;
11363
+ }
11364
+ return void 0;
11365
+ }
11366
+ function bashScript() {
11367
+ const cmds = SUBCOMMANDS.join(" ");
11368
+ return `# anygate bash completion
11369
+ _anygate() {
11370
+ local cur prev
11371
+ COMPREPLY=()
11372
+ cur="\${COMP_WORDS[COMP_CWORD]}"
11373
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
11374
+ local subcommands='${cmds}'
11375
+ local rootflags='${ROOT_FLAGS.join(" ")}'
11376
+ if [ "\${COMP_CWORD}" -eq 1 ]; then
11377
+ COMPREPLY=( $(compgen -W "\${subcommands} \${rootflags}" -- "\${cur}") )
11378
+ return 0
11379
+ fi
11380
+ COMPREPLY=( $(compgen -W "\${subcommands} \${rootflags}" -- "\${cur}") )
11381
+ return 0
11382
+ }
11383
+ complete -F _anygate anygate
11384
+ `;
11385
+ }
11386
+ function zshScript() {
11387
+ const cmds = SUBCOMMANDS.join(" ");
11388
+ return `# anygate zsh completion
11389
+ #compdef anygate
11390
+ _anygate() {
11391
+ local -a subcommands
11392
+ subcommands=(${cmds})
11393
+ _arguments '1:subcommand:(\${subcommands})' '*:: :_gnu_generic'
11394
+ }
11395
+ _anygate "$@"
11396
+ `;
11397
+ }
11398
+ function fishScript() {
11399
+ const lines = SUBCOMMANDS.map((c) => `complete -c anygate -n "not __fish_seen_subcommand_from ${SUBCOMMANDS.join(" ")}" -a ${c} -d 'anygate ${c}'`);
11400
+ lines.push(`complete -c anygate -s h -l help -d 'Show help'`);
11401
+ lines.push(`complete -c anygate -s v -l version -d 'Show version'`);
11402
+ return `# anygate fish completion
11403
+ ${lines.join("\n")}
11404
+ `;
11405
+ }
11406
+ function powershellScript() {
11407
+ const cmds = SUBCOMMANDS.map((c) => `'${c}'`).join(", ");
11408
+ return `# anygate PowerShell completion
11409
+ Register-ArgumentCompleter -CommandName anygate -ScriptBlock {
11410
+ param($wordToComplete, $commandAst, $cursorPosition)
11411
+ $subcommands = @(${cmds})
11412
+ $subcommands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
11413
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'Command', "anygate $_")
11414
+ }
11415
+ }
11416
+ `;
11417
+ }
11418
+ var SCRIPTS = {
11419
+ bash: bashScript,
11420
+ zsh: zshScript,
11421
+ fish: fishScript,
11422
+ powershell: powershellScript
11423
+ };
11424
+ function runCompletionsCommand(shellArg) {
11425
+ const shell = normalizeShell(shellArg) ?? detectShell();
11426
+ if (!shell) {
11427
+ console.error(pc13.red("\\nError: could not detect your shell.\\n"));
11428
+ console.error("Pass one explicitly: anygate completions <bash|zsh|fish|powershell>\\n");
11429
+ return Promise.resolve(1);
11430
+ }
11431
+ process.stdout.write(SCRIPTS[shell]());
11432
+ return Promise.resolve(0);
11433
+ }
11434
+
11435
+ // src/agents/shared/self-update.ts
11436
+ import pc14 from "picocolors";
11437
+ import { spawn as spawn5, execFileSync as execFileSync4 } from "child_process";
11438
+ import * as p14 from "@clack/prompts";
11439
+ function resolveNpmBin() {
11440
+ if (process.platform === "win32") {
11441
+ try {
11442
+ 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"));
11443
+ if (found) return found;
11444
+ } catch {
11445
+ }
11446
+ return "npm.cmd";
11447
+ }
11448
+ return "npm";
11449
+ }
11450
+ async function runUpdateCommand(dryRun) {
11451
+ const update = await checkForUpdates();
11452
+ if (!update.updateAvailable || !update.latestVersion) {
11453
+ p14.log.success(`anygate is up to date (v${VERSION}).`);
11454
+ return 0;
11455
+ }
11456
+ p14.log.info(
11457
+ `Update available: ${pc14.cyan(`v${update.currentVersion}`)} \u2192 ${pc14.green(`v${update.latestVersion}`)}`
11458
+ );
11459
+ const npmBin = resolveNpmBin();
11460
+ if (dryRun) {
11461
+ p14.log.step(`Would run: ${pc14.bold(`${npmBin} install -g anygate@latest`)}`);
11462
+ p14.log.warn("Dry run \u2014 no changes made.");
11463
+ return 0;
11464
+ }
11465
+ const confirmed = await p14.confirm({
11466
+ message: `Install anygate@${update.latestVersion} now?`,
11467
+ initialValue: false
11468
+ });
11469
+ if (p14.isCancel(confirmed) || !confirmed) {
11470
+ p14.log.info(`Update skipped. Run ${pc14.cyan(UPDATE_COMMAND)} later if you change your mind.`);
11471
+ return 0;
11472
+ }
11473
+ p14.log.info(`Running ${pc14.cyan(`${npmBin} install -g anygate@latest`)}...`);
11474
+ const child = spawn5(npmBin, ["install", "-g", "anygate@latest"], {
11475
+ stdio: "inherit",
11476
+ windowsHide: true
11477
+ });
11478
+ return new Promise((resolve) => {
11479
+ child.on("error", (err) => {
11480
+ p14.log.error(`Failed to start npm: ${err instanceof Error ? err.message : String(err)}`);
11481
+ resolve(1);
11482
+ });
11483
+ child.on("close", (code) => {
11484
+ if (code === 0) {
11485
+ p14.log.success("anygate updated. Restart your shell or re-run anygate to use the new version.");
11486
+ } else {
11487
+ p14.log.error(`Update failed (exit ${code}). Try ${pc14.cyan(UPDATE_COMMAND)} manually.`);
11488
+ }
11489
+ resolve(code ?? 1);
11490
+ });
11491
+ });
11492
+ }
11493
+
11228
11494
  // src/cli.ts
11229
11495
  var STARTER_CLAUDE_FLAGS = /* @__PURE__ */ new Set(["--dry-run", "--setup", "--trace", "--help", "-h", "--version", "-v"]);
11230
11496
  var GATEWAY_LAUNCH_FLAGS = /* @__PURE__ */ new Set(["--provider", "--model"]);
@@ -11549,6 +11815,55 @@ function parseArgs(args) {
11549
11815
  }
11550
11816
  return parsed2;
11551
11817
  }
11818
+ if (first === "doctor") {
11819
+ const parsed2 = emptyParsed("doctor");
11820
+ for (const arg of rest) {
11821
+ if (arg === "--help" || arg === "-h") parsed2.showHelp = true;
11822
+ else if (arg === "--version" || arg === "-v") parsed2.showVersion = true;
11823
+ else if (!parsed2.error) parsed2.error = `Unknown doctor option: ${arg}`;
11824
+ }
11825
+ return parsed2;
11826
+ }
11827
+ if (first === "completions") {
11828
+ const parsed2 = emptyParsed("completions");
11829
+ for (let i = 0; i < rest.length; i += 1) {
11830
+ const arg = rest[i];
11831
+ if (arg === "--help" || arg === "-h") {
11832
+ parsed2.showHelp = true;
11833
+ continue;
11834
+ }
11835
+ if (arg === "--version" || arg === "-v") {
11836
+ parsed2.showVersion = true;
11837
+ continue;
11838
+ }
11839
+ if (arg.startsWith("--shell=")) {
11840
+ parsed2.completionsShell = arg.slice("--shell=".length);
11841
+ continue;
11842
+ }
11843
+ if (arg === "--shell") {
11844
+ const value = rest[i + 1];
11845
+ if (!value || value.startsWith("-")) {
11846
+ parsed2.error = "Missing value for --shell";
11847
+ return parsed2;
11848
+ }
11849
+ parsed2.completionsShell = value;
11850
+ i += 1;
11851
+ continue;
11852
+ }
11853
+ if (!parsed2.error) parsed2.error = `Unknown completions option: ${arg}`;
11854
+ }
11855
+ return parsed2;
11856
+ }
11857
+ if (first === "update") {
11858
+ const parsed2 = emptyParsed("update");
11859
+ for (const arg of rest) {
11860
+ if (arg === "--help" || arg === "-h") parsed2.showHelp = true;
11861
+ else if (arg === "--version" || arg === "-v") parsed2.showVersion = true;
11862
+ else if (arg === "--dry-run") parsed2.dryRun = true;
11863
+ else if (!parsed2.error) parsed2.error = `Unknown update option: ${arg}`;
11864
+ }
11865
+ return parsed2;
11866
+ }
11552
11867
  if (first !== "claude") {
11553
11868
  return {
11554
11869
  ...emptyParsed("root"),
@@ -11581,11 +11896,11 @@ function parseArgs(args) {
11581
11896
  return parsed;
11582
11897
  }
11583
11898
  function rootHelpText() {
11584
- return `${pc12.bold("anygate")} v${VERSION}
11899
+ return `${pc15.bold("anygate")} v${VERSION}
11585
11900
  Launch AI coding tools with OpenCode Zen / Go or local providers (Groq, Mistral,
11586
11901
  OpenAI, Gemini, Ollama, and more).
11587
11902
 
11588
- ${pc12.bold("Usage:")}
11903
+ ${pc15.bold("Usage:")}
11589
11904
  anygate claude [options] [claude-flags]
11590
11905
  anygate claude-app [options]
11591
11906
  anygate codex [options] [codex-flags]
@@ -11600,20 +11915,23 @@ ${pc12.bold("Usage:")}
11600
11915
  anygate models
11601
11916
  anygate favorites
11602
11917
  anygate providers
11918
+ anygate doctor
11919
+ anygate completions <bash|zsh|fish|powershell>
11920
+ anygate update
11603
11921
  anygate --help
11604
11922
  anygate --version
11605
11923
  anygate --ai Full reference for AI agents (run this when unsure)
11606
11924
  anygate --ai --install Install or upgrade agent skill when version changed
11607
11925
  anygate --ai --install --force Reinstall skill even if already current
11608
11926
 
11609
- ${pc12.bold("Root options:")}
11927
+ ${pc15.bold("Root options:")}
11610
11928
  -h, --help Show this help
11611
11929
  -v, --version Show version
11612
11930
  --ai Print the full reference for AI agents
11613
11931
  --ai --install Install or upgrade the anygate agent skill
11614
11932
  --force Reinstall the agent skill when used with --ai --install
11615
11933
 
11616
- ${pc12.bold("Commands:")}
11934
+ ${pc15.bold("Commands:")}
11617
11935
  claude Launch Claude Code \u2014 pick a provider from your registry
11618
11936
  models Manage favorite models for mid-session /model switching (max ${MAX_MODEL_CATALOG})
11619
11937
  favorites Alias for models
@@ -11627,16 +11945,19 @@ ${pc12.bold("Commands:")}
11627
11945
  codex-app Launch ChatGPT desktop app (Codex mode) with registry providers (macOS + Windows)
11628
11946
  chatgpt Alias for codex-app
11629
11947
  claude-app Launch Claude Desktop app with registry providers (macOS + Windows)
11948
+ doctor Run an environment diagnostic (Node, keyring, key, port, env conflicts)
11949
+ completions Print a shell completion script for anygate
11950
+ update Interactively upgrade anygate to the latest published version
11630
11951
 
11631
- ${pc12.bold("Antigravity favorites:")}
11952
+ ${pc15.bold("Antigravity favorites:")}
11632
11953
  agy, antigravity, and antigravity-ide share up to six Antigravity favorites
11633
11954
  from anygate favorites --agy, plus the selected launch model.
11634
11955
 
11635
- ${pc12.bold("Upgradeion:")}
11956
+ ${pc15.bold("Upgradeion:")}
11636
11957
  Bare anygate prints this help instead of launching Claude Code.
11637
11958
  Use anygate claude for the wizard and launcher.
11638
11959
 
11639
- ${pc12.bold("Examples:")}
11960
+ ${pc15.bold("Examples:")}
11640
11961
  anygate claude
11641
11962
  anygate models
11642
11963
  anygate providers
@@ -11653,15 +11974,15 @@ ${pc12.bold("Examples:")}
11653
11974
  anygate claude -- --print "hello"`;
11654
11975
  }
11655
11976
  function claudeHelpText() {
11656
- return `${pc12.bold("anygate claude")} v${VERSION}
11977
+ return `${pc15.bold("anygate claude")} v${VERSION}
11657
11978
  Launch Claude Code with OpenCode Zen, Go, or local providers as the API backend.
11658
11979
 
11659
- ${pc12.bold("Usage:")}
11980
+ ${pc15.bold("Usage:")}
11660
11981
  anygate claude [options] [claude-flags]
11661
11982
  anygate claude --help
11662
11983
  anygate claude --version
11663
11984
 
11664
- ${pc12.bold("Options:")}
11985
+ ${pc15.bold("Options:")}
11665
11986
  --dry-run Run the wizard but show a preview instead of launching Claude Code
11666
11987
  --setup Hint: use anygate providers to add or manage providers
11667
11988
  --trace Write debug logs to ~/.anygate/logs/ and show errors on exit
@@ -11670,22 +11991,22 @@ ${pc12.bold("Options:")}
11670
11991
  --help Show this command help
11671
11992
  --version Show version
11672
11993
 
11673
- ${pc12.bold("Providers:")}
11994
+ ${pc15.bold("Providers:")}
11674
11995
  Cloud (Zen/Go) Requires OPENCODE_API_KEY \u2014 get one at https://opencode.ai/auth
11675
11996
  Registry Configure with anygate providers add or import (Groq, Mistral,
11676
11997
  Nvidia, DeepSeek, OpenAI, custom endpoints, etc.).
11677
11998
 
11678
- ${pc12.bold("Model switching:")}
11999
+ ${pc15.bold("Model switching:")}
11679
12000
  Run anygate models to save favorites (max ${MAX_MODEL_CATALOG}).
11680
12001
  When favorites exist, launch starts a multi-route proxy and Claude Code /model
11681
12002
  lists your starting model plus favorites for live switching.
11682
12003
  With no favorites, launch uses a single model as before.
11683
12004
 
11684
- ${pc12.bold("Note:")}
12005
+ ${pc15.bold("Note:")}
11685
12006
  Claude Code may save the launched model to ~/.claude/settings.json.
11686
12007
  Bare claude later can still show that model \u2014 reset with claude --model sonnet.
11687
12008
 
11688
- ${pc12.bold("Examples:")}
12009
+ ${pc15.bold("Examples:")}
11689
12010
  anygate claude
11690
12011
  anygate claude -c
11691
12012
  anygate claude --resume abc-123
@@ -11699,10 +12020,10 @@ ${pc12.bold("Examples:")}
11699
12020
  anygate claude -- --dangerously-skip-permissions`;
11700
12021
  }
11701
12022
  function serverHelpText() {
11702
- return `${pc12.bold("anygate server")} v${VERSION}
12023
+ return `${pc15.bold("anygate server")} v${VERSION}
11703
12024
  Run a foreground API gateway for registry providers, Zen/Go, or Vertex AI.
11704
12025
 
11705
- ${pc12.bold("Usage:")}
12026
+ ${pc15.bold("Usage:")}
11706
12027
  anygate server
11707
12028
  anygate server --quick
11708
12029
  anygate server --listen network --password <password>
@@ -11710,7 +12031,7 @@ ${pc12.bold("Usage:")}
11710
12031
  anygate server --help
11711
12032
  anygate server --version
11712
12033
 
11713
- ${pc12.bold("Options:")}
12034
+ ${pc15.bold("Options:")}
11714
12035
  --quick, --saved Start immediately from saved/default settings
11715
12036
  --listen local|network One-run listen mode override
11716
12037
  --providers all|favorites|id1,id2
@@ -11721,7 +12042,7 @@ ${pc12.bold("Options:")}
11721
12042
  --password <value> One-run network-mode server password
11722
12043
  --vertex Use Claude on Google Vertex AI
11723
12044
 
11724
- ${pc12.bold("Behavior:")}
12045
+ ${pc15.bold("Behavior:")}
11725
12046
  Default: interactive wizard for exposed providers, discovery id masking (for
11726
12047
  Claude Desktop / Cowork), optional favorites-only catalog, then listen mode.
11727
12048
  Quick mode skips prompts and uses saved settings. Any one-run option also
@@ -11731,129 +12052,129 @@ ${pc12.bold("Behavior:")}
11731
12052
  local gcloud Application Default Credentials (no OpenCode API key).
11732
12053
  Binds to port 17645. Network mode asks for a server password.
11733
12054
 
11734
- ${pc12.bold("Vertex env:")}
12055
+ ${pc15.bold("Vertex env:")}
11735
12056
  ANTHROPIC_VERTEX_PROJECT_ID or GOOGLE_CLOUD_PROJECT \u2014 your GCP project
11736
12057
  GOOGLE_CLOUD_LOCATION or CLOUD_ML_REGION \u2014 region (default: global)
11737
12058
  Optional catalog: ~/.anygate/vertex-models.json (see assets/vertex-models.example.json)
11738
12059
 
11739
- ${pc12.bold("Endpoints:")}
12060
+ ${pc15.bold("Endpoints:")}
11740
12061
  Anthropic-compatible: ANTHROPIC_BASE_URL=http://127.0.0.1:17645/anthropic
11741
12062
  OpenAI-compatible: OPENAI_BASE_URL=http://127.0.0.1:17645/openai/v1
11742
12063
  API key: use anything locally; use the server password in network mode.`;
11743
12064
  }
11744
12065
  function modelsHelpText() {
11745
- return `${pc12.bold("anygate favorites")} v${VERSION}
12066
+ return `${pc15.bold("anygate favorites")} v${VERSION}
11746
12067
  Manage favorite models for mid-session switching.
11747
12068
 
11748
- ${pc12.bold("Usage:")}
12069
+ ${pc15.bold("Usage:")}
11749
12070
  anygate favorites
11750
12071
  anygate favorites --agy
11751
12072
  anygate models
11752
12073
  anygate favorites --help
11753
12074
  anygate favorites --version
11754
12075
 
11755
- ${pc12.bold("Behavior:")}
12076
+ ${pc15.bold("Behavior:")}
11756
12077
  Opens an interactive manager to add or remove favorites.
11757
12078
  Search all providers at once (paginated results) or browse one provider at a time.
11758
12079
  Pick from Zen, Go, or any provider in your registry.
11759
12080
  Global favorites are saved to ~/.anygate/config.json (max ${MAX_MODEL_CATALOG}).
11760
12081
  --agy manages Antigravity CLI favorites only (max 6).
11761
12082
 
11762
- ${pc12.bold("How it works:")}
12083
+ ${pc15.bold("How it works:")}
11763
12084
  Claude/Codex/Gemini/server use the global favorites list.
11764
12085
  Favorites appear in supported /model switch menus.
11765
12086
  anygate agy, antigravity, and antigravity-ide use the Antigravity favorites
11766
12087
  list so the limited native switch slots stay predictable: one selected launch
11767
12088
  model plus up to six Antigravity favorites.
11768
12089
 
11769
- ${pc12.bold("Examples:")}
12090
+ ${pc15.bold("Examples:")}
11770
12091
  anygate favorites
11771
12092
  anygate favorites --agy
11772
12093
  anygate claude # switch menu active when favorites are set`;
11773
12094
  }
11774
12095
  function antigravityCliHelpText() {
11775
- return `${pc12.bold("anygate agy")} v${VERSION}
12096
+ return `${pc15.bold("anygate agy")} v${VERSION}
11776
12097
  Launch Antigravity CLI with anygate provider registry.
11777
12098
 
11778
- ${pc12.bold("Usage:")}
12099
+ ${pc15.bold("Usage:")}
11779
12100
  anygate agy [options] [agy-flags]
11780
12101
  anygate agy --help
11781
12102
  anygate agy --version
11782
12103
 
11783
- ${pc12.bold("Options:")}
12104
+ ${pc15.bold("Options:")}
11784
12105
  --provider <id> Use a specific provider (skip picker)
11785
12106
  --model <id> Use a specific model (skip picker)
11786
12107
  --trace Write debug log to /tmp/anygate-debug.log
11787
12108
  -h, --help Show this help
11788
12109
  -v, --version Show version
11789
12110
 
11790
- ${pc12.bold("How it works:")}
12111
+ ${pc15.bold("How it works:")}
11791
12112
  Starts a local Cloud Code gateway, points agy at it via CLOUD_CODE_URL,
11792
12113
  and injects anygate models into Antigravity's native model picker.
11793
12114
  All Cloud Code traffic routes through anygate \u2014 no Google Cloud Code upstream.
11794
12115
 
11795
- ${pc12.bold("Examples:")}
12116
+ ${pc15.bold("Examples:")}
11796
12117
  anygate agy
11797
12118
  anygate agy --provider zen --model deepseek-v4-flash-free
11798
12119
  anygate agy -p "fix this bug"`;
11799
12120
  }
11800
12121
  function antigravityIdeHelpText() {
11801
- return `${pc12.bold("anygate antigravity-ide")} v${VERSION}
12122
+ return `${pc15.bold("anygate antigravity-ide")} v${VERSION}
11802
12123
  Launch Antigravity IDE with anygate provider registry.
11803
12124
 
11804
- ${pc12.bold("Usage:")}
12125
+ ${pc15.bold("Usage:")}
11805
12126
  anygate antigravity-ide [options]
11806
12127
  anygate antigravity-ide --help
11807
12128
  anygate antigravity-ide --version
11808
12129
 
11809
- ${pc12.bold("Options:")}
12130
+ ${pc15.bold("Options:")}
11810
12131
  --provider <id> Use a specific provider (skip picker)
11811
12132
  --model <id> Use a specific model (skip picker)
11812
12133
  --trace Write debug log to /tmp/anygate-debug.log
11813
12134
  -h, --help Show this help
11814
12135
  -v, --version Show version
11815
12136
 
11816
- ${pc12.bold("How it works:")}
12137
+ ${pc15.bold("How it works:")}
11817
12138
  Creates an isolated anygate-managed IDE profile, starts a local Cloud Code
11818
12139
  gateway, and injects anygate models into Antigravity's native picker.
11819
12140
  The normal IDE profile is never modified.
11820
12141
 
11821
- ${pc12.bold("Platform:")}
12142
+ ${pc15.bold("Platform:")}
11822
12143
  macOS (Apple Silicon) \u2014 other platforms coming after testing.
11823
12144
 
11824
- ${pc12.bold("Examples:")}
12145
+ ${pc15.bold("Examples:")}
11825
12146
  anygate antigravity-ide
11826
12147
  anygate antigravity-ide --provider zen --model deepseek-v4-flash-free`;
11827
12148
  }
11828
12149
  function antigravityAppHelpText() {
11829
- return `${pc12.bold("anygate antigravity")} v${VERSION}
12150
+ return `${pc15.bold("anygate antigravity")} v${VERSION}
11830
12151
  Launch Antigravity with anygate provider registry.
11831
12152
 
11832
- ${pc12.bold("Usage:")}
12153
+ ${pc15.bold("Usage:")}
11833
12154
  anygate antigravity [options]
11834
12155
  anygate antigravity --help
11835
12156
  anygate antigravity --version
11836
12157
 
11837
- ${pc12.bold("Options:")}
12158
+ ${pc15.bold("Options:")}
11838
12159
  --provider <id> Use a specific provider (skip picker)
11839
12160
  --model <id> Use a specific model (skip picker)
11840
12161
  --trace Write debug log to /tmp/anygate-debug.log
11841
12162
  -h, --help Show this help
11842
12163
  -v, --version Show version
11843
12164
 
11844
- ${pc12.bold("How it works:")}
12165
+ ${pc15.bold("How it works:")}
11845
12166
  Creates an isolated anygate-managed Antigravity profile, starts a local Cloud
11846
12167
  Code gateway, and injects anygate models into Antigravity's native picker.
11847
12168
  The normal Antigravity profile is never modified.
11848
12169
 
11849
- ${pc12.bold("Favorites:")}
12170
+ ${pc15.bold("Favorites:")}
11850
12171
  Uses the same Antigravity favorites list as anygate favorites --agy:
11851
12172
  up to six saved favorites plus the selected launch model.
11852
12173
 
11853
- ${pc12.bold("Platform:")}
12174
+ ${pc15.bold("Platform:")}
11854
12175
  macOS (Apple Silicon) \u2014 other platforms coming after testing.
11855
12176
 
11856
- ${pc12.bold("Examples:")}
12177
+ ${pc15.bold("Examples:")}
11857
12178
  anygate antigravity
11858
12179
  anygate antigravity --provider zen --model deepseek-v4-flash-free`;
11859
12180
  }
@@ -11866,11 +12187,11 @@ async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindo
11866
12187
  let proxyHandle;
11867
12188
  try {
11868
12189
  proxyHandle = await startProxyCatalog(catalogRoutes, startingRoute.aliasId, trace);
11869
- p14.log.info(
11870
- `Switch menu active \u2014 proxy on port ${proxyHandle.port} ` + pc12.dim(`(${catalogRoutes.length} model${catalogRoutes.length !== 1 ? "s" : ""} in /model)`)
12190
+ p15.log.info(
12191
+ `Switch menu active \u2014 proxy on port ${proxyHandle.port} ` + pc15.dim(`(${catalogRoutes.length} model${catalogRoutes.length !== 1 ? "s" : ""} in /model)`)
11871
12192
  );
11872
12193
  } catch (err) {
11873
- p14.log.error(`Failed to start proxy: ${err instanceof Error ? err.message : String(err)}`);
12194
+ p15.log.error(`Failed to start proxy: ${err instanceof Error ? err.message : String(err)}`);
11874
12195
  return 1;
11875
12196
  }
11876
12197
  const childEnv = buildChildEnv(
@@ -11883,7 +12204,7 @@ async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindo
11883
12204
  );
11884
12205
  const debugLogPath = prepareClaudeTraceLog();
11885
12206
  const traceArgs = trace ? ["--debug-file", debugLogPath] : [];
11886
- if (trace) p14.log.info(`Debug log: ${debugLogPath}`);
12207
+ if (trace) p15.log.info(`Debug log: ${debugLogPath}`);
11887
12208
  const exitCode = await launchClaude(
11888
12209
  childEnv,
11889
12210
  claudeCodeClientModelId(startingRoute.aliasId, contextWindow),
@@ -11900,7 +12221,7 @@ async function runModelsCommand(opts = {}) {
11900
12221
  const scopeName = scope === "agy" ? "Antigravity CLI Favorites" : "Favorite Models";
11901
12222
  const configKey = scope === "agy" ? "antigravityCliFavoriteModels" : "favoriteModels";
11902
12223
  gateIntro(scopeName);
11903
- const spinner9 = p14.spinner();
12224
+ const spinner9 = p15.spinner();
11904
12225
  spinner9.start("Loading providers...");
11905
12226
  const catalog = await fetchProviderCatalog();
11906
12227
  spinner9.stop("");
@@ -11910,8 +12231,8 @@ async function runModelsCommand(opts = {}) {
11910
12231
  name: favoriteProviderDisplayName(provider)
11911
12232
  }));
11912
12233
  if (favoriteProviders.length === 0) {
11913
- p14.log.warn("No providers found.");
11914
- p14.log.info(`${pc12.dim("OpenCode Zen/Go is always available. Add providers with ")}${pc12.cyan("anygate providers")}${pc12.dim(".")}`);
12234
+ p15.log.warn("No providers found.");
12235
+ p15.log.info(`${pc15.dim("OpenCode Zen/Go is always available. Add providers with ")}${pc15.cyan("anygate providers")}${pc15.dim(".")}`);
11915
12236
  gateOutro("Done");
11916
12237
  return 0;
11917
12238
  }
@@ -11929,50 +12250,50 @@ async function runModelsCommand(opts = {}) {
11929
12250
  for (let i = 0; i < favorites.length; i++) {
11930
12251
  const fav = favorites[i];
11931
12252
  const entry = modelLookup.get(`${fav.providerId}:${fav.modelId}`);
11932
- const label = entry ? `${fmtEnabledStar(true)} ${fmtModel(entry.modelName)} ${pc12.dim(`(${entry.providerName})`)}` : pc12.dim(`\u2605 ${fav.modelId} \u2014 provider gone`);
12253
+ const label = entry ? `${fmtEnabledStar(true)} ${fmtModel(entry.modelName)} ${pc15.dim(`(${entry.providerName})`)}` : pc15.dim(`\u2605 ${fav.modelId} \u2014 provider gone`);
11933
12254
  options.push({ value: `fav-${i}`, label, hint: "select to remove" });
11934
12255
  }
11935
12256
  const atCap = favorites.length >= maxFavorites;
11936
12257
  options.push({
11937
12258
  value: "__add__",
11938
- label: atCap ? pc12.dim(`+ Add a model \u2192 (limit of ${maxFavorites} reached)`) : pc12.cyan("+ Add a model \u2192"),
12259
+ label: atCap ? pc15.dim(`+ Add a model \u2192 (limit of ${maxFavorites} reached)`) : pc15.cyan("+ Add a model \u2192"),
11939
12260
  hint: atCap ? "Remove a favorite first to make room" : `${allProviders.length} provider${allProviders.length !== 1 ? "s" : ""} available`
11940
12261
  });
11941
12262
  options.push({ value: "__done__", label: "Done", hint: "" });
11942
12263
  const header = favorites.length === 0 ? `${scopeName} (0/${maxFavorites})` : `${scopeName} (${favorites.length}/${maxFavorites}) \u2014 select to remove`;
11943
- const choice = await p14.select({
12264
+ const choice = await p15.select({
11944
12265
  message: header,
11945
12266
  options,
11946
12267
  initialValue: "__done__"
11947
12268
  });
11948
- if (p14.isCancel(choice) || choice === "__done__") break;
12269
+ if (p15.isCancel(choice) || choice === "__done__") break;
11949
12270
  if (choice === "__add__") {
11950
12271
  if (atCap) {
11951
- p14.log.warn(`Limit of ${maxFavorites} favorites reached \u2014 remove one first.`);
12272
+ p15.log.warn(`Limit of ${maxFavorites} favorites reached \u2014 remove one first.`);
11952
12273
  continue;
11953
12274
  }
11954
12275
  const globalCount = buildGlobalFavoriteIndex(favoriteProviders).length;
11955
- const addPath = await p14.select({
12276
+ const addPath = await p15.select({
11956
12277
  message: "Add a favorite",
11957
12278
  options: [
11958
12279
  {
11959
12280
  value: "global",
11960
- label: pc12.cyan("Search all providers"),
12281
+ label: pc15.cyan("Search all providers"),
11961
12282
  hint: `${globalCount} models \xB7 ${favoriteProviders.length} provider${favoriteProviders.length !== 1 ? "s" : ""}`
11962
12283
  },
11963
12284
  {
11964
12285
  value: "free",
11965
- label: pc12.cyan("Search free models"),
12286
+ label: pc15.cyan("Search free models"),
11966
12287
  hint: `${buildGlobalFavoriteIndex(favoriteProviders).filter((e) => e.model.isFree || e.model.freeStatus === "verified_free" || e.model.freeStatus === "free_provider").length} free/free-access models`
11967
12288
  },
11968
12289
  {
11969
12290
  value: "provider",
11970
- label: pc12.cyan("Browse by provider \u2192"),
12291
+ label: pc15.cyan("Browse by provider \u2192"),
11971
12292
  hint: "Pick one provider first"
11972
12293
  }
11973
12294
  ]
11974
12295
  });
11975
- if (p14.isCancel(addPath)) continue;
12296
+ if (p15.isCancel(addPath)) continue;
11976
12297
  let provider;
11977
12298
  let browsedMultiple = [];
11978
12299
  if (addPath === "global") {
@@ -11995,12 +12316,12 @@ async function runModelsCommand(opts = {}) {
11995
12316
  let currentInitialProvider = void 0;
11996
12317
  while (true) {
11997
12318
  const providerOptions = favoriteProviders.map((ap) => providerSelectOption(ap));
11998
- const pickedProviderId = await p14.select({
12319
+ const pickedProviderId = await p15.select({
11999
12320
  message: "Which provider?",
12000
12321
  options: providerOptions,
12001
12322
  initialValue: currentInitialProvider
12002
12323
  });
12003
- if (p14.isCancel(pickedProviderId)) break;
12324
+ if (p15.isCancel(pickedProviderId)) break;
12004
12325
  provider = favoriteProviders.find((ap) => ap.id === pickedProviderId);
12005
12326
  const options2 = provider.models.map((m) => {
12006
12327
  const favorited = isFavorite(favorites, { providerId: provider.id, modelId: m.id });
@@ -12008,15 +12329,15 @@ async function runModelsCommand(opts = {}) {
12008
12329
  return {
12009
12330
  value: m.id,
12010
12331
  label: fmtModel(label, m.id),
12011
- hint: favorited ? pc12.yellow("\u2605 already favorite") : ""
12332
+ hint: favorited ? pc15.yellow("\u2605 already favorite") : ""
12012
12333
  };
12013
12334
  });
12014
- const pickedModelIds = await p14.multiselect({
12015
- message: `Select models to add from ${provider.name} ${pc12.dim("(Space to select, Enter to confirm)")}`,
12335
+ const pickedModelIds = await p15.multiselect({
12336
+ message: `Select models to add from ${provider.name} ${pc15.dim("(Space to select, Enter to confirm)")}`,
12016
12337
  options: options2,
12017
12338
  required: false
12018
12339
  });
12019
- if (p14.isCancel(pickedModelIds)) {
12340
+ if (p15.isCancel(pickedModelIds)) {
12020
12341
  currentInitialProvider = provider.id;
12021
12342
  continue;
12022
12343
  }
@@ -12051,27 +12372,27 @@ async function runModelsCommand(opts = {}) {
12051
12372
  if (addedModels.length > 0) {
12052
12373
  if (addedModels.length === 1) {
12053
12374
  const modelName = addedModels[0].name || addedModels[0].id;
12054
- p14.log.success(`Added ${modelName} (${provider.name}) to favorites.`);
12375
+ p15.log.success(`Added ${modelName} (${provider.name}) to favorites.`);
12055
12376
  } else {
12056
- p14.log.success(`Added ${addedModels.length} models from ${provider.name} to favorites.`);
12377
+ p15.log.success(`Added ${addedModels.length} models from ${provider.name} to favorites.`);
12057
12378
  }
12058
12379
  }
12059
12380
  if (duplicateCount > 0) {
12060
- p14.log.warn(`${duplicateCount} selected model(s) were already in your favorites.`);
12381
+ p15.log.warn(`${duplicateCount} selected model(s) were already in your favorites.`);
12061
12382
  }
12062
12383
  if (limitReached) {
12063
- p14.log.warn(`Limit of ${maxFavorites} favorites reached \u2014 some selected models could not be added.`);
12384
+ p15.log.warn(`Limit of ${maxFavorites} favorites reached \u2014 some selected models could not be added.`);
12064
12385
  }
12065
12386
  } else if (choice.startsWith("fav-")) {
12066
12387
  const idx = parseInt(choice.slice(4), 10);
12067
12388
  const fav = favorites[idx];
12068
12389
  const entry = modelLookup.get(`${fav.providerId}:${fav.modelId}`);
12069
12390
  const label = entry ? `${entry.modelName} (${entry.providerName})` : fav.modelId;
12070
- const confirmed = await p14.confirm({ message: `Remove ${label} from favorites?` });
12071
- if (p14.isCancel(confirmed) || !confirmed) continue;
12391
+ const confirmed = await p15.confirm({ message: `Remove ${label} from favorites?` });
12392
+ if (p15.isCancel(confirmed) || !confirmed) continue;
12072
12393
  favorites = removeFavorite(favorites, fav);
12073
12394
  favoritesDirty = true;
12074
- p14.log.success(`Removed ${label} from favorites.`);
12395
+ p15.log.success(`Removed ${label} from favorites.`);
12075
12396
  }
12076
12397
  }
12077
12398
  if (favoritesDirty) {
@@ -12080,7 +12401,7 @@ async function runModelsCommand(opts = {}) {
12080
12401
  const favLabel = scope === "agy" ? "Antigravity CLI " : "";
12081
12402
  gateOutro(
12082
12403
  favorites.length === 0 ? `No ${favLabel}favorites saved` : `${favorites.length} ${favLabel}favorite${favorites.length !== 1 ? "s" : ""} saved`,
12083
- favorites.length === 0 ? pc12.dim("Launch uses single-model mode") : pc12.cyan("/model menu ready on next launch")
12404
+ favorites.length === 0 ? pc15.dim("Launch uses single-model mode") : pc15.cyan("/model menu ready on next launch")
12084
12405
  );
12085
12406
  return 0;
12086
12407
  }
@@ -12091,7 +12412,7 @@ async function runClaudeCommand(parsed) {
12091
12412
  setAgentStdoutMode(agentStdout);
12092
12413
  const claudePath = findClaudeBinary();
12093
12414
  if (!claudePath) {
12094
- console.error(pc12.red("\nError: claude binary not found on PATH.\n"));
12415
+ console.error(pc15.red("\nError: claude binary not found on PATH.\n"));
12095
12416
  console.error("Install Claude Code:");
12096
12417
  console.error(" npm install -g @anthropic-ai/claude-code\n");
12097
12418
  return 1;
@@ -12106,7 +12427,7 @@ async function runClaudeCommand(parsed) {
12106
12427
  prefs
12107
12428
  });
12108
12429
  if (launchPlan.error) {
12109
- console.error(pc12.red(`
12430
+ console.error(pc15.red(`
12110
12431
  Error: ${launchPlan.error}
12111
12432
  `));
12112
12433
  return 1;
@@ -12114,7 +12435,7 @@ Error: ${launchPlan.error}
12114
12435
  const switchMenuActive = favorites.length > 0 && !launchPlan.skip;
12115
12436
  if (!agentStdout) gateIntro("Claude Code");
12116
12437
  if (setup && !dryRun && !agentStdout) {
12117
- p14.log.info("Provider setup now lives in anygate providers \u2014 opening that next is recommended.");
12438
+ p15.log.info("Provider setup now lives in anygate providers \u2014 opening that next is recommended.");
12118
12439
  }
12119
12440
  if (!dryRun && await needsFirstRunSetup()) {
12120
12441
  const firstRun = await runFirstRunWizard(trace);
@@ -12125,25 +12446,25 @@ Error: ${launchPlan.error}
12125
12446
  try {
12126
12447
  catalog = await fetchProviderCatalog();
12127
12448
  } catch (err) {
12128
- console.error(pc12.red(String(err instanceof Error ? err.message : err)));
12449
+ console.error(pc15.red(String(err instanceof Error ? err.message : err)));
12129
12450
  return 1;
12130
12451
  }
12131
12452
  } else {
12132
- const catalogSpinner = p14.spinner();
12453
+ const catalogSpinner = p15.spinner();
12133
12454
  catalogSpinner.start("Loading your providers...");
12134
12455
  try {
12135
12456
  catalog = await fetchProviderCatalog();
12136
12457
  } catch (err) {
12137
12458
  catalogSpinner.stop("");
12138
- console.error(pc12.red(String(err instanceof Error ? err.message : err)));
12459
+ console.error(pc15.red(String(err instanceof Error ? err.message : err)));
12139
12460
  return 1;
12140
12461
  }
12141
12462
  catalogSpinner.stop("");
12142
12463
  }
12143
12464
  const allProviders = providersForTarget(providersForPicker(catalog), "claude");
12144
12465
  if (allProviders.length === 0) {
12145
- p14.log.warn("No providers available.");
12146
- p14.log.info(pc12.dim("Run anygate providers add or import to get started."));
12466
+ p15.log.warn("No providers available.");
12467
+ p15.log.info(pc15.dim("Run anygate providers add or import to get started."));
12147
12468
  return 0;
12148
12469
  }
12149
12470
  const providerOptions = allProviders.map((lp) => providerSelectOption(lp));
@@ -12160,7 +12481,7 @@ Error: ${launchPlan.error}
12160
12481
  if (launchPlan.skip && launchPlan.target) {
12161
12482
  const resolved = findProviderAndModel(allProviders, launchPlan.target);
12162
12483
  if (!resolved) {
12163
- p14.log.error(
12484
+ p15.log.error(
12164
12485
  `Provider/model not found: ${launchPlan.target.providerId} / ${launchPlan.target.modelId}`
12165
12486
  );
12166
12487
  return 1;
@@ -12168,19 +12489,19 @@ Error: ${launchPlan.error}
12168
12489
  activeProvider = resolved.provider;
12169
12490
  selectedModel = resolved.model;
12170
12491
  if (!agentStdout) {
12171
- p14.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
12492
+ p15.log.step(`Using ${selectedModel.name || selectedModel.id} (${activeProvider.name})`);
12172
12493
  }
12173
12494
  if (!dryRun) recordLaunchSelection("claude", activeProvider.id, selectedModel.id, prefs);
12174
12495
  } else {
12175
12496
  let currentInitialProvider = initialProvider;
12176
12497
  while (true) {
12177
- const chosen = await p14.select({
12498
+ const chosen = await p15.select({
12178
12499
  message: "Which provider?",
12179
12500
  options: providerOptions,
12180
12501
  initialValue: currentInitialProvider
12181
12502
  });
12182
- if (p14.isCancel(chosen)) {
12183
- p14.cancel("Cancelled.");
12503
+ if (p15.isCancel(chosen)) {
12504
+ p15.cancel("Cancelled.");
12184
12505
  return 0;
12185
12506
  }
12186
12507
  const providerChoice = chosen;
@@ -12192,7 +12513,7 @@ Error: ${launchPlan.error}
12192
12513
  if (prov && mod) available.push({ provider: prov, model: mod });
12193
12514
  }
12194
12515
  if (available.length === 0) {
12195
- p14.log.warn("No saved favorites are currently available.");
12516
+ p15.log.warn("No saved favorites are currently available.");
12196
12517
  return 0;
12197
12518
  }
12198
12519
  const favOptions = available.map((f, i) => ({
@@ -12200,13 +12521,13 @@ Error: ${launchPlan.error}
12200
12521
  label: `${f.model.name || f.model.id} \u2014 ${f.provider.name}`,
12201
12522
  hint: f.model.id
12202
12523
  }));
12203
- const pickedIdx = await p14.select({
12524
+ const pickedIdx = await p15.select({
12204
12525
  message: "Starting model?",
12205
12526
  options: favOptions,
12206
12527
  initialValue: "0"
12207
12528
  });
12208
- if (p14.isCancel(pickedIdx)) {
12209
- p14.cancel("Cancelled.");
12529
+ if (p15.isCancel(pickedIdx)) {
12530
+ p15.cancel("Cancelled.");
12210
12531
  return 0;
12211
12532
  }
12212
12533
  const sel = available[Number(pickedIdx)];
@@ -12235,27 +12556,27 @@ Error: ${launchPlan.error}
12235
12556
  );
12236
12557
  const startingRoute = resolveRoute(activeProvider.id, selectedModel.id) ?? null;
12237
12558
  if (!startingRoute) {
12238
- p14.log.error("Could not resolve a proxy route for the selected model.");
12559
+ p15.log.error("Could not resolve a proxy route for the selected model.");
12239
12560
  return 1;
12240
12561
  }
12241
12562
  const { routes: catalogRoutes, droppedFavorites } = buildCatalogRoutes(startingRoute, favorites, resolveRoute);
12242
12563
  if (droppedFavorites.length > 0) {
12243
- p14.log.warn(
12564
+ p15.log.warn(
12244
12565
  `Skipping ${droppedFavorites.length} favorite${droppedFavorites.length === 1 ? "" : "s"} that are no longer available in /model`
12245
12566
  );
12246
12567
  }
12247
12568
  if (dryRun) {
12248
12569
  const endpoint = selectedModel.baseUrl ?? selectedModel.completionsUrl ?? "(unknown)";
12249
12570
  console.log("");
12250
- console.log(pc12.bold(pc12.cyan(" DRY RUN \u2014 would execute (switch-menu mode):")));
12571
+ console.log(pc15.bold(pc15.cyan(" DRY RUN \u2014 would execute (switch-menu mode):")));
12251
12572
  console.log("");
12252
- console.log(` ${pc12.bold("Provider:")} ${activeProvider.name}`);
12253
- console.log(` ${pc12.bold("Starting model:")} ${selectedModel.id}`);
12254
- console.log(` ${pc12.bold("Endpoint:")} ${endpoint}`);
12255
- console.log(` ${pc12.bold("/model catalog:")} ${catalogRoutes.length} model(s)`);
12256
- catalogRoutes.forEach((r) => console.log(` ${pc12.dim(r.displayName)}`));
12573
+ console.log(` ${pc15.bold("Provider:")} ${activeProvider.name}`);
12574
+ console.log(` ${pc15.bold("Starting model:")} ${selectedModel.id}`);
12575
+ console.log(` ${pc15.bold("Endpoint:")} ${endpoint}`);
12576
+ console.log(` ${pc15.bold("/model catalog:")} ${catalogRoutes.length} model(s)`);
12577
+ catalogRoutes.forEach((r) => console.log(` ${pc15.dim(r.displayName)}`));
12257
12578
  console.log("");
12258
- console.log(pc12.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
12579
+ console.log(pc15.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
12259
12580
  console.log("");
12260
12581
  return 0;
12261
12582
  }
@@ -12271,21 +12592,21 @@ Error: ${launchPlan.error}
12271
12592
  const formatDesc = selectedModel.modelFormat === "anthropic" ? "direct passthrough" : "via SDK adapter proxy";
12272
12593
  const endpoint = selectedModel.modelFormat === "anthropic" ? selectedModel.baseUrl ?? "(unknown)" : selectedModel.npm ?? "SDK";
12273
12594
  console.log("");
12274
- console.log(pc12.bold(pc12.cyan(" DRY RUN \u2014 would execute:")));
12595
+ console.log(pc15.bold(pc15.cyan(" DRY RUN \u2014 would execute:")));
12275
12596
  console.log("");
12276
- console.log(` ${pc12.bold("Provider:")} ${activeProvider.name}`);
12277
- console.log(` ${pc12.bold("Model:")} ${selectedModel.id}`);
12278
- console.log(` ${pc12.bold("Format:")} ${selectedModel.modelFormat} (${formatDesc})`);
12279
- console.log(` ${pc12.bold(selectedModel.modelFormat === "anthropic" ? "Endpoint:" : "SDK npm:")} ${endpoint}`);
12280
- console.log(` ${pc12.bold("Key:")} ${activeProvider.name} provider key`);
12597
+ console.log(` ${pc15.bold("Provider:")} ${activeProvider.name}`);
12598
+ console.log(` ${pc15.bold("Model:")} ${selectedModel.id}`);
12599
+ console.log(` ${pc15.bold("Format:")} ${selectedModel.modelFormat} (${formatDesc})`);
12600
+ console.log(` ${pc15.bold(selectedModel.modelFormat === "anthropic" ? "Endpoint:" : "SDK npm:")} ${endpoint}`);
12601
+ console.log(` ${pc15.bold("Key:")} ${activeProvider.name} provider key`);
12281
12602
  console.log("");
12282
- console.log(pc12.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
12603
+ console.log(pc15.dim(" (dry run complete \u2014 Claude Code was NOT launched)"));
12283
12604
  console.log("");
12284
12605
  return 0;
12285
12606
  }
12286
12607
  const launchApiKey = await resolveLocalProviderApiKey(activeProvider);
12287
12608
  if (!launchApiKey?.trim()) {
12288
- p14.log.error(
12609
+ p15.log.error(
12289
12610
  `No credential found for ${activeProvider.name}. Add a key with anygate providers or set OPENCODE_API_KEY.`
12290
12611
  );
12291
12612
  return 1;
@@ -12305,13 +12626,14 @@ Error: ${launchPlan.error}
12305
12626
  providerId: activeProvider.id,
12306
12627
  authType: "oauth",
12307
12628
  providerData: activeProvider.providerData,
12308
- modelFormat: "cloud-code"
12629
+ modelFormat: "cloud-code",
12630
+ app: "Antigravity"
12309
12631
  },
12310
12632
  launchApiKey
12311
12633
  );
12312
- if (!isAgentStdoutMode()) p14.log.info(`Cloud Code proxy started on port ${proxyHandle.port}`);
12634
+ if (!isAgentStdoutMode()) p15.log.info(`Cloud Code proxy started on port ${proxyHandle.port}`);
12313
12635
  } catch (err) {
12314
- p14.log.error(`Failed to start Cloud Code proxy: ${err instanceof Error ? err.message : String(err)}`);
12636
+ p15.log.error(`Failed to start Cloud Code proxy: ${err instanceof Error ? err.message : String(err)}`);
12315
12637
  return 1;
12316
12638
  }
12317
12639
  childEnv = buildChildEnv(
@@ -12333,13 +12655,14 @@ Error: ${launchPlan.error}
12333
12655
  authType: "oauth",
12334
12656
  oauthAccountId: activeProvider.oauthAccountId,
12335
12657
  providerData: activeProvider.providerData,
12336
- modelFormat: "anthropic"
12658
+ modelFormat: "anthropic",
12659
+ app: "Claude"
12337
12660
  },
12338
12661
  launchApiKey
12339
12662
  );
12340
- if (!isAgentStdoutMode()) p14.log.info(`OAuth proxy started on port ${proxyHandle.port}`);
12663
+ if (!isAgentStdoutMode()) p15.log.info(`OAuth proxy started on port ${proxyHandle.port}`);
12341
12664
  } catch (err) {
12342
- p14.log.error(`Failed to start OAuth proxy: ${err instanceof Error ? err.message : String(err)}`);
12665
+ p15.log.error(`Failed to start OAuth proxy: ${err instanceof Error ? err.message : String(err)}`);
12343
12666
  return 1;
12344
12667
  }
12345
12668
  childEnv = buildChildEnv(
@@ -12375,17 +12698,18 @@ Error: ${launchPlan.error}
12375
12698
  reasoning: selectedModel.reasoning,
12376
12699
  interleavedReasoningField: selectedModel.interleavedReasoningField,
12377
12700
  useResponsesLite: selectedModel.useResponsesLite,
12378
- preferWebSockets: selectedModel.preferWebSockets
12701
+ preferWebSockets: selectedModel.preferWebSockets,
12702
+ app: "Claude"
12379
12703
  },
12380
12704
  launchApiKey
12381
12705
  );
12382
12706
  if (!isAgentStdoutMode()) {
12383
- p14.log.info(
12384
- `SDK adapter proxy started on port ${proxyHandle.port}` + (selectedModel.npm ? pc12.dim(` (${selectedModel.npm})`) : "")
12707
+ p15.log.info(
12708
+ `SDK adapter proxy started on port ${proxyHandle.port}` + (selectedModel.npm ? pc15.dim(` (${selectedModel.npm})`) : "")
12385
12709
  );
12386
12710
  }
12387
12711
  } catch (err) {
12388
- p14.log.error(`Failed to start SDK adapter proxy: ${err instanceof Error ? err.message : String(err)}`);
12712
+ p15.log.error(`Failed to start SDK adapter proxy: ${err instanceof Error ? err.message : String(err)}`);
12389
12713
  return 1;
12390
12714
  }
12391
12715
  childEnv = buildChildEnv(
@@ -12401,7 +12725,7 @@ Error: ${launchPlan.error}
12401
12725
  }
12402
12726
  const debugLogPath = prepareClaudeTraceLog();
12403
12727
  const traceArgs = trace ? ["--debug-file", debugLogPath] : [];
12404
- if (trace) p14.log.info(`Debug log: ${debugLogPath}`);
12728
+ if (trace) p15.log.info(`Debug log: ${debugLogPath}`);
12405
12729
  const exitCode = await launchClaude(
12406
12730
  childEnv,
12407
12731
  claudeCodeClientModelId(selectedModel.id, selectedModel.contextWindow),
@@ -12425,7 +12749,7 @@ ${formatUpdateNotification(update.currentVersion, update.latestVersion)}
12425
12749
  else console.error(notice);
12426
12750
  }
12427
12751
  if (parsed.error) {
12428
- console.error(pc12.red(`
12752
+ console.error(pc15.red(`
12429
12753
  Error: ${parsed.error}
12430
12754
  `));
12431
12755
  printHelp(rootHelpText());
@@ -12478,7 +12802,7 @@ Error: ${parsed.error}
12478
12802
  console.log("Usage: anygate ui [--trace]\n\nOpen the settings UI in your browser.");
12479
12803
  return 0;
12480
12804
  }
12481
- const { runUiCommand } = await import("./command-OQI56XYG.js");
12805
+ const { runUiCommand } = await import("./command-GJYPBC6E.js");
12482
12806
  return runUiCommand({ trace: parsed.trace });
12483
12807
  }
12484
12808
  if (parsed.command === "models") {
@@ -12591,6 +12915,39 @@ Error: ${parsed.error}
12591
12915
  launchModel: parsed.launchModel
12592
12916
  });
12593
12917
  }
12918
+ if (parsed.command === "doctor") {
12919
+ if (parsed.showVersion) {
12920
+ console.log(VERSION);
12921
+ return 0;
12922
+ }
12923
+ if (parsed.showHelp) {
12924
+ console.log("Usage: anygate doctor [--help] [--version]\n\nRun an environment diagnostic (Node, keyring, API key, port, env conflicts).");
12925
+ return 0;
12926
+ }
12927
+ return runDoctorCommand(parsed.dryRun);
12928
+ }
12929
+ if (parsed.command === "completions") {
12930
+ if (parsed.showVersion) {
12931
+ console.log(VERSION);
12932
+ return 0;
12933
+ }
12934
+ if (parsed.showHelp) {
12935
+ console.log("Usage: anygate completions [bash|zsh|fish|powershell] [--shell <shell>]\n\nPrint a shell completion script for anygate to stdout.");
12936
+ return 0;
12937
+ }
12938
+ return runCompletionsCommand(parsed.completionsShell);
12939
+ }
12940
+ if (parsed.command === "update") {
12941
+ if (parsed.showVersion) {
12942
+ console.log(VERSION);
12943
+ return 0;
12944
+ }
12945
+ if (parsed.showHelp) {
12946
+ console.log("Usage: anygate update [--dry-run] [--help] [--version]\n\nInteractively upgrade anygate to the latest published version.");
12947
+ return 0;
12948
+ }
12949
+ return runUpdateCommand(parsed.dryRun);
12950
+ }
12594
12951
  if (parsed.showVersion) {
12595
12952
  console.log(VERSION);
12596
12953
  return 0;
@@ -12616,7 +12973,7 @@ if (isCliEntryPoint()) {
12616
12973
  if (err === /* @__PURE__ */ Symbol.for("clack:cancel")) {
12617
12974
  process.exit(0);
12618
12975
  }
12619
- console.error(pc12.red("\nUnexpected error:"), err);
12976
+ console.error(pc15.red("\nUnexpected error:"), err);
12620
12977
  process.exit(1);
12621
12978
  });
12622
12979
  }