claudish 7.34.0 → 7.36.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 +729 -328
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -651,7 +651,7 @@ var init_onepassword_config = __esm(() => {
651
651
  });
652
652
 
653
653
  // src/version.ts
654
- var VERSION = "7.34.0";
654
+ var VERSION = "7.36.0";
655
655
 
656
656
  // src/logger.ts
657
657
  var exports_logger = {};
@@ -4611,9 +4611,12 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
4611
4611
  } catch {
4612
4612
  return false;
4613
4613
  }
4614
- }, screenLockProbe, defaultAppLockProbe = () => false, appLockProbe, defaultOpAccountLister = () => {
4614
+ }, screenLockProbe, defaultAppLockProbe = () => false, appLockProbe, OP_PROBE_TIMEOUT_MS = 5000, defaultOpAccountLister = () => {
4615
4615
  try {
4616
- const res = spawnSync("op", ["account", "list", "--format=json"], { encoding: "utf-8" });
4616
+ const res = spawnSync("op", ["account", "list", "--format=json"], {
4617
+ encoding: "utf-8",
4618
+ timeout: OP_PROBE_TIMEOUT_MS
4619
+ });
4617
4620
  if (res.error || res.status !== 0)
4618
4621
  return null;
4619
4622
  const parsed = JSON.parse(res.stdout ?? "");
@@ -4639,7 +4642,10 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
4639
4642
  }
4640
4643
  }, defaultOpDefaultAccountProbe = () => {
4641
4644
  try {
4642
- const res = spawnSync("op", ["account", "get", "--format=json"], { encoding: "utf-8" });
4645
+ const res = spawnSync("op", ["account", "get", "--format=json"], {
4646
+ encoding: "utf-8",
4647
+ timeout: OP_PROBE_TIMEOUT_MS
4648
+ });
4643
4649
  if (res.error || res.status !== 0)
4644
4650
  return null;
4645
4651
  const parsed = JSON.parse(res.stdout ?? "");
@@ -29562,7 +29568,7 @@ class AntigravityProviderTransport {
29562
29568
  const servesClause = served.length > 0 ? `That tier currently serves: ${served.join(", ")}. ` : "";
29563
29569
  const tier = this._displayName || "Antigravity";
29564
29570
  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}.`;
29571
+ 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
29572
  const list = served.join(", ");
29567
29573
  const body = JSON.stringify({
29568
29574
  error: { code: 404, status: "NOT_FOUND", message }
@@ -29618,8 +29624,8 @@ ${lines.join(`
29618
29624
  }
29619
29625
  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
29626
  var init_antigravity = __esm(() => {
29621
- init_authority();
29622
29627
  init_antigravity_token();
29628
+ init_authority();
29623
29629
  init_gemini_oauth();
29624
29630
  init_gemini_queue();
29625
29631
  init_logger();
@@ -32394,10 +32400,10 @@ var API_KEY_INFO, PROVIDER_DISPLAY_NAMES;
32394
32400
  var init_provider_resolver = __esm(() => {
32395
32401
  init_authority();
32396
32402
  init_model_parser();
32403
+ init_onepassword();
32397
32404
  init_provider_definitions();
32398
32405
  init_provider_registry();
32399
32406
  init_remote_provider_registry();
32400
- init_onepassword();
32401
32407
  init_routing_hints();
32402
32408
  init_routing_rules();
32403
32409
  API_KEY_INFO = new Proxy({}, {
@@ -37352,10 +37358,24 @@ var init_glm_model_dialect = __esm(() => {
37352
37358
  }
37353
37359
  applyNativeReasoning(request, originalRequest) {
37354
37360
  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}`);
37361
+ const reasoning = this.lookupReasoningCapability();
37362
+ if (effort && this.acceptsThinkingToggle(reasoning)) {
37363
+ if (effort === "none" || effort === "minimal") {
37364
+ request.thinking = { type: "disabled" };
37365
+ if (request.reasoning_effort !== undefined)
37366
+ delete request.reasoning_effort;
37367
+ log(`[GLMModelDialect] effort ${effort} -> thinking.type: disabled for ${this.modelId}`);
37368
+ return request;
37369
+ }
37370
+ request.thinking = { type: "enabled" };
37371
+ if (reasoning?.control === "effort" && reasoning.efforts?.length) {
37372
+ const level = this.clampToAdvertisedEffort(effort, reasoning);
37373
+ if (level)
37374
+ request.reasoning_effort = level;
37375
+ log(`[GLMModelDialect] effort ${effort} -> thinking: enabled, reasoning_effort: ${level ?? "(none advertised)"} for ${this.modelId} (advertised: ${reasoning.efforts.join("/")})`);
37376
+ return request;
37377
+ }
37378
+ log(`[GLMModelDialect] effort ${effort} -> thinking.type: enabled for ${this.modelId}`);
37359
37379
  return request;
37360
37380
  }
37361
37381
  if (request.thinking) {
@@ -37364,9 +37384,19 @@ var init_glm_model_dialect = __esm(() => {
37364
37384
  }
37365
37385
  return request;
37366
37386
  }
37367
- isHybridThinkingModel() {
37368
- const model = this.modelId.toLowerCase();
37369
- return /glm-4\.[56]/.test(model);
37387
+ acceptsThinkingToggle(reasoning) {
37388
+ if (reasoning)
37389
+ return reasoning.supported !== false;
37390
+ return this.looksLikeThinkingCapableGlm();
37391
+ }
37392
+ looksLikeThinkingCapableGlm() {
37393
+ const bare = this.modelId.toLowerCase().split("/").pop() ?? "";
37394
+ const match2 = /^glm-(\d+)(?:\.(\d+))?/.exec(bare);
37395
+ if (!match2)
37396
+ return false;
37397
+ const major = Number(match2[1]);
37398
+ const minor = match2[2] === undefined ? 0 : Number(match2[2]);
37399
+ return major > 4 || major === 4 && minor >= 5;
37370
37400
  }
37371
37401
  shouldHandle(modelId) {
37372
37402
  return matchesModelFamily(modelId, "glm-") || matchesModelFamily(modelId, "chatglm-") || modelId.toLowerCase().includes("zhipu/");
@@ -38163,6 +38193,79 @@ ${text}`;
38163
38193
  };
38164
38194
  });
38165
38195
 
38196
+ // src/behavior/hooks.ts
38197
+ import { isAbsolute, resolve } from "path";
38198
+ function isBehaviorRule(value) {
38199
+ 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");
38200
+ }
38201
+ function collectRules(mod) {
38202
+ const found = [];
38203
+ const consider = (v) => {
38204
+ if (Array.isArray(v))
38205
+ v.forEach(consider);
38206
+ else if (isBehaviorRule(v))
38207
+ found.push(v);
38208
+ };
38209
+ consider(mod?.default);
38210
+ consider(mod?.rules);
38211
+ for (const [key, value] of Object.entries(mod ?? {})) {
38212
+ if (key === "default" || key === "rules")
38213
+ continue;
38214
+ consider(value);
38215
+ }
38216
+ return [...new Set(found)];
38217
+ }
38218
+ function shortName(path) {
38219
+ const base = path.split("/").pop() ?? path;
38220
+ return base.replace(/\.[cm]?[jt]s$/, "");
38221
+ }
38222
+ async function loadHookRules(paths, cwd = process.cwd()) {
38223
+ if (!paths?.length)
38224
+ return [];
38225
+ const loaded = [];
38226
+ const seen = new Set;
38227
+ for (const raw2 of paths) {
38228
+ const abs = isAbsolute(raw2) ? raw2 : resolve(cwd, raw2);
38229
+ const rules = await importHook(abs, raw2);
38230
+ for (const rule of rules)
38231
+ namespaceInto(rule, abs, seen, loaded);
38232
+ }
38233
+ if (loaded.length > 0) {
38234
+ logStderr(`[behavior] Loaded ${loaded.length} hook rule(s): ${loaded.map((r) => r.id).join(", ")}`);
38235
+ }
38236
+ return loaded;
38237
+ }
38238
+ async function importHook(abs, raw2) {
38239
+ let mod;
38240
+ try {
38241
+ mod = await import(abs);
38242
+ } catch (err) {
38243
+ logStderr(`[behavior] Skipping hook ${raw2}: ${err instanceof Error ? err.message : err}`);
38244
+ return [];
38245
+ }
38246
+ const rules = collectRules(mod);
38247
+ if (rules.length === 0) {
38248
+ logStderr(`[behavior] Hook ${raw2} exported no valid BehaviorRule \u2014 skipped`);
38249
+ }
38250
+ return rules;
38251
+ }
38252
+ function namespaceInto(rule, abs, seen, out) {
38253
+ const namespaced = `hook:${shortName(abs)}/${rule.id}`;
38254
+ if (seen.has(namespaced)) {
38255
+ logStderr(`[behavior] Duplicate hook rule ${namespaced} \u2014 keeping the first`);
38256
+ return;
38257
+ }
38258
+ seen.add(namespaced);
38259
+ out.push({
38260
+ ...rule,
38261
+ id: namespaced,
38262
+ defaultSeverity: rule.defaultSeverity ?? "warn"
38263
+ });
38264
+ }
38265
+ var init_hooks = __esm(() => {
38266
+ init_logger();
38267
+ });
38268
+
38166
38269
  // ../../node_modules/.bun/zod@4.1.13/node_modules/zod/index.js
38167
38270
  var init_zod = __esm(() => {
38168
38271
  init_external2();
@@ -38401,6 +38504,174 @@ var init_journal = __esm(() => {
38401
38504
  PRUNE_TO_BYTES = Math.floor(MAX_JOURNAL_BYTES * 0.6);
38402
38505
  });
38403
38506
 
38507
+ // src/behavior/telemetry/aggregate.ts
38508
+ var exports_aggregate = {};
38509
+ __export(exports_aggregate, {
38510
+ spoolPendingSync: () => spoolPendingSync,
38511
+ setTelemetryConsent: () => setTelemetryConsent,
38512
+ setSessionContextWindow: () => setSessionContextWindow,
38513
+ resetTelemetryState: () => resetTelemetryState,
38514
+ recordTelemetryTurn: () => recordTelemetryTurn,
38515
+ recordTelemetryDecision: () => recordTelemetryDecision,
38516
+ pendingReports: () => pendingReports,
38517
+ outboxPath: () => outboxPath,
38518
+ contextFillPct: () => contextFillPct,
38519
+ contextBucket: () => contextBucket,
38520
+ TELEMETRY_SCHEMA_VERSION: () => TELEMETRY_SCHEMA_VERSION
38521
+ });
38522
+ import { createHash as createHash4, randomBytes as randomBytes4 } from "crypto";
38523
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync9 } from "fs";
38524
+ import { homedir as homedir19 } from "os";
38525
+ import { dirname as dirname7, join as join19 } from "path";
38526
+ function contextBucket(inputTokens) {
38527
+ if (inputTokens < 50000)
38528
+ return "0-50k";
38529
+ if (inputTokens < 1e5)
38530
+ return "50-100k";
38531
+ if (inputTokens < 150000)
38532
+ return "100-150k";
38533
+ if (inputTokens < 200000)
38534
+ return "150-200k";
38535
+ return "200k+";
38536
+ }
38537
+ function setSessionContextWindow(tokens) {
38538
+ enforcedContextWindow = tokens > 0 ? tokens : 0;
38539
+ }
38540
+ function contextFillPct(peakTokens, window2 = enforcedContextWindow) {
38541
+ if (!(window2 > 0) || !(peakTokens > 0))
38542
+ return;
38543
+ return Math.min(100, Math.max(0, Math.round(peakTokens / window2 * 100)));
38544
+ }
38545
+ function hashSessionId(rawSessionId, model) {
38546
+ return createHash4("sha256").update(`${SESSION_SALT}:${rawSessionId}:${model}`).digest("hex");
38547
+ }
38548
+ function setTelemetryConsent(value) {
38549
+ consent = value;
38550
+ }
38551
+ function enabled() {
38552
+ return consent;
38553
+ }
38554
+ function resetTelemetryState() {
38555
+ consent = false;
38556
+ sessions.clear();
38557
+ }
38558
+ function stateFor(rawSessionId, model, provider) {
38559
+ const key = `${rawSessionId}|${model}`;
38560
+ let state = sessions.get(key);
38561
+ if (!state) {
38562
+ while (sessions.size >= MAX_TRACKED_SESSIONS) {
38563
+ const oldest = sessions.keys().next().value;
38564
+ if (oldest === undefined)
38565
+ break;
38566
+ sessions.delete(oldest);
38567
+ }
38568
+ const now = new Date().toISOString();
38569
+ state = {
38570
+ sessionId: hashSessionId(rawSessionId, model),
38571
+ model,
38572
+ provider,
38573
+ startedAt: now,
38574
+ endedAt: now,
38575
+ turns: 0,
38576
+ maxInputTokens: 0,
38577
+ decisions: new Map
38578
+ };
38579
+ sessions.set(key, state);
38580
+ }
38581
+ return state;
38582
+ }
38583
+ function recordTelemetryTurn(p) {
38584
+ if (!enabled() || !p.sessionId)
38585
+ return;
38586
+ const state = stateFor(p.sessionId, p.model, p.provider);
38587
+ if (!state)
38588
+ return;
38589
+ state.turns++;
38590
+ state.endedAt = new Date().toISOString();
38591
+ if (typeof p.inputTokens === "number" && p.inputTokens > state.maxInputTokens) {
38592
+ state.maxInputTokens = p.inputTokens;
38593
+ }
38594
+ }
38595
+ function recordTelemetryDecision(p) {
38596
+ if (!enabled() || !p.sessionId)
38597
+ return;
38598
+ const state = stateFor(p.sessionId, p.model, p.provider);
38599
+ if (!state)
38600
+ return;
38601
+ const key = `${p.ruleId ?? ""}|${p.surface}|${p.toolName ?? ""}`;
38602
+ let agg = state.decisions.get(key);
38603
+ if (!agg) {
38604
+ if (state.decisions.size >= MAX_DECISION_KEYS)
38605
+ return;
38606
+ agg = {
38607
+ rule_id: p.ruleId,
38608
+ surface: p.surface,
38609
+ tool_name: p.toolName,
38610
+ counts: {},
38611
+ path_relations: {}
38612
+ };
38613
+ state.decisions.set(key, agg);
38614
+ }
38615
+ agg.counts[p.decision] = (agg.counts[p.decision] ?? 0) + 1;
38616
+ if (p.pathRelation) {
38617
+ agg.path_relations[p.pathRelation] = (agg.path_relations[p.pathRelation] ?? 0) + 1;
38618
+ }
38619
+ state.endedAt = new Date().toISOString();
38620
+ }
38621
+ function toReport(state) {
38622
+ return {
38623
+ schema_version: TELEMETRY_SCHEMA_VERSION,
38624
+ session_id: state.sessionId,
38625
+ started_at: state.startedAt,
38626
+ ended_at: state.endedAt,
38627
+ claudish_version: VERSION,
38628
+ platform: process.platform,
38629
+ model_id: state.model,
38630
+ provider_name: state.provider,
38631
+ context_bucket: contextBucket(state.maxInputTokens),
38632
+ ...contextFillPct(state.maxInputTokens) !== undefined && {
38633
+ context_fill_pct: contextFillPct(state.maxInputTokens)
38634
+ },
38635
+ turns: state.turns,
38636
+ decisions: [...state.decisions.values()]
38637
+ };
38638
+ }
38639
+ function pendingReports() {
38640
+ return [...sessions.values()].map(toReport);
38641
+ }
38642
+ function outboxPath() {
38643
+ return join19(homedir19(), ".claudish", "behavior-outbox.jsonl");
38644
+ }
38645
+ function spoolPendingSync(path = outboxPath()) {
38646
+ if (sessions.size === 0)
38647
+ return 0;
38648
+ const reports = pendingReports().filter((r) => r.turns > 0 || r.decisions.length > 0);
38649
+ sessions.clear();
38650
+ if (reports.length === 0)
38651
+ return 0;
38652
+ try {
38653
+ mkdirSync9(dirname7(path), { recursive: true });
38654
+ appendFileSync3(path, `${reports.map((r) => JSON.stringify(r)).join(`
38655
+ `)}
38656
+ `);
38657
+ return reports.length;
38658
+ } catch (err) {
38659
+ log(`[behavior:telemetry] could not spool: ${err}`);
38660
+ return 0;
38661
+ }
38662
+ }
38663
+ var TELEMETRY_SCHEMA_VERSION = 1, enforcedContextWindow = 0, SESSION_SALT, MAX_TRACKED_SESSIONS = 32, MAX_DECISION_KEYS = 200, sessions, consent = false;
38664
+ var init_aggregate = __esm(() => {
38665
+ init_logger();
38666
+ SESSION_SALT = randomBytes4(32).toString("hex");
38667
+ sessions = new Map;
38668
+ process.on("exit", () => {
38669
+ try {
38670
+ spoolPendingSync();
38671
+ } catch {}
38672
+ });
38673
+ });
38674
+
38404
38675
  // src/behavior/observer/digest.ts
38405
38676
  var exports_digest = {};
38406
38677
  __export(exports_digest, {
@@ -38592,10 +38863,10 @@ __export(exports_live_log, {
38592
38863
  recordLiveDivergence: () => recordLiveDivergence
38593
38864
  });
38594
38865
  import { appendFile as appendFile3 } from "fs/promises";
38595
- import { homedir as homedir19 } from "os";
38596
- import { join as join19 } from "path";
38866
+ import { homedir as homedir20 } from "os";
38867
+ import { join as join20 } from "path";
38597
38868
  function defaultPath() {
38598
- return join19(homedir19(), ".claudish", "behavior-divergences.jsonl");
38869
+ return join20(homedir20(), ".claudish", "behavior-divergences.jsonl");
38599
38870
  }
38600
38871
  async function recordLiveDivergence(entry, path = defaultPath()) {
38601
38872
  try {
@@ -38609,6 +38880,109 @@ var init_live_log = __esm(() => {
38609
38880
  init_logger();
38610
38881
  });
38611
38882
 
38883
+ // src/behavior/telemetry/upload.ts
38884
+ var exports_upload = {};
38885
+ __export(exports_upload, {
38886
+ resetDrainState: () => resetDrainState,
38887
+ drainOutbox: () => drainOutbox
38888
+ });
38889
+ import { readFile as readFile2, rename as rename2, unlink, writeFile as writeFile2 } from "fs/promises";
38890
+ function sleep2(ms) {
38891
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
38892
+ }
38893
+ async function post(report) {
38894
+ const controller = new AbortController;
38895
+ const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
38896
+ try {
38897
+ const res = await fetch(ENDPOINT, {
38898
+ method: "POST",
38899
+ headers: { "Content-Type": "application/json" },
38900
+ body: JSON.stringify(report),
38901
+ signal: controller.signal
38902
+ });
38903
+ if (res.status === 202)
38904
+ return "sent";
38905
+ if (res.status === 400) {
38906
+ log("[behavior:telemetry] rejected as malformed (400), dropping");
38907
+ return "drop";
38908
+ }
38909
+ if (res.status === 429) {
38910
+ log("[behavior:telemetry] rate limited, deferring to next run");
38911
+ return "retry";
38912
+ }
38913
+ return res.status >= 500 ? "retry" : "drop";
38914
+ } catch {
38915
+ return "retry";
38916
+ } finally {
38917
+ clearTimeout(timer);
38918
+ }
38919
+ }
38920
+ function parseOutbox(content) {
38921
+ const out = [];
38922
+ for (const line of content.split(`
38923
+ `)) {
38924
+ if (!line.trim())
38925
+ continue;
38926
+ try {
38927
+ const parsed = JSON.parse(line);
38928
+ if (parsed && typeof parsed.session_id === "string")
38929
+ out.push(parsed);
38930
+ } catch {}
38931
+ }
38932
+ return out;
38933
+ }
38934
+ async function persistRemaining(path, remaining) {
38935
+ if (remaining.length === 0) {
38936
+ await unlink(path).catch(() => {});
38937
+ return;
38938
+ }
38939
+ const kept = remaining.slice(-MAX_OUTBOX_ENTRIES);
38940
+ const tmp = `${path}.draining`;
38941
+ await writeFile2(tmp, `${kept.map((r) => JSON.stringify(r)).join(`
38942
+ `)}
38943
+ `);
38944
+ await rename2(tmp, path);
38945
+ }
38946
+ async function drainOutbox(path = outboxPath()) {
38947
+ if (drained)
38948
+ return { sent: 0, kept: 0 };
38949
+ drained = true;
38950
+ try {
38951
+ const content = await readFile2(path, "utf8").catch(() => "");
38952
+ const reports = parseOutbox(content);
38953
+ if (reports.length === 0)
38954
+ return { sent: 0, kept: 0 };
38955
+ const batch = reports.slice(-MAX_DRAIN_PER_RUN).reverse();
38956
+ const older = reports.slice(0, Math.max(0, reports.length - MAX_DRAIN_PER_RUN));
38957
+ const keep = [];
38958
+ let sent = 0;
38959
+ for (let i = 0;i < batch.length; i++) {
38960
+ if (i > 0)
38961
+ await sleep2(SEND_INTERVAL_MS);
38962
+ const outcome = await post(batch[i]);
38963
+ if (outcome === "sent")
38964
+ sent++;
38965
+ else if (outcome === "retry")
38966
+ keep.push(batch[i]);
38967
+ }
38968
+ await persistRemaining(path, [...older, ...keep]);
38969
+ if (sent > 0)
38970
+ log(`[behavior:telemetry] delivered ${sent} session report(s)`);
38971
+ return { sent, kept: keep.length };
38972
+ } catch (err) {
38973
+ log(`[behavior:telemetry] drain failed: ${err}`);
38974
+ return { sent: 0, kept: 0 };
38975
+ }
38976
+ }
38977
+ function resetDrainState() {
38978
+ drained = false;
38979
+ }
38980
+ var ENDPOINT = "https://claudish.com/v1/behavior", REQUEST_TIMEOUT_MS = 15000, SEND_INTERVAL_MS = 1100, MAX_DRAIN_PER_RUN = 50, MAX_OUTBOX_ENTRIES = 200, drained = false;
38981
+ var init_upload = __esm(() => {
38982
+ init_logger();
38983
+ init_aggregate();
38984
+ });
38985
+
38612
38986
  // src/behavior/engine.ts
38613
38987
  class BehaviorSession {
38614
38988
  active;
@@ -38713,6 +39087,14 @@ class BehaviorSession {
38713
39087
  interceptsTool(toolName) {
38714
39088
  return this.bufferedTools.has(toolName);
38715
39089
  }
39090
+ noteTurnComplete(inputTokens) {
39091
+ recordTelemetryTurn({
39092
+ sessionId: this.sessionId,
39093
+ model: this.modelId,
39094
+ provider: this.providerName,
39095
+ inputTokens
39096
+ });
39097
+ }
38716
39098
  observeText(text, kind = "text") {
38717
39099
  if (!this.watchesOutput || !text)
38718
39100
  return;
@@ -38841,6 +39223,17 @@ class BehaviorSession {
38841
39223
  return changed ? JSON.stringify(args) : null;
38842
39224
  }
38843
39225
  journal(surface, decision, detail) {
39226
+ const pathRelation = classifyPath(detail.observedPath, detail.expectedPath);
39227
+ recordTelemetryDecision({
39228
+ sessionId: this.sessionId,
39229
+ model: this.modelId,
39230
+ provider: this.providerName,
39231
+ surface,
39232
+ decision,
39233
+ ruleId: detail.ruleId,
39234
+ toolName: detail.toolName,
39235
+ pathRelation
39236
+ });
38844
39237
  recordDecision({
38845
39238
  ts: new Date().toISOString(),
38846
39239
  model: this.modelId,
@@ -38850,7 +39243,7 @@ class BehaviorSession {
38850
39243
  ruleId: detail.ruleId,
38851
39244
  toolName: detail.toolName,
38852
39245
  argKeys: detail.argKeys,
38853
- pathRelation: classifyPath(detail.observedPath, detail.expectedPath),
39246
+ pathRelation,
38854
39247
  local: {
38855
39248
  observedPath: detail.observedPath,
38856
39249
  expectedPath: detail.expectedPath,
@@ -38944,6 +39337,11 @@ class BehaviorEngine {
38944
39337
  constructor(config2, rules) {
38945
39338
  this.config = config2;
38946
39339
  this.rules = rules;
39340
+ const optedIn = config2.telemetry?.enabled === true;
39341
+ setTelemetryConsent(optedIn);
39342
+ if (optedIn) {
39343
+ Promise.resolve().then(() => (init_upload(), exports_upload)).then((m) => m.drainOutbox()).catch((err) => log(`[behavior:telemetry] drain unavailable: ${err}`));
39344
+ }
38947
39345
  }
38948
39346
  queueCorrection(key, text) {
38949
39347
  const list = this.corrections.get(key) ?? [];
@@ -38991,6 +39389,7 @@ var init_engine = __esm(() => {
38991
39389
  init_config();
38992
39390
  init_harness();
38993
39391
  init_journal();
39392
+ init_aggregate();
38994
39393
  MAX_OBSERVED_CHARS = 64 * 1024;
38995
39394
  });
38996
39395
 
@@ -39050,83 +39449,10 @@ Do not invent a different filename, and do not derive one from the task. Claude
39050
39449
  PLAN_MODE_RULES = [planFilePathRule];
39051
39450
  });
39052
39451
 
39053
- // src/behavior/hooks.ts
39054
- import { isAbsolute, resolve } from "path";
39055
- function isBehaviorRule(value) {
39056
- 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");
39057
- }
39058
- function collectRules(mod) {
39059
- const found = [];
39060
- const consider = (v) => {
39061
- if (Array.isArray(v))
39062
- v.forEach(consider);
39063
- else if (isBehaviorRule(v))
39064
- found.push(v);
39065
- };
39066
- consider(mod?.default);
39067
- consider(mod?.rules);
39068
- for (const [key, value] of Object.entries(mod ?? {})) {
39069
- if (key === "default" || key === "rules")
39070
- continue;
39071
- consider(value);
39072
- }
39073
- return [...new Set(found)];
39074
- }
39075
- function shortName(path) {
39076
- const base = path.split("/").pop() ?? path;
39077
- return base.replace(/\.[cm]?[jt]s$/, "");
39078
- }
39079
- async function loadHookRules(paths, cwd = process.cwd()) {
39080
- if (!paths?.length)
39081
- return [];
39082
- const loaded = [];
39083
- const seen = new Set;
39084
- for (const raw2 of paths) {
39085
- const abs = isAbsolute(raw2) ? raw2 : resolve(cwd, raw2);
39086
- const rules = await importHook(abs, raw2);
39087
- for (const rule of rules)
39088
- namespaceInto(rule, abs, seen, loaded);
39089
- }
39090
- if (loaded.length > 0) {
39091
- logStderr(`[behavior] Loaded ${loaded.length} hook rule(s): ${loaded.map((r) => r.id).join(", ")}`);
39092
- }
39093
- return loaded;
39094
- }
39095
- async function importHook(abs, raw2) {
39096
- let mod;
39097
- try {
39098
- mod = await import(abs);
39099
- } catch (err) {
39100
- logStderr(`[behavior] Skipping hook ${raw2}: ${err instanceof Error ? err.message : err}`);
39101
- return [];
39102
- }
39103
- const rules = collectRules(mod);
39104
- if (rules.length === 0) {
39105
- logStderr(`[behavior] Hook ${raw2} exported no valid BehaviorRule \u2014 skipped`);
39106
- }
39107
- return rules;
39108
- }
39109
- function namespaceInto(rule, abs, seen, out) {
39110
- const namespaced = `hook:${shortName(abs)}/${rule.id}`;
39111
- if (seen.has(namespaced)) {
39112
- logStderr(`[behavior] Duplicate hook rule ${namespaced} \u2014 keeping the first`);
39113
- return;
39114
- }
39115
- seen.add(namespaced);
39116
- out.push({
39117
- ...rule,
39118
- id: namespaced,
39119
- defaultSeverity: rule.defaultSeverity ?? "warn"
39120
- });
39121
- }
39122
- var init_hooks = __esm(() => {
39123
- init_logger();
39124
- });
39125
-
39126
39452
  // src/behavior/observer/corpus.ts
39127
- import { appendFileSync as appendFileSync3, readFileSync as readFileSync12, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
39128
- import { homedir as homedir20 } from "os";
39129
- import { join as join20 } from "path";
39453
+ import { appendFileSync as appendFileSync4, readFileSync as readFileSync12, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
39454
+ import { homedir as homedir21 } from "os";
39455
+ import { join as join21 } from "path";
39130
39456
  function directoryOf2(filePath) {
39131
39457
  const slash = filePath.lastIndexOf("/");
39132
39458
  return slash > 0 ? filePath.slice(0, slash) : undefined;
@@ -39205,28 +39531,28 @@ function listTranscripts(root) {
39205
39531
  return files;
39206
39532
  }
39207
39533
  for (const project of projects) {
39208
- const dir = join20(root, project);
39534
+ const dir = join21(root, project);
39209
39535
  try {
39210
39536
  if (!statSync2(dir).isDirectory())
39211
39537
  continue;
39212
39538
  for (const f of readdirSync2(dir)) {
39213
39539
  if (f.endsWith(".jsonl"))
39214
- files.push(join20(dir, f));
39540
+ files.push(join21(dir, f));
39215
39541
  }
39216
39542
  } catch {}
39217
39543
  }
39218
39544
  return files;
39219
39545
  }
39220
39546
  function buildCorpus(options = {}) {
39221
- const root = options.projectsRoot ?? join20(homedir20(), ".claude", "projects");
39547
+ const root = options.projectsRoot ?? join21(homedir21(), ".claude", "projects");
39222
39548
  const files = listTranscripts(root);
39223
39549
  const records = [];
39224
39550
  for (const f of files)
39225
39551
  records.push(...replayTranscript(f));
39226
39552
  if (options.write && records.length > 0) {
39227
- const outputPath = options.outputPath ?? join20(homedir20(), ".claudish", "behavior-divergences.jsonl");
39553
+ const outputPath = options.outputPath ?? join21(homedir21(), ".claudish", "behavior-divergences.jsonl");
39228
39554
  try {
39229
- appendFileSync3(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
39555
+ appendFileSync4(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
39230
39556
  `)}
39231
39557
  `);
39232
39558
  return { scanned: files.length, records, outputPath };
@@ -39266,6 +39592,8 @@ var init_behavior = __esm(() => {
39266
39592
  init_digest();
39267
39593
  init_client();
39268
39594
  init_corpus();
39595
+ init_aggregate();
39596
+ init_upload();
39269
39597
  BUILTIN_RULES = [...PLAN_MODE_RULES];
39270
39598
  hookRules = [];
39271
39599
  });
@@ -39836,17 +40164,17 @@ var init_vision_proxy = __esm(() => {
39836
40164
  // src/stats-buffer.ts
39837
40165
  import {
39838
40166
  existsSync as existsSync15,
39839
- mkdirSync as mkdirSync9,
40167
+ mkdirSync as mkdirSync10,
39840
40168
  readFileSync as readFileSync13,
39841
40169
  renameSync,
39842
40170
  unlinkSync as unlinkSync5,
39843
40171
  writeFileSync as writeFileSync9
39844
40172
  } from "fs";
39845
- import { homedir as homedir21 } from "os";
39846
- import { join as join21 } from "path";
40173
+ import { homedir as homedir22 } from "os";
40174
+ import { join as join22 } from "path";
39847
40175
  function ensureDir() {
39848
40176
  if (!existsSync15(CLAUDISH_DIR)) {
39849
- mkdirSync9(CLAUDISH_DIR, { recursive: true });
40177
+ mkdirSync10(CLAUDISH_DIR, { recursive: true });
39850
40178
  }
39851
40179
  }
39852
40180
  function readFromDisk() {
@@ -39878,7 +40206,7 @@ function writeToDisk(events) {
39878
40206
  ensureDir();
39879
40207
  const trimmed = enforceSizeCap([...events]);
39880
40208
  const payload = { version: 1, events: trimmed };
39881
- const tmpFile = join21(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
40209
+ const tmpFile = join22(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
39882
40210
  writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
39883
40211
  renameSync(tmpFile, BUFFER_FILE);
39884
40212
  memoryCache = trimmed;
@@ -39951,8 +40279,8 @@ function syncFlushOnExit() {
39951
40279
  var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false;
39952
40280
  var init_stats_buffer = __esm(() => {
39953
40281
  BUFFER_MAX_BYTES = 64 * 1024;
39954
- CLAUDISH_DIR = join21(homedir21(), ".claudish");
39955
- BUFFER_FILE = join21(CLAUDISH_DIR, "stats-buffer.json");
40282
+ CLAUDISH_DIR = join22(homedir22(), ".claudish");
40283
+ BUFFER_FILE = join22(CLAUDISH_DIR, "stats-buffer.json");
39956
40284
  process.on("exit", syncFlushOnExit);
39957
40285
  process.on("SIGTERM", () => {
39958
40286
  try {
@@ -40089,7 +40417,7 @@ __export(exports_telemetry, {
40089
40417
  classifyError: () => classifyError,
40090
40418
  buildReport: () => buildReport
40091
40419
  });
40092
- import { randomBytes as randomBytes4 } from "crypto";
40420
+ import { randomBytes as randomBytes5 } from "crypto";
40093
40421
  function getVersion() {
40094
40422
  return VERSION;
40095
40423
  }
@@ -40357,7 +40685,7 @@ function initTelemetry(_config) {
40357
40685
  } catch {
40358
40686
  consentEnabled = false;
40359
40687
  }
40360
- sessionId = randomBytes4(8).toString("hex");
40688
+ sessionId = randomBytes5(8).toString("hex");
40361
40689
  claudishVersion = getVersion();
40362
40690
  installMethod = detectInstallMethod();
40363
40691
  }
@@ -40667,11 +40995,11 @@ function showMonthlyBanner() {
40667
40995
  if (isStatsDisabledByEnv())
40668
40996
  return;
40669
40997
  const profileConfig = loadConfig();
40670
- const consent = profileConfig.stats;
40998
+ const consent2 = profileConfig.stats;
40671
40999
  const now = Date.now();
40672
- const lastPrompt = consent?.lastMonthlyPrompt ? new Date(consent.lastMonthlyPrompt).getTime() : 0;
41000
+ const lastPrompt = consent2?.lastMonthlyPrompt ? new Date(consent2.lastMonthlyPrompt).getTime() : 0;
40673
41001
  const timeSincePrompt = now - lastPrompt;
40674
- const isFirstRun = !consent?.lastMonthlyPrompt;
41002
+ const isFirstRun = !consent2?.lastMonthlyPrompt;
40675
41003
  const isMonthlyInterval = timeSincePrompt >= MONTHLY_INTERVAL_MS;
40676
41004
  if (!isFirstRun && !isMonthlyInterval)
40677
41005
  return;
@@ -40680,7 +41008,7 @@ function showMonthlyBanner() {
40680
41008
  ` + ` No prompts, API keys, or personal data \u2014 just model, latency, and token counts.
40681
41009
  ` + ` Enable: claudish stats on | Docs: claudish stats status
40682
41010
  `);
40683
- } else if (consent?.enabled) {
41011
+ } else if (consent2?.enabled) {
40684
41012
  process.stderr.write(`[claudish] Usage stats are ON \u2014 thank you for helping improve claudish!
40685
41013
  `);
40686
41014
  } else {
@@ -42335,9 +42663,9 @@ var init_openai_responses_sse = __esm(() => {
42335
42663
  });
42336
42664
 
42337
42665
  // src/handlers/shared/token-tracker.ts
42338
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
42339
- import { homedir as homedir22 } from "os";
42340
- import { dirname as dirname7, join as join22 } from "path";
42666
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "fs";
42667
+ import { homedir as homedir23 } from "os";
42668
+ import { dirname as dirname8, join as join23 } from "path";
42341
42669
  function stripProviderPrefix(name) {
42342
42670
  const at = name.indexOf("@");
42343
42671
  return at === -1 ? name : name.slice(at + 1);
@@ -42489,8 +42817,8 @@ class TokenTracker {
42489
42817
  data.quota_remaining = this.quotaRemaining;
42490
42818
  }
42491
42819
  const override = process.env.CLAUDISH_TOKEN_FILE;
42492
- const outPath = override || join22(homedir22(), ".claudish", `tokens-${this.port}.json`);
42493
- mkdirSync10(dirname7(outPath), { recursive: true });
42820
+ const outPath = override || join23(homedir23(), ".claudish", `tokens-${this.port}.json`);
42821
+ mkdirSync11(dirname8(outPath), { recursive: true });
42494
42822
  writeFileSync10(outPath, JSON.stringify(data), "utf-8");
42495
42823
  } catch (e) {
42496
42824
  log(`[TokenTracker] Error writing token file: ${e}`);
@@ -43006,6 +43334,9 @@ class ComposedHandler {
43006
43334
  invocation_mode: this.options.invocationMode ?? "auto-route"
43007
43335
  });
43008
43336
  } catch {}
43337
+ try {
43338
+ behaviorSession?.noteTurnComplete(this.tokenTracker.getInputTokens());
43339
+ } catch {}
43009
43340
  };
43010
43341
  return this.handleStream(c, response, adapter, claudeRequest, toolNameMap, onStreamComplete, (code, message) => {
43011
43342
  streamApiError = { code, message };
@@ -43210,8 +43541,9 @@ function getRecoveryHint(status, errorText, providerName) {
43210
43541
  var STREAM_RETRY_DELAYS_MS;
43211
43542
  var init_composed_handler = __esm(() => {
43212
43543
  init_dialect_manager();
43213
- init_logger();
43544
+ init_model_catalog();
43214
43545
  init_behavior();
43546
+ init_logger();
43215
43547
  init_middleware();
43216
43548
  init_openai();
43217
43549
  init_vision_proxy();
@@ -43226,7 +43558,6 @@ var init_composed_handler = __esm(() => {
43226
43558
  init_anthropic_sse();
43227
43559
  init_gemini_sse();
43228
43560
  init_ollama_jsonl();
43229
- init_model_catalog();
43230
43561
  init_openai_responses_sse();
43231
43562
  init_openai_sse();
43232
43563
  init_token_tracker();
@@ -43358,7 +43689,7 @@ var init_fallback_handler = __esm(() => {
43358
43689
  });
43359
43690
 
43360
43691
  // src/handlers/native-handler-advisor.ts
43361
- import { appendFileSync as appendFileSync4 } from "fs";
43692
+ import { appendFileSync as appendFileSync5 } from "fs";
43362
43693
  function loadAdvisorSwapConfig(cliModels, cliCollector) {
43363
43694
  return {
43364
43695
  enabled: process.env.CLAUDISH_SWAP_ADVISOR === "1" || (cliModels?.length ?? 0) > 0,
@@ -43413,7 +43744,7 @@ function logAdvisorEvent(cfg, event) {
43413
43744
  const line = `${JSON.stringify({ ts: new Date().toISOString(), ...event })}
43414
43745
  `;
43415
43746
  try {
43416
- appendFileSync4(cfg.logPath, line);
43747
+ appendFileSync5(cfg.logPath, line);
43417
43748
  } catch {}
43418
43749
  }
43419
43750
  function recordAdvisorEventsFromChunk(cfg, chunkText) {
@@ -44249,7 +44580,7 @@ function readContextWindow(row) {
44249
44580
  }
44250
44581
  function readCreatedDate(row) {
44251
44582
  const raw2 = row.created;
44252
- const seconds = typeof raw2 === "number" ? raw2 : typeof raw2 === "string" ? Number(raw2) : NaN;
44583
+ const seconds = typeof raw2 === "number" ? raw2 : typeof raw2 === "string" ? Number(raw2) : Number.NaN;
44253
44584
  if (!Number.isFinite(seconds))
44254
44585
  return;
44255
44586
  if (seconds < MIN_CREATED_SECONDS || seconds > MAX_CREATED_SECONDS)
@@ -45170,10 +45501,10 @@ var init_ollama_api_format = __esm(() => {
45170
45501
 
45171
45502
  // src/providers/api-key-provenance.ts
45172
45503
  import { existsSync as existsSync16, readFileSync as readFileSync14 } from "fs";
45173
- import { homedir as homedir23 } from "os";
45174
- import { join as join23, resolve as resolve2 } from "path";
45504
+ import { homedir as homedir24 } from "os";
45505
+ import { join as join24, resolve as resolve2 } from "path";
45175
45506
  function activeConfigPath() {
45176
- return activeGlobalConfigFile(join23(homedir23(), ".claudish", "config.json"));
45507
+ return activeGlobalConfigFile(join24(homedir24(), ".claudish", "config.json"));
45177
45508
  }
45178
45509
  function configLayerLabel() {
45179
45510
  return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
@@ -45540,7 +45871,7 @@ class GeminiCodeAssistProviderTransport {
45540
45871
  const list = served.join(", ");
45541
45872
  const tier = this._displayName || "Gemini Code Assist";
45542
45873
  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}. `;
45543
- 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}.`;
45874
+ 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}.`;
45544
45875
  const body = JSON.stringify({
45545
45876
  error: { code: 404, status: "NOT_FOUND", message }
45546
45877
  });
@@ -46051,10 +46382,10 @@ class LocalModelQueue {
46051
46382
  return LocalModelQueue.instance;
46052
46383
  }
46053
46384
  static isEnabled() {
46054
- const enabled = process.env.CLAUDISH_LOCAL_QUEUE_ENABLED;
46055
- if (enabled === undefined || enabled === "")
46385
+ const enabled2 = process.env.CLAUDISH_LOCAL_QUEUE_ENABLED;
46386
+ if (enabled2 === undefined || enabled2 === "")
46056
46387
  return true;
46057
- return enabled !== "false" && enabled !== "0";
46388
+ return enabled2 !== "false" && enabled2 !== "0";
46058
46389
  }
46059
46390
  async enqueue(fetchFn, providerId, concurrencyOverride) {
46060
46391
  if (concurrencyOverride !== undefined) {
@@ -46741,8 +47072,8 @@ var init_poe = __esm(() => {
46741
47072
 
46742
47073
  // src/services/pricing-cache.ts
46743
47074
  import { existsSync as existsSync17, readFileSync as readFileSync15, statSync as statSync4 } from "fs";
46744
- import { homedir as homedir24 } from "os";
46745
- import { join as join24 } from "path";
47075
+ import { homedir as homedir25 } from "os";
47076
+ import { join as join25 } from "path";
46746
47077
  function prefixMatch(modelName) {
46747
47078
  for (const [key, pricing] of pricingMap) {
46748
47079
  if (modelName.startsWith(key))
@@ -46801,8 +47132,8 @@ var init_pricing_cache = __esm(() => {
46801
47132
  init_logger();
46802
47133
  init_catalog_query();
46803
47134
  pricingMap = new Map;
46804
- CACHE_DIR = join24(homedir24(), ".claudish");
46805
- CACHE_FILE = join24(CACHE_DIR, "pricing-cache.json");
47135
+ CACHE_DIR = join25(homedir25(), ".claudish");
47136
+ CACHE_FILE = join25(CACHE_DIR, "pricing-cache.json");
46806
47137
  CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
46807
47138
  });
46808
47139
 
@@ -47228,6 +47559,8 @@ var init_proxy_server = __esm(() => {
47228
47559
  init_local_adapter();
47229
47560
  init_openrouter_api_format();
47230
47561
  init_authority();
47562
+ init_hooks();
47563
+ init_behavior();
47231
47564
  init_composed_handler();
47232
47565
  init_fallback_handler();
47233
47566
  init_native_handler();
@@ -47236,8 +47569,6 @@ var init_proxy_server = __esm(() => {
47236
47569
  init_model_loader();
47237
47570
  init_profile_config();
47238
47571
  init_api_key_map();
47239
- init_behavior();
47240
- init_hooks();
47241
47572
  init_custom_endpoints_loader();
47242
47573
  init_model_catalog_resolver();
47243
47574
  init_model_parser();
@@ -47298,12 +47629,12 @@ var init_redact = __esm(() => {
47298
47629
 
47299
47630
  // src/team-stats.ts
47300
47631
  import { existsSync as existsSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync11 } from "fs";
47301
- import { join as join25 } from "path";
47632
+ import { join as join26 } from "path";
47302
47633
  function statsDir(sessionPath) {
47303
- return join25(sessionPath, "stats");
47634
+ return join26(sessionPath, "stats");
47304
47635
  }
47305
47636
  function tokenFileFor(sessionPath, anonId) {
47306
- return join25(statsDir(sessionPath), `${anonId}.json`);
47637
+ return join26(statsDir(sessionPath), `${anonId}.json`);
47307
47638
  }
47308
47639
  function readTokenStats(sessionPath, anonId) {
47309
47640
  const path = tokenFileFor(sessionPath, anonId);
@@ -47458,7 +47789,7 @@ ${segs.join(" \xB7 ")}`;
47458
47789
  }
47459
47790
  function writeStatusFile(sessionPath, manifest, status, opts) {
47460
47791
  try {
47461
- writeFileSync11(join25(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
47792
+ writeFileSync11(join26(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
47462
47793
  `, "utf-8");
47463
47794
  } catch {}
47464
47795
  }
@@ -47485,12 +47816,12 @@ import { spawn as spawn2 } from "child_process";
47485
47816
  import {
47486
47817
  createWriteStream as createWriteStream2,
47487
47818
  existsSync as existsSync19,
47488
- mkdirSync as mkdirSync11,
47819
+ mkdirSync as mkdirSync12,
47489
47820
  readFileSync as readFileSync17,
47490
47821
  readdirSync as readdirSync3,
47491
47822
  writeFileSync as writeFileSync12
47492
47823
  } from "fs";
47493
- import { join as join26, resolve as resolve3 } from "path";
47824
+ import { join as join27, resolve as resolve3 } from "path";
47494
47825
  function classifyRunOutput(opts) {
47495
47826
  const { outputSize, stdoutTail, stderr, minOutputBytes } = opts;
47496
47827
  const apiError = API_ERROR_RE.exec(stdoutTail);
@@ -47504,7 +47835,7 @@ function classifyRunOutput(opts) {
47504
47835
  if (bgCeiling) {
47505
47836
  return {
47506
47837
  reason: "background_task_ceiling",
47507
- 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.`
47838
+ 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."
47508
47839
  };
47509
47840
  }
47510
47841
  const tailIsWholeOutput = outputSize <= STDOUT_TAIL_LIMIT;
@@ -47551,18 +47882,18 @@ function setupSession(sessionPath, models, input) {
47551
47882
  if (models.length === 0) {
47552
47883
  throw new Error("At least one model is required");
47553
47884
  }
47554
- if (existsSync19(join26(sessionPath, "manifest.json"))) {
47885
+ if (existsSync19(join27(sessionPath, "manifest.json"))) {
47555
47886
  throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
47556
47887
  }
47557
47888
  const sentinels = models.filter(isSentinelModel);
47558
47889
  if (sentinels.length > 0) {
47559
47890
  throw new Error(`Invalid model(s) for team run: ${sentinels.join(", ")}. These are Claude Code agent selectors, not external model IDs. Use real external models (e.g., "gemini-2.0-flash", "gpt-4o", "or@deepseek/deepseek-r1"). For Claude models, use a Task agent instead of the team tool.`);
47560
47891
  }
47561
- mkdirSync11(join26(sessionPath, "work"), { recursive: true });
47562
- mkdirSync11(join26(sessionPath, "errors"), { recursive: true });
47892
+ mkdirSync12(join27(sessionPath, "work"), { recursive: true });
47893
+ mkdirSync12(join27(sessionPath, "errors"), { recursive: true });
47563
47894
  if (input !== undefined) {
47564
- writeFileSync12(join26(sessionPath, "input.md"), input, "utf-8");
47565
- } else if (!existsSync19(join26(sessionPath, "input.md"))) {
47895
+ writeFileSync12(join27(sessionPath, "input.md"), input, "utf-8");
47896
+ } else if (!existsSync19(join27(sessionPath, "input.md"))) {
47566
47897
  throw new Error(`No input.md found at ${sessionPath} and no input provided`);
47567
47898
  }
47568
47899
  const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
@@ -47579,9 +47910,9 @@ function setupSession(sessionPath, models, input) {
47579
47910
  model: models[i],
47580
47911
  assignedAt: now
47581
47912
  };
47582
- mkdirSync11(join26(sessionPath, "work", anonId), { recursive: true });
47913
+ mkdirSync12(join27(sessionPath, "work", anonId), { recursive: true });
47583
47914
  }
47584
- writeFileSync12(join26(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
47915
+ writeFileSync12(join27(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
47585
47916
  const status = {
47586
47917
  startedAt: now,
47587
47918
  models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
@@ -47595,14 +47926,14 @@ function setupSession(sessionPath, models, input) {
47595
47926
  }
47596
47927
  ]))
47597
47928
  };
47598
- writeFileSync12(join26(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
47929
+ writeFileSync12(join27(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
47599
47930
  return manifest;
47600
47931
  }
47601
47932
  async function runModels(sessionPath, opts = {}) {
47602
47933
  const timeoutMs = (opts.timeout ?? 300) * 1000;
47603
- const manifest = JSON.parse(readFileSync17(join26(sessionPath, "manifest.json"), "utf-8"));
47604
- const statusPath = join26(sessionPath, "status.json");
47605
- const inputPath = join26(sessionPath, "input.md");
47934
+ const manifest = JSON.parse(readFileSync17(join27(sessionPath, "manifest.json"), "utf-8"));
47935
+ const statusPath = join27(sessionPath, "status.json");
47936
+ const inputPath = join27(sessionPath, "input.md");
47606
47937
  const inputContent = readFileSync17(inputPath, "utf-8");
47607
47938
  await prehydrateCredentialsForSpawn(Object.values(manifest.models).map((m) => m.model));
47608
47939
  const statusCache = JSON.parse(readFileSync17(statusPath, "utf-8"));
@@ -47611,7 +47942,7 @@ async function runModels(sessionPath, opts = {}) {
47611
47942
  writeFileSync12(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
47612
47943
  }
47613
47944
  const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
47614
- mkdirSync11(statsDir(sessionPath), { recursive: true });
47945
+ mkdirSync12(statsDir(sessionPath), { recursive: true });
47615
47946
  const processes = new Map;
47616
47947
  const runtimes = new Map;
47617
47948
  const sigintHandler = () => {
@@ -47624,8 +47955,8 @@ async function runModels(sessionPath, opts = {}) {
47624
47955
  process.on("SIGINT", sigintHandler);
47625
47956
  const completionPromises = [];
47626
47957
  for (const [anonId, entry] of Object.entries(manifest.models)) {
47627
- const outputPath = join26(sessionPath, `response-${anonId}.md`);
47628
- const errorLogPath = join26(sessionPath, "errors", `${anonId}.log`);
47958
+ const outputPath = join27(sessionPath, `response-${anonId}.md`);
47959
+ const errorLogPath = join27(sessionPath, "errors", `${anonId}.log`);
47629
47960
  const args = ["--model", entry.model, "-y", "--stdin", "--quiet", ...opts.claudeFlags ?? []];
47630
47961
  updateModelStatus(anonId, {
47631
47962
  state: "RUNNING",
@@ -47774,7 +48105,7 @@ async function runModels(sessionPath, opts = {}) {
47774
48105
  const stderr = rt?.getStderr() ?? "";
47775
48106
  const stdoutTail = rt?.getStdoutTail() ?? "";
47776
48107
  const bytes = rt?.getByteCount() ?? 0;
47777
- 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".`;
48108
+ 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".`;
47778
48109
  if (rt)
47779
48110
  persistErrorLog(rt.errorLogPath, `TIMEOUT: ${detail}`, stderr, stdoutTail);
47780
48111
  updateModelStatus(id, {
@@ -47814,23 +48145,23 @@ async function judgeResponses(sessionPath, opts = {}) {
47814
48145
  const responses = {};
47815
48146
  for (const file2 of responseFiles) {
47816
48147
  const id = file2.replace(/^response-/, "").replace(/\.md$/, "");
47817
- responses[id] = readFileSync17(join26(sessionPath, file2), "utf-8");
48148
+ responses[id] = readFileSync17(join27(sessionPath, file2), "utf-8");
47818
48149
  }
47819
- const input = readFileSync17(join26(sessionPath, "input.md"), "utf-8");
48150
+ const input = readFileSync17(join27(sessionPath, "input.md"), "utf-8");
47820
48151
  const judgePrompt = buildJudgePrompt(input, responses);
47821
- writeFileSync12(join26(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
48152
+ writeFileSync12(join27(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
47822
48153
  const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
47823
- const judgePath = join26(sessionPath, "judging");
47824
- mkdirSync11(judgePath, { recursive: true });
48154
+ const judgePath = join27(sessionPath, "judging");
48155
+ mkdirSync12(judgePath, { recursive: true });
47825
48156
  setupSession(judgePath, judgeModels, judgePrompt);
47826
48157
  await runModels(judgePath, { claudeFlags: opts.claudeFlags });
47827
48158
  const votes = parseJudgeVotes(judgePath, Object.keys(responses));
47828
48159
  const verdict = aggregateVerdict(votes, Object.keys(responses));
47829
- writeFileSync12(join26(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
48160
+ writeFileSync12(join27(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
47830
48161
  return verdict;
47831
48162
  }
47832
48163
  function getStatus(sessionPath) {
47833
- return JSON.parse(readFileSync17(join26(sessionPath, "status.json"), "utf-8"));
48164
+ return JSON.parse(readFileSync17(join27(sessionPath, "status.json"), "utf-8"));
47834
48165
  }
47835
48166
  function fisherYatesShuffle(arr) {
47836
48167
  for (let i = arr.length - 1;i > 0; i--) {
@@ -47840,7 +48171,7 @@ function fisherYatesShuffle(arr) {
47840
48171
  return arr;
47841
48172
  }
47842
48173
  function getDefaultJudgeModels(sessionPath) {
47843
- const manifest = JSON.parse(readFileSync17(join26(sessionPath, "manifest.json"), "utf-8"));
48174
+ const manifest = JSON.parse(readFileSync17(join27(sessionPath, "manifest.json"), "utf-8"));
47844
48175
  return Object.values(manifest.models).map((e) => e.model);
47845
48176
  }
47846
48177
  function buildJudgePrompt(input, responses) {
@@ -47903,7 +48234,7 @@ function parseJudgeVotes(judgePath, responseIds) {
47903
48234
  const judgeId = file2.replace(/^response-/, "").replace(/\.md$/, "");
47904
48235
  let content;
47905
48236
  try {
47906
- content = readFileSync17(join26(judgePath, file2), "utf-8");
48237
+ content = readFileSync17(join27(judgePath, file2), "utf-8");
47907
48238
  } catch {
47908
48239
  continue;
47909
48240
  }
@@ -47955,7 +48286,7 @@ function aggregateVerdict(votes, responseIds) {
47955
48286
  function formatVerdict(verdict, sessionPath) {
47956
48287
  let manifest = null;
47957
48288
  try {
47958
- manifest = JSON.parse(readFileSync17(join26(sessionPath, "manifest.json"), "utf-8"));
48289
+ manifest = JSON.parse(readFileSync17(join27(sessionPath, "manifest.json"), "utf-8"));
47959
48290
  } catch {}
47960
48291
  let output = `# Team Verdict
47961
48292
 
@@ -48010,9 +48341,9 @@ __export(exports_mcp_server, {
48010
48341
  parseAnthropicSse: () => parseAnthropicSse,
48011
48342
  formatTeamResult: () => formatTeamResult
48012
48343
  });
48013
- import { existsSync as existsSync20, mkdirSync as mkdirSync12, readFileSync as readFileSync18, readdirSync as readdirSync4, writeFileSync as writeFileSync13 } from "fs";
48014
- import { homedir as homedir25 } from "os";
48015
- import { dirname as dirname8, join as join27 } from "path";
48344
+ import { existsSync as existsSync20, mkdirSync as mkdirSync13, readFileSync as readFileSync18, readdirSync as readdirSync4, writeFileSync as writeFileSync13 } from "fs";
48345
+ import { homedir as homedir26 } from "os";
48346
+ import { dirname as dirname9, join as join28 } from "path";
48016
48347
  import { fileURLToPath } from "url";
48017
48348
  async function loadAllModels(forceRefresh = false) {
48018
48349
  if (!forceRefresh && existsSync20(ALL_MODELS_CACHE_PATH2)) {
@@ -48031,7 +48362,7 @@ async function loadAllModels(forceRefresh = false) {
48031
48362
  throw new Error(`API returned ${response.status}`);
48032
48363
  const data = await response.json();
48033
48364
  const models = data.data || [];
48034
- mkdirSync12(CLAUDISH_CACHE_DIR, { recursive: true });
48365
+ mkdirSync13(CLAUDISH_CACHE_DIR, { recursive: true });
48035
48366
  writeFileSync13(ALL_MODELS_CACHE_PATH2, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
48036
48367
  return models;
48037
48368
  } catch {
@@ -48174,7 +48505,7 @@ function formatTeamResult(status, sessionPath) {
48174
48505
  }
48175
48506
  }
48176
48507
  lines.push("actions:");
48177
- lines.push(` full stderr/stdout for one failure \u2192 Read the evidence path above`);
48508
+ lines.push(" full stderr/stdout for one failure \u2192 Read the evidence path above");
48178
48509
  lines.push(` machine-readable status \u2192 team(mode="status", path="${sessionPath}")`);
48179
48510
  lines.push(` report a provider bug \u2192 report_error(session_path="${sessionPath}")`);
48180
48511
  }
@@ -48626,16 +48957,16 @@ Use with: run_prompt(model="${results2[0].model.id}", prompt="your prompt")`;
48626
48957
  const sp = session_path;
48627
48958
  for (const file2 of ["status.json", "manifest.json", "input.md"]) {
48628
48959
  try {
48629
- sessionData[file2] = readFileSync18(join27(sp, file2), "utf-8");
48960
+ sessionData[file2] = readFileSync18(join28(sp, file2), "utf-8");
48630
48961
  } catch {}
48631
48962
  }
48632
48963
  try {
48633
- const errorDir = join27(sp, "errors");
48964
+ const errorDir = join28(sp, "errors");
48634
48965
  if (existsSync20(errorDir)) {
48635
48966
  for (const f of readdirSync4(errorDir)) {
48636
48967
  if (f.endsWith(".log")) {
48637
48968
  try {
48638
- sessionData[`errors/${f}`] = readFileSync18(join27(errorDir, f), "utf-8");
48969
+ sessionData[`errors/${f}`] = readFileSync18(join28(errorDir, f), "utf-8");
48639
48970
  } catch {}
48640
48971
  }
48641
48972
  }
@@ -48645,7 +48976,7 @@ Use with: run_prompt(model="${results2[0].model.id}", prompt="your prompt")`;
48645
48976
  for (const f of readdirSync4(sp)) {
48646
48977
  if (f.startsWith("response-") && f.endsWith(".md")) {
48647
48978
  try {
48648
- const content = readFileSync18(join27(sp, f), "utf-8");
48979
+ const content = readFileSync18(join28(sp, f), "utf-8");
48649
48980
  sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
48650
48981
  } catch {}
48651
48982
  }
@@ -48654,7 +48985,7 @@ Use with: run_prompt(model="${results2[0].model.id}", prompt="your prompt")`;
48654
48985
  }
48655
48986
  let version2 = "unknown";
48656
48987
  try {
48657
- const pkgPath = join27(__dirname2, "../package.json");
48988
+ const pkgPath = join28(__dirname2, "../package.json");
48658
48989
  if (existsSync20(pkgPath)) {
48659
48990
  version2 = JSON.parse(readFileSync18(pkgPath, "utf-8")).version;
48660
48991
  }
@@ -48883,9 +49214,9 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
48883
49214
  },
48884
49215
  group: "channel",
48885
49216
  handler: async (args) => {
48886
- const sessions = sessionManager.listSessions(args.include_completed);
49217
+ const sessions2 = sessionManager.listSessions(args.include_completed);
48887
49218
  return {
48888
- content: [{ type: "text", text: JSON.stringify({ sessions }) }]
49219
+ content: [{ type: "text", text: JSON.stringify({ sessions: sessions2 }) }]
48889
49220
  };
48890
49221
  }
48891
49222
  });
@@ -49054,9 +49385,9 @@ var init_mcp_server = __esm(() => {
49054
49385
  import_dotenv2 = __toESM(require_main(), 1);
49055
49386
  import_dotenv2.config({ quiet: true });
49056
49387
  __filename2 = fileURLToPath(import.meta.url);
49057
- __dirname2 = dirname8(__filename2);
49058
- CLAUDISH_CACHE_DIR = join27(homedir25(), ".claudish");
49059
- ALL_MODELS_CACHE_PATH2 = join27(CLAUDISH_CACHE_DIR, "all-models.json");
49388
+ __dirname2 = dirname9(__filename2);
49389
+ CLAUDISH_CACHE_DIR = join28(homedir26(), ".claudish");
49390
+ ALL_MODELS_CACHE_PATH2 = join28(CLAUDISH_CACHE_DIR, "all-models.json");
49060
49391
  NEXT_STEP = {
49061
49392
  nonzero_exit: "read the evidence log, then retry or drop the model",
49062
49393
  timeout: "raise `timeout`, or pick a faster model",
@@ -49182,6 +49513,7 @@ var exports_behavior_command = {};
49182
49513
  __export(exports_behavior_command, {
49183
49514
  behaviorCommand: () => behaviorCommand
49184
49515
  });
49516
+ import { existsSync as existsSync22, readFileSync as readFileSync20, writeFileSync as writeFileSync14 } from "fs";
49185
49517
  function severityColor(sev) {
49186
49518
  if (sev === "fix")
49187
49519
  return green(sev);
@@ -49275,6 +49607,67 @@ Behavior divergence corpus
49275
49607
  `));
49276
49608
  }
49277
49609
  }
49610
+ function setTelemetryEnabled(value) {
49611
+ const path = getConfigPath();
49612
+ let cfg = {};
49613
+ try {
49614
+ if (existsSync22(path)) {
49615
+ const parsed = JSON.parse(readFileSync20(path, "utf-8"));
49616
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
49617
+ cfg = parsed;
49618
+ }
49619
+ }
49620
+ } catch {}
49621
+ const behavior = cfg.behavior && typeof cfg.behavior === "object" && !Array.isArray(cfg.behavior) ? { ...cfg.behavior } : {};
49622
+ behavior.telemetry = { enabled: value };
49623
+ cfg.behavior = behavior;
49624
+ writeFileSync14(path, `${JSON.stringify(cfg, null, 2)}
49625
+ `, "utf-8");
49626
+ }
49627
+ function showTelemetry(action, json2) {
49628
+ if (action !== "status") {
49629
+ setTelemetryEnabled(action === "enable");
49630
+ }
49631
+ const config3 = parseBehaviorConfig(loadConfig().behavior);
49632
+ const on = config3.telemetry?.enabled === true;
49633
+ let pending = 0;
49634
+ try {
49635
+ const path = outboxPath();
49636
+ if (existsSync22(path)) {
49637
+ pending = readFileSync20(path, "utf8").split(`
49638
+ `).filter(Boolean).length;
49639
+ }
49640
+ } catch {}
49641
+ if (json2) {
49642
+ console.log(JSON.stringify({ enabled: on, pendingReports: pending }, null, 2));
49643
+ return;
49644
+ }
49645
+ console.log(bold2(`
49646
+ Behavior telemetry
49647
+ `));
49648
+ console.log(` status : ${on ? green("enabled") : dim2("disabled")}`);
49649
+ console.log(` pending : ${pending} session report(s) awaiting delivery
49650
+ `);
49651
+ if (!on) {
49652
+ console.log(" Opting in shares which models violate Claude Code conventions,");
49653
+ console.log(` so rules can be written for models we cannot test ourselves.
49654
+ `);
49655
+ console.log(dim2(" Sent : model, provider, rule id, tool name, decision counts,"));
49656
+ console.log(dim2(" a coarse context bucket, and categorical path relations"));
49657
+ console.log(dim2(" Never : file paths, argument values, prompts, code, model output,"));
49658
+ console.log(dim2(" credentials, or repo/branch/project names"));
49659
+ console.log(dim2(" Session : identified by a salted hash, unlinkable across sessions"));
49660
+ console.log(dim2(` Kept : 12 months, then non-identifying weekly aggregates only
49661
+ `));
49662
+ console.log(` Enable with ${bold2("claudish behavior telemetry --enable")}
49663
+ `);
49664
+ return;
49665
+ }
49666
+ console.log(dim2(` Local journalling is always on and unaffected by this setting.
49667
+ `));
49668
+ console.log(` Disable with ${bold2("claudish behavior telemetry --disable")}
49669
+ `);
49670
+ }
49278
49671
  async function behaviorCommand(argv) {
49279
49672
  const json2 = argv.includes("--json");
49280
49673
  const write = argv.includes("--write");
@@ -49286,12 +49679,16 @@ async function behaviorCommand(argv) {
49286
49679
  case "corpus":
49287
49680
  showCorpus(write, json2);
49288
49681
  return;
49682
+ case "telemetry":
49683
+ showTelemetry(argv.includes("--enable") ? "enable" : argv.includes("--disable") ? "disable" : "status", json2);
49684
+ return;
49289
49685
  default:
49290
49686
  console.error(`Unknown action "${action}".
49291
49687
 
49292
49688
  Usage:
49293
- claudish behavior rules [--json]
49294
- claudish behavior corpus [--write] [--json]
49689
+ claudish behavior rules [--json]
49690
+ claudish behavior corpus [--write] [--json]
49691
+ claudish behavior telemetry [--enable | --disable] [--json]
49295
49692
  `);
49296
49693
  process.exit(1);
49297
49694
  }
@@ -49393,8 +49790,8 @@ function maskKey2(key) {
49393
49790
  }
49394
49791
  var SKIP, PROVIDERS;
49395
49792
  var init_providers = __esm(() => {
49396
- init_source();
49397
49793
  init_antigravity_token();
49794
+ init_source();
49398
49795
  init_oauth_registry();
49399
49796
  init_provider_definitions();
49400
49797
  SKIP = new Set(["qwen", "native-anthropic"]);
@@ -60706,7 +61103,7 @@ var init_RemoveFileError = __esm(() => {
60706
61103
 
60707
61104
  // ../../node_modules/.bun/@inquirer+external-editor@2.0.1+04f2146be16c61ef/node_modules/@inquirer/external-editor/dist/index.js
60708
61105
  import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
60709
- import { readFileSync as readFileSync20, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
61106
+ import { readFileSync as readFileSync21, unlinkSync as unlinkSync6, writeFileSync as writeFileSync15 } from "fs";
60710
61107
  import path from "path";
60711
61108
  import os from "os";
60712
61109
  import { randomUUID as randomUUID6 } from "crypto";
@@ -60815,14 +61212,14 @@ class ExternalEditor {
60815
61212
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
60816
61213
  opt.mode = this.fileOptions.mode;
60817
61214
  }
60818
- writeFileSync14(this.tempFile, this.text, opt);
61215
+ writeFileSync15(this.tempFile, this.text, opt);
60819
61216
  } catch (createFileError) {
60820
61217
  throw new CreateFileError(createFileError);
60821
61218
  }
60822
61219
  }
60823
61220
  readTemporaryFile() {
60824
61221
  try {
60825
- const tempFileBuffer = readFileSync20(this.tempFile);
61222
+ const tempFileBuffer = readFileSync21(this.tempFile);
60826
61223
  if (tempFileBuffer.length === 0) {
60827
61224
  this.text = "";
60828
61225
  } else {
@@ -61803,9 +62200,9 @@ var init_dist16 = __esm(() => {
61803
62200
 
61804
62201
  // src/auth/antigravity-oauth.ts
61805
62202
  import { spawnSync as spawnSync3 } from "child_process";
61806
- import { existsSync as existsSync22, unlinkSync as unlinkSync7 } from "fs";
61807
- import { homedir as homedir26 } from "os";
61808
- import { join as join28 } from "path";
62203
+ import { existsSync as existsSync23, unlinkSync as unlinkSync7 } from "fs";
62204
+ import { homedir as homedir27 } from "os";
62205
+ import { join as join29 } from "path";
61809
62206
  async function defaultSuggestModel() {
61810
62207
  try {
61811
62208
  const tok = readSharedAntigravityToken();
@@ -61926,8 +62323,8 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
61926
62323
  async logout(deps) {
61927
62324
  deleteSharedAntigravityToken(deps);
61928
62325
  try {
61929
- const tokenFile = join28(homedir26(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
61930
- if (existsSync22(tokenFile))
62326
+ const tokenFile = join29(homedir27(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
62327
+ if (existsSync23(tokenFile))
61931
62328
  unlinkSync7(tokenFile);
61932
62329
  } catch {}
61933
62330
  log("[AntigravityOAuth] Antigravity session cleared (keychain + agy token file)");
@@ -62184,15 +62581,15 @@ async function geminiQuotaHandler() {
62184
62581
  }
62185
62582
  }
62186
62583
  async function codexQuotaHandler() {
62187
- const { readFileSync: readFileSync21, existsSync: existsSync23 } = await import("fs");
62188
- const { join: join29 } = await import("path");
62189
- const { homedir: homedir27 } = await import("os");
62190
- const credPath = join29(homedir27(), ".claudish", "codex-oauth.json");
62191
- if (!existsSync23(credPath)) {
62584
+ const { readFileSync: readFileSync22, existsSync: existsSync24 } = await import("fs");
62585
+ const { join: join30 } = await import("path");
62586
+ const { homedir: homedir28 } = await import("os");
62587
+ const credPath = join30(homedir28(), ".claudish", "codex-oauth.json");
62588
+ if (!existsSync24(credPath)) {
62192
62589
  console.error(`${RED}No Codex credentials found.${R} Run: ${B}claudish login codex${R}`);
62193
62590
  process.exit(1);
62194
62591
  }
62195
- const creds = JSON.parse(readFileSync21(credPath, "utf-8"));
62592
+ const creds = JSON.parse(readFileSync22(credPath, "utf-8"));
62196
62593
  let email3 = "";
62197
62594
  try {
62198
62595
  const parts = creds.access_token.split(".");
@@ -62244,9 +62641,9 @@ async function codexQuotaHandler() {
62244
62641
  }
62245
62642
  let modelSlugs = [];
62246
62643
  try {
62247
- const modelsPath = join29(homedir27(), ".codex", "models_cache.json");
62248
- if (existsSync23(modelsPath)) {
62249
- const cache2 = JSON.parse(readFileSync21(modelsPath, "utf-8"));
62644
+ const modelsPath = join30(homedir28(), ".codex", "models_cache.json");
62645
+ if (existsSync24(modelsPath)) {
62646
+ const cache2 = JSON.parse(readFileSync22(modelsPath, "utf-8"));
62250
62647
  modelSlugs = (cache2.models || []).map((m) => m.slug || m.id).filter(Boolean);
62251
62648
  }
62252
62649
  } catch {}
@@ -63998,7 +64395,7 @@ var init_theme2 = __esm(() => {
63998
64395
  bold3 = createTextAttributes({ bold: true });
63999
64396
  A = {
64000
64397
  bold: bold3,
64001
- boldIf: (enabled) => enabled ? bold3 : undefined
64398
+ boldIf: (enabled2) => enabled2 ? bold3 : undefined
64002
64399
  };
64003
64400
  LATENCY_BUCKETS = [
64004
64401
  { maxMs: 500, hex: "#1f8f3b" },
@@ -66134,22 +66531,22 @@ __export(exports_cli, {
66134
66531
  });
66135
66532
  import {
66136
66533
  copyFileSync as copyFileSync2,
66137
- existsSync as existsSync23,
66138
- mkdirSync as mkdirSync13,
66139
- readFileSync as readFileSync21,
66534
+ existsSync as existsSync24,
66535
+ mkdirSync as mkdirSync14,
66536
+ readFileSync as readFileSync22,
66140
66537
  readdirSync as readdirSync5,
66141
66538
  unlinkSync as unlinkSync8,
66142
- writeFileSync as writeFileSync15
66539
+ writeFileSync as writeFileSync16
66143
66540
  } from "fs";
66144
- import { homedir as homedir27 } from "os";
66145
- import { dirname as dirname9, join as join29 } from "path";
66541
+ import { homedir as homedir28 } from "os";
66542
+ import { dirname as dirname10, join as join30 } from "path";
66146
66543
  import { fileURLToPath as fileURLToPath2 } from "url";
66147
66544
  function getVersion3() {
66148
66545
  return VERSION;
66149
66546
  }
66150
66547
  function clearAllModelCaches() {
66151
- const cacheDir = join29(homedir27(), ".claudish");
66152
- if (!existsSync23(cacheDir))
66548
+ const cacheDir = join30(homedir28(), ".claudish");
66549
+ if (!existsSync24(cacheDir))
66153
66550
  return;
66154
66551
  const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
66155
66552
  let cleared = 0;
@@ -66157,7 +66554,7 @@ function clearAllModelCaches() {
66157
66554
  const files = readdirSync5(cacheDir);
66158
66555
  for (const file2 of files) {
66159
66556
  if (cachePatterns.includes(file2)) {
66160
- unlinkSync8(join29(cacheDir, file2));
66557
+ unlinkSync8(join30(cacheDir, file2));
66161
66558
  cleared++;
66162
66559
  }
66163
66560
  }
@@ -66567,15 +66964,15 @@ Usage: claudish --models --provider <slug>`);
66567
66964
  });
66568
66965
  config3.resolvedDefaultProvider = resolved;
66569
66966
  if (resolved.legacyAutoPromoted && !config3.quiet) {
66570
- const markerFile = join29(homedir27(), ".claudish", ".legacy-litellm-hint-shown");
66571
- if (!existsSync23(markerFile)) {
66967
+ const markerFile = join30(homedir28(), ".claudish", ".legacy-litellm-hint-shown");
66968
+ if (!existsSync24(markerFile)) {
66572
66969
  const hint = buildLegacyHint(resolved);
66573
66970
  if (hint) {
66574
66971
  console.error(hint);
66575
66972
  }
66576
66973
  try {
66577
- mkdirSync13(dirname9(markerFile), { recursive: true });
66578
- writeFileSync15(markerFile, new Date().toISOString(), "utf-8");
66974
+ mkdirSync14(dirname10(markerFile), { recursive: true });
66975
+ writeFileSync16(markerFile, new Date().toISOString(), "utf-8");
66579
66976
  } catch {}
66580
66977
  }
66581
66978
  }
@@ -67642,8 +68039,8 @@ ${h("MORE INFO")}
67642
68039
  }
67643
68040
  function printAIAgentGuide() {
67644
68041
  try {
67645
- const guidePath = join29(__dirname3, "../AI_AGENT_GUIDE.md");
67646
- const guideContent = readFileSync21(guidePath, "utf-8");
68042
+ const guidePath = join30(__dirname3, "../AI_AGENT_GUIDE.md");
68043
+ const guideContent = readFileSync22(guidePath, "utf-8");
67647
68044
  console.log(guideContent);
67648
68045
  } catch (error46) {
67649
68046
  console.error("Error reading AI Agent Guide:");
@@ -67659,19 +68056,19 @@ async function initializeClaudishSkill() {
67659
68056
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
67660
68057
  `);
67661
68058
  const cwd = process.cwd();
67662
- const claudeDir = join29(cwd, ".claude");
67663
- const skillsDir = join29(claudeDir, "skills");
67664
- const claudishSkillDir = join29(skillsDir, "claudish-usage");
67665
- const skillFile = join29(claudishSkillDir, "SKILL.md");
67666
- if (existsSync23(skillFile)) {
68059
+ const claudeDir = join30(cwd, ".claude");
68060
+ const skillsDir = join30(claudeDir, "skills");
68061
+ const claudishSkillDir = join30(skillsDir, "claudish-usage");
68062
+ const skillFile = join30(claudishSkillDir, "SKILL.md");
68063
+ if (existsSync24(skillFile)) {
67667
68064
  console.log("\u2705 Claudish skill already installed at:");
67668
68065
  console.log(` ${skillFile}
67669
68066
  `);
67670
68067
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
67671
68068
  return;
67672
68069
  }
67673
- const sourceSkillPath = join29(__dirname3, "../skills/claudish-usage/SKILL.md");
67674
- if (!existsSync23(sourceSkillPath)) {
68070
+ const sourceSkillPath = join30(__dirname3, "../skills/claudish-usage/SKILL.md");
68071
+ if (!existsSync24(sourceSkillPath)) {
67675
68072
  console.error("\u274C Error: Claudish skill file not found in installation.");
67676
68073
  console.error(` Expected at: ${sourceSkillPath}`);
67677
68074
  console.error(`
@@ -67680,16 +68077,16 @@ async function initializeClaudishSkill() {
67680
68077
  process.exit(1);
67681
68078
  }
67682
68079
  try {
67683
- if (!existsSync23(claudeDir)) {
67684
- mkdirSync13(claudeDir, { recursive: true });
68080
+ if (!existsSync24(claudeDir)) {
68081
+ mkdirSync14(claudeDir, { recursive: true });
67685
68082
  console.log("\uD83D\uDCC1 Created .claude/ directory");
67686
68083
  }
67687
- if (!existsSync23(skillsDir)) {
67688
- mkdirSync13(skillsDir, { recursive: true });
68084
+ if (!existsSync24(skillsDir)) {
68085
+ mkdirSync14(skillsDir, { recursive: true });
67689
68086
  console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
67690
68087
  }
67691
- if (!existsSync23(claudishSkillDir)) {
67692
- mkdirSync13(claudishSkillDir, { recursive: true });
68088
+ if (!existsSync24(claudishSkillDir)) {
68089
+ mkdirSync14(claudishSkillDir, { recursive: true });
67693
68090
  console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
67694
68091
  }
67695
68092
  copyFileSync2(sourceSkillPath, skillFile);
@@ -67761,7 +68158,7 @@ var init_cli = __esm(() => {
67761
68158
  init_routing_rules();
67762
68159
  init_provider_resolver();
67763
68160
  __filename3 = fileURLToPath2(import.meta.url);
67764
- __dirname3 = dirname9(__filename3);
68161
+ __dirname3 = dirname10(__filename3);
67765
68162
  });
67766
68163
 
67767
68164
  // src/update-checker.ts
@@ -67773,33 +68170,33 @@ __export(exports_update_checker, {
67773
68170
  clearCache: () => clearCache,
67774
68171
  checkForUpdates: () => checkForUpdates
67775
68172
  });
67776
- import { existsSync as existsSync24, mkdirSync as mkdirSync14, readFileSync as readFileSync22, unlinkSync as unlinkSync9, writeFileSync as writeFileSync16 } from "fs";
67777
- import { homedir as homedir28, platform as platform2, tmpdir } from "os";
67778
- import { join as join30 } from "path";
68173
+ import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync23, unlinkSync as unlinkSync9, writeFileSync as writeFileSync17 } from "fs";
68174
+ import { homedir as homedir29, platform as platform2, tmpdir } from "os";
68175
+ import { join as join31 } from "path";
67779
68176
  function getCacheFilePath() {
67780
68177
  let cacheDir;
67781
68178
  if (isWindows) {
67782
- const localAppData = process.env.LOCALAPPDATA || join30(homedir28(), "AppData", "Local");
67783
- cacheDir = join30(localAppData, "claudish");
68179
+ const localAppData = process.env.LOCALAPPDATA || join31(homedir29(), "AppData", "Local");
68180
+ cacheDir = join31(localAppData, "claudish");
67784
68181
  } else {
67785
- cacheDir = join30(homedir28(), ".cache", "claudish");
68182
+ cacheDir = join31(homedir29(), ".cache", "claudish");
67786
68183
  }
67787
68184
  try {
67788
- if (!existsSync24(cacheDir)) {
67789
- mkdirSync14(cacheDir, { recursive: true });
68185
+ if (!existsSync25(cacheDir)) {
68186
+ mkdirSync15(cacheDir, { recursive: true });
67790
68187
  }
67791
- return join30(cacheDir, "update-check.json");
68188
+ return join31(cacheDir, "update-check.json");
67792
68189
  } catch {
67793
- return join30(tmpdir(), "claudish-update-check.json");
68190
+ return join31(tmpdir(), "claudish-update-check.json");
67794
68191
  }
67795
68192
  }
67796
68193
  function readCache() {
67797
68194
  try {
67798
68195
  const cachePath = getCacheFilePath();
67799
- if (!existsSync24(cachePath)) {
68196
+ if (!existsSync25(cachePath)) {
67800
68197
  return null;
67801
68198
  }
67802
- const data = JSON.parse(readFileSync22(cachePath, "utf-8"));
68199
+ const data = JSON.parse(readFileSync23(cachePath, "utf-8"));
67803
68200
  return data;
67804
68201
  } catch {
67805
68202
  return null;
@@ -67812,7 +68209,7 @@ function writeCache(latestVersion) {
67812
68209
  lastCheck: Date.now(),
67813
68210
  latestVersion
67814
68211
  };
67815
- writeFileSync16(cachePath, JSON.stringify(data), "utf-8");
68212
+ writeFileSync17(cachePath, JSON.stringify(data), "utf-8");
67816
68213
  } catch {}
67817
68214
  }
67818
68215
  function isCacheValid(cache2) {
@@ -67822,7 +68219,7 @@ function isCacheValid(cache2) {
67822
68219
  function clearCache() {
67823
68220
  try {
67824
68221
  const cachePath = getCacheFilePath();
67825
- if (existsSync24(cachePath)) {
68222
+ if (existsSync25(cachePath)) {
67826
68223
  unlinkSync9(cachePath);
67827
68224
  }
67828
68225
  } catch {}
@@ -68707,15 +69104,15 @@ var init_local_liveness = __esm(() => {
68707
69104
  });
68708
69105
 
68709
69106
  // src/providers/probe-catalog.ts
68710
- import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync23, writeFileSync as writeFileSync17 } from "fs";
68711
- import { homedir as homedir29 } from "os";
68712
- import { dirname as dirname10, join as join31 } from "path";
69107
+ import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync24, writeFileSync as writeFileSync18 } from "fs";
69108
+ import { homedir as homedir30 } from "os";
69109
+ import { dirname as dirname11, join as join32 } from "path";
68713
69110
  function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
68714
- if (!existsSync25(path2))
69111
+ if (!existsSync26(path2))
68715
69112
  return null;
68716
69113
  let raw2;
68717
69114
  try {
68718
- raw2 = JSON.parse(readFileSync23(path2, "utf-8"));
69115
+ raw2 = JSON.parse(readFileSync24(path2, "utf-8"));
68719
69116
  } catch {
68720
69117
  return null;
68721
69118
  }
@@ -68724,8 +69121,8 @@ function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
68724
69121
  return raw2;
68725
69122
  }
68726
69123
  function writeProbeModelsCache(data, path2 = PROBE_MODELS_CACHE_PATH) {
68727
- mkdirSync15(dirname10(path2), { recursive: true });
68728
- writeFileSync17(path2, JSON.stringify(data), "utf-8");
69124
+ mkdirSync16(dirname11(path2), { recursive: true });
69125
+ writeFileSync18(path2, JSON.stringify(data), "utf-8");
68729
69126
  }
68730
69127
  function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
68731
69128
  if (!data?.generatedAt)
@@ -68844,7 +69241,7 @@ function isValidResponse(raw2) {
68844
69241
  var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels", CACHE_TTL_MS4, FETCH_TIMEOUT_MS3 = 15000, PROBE_MODELS_CACHE_PATH, _inFlight = null;
68845
69242
  var init_probe_catalog = __esm(() => {
68846
69243
  CACHE_TTL_MS4 = 60 * 60 * 1000;
68847
- PROBE_MODELS_CACHE_PATH = join31(homedir29(), ".claudish", "probe-models.json");
69244
+ PROBE_MODELS_CACHE_PATH = join32(homedir30(), ".claudish", "probe-models.json");
68848
69245
  });
68849
69246
 
68850
69247
  // src/tui/constants.ts
@@ -71532,8 +71929,8 @@ function ProvidersContent({
71532
71929
  let statusText = p.isLocal ? isReady ? "enabled" : "disabled" : isReady ? "ready" : "not set";
71533
71930
  if (p.isLocal) {
71534
71931
  const live = localLiveness[p.catalogName];
71535
- const enabled = providerAuthSource(p, config3) !== null;
71536
- if (enabled) {
71932
+ const enabled2 = providerAuthSource(p, config3) !== null;
71933
+ if (enabled2) {
71537
71934
  if (live === "running") {
71538
71935
  statusFg = C.green;
71539
71936
  statusText = "running";
@@ -75195,17 +75592,17 @@ __export(exports_claude_runner, {
75195
75592
  import { spawn as spawn4 } from "child_process";
75196
75593
  import {
75197
75594
  closeSync as closeSync5,
75198
- existsSync as existsSync26,
75199
- mkdirSync as mkdirSync16,
75595
+ existsSync as existsSync27,
75596
+ mkdirSync as mkdirSync17,
75200
75597
  openSync as openSync5,
75201
- readFileSync as readFileSync24,
75598
+ readFileSync as readFileSync25,
75202
75599
  readdirSync as readdirSync6,
75203
75600
  statSync as statSync5,
75204
75601
  unlinkSync as unlinkSync10,
75205
- writeFileSync as writeFileSync18
75602
+ writeFileSync as writeFileSync19
75206
75603
  } from "fs";
75207
- import { homedir as homedir30, tmpdir as tmpdir2 } from "os";
75208
- import { dirname as dirname11, join as join32 } from "path";
75604
+ import { homedir as homedir31, tmpdir as tmpdir2 } from "os";
75605
+ import { dirname as dirname12, join as join33 } from "path";
75209
75606
  import { isatty } from "tty";
75210
75607
  function releaseTerminalIsolation() {
75211
75608
  if (!restoreTerminal)
@@ -75240,16 +75637,16 @@ function isProxyAuthMode(config3) {
75240
75637
  }
75241
75638
  function managedSettingsPath() {
75242
75639
  if (isWindows2()) {
75243
- return join32(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
75640
+ return join33(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
75244
75641
  }
75245
75642
  if (process.platform === "darwin") {
75246
75643
  return "/Library/Application Support/ClaudeCode/managed-settings.json";
75247
75644
  }
75248
75645
  return "/etc/claude-code/managed-settings.json";
75249
75646
  }
75250
- function managedSettingsForcesClaudeAi(readFile2 = readFileSync24) {
75647
+ function managedSettingsForcesClaudeAi(readFile3 = readFileSync25) {
75251
75648
  try {
75252
- const raw2 = readFile2(managedSettingsPath(), "utf-8");
75649
+ const raw2 = readFile3(managedSettingsPath(), "utf-8");
75253
75650
  const parsed = JSON.parse(raw2);
75254
75651
  return parsed.forceLoginMethod === "claudeai";
75255
75652
  } catch {
@@ -75261,9 +75658,9 @@ function isWindows2() {
75261
75658
  }
75262
75659
  function createStatusLineScript(tokenFilePath) {
75263
75660
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
75264
- const claudishDir = join32(homeDir, ".claudish");
75661
+ const claudishDir = join33(homeDir, ".claudish");
75265
75662
  const timestamp = Date.now();
75266
- const scriptPath = join32(claudishDir, `status-${timestamp}.js`);
75663
+ const scriptPath = join33(claudishDir, `status-${timestamp}.js`);
75267
75664
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
75268
75665
  const script = `
75269
75666
  const fs = require('fs');
@@ -75381,13 +75778,13 @@ process.stdin.on('end', () => {
75381
75778
  }
75382
75779
  });
75383
75780
  `;
75384
- writeFileSync18(scriptPath, script, "utf-8");
75781
+ writeFileSync19(scriptPath, script, "utf-8");
75385
75782
  return scriptPath;
75386
75783
  }
75387
75784
  function initializeTokenFile(tokenFilePath) {
75388
75785
  try {
75389
- mkdirSync16(dirname11(tokenFilePath), { recursive: true });
75390
- writeFileSync18(tokenFilePath, JSON.stringify({
75786
+ mkdirSync17(dirname12(tokenFilePath), { recursive: true });
75787
+ writeFileSync19(tokenFilePath, JSON.stringify({
75391
75788
  input_tokens: 0,
75392
75789
  output_tokens: 0,
75393
75790
  total_tokens: 0,
@@ -75418,7 +75815,7 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
75418
75815
  if (!name.startsWith("tokens-") || !name.endsWith(".json"))
75419
75816
  continue;
75420
75817
  scanned++;
75421
- const full = join32(dir, name);
75818
+ const full = join33(dir, name);
75422
75819
  try {
75423
75820
  if (statSync5(full).mtimeMs >= cutoff)
75424
75821
  continue;
@@ -75435,7 +75832,7 @@ function parseSettingsArg(value) {
75435
75832
  if (value.trimStart().startsWith("{")) {
75436
75833
  return JSON.parse(value);
75437
75834
  }
75438
- return JSON.parse(readFileSync24(value, "utf-8"));
75835
+ return JSON.parse(readFileSync25(value, "utf-8"));
75439
75836
  }
75440
75837
  function parseSettingsArgSafe(value) {
75441
75838
  try {
@@ -75447,13 +75844,13 @@ function parseSettingsArgSafe(value) {
75447
75844
  }
75448
75845
  function userSettingsFileCandidates(cwd) {
75449
75846
  return [
75450
- join32(homedir30(), ".claude", "settings.json"),
75451
- join32(cwd, ".claude", "settings.json"),
75452
- join32(cwd, ".claude", "settings.local.json")
75847
+ join33(homedir31(), ".claude", "settings.json"),
75848
+ join33(cwd, ".claude", "settings.json"),
75849
+ join33(cwd, ".claude", "settings.local.json")
75453
75850
  ];
75454
75851
  }
75455
75852
  function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
75456
- const sources = userSettingsFileCandidates(cwd).filter((file2) => existsSync26(file2));
75853
+ const sources = userSettingsFileCandidates(cwd).filter((file2) => existsSync27(file2));
75457
75854
  const idx = claudeArgs.indexOf("--settings");
75458
75855
  const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
75459
75856
  if (settingsArg)
@@ -75490,13 +75887,13 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
75490
75887
  }
75491
75888
  function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
75492
75889
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
75493
- const claudishDir = join32(homeDir, ".claudish");
75890
+ const claudishDir = join33(homeDir, ".claudish");
75494
75891
  try {
75495
- mkdirSync16(claudishDir, { recursive: true });
75892
+ mkdirSync17(claudishDir, { recursive: true });
75496
75893
  } catch {}
75497
75894
  const timestamp = Date.now();
75498
- const tempPath = join32(claudishDir, `settings-${timestamp}.json`);
75499
- const tokenFilePath = join32(claudishDir, `tokens-${port}.json`);
75895
+ const tempPath = join33(claudishDir, `settings-${timestamp}.json`);
75896
+ const tokenFilePath = join33(claudishDir, `tokens-${port}.json`);
75500
75897
  cleanupStaleTokenFiles(claudishDir);
75501
75898
  initializeTokenFile(tokenFilePath);
75502
75899
  let statusCommand;
@@ -75527,7 +75924,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
75527
75924
  padding: 0
75528
75925
  };
75529
75926
  const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
75530
- writeFileSync18(tempPath, JSON.stringify(settings, null, 2), "utf-8");
75927
+ writeFileSync19(tempPath, JSON.stringify(settings, null, 2), "utf-8");
75531
75928
  return { path: tempPath, statusLine, tokenFilePath };
75532
75929
  }
75533
75930
  function buildClaudishSettingsOverlay(statusLine, proxyAuthMode) {
@@ -75552,7 +75949,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
75552
75949
  if (proxyAuthMode && !("forceLoginMethod" in userSettings)) {
75553
75950
  userSettings.forceLoginMethod = "console";
75554
75951
  }
75555
- writeFileSync18(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
75952
+ writeFileSync19(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
75556
75953
  } catch {
75557
75954
  if (!config3.quiet) {
75558
75955
  console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
@@ -75727,6 +76124,10 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
75727
76124
  const realWindow = await computeMainThreadContextWindow(config3);
75728
76125
  const contextEnv = resolveContextWindowEnv(realWindow, process.env);
75729
76126
  Object.assign(env, contextEnv.vars);
76127
+ try {
76128
+ const { setSessionContextWindow: setSessionContextWindow2 } = await Promise.resolve().then(() => (init_aggregate(), exports_aggregate));
76129
+ setSessionContextWindow2(realWindow);
76130
+ } catch {}
75730
76131
  if (contextEnv.notice && !config3.quiet) {
75731
76132
  console.error(contextEnv.notice);
75732
76133
  }
@@ -75763,8 +76164,8 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
75763
76164
  console.error("Install it from: https://claude.com/claude-code");
75764
76165
  console.error(`
75765
76166
  Or set CLAUDE_PATH to your custom installation:`);
75766
- const home = homedir30();
75767
- const localPath = isWindows2() ? join32(home, ".claude", "local", "claude.exe") : join32(home, ".claude", "local", "claude");
76167
+ const home = homedir31();
76168
+ const localPath = isWindows2() ? join33(home, ".claude", "local", "claude.exe") : join33(home, ".claude", "local", "claude");
75768
76169
  console.error(` export CLAUDE_PATH=${localPath}`);
75769
76170
  process.exit(1);
75770
76171
  }
@@ -75785,7 +76186,7 @@ Or set CLAUDE_PATH to your custom installation:`);
75785
76186
  ttyFd = undefined;
75786
76187
  }
75787
76188
  } else if (config3.interactive && !process.stdout.isTTY && !process.stdin.isTTY) {
75788
- 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.");
76189
+ 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.");
75789
76190
  }
75790
76191
  const stdio = ttyFd !== undefined ? [0, ttyFd, ttyFd] : "inherit";
75791
76192
  const proc = spawn4(spawnCommand, claudeArgs, {
@@ -75844,23 +76245,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
75844
76245
  async function findClaudeBinary() {
75845
76246
  const isWindows3 = process.platform === "win32";
75846
76247
  if (process.env.CLAUDE_PATH) {
75847
- if (existsSync26(process.env.CLAUDE_PATH)) {
76248
+ if (existsSync27(process.env.CLAUDE_PATH)) {
75848
76249
  return process.env.CLAUDE_PATH;
75849
76250
  }
75850
76251
  }
75851
- const home = homedir30();
75852
- const localPath = isWindows3 ? join32(home, ".claude", "local", "claude.exe") : join32(home, ".claude", "local", "claude");
75853
- if (existsSync26(localPath)) {
76252
+ const home = homedir31();
76253
+ const localPath = isWindows3 ? join33(home, ".claude", "local", "claude.exe") : join33(home, ".claude", "local", "claude");
76254
+ if (existsSync27(localPath)) {
75854
76255
  return localPath;
75855
76256
  }
75856
76257
  if (isWindows3) {
75857
76258
  const windowsPaths = [
75858
- join32(home, "AppData", "Roaming", "npm", "claude.cmd"),
75859
- join32(home, ".npm-global", "claude.cmd"),
75860
- join32(home, "node_modules", ".bin", "claude.cmd")
76259
+ join33(home, "AppData", "Roaming", "npm", "claude.cmd"),
76260
+ join33(home, ".npm-global", "claude.cmd"),
76261
+ join33(home, "node_modules", ".bin", "claude.cmd")
75861
76262
  ];
75862
76263
  for (const path2 of windowsPaths) {
75863
- if (existsSync26(path2)) {
76264
+ if (existsSync27(path2)) {
75864
76265
  return path2;
75865
76266
  }
75866
76267
  }
@@ -75868,14 +76269,14 @@ async function findClaudeBinary() {
75868
76269
  const commonPaths = [
75869
76270
  "/usr/local/bin/claude",
75870
76271
  "/opt/homebrew/bin/claude",
75871
- join32(home, ".npm-global/bin/claude"),
75872
- join32(home, ".local/bin/claude"),
75873
- join32(home, "node_modules/.bin/claude"),
76272
+ join33(home, ".npm-global/bin/claude"),
76273
+ join33(home, ".local/bin/claude"),
76274
+ join33(home, "node_modules/.bin/claude"),
75874
76275
  "/data/data/com.termux/files/usr/bin/claude",
75875
- join32(home, "../usr/bin/claude")
76276
+ join33(home, "../usr/bin/claude")
75876
76277
  ];
75877
76278
  for (const path2 of commonPaths) {
75878
- if (existsSync26(path2)) {
76279
+ if (existsSync27(path2)) {
75879
76280
  return path2;
75880
76281
  }
75881
76282
  }
@@ -75935,18 +76336,18 @@ __export(exports_diag_output, {
75935
76336
  NullDiagOutput: () => NullDiagOutput,
75936
76337
  LogFileDiagOutput: () => LogFileDiagOutput
75937
76338
  });
75938
- import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync17, unlinkSync as unlinkSync11, writeFileSync as writeFileSync19 } from "fs";
75939
- import { homedir as homedir31 } from "os";
75940
- import { join as join33 } from "path";
76339
+ import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync18, unlinkSync as unlinkSync11, writeFileSync as writeFileSync20 } from "fs";
76340
+ import { homedir as homedir32 } from "os";
76341
+ import { join as join34 } from "path";
75941
76342
  function getClaudishDir() {
75942
- const dir = join33(homedir31(), ".claudish");
76343
+ const dir = join34(homedir32(), ".claudish");
75943
76344
  try {
75944
- mkdirSync17(dir, { recursive: true });
76345
+ mkdirSync18(dir, { recursive: true });
75945
76346
  } catch {}
75946
76347
  return dir;
75947
76348
  }
75948
76349
  function getDiagLogPath() {
75949
- return join33(getClaudishDir(), `diag-${process.pid}.log`);
76350
+ return join34(getClaudishDir(), `diag-${process.pid}.log`);
75950
76351
  }
75951
76352
 
75952
76353
  class LogFileDiagOutput {
@@ -75955,7 +76356,7 @@ class LogFileDiagOutput {
75955
76356
  constructor() {
75956
76357
  this.logPath = getDiagLogPath();
75957
76358
  try {
75958
- writeFileSync19(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
76359
+ writeFileSync20(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
75959
76360
  `);
75960
76361
  } catch {}
75961
76362
  this.stream = createWriteStream3(this.logPath, { flags: "a" });
@@ -76157,9 +76558,9 @@ __export(exports_team_grid, {
76157
76558
  });
76158
76559
  import { spawn as spawn5 } from "child_process";
76159
76560
  import { execSync as execSync2 } from "child_process";
76160
- import { existsSync as existsSync27, readFileSync as readFileSync25, writeFileSync as writeFileSync20 } from "fs";
76561
+ import { existsSync as existsSync28, readFileSync as readFileSync26, writeFileSync as writeFileSync21 } from "fs";
76161
76562
  import { connect as netConnect } from "net";
76162
- import { dirname as dirname12, join as join34 } from "path";
76563
+ import { dirname as dirname13, join as join35 } from "path";
76163
76564
  import { setTimeout as wait } from "timers/promises";
76164
76565
  import { fileURLToPath as fileURLToPath3 } from "url";
76165
76566
  function resolveRouteInfo(modelId) {
@@ -76252,21 +76653,21 @@ function buildPaneHeader(model, prompt, bg) {
76252
76653
  }
76253
76654
  function findMagmuxBinary() {
76254
76655
  const thisFile = fileURLToPath3(import.meta.url);
76255
- const thisDir = dirname12(thisFile);
76256
- const pkgRoot = join34(thisDir, "..");
76656
+ const thisDir = dirname13(thisFile);
76657
+ const pkgRoot = join35(thisDir, "..");
76257
76658
  const platform3 = process.platform;
76258
76659
  const arch = process.arch;
76259
- const bundledMagmux = join34(pkgRoot, "native", `magmux-${platform3}-${arch}`);
76260
- if (existsSync27(bundledMagmux))
76660
+ const bundledMagmux = join35(pkgRoot, "native", `magmux-${platform3}-${arch}`);
76661
+ if (existsSync28(bundledMagmux))
76261
76662
  return bundledMagmux;
76262
76663
  try {
76263
76664
  const pkgName = `@claudish/magmux-${platform3}-${arch}`;
76264
76665
  let searchDir = pkgRoot;
76265
76666
  for (let i = 0;i < 5; i++) {
76266
- const candidate = join34(searchDir, "node_modules", pkgName, "bin", "magmux");
76267
- if (existsSync27(candidate))
76667
+ const candidate = join35(searchDir, "node_modules", pkgName, "bin", "magmux");
76668
+ if (existsSync28(candidate))
76268
76669
  return candidate;
76269
- const parent = dirname12(searchDir);
76670
+ const parent = dirname13(searchDir);
76270
76671
  if (parent === searchDir)
76271
76672
  break;
76272
76673
  searchDir = parent;
@@ -76283,7 +76684,7 @@ function findMagmuxBinary() {
76283
76684
  async function subscribeToMagmux(sockPath, onEvent) {
76284
76685
  let client = null;
76285
76686
  for (let attempt = 0;attempt < 40; attempt++) {
76286
- if (existsSync27(sockPath)) {
76687
+ if (existsSync28(sockPath)) {
76287
76688
  try {
76288
76689
  client = await new Promise((resolve4, reject) => {
76289
76690
  const s = netConnect(sockPath);
@@ -76370,9 +76771,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
76370
76771
  const keep = opts?.keep ?? false;
76371
76772
  const manifest = setupSession(sessionPath, models, input);
76372
76773
  const startedAt = new Date().toISOString();
76373
- const gridfilePath = join34(sessionPath, "gridfile.txt");
76374
- const prompt = readFileSync25(join34(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
76375
- const rawPrompt = readFileSync25(join34(sessionPath, "input.md"), "utf-8");
76774
+ const gridfilePath = join35(sessionPath, "gridfile.txt");
76775
+ const prompt = readFileSync26(join35(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
76776
+ const rawPrompt = readFileSync26(join35(sessionPath, "input.md"), "utf-8");
76376
76777
  const usedBannerColors = new Set;
76377
76778
  const gridLines = Object.entries(manifest.models).map(([anonId]) => {
76378
76779
  const model = manifest.models[anonId].model;
@@ -76383,7 +76784,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
76383
76784
  const header = buildPaneHeader(model, rawPrompt, bg);
76384
76785
  return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
76385
76786
  });
76386
- writeFileSync20(gridfilePath, `${gridLines.join(`
76787
+ writeFileSync21(gridfilePath, `${gridLines.join(`
76387
76788
  `)}
76388
76789
  `, "utf-8");
76389
76790
  const magmuxPath = findMagmuxBinary();
@@ -76403,8 +76804,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
76403
76804
  });
76404
76805
  const [{ results: results2 }] = await Promise.all([subscription, procExit]);
76405
76806
  const status = buildTeamStatus(manifest, startedAt, results2?.panes ?? null);
76406
- const statusPath = join34(sessionPath, "status.json");
76407
- writeFileSync20(statusPath, JSON.stringify(status, null, 2), "utf-8");
76807
+ const statusPath = join35(sessionPath, "status.json");
76808
+ writeFileSync21(statusPath, JSON.stringify(status, null, 2), "utf-8");
76408
76809
  return status;
76409
76810
  }
76410
76811
  var BANNER_BG_COLORS;
@@ -76427,8 +76828,8 @@ var init_team_grid = __esm(() => {
76427
76828
  init_op_source();
76428
76829
  init_startup_trace();
76429
76830
  var import_dotenv3 = __toESM(require_main(), 1);
76430
- import { existsSync as existsSync28, readFileSync as readFileSync26 } from "fs";
76431
- import { join as join35, resolve as resolve4 } from "path";
76831
+ import { existsSync as existsSync29, readFileSync as readFileSync27 } from "fs";
76832
+ import { join as join36, resolve as resolve4 } from "path";
76432
76833
  import_dotenv3.config({ quiet: true });
76433
76834
  function classifyStartupKind() {
76434
76835
  const argv = process.argv.slice(2);
@@ -76527,7 +76928,7 @@ async function applyConfigOverride() {
76527
76928
  const { planConfigOverride: planConfigOverride2, setConfigFileOverride: setConfigFileOverride2 } = await Promise.resolve().then(() => exports_config_override);
76528
76929
  const plan = planConfigOverride2(process.argv.slice(2), process.env, {
76529
76930
  resolve: resolve4,
76530
- exists: existsSync28
76931
+ exists: existsSync29
76531
76932
  });
76532
76933
  if (plan.kind === "none")
76533
76934
  return;
@@ -76675,14 +77076,14 @@ async function runCli() {
76675
77076
  if (cliConfig.team && cliConfig.team.length > 0) {
76676
77077
  let prompt = cliConfig.claudeArgs.join(" ");
76677
77078
  if (cliConfig.inputFile) {
76678
- prompt = readFileSync26(cliConfig.inputFile, "utf-8");
77079
+ prompt = readFileSync27(cliConfig.inputFile, "utf-8");
76679
77080
  }
76680
77081
  if (!prompt.trim()) {
76681
77082
  console.error("Error: --team requires a prompt (positional args or -f <file>)");
76682
77083
  process.exit(1);
76683
77084
  }
76684
77085
  const mode = cliConfig.teamMode ?? "default";
76685
- const sessionPath = join35(process.cwd(), `.claudish-team-${Date.now()}`);
77086
+ const sessionPath = join36(process.cwd(), `.claudish-team-${Date.now()}`);
76686
77087
  if (mode === "json") {
76687
77088
  const { setupSession: setupSession2, runModels: runModels2 } = await Promise.resolve().then(() => (init_team_orchestrator(), exports_team_orchestrator));
76688
77089
  setupSession2(sessionPath, cliConfig.team, prompt);
@@ -76692,9 +77093,9 @@ async function runCli() {
76692
77093
  });
76693
77094
  const result = { ...status2, responses: {} };
76694
77095
  for (const anonId of Object.keys(status2.models)) {
76695
- const responsePath = join35(sessionPath, `response-${anonId}.md`);
77096
+ const responsePath = join36(sessionPath, `response-${anonId}.md`);
76696
77097
  try {
76697
- const raw2 = readFileSync26(responsePath, "utf-8").trim();
77098
+ const raw2 = readFileSync27(responsePath, "utf-8").trim();
76698
77099
  try {
76699
77100
  result.responses[anonId] = JSON.parse(raw2);
76700
77101
  } catch {