claudish 9.6.1 → 9.7.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.
Files changed (2) hide show
  1. package/dist/index.js +726 -473
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -715,7 +715,7 @@ var init_onepassword_config = __esm(() => {
715
715
  });
716
716
 
717
717
  // src/version.ts
718
- var VERSION = "9.6.1";
718
+ var VERSION = "9.7.1";
719
719
 
720
720
  // src/logger.ts
721
721
  import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
@@ -18165,10 +18165,126 @@ var init_stdio2 = __esm(() => {
18165
18165
  init_stdio();
18166
18166
  });
18167
18167
 
18168
- // src/providers/all-models-cache.ts
18169
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
18168
+ // src/providers/catalog-compatibility.ts
18169
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
18170
18170
  import { homedir as homedir7 } from "os";
18171
18171
  import { dirname as dirname4, join as join7 } from "path";
18172
+ function catalogIncompatiblePath() {
18173
+ const override = process.env.CLAUDISH_CATALOG_INCOMPATIBLE_PATH;
18174
+ return override !== undefined && override.length > 0 ? override : CATALOG_INCOMPATIBLE_PATH;
18175
+ }
18176
+ function parseContractEnvelope(body) {
18177
+ if (!body || typeof body !== "object")
18178
+ return { contractVersion: null };
18179
+ const data = body;
18180
+ const contractVersion = typeof data.contractVersion === "number" ? data.contractVersion : null;
18181
+ const err = data.error;
18182
+ const minimum = err && typeof err === "object" ? err.minimumContractVersion : undefined;
18183
+ return {
18184
+ contractVersion,
18185
+ ...typeof minimum === "number" ? { minimumContractVersion: minimum } : {}
18186
+ };
18187
+ }
18188
+ function isIncompatibleContractVersion(version) {
18189
+ return typeof version === "number" && version > SUPPORTED_CONTRACT_VERSION;
18190
+ }
18191
+ function markCatalogIncompatible(info, path = catalogIncompatiblePath()) {
18192
+ const record = {
18193
+ detectedAt: new Date().toISOString(),
18194
+ serverContractVersion: info.serverContractVersion,
18195
+ clientContractVersion: SUPPORTED_CONTRACT_VERSION,
18196
+ ...info.minimumContractVersion !== undefined ? { minimumContractVersion: info.minimumContractVersion } : {}
18197
+ };
18198
+ _memFlag = record;
18199
+ _fileMemo = { path, value: record };
18200
+ try {
18201
+ mkdirSync5(dirname4(path), { recursive: true });
18202
+ writeFileSync5(path, JSON.stringify(record), "utf-8");
18203
+ } catch {}
18204
+ }
18205
+ function readCatalogIncompatibility(path = catalogIncompatiblePath()) {
18206
+ if (_memFlag)
18207
+ return _memFlag;
18208
+ if (_fileMemo && _fileMemo.path === path)
18209
+ return _fileMemo.value;
18210
+ let value = null;
18211
+ try {
18212
+ if (existsSync5(path))
18213
+ value = parseSentinelFile(readFileSync5(path, "utf-8"));
18214
+ } catch {}
18215
+ if (value !== null && isSentinelStale(value)) {
18216
+ clearCatalogIncompatibility(path);
18217
+ return null;
18218
+ }
18219
+ _fileMemo = { path, value };
18220
+ return value;
18221
+ }
18222
+ function isSentinelStale(record) {
18223
+ if (typeof record.minimumContractVersion === "number" && record.minimumContractVersion > SUPPORTED_CONTRACT_VERSION) {
18224
+ return false;
18225
+ }
18226
+ if (record.serverContractVersion !== null) {
18227
+ return record.serverContractVersion <= SUPPORTED_CONTRACT_VERSION;
18228
+ }
18229
+ if (typeof record.clientContractVersion === "number") {
18230
+ return record.clientContractVersion < SUPPORTED_CONTRACT_VERSION;
18231
+ }
18232
+ return false;
18233
+ }
18234
+ function parseSentinelFile(raw) {
18235
+ const unspecific = {
18236
+ detectedAt: new Date(0).toISOString(),
18237
+ serverContractVersion: null
18238
+ };
18239
+ let parsed;
18240
+ try {
18241
+ parsed = JSON.parse(raw);
18242
+ } catch {
18243
+ return unspecific;
18244
+ }
18245
+ if (!parsed || typeof parsed !== "object")
18246
+ return unspecific;
18247
+ const data = parsed;
18248
+ return {
18249
+ detectedAt: typeof data.detectedAt === "string" ? data.detectedAt : unspecific.detectedAt,
18250
+ serverContractVersion: typeof data.serverContractVersion === "number" ? data.serverContractVersion : null,
18251
+ ...typeof data.minimumContractVersion === "number" ? { minimumContractVersion: data.minimumContractVersion } : {},
18252
+ ...typeof data.clientContractVersion === "number" ? { clientContractVersion: data.clientContractVersion } : {}
18253
+ };
18254
+ }
18255
+ function clearCatalogIncompatibility(path = catalogIncompatiblePath()) {
18256
+ _memFlag = null;
18257
+ _fileMemo = { path, value: null };
18258
+ try {
18259
+ rmSync2(path, { force: true });
18260
+ } catch {}
18261
+ }
18262
+ function catalogIncompatibilityMessage(i) {
18263
+ const serverSays = typeof i.serverContractVersion === "number" ? `catalog contract version ${i.serverContractVersion}` : typeof i.minimumContractVersion === "number" ? `catalog contract version ${i.minimumContractVersion} or newer` : "a newer catalog contract";
18264
+ return [
18265
+ `This claudish build cannot read the model catalog. The catalog server publishes ${serverSays}; this build reads version ${SUPPORTED_CONTRACT_VERSION}.`,
18266
+ "",
18267
+ "Routing cannot tell which models your subscriptions cover, so continuing would send this request to a provider that bills per token without saying so.",
18268
+ "",
18269
+ "Run `claudish update` to get a build that reads the current catalog."
18270
+ ].join(`
18271
+ `);
18272
+ }
18273
+ var SUPPORTED_CONTRACT_VERSION = 2, CATALOG_INCOMPATIBLE_PATH, _memFlag = null, _fileMemo = null, CatalogIncompatibleError;
18274
+ var init_catalog_compatibility = __esm(() => {
18275
+ CATALOG_INCOMPATIBLE_PATH = join7(homedir7(), ".claudish", "catalog-incompatible.json");
18276
+ CatalogIncompatibleError = class CatalogIncompatibleError extends Error {
18277
+ constructor(message) {
18278
+ super(message);
18279
+ this.name = "CatalogIncompatibleError";
18280
+ }
18281
+ };
18282
+ });
18283
+
18284
+ // src/providers/all-models-cache.ts
18285
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
18286
+ import { homedir as homedir8 } from "os";
18287
+ import { dirname as dirname5, join as join8 } from "path";
18172
18288
  function reasoningStatusOf(entry) {
18173
18289
  if (entry.reasoningStatus === "known" || entry.reasoningStatus === "unknown") {
18174
18290
  return entry.reasoningStatus;
@@ -18176,11 +18292,16 @@ function reasoningStatusOf(entry) {
18176
18292
  return entry.reasoning !== undefined ? "known" : "unknown";
18177
18293
  }
18178
18294
  function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
18179
- if (!existsSync5(path))
18295
+ if (readCatalogIncompatibility())
18296
+ return null;
18297
+ return readCacheFile(path);
18298
+ }
18299
+ function readCacheFile(path) {
18300
+ if (!existsSync6(path))
18180
18301
  return null;
18181
18302
  let raw;
18182
18303
  try {
18183
- raw = JSON.parse(readFileSync5(path, "utf-8"));
18304
+ raw = JSON.parse(readFileSync6(path, "utf-8"));
18184
18305
  } catch {
18185
18306
  return null;
18186
18307
  }
@@ -18202,7 +18323,7 @@ function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
18202
18323
  };
18203
18324
  }
18204
18325
  function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
18205
- const existing = readAllModelsCache(path);
18326
+ const existing = readCacheFile(path);
18206
18327
  const merged = {
18207
18328
  version: 2,
18208
18329
  lastUpdated: data.lastUpdated ?? new Date().toISOString(),
@@ -18211,12 +18332,13 @@ function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
18211
18332
  ...data.plans !== undefined || existing?.plans !== undefined ? { plans: data.plans ?? existing?.plans ?? [] } : {},
18212
18333
  ...data.catalogRevision !== undefined ? { catalogRevision: data.catalogRevision } : {}
18213
18334
  };
18214
- mkdirSync5(dirname4(path), { recursive: true });
18215
- writeFileSync5(path, JSON.stringify(merged), "utf-8");
18335
+ mkdirSync6(dirname5(path), { recursive: true });
18336
+ writeFileSync6(path, JSON.stringify(merged), "utf-8");
18216
18337
  }
18217
18338
  var ALL_MODELS_CACHE_PATH;
18218
18339
  var init_all_models_cache = __esm(() => {
18219
- ALL_MODELS_CACHE_PATH = join7(homedir7(), ".claudish", "all-models.json");
18340
+ init_catalog_compatibility();
18341
+ ALL_MODELS_CACHE_PATH = join8(homedir8(), ".claudish", "all-models.json");
18220
18342
  });
18221
18343
 
18222
18344
  // src/providers/model-ordering.ts
