claudish 7.45.0 → 7.46.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 +284 -195
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -729,7 +729,7 @@ var init_onepassword_config = __esm(() => {
729
729
  });
730
730
 
731
731
  // src/version.ts
732
- var VERSION = "7.45.0";
732
+ var VERSION = "7.46.0";
733
733
 
734
734
  // src/logger.ts
735
735
  var exports_logger = {};
@@ -1219,11 +1219,6 @@ function writeJsonlCapped(payload) {
1219
1219
  `);
1220
1220
  }
1221
1221
  }
1222
- function printSlowLine(payload) {
1223
- const top = [...payload.spans].sort((a, b) => b.durMs - a.durMs).slice(0, 3).map((s) => `${s.name} ${fmtDur(s.durMs)}${fmtWaitExec(s.meta)}`);
1224
- const detail = top.length > 0 ? ` \u2014 ${top.join(", ")}` : "";
1225
- seams.stderr(`[claudish] slow start ${fmtDur(payload.totalMs)}${detail} \u2026 full data: ` + `${displayPath(seams.outPath)} (CLAUDISH_STARTUP_TRACE=1 for live detail)`);
1226
- }
1227
1222
  function printTable(payload) {
1228
1223
  seams.stderr(`[claudish] startup trace (${payload.argvKind}) \u2014 total ${fmtDur(payload.totalMs)}` + ` \xB7 auth ${payload.authKind} \xB7 v${payload.version}`);
1229
1224
  seams.stderr(" start dur span");
@@ -1234,7 +1229,7 @@ function printTable(payload) {
1234
1229
  }
1235
1230
  seams.stderr(` metrics: ${displayPath(seams.outPath)}`);
1236
1231
  }
1237
- function finalizeStartupTrace(context, opts = {}) {
1232
+ function finalizeStartupTrace(context, _opts = {}) {
1238
1233
  try {
1239
1234
  if (finalized)
1240
1235
  return;
@@ -1254,8 +1249,6 @@ function finalizeStartupTrace(context, opts = {}) {
1254
1249
  try {
1255
1250
  if (terminalSuppressed) {} else if (traceModeOn()) {
1256
1251
  printTable(payload);
1257
- } else if (totalMs > seams.slowThresholdMs && !opts.quiet) {
1258
- printSlowLine(payload);
1259
1252
  }
1260
1253
  } catch {}
1261
1254
  } catch {}
@@ -1345,6 +1338,20 @@ function isAbandoned(path) {
1345
1338
  return true;
1346
1339
  return Date.now() - holder.at > timing.staleMs;
1347
1340
  }
1341
+ function peerHoldsHandshakeLock() {
1342
+ if (lastHandshake?.heldByUs)
1343
+ return false;
1344
+ const holder = readHolder(currentLockPath());
1345
+ if (!holder || holder.pid === process.pid)
1346
+ return false;
1347
+ if (!holderAlive(holder.pid))
1348
+ return false;
1349
+ if (Date.now() - holder.at > timing.staleMs)
1350
+ return false;
1351
+ if (lastHandshake && holder.at > lastHandshake.startedAt)
1352
+ return false;
1353
+ return true;
1354
+ }
1348
1355
  async function acquire(path) {
1349
1356
  const deadline = Date.now() + timing.timeoutMs;
1350
1357
  let madeDir = false;
@@ -1385,6 +1392,7 @@ function release(path) {
1385
1392
  async function withHandshakeLock(handshake) {
1386
1393
  if (process.env.CLAUDISH_NO_OP_HANDSHAKE_LOCK === "1") {
1387
1394
  trace("bypassed (CLAUDISH_NO_OP_HANDSHAKE_LOCK=1)");
1395
+ lastHandshake = { heldByUs: false, startedAt: Date.now() };
1388
1396
  return handshake();
1389
1397
  }
1390
1398
  const path = currentLockPath();
@@ -1396,6 +1404,7 @@ async function withHandshakeLock(handshake) {
1396
1404
  held = false;
1397
1405
  }
1398
1406
  trace(`${held ? "acquired" : "NOT held (timeout or unwritable)"} after ${Date.now() - t0}ms`);
1407
+ lastHandshake = { heldByUs: held, startedAt: t0 };
1399
1408
  try {
1400
1409
  return await handshake();
1401
1410
  } finally {
@@ -1404,7 +1413,7 @@ async function withHandshakeLock(handshake) {
1404
1413
  trace(`handshake done after ${Date.now() - t0}ms${held ? ", released" : ""}`);
1405
1414
  }
1406
1415
  }
1407
- var DEFAULT_STALE_MS = 120000, DEFAULT_TIMEOUT_MS = 45000, DEFAULT_POLL_MS = 60, timing, lockPath, sleep = (ms) => new Promise((r) => setTimeout(r, ms));
1416
+ var DEFAULT_STALE_MS = 120000, DEFAULT_TIMEOUT_MS = 45000, DEFAULT_POLL_MS = 60, timing, lockPath, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), lastHandshake;
1408
1417
  var init_onepassword_handshake_lock = __esm(() => {
1409
1418
  timing = {
1410
1419
  staleMs: DEFAULT_STALE_MS,
@@ -3897,6 +3906,7 @@ __export(exports_onepassword, {
3897
3906
  wasOpAuthorizationDenied: () => wasOpAuthorizationDenied,
3898
3907
  valueTail: () => valueTail,
3899
3908
  setScreenLockProbe: () => setScreenLockProbe,
3909
+ setPeerLockProbe: () => setPeerLockProbe,
3900
3910
  setLockRetryTiming: () => setLockRetryTiming,
3901
3911
  setAppLockProbe: () => setAppLockProbe,
3902
3912
  resolveSecretsPartial: () => resolveSecretsPartial,
@@ -3920,11 +3930,13 @@ __export(exports_onepassword, {
3920
3930
  listItems: () => listItems,
3921
3931
  isTransientSdkError: () => isTransientSdkError,
3922
3932
  isScreenLocked: () => isScreenLocked,
3933
+ isPeerHoldingPrompt: () => isPeerHoldingPrompt,
3923
3934
  isOpReference: () => isOpReference,
3924
3935
  isOpHydratedVar: () => isOpHydratedVar,
3925
3936
  isLockedDenial: () => isLockedDenial,
3926
3937
  isGlobImport: () => isGlobImport,
3927
3938
  isAppLocked: () => isAppLocked,
3939
+ humanizeOpError: () => humanizeOpError,
3928
3940
  globToRegExp: () => globToRegExp,
3929
3941
  getOpFailures: () => getOpFailures,
3930
3942
  filterGlobFields: () => filterGlobFields,
@@ -3938,6 +3950,7 @@ __export(exports_onepassword, {
3938
3950
  defaultAppLockProbe: () => defaultAppLockProbe,
3939
3951
  currentLockCause: () => currentLockCause,
3940
3952
  collectConfigImports: () => collectConfigImports,
3953
+ clearOpSkip: () => clearOpSkip,
3941
3954
  classifyLockedDenial: () => classifyLockedDenial,
3942
3955
  buildAuthError: () => buildAuthError,
3943
3956
  appLockedFromSettings: () => appLockedFromSettings,
@@ -3971,6 +3984,21 @@ function resetOpFailures() {
3971
3984
  function wasOpAuthorizationDenied() {
3972
3985
  return opSourceFailures.some((f) => /denied authorization/i.test(f.message));
3973
3986
  }
3987
+ function humanizeOpError(err) {
3988
+ const raw = (err instanceof Error ? err.message : String(err)).trim();
3989
+ if (/denied authorization/i.test(raw)) {
3990
+ const cause = currentLockCause();
3991
+ if (cause === "screen")
3992
+ return "your Mac is locked, so the approval prompt couldn't be shown";
3993
+ if (cause === "app")
3994
+ return "the 1Password app is locked, so it declined without prompting";
3995
+ if (cause === "peer")
3996
+ return "another claudish process is holding the 1Password prompt";
3997
+ return "the 1Password approval prompt was dismissed (or never answered)";
3998
+ }
3999
+ const unwrapped = raw.match(/Error\s*\{\s*msg:\s*(.*?)(?:,\s*inner:|\s*\})/s);
4000
+ return (unwrapped?.[1] ?? raw).trim();
4001
+ }
3974
4002
  function renderOpFailureNotice(envVar) {
3975
4003
  return renderOpFailureBlock(`for ${envVar} this run`);
3976
4004
  }
@@ -3997,6 +4025,12 @@ function renderOpFailureBlock(subject) {
3997
4025
  lines.push("");
3998
4026
  lines.push(" Fix: unlock 1Password (Touch ID is enough) and re-run.");
3999
4027
  lines.push(" To stop it re-locking mid-session, raise Settings \u2192 Security \u2192 auto-lock.");
4028
+ } else if (cause === "peer") {
4029
+ lines.push(" Another claudish process is at the 1Password prompt right now. 1Password");
4030
+ lines.push(" authorizes ONE client at a time and denies every peer instantly, so this");
4031
+ lines.push(" run lost a race rather than being refused.");
4032
+ lines.push("");
4033
+ lines.push(" Fix: approve the prompt in the other window, then re-run this one.");
4000
4034
  } else {
4001
4035
  lines.push(" The 1Password desktop app declined to release secrets. The approval prompt");
4002
4036
  lines.push(" was most likely dismissed.");
@@ -4373,11 +4407,19 @@ function setAppLockProbe(probe) {
4373
4407
  function isAppLocked() {
4374
4408
  return appLockProbe();
4375
4409
  }
4410
+ function setPeerLockProbe(probe) {
4411
+ peerLockProbe = probe ?? peerHoldsHandshakeLock;
4412
+ }
4413
+ function isPeerHoldingPrompt() {
4414
+ return peerLockProbe();
4415
+ }
4376
4416
  function currentLockCause() {
4377
4417
  if (isScreenLocked())
4378
4418
  return "screen";
4379
4419
  if (isAppLocked())
4380
4420
  return "app";
4421
+ if (isPeerHoldingPrompt())
4422
+ return "peer";
4381
4423
  return null;
4382
4424
  }
4383
4425
  function classifyLockedDenial(err, env = process.env) {
@@ -4395,23 +4437,28 @@ async function countdownForUnlock(round, rounds, cause) {
4395
4437
  const ttyOut = process.stderr.isTTY === true;
4396
4438
  const ttyIn = process.stdin.isTTY === true;
4397
4439
  let cancelled = false;
4440
+ let skipped = false;
4398
4441
  if (round === 1) {
4399
4442
  const explain = cause === "screen" ? `${bold("\uD83D\uDD10 1Password needs your OK \u2014 but your Mac is locked, so it can't ask.")}
4400
- Unlock your Mac and approve the popup. Claudish picks it up from there.` : `${bold("\uD83D\uDD10 1Password is locked, so it turned claudish away without asking you.")}
4443
+ Unlock your Mac and approve the popup. Claudish picks it up from there.` : cause === "app" ? `${bold("\uD83D\uDD10 1Password is locked, so it turned claudish away without asking you.")}
4401
4444
  Unlock 1Password (Touch ID is enough). Claudish retries on its own \u2014
4402
- no popup will appear until it's unlocked.`;
4445
+ no popup will appear until it's unlocked.` : `${bold("\uD83D\uDD10 Another claudish is already at the 1Password prompt.")}
4446
+ 1Password only lets one through at a time, so this run has to queue.
4447
+ Approve it in the other window (or wait \u2014 it usually takes a second).`;
4403
4448
  process.stderr.write(`
4404
4449
  ${explain}
4405
4450
 
4406
4451
  `);
4407
4452
  }
4408
- const stillLocked = () => cause === "screen" ? isScreenLocked() : isAppLocked();
4453
+ const stillLocked = () => cause === "screen" ? isScreenLocked() : cause === "app" ? isAppLocked() : isPeerHoldingPrompt();
4409
4454
  let restoreInput = () => {};
4410
4455
  if (ttyIn) {
4411
4456
  const onKey = (buf) => {
4412
4457
  const k = buf.toString();
4413
4458
  if (k === "\x1B" || k === "q" || k === "\x03")
4414
4459
  cancelled = true;
4460
+ if (k === "s" || k === "S")
4461
+ skipped = true;
4415
4462
  };
4416
4463
  const wasRaw = process.stdin.isRaw === true;
4417
4464
  try {
@@ -4427,14 +4474,20 @@ ${explain}
4427
4474
  restoreInput = () => {};
4428
4475
  }
4429
4476
  }
4430
- const stop = ttyIn ? "Esc to stop waiting" : "Ctrl-C to stop waiting";
4431
- const line = (secs) => dim(` waiting ${secs}s \xB7 try ${round} of ${rounds} \xB7 ${stop}`);
4477
+ const stop = ttyIn ? "Esc stop waiting" : "Ctrl-C stop waiting";
4478
+ const skip = ttyIn ? " \xB7 s skip 1Password" : "";
4479
+ const bar = (secs) => {
4480
+ const total = Math.max(1, lockRetrySeconds);
4481
+ const filled = Math.round((total - secs) / total * 10);
4482
+ return `${"\u2501".repeat(filled)}${"\u2500".repeat(Math.max(0, 10 - filled))}`;
4483
+ };
4484
+ const line = (secs) => dim(` ${bar(secs)} ${secs}s \xB7 try ${round}/${rounds} \xB7 ${stop}${skip}`);
4432
4485
  if (!ttyOut)
4433
4486
  process.stderr.write(`${line(lockRetrySeconds)}
4434
4487
  `);
4435
4488
  try {
4436
4489
  for (let remaining = lockRetrySeconds;remaining > 0; remaining--) {
4437
- if (cancelled)
4490
+ if (cancelled || skipped)
4438
4491
  break;
4439
4492
  if (!stillLocked())
4440
4493
  break;
@@ -4447,6 +4500,12 @@ ${explain}
4447
4500
  if (ttyOut)
4448
4501
  process.stderr.write("\r\x1B[2K");
4449
4502
  }
4503
+ if (skipped) {
4504
+ process.stderr.write(` Skipping 1Password for this run. Keys already in your environment still work;
4505
+ ` + ` anything only 1Password has will report as missing.
4506
+ `);
4507
+ return "skip";
4508
+ }
4450
4509
  if (cancelled) {
4451
4510
  process.stderr.write(` OK, not waiting. You can unlock and re-run any time.
4452
4511
  `);
@@ -4454,6 +4513,17 @@ ${explain}
4454
4513
  }
4455
4514
  return "retry";
4456
4515
  }
4516
+ function latchOpSkip() {
4517
+ opSkipLatchedByPrompt = true;
4518
+ process.env.CLAUDISH_DISABLE_OP = "1";
4519
+ }
4520
+ function clearOpSkip() {
4521
+ if (!opSkipLatchedByPrompt)
4522
+ return false;
4523
+ opSkipLatchedByPrompt = false;
4524
+ delete process.env.CLAUDISH_DISABLE_OP;
4525
+ return true;
4526
+ }
4457
4527
  async function withSdkRetry(op, label = "op:sdk-op") {
4458
4528
  for (let round = 1;; round++) {
4459
4529
  try {
@@ -4462,7 +4532,12 @@ async function withSdkRetry(op, label = "op:sdk-op") {
4462
4532
  const cause = classifyLockedDenial(err);
4463
4533
  if (round > LOCK_RETRY_ROUNDS || cause === null)
4464
4534
  throw err;
4465
- if (await countdownForUnlock(round, LOCK_RETRY_ROUNDS, cause) === "cancel")
4535
+ const choice = await countdownForUnlock(round, LOCK_RETRY_ROUNDS, cause);
4536
+ if (choice === "skip") {
4537
+ latchOpSkip();
4538
+ throw err;
4539
+ }
4540
+ if (choice === "cancel")
4466
4541
  throw err;
4467
4542
  resetSdkClientCache();
4468
4543
  }
@@ -4680,7 +4755,7 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
4680
4755
  } catch {
4681
4756
  return false;
4682
4757
  }
4683
- }, screenLockProbe, defaultAppLockProbe = () => false, appLockProbe, OP_PROBE_TIMEOUT_MS = 5000, defaultOpAccountLister = () => {
4758
+ }, screenLockProbe, defaultAppLockProbe = () => false, appLockProbe, peerLockProbe, opSkipLatchedByPrompt = false, OP_PROBE_TIMEOUT_MS = 5000, defaultOpAccountLister = () => {
4684
4759
  try {
4685
4760
  const res = spawnSync("op", ["--cache=false", "account", "list", "--format=json"], {
4686
4761
  encoding: "utf-8",
@@ -4723,6 +4798,7 @@ var init_onepassword = __esm(() => {
4723
4798
  lockRetrySeconds = LOCK_RETRY_SECONDS;
4724
4799
  screenLockProbe = defaultScreenLockProbe;
4725
4800
  appLockProbe = defaultAppLockProbe;
4801
+ peerLockProbe = peerHoldsHandshakeLock;
4726
4802
  });
4727
4803
 
4728
4804
  // src/auth/credentials/op-source.ts
@@ -4859,6 +4935,8 @@ function readConfigRaw() {
4859
4935
  }
4860
4936
  }
4861
4937
  function hasOpSources() {
4938
+ if (process.env.CLAUDISH_DISABLE_OP === "1")
4939
+ return false;
4862
4940
  if (sniffed !== undefined)
4863
4941
  return sniffed;
4864
4942
  sniffed = computeHasOpSources();
@@ -5137,7 +5215,8 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5137
5215
  resolveSecrets: resolveSecrets2,
5138
5216
  recordOpHydratedVars: recordOpHydratedVars2,
5139
5217
  recordOpFailure: recordOpFailure2,
5140
- withSdkRetry: withSdkRetry2
5218
+ withSdkRetry: withSdkRetry2,
5219
+ humanizeOpError: humanizeOpError2
5141
5220
  } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
5142
5221
  const cfg = readConfigRaw();
5143
5222
  const out = {};
@@ -5198,7 +5277,7 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5198
5277
  }
5199
5278
  } catch (globErr) {
5200
5279
  const m = globErr instanceof Error ? globErr.message : String(globErr);
5201
- warnOnce(`[claudish] 1Password import skipped: ${m}`);
5280
+ warnOnce(`[claudish] 1Password import skipped: ${humanizeOpError2(globErr)}`);
5202
5281
  recordOpFailure2({ kind: "import", source: globPath, message: m });
5203
5282
  }
5204
5283
  }
@@ -5239,7 +5318,7 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5239
5318
  }
5240
5319
  } catch (envErr) {
5241
5320
  const m = envErr instanceof Error ? envErr.message : String(envErr);
5242
- warnOnce(`[claudish] 1Password environment skipped: ${m}`);
5321
+ warnOnce(`[claudish] 1Password environment skipped: ${humanizeOpError2(envErr)}`);
5243
5322
  recordOpFailure2({ kind: "environment", source: envId, message: m });
5244
5323
  }
5245
5324
  }
@@ -5251,7 +5330,7 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5251
5330
  return out;
5252
5331
  }
5253
5332
  const message = err instanceof Error ? err.message : String(err);
5254
- warnOnce(`[claudish] 1Password secret resolution failed: ${message}`);
5333
+ warnOnce(`[claudish] 1Password secret resolution failed: ${humanizeOpError2(err)}`);
5255
5334
  recordOpFailure2({ kind: "reference", message });
5256
5335
  if (onAuthFailure === "throw")
5257
5336
  throw err;
@@ -28811,7 +28890,9 @@ var init_remote_provider_types = __esm(() => {
28811
28890
  "kimi-coding",
28812
28891
  "glm-coding",
28813
28892
  "qwen-cloud",
28814
- "devin"
28893
+ "devin",
28894
+ "antigravity",
28895
+ "sakana-subscription"
28815
28896
  ]);
28816
28897
  PROVIDER_ALIAS = {
28817
28898
  google: "gemini",
@@ -29911,23 +29992,33 @@ import { execFileSync } from "child_process";
29911
29992
  import { existsSync as existsSync7 } from "fs";
29912
29993
  import { homedir as homedir9 } from "os";
29913
29994
  import { join as join9 } from "path";
29995
+ function invalidateReadStoreMemo() {
29996
+ cachedRawStore = null;
29997
+ }
29914
29998
  function defaultReadStore() {
29915
29999
  if (process.platform !== "darwin") {
29916
30000
  logStderr("[Antigravity] Shared token store is macOS-only for now (other keyring backends are a follow-up).");
29917
30001
  return null;
29918
30002
  }
30003
+ const now = Date.now();
30004
+ if (cachedRawStore && now - cachedRawStore.at < READ_STORE_TTL_MS)
30005
+ return cachedRawStore.value;
30006
+ let value = null;
29919
30007
  try {
29920
30008
  const out = execFileSync("security", ["find-generic-password", "-s", KC_SERVICE, "-a", KC_ACCOUNT, "-w"], { encoding: "utf8" });
29921
30009
  const trimmed2 = out.trim();
29922
- return trimmed2.length > 0 ? trimmed2 : null;
30010
+ value = trimmed2.length > 0 ? trimmed2 : null;
29923
30011
  } catch {
29924
- return null;
30012
+ value = null;
29925
30013
  }
30014
+ cachedRawStore = { at: now, value };
30015
+ return value;
29926
30016
  }
29927
30017
  function defaultWriteStore(rawValue) {
29928
30018
  if (process.platform !== "darwin") {
29929
30019
  throw new Error("[Antigravity] Cannot write the shared token store on a non-macOS platform.");
29930
30020
  }
30021
+ invalidateReadStoreMemo();
29931
30022
  execFileSync("security", ["add-generic-password", "-U", "-s", KC_SERVICE, "-a", KC_ACCOUNT, "-w", rawValue], { stdio: ["ignore", "ignore", "ignore"] });
29932
30023
  }
29933
30024
  function locateAgyBinary() {
@@ -29942,6 +30033,7 @@ function locateAgyBinary() {
29942
30033
  function defaultDeleteStore() {
29943
30034
  if (process.platform !== "darwin")
29944
30035
  return;
30036
+ invalidateReadStoreMemo();
29945
30037
  try {
29946
30038
  execFileSync("security", ["delete-generic-password", "-s", KC_SERVICE, "-a", KC_ACCOUNT], {
29947
30039
  stdio: ["ignore", "ignore", "ignore"]
@@ -29957,7 +30049,9 @@ function defaultRunAgyRefresh() {
29957
30049
  stdio: ["ignore", "ignore", "ignore"],
29958
30050
  timeout: AGY_REFRESH_TIMEOUT_MS
29959
30051
  });
29960
- } catch {}
30052
+ } catch {} finally {
30053
+ invalidateReadStoreMemo();
30054
+ }
29961
30055
  }
29962
30056
  function parseRecord(raw) {
29963
30057
  if (!raw)
@@ -30035,8 +30129,9 @@ function getValidAntigravityAccessToken(deps = defaultDeps) {
30035
30129
  function _resetAntigravityTokenState() {
30036
30130
  inFlight = null;
30037
30131
  cachedHasToken = null;
30132
+ invalidateReadStoreMemo();
30038
30133
  }
30039
- var KC_SERVICE = "gemini", KC_ACCOUNT = "antigravity", PREFIX = "go-keyring-base64:", EXPIRY_SKEW_MS = 120000, AGY_REFRESH_TIMEOUT_MS = 40000, defaultDeps, cachedHasToken = null, HAS_TOKEN_TTL_MS = 5000, inFlight = null;
30134
+ var KC_SERVICE = "gemini", KC_ACCOUNT = "antigravity", PREFIX = "go-keyring-base64:", EXPIRY_SKEW_MS = 120000, AGY_REFRESH_TIMEOUT_MS = 40000, READ_STORE_TTL_MS = 3000, cachedRawStore = null, defaultDeps, cachedHasToken = null, HAS_TOKEN_TTL_MS = 5000, inFlight = null;
30040
30135
  var init_antigravity_token = __esm(() => {
30041
30136
  init_logger();
30042
30137
  defaultDeps = {
@@ -64519,8 +64614,11 @@ __export(exports_model_selector, {
64519
64614
  promptForApiKey: () => promptForApiKey,
64520
64615
  pickerProviderToFirebaseSlug: () => pickerProviderToFirebaseSlug,
64521
64616
  isUserDeployedProvider: () => isUserDeployedProvider,
64617
+ isPickableProvider: () => isPickableProvider,
64618
+ getProviderFilterAliases: () => getProviderFilterAliases,
64522
64619
  confirmAction: () => confirmAction,
64523
64620
  compareByReleaseDateDesc: () => compareByReleaseDateDesc,
64621
+ buildProviderChoices: () => buildProviderChoices,
64524
64622
  buildExplicitModelSpec: () => buildExplicitModelSpec,
64525
64623
  buildDiscoveredModelRows: () => buildDiscoveredModelRows
64526
64624
  });
@@ -64679,6 +64777,18 @@ function dedupeModels(models) {
64679
64777
  }
64680
64778
  return deduped;
64681
64779
  }
64780
+ function dedupeByProviderSpec(provider, models) {
64781
+ const seen = new Set;
64782
+ const deduped = [];
64783
+ for (const model of models) {
64784
+ const spec = buildExplicitModelSpec(provider, resolveProviderExternalId(provider, model));
64785
+ if (seen.has(spec))
64786
+ continue;
64787
+ seen.add(spec);
64788
+ deduped.push(model);
64789
+ }
64790
+ return deduped;
64791
+ }
64682
64792
  function sortModelsNewestFirst(models) {
64683
64793
  return [...models].sort(compareByReleaseDateDesc);
64684
64794
  }
@@ -64729,6 +64839,16 @@ function formatModelChoiceAsSpec(model, spec, priceStr) {
64729
64839
  const dateStr = model.releaseDate ? `, ${model.releaseDate.slice(0, 7)}` : "";
64730
64840
  return `${spec} (${priceStr}, ${ctxStr}${capsStr}${dateStr})`;
64731
64841
  }
64842
+ function getProviderFilterAliases() {
64843
+ const aliases = {};
64844
+ for (const def of pickableProvidersInPickerOrder()) {
64845
+ aliases[def.name.toLowerCase()] = def.name;
64846
+ for (const shortcut of def.shortcuts) {
64847
+ aliases[shortcut.toLowerCase()] = def.name;
64848
+ }
64849
+ }
64850
+ return { ...aliases, ...PROVIDER_FILTER_ALIAS_EXTRA };
64851
+ }
64732
64852
  function parseProviderFilter(term, providers = []) {
64733
64853
  if (!term.startsWith("@")) {
64734
64854
  return { provider: null, searchTerm: term };
@@ -64744,7 +64864,7 @@ function parseProviderFilter(term, providers = []) {
64744
64864
  prefix = withoutAt.slice(0, spaceIdx);
64745
64865
  rest = withoutAt.slice(spaceIdx + 1).trim();
64746
64866
  }
64747
- const source = PROVIDER_FILTER_ALIASES[prefix.toLowerCase()];
64867
+ const source = getProviderFilterAliases()[prefix.toLowerCase()];
64748
64868
  if (source) {
64749
64869
  return { provider: source, searchTerm: rest };
64750
64870
  }
@@ -64752,7 +64872,7 @@ function parseProviderFilter(term, providers = []) {
64752
64872
  if (exactMatch) {
64753
64873
  return { provider: exactMatch.slug, searchTerm: rest };
64754
64874
  }
64755
- const partialMatch = Object.entries(PROVIDER_FILTER_ALIASES).find(([alias]) => alias.startsWith(prefix.toLowerCase()));
64875
+ const partialMatch = Object.entries(getProviderFilterAliases()).find(([alias]) => alias.startsWith(prefix.toLowerCase()));
64756
64876
  if (partialMatch) {
64757
64877
  return { provider: partialMatch[1], searchTerm: rest };
64758
64878
  }
@@ -64766,7 +64886,7 @@ async function fetchPickerModels(providerSlug, searchTerm, defaultModels, catalo
64766
64886
  if (providerSlug) {
64767
64887
  const firebaseSlug = pickerProviderToFirebaseSlug[providerSlug] ?? providerSlug;
64768
64888
  const vendorModels = await catalog.modelsByVendor(firebaseSlug);
64769
- const infos = sortModelsNewestFirst(dedupeModels(vendorModels.map(catalogModelToModelInfo)));
64889
+ const infos = dedupeByProviderSpec(providerSlug, sortModelsNewestFirst(dedupeModels(vendorModels.map(catalogModelToModelInfo))));
64770
64890
  if (!searchTerm)
64771
64891
  return infos;
64772
64892
  const needle = searchTerm.toLowerCase();
@@ -64784,6 +64904,7 @@ async function selectModel(options = {}) {
64784
64904
  let models;
64785
64905
  let recommendedModels = [];
64786
64906
  let pickerProviders = [];
64907
+ let interactiveProviderChoices = [];
64787
64908
  const remoteQueryCache = new Map;
64788
64909
  if (freeOnly) {
64789
64910
  models = await getFreeModels();
@@ -64798,7 +64919,8 @@ async function selectModel(options = {}) {
64798
64919
  const topModels = top100Result.status === "fulfilled" ? sortModelsNewestFirst(dedupeModels(top100Result.value.models.map(modelDocToModelInfo))) : [];
64799
64920
  recommendedModels = recommendedResult.status === "fulfilled" ? recommendedResult.value : [];
64800
64921
  models = topModels.length > 0 ? topModels : recommendedModels;
64801
- pickerProviders = toPickerProviders(await getInteractiveProviderChoices());
64922
+ interactiveProviderChoices = await getInteractiveProviderChoices();
64923
+ pickerProviders = toPickerProviders(interactiveProviderChoices);
64802
64924
  }
64803
64925
  const loadRemoteModels = async (providerSlug, searchTerm) => {
64804
64926
  const cacheKey = `${providerSlug || "__all__"}::${searchTerm}`;
@@ -64827,7 +64949,6 @@ async function selectModel(options = {}) {
64827
64949
  const cleanupKeypress = () => process.stdin.removeListener("data", onData);
64828
64950
  try {
64829
64951
  if (!freeOnly && !message && pickerProviders.length > 1) {
64830
- const interactiveProviderChoices = await getInteractiveProviderChoices();
64831
64952
  const providerChoices = [
64832
64953
  {
64833
64954
  name: "All providers",
@@ -64860,11 +64981,14 @@ async function selectModel(options = {}) {
64860
64981
  const { provider: filterProvider, searchTerm } = parseProviderFilter(normalizedTerm, pickerProviders);
64861
64982
  const effectiveProvider = filterProvider;
64862
64983
  const remoteModels = await loadRemoteModels(effectiveProvider, searchTerm);
64863
- return remoteModels.slice(0, 100).map((model) => ({
64864
- name: formatModelChoice(model, true),
64865
- value: effectiveProvider ? buildExplicitModelSpec(effectiveProvider, model.id) : model.id,
64866
- description: model.description?.slice(0, 160)
64867
- }));
64984
+ return remoteModels.slice(0, 100).map((model) => {
64985
+ const spec = effectiveProvider ? buildExplicitModelSpec(effectiveProvider, resolveProviderExternalId(effectiveProvider, model)) : model.id;
64986
+ return {
64987
+ name: effectiveProvider ? formatModelChoiceAsSpec(model, spec, resolveProviderDisplayPrice(effectiveProvider, model)) : formatModelChoice(model, true),
64988
+ value: spec,
64989
+ description: model.description?.slice(0, 160)
64990
+ };
64991
+ });
64868
64992
  }
64869
64993
  }, { signal: ac.signal });
64870
64994
  return selected;
@@ -64878,13 +65002,59 @@ async function selectModel(options = {}) {
64878
65002
  cleanupKeypress();
64879
65003
  }
64880
65004
  }
65005
+ function isPickableProvider(def) {
65006
+ return def.shortcuts.length > 0;
65007
+ }
65008
+ function pickableProvidersInPickerOrder() {
65009
+ const rank = new Map(PICKER_ORDER.map((name, i) => [name, i]));
65010
+ return getAllProviders().filter(isPickableProvider).sort((a, b) => {
65011
+ const ra = rank.get(a.name) ?? Number.MAX_SAFE_INTEGER;
65012
+ const rb = rank.get(b.name) ?? Number.MAX_SAFE_INTEGER;
65013
+ return ra !== rb ? ra - rb : a.displayName.localeCompare(b.displayName);
65014
+ });
65015
+ }
65016
+ function buildProviderChoices() {
65017
+ const derived = pickableProvidersInPickerOrder().map((def) => {
65018
+ const copy = PICKER_COPY[def.name] ?? {};
65019
+ return {
65020
+ name: copy.name ?? def.displayName,
65021
+ value: def.name,
65022
+ description: copy.description ?? def.description ?? "",
65023
+ provider: def.name
65024
+ };
65025
+ });
65026
+ return [
65027
+ {
65028
+ name: "Skip (keep Claude default)",
65029
+ value: "skip",
65030
+ description: "Use native Claude model for this tier"
65031
+ },
65032
+ ...derived,
65033
+ {
65034
+ name: "Enter custom model",
65035
+ value: "custom",
65036
+ description: "Type a provider@model specification"
65037
+ }
65038
+ ];
65039
+ }
64881
65040
  async function getProviderChoices() {
64882
- const checks4 = await Promise.all(ALL_PROVIDER_CHOICES.map(async (choice) => {
65041
+ const all = buildProviderChoices();
65042
+ const checks4 = await Promise.all(all.map(async (choice) => {
64883
65043
  if (!choice.provider)
64884
65044
  return true;
64885
65045
  return credentials.isAvailable(choice.provider);
64886
65046
  }));
64887
- return ALL_PROVIDER_CHOICES.filter((_, i) => checks4[i]);
65047
+ return all.filter((_, i) => checks4[i]);
65048
+ }
65049
+ function pickerModelPrefix(provider) {
65050
+ const override = PROVIDER_MODEL_PREFIX_OVERRIDE[provider];
65051
+ if (override)
65052
+ return override;
65053
+ const def = getProviderByName(provider);
65054
+ if (!def || !isPickableProvider(def))
65055
+ return;
65056
+ const prefix = def.shortestPrefix || def.shortcuts[0];
65057
+ return prefix ? `${prefix}@` : undefined;
64888
65058
  }
64889
65059
  async function getInteractiveProviderChoices() {
64890
65060
  return (await getProviderChoices()).filter((choice) => choice.value !== "skip");
@@ -64897,7 +65067,7 @@ function toPickerProviders(choices) {
64897
65067
  }));
64898
65068
  }
64899
65069
  function buildExplicitModelSpec(provider, modelId) {
64900
- const prefix = PROVIDER_MODEL_PREFIX[provider];
65070
+ const prefix = pickerModelPrefix(provider);
64901
65071
  if (!prefix) {
64902
65072
  return modelId;
64903
65073
  }
@@ -64916,6 +65086,8 @@ function resolveProviderAggregatorEntry(provider, model) {
64916
65086
  return model.aggregators.find((a) => a.provider.toLowerCase() === firebaseSlug.toLowerCase());
64917
65087
  }
64918
65088
  function resolveProviderDisplayPrice(provider, model) {
65089
+ if (isSubscriptionProvider(provider))
65090
+ return "SUB";
64919
65091
  const entry = resolveProviderAggregatorEntry(provider, model);
64920
65092
  const entryPrice = formatAveragePricing(entry?.pricing);
64921
65093
  if (entryPrice?.average)
@@ -64923,7 +65095,7 @@ function resolveProviderDisplayPrice(provider, model) {
64923
65095
  return model.pricing?.average || "N/A";
64924
65096
  }
64925
65097
  function getPickerDisplayName(providerValue) {
64926
- const choice = ALL_PROVIDER_CHOICES.find((c) => c.value === providerValue);
65098
+ const choice = buildProviderChoices().find((c) => c.value === providerValue);
64927
65099
  if (choice)
64928
65100
  return choice.name;
64929
65101
  return getDisplayName(providerValue);
@@ -64932,7 +65104,7 @@ async function loadModelsForPickerProvider(providerValue, catalog) {
64932
65104
  const firebaseSlug = pickerProviderToFirebaseSlug[providerValue] ?? providerValue;
64933
65105
  try {
64934
65106
  const vendorModels = await catalog.modelsByVendor(firebaseSlug);
64935
- return sortModelsNewestFirst(dedupeModels(vendorModels.map(catalogModelToModelInfo)));
65107
+ return dedupeByProviderSpec(providerValue, sortModelsNewestFirst(dedupeModels(vendorModels.map(catalogModelToModelInfo))));
64936
65108
  } catch {
64937
65109
  return [];
64938
65110
  }
@@ -65024,7 +65196,7 @@ async function buildDiscoveredModelRows(provider, displayName, catalog) {
65024
65196
  return sortModelsNewestFirst(rows);
65025
65197
  }
65026
65198
  async function selectModelFromProvider(provider, tierName, recommendedModels, _forceUpdate, catalog) {
65027
- const prefix = PROVIDER_MODEL_PREFIX[provider] || `${provider}@`;
65199
+ const prefix = pickerModelPrefix(provider) ?? `${provider}@`;
65028
65200
  const displayName = getPickerDisplayName(provider);
65029
65201
  const def = getProviderByName(provider);
65030
65202
  if (def?.modelDiscovery) {
@@ -65189,7 +65361,7 @@ async function selectProfile(profiles) {
65189
65361
  async function confirmAction(message) {
65190
65362
  return dist_default4({ message, default: false });
65191
65363
  }
65192
- var pickerProviderToFirebaseSlug, LOCAL_OR_USER_DEPLOYED, SUBSCRIPTION_PRICING, PROVIDER_FILTER_ALIASES, ALL_PROVIDER_CHOICES, PROVIDER_MODEL_PREFIX;
65364
+ var pickerProviderToFirebaseSlug, LOCAL_OR_USER_DEPLOYED, SUBSCRIPTION_PRICING, PROVIDER_FILTER_ALIAS_EXTRA, PICKER_COPY, PICKER_ORDER, PROVIDER_MODEL_PREFIX_OVERRIDE;
65193
65365
  var init_model_selector = __esm(() => {
65194
65366
  init_dist16();
65195
65367
  init_model_catalog();
@@ -65227,160 +65399,73 @@ var init_model_selector = __esm(() => {
65227
65399
  output: "SUB",
65228
65400
  average: "SUB"
65229
65401
  };
65230
- PROVIDER_FILTER_ALIASES = {
65231
- openrouter: "openrouter",
65232
- or: "openrouter",
65233
- google: "google",
65234
- gemini: "google",
65402
+ PROVIDER_FILTER_ALIAS_EXTRA = {
65235
65403
  gem: "google",
65236
- openai: "openai",
65237
- oai: "openai",
65238
- codex: "openai-codex",
65239
- cx: "openai-codex",
65240
- "x-ai": "x-ai",
65241
- xai: "x-ai",
65242
- grok: "x-ai",
65243
- minimax: "minimax",
65244
- mm: "minimax",
65245
- "minimax-coding": "minimax-coding",
65246
- mmc: "minimax-coding",
65247
- kimi: "kimi",
65248
- moon: "kimi",
65249
- moonshot: "kimi",
65250
- "kimi-coding": "kimi-coding",
65251
- kc: "kimi-coding",
65252
- glm: "glm",
65253
- "glm-coding": "glm-coding",
65254
- gc: "glm-coding",
65255
- "z-ai": "z-ai",
65256
- zai: "z-ai",
65257
- zen: "zen",
65258
- ollamacloud: "ollamacloud",
65259
- oc: "ollamacloud",
65260
- litellm: "litellm",
65261
- ll: "litellm",
65262
- deepseek: "deepseek",
65263
- mistralai: "mistralai",
65264
- mistral: "mistralai",
65265
- sakana: "sakana",
65266
- fugu: "sakana",
65267
- "sakana-subscription": "sakana-subscription",
65268
- sc: "sakana-subscription",
65269
- "qwen-cloud": "qwen-cloud",
65270
- qc: "qwen-cloud"
65271
- };
65272
- ALL_PROVIDER_CHOICES = [
65273
- {
65274
- name: "Skip (keep Claude default)",
65275
- value: "skip",
65276
- description: "Use native Claude model for this tier"
65277
- },
65278
- {
65279
- name: "OpenRouter",
65280
- value: "openrouter",
65281
- description: "580+ models via unified API",
65282
- provider: "openrouter"
65283
- },
65284
- {
65285
- name: "OpenCode Zen",
65286
- value: "zen",
65287
- description: "Free models, no API key needed",
65288
- provider: "opencode-zen"
65289
- },
65290
- { name: "Google Gemini", value: "google", description: "Direct API", provider: "google" },
65291
- { name: "OpenAI", value: "openai", description: "Direct API", provider: "openai" },
65292
- {
65293
- name: "OpenAI Codex",
65294
- value: "openai-codex",
65295
- description: "ChatGPT Plus/Pro subscription (Responses API)",
65296
- provider: "openai-codex"
65297
- },
65298
- { name: "xAI / Grok", value: "x-ai", description: "Direct API", provider: "x-ai" },
65299
- { name: "DeepSeek", value: "deepseek", description: "Direct API", provider: "deepseek" },
65300
- { name: "Mistral", value: "mistralai", description: "Direct API", provider: "mistralai" },
65301
- { name: "Sakana Fugu", value: "sakana", description: "Direct API", provider: "sakana" },
65302
- {
65303
- name: "Sakana Fugu Subscription",
65304
- value: "sakana-subscription",
65305
- description: "Subscription plan",
65306
- provider: "sakana-subscription"
65307
- },
65308
- { name: "MiniMax", value: "minimax", description: "Direct API", provider: "minimax" },
65309
- {
65310
- name: "MiniMax Coding",
65311
- value: "minimax-coding",
65312
- description: "Coding subscription",
65313
- provider: "minimax-coding"
65314
- },
65315
- { name: "Kimi / Moonshot", value: "kimi", description: "Direct API", provider: "kimi" },
65316
- {
65317
- name: "Kimi Coding",
65318
- value: "kimi-coding",
65319
- description: "Coding subscription",
65320
- provider: "kimi-coding"
65321
- },
65322
- {
65323
- name: "Qwen Plan",
65324
- value: "qwen-cloud",
65325
- description: "Alibaba Model Studio subscription",
65326
- provider: "qwen-cloud"
65327
- },
65328
- { name: "GLM / Zhipu", value: "glm", description: "Direct API", provider: "glm" },
65329
- {
65330
- name: "GLM Coding Plan",
65331
- value: "glm-coding",
65332
- description: "Coding subscription",
65333
- provider: "glm-coding"
65334
- },
65335
- { name: "Z.AI", value: "z-ai", description: "Direct API", provider: "z-ai" },
65336
- {
65337
- name: "OllamaCloud",
65338
- value: "ollamacloud",
65339
- description: "Cloud models",
65340
- provider: "ollamacloud"
65341
- },
65342
- { name: "LiteLLM", value: "litellm", description: "Configured proxy", provider: "litellm" },
65343
- {
65344
- name: "Ollama (local)",
65345
- value: "ollama",
65346
- description: "Local Ollama instance",
65347
- provider: "ollama"
65348
- },
65349
- {
65350
- name: "LM Studio (local)",
65351
- value: "lmstudio",
65352
- description: "Local LM Studio instance",
65353
- provider: "lmstudio"
65354
- },
65355
- {
65356
- name: "Enter custom model",
65357
- value: "custom",
65358
- description: "Type a provider@model specification"
65359
- }
65404
+ zen: "opencode-zen"
65405
+ };
65406
+ PICKER_COPY = {
65407
+ openrouter: { description: "580+ models via unified API" },
65408
+ "opencode-zen": { name: "OpenCode Zen", description: "Free models, no API key needed" },
65409
+ google: { name: "Google Gemini", description: "Direct API" },
65410
+ openai: { description: "Direct API" },
65411
+ "openai-codex": { description: "ChatGPT Plus/Pro subscription (Responses API)" },
65412
+ "x-ai": { name: "xAI / Grok", description: "Direct API" },
65413
+ deepseek: { description: "Direct API" },
65414
+ mistralai: { name: "Mistral", description: "Direct API" },
65415
+ sakana: { name: "Sakana Fugu", description: "Direct API" },
65416
+ "sakana-subscription": { name: "Sakana Fugu Subscription", description: "Subscription plan" },
65417
+ minimax: { description: "Direct API" },
65418
+ "minimax-coding": { name: "MiniMax Coding", description: "Coding subscription" },
65419
+ kimi: { name: "Kimi / Moonshot", description: "Direct API" },
65420
+ "kimi-coding": { name: "Kimi Coding", description: "Coding subscription" },
65421
+ "qwen-cloud": { name: "Qwen Plan", description: "Alibaba Model Studio subscription" },
65422
+ glm: { name: "GLM / Zhipu", description: "Direct API" },
65423
+ "glm-coding": { name: "GLM Coding Plan", description: "Coding subscription" },
65424
+ "z-ai": { name: "Z.AI", description: "Direct API" },
65425
+ ollamacloud: { name: "OllamaCloud", description: "Cloud models" },
65426
+ litellm: { description: "Configured proxy" },
65427
+ ollama: { name: "Ollama (local)", description: "Local Ollama instance" },
65428
+ lmstudio: { name: "LM Studio (local)", description: "Local LM Studio instance" },
65429
+ vllm: { name: "vLLM (local)", description: "Local vLLM server" },
65430
+ mlx: { name: "MLX (local)", description: "Local MLX server" }
65431
+ };
65432
+ PICKER_ORDER = [
65433
+ "openrouter",
65434
+ "opencode-zen",
65435
+ "opencode-zen-go",
65436
+ "google",
65437
+ "antigravity",
65438
+ "openai",
65439
+ "openai-codex",
65440
+ "devin",
65441
+ "x-ai",
65442
+ "deepseek",
65443
+ "mistralai",
65444
+ "sakana",
65445
+ "sakana-subscription",
65446
+ "minimax",
65447
+ "minimax-coding",
65448
+ "kimi",
65449
+ "kimi-coding",
65450
+ "qwen-cloud",
65451
+ "glm",
65452
+ "glm-coding",
65453
+ "z-ai",
65454
+ "ollamacloud",
65455
+ "poe",
65456
+ "vertex",
65457
+ "litellm",
65458
+ "ollama",
65459
+ "lmstudio",
65460
+ "vllm",
65461
+ "mlx"
65360
65462
  ];
65361
- PROVIDER_MODEL_PREFIX = {
65463
+ PROVIDER_MODEL_PREFIX_OVERRIDE = {
65362
65464
  google: "google@",
65363
- antigravity: "ag@",
65364
- openai: "oai@",
65365
- "openai-codex": "cx@",
65366
- "x-ai": "x-ai@",
65367
- deepseek: "ds@",
65368
- mistralai: "mistral@",
65369
- sakana: "sakana@",
65370
- "sakana-subscription": "sc@",
65371
- minimax: "mm@",
65372
- kimi: "kimi@",
65373
- "minimax-coding": "mmc@",
65374
- "kimi-coding": "kc@",
65375
- "qwen-cloud": "qc@",
65376
- glm: "glm@",
65377
- "glm-coding": "gc@",
65378
- "z-ai": "z-ai@",
65379
- ollamacloud: "oc@",
65380
- ollama: "ollama@",
65465
+ openrouter: "openrouter@",
65381
65466
  lmstudio: "lmstudio@",
65382
- zen: "zen@",
65383
- openrouter: "openrouter@"
65467
+ sakana: "sakana@",
65468
+ zen: "zen@"
65384
65469
  };
65385
65470
  });
65386
65471
 
@@ -75521,6 +75606,7 @@ function App({ requestLogin } = {}) {
75521
75606
  setOpFieldCursor(idx < 0 ? 0 : idx);
75522
75607
  }, [opFieldOptionsFiltered, opFieldCursor, mode]);
75523
75608
  const acquireOpAuth = useCallback3(async () => {
75609
+ clearOpSkip();
75524
75610
  const auth = await resolveSdkAuth({
75525
75611
  interactive: true,
75526
75612
  configAccount: readOnepasswordAccount(),
@@ -77636,7 +77722,10 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
77636
77722
  setSessionContextWindow2(realWindow);
77637
77723
  } catch {}
77638
77724
  if (contextEnv.notice && !config3.quiet) {
77639
- console.error(contextEnv.notice);
77725
+ if (config3.interactive)
77726
+ console.log(contextEnv.notice);
77727
+ else
77728
+ console.error(contextEnv.notice);
77640
77729
  }
77641
77730
  }
77642
77731
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.45.0",
3
+ "version": "7.46.0",
4
4
  "description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -60,10 +60,10 @@
60
60
  "ai"
61
61
  ],
62
62
  "optionalDependencies": {
63
- "@claudish/magmux-darwin-arm64": "7.45.0",
64
- "@claudish/magmux-darwin-x64": "7.45.0",
65
- "@claudish/magmux-linux-arm64": "7.45.0",
66
- "@claudish/magmux-linux-x64": "7.45.0"
63
+ "@claudish/magmux-darwin-arm64": "7.46.0",
64
+ "@claudish/magmux-darwin-x64": "7.46.0",
65
+ "@claudish/magmux-linux-arm64": "7.46.0",
66
+ "@claudish/magmux-linux-x64": "7.46.0"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",