claudish 9.6.1 → 9.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +687 -460
  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.0";
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,122 @@ 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 parseContractEnvelope(body) {
18173
+ if (!body || typeof body !== "object")
18174
+ return { contractVersion: null };
18175
+ const data = body;
18176
+ const contractVersion = typeof data.contractVersion === "number" ? data.contractVersion : null;
18177
+ const err = data.error;
18178
+ const minimum = err && typeof err === "object" ? err.minimumContractVersion : undefined;
18179
+ return {
18180
+ contractVersion,
18181
+ ...typeof minimum === "number" ? { minimumContractVersion: minimum } : {}
18182
+ };
18183
+ }
18184
+ function isIncompatibleContractVersion(version) {
18185
+ return typeof version === "number" && version > SUPPORTED_CONTRACT_VERSION;
18186
+ }
18187
+ function markCatalogIncompatible(info, path = CATALOG_INCOMPATIBLE_PATH) {
18188
+ const record = {
18189
+ detectedAt: new Date().toISOString(),
18190
+ serverContractVersion: info.serverContractVersion,
18191
+ clientContractVersion: SUPPORTED_CONTRACT_VERSION,
18192
+ ...info.minimumContractVersion !== undefined ? { minimumContractVersion: info.minimumContractVersion } : {}
18193
+ };
18194
+ _memFlag = record;
18195
+ _fileMemo = { path, value: record };
18196
+ try {
18197
+ mkdirSync5(dirname4(path), { recursive: true });
18198
+ writeFileSync5(path, JSON.stringify(record), "utf-8");
18199
+ } catch {}
18200
+ }
18201
+ function readCatalogIncompatibility(path = CATALOG_INCOMPATIBLE_PATH) {
18202
+ if (_memFlag)
18203
+ return _memFlag;
18204
+ if (_fileMemo && _fileMemo.path === path)
18205
+ return _fileMemo.value;
18206
+ let value = null;
18207
+ try {
18208
+ if (existsSync5(path))
18209
+ value = parseSentinelFile(readFileSync5(path, "utf-8"));
18210
+ } catch {}
18211
+ if (value !== null && isSentinelStale(value)) {
18212
+ clearCatalogIncompatibility(path);
18213
+ return null;
18214
+ }
18215
+ _fileMemo = { path, value };
18216
+ return value;
18217
+ }
18218
+ function isSentinelStale(record) {
18219
+ if (typeof record.minimumContractVersion === "number" && record.minimumContractVersion > SUPPORTED_CONTRACT_VERSION) {
18220
+ return false;
18221
+ }
18222
+ if (record.serverContractVersion !== null) {
18223
+ return record.serverContractVersion <= SUPPORTED_CONTRACT_VERSION;
18224
+ }
18225
+ if (typeof record.clientContractVersion === "number") {
18226
+ return record.clientContractVersion < SUPPORTED_CONTRACT_VERSION;
18227
+ }
18228
+ return false;
18229
+ }
18230
+ function parseSentinelFile(raw) {
18231
+ const unspecific = {
18232
+ detectedAt: new Date(0).toISOString(),
18233
+ serverContractVersion: null
18234
+ };
18235
+ let parsed;
18236
+ try {
18237
+ parsed = JSON.parse(raw);
18238
+ } catch {
18239
+ return unspecific;
18240
+ }
18241
+ if (!parsed || typeof parsed !== "object")
18242
+ return unspecific;
18243
+ const data = parsed;
18244
+ return {
18245
+ detectedAt: typeof data.detectedAt === "string" ? data.detectedAt : unspecific.detectedAt,
18246
+ serverContractVersion: typeof data.serverContractVersion === "number" ? data.serverContractVersion : null,
18247
+ ...typeof data.minimumContractVersion === "number" ? { minimumContractVersion: data.minimumContractVersion } : {},
18248
+ ...typeof data.clientContractVersion === "number" ? { clientContractVersion: data.clientContractVersion } : {}
18249
+ };
18250
+ }
18251
+ function clearCatalogIncompatibility(path = CATALOG_INCOMPATIBLE_PATH) {
18252
+ _memFlag = null;
18253
+ _fileMemo = { path, value: null };
18254
+ try {
18255
+ rmSync2(path, { force: true });
18256
+ } catch {}
18257
+ }
18258
+ function catalogIncompatibilityMessage(i) {
18259
+ 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";
18260
+ return [
18261
+ `This claudish build cannot read the model catalog. The catalog server publishes ${serverSays}; this build reads version ${SUPPORTED_CONTRACT_VERSION}.`,
18262
+ "",
18263
+ "Routing cannot tell which models your subscriptions cover, so continuing would send this request to a provider that bills per token without saying so.",
18264
+ "",
18265
+ "Run `claudish update` to get a build that reads the current catalog."
18266
+ ].join(`
18267
+ `);
18268
+ }
18269
+ var SUPPORTED_CONTRACT_VERSION = 2, CATALOG_INCOMPATIBLE_PATH, _memFlag = null, _fileMemo = null, CatalogIncompatibleError;
18270
+ var init_catalog_compatibility = __esm(() => {
18271
+ CATALOG_INCOMPATIBLE_PATH = join7(homedir7(), ".claudish", "catalog-incompatible.json");
18272
+ CatalogIncompatibleError = class CatalogIncompatibleError extends Error {
18273
+ constructor(message) {
18274
+ super(message);
18275
+ this.name = "CatalogIncompatibleError";
18276
+ }
18277
+ };
18278
+ });
18279
+
18280
+ // src/providers/all-models-cache.ts
18281
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
18282
+ import { homedir as homedir8 } from "os";
18283
+ import { dirname as dirname5, join as join8 } from "path";
18172
18284
  function reasoningStatusOf(entry) {
18173
18285
  if (entry.reasoningStatus === "known" || entry.reasoningStatus === "unknown") {
18174
18286
  return entry.reasoningStatus;
@@ -18176,11 +18288,16 @@ function reasoningStatusOf(entry) {
18176
18288
  return entry.reasoning !== undefined ? "known" : "unknown";
18177
18289
  }
18178
18290
  function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
18179
- if (!existsSync5(path))
18291
+ if (readCatalogIncompatibility())
18292
+ return null;
18293
+ return readCacheFile(path);
18294
+ }
18295
+ function readCacheFile(path) {
18296
+ if (!existsSync6(path))
18180
18297
  return null;
18181
18298
  let raw;
18182
18299
  try {
18183
- raw = JSON.parse(readFileSync5(path, "utf-8"));
18300
+ raw = JSON.parse(readFileSync6(path, "utf-8"));
18184
18301
  } catch {
18185
18302
  return null;
18186
18303
  }
@@ -18202,7 +18319,7 @@ function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
18202
18319
  };
18203
18320
  }
18204
18321
  function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
18205
- const existing = readAllModelsCache(path);
18322
+ const existing = readCacheFile(path);
18206
18323
  const merged = {
18207
18324
  version: 2,
18208
18325
  lastUpdated: data.lastUpdated ?? new Date().toISOString(),
@@ -18211,12 +18328,13 @@ function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
18211
18328
  ...data.plans !== undefined || existing?.plans !== undefined ? { plans: data.plans ?? existing?.plans ?? [] } : {},
18212
18329
  ...data.catalogRevision !== undefined ? { catalogRevision: data.catalogRevision } : {}
18213
18330
  };
18214
- mkdirSync5(dirname4(path), { recursive: true });
18215
- writeFileSync5(path, JSON.stringify(merged), "utf-8");
18331
+ mkdirSync6(dirname5(path), { recursive: true });
18332
+ writeFileSync6(path, JSON.stringify(merged), "utf-8");
18216
18333
  }
18217
18334
  var ALL_MODELS_CACHE_PATH;
18218
18335
  var init_all_models_cache = __esm(() => {
18219
- ALL_MODELS_CACHE_PATH = join7(homedir7(), ".claudish", "all-models.json");
18336
+ init_catalog_compatibility();
18337
+ ALL_MODELS_CACHE_PATH = join8(homedir8(), ".claudish", "all-models.json");
18220
18338
  });
18221
18339
 
18222
18340
  // src/providers/model-ordering.ts
