claudish 7.35.0 → 7.37.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 +448 -224
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -523,6 +523,68 @@ function scanConfigFlag(argv) {
523
523
  }
524
524
  var SUPPRESSED_PROJECT_CONFIG = "", overridePath = null;
525
525
 
526
+ // src/providers/op-source-entry.ts
527
+ function trimmed(v) {
528
+ return typeof v === "string" && v.trim() ? v.trim() : undefined;
529
+ }
530
+ function parseOpSourceEntry(raw, valueKey) {
531
+ const bare = trimmed(raw);
532
+ if (bare)
533
+ return { value: bare };
534
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
535
+ return;
536
+ const obj = raw;
537
+ const value = trimmed(obj[valueKey]);
538
+ if (!value)
539
+ return;
540
+ const account = trimmed(obj.account);
541
+ return account ? { value, account } : { value };
542
+ }
543
+ function parseOpSourceEntries(raw, valueKey) {
544
+ if (!Array.isArray(raw))
545
+ return [];
546
+ const out = [];
547
+ for (const item of raw) {
548
+ const parsed = parseOpSourceEntry(item, valueKey);
549
+ if (parsed)
550
+ out.push(parsed);
551
+ }
552
+ return out;
553
+ }
554
+ function serializeOpSourceEntry(entry, valueKey) {
555
+ if (!entry.account)
556
+ return entry.value;
557
+ return { [valueKey]: entry.value, account: entry.account };
558
+ }
559
+ function dedupeOpSourceEntries(entries) {
560
+ const seen = new Set;
561
+ const out = [];
562
+ for (const e of entries) {
563
+ if (seen.has(e.value))
564
+ continue;
565
+ seen.add(e.value);
566
+ out.push(e);
567
+ }
568
+ return out;
569
+ }
570
+ function groupEntriesByAccount(entries, resolveAccount) {
571
+ const byAccount = new Map;
572
+ const undeclared = [];
573
+ for (const entry of entries) {
574
+ const account = resolveAccount(entry);
575
+ if (!account) {
576
+ undeclared.push(entry);
577
+ continue;
578
+ }
579
+ const bucket = byAccount.get(account);
580
+ if (bucket)
581
+ bucket.push(entry);
582
+ else
583
+ byAccount.set(account, [entry]);
584
+ }
585
+ return { byAccount, undeclared };
586
+ }
587
+
526
588
  // src/providers/onepassword-config.ts
527
589
  import { existsSync, readFileSync, writeFileSync } from "fs";
528
590
  import { homedir } from "os";
@@ -580,60 +642,76 @@ function clearOnepasswordAccount(scope, paths = defaultOpConfigPaths) {
580
642
  }
581
643
  function readStringList(scope, key, paths) {
582
644
  const cfg = readRawConfig(pathFor(scope, paths));
583
- const raw = cfg[key];
584
- if (!Array.isArray(raw))
585
- return [];
586
- return raw.filter((v) => typeof v === "string");
645
+ const valueKey = key === "onepassword" ? "ref" : "id";
646
+ return parseOpSourceEntries(cfg[key], valueKey).map((e) => e.value);
587
647
  }
