claudish 6.1.0 → 6.1.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.
package/dist/index.js CHANGED
@@ -28505,14 +28505,7 @@ async function runModels(sessionPath, opts = {}) {
28505
28505
  const outputPath = join(sessionPath, `response-${anonId}.md`);
28506
28506
  const errorLogPath = join(sessionPath, "errors", `${anonId}.log`);
28507
28507
  const workDir = join(sessionPath, "work", anonId);
28508
- const args = [
28509
- "--model",
28510
- entry.model,
28511
- "-y",
28512
- "--stdin",
28513
- "--quiet",
28514
- ...opts.claudeFlags ?? []
28515
- ];
28508
+ const args = ["--model", entry.model, "-y", "--stdin", "--quiet", ...opts.claudeFlags ?? []];
28516
28509
  updateModelStatus(anonId, {
28517
28510
  state: "RUNNING",
28518
28511
  startedAt: new Date().toISOString()
@@ -29243,31 +29236,52 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
29243
29236
  signal: AbortSignal.timeout(5000)
29244
29237
  });
29245
29238
  if (response.ok) {
29246
- return { content: [{ type: "text", text: `Error report sent successfully.
29239
+ return {
29240
+ content: [
29241
+ {
29242
+ type: "text",
29243
+ text: `Error report sent successfully.
29247
29244
 
29248
29245
  **Sanitized data sent:**
29249
29246
  \`\`\`json
29250
29247
  ${reportSummary}
29251
- \`\`\`${autoSendHint}` }] };
29248
+ \`\`\`${autoSendHint}`
29249
+ }
29250
+ ]
29251
+ };
29252
29252
  } else {
29253
- return { content: [{ type: "text", text: `Error report endpoint returned ${response.status}. Report was NOT sent.
29253
+ return {
29254
+ content: [
29255
+ {
29256
+ type: "text",
29257
+ text: `Error report endpoint returned ${response.status}. Report was NOT sent.
29254
29258
 
29255
29259
  **Data that would have been sent (all sanitized):**
29256
29260
  \`\`\`json
29257
29261
  ${reportSummary}
29258
29262
  \`\`\`
29259
29263
 
29260
- You can manually report this at https://github.com/anthropics/claudish/issues${autoSendHint}` }] };
29264
+ You can manually report this at https://github.com/anthropics/claudish/issues${autoSendHint}`
29265
+ }
29266
+ ]
29267
+ };
29261
29268
  }
29262
29269
  } catch (err) {
29263
- return { content: [{ type: "text", text: `Could not reach error reporting endpoint (${err instanceof Error ? err.message : "network error"}).
29270
+ return {
29271
+ content: [
29272
+ {
29273
+ type: "text",
29274
+ text: `Could not reach error reporting endpoint (${err instanceof Error ? err.message : "network error"}).
29264
29275
 
29265
29276
  **Sanitized error data (for manual reporting):**
29266
29277
  \`\`\`json
29267
29278
  ${reportSummary}
29268
29279
  \`\`\`
29269
29280
 
29270
- Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}` }] };
29281
+ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
29282
+ }
29283
+ ]
29284
+ };
29271
29285
  }
29272
29286
  });
29273
29287
  }
@@ -30641,6 +30655,36 @@ function fuzzyScore2(text, query) {
30641
30655
  }
30642
30656
 
30643
30657
  // src/profile-config.ts
30658
+ var exports_profile_config = {};
30659
+ __export(exports_profile_config, {
30660
+ setProfile: () => setProfile,
30661
+ setEndpoint: () => setEndpoint,
30662
+ setDefaultProfile: () => setDefaultProfile,
30663
+ setApiKey: () => setApiKey,
30664
+ saveLocalConfig: () => saveLocalConfig,
30665
+ saveConfig: () => saveConfig,
30666
+ removeEndpoint: () => removeEndpoint,
30667
+ removeApiKey: () => removeApiKey,
30668
+ localConfigExists: () => localConfigExists,
30669
+ loadLocalConfig: () => loadLocalConfig,
30670
+ loadConfig: () => loadConfig,
30671
+ listProfiles: () => listProfiles,
30672
+ listAllProfiles: () => listAllProfiles,
30673
+ isProjectDirectory: () => isProjectDirectory,
30674
+ getProfileNames: () => getProfileNames,
30675
+ getProfile: () => getProfile,
30676
+ getModelMapping: () => getModelMapping,
30677
+ getLocalConfigPath: () => getLocalConfigPath,
30678
+ getEndpoint: () => getEndpoint,
30679
+ getDefaultProfile: () => getDefaultProfile,
30680
+ getConfigPathForScope: () => getConfigPathForScope,
30681
+ getConfigPath: () => getConfigPath,
30682
+ getApiKey: () => getApiKey,
30683
+ deleteProfile: () => deleteProfile,
30684
+ createProfile: () => createProfile,
30685
+ configExistsForScope: () => configExistsForScope,
30686
+ configExists: () => configExists
30687
+ });
30644
30688
  import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
30645
30689
  import { homedir as homedir6 } from "os";
30646
30690
  import { join as join7 } from "path";
@@ -30877,6 +30921,13 @@ function createProfile(name, models, description, scope = "global") {
30877
30921
  setProfile(profile, scope);
30878
30922
  return profile;
30879
30923
  }
30924
+ function listProfiles() {
30925
+ const config3 = loadConfig();
30926
+ return Object.values(config3.profiles).map((profile) => ({
30927
+ ...profile,
30928
+ isDefault: profile.name === config3.defaultProfile
30929
+ }));
30930
+ }
30880
30931
  function listAllProfiles() {
30881
30932
  const globalConfig2 = loadConfig();
30882
30933
  const localConfig = loadLocalConfig();
@@ -30901,6 +30952,10 @@ function listAllProfiles() {
30901
30952
  }
30902
30953
  return result;
30903
30954
  }
30955
+ function getApiKey(envVar) {
30956
+ const config3 = loadConfig();
30957
+ return config3.apiKeys?.[envVar];
30958
+ }
30904
30959
  function setApiKey(envVar, value) {
30905
30960
  const config3 = loadConfig();
30906
30961
  if (!config3.apiKeys)
@@ -30915,6 +30970,10 @@ function removeApiKey(envVar) {
30915
30970
  saveConfig(config3);
30916
30971
  }
30917
30972
  }
