claudish 14.18.1 → 14.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +185 -64
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -5494,7 +5494,7 @@ var init_onepassword_config = __esm(() => {
5494
5494
  });
5495
5495
 
5496
5496
  // src/version.ts
5497
- var VERSION = "14.18.1";
5497
+ var VERSION = "14.18.2";
5498
5498
 
5499
5499
  // src/redact.ts
5500
5500
  function isPlaceholder(value) {
@@ -26401,6 +26401,7 @@ var version2 = null, readForToken = null;
26401
26401
 
26402
26402
  // src/auth/antigravity-token.ts
26403
26403
  import { execFileSync } from "child_process";
26404
+ import { createHash as createHash3 } from "crypto";
26404
26405
  import { existsSync as existsSync11 } from "fs";
26405
26406
  import { homedir as homedir12 } from "os";
26406
26407
  import { join as join12 } from "path";
@@ -26408,6 +26409,8 @@ function invalidateReadStoreMemo() {
26408
26409
  cachedRawStore = null;
26409
26410
  }
26410
26411
  function defaultReadStore() {
26412
+ if (process.env.CLAUDISH_DISABLE_KEYCHAIN === "1")
26413
+ return null;
26411
26414
  if (process.platform !== "darwin") {
26412
26415
  logStderr("[Antigravity] Shared token store is macOS-only for now (other keyring backends are a follow-up).");
26413
26416
  return null;
@@ -26549,7 +26552,7 @@ function encodeRecord(rec) {
26549
26552
  return PREFIX + Buffer.from(JSON.stringify(rec), "utf8").toString("base64");
26550
26553
  }
26551
26554
  function readSharedAntigravityToken(deps = defaultDeps3) {
26552
- const rec = parseRecord2(deps.readStore());
26555
+ const rec = readObservedRecord(deps);
26553
26556
  return rec ? rec.token : null;
26554
26557
  }
26555
26558
  function hasSharedAntigravityToken(deps = defaultDeps3) {
@@ -26596,11 +26599,44 @@ function captureAgyClientVersion(accessToken, deps) {
26596
26599
  log("[Antigravity] Could not read the agy version" + (kept ? `; keeping ${kept}.` : "; using the fallback version."));
26597
26600
  }
26598
26601
  }
26602
+ function antigravityTokenLineageMaterial(token) {
26603
+ if (token.refresh_token)
26604
+ return `refresh:${token.refresh_token}`;
26605
+ if (token.access_token)
26606
+ return `access:${token.access_token}`;
26607
+ return;
26608
+ }
26609
+ function sha256(value) {
26610
+ return createHash3("sha256").update(value).digest("hex");
26611
+ }
26612
+ function observeLineage(token) {
26613
+ const material = token ? antigravityTokenLineageMaterial(token) : undefined;
26614
+ observedLineage = material ? sha256(material) : null;
26615
+ if (!observedLineage || !token?.access_token)
26616
+ return;
26617
+ const key = sha256(token.access_token);
26618
+ lineageByAccessToken.delete(key);
26619
+ lineageByAccessToken.set(key, observedLineage);
26620
+ if (lineageByAccessToken.size > MAX_TRACKED_ACCESS_TOKENS) {
26621
+ lineageByAccessToken.delete(lineageByAccessToken.keys().next().value);
26622
+ }
26623
+ }
26624
+ function readObservedRecord(deps) {
26625
+ const rec = parseRecord2(deps.readStore());
26626
+ observeLineage(rec ? rec.token : null);
26627
+ return rec;
26628
+ }
26629
+ function currentAntigravityTokenLineage() {
26630
+ return observedLineage;
26631
+ }
26632
+ function lineageForAntigravityAccessToken(accessToken) {
26633
+ return lineageByAccessToken.get(sha256(accessToken)) ?? null;
26634
+ }
26599
26635
  async function resolveValidToken(deps) {
26600
26636
  if (process.platform !== "darwin") {
26601
26637
  throw terminalCredentialError("[Antigravity] The shared Antigravity token store is macOS-only for now. " + "Use g@<model> with GEMINI_API_KEY on this platform.");
26602
26638
  }
26603
- const rec = parseRecord2(deps.readStore());
26639
+ const rec = readObservedRecord(deps);
26604
26640
  if (!rec) {
26605
26641
  throw terminalCredentialError("[Antigravity] No Antigravity session found. Sign in with `claudish login antigravity`, " + "or use g@<model> with GEMINI_API_KEY " + "(get one at https://aistudio.google.com/app/apikey).");
26606
26642
  }
@@ -26610,7 +26646,7 @@ async function resolveValidToken(deps) {
26610
26646
  }
26611
26647
  log("[Antigravity] Access token expired/near-expiry \u2014 asking the Antigravity CLI to refresh.");
26612
26648
  const outcome = deps.runAgyRefresh();
26613
- const refreshedRec = parseRecord2(deps.readStore());
26649
+ const refreshedRec = readObservedRecord(deps);
26614
26650
  if (refreshedRec && !needsRefresh(refreshedRec.token, deps.now())) {
26615
26651
  log("[Antigravity] Shared token refreshed by the Antigravity CLI.");
26616
26652
  captureAgyClientVersion(refreshedRec.token.access_token, deps);
@@ -26647,8 +26683,8 @@ async function forceRefreshAntigravityToken(deps = defaultDeps3) {
26647
26683
  if (process.platform !== "darwin") {
26648
26684
  throw terminalCredentialError("[Antigravity] The shared Antigravity token store is macOS-only for now. " + "Use g@<model> with GEMINI_API_KEY on this platform.");
26649
26685
  }
26650
- _resetAntigravityTokenState();
26651
- const rec = parseRecord2(deps.readStore());
26686
+ resetObservedTokenState();
26687
+ const rec = readObservedRecord(deps);
26652
26688
  if (!rec) {
26653
26689
  throw terminalCredentialError("[Antigravity] No Antigravity session found. Sign in with `claudish login antigravity`, " + "or use g@<model> with GEMINI_API_KEY " + "(get one at https://aistudio.google.com/app/apikey).");
26654
26690
  }
@@ -26656,7 +26692,7 @@ async function forceRefreshAntigravityToken(deps = defaultDeps3) {
26656
26692
  log("[Antigravity] Upstream rejected the current token \u2014 asking the Antigravity CLI to re-mint.");
26657
26693
  writeSharedAntigravityToken({ ...original, expiry: new Date(deps.now() - 1000).toISOString() }, deps);
26658
26694
  const outcome = deps.runAgyRefresh();
26659
- const refreshed = parseRecord2(deps.readStore());
26695
+ const refreshed = readObservedRecord(deps);
26660
26696
  const token = refreshed?.token;
26661
26697
  if (token && token.access_token !== original.access_token && !needsRefresh(token, deps.now())) {
26662
26698
  log("[Antigravity] Shared token re-minted by the Antigravity CLI.");
@@ -26666,7 +26702,7 @@ async function forceRefreshAntigravityToken(deps = defaultDeps3) {
26666
26702
  if (!refreshed || refreshed.token.access_token === original.access_token) {
26667
26703
  writeSharedAntigravityToken(original, deps);
26668
26704
  }
26669
- _resetAntigravityTokenState();
26705
+ resetObservedTokenState();
26670
26706
  if (outcome.kind === "timeout" || outcome.kind === "failed") {
26671
26707
  const message = `[Antigravity] ${describeRefreshFailure(outcome)}`;
26672
26708
  if (outcome.kind === "timeout") {
@@ -26680,11 +26716,16 @@ async function forceRefreshAntigravityToken(deps = defaultDeps3) {
26680
26716
  throw terminalCredentialError("[Antigravity] The Antigravity session was rejected upstream and could not be re-minted. " + "Run `claudish login antigravity` to sign in again.");
26681
26717
  }
26682
26718
  function _resetAntigravityTokenState() {
26719
+ resetObservedTokenState();
26720
+ lineageByAccessToken.clear();
26721
+ }
26722
+ function resetObservedTokenState() {
26683
26723
  inFlight = null;
26684
26724
  cachedHasToken = null;
26725
+ observedLineage = null;
26685
26726
  invalidateReadStoreMemo();
26686
26727
  }
26687
- var KC_SERVICE = "gemini", KC_ACCOUNT = "antigravity", PREFIX = "go-keyring-base64:", EXPIRY_SKEW_MS = 120000, AGY_REFRESH_TIMEOUT_MS = 12000, AGY_VERSION_TIMEOUT_MS = 5000, READ_STORE_TTL_MS = 3000, cachedRawStore = null, defaultDeps3, KEYCHAIN_LOCKED_EXIT_CODES, cachedHasToken = null, HAS_TOKEN_TTL_MS = 5000, inFlight = null;
26728
+ var KC_SERVICE = "gemini", KC_ACCOUNT = "antigravity", PREFIX = "go-keyring-base64:", EXPIRY_SKEW_MS = 120000, AGY_REFRESH_TIMEOUT_MS = 12000, AGY_VERSION_TIMEOUT_MS = 5000, READ_STORE_TTL_MS = 3000, cachedRawStore = null, defaultDeps3, KEYCHAIN_LOCKED_EXIT_CODES, cachedHasToken = null, HAS_TOKEN_TTL_MS = 5000, inFlight = null, observedLineage = null, MAX_TRACKED_ACCESS_TOKENS = 8, lineageByAccessToken;
26688
26729
  var init_antigravity_token = __esm(() => {
26689
26730
  init_logger();
26690
26731
  init_keychain();
@@ -26697,6 +26738,7 @@ var init_antigravity_token = __esm(() => {
26697
26738
  now: () => Date.now()
26698
26739
  };
26699
26740
  KEYCHAIN_LOCKED_EXIT_CODES = new Set([36, 51, 128]);
26741
+ lineageByAccessToken = new Map;
26700
26742
  });
26701
26743
 
26702
26744
  // src/auth/antigravity-user.ts
@@ -26749,6 +26791,26 @@ function resetAntigravityUserCache() {
26749
26791
  agServedCache = null;
26750
26792
  agServedCacheAt = 0;
26751
26793
  agServedCacheVersion = null;
26794
+ cachedAgLineage = null;
26795
+ }
26796
+ function syncAccountCaches() {
26797
+ const lineage = currentAntigravityTokenLineage();
26798
+ if (lineage === cachedAgLineage)
26799
+ return;
26800
+ if (cachedAgProjectId || agServedCache) {
26801
+ log("[Antigravity] Token lineage changed; dropping the cached project, tier and models.");
26802
+ }
26803
+ resetAntigravityUserCache();
26804
+ cachedAgLineage = lineage;
26805
+ }
26806
+ function lineageOfToken(accessToken) {
26807
+ return lineageForAntigravityAccessToken(accessToken) ?? currentAntigravityTokenLineage();
26808
+ }
26809
+ function mayPublishFor(lineage) {
26810
+ if (currentAntigravityTokenLineage() !== lineage)
26811
+ return false;
26812
+ syncAccountCaches();
26813
+ return true;
26752
26814
  }
26753
26815
  async function callLoadCodeAssistAntigravity(accessToken) {
26754
26816
  const res = await fetch(`${apiBase()}:loadCodeAssist`, {
@@ -26766,7 +26828,9 @@ async function callLoadCodeAssistAntigravity(accessToken) {
26766
26828
  return await res.json();
26767
26829
  }
26768
26830
  async function setupAntigravityUser(accessToken) {
26769
- if (cachedAgProjectId && cachedAgTierId) {
26831
+ syncAccountCaches();
26832
+ const lineage = lineageOfToken(accessToken);
26833
+ if (lineage === cachedAgLineage && cachedAgProjectId && cachedAgTierId) {
26770
26834
  return { projectId: cachedAgProjectId, tierId: cachedAgTierId };
26771
26835
  }
26772
26836
  const loadRes = await callLoadCodeAssistAntigravity(accessToken);
@@ -26776,13 +26840,18 @@ async function setupAntigravityUser(accessToken) {
26776
26840
  if (!projectId) {
26777
26841
  throw makeTerminalSetupError("Antigravity did not return a project for this account. Sign in to Antigravity " + "(`claudish login antigravity`) and try again, or use g@<model> with GEMINI_API_KEY " + "(get one at https://aistudio.google.com/app/apikey).");
26778
26842
  }
26779
- cachedAgProjectId = projectId;
26780
- cachedAgTierId = resolvedTier;
26781
- cachedAgTierName = loadRes.paidTier?.name || null;
26843
+ if (mayPublishFor(lineage)) {
26844
+ cachedAgProjectId = projectId;
26845
+ cachedAgTierId = resolvedTier;
26846
+ cachedAgTierName = loadRes.paidTier?.name || null;
26847
+ } else {
26848
+ log("[Antigravity] Token lineage changed during setup; the result is not cached.");
26849
+ }
26782
26850
  log(`[Antigravity] User set up, project: ${projectId}, tier: ${resolvedTier}`);
26783
26851
  return { projectId, tierId: resolvedTier };
26784
26852
  }
26785
26853
  function getAntigravityTierDisplayName() {
26854
+ syncAccountCaches();
26786
26855
  if (!cachedAgTierName && !cachedAgTierId)
26787
26856
  return "Antigravity";
26788
26857
  const id = cachedAgTierId || "";
@@ -26872,6 +26941,9 @@ async function fetchAntigravityAvailableModelsRaw(accessToken, projectId, opts)
26872
26941
  }
26873
26942
  }
26874
26943
  async function getServedAntigravityModels(accessToken, projectId, opts) {
26944
+ syncAccountCaches();
26945
+ const lineage = lineageOfToken(accessToken);
26946
+ const ownList = lineage === cachedAgLineage;
26875
26947
  const now = Date.now();
26876
26948
  const version = antigravityClientVersion();
26877
26949
  if (agServedCache && agServedCacheVersion !== version) {
@@ -26879,9 +26951,10 @@ async function getServedAntigravityModels(accessToken, projectId, opts) {
26879
26951
  agServedCache = null;
26880
26952
  agServedCacheAt = 0;
26881
26953
  }
26882
- if (!opts?.force && agServedCache && now - agServedCacheAt < SERVED_MODELS_TTL_MS) {
26954
+ if (!opts?.force && ownList && agServedCache && now - agServedCacheAt < SERVED_MODELS_TTL_MS) {
26883
26955
  return agServedCache;
26884
26956
  }
26957
+ const prior = ownList ? agServedCache : null;
26885
26958
  try {
26886
26959
  const raw = await fetchAntigravityAvailableModelsRaw(accessToken, projectId);
26887
26960
  if (raw.kind === "unreachable") {
@@ -26929,7 +27002,7 @@ async function getServedAntigravityModels(accessToken, projectId, opts) {
26929
27002
  deprecatedReplacements[oldId] = info.newModelId;
26930
27003
  }
26931
27004
  const agentModelIds = flattenAgentModelSorts(data.agentModelSorts);
26932
- agServedCache = {
27005
+ const served = {
26933
27006
  servedIds,
26934
27007
  defaultId,
26935
27008
  meta,
@@ -26937,26 +27010,34 @@ async function getServedAntigravityModels(accessToken, projectId, opts) {
26937
27010
  deprecatedReplacements,
26938
27011
  ...agentModelIds ? { agentModelIds } : {}
26939
27012
  };
27013
+ if (!mayPublishFor(lineage)) {
27014
+ log("[Antigravity] Token lineage changed during discovery; the result is not cached.");
27015
+ return served;
27016
+ }
27017
+ agServedCache = served;
26940
27018
  agServedCacheAt = now;
26941
27019
  agServedCacheVersion = raw.clientVersion;
26942
- return agServedCache;
27020
+ return served;
26943
27021
  }
26944
27022
  }
26945
27023
  } catch (err) {
26946
27024
  log(`[Antigravity] fetchAvailableModels error: ${err}`);
26947
27025
  }
26948
- if (agServedCache)
26949
- return agServedCache;
27026
+ if (prior)
27027
+ return prior;
26950
27028
  return { servedIds: [], defaultId: null, meta: {} };
26951
27029
  }
26952
27030
  function peekServedAntigravityModels() {
26953
27031
  if (!agServedCache || agServedCacheVersion !== antigravityClientVersion())
26954
27032
  return null;
27033
+ if (cachedAgLineage !== currentAntigravityTokenLineage())
27034
+ return null;
26955
27035
  return agServedCache;
26956
27036
  }
26957
- var ANTIGRAVITY_DEFAULT_HOST = "https://daily-cloudcode-pa.googleapis.com", SERVED_MODELS_TTL_MS, ANTIGRAVITY_IDE_TYPE = "ANTIGRAVITY", AGY_FALLBACK_CLIENT_VERSION = "1.1.9", cachedAgProjectId = null, cachedAgTierId = null, cachedAgTierName = null, agServedCache = null, agServedCacheAt = 0, agServedCacheVersion = null;
27037
+ var ANTIGRAVITY_DEFAULT_HOST = "https://daily-cloudcode-pa.googleapis.com", SERVED_MODELS_TTL_MS, ANTIGRAVITY_IDE_TYPE = "ANTIGRAVITY", AGY_FALLBACK_CLIENT_VERSION = "1.1.9", cachedAgProjectId = null, cachedAgTierId = null, cachedAgTierName = null, cachedAgLineage = null, agServedCache = null, agServedCacheAt = 0, agServedCacheVersion = null;
26958
27038
  var init_antigravity_user = __esm(() => {
26959
27039
  init_logger();
27040
+ init_antigravity_token();
26960
27041
  SERVED_MODELS_TTL_MS = 10 * 60 * 1000;
26961
27042
  });
26962
27043
 
@@ -27318,7 +27399,7 @@ var init_credential_file = __esm(() => {
27318
27399
 
27319
27400
  // src/auth/oauth-manager.ts
27320
27401
  import { exec as exec2 } from "child_process";
27321
- import { createHash as createHash3, randomBytes as randomBytes5 } from "crypto";
27402
+ import { createHash as createHash4, randomBytes as randomBytes5 } from "crypto";
27322
27403
  import { existsSync as existsSync12, mkdirSync as mkdirSync10, unlinkSync as unlinkSync5 } from "fs";
27323
27404
  import { homedir as homedir13 } from "os";
27324
27405
  import { join as join13 } from "path";
@@ -27421,7 +27502,7 @@ class OAuthManager {
27421
27502
  return randomBytes5(64).toString("base64url");
27422
27503
  }
27423
27504
  generateCodeChallenge(verifier) {
27424
- return createHash3("sha256").update(verifier).digest("base64url");
27505
+ return createHash4("sha256").update(verifier).digest("base64url");
27425
27506
  }
27426
27507
  async openBrowser(url, message) {
27427
27508
  try {
@@ -28787,9 +28868,9 @@ var init_registry2 = __esm(() => {
28787
28868
  });
28788
28869
 
28789
28870
  // src/code-mode/ids.ts
28790
- import { createHash as createHash4 } from "crypto";
28871
+ import { createHash as createHash5 } from "crypto";
28791
28872
  function sha256Hex(input) {
28792
- return createHash4("sha256").update(input).digest("hex");
28873
+ return createHash5("sha256").update(input).digest("hex");
28793
28874
  }
28794
28875
  function accountKeyFromBinding(binding) {
28795
28876
  const auth = binding?.auth;
@@ -28827,8 +28908,8 @@ function decodeNestedId(id) {
28827
28908
  return { execKey: match[1], seq: Number(match[2]) };
28828
28909
  }
28829
28910
  function uuidV5(namespace, name) {
28830
- const ns = createHash4("sha256").update(namespace).digest().subarray(0, 16);
28831
- const hash = createHash4("sha1").update(ns).update(name).digest();
28911
+ const ns = createHash5("sha256").update(namespace).digest().subarray(0, 16);
28912
+ const hash = createHash5("sha1").update(ns).update(name).digest();
28832
28913
  const bytes = Buffer.from(hash.subarray(0, 16));
28833
28914
  bytes[6] = bytes[6] & 15 | 80;
28834
28915
  bytes[8] = bytes[8] & 63 | 128;
@@ -29190,7 +29271,7 @@ var init_exec_tool = __esm(() => {
29190
29271
  });
29191
29272
 
29192
29273
  // src/code-mode/hashes.ts
29193
- import { createHash as createHash5 } from "crypto";
29274
+ import { createHash as createHash6 } from "crypto";
29194
29275
  function withoutCacheMarkers(value) {
29195
29276
  if (Array.isArray(value))
29196
29277
  return value.map(withoutCacheMarkers);
@@ -29213,7 +29294,7 @@ function canonicalJson(value) {
29213
29294
  return `{${body}}`;
29214
29295
  }
29215
29296
  function inputHash(input) {
29216
- return createHash5("sha256").update(canonicalJson(input ?? {})).digest("hex");
29297
+ return createHash6("sha256").update(canonicalJson(input ?? {})).digest("hex");
29217
29298
  }
29218
29299
  function compareIds(a, b) {
29219
29300
  const da = decodeNestedId(a);
@@ -29224,7 +29305,7 @@ function compareIds(a, b) {
29224
29305
  }
29225
29306
  function batchHash(entries) {
29226
29307
  const ordered = [...entries].sort((a, b) => compareIds(a.toolUseId, b.toolUseId));
29227
- const hash = createHash5("sha256");
29308
+ const hash = createHash6("sha256");
29228
29309
  for (const entry of ordered) {
29229
29310
  const canonical = entry.result ? canonicalJson([
29230
29311
  entry.toolUseId,
@@ -29238,7 +29319,7 @@ function batchHash(entries) {
29238
29319
  return hash.digest("hex");
29239
29320
  }
29240
29321
  function completionKey(batchHashes) {
29241
- const hash = createHash5("sha256");
29322
+ const hash = createHash6("sha256");
29242
29323
  for (const h of batchHashes) {
29243
29324
  hash.update(h);
29244
29325
  hash.update(`
@@ -33371,9 +33452,9 @@ var init_prelude = __esm(() => {
33371
33452
  });
33372
33453
 
33373
33454
  // src/code-mode/sandbox/script-runtime.ts
33374
- import { createHash as createHash6 } from "crypto";
33455
+ import { createHash as createHash7 } from "crypto";
33375
33456
  function seedNumber(seed) {
33376
- return createHash6("sha256").update(seed).digest().readUInt32BE(0);
33457
+ return createHash7("sha256").update(seed).digest().readUInt32BE(0);
33377
33458
  }
33378
33459
  function utf8Bytes2(text) {
33379
33460
  return Buffer.byteLength(text, "utf8");
@@ -33919,9 +34000,9 @@ var init_script_runtime = __esm(() => {
33919
34000
  });
33920
34001
 
33921
34002
  // src/code-mode/turn-records.ts
33922
- import { createHash as createHash7 } from "crypto";
34003
+ import { createHash as createHash8 } from "crypto";
33923
34004
  function sha256Hex2(text) {
33924
- return createHash7("sha256").update(text).digest("hex");
34005
+ return createHash8("sha256").update(text).digest("hex");
33925
34006
  }
33926
34007
  function recordKey(sessionKey, anchor) {
33927
34008
  return `${sessionKey}\x00${anchor}`;
@@ -34758,9 +34839,9 @@ var init_tool_results = __esm(() => {
34758
34839
  });
34759
34840
 
34760
34841
  // src/code-mode/transliterate.ts
34761
- import { createHash as createHash8 } from "crypto";
34842
+ import { createHash as createHash9 } from "crypto";
34762
34843
  function transliteratedCallId(firstToolUseId) {
34763
- return `call_${createHash8("sha256").update(firstToolUseId).digest("hex").slice(0, 32)}`;
34844
+ return `call_${createHash9("sha256").update(firstToolUseId).digest("hex").slice(0, 32)}`;
34764
34845
  }
34765
34846
  function callExpression(use, names) {
34766
34847
  const name = typeof use.name === "string" ? use.name : "";
@@ -34834,12 +34915,12 @@ function relayNestedInput(block, repair) {
34834
34915
  }
34835
34916
 
34836
34917
  // src/code-mode/input-builder.ts
34837
- import { createHash as createHash9 } from "crypto";
34918
+ import { createHash as createHash10 } from "crypto";
34838
34919
  function blocksOf2(message) {
34839
34920
  return message && Array.isArray(message.content) ? message.content : [];
34840
34921
  }
34841
34922
  function sha256Hex3(text) {
34842
- return createHash9("sha256").update(text).digest("hex");
34923
+ return createHash10("sha256").update(text).digest("hex");
34843
34924
  }
34844
34925
  function reasoningKey(item) {
34845
34926
  if (typeof item.id === "string" && item.id)
@@ -35590,7 +35671,7 @@ var init_stores = __esm(() => {
35590
35671
  });
35591
35672
 
35592
35673
  // src/code-mode/request.ts
35593
- import { createHash as createHash10 } from "crypto";
35674
+ import { createHash as createHash11 } from "crypto";
35594
35675
  function isLiteFallbackActive(model, now = Date.now()) {
35595
35676
  const until = liteFallbackUntil.get(model.toLowerCase());
35596
35677
  if (until === undefined)
@@ -35633,7 +35714,7 @@ function applyCodeModeToPayload(payload, ctx) {
35633
35714
  if (shape === "lite") {
35634
35715
  const reasoning = liteReasoning(payload, ctx.modelInfo);
35635
35716
  if (reasoning) {
35636
- const toolsHash = createHash10("sha256").update(JSON.stringify(ctx.execTool)).digest("hex");
35717
+ const toolsHash = createHash11("sha256").update(JSON.stringify(ctx.execTool)).digest("hex");
35637
35718
  payload.reasoning = reasoning;
35638
35719
  delete payload.tools;
35639
35720
  delete payload.instructions;
@@ -37911,7 +37992,7 @@ var init_output_capture = __esm(() => {
37911
37992
  });
37912
37993
 
37913
37994
  // src/hooks/telemetry/aggregate.ts
37914
- import { createHash as createHash11, randomBytes as randomBytes6 } from "crypto";
37995
+ import { createHash as createHash12, randomBytes as randomBytes6 } from "crypto";
37915
37996
  import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync11 } from "fs";
37916
37997
  import { homedir as homedir19 } from "os";
37917
37998
  import { dirname as dirname11, join as join19 } from "path";
@@ -37935,7 +38016,7 @@ function contextFillPct(peakTokens, window2 = enforcedContextWindow) {
37935
38016
  return Math.min(100, Math.max(0, Math.round(peakTokens / window2 * 100)));
37936
38017
  }
37937
38018
  function hashSessionId(rawSessionId, model) {
37938
- return createHash11("sha256").update(`${SESSION_SALT}:${rawSessionId}:${model}`).digest("hex");
38019
+ return createHash12("sha256").update(`${SESSION_SALT}:${rawSessionId}:${model}`).digest("hex");
37939
38020
  }
37940
38021
  function setTelemetryConsent(value) {
37941
38022
  consent = value;
@@ -42128,7 +42209,7 @@ class AntigravityCredentialProvider {
42128
42209
  const token = readSharedAntigravityToken();
42129
42210
  if (!token)
42130
42211
  return;
42131
- const lineage = token.refresh_token ? `refresh:${token.refresh_token}` : token.access_token ? `access:${token.access_token}` : undefined;
42212
+ const lineage = antigravityTokenLineageMaterial(token);
42132
42213
  return lineage ? `${lineage}
42133
42214
  ${antigravityHost()}` : undefined;
42134
42215
  }
@@ -44741,7 +44822,7 @@ var init_dist12 = __esm(() => {
44741
44822
 
44742
44823
  // src/auth/codex-pkce.ts
44743
44824
  import { exec as exec4 } from "child_process";
44744
- import { createHash as createHash12, randomBytes as randomBytes7 } from "crypto";
44825
+ import { createHash as createHash13, randomBytes as randomBytes7 } from "crypto";
44745
44826
  import { createServer } from "http";
44746
44827
  import { promisify as promisify3 } from "util";
44747
44828
  function loginClaims(idToken) {
@@ -44853,7 +44934,7 @@ function waitForCallback(options, deps) {
44853
44934
  async function loginCodexPkce(deps = {}) {
44854
44935
  log("[CodexOAuth] Starting OAuth login flow");
44855
44936
  const verifier = randomBytes7(64).toString("base64url");
44856
- const challenge = createHash12("sha256").update(verifier).digest("base64url");
44937
+ const challenge = createHash13("sha256").update(verifier).digest("base64url");
44857
44938
  const state = randomBytes7(32).toString("base64url");
44858
44939
  const options = {
44859
44940
  port: 1455,
@@ -48533,10 +48614,6 @@ var init_dynamic_models_catalog_store = __esm(() => {
48533
48614
 
48534
48615
  // src/providers/dynamic-models-catalog.ts
48535
48616
  import { createHmac as createHmac2, randomBytes as randomBytes11 } from "crypto";
48536
- function isPersistedListProvider(provider) {
48537
- const def = getProviderByName(provider);
48538
- return def !== undefined && def.modelDiscovery !== undefined && !def.isLocal && (def.tier === "subscription" || def.tier === "dynamic-subscription");
48539
- }
48540
48617
  function nowOf2(opts) {
48541
48618
  return opts?.now ? opts.now() : Date.now();
48542
48619
  }
@@ -48740,6 +48817,7 @@ var init_dynamic_models_catalog = __esm(() => {
48740
48817
  inFlight4 = new Map;
48741
48818
  listeners = new Set;
48742
48819
  credentials.onInvalidate((name) => {
48820
+ invalidateModelDiscovery(name);
48743
48821
  if (name) {
48744
48822
  identityMemo.delete(name);
48745
48823
  liveMemory.delete(name);
@@ -50183,6 +50261,7 @@ var init_devin_request = __esm(() => {
50183
50261
  });
50184
50262
 
50185
50263
  // src/providers/devin/devin-models.ts
50264
+ import { createHash as createHash14 } from "crypto";
50186
50265
  function unaryMetadata(apiKey) {
50187
50266
  return msg(bytes(1, "chisel"), bytes(2, DEVIN_CLI_VERSION), bytes(3, apiKey), bytes(4, "en"), bytes(5, process.platform), bytes(7, DEVIN_CLI_VERSION));
50188
50267
  }
@@ -50370,20 +50449,25 @@ function decodeAllowedUids(body) {
50370
50449
  }
50371
50450
  return uids;
50372
50451
  }
50452
+ function hashApiKey(apiKey) {
50453
+ return createHash14("sha256").update(apiKey).digest("hex");
50454
+ }
50373
50455
  async function getServedDevinModels(opts) {
50374
50456
  const now = Date.now();
50375
- if (!opts?.force && modelsCatalogCache && now - modelsCatalogCacheAt < MODELS_CATALOG_TTL_MS)
50376
- return modelsCatalogCache;
50377
50457
  const apiKey = opts?.apiKey ?? readDevinApiKey();
50378
50458
  if (!apiKey)
50379
- return modelsCatalogCache ?? [];
50459
+ return [];
50460
+ const keyHash = hashApiKey(apiKey);
50461
+ const sameKeyCache = modelsCatalogCacheKeyHash === keyHash ? modelsCatalogCache : null;
50462
+ if (!opts?.force && sameKeyCache && now - modelsCatalogCacheAt < MODELS_CATALOG_TTL_MS)
50463
+ return sameKeyCache;
50380
50464
  try {
50381
50465
  const [configs, allowed] = await Promise.all([
50382
50466
  fetchDevinModelConfigs(apiKey),
50383
50467
  fetchDevinAllowedUids(apiKey)
50384
50468
  ]);
50385
50469
  if (configs.length === 0)
50386
- return modelsCatalogCache ?? [];
50470
+ return sameKeyCache ?? [];
50387
50471
  const entitled = new Set(allowed);
50388
50472
  const served = configs.filter((config) => config.contextWindow > 0 && (entitled.size === 0 || entitled.has(config.uid)));
50389
50473
  if (entitled.size === 0) {
@@ -50391,13 +50475,14 @@ async function getServedDevinModels(opts) {
50391
50475
  }
50392
50476
  modelsCatalogCache = served;
50393
50477
  modelsCatalogCacheAt = now;
50478
+ modelsCatalogCacheKeyHash = keyHash;
50394
50479
  return served;
50395
50480
  } catch (err) {
50396
50481
  log(`[Devin] served-model discovery error: ${err}`);
50397
- return modelsCatalogCache ?? [];
50482
+ return sameKeyCache ?? [];
50398
50483
  }
50399
50484
  }
50400
- var MODEL_CONFIGS_PATH = "/exa.api_server_pb.ApiServerService/GetCliModelConfigs", TEAM_SETTINGS_PATH = "/exa.seat_management_pb.SeatManagementService/GetCliTeamSettings", MODELS_CATALOG_TTL_MS, UNARY_TIMEOUT_MS = 1e4, modelsCatalogCache = null, modelsCatalogCacheAt = 0;
50485
+ var MODEL_CONFIGS_PATH = "/exa.api_server_pb.ApiServerService/GetCliModelConfigs", TEAM_SETTINGS_PATH = "/exa.seat_management_pb.SeatManagementService/GetCliTeamSettings", MODELS_CATALOG_TTL_MS, UNARY_TIMEOUT_MS = 1e4, modelsCatalogCache = null, modelsCatalogCacheAt = 0, modelsCatalogCacheKeyHash = null;
50401
50486
  var init_devin_models = __esm(() => {
50402
50487
  init_logger();
50403
50488
  init_devin_credentials();
@@ -50863,6 +50948,7 @@ var init_model_discovery_builtins = __esm(() => {
50863
50948
  });
50864
50949
 
50865
50950
  // src/providers/model-discovery.ts
50951
+ import { createHash as createHash15 } from "crypto";
50866
50952
  function toModelsCatalogEntry(model) {
50867
50953
  const { id, ...rest } = model;
50868
50954
  return { wireId: id, ...rest };
@@ -50873,6 +50959,10 @@ function registerModelDiscoveryFetcher(format, fetcher) {
50873
50959
  function getModelDiscoveryFetcher(format) {
50874
50960
  return _fetchers.get(format);
50875
50961
  }
50962
+ async function accountFingerprint(providerName) {
50963
+ const identity = await credentials.accountIdentity(providerName, { allowOpPrompt: false });
50964
+ return identity ? createHash15("sha256").update(identity).digest("hex") : undefined;
50965
+ }
50876
50966
  function recordFailure(failure) {
50877
50967
  _failures.set(failure.provider, failure);
50878
50968
  log(`[model-discovery:${failure.provider}] ${describeDiscoveryFailure(failure)}`);
@@ -50910,15 +51000,20 @@ function describeDiscoveryFailure(failure) {
50910
51000
  return `the endpoint answered${at} but listed no models`;
50911
51001
  }
50912
51002
  }
51003
+ function invalidationCount(providerName) {
51004
+ return invalidationsOfAll + (invalidationsByProvider.get(providerName) ?? 0);
51005
+ }
50913
51006
  function invalidateModelDiscovery(provider) {
50914
51007
  if (provider) {
50915
51008
  _cache2.delete(provider);
50916
51009
  _failures.delete(provider);
50917
51010
  coldRefreshes.delete(provider);
51011
+ invalidationsByProvider.set(provider, (invalidationsByProvider.get(provider) ?? 0) + 1);
50918
51012
  } else {
50919
51013
  _cache2.clear();
50920
51014
  _failures.clear();
50921
51015
  coldRefreshes.clear();
51016
+ invalidationsOfAll++;
50922
51017
  }
50923
51018
  }
50924
51019
  function registryModelsEndpoint(providerName, def) {
@@ -51041,7 +51136,6 @@ async function discoverViaFetcher(providerName, format) {
51041
51136
  }
51042
51137
  _failures.delete(providerName);
51043
51138
  log(`[model-discovery:${providerName}] discovered ${models.length} models`);
51044
- _cache2.set(providerName, { models, expiresAt: Date.now() + CACHE_TTL_MS2 });
51045
51139
  return { kind: "served", models };
51046
51140
  }
51047
51141
  async function discoverProviderModelsCatalog(providerName) {
@@ -51075,9 +51169,32 @@ function peekDiscoveredModels(providerName) {
51075
51169
  return cached && cached.expiresAt > Date.now() ? cached.models : undefined;
51076
51170
  }
51077
51171
  async function discoverEveryServedModel(providerName) {
51172
+ if (!getProviderByName(providerName)?.modelDiscovery) {
51173
+ return { kind: "unsupported", reason: "no-descriptor" };
51174
+ }
51175
+ const invalidationsBefore = invalidationCount(providerName);
51176
+ const perAccount = isPersistedListProvider(providerName);
51177
+ const accountBefore = perAccount ? await accountFingerprint(providerName) : undefined;
51078
51178
  const cached = _cache2.get(providerName);
51079
- if (cached && cached.expiresAt > Date.now())
51179
+ if (cached && cached.expiresAt > Date.now() && cached.account === accountBefore) {
51080
51180
  return { kind: "served", models: cached.models };
51181
+ }
51182
+ const outcome = await fetchServedModels(providerName);
51183
+ if (outcome.kind !== "served")
51184
+ return outcome;
51185
+ const accountAfter = perAccount ? await accountFingerprint(providerName) : undefined;
51186
+ if (accountBefore && accountAfter && accountBefore !== accountAfter)
51187
+ return outcome;
51188
+ if (invalidationCount(providerName) !== invalidationsBefore)
51189
+ return outcome;
51190
+ _cache2.set(providerName, {
51191
+ models: outcome.models,
51192
+ expiresAt: Date.now() + CACHE_TTL_MS2,
51193
+ account: accountAfter ?? accountBefore
51194
+ });
51195
+ return outcome;
51196
+ }
51197
+ async function fetchServedModels(providerName) {
51081
51198
  const def = getProviderByName(providerName);
51082
51199
  const descriptor = def?.modelDiscovery;
51083
51200
  if (!def || !descriptor)
@@ -51171,7 +51288,6 @@ async function discoverEveryServedModel(providerName) {
51171
51288
  const models = parsed.models;
51172
51289
  _failures.delete(providerName);
51173
51290
  log(`[model-discovery:${providerName}] discovered ${models.length} models from ${endpoint}: ` + models.map((m) => `${m.id}(${m.contextWindow ?? "?"})`).join(", "));
51174
- _cache2.set(providerName, { models, expiresAt: Date.now() + CACHE_TTL_MS2 });
51175
51291
  return { kind: "served", models };
51176
51292
  }
51177
51293
  async function discoverProviderModels(providerName) {
@@ -51234,7 +51350,7 @@ function rankDiscoveredModels(models) {
51234
51350
  return diff !== 0 ? diff : compareByReleaseDateDesc(a, b);
51235
51351
  });
51236
51352
  }
51237
- var _fetchers, CACHE_TTL_MS2, FETCH_TIMEOUT_MS3 = 5000, _cache2, _failures, coldRefreshes, MIN_CREATED_SECONDS = 946684800, MAX_CREATED_SECONDS = 4102444800, CONTINUATION_FIELDS, LIVE_DISCOVERY_BOUND_MS = 2000;
51353
+ var _fetchers, CACHE_TTL_MS2, FETCH_TIMEOUT_MS3 = 5000, _cache2, _failures, coldRefreshes, invalidationsByProvider, invalidationsOfAll = 0, MIN_CREATED_SECONDS = 946684800, MAX_CREATED_SECONDS = 4102444800, CONTINUATION_FIELDS, LIVE_DISCOVERY_BOUND_MS = 2000;
51238
51354
  var init_model_discovery = __esm(() => {
51239
51355
  init_authority();
51240
51356
  init_logger();
@@ -51245,6 +51361,7 @@ var init_model_discovery = __esm(() => {
51245
51361
  _cache2 = new Map;
51246
51362
  _failures = new Map;
51247
51363
  coldRefreshes = new Map;
51364
+ invalidationsByProvider = new Map;
51248
51365
  CONTINUATION_FIELDS = ["has_more", "next", "next_page", "next_page_token"];
51249
51366
  });
51250
51367
 
@@ -59790,12 +59907,12 @@ var init_ollamacloud = __esm(() => {
59790
59907
  });
59791
59908
 
59792
59909
  // src/providers/transport/conversation-key.ts
59793
- import { createHash as createHash13, randomBytes as randomBytes13 } from "crypto";
59910
+ import { createHash as createHash16, randomBytes as randomBytes13 } from "crypto";
59794
59911
  function conversationKey(claudeRequest) {
59795
59912
  const sessionId = extractSessionId(claudeRequest);
59796
59913
  if (!sessionId)
59797
59914
  return `claudish_${FALLBACK_CONVERSATION_KEY}`;
59798
- return `claudish_${createHash13("sha256").update(sessionId).digest("hex").slice(0, 32)}`;
59915
+ return `claudish_${createHash16("sha256").update(sessionId).digest("hex").slice(0, 32)}`;
59799
59916
  }
59800
59917
  var FALLBACK_CONVERSATION_KEY;
59801
59918
  var init_conversation_key = __esm(() => {
@@ -61315,6 +61432,10 @@ function getProviderByName(name) {
61315
61432
  return builtin;
61316
61433
  return getRuntimeProviders().get(name);
61317
61434
  }
61435
+ function isPersistedListProvider(provider) {
61436
+ const def = getProviderByName(provider);
61437
+ return def !== undefined && def.modelDiscovery !== undefined && !def.isLocal && (def.tier === "subscription" || def.tier === "dynamic-subscription");
61438
+ }
61318
61439
  function getApiKeyInfo(providerName) {
61319
61440
  const def = getProviderByName(providerName);
61320
61441
  if (!def)
@@ -74653,14 +74774,14 @@ var init_prehydrate = __esm(() => {
74653
74774
  });
74654
74775
 
74655
74776
  // src/auth/claude-code-facts.ts
74656
- import { createHash as createHash14 } from "crypto";
74777
+ import { createHash as createHash17 } from "crypto";
74657
74778
  import { homedir as homedir33 } from "os";
74658
74779
  import { isAbsolute as isAbsolute2, resolve as resolve4 } from "path";
74659
74780
  function defaultConfigDir(env) {
74660
74781
  return resolve4(env.HOME || homedir33(), ".claude");
74661
74782
  }
74662
74783
  function configDirHash(configDir) {
74663
- return createHash14("sha256").update(configDir).digest("hex").slice(0, 8);
74784
+ return createHash17("sha256").update(configDir).digest("hex").slice(0, 8);
74664
74785
  }
74665
74786
  function claudeCodeKeychainService(env = process.env) {
74666
74787
  const raw = env.CLAUDE_CONFIG_DIR?.trim();
@@ -122069,14 +122190,14 @@ function reportFetchFailure(state, cache, now) {
122069
122190
  if (state === "stale") {
122070
122191
  const ageMs = now.getTime() - Date.parse(cache.lastUpdated);
122071
122192
  const ageStr = humanizeAge(ageMs);
122072
- process.stderr.write(`WARNING: Catalog stale (${ageStr}). Using cached version. Run \`claudish --models-refresh\` to retry.
122193
+ process.stderr.write(`WARNING: The ${MODEL_CATALOG_NAME} is stale (${ageStr}). Using cached version. Run \`claudish --models-refresh\` to retry.
122073
122194
  `);
122074
122195
  return "warned";
122075
122196
  }
122076
122197
  if (state === "fresh") {
122077
122198
  const ageMs = now.getTime() - Date.parse(cache.lastUpdated);
122078
122199
  const ageStr = humanizeAge(ageMs);
122079
- process.stderr.write(`WARNING: Catalog refresh failed (cache age ${ageStr}). Using cached version.
122200
+ process.stderr.write(`WARNING: Could not refresh the ${MODEL_CATALOG_NAME} (cache age ${ageStr}). Using cached version.
122080
122201
  `);
122081
122202
  return "warned";
122082
122203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "14.18.1",
3
+ "version": "14.18.2",
4
4
  "description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -71,10 +71,10 @@
71
71
  "ai"
72
72
  ],
73
73
  "optionalDependencies": {
74
- "@claudish/magmux-darwin-arm64": "14.18.1",
75
- "@claudish/magmux-darwin-x64": "14.18.1",
76
- "@claudish/magmux-linux-arm64": "14.18.1",
77
- "@claudish/magmux-linux-x64": "14.18.1"
74
+ "@claudish/magmux-darwin-arm64": "14.18.2",
75
+ "@claudish/magmux-darwin-x64": "14.18.2",
76
+ "@claudish/magmux-linux-arm64": "14.18.2",
77
+ "@claudish/magmux-linux-x64": "14.18.2"
78
78
  },
79
79
  "author": "Jack Rudenko <i@madappgang.com>",
80
80
  "license": "MIT",