anygate 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,11 +13,11 @@ import {
13
13
  VERSION,
14
14
  VERTEX_ANTHROPIC_NPM,
15
15
  classifyModelFormat
16
- } from "./chunk-QLHVQYQN.js";
16
+ } from "./chunk-UE2I2ETX.js";
17
17
  import {
18
18
  getTemplateById,
19
19
  listAddableTemplates
20
- } from "./chunk-VGM6EBG4.js";
20
+ } from "./chunk-4N4RDHGZ.js";
21
21
 
22
22
  // src/apps/shared/ui.ts
23
23
  import pc from "picocolors";
@@ -156,13 +156,19 @@ async function pollOpenAiDeviceCodeToken(deviceData, opts) {
156
156
  }).toString()
157
157
  });
158
158
  if (!tokenResponse.ok) {
159
- throw new Error(`OpenAI token exchange failed (${tokenResponse.status})`);
159
+ const detail = await tokenResponse.text().catch(() => "");
160
+ throw new Error(
161
+ `OpenAI token exchange failed (${tokenResponse.status})${detail.trim() ? `: ${detail.replace(/\s+/g, " ").trim().slice(0, 200)}` : ""}`
162
+ );
160
163
  }
161
164
  const tokens = await tokenResponse.json();
162
165
  return { tokens, accountId: extractOpenAiAccountId(tokens) };
163
166
  }
164
167
  if (response.status !== 403 && response.status !== 404) {
165
- throw new Error(`OpenAI device authorization failed (${response.status})`);
168
+ const detail = await response.text().catch(() => "");
169
+ throw new Error(
170
+ `OpenAI device authorization failed (${response.status})${detail.trim() ? `: ${detail.replace(/\s+/g, " ").trim().slice(0, 200)}` : ""}`
171
+ );
166
172
  }