30973
+ function getEndpoint(name) {
30974
+ const config3 = loadConfig();
30975
+ return config3.endpoints?.[name];
30976
+ }
30918
30977
  function setEndpoint(name, value) {
30919
30978
  const config3 = loadConfig();
30920
30979
  if (!config3.endpoints)
@@ -30949,6 +31008,9 @@ var init_profile_config = __esm(() => {
30949
31008
  });
30950
31009
 
30951
31010
  // src/providers/provider-definitions.ts
31011
+ import { existsSync as existsSync8 } from "fs";
31012
+ import { join as join8 } from "path";
31013
+ import { homedir as homedir7 } from "os";
30952
31014
  function ensureProviderByNameCache() {
30953
31015
  if (!_providerByNameCache) {
30954
31016
  _providerByNameCache = new Map;
@@ -31071,6 +31133,29 @@ function getApiKeyEnvVars(providerName) {
31071
31133
  aliases: def.apiKeyAliases
31072
31134
  };
31073
31135
  }
31136
+ function isProviderAvailable(def) {
31137
+ if (def.isLocal)
31138
+ return true;
31139
+ if (def.publicKeyFallback)
31140
+ return true;
31141
+ if (!def.apiKeyEnvVar)
31142
+ return true;
31143
+ if (process.env[def.apiKeyEnvVar])
31144
+ return true;
31145
+ if (def.apiKeyAliases) {
31146
+ for (const alias of def.apiKeyAliases) {
31147
+ if (process.env[alias])
31148
+ return true;
31149
+ }
31150
+ }
31151
+ if (def.oauthFallback) {
31152
+ try {
31153
+ if (existsSync8(join8(homedir7(), ".claudish", def.oauthFallback)))
31154
+ return true;
31155
+ } catch {}
31156
+ }
31157
+ return false;
31158
+ }
31074
31159
  var BUILTIN_PROVIDERS, _shortcutsCache = null, _legacyPrefixCache = null, _nativeModelPatternsCache = null, _providerByNameCache = null, _localProvidersCache = null;
31075
31160
  var init_provider_definitions = __esm(() => {
31076
31161
  BUILTIN_PROVIDERS = [
@@ -31091,7 +31176,8 @@ var init_provider_definitions = __esm(() => {
31091
31176
  { prefix: "gemini/", stripPrefix: true }
31092
31177
  ],
31093
31178
  nativeModelPatterns: [{ pattern: /^google\//i }, { pattern: /^gemini-/i }],
31094
- isDirectApi: true
31179
+ isDirectApi: true,
31180
+ description: "Direct Gemini API (g@, google@)"
31095
31181
  },
31096
31182
  {
31097
31183
  name: "gemini-codeassist",
@@ -31105,7 +31191,8 @@ var init_provider_definitions = __esm(() => {
31105
31191
  shortcuts: ["go"],
31106
31192
  shortestPrefix: "go",
31107
31193
  legacyPrefixes: [{ prefix: "go/", stripPrefix: true }],
31108
- isDirectApi: true
31194
+ isDirectApi: true,
31195
+ description: "Gemini Code Assist OAuth (go@)"
31109
31196
  },
31110
31197
  {
31111
31198
  name: "openai",
@@ -31128,7 +31215,8 @@ var init_provider_definitions = __esm(() => {
31128
31215
  { pattern: /^o3(-|$)/i },
31129
31216
  { pattern: /^chatgpt-/i }
31130
31217
  ],
31131
- isDirectApi: true
31218
+ isDirectApi: true,
31219
+ description: "Direct OpenAI API (oai@)"
31132
31220
  },
31133
31221
  {
31134
31222
  name: "openrouter",
@@ -31147,6 +31235,26 @@ var init_provider_definitions = __esm(() => {
31147
31235
  "HTTP-Referer": "https://claudish.com",
31148
31236
  "X-Title": "Claudish - OpenRouter Proxy"
31149
31237
  },
31238
+ isDirectApi: true,
31239
+ description: "580+ models, default backend (or@)"
31240
+ },
31241
+ {
31242
+ name: "xai",
31243
+ displayName: "xAI",
31244
+ transport: "openai",
31245
+ tokenStrategy: "delta-aware",
31246
+ baseUrl: "https://api.x.ai",
31247
+ apiPath: "/v1/chat/completions",
31248
+ apiKeyEnvVar: "XAI_API_KEY",
31249
+ apiKeyDescription: "xAI API Key",
31250
+ apiKeyUrl: "https://console.x.ai/",
31251
+ shortcuts: ["xai", "grok"],
31252
+ shortestPrefix: "xai",
31253
+ legacyPrefixes: [{ prefix: "xai/", stripPrefix: true }],
31254
+ nativeModelPatterns: [
31255
+ { pattern: /^x-ai\//i },
31256
+ { pattern: /^grok-/i }
31257
+ ],
31150
31258
  isDirectApi: true
31151
31259
  },
31152
31260
  {
@@ -31171,7 +31279,8 @@ var init_provider_definitions = __esm(() => {
31171
31279
  { pattern: /^minimax-/i },
31172
31280
  { pattern: /^abab-/i }
31173
31281
  ],
31174
- isDirectApi: true
31282
+ isDirectApi: true,
31283
+ description: "MiniMax API (mm@, mmax@)"
31175
31284
  },
31176
31285
  {
31177
31286
  name: "minimax-coding",
@@ -31187,7 +31296,8 @@ var init_provider_definitions = __esm(() => {
31187
31296
  shortcuts: ["mmc"],
31188
31297
  shortestPrefix: "mmc",
31189
31298
  legacyPrefixes: [{ prefix: "mmc/", stripPrefix: true }],
31190
- isDirectApi: true
31299
+ isDirectApi: true,
31300
+ description: "MiniMax Coding Plan (mmc@)"
31191
31301
  },
31192
31302
  {
31193
31303
  name: "kimi-coding",
@@ -31203,7 +31313,8 @@ var init_provider_definitions = __esm(() => {
31203
31313
  shortestPrefix: "kc",
31204
31314
  legacyPrefixes: [{ prefix: "kc/", stripPrefix: true }],
31205
31315
  nativeModelPatterns: [{ pattern: /^kimi-for-coding$/i }],
31206
- isDirectApi: true
31316
+ isDirectApi: true,
31317
+ description: "Kimi Coding Plan (kc@)"
31207
31318
  },
31208
31319
  {
31209
31320
  name: "kimi",
@@ -31227,7 +31338,8 @@ var init_provider_definitions = __esm(() => {
31227
31338
  { pattern: /^moonshot-/i },
31228
31339
  { pattern: /^kimi-/i }
31229
31340
  ],
31230
- isDirectApi: true
31341
+ isDirectApi: true,
31342
+ description: "Kimi API (kimi@, moon@)"
31231
31343
  },
31232
31344
  {
31233
31345
  name: "glm",
@@ -31252,7 +31364,8 @@ var init_provider_definitions = __esm(() => {
31252
31364
  { pattern: /^glm-/i },
31253
31365
  { pattern: /^chatglm-/i }
31254
31366
  ],
31255
- isDirectApi: true
31367
+ isDirectApi: true,
31368
+ description: "GLM API (glm@, zhipu@)"
31256
31369
  },
31257
31370
  {
31258
31371
  name: "glm-coding",
@@ -31268,7 +31381,8 @@ var init_provider_definitions = __esm(() => {
31268
31381
  shortcuts: ["gc"],
31269
31382
  shortestPrefix: "gc",
31270
31383
  legacyPrefixes: [{ prefix: "gc/", stripPrefix: true }],
31271
- isDirectApi: true
31384
+ isDirectApi: true,
31385
+ description: "GLM Coding Plan (gc@)"
31272
31386
  },
31273
31387
  {
31274
31388
  name: "zai",
@@ -31284,7 +31398,8 @@ var init_provider_definitions = __esm(() => {
31284
31398
  shortestPrefix: "zai",
31285
31399
  legacyPrefixes: [{ prefix: "zai/", stripPrefix: true }],
31286
31400
  nativeModelPatterns: [{ pattern: /^z-ai\//i }, { pattern: /^zai\//i }],
31287
- isDirectApi: true
31401
+ isDirectApi: true,
31402
+ description: "Z.AI API (zai@)"
31288
31403
  },
31289
31404
  {
31290
31405
  name: "ollamacloud",
@@ -31306,7 +31421,8 @@ var init_provider_definitions = __esm(() => {
31306
31421
  { pattern: /^llama-/i },
31307
31422
  { pattern: /^llama3/i }
31308
31423
  ],
31309
- isDirectApi: true
31424
+ isDirectApi: true,
31425
+ description: "Cloud Ollama (oc@, llama@)"
31310
31426
  },
31311
31427
  {
31312
31428
  name: "opencode-zen",
@@ -31323,7 +31439,8 @@ var init_provider_definitions = __esm(() => {
31323
31439
  shortcuts: ["zen"],
31324
31440
  shortestPrefix: "zen",
31325
31441
  legacyPrefixes: [{ prefix: "zen/", stripPrefix: true }],
31326
- isDirectApi: true
31442
+ isDirectApi: true,
31443
+ description: "OpenCode Zen (zen@) - free models"
31327
31444
  },
31328
31445
  {
31329
31446
  name: "opencode-zen-go",
@@ -31342,7 +31459,8 @@ var init_provider_definitions = __esm(() => {
31342
31459
  { prefix: "zengo/", stripPrefix: true },
31343
31460
  { prefix: "zgo/", stripPrefix: true }
31344
31461
  ],
31345
- isDirectApi: true
31462
+ isDirectApi: true,
31463
+ description: "OpenCode Zen Go plan (zengo@)"
31346
31464
  },
31347
31465
  {
31348
31466
  name: "vertex",
@@ -31360,7 +31478,8 @@ var init_provider_definitions = __esm(() => {
31360
31478
  { prefix: "v/", stripPrefix: true },
31361
31479
  { prefix: "vertex/", stripPrefix: true }
31362
31480
  ],
31363
- isDirectApi: true
31481
+ isDirectApi: true,
31482
+ description: "Vertex AI Express (v@, vertex@)"
31364
31483
  },
31365
31484
  {
31366
31485
  name: "litellm",
@@ -31378,7 +31497,8 @@ var init_provider_definitions = __esm(() => {
31378
31497
  { prefix: "litellm/", stripPrefix: true },
31379
31498
  { prefix: "ll/", stripPrefix: true }
31380
31499
  ],
31381
- isDirectApi: true
31500
+ isDirectApi: true,
31501
+ description: "LiteLLM proxy (ll@, litellm@)"
31382
31502
  },
31383
31503
  {
31384
31504
  name: "poe",
@@ -31393,7 +31513,8 @@ var init_provider_definitions = __esm(() => {
31393
31513
  shortestPrefix: "poe",
31394
31514
  legacyPrefixes: [],
31395
31515
  nativeModelPatterns: [{ pattern: /^poe:/i }],
31396
- isDirectApi: true
31516
+ isDirectApi: true,
31517
+ description: "Poe API (poe@)"
31397
31518
  },
31398
31519
  {
31399
31520
  name: "ollama",
@@ -31410,7 +31531,8 @@ var init_provider_definitions = __esm(() => {
31410
31531
  { prefix: "ollama/", stripPrefix: true },
31411
31532
  { prefix: "ollama:", stripPrefix: true }
31412
31533
  ],
31413
- isLocal: true
31534
+ isLocal: true,
31535
+ description: "Local Ollama (ollama@)"
31414
31536
  },
31415
31537
  {
31416
31538
  name: "lmstudio",
@@ -31429,7 +31551,8 @@ var init_provider_definitions = __esm(() => {
31429
31551
  { prefix: "mlstudio/", stripPrefix: true },
31430
31552
  { prefix: "mlstudio:", stripPrefix: true }
31431
31553
  ],
31432
- isLocal: true
31554
+ isLocal: true,
31555
+ description: "Local LM Studio (lms@)"
31433
31556
  },
31434
31557
  {
31435
31558
  name: "vllm",
@@ -31446,7 +31569,8 @@ var init_provider_definitions = __esm(() => {
31446
31569
  { prefix: "vllm/", stripPrefix: true },
31447
31570
  { prefix: "vllm:", stripPrefix: true }
31448
31571
  ],
31449
- isLocal: true
31572
+ isLocal: true,
31573
+ description: "Local vLLM (vllm@)"
31450
31574
  },
31451
31575
  {
31452
31576
  name: "mlx",
@@ -31463,7 +31587,8 @@ var init_provider_definitions = __esm(() => {
31463
31587
  { prefix: "mlx/", stripPrefix: true },
31464
31588
  { prefix: "mlx:", stripPrefix: true }
31465
31589
  ],
31466
- isLocal: true
31590
+ isLocal: true,
31591
+ description: "Local MLX (mlx@)"
31467
31592
  },
31468
31593
  {
31469
31594
  name: "qwen",
@@ -31477,7 +31602,8 @@ var init_provider_definitions = __esm(() => {
31477
31602
  shortcuts: [],
31478
31603
  shortestPrefix: "qwen",
31479
31604
  legacyPrefixes: [],
31480
- nativeModelPatterns: [{ pattern: /^qwen/i }]
31605
+ nativeModelPatterns: [{ pattern: /^qwen/i }],
31606
+ description: "Qwen (auto-routed via OpenRouter)"
31481
31607
  },
31482
31608
  {
31483
31609
  name: "native-anthropic",
@@ -31491,7 +31617,8 @@ var init_provider_definitions = __esm(() => {
31491
31617
  shortcuts: [],
31492
31618
  shortestPrefix: "",
31493
31619
  legacyPrefixes: [],
31494
- nativeModelPatterns: [{ pattern: /^anthropic\//i }, { pattern: /^claude-/i }]
31620
+ nativeModelPatterns: [{ pattern: /^anthropic\//i }, { pattern: /^claude-/i }],
31621
+ description: "Native Claude Code auth"
31495
31622
  }
31496
31623
  ];
31497
31624
  });
@@ -31606,12 +31733,12 @@ var init_model_parser = __esm(() => {
31606
31733
  });
31607
31734
 
31608
31735
  // src/auth/oauth-registry.ts
31609
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
31610
- import { join as join8 } from "path";
31611
- import { homedir as homedir7 } from "os";
31736
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
31737
+ import { join as join9 } from "path";
31738
+ import { homedir as homedir8 } from "os";
31612
31739
  function hasValidOAuthCredentials(descriptor) {
31613
- const credPath = join8(homedir7(), ".claudish", descriptor.credentialFile);
31614
- if (!existsSync8(credPath))
31740
+ const credPath = join9(homedir8(), ".claudish", descriptor.credentialFile);
31741
+ if (!existsSync9(credPath))
31615
31742
  return false;
31616
31743
  if (descriptor.validationMode === "file-exists") {
31617
31744
  return true;
@@ -31697,9 +31824,9 @@ var init_static_fallback = __esm(() => {
31697
31824
  });
31698
31825
 
31699
31826
  // src/providers/catalog-resolvers/openrouter.ts
31700
- import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs";
31701
- import { join as join9 } from "path";
31702
- import { homedir as homedir8 } from "os";
31827
+ import { readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
31828
+ import { join as join10 } from "path";
31829
+ import { homedir as homedir9 } from "os";
31703
31830
 
31704
31831
  class OpenRouterCatalogResolver {
31705
31832
  provider = "openrouter";
@@ -31744,8 +31871,8 @@ class OpenRouterCatalogResolver {
31744
31871
  _getModels() {
31745
31872
  if (_memCache)
31746
31873
  return _memCache;
31747
- const diskPath = join9(homedir8(), ".claudish", "all-models.json");
31748
- if (existsSync9(diskPath)) {
31874
+ const diskPath = join10(homedir9(), ".claudish", "all-models.json");
31875
+ if (existsSync10(diskPath)) {
31749
31876
  try {
31750
31877
  const data = JSON.parse(readFileSync8(diskPath, "utf-8"));
31751
31878
  if (Array.isArray(data.models) && data.models.length > 0) {
@@ -31764,16 +31891,16 @@ var init_openrouter = __esm(() => {
31764
31891
  });
31765
31892
 
31766
31893
  // src/providers/catalog-resolvers/litellm.ts
31767
- import { readFileSync as readFileSync9, existsSync as existsSync10 } from "fs";
31768
- import { join as join10 } from "path";
31769
- import { homedir as homedir9 } from "os";
31894
+ import { readFileSync as readFileSync9, existsSync as existsSync11 } from "fs";
31895
+ import { join as join11 } from "path";
31896
+ import { homedir as homedir10 } from "os";
31770
31897
  import { createHash as createHash3 } from "crypto";
31771
31898
  function getCachePath() {
31772
31899
  const baseUrl = process.env.LITELLM_BASE_URL;
31773
31900
  if (!baseUrl)
31774
31901
  return null;
31775
31902
  const hash2 = createHash3("sha256").update(baseUrl).digest("hex").substring(0, 16);
31776
- return join10(homedir9(), ".claudish", `litellm-models-${hash2}.json`);
31903
+ return join11(homedir10(), ".claudish", `litellm-models-${hash2}.json`);
31777
31904
  }
31778
31905
 
31779
31906
  class LiteLLMCatalogResolver {
@@ -31801,7 +31928,7 @@ class LiteLLMCatalogResolver {
31801
31928
  }
31802
31929
  async warmCache() {
31803
31930
  const path = getCachePath();
31804
- if (!path || !existsSync10(path))
31931
+ if (!path || !existsSync11(path))
31805
31932
  return;
31806
31933
  try {
31807
31934
  const data = JSON.parse(readFileSync9(path, "utf-8"));
@@ -31817,7 +31944,7 @@ class LiteLLMCatalogResolver {
31817
31944
  if (_memCache2)
31818
31945
  return _memCache2;
31819
31946
  const path = getCachePath();
31820
- if (!path || !existsSync10(path))
31947
+ if (!path || !existsSync11(path))
31821
31948
  return null;
31822
31949
  try {
31823
31950
  const data = JSON.parse(readFileSync9(path, "utf-8"));
@@ -31879,14 +32006,14 @@ var init_model_catalog_resolver = __esm(() => {
31879
32006
  });
31880
32007
 
31881
32008
  // src/providers/auto-route.ts
31882
- import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
31883
- import { join as join11 } from "path";
31884
- import { homedir as homedir10 } from "os";
32009
+ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
32010
+ import { join as join12 } from "path";
32011
+ import { homedir as homedir11 } from "os";
31885
32012
  import { createHash as createHash4 } from "crypto";
31886
32013
  function readLiteLLMCacheSync(baseUrl) {
31887
32014
  const hash2 = createHash4("sha256").update(baseUrl).digest("hex").substring(0, 16);
31888
- const cachePath = join11(homedir10(), ".claudish", `litellm-models-${hash2}.json`);
31889
- if (!existsSync11(cachePath))
32015
+ const cachePath = join12(homedir11(), ".claudish", `litellm-models-${hash2}.json`);
32016
+ if (!existsSync12(cachePath))
31890
32017
  return null;
31891
32018
  try {
31892
32019
  const data = JSON.parse(readFileSync10(cachePath, "utf-8"));
@@ -31999,9 +32126,27 @@ function autoRoute(modelName, nativeProvider) {
31999
32126
  }
32000
32127
  return null;
32001
32128
  }
32002
- function readZenModelCacheSync() {
32003
- const cachePath = join11(homedir10(), ".claudish", "zen-models.json");
32004
- if (!existsSync11(cachePath))
32129
+ async function warmZenModelCache() {
32130
+ const apiKey = process.env.OPENCODE_API_KEY || "public";
32131
+ const baseUrl = process.env.OPENCODE_BASE_URL || "https://opencode.ai/zen";
32132
+ const resp = await fetch(`${baseUrl}/v1/models`, {
32133
+ headers: { Authorization: `Bearer ${apiKey}` },
32134
+ signal: AbortSignal.timeout(5000)
32135
+ });
32136
+ if (!resp.ok)
32137
+ return;
32138
+ const data = await resp.json();
32139
+ const models = (data.data ?? []).map((m) => ({ id: m.id }));
32140
+ if (models.length === 0)
32141
+ return;
32142
+ const cacheDir = join12(homedir11(), ".claudish");
32143
+ const { mkdirSync: mkdirSync6, writeFileSync: writeSync3 } = await import("fs");
32144
+ mkdirSync6(cacheDir, { recursive: true });
32145
+ writeSync3(join12(cacheDir, "zen-models.json"), JSON.stringify({ models, fetchedAt: new Date().toISOString() }));
32146
+ }
32147
+ function readZenGoModelCacheSync() {
32148
+ const cachePath = join12(homedir11(), ".claudish", "zen-go-models.json");
32149
+ if (!existsSync12(cachePath))
32005
32150
  return null;
32006
32151
  try {
32007
32152
  const data = JSON.parse(readFileSync10(cachePath, "utf-8"));
@@ -32012,16 +32157,16 @@ function readZenModelCacheSync() {
32012
32157
  return null;
32013
32158
  }
32014
32159
  }
32015
- function isZenCompatibleModel(modelName) {
32016
- const zenModels = readZenModelCacheSync();
32017
- if (!zenModels)
32160
+ function isZenGoCompatibleModel(modelName) {
32161
+ const zenGoModels = readZenGoModelCacheSync();
32162
+ if (!zenGoModels)
32018
32163
  return false;
32019
- return zenModels.has(modelName);
32164
+ return zenGoModels.has(modelName);
32020
32165
  }
32021
- async function warmZenModelCache() {
32166
+ async function warmZenGoModelCache() {
32022
32167
  const apiKey = process.env.OPENCODE_API_KEY || "public";
32023
32168
  const baseUrl = process.env.OPENCODE_BASE_URL || "https://opencode.ai/zen";
32024
- const resp = await fetch(`${baseUrl}/v1/models`, {
32169
+ const resp = await fetch(`${baseUrl}/go/v1/models`, {
32025
32170
  headers: { Authorization: `Bearer ${apiKey}` },
32026
32171
  signal: AbortSignal.timeout(5000)
32027
32172
  });
@@ -32031,10 +32176,10 @@ async function warmZenModelCache() {
32031
32176
  const models = (data.data ?? []).map((m) => ({ id: m.id }));
32032
32177
  if (models.length === 0)
32033
32178
  return;
32034
- const cacheDir = join11(homedir10(), ".claudish");
32179
+ const cacheDir = join12(homedir11(), ".claudish");
32035
32180
  const { mkdirSync: mkdirSync6, writeFileSync: writeSync3 } = await import("fs");
32036
32181
  mkdirSync6(cacheDir, { recursive: true });
32037
- writeSync3(join11(cacheDir, "zen-models.json"), JSON.stringify({ models, fetchedAt: new Date().toISOString() }));
32182
+ writeSync3(join12(cacheDir, "zen-go-models.json"), JSON.stringify({ models, fetchedAt: new Date().toISOString() }));
32038
32183
  }
32039
32184
  function hasProviderCredentials(provider) {
32040
32185
  const keyInfo = getApiKeyEnvVars(provider);
@@ -32054,7 +32199,7 @@ function getFallbackChain(modelName, nativeProvider) {
32054
32199
  displayName: "LiteLLM"
32055
32200
  });
32056
32201
  }
32057
- if (process.env.OPENCODE_API_KEY && isZenCompatibleModel(modelName)) {
32202
+ if (process.env.OPENCODE_API_KEY && isZenGoCompatibleModel(modelName)) {
32058
32203
  routes.push({
32059
32204
  provider: "opencode-zen-go",
32060
32205
  modelSpec: `zengo@${modelName}`,
@@ -32263,9 +32408,9 @@ var init_routing_rules = __esm(() => {
32263
32408
  });
32264
32409
 
32265
32410
  // src/providers/api-key-provenance.ts
32266
- import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
32267
- import { join as join12, resolve as resolve2 } from "path";
32268
- import { homedir as homedir11 } from "os";
32411
+ import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
32412
+ import { join as join13, resolve as resolve2 } from "path";
32413
+ import { homedir as homedir12 } from "os";
32269
32414
  function maskKey(key) {
32270
32415
  if (!key)
32271
32416
  return null;
@@ -32350,7 +32495,7 @@ function formatProvenanceProbe(p, indent = " ") {
32350
32495
  function readDotenvKey(envVars) {
32351
32496
  try {
32352
32497
  const dotenvPath = resolve2(".env");
32353
- if (!existsSync12(dotenvPath))
32498
+ if (!existsSync13(dotenvPath))
32354
32499
  return null;
32355
32500
  const parsed = import_dotenv2.parse(readFileSync11(dotenvPath, "utf-8"));
32356
32501
  for (const v of envVars) {
@@ -32364,8 +32509,8 @@ function readDotenvKey(envVars) {
32364
32509
  }
32365
32510
  function readConfigKey(envVar) {
32366
32511
  try {
32367
- const configPath = join12(homedir11(), ".claudish", "config.json");
32368
- if (!existsSync12(configPath))
32512
+ const configPath = join13(homedir12(), ".claudish", "config.json");
32513
+ if (!existsSync13(configPath))
32369
32514
  return null;
32370
32515
  const cfg = JSON.parse(readFileSync11(configPath, "utf-8"));
32371
32516
  return cfg.apiKeys?.[envVar] || null;
@@ -32579,9 +32724,9 @@ __export(exports_provider_resolver, {
32579
32724
  getMissingKeyResolutions: () => getMissingKeyResolutions,
32580
32725
  getMissingKeyError: () => getMissingKeyError
32581
32726
  });
32582
- import { existsSync as existsSync13 } from "fs";
32583
- import { join as join13 } from "path";
32584
- import { homedir as homedir12 } from "os";
32727
+ import { existsSync as existsSync14 } from "fs";
32728
+ import { join as join14 } from "path";
32729
+ import { homedir as homedir13 } from "os";
32585
32730
  function getApiKeyInfoForProvider(providerName) {
32586
32731
  const lookupName = providerName === "gemini" ? "google" : providerName;
32587
32732
  const info = getApiKeyInfo(lookupName);
@@ -32616,8 +32761,8 @@ function isApiKeyAvailable(info) {
32616
32761
  }
32617
32762
  if (info.oauthFallback) {
32618
32763
  try {
32619
- const credPath = join13(homedir12(), ".claudish", info.oauthFallback);
32620
- if (existsSync13(credPath)) {
32764
+ const credPath = join14(homedir13(), ".claudish", info.oauthFallback);
32765
+ if (existsSync14(credPath)) {
32621
32766
  return true;
32622
32767
  }
32623
32768
  } catch {}
@@ -33079,12 +33224,14 @@ function processAssistantMessage(msg, messages, simpleFormat = false) {
33079
33224
  const toolCalls = [];
33080
33225
  const seen = new Set;
33081
33226
  let reasoningContent = "";
33227
+ let hasThinking = false;
33082
33228
  for (const block of msg.content) {
33083
33229
  if (block.type === "text") {
33084
33230
  strings.push(block.text);
33085
33231
  } else if (block.type === "thinking") {
33086
- if (!simpleFormat && block.thinking) {
33087
- reasoningContent += block.thinking;
33232
+ if (!simpleFormat) {
33233
+ hasThinking = true;
33234
+ reasoningContent += block.thinking || "";
33088
33235
  }
33089
33236
  } else if (block.type === "tool_use") {
33090
33237
  if (seen.has(block.id))
@@ -33114,7 +33261,7 @@ function processAssistantMessage(msg, messages, simpleFormat = false) {
33114
33261
  m.content = null;
33115
33262
  if (toolCalls.length)
33116
33263
  m.tool_calls = toolCalls;
33117
- if (reasoningContent)
33264
+ if (hasThinking)
33118
33265
  m.reasoning_content = reasoningContent;
33119
33266
  if (m.content !== undefined || m.tool_calls)
33120
33267
  messages.push(m);
@@ -33200,13 +33347,34 @@ function transformOpenAIToClaude(claudeRequestInput) {
33200
33347
  var init_transform = () => {};
33201
33348
 
33202
33349
  // src/handlers/shared/format/openai-tools.ts
33350
+ function sanitizeSchemaForOpenAI(schema) {
33351
+ if (!schema || typeof schema !== "object") {
33352
+ return removeUriFormat(schema);
33353
+ }
33354
+ let root = { ...schema };
33355
+ const combinerKey = ["oneOf", "anyOf", "allOf"].find((k) => Array.isArray(root[k]) && root[k].length > 0);
33356
+ if (combinerKey) {
33357
+ const branches = root[combinerKey];
33358
+ const objectBranch = branches.find((b) => b && typeof b === "object" && b.type === "object");
33359
+ if (objectBranch) {
33360
+ const { [combinerKey]: _dropped, ...rest } = root;
33361
+ root = { ...rest, ...objectBranch };
33362
+ } else {
33363
+ root = { type: "object", properties: {}, additionalProperties: true };
33364
+ }
33365
+ }
33366
+ const { enum: _enum3, not: _not, ...withoutForbidden } = root;
33367
+ root = withoutForbidden;
33368
+ root.type = "object";
33369
+ return removeUriFormat(root);
33370
+ }
33203
33371
  function convertToolsToOpenAI(req, summarize = false) {
33204
33372
  return req.tools?.map((tool) => ({
33205
33373
  type: "function",
33206
33374
  function: {
33207
33375
  name: tool.name,
33208
33376
  description: summarize ? summarizeToolDescription(tool.name, tool.description) : tool.description,
33209
- parameters: summarize ? summarizeToolParameters(tool.input_schema) : removeUriFormat(tool.input_schema)
33377
+ parameters: summarize ? summarizeToolParameters(tool.input_schema) : sanitizeSchemaForOpenAI(tool.input_schema)
33210
33378
  }
33211
33379
  })) || [];
33212
33380
  }
@@ -33223,7 +33391,7 @@ function summarizeToolDescription(name, description) {
33223
33391
  function summarizeToolParameters(schema) {
33224
33392
  if (!schema)
33225
33393
  return schema;
33226
- const summarized = removeUriFormat({ ...schema });
33394
+ const summarized = sanitizeSchemaForOpenAI({ ...schema });
33227
33395
  if (summarized.properties) {
33228
33396
  for (const [key, prop] of Object.entries(summarized.properties)) {
33229
33397
  const p = prop;
@@ -35290,21 +35458,21 @@ __export(exports_cli, {
35290
35458
  import {
35291
35459
  readFileSync as readFileSync12,
35292
35460
  writeFileSync as writeFileSync6,
35293
- existsSync as existsSync14,
35461
+ existsSync as existsSync15,
35294
35462
  mkdirSync as mkdirSync6,
35295
35463
  copyFileSync,
35296
35464
  readdirSync as readdirSync4,
35297
35465
  unlinkSync as unlinkSync4
35298
35466
  } from "fs";
35299
35467
  import { fileURLToPath as fileURLToPath3 } from "url";
35300
- import { dirname as dirname3, join as join14 } from "path";
35301
- import { homedir as homedir13 } from "os";
35468
+ import { dirname as dirname3, join as join15 } from "path";
35469
+ import { homedir as homedir14 } from "os";
35302
35470
  function getVersion() {
35303
35471
  return VERSION;
35304
35472
  }
35305
35473
  function clearAllModelCaches() {
35306
- const cacheDir = join14(homedir13(), ".claudish");
35307
- if (!existsSync14(cacheDir))
35474
+ const cacheDir = join15(homedir14(), ".claudish");
35475
+ if (!existsSync15(cacheDir))
35308
35476
  return;
35309
35477
  const cachePatterns = ["all-models.json", "pricing-cache.json"];
35310
35478
  let cleared = 0;
@@ -35312,7 +35480,7 @@ function clearAllModelCaches() {
35312
35480
  const files = readdirSync4(cacheDir);
35313
35481
  for (const file2 of files) {
35314
35482
  if (cachePatterns.includes(file2) || file2.startsWith("litellm-models-")) {
35315
- unlinkSync4(join14(cacheDir, file2));
35483
+ unlinkSync4(join15(cacheDir, file2));
35316
35484
  cleared++;
35317
35485
  }
35318
35486
  }
@@ -35326,7 +35494,7 @@ function clearAllModelCaches() {
35326
35494
  async function parseArgs(args) {
35327
35495
  const config3 = {
35328
35496
  model: undefined,
35329
- autoApprove: false,
35497
+ autoApprove: true,
35330
35498
  dangerous: false,
35331
35499
  interactive: false,
35332
35500
  debug: false,
@@ -35616,7 +35784,7 @@ async function fetchOllamaModels() {
35616
35784
  }
35617
35785
  async function searchAndPrintModels(query, forceUpdate) {
35618
35786
  let models = [];
35619
- if (!forceUpdate && existsSync14(ALL_MODELS_JSON_PATH)) {
35787
+ if (!forceUpdate && existsSync15(ALL_MODELS_JSON_PATH)) {
35620
35788
  try {
35621
35789
  const cacheData = JSON.parse(readFileSync12(ALL_MODELS_JSON_PATH, "utf-8"));
35622
35790
  const lastUpdated = new Date(cacheData.lastUpdated);
@@ -35786,7 +35954,7 @@ Found ${results.length} matching models:
35786
35954
  async function printAllModels(jsonOutput, forceUpdate) {
35787
35955
  let models = [];
35788
35956
  const [ollamaModels, zenModels] = await Promise.all([fetchOllamaModels(), fetchZenModels()]);
35789
- if (!forceUpdate && existsSync14(ALL_MODELS_JSON_PATH)) {
35957
+ if (!forceUpdate && existsSync15(ALL_MODELS_JSON_PATH)) {
35790
35958
  try {
35791
35959
  const cacheData = JSON.parse(readFileSync12(ALL_MODELS_JSON_PATH, "utf-8"));
35792
35960
  const lastUpdated = new Date(cacheData.lastUpdated);
@@ -35989,8 +36157,8 @@ async function printAllModels(jsonOutput, forceUpdate) {
35989
36157
  console.log("Top models: claudish --top-models");
35990
36158
  }
35991
36159
  function isCacheStale() {
35992
- const cachePath = existsSync14(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
35993
- if (!existsSync14(cachePath)) {
36160
+ const cachePath = existsSync15(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36161
+ if (!existsSync15(cachePath)) {
35994
36162
  return true;
35995
36163
  }
35996
36164
  try {
@@ -36073,8 +36241,8 @@ async function updateModelsFromOpenRouter() {
36073
36241
  providers.add(provider);
36074
36242
  }
36075
36243
  let version2 = "1.2.0";
36076
- const existingPath = existsSync14(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36077
- if (existsSync14(existingPath)) {
36244
+ const existingPath = existsSync15(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36245
+ if (existsSync15(existingPath)) {
36078
36246
  try {
36079
36247
  const existing = JSON.parse(readFileSync12(existingPath, "utf-8"));
36080
36248
  version2 = existing.version || version2;
@@ -36105,7 +36273,7 @@ async function checkAndUpdateModelsCache(forceUpdate = false) {
36105
36273
  await updateModelsFromOpenRouter();
36106
36274
  } else {
36107
36275
  try {
36108
- const cachePath = existsSync14(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36276
+ const cachePath = existsSync15(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36109
36277
  const data = JSON.parse(readFileSync12(cachePath, "utf-8"));
36110
36278
  console.error(`\u2713 Using cached models (last updated: ${data.lastUpdated})`);
36111
36279
  } catch {}
@@ -36125,7 +36293,8 @@ async function probeModelRouting(models, jsonOutput) {
36125
36293
  const BG_DIM = "\x1B[48;5;236m";
36126
36294
  console.error(`${DIM}Warming provider caches...${RESET}`);
36127
36295
  await Promise.allSettled([
36128
- warmZenModelCache()
36296
+ warmZenModelCache(),
36297
+ warmZenGoModelCache()
36129
36298
  ]);
36130
36299
  const routingRules = loadRoutingRules();
36131
36300
  const results = [];
@@ -36697,7 +36866,7 @@ MORE INFO:
36697
36866
  }
36698
36867
  function printAIAgentGuide() {
36699
36868
  try {
36700
- const guidePath = join14(__dirname4, "../AI_AGENT_GUIDE.md");
36869
+ const guidePath = join15(__dirname4, "../AI_AGENT_GUIDE.md");
36701
36870
  const guideContent = readFileSync12(guidePath, "utf-8");
36702
36871
  console.log(guideContent);
36703
36872
  } catch (error46) {
@@ -36714,19 +36883,19 @@ async function initializeClaudishSkill() {
36714
36883
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
36715
36884
  `);
36716
36885
  const cwd = process.cwd();
36717
- const claudeDir = join14(cwd, ".claude");
36718
- const skillsDir = join14(claudeDir, "skills");
36719
- const claudishSkillDir = join14(skillsDir, "claudish-usage");
36720
- const skillFile = join14(claudishSkillDir, "SKILL.md");
36721
- if (existsSync14(skillFile)) {
36886
+ const claudeDir = join15(cwd, ".claude");
36887
+ const skillsDir = join15(claudeDir, "skills");
36888
+ const claudishSkillDir = join15(skillsDir, "claudish-usage");
36889
+ const skillFile = join15(claudishSkillDir, "SKILL.md");
36890
+ if (existsSync15(skillFile)) {
36722
36891
  console.log("\u2705 Claudish skill already installed at:");
36723
36892
  console.log(` ${skillFile}
36724
36893
  `);
36725
36894
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
36726
36895
  return;
36727
36896
  }
36728
- const sourceSkillPath = join14(__dirname4, "../skills/claudish-usage/SKILL.md");
36729
- if (!existsSync14(sourceSkillPath)) {
36897
+ const sourceSkillPath = join15(__dirname4, "../skills/claudish-usage/SKILL.md");
36898
+ if (!existsSync15(sourceSkillPath)) {
36730
36899
  console.error("\u274C Error: Claudish skill file not found in installation.");
36731
36900
  console.error(` Expected at: ${sourceSkillPath}`);
36732
36901
  console.error(`
@@ -36735,15 +36904,15 @@ async function initializeClaudishSkill() {
36735
36904
  process.exit(1);
36736
36905
  }
36737
36906
  try {
36738
- if (!existsSync14(claudeDir)) {
36907
+ if (!existsSync15(claudeDir)) {
36739
36908
  mkdirSync6(claudeDir, { recursive: true });
36740
36909
  console.log("\uD83D\uDCC1 Created .claude/ directory");
36741
36910
  }
36742
- if (!existsSync14(skillsDir)) {
36911
+ if (!existsSync15(skillsDir)) {
36743
36912
  mkdirSync6(skillsDir, { recursive: true });
36744
36913
  console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
36745
36914
  }
36746
- if (!existsSync14(claudishSkillDir)) {
36915
+ if (!existsSync15(claudishSkillDir)) {
36747
36916
  mkdirSync6(claudishSkillDir, { recursive: true });
36748
36917
  console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
36749
36918
  }
@@ -36786,8 +36955,8 @@ function printAvailableModels() {
36786
36955
  let lastUpdated = "unknown";
36787
36956
  let models = [];
36788
36957
  try {
36789
- const cachePath = existsSync14(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36790
- if (existsSync14(cachePath)) {
36958
+ const cachePath = existsSync15(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36959
+ if (existsSync15(cachePath)) {
36791
36960
  const data = JSON.parse(readFileSync12(cachePath, "utf-8"));
36792
36961
  lastUpdated = data.lastUpdated || "unknown";
36793
36962
  models = data.models || [];
@@ -36837,7 +37006,7 @@ Force update: claudish --list-models --force-update
36837
37006
  `);
36838
37007
  }
36839
37008
  function printAvailableModelsJSON() {
36840
- const jsonPath = existsSync14(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
37009
+ const jsonPath = existsSync15(CACHED_MODELS_PATH) ? CACHED_MODELS_PATH : BUNDLED_MODELS_PATH;
36841
37010
  try {
36842
37011
  const jsonContent = readFileSync12(jsonPath, "utf-8");
36843
37012
  const data = JSON.parse(jsonContent);
@@ -36924,7 +37093,7 @@ async function fetchGLMCodingModels() {
36924
37093
  return [];
36925
37094
  }
36926
37095
  }
36927
- var __filename4, __dirname4, VERSION = "6.1.0", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
37096
+ var __filename4, __dirname4, VERSION = "6.1.1", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
36928
37097
  var init_cli = __esm(() => {
36929
37098
  init_config();
36930
37099
  init_model_loader();
@@ -36937,13 +37106,13 @@ var init_cli = __esm(() => {
36937
37106
  __filename4 = fileURLToPath3(import.meta.url);
36938
37107
  __dirname4 = dirname3(__filename4);
36939
37108
  try {
36940
- const packageJson = JSON.parse(readFileSync12(join14(__dirname4, "../package.json"), "utf-8"));
37109
+ const packageJson = JSON.parse(readFileSync12(join15(__dirname4, "../package.json"), "utf-8"));
36941
37110
  VERSION = packageJson.version;
36942
37111
  } catch {}
36943
- CLAUDISH_CACHE_DIR2 = join14(homedir13(), ".claudish");
36944
- BUNDLED_MODELS_PATH = join14(__dirname4, "../recommended-models.json");
36945
- CACHED_MODELS_PATH = join14(CLAUDISH_CACHE_DIR2, "recommended-models.json");
36946
- ALL_MODELS_JSON_PATH = join14(CLAUDISH_CACHE_DIR2, "all-models.json");
37112
+ CLAUDISH_CACHE_DIR2 = join15(homedir14(), ".claudish");
37113
+ BUNDLED_MODELS_PATH = join15(__dirname4, "../recommended-models.json");
37114
+ CACHED_MODELS_PATH = join15(CLAUDISH_CACHE_DIR2, "recommended-models.json");
37115
+ ALL_MODELS_JSON_PATH = join15(CLAUDISH_CACHE_DIR2, "all-models.json");
36947
37116
  });
36948
37117
 
36949
37118
  // src/update-checker.ts
@@ -36955,9 +37124,9 @@ __export(exports_update_checker, {
36955
37124
  checkForUpdates: () => checkForUpdates
36956
37125
  });
36957
37126
  import { execSync } from "child_process";
36958
- import { existsSync as existsSync15, mkdirSync as mkdirSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync7 } from "fs";
36959
- import { homedir as homedir14, platform as platform2, tmpdir } from "os";
36960
- import { join as join15 } from "path";
37127
+ import { existsSync as existsSync16, mkdirSync as mkdirSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync7 } from "fs";
37128
+ import { homedir as homedir15, platform as platform2, tmpdir } from "os";
37129
+ import { join as join16 } from "path";
36961
37130
  import { createInterface } from "readline";
36962
37131
  function getUpdateCommand() {
36963
37132
  const scriptPath = process.argv[1] || "";
@@ -36969,24 +37138,24 @@ function getUpdateCommand() {
36969
37138
  function getCacheFilePath() {
36970
37139
  let cacheDir;
36971
37140
  if (isWindows) {
36972
- const localAppData = process.env.LOCALAPPDATA || join15(homedir14(), "AppData", "Local");
36973
- cacheDir = join15(localAppData, "claudish");
37141
+ const localAppData = process.env.LOCALAPPDATA || join16(homedir15(), "AppData", "Local");
37142
+ cacheDir = join16(localAppData, "claudish");
36974
37143
  } else {
36975
- cacheDir = join15(homedir14(), ".cache", "claudish");
37144
+ cacheDir = join16(homedir15(), ".cache", "claudish");
36976
37145
  }
36977
37146
  try {
36978
- if (!existsSync15(cacheDir)) {
37147
+ if (!existsSync16(cacheDir)) {
36979
37148
  mkdirSync7(cacheDir, { recursive: true });
36980
37149
  }
36981
- return join15(cacheDir, "update-check.json");
37150
+ return join16(cacheDir, "update-check.json");
36982
37151
  } catch {
36983
- return join15(tmpdir(), "claudish-update-check.json");
37152
+ return join16(tmpdir(), "claudish-update-check.json");
36984
37153
  }
36985
37154
  }
36986
37155
  function readCache() {
36987
37156
  try {
36988
37157
  const cachePath = getCacheFilePath();
36989
- if (!existsSync15(cachePath)) {
37158
+ if (!existsSync16(cachePath)) {
36990
37159
  return null;
36991
37160
  }
36992
37161
  const data = JSON.parse(readFileSync13(cachePath, "utf-8"));
@@ -37012,7 +37181,7 @@ function isCacheValid(cache) {
37012
37181
  function clearCache() {
37013
37182
  try {
37014
37183
  const cachePath = getCacheFilePath();
37015
- if (existsSync15(cachePath)) {
37184
+ if (existsSync16(cachePath)) {
37016
37185
  unlinkSync5(cachePath);
37017
37186
  }
37018
37187
  } catch {}
@@ -39493,12 +39662,12 @@ __export(exports_model_selector, {
39493
39662
  promptForApiKey: () => promptForApiKey,
39494
39663
  confirmAction: () => confirmAction
39495
39664
  });
39496
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, existsSync as existsSync16, mkdirSync as mkdirSync8 } from "fs";
39497
- import { join as join16, dirname as dirname4 } from "path";
39498
- import { homedir as homedir15 } from "os";
39665
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, existsSync as existsSync17, mkdirSync as mkdirSync8 } from "fs";
39666
+ import { join as join17, dirname as dirname4 } from "path";
39667
+ import { homedir as homedir16 } from "os";
39499
39668
  import { fileURLToPath as fileURLToPath4 } from "url";
39500
39669
  function loadRecommendedModels2() {
39501
- if (existsSync16(RECOMMENDED_MODELS_JSON_PATH)) {
39670
+ if (existsSync17(RECOMMENDED_MODELS_JSON_PATH)) {
39502
39671
  try {
39503
39672
  const content = readFileSync14(RECOMMENDED_MODELS_JSON_PATH, "utf-8");
39504
39673
  const data = JSON.parse(content);
@@ -39513,7 +39682,7 @@ function loadRecommendedModels2() {
39513
39682
  return [];
39514
39683
  }
39515
39684
  async function fetchAllModels(forceUpdate = false) {
39516
- if (!forceUpdate && existsSync16(ALL_MODELS_JSON_PATH2)) {
39685
+ if (!forceUpdate && existsSync17(ALL_MODELS_JSON_PATH2)) {
39517
39686
  try {
39518
39687
  const cacheData = JSON.parse(readFileSync14(ALL_MODELS_JSON_PATH2, "utf-8"));
39519
39688
  const lastUpdated = new Date(cacheData.lastUpdated);
@@ -40017,7 +40186,7 @@ async function fetchOllamaCloudModels() {
40017
40186
  }
40018
40187
  }
40019
40188
  function shouldRefreshForFreeModels() {
40020
- if (!existsSync16(ALL_MODELS_JSON_PATH2)) {
40189
+ if (!existsSync17(ALL_MODELS_JSON_PATH2)) {
40021
40190
  return true;
40022
40191
  }
40023
40192
  try {
@@ -40063,45 +40232,61 @@ async function getFreeModels() {
40063
40232
  async function getAllModelsForSearch(forceUpdate = false) {
40064
40233
  const litellmBaseUrl = process.env.LITELLM_BASE_URL;
40065
40234
  const litellmApiKey = process.env.LITELLM_API_KEY;
40066
- const fetchEntries = [
40235
+ const allEntries = [
40067
40236
  {
40068
40237
  name: "OpenRouter",
40069
- promise: fetchAllModels(forceUpdate).then((models) => models.map(toModelInfo))
40238
+ promise: () => fetchAllModels(forceUpdate).then((models) => models.map(toModelInfo))
40070
40239
  },
40071
- { name: "xAI", promise: fetchXAIModels() },
40072
- { name: "Gemini", promise: fetchGeminiModels() },
40073
- { name: "OpenAI", promise: fetchOpenAIModels() },
40074
- { name: "GLM", promise: fetchGLMDirectModels() },
40075
- { name: "GLM Coding", promise: fetchGLMCodingModels2() },
40076
- { name: "OllamaCloud", promise: fetchOllamaCloudModels() },
40077
- { name: "Zen", promise: fetchZenFreeModels() },
40078
- { name: "Zen Go", promise: fetchZenGoModels() }
40240
+ { name: "xAI", provider: "xai", promise: () => fetchXAIModels() },
40241
+ { name: "Gemini", provider: "google", promise: () => fetchGeminiModels() },
40242
+ { name: "OpenAI", provider: "openai", promise: () => fetchOpenAIModels() },
40243
+ { name: "GLM", provider: "glm", promise: () => fetchGLMDirectModels() },
40244
+ { name: "GLM Coding", provider: "glm-coding", promise: () => fetchGLMCodingModels2() },
40245
+ { name: "OllamaCloud", provider: "ollamacloud", promise: () => fetchOllamaCloudModels() },
40246
+ { name: "Zen", provider: "opencode-zen", promise: () => fetchZenFreeModels() },
40247
+ { name: "Zen Go", provider: "opencode-zen-go", promise: () => fetchZenGoModels() },
40248
+ { name: "MiniMax", provider: "minimax", promise: () => Promise.resolve(getKnownModels("minimax")) },
40249
+ { name: "MiniMax Coding", provider: "minimax-coding", promise: () => Promise.resolve(getKnownModels("minimax-coding")) },
40250
+ { name: "Kimi", provider: "kimi", promise: () => Promise.resolve(getKnownModels("kimi")) },
40251
+ { name: "Kimi Coding", provider: "kimi-coding", promise: () => Promise.resolve(getKnownModels("kimi-coding")) },
40252
+ { name: "Z.AI", provider: "zai", promise: () => Promise.resolve(getKnownModels("zai")) }
40079
40253
  ];
40080
40254
  if (litellmBaseUrl && litellmApiKey) {
40081
- fetchEntries.push({
40255
+ allEntries.push({
40082
40256
  name: "LiteLLM",
40083
- promise: fetchLiteLLMModels(litellmBaseUrl, litellmApiKey, forceUpdate)
40257
+ provider: "litellm",
40258
+ promise: () => fetchLiteLLMModels(litellmBaseUrl, litellmApiKey, forceUpdate)
40084
40259
  });
40085
40260
  }
40261
+ const fetchEntries = allEntries.filter((e) => {
40262
+ if (!e.provider)
40263
+ return true;
40264
+ const def = getProviderByName(e.provider);
40265
+ return def ? isProviderAvailable(def) : true;
40266
+ }).map((e) => ({ name: e.name, promise: e.promise() }));
40086
40267
  const settled = await Promise.allSettled(fetchEntries.map((e) => e.promise));
40087
40268
  const fetchResults = {};
40088
40269
  for (let i = 0;i < settled.length; i++) {
40089
40270
  const result = settled[i];
40090
40271
  fetchResults[fetchEntries[i].name] = result.status === "fulfilled" ? result.value : [];
40091
40272
  }
40092
- const directApiModels = [
40093
- ...fetchResults["xAI"],
40094
- ...fetchResults["Gemini"],
40095
- ...fetchResults["OpenAI"],
40096
- ...fetchResults["GLM"],
40097
- ...fetchResults["GLM Coding"]
40098
- ];
40273
+ const r = (name) => fetchResults[name] || [];
40099
40274
  const allModels = [
40100
- ...fetchResults["Zen"],
40101
- ...fetchResults["OllamaCloud"],
40102
- ...directApiModels,
40103
- ...fetchResults["LiteLLM"] || [],
40104
- ...fetchResults["OpenRouter"]
40275
+ ...r("Zen"),
40276
+ ...r("Zen Go"),
40277
+ ...r("OllamaCloud"),
40278
+ ...r("xAI"),
40279
+ ...r("Gemini"),
40280
+ ...r("OpenAI"),
40281
+ ...r("GLM"),
40282
+ ...r("GLM Coding"),
40283
+ ...r("MiniMax"),
40284
+ ...r("MiniMax Coding"),
40285
+ ...r("Kimi"),
40286
+ ...r("Kimi Coding"),
40287
+ ...r("Z.AI"),
40288
+ ...r("LiteLLM"),
40289
+ ...r("OpenRouter")
40105
40290
  ];
40106
40291
  return allModels;
40107
40292
  }
@@ -40123,8 +40308,11 @@ function formatModelChoice(model, showSource = false) {
40123
40308
  OpenAI: "OAI",
40124
40309
  GLM: "GLM",
40125
40310
  "GLM Coding": "GC",
40311
+ MiniMax: "MM",
40126
40312
  "MiniMax Coding": "MMC",
40313
+ Kimi: "Kimi",
40127
40314
  "Kimi Coding": "KC",
40315
+ "Z.AI": "ZAI",
40128
40316
  OllamaCloud: "OC",
40129
40317
  LiteLLM: "LL"
40130
40318
  };
@@ -40283,7 +40471,12 @@ async function selectModel(options = {}) {
40283
40471
  return selected;
40284
40472
  }
40285
40473
  function getProviderChoices() {
40286
- return ALL_PROVIDER_CHOICES.filter((choice) => !choice.envVar || process.env[choice.envVar]);
40474
+ return ALL_PROVIDER_CHOICES.filter((choice) => {
40475
+ if (!choice.provider)
40476
+ return true;
40477
+ const def = getProviderByName(choice.provider);
40478
+ return def ? isProviderAvailable(def) : true;
40479
+ });
40287
40480
  }
40288
40481
  function getKnownModels(provider) {
40289
40482
  const known = {
@@ -40416,6 +40609,19 @@ function getKnownModels(provider) {
40416
40609
  }
40417
40610
  ]
40418
40611
  };
40612
+ const sourceMap = {
40613
+ minimax: "MiniMax",
40614
+ "minimax-coding": "MiniMax Coding",
40615
+ kimi: "Kimi",
40616
+ "kimi-coding": "Kimi Coding",
40617
+ zai: "Z.AI",
40618
+ glm: "GLM",
40619
+ "glm-coding": "GLM Coding",
40620
+ ollamacloud: "OllamaCloud",
40621
+ google: "Gemini",
40622
+ openai: "OpenAI",
40623
+ xai: "xAI"
40624
+ };
40419
40625
  const providerDisplay = provider.charAt(0).toUpperCase() + provider.slice(1);
40420
40626
  return (known[provider] || []).map((m) => ({
40421
40627
  id: m.id,
@@ -40423,7 +40629,8 @@ function getKnownModels(provider) {
40423
40629
  description: m.description || `${providerDisplay} model`,
40424
40630
  provider: providerDisplay,
40425
40631
  context: m.context,
40426
- supportsTools: true
40632
+ supportsTools: true,
40633
+ source: sourceMap[provider]
40427
40634
  }));
40428
40635
  }
40429
40636
  function filterModelsByProvider(allModels, provider) {
@@ -40620,11 +40827,12 @@ var __filename5, __dirname5, CLAUDISH_CACHE_DIR3, ALL_MODELS_JSON_PATH2, RECOMME
40620
40827
  var init_model_selector = __esm(() => {
40621
40828
  init_dist8();
40622
40829
  init_model_loader();
40830
+ init_provider_definitions();
40623
40831
  __filename5 = fileURLToPath4(import.meta.url);
40624
40832
  __dirname5 = dirname4(__filename5);
40625
- CLAUDISH_CACHE_DIR3 = join16(homedir15(), ".claudish");
40626
- ALL_MODELS_JSON_PATH2 = join16(CLAUDISH_CACHE_DIR3, "all-models.json");
40627
- RECOMMENDED_MODELS_JSON_PATH = join16(__dirname5, "../recommended-models.json");
40833
+ CLAUDISH_CACHE_DIR3 = join17(homedir16(), ".claudish");
40834
+ ALL_MODELS_JSON_PATH2 = join17(CLAUDISH_CACHE_DIR3, "all-models.json");
40835
+ RECOMMENDED_MODELS_JSON_PATH = join17(__dirname5, "../recommended-models.json");
40628
40836
  PROVIDER_FILTER_ALIASES = {
40629
40837
  zen: "Zen",
40630
40838
  openrouter: "OpenRouter",
@@ -40638,10 +40846,16 @@ var init_model_selector = __esm(() => {
40638
40846
  glm: "GLM",
40639
40847
  "glm-coding": "GLM Coding",
40640
40848
  gc: "GLM Coding",
40849
+ minimax: "MiniMax",
40850
+ mm: "MiniMax",
40641
40851
  mmc: "MiniMax Coding",
40642
40852
  "minimax-coding": "MiniMax Coding",
40853
+ kimi: "Kimi",
40854
+ moon: "Kimi",
40855
+ moonshot: "Kimi",
40643
40856
  kc: "Kimi Coding",
40644
40857
  "kimi-coding": "Kimi Coding",
40858
+ zai: "Z.AI",
40645
40859
  ollamacloud: "OllamaCloud",
40646
40860
  oc: "OllamaCloud",
40647
40861
  litellm: "LiteLLM",
@@ -40653,66 +40867,21 @@ var init_model_selector = __esm(() => {
40653
40867
  value: "skip",
40654
40868
  description: "Use native Claude model for this tier"
40655
40869
  },
40656
- { name: "OpenRouter", value: "openrouter", description: "580+ models via unified API" },
40657
- { name: "OpenCode Zen", value: "zen", description: "Free models, no API key needed" },
40658
- {
40659
- name: "Google Gemini",
40660
- value: "google",
40661
- description: "Direct API (GEMINI_API_KEY)",
40662
- envVar: "GEMINI_API_KEY"
40663
- },
40664
- {
40665
- name: "OpenAI",
40666
- value: "openai",
40667
- description: "Direct API (OPENAI_API_KEY)",
40668
- envVar: "OPENAI_API_KEY"
40669
- },
40670
- {
40671
- name: "xAI / Grok",
40672
- value: "xai",
40673
- description: "Direct API (XAI_API_KEY)",
40674
- envVar: "XAI_API_KEY"
40675
- },
40676
- {
40677
- name: "MiniMax",
40678
- value: "minimax",
40679
- description: "Direct API (MINIMAX_API_KEY)",
40680
- envVar: "MINIMAX_API_KEY"
40681
- },
40682
- {
40683
- name: "MiniMax Coding",
40684
- value: "minimax-coding",
40685
- description: "MiniMax Coding subscription (MINIMAX_CODING_API_KEY)",
40686
- envVar: "MINIMAX_CODING_API_KEY"
40687
- },
40688
- {
40689
- name: "Kimi / Moonshot",
40690
- value: "kimi",
40691
- description: "Direct API (MOONSHOT_API_KEY)",
40692
- envVar: "MOONSHOT_API_KEY"
40693
- },
40694
- {
40695
- name: "Kimi Coding",
40696
- value: "kimi-coding",
40697
- description: "Kimi Coding subscription (KIMI_CODING_API_KEY)",
40698
- envVar: "KIMI_CODING_API_KEY"
40699
- },
40700
- {
40701
- name: "GLM / Zhipu",
40702
- value: "glm",
40703
- description: "Direct API (ZHIPU_API_KEY)",
40704
- envVar: "ZHIPU_API_KEY"
40705
- },
40706
- {
40707
- name: "GLM Coding Plan",
40708
- value: "glm-coding",
40709
- description: "GLM Coding subscription (GLM_CODING_API_KEY)",
40710
- envVar: "GLM_CODING_API_KEY"
40711
- },
40712
- { name: "Z.AI", value: "zai", description: "Z.AI API (ZAI_API_KEY)", envVar: "ZAI_API_KEY" },
40713
- { name: "OllamaCloud", value: "ollamacloud", description: "Cloud models (OLLAMA_API_KEY)" },
40714
- { name: "Ollama (local)", value: "ollama", description: "Local Ollama instance" },
40715
- { name: "LM Studio (local)", value: "lmstudio", description: "Local LM Studio instance" },
40870
+ { name: "OpenRouter", value: "openrouter", description: "580+ models via unified API", provider: "openrouter" },
40871
+ { name: "OpenCode Zen", value: "zen", description: "Free models, no API key needed", provider: "opencode-zen" },
40872
+ { name: "Google Gemini", value: "google", description: "Direct API", provider: "google" },
40873
+ { name: "OpenAI", value: "openai", description: "Direct API", provider: "openai" },
40874
+ { name: "xAI / Grok", value: "xai", description: "Direct API", provider: "xai" },
40875
+ { name: "MiniMax", value: "minimax", description: "Direct API", provider: "minimax" },
40876
+ { name: "MiniMax Coding", value: "minimax-coding", description: "Coding subscription", provider: "minimax-coding" },
40877
+ { name: "Kimi / Moonshot", value: "kimi", description: "Direct API", provider: "kimi" },
40878
+ { name: "Kimi Coding", value: "kimi-coding", description: "Coding subscription", provider: "kimi-coding" },
40879
+ { name: "GLM / Zhipu", value: "glm", description: "Direct API", provider: "glm" },
40880
+ { name: "GLM Coding Plan", value: "glm-coding", description: "Coding subscription", provider: "glm-coding" },
40881
+ { name: "Z.AI", value: "zai", description: "Direct API", provider: "zai" },
40882
+ { name: "OllamaCloud", value: "ollamacloud", description: "Cloud models", provider: "ollamacloud" },
40883
+ { name: "Ollama (local)", value: "ollama", description: "Local Ollama instance", provider: "ollama" },
40884
+ { name: "LM Studio (local)", value: "lmstudio", description: "Local LM Studio instance", provider: "lmstudio" },
40716
40885
  {
40717
40886
  name: "Enter custom model",
40718
40887
  value: "custom",
@@ -40742,6 +40911,12 @@ var init_model_selector = __esm(() => {
40742
40911
  openai: "OpenAI",
40743
40912
  xai: "xAI",
40744
40913
  glm: "GLM",
40914
+ "glm-coding": "GLM Coding",
40915
+ minimax: "MiniMax",
40916
+ "minimax-coding": "MiniMax Coding",
40917
+ kimi: "Kimi",
40918
+ "kimi-coding": "Kimi Coding",
40919
+ zai: "Z.AI",
40745
40920
  ollamacloud: "OllamaCloud",
40746
40921
  zen: "Zen"
40747
40922
  };
@@ -41670,23 +41845,23 @@ var init_telemetry = __esm(() => {
41670
41845
 
41671
41846
  // src/stats-buffer.ts
41672
41847
  import {
41673
- existsSync as existsSync17,
41848
+ existsSync as existsSync18,
41674
41849
  mkdirSync as mkdirSync9,
41675
41850
  readFileSync as readFileSync15,
41676
41851
  renameSync,
41677
41852
  unlinkSync as unlinkSync6,
41678
41853
  writeFileSync as writeFileSync9
41679
41854
  } from "fs";
41680
- import { homedir as homedir16 } from "os";
41681
- import { join as join17 } from "path";
41855
+ import { homedir as homedir17 } from "os";
41856
+ import { join as join18 } from "path";
41682
41857
  function ensureDir() {
41683
- if (!existsSync17(CLAUDISH_DIR)) {
41858
+ if (!existsSync18(CLAUDISH_DIR)) {
41684
41859
  mkdirSync9(CLAUDISH_DIR, { recursive: true });
41685
41860
  }
41686
41861
  }
41687
41862
  function readFromDisk() {
41688
41863
  try {
41689
- if (!existsSync17(BUFFER_FILE))
41864
+ if (!existsSync18(BUFFER_FILE))
41690
41865
  return [];
41691
41866
  const raw = readFileSync15(BUFFER_FILE, "utf-8");
41692
41867
  const parsed = JSON.parse(raw);
@@ -41712,7 +41887,7 @@ function writeToDisk(events) {
41712
41887
  ensureDir();
41713
41888
  const trimmed = enforceSizeCap([...events]);
41714
41889
  const payload = { version: 1, events: trimmed };
41715
- const tmpFile = join17(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
41890
+ const tmpFile = join18(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
41716
41891
  writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
41717
41892
  renameSync(tmpFile, BUFFER_FILE);
41718
41893
  memoryCache = trimmed;
@@ -41757,7 +41932,7 @@ function clearBuffer() {
41757
41932
  try {
41758
41933
  memoryCache = [];
41759
41934
  eventsSinceLastFlush = 0;
41760
- if (existsSync17(BUFFER_FILE)) {
41935
+ if (existsSync18(BUFFER_FILE)) {
41761
41936
  unlinkSync6(BUFFER_FILE);
41762
41937
  }
41763
41938
  } catch {}
@@ -41786,8 +41961,8 @@ function syncFlushOnExit() {
41786
41961
  var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, lastFlushTime, flushScheduled = false;
41787
41962
  var init_stats_buffer = __esm(() => {
41788
41963
  BUFFER_MAX_BYTES = 64 * 1024;
41789
- CLAUDISH_DIR = join17(homedir16(), ".claudish");
41790
- BUFFER_FILE = join17(CLAUDISH_DIR, "stats-buffer.json");
41964
+ CLAUDISH_DIR = join18(homedir17(), ".claudish");
41965
+ BUFFER_FILE = join18(CLAUDISH_DIR, "stats-buffer.json");
41791
41966
  lastFlushTime = Date.now();
41792
41967
  process.on("exit", syncFlushOnExit);
41793
41968
  process.on("SIGTERM", () => {
@@ -42275,8 +42450,8 @@ import { EventEmitter as EventEmitter2 } from "events";
42275
42450
  import { resolve as resolve3, dirname as dirname5 } from "path";
42276
42451
  import { fileURLToPath as fileURLToPath5 } from "url";
42277
42452
  import { resolve as resolve22, isAbsolute, parse as parse6 } from "path";
42278
- import { existsSync as existsSync18 } from "fs";
42279
- import { basename, join as join18 } from "path";
42453
+ import { existsSync as existsSync19 } from "fs";
42454
+ import { basename, join as join19 } from "path";
42280
42455
  import os from "os";
42281
42456
  import path from "path";
42282
42457
  import { EventEmitter as EventEmitter3 } from "events";
@@ -44675,7 +44850,7 @@ function getBunfsRootPath() {
44675
44850
  return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
44676
44851
  }
44677
44852
  function normalizeBunfsPath(fileName) {
44678
- return join18(getBunfsRootPath(), basename(fileName));
44853
+ return join19(getBunfsRootPath(), basename(fileName));
44679
44854
  }
44680
44855
  function isValidDirectoryName(name) {
44681
44856
  if (!name || typeof name !== "string") {
@@ -54871,7 +55046,7 @@ var init_index_0wbvecnk = __esm(async () => {
54871
55046
  worker_path = this.options.workerPath;
54872
55047
  } else {
54873
55048
  worker_path = new URL("./parser.worker.js", import.meta.url).href;
54874
- if (!existsSync18(resolve22(import.meta.dirname, "parser.worker.js"))) {
55049
+ if (!existsSync19(resolve22(import.meta.dirname, "parser.worker.js"))) {
54875
55050
  worker_path = new URL("./parser.worker.ts", import.meta.url).href;
54876
55051
  }
54877
55052
  }
@@ -98134,6 +98309,18 @@ var init_react = __esm(async () => {
98134
98309
  });
98135
98310
 
98136
98311
  // src/tui/providers.ts
98312
+ function toProviderDef(def) {
98313
+ return {
98314
+ name: def.name === "google" ? "gemini" : def.name,
98315
+ displayName: def.displayName,
98316
+ apiKeyEnvVar: def.apiKeyEnvVar,
98317
+ description: def.description || def.apiKeyDescription,
98318
+ keyUrl: def.apiKeyUrl,
98319
+ endpointEnvVar: def.baseUrlEnvVars?.[0],
98320
+ defaultEndpoint: def.baseUrl || undefined,
98321
+ aliases: def.apiKeyAliases
98322
+ };
98323
+ }
98137
98324
  function maskKey2(key) {
98138
98325
  if (!key)
98139
98326
  return "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
@@ -98141,113 +98328,11 @@ function maskKey2(key) {
98141
98328
  return "**** ";
98142
98329
  return `${key.slice(0, 3)}\u2022\u2022${key.slice(-3)}`;
98143
98330
  }
98144
- var PROVIDERS;
98331
+ var SKIP, PROVIDERS;
98145
98332
  var init_providers = __esm(() => {
98146
- PROVIDERS = [
98147
- {
98148
- name: "openrouter",
98149
- displayName: "OpenRouter",
98150
- apiKeyEnvVar: "OPENROUTER_API_KEY",
98151
- description: "580+ models, default backend",
98152
- keyUrl: "https://openrouter.ai/keys"
98153
- },
98154
- {
98155
- name: "gemini",
98156
- displayName: "Google Gemini",
98157
- apiKeyEnvVar: "GEMINI_API_KEY",
98158
- description: "Direct Gemini API (g@, google@)",
98159
- keyUrl: "https://aistudio.google.com/app/apikey",
98160
- endpointEnvVar: "GEMINI_BASE_URL",
98161
- defaultEndpoint: "https://generativelanguage.googleapis.com"
98162
- },
98163
- {
98164
- name: "openai",
98165
- displayName: "OpenAI",
98166
- apiKeyEnvVar: "OPENAI_API_KEY",
98167
- description: "Direct OpenAI API (oai@)",
98168
- keyUrl: "https://platform.openai.com/api-keys",
98169
- endpointEnvVar: "OPENAI_BASE_URL",
98170
- defaultEndpoint: "https://api.openai.com"
98171
- },
98172
- {
98173
- name: "minimax",
98174
- displayName: "MiniMax",
98175
- apiKeyEnvVar: "MINIMAX_API_KEY",
98176
- description: "MiniMax API (mm@, mmax@)",
98177
- keyUrl: "https://www.minimaxi.com/",
98178
- endpointEnvVar: "MINIMAX_BASE_URL",
98179
- defaultEndpoint: "https://api.minimax.io"
98180
- },
98181
- {
98182
- name: "kimi",
98183
- displayName: "Kimi / Moonshot",
98184
- apiKeyEnvVar: "MOONSHOT_API_KEY",
98185
- description: "Kimi API (kimi@, moon@)",
98186
- keyUrl: "https://platform.moonshot.cn/",
98187
- aliases: ["KIMI_API_KEY"],
98188
- endpointEnvVar: "MOONSHOT_BASE_URL",
98189
- defaultEndpoint: "https://api.moonshot.ai"
98190
- },
98191
- {
98192
- name: "glm",
98193
- displayName: "GLM / Zhipu",
98194
- apiKeyEnvVar: "ZHIPU_API_KEY",
98195
- description: "GLM API (glm@, zhipu@)",
98196
- keyUrl: "https://open.bigmodel.cn/",
98197
- aliases: ["GLM_API_KEY"],
98198
- endpointEnvVar: "ZHIPU_BASE_URL",
98199
- defaultEndpoint: "https://open.bigmodel.cn"
98200
- },
98201
- {
98202
- name: "zai",
98203
- displayName: "Z.AI",
98204
- apiKeyEnvVar: "ZAI_API_KEY",
98205
- description: "Z.AI API (zai@)",
98206
- keyUrl: "https://z.ai/",
98207
- endpointEnvVar: "ZAI_BASE_URL",
98208
- defaultEndpoint: "https://api.z.ai"
98209
- },
98210
- {
98211
- name: "ollamacloud",
98212
- displayName: "OllamaCloud",
98213
- apiKeyEnvVar: "OLLAMA_API_KEY",
98214
- description: "Cloud Ollama (oc@, llama@)",
98215
- keyUrl: "https://ollama.com/account",
98216
- endpointEnvVar: "OLLAMACLOUD_BASE_URL",
98217
- defaultEndpoint: "https://ollama.com"
98218
- },
98219
- {
98220
- name: "opencode",
98221
- displayName: "OpenCode Zen",
98222
- apiKeyEnvVar: "OPENCODE_API_KEY",
98223
- description: "OpenCode Zen (zen@) \u2014 optional for free models",
98224
- keyUrl: "https://opencode.ai/",
98225
- endpointEnvVar: "OPENCODE_BASE_URL",
98226
- defaultEndpoint: "https://opencode.ai/zen"
98227
- },
98228
- {
98229
- name: "litellm",
98230
- displayName: "LiteLLM",
98231
- apiKeyEnvVar: "LITELLM_API_KEY",
98232
- description: "LiteLLM proxy (ll@, litellm@)",
98233
- keyUrl: "https://docs.litellm.ai/",
98234
- endpointEnvVar: "LITELLM_BASE_URL"
98235
- },
98236
- {
98237
- name: "vertex",
98238
- displayName: "Vertex AI",
98239
- apiKeyEnvVar: "VERTEX_API_KEY",
98240
- description: "Vertex AI Express (v@, vertex@)",
98241
- keyUrl: "https://console.cloud.google.com/vertex-ai"
98242
- },
98243
- {
98244
- name: "poe",
98245
- displayName: "Poe",
98246
- apiKeyEnvVar: "POE_API_KEY",
98247
- description: "Poe API (poe@)",
98248
- keyUrl: "https://poe.com/"
98249
- }
98250
- ];
98333
+ init_provider_definitions();
98334
+ SKIP = new Set(["qwen", "native-anthropic"]);
98335
+ PROVIDERS = getAllProviders().filter((d2) => !SKIP.has(d2.name)).map(toProviderDef);
98251
98336
  });
98252
98337
 
98253
98338
  // src/tui/theme.ts
@@ -98304,7 +98389,11 @@ function App() {
98304
98389
  const [inputValue, setInputValue] = import_react13.useState("");
98305
98390
  const [routingPattern, setRoutingPattern] = import_react13.useState("");
98306
98391
  const [routingChain, setRoutingChain] = import_react13.useState("");
98392
+ const [chainSelected, setChainSelected] = import_react13.useState(new Set);
98393
+ const [chainOrder, setChainOrder] = import_react13.useState([]);
98394
+ const [chainCursor, setChainCursor] = import_react13.useState(0);
98307
98395
  const [statusMsg, setStatusMsg] = import_react13.useState(null);
98396
+ const CHAIN_PROVIDERS = PROVIDERS;
98308
98397
  const quit = import_react13.useCallback(() => renderer.destroy(), [renderer]);
98309
98398
  const displayProviders = import_react13.useMemo(() => {
98310
98399
  return [...PROVIDERS].sort((a, b2) => {
@@ -98365,30 +98454,75 @@ function App() {
98365
98454
  }
98366
98455
  if (mode === "add_routing_pattern") {
98367
98456
  if (key.name === "return" || key.name === "enter") {
98368
- if (routingPattern.trim())
98457
+ if (routingPattern.trim()) {
98458
+ setChainSelected(new Set);
98459
+ setChainCursor(0);
98460
+ setChainOrder([]);
98369
98461
  setMode("add_routing_chain");
98462
+ }
98370
98463
  } else if (key.name === "escape") {
98464
+ setRoutingPattern("");
98371
98465
  setMode("browse");
98466
+ } else if (key.name === "backspace" || key.name === "delete") {
98467
+ setRoutingPattern((p) => p.slice(0, -1));
98468
+ } else if (key.raw && key.raw.length === 1 && !key.ctrl && !key.meta) {
98469
+ setRoutingPattern((p) => p + key.raw);
98372
98470
  }
98373
98471
  return;
98374
98472
  }
98375
98473
  if (mode === "add_routing_chain") {
98376
- if (key.name === "return" || key.name === "enter") {
98474
+ if (key.name === "up" || key.name === "k") {
98475
+ setChainCursor((i) => Math.max(0, i - 1));
98476
+ } else if (key.name === "down" || key.name === "j") {
98477
+ setChainCursor((i) => Math.min(CHAIN_PROVIDERS.length - 1, i + 1));
98478
+ } else if (key.name === "space" || key.raw === " ") {
98479
+ const provName = CHAIN_PROVIDERS[chainCursor].name;
98480
+ setChainSelected((prev) => {
98481
+ const next = new Set(prev);
98482
+ if (next.has(provName)) {
98483
+ next.delete(provName);
98484
+ setChainOrder((o) => o.filter((p) => p !== provName));
98485
+ } else {
98486
+ next.add(provName);
98487
+ setChainOrder((o) => [...o, provName]);
98488
+ }
98489
+ return next;
98490
+ });
98491
+ } else if (key.raw && key.raw >= "1" && key.raw <= "9") {
98492
+ const provName = CHAIN_PROVIDERS[chainCursor].name;
98493
+ const targetPos = parseInt(key.raw, 10) - 1;
98494
+ setChainSelected((prev) => {
98495
+ const next = new Set(prev);
98496
+ next.add(provName);
98497
+ return next;
98498
+ });
98499
+ setChainOrder((prev) => {
98500
+ const without = prev.filter((p) => p !== provName);
98501
+ const insertAt = Math.min(targetPos, without.length);
98502
+ without.splice(insertAt, 0, provName);
98503
+ return without;
98504
+ });
98505
+ } else if (key.name === "return" || key.name === "enter") {
98377
98506
  const pat = routingPattern.trim();
98378
- const ch = routingChain.trim().split(",").map((s) => s.trim()).filter(Boolean);
98379
- if (pat && ch.length) {
98507
+ if (pat && chainOrder.length) {
98380
98508
  const cfg = loadConfig();
98381
98509
  if (!cfg.routing)
98382
98510
  cfg.routing = {};
98383
- cfg.routing[pat] = ch;
98511
+ cfg.routing[pat] = chainOrder;
98384
98512
  saveConfig(cfg);
98385
98513
  refreshConfig();
98386
- setStatusMsg(`Rule added for '${pat}'.`);
98514
+ setStatusMsg(`Rule added: ${pat} \u2192 ${chainOrder.join(", ")}`);
98387
98515
  }
98388
98516
  setRoutingPattern("");
98389
98517
  setRoutingChain("");
98518
+ setChainSelected(new Set);
98519
+ setChainOrder([]);
98520
+ setChainCursor(0);
98390
98521
  setMode("browse");
98391
98522
  } else if (key.name === "escape") {
98523
+ setChainSelected(new Set);
98524
+ setChainOrder([]);
98525
+ setChainCursor(0);
98392
98526
  setMode("add_routing_pattern");
98393
98527
  }
98394
98528
  return;
@@ -98527,7 +98661,7 @@ function App() {
98527
98661
  const HEADER_H = 1;
98528
98662
  const TABS_H = 3;
98529
98663
  const FOOTER_H = 1;
98530
- const DETAIL_H = 5;
98664
+ const DETAIL_H = 7;
98531
98665
  const contentH = Math.max(4, height2 - HEADER_H - TABS_H - DETAIL_H - FOOTER_H - 1);
98532
98666
  function TabBar() {
98533
98667
  const tabs = [
@@ -98758,8 +98892,11 @@ function App() {
98758
98892
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98759
98893
  fg: C2.green,
98760
98894
  bold: true,
98761
- children: "Enter "
98762
- }, undefined, false, undefined, this),
98895
+ children: [
98896
+ "Enter",
98897
+ " "
98898
+ ]
98899
+ }, undefined, true, undefined, this),
98763
98900
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98764
98901
  fg: C2.fgMuted,
98765
98902
  children: "to save \xB7 "
@@ -98767,8 +98904,11 @@ function App() {
98767
98904
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98768
98905
  fg: C2.red,
98769
98906
  bold: true,
98770
- children: "Esc "
98771
- }, undefined, false, undefined, this),
98907
+ children: [
98908
+ "Esc",
98909
+ " "
98910
+ ]
98911
+ }, undefined, true, undefined, this),
98772
98912
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98773
98913
  fg: C2.fgMuted,
98774
98914
  children: "to cancel"
@@ -98782,8 +98922,11 @@ function App() {
98782
98922
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98783
98923
  fg: C2.green,
98784
98924
  bold: true,
98785
- children: "> "
98786
- }, undefined, false, undefined, this)
98925
+ children: [
98926
+ ">",
98927
+ " "
98928
+ ]
98929
+ }, undefined, true, undefined, this)
98787
98930
  }, undefined, false, undefined, this),
98788
98931
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
98789
98932
  value: inputValue,
@@ -98815,8 +98958,11 @@ function App() {
98815
98958
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98816
98959
  fg: C2.blue,
98817
98960
  bold: true,
98818
- children: "Status: "
98819
- }, undefined, false, undefined, this),
98961
+ children: [
98962
+ "Status:",
98963
+ " "
98964
+ ]
98965
+ }, undefined, true, undefined, this),
98820
98966
  hasKey ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98821
98967
  fg: C2.green,
98822
98968
  bold: true,
@@ -98832,8 +98978,11 @@ function App() {
98832
98978
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98833
98979
  fg: C2.blue,
98834
98980
  bold: true,
98835
- children: "Key: "
98836
- }, undefined, false, undefined, this),
98981
+ children: [
98982
+ "Key:",
98983
+ " "
98984
+ ]
98985
+ }, undefined, true, undefined, this),
98837
98986
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98838
98987
  fg: C2.green,
98839
98988
  children: displayKey
@@ -98854,8 +99003,11 @@ function App() {
98854
99003
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98855
99004
  fg: C2.blue,
98856
99005
  bold: true,
98857
- children: "URL: "
98858
- }, undefined, false, undefined, this),
99006
+ children: [
99007
+ "URL:",
99008
+ " "
99009
+ ]
99010
+ }, undefined, true, undefined, this),
98859
99011
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98860
99012
  fg: C2.cyan,
98861
99013
  children: activeEndpoint || selectedProvider.defaultEndpoint || "default"
@@ -98867,8 +99019,11 @@ function App() {
98867
99019
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98868
99020
  fg: C2.blue,
98869
99021
  bold: true,
98870
- children: "Desc: "
98871
- }, undefined, false, undefined, this),
99022
+ children: [
99023
+ "Desc:",
99024
+ " "
99025
+ ]
99026
+ }, undefined, true, undefined, this),
98872
99027
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98873
99028
  fg: C2.white,
98874
99029
  children: selectedProvider.description
@@ -98880,8 +99035,11 @@ function App() {
98880
99035
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98881
99036
  fg: C2.blue,
98882
99037
  bold: true,
98883
- children: "Get Key: "
98884
- }, undefined, false, undefined, this),
99038
+ children: [
99039
+ "Get Key:",
99040
+ " "
99041
+ ]
99042
+ }, undefined, true, undefined, this),
98885
99043
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98886
99044
  fg: C2.cyan,
98887
99045
  children: selectedProvider.keyUrl
@@ -98905,37 +99063,81 @@ function App() {
98905
99063
  flexDirection: "column",
98906
99064
  paddingX: 1,
98907
99065
  children: [
99066
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99067
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99068
+ fg: C2.blue,
99069
+ bold: true,
99070
+ children: " Default fallback chain:"
99071
+ }, undefined, false, undefined, this)
99072
+ }, undefined, false, undefined, this),
98908
99073
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
98909
99074
  children: [
98910
99075
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98911
99076
  fg: C2.dim,
98912
- children: " * "
99077
+ children: " "
98913
99078
  }, undefined, false, undefined, this),
98914
99079
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98915
- fg: C2.fgMuted,
98916
- children: "LiteLLM \u2192 Zen Go \u2192 Subscription \u2192 Provider Direct \u2192 OpenRouter"
99080
+ fg: C2.cyan,
99081
+ children: "LiteLLM"
99082
+ }, undefined, false, undefined, this),
99083
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99084
+ fg: C2.dim,
99085
+ children: " \u2192 "
99086
+ }, undefined, false, undefined, this),
99087
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99088
+ fg: C2.cyan,
99089
+ children: "Zen Go"
98917
99090
  }, undefined, false, undefined, this),
98918
99091
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98919
99092
  fg: C2.dim,
98920
- children: " (built-in)"
99093
+ children: " \u2192 "
99094
+ }, undefined, false, undefined, this),
99095
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99096
+ fg: C2.cyan,
99097
+ children: "Subscription"
99098
+ }, undefined, false, undefined, this),
99099
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99100
+ fg: C2.dim,
99101
+ children: " \u2192 "
99102
+ }, undefined, false, undefined, this),
99103
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99104
+ fg: C2.cyan,
99105
+ children: "Provider Direct"
99106
+ }, undefined, false, undefined, this),
99107
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99108
+ fg: C2.dim,
99109
+ children: " \u2192 "
99110
+ }, undefined, false, undefined, this),
99111
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99112
+ fg: C2.cyan,
99113
+ children: "OpenRouter"
98921
99114
  }, undefined, false, undefined, this)
98922
99115
  ]
98923
99116
  }, undefined, true, undefined, this),
98924
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
98925
- children: " "
98926
- }, undefined, false, undefined, this),
98927
99117
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
98928
99118
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98929
- fg: C2.blue,
98930
- bold: true,
98931
- children: " PATTERN CHAIN"
99119
+ fg: C2.dim,
99120
+ children: " \u2500".repeat(Math.max(1, Math.floor((width - 6) / 2)))
98932
99121
  }, undefined, false, undefined, this)
98933
99122
  }, undefined, false, undefined, this),
99123
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99124
+ children: [
99125
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99126
+ fg: C2.blue,
99127
+ bold: true,
99128
+ children: " Custom rules:"
99129
+ }, undefined, false, undefined, this),
99130
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99131
+ fg: C2.fgMuted,
99132
+ children: " (override default for matching models)"
99133
+ }, undefined, false, undefined, this)
99134
+ ]
99135
+ }, undefined, true, undefined, this),
98934
99136
  ruleEntries.length === 0 && !isRoutingInput && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
98935
99137
  children: [
98936
99138
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98937
99139
  fg: C2.fgMuted,
98938
- children: " No custom rules. Press "
99140
+ children: " None configured. Press "
98939
99141
  }, undefined, false, undefined, this),
98940
99142
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98941
99143
  fg: C2.green,
@@ -98944,7 +99146,7 @@ function App() {
98944
99146
  }, undefined, false, undefined, this),
98945
99147
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
98946
99148
  fg: C2.fgMuted,
98947
- children: " to add one."
99149
+ children: " to add."
98948
99150
  }, undefined, false, undefined, this)
98949
99151
  ]
98950
99152
  }, undefined, true, undefined, this),
@@ -99007,23 +99209,20 @@ function App() {
99007
99209
  }, undefined, false, undefined, this)
99008
99210
  ]
99009
99211
  }, undefined, true, undefined, this),
99010
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
99011
- flexDirection: "row",
99212
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99012
99213
  children: [
99013
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99014
- children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99015
- fg: C2.green,
99016
- bold: true,
99017
- children: "> "
99018
- }, undefined, false, undefined, this)
99214
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99215
+ fg: C2.green,
99216
+ bold: true,
99217
+ children: "> "
99218
+ }, undefined, false, undefined, this),
99219
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99220
+ fg: C2.white,
99221
+ children: routingPattern
99019
99222
  }, undefined, false, undefined, this),
99020
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
99021
- value: routingPattern,
99022
- onChange: setRoutingPattern,
99023
- focused: true,
99024
- width: width - 8,
99025
- backgroundColor: C2.bgHighlight,
99026
- textColor: C2.white
99223
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99224
+ fg: C2.cyan,
99225
+ children: "\u2588"
99027
99226
  }, undefined, false, undefined, this)
99028
99227
  ]
99029
99228
  }, undefined, true, undefined, this),
@@ -99032,8 +99231,11 @@ function App() {
99032
99231
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99033
99232
  fg: C2.green,
99034
99233
  bold: true,
99035
- children: "Enter "
99036
- }, undefined, false, undefined, this),
99234
+ children: [
99235
+ "Enter",
99236
+ " "
99237
+ ]
99238
+ }, undefined, true, undefined, this),
99037
99239
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99038
99240
  fg: C2.fgMuted,
99039
99241
  children: "to continue \xB7 "
@@ -99041,8 +99243,11 @@ function App() {
99041
99243
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99042
99244
  fg: C2.red,
99043
99245
  bold: true,
99044
- children: "Esc "
99045
- }, undefined, false, undefined, this),
99246
+ children: [
99247
+ "Esc",
99248
+ " "
99249
+ ]
99250
+ }, undefined, true, undefined, this),
99046
99251
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99047
99252
  fg: C2.fgMuted,
99048
99253
  children: "to cancel"
@@ -99059,7 +99264,7 @@ function App() {
99059
99264
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99060
99265
  fg: C2.blue,
99061
99266
  bold: true,
99062
- children: "Chain for "
99267
+ children: "Select providers for "
99063
99268
  }, undefined, false, undefined, this),
99064
99269
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99065
99270
  fg: C2.white,
@@ -99068,52 +99273,57 @@ function App() {
99068
99273
  }, undefined, false, undefined, this),
99069
99274
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99070
99275
  fg: C2.dim,
99071
- children: " (comma-separated providers):"
99072
- }, undefined, false, undefined, this)
99073
- ]
99074
- }, undefined, true, undefined, this),
99075
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
99076
- flexDirection: "row",
99077
- children: [
99078
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99079
- children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99080
- fg: C2.green,
99081
- bold: true,
99082
- children: "> "
99083
- }, undefined, false, undefined, this)
99084
- }, undefined, false, undefined, this),
99085
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
99086
- value: routingChain,
99087
- onChange: setRoutingChain,
99088
- focused: true,
99089
- width: width - 8,
99090
- backgroundColor: C2.bgHighlight,
99091
- textColor: C2.white
99276
+ children: " (Space=toggle, 1-9=set position, Enter=save)"
99092
99277
  }, undefined, false, undefined, this)
99093
99278
  ]
99094
99279
  }, undefined, true, undefined, this),
99095
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99280
+ chainOrder.length > 0 && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99096
99281
  children: [
99097
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99098
- fg: C2.green,
99099
- bold: true,
99100
- children: "Enter "
99101
- }, undefined, false, undefined, this),
99102
99282
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99103
99283
  fg: C2.fgMuted,
99104
- children: "to save \xB7 "
99284
+ children: " Chain: "
99105
99285
  }, undefined, false, undefined, this),
99106
99286
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99107
- fg: C2.red,
99108
- bold: true,
99109
- children: "Esc "
99110
- }, undefined, false, undefined, this),
99111
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99112
- fg: C2.fgMuted,
99113
- children: "to go back"
99287
+ fg: C2.cyan,
99288
+ children: chainOrder.join(" \u2192 ")
99114
99289
  }, undefined, false, undefined, this)
99115
99290
  ]
99116
- }, undefined, true, undefined, this)
99291
+ }, undefined, true, undefined, this),
99292
+ CHAIN_PROVIDERS.map((prov, idx) => {
99293
+ const isCursor = idx === chainCursor;
99294
+ const isOn = chainSelected.has(prov.name);
99295
+ const pos = isOn ? chainOrder.indexOf(prov.name) + 1 : 0;
99296
+ const hasKey2 = !!(config3.apiKeys?.[prov.apiKeyEnvVar] || process.env[prov.apiKeyEnvVar]);
99297
+ const label = prov.displayName.padEnd(18).substring(0, 18);
99298
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
99299
+ height: 1,
99300
+ backgroundColor: isCursor ? C2.bgHighlight : C2.bg,
99301
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99302
+ children: [
99303
+ isOn ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99304
+ fg: C2.green,
99305
+ bold: true,
99306
+ children: ` [${pos}] `
99307
+ }, undefined, false, undefined, this) : /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99308
+ fg: C2.dim,
99309
+ children: " [ ] "
99310
+ }, undefined, false, undefined, this),
99311
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99312
+ fg: isCursor ? C2.white : hasKey2 ? C2.fgMuted : C2.dim,
99313
+ bold: isCursor,
99314
+ children: label
99315
+ }, undefined, false, undefined, this),
99316
+ hasKey2 ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99317
+ fg: C2.green,
99318
+ children: " \u25CF"
99319
+ }, undefined, false, undefined, this) : /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99320
+ fg: C2.dim,
99321
+ children: " \u25CB no key"
99322
+ }, undefined, false, undefined, this)
99323
+ ]
99324
+ }, undefined, true, undefined, this)
99325
+ }, prov.name, false, undefined, this);
99326
+ })
99117
99327
  ]
99118
99328
  }, undefined, true, undefined, this)
99119
99329
  ]
@@ -99132,74 +99342,74 @@ function App() {
99132
99342
  children: [
99133
99343
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99134
99344
  children: [
99135
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99136
- fg: C2.dim,
99137
- children: "kimi-* "
99138
- }, undefined, false, undefined, this),
99139
99345
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99140
99346
  fg: C2.fgMuted,
99141
- children: "kimi \u2192 or"
99347
+ children: " kimi-* "
99142
99348
  }, undefined, false, undefined, this),
99143
99349
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99144
99350
  fg: C2.dim,
99145
- children: " "
99351
+ children: " \u2192 "
99146
99352
  }, undefined, false, undefined, this),
99147
99353
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99148
- fg: C2.dim,
99149
- children: "gpt-* "
99150
- }, undefined, false, undefined, this),
99354
+ fg: C2.cyan,
99355
+ children: "kimi, openrouter"
99356
+ }, undefined, false, undefined, this)
99357
+ ]
99358
+ }, undefined, true, undefined, this),
99359
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99360
+ children: [
99151
99361
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99152
99362
  fg: C2.fgMuted,
99153
- children: "oai \u2192 litellm"
99363
+ children: " gpt-* "
99154
99364
  }, undefined, false, undefined, this),
99155
99365
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99156
99366
  fg: C2.dim,
99157
- children: " "
99367
+ children: " \u2192 "
99158
99368
  }, undefined, false, undefined, this),
99159
99369
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99160
- fg: C2.dim,
99161
- children: "gemini-* "
99162
- }, undefined, false, undefined, this),
99163
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99164
- fg: C2.fgMuted,
99165
- children: "google \u2192 zen \u2192 or"
99370
+ fg: C2.cyan,
99371
+ children: "oai, litellm"
99166
99372
  }, undefined, false, undefined, this)
99167
99373
  ]
99168
99374
  }, undefined, true, undefined, this),
99169
99375
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99170
99376
  children: [
99171
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99172
- fg: C2.dim,
99173
- children: "glm-* "
99174
- }, undefined, false, undefined, this),
99175
99377
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99176
99378
  fg: C2.fgMuted,
99177
- children: "glm \u2192 zen \u2192 or"
99379
+ children: " gemini-* "
99178
99380
  }, undefined, false, undefined, this),
99179
99381
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99180
99382
  fg: C2.dim,
99181
- children: " "
99383
+ children: " \u2192 "
99182
99384
  }, undefined, false, undefined, this),
99183
99385
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99184
- fg: C2.dim,
99185
- children: "deepseek-* "
99186
- }, undefined, false, undefined, this),
99386
+ fg: C2.cyan,
99387
+ children: "google, zen, openrouter"
99388
+ }, undefined, false, undefined, this)
99389
+ ]
99390
+ }, undefined, true, undefined, this),
99391
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99392
+ children: [
99187
99393
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99188
99394
  fg: C2.fgMuted,
99189
- children: "zen \u2192 or"
99395
+ children: " deepseek-* "
99190
99396
  }, undefined, false, undefined, this),
99191
99397
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99192
99398
  fg: C2.dim,
99193
- children: " "
99399
+ children: " \u2192 "
99194
99400
  }, undefined, false, undefined, this),
99195
99401
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99196
- fg: C2.dim,
99197
- children: "Pattern: glob (* = any)"
99402
+ fg: C2.cyan,
99403
+ children: "zen, openrouter"
99198
99404
  }, undefined, false, undefined, this)
99199
99405
  ]
99200
99406
  }, undefined, true, undefined, this),
99201
99407
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
99202
99408
  children: [
99409
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99410
+ fg: C2.dim,
99411
+ children: " Glob pattern (* = any). Chain tried left to right. "
99412
+ }, undefined, false, undefined, this),
99203
99413
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99204
99414
  fg: C2.cyan,
99205
99415
  bold: true,
@@ -99207,8 +99417,11 @@ function App() {
99207
99417
  }, undefined, false, undefined, this),
99208
99418
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99209
99419
  fg: C2.fgMuted,
99210
- children: ` custom rule${ruleEntries.length !== 1 ? "s" : ""}`
99211
- }, undefined, false, undefined, this)
99420
+ children: [
99421
+ " custom rule",
99422
+ ruleEntries.length !== 1 ? "s" : ""
99423
+ ]
99424
+ }, undefined, true, undefined, this)
99212
99425
  ]
99213
99426
  }, undefined, true, undefined, this)
99214
99427
  ]
@@ -99239,8 +99452,11 @@ function App() {
99239
99452
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99240
99453
  fg: C2.blue,
99241
99454
  bold: true,
99242
- children: "Status: "
99243
- }, undefined, false, undefined, this),
99455
+ children: [
99456
+ "Status:",
99457
+ " "
99458
+ ]
99459
+ }, undefined, true, undefined, this),
99244
99460
  telemetryEnabled ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99245
99461
  fg: C2.green,
99246
99462
  bold: true,
@@ -99314,8 +99530,11 @@ function App() {
99314
99530
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99315
99531
  fg: C2.blue,
99316
99532
  bold: true,
99317
- children: "Status: "
99318
- }, undefined, false, undefined, this),
99533
+ children: [
99534
+ "Status:",
99535
+ " "
99536
+ ]
99537
+ }, undefined, true, undefined, this),
99319
99538
  statsEnabled2 ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99320
99539
  fg: C2.green,
99321
99540
  bold: true,
@@ -99331,8 +99550,11 @@ function App() {
99331
99550
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99332
99551
  fg: C2.blue,
99333
99552
  bold: true,
99334
- children: "Buffer: "
99335
- }, undefined, false, undefined, this),
99553
+ children: [
99554
+ "Buffer:",
99555
+ " "
99556
+ ]
99557
+ }, undefined, true, undefined, this),
99336
99558
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
99337
99559
  fg: C2.white,
99338
99560
  bold: true,
@@ -99610,7 +99832,7 @@ __export(exports_team_cli, {
99610
99832
  teamCommand: () => teamCommand
99611
99833
  });
99612
99834
  import { readFileSync as readFileSync16 } from "fs";
99613
- import { join as join19 } from "path";
99835
+ import { join as join20 } from "path";
99614
99836
  function getFlag(args, flag) {
99615
99837
  const idx = args.indexOf(flag);
99616
99838
  if (idx === -1 || idx + 1 >= args.length)
@@ -99702,7 +99924,7 @@ async function teamCommand(args) {
99702
99924
  }
99703
99925
  case "judge": {
99704
99926
  const verdict = await judgeResponses(sessionPath, { judges });
99705
- console.log(readFileSync16(join19(sessionPath, "verdict.md"), "utf-8"));
99927
+ console.log(readFileSync16(join20(sessionPath, "verdict.md"), "utf-8"));
99706
99928
  break;
99707
99929
  }
99708
99930
  case "run-and-judge": {
@@ -99720,7 +99942,7 @@ async function teamCommand(args) {
99720
99942
  });
99721
99943
  printStatus(status);
99722
99944
  await judgeResponses(sessionPath, { judges });
99723
- console.log(readFileSync16(join19(sessionPath, "verdict.md"), "utf-8"));
99945
+ console.log(readFileSync16(join20(sessionPath, "verdict.md"), "utf-8"));
99724
99946
  break;
99725
99947
  }
99726
99948
  case "status": {
@@ -99746,11 +99968,17 @@ __export(exports_claude_runner, {
99746
99968
  checkClaudeInstalled: () => checkClaudeInstalled
99747
99969
  });
99748
99970
  import { spawn as spawn2 } from "child_process";
99749
- import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync7, mkdirSync as mkdirSync10, existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
99750
- import { tmpdir as tmpdir2, homedir as homedir17 } from "os";
99751
- import { join as join20 } from "path";
99971
+ import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync7, mkdirSync as mkdirSync10, existsSync as existsSync20, readFileSync as readFileSync17 } from "fs";
99972
+ import { tmpdir as tmpdir2, homedir as homedir18 } from "os";
99973
+ import { join as join21 } from "path";
99752
99974
  function hasNativeAnthropicMapping(config3) {
99753
- const models = [config3.model, config3.modelOpus, config3.modelSonnet, config3.modelHaiku, config3.modelSubagent];
99975
+ const models = [
99976
+ config3.model,
99977
+ config3.modelOpus,
99978
+ config3.modelSonnet,
99979
+ config3.modelHaiku,
99980
+ config3.modelSubagent
99981
+ ];
99754
99982
  return models.some((m2) => m2 && parseModelSpec(m2).provider === "native-anthropic");
99755
99983
  }
99756
99984
  function isWindows2() {
@@ -99758,9 +99986,9 @@ function isWindows2() {
99758
99986
  }
99759
99987
  function createStatusLineScript(tokenFilePath) {
99760
99988
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
99761
- const claudishDir = join20(homeDir, ".claudish");
99989
+ const claudishDir = join21(homeDir, ".claudish");
99762
99990
  const timestamp = Date.now();
99763
- const scriptPath = join20(claudishDir, `status-${timestamp}.js`);
99991
+ const scriptPath = join21(claudishDir, `status-${timestamp}.js`);
99764
99992
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
99765
99993
  const script = `
99766
99994
  const fs = require('fs');
@@ -99845,13 +100073,13 @@ process.stdin.on('end', () => {
99845
100073
  }
99846
100074
  function createTempSettingsFile(modelDisplay, port) {
99847
100075
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
99848
- const claudishDir = join20(homeDir, ".claudish");
100076
+ const claudishDir = join21(homeDir, ".claudish");
99849
100077
  try {
99850
100078
  mkdirSync10(claudishDir, { recursive: true });
99851
100079
  } catch {}
99852
100080
  const timestamp = Date.now();
99853
- const tempPath = join20(claudishDir, `settings-${timestamp}.json`);
99854
- const tokenFilePath = join20(claudishDir, `tokens-${port}.json`);
100081
+ const tempPath = join21(claudishDir, `settings-${timestamp}.json`);
100082
+ const tokenFilePath = join21(claudishDir, `tokens-${port}.json`);
99855
100083
  let statusCommand;
99856
100084
  if (isWindows2()) {
99857
100085
  const scriptPath = createStatusLineScript(tokenFilePath);
@@ -99979,8 +100207,8 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup, ptyDiagRunner) {
99979
100207
  console.error("Install it from: https://claude.com/claude-code");
99980
100208
  console.error(`
99981
100209
  Or set CLAUDE_PATH to your custom installation:`);
99982
- const home = homedir17();
99983
- const localPath = isWindows2() ? join20(home, ".claude", "local", "claude.exe") : join20(home, ".claude", "local", "claude");
100210
+ const home = homedir18();
100211
+ const localPath = isWindows2() ? join21(home, ".claude", "local", "claude.exe") : join21(home, ".claude", "local", "claude");
99984
100212
  console.error(` export CLAUDE_PATH=${localPath}`);
99985
100213
  process.exit(1);
99986
100214
  }
@@ -100034,23 +100262,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
100034
100262
  async function findClaudeBinary() {
100035
100263
  const isWindows3 = process.platform === "win32";
100036
100264
  if (process.env.CLAUDE_PATH) {
100037
- if (existsSync19(process.env.CLAUDE_PATH)) {
100265
+ if (existsSync20(process.env.CLAUDE_PATH)) {
100038
100266
  return process.env.CLAUDE_PATH;
100039
100267
  }
100040
100268
  }
100041
- const home = homedir17();
100042
- const localPath = isWindows3 ? join20(home, ".claude", "local", "claude.exe") : join20(home, ".claude", "local", "claude");
100043
- if (existsSync19(localPath)) {
100269
+ const home = homedir18();
100270
+ const localPath = isWindows3 ? join21(home, ".claude", "local", "claude.exe") : join21(home, ".claude", "local", "claude");
100271
+ if (existsSync20(localPath)) {
100044
100272
  return localPath;
100045
100273
  }
100046
100274
  if (isWindows3) {
100047
100275
  const windowsPaths = [
100048
- join20(home, "AppData", "Roaming", "npm", "claude.cmd"),
100049
- join20(home, ".npm-global", "claude.cmd"),
100050
- join20(home, "node_modules", ".bin", "claude.cmd")
100276
+ join21(home, "AppData", "Roaming", "npm", "claude.cmd"),
100277
+ join21(home, ".npm-global", "claude.cmd"),
100278
+ join21(home, "node_modules", ".bin", "claude.cmd")
100051
100279
  ];
100052
100280
  for (const path2 of windowsPaths) {
100053
- if (existsSync19(path2)) {
100281
+ if (existsSync20(path2)) {
100054
100282
  return path2;
100055
100283
  }
100056
100284
  }
@@ -100058,14 +100286,14 @@ async function findClaudeBinary() {
100058
100286
  const commonPaths = [
100059
100287
  "/usr/local/bin/claude",
100060
100288
  "/opt/homebrew/bin/claude",
100061
- join20(home, ".npm-global/bin/claude"),
100062
- join20(home, ".local/bin/claude"),
100063
- join20(home, "node_modules/.bin/claude"),
100289
+ join21(home, ".npm-global/bin/claude"),
100290
+ join21(home, ".local/bin/claude"),
100291
+ join21(home, "node_modules/.bin/claude"),
100064
100292
  "/data/data/com.termux/files/usr/bin/claude",
100065
- join20(home, "../usr/bin/claude")
100293
+ join21(home, "../usr/bin/claude")
100066
100294
  ];
100067
100295
  for (const path2 of commonPaths) {
100068
- if (existsSync19(path2)) {
100296
+ if (existsSync20(path2)) {
100069
100297
  return path2;
100070
100298
  }
100071
100299
  }
@@ -100114,21 +100342,22 @@ __export(exports_diag_output, {
100114
100342
  TmuxDiagOutput: () => TmuxDiagOutput,
100115
100343
  OpentUiDiagOutput: () => OpentUiDiagOutput,
100116
100344
  NullDiagOutput: () => NullDiagOutput,
100345
+ MtmDiagOutput: () => MtmDiagOutput,
100117
100346
  LogFileDiagOutput: () => LogFileDiagOutput
100118
100347
  });
100119
100348
  import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync11, writeFileSync as writeFileSync12, unlinkSync as unlinkSync8 } from "fs";
100120
100349
  import { execFileSync } from "child_process";
100121
- import { homedir as homedir18 } from "os";
100122
- import { join as join21 } from "path";
100350
+ import { homedir as homedir19 } from "os";
100351
+ import { join as join22 } from "path";
100123
100352
  function getClaudishDir() {
100124
- const dir = join21(homedir18(), ".claudish");
100353
+ const dir = join22(homedir19(), ".claudish");
100125
100354
  try {
100126
100355
  mkdirSync11(dir, { recursive: true });
100127
100356
  } catch {}
100128
100357
  return dir;
100129
100358
  }
100130
100359
  function getDiagLogPath() {
100131
- return join21(getClaudishDir(), `diag-${process.pid}.log`);
100360
+ return join22(getClaudishDir(), `diag-${process.pid}.log`);
100132
100361
  }
100133
100362
 
100134
100363
  class LogFileDiagOutput {
@@ -100164,22 +100393,27 @@ class LogFileDiagOutput {
100164
100393
  }
100165
100394
  }
100166
100395
 
100167
- class OpentUiDiagOutput {
100396
+ class MtmDiagOutput {
100168
100397
  runner;
100169
- messages = [];
100170
100398
  constructor(runner) {
100171
100399
  this.runner = runner;
100172
100400
  }
100173
100401
  write(msg) {
100174
- const level = msg.toLowerCase().includes("error") ? "error" : msg.toLowerCase().includes("warn") ? "warn" : "info";
100175
- this.messages.push({ text: msg, level });
100176
- if (this.messages.length > 4) {
100177
- this.messages = this.messages.slice(-4);
100178
- }
100179
- this.runner.showDiag(this.messages).catch(() => {});
100402
+ this.runner.write(msg);
100403
+ }
100404
+ cleanup() {}
100405
+ }
100406
+
100407
+ class OpentUiDiagOutput {
100408
+ inner;
100409
+ constructor(runner) {
100410
+ this.inner = new MtmDiagOutput(runner);
100411
+ }
100412
+ write(msg) {
100413
+ this.inner.write(msg);
100180
100414
  }
100181
100415
  cleanup() {
100182
- this.runner.hideDiag();
100416
+ this.inner.cleanup();
100183
100417
  }
100184
100418
  }
100185
100419
 
@@ -100195,9 +100429,10 @@ function createDiagOutput(options) {
100195
100429
  if (mode === "off") {
100196
100430
  return new NullDiagOutput;
100197
100431
  }
100432
+ const mtmRunner = options.mtmRunner ?? options.ptyRunner ?? null;
100198
100433
  if (mode === "pty" || mode === "auto") {
100199
- if (options.ptyRunner) {
100200
- return new OpentUiDiagOutput(options.ptyRunner);
100434
+ if (mtmRunner) {
100435
+ return new MtmDiagOutput(mtmRunner);
100201
100436
  }
100202
100437
  if (mode === "pty") {
100203
100438
  return new LogFileDiagOutput;
@@ -100229,7 +100464,10 @@ var init_diag_output = __esm(() => {
100229
100464
  args.push("-t", targetPane);
100230
100465
  }
100231
100466
  args.push("tail", "-f", this.logPath);
100232
- const output = execFileSync("tmux", args, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
100467
+ const output = execFileSync("tmux", args, {
100468
+ encoding: "utf-8",
100469
+ stdio: ["pipe", "pipe", "pipe"]
100470
+ });
100233
100471
  this.paneId = output.trim();
100234
100472
  } catch {
100235
100473
  this.paneId = null;
@@ -100249,213 +100487,199 @@ var init_diag_output = __esm(() => {
100249
100487
  };
100250
100488
  });
100251
100489
 
100252
- // src/tui/DiagPanel.tsx
100253
- function DiagPanel({ messages }) {
100254
- const { width } = useTerminalDimensions();
100255
- const panelWidth = Math.max(1, width);
100256
- const separator = "\u2500".repeat(panelWidth);
100257
- return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
100258
- x: 0,
100259
- y: 0,
100260
- width: panelWidth,
100261
- height: 5,
100262
- backgroundColor: "#1a1a2e",
100263
- children: [
100264
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
100265
- x: 0,
100266
- y: 0,
100267
- content: separator,
100268
- color: "#44475a"
100269
- }, undefined, false, undefined, this),
100270
- messages.slice(-3).map((msg, i) => {
100271
- const prefix = LEVEL_PREFIX[msg.level];
100272
- const color = LEVEL_COLORS[msg.level];
100273
- const maxTextLen = Math.max(1, panelWidth - prefix.length - 1);
100274
- const truncated = msg.text.length > maxTextLen ? `${msg.text.slice(0, maxTextLen - 1)}\u2026` : msg.text;
100275
- return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
100276
- x: 0,
100277
- y: i + 1,
100278
- content: `${prefix} ${truncated}`,
100279
- color
100280
- }, `msg-${i}`, false, undefined, this);
100281
- }),
100282
- messages.length < 3 && Array.from({ length: 3 - messages.length }).map((_2, i) => /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
100283
- x: 0,
100284
- y: messages.length + i + 1,
100285
- content: ""
100286
- }, `empty-${i}`, false, undefined, this)),
100287
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
100288
- x: 0,
100289
- y: 4,
100290
- content: "Press ESC to dismiss",
100291
- color: "#6272a4"
100292
- }, undefined, false, undefined, this)
100293
- ]
100294
- }, undefined, true, undefined, this);
100295
- }
100296
- var LEVEL_COLORS, LEVEL_PREFIX;
100297
- var init_DiagPanel = __esm(async () => {
100298
- init_jsx_dev_runtime();
100299
- await init_react();
100300
- LEVEL_COLORS = {
100301
- error: "#ff5555",
100302
- warn: "#ffb86c",
100303
- info: "#8be9fd"
100304
- };
100305
- LEVEL_PREFIX = {
100306
- error: "[ERROR]",
100307
- warn: "[WARN] ",
100308
- info: "[INFO] "
100309
- };
100310
- });
100311
-
100312
100490
  // src/pty-diag-runner.ts
100313
100491
  var exports_pty_diag_runner = {};
100314
100492
  __export(exports_pty_diag_runner, {
100315
100493
  tryCreatePtyRunner: () => tryCreatePtyRunner,
100316
- PtyDiagRunner: () => PtyDiagRunner
100494
+ tryCreateMtmRunner: () => tryCreateMtmRunner,
100495
+ PtyDiagRunner: () => MtmDiagRunner,
100496
+ MtmDiagRunner: () => MtmDiagRunner
100317
100497
  });
100318
- import { writeSync as writeSync3 } from "fs";
100498
+ import { spawn as spawn3 } from "child_process";
100499
+ import { appendFileSync, createWriteStream as createWriteStream3, existsSync as existsSync21, mkdirSync as mkdirSync12, unlinkSync as unlinkSync9, writeFileSync as writeFileSync13 } from "fs";
100500
+ import { homedir as homedir20 } from "os";
100501
+ import { dirname as dirname6, join as join23 } from "path";
100502
+ import { execSync as execSync3 } from "child_process";
100503
+ import { fileURLToPath as fileURLToPath6 } from "url";
100319
100504
 
100320
- class PtyDiagRunner {
100321
- renderer = null;
100322
- bunProc = null;
100323
- messages = [];
100324
- autoHideTimer = null;
100325
- reactRoot = null;
100326
- rawStdinHandler = null;
100327
- rendererInitializing = false;
100328
- async run(command, args, env2) {
100329
- const cols = process.stdout.columns || 80;
100330
- const rows = process.stdout.rows || 24;
100331
- this.bunProc = Bun.spawn([command, ...args], {
100332
- terminal: {
100333
- cols,
100334
- rows,
100335
- data: (_terminal, data) => {
100336
- const buf = typeof data === "string" ? Buffer.from(data, "binary") : data;
100337
- writeSync3(1, buf);
100338
- }
100339
- },
100340
- cwd: process.cwd(),
100341
- env: env2
100505
+ class MtmDiagRunner {
100506
+ mtmProc = null;
100507
+ logPath;
100508
+ statusPath;
100509
+ logStream = null;
100510
+ constructor() {
100511
+ const dir = join23(homedir20(), ".claudish");
100512
+ try {
100513
+ mkdirSync12(dir, { recursive: true });
100514
+ } catch {}
100515
+ this.logPath = join23(dir, `diag-${process.pid}.log`);
100516
+ this.statusPath = join23(dir, `status-${process.pid}.txt`);
100517
+ this.logStream = createWriteStream3(this.logPath, { flags: "w" });
100518
+ this.logStream.on("error", () => {});
100519
+ try {
100520
+ writeFileSync13(this.statusPath, renderStatusBar({ model: "", provider: "", errorCount: 0, lastError: "" }) + `
100521
+ `);
100522
+ } catch {}
100523
+ }
100524
+ async run(claudeCommand, claudeArgs, env2) {
100525
+ const mtmBin = this.findMtmBinary();
100526
+ const quotedArgs = claudeArgs.map((a) => shellQuote(a)).join(" ");
100527
+ const claudeCmd = `${shellQuote(claudeCommand)} ${quotedArgs}`;
100528
+ const mergedEnv = { ...process.env, ...env2 };
100529
+ this.mtmProc = spawn3(mtmBin, ["-e", claudeCmd, "-S", this.statusPath], {
100530
+ stdio: "inherit",
100531
+ env: mergedEnv
100532
+ });
100533
+ const exitCode = await new Promise((resolve4) => {
100534
+ this.mtmProc.on("exit", (code) => resolve4(code ?? 1));
100535
+ this.mtmProc.on("error", () => resolve4(1));
100342
100536
  });
100343
- const startTime = Date.now();
100344
- const GRACE_PERIOD_MS = 2000;
100345
- this.rawStdinHandler = (chunk) => {
100346
- if (!this.bunProc?.terminal)
100347
- return;
100348
- const str = typeof chunk === "string" ? chunk : chunk.toString("binary");
100349
- if (Date.now() - startTime < GRACE_PERIOD_MS) {
100350
- if (str.includes("\x1B"))
100351
- return;
100352
- }
100353
- this.bunProc.terminal.write(str);
100354
- };
100355
- process.stdin.on("data", this.rawStdinHandler);
100356
- const resizeHandler = () => {
100357
- if (this.bunProc?.terminal) {
100358
- try {
100359
- this.bunProc.terminal.resize(process.stdout.columns || 80, process.stdout.rows || 24);
100360
- } catch {}
100361
- }
100362
- };
100363
- process.on("SIGWINCH", resizeHandler);
100364
- await this.bunProc.exited;
100365
- const exitCode = this.bunProc.exitCode ?? 1;
100366
- process.removeListener("SIGWINCH", resizeHandler);
100367
100537
  this.cleanup();
100368
100538
  return exitCode;
100369
100539
  }
100370
- async showDiag(messages) {
100371
- this.messages = messages.slice(-4);
100372
- if (!this.renderer && !this.rendererInitializing) {
100373
- this.rendererInitializing = true;
100374
- try {
100375
- this.renderer = await createCliRenderer({
100376
- useAlternateScreen: false,
100377
- experimental_splitHeight: 5,
100378
- exitOnCtrlC: false,
100379
- useMouse: false,
100380
- useKittyKeyboard: null,
100381
- targetFps: 10
100382
- });
100383
- this.reactRoot = createRoot(this.renderer);
100384
- this.renderDiagPanel();
100385
- } catch {
100386
- this.rendererInitializing = false;
100387
- return;
100388
- }
100389
- this.rendererInitializing = false;
100390
- } else if (this.renderer) {
100391
- if (this.renderer.experimental_splitHeight === 0) {
100392
- this.renderer.experimental_splitHeight = 5;
100393
- }
100394
- this.renderDiagPanel();
100395
- }
100396
- if (this.autoHideTimer)
100397
- clearTimeout(this.autoHideTimer);
100398
- this.autoHideTimer = setTimeout(() => this.hideDiag(), 1e4);
100399
- }
100400
- hideDiag() {
100401
- if (!this.renderer)
100540
+ write(msg) {
100541
+ if (!this.logStream)
100402
100542
  return;
100403
- if (this.autoHideTimer) {
100404
- clearTimeout(this.autoHideTimer);
100405
- this.autoHideTimer = null;
100406
- }
100407
- this.renderer.experimental_splitHeight = 0;
100543
+ const timestamp = new Date().toISOString();
100544
+ try {
100545
+ this.logStream.write(`[${timestamp}] ${msg}
100546
+ `);
100547
+ } catch {}
100548
+ const parsed = parseLogMessage(msg);
100549
+ if (parsed.isError) {
100550
+ this.errorCount++;
100551
+ this.lastError = parsed.short;
100552
+ if (parsed.provider)
100553
+ this.provider = parsed.provider;
100554
+ }
100555
+ this.refreshStatusBar();
100556
+ }
100557
+ modelName = "";
100558
+ provider = "";
100559
+ lastError = "";
100560
+ errorCount = 0;
100561
+ setModel(name) {
100562
+ this.modelName = name.includes("/") ? name.split("/").pop() : name;
100563
+ if (name.includes("@")) {
100564
+ this.provider = name.split("@")[0];
100565
+ } else if (name.includes("/")) {
100566
+ this.provider = name.split("/")[0];
100567
+ }
100568
+ this.refreshStatusBar();
100569
+ }
100570
+ refreshStatusBar() {
100571
+ const bar = renderStatusBar({
100572
+ model: this.modelName,
100573
+ provider: this.provider,
100574
+ errorCount: this.errorCount,
100575
+ lastError: this.lastError
100576
+ });
100577
+ try {
100578
+ appendFileSync(this.statusPath, bar + `
100579
+ `);
100580
+ } catch {}
100408
100581
  }
100409
- renderDiagPanel() {
100410
- if (!this.reactRoot)
100411
- return;
100412
- this.reactRoot.render(import_react17.createElement(DiagPanel, { messages: this.messages }));
100582
+ getLogPath() {
100583
+ return this.logPath;
100413
100584
  }
100414
100585
  cleanup() {
100415
- if (this.autoHideTimer) {
100416
- clearTimeout(this.autoHideTimer);
100417
- this.autoHideTimer = null;
100418
- }
100419
- if (this.rawStdinHandler) {
100420
- process.stdin.removeListener("data", this.rawStdinHandler);
100421
- this.rawStdinHandler = null;
100422
- }
100423
- if (this.bunProc) {
100424
- try {
100425
- this.bunProc.kill();
100426
- } catch {}
100586
+ if (this.logStream) {
100427
100587
  try {
100428
- this.bunProc.terminal?.close();
100588
+ this.logStream.end();
100429
100589
  } catch {}
100430
- this.bunProc = null;
100590
+ this.logStream = null;
100431
100591
  }
100432
- if (this.renderer && !this.renderer.isDestroyed) {
100592
+ try {
100593
+ unlinkSync9(this.logPath);
100594
+ } catch {}
100595
+ try {
100596
+ unlinkSync9(this.statusPath);
100597
+ } catch {}
100598
+ if (this.mtmProc) {
100433
100599
  try {
100434
- this.renderer.destroy();
100600
+ this.mtmProc.kill();
100435
100601
  } catch {}
100436
- this.renderer = null;
100602
+ this.mtmProc = null;
100603
+ }
100604
+ }
100605
+ findMtmBinary() {
100606
+ const thisFile = fileURLToPath6(import.meta.url);
100607
+ const thisDir = dirname6(thisFile);
100608
+ const platform3 = process.platform;
100609
+ const arch = process.arch;
100610
+ const bundledPlatform = join23(thisDir, "..", "..", "native", "mtm", `mtm-${platform3}-${arch}`);
100611
+ if (existsSync21(bundledPlatform))
100612
+ return bundledPlatform;
100613
+ const builtDev = join23(thisDir, "..", "native", "mtm", "mtm");
100614
+ if (existsSync21(builtDev))
100615
+ return builtDev;
100616
+ try {
100617
+ const result = execSync3("which mtm", { encoding: "utf-8" }).trim();
100618
+ if (result)
100619
+ return result;
100620
+ } catch {}
100621
+ throw new Error("mtm binary not found. Build it with: cd packages/cli/native/mtm && make");
100622
+ }
100623
+ }
100624
+ function shellQuote(s) {
100625
+ return "'" + s.replace(/'/g, "'\\''") + "'";
100626
+ }
100627
+ function renderStatusBar(state) {
100628
+ const { model, provider, errorCount, lastError } = state;
100629
+ const parts = [];
100630
+ parts.push("M: claudish ");
100631
+ if (model)
100632
+ parts.push(`C: ${model} `);
100633
+ if (provider)
100634
+ parts.push(`D: ${provider} `);
100635
+ if (errorCount > 0) {
100636
+ const errLabel = errorCount === 1 ? " \u26A0 1 error " : ` \u26A0 ${errorCount} errors `;
100637
+ parts.push(`R:${errLabel}`);
100638
+ if (lastError)
100639
+ parts.push(`D: ${lastError} `);
100640
+ } else {
100641
+ parts.push("G: \u25CF ok ");
100642
+ }
100643
+ return parts.join("\t");
100644
+ }
100645
+ function parseLogMessage(msg) {
100646
+ const providerMatch = msg.match(/\[(\w+)\]/);
100647
+ const provider = providerMatch?.[1];
100648
+ const httpMatch = msg.match(/HTTP (\d{3})/);
100649
+ if (httpMatch) {
100650
+ const jsonMatch = msg.match(/"message"\s*:\s*"([^"]+)"/);
100651
+ if (jsonMatch?.[1]) {
100652
+ const detail = jsonMatch[1].replace(/is not a valid model ID/, "invalid model").replace(/Provider returned error/, "provider error");
100653
+ return { isError: true, short: detail, provider };
100437
100654
  }
100655
+ const hintMatch = msg.match(/HTTP \d{3}\.\s*(.+?)\.?\s*$/);
100656
+ if (hintMatch?.[1]) {
100657
+ return { isError: true, short: hintMatch[1], provider };
100658
+ }
100659
+ return { isError: true, short: `HTTP ${httpMatch[1]}`, provider };
100660
+ }
100661
+ if (msg.includes("[Fallback]")) {
100662
+ const countMatch = msg.match(/(\d+) provider/);
100663
+ return { isError: false, short: `fallback: ${countMatch?.[1] || "?"} providers`, provider };
100438
100664
  }
100665
+ if (msg.toLowerCase().includes("error")) {
100666
+ const short = msg.replace(/^Error\s*\[\w+\]:\s*/, "").replace(/\.\s*$/, "");
100667
+ return { isError: true, short: short.length > 40 ? short.slice(0, 39) + "\u2026" : short, provider };
100668
+ }
100669
+ return { isError: false, short: msg.length > 40 ? msg.slice(0, 39) + "\u2026" : msg };
100439
100670
  }
100440
- async function tryCreatePtyRunner() {
100671
+ async function tryCreateMtmRunner() {
100441
100672
  try {
100442
- if (typeof Bun === "undefined")
100443
- return null;
100444
- const test = Bun.spawn(["true"], { terminal: { cols: 1, rows: 1 } });
100445
- await test.exited;
100446
- return new PtyDiagRunner;
100673
+ const runner = new MtmDiagRunner;
100674
+ runner.findMtmBinary();
100675
+ return runner;
100447
100676
  } catch {
100448
100677
  return null;
100449
100678
  }
100450
100679
  }
100451
- var import_react17;
100452
- var init_pty_diag_runner = __esm(async () => {
100453
- await __promiseAll([
100454
- init_core3(),
100455
- init_react(),
100456
- init_DiagPanel()
100457
- ]);
100458
- import_react17 = __toESM(require_react(), 1);
100680
+ var tryCreatePtyRunner;
100681
+ var init_pty_diag_runner = __esm(() => {
100682
+ tryCreatePtyRunner = tryCreateMtmRunner;
100459
100683
  });
100460
100684
 
100461
100685
  // src/port-manager.ts
@@ -104041,9 +104265,9 @@ var init_middleware = __esm(() => {
104041
104265
  });
104042
104266
 
104043
104267
  // src/handlers/shared/token-tracker.ts
104044
- import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync13 } from "fs";
104045
- import { homedir as homedir19 } from "os";
104046
- import { join as join22 } from "path";
104268
+ import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync14 } from "fs";
104269
+ import { homedir as homedir21 } from "os";
104270
+ import { join as join24 } from "path";
104047
104271
 
104048
104272
  class TokenTracker {
104049
104273
  port;
@@ -104157,9 +104381,9 @@ class TokenTracker {
104157
104381
  is_free: isFreeModel,
104158
104382
  is_estimated: isEstimate || false
104159
104383
  };
104160
- const claudishDir = join22(homedir19(), ".claudish");
104161
- mkdirSync12(claudishDir, { recursive: true });
104162
- writeFileSync13(join22(claudishDir, `tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
104384
+ const claudishDir = join24(homedir21(), ".claudish");
104385
+ mkdirSync13(claudishDir, { recursive: true });
104386
+ writeFileSync14(join24(claudishDir, `tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
104163
104387
  } catch (e) {
104164
104388
  log(`[TokenTracker] Error writing token file: ${e}`);
104165
104389
  }
@@ -105595,9 +105819,9 @@ var init_composed_handler = __esm(() => {
105595
105819
  });
105596
105820
 
105597
105821
  // src/services/pricing-cache.ts
105598
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync14, existsSync as existsSync20, mkdirSync as mkdirSync13, statSync as statSync2 } from "fs";
105599
- import { homedir as homedir20 } from "os";
105600
- import { join as join23 } from "path";
105822
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync15, existsSync as existsSync23, mkdirSync as mkdirSync14, statSync as statSync2 } from "fs";
105823
+ import { homedir as homedir22 } from "os";
105824
+ import { join as join25 } from "path";
105601
105825
  function getDynamicPricingSync(provider, modelName) {
105602
105826
  if (provider === "openrouter") {
105603
105827
  const direct = pricingMap.get(modelName);
@@ -105662,7 +105886,7 @@ async function warmPricingCache() {
105662
105886
  }
105663
105887
  function loadDiskCache() {
105664
105888
  try {
105665
- if (!existsSync20(CACHE_FILE))
105889
+ if (!existsSync23(CACHE_FILE))
105666
105890
  return false;
105667
105891
  const stat = statSync2(CACHE_FILE);
105668
105892
  const age = Date.now() - stat.mtimeMs;
@@ -105679,12 +105903,12 @@ function loadDiskCache() {
105679
105903
  }
105680
105904
  function saveDiskCache() {
105681
105905
  try {
105682
- mkdirSync13(CACHE_DIR, { recursive: true });
105906
+ mkdirSync14(CACHE_DIR, { recursive: true });
105683
105907
  const data = {};
105684
105908
  for (const [key, pricing] of pricingMap) {
105685
105909
  data[key] = pricing;
105686
105910
  }
105687
- writeFileSync14(CACHE_FILE, JSON.stringify(data), "utf-8");
105911
+ writeFileSync15(CACHE_FILE, JSON.stringify(data), "utf-8");
105688
105912
  } catch (error46) {
105689
105913
  log(`[PricingCache] Error saving disk cache: ${error46}`);
105690
105914
  }
@@ -105714,8 +105938,8 @@ var init_pricing_cache = __esm(() => {
105714
105938
  init_model_loader();
105715
105939
  init_remote_provider_types();
105716
105940
  pricingMap = new Map;
105717
- CACHE_DIR = join23(homedir20(), ".claudish");
105718
- CACHE_FILE = join23(CACHE_DIR, "pricing-cache.json");
105941
+ CACHE_DIR = join25(homedir22(), ".claudish");
105942
+ CACHE_FILE = join25(CACHE_DIR, "pricing-cache.json");
105719
105943
  CACHE_TTL_MS = 24 * 60 * 60 * 1000;
105720
105944
  PROVIDER_TO_OR_PREFIX = {
105721
105945
  openai: ["openai/"],
@@ -106174,11 +106398,11 @@ class AnthropicProviderTransport {
106174
106398
  }
106175
106399
  if (this.provider.name === "kimi-coding" && !this.apiKey) {
106176
106400
  try {
106177
- const { existsSync: existsSync21, readFileSync: readFileSync19 } = await import("fs");
106178
- const { join: join24 } = await import("path");
106179
- const { homedir: homedir21 } = await import("os");
106180
- const credPath = join24(homedir21(), ".claudish", "kimi-oauth.json");
106181
- if (existsSync21(credPath)) {
106401
+ const { existsSync: existsSync24, readFileSync: readFileSync19 } = await import("fs");
106402
+ const { join: join26 } = await import("path");
106403
+ const { homedir: homedir23 } = await import("os");
106404
+ const credPath = join26(homedir23(), ".claudish", "kimi-oauth.json");
106405
+ if (existsSync24(credPath)) {
106182
106406
  const data = JSON.parse(readFileSync19(credPath, "utf-8"));
106183
106407
  if (data.access_token && data.refresh_token) {
106184
106408
  const { KimiOAuth: KimiOAuth2 } = await Promise.resolve().then(() => (init_kimi_oauth(), exports_kimi_oauth));
@@ -106480,10 +106704,10 @@ var init_litellm2 = __esm(() => {
106480
106704
  });
106481
106705
 
106482
106706
  // src/adapters/litellm-api-format.ts
106483
- import { existsSync as existsSync21, readFileSync as readFileSync19 } from "fs";
106707
+ import { existsSync as existsSync25, readFileSync as readFileSync19 } from "fs";
106484
106708
  import { createHash as createHash5 } from "crypto";
106485
- import { homedir as homedir21 } from "os";
106486
- import { join as join24 } from "path";
106709
+ import { homedir as homedir23 } from "os";
106710
+ import { join as join26 } from "path";
106487
106711
  var INLINE_IMAGE_MODEL_PATTERNS, LiteLLMAPIFormat;
106488
106712
  var init_litellm_api_format = __esm(() => {
106489
106713
  init_base_api_format();
@@ -106579,8 +106803,8 @@ var init_litellm_api_format = __esm(() => {
106579
106803
  checkVisionSupport() {
106580
106804
  try {
106581
106805
  const hash2 = createHash5("sha256").update(this.baseUrl).digest("hex").substring(0, 16);
106582
- const cachePath = join24(homedir21(), ".claudish", `litellm-models-${hash2}.json`);
106583
- if (!existsSync21(cachePath))
106806
+ const cachePath = join26(homedir23(), ".claudish", `litellm-models-${hash2}.json`);
106807
+ if (!existsSync25(cachePath))
106584
106808
  return true;
106585
106809
  const cacheData = JSON.parse(readFileSync19(cachePath, "utf-8"));
106586
106810
  const model = cacheData.models?.find((m2) => m2.name === this.modelId);
@@ -106599,9 +106823,9 @@ var init_litellm_api_format = __esm(() => {
106599
106823
  // src/auth/vertex-auth.ts
106600
106824
  import { exec as exec4 } from "child_process";
106601
106825
  import { promisify as promisify3 } from "util";
106602
- import { existsSync as existsSync23 } from "fs";
106603
- import { homedir as homedir22 } from "os";
106604
- import { join as join25 } from "path";
106826
+ import { existsSync as existsSync26 } from "fs";
106827
+ import { homedir as homedir24 } from "os";
106828
+ import { join as join27 } from "path";
106605
106829
 
106606
106830
  class VertexAuthManager {
106607
106831
  cachedToken = null;
@@ -106655,8 +106879,8 @@ class VertexAuthManager {
106655
106879
  }
106656
106880
  async tryADC() {
106657
106881
  try {
106658
- const adcPath = join25(homedir22(), ".config/gcloud/application_default_credentials.json");
106659
- if (!existsSync23(adcPath)) {
106882
+ const adcPath = join27(homedir24(), ".config/gcloud/application_default_credentials.json");
106883
+ if (!existsSync26(adcPath)) {
106660
106884
  log("[VertexAuth] ADC credentials file not found");
106661
106885
  return null;
106662
106886
  }
@@ -106680,7 +106904,7 @@ class VertexAuthManager {
106680
106904
  if (!credPath) {
106681
106905
  return null;
106682
106906
  }
106683
- if (!existsSync23(credPath)) {
106907
+ if (!existsSync26(credPath)) {
106684
106908
  throw new Error(`Service account file not found: ${credPath}
106685
106909
 
106686
106910
  Check GOOGLE_APPLICATION_CREDENTIALS path.`);
@@ -106719,8 +106943,8 @@ function validateVertexOAuthConfig() {
106719
106943
  ` + ` export VERTEX_PROJECT='your-gcp-project-id'
106720
106944
  ` + " export VERTEX_LOCATION='us-central1' # optional";
106721
106945
  }
106722
- const adcPath = join25(homedir22(), ".config/gcloud/application_default_credentials.json");
106723
- const hasADC = existsSync23(adcPath);
106946
+ const adcPath = join27(homedir24(), ".config/gcloud/application_default_credentials.json");
106947
+ const hasADC = existsSync26(adcPath);
106724
106948
  const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
106725
106949
  if (!hasADC && !hasServiceAccount) {
106726
106950
  return `No Vertex AI credentials found.
@@ -106852,6 +107076,7 @@ var init_provider_profiles = __esm(() => {
106852
107076
  init_ollama_api_format();
106853
107077
  init_litellm2();
106854
107078
  init_litellm_api_format();
107079
+ init_codex_api_format();
106855
107080
  init_vertex_oauth();
106856
107081
  init_base_api_format();
106857
107082
  init_remote_provider_registry();
@@ -106935,6 +107160,18 @@ var init_provider_profiles = __esm(() => {
106935
107160
  log(`[Proxy] Created OpenCode Zen${isGoProvider ? " Go" : ""} (Anthropic composed): ${ctx.modelName}`);
106936
107161
  return handler2;
106937
107162
  }
107163
+ if (ctx.modelName.toLowerCase().startsWith("gpt-")) {
107164
+ const responsesProvider = { ...ctx.provider, apiPath: "/v1/responses" };
107165
+ const transport2 = new OpenAIProviderTransport(responsesProvider, ctx.modelName, zenApiKey);
107166
+ const adapter2 = new CodexAPIFormat(ctx.modelName);
107167
+ const handler2 = new ComposedHandler(transport2, ctx.targetModel, ctx.modelName, ctx.port, {
107168
+ adapter: adapter2,
107169
+ tokenStrategy: "delta-aware",
107170
+ ...ctx.sharedOpts
107171
+ });
107172
+ log(`[Proxy] Created OpenCode Zen${isGoProvider ? " Go" : ""} (Responses API composed): ${ctx.modelName}`);
107173
+ return handler2;
107174
+ }
106938
107175
  const transport = new OpenAIProviderTransport(ctx.provider, ctx.modelName, zenApiKey);
106939
107176
  const adapter = new OpenAIAPIFormat(ctx.modelName);
106940
107177
  const handler = new ComposedHandler(transport, ctx.targetModel, ctx.modelName, ctx.port, {
@@ -107174,6 +107411,7 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
107174
107411
  }).catch(() => {});
107175
107412
  }
107176
107413
  warmZenModelCache().then(() => log("[Proxy] Zen model cache pre-warmed for fallback filtering")).catch(() => {});
107414
+ warmZenGoModelCache().then(() => log("[Proxy] Zen Go model cache pre-warmed for fallback filtering")).catch(() => {});
107177
107415
  const customRoutingRules = loadRoutingRules();
107178
107416
  const fallbackHandlerCache = new Map;
107179
107417
  const detectInvocationMode = (target, wasFromModelMap) => {
@@ -107363,14 +107601,14 @@ var init_proxy_server = __esm(() => {
107363
107601
 
107364
107602
  // src/index.ts
107365
107603
  var import_dotenv3 = __toESM(require_main(), 1);
107366
- import { existsSync as existsSync25, readFileSync as readFileSync21 } from "fs";
107367
- import { homedir as homedir23 } from "os";
107368
- import { join as join26 } from "path";
107604
+ import { existsSync as existsSync27, readFileSync as readFileSync21 } from "fs";
107605
+ import { homedir as homedir25 } from "os";
107606
+ import { join as join28 } from "path";
107369
107607
  import_dotenv3.config({ quiet: true });
107370
107608
  function loadStoredApiKeys() {
107371
107609
  try {
107372
- const configPath = join26(homedir23(), ".claudish", "config.json");
107373
- if (!existsSync25(configPath))
107610
+ const configPath = join28(homedir25(), ".claudish", "config.json");
107611
+ if (!existsSync27(configPath))
107374
107612
  return;
107375
107613
  const raw2 = readFileSync21(configPath, "utf-8");
107376
107614
  const cfg = JSON.parse(raw2);
@@ -107507,7 +107745,7 @@ async function runCli() {
107507
107745
  } = await Promise.resolve().then(() => (init_provider_resolver(), exports_provider_resolver));
107508
107746
  const { initLogger: initLogger2, getLogFilePath: getLogFilePath2, getAlwaysOnLogPath: getAlwaysOnLogPath2, setDiagOutput: setDiagOutput2 } = await Promise.resolve().then(() => (init_logger(), exports_logger));
107509
107747
  const { createDiagOutput: createDiagOutput2, LogFileDiagOutput: LogFileDiagOutput2 } = await Promise.resolve().then(() => (init_diag_output(), exports_diag_output));
107510
- const { tryCreatePtyRunner: tryCreatePtyRunner2 } = await init_pty_diag_runner().then(() => exports_pty_diag_runner);
107748
+ const { tryCreateMtmRunner: tryCreateMtmRunner2 } = await Promise.resolve().then(() => (init_pty_diag_runner(), exports_pty_diag_runner));
107511
107749
  const { findAvailablePort: findAvailablePort2 } = await Promise.resolve().then(() => (init_port_manager(), exports_port_manager));
107512
107750
  const { createProxyServer: createProxyServer2 } = await Promise.resolve().then(() => (init_proxy_server(), exports_proxy_server));
107513
107751
  const { checkForUpdates: checkForUpdates2 } = await Promise.resolve().then(() => (init_update_checker(), exports_update_checker));
@@ -107520,6 +107758,43 @@ async function runCli() {
107520
107758
  }
107521
107759
  try {
107522
107760
  const cliConfig = await parseArgs2(process.argv.slice(2));
107761
+ const rawArgs = process.argv.slice(2);
107762
+ const explicitNoAutoApprove = rawArgs.includes("--no-auto-approve");
107763
+ if (cliConfig.autoApprove && !explicitNoAutoApprove) {
107764
+ const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = await Promise.resolve().then(() => (init_profile_config(), exports_profile_config));
107765
+ try {
107766
+ const cfg = loadConfig2();
107767
+ if (!cfg.autoApproveConfirmedAt) {
107768
+ const { createInterface: createInterface4 } = await import("readline");
107769
+ process.stderr.write(`
107770
+ [claudish] Auto-approve is enabled by default.
107771
+ This skips Claude Code permission prompts for tools like Bash, Read, Write.
107772
+ You can disable it anytime with: --no-auto-approve
107773
+
107774
+ `);
107775
+ const answer = await new Promise((resolve4) => {
107776
+ const rl = createInterface4({ input: process.stdin, output: process.stderr });
107777
+ rl.question("Enable auto-approve? [Y/n] ", (ans) => {
107778
+ rl.close();
107779
+ resolve4(ans.trim().toLowerCase());
107780
+ });
107781
+ });
107782
+ const declined = answer === "n" || answer === "no";
107783
+ if (declined) {
107784
+ cliConfig.autoApprove = false;
107785
+ process.stderr.write(`[claudish] Auto-approve disabled. Use -y to enable per-run.
107786
+
107787
+ `);
107788
+ } else {
107789
+ process.stderr.write(`[claudish] Auto-approve confirmed.
107790
+
107791
+ `);
107792
+ }
107793
+ cfg.autoApproveConfirmedAt = new Date().toISOString();
107794
+ saveConfig2(cfg);
107795
+ }
107796
+ } catch {}
107797
+ }
107523
107798
  initLogger2(cliConfig.debug, cliConfig.logLevel, cliConfig.noLogs);
107524
107799
  const { initTelemetry: initTelemetry2 } = await Promise.resolve().then(() => (init_telemetry(), exports_telemetry));
107525
107800
  initTelemetry2(cliConfig);
@@ -107625,22 +107900,25 @@ async function runCli() {
107625
107900
  quiet: cliConfig.quiet,
107626
107901
  isInteractive: cliConfig.interactive
107627
107902
  });
107628
- const needsPty = cliConfig.interactive && (cliConfig.diagMode === "auto" || cliConfig.diagMode === "pty");
107629
- const ptyRunner = needsPty ? await tryCreatePtyRunner2() : null;
107903
+ const needsMtm = cliConfig.interactive && (cliConfig.diagMode === "auto" || cliConfig.diagMode === "pty");
107904
+ const mtmRunner = needsMtm ? await tryCreateMtmRunner2() : null;
107905
+ if (mtmRunner && explicitModel) {
107906
+ mtmRunner.setModel(explicitModel);
107907
+ }
107630
107908
  const diag = createDiagOutput2({
107631
107909
  interactive: cliConfig.interactive,
107632
- ptyRunner,
107910
+ mtmRunner,
107633
107911
  diagMode: cliConfig.diagMode
107634
107912
  });
107635
107913
  if (cliConfig.interactive) {
107636
107914
  setDiagOutput2(diag);
107637
- if (!ptyRunner && !process.env.TMUX && !cliConfig.quiet && diag instanceof LogFileDiagOutput2) {
107915
+ if (!mtmRunner && !process.env.TMUX && !cliConfig.quiet && diag instanceof LogFileDiagOutput2) {
107638
107916
  console.log(`[claudish] Diagnostic log: ${diag.getLogPath()}`);
107639
107917
  }
107640
107918
  }
107641
107919
  let exitCode = 0;
107642
107920
  try {
107643
- exitCode = await runClaudeWithProxy2(cliConfig, proxy.url, () => diag.cleanup(), ptyRunner);
107921
+ exitCode = await runClaudeWithProxy2(cliConfig, proxy.url, () => diag.cleanup(), mtmRunner);
107644
107922
  } finally {
107645
107923
  setDiagOutput2(null);
107646
107924
  diag.cleanup();