@@ -18370,19 +18492,25 @@ function resolveSubscriptionRouting(modelId, provider, cachePath) {
18370
18492
  if (providerPlans.length === 0)
18371
18493
  return { kind: "unknown" };
18372
18494
  const providerPlanIds = new Set(providerPlans.map((plan) => plan.id));
18373
- const hasMembership = entry.subscriptionPlans?.some((planId) => providerPlanIds.has(planId));
18374
- if (hasMembership) {
18495
+ const memberships = entry.subscriptionPlans ?? [];
18496
+ const includingPlans = providerPlans.filter((plan) => memberships.includes(plan.id));
18497
+ if (includingPlans.length > 0) {
18498
+ if (includingPlans.length < providerPlans.length)
18499
+ return { kind: "unknown" };
18375
18500
  const agg = entry.aggregators?.find((a) => a.provider === provider);
18376
18501
  return agg?.externalId ? { kind: "serves", externalId: agg.externalId } : { kind: "unknown" };
18377
18502
  }
18378
- const hasPublishedProviderRoster = cache.entries.some((candidate) => candidate.subscriptionPlans?.some((planId) => providerPlanIds.has(planId)));
18379
- if (!hasPublishedProviderRoster)
18503
+ const hasAnyMembershipRow = cache.entries.some((candidate) => candidate.subscriptionPlans?.some((planId) => providerPlanIds.has(planId)));
18504
+ if (!hasAnyMembershipRow)
18380
18505
  return { kind: "unknown" };
18381
18506
  const vendorsInView = new Set(providerPlans.map((plan) => plan.provider).filter((v) => v !== undefined));
18382
18507
  const hasUnroutableSiblingPlan = (cache.plans ?? []).some((plan) => plan.provider !== undefined && vendorsInView.has(plan.provider) && plan.routing?.providerUid === undefined);
18383
18508
  if (hasUnroutableSiblingPlan)
18384
18509
  return { kind: "unknown" };
18385
- return providerPlans.every(isCatalogDiscoveredPlan) ? { kind: "not-served" } : { kind: "unknown" };
18510
+ const hasCompleteMembershipView = providerPlans.every(isCatalogDiscoveredPlan);
18511
+ if (!hasCompleteMembershipView)
18512
+ return { kind: "unknown" };
18513
+ return { kind: "not-served" };
18386
18514
  }
18387
18515
  function isCatalogDiscoveredPlan(plan) {
18388
18516
  return plan.modelDiscovery === "catalog";
@@ -18570,26 +18698,26 @@ var init_agent_availability = __esm(() => {
18570
18698
  });
18571
18699
 
18572
18700
  // src/profile-config.ts
18573
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
18574
- import { homedir as homedir8 } from "os";
18575
- import { dirname as dirname5, join as join8, parse as parse6 } from "path";
18701
+ import { existsSync as existsSync7, mkdirSync as mkdirSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
18702
+ import { homedir as homedir9 } from "os";
18703
+ import { dirname as dirname6, join as join9, parse as parse6 } from "path";
18576
18704
  function activeConfigFile() {
18577
18705
  return activeGlobalConfigFile(CONFIG_FILE);
18578
18706
  }
18579
18707
  function ensureConfigDir() {
18580
- if (!existsSync6(CONFIG_DIR)) {
18581
- mkdirSync6(CONFIG_DIR, { recursive: true });
18708
+ if (!existsSync7(CONFIG_DIR)) {
18709
+ mkdirSync7(CONFIG_DIR, { recursive: true });
18582
18710
  }
18583
18711
  }
18584
18712
  function loadConfig() {
18585
18713
  const activeFile = activeConfigFile();
18586
18714
  if (!getConfigFileOverride())
18587
18715
  ensureConfigDir();
18588
- if (!existsSync6(activeFile)) {
18716
+ if (!existsSync7(activeFile)) {
18589
18717
  return { ...DEFAULT_CONFIG };
18590
18718
  }
18591
18719
  try {
18592
- const content = readFileSync6(activeFile, "utf-8");
18720
+ const content = readFileSync7(activeFile, "utf-8");
18593
18721
  const config = JSON.parse(content);
18594
18722
  const merged = {
18595
18723
  version: config.version || DEFAULT_CONFIG.version,
@@ -18659,39 +18787,39 @@ function loadConfig() {
18659
18787
  function saveConfig(config) {
18660
18788
  if (!getConfigFileOverride())
18661
18789
  ensureConfigDir();
18662
- writeFileSync6(activeConfigFile(), JSON.stringify(config, null, 2), "utf-8");
18790
+ writeFileSync7(activeConfigFile(), JSON.stringify(config, null, 2), "utf-8");
18663
18791
  }
18664
18792
  function configExists() {
18665
- return existsSync6(CONFIG_FILE);
18793
+ return existsSync7(CONFIG_FILE);
18666
18794
  }
18667
18795
  function getConfigPath() {
18668
18796
  return CONFIG_FILE;
18669
18797
  }
18670
18798
  function getLocalConfigPath() {
18671
- const home = homedir8();
18799
+ const home = homedir9();
18672
18800
  let dir = process.cwd();
18673
18801
  const root = parse6(dir).root;
18674
18802
  while (dir !== root && dir !== home) {
18675
- const candidate = join8(dir, LOCAL_CONFIG_FILENAME);
18676
- if (existsSync6(candidate))
18803
+ const candidate = join9(dir, LOCAL_CONFIG_FILENAME);
18804
+ if (existsSync7(candidate))
18677
18805
  return candidate;
18678
- if (existsSync6(join8(dir, ".git"))) {
18806
+ if (existsSync7(join9(dir, ".git"))) {
18679
18807
  return candidate;
18680
18808
  }
18681
- dir = dirname5(dir);
18809
+ dir = dirname6(dir);
18682
18810
  }
18683
- return join8(process.cwd(), LOCAL_CONFIG_FILENAME);
18811
+ return join9(process.cwd(), LOCAL_CONFIG_FILENAME);
18684
18812
  }
18685
18813
  function localConfigExists() {
18686
- return existsSync6(getLocalConfigPath());
18814
+ return existsSync7(getLocalConfigPath());
18687
18815
  }
18688
18816
  function readProOnUltracode(paths = defaultScopedConfigPaths) {
18689
18817
  for (const pathFn of [paths.project, paths.global]) {
18690
18818
  try {
18691
18819
  const path = pathFn();
18692
- if (!existsSync6(path))
18820
+ if (!existsSync7(path))
18693
18821
  continue;
18694
- const parsed = JSON.parse(readFileSync6(path, "utf-8"));
18822
+ const parsed = JSON.parse(readFileSync7(path, "utf-8"));
18695
18823
  if (typeof parsed?.proOnUltracode === "boolean")
18696
18824
  return parsed.proOnUltracode;
18697
18825
  } catch {}
@@ -18700,17 +18828,17 @@ function readProOnUltracode(paths = defaultScopedConfigPaths) {
18700
18828
  }
18701
18829
  function isProjectDirectory() {
18702
18830
  const cwd = process.cwd();
18703
- return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) => existsSync6(join8(cwd, f)));
18831
+ return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) => existsSync7(join9(cwd, f)));
18704
18832
  }
18705
18833
  function loadLocalConfig() {
18706
18834
  if (getConfigFileOverride())
18707
18835
  return null;
18708
18836
  const localPath = getLocalConfigPath();
18709
- if (!existsSync6(localPath)) {
18837
+ if (!existsSync7(localPath)) {
18710
18838
  return null;
18711
18839
  }
18712
18840
  try {
18713
- const content = readFileSync6(localPath, "utf-8");
18841
+ const content = readFileSync7(localPath, "utf-8");
18714
18842
  const config = JSON.parse(content);
18715
18843
  return {
18716
18844
  ...config,
@@ -18728,7 +18856,7 @@ function saveLocalConfig(config) {
18728
18856
  if (toWrite.routing !== undefined && Object.keys(toWrite.routing).length === 0) {
18729
18857
  delete toWrite.routing;
18730
18858
  }
18731
- writeFileSync6(getLocalConfigPath(), JSON.stringify(toWrite, null, 2), "utf-8");
18859
+ writeFileSync7(getLocalConfigPath(), JSON.stringify(toWrite, null, 2), "utf-8");
18732
18860
  }
18733
18861
  function loadConfigForScope(scope) {
18734
18862
  if (scope === "local") {
@@ -18976,8 +19104,8 @@ function disableLocalProvider(providerName) {
18976
19104
  }
18977
19105
  var CONFIG_DIR, CONFIG_FILE, LOCAL_CONFIG_FILENAME = ".claudish.json", DEFAULT_CONFIG, defaultScopedConfigPaths;
18978
19106
  var init_profile_config = __esm(() => {
18979
- CONFIG_DIR = join8(homedir8(), ".claudish");
18980
- CONFIG_FILE = join8(CONFIG_DIR, "config.json");
19107
+ CONFIG_DIR = join9(homedir9(), ".claudish");
19108
+ CONFIG_FILE = join9(CONFIG_DIR, "config.json");
18981
19109
  DEFAULT_CONFIG = {
18982
19110
  version: "1.0.0",
18983
19111
  defaultProfile: "default",
@@ -22884,9 +23012,9 @@ var init_openai_api_format = __esm(() => {
22884
23012
 
22885
23013
  // src/auth/vertex-auth.ts
22886
23014
  import { exec } from "child_process";
22887
- import { existsSync as existsSync7 } from "fs";
22888
- import { homedir as homedir9 } from "os";
22889
- import { join as join9 } from "path";
23015
+ import { existsSync as existsSync8 } from "fs";
23016
+ import { homedir as homedir10 } from "os";
23017
+ import { join as join10 } from "path";
22890
23018
  import { promisify } from "util";
22891
23019
 
22892
23020
  class VertexAuthManager {
@@ -22941,8 +23069,8 @@ class VertexAuthManager {
22941
23069
  }
22942
23070
  async tryADC() {
22943
23071
  try {
22944
- const adcPath = join9(homedir9(), ".config/gcloud/application_default_credentials.json");
22945
- if (!existsSync7(adcPath)) {
23072
+ const adcPath = join10(homedir10(), ".config/gcloud/application_default_credentials.json");
23073
+ if (!existsSync8(adcPath)) {
22946
23074
  log("[VertexAuth] ADC credentials file not found");
22947
23075
  return null;
22948
23076
  }
@@ -22966,7 +23094,7 @@ class VertexAuthManager {
22966
23094
  if (!credPath) {
22967
23095
  return null;
22968
23096
  }
22969
- if (!existsSync7(credPath)) {
23097
+ if (!existsSync8(credPath)) {
22970
23098
  throw new Error(`Service account file not found: ${credPath}
22971
23099
 
22972
23100
  Check GOOGLE_APPLICATION_CREDENTIALS path.`);
@@ -23005,8 +23133,8 @@ function validateVertexOAuthConfig() {
23005
23133
  ` + ` export VERTEX_PROJECT='your-gcp-project-id'
23006
23134
  ` + " export VERTEX_LOCATION='us-central1' # optional";
23007
23135
  }
23008
- const adcPath = join9(homedir9(), ".config/gcloud/application_default_credentials.json");
23009
- const hasADC = existsSync7(adcPath);
23136
+ const adcPath = join10(homedir10(), ".config/gcloud/application_default_credentials.json");
23137
+ const hasADC = existsSync8(adcPath);
23010
23138
  const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
23011
23139
  if (!hasADC && !hasServiceAccount) {
23012
23140
  return `No Vertex AI credentials found.
@@ -23616,9 +23744,9 @@ var init_dialect_manager = __esm(() => {
23616
23744
 
23617
23745
  // src/auth/antigravity-token.ts
23618
23746
  import { execFileSync } from "child_process";
23619
- import { existsSync as existsSync8 } from "fs";
23620
- import { homedir as homedir10 } from "os";
23621
- import { join as join10 } from "path";
23747
+ import { existsSync as existsSync9 } from "fs";
23748
+ import { homedir as homedir11 } from "os";
23749
+ import { join as join11 } from "path";
23622
23750
  function invalidateReadStoreMemo() {
23623
23751
  cachedRawStore = null;
23624
23752
  }
@@ -23654,8 +23782,8 @@ function locateAgyBinary() {
23654
23782
  if (p.length > 0)
23655
23783
  return p;
23656
23784
  } catch {}
23657
- const fallback = join10(homedir10(), ".local", "bin", "agy");
23658
- return existsSync8(fallback) ? fallback : null;
23785
+ const fallback = join11(homedir11(), ".local", "bin", "agy");
23786
+ return existsSync9(fallback) ? fallback : null;
23659
23787
  }
23660
23788
  function defaultDeleteStore() {
23661
23789
  if (process.platform !== "darwin")
@@ -24142,9 +24270,9 @@ var init_antigravity = __esm(() => {
24142
24270
  });
24143
24271
 
24144
24272
  // src/auth/quota/sources/codex.ts
24145
- import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
24146
- import { homedir as homedir11 } from "os";
24147
- import { join as join11 } from "path";
24273
+ import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
24274
+ import { homedir as homedir12 } from "os";
24275
+ import { join as join12 } from "path";
24148
24276
  function formatWindowMinutes(minutes) {
24149
24277
  if (!Number.isFinite(minutes) || minutes <= 0)
24150
24278
  return "";
@@ -24158,7 +24286,7 @@ function formatWindowMinutes(minutes) {
24158
24286
  return `${hours}h${minutes % 60}m`;
24159
24287
  }
24160
24288
  function credentialsPath() {
24161
- return join11(homedir11(), ".claudish", "codex-oauth.json");
24289
+ return join12(homedir12(), ".claudish", "codex-oauth.json");
24162
24290
  }
24163
24291
  function planLabel(planType) {
24164
24292
  if (!planType)
@@ -24210,10 +24338,10 @@ function scrapeCodexHeaders(headers) {
24210
24338
  }
24211
24339
  function resolveProbeModel() {
24212
24340
  try {
24213
- const cachePath = join11(homedir11(), ".codex", "models_cache.json");
24214
- if (!existsSync9(cachePath))
24341
+ const cachePath = join12(homedir12(), ".codex", "models_cache.json");
24342
+ if (!existsSync10(cachePath))
24215
24343
  return;
24216
- const cache = JSON.parse(readFileSync7(cachePath, "utf-8"));
24344
+ const cache = JSON.parse(readFileSync8(cachePath, "utf-8"));
24217
24345
  for (const m of cache.models ?? []) {
24218
24346
  const slug = m?.slug ?? m?.id;
24219
24347
  if (typeof slug === "string" && slug.length > 0)
@@ -24225,9 +24353,9 @@ function resolveProbeModel() {
24225
24353
  function readCodexCredentials() {
24226
24354
  try {
24227
24355
  const path = credentialsPath();
24228
- if (!existsSync9(path))
24356
+ if (!existsSync10(path))
24229
24357
  return;
24230
- return JSON.parse(readFileSync7(path, "utf-8"));
24358
+ return JSON.parse(readFileSync8(path, "utf-8"));
24231
24359
  } catch {
24232
24360
  return;
24233
24361
  }
@@ -24258,7 +24386,7 @@ var init_codex = __esm(() => {
24258
24386
  },
24259
24387
  isAvailable() {
24260
24388
  try {
24261
- return existsSync9(credentialsPath());
24389
+ return existsSync10(credentialsPath());
24262
24390
  } catch {
24263
24391
  return false;
24264
24392
  }
@@ -24312,15 +24440,15 @@ import { exec as exec2 } from "child_process";
24312
24440
  import { createHash as createHash2, randomBytes } from "crypto";
24313
24441
  import {
24314
24442
  closeSync as closeSync2,
24315
- existsSync as existsSync10,
24316
- mkdirSync as mkdirSync7,
24443
+ existsSync as existsSync11,
24444
+ mkdirSync as mkdirSync8,
24317
24445
  openSync as openSync2,
24318
- readFileSync as readFileSync8,
24446
+ readFileSync as readFileSync9,
24319
24447
  unlinkSync as unlinkSync2,
24320
24448
  writeSync as writeSync2
24321
24449
  } from "fs";
24322
- import { homedir as homedir12 } from "os";
24323
- import { join as join12 } from "path";
24450
+ import { homedir as homedir13 } from "os";
24451
+ import { join as join13 } from "path";
24324
24452
  import { promisify as promisify2 } from "util";
24325
24453
 
24326
24454
  class OAuthManager {
@@ -24328,21 +24456,21 @@ class OAuthManager {
24328
24456
  refreshPromise = null;
24329
24457
  tokenRefreshMargin = 5 * 60 * 1000;
24330
24458
  static ensureClaudishDir() {
24331
- const dir = join12(homedir12(), ".claudish");
24332
- if (!existsSync10(dir)) {
24333
- mkdirSync7(dir, { recursive: true });
24459
+ const dir = join13(homedir13(), ".claudish");
24460
+ if (!existsSync11(dir)) {
24461
+ mkdirSync8(dir, { recursive: true });
24334
24462
  }
24335
24463
  return dir;
24336
24464
  }
24337
24465
  getCredentialsPath() {
24338
- return join12(homedir12(), ".claudish", this.credentialFile);
24466
+ return join13(homedir13(), ".claudish", this.credentialFile);
24339
24467
  }
24340
24468
  loadCredentials() {
24341
24469
  const credPath = this.getCredentialsPath();
24342
- if (!existsSync10(credPath))
24470
+ if (!existsSync11(credPath))
24343
24471
  return null;
24344
24472
  try {
24345
- const data = JSON.parse(readFileSync8(credPath, "utf-8"));
24473
+ const data = JSON.parse(readFileSync9(credPath, "utf-8"));
24346
24474
  if (!this.validateCredentials(data)) {
24347
24475
  log(`[${this.providerName}] Invalid credentials file structure`);
24348
24476
  return null;
@@ -24367,7 +24495,7 @@ class OAuthManager {
24367
24495
  }
24368
24496
  deleteCredentials() {
24369
24497
  const credPath = this.getCredentialsPath();
24370
- if (existsSync10(credPath)) {
24498
+ if (existsSync11(credPath)) {
24371
24499
  unlinkSync2(credPath);
24372
24500
  log(`[${this.providerName}] Credentials deleted`);
24373
24501
  }
@@ -24674,14 +24802,14 @@ Signed in to Grok. Try it with: claudish --model gk@grok-4.6 "hello"
24674
24802
  });
24675
24803
 
24676
24804
  // src/providers/grok/grok-credentials.ts
24677
- import { existsSync as existsSync11, readFileSync as readFileSync9, renameSync, writeFileSync as writeFileSync7 } from "fs";
24678
- import { homedir as homedir13 } from "os";
24679
- import { join as join13 } from "path";
24805
+ import { existsSync as existsSync12, readFileSync as readFileSync10, renameSync, writeFileSync as writeFileSync8 } from "fs";
24806
+ import { homedir as homedir14 } from "os";
24807
+ import { join as join14 } from "path";
24680
24808
  function grokHome() {
24681
- return grokHomeOverride ?? join13(homedir13(), ".grok");
24809
+ return grokHomeOverride ?? join14(homedir14(), ".grok");
24682
24810
  }
24683
24811
  function grokAuthPath() {
24684
- return join13(grokHome(), "auth.json");
24812
+ return join14(grokHome(), "auth.json");
24685
24813
  }
24686
24814
  function str(value) {
24687
24815
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
@@ -24689,7 +24817,7 @@ function str(value) {
24689
24817
  function readGrokCredential() {
24690
24818
  let parsed;
24691
24819
  try {
24692
- parsed = JSON.parse(readFileSync9(grokAuthPath(), "utf8"));
24820
+ parsed = JSON.parse(readFileSync10(grokAuthPath(), "utf8"));
24693
24821
  } catch {
24694
24822
  return;
24695
24823
  }
@@ -24714,10 +24842,10 @@ function readGrokCredential() {
24714
24842
  };
24715
24843
  }
24716
24844
  function claudishGrokOAuthPath() {
24717
- return claudishOAuthPathOverride ?? join13(homedir13(), ".claudish", "grok-oauth.json");
24845
+ return claudishOAuthPathOverride ?? join14(homedir14(), ".claudish", "grok-oauth.json");
24718
24846
  }
24719
24847
  function hasClaudishGrokOAuth() {
24720
- return existsSync11(claudishGrokOAuthPath());
24848
+ return existsSync12(claudishGrokOAuthPath());
24721
24849
  }
24722
24850
  function hasGrokCredentials() {
24723
24851
  return hasClaudishGrokOAuth() || readGrokCredential() !== undefined;
@@ -24739,7 +24867,7 @@ function readLocalGrokVersion() {
24739
24867
  ["models_cache.json", "grok_version"]
24740
24868
  ]) {
24741
24869
  try {
24742
- const parsed = JSON.parse(readFileSync9(join13(grokHome(), file), "utf8"));
24870
+ const parsed = JSON.parse(readFileSync10(join14(grokHome(), file), "utf8"));
24743
24871
  const version = str(parsed[field]);
24744
24872
  if (version)
24745
24873
  return version;
@@ -24785,7 +24913,7 @@ function persistRefreshedToken(scope, next) {
24785
24913
  const path = grokAuthPath();
24786
24914
  let parsed;
24787
24915
  try {
24788
- parsed = JSON.parse(readFileSync9(path, "utf8"));
24916
+ parsed = JSON.parse(readFileSync10(path, "utf8"));
24789
24917
  } catch {
24790
24918
  return;
24791
24919
  }
@@ -24798,7 +24926,7 @@ function persistRefreshedToken(scope, next) {
24798
24926
  if (next.expiresAt)
24799
24927
  entry.expires_at = next.expiresAt;
24800
24928
  const tmp = `${path}.claudish.tmp`;
24801
- writeFileSync7(tmp, `${JSON.stringify(parsed, null, 2)}
24929
+ writeFileSync8(tmp, `${JSON.stringify(parsed, null, 2)}
24802
24930
  `, { mode: 384 });
24803
24931
  renameSync(tmp, path);
24804
24932
  }
@@ -25328,8 +25456,8 @@ var init_harness = __esm(() => {
25328
25456
 
25329
25457
  // src/behavior/journal.ts
25330
25458
  import { appendFile as appendFile2, mkdir, readFile, rename, stat, writeFile } from "fs/promises";
25331
- import { homedir as homedir14 } from "os";
25332
- import { dirname as dirname6, join as join14 } from "path";
25459
+ import { homedir as homedir15 } from "os";
25460
+ import { dirname as dirname7, join as join15 } from "path";
25333
25461
  function classifyPath(observed, expected) {
25334
25462
  if (!observed)
25335
25463
  return "not_applicable";
@@ -25341,7 +25469,7 @@ function classifyPath(observed, expected) {
25341
25469
  return dirOf(observed) === dirOf(expected) ? "same_dir_wrong_name" : "outside_expected_dir";
25342
25470
  }
25343
25471
  function journalPath() {
25344
- return join14(homedir14(), ".claudish", "behavior-journal.jsonl");
25472
+ return join15(homedir15(), ".claudish", "behavior-journal.jsonl");
25345
25473
  }
25346
25474
  async function prune(path) {
25347
25475
  const content = await readFile(path, "utf8");
@@ -25368,7 +25496,7 @@ async function recordDecision(entry, path = journalPath()) {
25368
25496
  try {
25369
25497
  const size = await stat(path).then((s) => s.size, () => 0);
25370
25498
  if (size === 0)
25371
- await mkdir(dirname6(path), { recursive: true }).catch(() => {});
25499
+ await mkdir(dirname7(path), { recursive: true }).catch(() => {});
25372
25500
  if (size > MAX_JOURNAL_BYTES) {
25373
25501
  await prune(path).catch((err) => log(`[behavior:journal] prune failed: ${err}`));
25374
25502
  }
@@ -25387,9 +25515,9 @@ var init_journal = __esm(() => {
25387
25515
 
25388
25516
  // src/behavior/telemetry/aggregate.ts
25389
25517
  import { createHash as createHash3, randomBytes as randomBytes2 } from "crypto";
25390
- import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync8 } from "fs";
25391
- import { homedir as homedir15 } from "os";
25392
- import { dirname as dirname7, join as join15 } from "path";
25518
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync9 } from "fs";
25519
+ import { homedir as homedir16 } from "os";
25520
+ import { dirname as dirname8, join as join16 } from "path";
25393
25521
  function contextBucket(inputTokens) {
25394
25522
  if (inputTokens < 50000)
25395
25523
  return "0-50k";
@@ -25503,7 +25631,7 @@ function pendingReports() {
25503
25631
  return [...sessions.values()].map(toReport);
25504
25632
  }
25505
25633
  function outboxPath() {
25506
- return join15(homedir15(), ".claudish", "behavior-outbox.jsonl");
25634
+ return join16(homedir16(), ".claudish", "behavior-outbox.jsonl");
25507
25635
  }
25508
25636
  function spoolPendingSync(path = outboxPath()) {
25509
25637
  if (sessions.size === 0)
@@ -25513,7 +25641,7 @@ function spoolPendingSync(path = outboxPath()) {
25513
25641
  if (reports.length === 0)
25514
25642
  return 0;
25515
25643
  try {
25516
- mkdirSync8(dirname7(path), { recursive: true });
25644
+ mkdirSync9(dirname8(path), { recursive: true });
25517
25645
  appendFileSync2(path, `${reports.map((r) => JSON.stringify(r)).join(`
25518
25646
  `)}
25519
25647
  `);
@@ -25710,10 +25838,10 @@ var init_client = __esm(() => {
25710
25838
 
25711
25839
  // src/behavior/observer/live-log.ts
25712
25840
  import { appendFile as appendFile3 } from "fs/promises";
25713
- import { homedir as homedir16 } from "os";
25714
- import { join as join16 } from "path";
25841
+ import { homedir as homedir17 } from "os";
25842
+ import { join as join17 } from "path";
25715
25843
  function defaultPath() {
25716
- return join16(homedir16(), ".claudish", "behavior-divergences.jsonl");
25844
+ return join17(homedir17(), ".claudish", "behavior-divergences.jsonl");
25717
25845
  }
25718
25846
  async function recordLiveDivergence(entry, path = defaultPath()) {
25719
25847
  try {
@@ -26401,9 +26529,9 @@ var init_hooks = __esm(() => {
26401
26529
  });
26402
26530
 
26403
26531
  // src/behavior/observer/corpus.ts
26404
- import { appendFileSync as appendFileSync3, readFileSync as readFileSync10, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
26405
- import { homedir as homedir17 } from "os";
26406
- import { join as join17 } from "path";
26532
+ import { appendFileSync as appendFileSync3, readFileSync as readFileSync11, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
26533
+ import { homedir as homedir18 } from "os";
26534
+ import { join as join18 } from "path";
26407
26535
  function directoryOf2(filePath) {
26408
26536
  const slash = filePath.lastIndexOf("/");
26409
26537
  return slash > 0 ? filePath.slice(0, slash) : undefined;
@@ -26425,7 +26553,7 @@ function writeTargetsOf(row) {
26425
26553
  function replayTranscript(file) {
26426
26554
  let text;
26427
26555
  try {
26428
- text = readFileSync10(file, "utf8");
26556
+ text = readFileSync11(file, "utf8");
26429
26557
  } catch {
26430
26558
  return [];
26431
26559
  }
@@ -26482,26 +26610,26 @@ function listTranscripts(root) {
26482
26610
  return files;
26483
26611
  }
26484
26612
  for (const project of projects) {
26485
- const dir = join17(root, project);
26613
+ const dir = join18(root, project);
26486
26614
  try {
26487
26615
  if (!statSync2(dir).isDirectory())
26488
26616
  continue;
26489
26617
  for (const f of readdirSync2(dir)) {
26490
26618
  if (f.endsWith(".jsonl"))
26491
- files.push(join17(dir, f));
26619
+ files.push(join18(dir, f));
26492
26620
  }
26493
26621
  } catch {}
26494
26622
  }
26495
26623
  return files;
26496
26624
  }
26497
26625
  function buildCorpus(options = {}) {
26498
- const root = options.projectsRoot ?? join17(homedir17(), ".claude", "projects");
26626
+ const root = options.projectsRoot ?? join18(homedir18(), ".claude", "projects");
26499
26627
  const files = listTranscripts(root);
26500
26628
  const records = [];
26501
26629
  for (const f of files)
26502
26630
  records.push(...replayTranscript(f));
26503
26631
  if (options.write && records.length > 0) {
26504
- const outputPath = options.outputPath ?? join17(homedir17(), ".claudish", "behavior-divergences.jsonl");
26632
+ const outputPath = options.outputPath ?? join18(homedir18(), ".claudish", "behavior-divergences.jsonl");
26505
26633
  try {
26506
26634
  appendFileSync3(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
26507
26635
  `)}
@@ -27878,9 +28006,9 @@ var init_keychain_source = __esm(() => {
27878
28006
  });
27879
28007
 
27880
28008
  // src/auth/credentials/api-key-credential.ts
27881
- import { existsSync as existsSync12 } from "fs";
27882
- import { homedir as homedir18 } from "os";
27883
- import { join as join18 } from "path";
28009
+ import { existsSync as existsSync13 } from "fs";
28010
+ import { homedir as homedir19 } from "os";
28011
+ import { join as join19 } from "path";
27884
28012
 
27885
28013
  class ApiKeyCredentialProvider {
27886
28014
  catalogName;
@@ -27915,7 +28043,7 @@ class ApiKeyCredentialProvider {
27915
28043
  if (!this.oauthFallback)
27916
28044
  return false;
27917
28045
  try {
27918
- return existsSync12(join18(homedir18(), ".claudish", this.oauthFallback));
28046
+ return existsSync13(join19(homedir19(), ".claudish", this.oauthFallback));
27919
28047
  } catch {
27920
28048
  return false;
27921
28049
  }
@@ -28006,10 +28134,10 @@ var init_api_key_credential = __esm(() => {
28006
28134
  // src/auth/codex-oauth.ts
28007
28135
  import { exec as exec3 } from "child_process";
28008
28136
  import { createHash as createHash4, randomBytes as randomBytes3 } from "crypto";
28009
- import { closeSync as closeSync3, existsSync as existsSync13, openSync as openSync3, readFileSync as readFileSync11, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "fs";
28137
+ import { closeSync as closeSync3, existsSync as existsSync14, openSync as openSync3, readFileSync as readFileSync12, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "fs";
28010
28138
  import { createServer } from "http";
28011
- import { homedir as homedir19 } from "os";
28012
- import { join as join19 } from "path";
28139
+ import { homedir as homedir20 } from "os";
28140
+ import { join as join20 } from "path";
28013
28141
  import { promisify as promisify3 } from "util";
28014
28142
 
28015
28143
  class CodexOAuth {
@@ -28035,8 +28163,8 @@ class CodexOAuth {
28035
28163
  return this.credentials !== null && !!this.credentials.refresh_token;
28036
28164
  }
28037
28165
  getCredentialsPath() {
28038
- const claudishDir = join19(homedir19(), ".claudish");
28039
- return join19(claudishDir, "codex-oauth.json");
28166
+ const claudishDir = join20(homedir20(), ".claudish");
28167
+ return join20(claudishDir, "codex-oauth.json");
28040
28168
  }
28041
28169
  async login() {
28042
28170
  log("[CodexOAuth] Starting OAuth login flow");
@@ -28062,7 +28190,7 @@ class CodexOAuth {
28062
28190
  }
28063
28191
  async logout() {
28064
28192
  const credPath = this.getCredentialsPath();
28065
- if (existsSync13(credPath)) {
28193
+ if (existsSync14(credPath)) {
28066
28194
  unlinkSync3(credPath);
28067
28195
  log("[CodexOAuth] Credentials deleted");
28068
28196
  }
@@ -28140,11 +28268,11 @@ Details: ${e.message}`);
28140
28268
  }
28141
28269
  loadCredentials() {
28142
28270
  const credPath = this.getCredentialsPath();
28143
- if (!existsSync13(credPath)) {
28271
+ if (!existsSync14(credPath)) {
28144
28272
  return null;
28145
28273
  }
28146
28274
  try {
28147
- const data = readFileSync11(credPath, "utf-8");
28275
+ const data = readFileSync12(credPath, "utf-8");
28148
28276
  const credentials = JSON.parse(data);
28149
28277
  if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at) {
28150
28278
  log("[CodexOAuth] Invalid credentials file structure");
@@ -28159,8 +28287,8 @@ Details: ${e.message}`);
28159
28287
  }
28160
28288
  saveCredentials(credentials) {
28161
28289
  const credPath = this.getCredentialsPath();
28162
- const claudishDir = join19(homedir19(), ".claudish");
28163
- if (!existsSync13(claudishDir)) {
28290
+ const claudishDir = join20(homedir20(), ".claudish");
28291
+ if (!existsSync14(claudishDir)) {
28164
28292
  const { mkdirSync } = __require("fs");
28165
28293
  mkdirSync(claudishDir, { recursive: true });
28166
28294
  }
@@ -28497,11 +28625,11 @@ var init_codex_credential = __esm(() => {
28497
28625
  });
28498
28626
 
28499
28627
  // src/providers/devin/devin-credentials.ts
28500
- import { readFileSync as readFileSync12 } from "fs";
28501
- import { homedir as homedir20 } from "os";
28502
- import { join as join20 } from "path";
28628
+ import { readFileSync as readFileSync13 } from "fs";
28629
+ import { homedir as homedir21 } from "os";
28630
+ import { join as join21 } from "path";
28503
28631
  function devinCredentialsPath() {
28504
- return credentialsPathOverride ?? join20(homedir20(), ".local", "share", "devin", "credentials.toml");
28632
+ return credentialsPathOverride ?? join21(homedir21(), ".local", "share", "devin", "credentials.toml");
28505
28633
  }
28506
28634
  function readTomlString(source, key) {
28507
28635
  const match = source.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, "m"));
@@ -28514,7 +28642,7 @@ function readCredentialsFile() {
28514
28642
  return fileCache.value;
28515
28643
  let value = {};
28516
28644
  try {
28517
- const source = readFileSync12(path, "utf8");
28645
+ const source = readFileSync13(path, "utf8");
28518
28646
  value = {
28519
28647
  apiKey: readTomlString(source, "windsurf_api_key"),
28520
28648
  serverUrl: readTomlString(source, "api_server_url")
@@ -28603,9 +28731,9 @@ var init_grok_credential = __esm(() => {
28603
28731
  // src/auth/kimi-oauth.ts
28604
28732
  import { exec as exec4 } from "child_process";
28605
28733
  import { randomBytes as randomBytes4 } from "crypto";
28606
- import { closeSync as closeSync4, existsSync as existsSync14, openSync as openSync4, readFileSync as readFileSync13, unlinkSync as unlinkSync4, writeSync as writeSync4 } from "fs";
28607
- import { homedir as homedir21, hostname, platform, release as release2 } from "os";
28608
- import { join as join21 } from "path";
28734
+ import { closeSync as closeSync4, existsSync as existsSync15, openSync as openSync4, readFileSync as readFileSync14, unlinkSync as unlinkSync4, writeSync as writeSync4 } from "fs";
28735
+ import { homedir as homedir22, hostname, platform, release as release2 } from "os";
28736
+ import { join as join22 } from "path";
28609
28737
  import { promisify as promisify4 } from "util";
28610
28738
 
28611
28739
  class KimiOAuth {
@@ -28633,23 +28761,23 @@ class KimiOAuth {
28633
28761
  return this.credentials !== null && !!this.credentials.refresh_token;
28634
28762
  }
28635
28763
  getCredentialsPath() {
28636
- const claudishDir = join21(homedir21(), ".claudish");
28637
- return join21(claudishDir, "kimi-oauth.json");
28764
+ const claudishDir = join22(homedir22(), ".claudish");
28765
+ return join22(claudishDir, "kimi-oauth.json");
28638
28766
  }
28639
28767
  getDeviceIdPath() {
28640
- const claudishDir = join21(homedir21(), ".claudish");
28641
- return join21(claudishDir, "kimi-device-id");
28768
+ const claudishDir = join22(homedir22(), ".claudish");
28769
+ return join22(claudishDir, "kimi-device-id");
28642
28770
  }
28643
28771
  loadOrCreateDeviceId() {
28644
28772
  const deviceIdPath = this.getDeviceIdPath();
28645
- const claudishDir = join21(homedir21(), ".claudish");
28646
- if (!existsSync14(claudishDir)) {
28773
+ const claudishDir = join22(homedir22(), ".claudish");
28774
+ if (!existsSync15(claudishDir)) {
28647
28775
  const { mkdirSync } = __require("fs");
28648
28776
  mkdirSync(claudishDir, { recursive: true });
28649
28777
  }
28650
- if (existsSync14(deviceIdPath)) {
28778
+ if (existsSync15(deviceIdPath)) {
28651
28779
  try {
28652
- const deviceId = readFileSync13(deviceIdPath, "utf-8").trim();
28780
+ const deviceId = readFileSync14(deviceIdPath, "utf-8").trim();
28653
28781
  if (deviceId) {
28654
28782
  return deviceId;
28655
28783
  }
@@ -28820,7 +28948,7 @@ Waiting for authorization...`);
28820
28948
  }
28821
28949
  async logout() {
28822
28950
  const credPath = this.getCredentialsPath();
28823
- if (existsSync14(credPath)) {
28951
+ if (existsSync15(credPath)) {
28824
28952
  unlinkSync4(credPath);
28825
28953
  log("[KimiOAuth] Credentials deleted");
28826
28954
  }
@@ -28887,7 +29015,7 @@ Waiting for authorization...`);
28887
29015
  } catch (e) {
28888
29016
  log(`[KimiOAuth] Refresh failed: ${e.message}`);
28889
29017
  const credPath = this.getCredentialsPath();
28890
- if (existsSync14(credPath)) {
29018
+ if (existsSync15(credPath)) {
28891
29019
  unlinkSync4(credPath);
28892
29020
  }
28893
29021
  this.credentials = null;
@@ -28904,11 +29032,11 @@ Details: ${e.message}`);
28904
29032
  }
28905
29033
  loadCredentials() {
28906
29034
  const credPath = this.getCredentialsPath();
28907
- if (!existsSync14(credPath)) {
29035
+ if (!existsSync15(credPath)) {
28908
29036
  return null;
28909
29037
  }
28910
29038
  try {
28911
- const data = readFileSync13(credPath, "utf-8");
29039
+ const data = readFileSync14(credPath, "utf-8");
28912
29040
  const credentials = JSON.parse(data);
28913
29041
  if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at || !credentials.scope || !credentials.token_type) {
28914
29042
  log("[KimiOAuth] Invalid credentials file structure");
@@ -28923,8 +29051,8 @@ Details: ${e.message}`);
28923
29051
  }
28924
29052
  saveCredentials(credentials) {
28925
29053
  const credPath = this.getCredentialsPath();
28926
- const claudishDir = join21(homedir21(), ".claudish");
28927
- if (!existsSync14(claudishDir)) {
29054
+ const claudishDir = join22(homedir22(), ".claudish");
29055
+ if (!existsSync15(claudishDir)) {
28928
29056
  const { mkdirSync } = __require("fs");
28929
29057
  mkdirSync(claudishDir, { recursive: true });
28930
29058
  }
@@ -28954,9 +29082,9 @@ var init_kimi_oauth = __esm(() => {
28954
29082
  });
28955
29083
 
28956
29084
  // src/auth/oauth-registry.ts
28957
- import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
28958
- import { homedir as homedir22 } from "os";
28959
- import { join as join22 } from "path";
29085
+ import { existsSync as existsSync16, readFileSync as readFileSync15 } from "fs";
29086
+ import { homedir as homedir23 } from "os";
29087
+ import { join as join23 } from "path";
28960
29088
  function credentialSatisfies(descriptor, data) {
28961
29089
  if (!data?.access_token)
28962
29090
  return false;
@@ -28969,14 +29097,14 @@ function credentialSatisfies(descriptor, data) {
28969
29097
  return true;
28970
29098
  }
28971
29099
  function hasValidOAuthCredentials(descriptor) {
28972
- const credPath = join22(homedir22(), ".claudish", descriptor.credentialFile);
28973
- if (!existsSync15(credPath))
29100
+ const credPath = join23(homedir23(), ".claudish", descriptor.credentialFile);
29101
+ if (!existsSync16(credPath))
28974
29102
  return false;
28975
29103
  if (descriptor.validationMode === "file-exists") {
28976
29104
  return true;
28977
29105
  }
28978
29106
  try {
28979
- return credentialSatisfies(descriptor, JSON.parse(readFileSync14(credPath, "utf-8")));
29107
+ return credentialSatisfies(descriptor, JSON.parse(readFileSync15(credPath, "utf-8")));
28980
29108
  } catch {
28981
29109
  return false;
28982
29110
  }
@@ -31062,9 +31190,9 @@ var DEFAULT_POLL_INTERVAL_MS = 250;
31062
31190
  var init_transcript_tailer = () => {};
31063
31191
 
31064
31192
  // src/session-events/index.ts
31065
- import { existsSync as existsSync16, readFileSync as readFileSync15, readdirSync as readdirSync3 } from "fs";
31066
- import { homedir as homedir23 } from "os";
31067
- import { join as join23 } from "path";
31193
+ import { existsSync as existsSync17, readFileSync as readFileSync16, readdirSync as readdirSync3 } from "fs";
31194
+ import { homedir as homedir24 } from "os";
31195
+ import { join as join24 } from "path";
31068
31196
  function extractSessionId2(metadata) {
31069
31197
  const userId = metadata?.user_id;
31070
31198
  if (typeof userId !== "string")
@@ -31089,7 +31217,7 @@ class SessionEventRegistry {
31089
31217
  claudeHome;
31090
31218
  pollIntervalMs;
31091
31219
  constructor(opts = {}) {
31092
- this.claudeHome = opts.claudeHome ?? join23(homedir23(), ".claude");
31220
+ this.claudeHome = opts.claudeHome ?? join24(homedir24(), ".claude");
31093
31221
  this.pollIntervalMs = opts.pollIntervalMs;
31094
31222
  }
31095
31223
  ensureSession(sessionId) {
@@ -31175,14 +31303,14 @@ class SessionEventRegistry {
31175
31303
  }
31176
31304
  }
31177
31305
  locateTranscript(sessionId) {
31178
- const projectsDir = join23(this.claudeHome, "projects");
31179
- const primary = join23(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
31180
- if (existsSync16(primary))
31306
+ const projectsDir = join24(this.claudeHome, "projects");
31307
+ const primary = join24(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
31308
+ if (existsSync17(primary))
31181
31309
  return primary;
31182
31310
  try {
31183
31311
  for (const dir of readdirSync3(projectsDir)) {
31184
- const candidate = join23(projectsDir, dir, `${sessionId}.jsonl`);
31185
- if (existsSync16(candidate))
31312
+ const candidate = join24(projectsDir, dir, `${sessionId}.jsonl`);
31313
+ if (existsSync17(candidate))
31186
31314
  return candidate;
31187
31315
  }
31188
31316
  } catch {}
@@ -31190,7 +31318,7 @@ class SessionEventRegistry {
31190
31318
  }
31191
31319
  readSettingsEffortLevel() {
31192
31320
  try {
31193
- const settings = JSON.parse(readFileSync15(join23(this.claudeHome, "settings.json"), "utf-8"));
31321
+ const settings = JSON.parse(readFileSync16(join24(this.claudeHome, "settings.json"), "utf-8"));
31194
31322
  return typeof settings.effortLevel === "string" ? settings.effortLevel : undefined;
31195
31323
  } catch {
31196
31324
  return;
@@ -31389,25 +31517,25 @@ var init_model_parser = __esm(() => {
31389
31517
 
31390
31518
  // src/stats-buffer.ts
31391
31519
  import {
31392
- existsSync as existsSync17,
31393
- mkdirSync as mkdirSync9,
31394
- readFileSync as readFileSync16,
31520
+ existsSync as existsSync18,
31521
+ mkdirSync as mkdirSync10,
31522
+ readFileSync as readFileSync17,
31395
31523
  renameSync as renameSync2,
31396
31524
  unlinkSync as unlinkSync5,
31397
- writeFileSync as writeFileSync8
31525
+ writeFileSync as writeFileSync9
31398
31526
  } from "fs";
31399
- import { homedir as homedir24 } from "os";
31400
- import { join as join24 } from "path";
31527
+ import { homedir as homedir25 } from "os";
31528
+ import { join as join25 } from "path";
31401
31529
  function ensureDir() {
31402
- if (!existsSync17(CLAUDISH_DIR)) {
31403
- mkdirSync9(CLAUDISH_DIR, { recursive: true });
31530
+ if (!existsSync18(CLAUDISH_DIR)) {
31531
+ mkdirSync10(CLAUDISH_DIR, { recursive: true });
31404
31532
  }
31405
31533
  }
31406
31534
  function readFromDisk() {
31407
31535
  try {
31408
- if (!existsSync17(BUFFER_FILE))
31536
+ if (!existsSync18(BUFFER_FILE))
31409
31537
  return [];
31410
- const raw = readFileSync16(BUFFER_FILE, "utf-8");
31538
+ const raw = readFileSync17(BUFFER_FILE, "utf-8");
31411
31539
  const parsed = JSON.parse(raw);
31412
31540
  if (!Array.isArray(parsed.events))
31413
31541
  return [];
@@ -31432,8 +31560,8 @@ function writeToDisk(events) {
31432
31560
  ensureDir();
31433
31561
  const trimmed = enforceSizeCap([...events]);
31434
31562
  const payload = { version: 1, events: trimmed };
31435
- const tmpFile = join24(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
31436
- writeFileSync8(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
31563
+ const tmpFile = join25(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
31564
+ writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
31437
31565
  renameSync2(tmpFile, BUFFER_FILE);
31438
31566
  memoryCache = trimmed;
31439
31567
  } catch {}
@@ -31476,7 +31604,7 @@ function clearBuffer() {
31476
31604
  try {
31477
31605
  memoryCache = [];
31478
31606
  eventsSinceLastFlush = 0;
31479
- if (existsSync17(BUFFER_FILE)) {
31607
+ if (existsSync18(BUFFER_FILE)) {
31480
31608
  unlinkSync5(BUFFER_FILE);
31481
31609
  }
31482
31610
  } catch {}
@@ -31505,8 +31633,8 @@ function syncFlushOnExit() {
31505
31633
  var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false, SIGNAL_EXIT_CODE;
31506
31634
  var init_stats_buffer = __esm(() => {
31507
31635
  BUFFER_MAX_BYTES = 64 * 1024;
31508
- CLAUDISH_DIR = join24(homedir24(), ".claudish");
31509
- BUFFER_FILE = join24(CLAUDISH_DIR, "stats-buffer.json");
31636
+ CLAUDISH_DIR = join25(homedir25(), ".claudish");
31637
+ BUFFER_FILE = join25(CLAUDISH_DIR, "stats-buffer.json");
31510
31638
  process.on("exit", syncFlushOnExit);
31511
31639
  SIGNAL_EXIT_CODE = { SIGTERM: 143, SIGINT: 130 };
31512
31640
  for (const signal of ["SIGTERM", "SIGINT"]) {
@@ -34625,9 +34753,9 @@ var init_openai_responses_sse = __esm(() => {
34625
34753
  });
34626
34754
 
34627
34755
  // src/handlers/shared/token-tracker.ts
34628
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
34629
- import { homedir as homedir25 } from "os";
34630
- import { dirname as dirname8, join as join25 } from "path";
34756
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "fs";
34757
+ import { homedir as homedir26 } from "os";
34758
+ import { dirname as dirname9, join as join26 } from "path";
34631
34759
  function stripProviderPrefix(name) {
34632
34760
  const at = name.indexOf("@");
34633
34761
  return at === -1 ? name : name.slice(at + 1);
@@ -34838,9 +34966,9 @@ class TokenTracker {
34838
34966
  };
34839
34967
  }
34840
34968
  const override = process.env.CLAUDISH_TOKEN_FILE;
34841
- const outPath = override || join25(homedir25(), ".claudish", `tokens-${this.port}.json`);
34842
- mkdirSync10(dirname8(outPath), { recursive: true });
34843
- writeFileSync9(outPath, JSON.stringify(data), "utf-8");
34969
+ const outPath = override || join26(homedir26(), ".claudish", `tokens-${this.port}.json`);
34970
+ mkdirSync11(dirname9(outPath), { recursive: true });
34971
+ writeFileSync10(outPath, JSON.stringify(data), "utf-8");
34844
34972
  } catch (e) {
34845
34973
  log(`[TokenTracker] Error writing token file: ${e}`);
34846
34974
  }
@@ -35881,11 +36009,11 @@ var init_composed_handler = __esm(() => {
35881
36009
  });
35882
36010
 
35883
36011
  // src/providers/api-key-provenance.ts
35884
- import { existsSync as existsSync18, readFileSync as readFileSync17 } from "fs";
35885
- import { homedir as homedir26 } from "os";
35886
- import { join as join26, resolve as resolve2 } from "path";
36012
+ import { existsSync as existsSync19, readFileSync as readFileSync18 } from "fs";
36013
+ import { homedir as homedir27 } from "os";
36014
+ import { join as join27, resolve as resolve2 } from "path";
35887
36015
  function activeConfigPath() {
35888
- return activeGlobalConfigFile(join26(homedir26(), ".claudish", "config.json"));
36016
+ return activeGlobalConfigFile(join27(homedir27(), ".claudish", "config.json"));
35889
36017
  }
35890
36018
  function configLayerLabel() {
35891
36019
  return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
@@ -35965,9 +36093,9 @@ function formatProvenanceLog(p) {
35965
36093
  function readDotenvKey(envVars) {
35966
36094
  try {
35967
36095
  const dotenvPath = resolve2(".env");
35968
- if (!existsSync18(dotenvPath))
36096
+ if (!existsSync19(dotenvPath))
35969
36097
  return null;
35970
- const parsed = import_dotenv.parse(readFileSync17(dotenvPath, "utf-8"));
36098
+ const parsed = import_dotenv.parse(readFileSync18(dotenvPath, "utf-8"));
35971
36099
  for (const v of envVars) {
35972
36100
  if (parsed[v])
35973
36101
  return parsed[v];
@@ -35980,9 +36108,9 @@ function readDotenvKey(envVars) {
35980
36108
  function readConfigKey(envVar) {
35981
36109
  try {
35982
36110
  const configPath = activeConfigPath();
35983
- if (!existsSync18(configPath))
36111
+ if (!existsSync19(configPath))
35984
36112
  return null;
35985
- const cfg = JSON.parse(readFileSync17(configPath, "utf-8"));
36113
+ const cfg = JSON.parse(readFileSync18(configPath, "utf-8"));
35986
36114
  return cfg.apiKeys?.[envVar] || null;
35987
36115
  } catch {
35988
36116
  return null;
@@ -37803,6 +37931,8 @@ function derivePlansUrl(catalogUrl) {
37803
37931
  function getCatalogEntries() {
37804
37932
  if (_catalogEntriesForTest !== undefined)
37805
37933
  return _catalogEntriesForTest;
37934
+ if (readCatalogIncompatibility())
37935
+ return null;
37806
37936
  if (_memCache)
37807
37937
  return _memCache;
37808
37938
  const cache = readAllModelsCache();
@@ -37955,14 +38085,32 @@ async function fetchCatalogPage(url, timeoutMs) {
37955
38085
  const reason = name === "TimeoutError" || name === "AbortError" ? "timeout" : "network";
37956
38086
  return { ok: false, reason };
37957
38087
  }
37958
- if (!response.ok)
38088
+ if (!response.ok) {
38089
+ const verdict = await contractVerdictForError(response);
38090
+ if (verdict) {
38091
+ return {
38092
+ ok: false,
38093
+ reason: "incompatible",
38094
+ serverContractVersion: verdict.serverContractVersion
38095
+ };
38096
+ }
37959
38097
  return { ok: false, reason: "http_error" };
38098
+ }
37960
38099
  let page;
37961
38100
  try {
37962
38101
  page = await response.json();
37963
38102
  } catch {
37964
38103
  return { ok: false, reason: "network" };
37965
38104
  }
38105
+ const bodyEnvelope = parseContractEnvelope(page);
38106
+ if (isIncompatibleContractVersion(bodyEnvelope.contractVersion)) {
38107
+ const verdict = recordIncompatibility(bodyEnvelope);
38108
+ return {
38109
+ ok: false,
38110
+ reason: "incompatible",
38111
+ serverContractVersion: verdict.serverContractVersion
38112
+ };
38113
+ }
37966
38114
  const revision = response.headers.get(CATALOG_REVISION_HEADER) ?? undefined;
37967
38115
  return { ok: true, page, revision };
37968
38116
  }
@@ -37978,6 +38126,12 @@ async function refreshCatalog(timeoutMs, options = {}) {
37978
38126
  const url = buildCatalogPageUrl(catalogUrl(), offset, CATALOG_PAGE_LIMIT, revision);
37979
38127
  const result = await fetchCatalogPage(url, timeoutMs);
37980
38128
  if (!result.ok) {
38129
+ if (result.reason === "incompatible") {
38130
+ return {
38131
+ kind: "incompatible",
38132
+ serverContractVersion: result.serverContractVersion
38133
+ };
38134
+ }
37981
38135
  return {
37982
38136
  kind: "fetch_failed",
37983
38137
  reason: pages === 0 ? result.reason : "incomplete"
@@ -38013,6 +38167,7 @@ async function refreshCatalog(timeoutMs, options = {}) {
38013
38167
  if (id)
38014
38168
  backwardCompatModels.push({ id });
38015
38169
  }
38170
+ clearCatalogIncompatibility();
38016
38171
  _memCache = entries;
38017
38172
  writeAllModelsCache({
38018
38173
  entries,
@@ -38023,6 +38178,20 @@ async function refreshCatalog(timeoutMs, options = {}) {
38023
38178
  _warmPromise = Promise.resolve();
38024
38179
  return { kind: "refreshed", modelCount: entries.length, catalogRevision: revision, pages };
38025
38180
  }
38181
+ async function contractVerdictForError(response) {
38182
+ const envelope = parseContractEnvelope(await readJsonBody(response));
38183
+ if (response.status === 426 || isIncompatibleContractVersion(envelope.contractVersion)) {
38184
+ return recordIncompatibility(envelope);
38185
+ }
38186
+ return null;
38187
+ }
38188
+ async function readJsonBody(response) {
38189
+ try {
38190
+ return await response.json();
38191
+ } catch {
38192
+ return;
38193
+ }
38194
+ }
38026
38195
  async function fetchSubscriptionPlans(timeoutMs, revision) {
38027
38196
  try {
38028
38197
  const url = new URL(plansUrl());
@@ -38031,14 +38200,28 @@ async function fetchSubscriptionPlans(timeoutMs, revision) {
38031
38200
  const response = await fetch(url.toString(), {
38032
38201
  signal: AbortSignal.timeout(timeoutMs)
38033
38202
  });
38034
- if (!response.ok)
38203
+ if (!response.ok) {
38204
+ await contractVerdictForError(response);
38035
38205
  return;
38206
+ }
38036
38207
  const data = await response.json();
38208
+ const envelope = parseContractEnvelope(data);
38209
+ if (isIncompatibleContractVersion(envelope.contractVersion)) {
38210
+ recordIncompatibility(envelope);
38211
+ return;
38212
+ }
38037
38213
  return Array.isArray(data.plans) ? data.plans : undefined;
38038
38214
  } catch {
38039
38215
  return;
38040
38216
  }
38041
38217
  }
38218
+ function recordIncompatibility(envelope) {
38219
+ markCatalogIncompatible({
38220
+ serverContractVersion: envelope.contractVersion,
38221
+ ...envelope.minimumContractVersion !== undefined ? { minimumContractVersion: envelope.minimumContractVersion } : {}
38222
+ });
38223
+ return { kind: "incompatible", serverContractVersion: envelope.contractVersion };
38224
+ }
38042
38225
  async function warmCatalog() {
38043
38226
  if (!_warmPromise) {
38044
38227
  _warmPromise = refreshCatalog(8000).then(() => {
@@ -38063,6 +38246,7 @@ async function ensureCatalogReady(timeoutMs = 5000) {
38063
38246
  var DEFAULT_CATALOG_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels?status=active&catalog=slim&limit=1000", _memCache = null, _catalogEntriesForTest, _warmPromise = null, CATALOG_REVISION_HEADER = "x-catalog-revision", MAX_CATALOG_PAGES = 40, CATALOG_PAGE_LIMIT = 1000;
38064
38247
  var init_catalog_client = __esm(() => {
38065
38248
  init_all_models_cache();
38249
+ init_catalog_compatibility();
38066
38250
  });
38067
38251
 
38068
38252
  // src/config-schema.ts
@@ -39331,7 +39515,16 @@ function globMatch(pattern, value) {
39331
39515
  async function hasCredentialsForProvider(provider) {
39332
39516
  return credentials.isAvailable(provider);
39333
39517
  }
39518
+ function warnOnceIfCatalogIncompatible() {
39519
+ if (_warnedCatalogIncompatible)
39520
+ return;
39521
+ if (!readCatalogIncompatibility())
39522
+ return;
39523
+ _warnedCatalogIncompatible = true;
39524
+ logStderr("Model catalog is unavailable \u2014 this build cannot read the catalog server's current " + "contract. Explicit provider@model routing still works; bare model names do not. " + "Run `claudish update`.");
39525
+ }
39334
39526
  async function routeExplicit(modelSpec, model, provider, cachePath) {
39527
+ warnOnceIfCatalogIncompatible();
39335
39528
  if (!await hasCredentialsForProvider(provider)) {
39336
39529
  return {
39337
39530
  kind: "no-route",
@@ -39356,6 +39549,10 @@ async function routeExplicit(modelSpec, model, provider, cachePath) {
39356
39549
  return { kind: "ok", primary: built, fallbacks: [] };
39357
39550
  }
39358
39551
  async function routeBare(model, nativeProvider, rules, defaultProvider, cachePath) {
39552
+ const incompatible = readCatalogIncompatibility();
39553
+ if (incompatible) {
39554
+ throw new CatalogIncompatibleError(catalogIncompatibilityMessage(incompatible));
39555
+ }
39359
39556
  const matched = matchRoutingRule(model, rules) ?? [];
39360
39557
  const entries = [...matched];
39361
39558
  if (defaultProvider && defaultProvider.length > 0) {
@@ -39437,6 +39634,7 @@ async function route(modelSpec, rulesOverride, defaultProviderOverride, cachePat
39437
39634
  const defaultProvider = defaultProviderOverride !== undefined ? defaultProviderOverride : rulesOverride !== undefined ? undefined : loadConfig().defaultProvider;
39438
39635
  return routeBare(normalizeGlmSlug(parsed.model), parsed.provider, rules, defaultProvider, cachePath);
39439
39636
  }
39637
+ var _warnedCatalogIncompatible = false;
39440
39638
  var init_routing_rules = __esm(() => {
39441
39639
  init_model_catalog();
39442
39640
  init_authority();
@@ -39445,6 +39643,7 @@ var init_routing_rules = __esm(() => {
39445
39643
  init_profile_config();
39446
39644
  init_auto_route();
39447
39645
  init_catalog_client();
39646
+ init_catalog_compatibility();
39448
39647
  init_default_routing_rules();
39449
39648
  init_model_availability();
39450
39649
  init_model_parser();
@@ -40549,8 +40748,8 @@ __export(exports_session_discovery, {
40549
40748
  });
40550
40749
  import { execFile, execFileSync as execFileSync2 } from "child_process";
40551
40750
  import { closeSync as closeSync6, openSync as openSync6, readSync as readSync2, readdirSync as readdirSync4, realpathSync, statSync as statSync5 } from "fs";
40552
- import { homedir as homedir27 } from "os";
40553
- import { basename, join as join27 } from "path";
40751
+ import { homedir as homedir28 } from "os";
40752
+ import { basename, join as join28 } from "path";
40554
40753
  function slugForPath(absPath) {
40555
40754
  return absPath.replace(/[/.]/g, "-");
40556
40755
  }
@@ -40559,7 +40758,7 @@ function transcriptPathFor(cwd, sessionUuid) {
40559
40758
  try {
40560
40759
  real = realpathSync(cwd);
40561
40760
  } catch {}
40562
- return join27(PROJECTS_DIR, slugForPath(real), `${sessionUuid}.jsonl`);
40761
+ return join28(PROJECTS_DIR, slugForPath(real), `${sessionUuid}.jsonl`);
40563
40762
  }
40564
40763
  function isAgentSession(row) {
40565
40764
  return row.entrypoint !== undefined && row.entrypoint !== "cli";
@@ -40606,7 +40805,7 @@ function projectDirs() {
40606
40805
  }
40607
40806
  }
40608
40807
  function sessionsIn(dirName) {
40609
- const dir = join27(PROJECTS_DIR, dirName);
40808
+ const dir = join28(PROJECTS_DIR, dirName);
40610
40809
  let names;
40611
40810
  try {
40612
40811
  names = readdirSync4(dir).filter((n) => n.endsWith(".jsonl"));
@@ -40615,7 +40814,7 @@ function sessionsIn(dirName) {
40615
40814
  }
40616
40815
  const rows = [];
40617
40816
  for (const n of names) {
40618
- const file = join27(dir, n);
40817
+ const file = join28(dir, n);
40619
40818
  try {
40620
40819
  const st = statSync5(file);
40621
40820
  if (st.size === 0)
@@ -40977,7 +41176,7 @@ function findLatestSessionId(cwd = process.cwd(), sinceMs = 0) {
40977
41176
  }
40978
41177
  var ENTRYPOINT_BYTES = 8192, PROJECTS_DIR, ACTIVE_WINDOW_MS = 120000, HEAD_BYTES, TAIL_BYTES, HARNESS_ENVELOPES, DEEP_TAIL_BYTES, RECENT_AI_TURNS = 5, RECENT_USER_TURNS = 1;
40979
41178
  var init_session_discovery = __esm(() => {
40980
- PROJECTS_DIR = join27(homedir27(), ".claude", "projects");
41179
+ PROJECTS_DIR = join28(homedir28(), ".claude", "projects");
40981
41180
  HEAD_BYTES = 64 * 1024;
40982
41181
  TAIL_BYTES = 128 * 1024;
40983
41182
  HARNESS_ENVELOPES = [
@@ -41012,19 +41211,19 @@ function newStdioDecoder() {
41012
41211
  var init_stdio_decode = () => {};
41013
41212
 
41014
41213
  // src/team-stats.ts
41015
- import { existsSync as existsSync19, readFileSync as readFileSync18, writeFileSync as writeFileSync10 } from "fs";
41016
- import { join as join28 } from "path";
41214
+ import { existsSync as existsSync20, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "fs";
41215
+ import { join as join29 } from "path";
41017
41216
  function statsDir(sessionPath) {
41018
- return join28(sessionPath, "stats");
41217
+ return join29(sessionPath, "stats");
41019
41218
  }
41020
41219
  function tokenFileFor(sessionPath, anonId) {
41021
- return join28(statsDir(sessionPath), `${anonId}.json`);
41220
+ return join29(statsDir(sessionPath), `${anonId}.json`);
41022
41221
  }
41023
41222
  function readTokenStatsAt(path) {
41024
- if (!existsSync19(path))
41223
+ if (!existsSync20(path))
41025
41224
  return null;
41026
41225
  try {
41027
- return JSON.parse(readFileSync18(path, "utf-8"));
41226
+ return JSON.parse(readFileSync19(path, "utf-8"));
41028
41227
  } catch {
41029
41228
  return null;
41030
41229
  }
@@ -41175,7 +41374,7 @@ ${segs.join(" \xB7 ")}`;
41175
41374
  }
41176
41375
  function writeStatusFile(sessionPath, manifest, status, opts) {
41177
41376
  try {
41178
- writeFileSync10(join28(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
41377
+ writeFileSync11(join29(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
41179
41378
  `, "utf-8");
41180
41379
  } catch {}
41181
41380
  }
@@ -41186,13 +41385,13 @@ var init_team_stats = () => {};
41186
41385
  import { spawn as spawn2 } from "child_process";
41187
41386
  import {
41188
41387
  createWriteStream,
41189
- existsSync as existsSync20,
41190
- mkdirSync as mkdirSync11,
41191
- readFileSync as readFileSync19,
41388
+ existsSync as existsSync21,
41389
+ mkdirSync as mkdirSync12,
41390
+ readFileSync as readFileSync20,
41192
41391
  readdirSync as readdirSync5,
41193
- writeFileSync as writeFileSync11
41392
+ writeFileSync as writeFileSync12
41194
41393
  } from "fs";
41195
- import { basename as basename2, join as join29, resolve as resolve3 } from "path";
41394
+ import { basename as basename2, join as join30, resolve as resolve3 } from "path";
41196
41395
  function resolveCaptureMode(explicit, env = process.env) {
41197
41396
  if (explicit)
41198
41397
  return explicit;
@@ -41340,7 +41539,7 @@ function persistErrorLog(errorLogPath, header, stderr, stdoutTail) {
41340
41539
  parts.push("--- stderr ---", stderr.trim() ? redactSecrets(stderr) : "(empty)", "");
41341
41540
  parts.push("--- stdout (tail) ---", stdoutTail.trim() ? redactSecrets(stdoutTail) : "(empty)", "");
41342
41541
  try {
41343
- writeFileSync11(errorLogPath, parts.join(`
41542
+ writeFileSync12(errorLogPath, parts.join(`
41344
41543
  `), "utf-8");
41345
41544
  } catch {}
41346
41545
  }
@@ -41358,10 +41557,10 @@ function readTeamInputFile(inputPath) {
41358
41557
  if (!resolved.startsWith(`${cwd}/`) && resolved !== cwd) {
41359
41558
  throw new Error(`Input file must be within current directory: ${inputPath}`);
41360
41559
  }
41361
- if (!existsSync20(resolved)) {
41560
+ if (!existsSync21(resolved)) {
41362
41561
  throw new Error(`Input file not found: ${resolved}`);
41363
41562
  }
41364
- const text = readFileSync19(resolved, "utf-8");
41563
+ const text = readFileSync20(resolved, "utf-8");
41365
41564
  if (text.trim().length === 0) {
41366
41565
  throw new Error(`Input file is empty: ${resolved}`);
41367
41566
  }
@@ -41371,14 +41570,14 @@ function setupSession(sessionPath, models, input) {
41371
41570
  if (models.length === 0) {
41372
41571
  throw new Error("At least one model is required");
41373
41572
  }
41374
- if (existsSync20(join29(sessionPath, "manifest.json"))) {
41573
+ if (existsSync21(join30(sessionPath, "manifest.json"))) {
41375
41574
  throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
41376
41575
  }
41377
- mkdirSync11(join29(sessionPath, "work"), { recursive: true });
41378
- mkdirSync11(join29(sessionPath, "errors"), { recursive: true });
41576
+ mkdirSync12(join30(sessionPath, "work"), { recursive: true });
41577
+ mkdirSync12(join30(sessionPath, "errors"), { recursive: true });
41379
41578
  if (input !== undefined) {
41380
- writeFileSync11(join29(sessionPath, "input.md"), input, "utf-8");
41381
- } else if (!existsSync20(join29(sessionPath, "input.md"))) {
41579
+ writeFileSync12(join30(sessionPath, "input.md"), input, "utf-8");
41580
+ } else if (!existsSync21(join30(sessionPath, "input.md"))) {
41382
41581
  throw new Error(`No input.md found at ${sessionPath} and no input provided`);
41383
41582
  }
41384
41583
  const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
@@ -41395,9 +41594,9 @@ function setupSession(sessionPath, models, input) {
41395
41594
  model: models[i],
41396
41595
  assignedAt: now
41397
41596
  };
41398
- mkdirSync11(join29(sessionPath, "work", anonId), { recursive: true });
41597
+ mkdirSync12(join30(sessionPath, "work", anonId), { recursive: true });
41399
41598
  }
41400
- writeFileSync11(join29(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
41599
+ writeFileSync12(join30(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
41401
41600
  const status = {
41402
41601
  startedAt: now,
41403
41602
  models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
@@ -41411,7 +41610,7 @@ function setupSession(sessionPath, models, input) {
41411
41610
  }
41412
41611
  ]))
41413
41612
  };
41414
- writeFileSync11(join29(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
41613
+ writeFileSync12(join30(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
41415
41614
  return manifest;
41416
41615
  }
41417
41616
  function assertValidRequirePattern(pattern) {
@@ -41428,22 +41627,22 @@ function readFullOutputIfNeeded(opts) {
41428
41627
  if (crashed || !requirePattern || outputSize <= STDOUT_TAIL_LIMIT)
41429
41628
  return;
41430
41629
  try {
41431
- return readFileSync19(outputPath, "utf-8");
41630
+ return readFileSync20(outputPath, "utf-8");
41432
41631
  } catch {
41433
41632
  return;
41434
41633
  }
41435
41634
  }
41436
41635
  async function startModels(sessionPath, opts = {}) {
41437
41636
  assertValidRequirePattern(opts.requirePattern);
41438
- const manifest = JSON.parse(readFileSync19(join29(sessionPath, "manifest.json"), "utf-8"));
41439
- const statusPath = join29(sessionPath, "status.json");
41440
- const inputPath = join29(sessionPath, "input.md");
41441
- const inputContent = readFileSync19(inputPath, "utf-8");
41637
+ const manifest = JSON.parse(readFileSync20(join30(sessionPath, "manifest.json"), "utf-8"));
41638
+ const statusPath = join30(sessionPath, "status.json");
41639
+ const inputPath = join30(sessionPath, "input.md");
41640
+ const inputContent = readFileSync20(inputPath, "utf-8");
41442
41641
  const spawnPlan = await (opts.spawnPlanner ?? prehydrateCredentialsForSpawn)(Object.values(manifest.models).map((m) => m.model));
41443
- const statusCache = JSON.parse(readFileSync19(statusPath, "utf-8"));
41642
+ const statusCache = JSON.parse(readFileSync20(statusPath, "utf-8"));
41444
41643
  function updateModelStatus(id, update) {
41445
41644
  statusCache.models[id] = { ...statusCache.models[id], ...update };
41446
- writeFileSync11(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
41645
+ writeFileSync12(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
41447
41646
  }
41448
41647
  const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
41449
41648
  const requirePattern = opts.requirePattern;
@@ -41476,7 +41675,7 @@ async function startModels(sessionPath, opts = {}) {
41476
41675
  persistErrorLog(rt.errorLogPath, `RECOVERED: ${note}`, stderr, stdoutTail);
41477
41676
  opts.onStatusChange?.(id, statusCache.models[id]);
41478
41677
  }
41479
- mkdirSync11(statsDir(sessionPath), { recursive: true });
41678
+ mkdirSync12(statsDir(sessionPath), { recursive: true });
41480
41679
  const processes = new Map;
41481
41680
  const runtimes = new Map;
41482
41681
  const cancelledSlots = new Set;
@@ -41489,9 +41688,9 @@ async function startModels(sessionPath, opts = {}) {
41489
41688
  process.on("SIGINT", sigintHandler);
41490
41689
  const completionPromises = [];
41491
41690
  for (const [anonId, entry] of Object.entries(manifest.models)) {
41492
- const outputPath = join29(sessionPath, `response-${anonId}.md`);
41493
- const errorLogPath = join29(sessionPath, "errors", `${anonId}.log`);
41494
- const upstreamErrorLogPath = join29(sessionPath, "errors", `${anonId}-upstream.jsonl`);
41691
+ const outputPath = join30(sessionPath, `response-${anonId}.md`);
41692
+ const errorLogPath = join30(sessionPath, "errors", `${anonId}.log`);
41693
+ const upstreamErrorLogPath = join30(sessionPath, "errors", `${anonId}-upstream.jsonl`);
41495
41694
  const spawnModel = spawnPlan.pinned.get(entry.model) ?? entry.model;
41496
41695
  const args = [
41497
41696
  "--model",
@@ -41645,7 +41844,7 @@ async function startModels(sessionPath, opts = {}) {
41645
41844
  stderrSnippet: stderr ? redactSecrets(stderr).slice(-2000) : undefined,
41646
41845
  stdoutSnippet: stdoutTail ? snippetHeadAndTail(redactSecrets(stdoutTail)) : undefined,
41647
41846
  errorLogPath,
41648
- upstreamErrorLogPath: existsSync20(upstreamErrorLogPath) ? upstreamErrorLogPath : undefined,
41847
+ upstreamErrorLogPath: existsSync21(upstreamErrorLogPath) ? upstreamErrorLogPath : undefined,
41649
41848
  workDir: sessionPath
41650
41849
  }
41651
41850
  });
@@ -41666,7 +41865,7 @@ async function startModels(sessionPath, opts = {}) {
41666
41865
  proc.on("exit", (code) => {
41667
41866
  const timedOut = statusCache.models[anonId]?.state === "TIMEOUT";
41668
41867
  if (!timedOut && meaningfulStderr(stderr)) {
41669
- writeFileSync11(errorLogPath, redactSecrets(stderr), "utf-8");
41868
+ writeFileSync12(errorLogPath, redactSecrets(stderr), "utf-8");
41670
41869
  }
41671
41870
  exitCode = code;
41672
41871
  if (outputStream.destroyed) {
@@ -41748,23 +41947,23 @@ async function judgeResponses(sessionPath, opts = {}) {
41748
41947
  const responses = {};
41749
41948
  for (const file of responseFiles) {
41750
41949
  const id = file.replace(/^response-/, "").replace(/\.md$/, "");
41751
- responses[id] = readFileSync19(join29(sessionPath, file), "utf-8");
41950
+ responses[id] = readFileSync20(join30(sessionPath, file), "utf-8");
41752
41951
  }
41753
- const input = readFileSync19(join29(sessionPath, "input.md"), "utf-8");
41952
+ const input = readFileSync20(join30(sessionPath, "input.md"), "utf-8");
41754
41953
  const judgePrompt = buildJudgePrompt(input, responses);
41755
- writeFileSync11(join29(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
41954
+ writeFileSync12(join30(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
41756
41955
  const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
41757
- const judgePath = join29(sessionPath, "judging");
41758
- mkdirSync11(judgePath, { recursive: true });
41956
+ const judgePath = join30(sessionPath, "judging");
41957
+ mkdirSync12(judgePath, { recursive: true });
41759
41958
  setupSession(judgePath, judgeModels, judgePrompt);
41760
41959
  await runModels(judgePath, { claudeFlags: opts.claudeFlags });
41761
41960
  const votes = parseJudgeVotes(judgePath, Object.keys(responses));
41762
41961
  const verdict = aggregateVerdict(votes, Object.keys(responses));
41763
- writeFileSync11(join29(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
41962
+ writeFileSync12(join30(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
41764
41963
  return verdict;
41765
41964
  }
41766
41965
  function getStatus(sessionPath) {
41767
- return JSON.parse(readFileSync19(join29(sessionPath, "status.json"), "utf-8"));
41966
+ return JSON.parse(readFileSync20(join30(sessionPath, "status.json"), "utf-8"));
41768
41967
  }
41769
41968
  function fisherYatesShuffle(arr) {
41770
41969
  for (let i = arr.length - 1;i > 0; i--) {
@@ -41774,7 +41973,7 @@ function fisherYatesShuffle(arr) {
41774
41973
  return arr;
41775
41974
  }
41776
41975
  function getDefaultJudgeModels(sessionPath) {
41777
- const manifest = JSON.parse(readFileSync19(join29(sessionPath, "manifest.json"), "utf-8"));
41976
+ const manifest = JSON.parse(readFileSync20(join30(sessionPath, "manifest.json"), "utf-8"));
41778
41977
  return Object.values(manifest.models).map((e) => e.model);
41779
41978
  }
41780
41979
  function buildJudgePrompt(input, responses) {
@@ -41837,7 +42036,7 @@ function parseJudgeVotes(judgePath, responseIds) {
41837
42036
  const judgeId = file.replace(/^response-/, "").replace(/\.md$/, "");
41838
42037
  let content;
41839
42038
  try {
41840
- content = readFileSync19(join29(judgePath, file), "utf-8");
42039
+ content = readFileSync20(join30(judgePath, file), "utf-8");
41841
42040
  } catch {
41842
42041
  continue;
41843
42042
  }
@@ -41889,7 +42088,7 @@ function aggregateVerdict(votes, responseIds) {
41889
42088
  function formatVerdict(verdict, sessionPath) {
41890
42089
  let manifest = null;
41891
42090
  try {
41892
- manifest = JSON.parse(readFileSync19(join29(sessionPath, "manifest.json"), "utf-8"));
42091
+ manifest = JSON.parse(readFileSync20(join30(sessionPath, "manifest.json"), "utf-8"));
41893
42092
  } catch {}
41894
42093
  let output = `# Team Verdict
41895
42094
 
@@ -41943,15 +42142,15 @@ import {
41943
42142
  appendFileSync as appendFileSync6,
41944
42143
  closeSync as closeSync7,
41945
42144
  createWriteStream as createWriteStream2,
41946
- mkdirSync as mkdirSync12,
42145
+ mkdirSync as mkdirSync13,
41947
42146
  openSync as openSync7,
41948
- readFileSync as readFileSync20,
42147
+ readFileSync as readFileSync21,
41949
42148
  readSync as readSync3,
41950
42149
  statSync as statSync6,
41951
- writeFileSync as writeFileSync12
42150
+ writeFileSync as writeFileSync13
41952
42151
  } from "fs";
41953
- import { homedir as homedir28 } from "os";
41954
- import { join as join30, resolve as resolve4, sep } from "path";
42152
+ import { homedir as homedir29 } from "os";
42153
+ import { join as join31, resolve as resolve4, sep } from "path";
41955
42154
  import { StringDecoder as StringDecoder2 } from "string_decoder";
41956
42155
  function buildChannelSpawnArgs(opts) {
41957
42156
  return [
@@ -42026,7 +42225,7 @@ function readJsonObject(path, maxBytes) {
42026
42225
  try {
42027
42226
  if (fileSize(path) > maxBytes)
42028
42227
  return null;
42029
- const parsed = JSON.parse(readFileSync20(path, "utf-8"));
42228
+ const parsed = JSON.parse(readFileSync21(path, "utf-8"));
42030
42229
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
42031
42230
  return null;
42032
42231
  return parsed;
@@ -42042,7 +42241,7 @@ function dropLeadingFragment(tail) {
42042
42241
  return firstBreak === -1 ? tail.text : tail.text.slice(firstBreak + 1);
42043
42242
  }
42044
42243
  function diskAccounting(sessionDir) {
42045
- const stats = readTokenStatsAt(join30(sessionDir, "tokens.json"));
42244
+ const stats = readTokenStatsAt(join31(sessionDir, "tokens.json"));
42046
42245
  return {
42047
42246
  tokensUsed: (stats?.total_tokens ?? 0) || (stats?.input_tokens ?? 0) + (stats?.output_tokens ?? 0),
42048
42247
  costUsd: stats?.total_cost ?? 0,
@@ -42082,7 +42281,7 @@ class SessionManager {
42082
42281
  this.maxSessions = options?.maxSessions ?? DEFAULT_MAX_SESSIONS;
42083
42282
  this.scrollbackCapacity = options?.scrollbackCapacity ?? DEFAULT_SCROLLBACK;
42084
42283
  this.terminalRetentionMs = options?.terminalRetentionMs ?? TERMINAL_RETENTION_MS;
42085
- this.sessionsDir = options?.sessionsDir ?? process.env.CLAUDISH_SESSIONS_DIR ?? join30(homedir28(), ".claudish", "sessions");
42284
+ this.sessionsDir = options?.sessionsDir ?? process.env.CLAUDISH_SESSIONS_DIR ?? join31(homedir29(), ".claudish", "sessions");
42086
42285
  this.stallSeconds = options?.stallSeconds;
42087
42286
  this.onStateChange = options?.onStateChange;
42088
42287
  }
@@ -42098,19 +42297,19 @@ class SessionManager {
42098
42297
  const claudeSessionId = randomUUID4();
42099
42298
  const timeout = Math.min(opts.timeoutSeconds ?? DEFAULT_TIMEOUT, MAX_TIMEOUT);
42100
42299
  const startedAt = new Date().toISOString();
42101
- const sessionDir = opts.sessionDir ?? join30(this.sessionsDir, sessionId);
42102
- mkdirSync12(sessionDir, { recursive: true });
42300
+ const sessionDir = opts.sessionDir ?? join31(this.sessionsDir, sessionId);
42301
+ mkdirSync13(sessionDir, { recursive: true });
42103
42302
  if (opts.prompt) {
42104
- writeFileSync12(join30(sessionDir, "prompt.md"), opts.prompt, "utf-8");
42303
+ writeFileSync13(join31(sessionDir, "prompt.md"), opts.prompt, "utf-8");
42105
42304
  }
42106
42305
  const args = buildChannelSpawnArgs({
42107
42306
  model: opts.spawnModel ?? opts.model,
42108
42307
  claudeSessionId,
42109
42308
  claudishFlags: opts.claudishFlags
42110
42309
  });
42111
- const tokenFile = opts.tokenFile ?? join30(sessionDir, "tokens.json");
42112
- const eventLogPath = join30(sessionDir, "events.jsonl");
42113
- const upstreamErrorLogPath = join30(sessionDir, "upstream-errors.jsonl");
42310
+ const tokenFile = opts.tokenFile ?? join31(sessionDir, "tokens.json");
42311
+ const eventLogPath = join31(sessionDir, "events.jsonl");
42312
+ const upstreamErrorLogPath = join31(sessionDir, "upstream-errors.jsonl");
42114
42313
  const cwd = opts.cwd ?? process.cwd();
42115
42314
  const spawnTarget = resolveClaudishSpawn();
42116
42315
  const proc = spawn3(spawnTarget.command, [...spawnTarget.prefixArgs, ...args], {
@@ -42125,7 +42324,7 @@ class SessionManager {
42125
42324
  }
42126
42325
  });
42127
42326
  const scrollback = new ScrollbackBuffer(this.scrollbackCapacity);
42128
- const outputLogStream = createWriteStream2(join30(sessionDir, "output.log"));
42327
+ const outputLogStream = createWriteStream2(join31(sessionDir, "output.log"));
42129
42328
  const entry = {
42130
42329
  info: {
42131
42330
  sessionId,
@@ -42417,7 +42616,7 @@ class SessionManager {
42417
42616
  return null;
42418
42617
  const root = resolve4(this.sessionsDir);
42419
42618
  const dir = resolve4(root, sessionId);
42420
- if (dir !== join30(root, sessionId))
42619
+ if (dir !== join31(root, sessionId))
42421
42620
  return null;
42422
42621
  if (!dir.startsWith(root + sep))
42423
42622
  return null;
@@ -42436,7 +42635,7 @@ class SessionManager {
42436
42635
  } catch {
42437
42636
  return null;
42438
42637
  }
42439
- const meta = readJsonObject(join30(sessionDir, "meta.json"), META_READ_LIMIT);
42638
+ const meta = readJsonObject(join31(sessionDir, "meta.json"), META_READ_LIMIT);
42440
42639
  const partial = meta === null;
42441
42640
  const measured = diskAccounting(sessionDir);
42442
42641
  const startedAt = metaString(meta?.startedAt) ?? new Date(dirMtimeMs).toISOString();
@@ -42466,7 +42665,7 @@ class SessionManager {
42466
42665
  };
42467
42666
  }
42468
42667
  diskOutput(record, tailLines) {
42469
- const tail = readTailText(join30(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
42668
+ const tail = readTailText(join31(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
42470
42669
  const buffer = new ScrollbackBuffer(this.scrollbackCapacity);
42471
42670
  if (tail?.text)
42472
42671
  buffer.append(dropLeadingFragment(tail));
@@ -42485,9 +42684,9 @@ class SessionManager {
42485
42684
  }
42486
42685
  diskDiagnostics(record, limit) {
42487
42686
  const { sessionDir, info } = record;
42488
- const eventLogPath = join30(sessionDir, "events.jsonl");
42489
- const upstreamErrorLogPath = join30(sessionDir, "upstream-errors.jsonl");
42490
- const outputLogPath = join30(sessionDir, "output.log");
42687
+ const eventLogPath = join31(sessionDir, "events.jsonl");
42688
+ const upstreamErrorLogPath = join31(sessionDir, "upstream-errors.jsonl");
42689
+ const outputLogPath = join31(sessionDir, "output.log");
42491
42690
  const events = readTailLines(eventLogPath, EVENT_TAIL_BYTES);
42492
42691
  const outputTail = readTailText(outputLogPath, OUTPUT_TAIL_BYTES);
42493
42692
  return {
@@ -42529,7 +42728,7 @@ class SessionManager {
42529
42728
  };
42530
42729
  }
42531
42730
  diskStderrForDiagnostics(record) {
42532
- const tail = readTailText(join30(record.sessionDir, "stderr.log"), STDERR_READ_BYTES);
42731
+ const tail = readTailText(join31(record.sessionDir, "stderr.log"), STDERR_READ_BYTES);
42533
42732
  const raw = tail?.text ?? "";
42534
42733
  const filtered = record.info.status === "completed";
42535
42734
  const source = filtered ? meaningfulStderr(raw) : raw;
@@ -42705,11 +42904,11 @@ ${STDERR_TRUNCATION_MARKER} ${STDERR_SIDE_LIMIT} bytes per end \u2026
42705
42904
  entry.outputLogStream?.end();
42706
42905
  entry.outputLogStream = null;
42707
42906
  if (entry.stderr) {
42708
- writeFileSync12(join30(entry.sessionDir, "stderr.log"), redactSecrets(entry.stderr), "utf-8");
42907
+ writeFileSync13(join31(entry.sessionDir, "stderr.log"), redactSecrets(entry.stderr), "utf-8");
42709
42908
  }
42710
42909
  this.refreshAccounting(entry);
42711
42910
  entry.info.claudeSessionId = entry.reducer.claudeSessionId ?? entry.info.claudeSessionId;
42712
- writeFileSync12(join30(entry.sessionDir, "meta.json"), JSON.stringify(entry.info, null, 2), "utf-8");
42911
+ writeFileSync13(join31(entry.sessionDir, "meta.json"), JSON.stringify(entry.info, null, 2), "utf-8");
42713
42912
  }
42714
42913
  scheduleEviction(entry) {
42715
42914
  if (entry.evictHandle)
@@ -42769,7 +42968,7 @@ ${STDERR_TRUNCATION_MARKER} ${STDERR_SIDE_LIMIT} bytes per end \u2026
42769
42968
  return { state: "completed", content: "" };
42770
42969
  }
42771
42970
  refreshAccounting(entry) {
42772
- const stats = readTokenStatsAt(join30(entry.sessionDir, "tokens.json"));
42971
+ const stats = readTokenStatsAt(join31(entry.sessionDir, "tokens.json"));
42773
42972
  const fileTokens = (stats?.total_tokens ?? 0) || (stats?.input_tokens ?? 0) + (stats?.output_tokens ?? 0);
42774
42973
  entry.info.tokensUsed = fileTokens || entry.reducer.tokens;
42775
42974
  entry.info.costUsd = stats?.total_cost ?? 0;
@@ -42967,9 +43166,9 @@ var init_cache_ttl = __esm(() => {
42967
43166
  });
42968
43167
 
42969
43168
  // src/model-loader.ts
42970
- import { existsSync as existsSync21, mkdirSync as mkdirSync13, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "fs";
42971
- import { homedir as homedir29 } from "os";
42972
- import { join as join31 } from "path";
43169
+ import { existsSync as existsSync22, mkdirSync as mkdirSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "fs";
43170
+ import { homedir as homedir30 } from "os";
43171
+ import { join as join32 } from "path";
42973
43172
  function groupRecommendedModels(entries) {
42974
43173
  const byId = new Map;
42975
43174
  const categoryOrder = new Map;
@@ -43097,9 +43296,9 @@ async function getRecommendedModels(opts = {}) {
43097
43296
  if (!forceRefresh && _cachedRecommendedModels) {
43098
43297
  return _cachedRecommendedModels;
43099
43298
  }
43100
- if (!forceRefresh && existsSync21(RECOMMENDED_MODELS_CACHE_PATH)) {
43299
+ if (!forceRefresh && existsSync22(RECOMMENDED_MODELS_CACHE_PATH)) {
43101
43300
  try {
43102
- const cacheData = JSON.parse(readFileSync21(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43301
+ const cacheData = JSON.parse(readFileSync22(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43103
43302
  if (cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
43104
43303
  _cachedRecommendedModels = cacheData;
43105
43304
  return cacheData;
@@ -43115,9 +43314,9 @@ async function getRecommendedModels(opts = {}) {
43115
43314
  if (data.models && data.models.length > 0) {
43116
43315
  _cachedRecommendedModels = data;
43117
43316
  try {
43118
- const cacheDir = join31(homedir29(), ".claudish");
43119
- mkdirSync13(cacheDir, { recursive: true });
43120
- writeFileSync13(RECOMMENDED_MODELS_CACHE_PATH, JSON.stringify(data), "utf-8");
43317
+ const cacheDir = join32(homedir30(), ".claudish");
43318
+ mkdirSync14(cacheDir, { recursive: true });
43319
+ writeFileSync14(RECOMMENDED_MODELS_CACHE_PATH, JSON.stringify(data), "utf-8");
43121
43320
  } catch {}
43122
43321
  return data;
43123
43322
  }
@@ -43128,9 +43327,9 @@ async function getRecommendedModels(opts = {}) {
43128
43327
  function getRecommendedModelsSync() {
43129
43328
  if (_cachedRecommendedModels)
43130
43329
  return _cachedRecommendedModels;
43131
- if (existsSync21(RECOMMENDED_MODELS_CACHE_PATH)) {
43330
+ if (existsSync22(RECOMMENDED_MODELS_CACHE_PATH)) {
43132
43331
  try {
43133
- const cacheData = JSON.parse(readFileSync21(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43332
+ const cacheData = JSON.parse(readFileSync22(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43134
43333
  if (cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
43135
43334
  _cachedRecommendedModels = cacheData;
43136
43335
  return cacheData;
@@ -43254,7 +43453,7 @@ var _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels =
43254
43453
  var init_model_loader = __esm(() => {
43255
43454
  init_cache_ttl();
43256
43455
  FIREBASE_RECOMMENDED_URL = `${FIREBASE_BASE_URL}?catalog=recommended`;
43257
- RECOMMENDED_MODELS_CACHE_PATH = join31(homedir29(), ".claudish", "recommended-models-cache.json");
43456
+ RECOMMENDED_MODELS_CACHE_PATH = join32(homedir30(), ".claudish", "recommended-models-cache.json");
43258
43457
  FIREBASE_SLUG_TO_PROVIDER_NAME = {
43259
43458
  openai: "openai",
43260
43459
  google: "google",
@@ -48264,9 +48463,9 @@ var init_poe = __esm(() => {
48264
48463
  });
48265
48464
 
48266
48465
  // src/services/pricing-cache.ts
48267
- import { existsSync as existsSync22, readFileSync as readFileSync22, statSync as statSync7 } from "fs";
48268
- import { homedir as homedir30 } from "os";
48269
- import { join as join32 } from "path";
48466
+ import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync7 } from "fs";
48467
+ import { homedir as homedir31 } from "os";
48468
+ import { join as join33 } from "path";
48270
48469
  function prefixMatch(modelName) {
48271
48470
  for (const [key, pricing] of pricingMap) {
48272
48471
  if (modelName.startsWith(key))
@@ -48304,12 +48503,12 @@ async function warmPricingCache() {
48304
48503
  }
48305
48504
  function loadDiskCache() {
48306
48505
  try {
48307
- if (!existsSync22(CACHE_FILE))
48506
+ if (!existsSync23(CACHE_FILE))
48308
48507
  return false;
48309
48508
  const stat = statSync7(CACHE_FILE);
48310
48509
  const age = Date.now() - stat.mtimeMs;
48311
48510
  const isFresh = age < CACHE_TTL_MS3;
48312
- const raw = readFileSync22(CACHE_FILE, "utf-8");
48511
+ const raw = readFileSync23(CACHE_FILE, "utf-8");
48313
48512
  const data = JSON.parse(raw);
48314
48513
  for (const [key, pricing] of Object.entries(data)) {
48315
48514
  pricingMap.set(key, pricing);
@@ -48325,21 +48524,24 @@ var init_pricing_cache = __esm(() => {
48325
48524
  init_logger();
48326
48525
  init_catalog_query();
48327
48526
  pricingMap = new Map;
48328
- CACHE_DIR = join32(homedir30(), ".claudish");
48329
- CACHE_FILE = join32(CACHE_DIR, "pricing-cache.json");
48527
+ CACHE_DIR = join33(homedir31(), ".claudish");
48528
+ CACHE_FILE = join33(CACHE_DIR, "pricing-cache.json");
48330
48529
  CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
48331
48530
  });
48332
48531
 
48333
48532
  // src/proxy-server.ts
48334
- import { appendFileSync as appendFileSync8, mkdirSync as mkdirSync14 } from "fs";
48335
- import { join as join33 } from "path";
48533
+ import { appendFileSync as appendFileSync8, mkdirSync as mkdirSync15 } from "fs";
48534
+ import { join as join34 } from "path";
48535
+ function isTerminalRoutingFailure(e) {
48536
+ return e instanceof RoutingError || e instanceof CatalogIncompatibleError;
48537
+ }
48336
48538
  function maybeCaptureClassifierRequest(c, body) {
48337
48539
  if (!process.env.CLAUDISH_CLASSIFIER_DEBUG)
48338
48540
  return;
48339
48541
  try {
48340
- const dir = join33(process.cwd(), "logs");
48542
+ const dir = join34(process.cwd(), "logs");
48341
48543
  if (!classifierCaptureDirReady) {
48342
- mkdirSync14(dir, { recursive: true });
48544
+ mkdirSync15(dir, { recursive: true });
48343
48545
  classifierCaptureDirReady = true;
48344
48546
  }
48345
48547
  const record = {
@@ -48362,7 +48564,7 @@ function maybeCaptureClassifierRequest(c, body) {
48362
48564
  "x-api-key": c.req.header("x-api-key") ? "<present>" : null
48363
48565
  }
48364
48566
  };
48365
- appendFileSync8(join33(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
48567
+ appendFileSync8(join34(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
48366
48568
  `);
48367
48569
  } catch {}
48368
48570
  }
@@ -48784,7 +48986,7 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
48784
48986
  const txt = JSON.stringify(body);
48785
48987
  return c.json({ input_tokens: Math.ceil(txt.length / 4) });
48786
48988
  } catch (e) {
48787
- if (e instanceof RoutingError) {
48989
+ if (isTerminalRoutingFailure(e)) {
48788
48990
  return c.json(wrapAnthropicError(400, e.message, "invalid_request_error"), 400);
48789
48991
  }
48790
48992
  return c.json(wrapAnthropicError(500, String(e)), 500);
@@ -48804,7 +49006,7 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
48804
49006
  return await handler.handle(c, body);
48805
49007
  } catch (e) {
48806
49008
  log(`[Proxy] Error: ${e}`);
48807
- if (e instanceof RoutingError) {
49009
+ if (isTerminalRoutingFailure(e)) {
48808
49010
  return c.json(wrapAnthropicError(400, e.message, "invalid_request_error"), 400);
48809
49011
  }
48810
49012
  return c.json(wrapAnthropicError(500, String(e)), 500);
@@ -48867,6 +49069,7 @@ var init_proxy_server = __esm(() => {
48867
49069
  init_profile_config();
48868
49070
  init_auto_route();
48869
49071
  init_catalog_client();
49072
+ init_catalog_compatibility();
48870
49073
  init_endpoint_diagnostics();
48871
49074
  init_endpoint_registration();
48872
49075
  init_model_parser();
@@ -48889,14 +49092,14 @@ var init_proxy_server = __esm(() => {
48889
49092
  });
48890
49093
 
48891
49094
  // src/mcp-server.ts
48892
- import { existsSync as existsSync23, mkdirSync as mkdirSync15, readFileSync as readFileSync23, readdirSync as readdirSync6, writeFileSync as writeFileSync14 } from "fs";
48893
- import { homedir as homedir31 } from "os";
48894
- import { dirname as dirname9, join as join34, resolve as resolve5 } from "path";
49095
+ import { existsSync as existsSync24, mkdirSync as mkdirSync16, readFileSync as readFileSync24, readdirSync as readdirSync6, writeFileSync as writeFileSync15 } from "fs";
49096
+ import { homedir as homedir32 } from "os";
49097
+ import { dirname as dirname10, join as join35, resolve as resolve5 } from "path";
48895
49098
  import { fileURLToPath } from "url";
48896
49099
  async function loadAllModels(forceRefresh = false) {
48897
- if (!forceRefresh && existsSync23(ALL_MODELS_CACHE_PATH2)) {
49100
+ if (!forceRefresh && existsSync24(ALL_MODELS_CACHE_PATH2)) {
48898
49101
  try {
48899
- const cacheData = JSON.parse(readFileSync23(ALL_MODELS_CACHE_PATH2, "utf-8"));
49102
+ const cacheData = JSON.parse(readFileSync24(ALL_MODELS_CACHE_PATH2, "utf-8"));
48900
49103
  const lastUpdated = new Date(cacheData.lastUpdated);
48901
49104
  const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
48902
49105
  if (ageInDays <= CACHE_MAX_AGE_DAYS) {
@@ -48910,12 +49113,12 @@ async function loadAllModels(forceRefresh = false) {
48910
49113
  throw new Error(`API returned ${response.status}`);
48911
49114
  const data = await response.json();
48912
49115
  const models = data.data || [];
48913
- mkdirSync15(CLAUDISH_CACHE_DIR, { recursive: true });
48914
- writeFileSync14(ALL_MODELS_CACHE_PATH2, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
49116
+ mkdirSync16(CLAUDISH_CACHE_DIR, { recursive: true });
49117
+ writeFileSync15(ALL_MODELS_CACHE_PATH2, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
48915
49118
  return models;
48916
49119
  } catch {
48917
- if (existsSync23(ALL_MODELS_CACHE_PATH2)) {
48918
- const cacheData = JSON.parse(readFileSync23(ALL_MODELS_CACHE_PATH2, "utf-8"));
49120
+ if (existsSync24(ALL_MODELS_CACHE_PATH2)) {
49121
+ const cacheData = JSON.parse(readFileSync24(ALL_MODELS_CACHE_PATH2, "utf-8"));
48919
49122
  return cacheData.models || [];
48920
49123
  }
48921
49124
  return [];
@@ -49778,7 +49981,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49778
49981
  let stderrFull = stderr_snippet || "";
49779
49982
  if (error_log_path) {
49780
49983
  try {
49781
- stderrFull = readFileSync23(error_log_path, "utf-8");
49984
+ stderrFull = readFileSync24(error_log_path, "utf-8");
49782
49985
  } catch {}
49783
49986
  }
49784
49987
  const sessionData = {};
@@ -49786,16 +49989,16 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49786
49989
  const sp = session_path;
49787
49990
  for (const file of ["status.json", "manifest.json", "input.md"]) {
49788
49991
  try {
49789
- sessionData[file] = readFileSync23(join34(sp, file), "utf-8");
49992
+ sessionData[file] = readFileSync24(join35(sp, file), "utf-8");
49790
49993
  } catch {}
49791
49994
  }
49792
49995
  try {
49793
- const errorDir = join34(sp, "errors");
49794
- if (existsSync23(errorDir)) {
49996
+ const errorDir = join35(sp, "errors");
49997
+ if (existsSync24(errorDir)) {
49795
49998
  for (const f of readdirSync6(errorDir)) {
49796
49999
  if (f.endsWith(".log")) {
49797
50000
  try {
49798
- sessionData[`errors/${f}`] = readFileSync23(join34(errorDir, f), "utf-8");
50001
+ sessionData[`errors/${f}`] = readFileSync24(join35(errorDir, f), "utf-8");
49799
50002
  } catch {}
49800
50003
  }
49801
50004
  }
@@ -49805,7 +50008,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49805
50008
  for (const f of readdirSync6(sp)) {
49806
50009
  if (f.startsWith("response-") && f.endsWith(".md")) {
49807
50010
  try {
49808
- const content = readFileSync23(join34(sp, f), "utf-8");
50011
+ const content = readFileSync24(join35(sp, f), "utf-8");
49809
50012
  sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
49810
50013
  } catch {}
49811
50014
  }
@@ -49814,9 +50017,9 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49814
50017
  }
49815
50018
  let version = "unknown";
49816
50019
  try {
49817
- const pkgPath = join34(__dirname2, "../package.json");
49818
- if (existsSync23(pkgPath)) {
49819
- version = JSON.parse(readFileSync23(pkgPath, "utf-8")).version;
50020
+ const pkgPath = join35(__dirname2, "../package.json");
50021
+ if (existsSync24(pkgPath)) {
50022
+ version = JSON.parse(readFileSync24(pkgPath, "utf-8")).version;
49820
50023
  }
49821
50024
  } catch {}
49822
50025
  const report = {
@@ -50283,9 +50486,9 @@ var init_mcp_server = __esm(() => {
50283
50486
  import_dotenv2 = __toESM(require_main(), 1);
50284
50487
  import_dotenv2.config({ quiet: true });
50285
50488
  __filename2 = fileURLToPath(import.meta.url);
50286
- __dirname2 = dirname9(__filename2);
50287
- CLAUDISH_CACHE_DIR = join34(homedir31(), ".claudish");
50288
- ALL_MODELS_CACHE_PATH2 = join34(CLAUDISH_CACHE_DIR, "all-models.json");
50489
+ __dirname2 = dirname10(__filename2);
50490
+ CLAUDISH_CACHE_DIR = join35(homedir32(), ".claudish");
50491
+ ALL_MODELS_CACHE_PATH2 = join35(CLAUDISH_CACHE_DIR, "all-models.json");
50289
50492
  NEXT_STEP = {
50290
50493
  nonzero_exit: "read the evidence log, then retry or drop the model",
50291
50494
  cancelled: "you stopped this slot; nothing is wrong with it. Re-run it if you still want its vote",
@@ -50309,7 +50512,7 @@ var init_mcp_server = __esm(() => {
50309
50512
  });
50310
50513
 
50311
50514
  // src/serve-command.ts
50312
- import { existsSync as existsSync24, readFileSync as readFileSync24 } from "fs";
50515
+ import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
50313
50516
  function parseServeArgs(args) {
50314
50517
  const out = {};
50315
50518
  for (let i = 0;i < args.length; i++) {
@@ -50328,12 +50531,12 @@ function parseServeArgs(args) {
50328
50531
  return out;
50329
50532
  }
50330
50533
  function loadModelMap(path) {
50331
- if (!existsSync24(path)) {
50534
+ if (!existsSync25(path)) {
50332
50535
  throw new Error(`--models file not found: ${path}`);
50333
50536
  }
50334
50537
  let raw;
50335
50538
  try {
50336
- raw = readFileSync24(path, "utf-8");
50539
+ raw = readFileSync25(path, "utf-8");
50337
50540
  } catch (e) {
50338
50541
  throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
50339
50542
  }
@@ -50613,7 +50816,7 @@ var init_ansi = __esm(() => {
50613
50816
  });
50614
50817
 
50615
50818
  // src/behavior-command.ts
50616
- import { existsSync as existsSync25, readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "fs";
50819
+ import { existsSync as existsSync26, readFileSync as readFileSync26, writeFileSync as writeFileSync16 } from "fs";
50617
50820
  function severityColor(sev) {
50618
50821
  if (sev === "fix")
50619
50822
  return green(sev);
@@ -50711,8 +50914,8 @@ function setTelemetryEnabled(value) {
50711
50914
  const path = getConfigPath();
50712
50915
  let cfg = {};
50713
50916
  try {
50714
- if (existsSync25(path)) {
50715
- const parsed = JSON.parse(readFileSync25(path, "utf-8"));
50917
+ if (existsSync26(path)) {
50918
+ const parsed = JSON.parse(readFileSync26(path, "utf-8"));
50716
50919
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
50717
50920
  cfg = parsed;
50718
50921
  }
@@ -50721,7 +50924,7 @@ function setTelemetryEnabled(value) {
50721
50924
  const behavior = cfg.behavior && typeof cfg.behavior === "object" && !Array.isArray(cfg.behavior) ? { ...cfg.behavior } : {};
50722
50925
  behavior.telemetry = { enabled: value };
50723
50926
  cfg.behavior = behavior;
50724
- writeFileSync15(path, `${JSON.stringify(cfg, null, 2)}
50927
+ writeFileSync16(path, `${JSON.stringify(cfg, null, 2)}
50725
50928
  `, "utf-8");
50726
50929
  }
50727
50930
  function showTelemetry(action, json) {
@@ -50733,8 +50936,8 @@ function showTelemetry(action, json) {
50733
50936
  let pending = 0;
50734
50937
  try {
50735
50938
  const path = outboxPath();
50736
- if (existsSync25(path)) {
50737
- pending = readFileSync25(path, "utf8").split(`
50939
+ if (existsSync26(path)) {
50940
+ pending = readFileSync26(path, "utf8").split(`
50738
50941
  `).filter(Boolean).length;
50739
50942
  }
50740
50943
  } catch {}
@@ -50815,9 +51018,9 @@ var init_behavior_command = __esm(() => {
50815
51018
  // src/team-grid.ts
50816
51019
  import { spawn as spawn4 } from "child_process";
50817
51020
  import { execSync } from "child_process";
50818
- import { existsSync as existsSync26, readFileSync as readFileSync26, writeFileSync as writeFileSync16 } from "fs";
51021
+ import { existsSync as existsSync27, readFileSync as readFileSync27, writeFileSync as writeFileSync17 } from "fs";
50819
51022
  import { connect as netConnect } from "net";
50820
- import { dirname as dirname10, join as join35 } from "path";
51023
+ import { dirname as dirname11, join as join36 } from "path";
50821
51024
  import { setTimeout as wait } from "timers/promises";
50822
51025
  import { fileURLToPath as fileURLToPath2 } from "url";
50823
51026
  function resolveRouteInfo(modelId) {
@@ -50910,21 +51113,21 @@ function buildPaneHeader(model, prompt, bg) {
50910
51113
  }
50911
51114
  function findMagmuxBinary() {
50912
51115
  const thisFile = fileURLToPath2(import.meta.url);
50913
- const thisDir = dirname10(thisFile);
50914
- const pkgRoot = join35(thisDir, "..");
51116
+ const thisDir = dirname11(thisFile);
51117
+ const pkgRoot = join36(thisDir, "..");
50915
51118
  const platform = process.platform;
50916
51119
  const arch = process.arch;
50917
- const bundledMagmux = join35(pkgRoot, "native", `magmux-${platform}-${arch}`);
50918
- if (existsSync26(bundledMagmux))
51120
+ const bundledMagmux = join36(pkgRoot, "native", `magmux-${platform}-${arch}`);
51121
+ if (existsSync27(bundledMagmux))
50919
51122
  return bundledMagmux;
50920
51123
  try {
50921
51124
  const pkgName = `@claudish/magmux-${platform}-${arch}`;
50922
51125
  let searchDir = pkgRoot;
50923
51126
  for (let i = 0;i < 5; i++) {
50924
- const candidate = join35(searchDir, "node_modules", pkgName, "bin", "magmux");
50925
- if (existsSync26(candidate))
51127
+ const candidate = join36(searchDir, "node_modules", pkgName, "bin", "magmux");
51128
+ if (existsSync27(candidate))
50926
51129
  return candidate;
50927
- const parent = dirname10(searchDir);
51130
+ const parent = dirname11(searchDir);
50928
51131
  if (parent === searchDir)
50929
51132
  break;
50930
51133
  searchDir = parent;
@@ -50946,7 +51149,7 @@ function withoutControlPanes(evt) {
50946
51149
  async function subscribeToMagmux(sockPath, onEvent) {
50947
51150
  let client = null;
50948
51151
  for (let attempt = 0;attempt < 40; attempt++) {
50949
- if (existsSync26(sockPath)) {
51152
+ if (existsSync27(sockPath)) {
50950
51153
  try {
50951
51154
  client = await new Promise((resolve, reject) => {
50952
51155
  const s = netConnect(sockPath);
@@ -51033,9 +51236,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
51033
51236
  const keep = opts?.keep ?? false;
51034
51237
  const manifest = setupSession(sessionPath, models, input);
51035
51238
  const startedAt = new Date().toISOString();
51036
- const gridfilePath = join35(sessionPath, "gridfile.txt");
51037
- const prompt = readFileSync26(join35(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
51038
- const rawPrompt = readFileSync26(join35(sessionPath, "input.md"), "utf-8");
51239
+ const gridfilePath = join36(sessionPath, "gridfile.txt");
51240
+ const prompt = readFileSync27(join36(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
51241
+ const rawPrompt = readFileSync27(join36(sessionPath, "input.md"), "utf-8");
51039
51242
  const usedBannerColors = new Set;
51040
51243
  const gridLines = Object.entries(manifest.models).map(([anonId]) => {
51041
51244
  const model = manifest.models[anonId].model;
@@ -51046,7 +51249,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
51046
51249
  const header = buildPaneHeader(model, rawPrompt, bg);
51047
51250
  return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
51048
51251
  });
51049
- writeFileSync16(gridfilePath, `${gridLines.join(`
51252
+ writeFileSync17(gridfilePath, `${gridLines.join(`
51050
51253
  `)}
51051
51254
  `, "utf-8");
51052
51255
  const magmuxPath = findMagmuxBinary();
@@ -51066,8 +51269,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
51066
51269
  });
51067
51270
  const [{ results }] = await Promise.all([subscription, procExit]);
51068
51271
  const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
51069
- const statusPath = join35(sessionPath, "status.json");
51070
- writeFileSync16(statusPath, JSON.stringify(status, null, 2), "utf-8");
51272
+ const statusPath = join36(sessionPath, "status.json");
51273
+ writeFileSync17(statusPath, JSON.stringify(status, null, 2), "utf-8");
51071
51274
  return status;
51072
51275
  }
51073
51276
  var BANNER_BG_COLORS;
@@ -51087,8 +51290,8 @@ var init_team_grid = __esm(() => {
51087
51290
  });
51088
51291
 
51089
51292
  // src/team-cli.ts
51090
- import { readFileSync as readFileSync27 } from "fs";
51091
- import { join as join36 } from "path";
51293
+ import { readFileSync as readFileSync28 } from "fs";
51294
+ import { join as join37 } from "path";
51092
51295
  function getFlag(args, flag) {
51093
51296
  const idx = args.indexOf(flag);
51094
51297
  if (idx === -1 || idx + 1 >= args.length)
@@ -51211,7 +51414,7 @@ async function teamCommand(args) {
51211
51414
  }
51212
51415
  case "judge": {
51213
51416
  await judgeResponses(sessionPath, { judges });
51214
- console.log(readFileSync27(join36(sessionPath, "verdict.md"), "utf-8"));
51417
+ console.log(readFileSync28(join37(sessionPath, "verdict.md"), "utf-8"));
51215
51418
  break;
51216
51419
  }
51217
51420
  case "run-and-judge": {
@@ -51228,7 +51431,7 @@ async function teamCommand(args) {
51228
51431
  });
51229
51432
  printStatus(status);
51230
51433
  await judgeResponses(sessionPath, { judges });
51231
- console.log(readFileSync27(join36(sessionPath, "verdict.md"), "utf-8"));
51434
+ console.log(readFileSync28(join37(sessionPath, "verdict.md"), "utf-8"));
51232
51435
  break;
51233
51436
  }
51234
51437
  case "status": {
@@ -54052,9 +54255,9 @@ var init_keychain_command = __esm(() => {
54052
54255
 
54053
54256
  // src/auth/antigravity-oauth.ts
54054
54257
  import { spawnSync as spawnSync2 } from "child_process";
54055
- import { existsSync as existsSync27, unlinkSync as unlinkSync6 } from "fs";
54056
- import { homedir as homedir32 } from "os";
54057
- import { join as join37 } from "path";
54258
+ import { existsSync as existsSync28, unlinkSync as unlinkSync6 } from "fs";
54259
+ import { homedir as homedir33 } from "os";
54260
+ import { join as join38 } from "path";
54058
54261
  async function defaultSuggestModel() {
54059
54262
  try {
54060
54263
  const tok = readSharedAntigravityToken();
@@ -54175,8 +54378,8 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
54175
54378
  async logout(deps) {
54176
54379
  deleteSharedAntigravityToken(deps);
54177
54380
  try {
54178
- const tokenFile = join37(homedir32(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
54179
- if (existsSync27(tokenFile))
54381
+ const tokenFile = join38(homedir33(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
54382
+ if (existsSync28(tokenFile))
54180
54383
  unlinkSync6(tokenFile);
54181
54384
  } catch {}
54182
54385
  log("[AntigravityOAuth] Antigravity session cleared (keychain + agy token file)");
@@ -58070,33 +58273,33 @@ var init_branding = __esm(() => {
58070
58273
  });
58071
58274
 
58072
58275
  // src/update-checker.ts
58073
- import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync28, unlinkSync as unlinkSync7, writeFileSync as writeFileSync17 } from "fs";
58074
- import { homedir as homedir33, platform as platform2, tmpdir } from "os";
58075
- import { join as join38 } from "path";
58276
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync29, unlinkSync as unlinkSync7, writeFileSync as writeFileSync18 } from "fs";
58277
+ import { homedir as homedir34, platform as platform2, tmpdir } from "os";
58278
+ import { join as join39 } from "path";
58076
58279
  function getCacheFilePath() {
58077
58280
  let cacheDir;
58078
58281
  if (isWindows) {
58079
- const localAppData = process.env.LOCALAPPDATA || join38(homedir33(), "AppData", "Local");
58080
- cacheDir = join38(localAppData, "claudish");
58282
+ const localAppData = process.env.LOCALAPPDATA || join39(homedir34(), "AppData", "Local");
58283
+ cacheDir = join39(localAppData, "claudish");
58081
58284
  } else {
58082
- cacheDir = join38(homedir33(), ".cache", "claudish");
58285
+ cacheDir = join39(homedir34(), ".cache", "claudish");
58083
58286
  }
58084
58287
  try {
58085
- if (!existsSync28(cacheDir)) {
58086
- mkdirSync16(cacheDir, { recursive: true });
58288
+ if (!existsSync29(cacheDir)) {
58289
+ mkdirSync17(cacheDir, { recursive: true });
58087
58290
  }
58088
- return join38(cacheDir, "update-check.json");
58291
+ return join39(cacheDir, "update-check.json");
58089
58292
  } catch {
58090
- return join38(tmpdir(), "claudish-update-check.json");
58293
+ return join39(tmpdir(), "claudish-update-check.json");
58091
58294
  }
58092
58295
  }
58093
58296
  function readCache() {
58094
58297
  try {
58095
58298
  const cachePath = getCacheFilePath();
58096
- if (!existsSync28(cachePath)) {
58299
+ if (!existsSync29(cachePath)) {
58097
58300
  return null;
58098
58301
  }
58099
- const data = JSON.parse(readFileSync28(cachePath, "utf-8"));
58302
+ const data = JSON.parse(readFileSync29(cachePath, "utf-8"));
58100
58303
  return data;
58101
58304
  } catch {
58102
58305
  return null;
@@ -58109,7 +58312,7 @@ function writeCache(latestVersion) {
58109
58312
  lastCheck: Date.now(),
58110
58313
  latestVersion
58111
58314
  };
58112
- writeFileSync17(cachePath, JSON.stringify(data), "utf-8");
58315
+ writeFileSync18(cachePath, JSON.stringify(data), "utf-8");
58113
58316
  } catch {}
58114
58317
  }
58115
58318
  function isCacheValid(cache) {
@@ -58119,7 +58322,7 @@ function isCacheValid(cache) {
58119
58322
  function clearCache() {
58120
58323
  try {
58121
58324
  const cachePath = getCacheFilePath();
58122
- if (existsSync28(cachePath)) {
58325
+ if (existsSync29(cachePath)) {
58123
58326
  unlinkSync7(cachePath);
58124
58327
  }
58125
58328
  } catch {}
@@ -58204,22 +58407,22 @@ var init_update_checker = __esm(() => {
58204
58407
  // src/cli.ts
58205
58408
  import {
58206
58409
  copyFileSync as copyFileSync2,
58207
- existsSync as existsSync29,
58208
- mkdirSync as mkdirSync17,
58209
- readFileSync as readFileSync29,
58410
+ existsSync as existsSync30,
58411
+ mkdirSync as mkdirSync18,
58412
+ readFileSync as readFileSync30,
58210
58413
  readdirSync as readdirSync7,
58211
58414
  unlinkSync as unlinkSync8,
58212
- writeFileSync as writeFileSync18
58415
+ writeFileSync as writeFileSync19
58213
58416
  } from "fs";
58214
- import { homedir as homedir34 } from "os";
58215
- import { dirname as dirname11, join as join39 } from "path";
58417
+ import { homedir as homedir35 } from "os";
58418
+ import { dirname as dirname12, join as join40 } from "path";
58216
58419
  import { fileURLToPath as fileURLToPath3 } from "url";
58217
58420
  function getVersion3() {
58218
58421
  return VERSION;
58219
58422
  }
58220
58423
  function clearAllModelCaches() {
58221
- const cacheDir = join39(homedir34(), ".claudish");
58222
- if (!existsSync29(cacheDir))
58424
+ const cacheDir = join40(homedir35(), ".claudish");
58425
+ if (!existsSync30(cacheDir))
58223
58426
  return;
58224
58427
  const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
58225
58428
  let cleared = 0;
@@ -58227,7 +58430,7 @@ function clearAllModelCaches() {
58227
58430
  const files = readdirSync7(cacheDir);
58228
58431
  for (const file of files) {
58229
58432
  if (cachePatterns.includes(file)) {
58230
- unlinkSync8(join39(cacheDir, file));
58433
+ unlinkSync8(join40(cacheDir, file));
58231
58434
  cleared++;
58232
58435
  }
58233
58436
  }
@@ -58701,15 +58904,15 @@ Usage: claudish --models --provider <slug>`);
58701
58904
  });
58702
58905
  config.resolvedDefaultProvider = resolved;
58703
58906
  if (resolved.legacyAutoPromoted && !config.quiet) {
58704
- const markerFile = join39(homedir34(), ".claudish", ".legacy-litellm-hint-shown");
58705
- if (!existsSync29(markerFile)) {
58907
+ const markerFile = join40(homedir35(), ".claudish", ".legacy-litellm-hint-shown");
58908
+ if (!existsSync30(markerFile)) {
58706
58909
  const hint = buildLegacyHint(resolved);
58707
58910
  if (hint) {
58708
58911
  console.error(hint);
58709
58912
  }
58710
58913
  try {
58711
- mkdirSync17(dirname11(markerFile), { recursive: true });
58712
- writeFileSync18(markerFile, new Date().toISOString(), "utf-8");
58914
+ mkdirSync18(dirname12(markerFile), { recursive: true });
58915
+ writeFileSync19(markerFile, new Date().toISOString(), "utf-8");
58713
58916
  } catch {}
58714
58917
  }
58715
58918
  }
@@ -59885,8 +60088,8 @@ ${h("MORE INFO")}
59885
60088
  }
59886
60089
  function printAIAgentGuide() {
59887
60090
  try {
59888
- const guidePath = join39(__dirname3, "../AI_AGENT_GUIDE.md");
59889
- const guideContent = readFileSync29(guidePath, "utf-8");
60091
+ const guidePath = join40(__dirname3, "../AI_AGENT_GUIDE.md");
60092
+ const guideContent = readFileSync30(guidePath, "utf-8");
59890
60093
  console.log(guideContent);
59891
60094
  } catch (error) {
59892
60095
  console.error("Error reading AI Agent Guide:");
@@ -59902,19 +60105,19 @@ async function initializeClaudishSkill() {
59902
60105
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
59903
60106
  `);
59904
60107
  const cwd = process.cwd();
59905
- const claudeDir = join39(cwd, ".claude");
59906
- const skillsDir = join39(claudeDir, "skills");
59907
- const claudishSkillDir = join39(skillsDir, "claudish-usage");
59908
- const skillFile = join39(claudishSkillDir, "SKILL.md");
59909
- if (existsSync29(skillFile)) {
60108
+ const claudeDir = join40(cwd, ".claude");
60109
+ const skillsDir = join40(claudeDir, "skills");
60110
+ const claudishSkillDir = join40(skillsDir, "claudish-usage");
60111
+ const skillFile = join40(claudishSkillDir, "SKILL.md");
60112
+ if (existsSync30(skillFile)) {
59910
60113
  console.log("\u2705 Claudish skill already installed at:");
59911
60114
  console.log(` ${skillFile}
59912
60115
  `);
59913
60116
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
59914
60117
  return;
59915
60118
  }
59916
- const sourceSkillPath = join39(__dirname3, "../skills/claudish-usage/SKILL.md");
59917
- if (!existsSync29(sourceSkillPath)) {
60119
+ const sourceSkillPath = join40(__dirname3, "../skills/claudish-usage/SKILL.md");
60120
+ if (!existsSync30(sourceSkillPath)) {
59918
60121
  console.error("\u274C Error: Claudish skill file not found in installation.");
59919
60122
  console.error(` Expected at: ${sourceSkillPath}`);
59920
60123
  console.error(`
@@ -59923,16 +60126,16 @@ async function initializeClaudishSkill() {
59923
60126
  process.exit(1);
59924
60127
  }
59925
60128
  try {
59926
- if (!existsSync29(claudeDir)) {
59927
- mkdirSync17(claudeDir, { recursive: true });
60129
+ if (!existsSync30(claudeDir)) {
60130
+ mkdirSync18(claudeDir, { recursive: true });
59928
60131
  console.log("\uD83D\uDCC1 Created .claude/ directory");
59929
60132
  }
59930
- if (!existsSync29(skillsDir)) {
59931
- mkdirSync17(skillsDir, { recursive: true });
60133
+ if (!existsSync30(skillsDir)) {
60134
+ mkdirSync18(skillsDir, { recursive: true });
59932
60135
  console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
59933
60136
  }
59934
- if (!existsSync29(claudishSkillDir)) {
59935
- mkdirSync17(claudishSkillDir, { recursive: true });
60137
+ if (!existsSync30(claudishSkillDir)) {
60138
+ mkdirSync18(claudishSkillDir, { recursive: true });
59936
60139
  console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
59937
60140
  }
59938
60141
  copyFileSync2(sourceSkillPath, skillFile);
@@ -60010,7 +60213,7 @@ var init_cli = __esm(() => {
60010
60213
  init_ansi();
60011
60214
  init_provider_resolver();
60012
60215
  __filename3 = fileURLToPath3(import.meta.url);
60013
- __dirname3 = dirname11(__filename3);
60216
+ __dirname3 = dirname12(__filename3);
60014
60217
  });
60015
60218
 
60016
60219
  // src/update-command.ts
@@ -60829,15 +61032,29 @@ var init_local_liveness = __esm(() => {
60829
61032
  });
60830
61033
 
60831
61034
  // src/providers/probe-catalog.ts
60832
- import { existsSync as existsSync30, mkdirSync as mkdirSync18, readFileSync as readFileSync30, writeFileSync as writeFileSync19 } from "fs";
60833
- import { homedir as homedir35 } from "os";
60834
- import { dirname as dirname12, join as join40 } from "path";
61035
+ import { existsSync as existsSync31, mkdirSync as mkdirSync19, readFileSync as readFileSync31, writeFileSync as writeFileSync20 } from "fs";
61036
+ import { homedir as homedir36 } from "os";
61037
+ import { dirname as dirname13, join as join41 } from "path";
61038
+ function describeProbeCatalogFailure(outcome) {
61039
+ switch (outcome.kind) {
61040
+ case "incompatible":
61041
+ return outcome.serverContractVersion === null ? "model catalog uses a newer contract than this build reads" : `model catalog uses contract v${outcome.serverContractVersion}, newer than this build reads`;
61042
+ case "http":
61043
+ return `model catalog returned HTTP ${outcome.status}`;
61044
+ case "timeout":
61045
+ return "could not reach model catalog (timeout)";
61046
+ case "network":
61047
+ return `could not reach model catalog (${outcome.reason})`;
61048
+ case "invalid":
61049
+ return `model catalog response unreadable (${outcome.reason})`;
61050
+ }
61051
+ }
60835
61052
  function readProbeModelsCache(path = PROBE_MODELS_CACHE_PATH) {
60836
- if (!existsSync30(path))
61053
+ if (!existsSync31(path))
60837
61054
  return null;
60838
61055
  let raw;
60839
61056
  try {
60840
- raw = JSON.parse(readFileSync30(path, "utf-8"));
61057
+ raw = JSON.parse(readFileSync31(path, "utf-8"));
60841
61058
  } catch {
60842
61059
  return null;
60843
61060
  }
@@ -60846,8 +61063,8 @@ function readProbeModelsCache(path = PROBE_MODELS_CACHE_PATH) {
60846
61063
  return raw;
60847
61064
  }
60848
61065
  function writeProbeModelsCache(data, path = PROBE_MODELS_CACHE_PATH) {
60849
- mkdirSync18(dirname12(path), { recursive: true });
60850
- writeFileSync19(path, JSON.stringify(data), "utf-8");
61066
+ mkdirSync19(dirname13(path), { recursive: true });
61067
+ writeFileSync20(path, JSON.stringify(data), "utf-8");
60851
61068
  }
60852
61069
  function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
60853
61070
  if (!data?.generatedAt)
@@ -60871,8 +61088,17 @@ async function fetchProbeModels(url = PROBE_MODELS_URL, timeoutMs = FETCH_TIMEOU
60871
61088
  reason: e instanceof Error ? e.message : String(e)
60872
61089
  };
60873
61090
  }
60874
- if (!response.ok)
61091
+ if (!response.ok) {
61092
+ let errorBody = null;
61093
+ try {
61094
+ errorBody = await response.json();
61095
+ } catch {}
61096
+ const envelope = parseContractEnvelope(errorBody);
61097
+ if (response.status === 426 || isIncompatibleContractVersion(envelope.contractVersion)) {
61098
+ return { kind: "incompatible", serverContractVersion: envelope.contractVersion };
61099
+ }
60875
61100
  return { kind: "http", status: response.status };
61101
+ }
60876
61102
  let body;
60877
61103
  try {
60878
61104
  body = await response.json();
@@ -60882,6 +61108,10 @@ async function fetchProbeModels(url = PROBE_MODELS_URL, timeoutMs = FETCH_TIMEOU
60882
61108
  reason: e instanceof Error ? e.message : "json parse error"
60883
61109
  };
60884
61110
  }
61111
+ const bodyEnvelope = parseContractEnvelope(body);
61112
+ if (isIncompatibleContractVersion(bodyEnvelope.contractVersion)) {
61113
+ return { kind: "incompatible", serverContractVersion: bodyEnvelope.contractVersion };
61114
+ }
60885
61115
  if (!isValidResponse(body)) {
60886
61116
  return { kind: "invalid", reason: "missing providers map" };
60887
61117
  }
@@ -60965,8 +61195,9 @@ function isValidResponse(raw) {
60965
61195
  }
60966
61196
  var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels", CACHE_TTL_MS4, FETCH_TIMEOUT_MS3 = 15000, PROBE_MODELS_CACHE_PATH, _inFlight = null;
60967
61197
  var init_probe_catalog = __esm(() => {
61198
+ init_catalog_compatibility();
60968
61199
  CACHE_TTL_MS4 = 60 * 60 * 1000;
60969
- PROBE_MODELS_CACHE_PATH = join40(homedir35(), ".claudish", "probe-models.json");
61200
+ PROBE_MODELS_CACHE_PATH = join41(homedir36(), ".claudish", "probe-models.json");
60970
61201
  });
60971
61202
 
60972
61203
  // src/tui/constants.ts
@@ -65434,6 +65665,13 @@ var probeProxy = null, probeProxyStarting = null;
65434
65665
 
65435
65666
  // src/tui/hooks/useRouteProbe.ts
65436
65667
  import { useCallback as useCallback2, useState as useState4 } from "react";
65668
+ async function routeForProbe(model) {
65669
+ try {
65670
+ return await route(model);
65671
+ } catch (err) {
65672
+ return { kind: "no-route", reason: err instanceof Error ? err.message : String(err) };
65673
+ }
65674
+ }
65437
65675
  function useRouteProbe(config) {
65438
65676
  const [probeMode, setProbeMode] = useState4("idle");
65439
65677
  const [probeModel, setProbeModel] = useState4("");
@@ -65472,7 +65710,7 @@ function useRouteProbe(config) {
65472
65710
  if (native) {
65473
65711
  chain = [native];
65474
65712
  } else {
65475
- const plan = await route(model);
65713
+ const plan = await routeForProbe(model);
65476
65714
  if (plan.kind !== "ok") {
65477
65715
  setProbeResults([
65478
65716
  {
@@ -66188,17 +66426,8 @@ function App({ requestLogin } = {}) {
66188
66426
  return;
66189
66427
  }
66190
66428
  }
66191
- const outcome = await ensureProbeModelsCached();
66192
- if (outcome.kind !== "ok") {
66193
- setTestResults((prev) => ({
66194
- ...prev,
66195
- [provName]: {
66196
- status: "failed",
66197
- error: `could not reach model catalog (${outcome.kind})`
66198
- }
66199
- }));
66200
- return;
66201
- }
66429
+ const catalogOutcome = await ensureProbeModelsCached();
66430
+ const catalogProblem = catalogOutcome.kind === "ok" ? undefined : describeProbeCatalogFailure(catalogOutcome);
66202
66431
  const startMs = Date.now();
66203
66432
  try {
66204
66433
  const proxyUrl = await ensureProbeProxy();
@@ -66250,7 +66479,10 @@ function App({ requestLogin } = {}) {
66250
66479
  ...prev,
66251
66480
  [provName]: {
66252
66481
  status: prov.isLocal ? "unavailable" : "failed",
66253
- error: lastDiscoveryReason ? `no probe model: ${lastDiscoveryReason}` : "no probe model available",
66482
+ error: [
66483
+ lastDiscoveryReason ? `no probe model: ${lastDiscoveryReason}` : "no probe model available",
66484
+ catalogProblem
66485
+ ].filter((part) => Boolean(part)).map((part) => part.replace(/\.$/, "")).join(" \xB7 "),
66254
66486
  ms
66255
66487
  }
66256
66488
  }));
@@ -67584,17 +67816,17 @@ var init_terminal_isolation = __esm(() => {
67584
67816
  import { spawn as spawn5, spawnSync as spawnSync4 } from "child_process";
67585
67817
  import {
67586
67818
  closeSync as closeSync8,
67587
- existsSync as existsSync31,
67588
- mkdirSync as mkdirSync19,
67819
+ existsSync as existsSync32,
67820
+ mkdirSync as mkdirSync20,
67589
67821
  openSync as openSync8,
67590
- readFileSync as readFileSync31,
67822
+ readFileSync as readFileSync32,
67591
67823
  readdirSync as readdirSync8,
67592
67824
  statSync as statSync8,
67593
67825
  unlinkSync as unlinkSync9,
67594
- writeFileSync as writeFileSync20
67826
+ writeFileSync as writeFileSync21
67595
67827
  } from "fs";
67596
- import { homedir as homedir36, tmpdir as tmpdir2 } from "os";
67597
- import { dirname as dirname13, join as join41 } from "path";
67828
+ import { homedir as homedir37, tmpdir as tmpdir2 } from "os";
67829
+ import { dirname as dirname14, join as join42 } from "path";
67598
67830
  import { isatty } from "tty";
67599
67831
  function releaseTerminalIsolation() {
67600
67832
  if (!restoreTerminal)
@@ -67654,12 +67886,12 @@ function isRealAnthropicEnvCredential(env, name) {
67654
67886
  }
67655
67887
  function hasResolvableAnthropicAuth(deps = {}) {
67656
67888
  const env = deps.env ?? process.env;
67657
- const fileExists = deps.fileExists ?? existsSync31;
67889
+ const fileExists = deps.fileExists ?? existsSync32;
67658
67890
  const keychainProbe = deps.keychainProbe ?? defaultKeychainAnthropicProbe;
67659
67891
  if (isRealAnthropicEnvCredential(env, "ANTHROPIC_API_KEY") || isRealAnthropicEnvCredential(env, "ANTHROPIC_AUTH_TOKEN")) {
67660
67892
  return true;
67661
67893
  }
67662
- if (fileExists(join41(homedir36(), ".claude", ".credentials.json")))
67894
+ if (fileExists(join42(homedir37(), ".claude", ".credentials.json")))
67663
67895
  return true;
67664
67896
  return keychainProbe();
67665
67897
  }
@@ -67674,14 +67906,14 @@ function isProxyAuthMode(config) {
67674
67906
  }
67675
67907
  function managedSettingsPath() {
67676
67908
  if (isWindows2()) {
67677
- return join41(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
67909
+ return join42(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
67678
67910
  }
67679
67911
  if (process.platform === "darwin") {
67680
67912
  return "/Library/Application Support/ClaudeCode/managed-settings.json";
67681
67913
  }
67682
67914
  return "/etc/claude-code/managed-settings.json";
67683
67915
  }
67684
- function managedSettingsForcesClaudeAi(readFile = readFileSync31) {
67916
+ function managedSettingsForcesClaudeAi(readFile = readFileSync32) {
67685
67917
  try {
67686
67918
  const raw = readFile(managedSettingsPath(), "utf-8");
67687
67919
  const parsed = JSON.parse(raw);
@@ -67695,9 +67927,9 @@ function isWindows2() {
67695
67927
  }
67696
67928
  function createStatusLineScript(tokenFilePath) {
67697
67929
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
67698
- const claudishDir = join41(homeDir, ".claudish");
67930
+ const claudishDir = join42(homeDir, ".claudish");
67699
67931
  const timestamp = Date.now();
67700
- const scriptPath = join41(claudishDir, `status-${timestamp}.js`);
67932
+ const scriptPath = join42(claudishDir, `status-${timestamp}.js`);
67701
67933
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
67702
67934
  const light = getThemeMode() === "light";
67703
67935
  const cyanCode = light ? "38;2;14;116;144" : "96";
@@ -67830,13 +68062,13 @@ process.stdin.on('end', () => {
67830
68062
  }
67831
68063
  });
67832
68064
  `;
67833
- writeFileSync20(scriptPath, script, "utf-8");
68065
+ writeFileSync21(scriptPath, script, "utf-8");
67834
68066
  return scriptPath;
67835
68067
  }
67836
68068
  function initializeTokenFile(tokenFilePath) {
67837
68069
  try {
67838
- mkdirSync19(dirname13(tokenFilePath), { recursive: true });
67839
- writeFileSync20(tokenFilePath, JSON.stringify({
68070
+ mkdirSync20(dirname14(tokenFilePath), { recursive: true });
68071
+ writeFileSync21(tokenFilePath, JSON.stringify({
67840
68072
  input_tokens: 0,
67841
68073
  output_tokens: 0,
67842
68074
  total_tokens: 0,
@@ -67867,7 +68099,7 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
67867
68099
  if (!name.startsWith("tokens-") || !name.endsWith(".json"))
67868
68100
  continue;
67869
68101
  scanned++;
67870
- const full = join41(dir, name);
68102
+ const full = join42(dir, name);
67871
68103
  try {
67872
68104
  if (statSync8(full).mtimeMs >= cutoff)
67873
68105
  continue;
@@ -67884,7 +68116,7 @@ function parseSettingsArg(value) {
67884
68116
  if (value.trimStart().startsWith("{")) {
67885
68117
  return JSON.parse(value);
67886
68118
  }
67887
- return JSON.parse(readFileSync31(value, "utf-8"));
68119
+ return JSON.parse(readFileSync32(value, "utf-8"));
67888
68120
  }
67889
68121
  function parseSettingsArgSafe(value) {
67890
68122
  try {
@@ -67896,13 +68128,13 @@ function parseSettingsArgSafe(value) {
67896
68128
  }
67897
68129
  function userSettingsFileCandidates(cwd) {
67898
68130
  return [
67899
- join41(homedir36(), ".claude", "settings.json"),
67900
- join41(cwd, ".claude", "settings.json"),
67901
- join41(cwd, ".claude", "settings.local.json")
68131
+ join42(homedir37(), ".claude", "settings.json"),
68132
+ join42(cwd, ".claude", "settings.json"),
68133
+ join42(cwd, ".claude", "settings.local.json")
67902
68134
  ];
67903
68135
  }
67904
68136
  function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
67905
- const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync31(file));
68137
+ const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync32(file));
67906
68138
  const idx = claudeArgs.indexOf("--settings");
67907
68139
  const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
67908
68140
  if (settingsArg)
@@ -67939,13 +68171,13 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
67939
68171
  }
67940
68172
  function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
67941
68173
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
67942
- const claudishDir = join41(homeDir, ".claudish");
68174
+ const claudishDir = join42(homeDir, ".claudish");
67943
68175
  try {
67944
- mkdirSync19(claudishDir, { recursive: true });
68176
+ mkdirSync20(claudishDir, { recursive: true });
67945
68177
  } catch {}
67946
68178
  const timestamp = Date.now();
67947
- const tempPath = join41(claudishDir, `settings-${timestamp}.json`);
67948
- const tokenFilePath = join41(claudishDir, `tokens-${port}.json`);
68179
+ const tempPath = join42(claudishDir, `settings-${timestamp}.json`);
68180
+ const tokenFilePath = join42(claudishDir, `tokens-${port}.json`);
67949
68181
  cleanupStaleTokenFiles(claudishDir);
67950
68182
  initializeTokenFile(tokenFilePath);
67951
68183
  let statusCommand;
@@ -67979,7 +68211,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
67979
68211
  padding: 0
67980
68212
  };
67981
68213
  const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
67982
- writeFileSync20(tempPath, JSON.stringify(settings, null, 2), "utf-8");
68214
+ writeFileSync21(tempPath, JSON.stringify(settings, null, 2), "utf-8");
67983
68215
  return { path: tempPath, statusLine, tokenFilePath };
67984
68216
  }
67985
68217
  function buildClaudishSettingsOverlay(statusLine, proxyAuthMode) {
@@ -68004,7 +68236,7 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
68004
68236
  if (proxyAuthMode && !("forceLoginMethod" in userSettings)) {
68005
68237
  userSettings.forceLoginMethod = "console";
68006
68238
  }
68007
- writeFileSync20(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
68239
+ writeFileSync21(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
68008
68240
  } catch {
68009
68241
  if (!config.quiet) {
68010
68242
  console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
@@ -68075,13 +68307,13 @@ function resolveAdvisorToolEnv(config, processEnv = process.env) {
68075
68307
  return { vars: { [ADVISOR_TOOL_ENV_VAR]: "1" }, source: "claudish" };
68076
68308
  }
68077
68309
  function discoverUserAdvisorModel(claudeArgs = [], cwd = process.cwd()) {
68078
- const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync31(file));
68310
+ const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync32(file));
68079
68311
  const idx = claudeArgs.indexOf("--settings");
68080
68312
  const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
68081
68313
  if (settingsArg)
68082
68314
  sources.push(settingsArg);
68083
68315
  const managed = managedSettingsPath();
68084
- if (existsSync31(managed))
68316
+ if (existsSync32(managed))
68085
68317
  sources.push(managed);
68086
68318
  let effective;
68087
68319
  for (const source of sources) {
@@ -68295,8 +68527,8 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
68295
68527
  console.error("Install it from: https://claude.com/claude-code");
68296
68528
  console.error(`
68297
68529
  Or set CLAUDE_PATH to your custom installation:`);
68298
- const home = homedir36();
68299
- const localPath = isWindows2() ? join41(home, ".claude", "local", "claude.exe") : join41(home, ".claude", "local", "claude");
68530
+ const home = homedir37();
68531
+ const localPath = isWindows2() ? join42(home, ".claude", "local", "claude.exe") : join42(home, ".claude", "local", "claude");
68300
68532
  console.error(` export CLAUDE_PATH=${localPath}`);
68301
68533
  process.exit(1);
68302
68534
  }
@@ -68384,23 +68616,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
68384
68616
  async function findClaudeBinary() {
68385
68617
  const isWindows = process.platform === "win32";
68386
68618
  if (process.env.CLAUDE_PATH) {
68387
- if (existsSync31(process.env.CLAUDE_PATH)) {
68619
+ if (existsSync32(process.env.CLAUDE_PATH)) {
68388
68620
  return process.env.CLAUDE_PATH;
68389
68621
  }
68390
68622
  }
68391
- const home = homedir36();
68392
- const localPath = isWindows ? join41(home, ".claude", "local", "claude.exe") : join41(home, ".claude", "local", "claude");
68393
- if (existsSync31(localPath)) {
68623
+ const home = homedir37();
68624
+ const localPath = isWindows ? join42(home, ".claude", "local", "claude.exe") : join42(home, ".claude", "local", "claude");
68625
+ if (existsSync32(localPath)) {
68394
68626
  return localPath;
68395
68627
  }
68396
68628
  if (isWindows) {
68397
68629
  const windowsPaths = [
68398
- join41(home, "AppData", "Roaming", "npm", "claude.cmd"),
68399
- join41(home, ".npm-global", "claude.cmd"),
68400
- join41(home, "node_modules", ".bin", "claude.cmd")
68630
+ join42(home, "AppData", "Roaming", "npm", "claude.cmd"),
68631
+ join42(home, ".npm-global", "claude.cmd"),
68632
+ join42(home, "node_modules", ".bin", "claude.cmd")
68401
68633
  ];
68402
68634
  for (const path of windowsPaths) {
68403
- if (existsSync31(path)) {
68635
+ if (existsSync32(path)) {
68404
68636
  return path;
68405
68637
  }
68406
68638
  }
@@ -68408,14 +68640,14 @@ async function findClaudeBinary() {
68408
68640
  const commonPaths = [
68409
68641
  "/usr/local/bin/claude",
68410
68642
  "/opt/homebrew/bin/claude",
68411
- join41(home, ".npm-global/bin/claude"),
68412
- join41(home, ".local/bin/claude"),
68413
- join41(home, "node_modules/.bin/claude"),
68643
+ join42(home, ".npm-global/bin/claude"),
68644
+ join42(home, ".local/bin/claude"),
68645
+ join42(home, "node_modules/.bin/claude"),
68414
68646
  "/data/data/com.termux/files/usr/bin/claude",
68415
- join41(home, "../usr/bin/claude")
68647
+ join42(home, "../usr/bin/claude")
68416
68648
  ];
68417
68649
  for (const path of commonPaths) {
68418
- if (existsSync31(path)) {
68650
+ if (existsSync32(path)) {
68419
68651
  return path;
68420
68652
  }
68421
68653
  }
@@ -68490,18 +68722,18 @@ var init_claude_runner = __esm(() => {
68490
68722
  });
68491
68723
 
68492
68724
  // src/diag-output.ts
68493
- import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync20, unlinkSync as unlinkSync10, writeFileSync as writeFileSync21 } from "fs";
68494
- import { homedir as homedir37 } from "os";
68495
- import { join as join42 } from "path";
68725
+ import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync21, unlinkSync as unlinkSync10, writeFileSync as writeFileSync22 } from "fs";
68726
+ import { homedir as homedir38 } from "os";
68727
+ import { join as join43 } from "path";
68496
68728
  function getClaudishDir() {
68497
- const dir = join42(homedir37(), ".claudish");
68729
+ const dir = join43(homedir38(), ".claudish");
68498
68730
  try {
68499
- mkdirSync20(dir, { recursive: true });
68731
+ mkdirSync21(dir, { recursive: true });
68500
68732
  } catch {}
68501
68733
  return dir;
68502
68734
  }
68503
68735
  function getDiagLogPath() {
68504
- return join42(getClaudishDir(), `diag-${process.pid}.log`);
68736
+ return join43(getClaudishDir(), `diag-${process.pid}.log`);
68505
68737
  }
68506
68738
 
68507
68739
  class LogFileDiagOutput {
@@ -68510,7 +68742,7 @@ class LogFileDiagOutput {
68510
68742
  constructor() {
68511
68743
  this.logPath = getDiagLogPath();
68512
68744
  try {
68513
- writeFileSync21(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
68745
+ writeFileSync22(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
68514
68746
  `);
68515
68747
  } catch {}
68516
68748
  this.stream = createWriteStream3(this.logPath, { flags: "a" });
@@ -68712,13 +68944,33 @@ async function warmCatalogIfNeeded(config, opts) {
68712
68944
  }
68713
68945
  return "ok";
68714
68946
  }
68947
+ return reportUnusableCatalog(outcome, state, cache, now, config.quiet === true);
68948
+ }
68949
+ function reportUnusableCatalog(outcome, state, cache, now, quiet) {
68950
+ if (outcome.kind === "incompatible") {
68951
+ return reportIncompatibleCatalog(readCatalogIncompatibility() ?? {
68952
+ detectedAt: new Date().toISOString(),
68953
+ serverContractVersion: outcome.serverContractVersion
68954
+ });
68955
+ }
68715
68956
  if (outcome.reason === "disabled") {
68716
- if (!config.quiet) {
68957
+ if (!quiet) {
68717
68958
  process.stderr.write(` Catalog refresh disabled (CLAUDISH_DISABLE_CATALOG_WARM=1).
68718
68959
  `);
68719
68960
  }
68720
68961
  return "skipped";
68721
68962
  }
68963
+ const recorded = readCatalogIncompatibility();
68964
+ if (recorded !== null)
68965
+ return reportIncompatibleCatalog(recorded);
68966
+ return reportFetchFailure(state, cache, now);
68967
+ }
68968
+ function reportIncompatibleCatalog(recorded) {
68969
+ process.stderr.write(`${catalogIncompatibilityMessage(recorded)}
68970
+ `);
68971
+ return "warned";
68972
+ }
68973
+ function reportFetchFailure(state, cache, now) {
68722
68974
  if (state === "stale") {
68723
68975
  const ageMs = now.getTime() - Date.parse(cache.lastUpdated);
68724
68976
  const ageStr = humanizeAge(ageMs);
@@ -68740,6 +68992,7 @@ var HARD_FAIL_MESSAGE, LOCAL_MODEL_PREFIXES;
68740
68992
  var init_catalog_warm = __esm(() => {
68741
68993
  init_all_models_cache();
68742
68994
  init_catalog_client();
68995
+ init_catalog_compatibility();
68743
68996
  HARD_FAIL_MESSAGE = `Error: cannot reach model catalog and no cached copy found.
68744
68997
  ` + `
68745
68998
  ` + `To proceed:
@@ -71106,16 +71359,16 @@ var exports_session_stats = {};
71106
71359
  __export(exports_session_stats, {
71107
71360
  readSessionStats: () => readSessionStats
71108
71361
  });
71109
- import { readFileSync as readFileSync32 } from "fs";
71110
- import { homedir as homedir38 } from "os";
71111
- import { join as join43 } from "path";
71362
+ import { readFileSync as readFileSync33 } from "fs";
71363
+ import { homedir as homedir39 } from "os";
71364
+ import { join as join44 } from "path";
71112
71365
  function tokenFilePath(port) {
71113
- return process.env.CLAUDISH_TOKEN_FILE || join43(homedir38(), ".claudish", `tokens-${port}.json`);
71366
+ return process.env.CLAUDISH_TOKEN_FILE || join44(homedir39(), ".claudish", `tokens-${port}.json`);
71114
71367
  }
71115
71368
  function readSessionStats(port, opts) {
71116
71369
  let raw;
71117
71370
  try {
71118
- raw = JSON.parse(readFileSync32(tokenFilePath(port), "utf-8"));
71371
+ raw = JSON.parse(readFileSync33(tokenFilePath(port), "utf-8"));
71119
71372
  } catch {
71120
71373
  return null;
71121
71374
  }
@@ -71472,8 +71725,8 @@ var init_session_summary = __esm(() => {
71472
71725
  init_op_source();
71473
71726
  init_startup_trace();
71474
71727
  var import_dotenv3 = __toESM(require_main(), 1);
71475
- import { existsSync as existsSync32, readFileSync as readFileSync33 } from "fs";
71476
- import { join as join44, resolve as resolve6 } from "path";
71728
+ import { existsSync as existsSync33, readFileSync as readFileSync34 } from "fs";
71729
+ import { join as join45, resolve as resolve6 } from "path";
71477
71730
  import_dotenv3.config({ quiet: true });
71478
71731
  function classifyStartupKind() {
71479
71732
  const argv = process.argv.slice(2);
@@ -71573,7 +71826,7 @@ async function applyConfigOverride() {
71573
71826
  await Promise.resolve();
71574
71827
  const plan = planConfigOverride(process.argv.slice(2), process.env, {
71575
71828
  resolve: resolve6,
71576
- exists: existsSync32
71829
+ exists: existsSync33
71577
71830
  });
71578
71831
  if (plan.kind === "none")
71579
71832
  return;
@@ -71742,14 +71995,14 @@ async function runCli() {
71742
71995
  if (cliConfig.team && cliConfig.team.length > 0) {
71743
71996
  let prompt = cliConfig.claudeArgs.join(" ");
71744
71997
  if (cliConfig.inputFile) {
71745
- prompt = readFileSync33(cliConfig.inputFile, "utf-8");
71998
+ prompt = readFileSync34(cliConfig.inputFile, "utf-8");
71746
71999
  }
71747
72000
  if (!prompt.trim()) {
71748
72001
  console.error("Error: --team requires a prompt (positional args or -f <file>)");
71749
72002
  process.exit(1);
71750
72003
  }
71751
72004
  const mode = cliConfig.teamMode ?? "default";
71752
- const sessionPath = join44(process.cwd(), `.claudish-team-${Date.now()}`);
72005
+ const sessionPath = join45(process.cwd(), `.claudish-team-${Date.now()}`);
71753
72006
  if (mode === "json") {
71754
72007
  await Promise.resolve().then(() => init_team_orchestrator());
71755
72008
  setupSession(sessionPath, cliConfig.team, prompt);
@@ -71758,9 +72011,9 @@ async function runCli() {
71758
72011
  });
71759
72012
  const result = { ...status, responses: {} };
71760
72013
  for (const anonId of Object.keys(status.models)) {
71761
- const responsePath = join44(sessionPath, `response-${anonId}.md`);
72014
+ const responsePath = join45(sessionPath, `response-${anonId}.md`);
71762
72015
  try {
71763
- const raw = readFileSync33(responsePath, "utf-8").trim();
72016
+ const raw = readFileSync34(responsePath, "utf-8").trim();
71764
72017
  try {
71765
72018
  result.responses[anonId] = JSON.parse(raw);
71766
72019
  } catch {