claudish 10.4.0 → 10.4.1

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.
package/bin/claudish.cjs CHANGED
@@ -114,7 +114,7 @@ Learn more: https://bun.sh`);
114
114
  // The pid pair tells the Bun child who launched it: this launcher, and the
115
115
  // launcher's own parent (Claude Code, for an MCP server). The child
116
116
  // believes the pair only when CLAUDISH_LAUNCHER_PID is its real parent
117
- // (channel/parent-proof.ts `hostPidFrom`), so a value leaked into a
117
+ // (channel/parent-session.ts `hostPidFrom`), so a value leaked into a
118
118
  // nested claudish is inert.
119
119
  env: {
120
120
  ...process.env,
package/dist/index.js CHANGED
@@ -889,7 +889,7 @@ var init_onepassword_config = __esm(() => {
889
889
  });
890
890
 
891
891
  // src/version.ts
892
- var VERSION = "10.4.0";
892
+ var VERSION = "10.4.1";
893
893
 
894
894
  // src/logger.ts
895
895
  import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
@@ -32422,66 +32422,6 @@ function sessionsDirFrom(env, homedirFn = homedir23) {
32422
32422
  return explicit;
32423
32423
  return join23(userHomeFrom(env, homedirFn), ".claudish", "sessions");
32424
32424
  }
32425
- var init_home_dir = () => {};
32426
-
32427
- // src/channel/parent-proof.ts
32428
- import * as fsPromises from "fs/promises";
32429
- import { join as join24 } from "path";
32430
- function positiveInt(value) {
32431
- if (value === undefined || !/^[1-9][0-9]*$/.test(value))
32432
- return;
32433
- const n = Number(value);
32434
- return Number.isSafeInteger(n) ? n : undefined;
32435
- }
32436
- function hostPidFrom(env, ppid) {
32437
- const launcherPpid = positiveInt(env.CLAUDISH_LAUNCHER_PPID);
32438
- if (env.CLAUDISH_LAUNCHER_PID === String(ppid) && launcherPpid !== undefined && launcherPpid !== ppid) {
32439
- return { hostPid: launcherPpid, launcherPid: ppid };
32440
- }
32441
- return { hostPid: ppid };
32442
- }
32443
- function parentSessionIdFrom(env) {
32444
- const id = env.CLAUDE_CODE_SESSION_ID;
32445
- if (id === undefined || !CLAUDE_ID_RE.test(id))
32446
- return;
32447
- if (env.CLAUDE_CODE_CHILD_SESSION)
32448
- return;
32449
- return id;
32450
- }
32451
- function claudeConfigDir(env) {
32452
- const fromEnv = env.CLAUDE_CONFIG_DIR;
32453
- return fromEnv && fromEnv.length > 0 ? fromEnv : join24(userHomeFrom(env), ".claude");
32454
- }
32455
- async function readHostSessionRecord(opts) {
32456
- const fs = opts.fs ?? defaultFs;
32457
- try {
32458
- const raw = await fs.readFile(join24(opts.configDir, "sessions", `${opts.hostPid}.json`), "utf-8");
32459
- const parsed = JSON.parse(raw);
32460
- if (!parsed || typeof parsed !== "object")
32461
- return;
32462
- const rec = parsed;
32463
- if (rec.pid !== opts.hostPid)
32464
- return;
32465
- if (typeof rec.sessionId !== "string" || !CLAUDE_ID_RE.test(rec.sessionId))
32466
- return;
32467
- return {
32468
- sessionId: rec.sessionId,
32469
- ...typeof rec.cwd === "string" && rec.cwd.length > 0 ? { cwd: rec.cwd } : {}
32470
- };
32471
- } catch {
32472
- return;
32473
- }
32474
- }
32475
- async function gatherProofCandidates(opts) {
32476
- const record = await readHostSessionRecord({
32477
- configDir: opts.configDir,
32478
- hostPid: opts.hostPid,
32479
- fs: opts.fs
32480
- });
32481
- const cwd = record?.cwd;
32482
- const ids = [parentSessionIdFrom(opts.env), record?.sessionId].filter((id) => id !== undefined);
32483
- return [...new Set(ids)].map((sessionId) => ({ sessionId, ...cwd ? { cwd } : {} }));
32484
- }
32485
32425
  function claudeCodeStringHash(s) {
32486
32426
  let h = 0;
32487
32427
  for (let i = 0;i < s.length; i++)
@@ -32494,183 +32434,8 @@ function projectDirNameFor(cwd) {
32494
32434
  return slug;
32495
32435
  return `${slug.slice(0, PROJECT_DIR_SLUG_MAX)}-${Math.abs(claudeCodeStringHash(cwd)).toString(36)}`;
32496
32436
  }
32497
- async function isTranscriptFile(fs, path) {
32498
- try {
32499
- return (await fs.stat(path)).isFile();
32500
- } catch {
32501
- return false;
32502
- }
32503
- }
32504
- async function findProjectDir(fs, configDir, candidate, cache) {
32505
- const cacheKey = `${configDir}\x00${candidate.sessionId}`;
32506
- const projectsDir = join24(configDir, "projects");
32507
- const fileName = `${candidate.sessionId}.jsonl`;
32508
- const cached = cache.get(cacheKey);
32509
- if (cached !== undefined) {
32510
- if (await isTranscriptFile(fs, join24(cached, fileName)))
32511
- return cached;
32512
- cache.delete(cacheKey);
32513
- }
32514
- if (candidate.cwd) {
32515
- const fast = join24(projectsDir, projectDirNameFor(candidate.cwd));
32516
- if (await isTranscriptFile(fs, join24(fast, fileName)))
32517
- return fast;
32518
- }
32519
- let names;
32520
- try {
32521
- names = await fs.readdir(projectsDir);
32522
- } catch {
32523
- return;
32524
- }
32525
- for (const name of names) {
32526
- const dir = join24(projectsDir, name);
32527
- if (await isTranscriptFile(fs, join24(dir, fileName))) {
32528
- cache.set(cacheKey, dir);
32529
- return dir;
32530
- }
32531
- }
32532
- return;
32533
- }
32534
- async function tailContains(fs, path, needle) {
32535
- let handle;
32536
- try {
32537
- const { size } = await fs.stat(path);
32538
- const length = Math.min(size, TRANSCRIPT_TAIL_BYTES);
32539
- if (length < needle.length)
32540
- return false;
32541
- const buffer = Buffer.alloc(length);
32542
- handle = await fs.open(path, "r");
32543
- const { bytesRead } = await handle.read(buffer, 0, length, size - length);
32544
- return buffer.subarray(0, bytesRead).includes(needle);
32545
- } catch {
32546
- return false;
32547
- } finally {
32548
- await handle?.close().catch(() => {});
32549
- }
32550
- }
32551
- async function recentSubagentTranscripts(fs, projectDir, candidateId, nowMs) {
32552
- const dir = join24(projectDir, candidateId, "subagents");
32553
- let names;
32554
- try {
32555
- names = await fs.readdir(dir);
32556
- } catch {
32557
- return [];
32558
- }
32559
- const recent = [];
32560
- for (const name of names) {
32561
- if (!name.endsWith(".jsonl"))
32562
- continue;
32563
- const path = join24(dir, name);
32564
- try {
32565
- const { mtimeMs } = await fs.stat(path);
32566
- if (nowMs - mtimeMs <= SUBAGENT_WINDOW_MS)
32567
- recent.push({ path, mtimeMs });
32568
- } catch {}
32569
- }
32570
- recent.sort((a, b) => b.mtimeMs - a.mtimeMs);
32571
- return recent.slice(0, MAX_SUBAGENT_FILES).map((f) => f.path);
32572
- }
32573
- async function candidateHolds(fs, configDir, candidate, needle, nowMs, cache) {
32574
- const projectDir = await findProjectDir(fs, configDir, candidate, cache);
32575
- if (projectDir === undefined)
32576
- return false;
32577
- if (await tailContains(fs, join24(projectDir, `${candidate.sessionId}.jsonl`), needle)) {
32578
- return true;
32579
- }
32580
- for (const path of await recentSubagentTranscripts(fs, projectDir, candidate.sessionId, nowMs)) {
32581
- if (await tailContains(fs, path, needle))
32582
- return true;
32583
- }
32584
- return false;
32585
- }
32586
- async function proveCallingConversation(opts) {
32587
- const { toolUseId } = opts;
32588
- if (typeof toolUseId !== "string" || !CLAUDE_ID_RE.test(toolUseId))
32589
- return;
32590
- const candidates = normaliseCandidates(opts.candidates);
32591
- if (candidates.length === 0)
32592
- return;
32593
- const fs = opts.fs ?? defaultFs;
32594
- const now = opts.now ?? Date.now;
32595
- const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
32596
- const cache = opts.cache ?? serverProjectDirCache;
32597
- const needle = Buffer.from(`"${toolUseId}"`, "utf-8");
32598
- const look = async () => {
32599
- for (const candidate of candidates) {
32600
- if (await candidateHolds(fs, opts.configDir, candidate, needle, now(), cache)) {
32601
- return candidate.sessionId;
32602
- }
32603
- }
32604
- return;
32605
- };
32606
- try {
32607
- const startedAt = now();
32608
- let slept = 0;
32609
- for (;; ) {
32610
- const found = await look();
32611
- if (found !== undefined)
32612
- return found;
32613
- const remaining = PROOF_DEADLINE_MS - Math.max(now() - startedAt, slept);
32614
- if (remaining <= 0)
32615
- return;
32616
- const wait = Math.min(PROOF_POLL_INTERVAL_MS, remaining);
32617
- await sleep(wait);
32618
- slept += wait;
32619
- }
32620
- } catch {
32621
- return;
32622
- }
32623
- }
32624
- function normaliseCandidates(raw) {
32625
- const out = [];
32626
- for (const entry of raw) {
32627
- const candidate = typeof entry === "string" ? { sessionId: entry } : entry;
32628
- if (!CLAUDE_ID_RE.test(candidate.sessionId))
32629
- continue;
32630
- if (out.some((c) => c.sessionId === candidate.sessionId))
32631
- continue;
32632
- out.push(candidate);
32633
- if (out.length === 2)
32634
- break;
32635
- }
32636
- return out;
32637
- }
32638
- async function proveParentForCall(opts) {
32639
- if (typeof opts.toolUseId !== "string" || !CLAUDE_ID_RE.test(opts.toolUseId))
32640
- return;
32641
- const env = opts.env ?? process.env;
32642
- const configDir = claudeConfigDir(env);
32643
- try {
32644
- const candidates = await gatherProofCandidates({
32645
- env,
32646
- hostPid: opts.hostPid,
32647
- configDir,
32648
- fs: opts.fs
32649
- });
32650
- return await proveCallingConversation({
32651
- toolUseId: opts.toolUseId,
32652
- candidates,
32653
- configDir,
32654
- fs: opts.fs
32655
- });
32656
- } catch {
32657
- return;
32658
- }
32659
- }
32660
- var CLAUDE_ID_RE, TOOL_USE_ID_META_KEY = "claudecode/toolUseId", TRANSCRIPT_TAIL_BYTES, SUBAGENT_WINDOW_MS, MAX_SUBAGENT_FILES = 32, PROOF_POLL_INTERVAL_MS = 100, PROOF_DEADLINE_MS = 2000, defaultFs, PROJECT_DIR_SLUG_MAX = 200, serverProjectDirCache;
32661
- var init_parent_proof = __esm(() => {
32662
- init_home_dir();
32663
- CLAUDE_ID_RE = /^[A-Za-z0-9_-]{8,128}$/;
32664
- TRANSCRIPT_TAIL_BYTES = 256 * 1024;
32665
- SUBAGENT_WINDOW_MS = 10 * 60000;
32666
- defaultFs = {
32667
- readFile: (path, encoding) => fsPromises.readFile(path, encoding),
32668
- readdir: (path) => fsPromises.readdir(path),
32669
- stat: (path) => fsPromises.stat(path),
32670
- open: (path, flags) => fsPromises.open(path, flags)
32671
- };
32672
- serverProjectDirCache = new Map;
32673
- });
32437
+ var PROJECT_DIR_SLUG_MAX = 200;
32438
+ var init_home_dir = () => {};
32674
32439
 
32675
32440
  // src/session-events/event-translator.ts
32676
32441
  function translateLine(line) {
@@ -32830,7 +32595,7 @@ var init_transcript_tailer = () => {};
32830
32595
  // src/session-events/index.ts
32831
32596
  import { existsSync as existsSync16, readFileSync as readFileSync16, readdirSync as readdirSync3 } from "fs";
32832
32597
  import { homedir as homedir24 } from "os";
32833
- import { join as join25 } from "path";
32598
+ import { join as join24 } from "path";
32834
32599
  function extractSessionId2(metadata) {
32835
32600
  const userId = metadata?.user_id;
32836
32601
  if (typeof userId !== "string")
@@ -32855,7 +32620,7 @@ class SessionEventRegistry {
32855
32620
  claudeHome;
32856
32621
  pollIntervalMs;
32857
32622
  constructor(opts = {}) {
32858
- this.claudeHome = opts.claudeHome ?? join25(homedir24(), ".claude");
32623
+ this.claudeHome = opts.claudeHome ?? join24(homedir24(), ".claude");
32859
32624
  this.pollIntervalMs = opts.pollIntervalMs;
32860
32625
  }
32861
32626
  ensureSession(sessionId) {
@@ -32941,13 +32706,13 @@ class SessionEventRegistry {
32941
32706
  }
32942
32707
  }
32943
32708
  locateTranscript(sessionId) {
32944
- const projectsDir = join25(this.claudeHome, "projects");
32945
- const primary = join25(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
32709
+ const projectsDir = join24(this.claudeHome, "projects");
32710
+ const primary = join24(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
32946
32711
  if (existsSync16(primary))
32947
32712
  return primary;
32948
32713
  try {
32949
32714
  for (const dir of readdirSync3(projectsDir)) {
32950
- const candidate = join25(projectsDir, dir, `${sessionId}.jsonl`);
32715
+ const candidate = join24(projectsDir, dir, `${sessionId}.jsonl`);
32951
32716
  if (existsSync16(candidate))
32952
32717
  return candidate;
32953
32718
  }
@@ -32956,7 +32721,7 @@ class SessionEventRegistry {
32956
32721
  }
32957
32722
  readSettingsEffortLevel() {
32958
32723
  try {
32959
- const settings = JSON.parse(readFileSync16(join25(this.claudeHome, "settings.json"), "utf-8"));
32724
+ const settings = JSON.parse(readFileSync16(join24(this.claudeHome, "settings.json"), "utf-8"));
32960
32725
  return typeof settings.effortLevel === "string" ? settings.effortLevel : undefined;
32961
32726
  } catch {
32962
32727
  return;
@@ -32974,7 +32739,7 @@ class SessionEventRegistry {
32974
32739
  }
32975
32740
  var MISS_TTL_MS = 5000, MAX_MISSES = 5, IDLE_SWEEP_MS, sessionEvents;
32976
32741
  var init_session_events = __esm(() => {
32977
- init_parent_proof();
32742
+ init_home_dir();
32978
32743
  init_logger();
32979
32744
  init_event_translator();
32980
32745
  init_transcript_tailer();
@@ -33213,7 +32978,7 @@ import {
33213
32978
  writeFileSync as writeFileSync8
33214
32979
  } from "fs";
33215
32980
  import { homedir as homedir25 } from "os";
33216
- import { join as join26 } from "path";
32981
+ import { join as join25 } from "path";
33217
32982
  function ensureDir() {
33218
32983
  if (!existsSync17(CLAUDISH_DIR)) {
33219
32984
  mkdirSync9(CLAUDISH_DIR, { recursive: true });
@@ -33248,7 +33013,7 @@ function writeToDisk(events) {
33248
33013
  ensureDir();
33249
33014
  const trimmed = enforceSizeCap([...events]);
33250
33015
  const payload = { version: 1, events: trimmed };
33251
- const tmpFile = join26(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
33016
+ const tmpFile = join25(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
33252
33017
  writeFileSync8(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
33253
33018
  renameSync2(tmpFile, BUFFER_FILE);
33254
33019
  memoryCache = trimmed;
@@ -33321,8 +33086,8 @@ function syncFlushOnExit() {
33321
33086
  var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false, SIGNAL_EXIT_CODE;
33322
33087
  var init_stats_buffer = __esm(() => {
33323
33088
  BUFFER_MAX_BYTES = 64 * 1024;
33324
- CLAUDISH_DIR = join26(homedir25(), ".claudish");
33325
- BUFFER_FILE = join26(CLAUDISH_DIR, "stats-buffer.json");
33089
+ CLAUDISH_DIR = join25(homedir25(), ".claudish");
33090
+ BUFFER_FILE = join25(CLAUDISH_DIR, "stats-buffer.json");
33326
33091
  process.on("exit", syncFlushOnExit);
33327
33092
  SIGNAL_EXIT_CODE = { SIGTERM: 143, SIGINT: 130 };
33328
33093
  for (const signal of ["SIGTERM", "SIGINT"]) {
@@ -36462,7 +36227,7 @@ var init_openai_responses_sse = __esm(() => {
36462
36227
  });
36463
36228
 
36464
36229
  // src/session/token-file.ts
36465
- import { join as join27 } from "path";
36230
+ import { join as join26 } from "path";
36466
36231
  function assignedTokenFile(env) {
36467
36232
  const f = env.CLAUDISH_TOKEN_FILE;
36468
36233
  if (!f || f === env.CLAUDISH_PUBLISHED_TOKEN_FILE)
@@ -36470,7 +36235,7 @@ function assignedTokenFile(env) {
36470
36235
  return f;
36471
36236
  }
36472
36237
  function resolveTokenFilePath(port, env = process.env) {
36473
- return assignedTokenFile(env) ?? join27(userHomeFrom(env), ".claudish", `tokens-${port}.json`);
36238
+ return assignedTokenFile(env) ?? join26(userHomeFrom(env), ".claudish", `tokens-${port}.json`);
36474
36239
  }
36475
36240
  var init_token_file = __esm(() => {
36476
36241
  init_home_dir();
@@ -38023,9 +37788,9 @@ var init_composed_handler = __esm(() => {
38023
37788
  // src/providers/api-key-provenance.ts
38024
37789
  import { existsSync as existsSync18, readFileSync as readFileSync18 } from "fs";
38025
37790
  import { homedir as homedir26 } from "os";
38026
- import { join as join28, resolve as resolve2 } from "path";
37791
+ import { join as join27, resolve as resolve2 } from "path";
38027
37792
  function activeConfigPath() {
38028
- return activeGlobalConfigFile(join28(homedir26(), ".claudish", "config.json"));
37793
+ return activeGlobalConfigFile(join27(homedir26(), ".claudish", "config.json"));
38029
37794
  }
38030
37795
  function configLayerLabel() {
38031
37796
  return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
@@ -41828,7 +41593,7 @@ function compareByConnectionPrice(a, b) {
41828
41593
  // src/providers/probe-catalog.ts
41829
41594
  import { existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync19, writeFileSync as writeFileSync10 } from "fs";
41830
41595
  import { homedir as homedir27 } from "os";
41831
- import { dirname as dirname9, join as join29 } from "path";
41596
+ import { dirname as dirname9, join as join28 } from "path";
41832
41597
  function describeProbeCatalogFailure(outcome) {
41833
41598
  switch (outcome.kind) {
41834
41599
  case "incompatible":
@@ -41999,7 +41764,7 @@ var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/pr
41999
41764
  var init_probe_catalog = __esm(() => {
42000
41765
  init_catalog_route_bindings();
42001
41766
  CACHE_TTL_MS4 = 60 * 60 * 1000;
42002
- PROBE_MODELS_CACHE_PATH = join29(homedir27(), ".claudish", "probe-models.json");
41767
+ PROBE_MODELS_CACHE_PATH = join28(homedir27(), ".claudish", "probe-models.json");
42003
41768
  });
42004
41769
 
42005
41770
  // src/providers/route-candidates.ts
@@ -43352,7 +43117,7 @@ var init_slot_row = __esm(() => {
43352
43117
 
43353
43118
  // src/pane/prompt-delivery.ts
43354
43119
  import { writeFileSync as writeFileSync11 } from "fs";
43355
- import { join as join30 } from "path";
43120
+ import { join as join29 } from "path";
43356
43121
  function stripControl(s) {
43357
43122
  let out = "";
43358
43123
  for (const ch of s) {
@@ -43419,7 +43184,7 @@ function renderTurnFile(text, limit = READ_LINE_LIMIT) {
43419
43184
  `), lines: out.length, marker };
43420
43185
  }
43421
43186
  function turnFilePath(turnDir, turnIndex) {
43422
- return join30(turnDir, `turn-${turnIndex}.md`);
43187
+ return join29(turnDir, `turn-${turnIndex}.md`);
43423
43188
  }
43424
43189
  function fileTemplate(file, marker) {
43425
43190
  const base = `Your task is in the file \`${file}\`. Read all of it with the Read tool (in parts if it is long), then do exactly what it says, treating its content as the user's message.`;
@@ -43500,12 +43265,12 @@ var init_prompt_delivery = __esm(() => {
43500
43265
 
43501
43266
  // src/team-stats.ts
43502
43267
  import { existsSync as existsSync20, readFileSync as readFileSync20, writeFileSync as writeFileSync12 } from "fs";
43503
- import { join as join31 } from "path";
43268
+ import { join as join30 } from "path";
43504
43269
  function statsDir(sessionPath) {
43505
- return join31(sessionPath, "stats");
43270
+ return join30(sessionPath, "stats");
43506
43271
  }
43507
43272
  function tokenFileFor(sessionPath, anonId) {
43508
- return join31(statsDir(sessionPath), `${anonId}.json`);
43273
+ return join30(statsDir(sessionPath), `${anonId}.json`);
43509
43274
  }
43510
43275
  function readTokenStatsAt(path) {
43511
43276
  if (!existsSync20(path))
@@ -43668,7 +43433,7 @@ ${segs.join(" \xB7 ")}`;
43668
43433
  }
43669
43434
  function writeStatusFile(sessionPath, manifest, status, opts) {
43670
43435
  try {
43671
- writeFileSync12(join31(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
43436
+ writeFileSync12(join30(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
43672
43437
  `, "utf-8");
43673
43438
  } catch {}
43674
43439
  }
@@ -43758,7 +43523,7 @@ var init_cache_ttl = __esm(() => {
43758
43523
  // src/model-loader.ts
43759
43524
  import { existsSync as existsSync21, mkdirSync as mkdirSync12, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "fs";
43760
43525
  import { homedir as homedir28 } from "os";
43761
- import { join as join32 } from "path";
43526
+ import { join as join31 } from "path";
43762
43527
  async function fetchCatalogPage(url, timeoutMs, generationId) {
43763
43528
  const requestUrl = new URL(url);
43764
43529
  if (generationId)
@@ -43985,7 +43750,7 @@ async function getRecommendedModels(opts = {}) {
43985
43750
  if (data.models.length > 0) {
43986
43751
  _cachedRecommendedModels = data;
43987
43752
  try {
43988
- const cacheDir = join32(homedir28(), ".claudish");
43753
+ const cacheDir = join31(homedir28(), ".claudish");
43989
43754
  mkdirSync12(cacheDir, { recursive: true });
43990
43755
  writeFileSync13(RECOMMENDED_MODELS_CACHE_PATH, JSON.stringify(data), "utf-8");
43991
43756
  } catch {}
@@ -44129,7 +43894,7 @@ var init_model_loader = __esm(() => {
44129
43894
  init_catalog_client();
44130
43895
  init_catalog_route_bindings();
44131
43896
  FIREBASE_RECOMMENDED_URL = `${FIREBASE_BASE_URL}?catalog=recommended`;
44132
- RECOMMENDED_MODELS_CACHE_PATH = join32(homedir28(), ".claudish", "recommended-models-cache.json");
43897
+ RECOMMENDED_MODELS_CACHE_PATH = join31(homedir28(), ".claudish", "recommended-models-cache.json");
44133
43898
  RECOMMENDED_ROUTE_TIER_ORDER = {
44134
43899
  native: 0,
44135
43900
  general: 1,
@@ -47697,7 +47462,7 @@ var init_DiscoveryNotice = __esm(() => {
47697
47462
  // src/providers/model-descriptions.ts
47698
47463
  import { existsSync as existsSync22, mkdirSync as mkdirSync13, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "fs";
47699
47464
  import { homedir as homedir29 } from "os";
47700
- import { dirname as dirname10, join as join33 } from "path";
47465
+ import { dirname as dirname10, join as join32 } from "path";
47701
47466
  function emptyDescriptionIndex() {
47702
47467
  return EMPTY_INDEX;
47703
47468
  }
@@ -47790,7 +47555,7 @@ var init_model_descriptions = __esm(() => {
47790
47555
  init_logger();
47791
47556
  init_model_loader();
47792
47557
  init_cache_ttl();
47793
- MODEL_DESCRIPTIONS_CACHE_PATH = join33(homedir29(), ".claudish", "model-descriptions.json");
47558
+ MODEL_DESCRIPTIONS_CACHE_PATH = join32(homedir29(), ".claudish", "model-descriptions.json");
47794
47559
  EMPTY_INDEX = { get: () => {
47795
47560
  return;
47796
47561
  }, size: 0 };
@@ -53728,22 +53493,22 @@ var init_branding = __esm(() => {
53728
53493
  // src/update-checker.ts
53729
53494
  import { existsSync as existsSync23, mkdirSync as mkdirSync14, readFileSync as readFileSync23, unlinkSync as unlinkSync6, writeFileSync as writeFileSync15 } from "fs";
53730
53495
  import { homedir as homedir30, platform as platform2, tmpdir } from "os";
53731
- import { join as join34 } from "path";
53496
+ import { join as join33 } from "path";
53732
53497
  function getCacheFilePath() {
53733
53498
  let cacheDir;
53734
53499
  if (isWindows) {
53735
- const localAppData = process.env.LOCALAPPDATA || join34(homedir30(), "AppData", "Local");
53736
- cacheDir = join34(localAppData, "claudish");
53500
+ const localAppData = process.env.LOCALAPPDATA || join33(homedir30(), "AppData", "Local");
53501
+ cacheDir = join33(localAppData, "claudish");
53737
53502
  } else {
53738
- cacheDir = join34(homedir30(), ".cache", "claudish");
53503
+ cacheDir = join33(homedir30(), ".cache", "claudish");
53739
53504
  }
53740
53505
  try {
53741
53506
  if (!existsSync23(cacheDir)) {
53742
53507
  mkdirSync14(cacheDir, { recursive: true });
53743
53508
  }
53744
- return join34(cacheDir, "update-check.json");
53509
+ return join33(cacheDir, "update-check.json");
53745
53510
  } catch {
53746
- return join34(tmpdir(), "claudish-update-check.json");
53511
+ return join33(tmpdir(), "claudish-update-check.json");
53747
53512
  }
53748
53513
  }
53749
53514
  function readCache2() {
@@ -58403,7 +58168,7 @@ var init_openrouter = __esm(() => {
58403
58168
  // src/services/pricing-cache.ts
58404
58169
  import { existsSync as existsSync24, readFileSync as readFileSync24, statSync as statSync6 } from "fs";
58405
58170
  import { homedir as homedir31 } from "os";
58406
- import { join as join35 } from "path";
58171
+ import { join as join34 } from "path";
58407
58172
  function prefixMatch(modelName) {
58408
58173
  for (const [key, pricing] of pricingMap) {
58409
58174
  if (modelName.startsWith(key))
@@ -58463,14 +58228,14 @@ var init_pricing_cache = __esm(() => {
58463
58228
  init_logger();
58464
58229
  init_catalog_query();
58465
58230
  pricingMap = new Map;
58466
- CACHE_DIR = join35(homedir31(), ".claudish");
58467
- CACHE_FILE = join35(CACHE_DIR, "pricing-cache.json");
58231
+ CACHE_DIR = join34(homedir31(), ".claudish");
58232
+ CACHE_FILE = join34(CACHE_DIR, "pricing-cache.json");
58468
58233
  CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
58469
58234
  });
58470
58235
 
58471
58236
  // src/proxy-server.ts
58472
58237
  import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync15 } from "fs";
58473
- import { join as join36 } from "path";
58238
+ import { join as join35 } from "path";
58474
58239
  function isTerminalRoutingFailure(e) {
58475
58240
  return e instanceof RoutingError;
58476
58241
  }
@@ -58478,7 +58243,7 @@ function maybeCaptureClassifierRequest(c, body) {
58478
58243
  if (!process.env.CLAUDISH_CLASSIFIER_DEBUG)
58479
58244
  return;
58480
58245
  try {
58481
- const dir = join36(process.cwd(), "logs");
58246
+ const dir = join35(process.cwd(), "logs");
58482
58247
  if (!classifierCaptureDirReady) {
58483
58248
  mkdirSync15(dir, { recursive: true });
58484
58249
  classifierCaptureDirReady = true;
@@ -58503,7 +58268,7 @@ function maybeCaptureClassifierRequest(c, body) {
58503
58268
  "x-api-key": c.req.header("x-api-key") ? "<present>" : null
58504
58269
  }
58505
58270
  };
58506
- appendFileSync7(join36(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
58271
+ appendFileSync7(join35(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
58507
58272
  `);
58508
58273
  } catch {}
58509
58274
  }
@@ -59052,13 +58817,13 @@ import {
59052
58817
  unlinkSync as unlinkSync7
59053
58818
  } from "fs";
59054
58819
  import { homedir as homedir32 } from "os";
59055
- import { dirname as dirname11, join as join37 } from "path";
58820
+ import { dirname as dirname11, join as join36 } from "path";
59056
58821
  import { fileURLToPath } from "url";
59057
58822
  function getVersion3() {
59058
58823
  return VERSION;
59059
58824
  }
59060
58825
  function clearAllModelCaches() {
59061
- const cacheDir = join37(homedir32(), ".claudish");
58826
+ const cacheDir = join36(homedir32(), ".claudish");
59062
58827
  if (!existsSync25(cacheDir))
59063
58828
  return;
59064
58829
  const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
@@ -59067,7 +58832,7 @@ function clearAllModelCaches() {
59067
58832
  const files = readdirSync4(cacheDir);
59068
58833
  for (const file of files) {
59069
58834
  if (cachePatterns.includes(file)) {
59070
- unlinkSync7(join37(cacheDir, file));
58835
+ unlinkSync7(join36(cacheDir, file));
59071
58836
  cleared++;
59072
58837
  }
59073
58838
  }
@@ -60601,7 +60366,7 @@ ${h("MORE INFO")}
60601
60366
  }
60602
60367
  function printAIAgentGuide() {
60603
60368
  try {
60604
- const guidePath = join37(__dirname2, "../AI_AGENT_GUIDE.md");
60369
+ const guidePath = join36(__dirname2, "../AI_AGENT_GUIDE.md");
60605
60370
  const guideContent = readFileSync25(guidePath, "utf-8");
60606
60371
  console.log(guideContent);
60607
60372
  } catch (error) {
@@ -60618,10 +60383,10 @@ async function initializeClaudishSkill() {
60618
60383
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
60619
60384
  `);
60620
60385
  const cwd = process.cwd();
60621
- const claudeDir = join37(cwd, ".claude");
60622
- const skillsDir = join37(claudeDir, "skills");
60623
- const claudishSkillDir = join37(skillsDir, "claudish-usage");
60624
- const skillFile = join37(claudishSkillDir, "SKILL.md");
60386
+ const claudeDir = join36(cwd, ".claude");
60387
+ const skillsDir = join36(claudeDir, "skills");
60388
+ const claudishSkillDir = join36(skillsDir, "claudish-usage");
60389
+ const skillFile = join36(claudishSkillDir, "SKILL.md");
60625
60390
  if (existsSync25(skillFile)) {
60626
60391
  console.log("\u2705 Claudish skill already installed at:");
60627
60392
  console.log(` ${skillFile}
@@ -60629,7 +60394,7 @@ async function initializeClaudishSkill() {
60629
60394
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
60630
60395
  return;
60631
60396
  }
60632
- const sourceSkillPath = join37(__dirname2, "../skills/claudish-usage/SKILL.md");
60397
+ const sourceSkillPath = join36(__dirname2, "../skills/claudish-usage/SKILL.md");
60633
60398
  if (!existsSync25(sourceSkillPath)) {
60634
60399
  console.error("\u274C Error: Claudish skill file not found in installation.");
60635
60400
  console.error(` Expected at: ${sourceSkillPath}`);
@@ -60819,16 +60584,16 @@ var init_cli = __esm(() => {
60819
60584
  // src/launcher/magmux-binary.ts
60820
60585
  import { execSync } from "child_process";
60821
60586
  import { existsSync as existsSync26 } from "fs";
60822
- import { dirname as dirname12, join as join38 } from "path";
60587
+ import { dirname as dirname12, join as join37 } from "path";
60823
60588
  import { fileURLToPath as fileURLToPath2 } from "url";
60824
60589
  function findMagmuxBinaryOrNull() {
60825
60590
  const thisFile = fileURLToPath2(import.meta.url);
60826
60591
  const thisDir = dirname12(thisFile);
60827
- const pkgRoots = [join38(thisDir, ".."), join38(thisDir, "..", "..")];
60592
+ const pkgRoots = [join37(thisDir, ".."), join37(thisDir, "..", "..")];
60828
60593
  const platform = process.platform;
60829
60594
  const arch = process.arch;
60830
60595
  for (const pkgRoot of pkgRoots) {
60831
- const bundled = join38(pkgRoot, "native", `magmux-${platform}-${arch}`);
60596
+ const bundled = join37(pkgRoot, "native", `magmux-${platform}-${arch}`);
60832
60597
  if (existsSync26(bundled))
60833
60598
  return bundled;
60834
60599
  }
@@ -60836,7 +60601,7 @@ function findMagmuxBinaryOrNull() {
60836
60601
  const pkgName = `@claudish/magmux-${platform}-${arch}`;
60837
60602
  let searchDir = pkgRoots[0];
60838
60603
  for (let i = 0;i < 5; i++) {
60839
- const candidate = join38(searchDir, "node_modules", pkgName, "bin", "magmux");
60604
+ const candidate = join37(searchDir, "node_modules", pkgName, "bin", "magmux");
60840
60605
  if (existsSync26(candidate))
60841
60606
  return candidate;
60842
60607
  const parent = dirname12(searchDir);
@@ -60873,7 +60638,7 @@ import {
60873
60638
  writeFileSync as writeFileSync16
60874
60639
  } from "fs";
60875
60640
  import { connect as netConnect } from "net";
60876
- import { join as join39 } from "path";
60641
+ import { join as join38 } from "path";
60877
60642
  function envDeltas(parentEnv, childEnv) {
60878
60643
  const set = [];
60879
60644
  const unset = [];
@@ -60939,9 +60704,9 @@ function planMagmuxWrap(input) {
60939
60704
  const controlSocket = `/tmp/magmux-${id}.sock`;
60940
60705
  const tmpRoot = input.tmpRoot ?? "/tmp";
60941
60706
  mkdirSync17(tmpRoot, { recursive: true });
60942
- const scriptDir = mkdtempSync(join39(tmpRoot, "claudish-launch-"));
60707
+ const scriptDir = mkdtempSync(join38(tmpRoot, "claudish-launch-"));
60943
60708
  chmodSync(scriptDir, 448);
60944
- const scriptPath = join39(scriptDir, "claude-launch.sh");
60709
+ const scriptPath = join38(scriptDir, "claude-launch.sh");
60945
60710
  const parentEnv = input.parentEnv ?? process.env;
60946
60711
  const deltas = envDeltas(parentEnv, input.childEnv);
60947
60712
  const fd = openSync6(scriptPath, "wx", 384);
@@ -61070,7 +60835,7 @@ var CLAUDISH_BIN_ENV = "CLAUDISH_BIN";
61070
60835
  // src/pane/process-identity.ts
61071
60836
  import { execFile, execFileSync as execFileSync2 } from "child_process";
61072
60837
  import { lstatSync } from "fs";
61073
- import { basename, dirname as dirname13, join as join40 } from "path";
60838
+ import { basename, dirname as dirname13, join as join39 } from "path";
61074
60839
  function collapse(s) {
61075
60840
  return s.trim().replace(/\s+/g, " ");
61076
60841
  }
@@ -61251,16 +61016,16 @@ function isValidPaneId(id) {
61251
61016
  return PANE_ID_RE.test(id) && !/^\d+$/.test(id);
61252
61017
  }
61253
61018
  function sockPathOf(root, paneId) {
61254
- return join40(root, `magmux-${paneId}.sock`);
61019
+ return join39(root, `magmux-${paneId}.sock`);
61255
61020
  }
61256
61021
  function recordPathOf(root, paneId) {
61257
- return join40(root, "panes", `${paneId}.json`);
61022
+ return join39(root, "panes", `${paneId}.json`);
61258
61023
  }
61259
61024
  function isPaneSockPath(root, p, paneId) {
61260
61025
  return isValidPaneId(paneId) && dirname13(p) === root && basename(p) === `magmux-${paneId}.sock`;
61261
61026
  }
61262
61027
  function isPaneRecordPath(root, p, paneId) {
61263
- return isValidPaneId(paneId) && dirname13(p) === join40(root, "panes") && basename(p) === `${paneId}.json`;
61028
+ return isValidPaneId(paneId) && dirname13(p) === join39(root, "panes") && basename(p) === `${paneId}.json`;
61264
61029
  }
61265
61030
  function watcherArgv(a) {
61266
61031
  return [
@@ -61361,7 +61126,7 @@ var init_process_identity = __esm(() => {
61361
61126
  import { execFile as execFile2, spawn } from "child_process";
61362
61127
  import { randomBytes as randomBytes7 } from "crypto";
61363
61128
  import { chmodSync as chmodSync2, lstatSync as lstatSync2, mkdirSync as mkdirSync18, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync17 } from "fs";
61364
- import { join as join41, resolve as resolve3 } from "path";
61129
+ import { join as join40, resolve as resolve3 } from "path";
61365
61130
  import { promisify as promisify5 } from "util";
61366
61131
  function uid() {
61367
61132
  return typeof process.getuid === "function" ? process.getuid() : 0;
@@ -61390,7 +61155,7 @@ function ensureSockRoot(given = sockRootFor()) {
61390
61155
  throw e;
61391
61156
  }
61392
61157
  assertPrivateDir(root);
61393
- const panes = join41(root, "panes");
61158
+ const panes = join40(root, "panes");
61394
61159
  try {
61395
61160
  mkdirSync18(panes, { mode: 448 });
61396
61161
  } catch (e) {
@@ -61445,7 +61210,7 @@ function buildPaneEnv(input) {
61445
61210
  if ((input.platform ?? process.platform) === "linux" && entryBytes > LINUX_ENV_STRING_LIMIT)
61446
61211
  throw new PaneEnvTooLargeError(`pane environment snapshot is ${entryBytes} bytes, over Linux's 131072-byte limit per variable`);
61447
61212
  env[ENV.CLAUDISH_PANE_ENV] = json;
61448
- env.SHELL = join41(input.ctlDir, "sh-shim");
61213
+ env.SHELL = join40(input.ctlDir, "sh-shim");
61449
61214
  return { magmuxEnv: env };
61450
61215
  }
61451
61216
  function buildClaudishPaneArgv(spawnModel, sessionUuid, turnDir, callerFlags) {
@@ -61591,21 +61356,21 @@ exec ${words}
61591
61356
  `;
61592
61357
  }
61593
61358
  function paneCommand(ctlDir) {
61594
- const cmd = `. ${shq2(join41(ctlDir, "pane-launch.sh"))}`;
61359
+ const cmd = `. ${shq2(join40(ctlDir, "pane-launch.sh"))}`;
61595
61360
  if (/claude /.test(cmd) || /claude$/.test(cmd) || /(^|\/)claude['"]?$/.test(cmd))
61596
61361
  throw new Error(`pane command would attach magmux's Claude Code controller: ${cmd}`);
61597
61362
  return cmd;
61598
61363
  }
61599
61364
  function createLaunchDirs(root) {
61600
- const ctlDir = mkdtempSync2(join41(root, "launch-"));
61365
+ const ctlDir = mkdtempSync2(join40(root, "launch-"));
61601
61366
  chmodSync2(ctlDir, 448);
61602
- const turnDir = mkdtempSync2(join41(root, "launch-"));
61367
+ const turnDir = mkdtempSync2(join40(root, "launch-"));
61603
61368
  chmodSync2(turnDir, 448);
61604
61369
  return { ctlDir, turnDir };
61605
61370
  }
61606
61371
  function writeLauncherFiles(ctlDir, script) {
61607
- writeFileSync17(join41(ctlDir, "pane-launch.sh"), script, { mode: 384, flag: "wx" });
61608
- writeFileSync17(join41(ctlDir, "sh-shim"), SHELL_SHIM, { mode: 448, flag: "wx" });
61372
+ writeFileSync17(join40(ctlDir, "pane-launch.sh"), script, { mode: 384, flag: "wx" });
61373
+ writeFileSync17(join40(ctlDir, "sh-shim"), SHELL_SHIM, { mode: 448, flag: "wx" });
61609
61374
  }
61610
61375
  function spawnPaneWatcher(args) {
61611
61376
  const proc = spawn("/bin/sh", watcherArgv(args), {
@@ -61983,7 +61748,7 @@ import {
61983
61748
  unlinkSync as unlinkSync8,
61984
61749
  writeFileSync as writeFileSync18
61985
61750
  } from "fs";
61986
- import { join as join42 } from "path";
61751
+ import { join as join41 } from "path";
61987
61752
  function ownerStartOfSelf() {
61988
61753
  if (ownStart)
61989
61754
  return ownStart;
@@ -61996,7 +61761,7 @@ function ownerAlive(rec, table) {
61996
61761
  return !!row && row.lstart === rec.ownerStart;
61997
61762
  }
61998
61763
  function recordsDir(root) {
61999
- return join42(root, "panes");
61764
+ return join41(root, "panes");
62000
61765
  }
62001
61766
  function writeRecord(root, rec) {
62002
61767
  const p = recordPathOf(root, rec.paneId);
@@ -62066,13 +61831,13 @@ function readRecords(root) {
62066
61831
  }
62067
61832
  function readGroupFile(ctlDir) {
62068
61833
  try {
62069
- return parseGroupFile(readFileSync26(join42(ctlDir, "group"), "utf8"));
61834
+ return parseGroupFile(readFileSync26(join41(ctlDir, "group"), "utf8"));
62070
61835
  } catch {
62071
61836
  return null;
62072
61837
  }
62073
61838
  }
62074
61839
  function writeGroupFile(ctlDir, snap) {
62075
- const p = join42(ctlDir, "group");
61840
+ const p = join41(ctlDir, "group");
62076
61841
  const tmp = `${p}.tmp`;
62077
61842
  try {
62078
61843
  writeFileSync18(tmp, formatGroupFile(snap), { mode: 384 });
@@ -62284,7 +62049,7 @@ async function sweepRecordlessSocket(root, name, out) {
62284
62049
  const table = readProcessTable();
62285
62050
  if (ownerOfIdAlive(id, table))
62286
62051
  return;
62287
- const sockPath = join42(root, name);
62052
+ const sockPath = join41(root, name);
62288
62053
  let client = null;
62289
62054
  try {
62290
62055
  client = await MagmuxClient.dial(sockPath);
@@ -62855,7 +62620,7 @@ import {
62855
62620
  realpathSync as realpathSync2,
62856
62621
  statSync as statSync7
62857
62622
  } from "fs";
62858
- import { join as join43 } from "path";
62623
+ import { join as join42 } from "path";
62859
62624
  function initialFollowerState(resolvePath = safeRealpath) {
62860
62625
  return {
62861
62626
  turns: [],
@@ -63361,7 +63126,7 @@ class TranscriptFollower {
63361
63126
  for (const f of this.subagentFiles()) {
63362
63127
  let tail = this.subs.get(f);
63363
63128
  if (!tail) {
63364
- tail = new Tail(join43(this.subagentsDir, f));
63129
+ tail = new Tail(join42(this.subagentsDir, f));
63365
63130
  this.subs.set(f, tail);
63366
63131
  }
63367
63132
  for (const { line } of tail.read()) {
@@ -63444,7 +63209,7 @@ var init_transcript_follower = __esm(() => {
63444
63209
 
63445
63210
  // src/pane/pane-session.ts
63446
63211
  import { readFileSync as readFileSync27, realpathSync as realpathSync3, rmSync as rmSync4, statSync as statSync8, writeFileSync as writeFileSync19 } from "fs";
63447
- import { join as join44 } from "path";
63212
+ import { join as join43 } from "path";
63448
63213
  function iso(ms) {
63449
63214
  return new Date(ms).toISOString();
63450
63215
  }
@@ -63546,7 +63311,7 @@ class PaneSessionImpl {
63546
63311
  this.queue.push(o.initialPrompt);
63547
63312
  this.secondaryQuietMs = o.timings?.secondaryQuietMs ?? SECONDARY_QUIET_MS;
63548
63313
  this.corroborationMs = o.timings?.corroborationMs ?? CORROBORATION_MS;
63549
- this.follower = new TranscriptFollower(o.transcriptPath, join44(o.transcriptPath.replace(/\.jsonl$/, ""), "subagents"));
63314
+ this.follower = new TranscriptFollower(o.transcriptPath, join43(o.transcriptPath.replace(/\.jsonl$/, ""), "subagents"));
63550
63315
  this.ready = new Promise((r) => {
63551
63316
  this.resolveReady = r;
63552
63317
  });
@@ -63587,7 +63352,7 @@ class PaneSessionImpl {
63587
63352
  return this.spawnFailed(new Error("magmux did not start"));
63588
63353
  this.magmux = proc;
63589
63354
  try {
63590
- writeFileSync19(join44(this.ctlDir, "magmux.pid"), `${proc.pid}
63355
+ writeFileSync19(join43(this.ctlDir, "magmux.pid"), `${proc.pid}
63591
63356
  `, { mode: 384 });
63592
63357
  } catch {}
63593
63358
  updateRecord(this.root, this.paneId, { magmuxPid: proc.pid });
@@ -64872,6 +64637,64 @@ var init_pane = __esm(() => {
64872
64637
  init_contract();
64873
64638
  });
64874
64639
 
64640
+ // src/channel/parent-session.ts
64641
+ import { readFile as readFile4 } from "fs/promises";
64642
+ import { join as join44 } from "path";
64643
+ function positiveInt(value) {
64644
+ if (value === undefined || !/^[1-9][0-9]*$/.test(value))
64645
+ return;
64646
+ const n = Number(value);
64647
+ return Number.isSafeInteger(n) ? n : undefined;
64648
+ }
64649
+ function hostPidFrom(env, ppid) {
64650
+ const launcherPpid = positiveInt(env.CLAUDISH_LAUNCHER_PPID);
64651
+ if (env.CLAUDISH_LAUNCHER_PID === String(ppid) && launcherPpid !== undefined && launcherPpid !== ppid) {
64652
+ return { hostPid: launcherPpid, launcherPid: ppid };
64653
+ }
64654
+ return { hostPid: ppid };
64655
+ }
64656
+ function parentSessionIdFrom(env) {
64657
+ const id = env.CLAUDE_CODE_SESSION_ID;
64658
+ if (id === undefined || !CLAUDE_ID_RE.test(id))
64659
+ return;
64660
+ if (env.CLAUDE_CODE_CHILD_SESSION)
64661
+ return;
64662
+ return id;
64663
+ }
64664
+ function claudeConfigDir(env) {
64665
+ const fromEnv = env.CLAUDE_CONFIG_DIR;
64666
+ return fromEnv && fromEnv.length > 0 ? fromEnv : join44(userHomeFrom(env), ".claude");
64667
+ }
64668
+ async function readHostSessionRecord(opts) {
64669
+ try {
64670
+ const raw = await readFile4(join44(opts.configDir, "sessions", `${opts.hostPid}.json`), "utf-8");
64671
+ const parsed = JSON.parse(raw);
64672
+ if (!parsed || typeof parsed !== "object")
64673
+ return;
64674
+ const rec = parsed;
64675
+ if (rec.pid !== opts.hostPid)
64676
+ return;
64677
+ if (typeof rec.sessionId !== "string" || !CLAUDE_ID_RE.test(rec.sessionId))
64678
+ return;
64679
+ return { sessionId: rec.sessionId };
64680
+ } catch {
64681
+ return;
64682
+ }
64683
+ }
64684
+ async function parentSessionForCall(opts) {
64685
+ const env = opts.env ?? process.env;
64686
+ const record = await readHostSessionRecord({
64687
+ configDir: claudeConfigDir(env),
64688
+ hostPid: opts.hostPid
64689
+ });
64690
+ return record?.sessionId ?? parentSessionIdFrom(env);
64691
+ }
64692
+ var CLAUDE_ID_RE;
64693
+ var init_parent_session = __esm(() => {
64694
+ init_home_dir();
64695
+ CLAUDE_ID_RE = /^[A-Za-z0-9_-]{8,128}$/;
64696
+ });
64697
+
64875
64698
  // src/session/session-discovery.ts
64876
64699
  var exports_session_discovery = {};
64877
64700
  __export(exports_session_discovery, {
@@ -65320,7 +65143,8 @@ function findLatestSessionId(cwd = process.cwd(), sinceMs = 0) {
65320
65143
  }
65321
65144
  var ENTRYPOINT_BYTES = 8192, ACTIVE_WINDOW_MS = 120000, HEAD_BYTES, TAIL_BYTES, HARNESS_ENVELOPES, DEEP_TAIL_BYTES, RECENT_AI_TURNS = 5, RECENT_USER_TURNS = 1;
65322
65145
  var init_session_discovery = __esm(() => {
65323
- init_parent_proof();
65146
+ init_home_dir();
65147
+ init_parent_session();
65324
65148
  HEAD_BYTES = 64 * 1024;
65325
65149
  TAIL_BYTES = 128 * 1024;
65326
65150
  HARNESS_ENVELOPES = [
@@ -67625,7 +67449,7 @@ var init_session_manager = __esm(() => {
67625
67449
  init_team_orchestrator();
67626
67450
  init_team_stats();
67627
67451
  init_home_dir();
67628
- init_parent_proof();
67452
+ init_parent_session();
67629
67453
  init_scrollback_buffer();
67630
67454
  TERMINAL_RETENTION_MS = 30 * 60000;
67631
67455
  EVENT_LOG_LIMIT = 4 * 1024 * 1024;
@@ -68638,8 +68462,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
68638
68462
  requirePattern
68639
68463
  });
68640
68464
  setupSession(resolved, models, input);
68641
- const parentClaudeSessionId = await proveParentForCall({
68642
- toolUseId: ctx.toolUseId,
68465
+ const parentClaudeSessionId = await parentSessionForCall({
68643
68466
  hostPid: sessionManager.hostPid
68644
68467
  });
68645
68468
  const monitorRecord = sessionManager.recordTeamRun({
@@ -68925,7 +68748,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
68925
68748
  required: ["model"]
68926
68749
  },
68927
68750
  group: "channel",
68928
- handler: async (args, ctx) => {
68751
+ handler: async (args) => {
68929
68752
  try {
68930
68753
  const claudishFlags = buildChildClaudeFlags(args.agent, args.claude_flags) ?? [];
68931
68754
  const flagCheck = checkChildFlags(claudishFlags);
@@ -68937,8 +68760,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
68937
68760
  const plan = await prehydrateCredentialsForSpawn([requestedModel], {
68938
68761
  pin: workDir === undefined || resolve6(workDir) === process.cwd()
68939
68762
  });
68940
- const parentClaudeSessionId = await proveParentForCall({
68941
- toolUseId: ctx.toolUseId,
68763
+ const parentClaudeSessionId = await parentSessionForCall({
68942
68764
  hostPid: sessionManager.hostPid
68943
68765
  });
68944
68766
  const sessionId = await sessionManager.createSession({
@@ -69251,10 +69073,8 @@ Call get_diagnostics with session_id: "${sessionId}" for the final screen, the u
69251
69073
  intervalMs: progressIntervalMs,
69252
69074
  send: (frame) => extra.sendNotification({ method: "notifications/progress", params: frame })
69253
69075
  }) : NOOP_HEARTBEAT;
69254
- const rawToolUseId = extra._meta?.[TOOL_USE_ID_META_KEY];
69255
69076
  const ctx = {
69256
- reportProgress: (message) => heartbeat.tick(message),
69257
- ...typeof rawToolUseId === "string" ? { toolUseId: rawToolUseId } : {}
69077
+ reportProgress: (message) => heartbeat.tick(message)
69258
69078
  };
69259
69079
  try {
69260
69080
  return await tool.handler(args ?? {}, ctx);
@@ -69332,7 +69152,7 @@ var init_mcp_server = __esm(() => {
69332
69152
  init_prehydrate();
69333
69153
  init_diagnostics();
69334
69154
  init_channel();
69335
- init_parent_proof();
69155
+ init_parent_session();
69336
69156
  init_remote_provider_types();
69337
69157
  init_progress_heartbeat();
69338
69158
  init_model_loader();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "10.4.0",
3
+ "version": "10.4.1",
4
4
  "description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -60,10 +60,10 @@
60
60
  "ai"
61
61
  ],
62
62
  "optionalDependencies": {
63
- "@claudish/magmux-darwin-arm64": "10.4.0",
64
- "@claudish/magmux-darwin-x64": "10.4.0",
65
- "@claudish/magmux-linux-arm64": "10.4.0",
66
- "@claudish/magmux-linux-x64": "10.4.0"
63
+ "@claudish/magmux-darwin-arm64": "10.4.1",
64
+ "@claudish/magmux-darwin-x64": "10.4.1",
65
+ "@claudish/magmux-linux-arm64": "10.4.1",
66
+ "@claudish/magmux-linux-x64": "10.4.1"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",