167
173
  await sleep(
168
174
  Math.min(intervalMs + OAUTH_POLLING_SAFETY_MARGIN_MS, Math.max(0, deadline - now()))
@@ -2548,6 +2554,7 @@ function loadPreferences() {
2548
2554
  antigravityCliFavoriteModels: config.antigravityCliFavoriteModels,
2549
2555
  antigravityCliFavoritesHintShown: config.antigravityCliFavoritesHintShown,
2550
2556
  appPathOverrides: config.appPathOverrides,
2557
+ launchPresets: config.launchPresets,
2551
2558
  recentLaunchFolders: config.recentLaunchFolders,
2552
2559
  server: config.server
2553
2560
  };
@@ -2577,6 +2584,19 @@ function savePreferences(prefs) {
2577
2584
  config.recentLaunchFolders = prefs.recentLaunchFolders;
2578
2585
  writeConfig(config);
2579
2586
  }
2587
+ var MAX_LAUNCH_PRESETS = 50;
2588
+ function loadLaunchPresets() {
2589
+ const presets = readConfig().launchPresets;
2590
+ return Array.isArray(presets) ? presets : [];
2591
+ }
2592
+ function saveLaunchPresets(presets) {
2593
+ const config = readConfig();
2594
+ const next = presets.slice(0, MAX_LAUNCH_PRESETS);
2595
+ if (next.length === 0) delete config.launchPresets;
2596
+ else config.launchPresets = next;
2597
+ writeConfig(config);
2598
+ return next;
2599
+ }
2580
2600
  function getAppPathOverride(appId) {
2581
2601
  const value = loadPreferences().appPathOverrides?.[appId];
2582
2602
  return typeof value === "string" && value.trim() ? value : void 0;
@@ -2801,6 +2821,14 @@ var PROVIDER_DEFAULTS = {
2801
2821
  "xai-oauth": 131072,
2802
2822
  "openai-oauth": 128e3
2803
2823
  };
2824
+ var SERVER_CONFIGURED_CONTEXT_PROVIDERS = /* @__PURE__ */ new Set(["ollama", "lmstudio"]);
2825
+ var OLLAMA_DEFAULT_CONTEXT_LENGTH = 4096;
2826
+ function serverConfiguredContextWindow(providerId) {
2827
+ if (!SERVER_CONFIGURED_CONTEXT_PROVIDERS.has(providerId)) return void 0;
2828
+ const fromEnv = Number(process.env.OLLAMA_CONTEXT_LENGTH?.trim());
2829
+ if (Number.isFinite(fromEnv) && fromEnv > 0) return fromEnv;
2830
+ return PROVIDER_DEFAULTS[providerId] ?? OLLAMA_DEFAULT_CONTEXT_LENGTH;
2831
+ }
2804
2832
  var parsedCache;
2805
2833
  var cacheIndex;
2806
2834
  var heuristicCache = /* @__PURE__ */ new Map();
@@ -2885,6 +2913,10 @@ function contextWindowFromHeuristics(modelId) {
2885
2913
  return DEFAULT_CONTEXT_WINDOW;
2886
2914
  }
2887
2915
  function lookupContextWindow(modelId, providerId) {
2916
+ if (providerId) {
2917
+ const fromServer = serverConfiguredContextWindow(providerId);
2918
+ if (fromServer) return fromServer;
2919
+ }
2888
2920
  const fromCache = getCacheIndex().get(modelId);
2889
2921
  if (fromCache) return fromCache;
2890
2922
  const fromModelsDev = getModelsDevIndex().get(modelId);
@@ -2904,7 +2936,7 @@ function resolveContextWindow(modelId, explicit, providerId) {
2904
2936
  // src/auth/github.ts
2905
2937
  var CLIENT_ID2 = "Iv1.b507a08c87ecfe98";
2906
2938
  var DEVICE_CODE_URL = "https://github.com/login/device/code";
2907
- var TOKEN_URL = "https://github.com/login/auth/access_token";
2939
+ var TOKEN_URL = "https://github.com/login/oauth/access_token";
2908
2940
  var COPILOT_TOKEN_URL = "https://api.github.com/copilot_internal/v2/token";
2909
2941
  var SCOPE = "copilot";
2910
2942
  var DEVICE_CODE_DEFAULT_INTERVAL_MS = 5e3;
@@ -2989,8 +3021,20 @@ async function pollGithubDeviceCodeToken(device, opts) {
2989
3021
  grant_type: "urn:ietf:params:oauth:grant-type:device_code"
2990
3022
  }).toString()
2991
3023
  });
2992
- const body = await response.json().catch(() => ({}));
3024
+ const raw = await response.text().catch(() => "");
3025
+ let body = {};
3026
+ try {
3027
+ if (raw.trim().startsWith("{")) body = JSON.parse(raw);
3028
+ } catch {
3029
+ }
2993
3030
  const error = body["error"];
3031
+ if (!error && !body["access_token"]) {
3032
+ if (!raw.trim().startsWith("{")) {
3033
+ throw new Error(
3034
+ `GitHub device authorization got a non-JSON response (HTTP ${response.status}) from ${TOKEN_URL}${raw.trim() ? `: ${raw.replace(/\s+/g, " ").trim().slice(0, 200)}` : ""}`
3035
+ );
3036
+ }
3037
+ }
2994
3038
  if (!error && body["access_token"]) {
2995
3039
  const ghuToken = body["access_token"];
2996
3040
  const copilot = await exchangeForCopilotToken(ghuToken);
@@ -3087,7 +3131,14 @@ async function pollXaiDeviceCodeToken(device, opts) {
3087
3131
  }).toString()
3088
3132
  });
3089
3133
  if (response.ok) return response.json();
3090
- const body = await response.json().catch(() => ({}));
3134
+ const raw = await response.text().catch(() => "");
3135
+ let body = {};
3136
+ try {
3137
+ if (raw.trim().startsWith("{")) {
3138
+ body = JSON.parse(raw);
3139
+ }
3140
+ } catch {
3141
+ }
3091
3142
  const remaining = Math.max(0, deadline - now());
3092
3143
  if (body.error === "authorization_pending") {
3093
3144
  await sleep(Math.min(intervalMs + OAUTH_POLLING_SAFETY_MARGIN_MS3, remaining));
@@ -3098,7 +3149,16 @@ async function pollXaiDeviceCodeToken(device, opts) {
3098
3149
  await sleep(Math.min(intervalMs + OAUTH_POLLING_SAFETY_MARGIN_MS3, remaining));
3099
3150
  continue;
3100
3151
  }
3101
- throw new Error(`xAI device authorization failed${body.error ? `: ${body.error}` : ""}`);
3152
+ if (body.error === "expired_token") {
3153
+ throw new Error("xAI device code expired \u2014 run anygate providers auth xai again");
3154
+ }
3155
+ if (body.error) {
3156
+ const detail = body.error_description ? ` \u2014 ${body.error_description}` : "";
3157
+ throw new Error(`xAI device authorization failed: ${body.error}${detail}`);
3158
+ }
3159
+ throw new Error(
3160
+ `xAI device authorization failed (HTTP ${response.status})${raw.trim() ? `: ${raw.replace(/\s+/g, " ").trim().slice(0, 200)}` : ""}`
3161
+ );
3102
3162
  }
