claudish 5.1.1 → 5.2.0

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
@@ -33320,6 +33320,275 @@ var init_remote_provider_registry = __esm(() => {
33320
33320
  init_model_parser();
33321
33321
  });
33322
33322
 
33323
+ // src/auth/oauth-registry.ts
33324
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
33325
+ import { join as join8 } from "node:path";
33326
+ import { homedir as homedir7 } from "node:os";
33327
+ function hasValidOAuthCredentials(descriptor) {
33328
+ const credPath = join8(homedir7(), ".claudish", descriptor.credentialFile);
33329
+ if (!existsSync8(credPath))
33330
+ return false;
33331
+ if (descriptor.validationMode === "file-exists") {
33332
+ return true;
33333
+ }
33334
+ try {
33335
+ const data = JSON.parse(readFileSync7(credPath, "utf-8"));
33336
+ if (!data.access_token)
33337
+ return false;
33338
+ if (data.refresh_token)
33339
+ return true;
33340
+ if (descriptor.expiresAtField && data[descriptor.expiresAtField]) {
33341
+ const buffer = descriptor.expiryBufferMs ?? 0;
33342
+ return data[descriptor.expiresAtField] > Date.now() + buffer;
33343
+ }
33344
+ return true;
33345
+ } catch {
33346
+ return false;
33347
+ }
33348
+ }
33349
+ function hasOAuthCredentials(providerName) {
33350
+ const descriptor = OAUTH_PROVIDERS[providerName];
33351
+ if (!descriptor)
33352
+ return false;
33353
+ return hasValidOAuthCredentials(descriptor);
33354
+ }
33355
+ var OAUTH_PROVIDERS;
33356
+ var init_oauth_registry = __esm(() => {
33357
+ OAUTH_PROVIDERS = {
33358
+ "kimi-coding": {
33359
+ credentialFile: "kimi-oauth.json",
33360
+ validationMode: "check-expiry",
33361
+ expiresAtField: "expires_at",
33362
+ expiryBufferMs: 5 * 60 * 1000
33363
+ },
33364
+ kimi: {
33365
+ credentialFile: "kimi-oauth.json",
33366
+ validationMode: "check-expiry",
33367
+ expiresAtField: "expires_at",
33368
+ expiryBufferMs: 5 * 60 * 1000
33369
+ },
33370
+ google: {
33371
+ credentialFile: "gemini-oauth.json",
33372
+ validationMode: "check-expiry",
33373
+ expiresAtField: "expires_at",
33374
+ expiryBufferMs: 5 * 60 * 1000
33375
+ },
33376
+ "gemini-codeassist": {
33377
+ credentialFile: "gemini-oauth.json",
33378
+ validationMode: "check-expiry",
33379
+ expiresAtField: "expires_at",
33380
+ expiryBufferMs: 5 * 60 * 1000
33381
+ }
33382
+ };
33383
+ });
33384
+
33385
+ // src/providers/auto-route.ts
33386
+ import { existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
33387
+ import { join as join9 } from "node:path";
33388
+ import { homedir as homedir8 } from "node:os";
33389
+ import { createHash as createHash3 } from "node:crypto";
33390
+ function readLiteLLMCacheSync(baseUrl) {
33391
+ const hash2 = createHash3("sha256").update(baseUrl).digest("hex").substring(0, 16);
33392
+ const cachePath = join9(homedir8(), ".claudish", `litellm-models-${hash2}.json`);
33393
+ if (!existsSync9(cachePath))
33394
+ return null;
33395
+ try {
33396
+ const data = JSON.parse(readFileSync8(cachePath, "utf-8"));
33397
+ if (!Array.isArray(data.models))
33398
+ return null;
33399
+ return data.models;
33400
+ } catch {
33401
+ return null;
33402
+ }
33403
+ }
33404
+ function checkOAuthForProvider(nativeProvider, modelName) {
33405
+ if (!hasOAuthCredentials(nativeProvider))
33406
+ return null;
33407
+ return {
33408
+ provider: nativeProvider,
33409
+ resolvedModelId: modelName,
33410
+ modelName,
33411
+ reason: "oauth-credentials",
33412
+ displayMessage: `Auto-routed: ${modelName} -> ${nativeProvider} (oauth)`
33413
+ };
33414
+ }
33415
+ function checkApiKeyForProvider(nativeProvider, modelName) {
33416
+ const keyInfo = API_KEY_ENV_VARS[nativeProvider];
33417
+ if (!keyInfo)
33418
+ return null;
33419
+ if (keyInfo.envVar && process.env[keyInfo.envVar]) {
33420
+ return {
33421
+ provider: nativeProvider,
33422
+ resolvedModelId: modelName,
33423
+ modelName,
33424
+ reason: "api-key",
33425
+ displayMessage: `Auto-routed: ${modelName} -> ${nativeProvider} (api-key)`
33426
+ };
33427
+ }
33428
+ if (keyInfo.aliases) {
33429
+ for (const alias of keyInfo.aliases) {
33430
+ if (process.env[alias]) {
33431
+ return {
33432
+ provider: nativeProvider,
33433
+ resolvedModelId: modelName,
33434
+ modelName,
33435
+ reason: "api-key",
33436
+ displayMessage: `Auto-routed: ${modelName} -> ${nativeProvider} (api-key)`
33437
+ };
33438
+ }
33439
+ }
33440
+ }
33441
+ return null;
33442
+ }
33443
+ function formatForOpenRouter(modelName, nativeProvider) {
33444
+ if (modelName.includes("/")) {
33445
+ return modelName;
33446
+ }
33447
+ const vendor = OPENROUTER_VENDOR_MAP[nativeProvider];
33448
+ if (vendor) {
33449
+ return `${vendor}/${modelName}`;
33450
+ }
33451
+ return modelName;
33452
+ }
33453
+ function getAutoRouteHint(modelName, nativeProvider) {
33454
+ const hint = PROVIDER_HINT_MAP[nativeProvider];
33455
+ const lines = [
33456
+ `No credentials found for "${modelName}". Options:`
33457
+ ];
33458
+ let hasOption = false;
33459
+ if (hint?.loginFlag) {
33460
+ lines.push(` Run: claudish ${hint.loginFlag} (authenticate via OAuth)`);
33461
+ hasOption = true;
33462
+ }
33463
+ if (hint?.apiKeyEnvVar) {
33464
+ lines.push(` Set: export ${hint.apiKeyEnvVar}=your-key`);
33465
+ hasOption = true;
33466
+ }
33467
+ if (hint?.openRouterModel) {
33468
+ lines.push(` Use: claudish --model or@${hint.openRouterModel} (route via OpenRouter)`);
33469
+ hasOption = true;
33470
+ }
33471
+ if (!hasOption) {
33472
+ return null;
33473
+ }
33474
+ lines.push(` Or set OPENROUTER_API_KEY for automatic OpenRouter fallback`);
33475
+ return lines.join(`
33476
+ `);
33477
+ }
33478
+ function autoRoute(modelName, nativeProvider) {
33479
+ const litellmBaseUrl = process.env.LITELLM_BASE_URL;
33480
+ if (litellmBaseUrl) {
33481
+ const models = readLiteLLMCacheSync(litellmBaseUrl);
33482
+ if (models !== null) {
33483
+ const match = models.find((m) => m.name === modelName || m.id === `litellm@${modelName}`);
33484
+ if (match) {
33485
+ return {
33486
+ provider: "litellm",
33487
+ resolvedModelId: `litellm@${modelName}`,
33488
+ modelName,
33489
+ reason: "litellm-cache",
33490
+ displayMessage: `Auto-routed: ${modelName} -> litellm`
33491
+ };
33492
+ }
33493
+ }
33494
+ }
33495
+ if (nativeProvider !== "unknown") {
33496
+ const oauthResult = checkOAuthForProvider(nativeProvider, modelName);
33497
+ if (oauthResult)
33498
+ return oauthResult;
33499
+ }
33500
+ if (nativeProvider !== "unknown") {
33501
+ const apiKeyResult = checkApiKeyForProvider(nativeProvider, modelName);
33502
+ if (apiKeyResult)
33503
+ return apiKeyResult;
33504
+ }
33505
+ if (process.env.OPENROUTER_API_KEY) {
33506
+ const orModelId = formatForOpenRouter(modelName, nativeProvider);
33507
+ return {
33508
+ provider: "openrouter",
33509
+ resolvedModelId: orModelId,
33510
+ modelName,
33511
+ reason: "openrouter-fallback",
33512
+ displayMessage: `Auto-routed: ${modelName} -> openrouter`
33513
+ };
33514
+ }
33515
+ return null;
33516
+ }
33517
+ var API_KEY_ENV_VARS, OPENROUTER_VENDOR_MAP, PROVIDER_HINT_MAP;
33518
+ var init_auto_route = __esm(() => {
33519
+ init_oauth_registry();
33520
+ API_KEY_ENV_VARS = {
33521
+ google: { envVar: "GEMINI_API_KEY" },
33522
+ "gemini-codeassist": { envVar: "GEMINI_API_KEY" },
33523
+ openai: { envVar: "OPENAI_API_KEY" },
33524
+ minimax: { envVar: "MINIMAX_API_KEY" },
33525
+ "minimax-coding": { envVar: "MINIMAX_CODING_API_KEY" },
33526
+ kimi: { envVar: "MOONSHOT_API_KEY", aliases: ["KIMI_API_KEY"] },
33527
+ "kimi-coding": { envVar: "KIMI_CODING_API_KEY" },
33528
+ glm: { envVar: "ZHIPU_API_KEY", aliases: ["GLM_API_KEY"] },
33529
+ "glm-coding": { envVar: "GLM_CODING_API_KEY", aliases: ["ZAI_CODING_API_KEY"] },
33530
+ zai: { envVar: "ZAI_API_KEY" },
33531
+ ollamacloud: { envVar: "OLLAMA_API_KEY" },
33532
+ litellm: { envVar: "LITELLM_API_KEY" },
33533
+ openrouter: { envVar: "OPENROUTER_API_KEY" },
33534
+ vertex: { envVar: "VERTEX_API_KEY", aliases: ["VERTEX_PROJECT"] },
33535
+ poe: { envVar: "POE_API_KEY" }
33536
+ };
33537
+ OPENROUTER_VENDOR_MAP = {
33538
+ google: "google",
33539
+ openai: "openai",
33540
+ kimi: "moonshot",
33541
+ "kimi-coding": "moonshot",
33542
+ glm: "zhipuai",
33543
+ "glm-coding": "zhipuai",
33544
+ minimax: "minimax",
33545
+ ollamacloud: "meta-llama"
33546
+ };
33547
+ PROVIDER_HINT_MAP = {
33548
+ "kimi-coding": {
33549
+ loginFlag: "--kimi-login",
33550
+ apiKeyEnvVar: "KIMI_CODING_API_KEY",
33551
+ openRouterModel: "moonshot/kimi-k2"
33552
+ },
33553
+ kimi: {
33554
+ loginFlag: "--kimi-login",
33555
+ apiKeyEnvVar: "MOONSHOT_API_KEY",
33556
+ openRouterModel: "moonshot/moonshot-v1-8k"
33557
+ },
33558
+ google: {
33559
+ loginFlag: "--gemini-login",
33560
+ apiKeyEnvVar: "GEMINI_API_KEY",
33561
+ openRouterModel: "google/gemini-2.0-flash"
33562
+ },
33563
+ "gemini-codeassist": {
33564
+ loginFlag: "--gemini-login",
33565
+ apiKeyEnvVar: "GEMINI_API_KEY",
33566
+ openRouterModel: "google/gemini-2.0-flash"
33567
+ },
33568
+ openai: {
33569
+ apiKeyEnvVar: "OPENAI_API_KEY",
33570
+ openRouterModel: "openai/gpt-4o"
33571
+ },
33572
+ minimax: {
33573
+ apiKeyEnvVar: "MINIMAX_API_KEY",
33574
+ openRouterModel: "minimax/minimax-01"
33575
+ },
33576
+ "minimax-coding": {
33577
+ apiKeyEnvVar: "MINIMAX_CODING_API_KEY"
33578
+ },
33579
+ glm: {
33580
+ apiKeyEnvVar: "ZHIPU_API_KEY",
33581
+ openRouterModel: "zhipuai/glm-4"
33582
+ },
33583
+ "glm-coding": {
33584
+ apiKeyEnvVar: "GLM_CODING_API_KEY"
33585
+ },
33586
+ ollamacloud: {
33587
+ apiKeyEnvVar: "OLLAMA_API_KEY"
33588
+ }
33589
+ };
33590
+ });
33591
+
33323
33592
  // src/providers/provider-resolver.ts
33324
33593
  var exports_provider_resolver = {};
33325
33594
  __export(exports_provider_resolver, {
@@ -33331,9 +33600,9 @@ __export(exports_provider_resolver, {
33331
33600
  getMissingKeyResolutions: () => getMissingKeyResolutions,
33332
33601
  getMissingKeyError: () => getMissingKeyError
33333
33602
  });
33334
- import { existsSync as existsSync8 } from "node:fs";
33335
- import { join as join8 } from "node:path";
33336
- import { homedir as homedir7 } from "node:os";
33603
+ import { existsSync as existsSync10 } from "node:fs";
33604
+ import { join as join10 } from "node:path";
33605
+ import { homedir as homedir9 } from "node:os";
33337
33606
  function isApiKeyAvailable(info) {
33338
33607
  if (!info.envVar) {
33339
33608
  return true;
@@ -33350,8 +33619,8 @@ function isApiKeyAvailable(info) {
33350
33619
  }
33351
33620
  if (info.oauthFallback) {
33352
33621
  try {
33353
- const credPath = join8(homedir7(), ".claudish", info.oauthFallback);
33354
- if (existsSync8(credPath)) {
33622
+ const credPath = join10(homedir9(), ".claudish", info.oauthFallback);
33623
+ if (existsSync10(credPath)) {
33355
33624
  return true;
33356
33625
  }
33357
33626
  } catch {}
@@ -33442,6 +33711,43 @@ function resolveModelProvider(modelId) {
33442
33711
  apiKeyUrl: info.url
33443
33712
  });
33444
33713
  }
33714
+ let pendingAutoRouteMessage;
33715
+ if (!parsed.isExplicitProvider && parsed.provider !== "native-anthropic") {
33716
+ const autoResult = autoRoute(parsed.model, parsed.provider);
33717
+ if (autoResult) {
33718
+ if (autoResult.provider === "litellm") {
33719
+ const info = API_KEY_INFO.litellm;
33720
+ return addCommonFields({
33721
+ category: "direct-api",
33722
+ providerName: "LiteLLM",
33723
+ modelName: autoResult.modelName,
33724
+ fullModelId: autoResult.resolvedModelId,
33725
+ requiredApiKeyEnvVar: info.envVar || null,
33726
+ apiKeyAvailable: isApiKeyAvailable(info),
33727
+ apiKeyDescription: info.description,
33728
+ apiKeyUrl: info.url,
33729
+ wasAutoRouted: true,
33730
+ autoRouteMessage: autoResult.displayMessage
33731
+ });
33732
+ }
33733
+ if (autoResult.provider === "openrouter") {
33734
+ const info = API_KEY_INFO.openrouter;
33735
+ return addCommonFields({
33736
+ category: "openrouter",
33737
+ providerName: "OpenRouter",
33738
+ modelName: autoResult.modelName,
33739
+ fullModelId: autoResult.resolvedModelId,
33740
+ requiredApiKeyEnvVar: info.envVar,
33741
+ apiKeyAvailable: isApiKeyAvailable(info),
33742
+ apiKeyDescription: info.description,
33743
+ apiKeyUrl: info.url,
33744
+ wasAutoRouted: true,
33745
+ autoRouteMessage: autoResult.displayMessage
33746
+ });
33747
+ }
33748
+ pendingAutoRouteMessage = autoResult.displayMessage;
33749
+ }
33750
+ }
33445
33751
  const remoteResolved = resolveRemoteProvider(modelId);
33446
33752
  if (remoteResolved) {
33447
33753
  const provider = remoteResolved.provider;
@@ -33451,6 +33757,7 @@ function resolveModelProvider(modelId) {
33451
33757
  url: ""
33452
33758
  };
33453
33759
  const providerDisplayName = PROVIDER_DISPLAY_NAMES[provider.name] || provider.name.charAt(0).toUpperCase() + provider.name.slice(1);
33760
+ const wasAutoRouted = !parsed.isExplicitProvider;
33454
33761
  return addCommonFields({
33455
33762
  category: "direct-api",
33456
33763
  providerName: providerDisplayName,
@@ -33459,7 +33766,9 @@ function resolveModelProvider(modelId) {
33459
33766
  requiredApiKeyEnvVar: info.envVar || null,
33460
33767
  apiKeyAvailable: isApiKeyAvailable(info),
33461
33768
  apiKeyDescription: info.envVar ? info.description : null,
33462
- apiKeyUrl: info.envVar ? info.url : null
33769
+ apiKeyUrl: info.envVar ? info.url : null,
33770
+ wasAutoRouted,
33771
+ autoRouteMessage: wasAutoRouted ? pendingAutoRouteMessage ?? `Auto-routed: ${parsed.model} -> ${providerDisplayName}` : undefined
33463
33772
  });
33464
33773
  }
33465
33774
  if (parsed.provider === "unknown") {
@@ -33522,6 +33831,16 @@ function getMissingKeyError(resolution) {
33522
33831
  lines.push("");
33523
33832
  lines.push(`Get your API key from: ${resolution.apiKeyUrl}`);
33524
33833
  }
33834
+ {
33835
+ const parsed = resolution.parsed;
33836
+ if (parsed && !parsed.isExplicitProvider && parsed.provider !== "unknown" && parsed.provider !== "native-anthropic") {
33837
+ const hint = getAutoRouteHint(parsed.model, parsed.provider);
33838
+ if (hint) {
33839
+ lines.push("");
33840
+ lines.push(hint);
33841
+ }
33842
+ }
33843
+ }
33525
33844
  if (resolution.category === "openrouter") {
33526
33845
  const provider = resolution.fullModelId.split("/")[0];
33527
33846
  lines.push("");
@@ -33582,6 +33901,7 @@ var API_KEY_INFO, PROVIDER_DISPLAY_NAMES;
33582
33901
  var init_provider_resolver = __esm(() => {
33583
33902
  init_provider_registry();
33584
33903
  init_remote_provider_registry();
33904
+ init_auto_route();
33585
33905
  init_model_parser();
33586
33906
  API_KEY_INFO = {
33587
33907
  openrouter: {
@@ -33697,16 +34017,16 @@ __export(exports_cli, {
33697
34017
  getMissingKeyResolutions: () => getMissingKeyResolutions,
33698
34018
  getMissingKeyError: () => getMissingKeyError
33699
34019
  });
33700
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync6, existsSync as existsSync9, mkdirSync as mkdirSync6, copyFileSync, readdirSync, unlinkSync as unlinkSync3 } from "node:fs";
34020
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync6, copyFileSync, readdirSync, unlinkSync as unlinkSync3 } from "node:fs";
33701
34021
  import { fileURLToPath as fileURLToPath4 } from "node:url";
33702
- import { dirname as dirname4, join as join9 } from "node:path";
33703
- import { homedir as homedir8 } from "node:os";
34022
+ import { dirname as dirname4, join as join11 } from "node:path";
34023
+ import { homedir as homedir10 } from "node:os";
33704
34024
  function getVersion() {
33705
34025
  return VERSION;
33706
34026
  }
33707
34027
  function clearAllModelCaches() {
33708
- const cacheDir = join9(homedir8(), ".claudish");
33709
- if (!existsSync9(cacheDir))
34028
+ const cacheDir = join11(homedir10(), ".claudish");
34029
+ if (!existsSync11(cacheDir))
33710
34030
  return;
33711
34031
  const cachePatterns = ["all-models.json", "pricing-cache.json"];
33712
34032
  let cleared = 0;
@@ -33714,7 +34034,7 @@ function clearAllModelCaches() {
33714
34034
  const files = readdirSync(cacheDir);
33715
34035
  for (const file2 of files) {
33716
34036
  if (cachePatterns.includes(file2) || file2.startsWith("litellm-models-")) {
33717
- unlinkSync3(join9(cacheDir, file2));
34037
+ unlinkSync3(join11(cacheDir, file2));
33718
34038
  cleared++;
33719
34039
  }
33720
34040
  }
@@ -33983,9 +34303,9 @@ async function fetchOllamaModels() {
33983
34303
  }
33984
34304
  async function searchAndPrintModels(query, forceUpdate) {
33985
34305
  let models = [];
33986
- if (!forceUpdate && existsSync9(ALL_MODELS_JSON_PATH2)) {
34306
+ if (!forceUpdate && existsSync11(ALL_MODELS_JSON_PATH2)) {
33987
34307
  try {
33988
- const cacheData = JSON.parse(readFileSync7(ALL_MODELS_JSON_PATH2, "utf-8"));
34308
+ const cacheData = JSON.parse(readFileSync9(ALL_MODELS_JSON_PATH2, "utf-8"));
33989
34309
  const lastUpdated = new Date(cacheData.lastUpdated);
33990
34310
  const now = new Date;
33991
34311
  const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
@@ -34153,9 +34473,9 @@ Found ${results.length} matching models:
34153
34473
  async function printAllModels(jsonOutput, forceUpdate) {
34154
34474
  let models = [];
34155
34475
  const [ollamaModels, zenModels] = await Promise.all([fetchOllamaModels(), fetchZenModels()]);
34156
- if (!forceUpdate && existsSync9(ALL_MODELS_JSON_PATH2)) {
34476
+ if (!forceUpdate && existsSync11(ALL_MODELS_JSON_PATH2)) {
34157
34477
  try {
34158
- const cacheData = JSON.parse(readFileSync7(ALL_MODELS_JSON_PATH2, "utf-8"));
34478
+ const cacheData = JSON.parse(readFileSync9(ALL_MODELS_JSON_PATH2, "utf-8"));
34159
34479
  const lastUpdated = new Date(cacheData.lastUpdated);
34160
34480
  const now = new Date;
34161
34481
  const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
@@ -34356,11 +34676,11 @@ async function printAllModels(jsonOutput, forceUpdate) {
34356
34676
  console.log("Top models: claudish --top-models");
34357
34677
  }
34358
34678
  function isCacheStale() {
34359
- if (!existsSync9(MODELS_JSON_PATH)) {
34679
+ if (!existsSync11(MODELS_JSON_PATH)) {
34360
34680
  return true;
34361
34681
  }
34362
34682
  try {
34363
- const jsonContent = readFileSync7(MODELS_JSON_PATH, "utf-8");
34683
+ const jsonContent = readFileSync9(MODELS_JSON_PATH, "utf-8");
34364
34684
  const data = JSON.parse(jsonContent);
34365
34685
  if (!data.lastUpdated) {
34366
34686
  return true;
@@ -34455,9 +34775,9 @@ async function updateModelsFromOpenRouter() {
34455
34775
  providers.add(provider);
34456
34776
  }
34457
34777
  let version2 = "1.1.5";
34458
- if (existsSync9(MODELS_JSON_PATH)) {
34778
+ if (existsSync11(MODELS_JSON_PATH)) {
34459
34779
  try {
34460
- const existing = JSON.parse(readFileSync7(MODELS_JSON_PATH, "utf-8"));
34780
+ const existing = JSON.parse(readFileSync9(MODELS_JSON_PATH, "utf-8"));
34461
34781
  version2 = existing.version || version2;
34462
34782
  } catch {}
34463
34783
  }
@@ -34485,7 +34805,7 @@ async function checkAndUpdateModelsCache(forceUpdate = false) {
34485
34805
  await updateModelsFromOpenRouter();
34486
34806
  } else {
34487
34807
  try {
34488
- const data = JSON.parse(readFileSync7(MODELS_JSON_PATH, "utf-8"));
34808
+ const data = JSON.parse(readFileSync9(MODELS_JSON_PATH, "utf-8"));
34489
34809
  console.error(`✓ Using cached models (last updated: ${data.lastUpdated})`);
34490
34810
  } catch {}
34491
34811
  }
@@ -34789,8 +35109,8 @@ MORE INFO:
34789
35109
  }
34790
35110
  function printAIAgentGuide() {
34791
35111
  try {
34792
- const guidePath = join9(__dirname5, "../AI_AGENT_GUIDE.md");
34793
- const guideContent = readFileSync7(guidePath, "utf-8");
35112
+ const guidePath = join11(__dirname5, "../AI_AGENT_GUIDE.md");
35113
+ const guideContent = readFileSync9(guidePath, "utf-8");
34794
35114
  console.log(guideContent);
34795
35115
  } catch (error46) {
34796
35116
  console.error("Error reading AI Agent Guide:");
@@ -34806,19 +35126,19 @@ async function initializeClaudishSkill() {
34806
35126
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
34807
35127
  `);
34808
35128
  const cwd = process.cwd();
34809
- const claudeDir = join9(cwd, ".claude");
34810
- const skillsDir = join9(claudeDir, "skills");
34811
- const claudishSkillDir = join9(skillsDir, "claudish-usage");
34812
- const skillFile = join9(claudishSkillDir, "SKILL.md");
34813
- if (existsSync9(skillFile)) {
35129
+ const claudeDir = join11(cwd, ".claude");
35130
+ const skillsDir = join11(claudeDir, "skills");
35131
+ const claudishSkillDir = join11(skillsDir, "claudish-usage");
35132
+ const skillFile = join11(claudishSkillDir, "SKILL.md");
35133
+ if (existsSync11(skillFile)) {
34814
35134
  console.log("✅ Claudish skill already installed at:");
34815
35135
  console.log(` ${skillFile}
34816
35136
  `);
34817
35137
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
34818
35138
  return;
34819
35139
  }
34820
- const sourceSkillPath = join9(__dirname5, "../skills/claudish-usage/SKILL.md");
34821
- if (!existsSync9(sourceSkillPath)) {
35140
+ const sourceSkillPath = join11(__dirname5, "../skills/claudish-usage/SKILL.md");
35141
+ if (!existsSync11(sourceSkillPath)) {
34822
35142
  console.error("❌ Error: Claudish skill file not found in installation.");
34823
35143
  console.error(` Expected at: ${sourceSkillPath}`);
34824
35144
  console.error(`
@@ -34827,15 +35147,15 @@ async function initializeClaudishSkill() {
34827
35147
  process.exit(1);
34828
35148
  }
34829
35149
  try {
34830
- if (!existsSync9(claudeDir)) {
35150
+ if (!existsSync11(claudeDir)) {
34831
35151
  mkdirSync6(claudeDir, { recursive: true });
34832
35152
  console.log("\uD83D\uDCC1 Created .claude/ directory");
34833
35153
  }
34834
- if (!existsSync9(skillsDir)) {
35154
+ if (!existsSync11(skillsDir)) {
34835
35155
  mkdirSync6(skillsDir, { recursive: true });
34836
35156
  console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
34837
35157
  }
34838
- if (!existsSync9(claudishSkillDir)) {
35158
+ if (!existsSync11(claudishSkillDir)) {
34839
35159
  mkdirSync6(claudishSkillDir, { recursive: true });
34840
35160
  console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
34841
35161
  }
@@ -34878,8 +35198,8 @@ function printAvailableModels() {
34878
35198
  let lastUpdated = "unknown";
34879
35199
  let models = [];
34880
35200
  try {
34881
- if (existsSync9(MODELS_JSON_PATH)) {
34882
- const data = JSON.parse(readFileSync7(MODELS_JSON_PATH, "utf-8"));
35201
+ if (existsSync11(MODELS_JSON_PATH)) {
35202
+ const data = JSON.parse(readFileSync9(MODELS_JSON_PATH, "utf-8"));
34883
35203
  lastUpdated = data.lastUpdated || "unknown";
34884
35204
  models = data.models || [];
34885
35205
  }
@@ -34932,9 +35252,9 @@ Force update: claudish --list-models --force-update
34932
35252
  `);
34933
35253
  }
34934
35254
  function printAvailableModelsJSON() {
34935
- const jsonPath = join9(__dirname5, "../recommended-models.json");
35255
+ const jsonPath = join11(__dirname5, "../recommended-models.json");
34936
35256
  try {
34937
- const jsonContent = readFileSync7(jsonPath, "utf-8");
35257
+ const jsonContent = readFileSync9(jsonPath, "utf-8");
34938
35258
  const data = JSON.parse(jsonContent);
34939
35259
  const outputData = {
34940
35260
  ...data,
@@ -35026,7 +35346,7 @@ async function fetchGLMCodingModels2() {
35026
35346
  return [];
35027
35347
  }
35028
35348
  }
35029
- var __filename5, __dirname5, VERSION = "5.1.1", CACHE_MAX_AGE_DAYS3 = 2, MODELS_JSON_PATH, CLAUDISH_CACHE_DIR3, ALL_MODELS_JSON_PATH2;
35349
+ var __filename5, __dirname5, VERSION = "5.2.0", CACHE_MAX_AGE_DAYS3 = 2, MODELS_JSON_PATH, CLAUDISH_CACHE_DIR3, ALL_MODELS_JSON_PATH2;
35030
35350
  var init_cli = __esm(() => {
35031
35351
  init_config();
35032
35352
  init_model_loader();
@@ -35035,12 +35355,12 @@ var init_cli = __esm(() => {
35035
35355
  __filename5 = fileURLToPath4(import.meta.url);
35036
35356
  __dirname5 = dirname4(__filename5);
35037
35357
  try {
35038
- const packageJson = JSON.parse(readFileSync7(join9(__dirname5, "../package.json"), "utf-8"));
35358
+ const packageJson = JSON.parse(readFileSync9(join11(__dirname5, "../package.json"), "utf-8"));
35039
35359
  VERSION = packageJson.version;
35040
35360
  } catch {}
35041
- MODELS_JSON_PATH = join9(__dirname5, "../recommended-models.json");
35042
- CLAUDISH_CACHE_DIR3 = join9(homedir8(), ".claudish");
35043
- ALL_MODELS_JSON_PATH2 = join9(CLAUDISH_CACHE_DIR3, "all-models.json");
35361
+ MODELS_JSON_PATH = join11(__dirname5, "../recommended-models.json");
35362
+ CLAUDISH_CACHE_DIR3 = join11(homedir10(), ".claudish");
35363
+ ALL_MODELS_JSON_PATH2 = join11(CLAUDISH_CACHE_DIR3, "all-models.json");
35044
35364
  });
35045
35365
 
35046
35366
  // src/claude-runner.ts
@@ -35050,17 +35370,17 @@ __export(exports_claude_runner, {
35050
35370
  checkClaudeInstalled: () => checkClaudeInstalled
35051
35371
  });
35052
35372
  import { spawn } from "node:child_process";
35053
- import { writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, mkdirSync as mkdirSync7, existsSync as existsSync10 } from "node:fs";
35054
- import { tmpdir, homedir as homedir9 } from "node:os";
35055
- import { join as join10 } from "node:path";
35373
+ import { writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, mkdirSync as mkdirSync7, existsSync as existsSync12 } from "node:fs";
35374
+ import { tmpdir, homedir as homedir11 } from "node:os";
35375
+ import { join as join12 } from "node:path";
35056
35376
  function isWindows() {
35057
35377
  return process.platform === "win32";
35058
35378
  }
35059
35379
  function createStatusLineScript(tokenFilePath) {
35060
35380
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir();
35061
- const claudishDir = join10(homeDir, ".claudish");
35381
+ const claudishDir = join12(homeDir, ".claudish");
35062
35382
  const timestamp = Date.now();
35063
- const scriptPath = join10(claudishDir, `status-${timestamp}.js`);
35383
+ const scriptPath = join12(claudishDir, `status-${timestamp}.js`);
35064
35384
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
35065
35385
  const script = `
35066
35386
  const fs = require('fs');
@@ -35145,13 +35465,13 @@ process.stdin.on('end', () => {
35145
35465
  }
35146
35466
  function createTempSettingsFile(modelDisplay, port) {
35147
35467
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir();
35148
- const claudishDir = join10(homeDir, ".claudish");
35468
+ const claudishDir = join12(homeDir, ".claudish");
35149
35469
  try {
35150
35470
  mkdirSync7(claudishDir, { recursive: true });
35151
35471
  } catch {}
35152
35472
  const timestamp = Date.now();
35153
- const tempPath = join10(claudishDir, `settings-${timestamp}.json`);
35154
- const tokenFilePath = join10(claudishDir, `tokens-${port}.json`);
35473
+ const tempPath = join12(claudishDir, `settings-${timestamp}.json`);
35474
+ const tokenFilePath = join12(claudishDir, `tokens-${port}.json`);
35155
35475
  let statusCommand;
35156
35476
  if (isWindows()) {
35157
35477
  const scriptPath = createStatusLineScript(tokenFilePath);
@@ -35257,8 +35577,8 @@ async function runClaudeWithProxy(config3, proxyUrl) {
35257
35577
  console.error("Install it from: https://claude.com/claude-code");
35258
35578
  console.error(`
35259
35579
  Or set CLAUDE_PATH to your custom installation:`);
35260
- const home = homedir9();
35261
- const localPath = isWindows() ? join10(home, ".claude", "local", "claude.exe") : join10(home, ".claude", "local", "claude");
35580
+ const home = homedir11();
35581
+ const localPath = isWindows() ? join12(home, ".claude", "local", "claude.exe") : join12(home, ".claude", "local", "claude");
35262
35582
  console.error(` export CLAUDE_PATH=${localPath}`);
35263
35583
  process.exit(1);
35264
35584
  }
@@ -35297,23 +35617,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet) {
35297
35617
  async function findClaudeBinary() {
35298
35618
  const isWindows2 = process.platform === "win32";
35299
35619
  if (process.env.CLAUDE_PATH) {
35300
- if (existsSync10(process.env.CLAUDE_PATH)) {
35620
+ if (existsSync12(process.env.CLAUDE_PATH)) {
35301
35621
  return process.env.CLAUDE_PATH;
35302
35622
  }
35303
35623
  }
35304
- const home = homedir9();
35305
- const localPath = isWindows2 ? join10(home, ".claude", "local", "claude.exe") : join10(home, ".claude", "local", "claude");
35306
- if (existsSync10(localPath)) {
35624
+ const home = homedir11();
35625
+ const localPath = isWindows2 ? join12(home, ".claude", "local", "claude.exe") : join12(home, ".claude", "local", "claude");
35626
+ if (existsSync12(localPath)) {
35307
35627
  return localPath;
35308
35628
  }
35309
35629
  if (isWindows2) {
35310
35630
  const windowsPaths = [
35311
- join10(home, "AppData", "Roaming", "npm", "claude.cmd"),
35312
- join10(home, ".npm-global", "claude.cmd"),
35313
- join10(home, "node_modules", ".bin", "claude.cmd")
35631
+ join12(home, "AppData", "Roaming", "npm", "claude.cmd"),
35632
+ join12(home, ".npm-global", "claude.cmd"),
35633
+ join12(home, "node_modules", ".bin", "claude.cmd")
35314
35634
  ];
35315
35635
  for (const path of windowsPaths) {
35316
- if (existsSync10(path)) {
35636
+ if (existsSync12(path)) {
35317
35637
  return path;
35318
35638
  }
35319
35639
  }
@@ -35321,14 +35641,14 @@ async function findClaudeBinary() {
35321
35641
  const commonPaths = [
35322
35642
  "/usr/local/bin/claude",
35323
35643
  "/opt/homebrew/bin/claude",
35324
- join10(home, ".npm-global/bin/claude"),
35325
- join10(home, ".local/bin/claude"),
35326
- join10(home, "node_modules/.bin/claude"),
35644
+ join12(home, ".npm-global/bin/claude"),
35645
+ join12(home, ".local/bin/claude"),
35646
+ join12(home, "node_modules/.bin/claude"),
35327
35647
  "/data/data/com.termux/files/usr/bin/claude",
35328
- join10(home, "../usr/bin/claude")
35648
+ join12(home, "../usr/bin/claude")
35329
35649
  ];
35330
35650
  for (const path of commonPaths) {
35331
- if (existsSync10(path)) {
35651
+ if (existsSync12(path)) {
35332
35652
  return path;
35333
35653
  }
35334
35654
  }
@@ -61219,9 +61539,9 @@ var init_gemini_codeassist = __esm(() => {
61219
61539
  // src/auth/vertex-auth.ts
61220
61540
  import { exec as exec4 } from "node:child_process";
61221
61541
  import { promisify as promisify3 } from "node:util";
61222
- import { existsSync as existsSync11 } from "node:fs";
61223
- import { homedir as homedir10 } from "node:os";
61224
- import { join as join11 } from "node:path";
61542
+ import { existsSync as existsSync13 } from "node:fs";
61543
+ import { homedir as homedir12 } from "node:os";
61544
+ import { join as join13 } from "node:path";
61225
61545
 
61226
61546
  class VertexAuthManager {
61227
61547
  cachedToken = null;
@@ -61275,8 +61595,8 @@ class VertexAuthManager {
61275
61595
  }
61276
61596
  async tryADC() {
61277
61597
  try {
61278
- const adcPath = join11(homedir10(), ".config/gcloud/application_default_credentials.json");
61279
- if (!existsSync11(adcPath)) {
61598
+ const adcPath = join13(homedir12(), ".config/gcloud/application_default_credentials.json");
61599
+ if (!existsSync13(adcPath)) {
61280
61600
  log("[VertexAuth] ADC credentials file not found");
61281
61601
  return null;
61282
61602
  }
@@ -61300,7 +61620,7 @@ class VertexAuthManager {
61300
61620
  if (!credPath) {
61301
61621
  return null;
61302
61622
  }
61303
- if (!existsSync11(credPath)) {
61623
+ if (!existsSync13(credPath)) {
61304
61624
  throw new Error(`Service account file not found: ${credPath}
61305
61625
 
61306
61626
  Check GOOGLE_APPLICATION_CREDENTIALS path.`);
@@ -61339,8 +61659,8 @@ function validateVertexOAuthConfig() {
61339
61659
  ` + ` export VERTEX_PROJECT='your-gcp-project-id'
61340
61660
  ` + " export VERTEX_LOCATION='us-central1' # optional";
61341
61661
  }
61342
- const adcPath = join11(homedir10(), ".config/gcloud/application_default_credentials.json");
61343
- const hasADC = existsSync11(adcPath);
61662
+ const adcPath = join13(homedir12(), ".config/gcloud/application_default_credentials.json");
61663
+ const hasADC = existsSync13(adcPath);
61344
61664
  const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
61345
61665
  if (!hasADC && !hasServiceAccount) {
61346
61666
  return `No Vertex AI credentials found.
@@ -61736,8 +62056,8 @@ var init_middleware = __esm(() => {
61736
62056
 
61737
62057
  // src/handlers/shared/token-tracker.ts
61738
62058
  import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "node:fs";
61739
- import { homedir as homedir11 } from "node:os";
61740
- import { join as join12 } from "node:path";
62059
+ import { homedir as homedir13 } from "node:os";
62060
+ import { join as join14 } from "node:path";
61741
62061
 
61742
62062
  class TokenTracker {
61743
62063
  port;
@@ -61851,9 +62171,9 @@ class TokenTracker {
61851
62171
  is_free: isFreeModel,
61852
62172
  is_estimated: isEstimate || false
61853
62173
  };
61854
- const claudishDir = join12(homedir11(), ".claudish");
62174
+ const claudishDir = join14(homedir13(), ".claudish");
61855
62175
  mkdirSync8(claudishDir, { recursive: true });
61856
- writeFileSync8(join12(claudishDir, `tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
62176
+ writeFileSync8(join14(claudishDir, `tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
61857
62177
  } catch (e) {
61858
62178
  log(`[TokenTracker] Error writing token file: ${e}`);
61859
62179
  }
@@ -63048,10 +63368,10 @@ var init_litellm = __esm(() => {
63048
63368
  });
63049
63369
 
63050
63370
  // src/adapters/litellm-adapter.ts
63051
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
63052
- import { createHash as createHash3 } from "node:crypto";
63053
- import { homedir as homedir12 } from "node:os";
63054
- import { join as join13 } from "node:path";
63371
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "node:fs";
63372
+ import { createHash as createHash4 } from "node:crypto";
63373
+ import { homedir as homedir14 } from "node:os";
63374
+ import { join as join15 } from "node:path";
63055
63375
  var INLINE_IMAGE_MODEL_PATTERNS, LiteLLMAdapter;
63056
63376
  var init_litellm_adapter = __esm(() => {
63057
63377
  init_base_adapter();
@@ -63146,11 +63466,11 @@ var init_litellm_adapter = __esm(() => {
63146
63466
  }
63147
63467
  checkVisionSupport() {
63148
63468
  try {
63149
- const hash2 = createHash3("sha256").update(this.baseUrl).digest("hex").substring(0, 16);
63150
- const cachePath = join13(homedir12(), ".claudish", `litellm-models-${hash2}.json`);
63151
- if (!existsSync12(cachePath))
63469
+ const hash2 = createHash4("sha256").update(this.baseUrl).digest("hex").substring(0, 16);
63470
+ const cachePath = join15(homedir14(), ".claudish", `litellm-models-${hash2}.json`);
63471
+ if (!existsSync14(cachePath))
63152
63472
  return true;
63153
- const cacheData = JSON.parse(readFileSync9(cachePath, "utf-8"));
63473
+ const cacheData = JSON.parse(readFileSync11(cachePath, "utf-8"));
63154
63474
  const model = cacheData.models?.find((m) => m.name === this.modelId);
63155
63475
  if (model && model.supportsVision === false) {
63156
63476
  log(`[LiteLLMAdapter] Model ${this.modelId} does not support vision`);
@@ -63268,12 +63588,12 @@ class AnthropicCompatProvider {
63268
63588
  }
63269
63589
  if (this.provider.name === "kimi-coding" && !this.apiKey) {
63270
63590
  try {
63271
- const { existsSync: existsSync13, readFileSync: readFileSync10 } = await import("node:fs");
63272
- const { join: join14 } = await import("node:path");
63273
- const { homedir: homedir13 } = await import("node:os");
63274
- const credPath = join14(homedir13(), ".claudish", "kimi-oauth.json");
63275
- if (existsSync13(credPath)) {
63276
- const data = JSON.parse(readFileSync10(credPath, "utf-8"));
63591
+ const { existsSync: existsSync15, readFileSync: readFileSync12 } = await import("node:fs");
63592
+ const { join: join16 } = await import("node:path");
63593
+ const { homedir: homedir15 } = await import("node:os");
63594
+ const credPath = join16(homedir15(), ".claudish", "kimi-oauth.json");
63595
+ if (existsSync15(credPath)) {
63596
+ const data = JSON.parse(readFileSync12(credPath, "utf-8"));
63277
63597
  if (data.access_token && data.refresh_token) {
63278
63598
  const { KimiOAuth: KimiOAuth2 } = await Promise.resolve().then(() => (init_kimi_oauth(), exports_kimi_oauth));
63279
63599
  const oauth = KimiOAuth2.getInstance();
@@ -63495,9 +63815,9 @@ var init_ollamacloud_adapter = __esm(() => {
63495
63815
  });
63496
63816
 
63497
63817
  // src/services/pricing-cache.ts
63498
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync9, existsSync as existsSync13, mkdirSync as mkdirSync9, statSync } from "node:fs";
63499
- import { homedir as homedir13 } from "node:os";
63500
- import { join as join14 } from "node:path";
63818
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, existsSync as existsSync15, mkdirSync as mkdirSync9, statSync } from "node:fs";
63819
+ import { homedir as homedir15 } from "node:os";
63820
+ import { join as join16 } from "node:path";
63501
63821
  function getDynamicPricingSync(provider, modelName) {
63502
63822
  if (provider === "openrouter") {
63503
63823
  const direct = pricingMap.get(modelName);
@@ -63562,12 +63882,12 @@ async function warmPricingCache() {
63562
63882
  }
63563
63883
  function loadDiskCache() {
63564
63884
  try {
63565
- if (!existsSync13(CACHE_FILE))
63885
+ if (!existsSync15(CACHE_FILE))
63566
63886
  return false;
63567
63887
  const stat = statSync(CACHE_FILE);
63568
63888
  const age = Date.now() - stat.mtimeMs;
63569
63889
  const isFresh = age < CACHE_TTL_MS;
63570
- const raw2 = readFileSync10(CACHE_FILE, "utf-8");
63890
+ const raw2 = readFileSync12(CACHE_FILE, "utf-8");
63571
63891
  const data = JSON.parse(raw2);
63572
63892
  for (const [key, pricing] of Object.entries(data)) {
63573
63893
  pricingMap.set(key, pricing);
@@ -63614,8 +63934,8 @@ var init_pricing_cache = __esm(() => {
63614
63934
  init_model_loader();
63615
63935
  init_remote_provider_types();
63616
63936
  pricingMap = new Map;
63617
- CACHE_DIR = join14(homedir13(), ".claudish");
63618
- CACHE_FILE = join14(CACHE_DIR, "pricing-cache.json");
63937
+ CACHE_DIR = join16(homedir15(), ".claudish");
63938
+ CACHE_FILE = join16(CACHE_DIR, "pricing-cache.json");
63619
63939
  CACHE_TTL_MS = 24 * 60 * 60 * 1000;
63620
63940
  PROVIDER_TO_OR_PREFIX = {
63621
63941
  openai: ["openai/"],
@@ -63710,11 +64030,18 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
63710
64030
  return remoteProviderHandlers.get(targetModel);
63711
64031
  }
63712
64032
  const resolution = resolveModelProvider(targetModel);
64033
+ if (resolution.wasAutoRouted && resolution.autoRouteMessage) {
64034
+ console.error(`[Auto-route] ${resolution.autoRouteMessage}`);
64035
+ }
63713
64036
  if (resolution.category === "openrouter") {
64037
+ if (resolution.wasAutoRouted && resolution.fullModelId) {
64038
+ return getOpenRouterHandler(resolution.fullModelId);
64039
+ }
63714
64040
  return null;
63715
64041
  }
64042
+ const resolveTarget = resolution.wasAutoRouted && resolution.fullModelId ? resolution.fullModelId : targetModel;
63716
64043
  if (resolution.category === "direct-api" && resolution.apiKeyAvailable) {
63717
- const resolved = resolveRemoteProvider(targetModel);
64044
+ const resolved = resolveRemoteProvider(resolveTarget);
63718
64045
  if (!resolved)
63719
64046
  return null;
63720
64047
  if (resolved.provider.name === "openrouter") {
@@ -63838,11 +64165,19 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
63838
64165
  } else {
63839
64166
  return null;
63840
64167
  }
63841
- remoteProviderHandlers.set(targetModel, handler);
64168
+ remoteProviderHandlers.set(resolveTarget, handler);
64169
+ if (resolveTarget !== targetModel) {
64170
+ remoteProviderHandlers.set(targetModel, handler);
64171
+ }
63842
64172
  return handler;
63843
64173
  }
63844
64174
  return null;
63845
64175
  };
64176
+ if (process.env.LITELLM_BASE_URL && process.env.LITELLM_API_KEY) {
64177
+ fetchLiteLLMModels(process.env.LITELLM_BASE_URL, process.env.LITELLM_API_KEY).then(() => {
64178
+ log("[Proxy] LiteLLM model cache pre-warmed for auto-routing");
64179
+ }).catch(() => {});
64180
+ }
63846
64181
  const getHandlerForRequest = (requestedModel) => {
63847
64182
  if (monitorMode)
63848
64183
  return nativeHandler;
@@ -63965,6 +64300,7 @@ var init_proxy_server = __esm(() => {
63965
64300
  init_vertex_auth();
63966
64301
  init_provider_resolver();
63967
64302
  init_pricing_cache();
64303
+ init_model_loader();
63968
64304
  });
63969
64305
 
63970
64306
  // src/update-checker.ts
@@ -63976,9 +64312,9 @@ __export(exports_update_checker, {
63976
64312
  checkForUpdates: () => checkForUpdates
63977
64313
  });
63978
64314
  import { execSync } from "node:child_process";
63979
- import { existsSync as existsSync14, mkdirSync as mkdirSync10, readFileSync as readFileSync11, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "node:fs";
63980
- import { homedir as homedir14, platform as platform2, tmpdir as tmpdir2 } from "node:os";
63981
- import { join as join15 } from "node:path";
64315
+ import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as readFileSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "node:fs";
64316
+ import { homedir as homedir16, platform as platform2, tmpdir as tmpdir2 } from "node:os";
64317
+ import { join as join17 } from "node:path";
63982
64318
  import { createInterface as createInterface2 } from "node:readline";
63983
64319
  function getUpdateCommand() {
63984
64320
  const scriptPath = process.argv[1] || "";
@@ -63990,27 +64326,27 @@ function getUpdateCommand() {
63990
64326
  function getCacheFilePath() {
63991
64327
  let cacheDir;
63992
64328
  if (isWindows2) {
63993
- const localAppData = process.env.LOCALAPPDATA || join15(homedir14(), "AppData", "Local");
63994
- cacheDir = join15(localAppData, "claudish");
64329
+ const localAppData = process.env.LOCALAPPDATA || join17(homedir16(), "AppData", "Local");
64330
+ cacheDir = join17(localAppData, "claudish");
63995
64331
  } else {
63996
- cacheDir = join15(homedir14(), ".cache", "claudish");
64332
+ cacheDir = join17(homedir16(), ".cache", "claudish");
63997
64333
  }
63998
64334
  try {
63999
- if (!existsSync14(cacheDir)) {
64335
+ if (!existsSync16(cacheDir)) {
64000
64336
  mkdirSync10(cacheDir, { recursive: true });
64001
64337
  }
64002
- return join15(cacheDir, "update-check.json");
64338
+ return join17(cacheDir, "update-check.json");
64003
64339
  } catch {
64004
- return join15(tmpdir2(), "claudish-update-check.json");
64340
+ return join17(tmpdir2(), "claudish-update-check.json");
64005
64341
  }
64006
64342
  }
64007
64343
  function readCache() {
64008
64344
  try {
64009
64345
  const cachePath = getCacheFilePath();
64010
- if (!existsSync14(cachePath)) {
64346
+ if (!existsSync16(cachePath)) {
64011
64347
  return null;
64012
64348
  }
64013
- const data = JSON.parse(readFileSync11(cachePath, "utf-8"));
64349
+ const data = JSON.parse(readFileSync13(cachePath, "utf-8"));
64014
64350
  return data;
64015
64351
  } catch {
64016
64352
  return null;
@@ -64033,7 +64369,7 @@ function isCacheValid(cache) {
64033
64369
  function clearCache() {
64034
64370
  try {
64035
64371
  const cachePath = getCacheFilePath();
64036
- if (existsSync14(cachePath)) {
64372
+ if (existsSync16(cachePath)) {
64037
64373
  unlinkSync5(cachePath);
64038
64374
  }
64039
64375
  } catch {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "5.1.1",
3
+ "version": "5.2.0",
4
4
  "description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "1.2.0",
3
- "lastUpdated": "2026-02-25",
3
+ "lastUpdated": "2026-02-26",
4
4
  "source": "https://openrouter.ai/models?categories=programming&fmt=cards&order=top-weekly",
5
5
  "models": [
6
6
  {