claudish 10.6.0 → 10.6.2

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/AI_AGENT_GUIDE.md CHANGED
@@ -437,52 +437,75 @@ Claude: [calls compare_models tool with models=["openai/gpt-5.3", "google/gemini
437
437
  ### JSON Output (Recommended)
438
438
 
439
439
  ```bash
440
- claudish --models --json
440
+ claudish --models-top --json
441
441
  ```
442
442
 
443
- **Output:**
443
+ **Output** (abridged; one row shown):
444
444
  ```json
445
445
  {
446
- "version": "1.8.0",
447
- "lastUpdated": "2025-11-19",
448
- "source": "https://openrouter.ai/models",
446
+ "contractVersion": 3,
447
+ "generationId": "g-20261016120000000-abcdef12",
448
+ "version": "g-20261016120000000-abcdef12",
449
+ "lastUpdated": "2026-10-16T12:00:00.000Z",
450
+ "generatedAt": "2026-10-16T12:00:00.000Z",
451
+ "recommendationTiers": ["flagship", "cost_efficient", "lightweight", "luxury", "subscription"],
449
452
  "models": [
450
453
  {
451
- "id": "x-ai/grok-code-fast-1",
454
+ "id": "grok-code-fast-1",
452
455
  "name": "Grok Code Fast 1",
453
456
  "description": "Ultra-fast agentic coding",
454
- "provider": "xAI",
455
- "category": "coding",
457
+ "provider": "x-ai",
458
+ "recommendationTier": "flagship",
456
459
  "priority": 1,
457
460
  "pricing": {
458
- "input": "$0.20/1M",
459
- "output": "$1.50/1M",
461
+ "input": "$0.2/1M",
462
+ "output": "$1.5/1M",
460
463
  "average": "$0.85/1M"
461
464
  },
462
- "context": "256K",
463
- "supportsTools": true,
464
- "supportsReasoning": true
465
+ "context": "256000"
465
466
  }
466
467
  ]
467
468
  }
468
469
  ```
469
470
 
471
+ `recommendationTier` is one of `flagship`, `cost_efficient`, `lightweight`, `luxury` or
472
+ `subscription`; `recommendationTiers` lists the tiers this claudish version knows. `priority` is
473
+ the rank within that tier, from 1. A model listed in two tiers is two rows, so dedupe ids
474
+ yourself. Only `subscription` rows carry `subscriptions[].command`, the model spec to run.
475
+ Prices are `"N/A"` when the catalog has none.
476
+
477
+ `claudish --models --json` prints the full catalog instead; its records carry no
478
+ `recommendationTier`.
479
+
480
+ ### Filter with jq
481
+
482
+ ```bash
483
+ # Flagship model ids, in rank order
484
+ claudish --models-top --json | jq -r '.models | map(select(.recommendationTier == "flagship")) | sort_by(.priority) | .[].id'
485
+
486
+ # Runnable subscription commands
487
+ claudish --models-top --json | jq -r '.models[] | select(.recommendationTier == "subscription") | .subscriptions[]?.command'
488
+ ```
489
+
470
490
  ### Parse in TypeScript
471
491
 
472
492
  ```typescript
473
- const { stdout } = await Bash("claudish --models --json");
493
+ const { stdout } = await Bash("claudish --models-top --json");
474
494
  const data = JSON.parse(stdout);
475
495
 
476
- // Get all model IDs
477
- const modelIds = data.models.map(m => m.id);
496
+ // Every recommended model id, once (a model in two tiers is two rows)
497
+ const modelIds = [...new Set(data.models.map(m => m.id))];
478
498
 
479
- // Get coding models
480
- const codingModels = data.models.filter(m => m.category === "coding");
499
+ // Flagship models, in rank order
500
+ const flagshipModels = data.models
501
+ .filter(m => m.recommendationTier === "flagship")
502
+ .sort((a, b) => a.priority - b.priority);
481
503
 
482
- // Get cheapest model
483
- const cheapest = data.models.sort((a, b) =>
484
- parseFloat(a.pricing.average) - parseFloat(b.pricing.average)
485
- )[0];
504
+ // Cheapest model by average price ("$0.85/1M"; "N/A" when unpriced)
505
+ const price = m => Number.parseFloat(m.pricing.average.replace(/^\$/, ""));
506
+ const cheapest = data.models
507
+ .filter(m => !Number.isNaN(price(m)))
508
+ .sort((a, b) => price(a) - price(b))[0];
486
509
  ```
487
510
 
488
511
  ## JSON Output Format
package/dist/index.js CHANGED
@@ -889,7 +889,7 @@ var init_onepassword_config = __esm(() => {
889
889
  });
890
890
 
891
891
  // src/version.ts
892
- var VERSION = "10.6.0";
892
+ var VERSION = "10.6.2";
893
893
 
894
894
  // src/logger.ts
895
895
  import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
@@ -44525,6 +44525,9 @@ var init_cache_ttl = __esm(() => {
44525
44525
  import { existsSync as existsSync21, mkdirSync as mkdirSync12, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "fs";
44526
44526
  import { homedir as homedir28 } from "os";
44527
44527
  import { join as join31 } from "path";
44528
+ function isRecommendationTier(value) {
44529
+ return typeof value === "string" && RECOMMENDATION_TIER_INDEX.has(value);
44530
+ }
44528
44531
  async function fetchCatalogPage(url, timeoutMs, generationId) {
44529
44532
  const requestUrl = new URL(url);
44530
44533
  if (generationId)
@@ -44546,93 +44549,262 @@ async function fetchCatalogPage(url, timeoutMs, generationId) {
44546
44549
  async function fetchCatalogData(url, timeoutMs, generationId) {
44547
44550
  return (await fetchCatalogPage(url, timeoutMs, generationId)).data;
44548
44551
  }
44549
- function recommendationProjection(recommendations, richModels = []) {
44552
+ function readWireEntry(value) {
44553
+ if (!value || typeof value !== "object")
44554
+ return null;
44555
+ const raw = value;
44556
+ if (typeof raw.modelId !== "string" || !isRecommendationTier(raw.tier))
44557
+ return null;
44558
+ const rawRoute = raw.route;
44559
+ const route = rawRoute && typeof rawRoute === "object" && typeof rawRoute.routeId === "string" && typeof rawRoute.routeProfileId === "string" ? { routeId: rawRoute.routeId, routeProfileId: rawRoute.routeProfileId } : undefined;
44560
+ return {
44561
+ modelId: raw.modelId,
44562
+ tier: raw.tier,
44563
+ ...route ? { route } : {},
44564
+ ...typeof raw.planId === "string" ? { planId: raw.planId } : {}
44565
+ };
44566
+ }
44567
+ function recommendationDedupeKey(entry) {
44568
+ return entry.tier === "subscription" ? JSON.stringify([
44569
+ entry.tier,
44570
+ entry.modelId,
44571
+ entry.route?.routeId ?? null,
44572
+ entry.route?.routeProfileId ?? null,
44573
+ entry.planId ?? null
44574
+ ]) : JSON.stringify([entry.tier, entry.modelId]);
44575
+ }
44576
+ function projectRecommendations(recommendations, catalog, richModels = [], now = new Date) {
44550
44577
  if (recommendations.contractVersion !== 3 || !Array.isArray(recommendations.entries)) {
44551
44578
  throw new Error("Model catalog recommendations do not match v3");
44552
44579
  }
44553
- const cache = readAllModelsCache();
44554
- if (!cache || cache.catalogGenerationId !== recommendations.generationId) {
44580
+ if (!catalog.catalogGenerationId || catalog.catalogGenerationId !== recommendations.generationId) {
44555
44581
  throw new Error("Recommendation and model catalog generations differ");
44556
44582
  }
44557
- const byId = new Map(cache?.entries.map((entry) => [entry.modelId, entry]) ?? []);
44558
- const richById = new Map(richModels.map((model) => [model.modelId, model]));
44583
+ const byId = new Map(catalog.entries.map((entry) => [entry.modelId, entry]));
44584
+ const richById = new Map;
44585
+ for (const model of richModels) {
44586
+ if (!richById.has(model.modelId))
44587
+ richById.set(model.modelId, model);
44588
+ }
44589
+ const seenKeys = new Set;
44590
+ const rankByTier = new Map;
44591
+ const models = [];
44592
+ for (const value of recommendations.entries) {
44593
+ const recommended = readWireEntry(value);
44594
+ if (!recommended)
44595
+ continue;
44596
+ const model = byId.get(recommended.modelId);
44597
+ if (!model)
44598
+ continue;
44599
+ const key = recommendationDedupeKey(recommended);
44600
+ if (seenKeys.has(key))
44601
+ continue;
44602
+ seenKeys.add(key);
44603
+ const priority = (rankByTier.get(recommended.tier) ?? 0) + 1;
44604
+ rankByTier.set(recommended.tier, priority);
44605
+ const rich = richById.get(recommended.modelId);
44606
+ const subscription = recommended.tier === "subscription" ? subscriptionRouteFor(recommended, model, catalog.plans) : undefined;
44607
+ models.push({
44608
+ id: recommended.modelId,
44609
+ name: rich?.displayName ?? model.displayName ?? recommended.modelId,
44610
+ description: rich?.description ?? "",
44611
+ provider: rich?.provider ?? model.provider ?? "",
44612
+ recommendationTier: recommended.tier,
44613
+ priority,
44614
+ pricing: {
44615
+ input: typeof rich?.pricing?.input === "number" ? `$${rich.pricing.input}/1M` : "N/A",
44616
+ output: typeof rich?.pricing?.output === "number" ? `$${rich.pricing.output}/1M` : "N/A",
44617
+ average: typeof rich?.pricing?.input === "number" && typeof rich?.pricing?.output === "number" ? `$${((rich.pricing.input + rich.pricing.output) / 2).toFixed(2)}/1M` : "N/A"
44618
+ },
44619
+ context: rich?.contextWindow ? String(rich.contextWindow) : model.contextWindow ? String(model.contextWindow) : "N/A",
44620
+ releaseDate: model.releaseDate,
44621
+ ...subscription ? { subscription, subscriptions: [subscription] } : {}
44622
+ });
44623
+ }
44624
+ const stamp = now.toISOString();
44559
44625
  return {
44560
44626
  contractVersion: 3,
44561
44627
  generationId: recommendations.generationId,
44562
44628
  version: recommendations.generationId,
44563
- lastUpdated: new Date().toISOString(),
44564
- generatedAt: new Date().toISOString(),
44565
- models: recommendations.entries.map((recommended, index) => {
44566
- const model = byId.get(recommended.modelId);
44567
- const rich = richById.get(recommended.modelId);
44568
- const provider = recommended.route ? providerForCatalogRoute(recommended.route) : undefined;
44569
- const connection = model?.aggregators?.find((candidate) => candidate.route?.routeId === recommended.route?.routeId && candidate.route?.routeProfileId === recommended.route?.routeProfileId);
44570
- const plan = cache?.plans.find((candidate) => candidate.id === recommended.planId);
44571
- const prefix = provider ? PROVIDER_TO_PREFIX[provider] ?? provider : undefined;
44572
- const command = prefix && connection?.externalModelId ? provider === "native-anthropic" ? connection.externalModelId : `${prefix}@${connection.externalModelId}` : undefined;
44573
- const subscription = recommended.tier === "subscription" && provider && command ? {
44574
- ...provider === "native-anthropic" ? {} : { prefix },
44575
- plan: plan?.id ?? recommended.planId ?? provider,
44576
- command,
44577
- planIds: recommended.planId ? [recommended.planId] : [],
44578
- routingProvider: provider,
44579
- tier: provider === "native-anthropic" ? "native" : "general"
44580
- } : undefined;
44581
- return {
44582
- id: recommended.modelId,
44583
- name: rich?.displayName ?? model?.displayName ?? recommended.modelId,
44584
- description: rich?.description ?? "",
44585
- provider: rich?.provider ?? model?.provider ?? "",
44586
- category: recommended.tier === "flagship" ? "programming" : recommended.tier === "lightweight" ? "fast" : "subscription",
44587
- priority: index + 1,
44588
- pricing: {
44589
- input: typeof rich?.pricing?.input === "number" ? `$${rich.pricing.input}/1M` : "N/A",
44590
- output: typeof rich?.pricing?.output === "number" ? `$${rich.pricing.output}/1M` : "N/A",
44591
- average: typeof rich?.pricing?.input === "number" && typeof rich?.pricing?.output === "number" ? `$${((rich.pricing.input + rich.pricing.output) / 2).toFixed(2)}/1M` : "N/A"
44592
- },
44593
- context: rich?.contextWindow ? String(rich.contextWindow) : model?.contextWindow ? String(model.contextWindow) : "N/A",
44594
- releaseDate: model?.releaseDate,
44595
- ...subscription ? { subscription, subscriptions: [subscription] } : {}
44596
- };
44597
- })
44629
+ lastUpdated: stamp,
44630
+ generatedAt: stamp,
44631
+ recommendationTiers: RECOMMENDATION_SECTIONS.map((section) => section.recommendationTier),
44632
+ models
44598
44633
  };
44599
44634
  }
44635
+ function subscriptionRouteFor(recommended, model, plans) {
44636
+ if (!recommended.route)
44637
+ return;
44638
+ const provider = providerForCatalogRoute(recommended.route);
44639
+ if (!provider)
44640
+ return;
44641
+ const connection = model.aggregators?.find((candidate) => candidate.route?.routeId === recommended.route?.routeId && candidate.route?.routeProfileId === recommended.route?.routeProfileId);
44642
+ const prefix = PROVIDER_TO_PREFIX[provider] ?? provider;
44643
+ if (!connection?.externalModelId)
44644
+ return;
44645
+ const command = provider === "native-anthropic" ? connection.externalModelId : `${prefix}@${connection.externalModelId}`;
44646
+ const plan = plans.find((candidate) => candidate.id === recommended.planId);
44647
+ return {
44648
+ ...provider === "native-anthropic" ? {} : { prefix },
44649
+ plan: plan?.id ?? recommended.planId ?? provider,
44650
+ command,
44651
+ planIds: recommended.planId ? [recommended.planId] : [],
44652
+ routingProvider: provider,
44653
+ tier: provider === "native-anthropic" ? "native" : "general"
44654
+ };
44655
+ }
44656
+ function recommendationProjection(recommendations, richModels = []) {
44657
+ const cache = readAllModelsCache();
44658
+ return projectRecommendations(recommendations, cache ? {
44659
+ catalogGenerationId: cache.catalogGenerationId,
44660
+ entries: cache.entries,
44661
+ plans: cache.plans
44662
+ } : { catalogGenerationId: "", entries: [], plans: [] }, richModels);
44663
+ }
44664
+ function isRecord(value) {
44665
+ return value !== null && typeof value === "object" && !Array.isArray(value);
44666
+ }
44667
+ function isStringArray(value) {
44668
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
44669
+ }
44670
+ function isRouteObject(value) {
44671
+ return isRecord(value) && typeof value.plan === "string" && typeof value.command === "string" && (value.prefix === undefined || typeof value.prefix === "string") && (value.planIds === undefined || isStringArray(value.planIds));
44672
+ }
44673
+ function isUsableRow(value) {
44674
+ if (!isRecord(value))
44675
+ return false;
44676
+ if (typeof value.id !== "string" || value.id.length === 0)
44677
+ return false;
44678
+ if (!isRecommendationTier(value.recommendationTier))
44679
+ return false;
44680
+ if (typeof value.priority !== "number" || !Number.isFinite(value.priority))
44681
+ return false;
44682
+ if (typeof value.name !== "string" || typeof value.description !== "string" || typeof value.provider !== "string" || typeof value.context !== "string") {
44683
+ return false;
44684
+ }
44685
+ const pricing = value.pricing;
44686
+ if (!isRecord(pricing) || typeof pricing.input !== "string" || typeof pricing.output !== "string" || typeof pricing.average !== "string") {
44687
+ return false;
44688
+ }
44689
+ if (value.releaseDate !== undefined && typeof value.releaseDate !== "string")
44690
+ return false;
44691
+ if (value.subscription !== undefined && !isRouteObject(value.subscription))
44692
+ return false;
44693
+ if (value.subscriptions !== undefined && !(Array.isArray(value.subscriptions) && value.subscriptions.every(isRouteObject))) {
44694
+ return false;
44695
+ }
44696
+ return true;
44697
+ }
44698
+ function readProjectedRecommendationsDoc(value) {
44699
+ if (!isRecord(value))
44700
+ return null;
44701
+ if (value.contractVersion !== 3)
44702
+ return null;
44703
+ if (typeof value.generationId !== "string" || typeof value.version !== "string" || typeof value.lastUpdated !== "string" || typeof value.generatedAt !== "string" || !Array.isArray(value.models)) {
44704
+ return null;
44705
+ }
44706
+ const writerTiers = value.recommendationTiers;
44707
+ if (!isStringArray(writerTiers))
44708
+ return null;
44709
+ if (!RECOMMENDATION_SECTIONS.every((section) => writerTiers.includes(section.recommendationTier)))
44710
+ return null;
44711
+ const models = value.models.filter(isUsableRow);
44712
+ if (models.length === 0)
44713
+ return null;
44714
+ return {
44715
+ ...value,
44716
+ recommendationTiers: RECOMMENDATION_SECTIONS.map((section) => section.recommendationTier),
44717
+ models
44718
+ };
44719
+ }
44720
+ function readRecommendedModelsCacheFile() {
44721
+ if (!existsSync21(RECOMMENDED_MODELS_CACHE_PATH))
44722
+ return null;
44723
+ let parsed;
44724
+ try {
44725
+ parsed = JSON.parse(readFileSync21(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
44726
+ } catch {
44727
+ return null;
44728
+ }
44729
+ return readProjectedRecommendationsDoc(parsed);
44730
+ }
44731
+ function sectionDefFor(tier) {
44732
+ const index = RECOMMENDATION_TIER_INDEX.get(tier);
44733
+ return index === undefined ? undefined : RECOMMENDATION_SECTIONS[index];
44734
+ }
44600
44735
  function groupRecommendedModels(entries) {
44601
- const byId = new Map;
44602
- const categoryOrder = new Map;
44736
+ const subscriptionRowsById = new Map;
44603
44737
  for (const entry of entries) {
44604
- const list = byId.get(entry.id);
44738
+ if (entry.recommendationTier !== "subscription")
44739
+ continue;
44740
+ const list = subscriptionRowsById.get(entry.id);
44605
44741
  if (list)
44606
44742
  list.push(entry);
44607
44743
  else
44608
- byId.set(entry.id, [entry]);
44609
- if (!categoryOrder.has(entry.category))
44610
- categoryOrder.set(entry.category, categoryOrder.size);
44611
- }
44612
- const flagship = [];
44613
- const fast = [];
44614
- for (const [id, members] of byId.entries()) {
44615
- const primary = members.find((m) => m.category !== "subscription") ?? members[0];
44616
- const subscriptions = members.filter((m) => m.category === "subscription");
44617
- const bucket = primary.category === "programming" || primary.category === "vision" || primary.category === "reasoning" ? "flagship" : "fast";
44618
- const group = { id, primary, subscriptions, bucket };
44619
- if (bucket === "flagship")
44620
- flagship.push(group);
44621
- else
44622
- fast.push(group);
44744
+ subscriptionRowsById.set(entry.id, [entry]);
44623
44745
  }
44624
- const byCuratedPriorityThenFreshness = (a, b) => {
44625
- const aCat = categoryOrder.get(a.primary.category) ?? Number.MAX_SAFE_INTEGER;
44626
- const bCat = categoryOrder.get(b.primary.category) ?? Number.MAX_SAFE_INTEGER;
44627
- if (aCat !== bCat)
44628
- return aCat - bCat;
44629
- if (a.primary.priority !== b.primary.priority)
44630
- return a.primary.priority - b.primary.priority;
44631
- return compareByReleaseDateDesc(a.primary, b.primary);
44632
- };
44633
- flagship.sort(byCuratedPriorityThenFreshness);
44634
- fast.sort(byCuratedPriorityThenFreshness);
44635
- return { flagship, fast };
44746
+ const sections = [];
44747
+ for (const def of RECOMMENDATION_SECTIONS) {
44748
+ const primaryById = new Map;
44749
+ for (const entry of entries) {
44750
+ if (entry.recommendationTier !== def.recommendationTier)
44751
+ continue;
44752
+ const current = primaryById.get(entry.id);
44753
+ if (!current || entry.priority < current.priority)
44754
+ primaryById.set(entry.id, entry);
44755
+ }
44756
+ if (primaryById.size === 0)
44757
+ continue;
44758
+ const groups = [...primaryById.values()].map((primary) => ({
44759
+ id: primary.id,
44760
+ primary,
44761
+ subscriptions: subscriptionRowsById.get(primary.id) ?? []
44762
+ }));
44763
+ groups.sort((a, b) => a.primary.priority - b.primary.priority || compareByReleaseDateDesc(a.primary, b.primary));
44764
+ const description = "description" in def ? def.description : undefined;
44765
+ sections.push({
44766
+ recommendationTier: def.recommendationTier,
44767
+ title: def.title,
44768
+ ...description ? { description } : {},
44769
+ groups
44770
+ });
44771
+ }
44772
+ return sections;
44773
+ }
44774
+ function quickPickCandidates(sections) {
44775
+ const excluded = new Set;
44776
+ for (const section of sections) {
44777
+ if (sectionDefFor(section.recommendationTier)?.quickPickEligible === false) {
44778
+ for (const group of section.groups)
44779
+ excluded.add(group.id);
44780
+ }
44781
+ }
44782
+ const seen = new Set;
44783
+ const candidates = [];
44784
+ for (const section of sections) {
44785
+ if (sectionDefFor(section.recommendationTier)?.quickPickEligible !== true)
44786
+ continue;
44787
+ for (const group of section.groups) {
44788
+ if (excluded.has(group.id) || seen.has(group.id))
44789
+ continue;
44790
+ seen.add(group.id);
44791
+ candidates.push(group.primary);
44792
+ }
44793
+ }
44794
+ return candidates;
44795
+ }
44796
+ function uniqueRecommendedModels(entries) {
44797
+ const sectionIndex = (entry) => RECOMMENDATION_TIER_INDEX.get(entry.recommendationTier) ?? Number.MAX_SAFE_INTEGER;
44798
+ const ordered = [...entries].sort((a, b) => sectionIndex(a) - sectionIndex(b) || a.priority - b.priority);
44799
+ const seen = new Set;
44800
+ const unique = [];
44801
+ for (const entry of ordered) {
44802
+ if (seen.has(entry.id))
44803
+ continue;
44804
+ seen.add(entry.id);
44805
+ unique.push(entry);
44806
+ }
44807
+ return unique;
44636
44808
  }
44637
44809
  function collectRoutingPrefixes(group, getNativePrefix) {
44638
44810
  const slug = (group.primary.provider || "").toLowerCase();
@@ -44725,14 +44897,12 @@ async function getRecommendedModels(opts = {}) {
44725
44897
  if (!forceRefresh && cached && cached.generationId === readAllModelsCache()?.catalogGenerationId) {
44726
44898
  return cached;
44727
44899
  }
44728
- if (!forceRefresh && existsSync21(RECOMMENDED_MODELS_CACHE_PATH)) {
44729
- try {
44730
- const cacheData = JSON.parse(readFileSync21(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
44731
- if (cacheData.contractVersion === 3 && cacheData.generationId === readAllModelsCache()?.catalogGenerationId && cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
44732
- _cachedRecommendedModels = cacheData;
44733
- return cacheData;
44734
- }
44735
- } catch {}
44900
+ if (!forceRefresh) {
44901
+ const cacheData = readRecommendedModelsCacheFile();
44902
+ if (cacheData && cacheData.generationId === readAllModelsCache()?.catalogGenerationId && isFreshEnough(cacheData)) {
44903
+ _cachedRecommendedModels = cacheData;
44904
+ return cacheData;
44905
+ }
44736
44906
  }
44737
44907
  let fetchFailure;
44738
44908
  try {
@@ -44767,14 +44937,10 @@ function getRecommendedModelsSync() {
44767
44937
  const cached = _cachedRecommendedModels;
44768
44938
  if (cached && cached.generationId === generationId)
44769
44939
  return cached;
44770
- if (existsSync21(RECOMMENDED_MODELS_CACHE_PATH)) {
44771
- try {
44772
- const cacheData = JSON.parse(readFileSync21(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
44773
- if (cacheData.contractVersion === 3 && cacheData.generationId === generationId && cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
44774
- _cachedRecommendedModels = cacheData;
44775
- return cacheData;
44776
- }
44777
- } catch {}
44940
+ const cacheData = readRecommendedModelsCacheFile();
44941
+ if (cacheData && cacheData.generationId === generationId && isFreshEnough(cacheData)) {
44942
+ _cachedRecommendedModels = cacheData;
44943
+ return cacheData;
44778
44944
  }
44779
44945
  return { version: "0", lastUpdated: "", models: [] };
44780
44946
  }
@@ -44860,7 +45026,7 @@ function loadModelInfo() {
44860
45026
  }
44861
45027
  const data = getRecommendedModelsSync();
44862
45028
  const modelInfo = {};
44863
- for (const model of data.models) {
45029
+ for (const model of uniqueRecommendedModels(data.models)) {
44864
45030
  modelInfo[model.id] = {
44865
45031
  name: model.name,
44866
45032
  description: model.description,
@@ -44882,20 +45048,38 @@ function getAvailableModels() {
44882
45048
  return _cachedModelIds;
44883
45049
  }
44884
45050
  const data = getRecommendedModelsSync();
44885
- const modelIds = data.models.sort((a, b) => a.priority - b.priority).map((m) => m.id);
45051
+ const modelIds = uniqueRecommendedModels(data.models).map((m) => m.id);
44886
45052
  const result = [...modelIds, "custom"];
44887
45053
  _cachedModelIds = result;
44888
45054
  return result;
44889
45055
  }
44890
- var _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels = null, FIREBASE_BASE_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels", FIREBASE_RECOMMENDED_URL, RECOMMENDED_MODELS_CACHE_PATH, RECOMMENDED_FETCH_TIMEOUT_MS = 5000, SEARCH_FETCH_TIMEOUT_MS = 1e4, RECOMMENDED_ROUTE_TIER_ORDER;
45056
+ var RECOMMENDATION_SECTIONS, RECOMMENDATION_TIER_INDEX, _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels = null, FIREBASE_BASE_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels", FIREBASE_RECOMMENDED_URL, RECOMMENDED_MODELS_CACHE_PATH, RECOMMENDED_FETCH_TIMEOUT_MS = 5000, SEARCH_FETCH_TIMEOUT_MS = 1e4, RECOMMENDED_ROUTE_TIER_ORDER;
44891
45057
  var init_model_loader = __esm(() => {
44892
45058
  init_all_models_cache();
44893
45059
  init_auto_route();
44894
45060
  init_cache_ttl();
44895
45061
  init_catalog_client();
44896
45062
  init_catalog_route_bindings();
45063
+ RECOMMENDATION_SECTIONS = [
45064
+ { recommendationTier: "flagship", title: "Flagship", quickPickEligible: true },
45065
+ {
45066
+ recommendationTier: "cost_efficient",
45067
+ title: "Cost-efficient",
45068
+ description: "Best value: strong models at a much lower cost per task",
45069
+ quickPickEligible: true
45070
+ },
45071
+ { recommendationTier: "lightweight", title: "Lightweight", quickPickEligible: true },
45072
+ {
45073
+ recommendationTier: "luxury",
45074
+ title: "Luxury",
45075
+ description: "Most capable, most expensive. Use for the hardest tasks",
45076
+ quickPickEligible: false
45077
+ },
45078
+ { recommendationTier: "subscription", title: "Subscription", quickPickEligible: true }
45079
+ ];
45080
+ RECOMMENDATION_TIER_INDEX = new Map(RECOMMENDATION_SECTIONS.map((section, index) => [section.recommendationTier, index]));
44897
45081
  FIREBASE_RECOMMENDED_URL = `${FIREBASE_BASE_URL}?catalog=recommended`;
44898
- RECOMMENDED_MODELS_CACHE_PATH = join31(homedir28(), ".claudish", "recommended-models-cache.json");
45082
+ RECOMMENDED_MODELS_CACHE_PATH = join31(homedir28(), ".claudish", "recommended-models-cache-v2.json");
44899
45083
  RECOMMENDED_ROUTE_TIER_ORDER = {
44900
45084
  native: 0,
44901
45085
  general: 1,
@@ -50508,25 +50692,28 @@ function formatFirebaseProviderLabel(slug) {
50508
50692
  }
50509
50693
  async function loadRecommendedModels(forceRefresh = false) {
50510
50694
  try {
50511
- const doc = await getRecommendedModels({ forceRefresh });
50512
- return sortModelsNewestFirst(doc.models.map((model) => ({
50513
- id: model.id,
50514
- name: model.name,
50515
- description: model.description,
50516
- provider: formatFirebaseProviderLabel(model.provider),
50517
- providerSlug: model.provider.toLowerCase(),
50518
- pricing: model.pricing,
50519
- context: model.context,
50520
- contextLength: parseContextString(model.context),
50521
- supportsTools: model.supportsTools,
50522
- supportsReasoning: model.supportsReasoning,
50523
- supportsVision: model.supportsVision,
50524
- source: formatFirebaseProviderLabel(model.provider)
50525
- })));
50695
+ return _recommendedFallbackRows(await getRecommendedModels({ forceRefresh }));
50526
50696
  } catch {
50527
50697
  return [];
50528
50698
  }
50529
50699
  }
50700
+ function _recommendedFallbackRows(doc) {
50701
+ return sortModelsNewestFirst(uniqueRecommendedModels(doc.models).map((model) => ({
50702
+ id: model.id,
50703
+ name: model.name,
50704
+ description: model.description,
50705
+ provider: formatFirebaseProviderLabel(model.provider),
50706
+ providerSlug: model.provider.toLowerCase(),
50707
+ pricing: model.pricing,
50708
+ context: model.context,
50709
+ contextLength: parseContextString(model.context),
50710
+ supportsTools: model.supportsTools,
50711
+ supportsReasoning: model.supportsReasoning,
50712
+ supportsVision: model.supportsVision,
50713
+ releaseDate: model.releaseDate,
50714
+ source: formatFirebaseProviderLabel(model.provider)
50715
+ })));
50716
+ }
50530
50717
  function parseContextString(ctx) {
50531
50718
  if (!ctx || ctx === "N/A")
50532
50719
  return 0;
@@ -54434,6 +54621,159 @@ var init_provider_slug_resolve = __esm(() => {
54434
54621
  init_reserved_namespace();
54435
54622
  });
54436
54623
 
54624
+ // src/recommended-listing.ts
54625
+ function nativeShortcutForVendor(vendorSlug) {
54626
+ const canonical = nativeProviderForVendor(vendorSlug);
54627
+ if (!canonical)
54628
+ return null;
54629
+ const def = BUILTIN_PROVIDERS.find((provider) => provider.name === canonical);
54630
+ const shortcut = def?.shortcuts?.[0];
54631
+ return shortcut ? shortcut : null;
54632
+ }
54633
+ function textHeading(section) {
54634
+ return section.description ? `${section.title} \u2014 ${section.description}` : section.title;
54635
+ }
54636
+ function textRow(group, getNativePrefix) {
54637
+ const m = group.primary;
54638
+ const rawId = m.id;
54639
+ const modelId = rawId.length > 28 ? `${rawId.substring(0, 25)}...` : rawId;
54640
+ const modelIdPadded = modelId.padEnd(28);
54641
+ const pricing = formatListingPrice(m, { compact: true });
54642
+ const pricingPadded = pricing.padEnd(10);
54643
+ const context = m.context || "N/A";
54644
+ const contextPadded = context.padEnd(6);
54645
+ const caps = [];
54646
+ if (m.supportsTools)
54647
+ caps.push("\uD83D\uDD27");
54648
+ if (m.supportsReasoning)
54649
+ caps.push("\uD83E\uDDE0");
54650
+ if (m.supportsVision)
54651
+ caps.push("\uD83D\uDC41\uFE0F");
54652
+ const capabilities = caps.join(" ");
54653
+ const lines = [` ${modelIdPadded} ${pricingPadded} ${contextPadded} ${capabilities}`];
54654
+ const prefixes = collectRoutingPrefixes(group, getNativePrefix);
54655
+ if (prefixes.length > 0) {
54656
+ const viaLine = prefixes.map((p) => `${p}@`).join(" \xB7 ");
54657
+ lines.push(` via: ${viaLine}`);
54658
+ }
54659
+ return lines;
54660
+ }
54661
+ function renderRecommendedText(doc, getNativePrefix) {
54662
+ const lastUpdated = doc.lastUpdated || "unknown";
54663
+ const sections = groupRecommendedModels(doc.models);
54664
+ const lines = ["", `Recommended Models (last updated: ${lastUpdated}):`, ""];
54665
+ sections.forEach((section, sectionIndex) => {
54666
+ if (sectionIndex > 0)
54667
+ lines.push("");
54668
+ lines.push(textHeading(section));
54669
+ lines.push(` ${"\u2500".repeat(70)}`);
54670
+ section.groups.forEach((group, groupIndex) => {
54671
+ lines.push(...textRow(group, getNativePrefix));
54672
+ if (groupIndex < section.groups.length - 1)
54673
+ lines.push("");
54674
+ });
54675
+ });
54676
+ lines.push("");
54677
+ lines.push(" Capabilities: \uD83D\uDD27 Tools \uD83E\uDDE0 Reasoning \uD83D\uDC41\uFE0F Vision");
54678
+ const picks = computeQuickPicks(quickPickCandidates(sections));
54679
+ const pickLines = [];
54680
+ if (picks.budget)
54681
+ pickLines.push(` Budget \u2192 ${picks.budget.id} (${normalizePricingDisplay(picks.budget.pricing?.average)})`);
54682
+ if (picks.largeContext)
54683
+ pickLines.push(` Large ctx \u2192 ${picks.largeContext.id} (${picks.largeContext.context || "N/A"})`);
54684
+ if (picks.mostCapable)
54685
+ pickLines.push(` Most capable \u2192 ${picks.mostCapable.id}`);
54686
+ if (picks.visionCoding)
54687
+ pickLines.push(` Vision+code \u2192 ${picks.visionCoding.id}`);
54688
+ if (picks.agentic)
54689
+ pickLines.push(` Agentic \u2192 ${picks.agentic.id}`);
54690
+ if (pickLines.length > 0) {
54691
+ lines.push("");
54692
+ lines.push(" Quick picks:");
54693
+ lines.push(...pickLines);
54694
+ }
54695
+ lines.push("");
54696
+ lines.push(" Set default: export CLAUDISH_MODEL=<model>");
54697
+ lines.push(" or: claudish --model <model> ...");
54698
+ lines.push("");
54699
+ lines.push(" For more: claudish --models (browse full catalog)");
54700
+ lines.push(" claudish --providers (list all providers + counts)");
54701
+ lines.push(" claudish -s <query> (search by keyword)");
54702
+ lines.push(" claudish --models-top --models-refresh (refresh from Firebase)");
54703
+ lines.push("");
54704
+ return lines.join(`
54705
+ `);
54706
+ }
54707
+ function markdownRow(group, getNativePrefix) {
54708
+ const m = group.primary;
54709
+ const pricing = formatListingPrice(m);
54710
+ const ctx = m.context || "N/A";
54711
+ const caps = [];
54712
+ if (m.supportsTools)
54713
+ caps.push("tools");
54714
+ if (m.supportsReasoning)
54715
+ caps.push("reasoning");
54716
+ if (m.supportsVision)
54717
+ caps.push("vision");
54718
+ const capsLine = caps.length > 0 ? caps.join(", ") : "none";
54719
+ const prefixes = collectRoutingPrefixes(group, getNativePrefix);
54720
+ const accessLine = prefixes.length > 0 ? prefixes.map((p) => `\`${p}@${m.id}\``).join(" \xB7 ") : `\`${m.id}\``;
54721
+ return [
54722
+ `### ${m.id}`,
54723
+ `- **Pricing**: ${pricing} avg \xB7 ${ctx} context`,
54724
+ `- **Capabilities**: ${capsLine}`,
54725
+ `- **Access**: ${accessLine}`,
54726
+ ""
54727
+ ].join(`
54728
+ `);
54729
+ }
54730
+ function renderRecommendedMarkdown(doc, getNativePrefix) {
54731
+ const sections = groupRecommendedModels(doc.models);
54732
+ let output = `# Recommended Models
54733
+
54734
+ `;
54735
+ output += `_Last updated: ${doc.lastUpdated || "unknown"}_
54736
+
54737
+ `;
54738
+ for (const section of sections) {
54739
+ output += `## ${section.title}
54740
+
54741
+ `;
54742
+ if (section.description)
54743
+ output += `_${section.description}_
54744
+
54745
+ `;
54746
+ for (const group of section.groups)
54747
+ output += markdownRow(group, getNativePrefix);
54748
+ }
54749
+ const picks = computeQuickPicks(quickPickCandidates(sections));
54750
+ const pickLines = [];
54751
+ if (picks.budget)
54752
+ pickLines.push(`- **Budget**: \`${picks.budget.id}\` (${normalizePricingDisplay(picks.budget.pricing?.average)})`);
54753
+ if (picks.largeContext)
54754
+ pickLines.push(`- **Large context**: \`${picks.largeContext.id}\` (${picks.largeContext.context || "N/A"})`);
54755
+ if (picks.mostCapable)
54756
+ pickLines.push(`- **Most capable**: \`${picks.mostCapable.id}\``);
54757
+ if (picks.visionCoding)
54758
+ pickLines.push(`- **Vision + coding**: \`${picks.visionCoding.id}\``);
54759
+ if (picks.agentic)
54760
+ pickLines.push(`- **Agentic**: \`${picks.agentic.id}\``);
54761
+ if (pickLines.length > 0) {
54762
+ output += `## Quick picks
54763
+
54764
+ `;
54765
+ output += `${pickLines.join(`
54766
+ `)}
54767
+ `;
54768
+ }
54769
+ return output;
54770
+ }
54771
+ var init_recommended_listing = __esm(() => {
54772
+ init_model_loader();
54773
+ init_provider_definitions();
54774
+ init_route_candidates();
54775
+ });
54776
+
54437
54777
  // src/branding.ts
54438
54778
  function paint(line) {
54439
54779
  const { RESET, BOLD, CYAN, BLUE, DIM } = cliAnsi();
@@ -59799,7 +60139,7 @@ function clearAllModelCaches() {
59799
60139
  const cacheDir = join36(homedir32(), ".claudish");
59800
60140
  if (!existsSync25(cacheDir))
59801
60141
  return;
59802
- const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
60142
+ const cachePatterns = ["pricing-cache.json", "recommended-models-cache-v2.json"];
59803
60143
  let cleared = 0;
59804
60144
  try {
59805
60145
  const files = readdirSync4(cacheDir);
@@ -60599,95 +60939,7 @@ async function printRecommendedModels(jsonOutput, forceUpdate) {
60599
60939
  console.log(JSON.stringify(doc, null, 2));
60600
60940
  return;
60601
60941
  }
60602
- const lastUpdated = doc.lastUpdated || "unknown";
60603
- const { flagship, fast } = groupRecommendedModels(doc.models);
60604
- const providerByName = new Map(BUILTIN_PROVIDERS.map((p) => [p.name, p]));
60605
- const getNativePrefix = (firebaseSlug) => {
60606
- const canonical = nativeProviderForVendor(firebaseSlug);
60607
- if (!canonical)
60608
- return null;
60609
- const def = providerByName.get(canonical);
60610
- if (!def || !def.shortcuts || def.shortcuts.length === 0)
60611
- return null;
60612
- return def.shortcuts[0];
60613
- };
60614
- const renderGroup = (group) => {
60615
- const m = group.primary;
60616
- const rawId = m.id;
60617
- const modelId = rawId.length > 28 ? `${rawId.substring(0, 25)}...` : rawId;
60618
- const modelIdPadded = modelId.padEnd(28);
60619
- const pricing = formatListingPrice(m, { compact: true });
60620
- const pricingPadded = pricing.padEnd(10);
60621
- const context = m.context || "N/A";
60622
- const contextPadded = context.padEnd(6);
60623
- const caps = [];
60624
- if (m.supportsTools)
60625
- caps.push("\uD83D\uDD27");
60626
- if (m.supportsReasoning)
60627
- caps.push("\uD83E\uDDE0");
60628
- if (m.supportsVision)
60629
- caps.push("\uD83D\uDC41\uFE0F");
60630
- const capabilities = caps.join(" ");
60631
- console.log(` ${modelIdPadded} ${pricingPadded} ${contextPadded} ${capabilities}`);
60632
- const prefixes = collectRoutingPrefixes(group, getNativePrefix);
60633
- if (prefixes.length > 0) {
60634
- const viaLine = prefixes.map((p) => `${p}@`).join(" \xB7 ");
60635
- console.log(` via: ${viaLine}`);
60636
- }
60637
- };
60638
- console.log(`
60639
- Recommended Models (last updated: ${lastUpdated}):
60640
- `);
60641
- if (flagship.length > 0) {
60642
- console.log("Flagship models");
60643
- console.log(` ${"\u2500".repeat(70)}`);
60644
- for (let i = 0;i < flagship.length; i++) {
60645
- renderGroup(flagship[i]);
60646
- if (i < flagship.length - 1)
60647
- console.log("");
60648
- }
60649
- }
60650
- if (fast.length > 0) {
60651
- if (flagship.length > 0)
60652
- console.log("");
60653
- console.log("Fast variants");
60654
- console.log(` ${"\u2500".repeat(70)}`);
60655
- for (let i = 0;i < fast.length; i++) {
60656
- renderGroup(fast[i]);
60657
- if (i < fast.length - 1)
60658
- console.log("");
60659
- }
60660
- }
60661
- console.log("");
60662
- console.log(" Capabilities: \uD83D\uDD27 Tools \uD83E\uDDE0 Reasoning \uD83D\uDC41\uFE0F Vision");
60663
- const primaries = [...flagship, ...fast].map((g) => g.primary);
60664
- const picks = computeQuickPicks(primaries);
60665
- const pickLines = [];
60666
- if (picks.budget)
60667
- pickLines.push(` Budget \u2192 ${picks.budget.id} (${normalizePricingDisplay(picks.budget.pricing?.average)})`);
60668
- if (picks.largeContext)
60669
- pickLines.push(` Large ctx \u2192 ${picks.largeContext.id} (${picks.largeContext.context || "N/A"})`);
60670
- if (picks.mostCapable)
60671
- pickLines.push(` Most capable \u2192 ${picks.mostCapable.id}`);
60672
- if (picks.visionCoding)
60673
- pickLines.push(` Vision+code \u2192 ${picks.visionCoding.id}`);
60674
- if (picks.agentic)
60675
- pickLines.push(` Agentic \u2192 ${picks.agentic.id}`);
60676
- if (pickLines.length > 0) {
60677
- console.log("");
60678
- console.log(" Quick picks:");
60679
- for (const line of pickLines)
60680
- console.log(line);
60681
- }
60682
- console.log("");
60683
- console.log(" Set default: export CLAUDISH_MODEL=<model>");
60684
- console.log(" or: claudish --model <model> ...");
60685
- console.log("");
60686
- console.log(" For more: claudish --models (browse full catalog)");
60687
- console.log(" claudish --providers (list all providers + counts)");
60688
- console.log(" claudish -s <query> (search by keyword)");
60689
- console.log(" claudish --models-top --models-refresh (refresh from Firebase)");
60690
- console.log("");
60942
+ console.log(renderRecommendedText(doc, nativeShortcutForVendor));
60691
60943
  }
60692
60944
  async function printVersion() {
60693
60945
  if (!process.stdout.isTTY) {
@@ -61470,8 +61722,8 @@ var init_cli = __esm(() => {
61470
61722
  init_probe_runner();
61471
61723
  init_provider_definitions();
61472
61724
  init_provider_slug_resolve();
61473
- init_route_candidates();
61474
61725
  init_routing_rules();
61726
+ init_recommended_listing();
61475
61727
  init_settings();
61476
61728
  init_ansi();
61477
61729
  init_provider_resolver();
@@ -69110,82 +69362,14 @@ Tokens: ${result.usage.input} input, ${result.usage.output} output`;
69110
69362
  ]
69111
69363
  };
69112
69364
  }
69113
- const { flagship, fast } = groupRecommendedModels(doc.models);
69114
- const providerByName = new Map(BUILTIN_PROVIDERS.map((p) => [p.name, p]));
69115
- const getNativePrefix = (firebaseSlug) => {
69116
- const canonical = nativeProviderForVendor(firebaseSlug);
69117
- if (!canonical)
69118
- return null;
69119
- const def = providerByName.get(canonical);
69120
- if (!def || !def.shortcuts || def.shortcuts.length === 0)
69121
- return null;
69122
- return def.shortcuts[0];
69123
- };
69124
- const renderGroup = (group) => {
69125
- const m = group.primary;
69126
- const pricing = formatListingPrice(m);
69127
- const ctx = m.context || "N/A";
69128
- const caps = [];
69129
- if (m.supportsTools)
69130
- caps.push("tools");
69131
- if (m.supportsReasoning)
69132
- caps.push("reasoning");
69133
- if (m.supportsVision)
69134
- caps.push("vision");
69135
- const capsLine = caps.length > 0 ? caps.join(", ") : "none";
69136
- const prefixes = collectRoutingPrefixes(group, getNativePrefix);
69137
- const accessLine = prefixes.length > 0 ? prefixes.map((p) => `\`${p}@${m.id}\``).join(" \xB7 ") : `\`${m.id}\``;
69138
- return [
69139
- `### ${m.id}`,
69140
- `- **Pricing**: ${pricing} avg \xB7 ${ctx} context`,
69141
- `- **Capabilities**: ${capsLine}`,
69142
- `- **Access**: ${accessLine}`,
69143
- ""
69144
- ].join(`
69145
- `);
69365
+ return {
69366
+ content: [
69367
+ {
69368
+ type: "text",
69369
+ text: renderRecommendedMarkdown(doc, nativeShortcutForVendor)
69370
+ }
69371
+ ]
69146
69372
  };
69147
- let output = `# Recommended Models
69148
-
69149
- `;
69150
- output += `_Last updated: ${doc.lastUpdated || "unknown"}_
69151
-
69152
- `;
69153
- if (flagship.length > 0) {
69154
- output += `## Flagship models
69155
-
69156
- `;
69157
- for (const group of flagship)
69158
- output += renderGroup(group);
69159
- }
69160
- if (fast.length > 0) {
69161
- output += `## Fast variants
69162
-
69163
- `;
69164
- for (const group of fast)
69165
- output += renderGroup(group);
69166
- }
69167
- const primaries = [...flagship, ...fast].map((g) => g.primary);
69168
- const picks = computeQuickPicks(primaries);
69169
- const pickLines = [];
69170
- if (picks.budget)
69171
- pickLines.push(`- **Budget**: \`${picks.budget.id}\` (${normalizePricingDisplay(picks.budget.pricing?.average)})`);
69172
- if (picks.largeContext)
69173
- pickLines.push(`- **Large context**: \`${picks.largeContext.id}\` (${picks.largeContext.context || "N/A"})`);
69174
- if (picks.mostCapable)
69175
- pickLines.push(`- **Most capable**: \`${picks.mostCapable.id}\``);
69176
- if (picks.visionCoding)
69177
- pickLines.push(`- **Vision + coding**: \`${picks.visionCoding.id}\``);
69178
- if (picks.agentic)
69179
- pickLines.push(`- **Agentic**: \`${picks.agentic.id}\``);
69180
- if (pickLines.length > 0) {
69181
- output += `## Quick picks
69182
-
69183
- `;
69184
- output += `${pickLines.join(`
69185
- `)}
69186
- `;
69187
- }
69188
- return { content: [{ type: "text", text: output }] };
69189
69373
  }
69190
69374
  });
69191
69375
  tools.push({
@@ -70302,10 +70486,9 @@ var init_mcp_server = __esm(() => {
70302
70486
  init_native_route();
70303
70487
  init_onepassword();
70304
70488
  init_probe_live();
70305
- init_provider_definitions();
70306
- init_route_candidates();
70307
70489
  init_routing_rules();
70308
70490
  init_proxy_server();
70491
+ init_recommended_listing();
70309
70492
  init_redact();
70310
70493
  init_team_orchestrator();
70311
70494
  import_dotenv2 = __toESM(require_main(), 1);
@@ -72244,7 +72427,22 @@ ${DIM}Updating...${RESET}
72244
72427
  }
72245
72428
  return { status: "failed", method: installInfo.method };
72246
72429
  }
72247
- async function updateCommand() {
72430
+ function printUpdateHelp() {
72431
+ console.log(`Usage: claudish update
72432
+
72433
+ Checks the npm registry for the latest claudish release and, when it is newer
72434
+ than this one, installs it with the package manager that installed this copy
72435
+ (bun, npm or Homebrew), then shows what changed.
72436
+
72437
+ Options:
72438
+ -h, --help Show this help and exit without checking or installing
72439
+ `);
72440
+ }
72441
+ async function updateCommand(args = []) {
72442
+ if (args.includes("--help") || args.includes("-h")) {
72443
+ printUpdateHelp();
72444
+ return;
72445
+ }
72248
72446
  refreshAnsi2();
72249
72447
  const currentVersion = getVersion3();
72250
72448
  const installInfo = detectInstallationMethod();
@@ -83710,7 +83908,7 @@ if (isMcpMode) {
83710
83908
  const quotaProviderArg = args.find((a, i) => i > args.indexOf(firstPositional) && !a.startsWith("-"));
83711
83909
  Promise.resolve().then(() => (init_quota_command(), {})).then((m) => quotaCommand(quotaProviderArg));
83712
83910
  } else if (isUpdateCommand) {
83713
- Promise.resolve().then(() => (init_update_command(), {})).then((m) => updateCommand());
83911
+ Promise.resolve().then(() => (init_update_command(), {})).then((m) => updateCommand(args));
83714
83912
  } else if (isInitCommand) {
83715
83913
  const scopeFlag = args.includes("--local") ? "local" : args.includes("--global") ? "global" : undefined;
83716
83914
  Promise.resolve().then(() => (init_profile_commands(), {})).then((pc) => initCommand(scopeFlag).catch(handlePromptExit));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "10.6.0",
3
+ "version": "10.6.2",
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",
@@ -60,10 +60,10 @@
60
60
  "ai"
61
61
  ],
62
62
  "optionalDependencies": {
63
- "@claudish/magmux-darwin-arm64": "10.6.0",
64
- "@claudish/magmux-darwin-x64": "10.6.0",
65
- "@claudish/magmux-linux-arm64": "10.6.0",
66
- "@claudish/magmux-linux-x64": "10.6.0"
63
+ "@claudish/magmux-darwin-arm64": "10.6.2",
64
+ "@claudish/magmux-darwin-x64": "10.6.2",
65
+ "@claudish/magmux-linux-arm64": "10.6.2",
66
+ "@claudish/magmux-linux-x64": "10.6.2"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",