@@ -18370,19 +18488,25 @@ function resolveSubscriptionRouting(modelId, provider, cachePath) {
18370
18488
  if (providerPlans.length === 0)
18371
18489
  return { kind: "unknown" };
18372
18490
  const providerPlanIds = new Set(providerPlans.map((plan) => plan.id));
18373
- const hasMembership = entry.subscriptionPlans?.some((planId) => providerPlanIds.has(planId));
18374
- if (hasMembership) {
18491
+ const memberships = entry.subscriptionPlans ?? [];
18492
+ const includingPlans = providerPlans.filter((plan) => memberships.includes(plan.id));
18493
+ if (includingPlans.length > 0) {
18494
+ if (includingPlans.length < providerPlans.length)
18495
+ return { kind: "unknown" };
18375
18496
  const agg = entry.aggregators?.find((a) => a.provider === provider);
18376
18497
  return agg?.externalId ? { kind: "serves", externalId: agg.externalId } : { kind: "unknown" };
18377
18498
  }
18378
- const hasPublishedProviderRoster = cache.entries.some((candidate) => candidate.subscriptionPlans?.some((planId) => providerPlanIds.has(planId)));
18379
- if (!hasPublishedProviderRoster)
18499
+ const hasAnyMembershipRow = cache.entries.some((candidate) => candidate.subscriptionPlans?.some((planId) => providerPlanIds.has(planId)));
18500
+ if (!hasAnyMembershipRow)
18380
18501
  return { kind: "unknown" };
18381
18502
  const vendorsInView = new Set(providerPlans.map((plan) => plan.provider).filter((v) => v !== undefined));
18382
18503
  const hasUnroutableSiblingPlan = (cache.plans ?? []).some((plan) => plan.provider !== undefined && vendorsInView.has(plan.provider) && plan.routing?.providerUid === undefined);
18383
18504
  if (hasUnroutableSiblingPlan)
18384
18505
  return { kind: "unknown" };
18385
- return providerPlans.every(isCatalogDiscoveredPlan) ? { kind: "not-served" } : { kind: "unknown" };
18506
+ const hasCompleteMembershipView = providerPlans.every(isCatalogDiscoveredPlan);
18507
+ if (!hasCompleteMembershipView)
18508
+ return { kind: "unknown" };
18509
+ return { kind: "not-served" };
18386
18510
  }
18387
18511
  function isCatalogDiscoveredPlan(plan) {
18388
18512
  return plan.modelDiscovery === "catalog";
@@ -18570,26 +18694,26 @@ var init_agent_availability = __esm(() => {
18570
18694
  });
18571
18695
 
18572
18696
  // 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";
18697
+ import { existsSync as existsSync7, mkdirSync as mkdirSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
18698
+ import { homedir as homedir9 } from "os";
18699
+ import { dirname as dirname6, join as join9, parse as parse6 } from "path";
18576
18700
  function activeConfigFile() {
18577
18701
  return activeGlobalConfigFile(CONFIG_FILE);
18578
18702
  }
18579
18703
  function ensureConfigDir() {
18580
- if (!existsSync6(CONFIG_DIR)) {
18581
- mkdirSync6(CONFIG_DIR, { recursive: true });
18704
+ if (!existsSync7(CONFIG_DIR)) {
18705
+ mkdirSync7(CONFIG_DIR, { recursive: true });
18582
18706
  }
18583
18707
  }
18584
18708
  function loadConfig() {
18585
18709
  const activeFile = activeConfigFile();
18586
18710
  if (!getConfigFileOverride())
18587
18711
  ensureConfigDir();
18588
- if (!existsSync6(activeFile)) {
18712
+ if (!existsSync7(activeFile)) {
18589
18713
  return { ...DEFAULT_CONFIG };
18590
18714
  }
18591
18715
  try {
18592
- const content = readFileSync6(activeFile, "utf-8");
18716
+ const content = readFileSync7(activeFile, "utf-8");
18593
18717
  const config = JSON.parse(content);
18594
18718
  const merged = {
18595
18719
  version: config.version || DEFAULT_CONFIG.version,
@@ -18659,39 +18783,39 @@ function loadConfig() {
18659
18783
  function saveConfig(config) {
18660
18784
  if (!getConfigFileOverride())
18661
18785
  ensureConfigDir();
18662
- writeFileSync6(activeConfigFile(), JSON.stringify(config, null, 2), "utf-8");
18786
+ writeFileSync7(activeConfigFile(), JSON.stringify(config, null, 2), "utf-8");
18663
18787
  }
18664
18788
  function configExists() {
18665
- return existsSync6(CONFIG_FILE);
18789
+ return existsSync7(CONFIG_FILE);
18666
18790
  }
18667
18791
  function getConfigPath() {
18668
18792
  return CONFIG_FILE;
18669
18793
  }
18670
18794
  function getLocalConfigPath() {
18671
- const home = homedir8();
18795
+ const home = homedir9();
18672
18796
  let dir = process.cwd();
18673
18797
  const root = parse6(dir).root;
18674
18798
  while (dir !== root && dir !== home) {
18675
- const candidate = join8(dir, LOCAL_CONFIG_FILENAME);
18676
- if (existsSync6(candidate))
18799
+ const candidate = join9(dir, LOCAL_CONFIG_FILENAME);
18800
+ if (existsSync7(candidate))
18677
18801
  return candidate;
18678
- if (existsSync6(join8(dir, ".git"))) {
18802
+ if (existsSync7(join9(dir, ".git"))) {
18679
18803
  return candidate;
18680
18804
  }
18681
- dir = dirname5(dir);
18805
+ dir = dirname6(dir);
18682
18806
  }
18683
- return join8(process.cwd(), LOCAL_CONFIG_FILENAME);
18807
+ return join9(process.cwd(), LOCAL_CONFIG_FILENAME);
18684
18808
  }
18685
18809
  function localConfigExists() {
18686
- return existsSync6(getLocalConfigPath());
18810
+ return existsSync7(getLocalConfigPath());
18687
18811
  }
18688
18812
  function readProOnUltracode(paths = defaultScopedConfigPaths) {
18689
18813
  for (const pathFn of [paths.project, paths.global]) {
18690
18814
  try {
18691
18815
  const path = pathFn();
18692
- if (!existsSync6(path))
18816
+ if (!existsSync7(path))
18693
18817
  continue;
18694
- const parsed = JSON.parse(readFileSync6(path, "utf-8"));
18818
+ const parsed = JSON.parse(readFileSync7(path, "utf-8"));
18695
18819
  if (typeof parsed?.proOnUltracode === "boolean")
18696
18820
  return parsed.proOnUltracode;
18697
18821
  } catch {}
@@ -18700,17 +18824,17 @@ function readProOnUltracode(paths = defaultScopedConfigPaths) {
18700
18824
  }
18701
18825
  function isProjectDirectory() {
18702
18826
  const cwd = process.cwd();
18703
- return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) => existsSync6(join8(cwd, f)));
18827
+ return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) => existsSync7(join9(cwd, f)));
18704
18828
  }
18705
18829
  function loadLocalConfig() {
18706
18830
  if (getConfigFileOverride())
18707
18831
  return null;
18708
18832
  const localPath = getLocalConfigPath();
18709
- if (!existsSync6(localPath)) {
18833
+ if (!existsSync7(localPath)) {
18710
18834
  return null;
18711
18835
  }
18712
18836
  try {
18713
- const content = readFileSync6(localPath, "utf-8");
18837
+ const content = readFileSync7(localPath, "utf-8");
18714
18838
  const config = JSON.parse(content);
18715
18839
  return {
18716
18840
  ...config,
@@ -18728,7 +18852,7 @@ function saveLocalConfig(config) {
18728
18852
  if (toWrite.routing !== undefined && Object.keys(toWrite.routing).length === 0) {
18729
18853
  delete toWrite.routing;
18730
18854
  }
18731
- writeFileSync6(getLocalConfigPath(), JSON.stringify(toWrite, null, 2), "utf-8");
18855
+ writeFileSync7(getLocalConfigPath(), JSON.stringify(toWrite, null, 2), "utf-8");
18732
18856
  }
18733
18857
  function loadConfigForScope(scope) {
18734
18858
  if (scope === "local") {
@@ -18976,8 +19100,8 @@ function disableLocalProvider(providerName) {
18976
19100
  }
18977
19101
  var CONFIG_DIR, CONFIG_FILE, LOCAL_CONFIG_FILENAME = ".claudish.json", DEFAULT_CONFIG, defaultScopedConfigPaths;
18978
19102
  var init_profile_config = __esm(() => {
18979
- CONFIG_DIR = join8(homedir8(), ".claudish");
18980
- CONFIG_FILE = join8(CONFIG_DIR, "config.json");
19103
+ CONFIG_DIR = join9(homedir9(), ".claudish");
19104
+ CONFIG_FILE = join9(CONFIG_DIR, "config.json");
18981
19105
  DEFAULT_CONFIG = {
18982
19106
  version: "1.0.0",
18983
19107
  defaultProfile: "default",
@@ -22884,9 +23008,9 @@ var init_openai_api_format = __esm(() => {
22884
23008
 
22885
23009
  // src/auth/vertex-auth.ts
22886
23010
  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";
23011
+ import { existsSync as existsSync8 } from "fs";
23012
+ import { homedir as homedir10 } from "os";
23013
+ import { join as join10 } from "path";
22890
23014
  import { promisify } from "util";
22891
23015
 
22892
23016
  class VertexAuthManager {
@@ -22941,8 +23065,8 @@ class VertexAuthManager {
22941
23065
  }
22942
23066
  async tryADC() {
22943
23067
  try {
22944
- const adcPath = join9(homedir9(), ".config/gcloud/application_default_credentials.json");
22945
- if (!existsSync7(adcPath)) {
23068
+ const adcPath = join10(homedir10(), ".config/gcloud/application_default_credentials.json");
23069
+ if (!existsSync8(adcPath)) {
22946
23070
  log("[VertexAuth] ADC credentials file not found");
22947
23071
  return null;
22948
23072
  }
@@ -22966,7 +23090,7 @@ class VertexAuthManager {
22966
23090
  if (!credPath) {
22967
23091
  return null;
22968
23092
  }
22969
- if (!existsSync7(credPath)) {
23093
+ if (!existsSync8(credPath)) {
22970
23094
  throw new Error(`Service account file not found: ${credPath}
22971
23095
 
22972
23096
  Check GOOGLE_APPLICATION_CREDENTIALS path.`);
@@ -23005,8 +23129,8 @@ function validateVertexOAuthConfig() {
23005
23129
  ` + ` export VERTEX_PROJECT='your-gcp-project-id'
23006
23130
  ` + " export VERTEX_LOCATION='us-central1' # optional";
23007
23131
  }
23008
- const adcPath = join9(homedir9(), ".config/gcloud/application_default_credentials.json");
23009
- const hasADC = existsSync7(adcPath);
23132
+ const adcPath = join10(homedir10(), ".config/gcloud/application_default_credentials.json");
23133
+ const hasADC = existsSync8(adcPath);
23010
23134
  const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
23011
23135
  if (!hasADC && !hasServiceAccount) {
23012
23136
  return `No Vertex AI credentials found.
@@ -23616,9 +23740,9 @@ var init_dialect_manager = __esm(() => {
23616
23740
 
23617
23741
  // src/auth/antigravity-token.ts
23618
23742
  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";
23743
+ import { existsSync as existsSync9 } from "fs";
23744
+ import { homedir as homedir11 } from "os";
23745
+ import { join as join11 } from "path";
23622
23746
  function invalidateReadStoreMemo() {
23623
23747
  cachedRawStore = null;
23624
23748
  }
@@ -23654,8 +23778,8 @@ function locateAgyBinary() {
23654
23778
  if (p.length > 0)
23655
23779
  return p;
23656
23780
  } catch {}
23657
- const fallback = join10(homedir10(), ".local", "bin", "agy");
23658
- return existsSync8(fallback) ? fallback : null;
23781
+ const fallback = join11(homedir11(), ".local", "bin", "agy");
23782
+ return existsSync9(fallback) ? fallback : null;
23659
23783
  }
23660
23784
  function defaultDeleteStore() {
23661
23785
  if (process.platform !== "darwin")
@@ -24142,9 +24266,9 @@ var init_antigravity = __esm(() => {
24142
24266
  });
24143
24267
 
24144
24268
  // 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";
24269
+ import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
24270
+ import { homedir as homedir12 } from "os";
24271
+ import { join as join12 } from "path";
24148
24272
  function formatWindowMinutes(minutes) {
24149
24273
  if (!Number.isFinite(minutes) || minutes <= 0)
24150
24274
  return "";
@@ -24158,7 +24282,7 @@ function formatWindowMinutes(minutes) {
24158
24282
  return `${hours}h${minutes % 60}m`;
24159
24283
  }
24160
24284
  function credentialsPath() {
24161
- return join11(homedir11(), ".claudish", "codex-oauth.json");
24285
+ return join12(homedir12(), ".claudish", "codex-oauth.json");
24162
24286
  }
24163
24287
  function planLabel(planType) {
24164
24288
  if (!planType)
@@ -24210,10 +24334,10 @@ function scrapeCodexHeaders(headers) {
24210
24334
  }
24211
24335
  function resolveProbeModel() {
24212
24336
  try {
24213
- const cachePath = join11(homedir11(), ".codex", "models_cache.json");
24214
- if (!existsSync9(cachePath))
24337
+ const cachePath = join12(homedir12(), ".codex", "models_cache.json");
24338
+ if (!existsSync10(cachePath))
24215
24339
  return;
24216
- const cache = JSON.parse(readFileSync7(cachePath, "utf-8"));
24340
+ const cache = JSON.parse(readFileSync8(cachePath, "utf-8"));
24217
24341
  for (const m of cache.models ?? []) {
24218
24342
  const slug = m?.slug ?? m?.id;
24219
24343
  if (typeof slug === "string" && slug.length > 0)
@@ -24225,9 +24349,9 @@ function resolveProbeModel() {
24225
24349
  function readCodexCredentials() {
24226
24350
  try {
24227
24351
  const path = credentialsPath();
24228
- if (!existsSync9(path))
24352
+ if (!existsSync10(path))
24229
24353
  return;
24230
- return JSON.parse(readFileSync7(path, "utf-8"));
24354
+ return JSON.parse(readFileSync8(path, "utf-8"));
24231
24355
  } catch {
24232
24356
  return;
24233
24357
  }
@@ -24258,7 +24382,7 @@ var init_codex = __esm(() => {
24258
24382
  },
24259
24383
  isAvailable() {
24260
24384
  try {
24261
- return existsSync9(credentialsPath());
24385
+ return existsSync10(credentialsPath());
24262
24386
  } catch {
24263
24387
  return false;
24264
24388
  }
@@ -24312,15 +24436,15 @@ import { exec as exec2 } from "child_process";
24312
24436
  import { createHash as createHash2, randomBytes } from "crypto";
24313
24437
  import {
24314
24438
  closeSync as closeSync2,
24315
- existsSync as existsSync10,
24316
- mkdirSync as mkdirSync7,
24439
+ existsSync as existsSync11,
24440
+ mkdirSync as mkdirSync8,
24317
24441
  openSync as openSync2,
24318
- readFileSync as readFileSync8,
24442
+ readFileSync as readFileSync9,
24319
24443
  unlinkSync as unlinkSync2,
24320
24444
  writeSync as writeSync2
24321
24445
  } from "fs";
24322
- import { homedir as homedir12 } from "os";
24323
- import { join as join12 } from "path";
24446
+ import { homedir as homedir13 } from "os";
24447
+ import { join as join13 } from "path";
24324
24448
  import { promisify as promisify2 } from "util";
24325
24449
 
24326
24450
  class OAuthManager {
@@ -24328,21 +24452,21 @@ class OAuthManager {
24328
24452
  refreshPromise = null;
24329
24453
  tokenRefreshMargin = 5 * 60 * 1000;
24330
24454
  static ensureClaudishDir() {
24331
- const dir = join12(homedir12(), ".claudish");
24332
- if (!existsSync10(dir)) {
24333
- mkdirSync7(dir, { recursive: true });
24455
+ const dir = join13(homedir13(), ".claudish");
24456
+ if (!existsSync11(dir)) {
24457
+ mkdirSync8(dir, { recursive: true });
24334
24458
  }
24335
24459
  return dir;
24336
24460
  }
24337
24461
  getCredentialsPath() {
24338
- return join12(homedir12(), ".claudish", this.credentialFile);
24462
+ return join13(homedir13(), ".claudish", this.credentialFile);
24339
24463
  }
24340
24464
  loadCredentials() {
24341
24465
  const credPath = this.getCredentialsPath();
24342
- if (!existsSync10(credPath))
24466
+ if (!existsSync11(credPath))
24343
24467
  return null;
24344
24468
  try {
24345
- const data = JSON.parse(readFileSync8(credPath, "utf-8"));
24469
+ const data = JSON.parse(readFileSync9(credPath, "utf-8"));
24346
24470
  if (!this.validateCredentials(data)) {
24347
24471
  log(`[${this.providerName}] Invalid credentials file structure`);
24348
24472
  return null;
@@ -24367,7 +24491,7 @@ class OAuthManager {
24367
24491
  }
24368
24492
  deleteCredentials() {
24369
24493
  const credPath = this.getCredentialsPath();
24370
- if (existsSync10(credPath)) {
24494
+ if (existsSync11(credPath)) {
24371
24495
  unlinkSync2(credPath);
24372
24496
  log(`[${this.providerName}] Credentials deleted`);
24373
24497
  }
@@ -24674,14 +24798,14 @@ Signed in to Grok. Try it with: claudish --model gk@grok-4.6 "hello"
24674
24798
  });
24675
24799
 
24676
24800
  // 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";
24801
+ import { existsSync as existsSync12, readFileSync as readFileSync10, renameSync, writeFileSync as writeFileSync8 } from "fs";
24802
+ import { homedir as homedir14 } from "os";
24803
+ import { join as join14 } from "path";
24680
24804
  function grokHome() {
24681
- return grokHomeOverride ?? join13(homedir13(), ".grok");
24805
+ return grokHomeOverride ?? join14(homedir14(), ".grok");
24682
24806
  }
24683
24807
  function grokAuthPath() {
24684
- return join13(grokHome(), "auth.json");
24808
+ return join14(grokHome(), "auth.json");
24685
24809
  }
24686
24810
  function str(value) {
24687
24811
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
@@ -24689,7 +24813,7 @@ function str(value) {
24689
24813
  function readGrokCredential() {
24690
24814
  let parsed;
24691
24815
  try {
24692
- parsed = JSON.parse(readFileSync9(grokAuthPath(), "utf8"));
24816
+ parsed = JSON.parse(readFileSync10(grokAuthPath(), "utf8"));
24693
24817
  } catch {
24694
24818
  return;
24695
24819
  }
@@ -24714,10 +24838,10 @@ function readGrokCredential() {
24714
24838
  };
24715
24839
  }
24716
24840
  function claudishGrokOAuthPath() {
24717
- return claudishOAuthPathOverride ?? join13(homedir13(), ".claudish", "grok-oauth.json");
24841
+ return claudishOAuthPathOverride ?? join14(homedir14(), ".claudish", "grok-oauth.json");
24718
24842
  }
24719
24843
  function hasClaudishGrokOAuth() {
24720
- return existsSync11(claudishGrokOAuthPath());
24844
+ return existsSync12(claudishGrokOAuthPath());
24721
24845
  }
24722
24846
  function hasGrokCredentials() {
24723
24847
  return hasClaudishGrokOAuth() || readGrokCredential() !== undefined;
@@ -24739,7 +24863,7 @@ function readLocalGrokVersion() {
24739
24863
  ["models_cache.json", "grok_version"]
24740
24864
  ]) {
24741
24865
  try {
24742
- const parsed = JSON.parse(readFileSync9(join13(grokHome(), file), "utf8"));
24866
+ const parsed = JSON.parse(readFileSync10(join14(grokHome(), file), "utf8"));
24743
24867
  const version = str(parsed[field]);
24744
24868
  if (version)
24745
24869
  return version;
@@ -24785,7 +24909,7 @@ function persistRefreshedToken(scope, next) {
24785
24909
  const path = grokAuthPath();
24786
24910
  let parsed;
24787
24911
  try {
24788
- parsed = JSON.parse(readFileSync9(path, "utf8"));
24912
+ parsed = JSON.parse(readFileSync10(path, "utf8"));
24789
24913
  } catch {
24790
24914
  return;
24791
24915
  }
@@ -24798,7 +24922,7 @@ function persistRefreshedToken(scope, next) {
24798
24922
  if (next.expiresAt)
24799
24923
  entry.expires_at = next.expiresAt;
24800
24924
  const tmp = `${path}.claudish.tmp`;
24801
- writeFileSync7(tmp, `${JSON.stringify(parsed, null, 2)}
24925
+ writeFileSync8(tmp, `${JSON.stringify(parsed, null, 2)}
24802
24926
  `, { mode: 384 });
24803
24927
  renameSync(tmp, path);
24804
24928
  }
@@ -25328,8 +25452,8 @@ var init_harness = __esm(() => {
25328
25452
 
25329
25453
  // src/behavior/journal.ts
25330
25454
  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";
25455
+ import { homedir as homedir15 } from "os";
25456
+ import { dirname as dirname7, join as join15 } from "path";
25333
25457
  function classifyPath(observed, expected) {
25334
25458
  if (!observed)
25335
25459
  return "not_applicable";
@@ -25341,7 +25465,7 @@ function classifyPath(observed, expected) {
25341
25465
  return dirOf(observed) === dirOf(expected) ? "same_dir_wrong_name" : "outside_expected_dir";
25342
25466
  }
25343
25467
  function journalPath() {
25344
- return join14(homedir14(), ".claudish", "behavior-journal.jsonl");
25468
+ return join15(homedir15(), ".claudish", "behavior-journal.jsonl");
25345
25469
  }
25346
25470
  async function prune(path) {
25347
25471
  const content = await readFile(path, "utf8");
@@ -25368,7 +25492,7 @@ async function recordDecision(entry, path = journalPath()) {
25368
25492
  try {
25369
25493
  const size = await stat(path).then((s) => s.size, () => 0);
25370
25494
  if (size === 0)
25371
- await mkdir(dirname6(path), { recursive: true }).catch(() => {});
25495
+ await mkdir(dirname7(path), { recursive: true }).catch(() => {});
25372
25496
  if (size > MAX_JOURNAL_BYTES) {
25373
25497
  await prune(path).catch((err) => log(`[behavior:journal] prune failed: ${err}`));
25374
25498
  }
@@ -25387,9 +25511,9 @@ var init_journal = __esm(() => {
25387
25511
 
25388
25512
  // src/behavior/telemetry/aggregate.ts
25389
25513
  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";
25514
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync9 } from "fs";
25515
+ import { homedir as homedir16 } from "os";
25516
+ import { dirname as dirname8, join as join16 } from "path";
25393
25517
  function contextBucket(inputTokens) {
25394
25518
  if (inputTokens < 50000)
25395
25519
  return "0-50k";
@@ -25503,7 +25627,7 @@ function pendingReports() {
25503
25627
  return [...sessions.values()].map(toReport);
25504
25628
  }
25505
25629
  function outboxPath() {
25506
- return join15(homedir15(), ".claudish", "behavior-outbox.jsonl");
25630
+ return join16(homedir16(), ".claudish", "behavior-outbox.jsonl");
25507
25631
  }
25508
25632
  function spoolPendingSync(path = outboxPath()) {
25509
25633
  if (sessions.size === 0)
@@ -25513,7 +25637,7 @@ function spoolPendingSync(path = outboxPath()) {
25513
25637
  if (reports.length === 0)
25514
25638
  return 0;
25515
25639
  try {
25516
- mkdirSync8(dirname7(path), { recursive: true });
25640
+ mkdirSync9(dirname8(path), { recursive: true });
25517
25641
  appendFileSync2(path, `${reports.map((r) => JSON.stringify(r)).join(`
25518
25642
  `)}
25519
25643
  `);
@@ -25710,10 +25834,10 @@ var init_client = __esm(() => {
25710
25834
 
25711
25835
  // src/behavior/observer/live-log.ts
25712
25836
  import { appendFile as appendFile3 } from "fs/promises";
25713
- import { homedir as homedir16 } from "os";
25714
- import { join as join16 } from "path";
25837
+ import { homedir as homedir17 } from "os";
25838
+ import { join as join17 } from "path";
25715
25839
  function defaultPath() {
25716
- return join16(homedir16(), ".claudish", "behavior-divergences.jsonl");
25840
+ return join17(homedir17(), ".claudish", "behavior-divergences.jsonl");
25717
25841
  }
25718
25842
  async function recordLiveDivergence(entry, path = defaultPath()) {
25719
25843
  try {
@@ -26401,9 +26525,9 @@ var init_hooks = __esm(() => {
26401
26525
  });
26402
26526
 
26403
26527
  // 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";
26528
+ import { appendFileSync as appendFileSync3, readFileSync as readFileSync11, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
26529
+ import { homedir as homedir18 } from "os";
26530
+ import { join as join18 } from "path";
26407
26531
  function directoryOf2(filePath) {
26408
26532
  const slash = filePath.lastIndexOf("/");
26409
26533
  return slash > 0 ? filePath.slice(0, slash) : undefined;
@@ -26425,7 +26549,7 @@ function writeTargetsOf(row) {
26425
26549
  function replayTranscript(file) {
26426
26550
  let text;
26427
26551
  try {
26428
- text = readFileSync10(file, "utf8");
26552
+ text = readFileSync11(file, "utf8");
26429
26553
  } catch {
26430
26554
  return [];
26431
26555
  }
@@ -26482,26 +26606,26 @@ function listTranscripts(root) {
26482
26606
  return files;
26483
26607
  }
26484
26608
  for (const project of projects) {
26485
- const dir = join17(root, project);
26609
+ const dir = join18(root, project);
26486
26610
  try {
26487
26611
  if (!statSync2(dir).isDirectory())
26488
26612
  continue;
26489
26613
  for (const f of readdirSync2(dir)) {
26490
26614
  if (f.endsWith(".jsonl"))
26491
- files.push(join17(dir, f));
26615
+ files.push(join18(dir, f));
26492
26616
  }
26493
26617
  } catch {}
26494
26618
  }
26495
26619
  return files;
26496
26620
  }
26497
26621
  function buildCorpus(options = {}) {
26498
- const root = options.projectsRoot ?? join17(homedir17(), ".claude", "projects");
26622
+ const root = options.projectsRoot ?? join18(homedir18(), ".claude", "projects");
26499
26623
  const files = listTranscripts(root);
26500
26624
  const records = [];
26501
26625
  for (const f of files)
26502
26626
  records.push(...replayTranscript(f));
26503
26627
  if (options.write && records.length > 0) {
26504
- const outputPath = options.outputPath ?? join17(homedir17(), ".claudish", "behavior-divergences.jsonl");
26628
+ const outputPath = options.outputPath ?? join18(homedir18(), ".claudish", "behavior-divergences.jsonl");
26505
26629
  try {
26506
26630
  appendFileSync3(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
26507
26631
  `)}
@@ -27878,9 +28002,9 @@ var init_keychain_source = __esm(() => {
27878
28002
  });
27879
28003
 
27880
28004
  // 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";
28005
+ import { existsSync as existsSync13 } from "fs";
28006
+ import { homedir as homedir19 } from "os";
28007
+ import { join as join19 } from "path";
27884
28008
 
27885
28009
  class ApiKeyCredentialProvider {
27886
28010
  catalogName;
@@ -27915,7 +28039,7 @@ class ApiKeyCredentialProvider {
27915
28039
  if (!this.oauthFallback)
27916
28040
  return false;
27917
28041
  try {
27918
- return existsSync12(join18(homedir18(), ".claudish", this.oauthFallback));
28042
+ return existsSync13(join19(homedir19(), ".claudish", this.oauthFallback));
27919
28043
  } catch {
27920
28044
  return false;
27921
28045
  }
@@ -28006,10 +28130,10 @@ var init_api_key_credential = __esm(() => {
28006
28130
  // src/auth/codex-oauth.ts
28007
28131
  import { exec as exec3 } from "child_process";
28008
28132
  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";
28133
+ import { closeSync as closeSync3, existsSync as existsSync14, openSync as openSync3, readFileSync as readFileSync12, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "fs";
28010
28134
  import { createServer } from "http";
28011
- import { homedir as homedir19 } from "os";
28012
- import { join as join19 } from "path";
28135
+ import { homedir as homedir20 } from "os";
28136
+ import { join as join20 } from "path";
28013
28137
  import { promisify as promisify3 } from "util";
28014
28138
 
28015
28139
  class CodexOAuth {
@@ -28035,8 +28159,8 @@ class CodexOAuth {
28035
28159
  return this.credentials !== null && !!this.credentials.refresh_token;
28036
28160
  }
28037
28161
  getCredentialsPath() {
28038
- const claudishDir = join19(homedir19(), ".claudish");
28039
- return join19(claudishDir, "codex-oauth.json");
28162
+ const claudishDir = join20(homedir20(), ".claudish");
28163
+ return join20(claudishDir, "codex-oauth.json");
28040
28164
  }
28041
28165
  async login() {
28042
28166
  log("[CodexOAuth] Starting OAuth login flow");
@@ -28062,7 +28186,7 @@ class CodexOAuth {
28062
28186
  }
28063
28187
  async logout() {
28064
28188
  const credPath = this.getCredentialsPath();
28065
- if (existsSync13(credPath)) {
28189
+ if (existsSync14(credPath)) {
28066
28190
  unlinkSync3(credPath);
28067
28191
  log("[CodexOAuth] Credentials deleted");
28068
28192
  }
@@ -28140,11 +28264,11 @@ Details: ${e.message}`);
28140
28264
  }
28141
28265
  loadCredentials() {
28142
28266
  const credPath = this.getCredentialsPath();
28143
- if (!existsSync13(credPath)) {
28267
+ if (!existsSync14(credPath)) {
28144
28268
  return null;
28145
28269
  }
28146
28270
  try {
28147
- const data = readFileSync11(credPath, "utf-8");
28271
+ const data = readFileSync12(credPath, "utf-8");
28148
28272
  const credentials = JSON.parse(data);
28149
28273
  if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at) {
28150
28274
  log("[CodexOAuth] Invalid credentials file structure");
@@ -28159,8 +28283,8 @@ Details: ${e.message}`);
28159
28283
  }
28160
28284
  saveCredentials(credentials) {
28161
28285
  const credPath = this.getCredentialsPath();
28162
- const claudishDir = join19(homedir19(), ".claudish");
28163
- if (!existsSync13(claudishDir)) {
28286
+ const claudishDir = join20(homedir20(), ".claudish");
28287
+ if (!existsSync14(claudishDir)) {
28164
28288
  const { mkdirSync } = __require("fs");
28165
28289
  mkdirSync(claudishDir, { recursive: true });
28166
28290
  }
@@ -28497,11 +28621,11 @@ var init_codex_credential = __esm(() => {
28497
28621
  });
28498
28622
 
28499
28623
  // 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";
28624
+ import { readFileSync as readFileSync13 } from "fs";
28625
+ import { homedir as homedir21 } from "os";
28626
+ import { join as join21 } from "path";
28503
28627
  function devinCredentialsPath() {
28504
- return credentialsPathOverride ?? join20(homedir20(), ".local", "share", "devin", "credentials.toml");
28628
+ return credentialsPathOverride ?? join21(homedir21(), ".local", "share", "devin", "credentials.toml");
28505
28629
  }
28506
28630
  function readTomlString(source, key) {
28507
28631
  const match = source.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, "m"));
@@ -28514,7 +28638,7 @@ function readCredentialsFile() {
28514
28638
  return fileCache.value;
28515
28639
  let value = {};
28516
28640
  try {
28517
- const source = readFileSync12(path, "utf8");
28641
+ const source = readFileSync13(path, "utf8");
28518
28642
  value = {
28519
28643
  apiKey: readTomlString(source, "windsurf_api_key"),
28520
28644
  serverUrl: readTomlString(source, "api_server_url")
@@ -28603,9 +28727,9 @@ var init_grok_credential = __esm(() => {
28603
28727
  // src/auth/kimi-oauth.ts
28604
28728
  import { exec as exec4 } from "child_process";
28605
28729
  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";
28730
+ import { closeSync as closeSync4, existsSync as existsSync15, openSync as openSync4, readFileSync as readFileSync14, unlinkSync as unlinkSync4, writeSync as writeSync4 } from "fs";
28731
+ import { homedir as homedir22, hostname, platform, release as release2 } from "os";
28732
+ import { join as join22 } from "path";
28609
28733
  import { promisify as promisify4 } from "util";
28610
28734
 
28611
28735
  class KimiOAuth {
@@ -28633,23 +28757,23 @@ class KimiOAuth {
28633
28757
  return this.credentials !== null && !!this.credentials.refresh_token;
28634
28758
  }
28635
28759
  getCredentialsPath() {
28636
- const claudishDir = join21(homedir21(), ".claudish");
28637
- return join21(claudishDir, "kimi-oauth.json");
28760
+ const claudishDir = join22(homedir22(), ".claudish");
28761
+ return join22(claudishDir, "kimi-oauth.json");
28638
28762
  }
28639
28763
  getDeviceIdPath() {
28640
- const claudishDir = join21(homedir21(), ".claudish");
28641
- return join21(claudishDir, "kimi-device-id");
28764
+ const claudishDir = join22(homedir22(), ".claudish");
28765
+ return join22(claudishDir, "kimi-device-id");
28642
28766
  }
28643
28767
  loadOrCreateDeviceId() {
28644
28768
  const deviceIdPath = this.getDeviceIdPath();
28645
- const claudishDir = join21(homedir21(), ".claudish");
28646
- if (!existsSync14(claudishDir)) {
28769
+ const claudishDir = join22(homedir22(), ".claudish");
28770
+ if (!existsSync15(claudishDir)) {
28647
28771
  const { mkdirSync } = __require("fs");
28648
28772
  mkdirSync(claudishDir, { recursive: true });
28649
28773
  }
28650
- if (existsSync14(deviceIdPath)) {
28774
+ if (existsSync15(deviceIdPath)) {
28651
28775
  try {
28652
- const deviceId = readFileSync13(deviceIdPath, "utf-8").trim();
28776
+ const deviceId = readFileSync14(deviceIdPath, "utf-8").trim();
28653
28777
  if (deviceId) {
28654
28778
  return deviceId;
28655
28779
  }
@@ -28820,7 +28944,7 @@ Waiting for authorization...`);
28820
28944
  }
28821
28945
  async logout() {
28822
28946
  const credPath = this.getCredentialsPath();
28823
- if (existsSync14(credPath)) {
28947
+ if (existsSync15(credPath)) {
28824
28948
  unlinkSync4(credPath);
28825
28949
  log("[KimiOAuth] Credentials deleted");
28826
28950
  }
@@ -28887,7 +29011,7 @@ Waiting for authorization...`);
28887
29011
  } catch (e) {
28888
29012
  log(`[KimiOAuth] Refresh failed: ${e.message}`);
28889
29013
  const credPath = this.getCredentialsPath();
28890
- if (existsSync14(credPath)) {
29014
+ if (existsSync15(credPath)) {
28891
29015
  unlinkSync4(credPath);
28892
29016
  }
28893
29017
  this.credentials = null;
@@ -28904,11 +29028,11 @@ Details: ${e.message}`);
28904
29028
  }
28905
29029
  loadCredentials() {
28906
29030
  const credPath = this.getCredentialsPath();
28907
- if (!existsSync14(credPath)) {
29031
+ if (!existsSync15(credPath)) {
28908
29032
  return null;
28909
29033
  }
28910
29034
  try {
28911
- const data = readFileSync13(credPath, "utf-8");
29035
+ const data = readFileSync14(credPath, "utf-8");
28912
29036
  const credentials = JSON.parse(data);
28913
29037
  if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at || !credentials.scope || !credentials.token_type) {
28914
29038
  log("[KimiOAuth] Invalid credentials file structure");
@@ -28923,8 +29047,8 @@ Details: ${e.message}`);
28923
29047
  }
28924
29048
  saveCredentials(credentials) {
28925
29049
  const credPath = this.getCredentialsPath();
28926
- const claudishDir = join21(homedir21(), ".claudish");
28927
- if (!existsSync14(claudishDir)) {
29050
+ const claudishDir = join22(homedir22(), ".claudish");
29051
+ if (!existsSync15(claudishDir)) {
28928
29052
  const { mkdirSync } = __require("fs");
28929
29053
  mkdirSync(claudishDir, { recursive: true });
28930
29054
  }
@@ -28954,9 +29078,9 @@ var init_kimi_oauth = __esm(() => {
28954
29078
  });
28955
29079
 
28956
29080
  // 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";
29081
+ import { existsSync as existsSync16, readFileSync as readFileSync15 } from "fs";
29082
+ import { homedir as homedir23 } from "os";
29083
+ import { join as join23 } from "path";
28960
29084
  function credentialSatisfies(descriptor, data) {
28961
29085
  if (!data?.access_token)
28962
29086
  return false;
@@ -28969,14 +29093,14 @@ function credentialSatisfies(descriptor, data) {
28969
29093
  return true;
28970
29094
  }
28971
29095
  function hasValidOAuthCredentials(descriptor) {
28972
- const credPath = join22(homedir22(), ".claudish", descriptor.credentialFile);
28973
- if (!existsSync15(credPath))
29096
+ const credPath = join23(homedir23(), ".claudish", descriptor.credentialFile);
29097
+ if (!existsSync16(credPath))
28974
29098
  return false;
28975
29099
  if (descriptor.validationMode === "file-exists") {
28976
29100
  return true;
28977
29101
  }
28978
29102
  try {
28979
- return credentialSatisfies(descriptor, JSON.parse(readFileSync14(credPath, "utf-8")));
29103
+ return credentialSatisfies(descriptor, JSON.parse(readFileSync15(credPath, "utf-8")));
28980
29104
  } catch {
28981
29105
  return false;
28982
29106
  }
@@ -31062,9 +31186,9 @@ var DEFAULT_POLL_INTERVAL_MS = 250;
31062
31186
  var init_transcript_tailer = () => {};
31063
31187
 
31064
31188
  // 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";
31189
+ import { existsSync as existsSync17, readFileSync as readFileSync16, readdirSync as readdirSync3 } from "fs";
31190
+ import { homedir as homedir24 } from "os";
31191
+ import { join as join24 } from "path";
31068
31192
  function extractSessionId2(metadata) {
31069
31193
  const userId = metadata?.user_id;
31070
31194
  if (typeof userId !== "string")
@@ -31089,7 +31213,7 @@ class SessionEventRegistry {
31089
31213
  claudeHome;
31090
31214
  pollIntervalMs;
31091
31215
  constructor(opts = {}) {
31092
- this.claudeHome = opts.claudeHome ?? join23(homedir23(), ".claude");
31216
+ this.claudeHome = opts.claudeHome ?? join24(homedir24(), ".claude");
31093
31217
  this.pollIntervalMs = opts.pollIntervalMs;
31094
31218
  }
31095
31219
  ensureSession(sessionId) {
@@ -31175,14 +31299,14 @@ class SessionEventRegistry {
31175
31299
  }
31176
31300
  }
31177
31301
  locateTranscript(sessionId) {
31178
- const projectsDir = join23(this.claudeHome, "projects");
31179
- const primary = join23(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
31180
- if (existsSync16(primary))
31302
+ const projectsDir = join24(this.claudeHome, "projects");
31303
+ const primary = join24(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
31304
+ if (existsSync17(primary))
31181
31305
  return primary;
31182
31306
  try {
31183
31307
  for (const dir of readdirSync3(projectsDir)) {
31184
- const candidate = join23(projectsDir, dir, `${sessionId}.jsonl`);
31185
- if (existsSync16(candidate))
31308
+ const candidate = join24(projectsDir, dir, `${sessionId}.jsonl`);
31309
+ if (existsSync17(candidate))
31186
31310
  return candidate;
31187
31311
  }
31188
31312
  } catch {}
@@ -31190,7 +31314,7 @@ class SessionEventRegistry {
31190
31314
  }
31191
31315
  readSettingsEffortLevel() {
31192
31316
  try {
31193
- const settings = JSON.parse(readFileSync15(join23(this.claudeHome, "settings.json"), "utf-8"));
31317
+ const settings = JSON.parse(readFileSync16(join24(this.claudeHome, "settings.json"), "utf-8"));
31194
31318
  return typeof settings.effortLevel === "string" ? settings.effortLevel : undefined;
31195
31319
  } catch {
31196
31320
  return;
@@ -31389,25 +31513,25 @@ var init_model_parser = __esm(() => {
31389
31513
 
31390
31514
  // src/stats-buffer.ts
31391
31515
  import {
31392
- existsSync as existsSync17,
31393
- mkdirSync as mkdirSync9,
31394
- readFileSync as readFileSync16,
31516
+ existsSync as existsSync18,
31517
+ mkdirSync as mkdirSync10,
31518
+ readFileSync as readFileSync17,
31395
31519
  renameSync as renameSync2,
31396
31520
  unlinkSync as unlinkSync5,
31397
- writeFileSync as writeFileSync8
31521
+ writeFileSync as writeFileSync9
31398
31522
  } from "fs";
31399
- import { homedir as homedir24 } from "os";
31400
- import { join as join24 } from "path";
31523
+ import { homedir as homedir25 } from "os";
31524
+ import { join as join25 } from "path";
31401
31525
  function ensureDir() {
31402
- if (!existsSync17(CLAUDISH_DIR)) {
31403
- mkdirSync9(CLAUDISH_DIR, { recursive: true });
31526
+ if (!existsSync18(CLAUDISH_DIR)) {
31527
+ mkdirSync10(CLAUDISH_DIR, { recursive: true });
31404
31528
  }
31405
31529
  }
31406
31530
  function readFromDisk() {
31407
31531
  try {
31408
- if (!existsSync17(BUFFER_FILE))
31532
+ if (!existsSync18(BUFFER_FILE))
31409
31533
  return [];
31410
- const raw = readFileSync16(BUFFER_FILE, "utf-8");
31534
+ const raw = readFileSync17(BUFFER_FILE, "utf-8");
31411
31535
  const parsed = JSON.parse(raw);
31412
31536
  if (!Array.isArray(parsed.events))
31413
31537
  return [];
@@ -31432,8 +31556,8 @@ function writeToDisk(events) {
31432
31556
  ensureDir();
31433
31557
  const trimmed = enforceSizeCap([...events]);
31434
31558
  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");
31559
+ const tmpFile = join25(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
31560
+ writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
31437
31561
  renameSync2(tmpFile, BUFFER_FILE);
31438
31562
  memoryCache = trimmed;
31439
31563
  } catch {}
@@ -31476,7 +31600,7 @@ function clearBuffer() {
31476
31600
  try {
31477
31601
  memoryCache = [];
31478
31602
  eventsSinceLastFlush = 0;
31479
- if (existsSync17(BUFFER_FILE)) {
31603
+ if (existsSync18(BUFFER_FILE)) {
31480
31604
  unlinkSync5(BUFFER_FILE);
31481
31605
  }
31482
31606
  } catch {}
@@ -31505,8 +31629,8 @@ function syncFlushOnExit() {
31505
31629
  var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false, SIGNAL_EXIT_CODE;
31506
31630
  var init_stats_buffer = __esm(() => {
31507
31631
  BUFFER_MAX_BYTES = 64 * 1024;
31508
- CLAUDISH_DIR = join24(homedir24(), ".claudish");
31509
- BUFFER_FILE = join24(CLAUDISH_DIR, "stats-buffer.json");
31632
+ CLAUDISH_DIR = join25(homedir25(), ".claudish");
31633
+ BUFFER_FILE = join25(CLAUDISH_DIR, "stats-buffer.json");
31510
31634
  process.on("exit", syncFlushOnExit);
31511
31635
  SIGNAL_EXIT_CODE = { SIGTERM: 143, SIGINT: 130 };
31512
31636
  for (const signal of ["SIGTERM", "SIGINT"]) {
@@ -34625,9 +34749,9 @@ var init_openai_responses_sse = __esm(() => {
34625
34749
  });
34626
34750
 
34627
34751
  // 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";
34752
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "fs";
34753
+ import { homedir as homedir26 } from "os";
34754
+ import { dirname as dirname9, join as join26 } from "path";
34631
34755
  function stripProviderPrefix(name) {
34632
34756
  const at = name.indexOf("@");
34633
34757
  return at === -1 ? name : name.slice(at + 1);
@@ -34838,9 +34962,9 @@ class TokenTracker {
34838
34962
  };
34839
34963
  }
34840
34964
  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");
34965
+ const outPath = override || join26(homedir26(), ".claudish", `tokens-${this.port}.json`);
34966
+ mkdirSync11(dirname9(outPath), { recursive: true });
34967
+ writeFileSync10(outPath, JSON.stringify(data), "utf-8");
34844
34968
  } catch (e) {
34845
34969
  log(`[TokenTracker] Error writing token file: ${e}`);
34846
34970
  }
@@ -35881,11 +36005,11 @@ var init_composed_handler = __esm(() => {
35881
36005
  });
35882
36006
 
35883
36007
  // 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";
36008
+ import { existsSync as existsSync19, readFileSync as readFileSync18 } from "fs";
36009
+ import { homedir as homedir27 } from "os";
36010
+ import { join as join27, resolve as resolve2 } from "path";
35887
36011
  function activeConfigPath() {
35888
- return activeGlobalConfigFile(join26(homedir26(), ".claudish", "config.json"));
36012
+ return activeGlobalConfigFile(join27(homedir27(), ".claudish", "config.json"));
35889
36013
  }
35890
36014
  function configLayerLabel() {
35891
36015
  return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
@@ -35965,9 +36089,9 @@ function formatProvenanceLog(p) {
35965
36089
  function readDotenvKey(envVars) {
35966
36090
  try {
35967
36091
  const dotenvPath = resolve2(".env");
35968
- if (!existsSync18(dotenvPath))
36092
+ if (!existsSync19(dotenvPath))
35969
36093
  return null;
35970
- const parsed = import_dotenv.parse(readFileSync17(dotenvPath, "utf-8"));
36094
+ const parsed = import_dotenv.parse(readFileSync18(dotenvPath, "utf-8"));
35971
36095
  for (const v of envVars) {
35972
36096
  if (parsed[v])
35973
36097
  return parsed[v];
@@ -35980,9 +36104,9 @@ function readDotenvKey(envVars) {
35980
36104
  function readConfigKey(envVar) {
35981
36105
  try {
35982
36106
  const configPath = activeConfigPath();
35983
- if (!existsSync18(configPath))
36107
+ if (!existsSync19(configPath))
35984
36108
  return null;
35985
- const cfg = JSON.parse(readFileSync17(configPath, "utf-8"));
36109
+ const cfg = JSON.parse(readFileSync18(configPath, "utf-8"));
35986
36110
  return cfg.apiKeys?.[envVar] || null;
35987
36111
  } catch {
35988
36112
  return null;
@@ -37803,6 +37927,8 @@ function derivePlansUrl(catalogUrl) {
37803
37927
  function getCatalogEntries() {
37804
37928
  if (_catalogEntriesForTest !== undefined)
37805
37929
  return _catalogEntriesForTest;
37930
+ if (readCatalogIncompatibility())
37931
+ return null;
37806
37932
  if (_memCache)
37807
37933
  return _memCache;
37808
37934
  const cache = readAllModelsCache();
@@ -37955,14 +38081,32 @@ async function fetchCatalogPage(url, timeoutMs) {
37955
38081
  const reason = name === "TimeoutError" || name === "AbortError" ? "timeout" : "network";
37956
38082
  return { ok: false, reason };
37957
38083
  }
37958
- if (!response.ok)
38084
+ if (!response.ok) {
38085
+ const verdict = await contractVerdictForError(response);
38086
+ if (verdict) {
38087
+ return {
38088
+ ok: false,
38089
+ reason: "incompatible",
38090
+ serverContractVersion: verdict.serverContractVersion
38091
+ };
38092
+ }
37959
38093
  return { ok: false, reason: "http_error" };
38094
+ }
37960
38095
  let page;
37961
38096
  try {
37962
38097
  page = await response.json();
37963
38098
  } catch {
37964
38099
  return { ok: false, reason: "network" };
37965
38100
  }
38101
+ const bodyEnvelope = parseContractEnvelope(page);
38102
+ if (isIncompatibleContractVersion(bodyEnvelope.contractVersion)) {
38103
+ const verdict = recordIncompatibility(bodyEnvelope);
38104
+ return {
38105
+ ok: false,
38106
+ reason: "incompatible",
38107
+ serverContractVersion: verdict.serverContractVersion
38108
+ };
38109
+ }
37966
38110
  const revision = response.headers.get(CATALOG_REVISION_HEADER) ?? undefined;
37967
38111
  return { ok: true, page, revision };
37968
38112
  }
@@ -37978,6 +38122,12 @@ async function refreshCatalog(timeoutMs, options = {}) {
37978
38122
  const url = buildCatalogPageUrl(catalogUrl(), offset, CATALOG_PAGE_LIMIT, revision);
37979
38123
  const result = await fetchCatalogPage(url, timeoutMs);
37980
38124
  if (!result.ok) {
38125
+ if (result.reason === "incompatible") {
38126
+ return {
38127
+ kind: "incompatible",
38128
+ serverContractVersion: result.serverContractVersion
38129
+ };
38130
+ }
37981
38131
  return {
37982
38132
  kind: "fetch_failed",
37983
38133
  reason: pages === 0 ? result.reason : "incomplete"
@@ -38013,6 +38163,7 @@ async function refreshCatalog(timeoutMs, options = {}) {
38013
38163
  if (id)
38014
38164
  backwardCompatModels.push({ id });
38015
38165
  }
38166
+ clearCatalogIncompatibility();
38016
38167
  _memCache = entries;
38017
38168
  writeAllModelsCache({
38018
38169
  entries,
@@ -38023,6 +38174,20 @@ async function refreshCatalog(timeoutMs, options = {}) {
38023
38174
  _warmPromise = Promise.resolve();
38024
38175
  return { kind: "refreshed", modelCount: entries.length, catalogRevision: revision, pages };
38025
38176
  }
38177
+ async function contractVerdictForError(response) {
38178
+ const envelope = parseContractEnvelope(await readJsonBody(response));
38179
+ if (response.status === 426 || isIncompatibleContractVersion(envelope.contractVersion)) {
38180
+ return recordIncompatibility(envelope);
38181
+ }
38182
+ return null;
38183
+ }
38184
+ async function readJsonBody(response) {
38185
+ try {
38186
+ return await response.json();
38187
+ } catch {
38188
+ return;
38189
+ }
38190
+ }
38026
38191
  async function fetchSubscriptionPlans(timeoutMs, revision) {
38027
38192
  try {
38028
38193
  const url = new URL(plansUrl());
@@ -38031,14 +38196,28 @@ async function fetchSubscriptionPlans(timeoutMs, revision) {
38031
38196
  const response = await fetch(url.toString(), {
38032
38197
  signal: AbortSignal.timeout(timeoutMs)
38033
38198
  });
38034
- if (!response.ok)
38199
+ if (!response.ok) {
38200
+ await contractVerdictForError(response);
38035
38201
  return;
38202
+ }
38036
38203
  const data = await response.json();
38204
+ const envelope = parseContractEnvelope(data);
38205
+ if (isIncompatibleContractVersion(envelope.contractVersion)) {
38206
+ recordIncompatibility(envelope);
38207
+ return;
38208
+ }
38037
38209
  return Array.isArray(data.plans) ? data.plans : undefined;
38038
38210
  } catch {
38039
38211
  return;
38040
38212
  }
38041
38213
  }
38214
+ function recordIncompatibility(envelope) {
38215
+ markCatalogIncompatible({
38216
+ serverContractVersion: envelope.contractVersion,
38217
+ ...envelope.minimumContractVersion !== undefined ? { minimumContractVersion: envelope.minimumContractVersion } : {}
38218
+ });
38219
+ return { kind: "incompatible", serverContractVersion: envelope.contractVersion };
38220
+ }
38042
38221
  async function warmCatalog() {
38043
38222
  if (!_warmPromise) {
38044
38223
  _warmPromise = refreshCatalog(8000).then(() => {
@@ -38063,6 +38242,7 @@ async function ensureCatalogReady(timeoutMs = 5000) {
38063
38242
  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
38243
  var init_catalog_client = __esm(() => {
38065
38244
  init_all_models_cache();
38245
+ init_catalog_compatibility();
38066
38246
  });
38067
38247
 
38068
38248
  // src/config-schema.ts
@@ -39331,7 +39511,16 @@ function globMatch(pattern, value) {
39331
39511
  async function hasCredentialsForProvider(provider) {
39332
39512
  return credentials.isAvailable(provider);
39333
39513
  }
39514
+ function warnOnceIfCatalogIncompatible() {
39515
+ if (_warnedCatalogIncompatible)
39516
+ return;
39517
+ if (!readCatalogIncompatibility())
39518
+ return;
39519
+ _warnedCatalogIncompatible = true;
39520
+ 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`.");
39521
+ }
39334
39522
  async function routeExplicit(modelSpec, model, provider, cachePath) {
39523
+ warnOnceIfCatalogIncompatible();
39335
39524
  if (!await hasCredentialsForProvider(provider)) {
39336
39525
  return {
39337
39526
  kind: "no-route",
@@ -39356,6 +39545,10 @@ async function routeExplicit(modelSpec, model, provider, cachePath) {
39356
39545
  return { kind: "ok", primary: built, fallbacks: [] };
39357
39546
  }
39358
39547
  async function routeBare(model, nativeProvider, rules, defaultProvider, cachePath) {
39548
+ const incompatible = readCatalogIncompatibility();
39549
+ if (incompatible) {
39550
+ throw new CatalogIncompatibleError(catalogIncompatibilityMessage(incompatible));
39551
+ }
39359
39552
  const matched = matchRoutingRule(model, rules) ?? [];
39360
39553
  const entries = [...matched];
39361
39554
  if (defaultProvider && defaultProvider.length > 0) {
@@ -39437,6 +39630,7 @@ async function route(modelSpec, rulesOverride, defaultProviderOverride, cachePat
39437
39630
  const defaultProvider = defaultProviderOverride !== undefined ? defaultProviderOverride : rulesOverride !== undefined ? undefined : loadConfig().defaultProvider;
39438
39631
  return routeBare(normalizeGlmSlug(parsed.model), parsed.provider, rules, defaultProvider, cachePath);
39439
39632
  }
39633
+ var _warnedCatalogIncompatible = false;
39440
39634
  var init_routing_rules = __esm(() => {
39441
39635
  init_model_catalog();
39442
39636
  init_authority();
@@ -39445,6 +39639,7 @@ var init_routing_rules = __esm(() => {
39445
39639
  init_profile_config();
39446
39640
  init_auto_route();
39447
39641
  init_catalog_client();
39642
+ init_catalog_compatibility();
39448
39643
  init_default_routing_rules();
39449
39644
  init_model_availability();
39450
39645
  init_model_parser();
@@ -40549,8 +40744,8 @@ __export(exports_session_discovery, {
40549
40744
  });
40550
40745
  import { execFile, execFileSync as execFileSync2 } from "child_process";
40551
40746
  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";
40747
+ import { homedir as homedir28 } from "os";
40748
+ import { basename, join as join28 } from "path";
40554
40749
  function slugForPath(absPath) {
40555
40750
  return absPath.replace(/[/.]/g, "-");
40556
40751
  }
@@ -40559,7 +40754,7 @@ function transcriptPathFor(cwd, sessionUuid) {
40559
40754
  try {
40560
40755
  real = realpathSync(cwd);
40561
40756
  } catch {}
40562
- return join27(PROJECTS_DIR, slugForPath(real), `${sessionUuid}.jsonl`);
40757
+ return join28(PROJECTS_DIR, slugForPath(real), `${sessionUuid}.jsonl`);
40563
40758
  }
40564
40759
  function isAgentSession(row) {
40565
40760
  return row.entrypoint !== undefined && row.entrypoint !== "cli";
@@ -40606,7 +40801,7 @@ function projectDirs() {
40606
40801
  }
40607
40802
  }
40608
40803
  function sessionsIn(dirName) {
40609
- const dir = join27(PROJECTS_DIR, dirName);
40804
+ const dir = join28(PROJECTS_DIR, dirName);
40610
40805
  let names;
40611
40806
  try {
40612
40807
  names = readdirSync4(dir).filter((n) => n.endsWith(".jsonl"));
@@ -40615,7 +40810,7 @@ function sessionsIn(dirName) {
40615
40810
  }
40616
40811
  const rows = [];
40617
40812
  for (const n of names) {
40618
- const file = join27(dir, n);
40813
+ const file = join28(dir, n);
40619
40814
  try {
40620
40815
  const st = statSync5(file);
40621
40816
  if (st.size === 0)
@@ -40977,7 +41172,7 @@ function findLatestSessionId(cwd = process.cwd(), sinceMs = 0) {
40977
41172
  }
40978
41173
  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
41174
  var init_session_discovery = __esm(() => {
40980
- PROJECTS_DIR = join27(homedir27(), ".claude", "projects");
41175
+ PROJECTS_DIR = join28(homedir28(), ".claude", "projects");
40981
41176
  HEAD_BYTES = 64 * 1024;
40982
41177
  TAIL_BYTES = 128 * 1024;
40983
41178
  HARNESS_ENVELOPES = [
@@ -41012,19 +41207,19 @@ function newStdioDecoder() {
41012
41207
  var init_stdio_decode = () => {};
41013
41208
 
41014
41209
  // src/team-stats.ts
41015
- import { existsSync as existsSync19, readFileSync as readFileSync18, writeFileSync as writeFileSync10 } from "fs";
41016
- import { join as join28 } from "path";
41210
+ import { existsSync as existsSync20, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "fs";
41211
+ import { join as join29 } from "path";
41017
41212
  function statsDir(sessionPath) {
41018
- return join28(sessionPath, "stats");
41213
+ return join29(sessionPath, "stats");
41019
41214
  }
41020
41215
  function tokenFileFor(sessionPath, anonId) {
41021
- return join28(statsDir(sessionPath), `${anonId}.json`);
41216
+ return join29(statsDir(sessionPath), `${anonId}.json`);
41022
41217
  }
41023
41218
  function readTokenStatsAt(path) {
41024
- if (!existsSync19(path))
41219
+ if (!existsSync20(path))
41025
41220
  return null;
41026
41221
  try {
41027
- return JSON.parse(readFileSync18(path, "utf-8"));
41222
+ return JSON.parse(readFileSync19(path, "utf-8"));
41028
41223
  } catch {
41029
41224
  return null;
41030
41225
  }
@@ -41175,7 +41370,7 @@ ${segs.join(" \xB7 ")}`;
41175
41370
  }
41176
41371
  function writeStatusFile(sessionPath, manifest, status, opts) {
41177
41372
  try {
41178
- writeFileSync10(join28(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
41373
+ writeFileSync11(join29(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
41179
41374
  `, "utf-8");
41180
41375
  } catch {}
41181
41376
  }
@@ -41186,13 +41381,13 @@ var init_team_stats = () => {};
41186
41381
  import { spawn as spawn2 } from "child_process";
41187
41382
  import {
41188
41383
  createWriteStream,
41189
- existsSync as existsSync20,
41190
- mkdirSync as mkdirSync11,
41191
- readFileSync as readFileSync19,
41384
+ existsSync as existsSync21,
41385
+ mkdirSync as mkdirSync12,
41386
+ readFileSync as readFileSync20,
41192
41387
  readdirSync as readdirSync5,
41193
- writeFileSync as writeFileSync11
41388
+ writeFileSync as writeFileSync12
41194
41389
  } from "fs";
41195
- import { basename as basename2, join as join29, resolve as resolve3 } from "path";
41390
+ import { basename as basename2, join as join30, resolve as resolve3 } from "path";
41196
41391
  function resolveCaptureMode(explicit, env = process.env) {
41197
41392
  if (explicit)
41198
41393
  return explicit;
@@ -41340,7 +41535,7 @@ function persistErrorLog(errorLogPath, header, stderr, stdoutTail) {
41340
41535
  parts.push("--- stderr ---", stderr.trim() ? redactSecrets(stderr) : "(empty)", "");
41341
41536
  parts.push("--- stdout (tail) ---", stdoutTail.trim() ? redactSecrets(stdoutTail) : "(empty)", "");
41342
41537
  try {
41343
- writeFileSync11(errorLogPath, parts.join(`
41538
+ writeFileSync12(errorLogPath, parts.join(`
41344
41539
  `), "utf-8");
41345
41540
  } catch {}
41346
41541
  }
@@ -41358,10 +41553,10 @@ function readTeamInputFile(inputPath) {
41358
41553
  if (!resolved.startsWith(`${cwd}/`) && resolved !== cwd) {
41359
41554
  throw new Error(`Input file must be within current directory: ${inputPath}`);
41360
41555
  }
41361
- if (!existsSync20(resolved)) {
41556
+ if (!existsSync21(resolved)) {
41362
41557
  throw new Error(`Input file not found: ${resolved}`);
41363
41558
  }
41364
- const text = readFileSync19(resolved, "utf-8");
41559
+ const text = readFileSync20(resolved, "utf-8");
41365
41560
  if (text.trim().length === 0) {
41366
41561
  throw new Error(`Input file is empty: ${resolved}`);
41367
41562
  }
@@ -41371,14 +41566,14 @@ function setupSession(sessionPath, models, input) {
41371
41566
  if (models.length === 0) {
41372
41567
  throw new Error("At least one model is required");
41373
41568
  }
41374
- if (existsSync20(join29(sessionPath, "manifest.json"))) {
41569
+ if (existsSync21(join30(sessionPath, "manifest.json"))) {
41375
41570
  throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
41376
41571
  }
41377
- mkdirSync11(join29(sessionPath, "work"), { recursive: true });
41378
- mkdirSync11(join29(sessionPath, "errors"), { recursive: true });
41572
+ mkdirSync12(join30(sessionPath, "work"), { recursive: true });
41573
+ mkdirSync12(join30(sessionPath, "errors"), { recursive: true });
41379
41574
  if (input !== undefined) {
41380
- writeFileSync11(join29(sessionPath, "input.md"), input, "utf-8");
41381
- } else if (!existsSync20(join29(sessionPath, "input.md"))) {
41575
+ writeFileSync12(join30(sessionPath, "input.md"), input, "utf-8");
41576
+ } else if (!existsSync21(join30(sessionPath, "input.md"))) {
41382
41577
  throw new Error(`No input.md found at ${sessionPath} and no input provided`);
41383
41578
  }
41384
41579
  const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
@@ -41395,9 +41590,9 @@ function setupSession(sessionPath, models, input) {
41395
41590
  model: models[i],
41396
41591
  assignedAt: now
41397
41592
  };
41398
- mkdirSync11(join29(sessionPath, "work", anonId), { recursive: true });
41593
+ mkdirSync12(join30(sessionPath, "work", anonId), { recursive: true });
41399
41594
  }
41400
- writeFileSync11(join29(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
41595
+ writeFileSync12(join30(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
41401
41596
  const status = {
41402
41597
  startedAt: now,
41403
41598
  models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
@@ -41411,7 +41606,7 @@ function setupSession(sessionPath, models, input) {
41411
41606
  }
41412
41607
  ]))
41413
41608
  };
41414
- writeFileSync11(join29(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
41609
+ writeFileSync12(join30(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
41415
41610
  return manifest;
41416
41611
  }
41417
41612
  function assertValidRequirePattern(pattern) {
@@ -41428,22 +41623,22 @@ function readFullOutputIfNeeded(opts) {
41428
41623
  if (crashed || !requirePattern || outputSize <= STDOUT_TAIL_LIMIT)
41429
41624
  return;
41430
41625
  try {
41431
- return readFileSync19(outputPath, "utf-8");
41626
+ return readFileSync20(outputPath, "utf-8");
41432
41627
  } catch {
41433
41628
  return;
41434
41629
  }
41435
41630
  }
41436
41631
  async function startModels(sessionPath, opts = {}) {
41437
41632
  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");
41633
+ const manifest = JSON.parse(readFileSync20(join30(sessionPath, "manifest.json"), "utf-8"));
41634
+ const statusPath = join30(sessionPath, "status.json");
41635
+ const inputPath = join30(sessionPath, "input.md");
41636
+ const inputContent = readFileSync20(inputPath, "utf-8");
41442
41637
  const spawnPlan = await (opts.spawnPlanner ?? prehydrateCredentialsForSpawn)(Object.values(manifest.models).map((m) => m.model));
41443
- const statusCache = JSON.parse(readFileSync19(statusPath, "utf-8"));
41638
+ const statusCache = JSON.parse(readFileSync20(statusPath, "utf-8"));
41444
41639
  function updateModelStatus(id, update) {
41445
41640
  statusCache.models[id] = { ...statusCache.models[id], ...update };
41446
- writeFileSync11(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
41641
+ writeFileSync12(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
41447
41642
  }
41448
41643
  const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
41449
41644
  const requirePattern = opts.requirePattern;
@@ -41476,7 +41671,7 @@ async function startModels(sessionPath, opts = {}) {
41476
41671
  persistErrorLog(rt.errorLogPath, `RECOVERED: ${note}`, stderr, stdoutTail);
41477
41672
  opts.onStatusChange?.(id, statusCache.models[id]);
41478
41673
  }
41479
- mkdirSync11(statsDir(sessionPath), { recursive: true });
41674
+ mkdirSync12(statsDir(sessionPath), { recursive: true });
41480
41675
  const processes = new Map;
41481
41676
  const runtimes = new Map;
41482
41677
  const cancelledSlots = new Set;
@@ -41489,9 +41684,9 @@ async function startModels(sessionPath, opts = {}) {
41489
41684
  process.on("SIGINT", sigintHandler);
41490
41685
  const completionPromises = [];
41491
41686
  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`);
41687
+ const outputPath = join30(sessionPath, `response-${anonId}.md`);
41688
+ const errorLogPath = join30(sessionPath, "errors", `${anonId}.log`);
41689
+ const upstreamErrorLogPath = join30(sessionPath, "errors", `${anonId}-upstream.jsonl`);
41495
41690
  const spawnModel = spawnPlan.pinned.get(entry.model) ?? entry.model;
41496
41691
  const args = [
41497
41692
  "--model",
@@ -41645,7 +41840,7 @@ async function startModels(sessionPath, opts = {}) {
41645
41840
  stderrSnippet: stderr ? redactSecrets(stderr).slice(-2000) : undefined,
41646
41841
  stdoutSnippet: stdoutTail ? snippetHeadAndTail(redactSecrets(stdoutTail)) : undefined,
41647
41842
  errorLogPath,
41648
- upstreamErrorLogPath: existsSync20(upstreamErrorLogPath) ? upstreamErrorLogPath : undefined,
41843
+ upstreamErrorLogPath: existsSync21(upstreamErrorLogPath) ? upstreamErrorLogPath : undefined,
41649
41844
  workDir: sessionPath
41650
41845
  }
41651
41846
  });
@@ -41666,7 +41861,7 @@ async function startModels(sessionPath, opts = {}) {
41666
41861
  proc.on("exit", (code) => {
41667
41862
  const timedOut = statusCache.models[anonId]?.state === "TIMEOUT";
41668
41863
  if (!timedOut && meaningfulStderr(stderr)) {
41669
- writeFileSync11(errorLogPath, redactSecrets(stderr), "utf-8");
41864
+ writeFileSync12(errorLogPath, redactSecrets(stderr), "utf-8");
41670
41865
  }
41671
41866
  exitCode = code;
41672
41867
  if (outputStream.destroyed) {
@@ -41748,23 +41943,23 @@ async function judgeResponses(sessionPath, opts = {}) {
41748
41943
  const responses = {};
41749
41944
  for (const file of responseFiles) {
41750
41945
  const id = file.replace(/^response-/, "").replace(/\.md$/, "");
41751
- responses[id] = readFileSync19(join29(sessionPath, file), "utf-8");
41946
+ responses[id] = readFileSync20(join30(sessionPath, file), "utf-8");
41752
41947
  }
41753
- const input = readFileSync19(join29(sessionPath, "input.md"), "utf-8");
41948
+ const input = readFileSync20(join30(sessionPath, "input.md"), "utf-8");
41754
41949
  const judgePrompt = buildJudgePrompt(input, responses);
41755
- writeFileSync11(join29(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
41950
+ writeFileSync12(join30(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
41756
41951
  const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
41757
- const judgePath = join29(sessionPath, "judging");
41758
- mkdirSync11(judgePath, { recursive: true });
41952
+ const judgePath = join30(sessionPath, "judging");
41953
+ mkdirSync12(judgePath, { recursive: true });
41759
41954
  setupSession(judgePath, judgeModels, judgePrompt);
41760
41955
  await runModels(judgePath, { claudeFlags: opts.claudeFlags });
41761
41956
  const votes = parseJudgeVotes(judgePath, Object.keys(responses));
41762
41957
  const verdict = aggregateVerdict(votes, Object.keys(responses));
41763
- writeFileSync11(join29(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
41958
+ writeFileSync12(join30(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
41764
41959
  return verdict;
41765
41960
  }
41766
41961
  function getStatus(sessionPath) {
41767
- return JSON.parse(readFileSync19(join29(sessionPath, "status.json"), "utf-8"));
41962
+ return JSON.parse(readFileSync20(join30(sessionPath, "status.json"), "utf-8"));
41768
41963
  }
41769
41964
  function fisherYatesShuffle(arr) {
41770
41965
  for (let i = arr.length - 1;i > 0; i--) {
@@ -41774,7 +41969,7 @@ function fisherYatesShuffle(arr) {
41774
41969
  return arr;
41775
41970
  }
41776
41971
  function getDefaultJudgeModels(sessionPath) {
41777
- const manifest = JSON.parse(readFileSync19(join29(sessionPath, "manifest.json"), "utf-8"));
41972
+ const manifest = JSON.parse(readFileSync20(join30(sessionPath, "manifest.json"), "utf-8"));
41778
41973
  return Object.values(manifest.models).map((e) => e.model);
41779
41974
  }
41780
41975
  function buildJudgePrompt(input, responses) {
@@ -41837,7 +42032,7 @@ function parseJudgeVotes(judgePath, responseIds) {
41837
42032
  const judgeId = file.replace(/^response-/, "").replace(/\.md$/, "");
41838
42033
  let content;
41839
42034
  try {
41840
- content = readFileSync19(join29(judgePath, file), "utf-8");
42035
+ content = readFileSync20(join30(judgePath, file), "utf-8");
41841
42036
  } catch {
41842
42037
  continue;
41843
42038
  }
@@ -41889,7 +42084,7 @@ function aggregateVerdict(votes, responseIds) {
41889
42084
  function formatVerdict(verdict, sessionPath) {
41890
42085
  let manifest = null;
41891
42086
  try {
41892
- manifest = JSON.parse(readFileSync19(join29(sessionPath, "manifest.json"), "utf-8"));
42087
+ manifest = JSON.parse(readFileSync20(join30(sessionPath, "manifest.json"), "utf-8"));
41893
42088
  } catch {}
41894
42089
  let output = `# Team Verdict
41895
42090
 
@@ -41943,15 +42138,15 @@ import {
41943
42138
  appendFileSync as appendFileSync6,
41944
42139
  closeSync as closeSync7,
41945
42140
  createWriteStream as createWriteStream2,
41946
- mkdirSync as mkdirSync12,
42141
+ mkdirSync as mkdirSync13,
41947
42142
  openSync as openSync7,
41948
- readFileSync as readFileSync20,
42143
+ readFileSync as readFileSync21,
41949
42144
  readSync as readSync3,
41950
42145
  statSync as statSync6,
41951
- writeFileSync as writeFileSync12
42146
+ writeFileSync as writeFileSync13
41952
42147
  } from "fs";
41953
- import { homedir as homedir28 } from "os";
41954
- import { join as join30, resolve as resolve4, sep } from "path";
42148
+ import { homedir as homedir29 } from "os";
42149
+ import { join as join31, resolve as resolve4, sep } from "path";
41955
42150
  import { StringDecoder as StringDecoder2 } from "string_decoder";
41956
42151
  function buildChannelSpawnArgs(opts) {
41957
42152
  return [
@@ -42026,7 +42221,7 @@ function readJsonObject(path, maxBytes) {
42026
42221
  try {
42027
42222
  if (fileSize(path) > maxBytes)
42028
42223
  return null;
42029
- const parsed = JSON.parse(readFileSync20(path, "utf-8"));
42224
+ const parsed = JSON.parse(readFileSync21(path, "utf-8"));
42030
42225
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
42031
42226
  return null;
42032
42227
  return parsed;
@@ -42042,7 +42237,7 @@ function dropLeadingFragment(tail) {
42042
42237
  return firstBreak === -1 ? tail.text : tail.text.slice(firstBreak + 1);
42043
42238
  }
42044
42239
  function diskAccounting(sessionDir) {
42045
- const stats = readTokenStatsAt(join30(sessionDir, "tokens.json"));
42240
+ const stats = readTokenStatsAt(join31(sessionDir, "tokens.json"));
42046
42241
  return {
42047
42242
  tokensUsed: (stats?.total_tokens ?? 0) || (stats?.input_tokens ?? 0) + (stats?.output_tokens ?? 0),
42048
42243
  costUsd: stats?.total_cost ?? 0,
@@ -42082,7 +42277,7 @@ class SessionManager {
42082
42277
  this.maxSessions = options?.maxSessions ?? DEFAULT_MAX_SESSIONS;
42083
42278
  this.scrollbackCapacity = options?.scrollbackCapacity ?? DEFAULT_SCROLLBACK;
42084
42279
  this.terminalRetentionMs = options?.terminalRetentionMs ?? TERMINAL_RETENTION_MS;
42085
- this.sessionsDir = options?.sessionsDir ?? process.env.CLAUDISH_SESSIONS_DIR ?? join30(homedir28(), ".claudish", "sessions");
42280
+ this.sessionsDir = options?.sessionsDir ?? process.env.CLAUDISH_SESSIONS_DIR ?? join31(homedir29(), ".claudish", "sessions");
42086
42281
  this.stallSeconds = options?.stallSeconds;
42087
42282
  this.onStateChange = options?.onStateChange;
42088
42283
  }
@@ -42098,19 +42293,19 @@ class SessionManager {
42098
42293
  const claudeSessionId = randomUUID4();
42099
42294
  const timeout = Math.min(opts.timeoutSeconds ?? DEFAULT_TIMEOUT, MAX_TIMEOUT);
42100
42295
  const startedAt = new Date().toISOString();
42101
- const sessionDir = opts.sessionDir ?? join30(this.sessionsDir, sessionId);
42102
- mkdirSync12(sessionDir, { recursive: true });
42296
+ const sessionDir = opts.sessionDir ?? join31(this.sessionsDir, sessionId);
42297
+ mkdirSync13(sessionDir, { recursive: true });
42103
42298
  if (opts.prompt) {
42104
- writeFileSync12(join30(sessionDir, "prompt.md"), opts.prompt, "utf-8");
42299
+ writeFileSync13(join31(sessionDir, "prompt.md"), opts.prompt, "utf-8");
42105
42300
  }
42106
42301
  const args = buildChannelSpawnArgs({
42107
42302
  model: opts.spawnModel ?? opts.model,
42108
42303
  claudeSessionId,
42109
42304
  claudishFlags: opts.claudishFlags
42110
42305
  });
42111
- const tokenFile = opts.tokenFile ?? join30(sessionDir, "tokens.json");
42112
- const eventLogPath = join30(sessionDir, "events.jsonl");
42113
- const upstreamErrorLogPath = join30(sessionDir, "upstream-errors.jsonl");
42306
+ const tokenFile = opts.tokenFile ?? join31(sessionDir, "tokens.json");
42307
+ const eventLogPath = join31(sessionDir, "events.jsonl");
42308
+ const upstreamErrorLogPath = join31(sessionDir, "upstream-errors.jsonl");
42114
42309
  const cwd = opts.cwd ?? process.cwd();
42115
42310
  const spawnTarget = resolveClaudishSpawn();
42116
42311
  const proc = spawn3(spawnTarget.command, [...spawnTarget.prefixArgs, ...args], {
@@ -42125,7 +42320,7 @@ class SessionManager {
42125
42320
  }
42126
42321
  });
42127
42322
  const scrollback = new ScrollbackBuffer(this.scrollbackCapacity);
42128
- const outputLogStream = createWriteStream2(join30(sessionDir, "output.log"));
42323
+ const outputLogStream = createWriteStream2(join31(sessionDir, "output.log"));
42129
42324
  const entry = {
42130
42325
  info: {
42131
42326
  sessionId,
@@ -42417,7 +42612,7 @@ class SessionManager {
42417
42612
  return null;
42418
42613
  const root = resolve4(this.sessionsDir);
42419
42614
  const dir = resolve4(root, sessionId);
42420
- if (dir !== join30(root, sessionId))
42615
+ if (dir !== join31(root, sessionId))
42421
42616
  return null;
42422
42617
  if (!dir.startsWith(root + sep))
42423
42618
  return null;
@@ -42436,7 +42631,7 @@ class SessionManager {
42436
42631
  } catch {
42437
42632
  return null;
42438
42633
  }
42439
- const meta = readJsonObject(join30(sessionDir, "meta.json"), META_READ_LIMIT);
42634
+ const meta = readJsonObject(join31(sessionDir, "meta.json"), META_READ_LIMIT);
42440
42635
  const partial = meta === null;
42441
42636
  const measured = diskAccounting(sessionDir);
42442
42637
  const startedAt = metaString(meta?.startedAt) ?? new Date(dirMtimeMs).toISOString();
@@ -42466,7 +42661,7 @@ class SessionManager {
42466
42661
  };
42467
42662
  }
42468
42663
  diskOutput(record, tailLines) {
42469
- const tail = readTailText(join30(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
42664
+ const tail = readTailText(join31(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
42470
42665
  const buffer = new ScrollbackBuffer(this.scrollbackCapacity);
42471
42666
  if (tail?.text)
42472
42667
  buffer.append(dropLeadingFragment(tail));
@@ -42485,9 +42680,9 @@ class SessionManager {
42485
42680
  }
42486
42681
  diskDiagnostics(record, limit) {
42487
42682
  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");
42683
+ const eventLogPath = join31(sessionDir, "events.jsonl");
42684
+ const upstreamErrorLogPath = join31(sessionDir, "upstream-errors.jsonl");
42685
+ const outputLogPath = join31(sessionDir, "output.log");
42491
42686
  const events = readTailLines(eventLogPath, EVENT_TAIL_BYTES);
42492
42687
  const outputTail = readTailText(outputLogPath, OUTPUT_TAIL_BYTES);
42493
42688
  return {
@@ -42529,7 +42724,7 @@ class SessionManager {
42529
42724
  };
42530
42725
  }
42531
42726
  diskStderrForDiagnostics(record) {
42532
- const tail = readTailText(join30(record.sessionDir, "stderr.log"), STDERR_READ_BYTES);
42727
+ const tail = readTailText(join31(record.sessionDir, "stderr.log"), STDERR_READ_BYTES);
42533
42728
  const raw = tail?.text ?? "";
42534
42729
  const filtered = record.info.status === "completed";
42535
42730
  const source = filtered ? meaningfulStderr(raw) : raw;
@@ -42705,11 +42900,11 @@ ${STDERR_TRUNCATION_MARKER} ${STDERR_SIDE_LIMIT} bytes per end \u2026
42705
42900
  entry.outputLogStream?.end();
42706
42901
  entry.outputLogStream = null;
42707
42902
  if (entry.stderr) {
42708
- writeFileSync12(join30(entry.sessionDir, "stderr.log"), redactSecrets(entry.stderr), "utf-8");
42903
+ writeFileSync13(join31(entry.sessionDir, "stderr.log"), redactSecrets(entry.stderr), "utf-8");
42709
42904
  }
42710
42905
  this.refreshAccounting(entry);
42711
42906
  entry.info.claudeSessionId = entry.reducer.claudeSessionId ?? entry.info.claudeSessionId;
42712
- writeFileSync12(join30(entry.sessionDir, "meta.json"), JSON.stringify(entry.info, null, 2), "utf-8");
42907
+ writeFileSync13(join31(entry.sessionDir, "meta.json"), JSON.stringify(entry.info, null, 2), "utf-8");
42713
42908
  }
42714
42909
  scheduleEviction(entry) {
42715
42910
  if (entry.evictHandle)
@@ -42769,7 +42964,7 @@ ${STDERR_TRUNCATION_MARKER} ${STDERR_SIDE_LIMIT} bytes per end \u2026
42769
42964
  return { state: "completed", content: "" };
42770
42965
  }
42771
42966
  refreshAccounting(entry) {
42772
- const stats = readTokenStatsAt(join30(entry.sessionDir, "tokens.json"));
42967
+ const stats = readTokenStatsAt(join31(entry.sessionDir, "tokens.json"));
42773
42968
  const fileTokens = (stats?.total_tokens ?? 0) || (stats?.input_tokens ?? 0) + (stats?.output_tokens ?? 0);
42774
42969
  entry.info.tokensUsed = fileTokens || entry.reducer.tokens;
42775
42970
  entry.info.costUsd = stats?.total_cost ?? 0;
@@ -42967,9 +43162,9 @@ var init_cache_ttl = __esm(() => {
42967
43162
  });
42968
43163
 
42969
43164
  // 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";
43165
+ import { existsSync as existsSync22, mkdirSync as mkdirSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "fs";
43166
+ import { homedir as homedir30 } from "os";
43167
+ import { join as join32 } from "path";
42973
43168
  function groupRecommendedModels(entries) {
42974
43169
  const byId = new Map;
42975
43170
  const categoryOrder = new Map;
@@ -43097,9 +43292,9 @@ async function getRecommendedModels(opts = {}) {
43097
43292
  if (!forceRefresh && _cachedRecommendedModels) {
43098
43293
  return _cachedRecommendedModels;
43099
43294
  }
43100
- if (!forceRefresh && existsSync21(RECOMMENDED_MODELS_CACHE_PATH)) {
43295
+ if (!forceRefresh && existsSync22(RECOMMENDED_MODELS_CACHE_PATH)) {
43101
43296
  try {
43102
- const cacheData = JSON.parse(readFileSync21(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43297
+ const cacheData = JSON.parse(readFileSync22(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43103
43298
  if (cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
43104
43299
  _cachedRecommendedModels = cacheData;
43105
43300
  return cacheData;
@@ -43115,9 +43310,9 @@ async function getRecommendedModels(opts = {}) {
43115
43310
  if (data.models && data.models.length > 0) {
43116
43311
  _cachedRecommendedModels = data;
43117
43312
  try {
43118
- const cacheDir = join31(homedir29(), ".claudish");
43119
- mkdirSync13(cacheDir, { recursive: true });
43120
- writeFileSync13(RECOMMENDED_MODELS_CACHE_PATH, JSON.stringify(data), "utf-8");
43313
+ const cacheDir = join32(homedir30(), ".claudish");
43314
+ mkdirSync14(cacheDir, { recursive: true });
43315
+ writeFileSync14(RECOMMENDED_MODELS_CACHE_PATH, JSON.stringify(data), "utf-8");
43121
43316
  } catch {}
43122
43317
  return data;
43123
43318
  }
@@ -43128,9 +43323,9 @@ async function getRecommendedModels(opts = {}) {
43128
43323
  function getRecommendedModelsSync() {
43129
43324
  if (_cachedRecommendedModels)
43130
43325
  return _cachedRecommendedModels;
43131
- if (existsSync21(RECOMMENDED_MODELS_CACHE_PATH)) {
43326
+ if (existsSync22(RECOMMENDED_MODELS_CACHE_PATH)) {
43132
43327
  try {
43133
- const cacheData = JSON.parse(readFileSync21(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43328
+ const cacheData = JSON.parse(readFileSync22(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
43134
43329
  if (cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
43135
43330
  _cachedRecommendedModels = cacheData;
43136
43331
  return cacheData;
@@ -43254,7 +43449,7 @@ var _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels =
43254
43449
  var init_model_loader = __esm(() => {
43255
43450
  init_cache_ttl();
43256
43451
  FIREBASE_RECOMMENDED_URL = `${FIREBASE_BASE_URL}?catalog=recommended`;
43257
- RECOMMENDED_MODELS_CACHE_PATH = join31(homedir29(), ".claudish", "recommended-models-cache.json");
43452
+ RECOMMENDED_MODELS_CACHE_PATH = join32(homedir30(), ".claudish", "recommended-models-cache.json");
43258
43453
  FIREBASE_SLUG_TO_PROVIDER_NAME = {
43259
43454
  openai: "openai",
43260
43455
  google: "google",
@@ -48264,9 +48459,9 @@ var init_poe = __esm(() => {
48264
48459
  });
48265
48460
 
48266
48461
  // 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";
48462
+ import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync7 } from "fs";
48463
+ import { homedir as homedir31 } from "os";
48464
+ import { join as join33 } from "path";
48270
48465
  function prefixMatch(modelName) {
48271
48466
  for (const [key, pricing] of pricingMap) {
48272
48467
  if (modelName.startsWith(key))
@@ -48304,12 +48499,12 @@ async function warmPricingCache() {
48304
48499
  }
48305
48500
  function loadDiskCache() {
48306
48501
  try {
48307
- if (!existsSync22(CACHE_FILE))
48502
+ if (!existsSync23(CACHE_FILE))
48308
48503
  return false;
48309
48504
  const stat = statSync7(CACHE_FILE);
48310
48505
  const age = Date.now() - stat.mtimeMs;
48311
48506
  const isFresh = age < CACHE_TTL_MS3;
48312
- const raw = readFileSync22(CACHE_FILE, "utf-8");
48507
+ const raw = readFileSync23(CACHE_FILE, "utf-8");
48313
48508
  const data = JSON.parse(raw);
48314
48509
  for (const [key, pricing] of Object.entries(data)) {
48315
48510
  pricingMap.set(key, pricing);
@@ -48325,21 +48520,24 @@ var init_pricing_cache = __esm(() => {
48325
48520
  init_logger();
48326
48521
  init_catalog_query();
48327
48522
  pricingMap = new Map;
48328
- CACHE_DIR = join32(homedir30(), ".claudish");
48329
- CACHE_FILE = join32(CACHE_DIR, "pricing-cache.json");
48523
+ CACHE_DIR = join33(homedir31(), ".claudish");
48524
+ CACHE_FILE = join33(CACHE_DIR, "pricing-cache.json");
48330
48525
  CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
48331
48526
  });
48332
48527
 
48333
48528
  // src/proxy-server.ts
48334
- import { appendFileSync as appendFileSync8, mkdirSync as mkdirSync14 } from "fs";
48335
- import { join as join33 } from "path";
48529
+ import { appendFileSync as appendFileSync8, mkdirSync as mkdirSync15 } from "fs";
48530
+ import { join as join34 } from "path";
48531
+ function isTerminalRoutingFailure(e) {
48532
+ return e instanceof RoutingError || e instanceof CatalogIncompatibleError;
48533
+ }
48336
48534
  function maybeCaptureClassifierRequest(c, body) {
48337
48535
  if (!process.env.CLAUDISH_CLASSIFIER_DEBUG)
48338
48536
  return;
48339
48537
  try {
48340
- const dir = join33(process.cwd(), "logs");
48538
+ const dir = join34(process.cwd(), "logs");
48341
48539
  if (!classifierCaptureDirReady) {
48342
- mkdirSync14(dir, { recursive: true });
48540
+ mkdirSync15(dir, { recursive: true });
48343
48541
  classifierCaptureDirReady = true;
48344
48542
  }
48345
48543
  const record = {
@@ -48362,7 +48560,7 @@ function maybeCaptureClassifierRequest(c, body) {
48362
48560
  "x-api-key": c.req.header("x-api-key") ? "<present>" : null
48363
48561
  }
48364
48562
  };
48365
- appendFileSync8(join33(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
48563
+ appendFileSync8(join34(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
48366
48564
  `);
48367
48565
  } catch {}
48368
48566
  }
@@ -48784,7 +48982,7 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
48784
48982
  const txt = JSON.stringify(body);
48785
48983
  return c.json({ input_tokens: Math.ceil(txt.length / 4) });
48786
48984
  } catch (e) {
48787
- if (e instanceof RoutingError) {
48985
+ if (isTerminalRoutingFailure(e)) {
48788
48986
  return c.json(wrapAnthropicError(400, e.message, "invalid_request_error"), 400);
48789
48987
  }
48790
48988
  return c.json(wrapAnthropicError(500, String(e)), 500);
@@ -48804,7 +49002,7 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
48804
49002
  return await handler.handle(c, body);
48805
49003
  } catch (e) {
48806
49004
  log(`[Proxy] Error: ${e}`);
48807
- if (e instanceof RoutingError) {
49005
+ if (isTerminalRoutingFailure(e)) {
48808
49006
  return c.json(wrapAnthropicError(400, e.message, "invalid_request_error"), 400);
48809
49007
  }
48810
49008
  return c.json(wrapAnthropicError(500, String(e)), 500);
@@ -48867,6 +49065,7 @@ var init_proxy_server = __esm(() => {
48867
49065
  init_profile_config();
48868
49066
  init_auto_route();
48869
49067
  init_catalog_client();
49068
+ init_catalog_compatibility();
48870
49069
  init_endpoint_diagnostics();
48871
49070
  init_endpoint_registration();
48872
49071
  init_model_parser();
@@ -48889,14 +49088,14 @@ var init_proxy_server = __esm(() => {
48889
49088
  });
48890
49089
 
48891
49090
  // 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";
49091
+ import { existsSync as existsSync24, mkdirSync as mkdirSync16, readFileSync as readFileSync24, readdirSync as readdirSync6, writeFileSync as writeFileSync15 } from "fs";
49092
+ import { homedir as homedir32 } from "os";
49093
+ import { dirname as dirname10, join as join35, resolve as resolve5 } from "path";
48895
49094
  import { fileURLToPath } from "url";
48896
49095
  async function loadAllModels(forceRefresh = false) {
48897
- if (!forceRefresh && existsSync23(ALL_MODELS_CACHE_PATH2)) {
49096
+ if (!forceRefresh && existsSync24(ALL_MODELS_CACHE_PATH2)) {
48898
49097
  try {
48899
- const cacheData = JSON.parse(readFileSync23(ALL_MODELS_CACHE_PATH2, "utf-8"));
49098
+ const cacheData = JSON.parse(readFileSync24(ALL_MODELS_CACHE_PATH2, "utf-8"));
48900
49099
  const lastUpdated = new Date(cacheData.lastUpdated);
48901
49100
  const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
48902
49101
  if (ageInDays <= CACHE_MAX_AGE_DAYS) {
@@ -48910,12 +49109,12 @@ async function loadAllModels(forceRefresh = false) {
48910
49109
  throw new Error(`API returned ${response.status}`);
48911
49110
  const data = await response.json();
48912
49111
  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");
49112
+ mkdirSync16(CLAUDISH_CACHE_DIR, { recursive: true });
49113
+ writeFileSync15(ALL_MODELS_CACHE_PATH2, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
48915
49114
  return models;
48916
49115
  } catch {
48917
- if (existsSync23(ALL_MODELS_CACHE_PATH2)) {
48918
- const cacheData = JSON.parse(readFileSync23(ALL_MODELS_CACHE_PATH2, "utf-8"));
49116
+ if (existsSync24(ALL_MODELS_CACHE_PATH2)) {
49117
+ const cacheData = JSON.parse(readFileSync24(ALL_MODELS_CACHE_PATH2, "utf-8"));
48919
49118
  return cacheData.models || [];
48920
49119
  }
48921
49120
  return [];
@@ -49778,7 +49977,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49778
49977
  let stderrFull = stderr_snippet || "";
49779
49978
  if (error_log_path) {
49780
49979
  try {
49781
- stderrFull = readFileSync23(error_log_path, "utf-8");
49980
+ stderrFull = readFileSync24(error_log_path, "utf-8");
49782
49981
  } catch {}
49783
49982
  }
49784
49983
  const sessionData = {};
@@ -49786,16 +49985,16 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49786
49985
  const sp = session_path;
49787
49986
  for (const file of ["status.json", "manifest.json", "input.md"]) {
49788
49987
  try {
49789
- sessionData[file] = readFileSync23(join34(sp, file), "utf-8");
49988
+ sessionData[file] = readFileSync24(join35(sp, file), "utf-8");
49790
49989
  } catch {}
49791
49990
  }
49792
49991
  try {
49793
- const errorDir = join34(sp, "errors");
49794
- if (existsSync23(errorDir)) {
49992
+ const errorDir = join35(sp, "errors");
49993
+ if (existsSync24(errorDir)) {
49795
49994
  for (const f of readdirSync6(errorDir)) {
49796
49995
  if (f.endsWith(".log")) {
49797
49996
  try {
49798
- sessionData[`errors/${f}`] = readFileSync23(join34(errorDir, f), "utf-8");
49997
+ sessionData[`errors/${f}`] = readFileSync24(join35(errorDir, f), "utf-8");
49799
49998
  } catch {}
49800
49999
  }
49801
50000
  }
@@ -49805,7 +50004,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49805
50004
  for (const f of readdirSync6(sp)) {
49806
50005
  if (f.startsWith("response-") && f.endsWith(".md")) {
49807
50006
  try {
49808
- const content = readFileSync23(join34(sp, f), "utf-8");
50007
+ const content = readFileSync24(join35(sp, f), "utf-8");
49809
50008
  sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
49810
50009
  } catch {}
49811
50010
  }
@@ -49814,9 +50013,9 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
49814
50013
  }
49815
50014
  let version = "unknown";
49816
50015
  try {
49817
- const pkgPath = join34(__dirname2, "../package.json");
49818
- if (existsSync23(pkgPath)) {
49819
- version = JSON.parse(readFileSync23(pkgPath, "utf-8")).version;
50016
+ const pkgPath = join35(__dirname2, "../package.json");
50017
+ if (existsSync24(pkgPath)) {
50018
+ version = JSON.parse(readFileSync24(pkgPath, "utf-8")).version;
49820
50019
  }
49821
50020
  } catch {}
49822
50021
  const report = {
@@ -50283,9 +50482,9 @@ var init_mcp_server = __esm(() => {
50283
50482
  import_dotenv2 = __toESM(require_main(), 1);
50284
50483
  import_dotenv2.config({ quiet: true });
50285
50484
  __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");
50485
+ __dirname2 = dirname10(__filename2);
50486
+ CLAUDISH_CACHE_DIR = join35(homedir32(), ".claudish");
50487
+ ALL_MODELS_CACHE_PATH2 = join35(CLAUDISH_CACHE_DIR, "all-models.json");
50289
50488
  NEXT_STEP = {
50290
50489
  nonzero_exit: "read the evidence log, then retry or drop the model",
50291
50490
  cancelled: "you stopped this slot; nothing is wrong with it. Re-run it if you still want its vote",
@@ -50309,7 +50508,7 @@ var init_mcp_server = __esm(() => {
50309
50508
  });
50310
50509
 
50311
50510
  // src/serve-command.ts
50312
- import { existsSync as existsSync24, readFileSync as readFileSync24 } from "fs";
50511
+ import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
50313
50512
  function parseServeArgs(args) {
50314
50513
  const out = {};
50315
50514
  for (let i = 0;i < args.length; i++) {
@@ -50328,12 +50527,12 @@ function parseServeArgs(args) {
50328
50527
  return out;
50329
50528
  }
50330
50529
  function loadModelMap(path) {
50331
- if (!existsSync24(path)) {
50530
+ if (!existsSync25(path)) {
50332
50531
  throw new Error(`--models file not found: ${path}`);
50333
50532
  }
50334
50533
  let raw;
50335
50534
  try {
50336
- raw = readFileSync24(path, "utf-8");
50535
+ raw = readFileSync25(path, "utf-8");
50337
50536
  } catch (e) {
50338
50537
  throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
50339
50538
  }
@@ -50613,7 +50812,7 @@ var init_ansi = __esm(() => {
50613
50812
  });
50614
50813
 
50615
50814
  // src/behavior-command.ts
50616
- import { existsSync as existsSync25, readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "fs";
50815
+ import { existsSync as existsSync26, readFileSync as readFileSync26, writeFileSync as writeFileSync16 } from "fs";
50617
50816
  function severityColor(sev) {
50618
50817
  if (sev === "fix")
50619
50818
  return green(sev);
@@ -50711,8 +50910,8 @@ function setTelemetryEnabled(value) {
50711
50910
  const path = getConfigPath();
50712
50911
  let cfg = {};
50713
50912
  try {
50714
- if (existsSync25(path)) {
50715
- const parsed = JSON.parse(readFileSync25(path, "utf-8"));
50913
+ if (existsSync26(path)) {
50914
+ const parsed = JSON.parse(readFileSync26(path, "utf-8"));
50716
50915
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
50717
50916
  cfg = parsed;
50718
50917
  }
@@ -50721,7 +50920,7 @@ function setTelemetryEnabled(value) {
50721
50920
  const behavior = cfg.behavior && typeof cfg.behavior === "object" && !Array.isArray(cfg.behavior) ? { ...cfg.behavior } : {};
50722
50921
  behavior.telemetry = { enabled: value };
50723
50922
  cfg.behavior = behavior;
50724
- writeFileSync15(path, `${JSON.stringify(cfg, null, 2)}
50923
+ writeFileSync16(path, `${JSON.stringify(cfg, null, 2)}
50725
50924
  `, "utf-8");
50726
50925
  }
50727
50926
  function showTelemetry(action, json) {
@@ -50733,8 +50932,8 @@ function showTelemetry(action, json) {
50733
50932
  let pending = 0;
50734
50933
  try {
50735
50934
  const path = outboxPath();
50736
- if (existsSync25(path)) {
50737
- pending = readFileSync25(path, "utf8").split(`
50935
+ if (existsSync26(path)) {
50936
+ pending = readFileSync26(path, "utf8").split(`
50738
50937
  `).filter(Boolean).length;
50739
50938
  }
50740
50939
  } catch {}
@@ -50815,9 +51014,9 @@ var init_behavior_command = __esm(() => {
50815
51014
  // src/team-grid.ts
50816
51015
  import { spawn as spawn4 } from "child_process";
50817
51016
  import { execSync } from "child_process";
50818
- import { existsSync as existsSync26, readFileSync as readFileSync26, writeFileSync as writeFileSync16 } from "fs";
51017
+ import { existsSync as existsSync27, readFileSync as readFileSync27, writeFileSync as writeFileSync17 } from "fs";
50819
51018
  import { connect as netConnect } from "net";
50820
- import { dirname as dirname10, join as join35 } from "path";
51019
+ import { dirname as dirname11, join as join36 } from "path";
50821
51020
  import { setTimeout as wait } from "timers/promises";
50822
51021
  import { fileURLToPath as fileURLToPath2 } from "url";
50823
51022
  function resolveRouteInfo(modelId) {
@@ -50910,21 +51109,21 @@ function buildPaneHeader(model, prompt, bg) {
50910
51109
  }
50911
51110
  function findMagmuxBinary() {
50912
51111
  const thisFile = fileURLToPath2(import.meta.url);
50913
- const thisDir = dirname10(thisFile);
50914
- const pkgRoot = join35(thisDir, "..");
51112
+ const thisDir = dirname11(thisFile);
51113
+ const pkgRoot = join36(thisDir, "..");
50915
51114
  const platform = process.platform;
50916
51115
  const arch = process.arch;
50917
- const bundledMagmux = join35(pkgRoot, "native", `magmux-${platform}-${arch}`);
50918
- if (existsSync26(bundledMagmux))
51116
+ const bundledMagmux = join36(pkgRoot, "native", `magmux-${platform}-${arch}`);
51117
+ if (existsSync27(bundledMagmux))
50919
51118
  return bundledMagmux;
50920
51119
  try {
50921
51120
  const pkgName = `@claudish/magmux-${platform}-${arch}`;
50922
51121
  let searchDir = pkgRoot;
50923
51122
  for (let i = 0;i < 5; i++) {
50924
- const candidate = join35(searchDir, "node_modules", pkgName, "bin", "magmux");
50925
- if (existsSync26(candidate))
51123
+ const candidate = join36(searchDir, "node_modules", pkgName, "bin", "magmux");
51124
+ if (existsSync27(candidate))
50926
51125
  return candidate;
50927
- const parent = dirname10(searchDir);
51126
+ const parent = dirname11(searchDir);
50928
51127
  if (parent === searchDir)
50929
51128
  break;
50930
51129
  searchDir = parent;
@@ -50946,7 +51145,7 @@ function withoutControlPanes(evt) {
50946
51145
  async function subscribeToMagmux(sockPath, onEvent) {
50947
51146
  let client = null;
50948
51147
  for (let attempt = 0;attempt < 40; attempt++) {
50949
- if (existsSync26(sockPath)) {
51148
+ if (existsSync27(sockPath)) {
50950
51149
  try {
50951
51150
  client = await new Promise((resolve, reject) => {
50952
51151
  const s = netConnect(sockPath);
@@ -51033,9 +51232,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
51033
51232
  const keep = opts?.keep ?? false;
51034
51233
  const manifest = setupSession(sessionPath, models, input);
51035
51234
  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");
51235
+ const gridfilePath = join36(sessionPath, "gridfile.txt");
51236
+ const prompt = readFileSync27(join36(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
51237
+ const rawPrompt = readFileSync27(join36(sessionPath, "input.md"), "utf-8");
51039
51238
  const usedBannerColors = new Set;
51040
51239
  const gridLines = Object.entries(manifest.models).map(([anonId]) => {
51041
51240
  const model = manifest.models[anonId].model;
@@ -51046,7 +51245,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
51046
51245
  const header = buildPaneHeader(model, rawPrompt, bg);
51047
51246
  return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
51048
51247
  });
51049
- writeFileSync16(gridfilePath, `${gridLines.join(`
51248
+ writeFileSync17(gridfilePath, `${gridLines.join(`
51050
51249
  `)}
51051
51250
  `, "utf-8");
51052
51251
  const magmuxPath = findMagmuxBinary();
@@ -51066,8 +51265,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
51066
51265
  });
51067
51266
  const [{ results }] = await Promise.all([subscription, procExit]);
51068
51267
  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");
51268
+ const statusPath = join36(sessionPath, "status.json");
51269
+ writeFileSync17(statusPath, JSON.stringify(status, null, 2), "utf-8");
51071
51270
  return status;
51072
51271
  }
51073
51272
  var BANNER_BG_COLORS;
@@ -51087,8 +51286,8 @@ var init_team_grid = __esm(() => {
51087
51286
  });
51088
51287
 
51089
51288
  // src/team-cli.ts
51090
- import { readFileSync as readFileSync27 } from "fs";
51091
- import { join as join36 } from "path";
51289
+ import { readFileSync as readFileSync28 } from "fs";
51290
+ import { join as join37 } from "path";
51092
51291
  function getFlag(args, flag) {
51093
51292
  const idx = args.indexOf(flag);
51094
51293
  if (idx === -1 || idx + 1 >= args.length)
@@ -51211,7 +51410,7 @@ async function teamCommand(args) {
51211
51410
  }
51212
51411
  case "judge": {
51213
51412
  await judgeResponses(sessionPath, { judges });
51214
- console.log(readFileSync27(join36(sessionPath, "verdict.md"), "utf-8"));
51413
+ console.log(readFileSync28(join37(sessionPath, "verdict.md"), "utf-8"));
51215
51414
  break;
51216
51415
  }
51217
51416
  case "run-and-judge": {
@@ -51228,7 +51427,7 @@ async function teamCommand(args) {
51228
51427
  });
51229
51428
  printStatus(status);
51230
51429
  await judgeResponses(sessionPath, { judges });
51231
- console.log(readFileSync27(join36(sessionPath, "verdict.md"), "utf-8"));
51430
+ console.log(readFileSync28(join37(sessionPath, "verdict.md"), "utf-8"));
51232
51431
  break;
51233
51432
  }
51234
51433
  case "status": {
@@ -54052,9 +54251,9 @@ var init_keychain_command = __esm(() => {
54052
54251
 
54053
54252
  // src/auth/antigravity-oauth.ts
54054
54253
  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";
54254
+ import { existsSync as existsSync28, unlinkSync as unlinkSync6 } from "fs";
54255
+ import { homedir as homedir33 } from "os";
54256
+ import { join as join38 } from "path";
54058
54257
  async function defaultSuggestModel() {
54059
54258
  try {
54060
54259
  const tok = readSharedAntigravityToken();
@@ -54175,8 +54374,8 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
54175
54374
  async logout(deps) {
54176
54375
  deleteSharedAntigravityToken(deps);
54177
54376
  try {
54178
- const tokenFile = join37(homedir32(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
54179
- if (existsSync27(tokenFile))
54377
+ const tokenFile = join38(homedir33(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
54378
+ if (existsSync28(tokenFile))
54180
54379
  unlinkSync6(tokenFile);
54181
54380
  } catch {}
54182
54381
  log("[AntigravityOAuth] Antigravity session cleared (keychain + agy token file)");
@@ -58070,33 +58269,33 @@ var init_branding = __esm(() => {
58070
58269
  });
58071
58270
 
58072
58271
  // 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";
58272
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync29, unlinkSync as unlinkSync7, writeFileSync as writeFileSync18 } from "fs";
58273
+ import { homedir as homedir34, platform as platform2, tmpdir } from "os";
58274
+ import { join as join39 } from "path";
58076
58275
  function getCacheFilePath() {
58077
58276
  let cacheDir;
58078
58277
  if (isWindows) {
58079
- const localAppData = process.env.LOCALAPPDATA || join38(homedir33(), "AppData", "Local");
58080
- cacheDir = join38(localAppData, "claudish");
58278
+ const localAppData = process.env.LOCALAPPDATA || join39(homedir34(), "AppData", "Local");
58279
+ cacheDir = join39(localAppData, "claudish");
58081
58280
  } else {
58082
- cacheDir = join38(homedir33(), ".cache", "claudish");
58281
+ cacheDir = join39(homedir34(), ".cache", "claudish");
58083
58282
  }
58084
58283
  try {
58085
- if (!existsSync28(cacheDir)) {
58086
- mkdirSync16(cacheDir, { recursive: true });
58284
+ if (!existsSync29(cacheDir)) {
58285
+ mkdirSync17(cacheDir, { recursive: true });
58087
58286
  }
58088
- return join38(cacheDir, "update-check.json");
58287
+ return join39(cacheDir, "update-check.json");
58089
58288
  } catch {
58090
- return join38(tmpdir(), "claudish-update-check.json");
58289
+ return join39(tmpdir(), "claudish-update-check.json");
58091
58290
  }
58092
58291
  }
58093
58292
  function readCache() {
58094
58293
  try {
58095
58294
  const cachePath = getCacheFilePath();
58096
- if (!existsSync28(cachePath)) {
58295
+ if (!existsSync29(cachePath)) {
58097
58296
  return null;
58098
58297
  }
58099
- const data = JSON.parse(readFileSync28(cachePath, "utf-8"));
58298
+ const data = JSON.parse(readFileSync29(cachePath, "utf-8"));
58100
58299
  return data;
58101
58300
  } catch {
58102
58301
  return null;
@@ -58109,7 +58308,7 @@ function writeCache(latestVersion) {
58109
58308
  lastCheck: Date.now(),
58110
58309
  latestVersion
58111
58310
  };
58112
- writeFileSync17(cachePath, JSON.stringify(data), "utf-8");
58311
+ writeFileSync18(cachePath, JSON.stringify(data), "utf-8");
58113
58312
  } catch {}
58114
58313
  }
58115
58314
  function isCacheValid(cache) {
@@ -58119,7 +58318,7 @@ function isCacheValid(cache) {
58119
58318
  function clearCache() {
58120
58319
  try {
58121
58320
  const cachePath = getCacheFilePath();
58122
- if (existsSync28(cachePath)) {
58321
+ if (existsSync29(cachePath)) {
58123
58322
  unlinkSync7(cachePath);
58124
58323
  }
58125
58324
  } catch {}
@@ -58204,22 +58403,22 @@ var init_update_checker = __esm(() => {
58204
58403
  // src/cli.ts
58205
58404
  import {
58206
58405
  copyFileSync as copyFileSync2,
58207
- existsSync as existsSync29,
58208
- mkdirSync as mkdirSync17,
58209
- readFileSync as readFileSync29,
58406
+ existsSync as existsSync30,
58407
+ mkdirSync as mkdirSync18,
58408
+ readFileSync as readFileSync30,
58210
58409
  readdirSync as readdirSync7,
58211
58410
  unlinkSync as unlinkSync8,
58212
- writeFileSync as writeFileSync18
58411
+ writeFileSync as writeFileSync19
58213
58412
  } from "fs";
58214
- import { homedir as homedir34 } from "os";
58215
- import { dirname as dirname11, join as join39 } from "path";
58413
+ import { homedir as homedir35 } from "os";
58414
+ import { dirname as dirname12, join as join40 } from "path";
58216
58415
  import { fileURLToPath as fileURLToPath3 } from "url";
58217
58416
  function getVersion3() {
58218
58417
  return VERSION;
58219
58418
  }
58220
58419
  function clearAllModelCaches() {
58221
- const cacheDir = join39(homedir34(), ".claudish");
58222
- if (!existsSync29(cacheDir))
58420
+ const cacheDir = join40(homedir35(), ".claudish");
58421
+ if (!existsSync30(cacheDir))
58223
58422
  return;
58224
58423
  const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
58225
58424
  let cleared = 0;
@@ -58227,7 +58426,7 @@ function clearAllModelCaches() {
58227
58426
  const files = readdirSync7(cacheDir);
58228
58427
  for (const file of files) {
58229
58428
  if (cachePatterns.includes(file)) {
58230
- unlinkSync8(join39(cacheDir, file));
58429
+ unlinkSync8(join40(cacheDir, file));
58231
58430
  cleared++;
58232
58431
  }
58233
58432
  }
@@ -58701,15 +58900,15 @@ Usage: claudish --models --provider <slug>`);
58701
58900
  });
58702
58901
  config.resolvedDefaultProvider = resolved;
58703
58902
  if (resolved.legacyAutoPromoted && !config.quiet) {
58704
- const markerFile = join39(homedir34(), ".claudish", ".legacy-litellm-hint-shown");
58705
- if (!existsSync29(markerFile)) {
58903
+ const markerFile = join40(homedir35(), ".claudish", ".legacy-litellm-hint-shown");
58904
+ if (!existsSync30(markerFile)) {
58706
58905
  const hint = buildLegacyHint(resolved);
58707
58906
  if (hint) {
58708
58907
  console.error(hint);
58709
58908
  }
58710
58909
  try {
58711
- mkdirSync17(dirname11(markerFile), { recursive: true });
58712
- writeFileSync18(markerFile, new Date().toISOString(), "utf-8");
58910
+ mkdirSync18(dirname12(markerFile), { recursive: true });
58911
+ writeFileSync19(markerFile, new Date().toISOString(), "utf-8");
58713
58912
  } catch {}
58714
58913
  }
58715
58914
  }
@@ -59885,8 +60084,8 @@ ${h("MORE INFO")}
59885
60084
  }
59886
60085
  function printAIAgentGuide() {
59887
60086
  try {
59888
- const guidePath = join39(__dirname3, "../AI_AGENT_GUIDE.md");
59889
- const guideContent = readFileSync29(guidePath, "utf-8");
60087
+ const guidePath = join40(__dirname3, "../AI_AGENT_GUIDE.md");
60088
+ const guideContent = readFileSync30(guidePath, "utf-8");
59890
60089
  console.log(guideContent);
59891
60090
  } catch (error) {
59892
60091
  console.error("Error reading AI Agent Guide:");
@@ -59902,19 +60101,19 @@ async function initializeClaudishSkill() {
59902
60101
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
59903
60102
  `);
59904
60103
  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)) {
60104
+ const claudeDir = join40(cwd, ".claude");
60105
+ const skillsDir = join40(claudeDir, "skills");
60106
+ const claudishSkillDir = join40(skillsDir, "claudish-usage");
60107
+ const skillFile = join40(claudishSkillDir, "SKILL.md");
60108
+ if (existsSync30(skillFile)) {
59910
60109
  console.log("\u2705 Claudish skill already installed at:");
59911
60110
  console.log(` ${skillFile}
59912
60111
  `);
59913
60112
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
59914
60113
  return;
59915
60114
  }
59916
- const sourceSkillPath = join39(__dirname3, "../skills/claudish-usage/SKILL.md");
59917
- if (!existsSync29(sourceSkillPath)) {
60115
+ const sourceSkillPath = join40(__dirname3, "../skills/claudish-usage/SKILL.md");
60116
+ if (!existsSync30(sourceSkillPath)) {
59918
60117
  console.error("\u274C Error: Claudish skill file not found in installation.");
59919
60118
  console.error(` Expected at: ${sourceSkillPath}`);
59920
60119
  console.error(`
@@ -59923,16 +60122,16 @@ async function initializeClaudishSkill() {
59923
60122
  process.exit(1);
59924
60123
  }
59925
60124
  try {
59926
- if (!existsSync29(claudeDir)) {
59927
- mkdirSync17(claudeDir, { recursive: true });
60125
+ if (!existsSync30(claudeDir)) {
60126
+ mkdirSync18(claudeDir, { recursive: true });
59928
60127
  console.log("\uD83D\uDCC1 Created .claude/ directory");
59929
60128
  }
59930
- if (!existsSync29(skillsDir)) {
59931
- mkdirSync17(skillsDir, { recursive: true });
60129
+ if (!existsSync30(skillsDir)) {
60130
+ mkdirSync18(skillsDir, { recursive: true });
59932
60131
  console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
59933
60132
  }
59934
- if (!existsSync29(claudishSkillDir)) {
59935
- mkdirSync17(claudishSkillDir, { recursive: true });
60133
+ if (!existsSync30(claudishSkillDir)) {
60134
+ mkdirSync18(claudishSkillDir, { recursive: true });
59936
60135
  console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
59937
60136
  }
59938
60137
  copyFileSync2(sourceSkillPath, skillFile);
@@ -60010,7 +60209,7 @@ var init_cli = __esm(() => {
60010
60209
  init_ansi();
60011
60210
  init_provider_resolver();
60012
60211
  __filename3 = fileURLToPath3(import.meta.url);
60013
- __dirname3 = dirname11(__filename3);
60212
+ __dirname3 = dirname12(__filename3);
60014
60213
  });
60015
60214
 
60016
60215
  // src/update-command.ts
@@ -60829,15 +61028,15 @@ var init_local_liveness = __esm(() => {
60829
61028
  });
60830
61029
 
60831
61030
  // 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";
61031
+ import { existsSync as existsSync31, mkdirSync as mkdirSync19, readFileSync as readFileSync31, writeFileSync as writeFileSync20 } from "fs";
61032
+ import { homedir as homedir36 } from "os";
61033
+ import { dirname as dirname13, join as join41 } from "path";
60835
61034
  function readProbeModelsCache(path = PROBE_MODELS_CACHE_PATH) {
60836
- if (!existsSync30(path))
61035
+ if (!existsSync31(path))
60837
61036
  return null;
60838
61037
  let raw;
60839
61038
  try {
60840
- raw = JSON.parse(readFileSync30(path, "utf-8"));
61039
+ raw = JSON.parse(readFileSync31(path, "utf-8"));
60841
61040
  } catch {
60842
61041
  return null;
60843
61042
  }
@@ -60846,8 +61045,8 @@ function readProbeModelsCache(path = PROBE_MODELS_CACHE_PATH) {
60846
61045
  return raw;
60847
61046
  }
60848
61047
  function writeProbeModelsCache(data, path = PROBE_MODELS_CACHE_PATH) {
60849
- mkdirSync18(dirname12(path), { recursive: true });
60850
- writeFileSync19(path, JSON.stringify(data), "utf-8");
61048
+ mkdirSync19(dirname13(path), { recursive: true });
61049
+ writeFileSync20(path, JSON.stringify(data), "utf-8");
60851
61050
  }
60852
61051
  function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
60853
61052
  if (!data?.generatedAt)
@@ -60966,7 +61165,7 @@ function isValidResponse(raw) {
60966
61165
  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
61166
  var init_probe_catalog = __esm(() => {
60968
61167
  CACHE_TTL_MS4 = 60 * 60 * 1000;
60969
- PROBE_MODELS_CACHE_PATH = join40(homedir35(), ".claudish", "probe-models.json");
61168
+ PROBE_MODELS_CACHE_PATH = join41(homedir36(), ".claudish", "probe-models.json");
60970
61169
  });
60971
61170
 
60972
61171
  // src/tui/constants.ts
@@ -65434,6 +65633,13 @@ var probeProxy = null, probeProxyStarting = null;
65434
65633
 
65435
65634
  // src/tui/hooks/useRouteProbe.ts
65436
65635
  import { useCallback as useCallback2, useState as useState4 } from "react";
65636
+ async function routeForProbe(model) {
65637
+ try {
65638
+ return await route(model);
65639
+ } catch (err) {
65640
+ return { kind: "no-route", reason: err instanceof Error ? err.message : String(err) };
65641
+ }
65642
+ }
65437
65643
  function useRouteProbe(config) {
65438
65644
  const [probeMode, setProbeMode] = useState4("idle");
65439
65645
  const [probeModel, setProbeModel] = useState4("");
@@ -65472,7 +65678,7 @@ function useRouteProbe(config) {
65472
65678
  if (native) {
65473
65679
  chain = [native];
65474
65680
  } else {
65475
- const plan = await route(model);
65681
+ const plan = await routeForProbe(model);
65476
65682
  if (plan.kind !== "ok") {
65477
65683
  setProbeResults([
65478
65684
  {
@@ -67584,17 +67790,17 @@ var init_terminal_isolation = __esm(() => {
67584
67790
  import { spawn as spawn5, spawnSync as spawnSync4 } from "child_process";
67585
67791
  import {
67586
67792
  closeSync as closeSync8,
67587
- existsSync as existsSync31,
67588
- mkdirSync as mkdirSync19,
67793
+ existsSync as existsSync32,
67794
+ mkdirSync as mkdirSync20,
67589
67795
  openSync as openSync8,
67590
- readFileSync as readFileSync31,
67796
+ readFileSync as readFileSync32,
67591
67797
  readdirSync as readdirSync8,
67592
67798
  statSync as statSync8,
67593
67799
  unlinkSync as unlinkSync9,
67594
- writeFileSync as writeFileSync20
67800
+ writeFileSync as writeFileSync21
67595
67801
  } from "fs";
67596
- import { homedir as homedir36, tmpdir as tmpdir2 } from "os";
67597
- import { dirname as dirname13, join as join41 } from "path";
67802
+ import { homedir as homedir37, tmpdir as tmpdir2 } from "os";
67803
+ import { dirname as dirname14, join as join42 } from "path";
67598
67804
  import { isatty } from "tty";
67599
67805
  function releaseTerminalIsolation() {
67600
67806
  if (!restoreTerminal)
@@ -67654,12 +67860,12 @@ function isRealAnthropicEnvCredential(env, name) {
67654
67860
  }
67655
67861
  function hasResolvableAnthropicAuth(deps = {}) {
67656
67862
  const env = deps.env ?? process.env;
67657
- const fileExists = deps.fileExists ?? existsSync31;
67863
+ const fileExists = deps.fileExists ?? existsSync32;
67658
67864
  const keychainProbe = deps.keychainProbe ?? defaultKeychainAnthropicProbe;
67659
67865
  if (isRealAnthropicEnvCredential(env, "ANTHROPIC_API_KEY") || isRealAnthropicEnvCredential(env, "ANTHROPIC_AUTH_TOKEN")) {
67660
67866
  return true;
67661
67867
  }
67662
- if (fileExists(join41(homedir36(), ".claude", ".credentials.json")))
67868
+ if (fileExists(join42(homedir37(), ".claude", ".credentials.json")))
67663
67869
  return true;
67664
67870
  return keychainProbe();
67665
67871
  }
@@ -67674,14 +67880,14 @@ function isProxyAuthMode(config) {
67674
67880
  }
67675
67881
  function managedSettingsPath() {
67676
67882
  if (isWindows2()) {
67677
- return join41(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
67883
+ return join42(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
67678
67884
  }
67679
67885
  if (process.platform === "darwin") {
67680
67886
  return "/Library/Application Support/ClaudeCode/managed-settings.json";
67681
67887
  }
67682
67888
  return "/etc/claude-code/managed-settings.json";
67683
67889
  }
67684
- function managedSettingsForcesClaudeAi(readFile = readFileSync31) {
67890
+ function managedSettingsForcesClaudeAi(readFile = readFileSync32) {
67685
67891
  try {
67686
67892
  const raw = readFile(managedSettingsPath(), "utf-8");
67687
67893
  const parsed = JSON.parse(raw);
@@ -67695,9 +67901,9 @@ function isWindows2() {
67695
67901
  }
67696
67902
  function createStatusLineScript(tokenFilePath) {
67697
67903
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
67698
- const claudishDir = join41(homeDir, ".claudish");
67904
+ const claudishDir = join42(homeDir, ".claudish");
67699
67905
  const timestamp = Date.now();
67700
- const scriptPath = join41(claudishDir, `status-${timestamp}.js`);
67906
+ const scriptPath = join42(claudishDir, `status-${timestamp}.js`);
67701
67907
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
67702
67908
  const light = getThemeMode() === "light";
67703
67909
  const cyanCode = light ? "38;2;14;116;144" : "96";
@@ -67830,13 +68036,13 @@ process.stdin.on('end', () => {
67830
68036
  }
67831
68037
  });
67832
68038
  `;
67833
- writeFileSync20(scriptPath, script, "utf-8");
68039
+ writeFileSync21(scriptPath, script, "utf-8");
67834
68040
  return scriptPath;
67835
68041
  }
67836
68042
  function initializeTokenFile(tokenFilePath) {
67837
68043
  try {
67838
- mkdirSync19(dirname13(tokenFilePath), { recursive: true });
67839
- writeFileSync20(tokenFilePath, JSON.stringify({
68044
+ mkdirSync20(dirname14(tokenFilePath), { recursive: true });
68045
+ writeFileSync21(tokenFilePath, JSON.stringify({
67840
68046
  input_tokens: 0,
67841
68047
  output_tokens: 0,
67842
68048
  total_tokens: 0,
@@ -67867,7 +68073,7 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
67867
68073
  if (!name.startsWith("tokens-") || !name.endsWith(".json"))
67868
68074
  continue;
67869
68075
  scanned++;
67870
- const full = join41(dir, name);
68076
+ const full = join42(dir, name);
67871
68077
  try {
67872
68078
  if (statSync8(full).mtimeMs >= cutoff)
67873
68079
  continue;
@@ -67884,7 +68090,7 @@ function parseSettingsArg(value) {
67884
68090
  if (value.trimStart().startsWith("{")) {
67885
68091
  return JSON.parse(value);
67886
68092
  }
67887
- return JSON.parse(readFileSync31(value, "utf-8"));
68093
+ return JSON.parse(readFileSync32(value, "utf-8"));
67888
68094
  }
67889
68095
  function parseSettingsArgSafe(value) {
67890
68096
  try {
@@ -67896,13 +68102,13 @@ function parseSettingsArgSafe(value) {
67896
68102
  }
67897
68103
  function userSettingsFileCandidates(cwd) {
67898
68104
  return [
67899
- join41(homedir36(), ".claude", "settings.json"),
67900
- join41(cwd, ".claude", "settings.json"),
67901
- join41(cwd, ".claude", "settings.local.json")
68105
+ join42(homedir37(), ".claude", "settings.json"),
68106
+ join42(cwd, ".claude", "settings.json"),
68107
+ join42(cwd, ".claude", "settings.local.json")
67902
68108
  ];
67903
68109
  }
67904
68110
  function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
67905
- const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync31(file));
68111
+ const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync32(file));
67906
68112
  const idx = claudeArgs.indexOf("--settings");
67907
68113
  const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
67908
68114
  if (settingsArg)
@@ -67939,13 +68145,13 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
67939
68145
  }
67940
68146
  function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
67941
68147
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
67942
- const claudishDir = join41(homeDir, ".claudish");
68148
+ const claudishDir = join42(homeDir, ".claudish");
67943
68149
  try {
67944
- mkdirSync19(claudishDir, { recursive: true });
68150
+ mkdirSync20(claudishDir, { recursive: true });
67945
68151
  } catch {}
67946
68152
  const timestamp = Date.now();
67947
- const tempPath = join41(claudishDir, `settings-${timestamp}.json`);
67948
- const tokenFilePath = join41(claudishDir, `tokens-${port}.json`);
68153
+ const tempPath = join42(claudishDir, `settings-${timestamp}.json`);
68154
+ const tokenFilePath = join42(claudishDir, `tokens-${port}.json`);
67949
68155
  cleanupStaleTokenFiles(claudishDir);
67950
68156
  initializeTokenFile(tokenFilePath);
67951
68157
  let statusCommand;
@@ -67979,7 +68185,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
67979
68185
  padding: 0
67980
68186
  };
67981
68187
  const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
67982
- writeFileSync20(tempPath, JSON.stringify(settings, null, 2), "utf-8");
68188
+ writeFileSync21(tempPath, JSON.stringify(settings, null, 2), "utf-8");
67983
68189
  return { path: tempPath, statusLine, tokenFilePath };
67984
68190
  }
67985
68191
  function buildClaudishSettingsOverlay(statusLine, proxyAuthMode) {
@@ -68004,7 +68210,7 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
68004
68210
  if (proxyAuthMode && !("forceLoginMethod" in userSettings)) {
68005
68211
  userSettings.forceLoginMethod = "console";
68006
68212
  }
68007
- writeFileSync20(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
68213
+ writeFileSync21(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
68008
68214
  } catch {
68009
68215
  if (!config.quiet) {
68010
68216
  console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
@@ -68075,13 +68281,13 @@ function resolveAdvisorToolEnv(config, processEnv = process.env) {
68075
68281
  return { vars: { [ADVISOR_TOOL_ENV_VAR]: "1" }, source: "claudish" };
68076
68282
  }
68077
68283
  function discoverUserAdvisorModel(claudeArgs = [], cwd = process.cwd()) {
68078
- const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync31(file));
68284
+ const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync32(file));
68079
68285
  const idx = claudeArgs.indexOf("--settings");
68080
68286
  const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
68081
68287
  if (settingsArg)
68082
68288
  sources.push(settingsArg);
68083
68289
  const managed = managedSettingsPath();
68084
- if (existsSync31(managed))
68290
+ if (existsSync32(managed))
68085
68291
  sources.push(managed);
68086
68292
  let effective;
68087
68293
  for (const source of sources) {
@@ -68295,8 +68501,8 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
68295
68501
  console.error("Install it from: https://claude.com/claude-code");
68296
68502
  console.error(`
68297
68503
  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");
68504
+ const home = homedir37();
68505
+ const localPath = isWindows2() ? join42(home, ".claude", "local", "claude.exe") : join42(home, ".claude", "local", "claude");
68300
68506
  console.error(` export CLAUDE_PATH=${localPath}`);
68301
68507
  process.exit(1);
68302
68508
  }
@@ -68384,23 +68590,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
68384
68590
  async function findClaudeBinary() {
68385
68591
  const isWindows = process.platform === "win32";
68386
68592
  if (process.env.CLAUDE_PATH) {
68387
- if (existsSync31(process.env.CLAUDE_PATH)) {
68593
+ if (existsSync32(process.env.CLAUDE_PATH)) {
68388
68594
  return process.env.CLAUDE_PATH;
68389
68595
  }
68390
68596
  }
68391
- const home = homedir36();
68392
- const localPath = isWindows ? join41(home, ".claude", "local", "claude.exe") : join41(home, ".claude", "local", "claude");
68393
- if (existsSync31(localPath)) {
68597
+ const home = homedir37();
68598
+ const localPath = isWindows ? join42(home, ".claude", "local", "claude.exe") : join42(home, ".claude", "local", "claude");
68599
+ if (existsSync32(localPath)) {
68394
68600
  return localPath;
68395
68601
  }
68396
68602
  if (isWindows) {
68397
68603
  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")
68604
+ join42(home, "AppData", "Roaming", "npm", "claude.cmd"),
68605
+ join42(home, ".npm-global", "claude.cmd"),
68606
+ join42(home, "node_modules", ".bin", "claude.cmd")
68401
68607
  ];
68402
68608
  for (const path of windowsPaths) {
68403
- if (existsSync31(path)) {
68609
+ if (existsSync32(path)) {
68404
68610
  return path;
68405
68611
  }
68406
68612
  }
@@ -68408,14 +68614,14 @@ async function findClaudeBinary() {
68408
68614
  const commonPaths = [
68409
68615
  "/usr/local/bin/claude",
68410
68616
  "/opt/homebrew/bin/claude",
68411
- join41(home, ".npm-global/bin/claude"),
68412
- join41(home, ".local/bin/claude"),
68413
- join41(home, "node_modules/.bin/claude"),
68617
+ join42(home, ".npm-global/bin/claude"),
68618
+ join42(home, ".local/bin/claude"),
68619
+ join42(home, "node_modules/.bin/claude"),
68414
68620
  "/data/data/com.termux/files/usr/bin/claude",
68415
- join41(home, "../usr/bin/claude")
68621
+ join42(home, "../usr/bin/claude")
68416
68622
  ];
68417
68623
  for (const path of commonPaths) {
68418
- if (existsSync31(path)) {
68624
+ if (existsSync32(path)) {
68419
68625
  return path;
68420
68626
  }
68421
68627
  }
@@ -68490,18 +68696,18 @@ var init_claude_runner = __esm(() => {
68490
68696
  });
68491
68697
 
68492
68698
  // 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";
68699
+ import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync21, unlinkSync as unlinkSync10, writeFileSync as writeFileSync22 } from "fs";
68700
+ import { homedir as homedir38 } from "os";
68701
+ import { join as join43 } from "path";
68496
68702
  function getClaudishDir() {
68497
- const dir = join42(homedir37(), ".claudish");
68703
+ const dir = join43(homedir38(), ".claudish");
68498
68704
  try {
68499
- mkdirSync20(dir, { recursive: true });
68705
+ mkdirSync21(dir, { recursive: true });
68500
68706
  } catch {}
68501
68707
  return dir;
68502
68708
  }
68503
68709
  function getDiagLogPath() {
68504
- return join42(getClaudishDir(), `diag-${process.pid}.log`);
68710
+ return join43(getClaudishDir(), `diag-${process.pid}.log`);
68505
68711
  }
68506
68712
 
68507
68713
  class LogFileDiagOutput {
@@ -68510,7 +68716,7 @@ class LogFileDiagOutput {
68510
68716
  constructor() {
68511
68717
  this.logPath = getDiagLogPath();
68512
68718
  try {
68513
- writeFileSync21(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
68719
+ writeFileSync22(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
68514
68720
  `);
68515
68721
  } catch {}
68516
68722
  this.stream = createWriteStream3(this.logPath, { flags: "a" });
@@ -68712,13 +68918,33 @@ async function warmCatalogIfNeeded(config, opts) {
68712
68918
  }
68713
68919
  return "ok";
68714
68920
  }
68921
+ return reportUnusableCatalog(outcome, state, cache, now, config.quiet === true);
68922
+ }
68923
+ function reportUnusableCatalog(outcome, state, cache, now, quiet) {
68924
+ if (outcome.kind === "incompatible") {
68925
+ return reportIncompatibleCatalog(readCatalogIncompatibility() ?? {
68926
+ detectedAt: new Date().toISOString(),
68927
+ serverContractVersion: outcome.serverContractVersion
68928
+ });
68929
+ }
68715
68930
  if (outcome.reason === "disabled") {
68716
- if (!config.quiet) {
68931
+ if (!quiet) {
68717
68932
  process.stderr.write(` Catalog refresh disabled (CLAUDISH_DISABLE_CATALOG_WARM=1).
68718
68933
  `);
68719
68934
  }
68720
68935
  return "skipped";
68721
68936
  }
68937
+ const recorded = readCatalogIncompatibility();
68938
+ if (recorded !== null)
68939
+ return reportIncompatibleCatalog(recorded);
68940
+ return reportFetchFailure(state, cache, now);
68941
+ }
68942
+ function reportIncompatibleCatalog(recorded) {
68943
+ process.stderr.write(`${catalogIncompatibilityMessage(recorded)}
68944
+ `);
68945
+ return "warned";
68946
+ }
68947
+ function reportFetchFailure(state, cache, now) {
68722
68948
  if (state === "stale") {
68723
68949
  const ageMs = now.getTime() - Date.parse(cache.lastUpdated);
68724
68950
  const ageStr = humanizeAge(ageMs);
@@ -68740,6 +68966,7 @@ var HARD_FAIL_MESSAGE, LOCAL_MODEL_PREFIXES;
68740
68966
  var init_catalog_warm = __esm(() => {
68741
68967
  init_all_models_cache();
68742
68968
  init_catalog_client();
68969
+ init_catalog_compatibility();
68743
68970
  HARD_FAIL_MESSAGE = `Error: cannot reach model catalog and no cached copy found.
68744
68971
  ` + `
68745
68972
  ` + `To proceed:
@@ -71106,16 +71333,16 @@ var exports_session_stats = {};
71106
71333
  __export(exports_session_stats, {
71107
71334
  readSessionStats: () => readSessionStats
71108
71335
  });
71109
- import { readFileSync as readFileSync32 } from "fs";
71110
- import { homedir as homedir38 } from "os";
71111
- import { join as join43 } from "path";
71336
+ import { readFileSync as readFileSync33 } from "fs";
71337
+ import { homedir as homedir39 } from "os";
71338
+ import { join as join44 } from "path";
71112
71339
  function tokenFilePath(port) {
71113
- return process.env.CLAUDISH_TOKEN_FILE || join43(homedir38(), ".claudish", `tokens-${port}.json`);
71340
+ return process.env.CLAUDISH_TOKEN_FILE || join44(homedir39(), ".claudish", `tokens-${port}.json`);
71114
71341
  }
71115
71342
  function readSessionStats(port, opts) {
71116
71343
  let raw;
71117
71344
  try {
71118
- raw = JSON.parse(readFileSync32(tokenFilePath(port), "utf-8"));
71345
+ raw = JSON.parse(readFileSync33(tokenFilePath(port), "utf-8"));
71119
71346
  } catch {
71120
71347
  return null;
71121
71348
  }
@@ -71472,8 +71699,8 @@ var init_session_summary = __esm(() => {
71472
71699
  init_op_source();
71473
71700
  init_startup_trace();
71474
71701
  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";
71702
+ import { existsSync as existsSync33, readFileSync as readFileSync34 } from "fs";
71703
+ import { join as join45, resolve as resolve6 } from "path";
71477
71704
  import_dotenv3.config({ quiet: true });
71478
71705
  function classifyStartupKind() {
71479
71706
  const argv = process.argv.slice(2);
@@ -71573,7 +71800,7 @@ async function applyConfigOverride() {
71573
71800
  await Promise.resolve();
71574
71801
  const plan = planConfigOverride(process.argv.slice(2), process.env, {
71575
71802
  resolve: resolve6,
71576
- exists: existsSync32
71803
+ exists: existsSync33
71577
71804
  });
71578
71805
  if (plan.kind === "none")
71579
71806
  return;
@@ -71742,14 +71969,14 @@ async function runCli() {
71742
71969
  if (cliConfig.team && cliConfig.team.length > 0) {
71743
71970
  let prompt = cliConfig.claudeArgs.join(" ");
71744
71971
  if (cliConfig.inputFile) {
71745
- prompt = readFileSync33(cliConfig.inputFile, "utf-8");
71972
+ prompt = readFileSync34(cliConfig.inputFile, "utf-8");
71746
71973
  }
71747
71974
  if (!prompt.trim()) {
71748
71975
  console.error("Error: --team requires a prompt (positional args or -f <file>)");
71749
71976
  process.exit(1);
71750
71977
  }
71751
71978
  const mode = cliConfig.teamMode ?? "default";
71752
- const sessionPath = join44(process.cwd(), `.claudish-team-${Date.now()}`);
71979
+ const sessionPath = join45(process.cwd(), `.claudish-team-${Date.now()}`);
71753
71980
  if (mode === "json") {
71754
71981
  await Promise.resolve().then(() => init_team_orchestrator());
71755
71982
  setupSession(sessionPath, cliConfig.team, prompt);
@@ -71758,9 +71985,9 @@ async function runCli() {
71758
71985
  });
71759
71986
  const result = { ...status, responses: {} };
71760
71987
  for (const anonId of Object.keys(status.models)) {
71761
- const responsePath = join44(sessionPath, `response-${anonId}.md`);
71988
+ const responsePath = join45(sessionPath, `response-${anonId}.md`);
71762
71989
  try {
71763
- const raw = readFileSync33(responsePath, "utf-8").trim();
71990
+ const raw = readFileSync34(responsePath, "utf-8").trim();
71764
71991
  try {
71765
71992
  result.responses[anonId] = JSON.parse(raw);
71766
71993
  } catch {