3103
3163
  throw new Error("xAI device authorization timed out");
3104
3164
  }
@@ -4993,7 +5053,7 @@ function parseModelList(body, npm, providerId) {
4993
5053
  const freeStatus = classifyFreeStatus({
4994
5054
  model: { cost, isFree: row.isFree }
4995
5055
  });
4996
- const contextWindow = row.context_length ?? row.contextWindow ?? row.context_window ?? resolveContextWindow(id);
5056
+ const contextWindow = row.context_length ?? row.contextWindow ?? row.context_window ?? resolveContextWindow(id, void 0, providerId);
4997
5057
  models.push({
4998
5058
  id,
4999
5059
  name: normalizeGoogleDisplayName(row.name, id),
@@ -5034,7 +5094,7 @@ async function fetchTemplateModels(template, apiKey, baseUrlOverride, extraHeade
5034
5094
  upstreamModelId: sm.id,
5035
5095
  family,
5036
5096
  brand: deriveBrand(family),
5037
- contextWindow: resolveContextWindow(sm.id),
5097
+ contextWindow: resolveContextWindow(sm.id, void 0, template.id),
5038
5098
  modelFormat: modelFormatForNpm(template.npm),
5039
5099
  npm: template.npm
5040
5100
  };
@@ -7194,16 +7254,51 @@ async function generateAnthropicResponse(model, params, modelId, options) {
7194
7254
  }
7195
7255
 
7196
7256
  // src/storage/analytics.ts
7197
- import { appendFileSync, openSync as openSync3, writeSync as writeSync3, closeSync as closeSync3, readFileSync as readFileSync11, existsSync as existsSync8 } from "fs";
7198
- import { join as join8 } from "path";
7257
+ import {
7258
+ appendFileSync,
7259
+ openSync as openSync3,
7260
+ writeSync as writeSync3,
7261
+ closeSync as closeSync3,
7262
+ readFileSync as readFileSync11,
7263
+ existsSync as existsSync8,
7264
+ mkdirSync as mkdirSync8
7265
+ } from "fs";
7266
+ import { join as join8, dirname as dirname5 } from "path";
7267
+
7268
+ // src/services/event-bus.ts
7269
+ var listeners = /* @__PURE__ */ new Set();
7270
+ function subscribeToAppEvents(listener) {
7271
+ listeners.add(listener);
7272
+ return () => {
7273
+ listeners.delete(listener);
7274
+ };
7275
+ }
7276
+ function emitAppEvent(event) {
7277
+ for (const listener of listeners) {
7278
+ try {
7279
+ listener(event);
7280
+ } catch {
7281
+ }
7282
+ }
7283
+ }
7284
+
7285
+ // src/storage/analytics.ts
7199
7286
  var ANALYTICS_FILE = "analytics.jsonl";
7200
7287
  function normalizeModelKey(modelId) {
7201
7288
  return modelId.toLowerCase().replace(/\//g, ":").replace(/\s*\([^)]*\)\s*$/g, "").replace(/\s+/g, " ").trim();
7202
7289
  }
7290
+ function normalizeAppKey(app) {
7291
+ const key = app.trim().toLowerCase().replace(/\s+/g, "-");
7292
+ return key || "unknown";
7293
+ }
7203
7294
  function analyticsPath() {
7204
7295
  return join8(getAppHome(), ANALYTICS_FILE);
7205
7296
  }
7206
7297
  function appendAtomic(path, line) {
7298
+ try {
7299
+ mkdirSync8(dirname5(path), { recursive: true, mode: 448 });
7300
+ } catch {
7301
+ }
7207
7302
  try {
7208
7303
  const fd = openSync3(path, "a", 384);
7209
7304
  try {
@@ -7233,6 +7328,18 @@ function recordUsage(event) {
7233
7328
  if (event.npm) clean.npm = event.npm;
7234
7329
  if (event.providerId) clean.providerId = event.providerId;
7235
7330
  appendAtomic(analyticsPath(), JSON.stringify(clean));
7331
+ try {
7332
+ emitAppEvent({
7333
+ type: "usage",
7334
+ app: clean.app,
7335
+ modelId: clean.modelId,
7336
+ ...clean.providerId ? { providerId: clean.providerId } : {},
7337
+ inputTokens: clean.inputTokens,
7338
+ outputTokens: clean.outputTokens,
7339
+ ts: clean.ts
7340
+ });
7341
+ } catch {
7342
+ }
7236
7343
  }
7237
7344
  function readAnalyticsLog() {
7238
7345
  const path = analyticsPath();
@@ -7293,11 +7400,22 @@ function aggregateAnalytics(range) {
7293
7400
  const modelMap = /* @__PURE__ */ new Map();
7294
7401
  let totalTokens = 0;
7295
7402
  let messages = 0;
7403
+ let totalInputTokens = 0;
7404
+ let totalOutputTokens = 0;
7405
+ const appMap = /* @__PURE__ */ new Map();
7296
7406
  for (const e of events) {
7297
7407
  const day = dayKey(e.ts);
7298
7408
  const tok = e.inputTokens + e.outputTokens;
7299
7409
  totalTokens += tok;
7410
+ totalInputTokens += e.inputTokens;
7411
+ totalOutputTokens += e.outputTokens;
7300
7412
  messages += 1;
7413
+ const appKey = normalizeAppKey(e.app || "unknown");
7414
+ const a = appMap.get(appKey) ?? { inputTokens: 0, outputTokens: 0, messages: 0 };
7415
+ a.inputTokens += e.inputTokens;
7416
+ a.outputTokens += e.outputTokens;
7417
+ a.messages += 1;
7418
+ appMap.set(appKey, a);
7301
7419
  eventsByDay.set(day, (eventsByDay.get(day) ?? 0) + 1);
7302
7420
  tokensByDay.set(day, (tokensByDay.get(day) ?? 0) + tok);
7303
7421
  activeDaySet.add(day);
@@ -7366,14 +7484,14 @@ function aggregateAnalytics(range) {
7366
7484
  }
7367
7485
  const models = [...modelMap.entries()].map(([, m], idx) => {
7368
7486
  const share = totalTokens > 0 ? (m.inputTokens + m.outputTokens) / totalTokens : 0;
7369
- const apps = [...m.apps];
7487
+ const apps2 = [...m.apps];
7370
7488
  return {
7371
7489
  provider: m.provider,
7372
7490
  model: m.model,
7373
7491
  tier: "",
7374
7492
  // source tier isn't tracked in the log; UI shows it from catalog elsewhere
7375
- app: apps[0] ?? m.app,
7376
- apps,
7493
+ app: apps2[0] ?? m.app,
7494
+ apps: apps2,
7377
7495
  inputTokens: m.inputTokens,
7378
7496
  outputTokens: m.outputTokens,
7379
7497
  share,
@@ -7382,19 +7500,31 @@ function aggregateAnalytics(range) {
7382
7500
  });
7383
7501
  models.sort((a, b) => b.share - a.share);
7384
7502
  const favoriteModel = models.length > 0 ? `${models[0].provider}: ${models[0].model}` : "";
7503
+ const apps = [...appMap.entries()].map(([app, a], idx) => ({
7504
+ app,
7505
+ inputTokens: a.inputTokens,
7506
+ outputTokens: a.outputTokens,
7507
+ messages: a.messages,
7508
+ share: totalTokens > 0 ? (a.inputTokens + a.outputTokens) / totalTokens : 0,
7509
+ color: MODEL_PALETTE[idx % MODEL_PALETTE.length]
7510
+ })).sort((x, y) => y.share - x.share);
7385
7511
  return {
7386
7512
  range,
7387
7513
  sessions: activeDaySet.size,
7388
7514
  messages,
7389
7515
  totalTokens,
7516
+ inputTokens: totalInputTokens,
7517
+ outputTokens: totalOutputTokens,
7390
7518
  activeDays: activeDaySet.size,
7391
7519
  currentStreakDays: currentStreak,
7392
7520
  longestStreakDays: longestStreak,
7393
7521
  peakHour,
7522
+ hourly: hourCounts,
7394
7523
  favoriteModel,
7395
7524
  heatmap,
7396
7525
  dailyTokens,
7397
- models
7526
+ models,
7527
+ apps
7398
7528
  };
7399
7529
  }
7400
7530
 
@@ -7461,8 +7591,9 @@ function lookupRoute(byAlias, id) {
7461
7591
  }
7462
7592
  return void 0;
7463
7593
  }
7464
- function startProxyCatalog(routes, defaultAliasId, debug = false) {
7594
+ function startProxyCatalog(routes, defaultAliasId, debug = false, opts) {
7465
7595
  const proxyToken = randomUUID5();
7596
+ const defaultApp = opts?.app;
7466
7597
  silenceSdkWarnings();
7467
7598
  if (routes.length === 0) {
7468
7599
  return Promise.reject(new Error("Proxy catalog requires at least one route"));
@@ -7654,7 +7785,7 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
7654
7785
  modelId: route.realModelId,
7655
7786
  npm: route.npm,
7656
7787
  providerId: route.providerId,
7657
- app: route.app ?? "gateway",
7788
+ app: route.app ?? defaultApp ?? "gateway",
7658
7789
  inputTokens: usage.inputTokens,
7659
7790
  outputTokens: usage.outputTokens
7660
7791
  });
@@ -7672,7 +7803,7 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
7672
7803
  modelId: route.realModelId,
7673
7804
  npm: route.npm,
7674
7805
  providerId: route.providerId,
7675
- app: route.app ?? "gateway",
7806
+ app: route.app ?? defaultApp ?? "gateway",
7676
7807
  inputTokens: u?.inputTokens ?? 0,
7677
7808
  outputTokens: u?.outputTokens ?? 0
7678
7809
  });
@@ -7763,7 +7894,7 @@ data: ${JSON.stringify({ type: "error", error: { type: errorType, message } })}
7763
7894
  ts: (/* @__PURE__ */ new Date()).toISOString(),
7764
7895
  modelId: route.realModelId,
7765
7896
  providerId: route.providerId,
7766
- app: route.app ?? "Antigravity",
7897
+ app: route.app ?? defaultApp ?? "Antigravity",
7767
7898
  inputTokens: usage.inputTokens,
7768
7899
  outputTokens: usage.outputTokens
7769
7900
  });
@@ -8018,7 +8149,7 @@ function cachedModelToLocal(cached, provider) {
8018
8149
  brand: cached.brand ?? deriveBrand(cached.family ?? ""),
8019
8150
  modelFormat: "cloud-code",
8020
8151
  upstreamModelId: cached.upstreamModelId ?? cached.id,
8021
- contextWindow: cached.contextWindow ?? resolveContextWindow(id2),
8152
+ contextWindow: cached.contextWindow ?? resolveContextWindow(id2, void 0, provider.id),
8022
8153
  isFree: isFreeStatus(freeStatus),
8023
8154
  freeStatus,
8024
8155
  reasoning: cached.reasoning,
@@ -8050,7 +8181,7 @@ function cachedModelToLocal(cached, provider) {
8050
8181
  cost: cached.cost,
8051
8182
  isFree: isFreeStatus(freeStatus),
8052
8183
  freeStatus,
8053
- contextWindow: cached.contextWindow ?? resolveContextWindow(id),
8184
+ contextWindow: cached.contextWindow ?? resolveContextWindow(id, void 0, provider.id),
8054
8185
  supportedParameters: cached.supportedParameters,
8055
8186
  reasoning: cached.reasoning ?? modelsDev?.reasoning,
8056
8187
  interleavedReasoningField: cached.interleavedReasoningField ?? modelsDev?.interleaved?.field,
@@ -8062,6 +8193,11 @@ function providerAllowsAnonymousFreeModels(provider) {
8062
8193
  const template = getTemplateById(provider.templateId) ?? getTemplateById(provider.id);
8063
8194
  return template?.anonymousFreeModels === true;
8064
8195
  }
8196
+ function providerAllowsMissingKey(provider) {
8197
+ if (provider.authType === "none") return true;
8198
+ const template = getTemplateById(provider.templateId) ?? getTemplateById(provider.id);
8199
+ return template?.apiKeyOptional === true;
8200
+ }
8065
8201
  function materializeOne(provider, resolveCredential, agent) {
8066
8202
  if (!provider.enabled) return null;
8067
8203
  if (!isValidProviderId(provider.id)) return null;
@@ -8082,7 +8218,7 @@ function materializeOne(provider, resolveCredential, agent) {
8082
8218
  models.push(model);
8083
8219
  }
8084
8220
  if (models.length === 0) return null;
8085
- if (!apiKey.trim() && !anonymousFreeOnly) return null;
8221
+ if (!apiKey.trim() && !anonymousFreeOnly && !providerAllowsMissingKey(provider)) return null;
8086
8222
  return {
8087
8223
  id: provider.id,
8088
8224
  name: provider.name,
@@ -8294,6 +8430,10 @@ function makeRouteResolver(localProviders) {
8294
8430
  return provider && model ? localModelToRoute(provider, model) ?? void 0 : void 0;
8295
8431
  };
8296
8432
  }
8433
+ function buildProviderAllModelRoutes(provider, startingRoute, resolveRoute2, max = MAX_MODEL_CATALOG) {
8434
+ const tail = provider.models.map((model) => resolveRoute2(provider.id, model.id)).filter((route) => route !== void 0).filter((route) => route.aliasId !== startingRoute.aliasId);
8435
+ return dedupeByKey([startingRoute, ...tail], (route) => route.aliasId, max);
8436
+ }
8297
8437
  function buildCatalogRoutes(startingRoute, favorites, resolveRoute2, max = MAX_MODEL_CATALOG) {
8298
8438
  const droppedFavorites = [];
8299
8439
  const tail = favorites.map((fav) => {
@@ -8651,9 +8791,9 @@ async function addCustomEndpointProvider(input) {
8651
8791
 
8652
8792
  // src/registry/storage/builtins.ts
8653
8793
  import { readFileSync as readFileSync12 } from "fs";
8654
- import { join as join9, dirname as dirname5 } from "path";
8794
+ import { join as join9, dirname as dirname6 } from "path";
8655
8795
  import { fileURLToPath } from "url";
8656
- var __dirname = dirname5(fileURLToPath(import.meta.url));
8796
+ var __dirname = dirname6(fileURLToPath(import.meta.url));
8657
8797
  var PROVIDERS_DIR = join9(__dirname, "..", "data", "providers");
8658
8798
  function loadBuiltinProviderSync(id) {
8659
8799
  try {
@@ -9892,12 +10032,22 @@ function oauthDisplayName(registryId, fallbackName) {
9892
10032
  if (registryId === "xai-oauth") return "xAI (SuperGrok)";
9893
10033
  return fallbackName;
9894
10034
  }
10035
+ function resolveOAuthTemplate(providerId) {
10036
+ const stripped = providerId.replace(/-oauth$/, "") || providerId;
10037
+ const strippedTemplate = getTemplateById(stripped);
10038
+ if (strippedTemplate) return { templateId: stripped, template: strippedTemplate };
10039
+ const exact = getTemplateById(providerId);
10040
+ if (exact) return { templateId: providerId, template: exact };
10041
+ const registryId = toOAuthRegistryId(providerId);
10042
+ const viaRegistryId = getTemplateById(registryId);
10043
+ if (viaRegistryId) return { templateId: registryId, template: viaRegistryId };
10044
+ return { templateId: stripped, template: void 0 };
10045
+ }
9895
10046
  async function upsertOAuthProvider(providerId, cred) {
9896
10047
  const registryId = toOAuthRegistryId(providerId);
9897
- const templateId = providerId.replace(/-oauth$/, "") || providerId;
10048
+ const { templateId, template } = resolveOAuthTemplate(providerId);
9898
10049
  const registry = loadRegistry();
9899
10050
  const authRef = oauthAuthRef(registryId);
9900
- const template = getTemplateById(templateId);
9901
10051
  let entry = registry.providers.find((pr) => pr.id === registryId);
9902
10052
  if (!entry) {
9903
10053
  const raw = await fetchRawOpencodeProviders();
@@ -10173,10 +10323,7 @@ function createVertexModelCatalog(models) {
10173
10323
  }
10174
10324
 
10175
10325
  // src/apps/codex/app-launch.ts
10176
- import { execSync as execSync4 } from "child_process";
10177
10326
  import { existsSync as existsSync14 } from "fs";
10178
- import { homedir as homedir8 } from "os";
10179
- import { join as join14 } from "path";
10180
10327
 
10181
10328
  // src/apps/shared/app-launcher.ts
10182
10329
  import { execSync as execSync3, spawn as spawn4 } from "child_process";
@@ -10442,6 +10589,24 @@ var CodexAppLauncher = class extends AppLauncher {
10442
10589
  return null;
10443
10590
  }
10444
10591
  }
10592
+ /**
10593
+ * Find a Microsoft Store (MSIX) install via Get-StartApps. Store installs have
10594
+ * no .exe at any fixed path, so the static winInstallBases search cannot see
10595
+ * them. Returns a version-independent shell:AppsFolder moniker, which
10596
+ * AppLauncher.openApp() launches via `cmd /c start`.
10597
+ */
10598
+ findWinAppExtra() {
10599
+ for (const name of this.winAppNames) {
10600
+ try {
10601
+ const appId = this.runPowerShell(
10602
+ `(Get-StartApps | Where-Object { $_.Name -eq '${name}' -or $_.Name -like '${name}*' } | Select-Object -First 1 -ExpandProperty AppID)`
10603
+ );
10604
+ if (appId) return `shell:AppsFolder\\${appId}`;
10605
+ } catch {
10606
+ }
10607
+ }
10608
+ return null;
10609
+ }
10445
10610
  winQuitGracefulCommand() {
10446
10611
  const nameFilter = this.winAppNames.map((name) => `'${name}'`).join(",");
10447
10612
  return `Get-Process ${nameFilter} -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowHandle -ne 0 } | ForEach-Object { [void]$_.CloseMainWindow() }`;
@@ -10462,38 +10627,7 @@ function codexAppSupported() {
10462
10627
  }
10463
10628
  }
10464
10629
  function findCodexApp() {
10465
- if (process.platform === "darwin") {
10466
- for (const bundleName of launcher.darwinAppBundleNames) {
10467
- const paths = [`/Applications/${bundleName}`, join14(homedir8(), "Applications", bundleName)];
10468
- for (const path of paths) {
10469
- if (existsSync14(path)) return path;
10470
- }
10471
- }
10472
- try {
10473
- const out = execSync4(`mdfind "kMDItemCFBundleIdentifier == '${CODEX_BUNDLE_ID}'"`, {
10474
- encoding: "utf8",
10475
- stdio: ["pipe", "pipe", "pipe"]
10476
- }).trim();
10477
- const first = out.split("\n").map((l) => l.trim()).find(Boolean);
10478
- if (first && existsSync14(first)) return first;
10479
- } catch {
10480
- }
10481
- }
10482
- if (process.platform === "win32") {
10483
- const localAppData = process.env.LOCALAPPDATA ?? join14(homedir8(), "AppData", "Local");
10484
- for (const base of launcher.winInstallBases) {
10485
- for (const exe of launcher.winExeNames) {
10486
- const paths = [join14(localAppData, "Programs", base, exe), join14(localAppData, base, exe)];
10487
- for (const path of paths) {
10488
- try {
10489
- if (existsSync14(path)) return path;
10490
- } catch {
10491
- }
10492
- }
10493
- }
10494
- }
10495
- }
10496
- return null;
10630
+ return launcher.findApp();
10497
10631
  }
10498
10632
  function isCodexAppRunning() {
10499
10633
  return launcher.isRunning();
@@ -10987,7 +11121,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
10987
11121
  modelId: responseModelId,
10988
11122
  npm: model.npm,
10989
11123
  providerId: model.providerId,
10990
- app: "gateway",
11124
+ app: options.app ?? "gateway",
10991
11125
  inputTokens: usage.inputTokens,
10992
11126
  outputTokens: usage.outputTokens
10993
11127
  });
@@ -11003,7 +11137,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
11003
11137
  modelId: responseModelId,
11004
11138
  npm: model.npm,
11005
11139
  providerId: model.providerId,
11006
- app: "gateway",
11140
+ app: options.app ?? "gateway",
11007
11141
  inputTokens: anthropicResponse._usage?.inputTokens ?? 0,
11008
11142
  outputTokens: anthropicResponse._usage?.outputTokens ?? 0
11009
11143
  });
@@ -11089,7 +11223,7 @@ async function handleOpenAIChatCompletions(req, res, options, modelCache, plog)
11089
11223
  modelId: responseModelId,
11090
11224
  npm: model.npm ?? (model.modelFormat === "anthropic" ? "@ai-sdk/anthropic" : void 0),
11091
11225
  providerId: model.providerId,
11092
- app: "gateway",
11226
+ app: options.app ?? "gateway",
11093
11227
  inputTokens: usage.inputTokens,
11094
11228
  outputTokens: usage.outputTokens
11095
11229
  });
@@ -11105,7 +11239,7 @@ async function handleOpenAIChatCompletions(req, res, options, modelCache, plog)
11105
11239
  modelId: responseModelId,
11106
11240
  npm: model.npm ?? (model.modelFormat === "anthropic" ? "@ai-sdk/anthropic" : void 0),
11107
11241
  providerId: model.providerId,
11108
- app: "gateway",
11242
+ app: options.app ?? "gateway",
11109
11243
  inputTokens: usage.inputTokens,
11110
11244
  outputTokens: usage.outputTokens
11111
11245
  });
@@ -11239,10 +11373,7 @@ function summarizeServerProviders(models) {
11239
11373
  }
11240
11374
 
11241
11375
  // src/apps/claude/desktop-launch.ts
11242
- import { execSync as execSync5 } from "child_process";
11243
11376
  import { existsSync as existsSync15 } from "fs";
11244
- import { homedir as homedir9 } from "os";
11245
- import { join as join15 } from "path";
11246
11377
  var CLAUDE_BUNDLE_ID = "com.anthropic.claudefordesktop";
11247
11378
  var ClaudeAppLauncher = class extends AppLauncher {
11248
11379
  appName = "Claude Desktop";
@@ -11284,40 +11415,7 @@ function claudeAppSupported() {
11284
11415
  }
11285
11416
  }
11286
11417
  function findClaudeApp() {
11287
- const override = getAppPathOverride("claude-app");
11288
- if (override && existsSync15(override)) return override;
11289
- if (process.platform === "darwin") {
11290
- for (const bundleName of launcher2.darwinAppBundleNames) {
11291
- const paths = [`/Applications/${bundleName}`, join15(homedir9(), "Applications", bundleName)];
11292
- for (const path of paths) {
11293
- if (existsSync15(path)) return path;
11294
- }
11295
- }
11296
- try {
11297
- const out = execSync5(`mdfind "kMDItemCFBundleIdentifier == '${CLAUDE_BUNDLE_ID}'"`, {
11298
- encoding: "utf8",
11299
- stdio: ["pipe", "pipe", "pipe"]
11300
- }).trim();
11301
- const first = out.split("\n").map((l) => l.trim()).find(Boolean);
11302
- if (first && existsSync15(first)) return first;
11303
- } catch {
11304
- }
11305
- }
11306
- if (process.platform === "win32") {
11307
- const localAppData = process.env.LOCALAPPDATA ?? join15(homedir9(), "AppData", "Local");
11308
- for (const base of launcher2.winInstallBases) {
11309
- for (const exe of launcher2.winExeNames) {
11310
- const paths = [join15(localAppData, "Programs", base, exe), join15(localAppData, base, exe)];
11311
- for (const path of paths) {
11312
- try {
11313
- if (existsSync15(path)) return path;
11314
- } catch {
11315
- }
11316
- }
11317
- }
11318
- }
11319
- }
11320
- return null;
11418
+ return launcher2.findApp();
11321
11419
  }
11322
11420
  function isClaudeAppRunning() {
11323
11421
  return launcher2.isRunning();
@@ -12065,6 +12163,8 @@ export {
12065
12163
  resolveInputTypes,
12066
12164
  loadPreferences,
12067
12165
  savePreferences,
12166
+ loadLaunchPresets,
12167
+ saveLaunchPresets,
12068
12168
  getAppPathOverride,
12069
12169
  setAppPathOverride,
12070
12170
  recordLaunchFolder,
@@ -12142,6 +12242,8 @@ export {
12142
12242
  encodeToolUseId,
12143
12243
  serializeToolResultContent,
12144
12244
  translateRequest,
12245
+ subscribeToAppEvents,
12246
+ emitAppEvent,
12145
12247
  recordUsage,
12146
12248
  aggregateAnalytics,
12147
12249
  aliasModelId,
@@ -12156,6 +12258,7 @@ export {
12156
12258
  resolveProvidersForDisplay,
12157
12259
  localProvidersToServerModels,
12158
12260
  makeRouteResolver,
12261
+ buildProviderAllModelRoutes,
12159
12262
  buildCatalogRoutes,
12160
12263
  findBinaryOnPath,
12161
12264
  findClaudeBinary,
@@ -12209,4 +12312,4 @@ export {
12209
12312
  runServerCommand,
12210
12313
  favoriteProviderDisplayName
12211
12314
  };
12212
- //# sourceMappingURL=chunk-CRK6YGKY.js.map
12315
+ //# sourceMappingURL=chunk-BY4AKT2X.js.map