588
- function addToStringList(scope, key, entry, paths) {
648
+ function addToStringList(scope, key, entry, paths, account) {
589
649
  const value = entry.trim();
590
650
  if (!value)
591
651
  return;
652
+ const valueKey = key === "onepassword" ? "ref" : "id";
653
+ const declared = account?.trim();
592
654
  mutateConfig(scope, paths, (cfg) => {
593
- const list = Array.isArray(cfg[key]) ? cfg[key].filter((v) => typeof v === "string") : [];
594
- if (!list.includes(value))
595
- list.push(value);
596
- cfg[key] = list;
655
+ const existing = parseOpSourceEntries(cfg[key], valueKey);
656
+ const match = existing.find((e) => e.value === value);
657
+ if (match) {
658
+ if (declared && !match.account)
659
+ match.account = declared;
660
+ } else {
661
+ existing.push(declared ? { value, account: declared } : { value });
662
+ }
663
+ cfg[key] = existing.map((e) => serializeOpSourceEntry(e, valueKey));
597
664
  });
598
665
  }
599
666
  function removeFromStringList(scope, key, entry, paths) {
600
667
  const value = entry.trim();
668
+ if (!value)
669
+ return;
670
+ const valueKey = key === "onepassword" ? "ref" : "id";
601
671
  mutateConfig(scope, paths, (cfg) => {
602
- const list = Array.isArray(cfg[key]) ? cfg[key].filter((v) => typeof v === "string") : [];
603
- const next = list.filter((v) => v !== value);
604
- if (next.length === 0)
672
+ const kept = parseOpSourceEntries(cfg[key], valueKey).filter((e) => e.value !== value);
673
+ if (kept.length === 0)
605
674
  delete cfg[key];
606
675
  else
607
- cfg[key] = next;
676
+ cfg[key] = kept.map((e) => serializeOpSourceEntry(e, valueKey));
608
677
  });
609
678
  }
610
679
  function listOnepasswordImports(scope, paths = defaultOpConfigPaths) {
611
680
  return readStringList(scope, "onepassword", paths);
612
681
  }
613
- function addOnepasswordImport(entry, scope, paths = defaultOpConfigPaths) {
614
- addToStringList(scope, "onepassword", entry, paths);
682
+ function addOnepasswordImport(entry, scope, paths = defaultOpConfigPaths, account) {
683
+ addToStringList(scope, "onepassword", entry, paths, account);
615
684
  }
616
685
  function removeOnepasswordImport(entry, scope, paths = defaultOpConfigPaths) {
617
686
  removeFromStringList(scope, "onepassword", entry, paths);
618
687
  }
688
+ function readEntryList(scope, key, valueKey, paths) {
689
+ const cfg = readRawConfig(pathFor(scope, paths));
690
+ return parseOpSourceEntries(cfg[key], valueKey);
691
+ }
692
+ function listOnepasswordImportEntries(scope, paths = defaultOpConfigPaths) {
693
+ return readEntryList(scope, "onepassword", "ref", paths);
694
+ }
695
+ function listOnepasswordEnvironmentEntries(scope, paths = defaultOpConfigPaths) {
696
+ return readEntryList(scope, "onepasswordEnvironments", "id", paths);
697
+ }
698
+ function readAllOnepasswordEnvironmentEntries(paths = defaultOpConfigPaths) {
699
+ return dedupeOpSourceEntries([
700
+ ...listOnepasswordEnvironmentEntries("project", paths),
701
+ ...listOnepasswordEnvironmentEntries("global", paths)
702
+ ]);
703
+ }
704
+ function readAllOnepasswordImportEntries(paths = defaultOpConfigPaths) {
705
+ return dedupeOpSourceEntries([
706
+ ...listOnepasswordImportEntries("project", paths),
707
+ ...listOnepasswordImportEntries("global", paths)
708
+ ]);
709
+ }
619
710
  function listOnepasswordEnvironments(scope, paths = defaultOpConfigPaths) {
620
711
  return readStringList(scope, "onepasswordEnvironments", paths);
621
712
  }
622
- function readAllOnepasswordEnvironments(paths = defaultOpConfigPaths) {
623
- const project = listOnepasswordEnvironments("project", paths);
624
- const global2 = listOnepasswordEnvironments("global", paths);
625
- const seen = new Set(project);
626
- const out = [...project];
627
- for (const id of global2) {
628
- if (!seen.has(id)) {
629
- seen.add(id);
630
- out.push(id);
631
- }
632
- }
633
- return out;
634
- }
635
- function addOnepasswordEnvironment(id, scope, paths = defaultOpConfigPaths) {
636
- addToStringList(scope, "onepasswordEnvironments", id, paths);
713
+ function addOnepasswordEnvironment(id, scope, paths = defaultOpConfigPaths, account) {
714
+ addToStringList(scope, "onepasswordEnvironments", id, paths, account);
637
715
  }
638
716
  function removeOnepasswordEnvironment(id, scope, paths = defaultOpConfigPaths) {
639
717
  removeFromStringList(scope, "onepasswordEnvironments", id, paths);
@@ -651,7 +729,7 @@ var init_onepassword_config = __esm(() => {
651
729
  });
652
730
 
653
731
  // src/version.ts
654
- var VERSION = "7.35.0";
732
+ var VERSION = "7.37.0";
655
733
 
656
734
  // src/logger.ts
657
735
  var exports_logger = {};
@@ -3856,7 +3934,6 @@ __export(exports_onepassword, {
3856
3934
  detectSdkAuth: () => detectSdkAuth,
3857
3935
  defaultSdkClientFactory: () => defaultSdkClientFactory,
3858
3936
  defaultScreenLockProbe: () => defaultScreenLockProbe,
3859
- defaultOpDefaultAccountProbe: () => defaultOpDefaultAccountProbe,
3860
3937
  defaultOpAccountLister: () => defaultOpAccountLister,
3861
3938
  defaultAppLockProbe: () => defaultAppLockProbe,
3862
3939
  currentLockCause: () => currentLockCause,
@@ -4193,25 +4270,25 @@ function collectApiKeyRefs(apiKeys, env, opRefs) {
4193
4270
  function collectOnepasswordEntry(entry, env, opRefs, globImports, warnings) {
4194
4271
  if (typeof entry !== "string")
4195
4272
  return;
4196
- const trimmed = entry.trim();
4197
- if (trimmed === "")
4273
+ const trimmed2 = entry.trim();
4274
+ if (trimmed2 === "")
4198
4275
  return;
4199
- if (isGlobImport(trimmed)) {
4200
- globImports.push(trimmed);
4276
+ if (isGlobImport(trimmed2)) {
4277
+ globImports.push(trimmed2);
4201
4278
  return;
4202
4279
  }
4203
- if (trimmed.startsWith("op://")) {
4204
- const name = envNameFromOpRef(trimmed);
4280
+ if (trimmed2.startsWith("op://")) {
4281
+ const name = envNameFromOpRef(trimmed2);
4205
4282
  if (name === null) {
4206
- warnings.push(`[claudish] skipped 1Password ref '${trimmed}' from onepassword[] (its trailing field label is not a valid env var name)`);
4283
+ warnings.push(`[claudish] skipped 1Password ref '${trimmed2}' from onepassword[] (its trailing field label is not a valid env var name)`);
4207
4284
  return;
4208
4285
  }
4209
4286
  if (!env[name]) {
4210
- opRefs[name] = trimmed;
4287
+ opRefs[name] = trimmed2;
4211
4288
  }
4212
4289
  return;
4213
4290
  }
4214
- warnings.push(`[claudish] skipped 1Password entry '${trimmed}' from onepassword[] (not a glob import or op:// reference)`);
4291
+ warnings.push(`[claudish] skipped 1Password entry '${trimmed2}' from onepassword[] (not a glob import or op:// reference)`);
4215
4292
  }
4216
4293
  function parseOpFlag(argv) {
4217
4294
  let glob;
@@ -4444,17 +4521,10 @@ function resolveDesktopAccount(opts = {}) {
4444
4521
  if (opts.interactive) {
4445
4522
  return { needsPicker: accounts };
4446
4523
  }
4447
- const probe = opts.opDefaultAccountProbe ?? defaultOpDefaultAccountProbe;
4448
- const defaultUuid = probe();
4449
- if (defaultUuid) {
4450
- const match = accounts.find((a) => a.account_uuid === defaultUuid);
4451
- if (match)
4452
- return { accountName: match.url };
4453
- }
4454
4524
  const listing = accounts.map((a) => ` - ${a.url}${a.email ? ` (${a.email})` : ""}`).join(`
4455
4525
  `);
4456
4526
  return {
4457
- error: `Multiple 1Password accounts are available, this is a non-interactive session, and \`op\` could not name a default account. ${remediation}
4527
+ error: `Multiple 1Password accounts are available and none is configured, so claudish cannot tell which one holds your keys. ${remediation}
4458
4528
  Accounts:
4459
4529
  ${listing}`
4460
4530
  };
@@ -4468,8 +4538,7 @@ async function resolveSdkAuth(opts = {}) {
4468
4538
  env,
4469
4539
  configAccount: opts.configAccount,
4470
4540
  interactive: opts.interactive,
4471
- opAccountLister: opts.opAccountLister,
4472
- opDefaultAccountProbe: opts.opDefaultAccountProbe
4541
+ opAccountLister: opts.opAccountLister
4473
4542
  });
4474
4543
  if ("accountName" in result) {
4475
4544
  return { kind: "desktop", accountName: result.accountName };
@@ -4611,9 +4680,12 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
4611
4680
  } catch {
4612
4681
  return false;
4613
4682
  }
4614
- }, screenLockProbe, defaultAppLockProbe = () => false, appLockProbe, defaultOpAccountLister = () => {
4683
+ }, screenLockProbe, defaultAppLockProbe = () => false, appLockProbe, OP_PROBE_TIMEOUT_MS = 5000, defaultOpAccountLister = () => {
4615
4684
  try {
4616
- const res = spawnSync("op", ["account", "list", "--format=json"], { encoding: "utf-8" });
4685
+ const res = spawnSync("op", ["--cache=false", "account", "list", "--format=json"], {
4686
+ encoding: "utf-8",
4687
+ timeout: OP_PROBE_TIMEOUT_MS
4688
+ });
4617
4689
  if (res.error || res.status !== 0)
4618
4690
  return null;
4619
4691
  const parsed = JSON.parse(res.stdout ?? "");
@@ -4637,16 +4709,6 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
4637
4709
  } catch {
4638
4710
  return null;
4639
4711
  }
4640
- }, defaultOpDefaultAccountProbe = () => {
4641
- try {
4642
- const res = spawnSync("op", ["account", "get", "--format=json"], { encoding: "utf-8" });
4643
- if (res.error || res.status !== 0)
4644
- return null;
4645
- const parsed = JSON.parse(res.stdout ?? "");
4646
- return typeof parsed.id === "string" && parsed.id ? parsed.id : null;
4647
- } catch {
4648
- return null;
4649
- }
4650
4712
  };
4651
4713
  var init_onepassword = __esm(() => {
4652
4714
  init_env_placeholder();
@@ -4734,8 +4796,11 @@ async function pickOnepasswordAccount(accounts) {
4734
4796
  return accounts[idx - 1].url;
4735
4797
  }
4736
4798
  async function getSdkAuth(allowPrompt) {
4737
- if (sdkAuthResolved)
4799
+ if (sdkAuthResolved) {
4800
+ if (cachedAuthError)
4801
+ throw cachedAuthError;
4738
4802
  return cachedSdkAuth;
4803
+ }
4739
4804
  if (authInFlight)
4740
4805
  return authInFlight;
4741
4806
  authInFlight = (async () => {
@@ -4759,13 +4824,25 @@ async function getSdkAuth(allowPrompt) {
4759
4824
  return auth;
4760
4825
  } catch (err) {
4761
4826
  const message = err instanceof Error ? err.message : String(err);
4762
- throw new OpAuthError(message);
4827
+ cachedAuthError = new OpAuthError(message);
4828
+ sdkAuthResolved = true;
4829
+ throw cachedAuthError;
4763
4830
  } finally {
4764
4831
  authInFlight = undefined;
4765
4832
  }
4766
4833
  })();
4767
4834
  return authInFlight;
4768
4835
  }
4836
+ async function authForEntry(entry, allowPrompt) {
4837
+ const token = process.env.OP_SERVICE_ACCOUNT_TOKEN?.trim();
4838
+ if (token)
4839
+ return { kind: "token", token };
4840
+ if (entry.account)
4841
+ return { kind: "desktop", accountName: entry.account };
4842
+ if (testSeams?.auth)
4843
+ return testSeams.auth;
4844
+ return getSdkAuth(allowPrompt);
4845
+ }
4769
4846
  function resolveExplicitFlagAuth() {
4770
4847
  return getSdkAuth(true);
4771
4848
  }
@@ -4857,12 +4934,27 @@ function flagEnvironmentIds() {
4857
4934
  return ids;
4858
4935
  }
4859
4936
  function configEnvironmentIds() {
4860
- if (testSeams?.config)
4861
- return testSeams.config.onepasswordEnvironments ?? [];
4862
- return readAllOnepasswordEnvironments();
4937
+ return configEnvironmentEntries().map((e) => e.value);
4863
4938
  }
4864
- function registeredEnvironmentIds() {
4865
- return [...new Set([...configEnvironmentIds(), ...flagEnvironmentIds()])];
4939
+ function configEnvironmentEntries() {
4940
+ if (testSeams?.config) {
4941
+ return parseOpSourceEntries(testSeams.config.onepasswordEnvironments ?? [], "id");
4942
+ }
4943
+ return readAllOnepasswordEnvironmentEntries();
4944
+ }
4945
+ function registeredEnvironmentEntries() {
4946
+ const seen = new Set;
4947
+ const out = [];
4948
+ for (const entry of [
4949
+ ...configEnvironmentEntries(),
4950
+ ...flagEnvironmentIds().map((value) => ({ value }))
4951
+ ]) {
4952
+ if (seen.has(entry.value))
4953
+ continue;
4954
+ seen.add(entry.value);
4955
+ out.push(entry);
4956
+ }
4957
+ return out;
4866
4958
  }
4867
4959
  function maskGlobForTrace(globPath) {
4868
4960
  const body = globPath.startsWith("op://") ? globPath.slice("op://".length) : globPath;
@@ -4974,6 +5066,34 @@ async function resolveOpKeyForEnvVars(wanted, opts = {}) {
4974
5066
  return out;
4975
5067
  }, label);
4976
5068
  }
5069
+ function hasNonEnvironmentOpSources() {
5070
+ const cfg = testSeams?.config ?? readConfigRaw();
5071
+ if (cfg.apiKeys) {
5072
+ for (const v of Object.values(cfg.apiKeys)) {
5073
+ if (typeof v === "string" && v.startsWith("op://"))
5074
+ return true;
5075
+ }
5076
+ }
5077
+ if (Array.isArray(cfg.onepassword) && cfg.onepassword.length > 0)
5078
+ return true;
5079
+ if (cfg.customEndpoints && typeof cfg.customEndpoints === "object") {
5080
+ for (const raw of Object.values(cfg.customEndpoints)) {
5081
+ if (raw && typeof raw === "object") {
5082
+ const apiKey = raw.apiKey;
5083
+ if (typeof apiKey === "string" && apiKey.startsWith("op://"))
5084
+ return true;
5085
+ }
5086
+ }
5087
+ }
5088
+ return false;
5089
+ }
5090
+ function importAccountLookup() {
5091
+ const entries = testSeams?.config ? parseOpSourceEntries(testSeams.config.onepassword ?? [], "ref") : readAllOnepasswordImportEntries();
5092
+ const out = new Map;
5093
+ for (const e of entries)
5094
+ out.set(e.value, e.account);
5095
+ return out;
5096
+ }
4977
5097
  async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
4978
5098
  if (wanted.size === 0)
4979
5099
  return {};
@@ -4981,20 +5101,35 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
4981
5101
  return {};
4982
5102
  const onAuthFailure = opts.onAuthFailure ?? "skip";
4983
5103
  const allowPrompt = opts.allowPrompt ?? false;
5104
+ let ambientFailure;
5105
+ const ambientAuth = async () => {
5106
+ if (testSeams?.auth)
5107
+ return testSeams.auth;
5108
+ if (ambientFailure)
5109
+ throw ambientFailure;
5110
+ try {
5111
+ return await getSdkAuth(allowPrompt);
5112
+ } catch (err) {
5113
+ if (err instanceof OpAuthError)
5114
+ ambientFailure = err;
5115
+ throw err;
5116
+ }
5117
+ };
5118
+ const reportAuthFailure = async (err) => {
5119
+ if (!(err instanceof OpAuthError) || onAuthFailure !== "skip")
5120
+ throw err;
5121
+ warnOnce(`[claudish] 1Password auth unavailable, skipping op:// keys: ${err.message}`);
5122
+ const { recordOpFailure: recordOpFailure3 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
5123
+ recordOpFailure3({ kind: "auth", message: err.message });
5124
+ };
4984
5125
  let auth;
4985
5126
  if (testSeams?.auth) {
4986
5127
  auth = testSeams.auth;
4987
- } else {
5128
+ } else if (hasNonEnvironmentOpSources()) {
4988
5129
  try {
4989
- auth = await getSdkAuth(allowPrompt);
5130
+ auth = await ambientAuth();
4990
5131
  } catch (err) {
4991
- if (err instanceof OpAuthError && onAuthFailure === "skip") {
4992
- warnOnce(`[claudish] 1Password auth unavailable, skipping op:// keys: ${err.message}`);
4993
- const { recordOpFailure: recordOpFailure3 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
4994
- recordOpFailure3({ kind: "auth", message: err.message });
4995
- return {};
4996
- }
4997
- throw err;
5132
+ await reportAuthFailure(err);
4998
5133
  }
4999
5134
  }
5000
5135
  const {
@@ -5007,7 +5142,11 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5007
5142
  const cfg = readConfigRaw();
5008
5143
  const out = {};
5009
5144
  try {
5010
- const collected = collectConfigImports2({ apiKeys: cfg.apiKeys, onepassword: cfg.onepassword }, process.env);
5145
+ const importAccounts = importAccountLookup();
5146
+ const collected = collectConfigImports2({
5147
+ apiKeys: cfg.apiKeys,
5148
+ onepassword: parseOpSourceEntries(cfg.onepassword ?? [], "ref").map((e) => e.value)
5149
+ }, process.env);
5011
5150
  for (const w of collected.warnings)
5012
5151
  console.error(w);
5013
5152
  const wantedRefs = {};
@@ -5016,15 +5155,38 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5016
5155
  wantedRefs[envVar] = ref;
5017
5156
  }
5018
5157
  if (Object.keys(wantedRefs).length > 0) {
5019
- const resolved = await withSdkRetry2(() => resolveSecrets2(wantedRefs, { auth, sdkFactory: testSeams?.sdkFactory }), "op:resolve-refs");
5020
- Object.assign(out, resolved);
5158
+ const refEntries = Object.entries(wantedRefs).map(([envVar, ref]) => ({
5159
+ value: envVar,
5160
+ ...importAccounts.get(ref) ? { account: importAccounts.get(ref) } : {}
5161
+ }));
5162
+ const { byAccount, undeclared } = groupEntriesByAccount(refEntries, (e) => e.account);
5163
+ const batches = [];
5164
+ for (const [account, entries] of byAccount) {
5165
+ batches.push({
5166
+ auth: { kind: "desktop", accountName: account },
5167
+ names: entries.map((e) => e.value)
5168
+ });
5169
+ }
5170
+ if (undeclared.length > 0)
5171
+ batches.push({ auth, names: undeclared.map((e) => e.value) });
5172
+ for (const batch of batches) {
5173
+ const refs = {};
5174
+ for (const n of batch.names)
5175
+ refs[n] = wantedRefs[n];
5176
+ const resolved = await withSdkRetry2(() => resolveSecrets2(refs, { auth: batch.auth, sdkFactory: testSeams?.sdkFactory }), "op:resolve-refs");
5177
+ Object.assign(out, resolved);
5178
+ }
5021
5179
  }
5022
5180
  const stillWanted = new Set([...wanted].filter((w) => !(w in out)));
5023
5181
  for (const globPath of collected.globImports) {
5024
5182
  if (stillWanted.size === 0)
5025
5183
  break;
5026
5184
  try {
5027
- const { resolved, cacheHit } = await resolveGlobShared(globPath, auth);
5185
+ const globAuth = await authForEntry({
5186
+ value: globPath,
5187
+ ...importAccounts.get(globPath) ? { account: importAccounts.get(globPath) } : {}
5188
+ }, allowPrompt);
5189
+ const { resolved, cacheHit } = await resolveGlobShared(globPath, globAuth);
5028
5190
  if (cacheHit)
5029
5191
  span?.addMeta({ globCacheHit: true });
5030
5192
  for (const w of [...stillWanted]) {
@@ -5059,11 +5221,13 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5059
5221
  }
5060
5222
  const stillWantedEnv = new Set([...wanted].filter((w) => !(w in out)));
5061
5223
  if (stillWantedEnv.size > 0) {
5062
- for (const envId of registeredEnvironmentIds()) {
5224
+ for (const envEntry of registeredEnvironmentEntries()) {
5063
5225
  if (stillWantedEnv.size === 0)
5064
5226
  break;
5227
+ const envId = envEntry.value;
5065
5228
  try {
5066
- const { resolved, cacheHit } = await resolveEnvironmentShared(envId, auth);
5229
+ const envAuth = await authForEntry(envEntry, allowPrompt);
5230
+ const { resolved, cacheHit } = await resolveEnvironmentShared(envId, envAuth);
5067
5231
  if (cacheHit)
5068
5232
  span?.addMeta({ globCacheHit: true });
5069
5233
  for (const w of [...stillWantedEnv]) {
@@ -5096,7 +5260,7 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
5096
5260
  recordOpHydratedVars2(Object.keys(out));
5097
5261
  return out;
5098
5262
  }
5099
- var warnedMessages, opUnavailableVars, OP_UNAVAILABLE_ENV = "CLAUDISH_OP_UNAVAILABLE", OpAuthError, cachedSdkAuth, sdkAuthResolved = false, authInFlight, testSeams, sniffed, opQueue, resolvedCache, globResolutions, globResolvedVars, environmentResolutions;
5263
+ var warnedMessages, opUnavailableVars, OP_UNAVAILABLE_ENV = "CLAUDISH_OP_UNAVAILABLE", OpAuthError, cachedSdkAuth, cachedAuthError, sdkAuthResolved = false, authInFlight, testSeams, sniffed, opQueue, resolvedCache, globResolutions, globResolvedVars, environmentResolutions;
5100
5264
  var init_op_source = __esm(() => {
5101
5265
  init_onepassword_config();
5102
5266
  init_startup_trace();
@@ -5168,8 +5332,8 @@ async function opPreviewCommand(globPath, opts = {}) {
5168
5332
  continue;
5169
5333
  }
5170
5334
  importable++;
5171
- const trimmed = m.field.label !== m.envName;
5172
- const detail = trimmed ? `(trimmed from '${m.field.label}')` : m.field.section ? `(section: ${m.field.section})` : "(top-level field)";
5335
+ const trimmed2 = m.field.label !== m.envName;
5336
+ const detail = trimmed2 ? `(trimmed from '${m.field.label}')` : m.field.section ? `(section: ${m.field.section})` : "(top-level field)";
5173
5337
  console.log(` ${name} \u2713 ${detail}`);
5174
5338
  }
5175
5339
  console.log(`${importable} importable, ${skipped} skipped`);
@@ -7353,8 +7517,8 @@ var init_schemas = __esm(() => {
7353
7517
  $ZodStringFormat.init(inst, def);
7354
7518
  inst._zod.check = (payload) => {
7355
7519
  try {
7356
- const trimmed = payload.value.trim();
7357
- const url = new URL(trimmed);
7520
+ const trimmed2 = payload.value.trim();
7521
+ const url = new URL(trimmed2);
7358
7522
  if (def.hostname) {
7359
7523
  def.hostname.lastIndex = 0;
7360
7524
  if (!def.hostname.test(url.hostname)) {
@@ -7386,7 +7550,7 @@ var init_schemas = __esm(() => {
7386
7550
  if (def.normalize) {
7387
7551
  payload.value = url.href;
7388
7552
  } else {
7389
- payload.value = trimmed;
7553
+ payload.value = trimmed2;
7390
7554
  }
7391
7555
  return;
7392
7556
  } catch (_) {
@@ -28352,8 +28516,8 @@ function defaultReadStore() {
28352
28516
  }
28353
28517
  try {
28354
28518
  const out = execFileSync("security", ["find-generic-password", "-s", KC_SERVICE, "-a", KC_ACCOUNT, "-w"], { encoding: "utf8" });
28355
- const trimmed = out.trim();
28356
- return trimmed.length > 0 ? trimmed : null;
28519
+ const trimmed2 = out.trim();
28520
+ return trimmed2.length > 0 ? trimmed2 : null;
28357
28521
  } catch {
28358
28522
  return null;
28359
28523
  }
@@ -29562,7 +29726,7 @@ class AntigravityProviderTransport {
29562
29726
  const servesClause = served.length > 0 ? `That tier currently serves: ${served.join(", ")}. ` : "";
29563
29727
  const tier = this._displayName || "Antigravity";
29564
29728
  const reason = capacityFallbacksExhausted ? `${this.modelName} could not be served after every Antigravity capacity fallback failed (${tier}, via ag@). ` + servesClause : `${this.modelName} is not served by your Antigravity tier (${tier}, via ag@). ` + servesClause;
29565
- const message = reason + `To use ${this.modelName}, go through the direct Gemini API instead \u2014 ` + `set GEMINI_API_KEY (get one at https://aistudio.google.com/app/apikey) and run ` + `google@${this.modelName}.`;
29729
+ const message = reason + `To use ${this.modelName}, go through the direct Gemini API instead \u2014 ` + "set GEMINI_API_KEY (get one at https://aistudio.google.com/app/apikey) and run " + `google@${this.modelName}.`;
29566
29730
  const list = served.join(", ");
29567
29731
  const body = JSON.stringify({
29568
29732
  error: { code: 404, status: "NOT_FOUND", message }
@@ -29618,8 +29782,8 @@ ${lines.join(`
29618
29782
  }
29619
29783
  var CODE_ASSIST_BASE = "https://cloudcode-pa.googleapis.com", CODE_ASSIST_ENDPOINT, MAX_RETRY_ATTEMPTS = 3, DEFAULT_RATE_LIMIT_DELAY_MS = 1e4, REASONING_TIER_RANK;
29620
29784
  var init_antigravity = __esm(() => {
29621
- init_authority();
29622
29785
  init_antigravity_token();
29786
+ init_authority();
29623
29787
  init_gemini_oauth();
29624
29788
  init_gemini_queue();
29625
29789
  init_logger();
@@ -32394,10 +32558,10 @@ var API_KEY_INFO, PROVIDER_DISPLAY_NAMES;
32394
32558
  var init_provider_resolver = __esm(() => {
32395
32559
  init_authority();
32396
32560
  init_model_parser();
32561
+ init_onepassword();
32397
32562
  init_provider_definitions();
32398
32563
  init_provider_registry();
32399
32564
  init_remote_provider_registry();
32400
- init_onepassword();
32401
32565
  init_routing_hints();
32402
32566
  init_routing_rules();
32403
32567
  API_KEY_INFO = new Proxy({}, {
@@ -37251,24 +37415,24 @@ CRITICAL INSTRUCTION FOR OUTPUT FORMAT:
37251
37415
  const cleanedLines = [];
37252
37416
  let wasFiltered = false;
37253
37417
  for (const line of lines) {
37254
- const trimmed = line.trim();
37255
- if (!trimmed) {
37418
+ const trimmed2 = line.trim();
37419
+ if (!trimmed2) {
37256
37420
  cleanedLines.push(line);
37257
37421
  continue;
37258
37422
  }
37259
- if (this.isReasoningLine(trimmed)) {
37260
- log(`[GeminiAPIFormat] Filtered reasoning: "${trimmed.substring(0, 50)}..."`);
37423
+ if (this.isReasoningLine(trimmed2)) {
37424
+ log(`[GeminiAPIFormat] Filtered reasoning: "${trimmed2.substring(0, 50)}..."`);
37261
37425
  wasFiltered = true;
37262
37426
  this.inReasoningBlock = true;
37263
37427
  this.reasoningBlockDepth++;
37264
37428
  continue;
37265
37429
  }
37266
- if (this.inReasoningBlock && this.isReasoningContinuation(trimmed)) {
37267
- log(`[GeminiAPIFormat] Filtered reasoning continuation: "${trimmed.substring(0, 50)}..."`);
37430
+ if (this.inReasoningBlock && this.isReasoningContinuation(trimmed2)) {
37431
+ log(`[GeminiAPIFormat] Filtered reasoning continuation: "${trimmed2.substring(0, 50)}..."`);
37268
37432
  wasFiltered = true;
37269
37433
  continue;
37270
37434
  }
37271
- if (this.inReasoningBlock && trimmed.length > 20 && !this.isReasoningContinuation(trimmed)) {
37435
+ if (this.inReasoningBlock && trimmed2.length > 20 && !this.isReasoningContinuation(trimmed2)) {
37272
37436
  this.inReasoningBlock = false;
37273
37437
  this.reasoningBlockDepth = 0;
37274
37438
  }
@@ -37352,10 +37516,24 @@ var init_glm_model_dialect = __esm(() => {
37352
37516
  }
37353
37517
  applyNativeReasoning(request, originalRequest) {
37354
37518
  const effort = this.resolveEffortLevel(originalRequest);
37355
- if (effort && this.isHybridThinkingModel()) {
37356
- const type = effort === "none" || effort === "minimal" ? "disabled" : "enabled";
37357
- request.thinking = { type };
37358
- log(`[GLMModelDialect] effort ${effort} -> thinking.type: ${type} for ${this.modelId}`);
37519
+ const reasoning = this.lookupReasoningCapability();
37520
+ if (effort && this.acceptsThinkingToggle(reasoning)) {
37521
+ if (effort === "none" || effort === "minimal") {
37522
+ request.thinking = { type: "disabled" };
37523
+ if (request.reasoning_effort !== undefined)
37524
+ delete request.reasoning_effort;
37525
+ log(`[GLMModelDialect] effort ${effort} -> thinking.type: disabled for ${this.modelId}`);
37526
+ return request;
37527
+ }
37528
+ request.thinking = { type: "enabled" };
37529
+ if (reasoning?.control === "effort" && reasoning.efforts?.length) {
37530
+ const level = this.clampToAdvertisedEffort(effort, reasoning);
37531
+ if (level)
37532
+ request.reasoning_effort = level;
37533
+ log(`[GLMModelDialect] effort ${effort} -> thinking: enabled, reasoning_effort: ${level ?? "(none advertised)"} for ${this.modelId} (advertised: ${reasoning.efforts.join("/")})`);
37534
+ return request;
37535
+ }
37536
+ log(`[GLMModelDialect] effort ${effort} -> thinking.type: enabled for ${this.modelId}`);
37359
37537
  return request;
37360
37538
  }
37361
37539
  if (request.thinking) {
@@ -37364,9 +37542,19 @@ var init_glm_model_dialect = __esm(() => {
37364
37542
  }
37365
37543
  return request;
37366
37544
  }
37367
- isHybridThinkingModel() {
37368
- const model = this.modelId.toLowerCase();
37369
- return /glm-4\.[56]/.test(model);
37545
+ acceptsThinkingToggle(reasoning) {
37546
+ if (reasoning)
37547
+ return reasoning.supported !== false;
37548
+ return this.looksLikeThinkingCapableGlm();
37549
+ }
37550
+ looksLikeThinkingCapableGlm() {
37551
+ const bare = this.modelId.toLowerCase().split("/").pop() ?? "";
37552
+ const match2 = /^glm-(\d+)(?:\.(\d+))?/.exec(bare);
37553
+ if (!match2)
37554
+ return false;
37555
+ const major = Number(match2[1]);
37556
+ const minor = match2[2] === undefined ? 0 : Number(match2[2]);
37557
+ return major > 4 || major === 4 && minor >= 5;
37370
37558
  }
37371
37559
  shouldHandle(modelId) {
37372
37560
  return matchesModelFamily(modelId, "glm-") || matchesModelFamily(modelId, "chatglm-") || modelId.toLowerCase().includes("zhipu/");
@@ -38163,6 +38351,79 @@ ${text}`;
38163
38351
  };
38164
38352
  });
38165
38353
 
38354
+ // src/behavior/hooks.ts
38355
+ import { isAbsolute, resolve } from "path";
38356
+ function isBehaviorRule(value) {
38357
+ return !!value && typeof value === "object" && typeof value.id === "string" && value.id.length > 0 && typeof value.appliesTo === "function" && (value.onRequest === undefined || typeof value.onRequest === "function") && (value.onToolCall === undefined || typeof value.onToolCall === "function");
38358
+ }
38359
+ function collectRules(mod) {
38360
+ const found = [];
38361
+ const consider = (v) => {
38362
+ if (Array.isArray(v))
38363
+ v.forEach(consider);
38364
+ else if (isBehaviorRule(v))
38365
+ found.push(v);
38366
+ };
38367
+ consider(mod?.default);
38368
+ consider(mod?.rules);
38369
+ for (const [key, value] of Object.entries(mod ?? {})) {
38370
+ if (key === "default" || key === "rules")
38371
+ continue;
38372
+ consider(value);
38373
+ }
38374
+ return [...new Set(found)];
38375
+ }
38376
+ function shortName(path) {
38377
+ const base = path.split("/").pop() ?? path;
38378
+ return base.replace(/\.[cm]?[jt]s$/, "");
38379
+ }
38380
+ async function loadHookRules(paths, cwd = process.cwd()) {
38381
+ if (!paths?.length)
38382
+ return [];
38383
+ const loaded = [];
38384
+ const seen = new Set;
38385
+ for (const raw2 of paths) {
38386
+ const abs = isAbsolute(raw2) ? raw2 : resolve(cwd, raw2);
38387
+ const rules = await importHook(abs, raw2);
38388
+ for (const rule of rules)
38389
+ namespaceInto(rule, abs, seen, loaded);
38390
+ }
38391
+ if (loaded.length > 0) {
38392
+ logStderr(`[behavior] Loaded ${loaded.length} hook rule(s): ${loaded.map((r) => r.id).join(", ")}`);
38393
+ }
38394
+ return loaded;
38395
+ }
38396
+ async function importHook(abs, raw2) {
38397
+ let mod;
38398
+ try {
38399
+ mod = await import(abs);
38400
+ } catch (err) {
38401
+ logStderr(`[behavior] Skipping hook ${raw2}: ${err instanceof Error ? err.message : err}`);
38402
+ return [];
38403
+ }
38404
+ const rules = collectRules(mod);
38405
+ if (rules.length === 0) {
38406
+ logStderr(`[behavior] Hook ${raw2} exported no valid BehaviorRule \u2014 skipped`);
38407
+ }
38408
+ return rules;
38409
+ }
38410
+ function namespaceInto(rule, abs, seen, out) {
38411
+ const namespaced = `hook:${shortName(abs)}/${rule.id}`;
38412
+ if (seen.has(namespaced)) {
38413
+ logStderr(`[behavior] Duplicate hook rule ${namespaced} \u2014 keeping the first`);
38414
+ return;
38415
+ }
38416
+ seen.add(namespaced);
38417
+ out.push({
38418
+ ...rule,
38419
+ id: namespaced,
38420
+ defaultSeverity: rule.defaultSeverity ?? "warn"
38421
+ });
38422
+ }
38423
+ var init_hooks = __esm(() => {
38424
+ init_logger();
38425
+ });
38426
+
38166
38427
  // ../../node_modules/.bun/zod@4.1.13/node_modules/zod/index.js
38167
38428
  var init_zod = __esm(() => {
38168
38429
  init_external2();
@@ -38254,10 +38515,10 @@ function extractAvailableSkills(systemText) {
38254
38515
  const body = systemText.slice(start.index + start[0].length);
38255
38516
  for (const line of body.split(`
38256
38517
  `)) {
38257
- const trimmed = line.trim();
38258
- if (!trimmed)
38518
+ const trimmed2 = line.trim();
38519
+ if (!trimmed2)
38259
38520
  continue;
38260
- const m = SKILL_LINE.exec(trimmed);
38521
+ const m = SKILL_LINE.exec(trimmed2);
38261
38522
  if (!m) {
38262
38523
  if (out.length > 0)
38263
38524
  break;
@@ -38402,6 +38663,20 @@ var init_journal = __esm(() => {
38402
38663
  });
38403
38664
 
38404
38665
  // src/behavior/telemetry/aggregate.ts
38666
+ var exports_aggregate = {};
38667
+ __export(exports_aggregate, {
38668
+ spoolPendingSync: () => spoolPendingSync,
38669
+ setTelemetryConsent: () => setTelemetryConsent,
38670
+ setSessionContextWindow: () => setSessionContextWindow,
38671
+ resetTelemetryState: () => resetTelemetryState,
38672
+ recordTelemetryTurn: () => recordTelemetryTurn,
38673
+ recordTelemetryDecision: () => recordTelemetryDecision,
38674
+ pendingReports: () => pendingReports,
38675
+ outboxPath: () => outboxPath,
38676
+ contextFillPct: () => contextFillPct,
38677
+ contextBucket: () => contextBucket,
38678
+ TELEMETRY_SCHEMA_VERSION: () => TELEMETRY_SCHEMA_VERSION
38679
+ });
38405
38680
  import { createHash as createHash4, randomBytes as randomBytes4 } from "crypto";
38406
38681
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync9 } from "fs";
38407
38682
  import { homedir as homedir19 } from "os";
@@ -38417,6 +38692,14 @@ function contextBucket(inputTokens) {
38417
38692
  return "150-200k";
38418
38693
  return "200k+";
38419
38694
  }
38695
+ function setSessionContextWindow(tokens) {
38696
+ enforcedContextWindow = tokens > 0 ? tokens : 0;
38697
+ }
38698
+ function contextFillPct(peakTokens, window2 = enforcedContextWindow) {
38699
+ if (!(window2 > 0) || !(peakTokens > 0))
38700
+ return;
38701
+ return Math.min(100, Math.max(0, Math.round(peakTokens / window2 * 100)));
38702
+ }
38420
38703
  function hashSessionId(rawSessionId, model) {
38421
38704
  return createHash4("sha256").update(`${SESSION_SALT}:${rawSessionId}:${model}`).digest("hex");
38422
38705
  }
@@ -38426,6 +38709,10 @@ function setTelemetryConsent(value) {
38426
38709
  function enabled() {
38427
38710
  return consent;
38428
38711
  }
38712
+ function resetTelemetryState() {
38713
+ consent = false;
38714
+ sessions.clear();
38715
+ }
38429
38716
  function stateFor(rawSessionId, model, provider) {
38430
38717
  const key = `${rawSessionId}|${model}`;
38431
38718
  let state = sessions.get(key);
@@ -38500,6 +38787,9 @@ function toReport(state) {
38500
38787
  model_id: state.model,
38501
38788
  provider_name: state.provider,
38502
38789
  context_bucket: contextBucket(state.maxInputTokens),
38790
+ ...contextFillPct(state.maxInputTokens) !== undefined && {
38791
+ context_fill_pct: contextFillPct(state.maxInputTokens)
38792
+ },
38503
38793
  turns: state.turns,
38504
38794
  decisions: [...state.decisions.values()]
38505
38795
  };
@@ -38528,7 +38818,7 @@ function spoolPendingSync(path = outboxPath()) {
38528
38818
  return 0;
38529
38819
  }
38530
38820
  }
38531
- var TELEMETRY_SCHEMA_VERSION = 1, SESSION_SALT, MAX_TRACKED_SESSIONS = 32, MAX_DECISION_KEYS = 200, sessions, consent = false;
38821
+ var TELEMETRY_SCHEMA_VERSION = 1, enforcedContextWindow = 0, SESSION_SALT, MAX_TRACKED_SESSIONS = 32, MAX_DECISION_KEYS = 200, sessions, consent = false;
38532
38822
  var init_aggregate = __esm(() => {
38533
38823
  init_logger();
38534
38824
  SESSION_SALT = randomBytes4(32).toString("hex");
@@ -38756,7 +39046,7 @@ __export(exports_upload, {
38756
39046
  });
38757
39047
  import { readFile as readFile2, rename as rename2, unlink, writeFile as writeFile2 } from "fs/promises";
38758
39048
  function sleep2(ms) {
38759
- return new Promise((resolve) => setTimeout(resolve, ms));
39049
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
38760
39050
  }
38761
39051
  async function post(report) {
38762
39052
  const controller = new AbortController;
@@ -39317,79 +39607,6 @@ Do not invent a different filename, and do not derive one from the task. Claude
39317
39607
  PLAN_MODE_RULES = [planFilePathRule];
39318
39608
  });
39319
39609
 
39320
- // src/behavior/hooks.ts
39321
- import { isAbsolute, resolve } from "path";
39322
- function isBehaviorRule(value) {
39323
- return !!value && typeof value === "object" && typeof value.id === "string" && value.id.length > 0 && typeof value.appliesTo === "function" && (value.onRequest === undefined || typeof value.onRequest === "function") && (value.onToolCall === undefined || typeof value.onToolCall === "function");
39324
- }
39325
- function collectRules(mod) {
39326
- const found = [];
39327
- const consider = (v) => {
39328
- if (Array.isArray(v))
39329
- v.forEach(consider);
39330
- else if (isBehaviorRule(v))
39331
- found.push(v);
39332
- };
39333
- consider(mod?.default);
39334
- consider(mod?.rules);
39335
- for (const [key, value] of Object.entries(mod ?? {})) {
39336
- if (key === "default" || key === "rules")
39337
- continue;
39338
- consider(value);
39339
- }
39340
- return [...new Set(found)];
39341
- }
39342
- function shortName(path) {
39343
- const base = path.split("/").pop() ?? path;
39344
- return base.replace(/\.[cm]?[jt]s$/, "");
39345
- }
39346
- async function loadHookRules(paths, cwd = process.cwd()) {
39347
- if (!paths?.length)
39348
- return [];
39349
- const loaded = [];
39350
- const seen = new Set;
39351
- for (const raw2 of paths) {
39352
- const abs = isAbsolute(raw2) ? raw2 : resolve(cwd, raw2);
39353
- const rules = await importHook(abs, raw2);
39354
- for (const rule of rules)
39355
- namespaceInto(rule, abs, seen, loaded);
39356
- }
39357
- if (loaded.length > 0) {
39358
- logStderr(`[behavior] Loaded ${loaded.length} hook rule(s): ${loaded.map((r) => r.id).join(", ")}`);
39359
- }
39360
- return loaded;
39361
- }
39362
- async function importHook(abs, raw2) {
39363
- let mod;
39364
- try {
39365
- mod = await import(abs);
39366
- } catch (err) {
39367
- logStderr(`[behavior] Skipping hook ${raw2}: ${err instanceof Error ? err.message : err}`);
39368
- return [];
39369
- }
39370
- const rules = collectRules(mod);
39371
- if (rules.length === 0) {
39372
- logStderr(`[behavior] Hook ${raw2} exported no valid BehaviorRule \u2014 skipped`);
39373
- }
39374
- return rules;
39375
- }
39376
- function namespaceInto(rule, abs, seen, out) {
39377
- const namespaced = `hook:${shortName(abs)}/${rule.id}`;
39378
- if (seen.has(namespaced)) {
39379
- logStderr(`[behavior] Duplicate hook rule ${namespaced} \u2014 keeping the first`);
39380
- return;
39381
- }
39382
- seen.add(namespaced);
39383
- out.push({
39384
- ...rule,
39385
- id: namespaced,
39386
- defaultSeverity: rule.defaultSeverity ?? "warn"
39387
- });
39388
- }
39389
- var init_hooks = __esm(() => {
39390
- init_logger();
39391
- });
39392
-
39393
39610
  // src/behavior/observer/corpus.ts
39394
39611
  import { appendFileSync as appendFileSync4, readFileSync as readFileSync12, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
39395
39612
  import { homedir as homedir21 } from "os";
@@ -40145,12 +40362,12 @@ function writeToDisk(events) {
40145
40362
  if (events.length === 0)
40146
40363
  return;
40147
40364
  ensureDir();
40148
- const trimmed = enforceSizeCap([...events]);
40149
- const payload = { version: 1, events: trimmed };
40365
+ const trimmed2 = enforceSizeCap([...events]);
40366
+ const payload = { version: 1, events: trimmed2 };
40150
40367
  const tmpFile = join22(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
40151
40368
  writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
40152
40369
  renameSync(tmpFile, BUFFER_FILE);
40153
- memoryCache = trimmed;
40370
+ memoryCache = trimmed2;
40154
40371
  } catch {}
40155
40372
  }
40156
40373
  function flushToDisk() {
@@ -40526,8 +40743,8 @@ function enforceReportSize(report) {
40526
40743
  let msg = report.error_message_template;
40527
40744
  while (serialized.length > MAX_REPORT_BYTES && msg.length > 0) {
40528
40745
  msg = msg.slice(0, Math.max(0, msg.length - 50));
40529
- const trimmed = { ...report, error_message_template: `${msg}...` };
40530
- serialized = JSON.stringify(trimmed);
40746
+ const trimmed2 = { ...report, error_message_template: `${msg}...` };
40747
+ serialized = JSON.stringify(trimmed2);
40531
40748
  }
40532
40749
  return serialized.length <= MAX_REPORT_BYTES ? serialized : null;
40533
40750
  }
@@ -41171,8 +41388,8 @@ function buildSurfacedErrorMessage(opts) {
41171
41388
  parts[0] = `${head}: ${hint}`;
41172
41389
  const detail = (providerMessage || "").trim();
41173
41390
  if (detail && !parts[0].includes(detail)) {
41174
- const trimmed = detail.length > 600 ? `${detail.slice(0, 600)}\u2026` : detail;
41175
- parts.push(`\u2014 ${trimmed}`);
41391
+ const trimmed2 = detail.length > 600 ? `${detail.slice(0, 600)}\u2026` : detail;
41392
+ parts.push(`\u2014 ${trimmed2}`);
41176
41393
  }
41177
41394
  return parts.join(" ");
41178
41395
  }
@@ -41404,10 +41621,10 @@ async function sniffResponsesStreamHead(response, opts = {}) {
41404
41621
  `);
41405
41622
  pending = lines.pop() ?? "";
41406
41623
  for (const line of lines) {
41407
- const trimmed = line.trim();
41408
- if (!trimmed.startsWith("data:"))
41624
+ const trimmed2 = line.trim();
41625
+ if (!trimmed2.startsWith("data:"))
41409
41626
  continue;
41410
- const payload = trimmed.slice(5).trim();
41627
+ const payload = trimmed2.slice(5).trim();
41411
41628
  if (!payload || payload === "[DONE]")
41412
41629
  continue;
41413
41630
  let event;
@@ -43482,8 +43699,9 @@ function getRecoveryHint(status, errorText, providerName) {
43482
43699
  var STREAM_RETRY_DELAYS_MS;
43483
43700
  var init_composed_handler = __esm(() => {
43484
43701
  init_dialect_manager();
43485
- init_logger();
43702
+ init_model_catalog();
43486
43703
  init_behavior();
43704
+ init_logger();
43487
43705
  init_middleware();
43488
43706
  init_openai();
43489
43707
  init_vision_proxy();
@@ -43498,7 +43716,6 @@ var init_composed_handler = __esm(() => {
43498
43716
  init_anthropic_sse();
43499
43717
  init_gemini_sse();
43500
43718
  init_ollama_jsonl();
43501
- init_model_catalog();
43502
43719
  init_openai_responses_sse();
43503
43720
  init_openai_sse();
43504
43721
  init_token_tracker();
@@ -44521,7 +44738,7 @@ function readContextWindow(row) {
44521
44738
  }
44522
44739
  function readCreatedDate(row) {
44523
44740
  const raw2 = row.created;
44524
- const seconds = typeof raw2 === "number" ? raw2 : typeof raw2 === "string" ? Number(raw2) : NaN;
44741
+ const seconds = typeof raw2 === "number" ? raw2 : typeof raw2 === "string" ? Number(raw2) : Number.NaN;
44525
44742
  if (!Number.isFinite(seconds))
44526
44743
  return;
44527
44744
  if (seconds < MIN_CREATED_SECONDS || seconds > MAX_CREATED_SECONDS)
@@ -45812,7 +46029,7 @@ class GeminiCodeAssistProviderTransport {
45812
46029
  const list = served.join(", ");
45813
46030
  const tier = this._displayName || "Gemini Code Assist";
45814
46031
  const reason = capacityFallbacksExhausted ? `${this.modelName} could not be served after every Gemini Code Assist capacity fallback failed (${tier}, via go@). ` + `That tier currently reports: ${list}. ` : `${this.modelName} is not served by your Gemini Code Assist tier (${tier}, via go@). ` + `That tier currently serves: ${list}. `;
45815
- const message = reason + `To use ${this.modelName}, go through the direct Gemini API instead \u2014 ` + `set GEMINI_API_KEY (get one at https://aistudio.google.com/app/apikey) and run ` + `google@${this.modelName}.`;
46032
+ const message = reason + `To use ${this.modelName}, go through the direct Gemini API instead \u2014 ` + "set GEMINI_API_KEY (get one at https://aistudio.google.com/app/apikey) and run " + `google@${this.modelName}.`;
45816
46033
  const body = JSON.stringify({
45817
46034
  error: { code: 404, status: "NOT_FOUND", message }
45818
46035
  });
@@ -47500,6 +47717,8 @@ var init_proxy_server = __esm(() => {
47500
47717
  init_local_adapter();
47501
47718
  init_openrouter_api_format();
47502
47719
  init_authority();
47720
+ init_hooks();
47721
+ init_behavior();
47503
47722
  init_composed_handler();
47504
47723
  init_fallback_handler();
47505
47724
  init_native_handler();
@@ -47508,8 +47727,6 @@ var init_proxy_server = __esm(() => {
47508
47727
  init_model_loader();
47509
47728
  init_profile_config();
47510
47729
  init_api_key_map();
47511
- init_behavior();
47512
- init_hooks();
47513
47730
  init_custom_endpoints_loader();
47514
47731
  init_model_catalog_resolver();
47515
47732
  init_model_parser();
@@ -47776,7 +47993,7 @@ function classifyRunOutput(opts) {
47776
47993
  if (bgCeiling) {
47777
47994
  return {
47778
47995
  reason: "background_task_ceiling",
47779
- detail: `Claude Code terminated the turn after ${bgCeiling[1]}s waiting on background tasks, ` + `flushing only partial output. Set CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 in the child ` + `environment to wait indefinitely, or tell the model not to spawn background work.`
47996
+ detail: `Claude Code terminated the turn after ${bgCeiling[1]}s waiting on background tasks, ` + "flushing only partial output. Set CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 in the child " + "environment to wait indefinitely, or tell the model not to spawn background work."
47780
47997
  };
47781
47998
  }
47782
47999
  const tailIsWholeOutput = outputSize <= STDOUT_TAIL_LIMIT;
@@ -48046,7 +48263,7 @@ async function runModels(sessionPath, opts = {}) {
48046
48263
  const stderr = rt?.getStderr() ?? "";
48047
48264
  const stdoutTail = rt?.getStdoutTail() ?? "";
48048
48265
  const bytes = rt?.getByteCount() ?? 0;
48049
- const detail = `Killed by the orchestrator after ${timeoutMs / 1000}s with ${bytes} B of stdout. ` + `In --quiet print mode the child emits its answer only at the end, so 0 B means ` + `"did not finish", not "produced nothing".`;
48266
+ const detail = `Killed by the orchestrator after ${timeoutMs / 1000}s with ${bytes} B of stdout. ` + "In --quiet print mode the child emits its answer only at the end, so 0 B means " + `"did not finish", not "produced nothing".`;
48050
48267
  if (rt)
48051
48268
  persistErrorLog(rt.errorLogPath, `TIMEOUT: ${detail}`, stderr, stdoutTail);
48052
48269
  updateModelStatus(id, {
@@ -48446,7 +48663,7 @@ function formatTeamResult(status, sessionPath) {
48446
48663
  }
48447
48664
  }
48448
48665
  lines.push("actions:");
48449
- lines.push(` full stderr/stdout for one failure \u2192 Read the evidence path above`);
48666
+ lines.push(" full stderr/stdout for one failure \u2192 Read the evidence path above");
48450
48667
  lines.push(` machine-readable status \u2192 team(mode="status", path="${sessionPath}")`);
48451
48668
  lines.push(` report a provider bug \u2192 report_error(session_path="${sessionPath}")`);
48452
48669
  }
@@ -49731,8 +49948,8 @@ function maskKey2(key) {
49731
49948
  }
49732
49949
  var SKIP, PROVIDERS;
49733
49950
  var init_providers = __esm(() => {
49734
- init_source();
49735
49951
  init_antigravity_token();
49952
+ init_source();
49736
49953
  init_oauth_registry();
49737
49954
  init_provider_definitions();
49738
49955
  SKIP = new Set(["qwen", "native-anthropic"]);
@@ -63578,15 +63795,15 @@ async function promptForProfileName(existing = []) {
63578
63795
  const name = await dist_default5({
63579
63796
  message: "Enter profile name:",
63580
63797
  validate: (value) => {
63581
- const trimmed = value.trim();
63582
- if (!trimmed) {
63798
+ const trimmed2 = value.trim();
63799
+ if (!trimmed2) {
63583
63800
  return "Profile name cannot be empty";
63584
63801
  }
63585
- if (!/^[a-z0-9-_]+$/i.test(trimmed)) {
63802
+ if (!/^[a-z0-9-_]+$/i.test(trimmed2)) {
63586
63803
  return "Profile name can only contain letters, numbers, hyphens, and underscores";
63587
63804
  }
63588
- if (existing.includes(trimmed)) {
63589
- return `Profile "${trimmed}" already exists`;
63805
+ if (existing.includes(trimmed2)) {
63806
+ return `Profile "${trimmed2}" already exists`;
63590
63807
  }
63591
63808
  return true;
63592
63809
  }
@@ -63983,10 +64200,10 @@ function extractErrorMessage(body) {
63983
64200
  return msg.length > 160 ? `${msg.slice(0, 157)}...` : msg;
63984
64201
  }
63985
64202
  } catch {}
63986
- const trimmed = body.trim();
63987
- if (!trimmed)
64203
+ const trimmed2 = body.trim();
64204
+ if (!trimmed2)
63988
64205
  return;
63989
- return trimmed.length > 160 ? `${trimmed.slice(0, 157)}...` : trimmed;
64206
+ return trimmed2.length > 160 ? `${trimmed2.slice(0, 157)}...` : trimmed2;
63990
64207
  }
63991
64208
  async function consumeProbeStream(response, timeoutMs, startedAt) {
63992
64209
  const body = response.body;
@@ -73761,6 +73978,7 @@ function App({ requestLogin } = {}) {
73761
73978
  const [opKindCursor, setOpKindCursor] = useState5(0);
73762
73979
  const [opAccountCursor, setOpAccountCursor] = useState5(0);
73763
73980
  const [opAccounts, setOpAccounts] = useState5([]);
73981
+ const opActiveAccount = useRef4(undefined);
73764
73982
  const [opTestResults, setOpTestResults] = useState5({});
73765
73983
  const [opPendingKind, setOpPendingKind] = useState5("ref");
73766
73984
  const [opPendingValue, setOpPendingValue] = useState5("");
@@ -73937,7 +74155,7 @@ function App({ requestLogin } = {}) {
73937
74155
  setOpFieldCursor(idx < 0 ? 0 : idx);
73938
74156
  }, [opFieldOptionsFiltered, opFieldCursor, mode]);
73939
74157
  const acquireOpAuth = useCallback3(async () => {
73940
- return resolveSdkAuth({
74158
+ const auth = await resolveSdkAuth({
73941
74159
  interactive: true,
73942
74160
  configAccount: readOnepasswordAccount(),
73943
74161
  onNeedsPicker: (accounts) => new Promise((resolve4) => {
@@ -73952,6 +74170,8 @@ function App({ requestLogin } = {}) {
73952
74170
  setMode("pick_op_account");
73953
74171
  })
73954
74172
  });
74173
+ opActiveAccount.current = auth.kind === "desktop" ? auth.accountName : undefined;
74174
+ return auth;
73955
74175
  }, []);
73956
74176
  const testOpEntry = useCallback3(async (entry) => {
73957
74177
  const key = `${entry.scope}:${entry.kind}:${entry.value}`;
@@ -74015,9 +74235,9 @@ function App({ requestLogin } = {}) {
74015
74235
  if (kind === "account") {
74016
74236
  saveOnepasswordAccount(value, scope);
74017
74237
  } else if (kind === "environment") {
74018
- addOnepasswordEnvironment(value, scope);
74238
+ addOnepasswordEnvironment(value, scope, undefined, opActiveAccount.current);
74019
74239
  } else {
74020
- addOnepasswordImport(value, scope);
74240
+ addOnepasswordImport(value, scope, undefined, opActiveAccount.current);
74021
74241
  }
74022
74242
  refreshConfig();
74023
74243
  const isGlob = kind === "glob" || isGlobImport(value);
@@ -75810,13 +76030,13 @@ function chainableCommandOf(statusLine) {
75810
76030
  const { type, command } = statusLine;
75811
76031
  if (type !== "command" || typeof command !== "string")
75812
76032
  return null;
75813
- const trimmed = command.trim();
75814
- if (!trimmed)
76033
+ const trimmed2 = command.trim();
76034
+ if (!trimmed2)
75815
76035
  return null;
75816
- if (trimmed.includes("CLAUDISH_ACTIVE_MODEL_NAME") || trimmed.includes("CLAUDISH_IS_LOCAL")) {
76036
+ if (trimmed2.includes("CLAUDISH_ACTIVE_MODEL_NAME") || trimmed2.includes("CLAUDISH_IS_LOCAL")) {
75817
76037
  return null;
75818
76038
  }
75819
- return trimmed;
76039
+ return trimmed2;
75820
76040
  }
75821
76041
  function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
75822
76042
  const quotedUser = `'${userCommand.replace(/'/g, `'\\''`)}'`;
@@ -76065,6 +76285,10 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
76065
76285
  const realWindow = await computeMainThreadContextWindow(config3);
76066
76286
  const contextEnv = resolveContextWindowEnv(realWindow, process.env);
76067
76287
  Object.assign(env, contextEnv.vars);
76288
+ try {
76289
+ const { setSessionContextWindow: setSessionContextWindow2 } = await Promise.resolve().then(() => (init_aggregate(), exports_aggregate));
76290
+ setSessionContextWindow2(realWindow);
76291
+ } catch {}
76068
76292
  if (contextEnv.notice && !config3.quiet) {
76069
76293
  console.error(contextEnv.notice);
76070
76294
  }
@@ -76123,7 +76347,7 @@ Or set CLAUDE_PATH to your custom installation:`);
76123
76347
  ttyFd = undefined;
76124
76348
  }
76125
76349
  } else if (config3.interactive && !process.stdout.isTTY && !process.stdin.isTTY) {
76126
- console.error("[claudish] An interactive session was requested but no terminal is attached " + "(stdin and stdout are both non-TTY). Pass a prompt argument, or use --stdin / -p " + "for non-interactive mode.");
76350
+ console.error("[claudish] An interactive session was requested but no terminal is attached (stdin and stdout are both non-TTY). Pass a prompt argument, or use --stdin / -p for non-interactive mode.");
76127
76351
  }
76128
76352
  const stdio = ttyFd !== undefined ? [0, ttyFd, ttyFd] : "inherit";
76129
76353
  const proc = spawn4(spawnCommand, claudeArgs, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.35.0",
3
+ "version": "7.37.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.35.0",
64
- "@claudish/magmux-darwin-x64": "7.35.0",
65
- "@claudish/magmux-linux-arm64": "7.35.0",
66
- "@claudish/magmux-linux-x64": "7.35.0"
63
+ "@claudish/magmux-darwin-arm64": "7.37.0",
64
+ "@claudish/magmux-darwin-x64": "7.37.0",
65
+ "@claudish/magmux-linux-arm64": "7.37.0",
66
+ "@claudish/magmux-linux-x64": "7.37.0"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",