claudish 14.18.5 → 14.19.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 +1338 -553
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -5494,7 +5494,7 @@ var init_onepassword_config = __esm(() => {
5494
5494
  });
5495
5495
 
5496
5496
  // src/version.ts
5497
- var VERSION = "14.18.5";
5497
+ var VERSION = "14.19.0";
5498
5498
 
5499
5499
  // src/redact.ts
5500
5500
  function isPlaceholder(value) {
@@ -11600,6 +11600,22 @@ var init_profile_config = __esm(() => {
11600
11600
  };
11601
11601
  });
11602
11602
 
11603
+ // src/providers/context-window-limit.ts
11604
+ function parseContextWindow(text) {
11605
+ const match = /^(\d+(?:\.\d+)?)([km]?)$/i.exec(text.trim());
11606
+ if (!match)
11607
+ return;
11608
+ const size = Math.round(Number(match[1]) * (UNIT_TOKENS[match[2].toLowerCase()] ?? 1));
11609
+ return size > 0 ? size : undefined;
11610
+ }
11611
+ function contextWindowLimit() {
11612
+ return parseContextWindow(process.env.CLAUDISH_CONTEXT_WINDOW ?? "");
11613
+ }
11614
+ var DEFAULT_LOCAL_CONTEXT_WINDOW = 128000, UNIT_TOKENS;
11615
+ var init_context_window_limit = __esm(() => {
11616
+ UNIT_TOKENS = { "": 1, k: 1000, m: 1e6 };
11617
+ });
11618
+
11603
11619
  // src/providers/runtime-providers.ts
11604
11620
  function registerRuntimeProvider(def) {
11605
11621
  _runtimeProviders.set(def.name, def);
@@ -12294,6 +12310,9 @@ function findCacheEntry(modelId, cachePath) {
12294
12310
  if (modelId.startsWith("@"))
12295
12311
  return;
12296
12312
  if (modelId.includes("@")) {
12313
+ const prefix = modelId.slice(0, modelId.indexOf("@")).toLowerCase();
12314
+ if (getShortcuts()[prefix] === undefined && !getProviderByName(prefix))
12315
+ return;
12297
12316
  throw new Error(`model-catalog lookup received provider-routed ID "${modelId}" \u2014 callers must strip the "@" prefix before calling`);
12298
12317
  }
12299
12318
  const cache = readAllModelsCache(cachePath);
@@ -12387,6 +12406,7 @@ function searchCatalogModels(query, limit = 10, cachePath) {
12387
12406
  var init_model_catalog = __esm(() => {
12388
12407
  init_all_models_cache();
12389
12408
  init_catalog_route_bindings();
12409
+ init_provider_definitions();
12390
12410
  });
12391
12411
 
12392
12412
  // src/adapters/optional-param-rejection.ts
@@ -50065,6 +50085,440 @@ var init_connection_resolver = __esm(() => {
50065
50085
  init_connection_wire();
50066
50086
  });
50067
50087
 
50088
+ // src/providers/lmstudio-devices.ts
50089
+ import { execFile as execFile2 } from "child_process";
50090
+ import {
50091
+ linkSync as linkSync3,
50092
+ mkdirSync as mkdirSync16,
50093
+ readFileSync as readFileSync29,
50094
+ readdirSync as readdirSync4,
50095
+ renameSync as renameSync8,
50096
+ rmSync as rmSync10,
50097
+ rmdirSync,
50098
+ statSync as statSync9,
50099
+ writeFileSync as writeFileSync11
50100
+ } from "fs";
50101
+ import { homedir as homedir28 } from "os";
50102
+ import { basename as basename2, dirname as dirname14, join as join29 } from "path";
50103
+ function execLms(binary, args, timeoutMs) {
50104
+ return new Promise((resolve) => {
50105
+ execFile2(binary, args, { timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
50106
+ resolve({
50107
+ stdout: error ? null : stdout,
50108
+ missing: error?.code === "ENOENT"
50109
+ });
50110
+ });
50111
+ });
50112
+ }
50113
+ function splitLMStudioDevice(modelId) {
50114
+ const at = modelId.lastIndexOf(LMSTUDIO_DEVICE_SEPARATOR);
50115
+ if (at <= 0 || at === modelId.length - 1)
50116
+ return { model: modelId };
50117
+ return { model: modelId.slice(0, at), device: modelId.slice(at + 1) };
50118
+ }
50119
+ function isLoopbackUrl(url) {
50120
+ try {
50121
+ const host = new URL(url).hostname;
50122
+ return host === "localhost" || host === "127.0.0.1" || host === "[::1]" || host === "::1";
50123
+ } catch {
50124
+ return false;
50125
+ }
50126
+ }
50127
+ function parseJson(text) {
50128
+ if (text === null)
50129
+ return null;
50130
+ try {
50131
+ return JSON.parse(text);
50132
+ } catch {
50133
+ return null;
50134
+ }
50135
+ }
50136
+ async function readLink(run) {
50137
+ const raw = parseJson(await run(["link", "status", "--json"], LIST_TIMEOUT_MS));
50138
+ if (!raw?.deviceIdentifier)
50139
+ return null;
50140
+ const peers = [];
50141
+ for (const peer of raw.peers ?? []) {
50142
+ if (peer.status === "connected" && peer.deviceIdentifier && peer.deviceName) {
50143
+ peers.push({ id: peer.deviceIdentifier, name: peer.deviceName });
50144
+ }
50145
+ }
50146
+ return { self: raw.deviceIdentifier, preferred: raw.preferredDeviceIdentifier, peers };
50147
+ }
50148
+ async function readLoaded(run) {
50149
+ return parseJson(await run(["ps", "--json"], LIST_TIMEOUT_MS));
50150
+ }
50151
+ function machineLabel(peer) {
50152
+ return /^[\w. -]+$/.test(peer.name) ? peer.name : peer.id;
50153
+ }
50154
+ async function readLMStudioMachines(run = runLms) {
50155
+ const [link, stored, loaded] = await Promise.all([
50156
+ readLink(run),
50157
+ run(["ls", "--json"], LIST_TIMEOUT_MS).then((text) => parseJson(text)),
50158
+ readLoaded(run)
50159
+ ]);
50160
+ if (!link || link.peers.length === 0 || !Array.isArray(stored))
50161
+ return null;
50162
+ const labelOf = (device) => {
50163
+ if (device === null || device === link.self)
50164
+ return LMSTUDIO_THIS_MACHINE;
50165
+ const peer = link.peers.find((p) => p.id === device);
50166
+ return peer ? machineLabel(peer) : undefined;
50167
+ };
50168
+ const labelsByModel = new Map;
50169
+ const maxWindows = new Map;
50170
+ for (const copy of stored) {
50171
+ const label = labelOf(copy.deviceIdentifier);
50172
+ if (!label)
50173
+ continue;
50174
+ if (copy.maxContextLength) {
50175
+ maxWindows.set(`${copy.modelKey}${LMSTUDIO_DEVICE_SEPARATOR}${label}`, copy.maxContextLength);
50176
+ }
50177
+ const labels = labelsByModel.get(copy.modelKey) ?? [];
50178
+ if (!labels.includes(label))
50179
+ labels.push(label);
50180
+ labelsByModel.set(copy.modelKey, labels);
50181
+ }
50182
+ for (const labels of labelsByModel.values()) {
50183
+ labels.sort((a, b) => Number(b === LMSTUDIO_THIS_MACHINE) - Number(a === LMSTUDIO_THIS_MACHINE));
50184
+ }
50185
+ const loadedWindows = new Map;
50186
+ for (const row of Array.isArray(loaded) ? loaded : []) {
50187
+ const label = labelOf(row.deviceIdentifier);
50188
+ if (label && row.modelKey && row.contextLength) {
50189
+ loadedWindows.set(`${row.modelKey}${LMSTUDIO_DEVICE_SEPARATOR}${label}`, row.contextLength);
50190
+ }
50191
+ }
50192
+ return { labelsByModel, loadedWindows, maxWindows };
50193
+ }
50194
+ function expandModelsToMachines(models, machines, defaultWindow) {
50195
+ return models.flatMap((model) => {
50196
+ const labels = machines.labelsByModel.get(model.id);
50197
+ if (!labels)
50198
+ return [model];
50199
+ return labels.map((label) => {
50200
+ const id = `${model.id}${LMSTUDIO_DEVICE_SEPARATOR}${label}`;
50201
+ const max = machines.maxWindows.get(id);
50202
+ const ceiling = defaultWindow && max && max < defaultWindow ? max : undefined;
50203
+ const loaded = machines.loadedWindows.get(id);
50204
+ const name = label === LMSTUDIO_THIS_MACHINE ? THIS_MACHINE_NAME : label;
50205
+ return {
50206
+ ...model,
50207
+ id,
50208
+ displayName: `${model.displayName ?? model.id} (${name})`,
50209
+ machine: { name, modelId: model.id },
50210
+ contextWindow: loaded ?? ceiling,
50211
+ maxContextWindow: loaded ?? max,
50212
+ contextCeiling: loaded ?? max ?? model.contextCeiling
50213
+ };
50214
+ });
50215
+ });
50216
+ }
50217
+ function defaultLockPath2() {
50218
+ return join29(homedir28(), ".claudish", "lmstudio-machine.lock");
50219
+ }
50220
+ function lookAtLock(lockPath) {
50221
+ const identity = lockIdentity(lockPath);
50222
+ if (identity === undefined)
50223
+ return;
50224
+ let owner = "";
50225
+ try {
50226
+ owner = readFileSync29(join29(lockPath, "owner"), "utf-8");
50227
+ } catch {}
50228
+ const pid = Number.parseInt(owner, 10);
50229
+ if (!Number.isInteger(pid) || pid <= 0) {
50230
+ try {
50231
+ return { alive: Date.now() - statSync9(lockPath).mtimeMs < LOAD_TIMEOUT_MS2, identity };
50232
+ } catch {
50233
+ return;
50234
+ }
50235
+ }
50236
+ return { alive: pidAlive(pid), identity };
50237
+ }
50238
+ function pidAlive(pid) {
50239
+ try {
50240
+ process.kill(pid, 0);
50241
+ return true;
50242
+ } catch (error) {
50243
+ return error.code === "EPERM";
50244
+ }
50245
+ }
50246
+ function lockIdentity(path) {
50247
+ let stats;
50248
+ try {
50249
+ stats = statSync9(path);
50250
+ } catch {
50251
+ return;
50252
+ }
50253
+ let owner = "";
50254
+ try {
50255
+ owner = readFileSync29(join29(path, "owner"), "utf-8");
50256
+ } catch {}
50257
+ return `${stats.ino}:${stats.birthtimeMs}:${owner}`;
50258
+ }
50259
+ function takeOverStaleLock(lockPath, identity) {
50260
+ const entry = makeClaim(join29(lockPath, CLAIM));
50261
+ if (entry === undefined)
50262
+ return false;
50263
+ if (lockIdentity(lockPath) !== identity) {
50264
+ rmSync10(entry, { force: true });
50265
+ try {
50266
+ rmdirSync(dirname14(entry));
50267
+ } catch {}
50268
+ return false;
50269
+ }
50270
+ const aside = `${lockPath}.dead.${process.pid}.${Math.random().toString(36).slice(2)}`;
50271
+ try {
50272
+ renameSync8(lockPath, aside);
50273
+ } catch {
50274
+ return false;
50275
+ }
50276
+ rmSync10(aside, { recursive: true, force: true });
50277
+ return true;
50278
+ }
50279
+ function makeClaim(claim) {
50280
+ try {
50281
+ mkdirSync16(claim);
50282
+ } catch (error) {
50283
+ if (error.code !== "EEXIST")
50284
+ return;
50285
+ }
50286
+ const draft = `${claim}.${process.pid}.${Math.random().toString(36).slice(2)}`;
50287
+ try {
50288
+ writeFileSync11(draft, String(process.pid));
50289
+ let name = "pid";
50290
+ for (let step = 0;step < MAX_CLAIM_CHAIN; step++) {
50291
+ const entry = join29(claim, name);
50292
+ try {
50293
+ linkSync3(draft, entry);
50294
+ return entry;
50295
+ } catch (error) {
50296
+ if (error.code !== "EEXIST")
50297
+ return;
50298
+ }
50299
+ const holder = entryPid(entry);
50300
+ if (holder === undefined)
50301
+ return;
50302
+ if (holder === process.pid)
50303
+ return entry;
50304
+ if (pidAlive(holder))
50305
+ return;
50306
+ name = `after-${holder}`;
50307
+ }
50308
+ return;
50309
+ } catch {
50310
+ return;
50311
+ } finally {
50312
+ rmSync10(draft, { force: true });
50313
+ }
50314
+ }
50315
+ function entryPid(entry) {
50316
+ try {
50317
+ const pid = Number.parseInt(readFileSync29(entry, "utf-8"), 10);
50318
+ return Number.isInteger(pid) && pid > 0 ? pid : undefined;
50319
+ } catch {
50320
+ return;
50321
+ }
50322
+ }
50323
+ function removeAbandonedCopies(lockPath) {
50324
+ const prefix = `${basename2(lockPath)}.dead.`;
50325
+ let names;
50326
+ try {
50327
+ names = readdirSync4(dirname14(lockPath));
50328
+ } catch {
50329
+ return;
50330
+ }
50331
+ for (const name of names) {
50332
+ if (!name.startsWith(prefix))
50333
+ continue;
50334
+ const pid = Number.parseInt(name.slice(prefix.length), 10);
50335
+ if (!Number.isInteger(pid) || pid <= 0 || pidAlive(pid))
50336
+ continue;
50337
+ rmSync10(join29(dirname14(lockPath), name), { recursive: true, force: true });
50338
+ }
50339
+ }
50340
+ function signLock(lockPath) {
50341
+ const draft = join29(lockPath, `owner.${process.pid}`);
50342
+ writeFileSync11(draft, String(process.pid));
50343
+ renameSync8(draft, join29(lockPath, "owner"));
50344
+ }
50345
+ async function withMachineLock(lockPath, pollMs, work) {
50346
+ mkdirSync16(dirname14(lockPath), { recursive: true });
50347
+ removeAbandonedCopies(lockPath);
50348
+ const deadline = Date.now() + LOAD_TIMEOUT_MS2 + LIST_TIMEOUT_MS;
50349
+ for (;; ) {
50350
+ try {
50351
+ mkdirSync16(lockPath);
50352
+ break;
50353
+ } catch (error) {
50354
+ if (error.code !== "EEXIST")
50355
+ throw error;
50356
+ }
50357
+ const look = lookAtLock(lockPath);
50358
+ if (look === undefined)
50359
+ continue;
50360
+ if (!look.alive && takeOverStaleLock(lockPath, look.identity))
50361
+ continue;
50362
+ if (Date.now() > deadline) {
50363
+ throw new Error(`Another claudish process is placing an LM Studio model (lock ${lockPath}). Retry when it finishes.`);
50364
+ }
50365
+ await new Promise((resolve) => setTimeout(resolve, pollMs));
50366
+ }
50367
+ let own;
50368
+ try {
50369
+ signLock(lockPath);
50370
+ own = lockIdentity(lockPath);
50371
+ return await work();
50372
+ } finally {
50373
+ if (own === undefined || lockIdentity(lockPath) === own) {
50374
+ rmSync10(lockPath, { recursive: true, force: true });
50375
+ }
50376
+ }
50377
+ }
50378
+ function serialized(work) {
50379
+ const result = machineQueue.then(work, work);
50380
+ machineQueue = result.catch(() => {
50381
+ return;
50382
+ });
50383
+ return result;
50384
+ }
50385
+ function requireMachine(link, device) {
50386
+ const wanted = device.toLowerCase();
50387
+ if (wanted === LMSTUDIO_THIS_MACHINE)
50388
+ return link.self;
50389
+ const peer = link.peers.find((p) => p.id.toLowerCase() === wanted || machineLabel(p).toLowerCase() === wanted);
50390
+ if (peer)
50391
+ return peer.id;
50392
+ const known = [LMSTUDIO_THIS_MACHINE, ...link.peers.map(machineLabel)].join(", ");
50393
+ throw new Error(`LM Studio machine "${device}" is not connected through LM Link. Connected: ${known}.`);
50394
+ }
50395
+ function loadContextLength(stored, model, device, link, wanted) {
50396
+ if (wanted === undefined)
50397
+ return;
50398
+ const copy = stored?.find((row) => row.modelKey === model && (row.deviceIdentifier ?? link.self) === device);
50399
+ return copy?.maxContextLength ? Math.min(wanted, copy.maxContextLength) : wanted;
50400
+ }
50401
+ function assertContextLength(identifier, actual, wanted) {
50402
+ if (wanted === undefined || actual === undefined || actual >= wanted)
50403
+ return;
50404
+ throw new Error(`LM Studio runs ${identifier} with ${actual} tokens of context and claudish needs ${wanted}. Reload it with more context in LM Studio, or pass --context-window ${actual} to accept this size.`);
50405
+ }
50406
+ function ambiguityError(identifier) {
50407
+ return new Error(`LM Studio has instances named ${identifier} on more than one machine, so a request cannot select one. Unload one of them in LM Studio.`);
50408
+ }
50409
+ async function ensureLMStudioInstance(options) {
50410
+ const {
50411
+ baseUrl,
50412
+ model,
50413
+ device,
50414
+ headers,
50415
+ contextLength,
50416
+ run = runLms,
50417
+ log,
50418
+ lockPath = defaultLockPath2(),
50419
+ lockPollMs = LOCK_POLL_MS2
50420
+ } = options;
50421
+ if (!isLoopbackUrl(baseUrl)) {
50422
+ throw new Error(`LM Studio at ${baseUrl} is on another host, so claudish cannot choose the machine "${device}" there. Remove the ~${device} suffix.`);
50423
+ }
50424
+ return serialized(() => withMachineLock(lockPath, lockPollMs, async () => {
50425
+ const link = await readLink(run);
50426
+ if (!link)
50427
+ throw new Error("Could not read LM Link status: `lms link status --json` failed.");
50428
+ const target = requireMachine(link, device);
50429
+ const isOnTarget = (row) => (row.deviceIdentifier ?? link.self) === target;
50430
+ const isThisMachine = target === link.self;
50431
+ const identifier = isThisMachine ? `${model}${LMSTUDIO_DEVICE_SEPARATOR}${LMSTUDIO_THIS_MACHINE}` : model;
50432
+ const before = await readLoaded(run);
50433
+ if (!before)
50434
+ throw listError();
50435
+ const hasNamesake = (name) => before.some((row) => row.identifier === name && !isOnTarget(row));
50436
+ const stored = parseJson(await run(["ls", "--json"], LIST_TIMEOUT_MS));
50437
+ const length = loadContextLength(stored, model, target, link, contextLength);
50438
+ const running = before.find((row) => row.modelKey === model && isOnTarget(row));
50439
+ if (running) {
50440
+ if (hasNamesake(running.identifier))
50441
+ throw ambiguityError(running.identifier);
50442
+ assertContextLength(running.identifier, running.contextLength, length);
50443
+ return { instanceId: running.identifier, contextLength: running.contextLength };
50444
+ }
50445
+ if (hasNamesake(identifier))
50446
+ throw ambiguityError(identifier);
50447
+ let expected = identifier;
50448
+ if (isThisMachine) {
50449
+ const lengthArgs = length === undefined ? [] : ["-c", String(length)];
50450
+ const loaded = await run(["load", model, "--identifier", identifier, "-y", ...lengthArgs], LOAD_TIMEOUT_MS2);
50451
+ if (loaded === null)
50452
+ throw new Error(`LM Studio could not load ${model} on this machine.`);
50453
+ } else {
50454
+ const reported = await loadOnLinkedMachine({ baseUrl, model, device, headers, run, log }, link, target, length);
50455
+ expected = reported ?? identifier;
50456
+ }
50457
+ const after = await readLoaded(run);
50458
+ if (!after)
50459
+ throw listError();
50460
+ const placed = after.find((row) => row.identifier === expected && isOnTarget(row));
50461
+ if (!placed) {
50462
+ throw new Error(`LM Studio loaded ${model} on a different machine than ${device}. Another LM Link client may have changed the preferred device; retry.`);
50463
+ }
50464
+ if (after.some((row) => row.identifier === expected && !isOnTarget(row))) {
50465
+ throw ambiguityError(expected);
50466
+ }
50467
+ assertContextLength(placed.identifier, placed.contextLength, length);
50468
+ return { instanceId: placed.identifier, contextLength: placed.contextLength };
50469
+ }));
50470
+ }
50471
+ function listError() {
50472
+ return new Error("Could not list the running LM Studio instances: `lms ps --json` failed. Without that list claudish cannot tell which machine a model name reaches.");
50473
+ }
50474
+ async function loadOnLinkedMachine(options, link, target, contextLength) {
50475
+ const { baseUrl, model, device, headers, run, log } = options;
50476
+ const original = link.preferred;
50477
+ const mustSwitch = original !== target;
50478
+ if (mustSwitch) {
50479
+ const switched = await run(["link", "set-preferred-device", target], LIST_TIMEOUT_MS);
50480
+ if (switched === null)
50481
+ throw new Error(`Could not select LM Link device ${device}.`);
50482
+ }
50483
+ try {
50484
+ const response = await fetch(`${baseUrl}/api/v1/models/load`, {
50485
+ method: "POST",
50486
+ headers: { "Content-Type": "application/json", ...headers },
50487
+ body: JSON.stringify({
50488
+ model,
50489
+ ...contextLength === undefined ? {} : { context_length: contextLength }
50490
+ }),
50491
+ signal: AbortSignal.timeout(LOAD_TIMEOUT_MS2)
50492
+ });
50493
+ if (!response.ok) {
50494
+ const body = redactExactValues(await response.text(), credentialValuesFromRequest(headers));
50495
+ throw new Error(`LM Studio could not load ${model} on ${device}: ${response.status} ${body}`);
50496
+ }
50497
+ const body = await response.json().catch(() => null);
50498
+ return typeof body?.instance_id === "string" && body.instance_id !== "" ? body.instance_id : undefined;
50499
+ } finally {
50500
+ if (mustSwitch && original) {
50501
+ const restored = await run(["link", "set-preferred-device", original], LIST_TIMEOUT_MS);
50502
+ if (restored === null)
50503
+ log?.(`Could not restore LM Link preferred device ${original}.`);
50504
+ }
50505
+ }
50506
+ }
50507
+ var LMSTUDIO_DEVICE_SEPARATOR = "~", LMSTUDIO_THIS_MACHINE = "local", LIST_TIMEOUT_MS = 5000, LOAD_TIMEOUT_MS2 = 600000, runLms = async (args, timeoutMs) => {
50508
+ const configured = process.env.CLAUDISH_LMS_BIN;
50509
+ if (configured)
50510
+ return (await execLms(configured, args, timeoutMs)).stdout;
50511
+ const onPath = await execLms("lms", args, timeoutMs);
50512
+ if (!onPath.missing)
50513
+ return onPath.stdout;
50514
+ return (await execLms(join29(homedir28(), ".lmstudio", "bin", "lms"), args, timeoutMs)).stdout;
50515
+ }, THIS_MACHINE_NAME = "this Mac", LOCK_POLL_MS2 = 250, CLAIM = "takeover", MAX_CLAIM_CHAIN = 64, machineQueue;
50516
+ var init_lmstudio_devices = __esm(() => {
50517
+ init_call_context();
50518
+ init_redact();
50519
+ machineQueue = Promise.resolve();
50520
+ });
50521
+
50068
50522
  // src/providers/devin/proto-codec.ts
50069
50523
  function cat(parts) {
50070
50524
  let total = 0;
@@ -51076,7 +51530,31 @@ function readCreatedDate(row) {
51076
51530
  const iso = new Date(seconds * 1000).toISOString();
51077
51531
  return iso.slice(0, 10);
51078
51532
  }
51079
- function parseOpenAIModelsList(body) {
51533
+ function readLMStudioContextWindow(row) {
51534
+ const loaded = positive(row.loaded_context_length);
51535
+ if (loaded !== undefined)
51536
+ return loaded;
51537
+ const max = positive(row.max_context_length);
51538
+ const wanted = getProviderByName("lmstudio")?.unknownContextWindow;
51539
+ return max !== undefined && wanted !== undefined && max < wanted ? max : undefined;
51540
+ }
51541
+ function ceilingOf(row) {
51542
+ const ceiling = positive(row.max_context_length);
51543
+ return ceiling === undefined ? {} : { contextCeiling: ceiling };
51544
+ }
51545
+ function positive(value) {
51546
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
51547
+ }
51548
+ async function withLMStudioMachines(models, baseUrl) {
51549
+ if (!isLoopbackUrl(baseUrl))
51550
+ return models;
51551
+ const machines = await readLMStudioMachines();
51552
+ if (!machines)
51553
+ return models;
51554
+ return expandModelsToMachines(models, machines, getProviderByName("lmstudio")?.unknownContextWindow);
51555
+ }
51556
+ function parseOpenAIModelsList(body, format) {
51557
+ const isLMStudio = format === "lmstudio-models";
51080
51558
  const data = body?.data;
51081
51559
  if (!Array.isArray(data))
51082
51560
  return { models: [], dropped: 0, total: null };
@@ -51097,8 +51575,10 @@ function parseOpenAIModelsList(body) {
51097
51575
  models.push({
51098
51576
  id,
51099
51577
  displayName,
51100
- contextWindow: readContextWindow(row),
51101
- releaseDate: readCreatedDate(row)
51578
+ contextWindow: isLMStudio ? readLMStudioContextWindow(row) : readContextWindow(row),
51579
+ releaseDate: readCreatedDate(row),
51580
+ ...isLMStudio ? { reported: lmStudioReported(row) } : {},
51581
+ ...isLMStudio ? ceilingOf(row) : {}
51102
51582
  });
51103
51583
  }
51104
51584
  return { models, dropped, total: data.length };
@@ -51223,9 +51703,10 @@ async function fetchServedModels(providerName) {
51223
51703
  const descriptor = def?.modelDiscovery;
51224
51704
  if (!def || !descriptor)
51225
51705
  return { kind: "unsupported", reason: "no-descriptor" };
51226
- if (descriptor.format !== "openai-models-list") {
51706
+ if (descriptor.format !== "openai-models-list" && descriptor.format !== "lmstudio-models") {
51227
51707
  return await discoverViaFetcher(providerName, descriptor.format);
51228
51708
  }
51709
+ const isLMStudio = descriptor.format === "lmstudio-models";
51229
51710
  const baseUrl = resolveBaseUrl(providerName);
51230
51711
  if (!baseUrl) {
51231
51712
  const overrides = (def.baseUrlEnvVars ?? []).join(", ");
@@ -51236,7 +51717,8 @@ async function fetchServedModels(providerName) {
51236
51717
  });
51237
51718
  }
51238
51719
  const definitionEndpoint = `${baseUrl}${descriptor.path}`;
51239
- let endpoint = registryModelsEndpoint(providerName, def) ?? definitionEndpoint;
51720
+ let endpoint = isLMStudio ? definitionEndpoint : registryModelsEndpoint(providerName, def) ?? definitionEndpoint;
51721
+ let bodyFormat = descriptor.format;
51240
51722
  let headers = {};
51241
51723
  if (def.isLocal) {
51242
51724
  const key = def.apiKeyEnvVar ? process.env[def.apiKeyEnvVar] : undefined;
@@ -51271,6 +51753,11 @@ async function fetchServedModels(providerName) {
51271
51753
  endpoint = definitionEndpoint;
51272
51754
  response = await fetchList(endpoint);
51273
51755
  }
51756
+ if (response.status === 404 && isLMStudio) {
51757
+ endpoint = `${baseUrl}/v1/models`;
51758
+ bodyFormat = "openai-models-list";
51759
+ response = await fetchList(endpoint);
51760
+ }
51274
51761
  } catch (e) {
51275
51762
  return recordFailure({
51276
51763
  kind: "unreachable",
@@ -51299,7 +51786,7 @@ async function fetchServedModels(providerName) {
51299
51786
  } catch {
51300
51787
  return recordFailure({ kind: "malformed", provider: providerName, endpoint });
51301
51788
  }
51302
- const parsed = parseOpenAIModelsList(body);
51789
+ const parsed = parseOpenAIModelsList(body, bodyFormat);
51303
51790
  const incomplete = describeIncompleteness(body, parsed);
51304
51791
  if (incomplete) {
51305
51792
  return recordFailure({
@@ -51309,7 +51796,7 @@ async function fetchServedModels(providerName) {
51309
51796
  detail: incomplete
51310
51797
  });
51311
51798
  }
51312
- const models = parsed.models;
51799
+ const models = isLMStudio ? await withLMStudioMachines(parsed.models, baseUrl) : parsed.models;
51313
51800
  _failures.delete(providerName);
51314
51801
  log(`[model-discovery:${providerName}] discovered ${models.length} models from ${endpoint}: ` + models.map((m) => `${m.id}(${m.contextWindow ?? "?"})`).join(", "));
51315
51802
  return { kind: "served", models };
@@ -51318,16 +51805,27 @@ async function discoverProviderModels(providerName) {
51318
51805
  const outcome = await discoverProviderModelsCatalog(providerName);
51319
51806
  return outcome.kind === "served" ? outcome.models : [];
51320
51807
  }
51321
- function windowOf(models, modelId) {
51808
+ function windowOf(models, modelId, upTo) {
51322
51809
  const needle = modelId.toLowerCase();
51323
- return models.find((m) => m.id.toLowerCase() === needle)?.contextWindow;
51810
+ const exact = models.find((m) => m.id.toLowerCase() === needle);
51811
+ if (exact)
51812
+ return rowWindow(exact, upTo);
51813
+ const windows = models.filter((m) => m.machine?.modelId.toLowerCase() === needle).map((m) => rowWindow(m, upTo)).filter((w) => w !== undefined);
51814
+ return windows.length > 0 ? Math.min(...windows) : undefined;
51815
+ }
51816
+ function rowWindow(model, upTo) {
51817
+ if (model.contextWindow !== undefined)
51818
+ return model.contextWindow;
51819
+ const ceiling = model.contextCeiling;
51820
+ return upTo !== undefined && ceiling !== undefined && ceiling < upTo ? ceiling : undefined;
51324
51821
  }
51325
51822
  async function discoverContextWindow(providerName, modelId, opts = {}) {
51823
+ const { upTo } = opts;
51326
51824
  if (opts.network === "cached-first") {
51327
51825
  await Promise.resolve().then(() => init_dynamic_models_catalog());
51328
51826
  const stored = await readAccountModelsList(providerName);
51329
51827
  if (stored)
51330
- return windowOf(stored.models, modelId);
51828
+ return windowOf(stored.models, modelId, upTo);
51331
51829
  coldRefresh(providerName);
51332
51830
  return;
51333
51831
  }
@@ -51337,13 +51835,13 @@ async function discoverContextWindow(providerName, modelId, opts = {}) {
51337
51835
  timer = setTimeout(() => resolve([]), LIVE_DISCOVERY_BOUND_MS);
51338
51836
  });
51339
51837
  try {
51340
- return windowOf(await Promise.race([coldRefresh(providerName), bound]), modelId);
51838
+ return windowOf(await Promise.race([coldRefresh(providerName), bound]), modelId, upTo);
51341
51839
  } finally {
51342
51840
  clearTimeout(timer);
51343
51841
  }
51344
51842
  }
51345
51843
  const { served, optIn } = await discoverProviderServedIds(providerName);
51346
- return windowOf([...served, ...optIn], modelId);
51844
+ return windowOf([...served, ...optIn], modelId, upTo);
51347
51845
  }
51348
51846
  function coldRefresh(providerName) {
51349
51847
  const running = coldRefreshes.get(providerName);
@@ -51379,7 +51877,9 @@ var init_model_discovery = __esm(() => {
51379
51877
  init_authority();
51380
51878
  init_logger();
51381
51879
  init_connection_resolver();
51880
+ init_lmstudio_devices();
51382
51881
  init_provider_definitions();
51882
+ init_probe_discovery();
51383
51883
  _fetchers = new Map;
51384
51884
  CACHE_TTL_MS2 = 5 * 60 * 1000;
51385
51885
  _cache2 = new Map;
@@ -51941,7 +52441,7 @@ var init_wire_markers = __esm(() => {
51941
52441
  });
51942
52442
 
51943
52443
  // src/providers/catalog-query.ts
51944
- import { statSync as statSync9 } from "fs";
52444
+ import { statSync as statSync10 } from "fs";
51945
52445
  function project(entry) {
51946
52446
  return {
51947
52447
  modelId: entry.modelId,
@@ -51955,7 +52455,7 @@ function project(entry) {
51955
52455
  function getCachedEntries() {
51956
52456
  let mtimeMs;
51957
52457
  try {
51958
- mtimeMs = statSync9(ALL_MODELS_CACHE_PATH).mtimeMs;
52458
+ mtimeMs = statSync10(ALL_MODELS_CACHE_PATH).mtimeMs;
51959
52459
  } catch {
51960
52460
  return null;
51961
52461
  }
@@ -52128,17 +52628,17 @@ var init_vision_proxy = __esm(() => {
52128
52628
  });
52129
52629
 
52130
52630
  // src/mcp-session/home-dir.ts
52131
- import { homedir as homedir28 } from "os";
52132
- import { join as join29 } from "path";
52133
- function userHomeFrom(env, homedirFn = homedir28) {
52631
+ import { homedir as homedir29 } from "os";
52632
+ import { join as join30 } from "path";
52633
+ function userHomeFrom(env, homedirFn = homedir29) {
52134
52634
  const home = env.HOME;
52135
52635
  return home && home.length > 0 ? home : homedirFn();
52136
52636
  }
52137
- function sessionsDirFrom(env, homedirFn = homedir28) {
52637
+ function sessionsDirFrom(env, homedirFn = homedir29) {
52138
52638
  const explicit = env.CLAUDISH_SESSIONS_DIR;
52139
52639
  if (explicit && explicit.length > 0)
52140
52640
  return explicit;
52141
- return join29(userHomeFrom(env, homedirFn), ".claudish", "sessions");
52641
+ return join30(userHomeFrom(env, homedirFn), ".claudish", "sessions");
52142
52642
  }
52143
52643
  function claudeCodeStringHash(s) {
52144
52644
  let h = 0;
@@ -52229,7 +52729,7 @@ function reduceEvent(state, event) {
52229
52729
  }
52230
52730
 
52231
52731
  // src/session-events/transcript-tailer.ts
52232
- import { closeSync as closeSync9, openSync as openSync9, readSync as readSync2, statSync as statSync10 } from "fs";
52732
+ import { closeSync as closeSync9, openSync as openSync9, readSync as readSync2, statSync as statSync11 } from "fs";
52233
52733
 
52234
52734
  class TranscriptTailer {
52235
52735
  filePath;
@@ -52274,7 +52774,7 @@ class TranscriptTailer {
52274
52774
  if (this.disposed)
52275
52775
  return;
52276
52776
  try {
52277
- const size = statSync10(this.filePath).size;
52777
+ const size = statSync11(this.filePath).size;
52278
52778
  if (size < this.offset) {
52279
52779
  this.offset = 0;
52280
52780
  this.buffer = "";
@@ -52311,9 +52811,9 @@ var DEFAULT_POLL_INTERVAL_MS = 250;
52311
52811
  var init_transcript_tailer = () => {};
52312
52812
 
52313
52813
  // src/session-events/index.ts
52314
- import { existsSync as existsSync22, readFileSync as readFileSync29, readdirSync as readdirSync4 } from "fs";
52315
- import { homedir as homedir29 } from "os";
52316
- import { join as join30 } from "path";
52814
+ import { existsSync as existsSync22, readFileSync as readFileSync30, readdirSync as readdirSync5 } from "fs";
52815
+ import { homedir as homedir30 } from "os";
52816
+ import { join as join31 } from "path";
52317
52817
  function extractSessionId2(metadata) {
52318
52818
  const userId = metadata?.user_id;
52319
52819
  if (typeof userId !== "string")
@@ -52338,7 +52838,7 @@ class SessionEventRegistry {
52338
52838
  claudeHome;
52339
52839
  pollIntervalMs;
52340
52840
  constructor(opts = {}) {
52341
- this.claudeHome = opts.claudeHome ?? join30(homedir29(), ".claude");
52841
+ this.claudeHome = opts.claudeHome ?? join31(homedir30(), ".claude");
52342
52842
  this.pollIntervalMs = opts.pollIntervalMs;
52343
52843
  }
52344
52844
  ensureSession(sessionId) {
@@ -52424,13 +52924,13 @@ class SessionEventRegistry {
52424
52924
  }
52425
52925
  }
52426
52926
  locateTranscript(sessionId) {
52427
- const projectsDir = join30(this.claudeHome, "projects");
52428
- const primary = join30(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
52927
+ const projectsDir = join31(this.claudeHome, "projects");
52928
+ const primary = join31(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
52429
52929
  if (existsSync22(primary))
52430
52930
  return primary;
52431
52931
  try {
52432
- for (const dir of readdirSync4(projectsDir)) {
52433
- const candidate = join30(projectsDir, dir, `${sessionId}.jsonl`);
52932
+ for (const dir of readdirSync5(projectsDir)) {
52933
+ const candidate = join31(projectsDir, dir, `${sessionId}.jsonl`);
52434
52934
  if (existsSync22(candidate))
52435
52935
  return candidate;
52436
52936
  }
@@ -52439,7 +52939,7 @@ class SessionEventRegistry {
52439
52939
  }
52440
52940
  readSettingsEffortLevel() {
52441
52941
  try {
52442
- const settings = JSON.parse(readFileSync29(join30(this.claudeHome, "settings.json"), "utf-8"));
52942
+ const settings = JSON.parse(readFileSync30(join31(this.claudeHome, "settings.json"), "utf-8"));
52443
52943
  return typeof settings.effortLevel === "string" ? settings.effortLevel : undefined;
52444
52944
  } catch {
52445
52945
  return;
@@ -52543,24 +53043,24 @@ var claimed = false;
52543
53043
  // src/stats-buffer.ts
52544
53044
  import {
52545
53045
  existsSync as existsSync23,
52546
- mkdirSync as mkdirSync16,
52547
- readFileSync as readFileSync30,
52548
- renameSync as renameSync8,
53046
+ mkdirSync as mkdirSync17,
53047
+ readFileSync as readFileSync31,
53048
+ renameSync as renameSync9,
52549
53049
  unlinkSync as unlinkSync8,
52550
- writeFileSync as writeFileSync11
53050
+ writeFileSync as writeFileSync12
52551
53051
  } from "fs";
52552
- import { homedir as homedir30 } from "os";
52553
- import { join as join31 } from "path";
53052
+ import { homedir as homedir31 } from "os";
53053
+ import { join as join32 } from "path";
52554
53054
  function ensureDir() {
52555
53055
  if (!existsSync23(CLAUDISH_DIR)) {
52556
- mkdirSync16(CLAUDISH_DIR, { recursive: true });
53056
+ mkdirSync17(CLAUDISH_DIR, { recursive: true });
52557
53057
  }
52558
53058
  }
52559
53059
  function readFromDisk() {
52560
53060
  try {
52561
53061
  if (!existsSync23(BUFFER_FILE))
52562
53062
  return [];
52563
- const raw = readFileSync30(BUFFER_FILE, "utf-8");
53063
+ const raw = readFileSync31(BUFFER_FILE, "utf-8");
52564
53064
  const parsed = JSON.parse(raw);
52565
53065
  if (!Array.isArray(parsed.events))
52566
53066
  return [];
@@ -52585,9 +53085,9 @@ function writeToDisk(events) {
52585
53085
  ensureDir();
52586
53086
  const trimmed = enforceSizeCap([...events]);
52587
53087
  const payload = { version: 1, events: trimmed };
52588
- const tmpFile = join31(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
52589
- writeFileSync11(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
52590
- renameSync8(tmpFile, BUFFER_FILE);
53088
+ const tmpFile = join32(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
53089
+ writeFileSync12(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
53090
+ renameSync9(tmpFile, BUFFER_FILE);
52591
53091
  memoryCache = trimmed;
52592
53092
  } catch {}
52593
53093
  }
@@ -52658,8 +53158,8 @@ function syncFlushOnExit() {
52658
53158
  var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false, SIGNAL_EXIT_CODE;
52659
53159
  var init_stats_buffer = __esm(() => {
52660
53160
  BUFFER_MAX_BYTES = 64 * 1024;
52661
- CLAUDISH_DIR = join31(homedir30(), ".claudish");
52662
- BUFFER_FILE = join31(CLAUDISH_DIR, "stats-buffer.json");
53161
+ CLAUDISH_DIR = join32(homedir31(), ".claudish");
53162
+ BUFFER_FILE = join32(CLAUDISH_DIR, "stats-buffer.json");
52663
53163
  process.on("exit", syncFlushOnExit);
52664
53164
  SIGNAL_EXIT_CODE = { SIGTERM: 143, SIGINT: 130 };
52665
53165
  for (const signal of ["SIGTERM", "SIGINT"]) {
@@ -56741,7 +57241,7 @@ var init_openai_responses_sse = __esm(() => {
56741
57241
  });
56742
57242
 
56743
57243
  // src/session/token-file.ts
56744
- import { join as join32 } from "path";
57244
+ import { join as join33 } from "path";
56745
57245
  function assignedTokenFile(env) {
56746
57246
  const f = env.CLAUDISH_TOKEN_FILE;
56747
57247
  if (!f || f === env.CLAUDISH_PUBLISHED_TOKEN_FILE)
@@ -56749,15 +57249,15 @@ function assignedTokenFile(env) {
56749
57249
  return f;
56750
57250
  }
56751
57251
  function resolveTokenFilePath(port, env = process.env) {
56752
- return assignedTokenFile(env) ?? join32(userHomeFrom(env), ".claudish", `tokens-${port}.json`);
57252
+ return assignedTokenFile(env) ?? join33(userHomeFrom(env), ".claudish", `tokens-${port}.json`);
56753
57253
  }
56754
57254
  var init_token_file = __esm(() => {
56755
57255
  init_home_dir();
56756
57256
  });
56757
57257
 
56758
57258
  // src/handlers/shared/token-tracker.ts
56759
- import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync12 } from "fs";
56760
- import { dirname as dirname14 } from "path";
57259
+ import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync13 } from "fs";
57260
+ import { dirname as dirname15 } from "path";
56761
57261
  function stripProviderPrefix(name) {
56762
57262
  if (!hasProviderPrefix(name))
56763
57263
  return name;
@@ -56998,8 +57498,8 @@ class TokenTracker {
56998
57498
  };
56999
57499
  }
57000
57500
  const outPath = resolveTokenFilePath(this.port);
57001
- mkdirSync17(dirname14(outPath), { recursive: true });
57002
- writeFileSync12(outPath, JSON.stringify(data), "utf-8");
57501
+ mkdirSync18(dirname15(outPath), { recursive: true });
57502
+ writeFileSync13(outPath, JSON.stringify(data), "utf-8");
57003
57503
  } catch (e) {
57004
57504
  log(`[TokenTracker] Error writing token file: ${e}`);
57005
57505
  }
@@ -59256,11 +59756,11 @@ var init_composed_handler = __esm(() => {
59256
59756
  });
59257
59757
 
59258
59758
  // src/providers/api-key-provenance.ts
59259
- import { existsSync as existsSync24, readFileSync as readFileSync31 } from "fs";
59260
- import { homedir as homedir31 } from "os";
59261
- import { join as join33, resolve as resolve3 } from "path";
59759
+ import { existsSync as existsSync24, readFileSync as readFileSync32 } from "fs";
59760
+ import { homedir as homedir32 } from "os";
59761
+ import { join as join34, resolve as resolve3 } from "path";
59262
59762
  function activeConfigPath() {
59263
- return activeGlobalConfigFile(join33(homedir31(), ".claudish", "config.json"));
59763
+ return activeGlobalConfigFile(join34(homedir32(), ".claudish", "config.json"));
59264
59764
  }
59265
59765
  function configLayerLabel() {
59266
59766
  return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
@@ -59387,7 +59887,7 @@ function readDotenvKey(envVars) {
59387
59887
  const dotenvPath = resolve3(".env");
59388
59888
  if (!existsSync24(dotenvPath))
59389
59889
  return null;
59390
- const parsed = readAllowedDotenv(readFileSync31(dotenvPath, "utf-8"));
59890
+ const parsed = readAllowedDotenv(readFileSync32(dotenvPath, "utf-8"));
59391
59891
  for (const v of envVars) {
59392
59892
  if (parsed[v])
59393
59893
  return parsed[v];
@@ -59402,7 +59902,7 @@ function readConfigKey(envVar) {
59402
59902
  const configPath = activeConfigPath();
59403
59903
  if (!existsSync24(configPath))
59404
59904
  return null;
59405
- const cfg = JSON.parse(readFileSync31(configPath, "utf-8"));
59905
+ const cfg = JSON.parse(readFileSync32(configPath, "utf-8"));
59406
59906
  return cfg.apiKeys?.[envVar] || null;
59407
59907
  } catch {
59408
59908
  return null;
@@ -61591,6 +62091,7 @@ var geminiHandler, antigravityHandler, devinHandler, grokSubscriptionHandler, mu
61591
62091
  var init_provider_definitions = __esm(() => {
61592
62092
  init_vertex_auth();
61593
62093
  init_profile_config();
62094
+ init_context_window_limit();
61594
62095
  init_runtime_providers();
61595
62096
  geminiHandler = lazyHandler((m) => m.geminiProfile);
61596
62097
  antigravityHandler = lazyHandler((m) => m.antigravityProfile);
@@ -62141,7 +62642,8 @@ var init_provider_definitions = __esm(() => {
62141
62642
  { prefix: "mlstudio:", stripPrefix: true }
62142
62643
  ],
62143
62644
  isLocal: true,
62144
- modelDiscovery: { path: "/v1/models", format: "openai-models-list" },
62645
+ modelDiscovery: { path: "/api/v0/models", format: "lmstudio-models" },
62646
+ unknownContextWindow: DEFAULT_LOCAL_CONTEXT_WINDOW,
62145
62647
  description: "Local LM Studio (lms@)"
62146
62648
  },
62147
62649
  {
@@ -73156,9 +73658,9 @@ function compareByConnectionPrice(a, b) {
73156
73658
  }
73157
73659
 
73158
73660
  // src/providers/probe-catalog.ts
73159
- import { existsSync as existsSync25, mkdirSync as mkdirSync18, readFileSync as readFileSync32, writeFileSync as writeFileSync13 } from "fs";
73160
- import { homedir as homedir32 } from "os";
73161
- import { dirname as dirname15, join as join34 } from "path";
73661
+ import { existsSync as existsSync25, mkdirSync as mkdirSync19, readFileSync as readFileSync33, writeFileSync as writeFileSync14 } from "fs";
73662
+ import { homedir as homedir33 } from "os";
73663
+ import { dirname as dirname16, join as join35 } from "path";
73162
73664
  function describeProbeCatalogFailure(outcome) {
73163
73665
  switch (outcome.kind) {
73164
73666
  case "incompatible":
@@ -73178,15 +73680,15 @@ function readProbeModelsCache(path = PROBE_MODELS_CACHE_PATH) {
73178
73680
  return null;
73179
73681
  let raw;
73180
73682
  try {
73181
- raw = JSON.parse(readFileSync32(path, "utf-8"));
73683
+ raw = JSON.parse(readFileSync33(path, "utf-8"));
73182
73684
  } catch {
73183
73685
  return null;
73184
73686
  }
73185
73687
  return isValidResponse(raw) ? raw : null;
73186
73688
  }
73187
73689
  function writeProbeModelsCache(data, path = PROBE_MODELS_CACHE_PATH) {
73188
- mkdirSync18(dirname15(path), { recursive: true });
73189
- writeFileSync13(path, JSON.stringify(data), "utf-8");
73690
+ mkdirSync19(dirname16(path), { recursive: true });
73691
+ writeFileSync14(path, JSON.stringify(data), "utf-8");
73190
73692
  }
73191
73693
  function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
73192
73694
  if (!data)
@@ -73330,7 +73832,7 @@ var init_probe_catalog = __esm(() => {
73330
73832
  init_catalog_endpoints();
73331
73833
  init_catalog_route_bindings();
73332
73834
  CACHE_TTL_MS4 = 60 * 60 * 1000;
73333
- PROBE_MODELS_CACHE_PATH = join34(homedir32(), ".claudish", "probe-models.json");
73835
+ PROBE_MODELS_CACHE_PATH = join35(homedir33(), ".claudish", "probe-models.json");
73334
73836
  });
73335
73837
 
73336
73838
  // src/providers/route-candidates.ts
@@ -74812,10 +75314,10 @@ var init_prehydrate = __esm(() => {
74812
75314
 
74813
75315
  // src/auth/claude-code-facts.ts
74814
75316
  import { createHash as createHash17 } from "crypto";
74815
- import { homedir as homedir33 } from "os";
75317
+ import { homedir as homedir34 } from "os";
74816
75318
  import { isAbsolute as isAbsolute2, resolve as resolve4 } from "path";
74817
75319
  function defaultConfigDir(env) {
74818
- return resolve4(env.HOME || homedir33(), ".claude");
75320
+ return resolve4(env.HOME || homedir34(), ".claude");
74819
75321
  }
74820
75322
  function configDirHash(configDir) {
74821
75323
  return createHash17("sha256").update(configDir).digest("hex").slice(0, 8);
@@ -75683,7 +76185,7 @@ var init_magmux_client = __esm(() => {
75683
76185
  });
75684
76186
 
75685
76187
  // src/pane/own-pane.ts
75686
- import { execFile as execFile2 } from "child_process";
76188
+ import { execFile as execFile3 } from "child_process";
75687
76189
  import { promisify as promisify5 } from "util";
75688
76190
  async function ancestorPids(maxDepth = ANCESTRY_DEPTH) {
75689
76191
  const out = new Set([process.pid]);
@@ -75733,12 +76235,12 @@ async function findOwnPane(list, ancestors = () => ancestorPids()) {
75733
76235
  }
75734
76236
  var execFileAsync2, ANCESTRY_DEPTH = 6;
75735
76237
  var init_own_pane = __esm(() => {
75736
- execFileAsync2 = promisify5(execFile2);
76238
+ execFileAsync2 = promisify5(execFile3);
75737
76239
  });
75738
76240
 
75739
76241
  // src/pane/prompt-delivery.ts
75740
- import { writeFileSync as writeFileSync14 } from "fs";
75741
- import { join as join35 } from "path";
76242
+ import { writeFileSync as writeFileSync15 } from "fs";
76243
+ import { join as join36 } from "path";
75742
76244
  function stripControl(s) {
75743
76245
  let out = "";
75744
76246
  for (const ch of s) {
@@ -75805,7 +76307,7 @@ function renderTurnFile(text, limit = READ_LINE_LIMIT) {
75805
76307
  `), lines: out.length, marker };
75806
76308
  }
75807
76309
  function turnFilePath(turnDir, turnIndex) {
75808
- return join35(turnDir, `turn-${turnIndex}.md`);
76310
+ return join36(turnDir, `turn-${turnIndex}.md`);
75809
76311
  }
75810
76312
  function fileTemplate(file, marker) {
75811
76313
  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.`;
@@ -75876,7 +76378,7 @@ function deliveryRefusal(text, readAvailable) {
75876
76378
  }
75877
76379
  function writeTurnFile(d) {
75878
76380
  if ((d.mode === "file" || d.mode === "command") && d.file && d.fileContent !== undefined) {
75879
- writeFileSync14(d.file, d.fileContent, { mode: 384, flag: "wx" });
76381
+ writeFileSync15(d.file, d.fileContent, { mode: 384, flag: "wx" });
75880
76382
  }
75881
76383
  }
75882
76384
  var READ_LINE_LIMIT = 20000, MAX_TYPED_LINE = 512, SPLIT_MARKER = "\u21A9", ALT_SPLIT_MARKER = "\u2936", SLASH;
@@ -76485,11 +76987,11 @@ import {
76485
76987
  fstatSync as fstatSync3,
76486
76988
  openSync as openSync10,
76487
76989
  readSync as readSync3,
76488
- readdirSync as readdirSync5,
76990
+ readdirSync as readdirSync6,
76489
76991
  realpathSync as realpathSync4,
76490
- statSync as statSync11
76992
+ statSync as statSync12
76491
76993
  } from "fs";
76492
- import { join as join36 } from "path";
76994
+ import { join as join37 } from "path";
76493
76995
  function initialFollowerState(resolvePath = safeRealpath) {
76494
76996
  return {
76495
76997
  turns: [],
@@ -77053,7 +77555,7 @@ class TranscriptFollower {
77053
77555
  if (!existsSync26(this.subagentsDir))
77054
77556
  return [];
77055
77557
  try {
77056
- return readdirSync5(this.subagentsDir).filter((f) => f.endsWith(".jsonl"));
77558
+ return readdirSync6(this.subagentsDir).filter((f) => f.endsWith(".jsonl"));
77057
77559
  } catch {
77058
77560
  return [];
77059
77561
  }
@@ -77063,7 +77565,7 @@ class TranscriptFollower {
77063
77565
  for (const f of this.subagentFiles()) {
77064
77566
  let tail = this.subs.get(f);
77065
77567
  if (!tail) {
77066
- tail = new Tail(join36(this.subagentsDir, f));
77568
+ tail = new Tail(join37(this.subagentsDir, f));
77067
77569
  this.subs.set(f, tail);
77068
77570
  }
77069
77571
  for (const { line } of tail.read()) {
@@ -77138,7 +77640,7 @@ function lastHumanPromptOffset(path) {
77138
77640
  }
77139
77641
  function fileSize(p) {
77140
77642
  try {
77141
- return statSync11(p).size;
77643
+ return statSync12(p).size;
77142
77644
  } catch {
77143
77645
  return 0;
77144
77646
  }
@@ -77163,7 +77665,7 @@ var init_transcript_follower = __esm(() => {
77163
77665
 
77164
77666
  // src/mcp-session/parent-session.ts
77165
77667
  import { readFile as readFile7 } from "fs/promises";
77166
- import { join as join37 } from "path";
77668
+ import { join as join38 } from "path";
77167
77669
  function positiveInt(value) {
77168
77670
  if (value === undefined || !/^[1-9][0-9]*$/.test(value))
77169
77671
  return;
@@ -77187,11 +77689,11 @@ function parentSessionIdFrom(env) {
77187
77689
  }
77188
77690
  function claudeConfigDir(env) {
77189
77691
  const fromEnv = env.CLAUDE_CONFIG_DIR;
77190
- return fromEnv && fromEnv.length > 0 ? fromEnv : join37(userHomeFrom(env), ".claude");
77692
+ return fromEnv && fromEnv.length > 0 ? fromEnv : join38(userHomeFrom(env), ".claude");
77191
77693
  }
77192
77694
  async function readHostSessionRecord(opts) {
77193
77695
  try {
77194
- const raw = await readFile7(join37(opts.configDir, "sessions", `${opts.hostPid}.json`), "utf-8");
77696
+ const raw = await readFile7(join38(opts.configDir, "sessions", `${opts.hostPid}.json`), "utf-8");
77195
77697
  const parsed = JSON.parse(raw);
77196
77698
  if (!parsed || typeof parsed !== "object")
77197
77699
  return;
@@ -77235,11 +77737,11 @@ __export(exports_session_discovery, {
77235
77737
  sessionLabel: () => sessionLabel,
77236
77738
  transcriptPathFor: () => transcriptPathFor
77237
77739
  });
77238
- import { execFile as execFile3, execFileSync as execFileSync2 } from "child_process";
77239
- import { closeSync as closeSync11, openSync as openSync11, readSync as readSync4, readdirSync as readdirSync6, realpathSync as realpathSync5, statSync as statSync12 } from "fs";
77240
- import { basename as basename2, join as join38 } from "path";
77740
+ import { execFile as execFile4, execFileSync as execFileSync2 } from "child_process";
77741
+ import { closeSync as closeSync11, openSync as openSync11, readSync as readSync4, readdirSync as readdirSync7, realpathSync as realpathSync5, statSync as statSync13 } from "fs";
77742
+ import { basename as basename3, join as join39 } from "path";
77241
77743
  function projectsDir(env = process.env) {
77242
- return join38(claudeConfigDir(env), "projects");
77744
+ return join39(claudeConfigDir(env), "projects");
77243
77745
  }
77244
77746
  function slugForPath(absPath) {
77245
77747
  return projectDirNameFor(absPath);
@@ -77249,7 +77751,7 @@ function transcriptPathFor(cwd, sessionUuid, projectsRoot = projectsDir()) {
77249
77751
  try {
77250
77752
  real = realpathSync5(cwd);
77251
77753
  } catch {}
77252
- return join38(projectsRoot, slugForPath(real), `${sessionUuid}.jsonl`);
77754
+ return join39(projectsRoot, slugForPath(real), `${sessionUuid}.jsonl`);
77253
77755
  }
77254
77756
  function isAgentSession(row) {
77255
77757
  return row.entrypoint !== undefined && row.entrypoint !== "cli";
@@ -77290,28 +77792,28 @@ function getRepoContext(cwd = process.cwd()) {
77290
77792
  }
77291
77793
  function projectDirs() {
77292
77794
  try {
77293
- return readdirSync6(projectsDir(), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
77795
+ return readdirSync7(projectsDir(), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
77294
77796
  } catch {
77295
77797
  return [];
77296
77798
  }
77297
77799
  }
77298
77800
  function sessionsIn2(dirName) {
77299
- const dir = join38(projectsDir(), dirName);
77801
+ const dir = join39(projectsDir(), dirName);
77300
77802
  let names;
77301
77803
  try {
77302
- names = readdirSync6(dir).filter((n) => n.endsWith(".jsonl"));
77804
+ names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
77303
77805
  } catch {
77304
77806
  return [];
77305
77807
  }
77306
77808
  const rows = [];
77307
77809
  for (const n of names) {
77308
- const file = join38(dir, n);
77810
+ const file = join39(dir, n);
77309
77811
  try {
77310
- const st = statSync12(file);
77812
+ const st = statSync13(file);
77311
77813
  if (st.size === 0)
77312
77814
  continue;
77313
77815
  const row = {
77314
- id: basename2(n, ".jsonl"),
77816
+ id: basename3(n, ".jsonl"),
77315
77817
  file,
77316
77818
  mtimeMs: st.mtimeMs,
77317
77819
  birthtimeMs: st.birthtimeMs,
@@ -77328,7 +77830,7 @@ function sessionsIn2(dirName) {
77328
77830
  }
77329
77831
  async function enrichWorktreeGit(groups, repoRoot) {
77330
77832
  const run = (cwd, args) => new Promise((resolve) => {
77331
- execFile3("git", args, { cwd, encoding: "utf-8" }, (err, stdout) => resolve(err ? "" : stdout));
77833
+ execFile4("git", args, { cwd, encoding: "utf-8" }, (err, stdout) => resolve(err ? "" : stdout));
77332
77834
  });
77333
77835
  const trackByBranch = new Map;
77334
77836
  const refs = await run(repoRoot, [
@@ -77413,7 +77915,7 @@ function discoverWorktreeGroups(repo) {
77413
77915
  if (hit) {
77414
77916
  path = hit.path;
77415
77917
  live = true;
77416
- name = hit.path === repo.root ? "(root)" : basename2(hit.path);
77918
+ name = hit.path === repo.root ? "(root)" : basename3(hit.path);
77417
77919
  } else if (at !== -1 && dir.startsWith(rootSlug)) {
77418
77920
  path = null;
77419
77921
  live = false;
@@ -77468,7 +77970,7 @@ function discoverWorktreeGroups(repo) {
77468
77970
  g.activeNow = g.sessions.some((s) => isActive(s));
77469
77971
  if (g.path) {
77470
77972
  try {
77471
- g.createdMs = statSync12(g.path).birthtimeMs;
77973
+ g.createdMs = statSync13(g.path).birthtimeMs;
77472
77974
  } catch {}
77473
77975
  }
77474
77976
  if (!g.createdMs && g.sessions.length > 0) {
@@ -77556,7 +78058,7 @@ function hydrateSession(row) {
77556
78058
  row.hydrated = true;
77557
78059
  if (isActive(row)) {
77558
78060
  try {
77559
- row.sizeBytes = statSync12(row.file).size;
78061
+ row.sizeBytes = statSync13(row.file).size;
77560
78062
  } catch {}
77561
78063
  }
77562
78064
  const head = parseRecords(readChunk(row.file, 0, Math.min(HEAD_BYTES, row.sizeBytes)), false);
@@ -77771,8 +78273,8 @@ var init_queue = __esm(() => {
77771
78273
  });
77772
78274
 
77773
78275
  // src/hooks/session/interactive-driver.ts
77774
- import { existsSync as existsSync27, statSync as statSync13 } from "fs";
77775
- import { join as join39 } from "path";
78276
+ import { existsSync as existsSync27, statSync as statSync14 } from "fs";
78277
+ import { join as join40 } from "path";
77776
78278
  function nextDriverPhase(phase, ev) {
77777
78279
  const row = EDGES[phase];
77778
78280
  return row[ev] ?? null;
@@ -77990,7 +78492,7 @@ class InteractiveDriver {
77990
78492
  }
77991
78493
  follow(sid, offset) {
77992
78494
  const path = transcriptPathFor(this.o.cwd, sid, this.o.projectsRoot);
77993
- this.follower = new TranscriptFollower(path, join39(path.replace(/\.jsonl$/, ""), "subagents"));
78495
+ this.follower = new TranscriptFollower(path, join40(path.replace(/\.jsonl$/, ""), "subagents"));
77994
78496
  this.sessionId = sid;
77995
78497
  this.settledTurn = null;
77996
78498
  this.lastPollAt = Date.now();
@@ -78535,7 +79037,7 @@ function assertNeverPhase(p) {
78535
79037
  }
78536
79038
  function fileSizeOf(path) {
78537
79039
  try {
78538
- return statSync13(path).size;
79040
+ return statSync14(path).size;
78539
79041
  } catch {
78540
79042
  return 0;
78541
79043
  }
@@ -78707,16 +79209,16 @@ var init_host_routing_env = __esm(() => {
78707
79209
  // src/launcher/magmux-binary.ts
78708
79210
  import { execSync } from "child_process";
78709
79211
  import { existsSync as existsSync28 } from "fs";
78710
- import { dirname as dirname16, join as join40 } from "path";
79212
+ import { dirname as dirname17, join as join41 } from "path";
78711
79213
  import { fileURLToPath } from "url";
78712
79214
  function findMagmuxBinaryOrNull() {
78713
79215
  const thisFile = fileURLToPath(import.meta.url);
78714
- const thisDir = dirname16(thisFile);
78715
- const pkgRoots = [join40(thisDir, ".."), join40(thisDir, "..", "..")];
79216
+ const thisDir = dirname17(thisFile);
79217
+ const pkgRoots = [join41(thisDir, ".."), join41(thisDir, "..", "..")];
78716
79218
  const platform = process.platform;
78717
79219
  const arch = process.arch;
78718
79220
  for (const pkgRoot of pkgRoots) {
78719
- const bundled = join40(pkgRoot, "native", `magmux-${platform}-${arch}`);
79221
+ const bundled = join41(pkgRoot, "native", `magmux-${platform}-${arch}`);
78720
79222
  if (existsSync28(bundled))
78721
79223
  return bundled;
78722
79224
  }
@@ -78724,10 +79226,10 @@ function findMagmuxBinaryOrNull() {
78724
79226
  const pkgName = `@claudish/magmux-${platform}-${arch}`;
78725
79227
  let searchDir = pkgRoots[0];
78726
79228
  for (let i = 0;i < 5; i++) {
78727
- const candidate = join40(searchDir, "node_modules", pkgName, "bin", "magmux");
79229
+ const candidate = join41(searchDir, "node_modules", pkgName, "bin", "magmux");
78728
79230
  if (existsSync28(candidate))
78729
79231
  return candidate;
78730
- const parent = dirname16(searchDir);
79232
+ const parent = dirname17(searchDir);
78731
79233
  if (parent === searchDir)
78732
79234
  break;
78733
79235
  searchDir = parent;
@@ -78754,14 +79256,14 @@ import {
78754
79256
  chmodSync as chmodSync3,
78755
79257
  closeSync as closeSync12,
78756
79258
  existsSync as existsSync29,
78757
- mkdirSync as mkdirSync19,
79259
+ mkdirSync as mkdirSync20,
78758
79260
  mkdtempSync,
78759
79261
  openSync as openSync12,
78760
- rmSync as rmSync10,
78761
- writeFileSync as writeFileSync15
79262
+ rmSync as rmSync11,
79263
+ writeFileSync as writeFileSync16
78762
79264
  } from "fs";
78763
79265
  import { connect as netConnect } from "net";
78764
- import { join as join41 } from "path";
79266
+ import { join as join42 } from "path";
78765
79267
  function envDeltas(parentEnv, childEnv) {
78766
79268
  const set = [];
78767
79269
  const unset = [];
@@ -78826,15 +79328,15 @@ function planMagmuxWrap(input) {
78826
79328
  const id = `claudish-${pid}`;
78827
79329
  const controlSocket = `/tmp/magmux-${id}.sock`;
78828
79330
  const tmpRoot = input.tmpRoot ?? "/tmp";
78829
- mkdirSync19(tmpRoot, { recursive: true });
78830
- const scriptDir = mkdtempSync(join41(tmpRoot, "claudish-launch-"));
79331
+ mkdirSync20(tmpRoot, { recursive: true });
79332
+ const scriptDir = mkdtempSync(join42(tmpRoot, "claudish-launch-"));
78831
79333
  chmodSync3(scriptDir, 448);
78832
- const scriptPath = join41(scriptDir, "claude-launch.sh");
79334
+ const scriptPath = join42(scriptDir, "claude-launch.sh");
78833
79335
  const parentEnv = input.parentEnv ?? process.env;
78834
79336
  const deltas = envDeltas(parentEnv, input.childEnv);
78835
79337
  const fd = openSync12(scriptPath, "wx", 384);
78836
79338
  try {
78837
- writeFileSync15(fd, buildLauncherScript(input.claudeBinary, input.claudeArgs, deltas));
79339
+ writeFileSync16(fd, buildLauncherScript(input.claudeBinary, input.claudeArgs, deltas));
78838
79340
  } finally {
78839
79341
  closeSync12(fd);
78840
79342
  }
@@ -78866,11 +79368,11 @@ function planMagmuxWrap(input) {
78866
79368
  } catch {}
78867
79369
  control = null;
78868
79370
  try {
78869
- rmSync10(scriptDir, { recursive: true, force: true });
79371
+ rmSync11(scriptDir, { recursive: true, force: true });
78870
79372
  } catch {}
78871
79373
  try {
78872
79374
  if (existsSync29(controlSocket))
78873
- rmSync10(controlSocket, { force: true });
79375
+ rmSync11(controlSocket, { force: true });
78874
79376
  } catch {}
78875
79377
  };
78876
79378
  process.on("exit", cleanup);
@@ -78950,7 +79452,7 @@ var init_cache_ttl = __esm(() => {
78950
79452
  });
78951
79453
 
78952
79454
  // src/providers/effort-recommendations.ts
78953
- import { readFileSync as readFileSync33, statSync as statSync14 } from "fs";
79455
+ import { readFileSync as readFileSync34, statSync as statSync15 } from "fs";
78954
79456
  function effortRecommendationsPathFor(catalogPath) {
78955
79457
  return catalogPath.endsWith(".json") ? `${catalogPath.slice(0, -5)}.efforts.json` : `${catalogPath}.efforts.json`;
78956
79458
  }
@@ -79026,7 +79528,7 @@ function parseSidecar(raw) {
79026
79528
  }
79027
79529
  function statOrNull2(path) {
79028
79530
  try {
79029
- const { mtimeMs, size } = statSync14(path);
79531
+ const { mtimeMs, size } = statSync15(path);
79030
79532
  return { mtimeMs, size };
79031
79533
  } catch {
79032
79534
  return null;
@@ -79034,7 +79536,7 @@ function statOrNull2(path) {
79034
79536
  }
79035
79537
  function readSidecarFile(path) {
79036
79538
  try {
79037
- return parseSidecar(JSON.parse(readFileSync33(path, "utf-8")));
79539
+ return parseSidecar(JSON.parse(readFileSync34(path, "utf-8")));
79038
79540
  } catch (err) {
79039
79541
  if (err?.code !== "ENOENT") {
79040
79542
  log(`[effort] unreadable ${path}: ${err instanceof Error ? err.message : String(err)}`);
@@ -79044,7 +79546,7 @@ function readSidecarFile(path) {
79044
79546
  }
79045
79547
  function foreignSidecarFormat(path) {
79046
79548
  try {
79047
- const raw = JSON.parse(readFileSync33(path, "utf-8"));
79549
+ const raw = JSON.parse(readFileSync34(path, "utf-8"));
79048
79550
  if (isRecord4(raw) && raw.format !== SIDECAR_FORMAT)
79049
79551
  return raw.format ?? "none";
79050
79552
  } catch {}
@@ -79103,9 +79605,9 @@ var init_effort_recommendations = __esm(() => {
79103
79605
  });
79104
79606
 
79105
79607
  // src/model-loader.ts
79106
- import { existsSync as existsSync30, readFileSync as readFileSync34 } from "fs";
79107
- import { homedir as homedir34 } from "os";
79108
- import { join as join42 } from "path";
79608
+ import { existsSync as existsSync30, readFileSync as readFileSync35 } from "fs";
79609
+ import { homedir as homedir35 } from "os";
79610
+ import { join as join43 } from "path";
79109
79611
  function isRecommendationTier(value) {
79110
79612
  return typeof value === "string" && RECOMMENDATION_TIER_INDEX.has(value);
79111
79613
  }
@@ -79310,7 +79812,7 @@ function readRecommendedModelsCacheFile() {
79310
79812
  return null;
79311
79813
  let parsed;
79312
79814
  try {
79313
- parsed = JSON.parse(readFileSync34(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
79815
+ parsed = JSON.parse(readFileSync35(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
79314
79816
  } catch (err) {
79315
79817
  log(`[recommended] unreadable ${RECOMMENDED_MODELS_CACHE_PATH}: ${err instanceof Error ? err.message : String(err)}`);
79316
79818
  return null;
@@ -79687,7 +80189,7 @@ var init_model_loader = __esm(() => {
79687
80189
  { recommendationTier: "subscription", title: "Subscription", quickPickEligible: true }
79688
80190
  ];
79689
80191
  RECOMMENDATION_TIER_INDEX = new Map(RECOMMENDATION_SECTIONS.map((section, index) => [section.recommendationTier, index]));
79690
- RECOMMENDED_MODELS_CACHE_PATH = join42(homedir34(), ".claudish", "recommended-models-cache-v2.json");
80192
+ RECOMMENDED_MODELS_CACHE_PATH = join43(homedir35(), ".claudish", "recommended-models-cache-v2.json");
79691
80193
  RECOMMENDED_ROUTE_TIER_ORDER = {
79692
80194
  native: 0,
79693
80195
  general: 1,
@@ -80989,9 +81491,9 @@ var init_DiscoveryNotice = __esm(() => {
80989
81491
  });
80990
81492
 
80991
81493
  // src/providers/model-descriptions.ts
80992
- import { existsSync as existsSync31, mkdirSync as mkdirSync20, readFileSync as readFileSync35, writeFileSync as writeFileSync16 } from "fs";
80993
- import { homedir as homedir35 } from "os";
80994
- import { dirname as dirname17, join as join43 } from "path";
81494
+ import { existsSync as existsSync31, mkdirSync as mkdirSync21, readFileSync as readFileSync36, writeFileSync as writeFileSync17 } from "fs";
81495
+ import { homedir as homedir36 } from "os";
81496
+ import { dirname as dirname18, join as join44 } from "path";
80995
81497
  function emptyDescriptionIndex() {
80996
81498
  return EMPTY_INDEX;
80997
81499
  }
@@ -81013,7 +81515,7 @@ function readCache(path) {
81013
81515
  if (!existsSync31(path))
81014
81516
  return null;
81015
81517
  try {
81016
- const raw = JSON.parse(readFileSync35(path, "utf-8"));
81518
+ const raw = JSON.parse(readFileSync36(path, "utf-8"));
81017
81519
  if (!raw || typeof raw !== "object" || typeof raw.byId !== "object" || raw.byId === null) {
81018
81520
  return null;
81019
81521
  }
@@ -81029,8 +81531,8 @@ function readCache(path) {
81029
81531
  }
81030
81532
  function writeCache(path, cache) {
81031
81533
  try {
81032
- mkdirSync20(dirname17(path), { recursive: true });
81033
- writeFileSync16(path, JSON.stringify(cache), "utf-8");
81534
+ mkdirSync21(dirname18(path), { recursive: true });
81535
+ writeFileSync17(path, JSON.stringify(cache), "utf-8");
81034
81536
  } catch (e) {
81035
81537
  log(`[model-descriptions] cache write failed: ${e?.message ?? String(e)}`);
81036
81538
  }
@@ -81084,7 +81586,7 @@ var init_model_descriptions = __esm(() => {
81084
81586
  init_logger();
81085
81587
  init_model_loader();
81086
81588
  init_cache_ttl();
81087
- MODEL_DESCRIPTIONS_CACHE_PATH = join43(homedir35(), ".claudish", "model-descriptions.json");
81589
+ MODEL_DESCRIPTIONS_CACHE_PATH = join44(homedir36(), ".claudish", "model-descriptions.json");
81088
81590
  EMPTY_INDEX = { get: () => {
81089
81591
  return;
81090
81592
  }, size: 0 };
@@ -81100,7 +81602,7 @@ function discoveryShapeOf(provider) {
81100
81602
  const format = getProviderByName(provider)?.modelDiscovery?.format;
81101
81603
  if (!format)
81102
81604
  return "none";
81103
- return format === "openai-models-list" ? "deadline" : "elapsed";
81605
+ return format === "openai-models-list" || format === "lmstudio-models" ? "deadline" : "elapsed";
81104
81606
  }
81105
81607
  async function* inCompletionOrder(promises) {
81106
81608
  const live = new Map(promises.map((p, i) => [i, p.then((v) => ({ i, v }))]));
@@ -81527,6 +82029,20 @@ var init_chrome = __esm(() => {
81527
82029
  init_tokens();
81528
82030
  });
81529
82031
 
82032
+ // src/picker/context-window-choices.ts
82033
+ function contextWindowChoices(max, defaultSize) {
82034
+ const choices = COMMON_SIZES.filter((size) => size < max * NEAR_MAXIMUM).map((size) => ({ size, label: formatContextLength(size) }));
82035
+ choices.push({ size: max, label: `${formatContextLength(max)} (model maximum)` });
82036
+ const distance = (choice) => Math.abs(choice.size - defaultSize);
82037
+ const closest = choices.reduce((best, choice) => distance(choice) < distance(best) ? choice : best);
82038
+ return { choices, defaultIndex: choices.indexOf(closest) };
82039
+ }
82040
+ var COMMON_SIZES, NEAR_MAXIMUM = 0.9;
82041
+ var init_context_window_choices = __esm(() => {
82042
+ init_model_selector();
82043
+ COMMON_SIZES = [32000, 64000, 128000, 256000, 512000];
82044
+ });
82045
+
81530
82046
  // src/picker/layout.ts
81531
82047
  function deriveRowLayout(inner, opts = {}) {
81532
82048
  const cells = Number.isFinite(inner) ? Math.max(0, Math.floor(inner)) : 0;
@@ -81683,7 +82199,7 @@ function detailText(spec, model) {
81683
82199
  };
81684
82200
  }
81685
82201
  function providerFactsText(facts) {
81686
- const billing = facts.billing === "sub" ? "flat-rate subscription \u2014 no per-token charge" : facts.billing === "local" ? "runs on this machine \u2014 no charge, no network" : "metered \u2014 billed per token";
82202
+ const billing = facts.billing === "sub" ? "flat-rate subscription \u2014 no per-token charge" : facts.billing === "local" ? "self-hosted \u2014 no per-token charge" : "metered \u2014 billed per token";
81687
82203
  const billingShort = facts.billing === "sub" ? "flat-rate plan" : facts.billing === "local" ? "local" : "metered";
81688
82204
  const auth = facts.envVar === "" ? "signs in \u2014 no API key variable" : facts.envVar;
81689
82205
  return { billing, billingShort, auth };
@@ -81962,7 +82478,13 @@ function ChipCell({
81962
82478
  ]
81963
82479
  }, undefined, true, undefined, this);
81964
82480
  }
81965
- function ColumnHeader({ layout }) {
82481
+ function lastColumnLabel(models) {
82482
+ return models.length > 0 && models.every((m) => m.machine) ? "machine" : "$/1M";
82483
+ }
82484
+ function ColumnHeader({
82485
+ layout,
82486
+ last = "$/1M"
82487
+ }) {
81966
82488
  return /* @__PURE__ */ jsxDEV9("box", {
81967
82489
  height: 1,
81968
82490
  flexShrink: 0,
@@ -81999,7 +82521,7 @@ function ColumnHeader({ layout }) {
81999
82521
  }, undefined, false, undefined, this),
82000
82522
  /* @__PURE__ */ jsxDEV9("span", {
82001
82523
  fg: tokens.trace,
82002
- children: padStartTo("$/1M", layout.price)
82524
+ children: padStartTo(last, layout.price)
82003
82525
  }, undefined, false, undefined, this),
82004
82526
  layout.mark > 0 ? /* @__PURE__ */ jsxDEV9("span", {
82005
82527
  fg: tokens.trace,
@@ -82044,7 +82566,7 @@ function ModelRow({
82044
82566
  }, undefined, true, undefined, this) : null,
82045
82567
  /* @__PURE__ */ jsxDEV9("span", {
82046
82568
  fg: idFg,
82047
- children: padTo(model.id, layout.id)
82569
+ children: padTo(model.machine?.modelId ?? model.id, layout.id)
82048
82570
  }, undefined, false, undefined, this),
82049
82571
  /* @__PURE__ */ jsxDEV9("span", {
82050
82572
  children: gap(GAPS.afterId)
@@ -82056,7 +82578,10 @@ function ModelRow({
82056
82578
  /* @__PURE__ */ jsxDEV9("span", {
82057
82579
  children: gap(GAPS.afterCtx)
82058
82580
  }, undefined, false, undefined, this),
82059
- chipBg === null ? /* @__PURE__ */ jsxDEV9("span", {
82581
+ model.machine ? /* @__PURE__ */ jsxDEV9("span", {
82582
+ fg: cursor ? C.strong : tokens.text,
82583
+ children: padStartTo(truncate(model.machine.name, layout.price), layout.price)
82584
+ }, undefined, false, undefined, this) : chipBg === null ? /* @__PURE__ */ jsxDEV9("span", {
82060
82585
  fg: priceFg(price),
82061
82586
  children: padStartTo(price, layout.price)
82062
82587
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9(ChipCell, {
@@ -82379,13 +82904,32 @@ function buildLoadTasks(input) {
82379
82904
  }
82380
82905
  return tasks;
82381
82906
  }
82382
- function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82907
+ function ModelPicker({
82908
+ source,
82909
+ onDone,
82910
+ askContextWindow = false,
82911
+ onDiscoveryFailure
82912
+ }) {
82383
82913
  const { width, height } = useTerminalDimensions();
82384
82914
  const providers = usePickerProviders(source);
82385
82915
  const [view, setView] = useState7("providers");
82386
- const [filter, setFilter] = useState7("");
82387
- const [typing, setTyping] = useState7(false);
82916
+ const [filter, setFilterState] = useState7("");
82917
+ const filterNow = useRef6(filter);
82918
+ filterNow.current = filter;
82919
+ const setFilter = (next) => {
82920
+ filterNow.current = typeof next === "function" ? next(filterNow.current) : next;
82921
+ setFilterState(filterNow.current);
82922
+ };
82923
+ const [typing, setTypingState] = useState7(false);
82924
+ const typingNow = useRef6(typing);
82925
+ typingNow.current = typing;
82926
+ const setTyping = (next) => {
82927
+ typingNow.current = next;
82928
+ setTypingState(next);
82929
+ };
82388
82930
  const [custom, setCustom] = useState7("");
82931
+ const [sizing, setSizing] = useState7(null);
82932
+ const [sizeCursor, setSizeCursor] = useState7(0);
82389
82933
  const [cursor, setCursor] = useState7(0);
82390
82934
  const [providerCursor, setProviderCursor] = useState7(0);
82391
82935
  const [revealKeyless, setRevealKeyless] = useState7(false);
@@ -82464,7 +83008,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82464
83008
  const needle = filter.trim().toLowerCase();
82465
83009
  if (!needle)
82466
83010
  return list.rows;
82467
- return list.rows.filter((r) => r.model.id.toLowerCase().includes(needle) || r.shortcut.toLowerCase().startsWith(needle) || (labels.get(r.provider) ?? "").toLowerCase().includes(needle));
83011
+ return list.rows.filter((r) => r.model.id.toLowerCase().includes(needle) || r.shortcut.toLowerCase().startsWith(needle) || (labels.get(r.provider) ?? "").toLowerCase().includes(needle) || (r.model.machine?.name ?? "").toLowerCase().includes(needle));
82468
83012
  }, [list.rows, filter, labels]);
82469
83013
  const busy = providers.probing || catalog.phase === "loading" || discovery.busy;
82470
83014
  const frame = useAnimationFrame(busy);
@@ -82504,6 +83048,21 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82504
83048
  onDone(null);
82505
83049
  return;
82506
83050
  }
83051
+ if (view === "context") {
83052
+ if (name === "escape") {
83053
+ setView("models");
83054
+ return;
83055
+ }
83056
+ if (name === "up" || name === "down") {
83057
+ const last = (sizing?.choices.length ?? 1) - 1;
83058
+ setSizeCursor((c) => Math.max(0, Math.min(last, c + (name === "up" ? -1 : 1))));
83059
+ return;
83060
+ }
83061
+ if ((name === "return" || name === "enter") && sizing) {
83062
+ onDone(sizing.spec, sizing.choices[sizeCursor]?.size);
83063
+ }
83064
+ return;
83065
+ }
82507
83066
  if (view === "custom") {
82508
83067
  if (name === "escape") {
82509
83068
  setView("models");
@@ -82525,7 +83084,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82525
83084
  }
82526
83085
  if (view === "providers") {
82527
83086
  if (name === "escape") {
82528
- if (filter !== "" || typing) {
83087
+ if (filterNow.current !== "" || typingNow.current) {
82529
83088
  setFilter("");
82530
83089
  setTyping(false);
82531
83090
  setProviderCursor(0);
@@ -82568,7 +83127,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82568
83127
  setProviderCursor(0);
82569
83128
  return;
82570
83129
  }
82571
- const providerCommands = filter === "" && !typing;
83130
+ const providerCommands = filterNow.current === "" && !typingNow.current;
82572
83131
  if (providerCommands && key.raw === "a") {
82573
83132
  setScope(null);
82574
83133
  setFilter("");
@@ -82596,7 +83155,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82596
83155
  return;
82597
83156
  }
82598
83157
  if (name === "escape") {
82599
- if (filter !== "" || typing) {
83158
+ if (filterNow.current !== "" || typingNow.current) {
82600
83159
  setFilter("");
82601
83160
  setTyping(false);
82602
83161
  setCursor(0);
@@ -82624,8 +83183,17 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82624
83183
  return;
82625
83184
  }
82626
83185
  if (name === "return" || name === "enter") {
82627
- if (selected)
83186
+ if (!selected)
83187
+ return;
83188
+ const max = askContextWindow ? selected.model.maxContextLength : undefined;
83189
+ if (max === undefined) {
82628
83190
  onDone(selected.spec);
83191
+ return;
83192
+ }
83193
+ const { choices, defaultIndex } = contextWindowChoices(max, DEFAULT_LOCAL_CONTEXT_WINDOW);
83194
+ setSizing({ spec: selected.spec, choices });
83195
+ setSizeCursor(defaultIndex);
83196
+ setView("context");
82629
83197
  return;
82630
83198
  }
82631
83199
  if (name === "backspace") {
@@ -82633,7 +83201,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82633
83201
  setCursor(0);
82634
83202
  return;
82635
83203
  }
82636
- const commandsLive = filter === "" && !typing;
83204
+ const commandsLive = filterNow.current === "" && !typingNow.current;
82637
83205
  if (commandsLive && key.raw === "c") {
82638
83206
  setView("custom");
82639
83207
  return;
@@ -82655,6 +83223,44 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82655
83223
  }
82656
83224
  }
82657
83225
  });
83226
+ if (view === "context" && sizing) {
83227
+ return /* @__PURE__ */ jsxDEV10(Centred, {
83228
+ width,
83229
+ height,
83230
+ children: /* @__PURE__ */ jsxDEV10(Dialog, {
83231
+ title: "context window",
83232
+ status: sizing.spec,
83233
+ width: layout.width,
83234
+ marginLeft: 0,
83235
+ children: [
83236
+ sizing.choices.map((choice, index) => /* @__PURE__ */ jsxDEV10("box", {
83237
+ height: 1,
83238
+ flexShrink: 0,
83239
+ children: /* @__PURE__ */ jsxDEV10("text", {
83240
+ children: [
83241
+ /* @__PURE__ */ jsxDEV10("span", {
83242
+ fg: tokens.accent,
83243
+ children: index === sizeCursor ? "\u25B6 " : " "
83244
+ }, undefined, false, undefined, this),
83245
+ /* @__PURE__ */ jsxDEV10("span", {
83246
+ fg: tokens.text,
83247
+ children: choice.label
83248
+ }, undefined, false, undefined, this)
83249
+ ]
83250
+ }, undefined, true, undefined, this)
83251
+ }, choice.size, false, undefined, this)),
83252
+ /* @__PURE__ */ jsxDEV10(Rule, {}, undefined, false, undefined, this),
83253
+ /* @__PURE__ */ jsxDEV10(Hints, {
83254
+ hints: [
83255
+ { key: "\u2191\u2193", label: "move" },
83256
+ { key: "\u23CE", label: "launch it" },
83257
+ { key: "esc", label: "back" }
83258
+ ]
83259
+ }, undefined, false, undefined, this)
83260
+ ]
83261
+ }, "context", true, undefined, this)
83262
+ }, undefined, false, undefined, this);
83263
+ }
82658
83264
  if (view === "custom") {
82659
83265
  return /* @__PURE__ */ jsxDEV10(Centred, {
82660
83266
  width,
@@ -82831,7 +83437,8 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82831
83437
  idle: orderedByProvider(storedShown ?? discovery.outcome) ? "" : undefined
82832
83438
  }, undefined, false, undefined, this),
82833
83439
  /* @__PURE__ */ jsxDEV10(ColumnHeader, {
82834
- layout: rowLayout
83440
+ layout: rowLayout,
83441
+ last: lastColumnLabel(list.rows.map((r) => r.model))
82835
83442
  }, undefined, false, undefined, this),
82836
83443
  /* @__PURE__ */ jsxDEV10("box", {
82837
83444
  flexDirection: "column",
@@ -82967,6 +83574,7 @@ function emptyLabel(loading, filter, total, scopedName, providers) {
82967
83574
  }
82968
83575
  var MAX_BANNER_ROWS = 5, HOUR_MS18;
82969
83576
  var init_ModelPicker = __esm(() => {
83577
+ init_context_window_limit();
82970
83578
  init_dynamic_models_catalog_store();
82971
83579
  init_dynamic_models_catalog();
82972
83580
  init_EmptyState();
@@ -82976,6 +83584,7 @@ var init_ModelPicker = __esm(() => {
82976
83584
  init_DiscoveryNotice();
82977
83585
  init_PickerDataSource();
82978
83586
  init_chrome();
83587
+ init_context_window_choices();
82979
83588
  init_detail();
82980
83589
  init_useModelDescriptions();
82981
83590
  init_usePickerModels();
@@ -83110,7 +83719,7 @@ async function resolveDataSource() {
83110
83719
  await Promise.resolve().then(() => init_fixture_source());
83111
83720
  return createFixtureDataSource(name);
83112
83721
  }
83113
- async function runModelPicker(_options = {}) {
83722
+ async function runModelPicker(options = {}) {
83114
83723
  ensureEndpointsRegistered();
83115
83724
  const source = await resolveDataSource();
83116
83725
  const deferred = [];
@@ -83123,18 +83732,21 @@ async function runModelPicker(_options = {}) {
83123
83732
  await applyRendererThemeMode(renderer);
83124
83733
  const root = createRoot(renderer);
83125
83734
  let chosen = null;
83735
+ let chosenContextWindow;
83126
83736
  try {
83127
83737
  await new Promise((resolve) => {
83128
83738
  let settled = false;
83129
- const done = (spec) => {
83739
+ const done = (spec, contextWindow) => {
83130
83740
  if (settled)
83131
83741
  return;
83132
83742
  settled = true;
83133
83743
  chosen = spec;
83744
+ chosenContextWindow = contextWindow;
83134
83745
  resolve();
83135
83746
  };
83136
83747
  root.render(/* @__PURE__ */ jsxDEV11(ModelPicker, {
83137
83748
  source,
83749
+ askContextWindow: options.onContextWindow !== undefined,
83138
83750
  onDone: done,
83139
83751
  onDiscoveryFailure: (provider, lines) => deferred.push({ provider, lines })
83140
83752
  }, undefined, false, undefined, this));
@@ -83152,7 +83764,7 @@ async function runModelPicker(_options = {}) {
83152
83764
  process.stderr.write(line);
83153
83765
  }
83154
83766
  }
83155
- return { model: chosen };
83767
+ return { model: chosen, contextWindow: chosenContextWindow };
83156
83768
  }
83157
83769
  var init_model_picker_run = __esm(() => {
83158
83770
  init_logger();
@@ -83473,6 +84085,8 @@ async function selectModel(options = {}) {
83473
84085
  const outcome = await selectModelInteractive(options);
83474
84086
  if (outcome.model === null)
83475
84087
  throw new PickerCancelled;
84088
+ if (outcome.contextWindow !== undefined)
84089
+ options.onContextWindow?.(outcome.contextWindow);
83476
84090
  return outcome.model;
83477
84091
  }
83478
84092
  async function selectModelInteractive(options = {}) {
@@ -83839,7 +84453,7 @@ function buildRowsFromDiscovered(provider, displayName, discovered, catalogRows)
83839
84453
  const discoveredById = new Map(discovered.map((m) => [m.id, m]));
83840
84454
  const rows = choices.map((c) => {
83841
84455
  const source = discoveredById.get(c.id);
83842
- const contextLength = source ? resolveDiscoveredContextLength(source) : c.contextWindow ?? 0;
84456
+ const contextLength = (source ? resolveDiscoveredContextLength(source) : c.contextWindow ?? 0) || (source?.maxContextWindow ?? 0);
83843
84457
  const parts = [c.displayName];
83844
84458
  if (contextLength)
83845
84459
  parts.push(`${formatContextLength(contextLength)} context`);
@@ -83857,6 +84471,8 @@ function buildRowsFromDiscovered(provider, displayName, discovered, catalogRows)
83857
84471
  pricing: subscription ? SUBSCRIPTION_PRICING : pricingById.get(c.id.toLowerCase()),
83858
84472
  context: formatContextLength(contextLength),
83859
84473
  contextLength,
84474
+ maxContextLength: source?.maxContextWindow,
84475
+ machine: source?.machine,
83860
84476
  supportsTools: lookupModelCapabilities(c.id)?.supportsTools ?? source?.supportsTools ?? true,
83861
84477
  isFree: flatRate,
83862
84478
  source: displayName
@@ -87577,24 +88193,24 @@ var init_branding = __esm(() => {
87577
88193
  });
87578
88194
 
87579
88195
  // src/update-checker.ts
87580
- import { existsSync as existsSync32, mkdirSync as mkdirSync21, readFileSync as readFileSync36, unlinkSync as unlinkSync9, writeFileSync as writeFileSync17 } from "fs";
87581
- import { homedir as homedir36, platform as platform2, tmpdir } from "os";
87582
- import { join as join44 } from "path";
88196
+ import { existsSync as existsSync32, mkdirSync as mkdirSync22, readFileSync as readFileSync37, unlinkSync as unlinkSync9, writeFileSync as writeFileSync18 } from "fs";
88197
+ import { homedir as homedir37, platform as platform2, tmpdir } from "os";
88198
+ import { join as join45 } from "path";
87583
88199
  function getCacheFilePath() {
87584
88200
  let cacheDir;
87585
88201
  if (isWindows) {
87586
- const localAppData = process.env.LOCALAPPDATA || join44(homedir36(), "AppData", "Local");
87587
- cacheDir = join44(localAppData, "claudish");
88202
+ const localAppData = process.env.LOCALAPPDATA || join45(homedir37(), "AppData", "Local");
88203
+ cacheDir = join45(localAppData, "claudish");
87588
88204
  } else {
87589
- cacheDir = join44(homedir36(), ".cache", "claudish");
88205
+ cacheDir = join45(homedir37(), ".cache", "claudish");
87590
88206
  }
87591
88207
  try {
87592
88208
  if (!existsSync32(cacheDir)) {
87593
- mkdirSync21(cacheDir, { recursive: true });
88209
+ mkdirSync22(cacheDir, { recursive: true });
87594
88210
  }
87595
- return join44(cacheDir, "update-check.json");
88211
+ return join45(cacheDir, "update-check.json");
87596
88212
  } catch {
87597
- return join44(tmpdir(), "claudish-update-check.json");
88213
+ return join45(tmpdir(), "claudish-update-check.json");
87598
88214
  }
87599
88215
  }
87600
88216
  function readCache2() {
@@ -87603,7 +88219,7 @@ function readCache2() {
87603
88219
  if (!existsSync32(cachePath)) {
87604
88220
  return null;
87605
88221
  }
87606
- const data = JSON.parse(readFileSync36(cachePath, "utf-8"));
88222
+ const data = JSON.parse(readFileSync37(cachePath, "utf-8"));
87607
88223
  return data;
87608
88224
  } catch {
87609
88225
  return null;
@@ -87616,7 +88232,7 @@ function writeCache2(latestVersion) {
87616
88232
  lastCheck: Date.now(),
87617
88233
  latestVersion
87618
88234
  };
87619
- writeFileSync17(cachePath, JSON.stringify(data), "utf-8");
88235
+ writeFileSync18(cachePath, JSON.stringify(data), "utf-8");
87620
88236
  } catch {}
87621
88237
  }
87622
88238
  function isCacheValid(cache) {
@@ -92569,6 +93185,13 @@ class LocalTransport {
92569
93185
  streamFormat = "openai-sse";
92570
93186
  config;
92571
93187
  modelName;
93188
+ lmStudioDevice;
93189
+ lmStudioInstance;
93190
+ lmStudioPlacedAt;
93191
+ lmStudioPlacementError;
93192
+ unplacedErrors = new Map;
93193
+ unplacedCount = 0;
93194
+ probeLeases = new Set;
92572
93195
  concurrency;
92573
93196
  healthChecked = false;
92574
93197
  isHealthy = false;
@@ -92578,17 +93201,21 @@ class LocalTransport {
92578
93201
  _isOllamaBackend;
92579
93202
  constructor(config, modelName, options) {
92580
93203
  this.config = config;
92581
- this.modelName = modelName;
93204
+ if (config.name === "lmstudio") {
93205
+ const { model, device } = splitLMStudioDevice(modelName);
93206
+ this.modelName = model;
93207
+ this.lmStudioDevice = device;
93208
+ } else {
93209
+ this.modelName = modelName;
93210
+ }
92582
93211
  this.name = config.name;
92583
93212
  this.displayName = DISPLAY_NAMES2[config.name] || "Local";
92584
93213
  this.concurrency = options?.concurrency;
92585
- const envContextWindow = process.env.CLAUDISH_CONTEXT_WINDOW;
92586
- if (envContextWindow) {
92587
- const parsed = Number.parseInt(envContextWindow, 10);
92588
- if (!Number.isNaN(parsed) && parsed > 0) {
92589
- this._contextWindow = parsed;
92590
- log(`[${this.displayName}] Context window from env: ${this._contextWindow}`);
92591
- }
93214
+ this._contextWindow = getProviderByName(config.name)?.unknownContextWindow ?? 32768;
93215
+ const limit = contextWindowLimit();
93216
+ if (limit !== undefined) {
93217
+ this._contextWindow = limit;
93218
+ log(`[${this.displayName}] Context window limit: ${limit}`);
92592
93219
  }
92593
93220
  if (this.concurrency !== undefined) {
92594
93221
  log(`[${this.displayName}] Concurrency: ${this.concurrency === 0 ? "unlimited" : this.concurrency}`);
@@ -92635,6 +93262,16 @@ class LocalTransport {
92635
93262
  };
92636
93263
  }
92637
93264
  async getExtraPayloadFields() {
93265
+ if (this.lmStudioDevice) {
93266
+ this.lmStudioPlacementError = undefined;
93267
+ try {
93268
+ return { model: (await this.placeOnDevice()).instanceId };
93269
+ } catch (error) {
93270
+ this.lmStudioPlacementError = error;
93271
+ this.lmStudioInstance = undefined;
93272
+ return { model: this.markUnplaced(error) };
93273
+ }
93274
+ }
92638
93275
  if (await this.isOllamaBackend()) {
92639
93276
  const numCtx = Math.max(this._contextWindow, 32768);
92640
93277
  log(`[${this.displayName}] Setting num_ctx: ${numCtx} (detected: ${this._contextWindow})`);
@@ -92648,15 +93285,96 @@ class LocalTransport {
92648
93285
  return LocalModelQueue.getInstance().enqueue(fetchFn, this.name, this.concurrency, opts?.signal);
92649
93286
  }
92650
93287
  async refreshAuth() {
92651
- if (this.healthChecked)
93288
+ const lease = acquireSigningLease();
93289
+ this.probeLeases.add(lease);
93290
+ try {
93291
+ await this.refreshAuthUnderLease();
93292
+ } finally {
93293
+ this.probeLeases.delete(lease);
93294
+ lease.release();
93295
+ }
93296
+ }
93297
+ async refreshAuthUnderLease() {
93298
+ if (this.healthChecked) {
93299
+ await this.confirmPlacement();
92652
93300
  return;
93301
+ }
92653
93302
  const healthy = await this.checkHealth();
92654
93303
  if (!healthy) {
93304
+ if (this.lmStudioPlacementError !== undefined) {
93305
+ this.lmStudioPlacementError = new Error(`LM Studio was not reachable when this request was built, so ${this.modelName} was not placed on ${this.lmStudioDevice}. Send the message again.`);
93306
+ }
92655
93307
  throw Object.assign(new Error(this.getConnectionErrorMessage(), {
92656
93308
  cause: this.lastProbeError
92657
93309
  }), { claudishEndpoint: this.lastProbeUrl ?? this.config.baseUrl });
92658
93310
  }
92659
93311
  await this.fetchContextWindow();
93312
+ await this.confirmPlacement();
93313
+ }
93314
+ placeOnDevice() {
93315
+ const placedAt = this.lmStudioPlacedAt;
93316
+ if (this.lmStudioInstance && placedAt !== undefined && Date.now() - placedAt > PLACEMENT_RECHECK_MS) {
93317
+ this.lmStudioInstance = undefined;
93318
+ }
93319
+ if (this.lmStudioInstance)
93320
+ return this.lmStudioInstance;
93321
+ this.lmStudioPlacedAt = undefined;
93322
+ const pending = this.getHeaders().then((headers) => ensureLMStudioInstance({
93323
+ baseUrl: this.config.baseUrl,
93324
+ model: this.modelName,
93325
+ device: this.lmStudioDevice,
93326
+ contextLength: contextWindowLimit() ?? getProviderByName(this.config.name)?.unknownContextWindow,
93327
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
93328
+ log
93329
+ })).then((instance) => {
93330
+ if (this.lmStudioInstance === pending)
93331
+ this.lmStudioPlacedAt = Date.now();
93332
+ return instance;
93333
+ });
93334
+ this.lmStudioInstance = pending;
93335
+ return pending;
93336
+ }
93337
+ async confirmPlacement() {
93338
+ if (!this.lmStudioDevice)
93339
+ return;
93340
+ if (this.lmStudioPlacementError !== undefined) {
93341
+ const error = this.lmStudioPlacementError;
93342
+ if (classifyConnectionError(error) === null)
93343
+ throw error;
93344
+ throw new Error(`LM Studio could not be reached while ${this.modelName} was placed on ${this.lmStudioDevice}. Send the message again.`);
93345
+ }
93346
+ let instance;
93347
+ try {
93348
+ instance = await this.placeOnDevice();
93349
+ } catch (error) {
93350
+ this.lmStudioInstance = undefined;
93351
+ throw error;
93352
+ }
93353
+ if (instance.contextLength) {
93354
+ this._contextWindow = Math.min(instance.contextLength, contextWindowLimit() ?? instance.contextLength);
93355
+ }
93356
+ }
93357
+ markUnplaced(error) {
93358
+ const marker = `${this.modelName}~${this.lmStudioDevice} (not placed #${++this.unplacedCount})`;
93359
+ this.unplacedErrors.set(marker, error);
93360
+ while (this.unplacedErrors.size > MAX_UNPLACED_ERRORS) {
93361
+ const oldest = this.unplacedErrors.keys().next().value;
93362
+ if (oldest === undefined)
93363
+ break;
93364
+ this.unplacedErrors.delete(oldest);
93365
+ }
93366
+ return marker;
93367
+ }
93368
+ transformPayload(payload) {
93369
+ const model = payload?.model;
93370
+ if (typeof model !== "string" || !model.endsWith(")") || !model.includes(" (not placed #")) {
93371
+ return payload;
93372
+ }
93373
+ const error = this.unplacedErrors.get(model);
93374
+ this.unplacedErrors.delete(model);
93375
+ if (error !== undefined && classifyConnectionError(error) === null)
93376
+ throw error;
93377
+ throw new Error(`LM Studio could not be reached while ${this.modelName} was placed on ${this.lmStudioDevice}. Send the message again.`);
92660
93378
  }
92661
93379
  getContextWindow() {
92662
93380
  return this._contextWindow;
@@ -92674,6 +93392,7 @@ class LocalTransport {
92674
93392
  try {
92675
93393
  const response = await fetch(`${this.config.baseUrl}/api/tags`, {
92676
93394
  method: "GET",
93395
+ headers: await this.probeHeaders(),
92677
93396
  signal: AbortSignal.timeout(5000)
92678
93397
  });
92679
93398
  this._isOllamaBackend = await hasOllamaTagsShape(response);
@@ -92683,6 +93402,13 @@ class LocalTransport {
92683
93402
  log(`[${this.displayName}] Ollama backend probe (${this.config.baseUrl}): ${this._isOllamaBackend}`);
92684
93403
  return this._isOllamaBackend;
92685
93404
  }
93405
+ async probeHeaders() {
93406
+ const headers = await this.getHeaders().catch(() => ({}));
93407
+ const values = credentialValuesFromRequest(headers);
93408
+ for (const lease of this.probeLeases)
93409
+ lease.add(values);
93410
+ return headers;
93411
+ }
92686
93412
  async checkHealth() {
92687
93413
  if (this.healthChecked)
92688
93414
  return this.isHealthy;
@@ -92693,6 +93419,7 @@ class LocalTransport {
92693
93419
  log(`[${this.displayName}] Trying health check: ${healthUrl}`);
92694
93420
  const response = await fetch(healthUrl, {
92695
93421
  method: "GET",
93422
+ headers: await this.probeHeaders(),
92696
93423
  signal: AbortSignal.timeout(5000)
92697
93424
  });
92698
93425
  this._isOllamaBackend ??= await hasOllamaTagsShape(response);
@@ -92713,6 +93440,7 @@ class LocalTransport {
92713
93440
  log(`[${this.displayName}] Trying health check: ${modelsUrl}`);
92714
93441
  const response = await fetch(modelsUrl, {
92715
93442
  method: "GET",
93443
+ headers: await this.probeHeaders(),
92716
93444
  signal: AbortSignal.timeout(5000)
92717
93445
  });
92718
93446
  if (response.ok) {
@@ -92732,11 +93460,13 @@ class LocalTransport {
92732
93460
  return false;
92733
93461
  }
92734
93462
  async fetchContextWindow() {
92735
- if (process.env.CLAUDISH_CONTEXT_WINDOW)
93463
+ if (contextWindowLimit() !== undefined)
92736
93464
  return;
92737
93465
  log(`[${this.displayName}] Fetching context window...`);
92738
93466
  if (await this.isOllamaBackend()) {
92739
93467
  await this.fetchOllamaContextWindow();
93468
+ } else if (this.lmStudioDevice) {
93469
+ log(`[${this.displayName}] Context window comes from the instance on ${this.lmStudioDevice}`);
92740
93470
  } else if (this.config.name === "lmstudio") {
92741
93471
  await this.fetchLMStudioContextWindow();
92742
93472
  } else {
@@ -92747,7 +93477,7 @@ class LocalTransport {
92747
93477
  try {
92748
93478
  const response = await fetch(`${this.config.baseUrl}/api/show`, {
92749
93479
  method: "POST",
92750
- headers: { "Content-Type": "application/json" },
93480
+ headers: { "Content-Type": "application/json", ...await this.probeHeaders() },
92751
93481
  body: JSON.stringify({ name: this.modelName }),
92752
93482
  signal: AbortSignal.timeout(3000)
92753
93483
  });
@@ -92778,8 +93508,9 @@ class LocalTransport {
92778
93508
  }
92779
93509
  async fetchLMStudioContextWindow() {
92780
93510
  try {
92781
- const response = await fetch(`${this.config.baseUrl}/v1/models`, {
93511
+ const response = await fetch(`${this.config.baseUrl}/api/v0/models`, {
92782
93512
  method: "GET",
93513
+ headers: await this.probeHeaders(),
92783
93514
  signal: AbortSignal.timeout(3000)
92784
93515
  });
92785
93516
  if (response.ok) {
@@ -92787,19 +93518,21 @@ class LocalTransport {
92787
93518
  log(`[${this.displayName}] Models response: ${JSON.stringify(data).slice(0, 500)}`);
92788
93519
  const models = data.data || [];
92789
93520
  const targetModel = models.find((m) => m.id === this.modelName) || models.find((m) => m.id?.endsWith(`/${this.modelName}`)) || models.find((m) => this.modelName.includes(m.id));
92790
- if (targetModel) {
92791
- const ctxLength = targetModel.context_length || targetModel.max_context_length || targetModel.context_window || targetModel.max_tokens;
92792
- if (ctxLength && typeof ctxLength === "number") {
92793
- this._contextWindow = ctxLength;
92794
- log(`[${this.displayName}] Context window from model: ${this._contextWindow}`);
92795
- return;
92796
- }
93521
+ const ctxLength = targetModel?.loaded_context_length;
93522
+ if (typeof ctxLength === "number" && ctxLength > 0) {
93523
+ this._contextWindow = ctxLength;
93524
+ log(`[${this.displayName}] Context window from model: ${this._contextWindow}`);
93525
+ return;
93526
+ }
93527
+ const maxLength = targetModel?.max_context_length;
93528
+ if (typeof maxLength === "number" && maxLength > 0 && maxLength < this._contextWindow) {
93529
+ this._contextWindow = maxLength;
93530
+ log(`[${this.displayName}] Context window from model maximum: ${maxLength}`);
93531
+ return;
92797
93532
  }
92798
- this._contextWindow = 32768;
92799
93533
  log(`[${this.displayName}] Using default context window: ${this._contextWindow}`);
92800
93534
  }
92801
93535
  } catch (e) {
92802
- this._contextWindow = 32768;
92803
93536
  log(`[${this.displayName}] Failed to fetch model info: ${e?.message || e}. Using default: ${this._contextWindow}`);
92804
93537
  }
92805
93538
  }
@@ -92816,12 +93549,17 @@ class LocalTransport {
92816
93549
  }
92817
93550
  }
92818
93551
  }
92819
- var localProviderAgent, DISPLAY_NAMES2;
93552
+ var MAX_UNPLACED_ERRORS = 64, localProviderAgent, DISPLAY_NAMES2, PLACEMENT_RECHECK_MS = 1e4;
92820
93553
  var init_local = __esm(() => {
92821
93554
  init_authority();
93555
+ init_call_context();
92822
93556
  init_connection_error();
92823
93557
  init_local_queue();
92824
93558
  init_logger();
93559
+ init_lmstudio_devices();
93560
+ init_provider_definitions();
93561
+ init_redact();
93562
+ init_context_window_limit();
92825
93563
  init_probe_discovery();
92826
93564
  localProviderAgent = new Agent({
92827
93565
  headersTimeout: 600000,
@@ -94064,9 +94802,9 @@ var init_response_seam = __esm(() => {
94064
94802
  });
94065
94803
 
94066
94804
  // src/services/pricing-cache.ts
94067
- import { existsSync as existsSync33, readFileSync as readFileSync37, statSync as statSync15 } from "fs";
94068
- import { homedir as homedir37 } from "os";
94069
- import { join as join45 } from "path";
94805
+ import { existsSync as existsSync33, readFileSync as readFileSync38, statSync as statSync16 } from "fs";
94806
+ import { homedir as homedir38 } from "os";
94807
+ import { join as join46 } from "path";
94070
94808
  function prefixMatch(modelName) {
94071
94809
  for (const [key, pricing] of pricingMap) {
94072
94810
  if (modelName.startsWith(key))
@@ -94106,10 +94844,10 @@ function loadDiskCache() {
94106
94844
  try {
94107
94845
  if (!existsSync33(CACHE_FILE))
94108
94846
  return false;
94109
- const stat = statSync15(CACHE_FILE);
94847
+ const stat = statSync16(CACHE_FILE);
94110
94848
  const age = Date.now() - stat.mtimeMs;
94111
94849
  const isFresh = age < CACHE_TTL_MS5;
94112
- const raw = readFileSync37(CACHE_FILE, "utf-8");
94850
+ const raw = readFileSync38(CACHE_FILE, "utf-8");
94113
94851
  const data = JSON.parse(raw);
94114
94852
  for (const [key, pricing] of Object.entries(data)) {
94115
94853
  pricingMap.set(key, pricing);
@@ -94126,14 +94864,14 @@ var init_pricing_cache = __esm(() => {
94126
94864
  init_logger();
94127
94865
  init_catalog_query();
94128
94866
  pricingMap = new Map;
94129
- CACHE_DIR = join45(homedir37(), ".claudish");
94130
- CACHE_FILE = join45(CACHE_DIR, "pricing-cache.json");
94867
+ CACHE_DIR = join46(homedir38(), ".claudish");
94868
+ CACHE_FILE = join46(CACHE_DIR, "pricing-cache.json");
94131
94869
  CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
94132
94870
  });
94133
94871
 
94134
94872
  // src/proxy-server.ts
94135
- import { appendFileSync as appendFileSync6, mkdirSync as mkdirSync22 } from "fs";
94136
- import { join as join46 } from "path";
94873
+ import { appendFileSync as appendFileSync6, mkdirSync as mkdirSync23 } from "fs";
94874
+ import { join as join47 } from "path";
94137
94875
  function isTerminalRoutingFailure(e) {
94138
94876
  return e instanceof RoutingError;
94139
94877
  }
@@ -94141,9 +94879,9 @@ function maybeCaptureClassifierRequest(c, body) {
94141
94879
  if (!process.env.CLAUDISH_CLASSIFIER_DEBUG)
94142
94880
  return;
94143
94881
  try {
94144
- const dir = join46(process.cwd(), "logs");
94882
+ const dir = join47(process.cwd(), "logs");
94145
94883
  if (!classifierCaptureDirReady) {
94146
- mkdirSync22(dir, { recursive: true });
94884
+ mkdirSync23(dir, { recursive: true });
94147
94885
  classifierCaptureDirReady = true;
94148
94886
  }
94149
94887
  const record = {
@@ -94166,7 +94904,7 @@ function maybeCaptureClassifierRequest(c, body) {
94166
94904
  "x-api-key": c.req.header("x-api-key") ? "<present>" : null
94167
94905
  }
94168
94906
  };
94169
- appendFileSync6(join46(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
94907
+ appendFileSync6(join47(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
94170
94908
  `);
94171
94909
  } catch {}
94172
94910
  }
@@ -94686,28 +95424,28 @@ var init_proxy_server = __esm(() => {
94686
95424
  import {
94687
95425
  copyFileSync as copyFileSync2,
94688
95426
  existsSync as existsSync34,
94689
- mkdirSync as mkdirSync23,
94690
- readFileSync as readFileSync38,
94691
- readdirSync as readdirSync7,
95427
+ mkdirSync as mkdirSync24,
95428
+ readFileSync as readFileSync39,
95429
+ readdirSync as readdirSync8,
94692
95430
  unlinkSync as unlinkSync10
94693
95431
  } from "fs";
94694
- import { homedir as homedir38 } from "os";
94695
- import { dirname as dirname18, join as join47 } from "path";
95432
+ import { homedir as homedir39 } from "os";
95433
+ import { dirname as dirname19, join as join48 } from "path";
94696
95434
  import { fileURLToPath as fileURLToPath2 } from "url";
94697
95435
  function getVersion3() {
94698
95436
  return VERSION;
94699
95437
  }
94700
95438
  function clearAllModelCaches() {
94701
- const cacheDir = join47(homedir38(), ".claudish");
95439
+ const cacheDir = join48(homedir39(), ".claudish");
94702
95440
  if (!existsSync34(cacheDir))
94703
95441
  return;
94704
95442
  const cachePatterns = ["pricing-cache.json", "recommended-models-cache-v2.json"];
94705
95443
  let cleared = 0;
94706
95444
  try {
94707
- const files = readdirSync7(cacheDir);
95445
+ const files = readdirSync8(cacheDir);
94708
95446
  for (const file of files) {
94709
95447
  if (cachePatterns.includes(file)) {
94710
- unlinkSync10(join47(cacheDir, file));
95448
+ unlinkSync10(join48(cacheDir, file));
94711
95449
  cleared++;
94712
95450
  }
94713
95451
  }
@@ -95045,6 +95783,13 @@ async function parseArgs(args) {
95045
95783
  process.exit(1);
95046
95784
  }
95047
95785
  config.effortOverride = effArg;
95786
+ } else if (arg === "--context-window") {
95787
+ const size = parseContextWindow(args[++i] ?? "");
95788
+ if (size === undefined) {
95789
+ console.error("--context-window requires a size in tokens (128000, 128k or 1m)");
95790
+ process.exit(1);
95791
+ }
95792
+ config.contextWindow = size;
95048
95793
  } else if (arg === "--pro-on-ultracode") {
95049
95794
  config.proOnUltracode = true;
95050
95795
  } else if (arg === "--no-pro-on-ultracode") {
@@ -95989,6 +96734,7 @@ ${h("OPTIONS")}
95989
96734
  ${green("--advisor")} ${yellow('"m1,m2[:collector]"')} Multi-model advisor replacement (works with any --model)
95990
96735
  ${green("--model-params")} ${yellow('"k=v,..."')} Extra request params merged into the payload (e.g. reasoning.mode=pro)
95991
96736
  ${green("--effort-override")} ${yellow("<level>")} Pin reasoning effort verbatim, skipping the per-model clamp
96737
+ ${green("--context-window")} ${yellow("<size>")} Largest context window (128000, 128k, 1m), for local models
95992
96738
  ${green("--pro-on-ultracode")} Apply the model's catalog preset while in ultracode (opt-in)
95993
96739
  ${green("--no-pro-on-ultracode")} Force that off for this run (when enabled in config/env)
95994
96740
  ${green("--code-mode")} ${yellow("<auto|on|off>")} cx@ tools as one exec script tool (default auto; env CLAUDISH_CODE_MODE)
@@ -96234,8 +96980,8 @@ ${h("MORE INFO")}
96234
96980
  }
96235
96981
  function printAIAgentGuide() {
96236
96982
  try {
96237
- const guidePath = join47(__dirname2, "../AI_AGENT_GUIDE.md");
96238
- const guideContent = readFileSync38(guidePath, "utf-8");
96983
+ const guidePath = join48(__dirname2, "../AI_AGENT_GUIDE.md");
96984
+ const guideContent = readFileSync39(guidePath, "utf-8");
96239
96985
  console.log(guideContent);
96240
96986
  } catch (error) {
96241
96987
  console.error("Error reading AI Agent Guide:");
@@ -96251,10 +96997,10 @@ async function initializeClaudishSkill() {
96251
96997
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
96252
96998
  `);
96253
96999
  const cwd = process.cwd();
96254
- const claudeDir = join47(cwd, ".claude");
96255
- const skillsDir = join47(claudeDir, "skills");
96256
- const claudishSkillDir = join47(skillsDir, "claudish-usage");
96257
- const skillFile = join47(claudishSkillDir, "SKILL.md");
97000
+ const claudeDir = join48(cwd, ".claude");
97001
+ const skillsDir = join48(claudeDir, "skills");
97002
+ const claudishSkillDir = join48(skillsDir, "claudish-usage");
97003
+ const skillFile = join48(claudishSkillDir, "SKILL.md");
96258
97004
  if (existsSync34(skillFile)) {
96259
97005
  console.log("\u2705 Claudish skill already installed at:");
96260
97006
  console.log(` ${skillFile}
@@ -96262,7 +97008,7 @@ async function initializeClaudishSkill() {
96262
97008
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
96263
97009
  return;
96264
97010
  }
96265
- const sourceSkillPath = join47(__dirname2, "../skills/claudish-usage/SKILL.md");
97011
+ const sourceSkillPath = join48(__dirname2, "../skills/claudish-usage/SKILL.md");
96266
97012
  if (!existsSync34(sourceSkillPath)) {
96267
97013
  console.error("\u274C Error: Claudish skill file not found in installation.");
96268
97014
  console.error(` Expected at: ${sourceSkillPath}`);
@@ -96273,15 +97019,15 @@ async function initializeClaudishSkill() {
96273
97019
  }
96274
97020
  try {
96275
97021
  if (!existsSync34(claudeDir)) {
96276
- mkdirSync23(claudeDir, { recursive: true });
97022
+ mkdirSync24(claudeDir, { recursive: true });
96277
97023
  console.log("\uD83D\uDCC1 Created .claude/ directory");
96278
97024
  }
96279
97025
  if (!existsSync34(skillsDir)) {
96280
- mkdirSync23(skillsDir, { recursive: true });
97026
+ mkdirSync24(skillsDir, { recursive: true });
96281
97027
  console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
96282
97028
  }
96283
97029
  if (!existsSync34(claudishSkillDir)) {
96284
- mkdirSync23(claudishSkillDir, { recursive: true });
97030
+ mkdirSync24(claudishSkillDir, { recursive: true });
96285
97031
  console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
96286
97032
  }
96287
97033
  copyFileSync2(sourceSkillPath, skillFile);
@@ -96353,6 +97099,7 @@ var init_cli = __esm(() => {
96353
97099
  init_api_key_map();
96354
97100
  init_api_key_provenance();
96355
97101
  init_claude_code_aliases();
97102
+ init_context_window_limit();
96356
97103
  init_endpoint_registration();
96357
97104
  init_muse_credentials();
96358
97105
  init_model_parser();
@@ -96367,7 +97114,7 @@ var init_cli = __esm(() => {
96367
97114
  init_ansi();
96368
97115
  init_provider_resolver();
96369
97116
  __filename2 = fileURLToPath2(import.meta.url);
96370
- __dirname2 = dirname18(__filename2);
97117
+ __dirname2 = dirname19(__filename2);
96371
97118
  CLAUDISH_FLAG_ARITY = {
96372
97119
  "--model": "value",
96373
97120
  "-m": "value",
@@ -96409,6 +97156,7 @@ var init_cli = __esm(() => {
96409
97156
  "--classifier-provider": "value",
96410
97157
  "--model-params": "value",
96411
97158
  "--effort-override": "value",
97159
+ "--context-window": "value",
96412
97160
  "--pro-on-ultracode": "none",
96413
97161
  "--no-pro-on-ultracode": "none",
96414
97162
  "--code-mode": "value",
@@ -96485,9 +97233,9 @@ function samePaneSize(a, b) {
96485
97233
  var DEFAULT_PANE_COLS = 160, DEFAULT_PANE_ROWS = 50, MIN_PANE_COLS = 40, MAX_PANE_COLS = 9999, MIN_PANE_ROWS = 24, MAX_PANE_ROWS = 9999, MAX_PANE_CELLS = 4000000, RESIZE_QUIET_MS = 2000;
96486
97234
 
96487
97235
  // src/pane/process-identity.ts
96488
- import { execFile as execFile4, execFileSync as execFileSync3 } from "child_process";
97236
+ import { execFile as execFile5, execFileSync as execFileSync3 } from "child_process";
96489
97237
  import { lstatSync as lstatSync6 } from "fs";
96490
- import { basename as basename3, dirname as dirname19, isAbsolute as isAbsolute3, join as join48, normalize } from "path";
97238
+ import { basename as basename4, dirname as dirname20, isAbsolute as isAbsolute3, join as join49, normalize } from "path";
96491
97239
  function collapse(s) {
96492
97240
  return s.trim().replace(/\s+/g, " ");
96493
97241
  }
@@ -96698,7 +97446,7 @@ function parseGroupFile(text) {
96698
97446
  return withEscaped(pgid, members, escaped);
96699
97447
  }
96700
97448
  function isLaunchDirPath(root, p) {
96701
- if (dirname19(p) !== root || !LAUNCH_DIR_RE.test(basename3(p)))
97449
+ if (dirname20(p) !== root || !LAUNCH_DIR_RE.test(basename4(p)))
96702
97450
  return false;
96703
97451
  try {
96704
97452
  const st = lstatSync6(p);
@@ -96711,24 +97459,24 @@ function isValidPaneId(id) {
96711
97459
  return PANE_ID_RE.test(id) && !/^\d+$/.test(id);
96712
97460
  }
96713
97461
  function sockPathOf(root, paneId) {
96714
- return join48(root, `magmux-${paneId}.sock`);
97462
+ return join49(root, `magmux-${paneId}.sock`);
96715
97463
  }
96716
97464
  function recordPathOf(root, paneId) {
96717
- return join48(root, "panes", `${paneId}.json`);
97465
+ return join49(root, "panes", `${paneId}.json`);
96718
97466
  }
96719
97467
  function isPaneSockPath(root, p, paneId) {
96720
- return isValidPaneId(paneId) && dirname19(p) === root && basename3(p) === `magmux-${paneId}.sock`;
97468
+ return isValidPaneId(paneId) && dirname20(p) === root && basename4(p) === `magmux-${paneId}.sock`;
96721
97469
  }
96722
97470
  function isPaneRecordPath(root, p, paneId) {
96723
- return isValidPaneId(paneId) && dirname19(p) === join48(root, "panes") && basename3(p) === `${paneId}.json`;
97471
+ return isValidPaneId(paneId) && dirname20(p) === join49(root, "panes") && basename4(p) === `${paneId}.json`;
96724
97472
  }
96725
97473
  function isForkRecordPath(projectsRoot, p, uuid) {
96726
97474
  if (!isAbsolute3(projectsRoot) || normalize(projectsRoot) !== projectsRoot)
96727
97475
  return false;
96728
- if (basename3(projectsRoot) !== "projects" || !FORK_UUID_RE.test(uuid))
97476
+ if (basename4(projectsRoot) !== "projects" || !FORK_UUID_RE.test(uuid))
96729
97477
  return false;
96730
- const dir = dirname19(p);
96731
- return dirname19(dir) === projectsRoot && PROJECT_SLUG_RE.test(basename3(dir)) && basename3(p) === `${uuid}.jsonl`;
97478
+ const dir = dirname20(p);
97479
+ return dirname20(dir) === projectsRoot && PROJECT_SLUG_RE.test(basename4(dir)) && basename4(p) === `${uuid}.jsonl`;
96732
97480
  }
96733
97481
  function watcherArgv(a) {
96734
97482
  const fork = a.fork ? [a.fork.projectsRoot, a.fork.path, a.fork.removeProjectDir ? "1" : "0"] : [];
@@ -96843,7 +97591,7 @@ var init_process_identity = __esm(() => {
96843
97591
  PS_ROW = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(?:((?:\d+-)?(?:\d+:)?\d+:\d+)\s+)?(\S+\s+\S+\s+\d+\s+\d\d:\d\d:\d\d\s+\d{4})\s?(.*)$/;
96844
97592
  PS_ENV = { PATH: "/bin:/usr/bin:/usr/sbin:/sbin", LC_ALL: "C" };
96845
97593
  PS_OPTIONS = { env: PS_ENV, encoding: "utf8", maxBuffer: 64 * 1024 * 1024 };
96846
- psSpawn = { execFile: execFile4, execFileSync: execFileSync3 };
97594
+ psSpawn = { execFile: execFile5, execFileSync: execFileSync3 };
96847
97595
  LAUNCH_DIR_RE = /^launch-[A-Za-z0-9]{6}$/;
96848
97596
  PANE_ID_RE = /^[A-Za-z0-9_-]{1,64}$/;
96849
97597
  FORK_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
@@ -96852,18 +97600,18 @@ var init_process_identity = __esm(() => {
96852
97600
  });
96853
97601
 
96854
97602
  // src/pane/pane-launch.ts
96855
- import { execFile as execFile5, spawn } from "child_process";
97603
+ import { execFile as execFile6, spawn } from "child_process";
96856
97604
  import { randomBytes as randomBytes14 } from "crypto";
96857
97605
  import {
96858
97606
  chmodSync as chmodSync4,
96859
97607
  lstatSync as lstatSync7,
96860
- mkdirSync as mkdirSync24,
97608
+ mkdirSync as mkdirSync25,
96861
97609
  mkdtempSync as mkdtempSync2,
96862
- readFileSync as readFileSync39,
96863
- statSync as statSync16,
96864
- writeFileSync as writeFileSync18
97610
+ readFileSync as readFileSync40,
97611
+ statSync as statSync17,
97612
+ writeFileSync as writeFileSync19
96865
97613
  } from "fs";
96866
- import { join as join49, resolve as resolve5 } from "path";
97614
+ import { join as join50, resolve as resolve5 } from "path";
96867
97615
  function uid() {
96868
97616
  return typeof process.getuid === "function" ? process.getuid() : 0;
96869
97617
  }
@@ -96883,17 +97631,17 @@ function assertPrivateDir(p) {
96883
97631
  function ensureSockRoot(given = sockRootFor()) {
96884
97632
  const root = resolve5(given);
96885
97633
  try {
96886
- mkdirSync24(root, { mode: 448 });
97634
+ mkdirSync25(root, { mode: 448 });
96887
97635
  } catch (e) {
96888
97636
  if (e.code === "ENOENT")
96889
- mkdirSync24(root, { recursive: true, mode: 448 });
97637
+ mkdirSync25(root, { recursive: true, mode: 448 });
96890
97638
  else if (e.code !== "EEXIST")
96891
97639
  throw e;
96892
97640
  }
96893
97641
  assertPrivateDir(root);
96894
- const panes = join49(root, "panes");
97642
+ const panes = join50(root, "panes");
96895
97643
  try {
96896
- mkdirSync24(panes, { mode: 448 });
97644
+ mkdirSync25(panes, { mode: 448 });
96897
97645
  } catch (e) {
96898
97646
  if (e.code !== "EEXIST")
96899
97647
  throw e;
@@ -96945,7 +97693,7 @@ function buildPaneEnv(input) {
96945
97693
  if ((input.platform ?? process.platform) === "linux" && entryBytes > LINUX_ENV_STRING_LIMIT)
96946
97694
  throw new PaneEnvTooLargeError(`pane environment snapshot is ${entryBytes} bytes, over Linux's 131072-byte limit per variable`);
96947
97695
  env[ENV.CLAUDISH_PANE_ENV] = json;
96948
- env.SHELL = join49(input.ctlDir, "sh-shim");
97696
+ env.SHELL = join50(input.ctlDir, "sh-shim");
96949
97697
  return { magmuxEnv: env };
96950
97698
  }
96951
97699
  function buildReplayEnv(input) {
@@ -96957,7 +97705,7 @@ function buildReplayEnv(input) {
96957
97705
  }
96958
97706
  if (input.configDirOverride)
96959
97707
  env.CLAUDE_CONFIG_DIR = input.configDirOverride;
96960
- env.SHELL = join49(input.ctlDir, "sh-shim");
97708
+ env.SHELL = join50(input.ctlDir, "sh-shim");
96961
97709
  env[ENV.CLAUDISH_PANE_CHILD] = "1";
96962
97710
  env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
96963
97711
  env.CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL = "1";
@@ -96990,10 +97738,10 @@ function replaySettingsJson(statusLine) {
96990
97738
  }
96991
97739
  function readUserStatusLine(configDir) {
96992
97740
  try {
96993
- const path = join49(configDir, "settings.json");
96994
- if (statSync16(path).size > MAX_USER_SETTINGS_BYTES)
97741
+ const path = join50(configDir, "settings.json");
97742
+ if (statSync17(path).size > MAX_USER_SETTINGS_BYTES)
96995
97743
  return null;
96996
- const v = JSON.parse(readFileSync39(path, "utf8"))?.statusLine;
97744
+ const v = JSON.parse(readFileSync40(path, "utf8"))?.statusLine;
96997
97745
  return v && typeof v === "object" && !Array.isArray(v) ? v : null;
96998
97746
  } catch {
96999
97747
  return null;
@@ -97175,7 +97923,7 @@ function runMagmuxVersion(found, timeoutMs) {
97175
97923
  rejectRun(new MagmuxUnavailableError(`magmux_unavailable: ${found} --version failed: ${detail}`));
97176
97924
  };
97177
97925
  try {
97178
- child = execFile5(found, ["--version"], { encoding: "utf8" }, (error, stdout, stderr) => {
97926
+ child = execFile6(found, ["--version"], { encoding: "utf8" }, (error, stdout, stderr) => {
97179
97927
  if (error)
97180
97928
  return fail(error.message);
97181
97929
  if (settle())
@@ -97210,21 +97958,21 @@ function replayLauncherScript(realShell, cwd, launch, argv) {
97210
97958
  ${launcherScript(cwd, launch, argv)}`;
97211
97959
  }
97212
97960
  function paneCommand(ctlDir) {
97213
- const cmd = `. ${shq2(join49(ctlDir, "pane-launch.sh"))}`;
97961
+ const cmd = `. ${shq2(join50(ctlDir, "pane-launch.sh"))}`;
97214
97962
  if (/claude /.test(cmd) || /claude$/.test(cmd) || /(^|\/)claude['"]?$/.test(cmd))
97215
97963
  throw new Error(`pane command would attach magmux's Claude Code controller: ${cmd}`);
97216
97964
  return cmd;
97217
97965
  }
97218
97966
  function createLaunchDirs(root) {
97219
- const ctlDir = mkdtempSync2(join49(root, "launch-"));
97967
+ const ctlDir = mkdtempSync2(join50(root, "launch-"));
97220
97968
  chmodSync4(ctlDir, 448);
97221
- const turnDir = mkdtempSync2(join49(root, "launch-"));
97969
+ const turnDir = mkdtempSync2(join50(root, "launch-"));
97222
97970
  chmodSync4(turnDir, 448);
97223
97971
  return { ctlDir, turnDir };
97224
97972
  }
97225
97973
  function writeLauncherFiles(ctlDir, script) {
97226
- writeFileSync18(join49(ctlDir, "pane-launch.sh"), script, { mode: 384, flag: "wx" });
97227
- writeFileSync18(join49(ctlDir, "sh-shim"), SHELL_SHIM, { mode: 448, flag: "wx" });
97974
+ writeFileSync19(join50(ctlDir, "pane-launch.sh"), script, { mode: 384, flag: "wx" });
97975
+ writeFileSync19(join50(ctlDir, "sh-shim"), SHELL_SHIM, { mode: 448, flag: "wx" });
97228
97976
  }
97229
97977
  function spawnPaneWatcher(args) {
97230
97978
  const proc = spawn("/bin/sh", watcherArgv(args), {
@@ -97989,18 +98737,18 @@ import {
97989
98737
  chmodSync as chmodSync5,
97990
98738
  closeSync as closeSync13,
97991
98739
  existsSync as existsSync36,
97992
- mkdirSync as mkdirSync25,
98740
+ mkdirSync as mkdirSync26,
97993
98741
  mkdtempSync as mkdtempSync3,
97994
98742
  openSync as openSync13,
97995
- readFileSync as readFileSync40,
97996
- readdirSync as readdirSync8,
97997
- rmSync as rmSync11,
97998
- statSync as statSync17,
98743
+ readFileSync as readFileSync41,
98744
+ readdirSync as readdirSync9,
98745
+ rmSync as rmSync12,
98746
+ statSync as statSync18,
97999
98747
  unlinkSync as unlinkSync11,
98000
- writeFileSync as writeFileSync19
98748
+ writeFileSync as writeFileSync20
98001
98749
  } from "fs";
98002
- import { homedir as homedir39, tmpdir as tmpdir2 } from "os";
98003
- import { dirname as dirname20, join as join50 } from "path";
98750
+ import { homedir as homedir40, tmpdir as tmpdir2 } from "os";
98751
+ import { dirname as dirname21, join as join51 } from "path";
98004
98752
  import { isatty } from "tty";
98005
98753
  function releaseTerminalIsolation() {
98006
98754
  if (!restoreTerminal)
@@ -98078,7 +98826,7 @@ function hasResolvableAnthropicAuth(deps = {}) {
98078
98826
  if (isRealAnthropicEnvCredential(env, "ANTHROPIC_API_KEY") || isRealAnthropicEnvCredential(env, "ANTHROPIC_AUTH_TOKEN")) {
98079
98827
  return true;
98080
98828
  }
98081
- if (fileExists(join50(homedir39(), ".claude", ".credentials.json")))
98829
+ if (fileExists(join51(homedir40(), ".claude", ".credentials.json")))
98082
98830
  return true;
98083
98831
  return keychainProbe();
98084
98832
  }
@@ -98173,15 +98921,15 @@ function settingsAuthSource(settings) {
98173
98921
  return null;
98174
98922
  }
98175
98923
  function readableClaudeSettingsLayers(config, env, deps) {
98176
- const readFile = deps.readFile ?? ((path) => readFileSync40(path, "utf-8"));
98177
- const home = deps.home ?? homedir39();
98924
+ const readFile = deps.readFile ?? ((path) => readFileSync41(path, "utf-8"));
98925
+ const home = deps.home ?? homedir40();
98178
98926
  const cwd = deps.cwd ?? process.cwd();
98179
98927
  const files = [
98180
98928
  managedSettingsPath(),
98181
- join50(home, ".claude", "settings.json"),
98182
- ...env.CLAUDE_CONFIG_DIR ? [join50(env.CLAUDE_CONFIG_DIR, "settings.json")] : [],
98183
- join50(cwd, ".claude", "settings.json"),
98184
- join50(cwd, ".claude", "settings.local.json")
98929
+ join51(home, ".claude", "settings.json"),
98930
+ ...env.CLAUDE_CONFIG_DIR ? [join51(env.CLAUDE_CONFIG_DIR, "settings.json")] : [],
98931
+ join51(cwd, ".claude", "settings.json"),
98932
+ join51(cwd, ".claude", "settings.local.json")
98185
98933
  ];
98186
98934
  const layers = [];
98187
98935
  for (const file of files) {
@@ -98213,14 +98961,14 @@ function readSettingsSource(source, readFile) {
98213
98961
  }
98214
98962
  function managedSettingsPath() {
98215
98963
  if (isWindows2()) {
98216
- return join50(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
98964
+ return join51(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
98217
98965
  }
98218
98966
  if (process.platform === "darwin") {
98219
98967
  return "/Library/Application Support/ClaudeCode/managed-settings.json";
98220
98968
  }
98221
98969
  return "/etc/claude-code/managed-settings.json";
98222
98970
  }
98223
- function managedSettingsForcesClaudeAi(readFile = readFileSync40) {
98971
+ function managedSettingsForcesClaudeAi(readFile = readFileSync41) {
98224
98972
  try {
98225
98973
  const raw = readFile(managedSettingsPath(), "utf-8");
98226
98974
  const parsed = JSON.parse(raw);
@@ -98234,8 +98982,8 @@ function isWindows2() {
98234
98982
  }
98235
98983
  function createStatusLineScript(tokenFilePath) {
98236
98984
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
98237
- const claudishDir = join50(homeDir, ".claudish");
98238
- const scriptPath = join50(claudishDir, `status-${process.pid}-${Date.now()}.js`);
98985
+ const claudishDir = join51(homeDir, ".claudish");
98986
+ const scriptPath = join51(claudishDir, `status-${process.pid}-${Date.now()}.js`);
98239
98987
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
98240
98988
  const light = getThemeMode() === "light";
98241
98989
  const cyanCode = light ? "38;2;14;116;144" : "96";
@@ -98347,6 +99095,8 @@ process.stdin.on('end', () => {
98347
99095
  // gap is the whole reason this line exists.
98348
99096
  const clamped = effWindow < contextWindow ? ' of ' + formatTokens(contextWindow) : '';
98349
99097
  ctxDisplay = '[' + bar + '] ' + formatTokens(inputTokens) + '/' + formatTokens(effWindow) + clamped;
99098
+ } else if (effWindow > 0) {
99099
+ ctxDisplay = '[' + '\u2591'.repeat(15) + '] 0/' + formatTokens(effWindow);
98350
99100
  } else {
98351
99101
  ctxDisplay = ctx + '%';
98352
99102
  }
@@ -98390,13 +99140,13 @@ process.stdin.on('end', () => {
98390
99140
  }
98391
99141
  });
98392
99142
  `;
98393
- writeFileSync19(scriptPath, script, "utf-8");
99143
+ writeFileSync20(scriptPath, script, "utf-8");
98394
99144
  return scriptPath;
98395
99145
  }
98396
99146
  function initializeTokenFile(tokenFilePath) {
98397
99147
  try {
98398
- mkdirSync25(dirname20(tokenFilePath), { recursive: true });
98399
- writeFileSync19(tokenFilePath, JSON.stringify({
99148
+ mkdirSync26(dirname21(tokenFilePath), { recursive: true });
99149
+ writeFileSync20(tokenFilePath, JSON.stringify({
98400
99150
  input_tokens: 0,
98401
99151
  output_tokens: 0,
98402
99152
  total_tokens: 0,
@@ -98411,11 +99161,23 @@ function initializeTokenFile(tokenFilePath) {
98411
99161
  log(`[claude-runner] Could not initialize token file ${tokenFilePath}: ${e}`);
98412
99162
  }
98413
99163
  }
99164
+ function seedTokenFileWindow(tokenFilePath, window2) {
99165
+ if (!window2 || window2 <= 0)
99166
+ return;
99167
+ try {
99168
+ const record = JSON.parse(readFileSync41(tokenFilePath, "utf-8"));
99169
+ if (record.input_tokens !== 0 || record.context_window !== "unknown")
99170
+ return;
99171
+ writeFileSync20(tokenFilePath, JSON.stringify({ ...record, context_window: window2, context_left_percent: 100 }), "utf-8");
99172
+ } catch (e) {
99173
+ log(`[claude-runner] Could not seed token file ${tokenFilePath}: ${e}`);
99174
+ }
99175
+ }
98414
99176
  function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FILE_MS) {
98415
99177
  let removed = 0;
98416
99178
  let entries;
98417
99179
  try {
98418
- entries = readdirSync8(dir);
99180
+ entries = readdirSync9(dir);
98419
99181
  } catch {
98420
99182
  return 0;
98421
99183
  }
@@ -98427,9 +99189,9 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
98427
99189
  if (!name.startsWith("tokens-") || !name.endsWith(".json"))
98428
99190
  continue;
98429
99191
  scanned++;
98430
- const full = join50(dir, name);
99192
+ const full = join51(dir, name);
98431
99193
  try {
98432
- if (statSync17(full).mtimeMs >= cutoff)
99194
+ if (statSync18(full).mtimeMs >= cutoff)
98433
99195
  continue;
98434
99196
  unlinkSync11(full);
98435
99197
  removed++;
@@ -98444,7 +99206,7 @@ function parseSettingsArg(value) {
98444
99206
  if (value.trimStart().startsWith("{")) {
98445
99207
  return JSON.parse(value);
98446
99208
  }
98447
- return JSON.parse(readFileSync40(value, "utf-8"));
99209
+ return JSON.parse(readFileSync41(value, "utf-8"));
98448
99210
  }
98449
99211
  function parseSettingsArgSafe(value) {
98450
99212
  try {
@@ -98456,9 +99218,9 @@ function parseSettingsArgSafe(value) {
98456
99218
  }
98457
99219
  function userSettingsFileCandidates(cwd) {
98458
99220
  return [
98459
- join50(homedir39(), ".claude", "settings.json"),
98460
- join50(cwd, ".claude", "settings.json"),
98461
- join50(cwd, ".claude", "settings.local.json")
99221
+ join51(homedir40(), ".claude", "settings.json"),
99222
+ join51(cwd, ".claude", "settings.json"),
99223
+ join51(cwd, ".claude", "settings.local.json")
98462
99224
  ];
98463
99225
  }
98464
99226
  function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
@@ -98499,11 +99261,11 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
98499
99261
  }
98500
99262
  function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
98501
99263
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
98502
- const claudishDir = join50(homeDir, ".claudish");
99264
+ const claudishDir = join51(homeDir, ".claudish");
98503
99265
  try {
98504
- mkdirSync25(claudishDir, { recursive: true });
99266
+ mkdirSync26(claudishDir, { recursive: true });
98505
99267
  } catch {}
98506
- const tempPath = join50(claudishDir, `settings-${process.pid}-${Date.now()}.json`);
99268
+ const tempPath = join51(claudishDir, `settings-${process.pid}-${Date.now()}.json`);
98507
99269
  const assignedFile = assignedTokenFile(process.env) !== null;
98508
99270
  const tokenFilePath = resolveTokenFilePath(port);
98509
99271
  cleanupStaleTokenFiles(claudishDir);
@@ -98529,7 +99291,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
98529
99291
  const formatTokensBash = `fmt_tok() { local n=\${1:-0}; if [ "$n" -ge 1000000 ]; then echo "$((n/1000000))M"; elif [ "$n" -ge 1000 ]; then echo "$((n/1000))k"; else echo "$n"; fi; }`;
98530
99292
  const effWinBash = `eff_win() { local w=\${1:-0}; local m=\${CLAUDE_CODE_MAX_CONTEXT_TOKENS:-}; local a=\${CLAUDE_CODE_AUTO_COMPACT_WINDOW:-}; case "$m" in ''|*[!0-9]*) m=${CLAUDE_CODE_DEFAULT_MAX_CONTEXT};; esac; case "$a" in ''|*[!0-9]*) a=0;; esac; case "$w" in ''|*[!0-9]*) w=0;; esac; if [ "$w" -gt 0 ]; then if [ "$m" -gt 0 ] && [ "$m" -lt "$w" ]; then w=$m; fi; if [ "$a" -gt 0 ] && [ "$a" -lt "$w" ]; then w=$a; fi; fi; echo "$w"; }`;
98531
99293
  const dirPrelude = `DIR=$(basename "$(pwd)"); [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true; `;
98532
- const readState = `CTX=-1; COST="0"; IS_FREE="false"; IS_EST="false"; PROVIDER=""; TOKEN_MODEL=""; IN_TOK=0; CTX_WIN=0; PLAN_DISPLAY=""; ALLOW_DISPLAY=""; ALLOW_COLOR=""; ${formatTokensBash}; ${effWinBash}; ${fmtAtBash}; if [ -f "${tokenFilePath}" ]; then TOKENS=$(cat "${tokenFilePath}" 2>/dev/null | tr -d '\\n\\r'); V=$(echo "$TOKENS" | grep -o '"context_left_percent": *-\\?[0-9]*' | grep -o '\\-\\?[0-9]*'); [ -n "$V" ] && CTX="$V"; V=$(echo "$TOKENS" | grep -o '"total_cost": *[0-9.]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && COST="$V"; V=$(echo "$TOKENS" | grep -o '"input_tokens": *[0-9]*' | grep -o '[0-9]*'); [ -n "$V" ] && IN_TOK="$V"; V=$(echo "$TOKENS" | grep -o '"context_window": *[0-9]*' | grep -o '[0-9]*'); [ -n "$V" ] && CTX_WIN="$V"; V=$(echo "$TOKENS" | grep -o '"is_free": *[a-z]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && IS_FREE="$V"; V=$(echo "$TOKENS" | grep -o '"is_estimated": *[a-z]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && IS_EST="$V"; V=$(echo "$TOKENS" | grep -o '"provider_name": *"[^"]*"' | cut -d'"' -f4); [ -n "$V" ] && PROVIDER="$V"; V=$(echo "$TOKENS" | grep -o '"model_name": *"[^"]*"' | cut -d'"' -f4); [ -n "$V" ] && TOKEN_MODEL="$V"; ${readPlanBash} ${readAllowanceBash} fi; if [ "$CLAUDISH_IS_LOCAL" = "true" ]; then COST_DISPLAY="LOCAL"; elif [ "$IS_FREE" = "true" ]; then COST_DISPLAY="FREE"; elif [ "$IS_EST" = "true" ]; then COST_DISPLAY=$(printf "~\\$%.3f" "$COST"); else COST_DISPLAY=$(printf "\\$%.3f" "$COST"); fi; MODEL_DISPLAY="\${TOKEN_MODEL:-$CLAUDISH_ACTIVE_MODEL_NAME}"; if [ -n "$PROVIDER" ]; then MODEL_DISPLAY="$PROVIDER $MODEL_DISPLAY"; fi; EFF_WIN=$(eff_win $CTX_WIN); if [ "$EFF_WIN" -gt 0 ] 2>/dev/null && [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX=$(( ((EFF_WIN - IN_TOK) * 200 / EFF_WIN + 1) / 2 )); if [ "$CTX" -lt 0 ]; then CTX=0; fi; fi; if [ "$CTX" -lt 0 ] 2>/dev/null || [ "$EFF_WIN" -le 0 ] 2>/dev/null; then if [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$(fmt_tok $IN_TOK) tokens"; else CTX_DISPLAY="N/A"; fi; elif [ "$IN_TOK" -gt 0 ] 2>/dev/null; then if [ "$EFF_WIN" -lt "$CTX_WIN" ] 2>/dev/null; then CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN) of $(fmt_tok $CTX_WIN))"; else CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN))"; fi; else CTX_DISPLAY="$CTX%"; fi`;
99294
+ const readState = `CTX=-1; COST="0"; IS_FREE="false"; IS_EST="false"; PROVIDER=""; TOKEN_MODEL=""; IN_TOK=0; CTX_WIN=0; PLAN_DISPLAY=""; ALLOW_DISPLAY=""; ALLOW_COLOR=""; ${formatTokensBash}; ${effWinBash}; ${fmtAtBash}; if [ -f "${tokenFilePath}" ]; then TOKENS=$(cat "${tokenFilePath}" 2>/dev/null | tr -d '\\n\\r'); V=$(echo "$TOKENS" | grep -o '"context_left_percent": *-\\?[0-9]*' | grep -o '\\-\\?[0-9]*'); [ -n "$V" ] && CTX="$V"; V=$(echo "$TOKENS" | grep -o '"total_cost": *[0-9.]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && COST="$V"; V=$(echo "$TOKENS" | grep -o '"input_tokens": *[0-9]*' | grep -o '[0-9]*'); [ -n "$V" ] && IN_TOK="$V"; V=$(echo "$TOKENS" | grep -o '"context_window": *[0-9]*' | grep -o '[0-9]*'); [ -n "$V" ] && CTX_WIN="$V"; V=$(echo "$TOKENS" | grep -o '"is_free": *[a-z]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && IS_FREE="$V"; V=$(echo "$TOKENS" | grep -o '"is_estimated": *[a-z]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && IS_EST="$V"; V=$(echo "$TOKENS" | grep -o '"provider_name": *"[^"]*"' | cut -d'"' -f4); [ -n "$V" ] && PROVIDER="$V"; V=$(echo "$TOKENS" | grep -o '"model_name": *"[^"]*"' | cut -d'"' -f4); [ -n "$V" ] && TOKEN_MODEL="$V"; ${readPlanBash} ${readAllowanceBash} fi; if [ "$CLAUDISH_IS_LOCAL" = "true" ]; then COST_DISPLAY="LOCAL"; elif [ "$IS_FREE" = "true" ]; then COST_DISPLAY="FREE"; elif [ "$IS_EST" = "true" ]; then COST_DISPLAY=$(printf "~\\$%.3f" "$COST"); else COST_DISPLAY=$(printf "\\$%.3f" "$COST"); fi; MODEL_DISPLAY="\${TOKEN_MODEL:-$CLAUDISH_ACTIVE_MODEL_NAME}"; if [ -n "$PROVIDER" ]; then MODEL_DISPLAY="$PROVIDER $MODEL_DISPLAY"; fi; EFF_WIN=$(eff_win $CTX_WIN); if [ "$EFF_WIN" -gt 0 ] 2>/dev/null && [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX=$(( ((EFF_WIN - IN_TOK) * 200 / EFF_WIN + 1) / 2 )); if [ "$CTX" -lt 0 ]; then CTX=0; fi; fi; if [ "$CTX" -lt 0 ] 2>/dev/null || [ "$EFF_WIN" -le 0 ] 2>/dev/null; then if [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$(fmt_tok $IN_TOK) tokens"; else CTX_DISPLAY="N/A"; fi; elif [ "$IN_TOK" -gt 0 ] 2>/dev/null; then if [ "$EFF_WIN" -lt "$CTX_WIN" ] 2>/dev/null; then CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN) of $(fmt_tok $CTX_WIN))"; else CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN))"; fi; elif [ "$EFF_WIN" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$CTX% (0/$(fmt_tok $EFF_WIN))"; else CTX_DISPLAY="$CTX%"; fi`;
98533
99295
  const planSuffix = `if [ -n "$PLAN_DISPLAY" ]; then printf " ${DIM}\u2022${RESET} ${GREEN}%s${RESET}" "$PLAN_DISPLAY"; fi; if [ -n "$ALLOW_DISPLAY" ]; then printf " ${DIM}\u2022${RESET} $ALLOW_COLOR%s${RESET}" "$ALLOW_DISPLAY"; fi`;
98534
99296
  const segmentWithDir = `printf "${CYAN}${BOLD}%s${RESET} ${DIM}\u2022${RESET} ${YELLOW}%s${RESET} ${DIM}\u2022${RESET} ${GREEN}%s${RESET} ${DIM}\u2022${RESET} ${MAGENTA}%s${RESET}" "$DIR" "$MODEL_DISPLAY" "$COST_DISPLAY" "$CTX_DISPLAY"; ${planSuffix}; printf "\\n"`;
98535
99297
  const segmentNoDirWithProvider = `printf "${YELLOW}%s${RESET} ${DIM}\u2022${RESET} ${GREEN}%s${RESET} ${DIM}\u2022${RESET} ${MAGENTA}%s${RESET}" "$PROVIDER" "$COST_DISPLAY" "$CTX_DISPLAY"; ${planSuffix}; printf "\\n"`;
@@ -98543,7 +99305,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
98543
99305
  padding: 0
98544
99306
  };
98545
99307
  const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
98546
- writeFileSync19(tempPath, JSON.stringify(settings, null, 2), { encoding: "utf-8", mode: 384 });
99308
+ writeFileSync20(tempPath, JSON.stringify(settings, null, 2), { encoding: "utf-8", mode: 384 });
98547
99309
  return { path: tempPath, statusLine, tokenFilePath };
98548
99310
  }
98549
99311
  function scrubChildEnv(env, opts) {
@@ -98595,7 +99357,7 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
98595
99357
  userSettings.tui = "fullscreen";
98596
99358
  }
98597
99359
  chmodSync5(tempSettingsPath, 384);
98598
- writeFileSync19(tempSettingsPath, JSON.stringify(userSettings, null, 2), {
99360
+ writeFileSync20(tempSettingsPath, JSON.stringify(userSettings, null, 2), {
98599
99361
  encoding: "utf-8",
98600
99362
  mode: 384
98601
99363
  });
@@ -98617,10 +99379,24 @@ async function resolveLocalContextWindow(spec, cachePath) {
98617
99379
  provider = plan.primary.provider;
98618
99380
  wireId = parseModelSpec(plan.primary.modelSpec).model;
98619
99381
  }
99382
+ const definition = getProviderByName(provider);
99383
+ const limit = definition?.isLocal ? contextWindowLimit() : undefined;
99384
+ const capped = (window2) => Math.min(window2, limit ?? window2);
99385
+ if (definition?.unknownContextWindow !== undefined) {
99386
+ const served = await discoverContextWindow(provider, wireId, {
99387
+ network: "bounded",
99388
+ upTo: limit ?? definition.unknownContextWindow
99389
+ });
99390
+ return {
99391
+ modelId: parsed.model,
99392
+ window: capped(served ?? limit ?? definition.unknownContextWindow)
99393
+ };
99394
+ }
98620
99395
  const win = await discoverContextWindow(provider, wireId, { network: "cached-first" }) ?? lookupModelForProvider(parsed.model, provider, cachePath) ?? (wireId !== parsed.model ? lookupModelForProvider(wireId, provider, cachePath) : undefined) ?? await discoverContextWindow(provider, wireId, { network: "bounded" });
99396
+ const known = typeof win === "number" && win > 0 ? win : undefined;
98621
99397
  return {
98622
99398
  modelId: parsed.model,
98623
- window: typeof win === "number" && win > 0 ? win : null
99399
+ window: known !== undefined ? capped(known) : limit ?? null
98624
99400
  };
98625
99401
  }
98626
99402
  async function computeMainThreadContextWindow(config, cachePath) {
@@ -98865,6 +99641,7 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
98865
99641
  applyHostRouting(env);
98866
99642
  const realWindow = await computeMainThreadContextWindow(config);
98867
99643
  const contextEnv = resolveContextWindowEnv(realWindow, process.env);
99644
+ seedTokenFileWindow(resolveTokenFilePath(port), realWindow);
98868
99645
  Object.assign(env, contextEnv.vars);
98869
99646
  try {
98870
99647
  await Promise.resolve().then(() => init_aggregate());
@@ -98914,8 +99691,8 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
98914
99691
  console.error("Install it from: https://claude.com/claude-code");
98915
99692
  console.error(`
98916
99693
  Or set CLAUDE_PATH to your custom installation:`);
98917
- const home = homedir39();
98918
- const localPath = isWindows2() ? join50(home, ".claude", "local", "claude.exe") : join50(home, ".claude", "local", "claude");
99694
+ const home = homedir40();
99695
+ const localPath = isWindows2() ? join51(home, ".claude", "local", "claude.exe") : join51(home, ".claude", "local", "claude");
98919
99696
  console.error(` export CLAUDE_PATH=${localPath}`);
98920
99697
  process.exit(1);
98921
99698
  }
@@ -98950,7 +99727,7 @@ Or set CLAUDE_PATH to your custom installation:`);
98950
99727
  let driverLaunch = null;
98951
99728
  if (surfaces.driver) {
98952
99729
  const minted = sessionFlags.sessionId || sessionFlags.resumes ? null : randomUUID8();
98953
- const turnDir = mkdtempSync3(join50(tmpdir2(), "claudish-turns-"));
99730
+ const turnDir = mkdtempSync3(join51(tmpdir2(), "claudish-turns-"));
98954
99731
  chmodSync5(turnDir, 448);
98955
99732
  claudeArgs.unshift(...driverLeadingArgs({ mintedSessionId: minted, turnDir }));
98956
99733
  const sink = new InProcessSink;
@@ -99056,7 +99833,7 @@ Or set CLAUDE_PATH to your custom installation:`);
99056
99833
  if (driverLaunch) {
99057
99834
  setProcessSink(null);
99058
99835
  try {
99059
- rmSync11(driverLaunch.turnDir, { recursive: true, force: true });
99836
+ rmSync12(driverLaunch.turnDir, { recursive: true, force: true });
99060
99837
  } catch {}
99061
99838
  }
99062
99839
  log(exitSignal ? `[Claude Code] Exited from ${exitSignal} (exit code ${exitCode})` : `[Claude Code] Exited with code ${exitCode}`);
@@ -99154,16 +99931,16 @@ async function findClaudeBinary(env = process.env) {
99154
99931
  return env.CLAUDE_PATH;
99155
99932
  }
99156
99933
  }
99157
- const home = homedir39();
99158
- const localPath = isWindows ? join50(home, ".claude", "local", "claude.exe") : join50(home, ".claude", "local", "claude");
99934
+ const home = homedir40();
99935
+ const localPath = isWindows ? join51(home, ".claude", "local", "claude.exe") : join51(home, ".claude", "local", "claude");
99159
99936
  if (existsSync36(localPath)) {
99160
99937
  return localPath;
99161
99938
  }
99162
99939
  if (isWindows) {
99163
99940
  const windowsPaths = [
99164
- join50(home, "AppData", "Roaming", "npm", "claude.cmd"),
99165
- join50(home, ".npm-global", "claude.cmd"),
99166
- join50(home, "node_modules", ".bin", "claude.cmd")
99941
+ join51(home, "AppData", "Roaming", "npm", "claude.cmd"),
99942
+ join51(home, ".npm-global", "claude.cmd"),
99943
+ join51(home, "node_modules", ".bin", "claude.cmd")
99167
99944
  ];
99168
99945
  for (const path of windowsPaths) {
99169
99946
  if (existsSync36(path)) {
@@ -99174,11 +99951,11 @@ async function findClaudeBinary(env = process.env) {
99174
99951
  const commonPaths = [
99175
99952
  "/usr/local/bin/claude",
99176
99953
  "/opt/homebrew/bin/claude",
99177
- join50(home, ".npm-global/bin/claude"),
99178
- join50(home, ".local/bin/claude"),
99179
- join50(home, "node_modules/.bin/claude"),
99954
+ join51(home, ".npm-global/bin/claude"),
99955
+ join51(home, ".local/bin/claude"),
99956
+ join51(home, "node_modules/.bin/claude"),
99180
99957
  "/data/data/com.termux/files/usr/bin/claude",
99181
- join50(home, "../usr/bin/claude")
99958
+ join51(home, "../usr/bin/claude")
99182
99959
  ];
99183
99960
  for (const path of commonPaths) {
99184
99961
  if (existsSync36(path)) {
@@ -99264,6 +100041,7 @@ var init_claude_runner = __esm(() => {
99264
100041
  init_pane_launch();
99265
100042
  init_process_tree();
99266
100043
  init_profile_config();
100044
+ init_context_window_limit();
99267
100045
  init_model_discovery();
99268
100046
  init_model_parser();
99269
100047
  init_provider_definitions();
@@ -99506,19 +100284,19 @@ var init_slot_row = __esm(() => {
99506
100284
  });
99507
100285
 
99508
100286
  // src/team-stats.ts
99509
- import { existsSync as existsSync37, readFileSync as readFileSync41, writeFileSync as writeFileSync20 } from "fs";
99510
- import { join as join51 } from "path";
100287
+ import { existsSync as existsSync37, readFileSync as readFileSync42, writeFileSync as writeFileSync21 } from "fs";
100288
+ import { join as join52 } from "path";
99511
100289
  function statsDir(sessionPath) {
99512
- return join51(sessionPath, "stats");
100290
+ return join52(sessionPath, "stats");
99513
100291
  }
99514
100292
  function tokenFileFor(sessionPath, anonId) {
99515
- return join51(statsDir(sessionPath), `${anonId}.json`);
100293
+ return join52(statsDir(sessionPath), `${anonId}.json`);
99516
100294
  }
99517
100295
  function readTokenStatsAt(path) {
99518
100296
  if (!existsSync37(path))
99519
100297
  return null;
99520
100298
  try {
99521
- return JSON.parse(readFileSync41(path, "utf-8"));
100299
+ return JSON.parse(readFileSync42(path, "utf-8"));
99522
100300
  } catch {
99523
100301
  return null;
99524
100302
  }
@@ -99675,7 +100453,7 @@ ${segs.join(" \xB7 ")}`;
99675
100453
  }
99676
100454
  function writeStatusFile(sessionPath, manifest, status, opts) {
99677
100455
  try {
99678
- writeFileSync20(join51(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
100456
+ writeFileSync21(join52(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
99679
100457
  `, "utf-8");
99680
100458
  } catch {}
99681
100459
  }
@@ -99685,11 +100463,11 @@ var init_team_stats = __esm(() => {
99685
100463
  });
99686
100464
 
99687
100465
  // src/pane/accounting.ts
99688
- import { statSync as statSync18 } from "fs";
100466
+ import { statSync as statSync19 } from "fs";
99689
100467
  function readTokenFileCached(path) {
99690
100468
  let st;
99691
100469
  try {
99692
- const s = statSync18(path);
100470
+ const s = statSync19(path);
99693
100471
  st = { mtimeMs: s.mtimeMs, size: s.size };
99694
100472
  } catch {
99695
100473
  cache2.delete(path);
@@ -99762,15 +100540,15 @@ import {
99762
100540
  accessSync as accessSync2,
99763
100541
  existsSync as existsSync38,
99764
100542
  lstatSync as lstatSync8,
99765
- readFileSync as readFileSync42,
99766
- readdirSync as readdirSync9,
99767
- renameSync as renameSync9,
99768
- rmSync as rmSync12,
99769
- rmdirSync,
100543
+ readFileSync as readFileSync43,
100544
+ readdirSync as readdirSync10,
100545
+ renameSync as renameSync10,
100546
+ rmSync as rmSync13,
100547
+ rmdirSync as rmdirSync2,
99770
100548
  unlinkSync as unlinkSync12,
99771
- writeFileSync as writeFileSync21
100549
+ writeFileSync as writeFileSync22
99772
100550
  } from "fs";
99773
- import { dirname as dirname21, join as join52 } from "path";
100551
+ import { dirname as dirname22, join as join53 } from "path";
99774
100552
  function ownerStartOfSelf() {
99775
100553
  if (ownStart)
99776
100554
  return ownStart;
@@ -99791,20 +100569,20 @@ function ownerAlive(owner, table) {
99791
100569
  return !minted || startedAt(row, minted.startMs);
99792
100570
  }
99793
100571
  function recordsDir(root) {
99794
- return join52(root, "panes");
100572
+ return join53(root, "panes");
99795
100573
  }
99796
100574
  function writeRecord(root, rec) {
99797
100575
  const p = recordPathOf(root, rec.paneId);
99798
100576
  const tmp = `${p}.tmp-${process.pid}`;
99799
- writeFileSync21(tmp, `${JSON.stringify(rec)}
100577
+ writeFileSync22(tmp, `${JSON.stringify(rec)}
99800
100578
  `, { mode: 384 });
99801
- renameSync9(tmp, p);
100579
+ renameSync10(tmp, p);
99802
100580
  }
99803
100581
  function readRecord(root, paneId) {
99804
100582
  if (!isValidPaneId(paneId))
99805
100583
  return null;
99806
100584
  try {
99807
- return validRecord(JSON.parse(readFileSync42(recordPathOf(root, paneId), "utf8")), paneId);
100585
+ return validRecord(JSON.parse(readFileSync43(recordPathOf(root, paneId), "utf8")), paneId);
99808
100586
  } catch {
99809
100587
  return null;
99810
100588
  }
@@ -99861,7 +100639,7 @@ function validForkRef(v) {
99861
100639
  function readRecords(root) {
99862
100640
  let names;
99863
100641
  try {
99864
- names = readdirSync9(recordsDir(root)).filter((n) => n.endsWith(".json"));
100642
+ names = readdirSync10(recordsDir(root)).filter((n) => n.endsWith(".json"));
99865
100643
  } catch {
99866
100644
  return [];
99867
100645
  }
@@ -99875,36 +100653,36 @@ function readRecords(root) {
99875
100653
  }
99876
100654
  function readGroupFile(ctlDir) {
99877
100655
  try {
99878
- return parseGroupFile(readFileSync42(join52(ctlDir, "group"), "utf8"));
100656
+ return parseGroupFile(readFileSync43(join53(ctlDir, "group"), "utf8"));
99879
100657
  } catch {
99880
100658
  return null;
99881
100659
  }
99882
100660
  }
99883
100661
  function writeGroupFile(ctlDir, snap) {
99884
- const p = join52(ctlDir, "group");
100662
+ const p = join53(ctlDir, "group");
99885
100663
  const tmp = `${p}.tmp`;
99886
100664
  try {
99887
- writeFileSync21(tmp, formatGroupFile(snap), { mode: 384 });
99888
- renameSync9(tmp, p);
100665
+ writeFileSync22(tmp, formatGroupFile(snap), { mode: 384 });
100666
+ renameSync10(tmp, p);
99889
100667
  } catch {}
99890
100668
  }
99891
100669
  function removeForkRecord(fork, forkUuid) {
99892
100670
  if (!isForkRecordPath(fork.projectsRoot, fork.path, forkUuid))
99893
100671
  return;
99894
100672
  try {
99895
- rmSync12(fork.path, { force: true });
100673
+ rmSync13(fork.path, { force: true });
99896
100674
  if (fork.removeProjectDir)
99897
- rmdirSync(dirname21(fork.path));
100675
+ rmdirSync2(dirname22(fork.path));
99898
100676
  } catch {}
99899
100677
  }
99900
100678
  function removePaneFiles(root, f) {
99901
100679
  if (f.fork && f.sessionUuid)
99902
100680
  removeForkRecord(f.fork, f.sessionUuid);
99903
100681
  if (isPaneSockPath(root, f.sockPath, f.paneId))
99904
- rmSync12(f.sockPath, { force: true });
100682
+ rmSync13(f.sockPath, { force: true });
99905
100683
  for (const d of [f.launcherDir, f.turnDir])
99906
100684
  if (d && isLaunchDirPath(root, d))
99907
- rmSync12(d, { recursive: true, force: true });
100685
+ rmSync13(d, { recursive: true, force: true });
99908
100686
  const rec = recordPathOf(root, f.paneId);
99909
100687
  if (isPaneRecordPath(root, rec, f.paneId))
99910
100688
  deleteRecord(root, f.paneId);
@@ -100169,11 +100947,11 @@ async function sweepRecordlessSocket(root, name, out) {
100169
100947
  const owner = ownerOfSocketId(id);
100170
100948
  if (!owner || ownerAlive(owner, table))
100171
100949
  return;
100172
- const sockPath = join52(root, name);
100950
+ const sockPath = join53(root, name);
100173
100951
  const magmuxMayLive = !table || table.some((r) => isPaneMagmuxCommand(r.command, id));
100174
100952
  const probe = await probeSocket(sockPath, magmuxMayLive);
100175
100953
  if (probe.state === "stale") {
100176
- rmSync12(sockPath, { force: true });
100954
+ rmSync13(sockPath, { force: true });
100177
100955
  out.cleaned.push(id);
100178
100956
  return;
100179
100957
  }
@@ -100199,7 +100977,7 @@ async function sweepRecordlessSocket(root, name, out) {
100199
100977
  if (mag)
100200
100978
  signal(mag.pid, "SIGKILL");
100201
100979
  await Bun.sleep(300);
100202
- rmSync12(sockPath, { force: true });
100980
+ rmSync13(sockPath, { force: true });
100203
100981
  (mag ? out.reaped : out.kept).push(id);
100204
100982
  }
100205
100983
  async function ensureSwept(root) {
@@ -100218,7 +100996,7 @@ async function sweepOrphanPanes(root = sockRootFor()) {
100218
100996
  const known = new Set(readRecords(root).map((r) => r.paneId));
100219
100997
  let names = [];
100220
100998
  try {
100221
- names = readdirSync9(root).filter((n) => /^magmux-c\d+-[A-Za-z0-9_-]+\.sock$/.test(n));
100999
+ names = readdirSync10(root).filter((n) => /^magmux-c\d+-[A-Za-z0-9_-]+\.sock$/.test(n));
100222
101000
  } catch {
100223
101001
  names = [];
100224
101002
  }
@@ -100249,19 +101027,19 @@ var init_pane_registry = __esm(() => {
100249
101027
 
100250
101028
  // src/pane/gate-binding.ts
100251
101029
  import { realpathSync as realpathSync6 } from "fs";
100252
- import { basename as basename4, dirname as dirname22, join as join53, resolve as resolve6 } from "path";
101030
+ import { basename as basename5, dirname as dirname23, join as join54, resolve as resolve6 } from "path";
100253
101031
  function normaliseTranscriptPath(p) {
100254
101032
  const abs = resolve6(p);
100255
101033
  const tail = [];
100256
101034
  let cur = abs;
100257
101035
  for (;; ) {
100258
101036
  try {
100259
- return tail.length ? join53(realpathSync6(cur), ...tail.reverse()) : realpathSync6(cur);
101037
+ return tail.length ? join54(realpathSync6(cur), ...tail.reverse()) : realpathSync6(cur);
100260
101038
  } catch {
100261
- const parent = dirname22(cur);
101039
+ const parent = dirname23(cur);
100262
101040
  if (parent === cur)
100263
101041
  return abs;
100264
- tail.push(basename4(cur));
101042
+ tail.push(basename5(cur));
100265
101043
  cur = parent;
100266
101044
  }
100267
101045
  }
@@ -100456,8 +101234,8 @@ var init_scroll_input = __esm(() => {
100456
101234
  });
100457
101235
 
100458
101236
  // src/pane/session-registry.ts
100459
- import { readFileSync as readFileSync43, readdirSync as readdirSync10 } from "fs";
100460
- import { join as join54 } from "path";
101237
+ import { readFileSync as readFileSync44, readdirSync as readdirSync11 } from "fs";
101238
+ import { join as join55 } from "path";
100461
101239
  function parseRegistryRecord(raw) {
100462
101240
  let parsed;
100463
101241
  try {
@@ -100484,7 +101262,7 @@ function parseRegistryRecord(raw) {
100484
101262
  version: typeof r.version === "string" ? r.version : null
100485
101263
  };
100486
101264
  }
100487
- function pidAlive(pid) {
101265
+ function pidAlive2(pid) {
100488
101266
  try {
100489
101267
  process.kill(pid, 0);
100490
101268
  return true;
@@ -100502,9 +101280,9 @@ class SessionRegistry {
100502
101280
  isAlive;
100503
101281
  constructor(o) {
100504
101282
  this.o = o;
100505
- this.dir = join54(o.configDir, "sessions");
101283
+ this.dir = join55(o.configDir, "sessions");
100506
101284
  this.now = o.now ?? Date.now;
100507
- this.isAlive = o.isAlive ?? pidAlive;
101285
+ this.isAlive = o.isAlive ?? pidAlive2;
100508
101286
  }
100509
101287
  read() {
100510
101288
  if (this.pid !== null) {
@@ -100519,7 +101297,7 @@ class SessionRegistry {
100519
101297
  this.lastScanAt = now;
100520
101298
  let names;
100521
101299
  try {
100522
- names = readdirSync10(this.dir);
101300
+ names = readdirSync11(this.dir);
100523
101301
  } catch {
100524
101302
  return null;
100525
101303
  }
@@ -100538,7 +101316,7 @@ class SessionRegistry {
100538
101316
  readPid(pid) {
100539
101317
  let raw;
100540
101318
  try {
100541
- raw = readFileSync43(join54(this.dir, `${pid}.json`), "utf8");
101319
+ raw = readFileSync44(join55(this.dir, `${pid}.json`), "utf8");
100542
101320
  } catch {
100543
101321
  return null;
100544
101322
  }
@@ -100651,8 +101429,8 @@ var init_slot_state = __esm(() => {
100651
101429
  });
100652
101430
 
100653
101431
  // src/pane/pane-session.ts
100654
- import { readFileSync as readFileSync44, realpathSync as realpathSync7, rmSync as rmSync13, statSync as statSync19, writeFileSync as writeFileSync22 } from "fs";
100655
- import { join as join55 } from "path";
101432
+ import { readFileSync as readFileSync45, realpathSync as realpathSync7, rmSync as rmSync14, statSync as statSync20, writeFileSync as writeFileSync23 } from "fs";
101433
+ import { join as join56 } from "path";
100656
101434
  function iso3(ms) {
100657
101435
  return new Date(ms).toISOString();
100658
101436
  }
@@ -100801,7 +101579,7 @@ class PaneSessionImpl {
100801
101579
  });
100802
101580
  this.secondaryQuietMs = o.timings?.secondaryQuietMs ?? SECONDARY_QUIET_MS;
100803
101581
  this.corroborationMs = o.timings?.corroborationMs ?? CORROBORATION_MS;
100804
- this.follower = new TranscriptFollower(o.transcriptPath, join55(o.transcriptPath.replace(/\.jsonl$/, ""), "subagents"));
101582
+ this.follower = new TranscriptFollower(o.transcriptPath, join56(o.transcriptPath.replace(/\.jsonl$/, ""), "subagents"));
100805
101583
  this.registry = new SessionRegistry({
100806
101584
  configDir: claudeConfigDir(o.parentEnv ?? process.env),
100807
101585
  sessionUuid: o.sessionUuid
@@ -100848,7 +101626,7 @@ class PaneSessionImpl {
100848
101626
  return this.spawnFailed(new Error("magmux did not start"));
100849
101627
  this.magmux = proc;
100850
101628
  try {
100851
- writeFileSync22(join55(this.ctlDir, "magmux.pid"), `${proc.pid}
101629
+ writeFileSync23(join56(this.ctlDir, "magmux.pid"), `${proc.pid}
100852
101630
  `, { mode: 384 });
100853
101631
  } catch {}
100854
101632
  updateRecord(this.root, this.paneId, { magmuxPid: proc.pid });
@@ -102596,7 +103374,7 @@ ${screenTailOf(this.screen)}`
102596
103374
  if (!p)
102597
103375
  return 0;
102598
103376
  try {
102599
- return statSync19(p).size;
103377
+ return statSync20(p).size;
102600
103378
  } catch {
102601
103379
  return 0;
102602
103380
  }
@@ -102605,7 +103383,7 @@ ${screenTailOf(this.screen)}`
102605
103383
  const p = this.errorLogPath();
102606
103384
  if (p && this.errorLogSize() > st.errorLogSize) {
102607
103385
  try {
102608
- const text = readFileSync44(p, "utf8").slice(st.errorLogSize).trim();
103386
+ const text = readFileSync45(p, "utf8").slice(st.errorLogSize).trim();
102609
103387
  return { status: null, category: "upstream_error_log", text };
102610
103388
  } catch {}
102611
103389
  }
@@ -103240,7 +104018,7 @@ function preparePane(o, root, parentEnv) {
103240
104018
  } catch (e) {
103241
104019
  for (const d of dirs ? [dirs.ctlDir, dirs.turnDir] : [])
103242
104020
  if (isLaunchDirPath(root, d))
103243
- rmSync13(d, { recursive: true, force: true });
104021
+ rmSync14(d, { recursive: true, force: true });
103244
104022
  if (e.code)
103245
104023
  throw e;
103246
104024
  throw new PaneStartError("pane_lost", e instanceof Error ? e.message : String(e));
@@ -103361,8 +104139,8 @@ var init_pane_session = __esm(() => {
103361
104139
  });
103362
104140
 
103363
104141
  // src/pane/replay-pane.ts
103364
- import { rmSync as rmSync14, writeFileSync as writeFileSync23 } from "fs";
103365
- import { join as join56 } from "path";
104142
+ import { rmSync as rmSync15, writeFileSync as writeFileSync24 } from "fs";
104143
+ import { join as join57 } from "path";
103366
104144
  async function waitUntil(pred, ms) {
103367
104145
  const end = Date.now() + ms;
103368
104146
  while (!pred() && Date.now() < end)
@@ -103471,7 +104249,7 @@ class ReplayPane {
103471
104249
  return failed(new Error("magmux did not start"));
103472
104250
  this.magmuxProc = proc;
103473
104251
  try {
103474
- writeFileSync23(join56(this.ctlDir, "magmux.pid"), `${proc.pid}
104252
+ writeFileSync24(join57(this.ctlDir, "magmux.pid"), `${proc.pid}
103475
104253
  `, { mode: 384 });
103476
104254
  } catch {}
103477
104255
  updateRecord(this.root, this.paneId, { magmuxPid: proc.pid });
@@ -103921,7 +104699,7 @@ async function startReplayPane(o) {
103921
104699
  } catch (e) {
103922
104700
  for (const d of dirs ? [dirs.ctlDir, dirs.turnDir] : [])
103923
104701
  if (isLaunchDirPath(root, d))
103924
- rmSync14(d, { recursive: true, force: true });
104702
+ rmSync15(d, { recursive: true, force: true });
103925
104703
  throw e;
103926
104704
  }
103927
104705
  const pane = new ReplayPane(o, {
@@ -104370,12 +105148,12 @@ import {
104370
105148
  lstatSync as lstatSync9,
104371
105149
  openSync as openSync15,
104372
105150
  readSync as readSync6,
104373
- readdirSync as readdirSync11,
105151
+ readdirSync as readdirSync12,
104374
105152
  readlinkSync,
104375
105153
  realpathSync as realpathSync8,
104376
- statSync as statSync20
105154
+ statSync as statSync21
104377
105155
  } from "fs";
104378
- import { basename as basename5, dirname as dirname23, join as join57, sep } from "path";
105156
+ import { basename as basename6, dirname as dirname24, join as join58, sep } from "path";
104379
105157
  function isUuid(v) {
104380
105158
  return typeof v === "string" && UUID_RE.test(v);
104381
105159
  }
@@ -104519,15 +105297,15 @@ function locateTranscriptByUuid(projectsRoot, uuid) {
104519
105297
  return null;
104520
105298
  let dirs;
104521
105299
  try {
104522
- dirs = readdirSync11(projectsRoot);
105300
+ dirs = readdirSync12(projectsRoot);
104523
105301
  } catch {
104524
105302
  return null;
104525
105303
  }
104526
105304
  let hit = null;
104527
105305
  for (const d of dirs) {
104528
- const p = join57(projectsRoot, d, `${uuid}.jsonl`);
105306
+ const p = join58(projectsRoot, d, `${uuid}.jsonl`);
104529
105307
  try {
104530
- if (!statSync20(p).isFile())
105308
+ if (!statSync21(p).isFile())
104531
105309
  continue;
104532
105310
  } catch {
104533
105311
  continue;
@@ -104555,7 +105333,7 @@ function writerLiveness(pid) {
104555
105333
  }
104556
105334
  function fileAgeMs(path, now = Date.now()) {
104557
105335
  try {
104558
- return now - statSync20(path).mtimeMs;
105336
+ return now - statSync21(path).mtimeMs;
104559
105337
  } catch {
104560
105338
  return null;
104561
105339
  }
@@ -104580,7 +105358,7 @@ function errText(e) {
104580
105358
  return e instanceof Error ? e.message : String(e);
104581
105359
  }
104582
105360
  function openContainedTranscript(path, uuid, projectsRoot) {
104583
- if (basename5(path) !== `${uuid}.jsonl`) {
105361
+ if (basename6(path) !== `${uuid}.jsonl`) {
104584
105362
  logRejection(path, "basename is not the session uuid");
104585
105363
  return null;
104586
105364
  }
@@ -104615,7 +105393,7 @@ function openContainedTranscript(path, uuid, projectsRoot) {
104615
105393
  closeQuietly(fd);
104616
105394
  return null;
104617
105395
  }
104618
- const parent = dirname23(real);
105396
+ const parent = dirname24(real);
104619
105397
  const named = lstatSync9(real);
104620
105398
  if (realpathSync8(parent) !== parent || !named.isFile() || named.dev !== st.dev || named.ino !== st.ino || !kernelPathMatches(fd, real)) {
104621
105399
  logRejection(path, "the opened file is not the one under the projects directory");
@@ -104761,8 +105539,8 @@ var init_pane = __esm(() => {
104761
105539
 
104762
105540
  // src/mcp-session/replay-manager.ts
104763
105541
  import { randomBytes as randomBytes15, randomUUID as randomUUID9 } from "crypto";
104764
- import { constants as constants6, accessSync as accessSync3, closeSync as closeSync16, existsSync as existsSync39, realpathSync as realpathSync9, statSync as statSync21 } from "fs";
104765
- import { dirname as dirname24, resolve as resolve7 } from "path";
105542
+ import { constants as constants6, accessSync as accessSync3, closeSync as closeSync16, existsSync as existsSync39, realpathSync as realpathSync9, statSync as statSync22 } from "fs";
105543
+ import { dirname as dirname25, resolve as resolve7 } from "path";
104766
105544
  function unavailable2(reason, message) {
104767
105545
  return new ContractErrorException("replay_unavailable", message, reason);
104768
105546
  }
@@ -104772,7 +105550,7 @@ function unknownReplay(id) {
104772
105550
  function replayCwd(own) {
104773
105551
  if (own) {
104774
105552
  try {
104775
- if (statSync21(own).isDirectory())
105553
+ if (statSync22(own).isDirectory())
104776
105554
  return realpathSync9(own);
104777
105555
  } catch {}
104778
105556
  }
@@ -104782,7 +105560,7 @@ async function replayClaudeBinary(env) {
104782
105560
  const named = env.CLAUDE_PATH ? resolve7(env.CLAUDE_PATH) : "";
104783
105561
  if (named) {
104784
105562
  try {
104785
- if (!statSync21(named).isFile())
105563
+ if (!statSync22(named).isFile())
104786
105564
  throw new Error("not a file");
104787
105565
  accessSync3(named, constants6.X_OK);
104788
105566
  } catch {
@@ -104837,8 +105615,8 @@ class ReplayManager {
104837
105615
  cwd,
104838
105616
  projectsRoot,
104839
105617
  forkPath,
104840
- removeProjectDir: !existsSync39(dirname24(forkPath)),
104841
- configDir: dirname24(projectsRoot),
105618
+ removeProjectDir: !existsSync39(dirname25(forkPath)),
105619
+ configDir: dirname25(projectsRoot),
104842
105620
  cols: size.cols ?? DEFAULT_PANE_COLS,
104843
105621
  rows: size.rows ?? DEFAULT_PANE_ROWS
104844
105622
  });
@@ -105005,15 +105783,15 @@ import { randomBytes as randomBytes16, randomUUID as randomUUID10 } from "crypto
105005
105783
  import {
105006
105784
  existsSync as existsSync40,
105007
105785
  lstatSync as lstatSync10,
105008
- mkdirSync as mkdirSync26,
105009
- readFileSync as readFileSync45,
105010
- readdirSync as readdirSync12,
105786
+ mkdirSync as mkdirSync27,
105787
+ readFileSync as readFileSync46,
105788
+ readdirSync as readdirSync13,
105011
105789
  realpathSync as realpathSync10,
105012
- rmSync as rmSync15,
105013
- statSync as statSync22,
105014
- writeFileSync as writeFileSync24
105790
+ rmSync as rmSync16,
105791
+ statSync as statSync23,
105792
+ writeFileSync as writeFileSync25
105015
105793
  } from "fs";
105016
- import { basename as basename6, dirname as dirname25, join as join58, resolve as resolve8, sep as sep2 } from "path";
105794
+ import { basename as basename7, dirname as dirname26, join as join59, resolve as resolve8, sep as sep2 } from "path";
105017
105795
  function slotTerminal(e) {
105018
105796
  if (!e.session)
105019
105797
  return true;
@@ -105082,7 +105860,7 @@ function notableAnomalies(snap) {
105082
105860
  return snap.anomalies.filter((a) => a.startsWith("background_shell_open") || a.startsWith("turn_end_record_missing") || a.startsWith("agent_count_mismatch") || a.startsWith("prompt_not_read"));
105083
105861
  }
105084
105862
  function upstreamLogPath(path, id) {
105085
- return join58(path, "errors", `${id}-upstream.jsonl`);
105863
+ return join59(path, "errors", `${id}-upstream.jsonl`);
105086
105864
  }
105087
105865
  function neverSpawnedRow(e, m) {
105088
105866
  return {
@@ -105179,9 +105957,9 @@ function teamRunRowFromDisk(path, status) {
105179
105957
  const settled = slots.length > 0 && slots.every((s) => isTerminalState(s.state));
105180
105958
  const completions = Object.values(status.models ?? {}).map((m) => m?.completedAt ? Date.parse(m.completedAt) : Number.NaN).filter(Number.isFinite);
105181
105959
  return {
105182
- run_id: status.runId ?? basename6(path),
105960
+ run_id: status.runId ?? basename7(path),
105183
105961
  path,
105184
- kind: status.kind ?? (basename6(path) === "judging" ? "judge" : "run"),
105962
+ kind: status.kind ?? (basename7(path) === "judging" ? "judge" : "run"),
105185
105963
  started_at: status.startedAt,
105186
105964
  finished_at: settled ? new Date(completions.length ? Math.max(...completions) : statusMtimeMs(path) ?? Date.parse(status.startedAt)).toISOString() : null,
105187
105965
  state: settled ? "SETTLED" : "ACTIVE",
@@ -105191,14 +105969,14 @@ function teamRunRowFromDisk(path, status) {
105191
105969
  }
105192
105970
  function statusMtimeMs(path) {
105193
105971
  try {
105194
- return statSync22(join58(path, "status.json")).mtimeMs;
105972
+ return statSync23(join59(path, "status.json")).mtimeMs;
105195
105973
  } catch {
105196
105974
  return null;
105197
105975
  }
105198
105976
  }
105199
105977
  function readManifestOrNull(path) {
105200
105978
  try {
105201
- return JSON.parse(readFileSync45(join58(path, "manifest.json"), "utf-8"));
105979
+ return JSON.parse(readFileSync46(join59(path, "manifest.json"), "utf-8"));
105202
105980
  } catch {
105203
105981
  return null;
105204
105982
  }
@@ -105321,7 +106099,7 @@ function teamSlotTranscriptSource(path, slot, runId, opts) {
105321
106099
  }
105322
106100
  if (!status || typeof status !== "object" || !status.models || typeof status.models !== "object")
105323
106101
  throw unknownRun(path, runId);
105324
- const fileRunId = typeof status.runId === "string" && status.runId ? status.runId : basename6(resolved);
106102
+ const fileRunId = typeof status.runId === "string" && status.runId ? status.runId : basename7(resolved);
105325
106103
  if (runId !== undefined && runId !== fileRunId)
105326
106104
  throw unknownRun(path, runId);
105327
106105
  const m = Object.hasOwn(status.models, slot) ? status.models[slot] : undefined;
@@ -105486,12 +106264,12 @@ function readWrittenFile(path, root) {
105486
106264
  if (real !== realRoot && !real.startsWith(realRoot + sep2))
105487
106265
  return { skip: "outside the working directory" };
105488
106266
  try {
105489
- const st = statSync22(real);
106267
+ const st = statSync23(real);
105490
106268
  if (!st.isFile())
105491
106269
  return { skip: "not a regular file" };
105492
106270
  if (st.size > MAX_FILE_ANSWER_BYTES)
105493
106271
  return { skip: "larger than 1 MiB" };
105494
- const buf = readFileSync45(real);
106272
+ const buf = readFileSync46(real);
105495
106273
  if (buf.includes(0))
105496
106274
  return { skip: "binary" };
105497
106275
  return { text: buf.toString("utf8") };
@@ -105528,7 +106306,7 @@ function persistErrorLog(errorLogPath, header, sections) {
105528
106306
  parts.push(`--- ${title} ---`, body.trim() ? redactSecrets(body) : "(empty)", "");
105529
106307
  }
105530
106308
  try {
105531
- writeFileSync24(errorLogPath, parts.join(`
106309
+ writeFileSync25(errorLogPath, parts.join(`
105532
106310
  `), "utf-8");
105533
106311
  } catch {}
105534
106312
  }
@@ -105542,16 +106320,16 @@ function validateSessionPath(sessionPath) {
105542
106320
  lstatSync10(existing);
105543
106321
  break;
105544
106322
  } catch {
105545
- const parent = dirname25(existing);
106323
+ const parent = dirname26(existing);
105546
106324
  if (parent === existing)
105547
106325
  break;
105548
- tail.unshift(basename6(existing));
106326
+ tail.unshift(basename7(existing));
105549
106327
  existing = parent;
105550
106328
  }
105551
106329
  }
105552
106330
  let real;
105553
106331
  try {
105554
- real = join58(realpathSync10(existing), ...tail);
106332
+ real = join59(realpathSync10(existing), ...tail);
105555
106333
  } catch {
105556
106334
  throw outside();
105557
106335
  }
@@ -105570,7 +106348,7 @@ function readTeamInputFile(inputPath) {
105570
106348
  if (!existsSync40(resolved)) {
105571
106349
  throw new Error(`Input file not found: ${resolved}`);
105572
106350
  }
105573
- const text = readFileSync45(resolved, "utf-8");
106351
+ const text = readFileSync46(resolved, "utf-8");
105574
106352
  if (text.trim().length === 0) {
105575
106353
  throw new Error(`Input file is empty: ${resolved}`);
105576
106354
  }
@@ -105580,14 +106358,14 @@ function setupSession(sessionPath, models, input) {
105580
106358
  if (models.length === 0) {
105581
106359
  throw new Error("At least one model is required");
105582
106360
  }
105583
- if (existsSync40(join58(sessionPath, "manifest.json"))) {
106361
+ if (existsSync40(join59(sessionPath, "manifest.json"))) {
105584
106362
  throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
105585
106363
  }
105586
- mkdirSync26(join58(sessionPath, "work"), { recursive: true });
105587
- mkdirSync26(join58(sessionPath, "errors"), { recursive: true });
106364
+ mkdirSync27(join59(sessionPath, "work"), { recursive: true });
106365
+ mkdirSync27(join59(sessionPath, "errors"), { recursive: true });
105588
106366
  if (input !== undefined) {
105589
- writeFileSync24(join58(sessionPath, "input.md"), input, "utf-8");
105590
- } else if (!existsSync40(join58(sessionPath, "input.md"))) {
106367
+ writeFileSync25(join59(sessionPath, "input.md"), input, "utf-8");
106368
+ } else if (!existsSync40(join59(sessionPath, "input.md"))) {
105591
106369
  throw new Error(`No input.md found at ${sessionPath} and no input provided`);
105592
106370
  }
105593
106371
  const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
@@ -105604,9 +106382,9 @@ function setupSession(sessionPath, models, input) {
105604
106382
  model: models[i],
105605
106383
  assignedAt: now
105606
106384
  };
105607
- mkdirSync26(join58(sessionPath, "work", anonId), { recursive: true });
106385
+ mkdirSync27(join59(sessionPath, "work", anonId), { recursive: true });
105608
106386
  }
105609
- writeFileSync24(join58(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
106387
+ writeFileSync25(join59(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
105610
106388
  const status = {
105611
106389
  startedAt: now,
105612
106390
  models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
@@ -105621,7 +106399,7 @@ function setupSession(sessionPath, models, input) {
105621
106399
  }
105622
106400
  ]))
105623
106401
  };
105624
- writeFileAtomic(join58(sessionPath, "status.json"), JSON.stringify(status, null, 2));
106402
+ writeFileAtomic(join59(sessionPath, "status.json"), JSON.stringify(status, null, 2));
105625
106403
  return manifest;
105626
106404
  }
105627
106405
  function assertValidRequirePattern(pattern) {
@@ -105656,7 +106434,7 @@ async function preflightTeamRun(opts) {
105656
106434
  throw new Error(`pane_limit: ${live} live panes for this user, ${opts.slots} more would exceed ${MAX_LIVE_PANES}`);
105657
106435
  }
105658
106436
  function mintRunId(path, startMs) {
105659
- return `${basename6(path)}-${startMs.toString(36)}-${randomBytes16(3).toString("hex")}`;
106437
+ return `${basename7(path)}-${startMs.toString(36)}-${randomBytes16(3).toString("hex")}`;
105660
106438
  }
105661
106439
  function startModels(sessionPath, opts = {}) {
105662
106440
  const flight = { aborted: false };
@@ -105682,9 +106460,9 @@ async function startModelsIn(flight, sessionPath, opts) {
105682
106460
  throw new Error(`invalid_args: ${flagCheck.message}`);
105683
106461
  const agentRequested = requestedAgentOf(claudeFlags);
105684
106462
  const path = resolve8(sessionPath);
105685
- const manifest = JSON.parse(readFileSync45(join58(path, "manifest.json"), "utf-8"));
105686
- const statusPath = join58(path, "status.json");
105687
- const inputContent = readFileSync45(join58(path, "input.md"), "utf-8");
106463
+ const manifest = JSON.parse(readFileSync46(join59(path, "manifest.json"), "utf-8"));
106464
+ const statusPath = join59(path, "status.json");
106465
+ const inputContent = readFileSync46(join59(path, "input.md"), "utf-8");
105688
106466
  const readAvailable = !flagsRemoveRead(claudeFlags);
105689
106467
  const refusal = deliveryRefusal(inputContent, readAvailable);
105690
106468
  if (refusal)
@@ -105695,7 +106473,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105695
106473
  const hookEngine = await (opts.hookEngine ?? (() => loadHooksOnce()))().catch(() => null);
105696
106474
  const spawnPlan = await (opts.spawnPlanner ?? prehydrateCredentialsForSpawn)(Object.values(manifest.models).map((m) => m.model));
105697
106475
  await assertMagmuxAvailable();
105698
- const statusCache = JSON.parse(readFileSync45(statusPath, "utf-8"));
106476
+ const statusCache = JSON.parse(readFileSync46(statusPath, "utf-8"));
105699
106477
  const startMs = Date.now();
105700
106478
  const runId = mintRunId(path, startMs);
105701
106479
  statusCache.runId = runId;
@@ -105721,10 +106499,10 @@ async function startModelsIn(flight, sessionPath, opts) {
105721
106499
  const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
105722
106500
  const requirePattern = opts.requirePattern;
105723
106501
  const cwd = opts.cwd ?? process.cwd();
105724
- mkdirSync26(statsDir(path), { recursive: true });
106502
+ mkdirSync27(statsDir(path), { recursive: true });
105725
106503
  const entries = new Map;
105726
106504
  let run = null;
105727
- const errorLogPathOf = (id) => join58(path, "errors", `${id}.log`);
106505
+ const errorLogPathOf = (id) => join59(path, "errors", `${id}.log`);
105728
106506
  const upstreamLogOf = (id) => upstreamLogPath(path, id);
105729
106507
  const flagsOf = (e) => {
105730
106508
  const effort = opts.efforts?.[e.model];
@@ -105734,7 +106512,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105734
106512
  function writeResponse(e, text) {
105735
106513
  e.answer = text;
105736
106514
  try {
105737
- writeFileSync24(join58(path, `response-${e.id}.md`), text, "utf-8");
106515
+ writeFileSync25(join59(path, `response-${e.id}.md`), text, "utf-8");
105738
106516
  } catch (err) {
105739
106517
  persistErrorLog(errorLogPathOf(e.id), `response file not written: ${String(err)}`, []);
105740
106518
  }
@@ -105744,7 +106522,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105744
106522
  if (e.answer !== null || !e.session)
105745
106523
  return;
105746
106524
  try {
105747
- writeFileSync24(join58(path, `response-${e.id}.md`), e.session.chainText(), "utf-8");
106525
+ writeFileSync25(join59(path, `response-${e.id}.md`), e.session.chainText(), "utf-8");
105748
106526
  } catch (err) {
105749
106527
  persistErrorLog(errorLogPathOf(e.id), `response file not written: ${String(err)}`, []);
105750
106528
  }
@@ -105941,7 +106719,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105941
106719
  }
105942
106720
  async function startSlot(e, uuid, transcriptPath) {
105943
106721
  let session;
105944
- e.inboxPath = createHookInbox(join58(path, "work"), `${e.id}.hook-inbox.jsonl`);
106722
+ e.inboxPath = createHookInbox(join59(path, "work"), `${e.id}.hook-inbox.jsonl`);
105945
106723
  const binding = bindingFor(e, uuid);
105946
106724
  e.binding = binding;
105947
106725
  try {
@@ -105996,7 +106774,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105996
106774
  if (!e.inboxPath)
105997
106775
  return;
105998
106776
  try {
105999
- rmSync15(e.inboxPath, { force: true });
106777
+ rmSync16(e.inboxPath, { force: true });
106000
106778
  } catch {}
106001
106779
  }
106002
106780
  const slotIds = Object.keys(manifest.models);
@@ -106161,7 +106939,7 @@ async function startModelsIn(flight, sessionPath, opts) {
106161
106939
  done.catch((err) => log(`[team] run failed at ${path}: ${err instanceof Error ? err.message : String(err)}`));
106162
106940
  return {
106163
106941
  runId,
106164
- teamSessionId: basename6(path),
106942
+ teamSessionId: basename7(path),
106165
106943
  sessionPath: path,
106166
106944
  slots: Object.fromEntries(Object.entries(manifest.models).map(([anonId, entry]) => [entry.model, anonId])),
106167
106945
  done
@@ -106175,21 +106953,21 @@ async function judgeResponses(sessionPath, opts = {}) {
106175
106953
  const active = activeRunAt(resolve8(sessionPath));
106176
106954
  if (active)
106177
106955
  throw new Error(`invalid_args: the team run at ${resolve8(sessionPath)} is still ACTIVE (run_id ${active.runId}); judge it once it has settled`);
106178
- const responseFiles = readdirSync12(sessionPath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
106956
+ const responseFiles = readdirSync13(sessionPath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
106179
106957
  if (responseFiles.length < 2) {
106180
106958
  throw new Error(`Need at least 2 responses to judge, found ${responseFiles.length}`);
106181
106959
  }
106182
106960
  const responses = {};
106183
106961
  for (const file of responseFiles) {
106184
106962
  const id = file.replace(/^response-/, "").replace(/\.md$/, "");
106185
- responses[id] = readFileSync45(join58(sessionPath, file), "utf-8");
106963
+ responses[id] = readFileSync46(join59(sessionPath, file), "utf-8");
106186
106964
  }
106187
- const input = readFileSync45(join58(sessionPath, "input.md"), "utf-8");
106965
+ const input = readFileSync46(join59(sessionPath, "input.md"), "utf-8");
106188
106966
  const judgePrompt = buildJudgePrompt(input, responses);
106189
- writeFileSync24(join58(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
106967
+ writeFileSync25(join59(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
106190
106968
  const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
106191
- const judgePath = join58(sessionPath, "judging");
106192
- mkdirSync26(judgePath, { recursive: true });
106969
+ const judgePath = join59(sessionPath, "judging");
106970
+ mkdirSync27(judgePath, { recursive: true });
106193
106971
  setupSession(judgePath, judgeModels, judgePrompt);
106194
106972
  await runModels(judgePath, {
106195
106973
  claudeFlags: opts.claudeFlags,
@@ -106200,11 +106978,11 @@ async function judgeResponses(sessionPath, opts = {}) {
106200
106978
  });
106201
106979
  const votes = parseJudgeVotes(judgePath, Object.keys(responses));
106202
106980
  const verdict = aggregateVerdict(votes, Object.keys(responses));
106203
- writeFileSync24(join58(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
106981
+ writeFileSync25(join59(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
106204
106982
  return verdict;
106205
106983
  }
106206
106984
  function getStatus(sessionPath) {
106207
- return JSON.parse(readFileSync45(join58(sessionPath, "status.json"), "utf-8"));
106985
+ return JSON.parse(readFileSync46(join59(sessionPath, "status.json"), "utf-8"));
106208
106986
  }
106209
106987
  function readTeamStatus(sessionPath) {
106210
106988
  try {
@@ -106244,7 +107022,7 @@ function fisherYatesShuffle(arr) {
106244
107022
  return arr;
106245
107023
  }
106246
107024
  function getDefaultJudgeModels(sessionPath) {
106247
- const manifest = JSON.parse(readFileSync45(join58(sessionPath, "manifest.json"), "utf-8"));
107025
+ const manifest = JSON.parse(readFileSync46(join59(sessionPath, "manifest.json"), "utf-8"));
106248
107026
  return Object.values(manifest.models).map((e) => e.model);
106249
107027
  }
106250
107028
  function buildJudgePrompt(input, responses) {
@@ -106302,12 +107080,12 @@ function buildJudgePrompt(input, responses) {
106302
107080
  }
106303
107081
  function parseJudgeVotes(judgePath, responseIds) {
106304
107082
  const votes = [];
106305
- const responseFiles = readdirSync12(judgePath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
107083
+ const responseFiles = readdirSync13(judgePath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
106306
107084
  for (const file of responseFiles) {
106307
107085
  const judgeId = file.replace(/^response-/, "").replace(/\.md$/, "");
106308
107086
  let content;
106309
107087
  try {
106310
- content = readFileSync45(join58(judgePath, file), "utf-8");
107088
+ content = readFileSync46(join59(judgePath, file), "utf-8");
106311
107089
  } catch (err) {
106312
107090
  log(`[team] judge answer ${file} unreadable: ${err instanceof Error ? err.message : String(err)}`);
106313
107091
  continue;
@@ -106360,7 +107138,7 @@ function aggregateVerdict(votes, responseIds) {
106360
107138
  function formatVerdict(verdict, sessionPath) {
106361
107139
  let manifest = null;
106362
107140
  try {
106363
- manifest = JSON.parse(readFileSync45(join58(sessionPath, "manifest.json"), "utf-8"));
107141
+ manifest = JSON.parse(readFileSync46(join59(sessionPath, "manifest.json"), "utf-8"));
106364
107142
  } catch {}
106365
107143
  let output = `# Team Verdict
106366
107144
 
@@ -106416,8 +107194,8 @@ var init_team_orchestrator = __esm(() => {
106416
107194
  });
106417
107195
 
106418
107196
  // src/mcp-session/inherited-settings.ts
106419
- import { existsSync as existsSync41, readFileSync as readFileSync46, statSync as statSync23 } from "fs";
106420
- import { join as join59, resolve as resolve9 } from "path";
107197
+ import { existsSync as existsSync41, readFileSync as readFileSync47, statSync as statSync24 } from "fs";
107198
+ import { join as join60, resolve as resolve9 } from "path";
106421
107199
  function isPlainObject7(value) {
106422
107200
  return typeof value === "object" && value !== null && !Array.isArray(value);
106423
107201
  }
@@ -106462,7 +107240,7 @@ function readSettingsValue(value) {
106462
107240
  return parseLayer(value, value);
106463
107241
  let text;
106464
107242
  try {
106465
- text = readFileSync46(value, "utf-8");
107243
+ text = readFileSync47(value, "utf-8");
106466
107244
  } catch (err) {
106467
107245
  throw new Error(`invalid_args: settings ${value} cannot be read (${err.message})`);
106468
107246
  }
@@ -106471,10 +107249,10 @@ function readSettingsValue(value) {
106471
107249
  function buildInheritedSettingsLayer(setupFrom, callerFlags) {
106472
107250
  const layers = [];
106473
107251
  for (const name of ["settings.json", "settings.local.json"]) {
106474
- const file = join59(setupFrom, ".claude", name);
107252
+ const file = join60(setupFrom, ".claude", name);
106475
107253
  if (!existsSync41(file))
106476
107254
  continue;
106477
- layers.push(parseLayer(readFileSync46(file, "utf-8"), file));
107255
+ layers.push(parseLayer(readFileSync47(file, "utf-8"), file));
106478
107256
  }
106479
107257
  const restFlags = [];
106480
107258
  for (let i = 0;i < callerFlags.length; i++) {
@@ -106504,7 +107282,7 @@ function resolveSetupFrom(arg, workDir, serverCwd) {
106504
107282
  let setupFrom = serverCwd;
106505
107283
  if (typeof arg === "string") {
106506
107284
  setupFrom = resolve9(arg);
106507
- if (!statSync23(setupFrom, { throwIfNoEntry: false })?.isDirectory()) {
107285
+ if (!statSync24(setupFrom, { throwIfNoEntry: false })?.isDirectory()) {
106508
107286
  throw new Error(`invalid_args: setup_from ${setupFrom} is not an existing directory`);
106509
107287
  }
106510
107288
  } else if (arg !== undefined) {
@@ -106521,16 +107299,16 @@ import {
106521
107299
  closeSync as closeSync17,
106522
107300
  createWriteStream,
106523
107301
  existsSync as existsSync42,
106524
- mkdirSync as mkdirSync27,
107302
+ mkdirSync as mkdirSync28,
106525
107303
  openSync as openSync16,
106526
- readFileSync as readFileSync47,
107304
+ readFileSync as readFileSync48,
106527
107305
  readSync as readSync7,
106528
- renameSync as renameSync10,
106529
- rmSync as rmSync16,
106530
- statSync as statSync24,
106531
- writeFileSync as writeFileSync25
107306
+ renameSync as renameSync11,
107307
+ rmSync as rmSync17,
107308
+ statSync as statSync25,
107309
+ writeFileSync as writeFileSync26
106532
107310
  } from "fs";
106533
- import { join as join60, resolve as resolve10, sep as sep3 } from "path";
107311
+ import { join as join61, resolve as resolve10, sep as sep3 } from "path";
106534
107312
  function normaliseTimeoutSeconds(raw) {
106535
107313
  const n = typeof raw === "string" && raw.trim() !== "" ? Number(raw) : raw;
106536
107314
  if (typeof n !== "number" || !Number.isFinite(n))
@@ -106624,8 +107402,8 @@ function toMetaRecord(info, cwd) {
106624
107402
  }
106625
107403
  function writeJsonAtomic(path, value) {
106626
107404
  const tmp = `${path}.tmp`;
106627
- writeFileSync25(tmp, JSON.stringify(value, null, 2), "utf-8");
106628
- renameSync10(tmp, path);
107405
+ writeFileSync26(tmp, JSON.stringify(value, null, 2), "utf-8");
107406
+ renameSync11(tmp, path);
106629
107407
  }
106630
107408
  function anomalyKey(a) {
106631
107409
  const at = a.lastIndexOf(" \xD7");
@@ -106634,7 +107412,7 @@ function anomalyKey(a) {
106634
107412
  function readTailText(path, maxBytes) {
106635
107413
  let fd = null;
106636
107414
  try {
106637
- const size = statSync24(path).size;
107415
+ const size = statSync25(path).size;
106638
107416
  if (size === 0)
106639
107417
  return { text: "", truncated: false };
106640
107418
  const start = Math.max(0, size - maxBytes);
@@ -106665,7 +107443,7 @@ function readTailLines2(path, maxBytes) {
106665
107443
  }
106666
107444
  function fileSize2(path) {
106667
107445
  try {
106668
- return statSync24(path).size;
107446
+ return statSync25(path).size;
106669
107447
  } catch {
106670
107448
  return 0;
106671
107449
  }
@@ -106674,7 +107452,7 @@ function readJsonObject(path, maxBytes) {
106674
107452
  try {
106675
107453
  if (fileSize2(path) > maxBytes)
106676
107454
  return null;
106677
- const parsed = JSON.parse(readFileSync47(path, "utf-8"));
107455
+ const parsed = JSON.parse(readFileSync48(path, "utf-8"));
106678
107456
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
106679
107457
  return null;
106680
107458
  return parsed;
@@ -106700,7 +107478,7 @@ function dropLeadingFragment(tail) {
106700
107478
  return firstBreak === -1 ? tail.text : tail.text.slice(firstBreak + 1);
106701
107479
  }
106702
107480
  function diskAccounting(sessionDir) {
106703
- const stats = readTokenStatsAt(join60(sessionDir, "tokens.json"));
107481
+ const stats = readTokenStatsAt(join61(sessionDir, "tokens.json"));
106704
107482
  return {
106705
107483
  tokensIn: stats?.billed_input_tokens ?? null,
106706
107484
  tokensOut: stats?.output_tokens ?? null,
@@ -106780,14 +107558,14 @@ class SessionManager {
106780
107558
  return this._launcherPid;
106781
107559
  }
106782
107560
  recordTeamRun(opts) {
106783
- mkdirSync27(this.sessionsDir, { recursive: true });
107561
+ mkdirSync28(this.sessionsDir, { recursive: true });
106784
107562
  let id = "";
106785
107563
  let dir = "";
106786
107564
  for (let attempt = 0;; attempt++) {
106787
107565
  id = `team-${randomUUID11().replace(/-/g, "").slice(0, 8)}`;
106788
- dir = join60(this.sessionsDir, id);
107566
+ dir = join61(this.sessionsDir, id);
106789
107567
  try {
106790
- mkdirSync27(dir);
107568
+ mkdirSync28(dir);
106791
107569
  break;
106792
107570
  } catch (err) {
106793
107571
  if (err?.code !== "EEXIST" || attempt >= 4)
@@ -106817,9 +107595,9 @@ class SessionManager {
106817
107595
  if (dir === null)
106818
107596
  throw new Error("not a record id");
106819
107597
  const completedAt = new Date().toISOString();
106820
- const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(join60(dir, "spawn.json"), META_READ_LIMIT)?.startedAt) ?? completedAt;
107598
+ const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(join61(dir, "spawn.json"), META_READ_LIMIT)?.startedAt) ?? completedAt;
106821
107599
  const elapsedMs = Date.parse(completedAt) - Date.parse(startedAt);
106822
- writeJsonAtomic(join60(dir, "meta.json"), {
107600
+ writeJsonAtomic(join61(dir, "meta.json"), {
106823
107601
  kind: "team",
106824
107602
  status: outcome.status,
106825
107603
  startedAt,
@@ -106851,7 +107629,7 @@ class SessionManager {
106851
107629
  startedAt,
106852
107630
  ...rest
106853
107631
  };
106854
- writeJsonAtomic(join60(dir, "spawn.json"), body);
107632
+ writeJsonAtomic(join61(dir, "spawn.json"), body);
106855
107633
  }
106856
107634
  async createSession(opts) {
106857
107635
  if (this.activeSessions + this.starting >= this.maxSessions) {
@@ -106891,7 +107669,7 @@ class SessionManager {
106891
107669
  throw err;
106892
107670
  }
106893
107671
  if (inherited.layer) {
106894
- flags = [...inherited.restFlags, "--settings", join60(entry.sessionDir, INHERITED_SETTINGS)];
107672
+ flags = [...inherited.restFlags, "--settings", join61(entry.sessionDir, INHERITED_SETTINGS)];
106895
107673
  }
106896
107674
  this.sessions.set(entry.info.sessionId, entry);
106897
107675
  uncount();
@@ -106916,10 +107694,10 @@ class SessionManager {
106916
107694
  const timeout = normaliseTimeoutSeconds(opts.timeoutSeconds);
106917
107695
  const agentRequested = requestedAgentOf(opts.claudishFlags ?? []);
106918
107696
  const startedAt = new Date().toISOString();
106919
- const sessionDir = opts.sessionDir ?? join60(this.sessionsDir, sessionId);
106920
- mkdirSync27(sessionDir, { recursive: true });
107697
+ const sessionDir = opts.sessionDir ?? join61(this.sessionsDir, sessionId);
107698
+ mkdirSync28(sessionDir, { recursive: true });
106921
107699
  if (opts.prompt)
106922
- writeFileSync25(join60(sessionDir, "prompt.md"), opts.prompt, "utf-8");
107700
+ writeFileSync26(join61(sessionDir, "prompt.md"), opts.prompt, "utf-8");
106923
107701
  this.writeSpawnRecord(sessionDir, {
106924
107702
  kind: "session",
106925
107703
  sessionId,
@@ -106932,13 +107710,13 @@ class SessionManager {
106932
107710
  ...agentRequested ? { agentRequested } : {}
106933
107711
  });
106934
107712
  if (inheritedLayer) {
106935
- writeFileSync25(join60(sessionDir, INHERITED_SETTINGS), `${JSON.stringify(inheritedLayer, null, 2)}
107713
+ writeFileSync26(join61(sessionDir, INHERITED_SETTINGS), `${JSON.stringify(inheritedLayer, null, 2)}
106936
107714
  `, { encoding: "utf-8", mode: 384 });
106937
107715
  }
106938
107716
  const cwd = opts.cwd ?? process.cwd();
106939
107717
  const parentEnv = opts.parentEnv ?? this.parentEnv;
106940
107718
  const spawnModel = opts.spawnModel ?? null;
106941
- const tokenFile = opts.tokenFile ?? join60(sessionDir, "tokens.json");
107719
+ const tokenFile = opts.tokenFile ?? join61(sessionDir, "tokens.json");
106942
107720
  return {
106943
107721
  info: {
106944
107722
  sessionId,
@@ -106976,18 +107754,18 @@ class SessionManager {
106976
107754
  },
106977
107755
  session: null,
106978
107756
  scrollback: new ScrollbackBuffer(this.scrollbackCapacity),
106979
- outputLogStream: createWriteStream(join60(sessionDir, "output.log")),
107757
+ outputLogStream: createWriteStream(join61(sessionDir, "output.log")),
106980
107758
  sessionDir,
106981
107759
  cwd,
106982
107760
  tokenFile,
106983
- eventLogPath: join60(sessionDir, "events.jsonl"),
107761
+ eventLogPath: join61(sessionDir, "events.jsonl"),
106984
107762
  eventLogBytes: 0,
106985
- upstreamErrorLogPath: join60(sessionDir, "upstream-errors.jsonl"),
107763
+ upstreamErrorLogPath: join61(sessionDir, "upstream-errors.jsonl"),
106986
107764
  eventRing: [],
106987
107765
  proseBytes: 0,
106988
107766
  answeredTurns: new Map,
106989
107767
  inboxPath: null,
106990
- waitLogPath: join60(sessionDir, "waits.jsonl"),
107768
+ waitLogPath: join61(sessionDir, "waits.jsonl"),
106991
107769
  waitLogBytes: 0,
106992
107770
  waitSince: null,
106993
107771
  ended: false,
@@ -107089,7 +107867,7 @@ class SessionManager {
107089
107867
  if (!entry.inboxPath)
107090
107868
  return;
107091
107869
  try {
107092
- rmSync16(entry.inboxPath, { force: true });
107870
+ rmSync17(entry.inboxPath, { force: true });
107093
107871
  } catch {}
107094
107872
  }
107095
107873
  failNeverSpawned(entry, err) {
@@ -107182,7 +107960,7 @@ class SessionManager {
107182
107960
  try {
107183
107961
  const text = screenLines.join(`
107184
107962
  `).replace(/\s+$/, "");
107185
- writeFileSync25(join60(entry.sessionDir, "screen.txt"), `${redactSecrets(text)}
107963
+ writeFileSync26(join61(entry.sessionDir, "screen.txt"), `${redactSecrets(text)}
107186
107964
  `, "utf-8");
107187
107965
  } catch {}
107188
107966
  }
@@ -107196,7 +107974,7 @@ class SessionManager {
107196
107974
  entry.waitSince = null;
107197
107975
  }
107198
107976
  try {
107199
- writeJsonAtomic(join60(entry.sessionDir, "meta.json"), toMetaRecord(entry.info, entry.cwd));
107977
+ writeJsonAtomic(join61(entry.sessionDir, "meta.json"), toMetaRecord(entry.info, entry.cwd));
107200
107978
  } catch (err) {
107201
107979
  process.stderr.write(`[claudish] session ${entry.info.sessionId}: could not write meta.json: ` + `${err instanceof Error ? err.message : String(err)}
107202
107980
  `);
@@ -107448,13 +108226,13 @@ class SessionManager {
107448
108226
  if (sessionDir === null)
107449
108227
  return null;
107450
108228
  try {
107451
- if (!statSync24(sessionDir).isDirectory())
108229
+ if (!statSync25(sessionDir).isDirectory())
107452
108230
  return null;
107453
108231
  } catch {
107454
108232
  return null;
107455
108233
  }
107456
- const spawnPath = join60(sessionDir, "spawn.json");
107457
- const metaPath = join60(sessionDir, "meta.json");
108234
+ const spawnPath = join61(sessionDir, "spawn.json");
108235
+ const metaPath = join61(sessionDir, "meta.json");
107458
108236
  const spawnRecord = readJsonObject(spawnPath, META_READ_LIMIT);
107459
108237
  if (spawnRecord?.kind === "team")
107460
108238
  return null;
@@ -107548,7 +108326,7 @@ class SessionManager {
107548
108326
  return null;
107549
108327
  const root = resolve10(this.sessionsDir);
107550
108328
  const dir = resolve10(root, sessionId);
107551
- if (dir !== join60(root, sessionId))
108329
+ if (dir !== join61(root, sessionId))
107552
108330
  return null;
107553
108331
  if (!dir.startsWith(root + sep3))
107554
108332
  return null;
@@ -107560,17 +108338,17 @@ class SessionManager {
107560
108338
  return null;
107561
108339
  let dirMtimeMs;
107562
108340
  try {
107563
- const stat = statSync24(sessionDir);
108341
+ const stat = statSync25(sessionDir);
107564
108342
  if (!stat.isDirectory())
107565
108343
  return null;
107566
108344
  dirMtimeMs = stat.mtimeMs;
107567
108345
  } catch {
107568
108346
  return null;
107569
108347
  }
107570
- const spawnRecord = readJsonObject(join60(sessionDir, "spawn.json"), META_READ_LIMIT);
108348
+ const spawnRecord = readJsonObject(join61(sessionDir, "spawn.json"), META_READ_LIMIT);
107571
108349
  if (spawnRecord?.kind === "team")
107572
108350
  return null;
107573
- const meta = readJsonObject(join60(sessionDir, "meta.json"), META_READ_LIMIT);
108351
+ const meta = readJsonObject(join61(sessionDir, "meta.json"), META_READ_LIMIT);
107574
108352
  if (meta?.kind === "team")
107575
108353
  return null;
107576
108354
  const partial = meta === null;
@@ -107592,7 +108370,7 @@ class SessionManager {
107592
108370
  return stored;
107593
108371
  }
107594
108372
  diskOutput(record, tailLines) {
107595
- const tail = readTailText(join60(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
108373
+ const tail = readTailText(join61(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
107596
108374
  const buffer = new ScrollbackBuffer(this.scrollbackCapacity);
107597
108375
  if (tail?.text)
107598
108376
  buffer.append(dropLeadingFragment(tail));
@@ -107612,12 +108390,12 @@ class SessionManager {
107612
108390
  }
107613
108391
  diskDiagnostics(record, limit) {
107614
108392
  const { sessionDir, info } = record;
107615
- const eventLogPath = join60(sessionDir, "events.jsonl");
107616
- const upstreamErrorLogPath = join60(sessionDir, "upstream-errors.jsonl");
107617
- const outputLogPath = join60(sessionDir, "output.log");
108393
+ const eventLogPath = join61(sessionDir, "events.jsonl");
108394
+ const upstreamErrorLogPath = join61(sessionDir, "upstream-errors.jsonl");
108395
+ const outputLogPath = join61(sessionDir, "output.log");
107618
108396
  const events = readTailLines2(eventLogPath, EVENT_TAIL_BYTES);
107619
108397
  const outputTail = readTailText(outputLogPath, OUTPUT_TAIL_BYTES);
107620
- const screen = readTailText(join60(sessionDir, "screen.txt"), SCREEN_READ_BYTES);
108398
+ const screen = readTailText(join61(sessionDir, "screen.txt"), SCREEN_READ_BYTES);
107621
108399
  return {
107622
108400
  sessionId: info.sessionId,
107623
108401
  state: info.state,
@@ -108022,9 +108800,9 @@ var init_progress_heartbeat = __esm(() => {
108022
108800
 
108023
108801
  // src/mcp/run-prompt-claude-code.ts
108024
108802
  import { spawn as spawn3 } from "child_process";
108025
- import { mkdirSync as mkdirSync28, mkdtempSync as mkdtempSync4, rmSync as rmSync17, writeFileSync as writeFileSync26 } from "fs";
108803
+ import { mkdirSync as mkdirSync29, mkdtempSync as mkdtempSync4, rmSync as rmSync18, writeFileSync as writeFileSync27 } from "fs";
108026
108804
  import { tmpdir as tmpdir3 } from "os";
108027
- import { join as join61 } from "path";
108805
+ import { join as join62 } from "path";
108028
108806
  function claudeCodePrintArgv(model, systemPromptFile) {
108029
108807
  const head = [PRINT_FLAGS[0], "--model", model, ...PRINT_FLAGS.slice(1)];
108030
108808
  return systemPromptFile !== undefined ? [...head, "--system-prompt-file", systemPromptFile] : [...head, "--system-prompt", ""];
@@ -108144,14 +108922,14 @@ async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
108144
108922
  } catch (e) {
108145
108923
  throw new Error(`cannot start claudish (${parentEnv.CLAUDISH_BIN?.trim() || "claudish"}): ${e instanceof Error ? e.message : String(e)}`);
108146
108924
  }
108147
- const root = mkdtempSync4(join61(tmpdir3(), "claudish-run-prompt-"));
108925
+ const root = mkdtempSync4(join62(tmpdir3(), "claudish-run-prompt-"));
108148
108926
  try {
108149
- const cwd = join61(root, "cwd");
108150
- mkdirSync28(cwd, { mode: 448 });
108927
+ const cwd = join62(root, "cwd");
108928
+ mkdirSync29(cwd, { mode: 448 });
108151
108929
  let systemPromptFile;
108152
108930
  if (typeof systemPrompt === "string" && systemPrompt.length > 0) {
108153
- systemPromptFile = join61(root, "system-prompt.txt");
108154
- writeFileSync26(systemPromptFile, systemPrompt, { mode: 384 });
108931
+ systemPromptFile = join62(root, "system-prompt.txt");
108932
+ writeFileSync27(systemPromptFile, systemPrompt, { mode: 384 });
108155
108933
  }
108156
108934
  const argv = claudeCodePrintArgv(model, systemPromptFile);
108157
108935
  const outcome = await runChild(launch, argv, cwd, claudeCodePrintEnv(parentEnv), prompt, signal);
@@ -108178,7 +108956,7 @@ async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
108178
108956
  answer.auth = auth;
108179
108957
  return answer;
108180
108958
  } finally {
108181
- rmSync17(root, { recursive: true, force: true });
108959
+ rmSync18(root, { recursive: true, force: true });
108182
108960
  }
108183
108961
  }
108184
108962
  function runChild(launch, argv, cwd, env, prompt, signal) {
@@ -108451,14 +109229,14 @@ var init_preflight_chain = __esm(() => {
108451
109229
  });
108452
109230
 
108453
109231
  // src/mcp-server.ts
108454
- import { existsSync as existsSync43, readFileSync as readFileSync48, readdirSync as readdirSync13 } from "fs";
108455
- import { homedir as homedir40 } from "os";
108456
- import { dirname as dirname26, join as join62, resolve as resolve11 } from "path";
109232
+ import { existsSync as existsSync43, readFileSync as readFileSync49, readdirSync as readdirSync14 } from "fs";
109233
+ import { homedir as homedir41 } from "os";
109234
+ import { dirname as dirname27, join as join63, resolve as resolve11 } from "path";
108457
109235
  import { fileURLToPath as fileURLToPath3 } from "url";
108458
109236
  async function loadAllModels(forceRefresh = false) {
108459
109237
  if (!forceRefresh && existsSync43(OPENROUTER_MODELS_CACHE_PATH)) {
108460
109238
  try {
108461
- const cacheData = JSON.parse(readFileSync48(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
109239
+ const cacheData = JSON.parse(readFileSync49(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
108462
109240
  const lastUpdated = new Date(cacheData.lastUpdated);
108463
109241
  const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
108464
109242
  if (ageInDays <= CACHE_MAX_AGE_DAYS) {
@@ -108482,7 +109260,7 @@ async function loadAllModels(forceRefresh = false) {
108482
109260
  log(`[mcp] OpenRouter models fetch failed: ${err instanceof Error ? err.message : String(err)}`);
108483
109261
  try {
108484
109262
  if (existsSync43(OPENROUTER_MODELS_CACHE_PATH)) {
108485
- const cacheData = JSON.parse(readFileSync48(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
109263
+ const cacheData = JSON.parse(readFileSync49(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
108486
109264
  return cacheData.models || [];
108487
109265
  }
108488
109266
  } catch (cacheErr) {
@@ -109661,8 +110439,8 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109661
110439
  const promptText = () => {
109662
110440
  if (input !== undefined)
109663
110441
  return input;
109664
- const existing = join62(resolved, "input.md");
109665
- return existsSync43(existing) ? readFileSync48(existing, "utf-8") : undefined;
110442
+ const existing = join63(resolved, "input.md");
110443
+ return existsSync43(existing) ? readFileSync49(existing, "utf-8") : undefined;
109666
110444
  };
109667
110445
  const choice = await modelChoiceStop([
109668
110446
  ...runsModels && givenModels && models ? givenModels.map((given, i) => ({ given, spec: models[i] })) : [],
@@ -109836,7 +110614,7 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109836
110614
  let stderrFull = stderr_snippet || "";
109837
110615
  if (error_log_path) {
109838
110616
  try {
109839
- stderrFull = readFileSync48(error_log_path, "utf-8");
110617
+ stderrFull = readFileSync49(error_log_path, "utf-8");
109840
110618
  } catch {}
109841
110619
  }
109842
110620
  const sessionData = {};
@@ -109844,26 +110622,26 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109844
110622
  const sp = session_path;
109845
110623
  for (const file of ["status.json", "manifest.json", "input.md"]) {
109846
110624
  try {
109847
- sessionData[file] = readFileSync48(join62(sp, file), "utf-8");
110625
+ sessionData[file] = readFileSync49(join63(sp, file), "utf-8");
109848
110626
  } catch {}
109849
110627
  }
109850
110628
  try {
109851
- const errorDir = join62(sp, "errors");
110629
+ const errorDir = join63(sp, "errors");
109852
110630
  if (existsSync43(errorDir)) {
109853
- for (const f of readdirSync13(errorDir)) {
110631
+ for (const f of readdirSync14(errorDir)) {
109854
110632
  if (f.endsWith(".log")) {
109855
110633
  try {
109856
- sessionData[`errors/${f}`] = readFileSync48(join62(errorDir, f), "utf-8");
110634
+ sessionData[`errors/${f}`] = readFileSync49(join63(errorDir, f), "utf-8");
109857
110635
  } catch {}
109858
110636
  }
109859
110637
  }
109860
110638
  }
109861
110639
  } catch {}
109862
110640
  try {
109863
- for (const f of readdirSync13(sp)) {
110641
+ for (const f of readdirSync14(sp)) {
109864
110642
  if (f.startsWith("response-") && f.endsWith(".md")) {
109865
110643
  try {
109866
- const content = readFileSync48(join62(sp, f), "utf-8");
110644
+ const content = readFileSync49(join63(sp, f), "utf-8");
109867
110645
  sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
109868
110646
  } catch {}
109869
110647
  }
@@ -109872,9 +110650,9 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109872
110650
  }
109873
110651
  let version = "unknown";
109874
110652
  try {
109875
- const pkgPath = join62(__dirname3, "../package.json");
110653
+ const pkgPath = join63(__dirname3, "../package.json");
109876
110654
  if (existsSync43(pkgPath)) {
109877
- version = JSON.parse(readFileSync48(pkgPath, "utf-8")).version;
110655
+ version = JSON.parse(readFileSync49(pkgPath, "utf-8")).version;
109878
110656
  }
109879
110657
  } catch {}
109880
110658
  const report = {
@@ -110609,9 +111387,9 @@ var init_mcp_server = __esm(() => {
110609
111387
  init_team_orchestrator();
110610
111388
  init_preflight_chain();
110611
111389
  __filename3 = fileURLToPath3(import.meta.url);
110612
- __dirname3 = dirname26(__filename3);
110613
- CLAUDISH_CACHE_DIR = join62(homedir40(), ".claudish");
110614
- OPENROUTER_MODELS_CACHE_PATH = join62(CLAUDISH_CACHE_DIR, "openrouter-models.json");
111390
+ __dirname3 = dirname27(__filename3);
111391
+ CLAUDISH_CACHE_DIR = join63(homedir41(), ".claudish");
111392
+ OPENROUTER_MODELS_CACHE_PATH = join63(CLAUDISH_CACHE_DIR, "openrouter-models.json");
110615
111393
  NEXT_STEP = {
110616
111394
  cancelled: "you stopped this slot; nothing is wrong with it. Re-run it if you still want its vote",
110617
111395
  timeout: "grid mode only \u2014 magmux ended the pane. The orchestrator has no deadline",
@@ -110636,7 +111414,7 @@ var init_mcp_server = __esm(() => {
110636
111414
  });
110637
111415
 
110638
111416
  // src/serve-command.ts
110639
- import { existsSync as existsSync44, readFileSync as readFileSync49 } from "fs";
111417
+ import { existsSync as existsSync44, readFileSync as readFileSync50 } from "fs";
110640
111418
  function parseServeArgs(args) {
110641
111419
  const out = {};
110642
111420
  for (let i = 0;i < args.length; i++) {
@@ -110660,7 +111438,7 @@ function loadModelMap(path) {
110660
111438
  }
110661
111439
  let raw;
110662
111440
  try {
110663
- raw = readFileSync49(path, "utf-8");
111441
+ raw = readFileSync50(path, "utf-8");
110664
111442
  } catch (e) {
110665
111443
  throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
110666
111444
  }
@@ -110741,9 +111519,9 @@ var init_serve_command = __esm(() => {
110741
111519
  var HOOKS_AMBIENT_DTS = '// claudish hook types \u2014 written by `claudish hooks init`. Do not edit: run\n// `claudish hooks init` from a newer claudish to refresh it.\n// With this file beside your hook, `import type { HookDefinition } from\n// "claudish/hooks"` type-checks with nothing installed.\ndeclare module "claudish/hooks" {\n /**\n * claudish/hooks \u2014 the public hook contract.\n *\n * Everything a hook author can import lives here, and nothing else does. This\n * file imports nothing from the rest of claudish and has no side effects, so it\n * can be built on its own into `dist/hooks.js` + `dist/hooks.d.ts` and served to\n * user modules as the `claudish/hooks` virtual module (see `loader.ts`).\n *\n * Every internal hooks module takes its types from here, so the contract has a\n * single source.\n *\n * ## Process isolation\n *\n * A hook module\'s top-level state is PER PROCESS. In the interactive launcher,\n * proxy events (`request` \u2026 `responseEnd`, raw) and session events\n * (`sessionStart` \u2026 `sessionEnd`) run in one process. In `create_session` and\n * team children they do not: proxy events run in the pane child, and session\n * events run in the MCP server or the CLI process that drives the pane. Pass\n * per-turn data from a proxy event to `sessionIdle` with `annotateTurn`, never\n * with module variables.\n *\n * ## Execution: a hook chain\n *\n * The hooks of one event run one after another, in effective order. Each hook\'s\n * actions are applied before the next hook is called, so `ctx.request`,\n * `ctx.tool.args` and `ctx.response` show what the earlier hooks did, and\n * `ctx.prior` lists it. A warn-severity or failing hook changes nothing for the\n * next one. Each event has a budget for all its hooks together; a hook\'s timeout\n * is cut to what is left of it.\n *\n * ## Output\n *\n * Log with `ctx.log`. `console.*` and `process.stdout`/`stderr` writes made by a\n * hook are routed to claudish\'s debug log, never to the terminal or the MCP\n * protocol stream.\n */\n export const HOOK_API_VERSION = 1;\n export type Severity = "off" | "warn" | "fix";\n export type HookOrder = "pre" | "normal" | "post";\n /** native = RouteInfo.native true; foreign = RouteInfo.native false; all = both */\n export type RouteScope = "foreign" | "native" | "all";\n export type HostMode = "interactive" | "pane-child" | "serve" | "mcp" | "other";\n export type JsonValue = string | number | boolean | null | ReadonlyArray<JsonValue> | {\n readonly [k: string]: JsonValue;\n };\n export interface HarnessFacts {\n readonly planModeActive: boolean;\n readonly planFilePath?: string;\n readonly planDir?: string;\n /** Claude Code session id from request metadata */\n readonly sessionId?: string;\n /** empty = no listing found, not "no skills" */\n readonly skills?: ReadonlyArray<{\n name: string;\n description: string;\n }>;\n }\n export interface RouteInfo {\n /** bare model name the handler serves, e.g. "glm-5" */\n readonly modelId: string;\n /** claudish provider name, e.g. "openrouter"; "anthropic" for native */\n readonly provider: string;\n /**\n * true when the request is served by the native Anthropic handler, OR when\n * !forceForeignModel && (/^claude[-.]/i.test(modelId) || provider === "anthropic")\n * where forceForeignModel is the provider profile\'s opt-in override. This is the exact\n * rule the plan-mode built-in has always used (a claude-* uid on an aggregator that sets\n * forceForeignModel is foreign).\n */\n readonly native: boolean;\n }\n export interface ClaudeTool {\n name: string;\n description?: string;\n input_schema?: unknown;\n }\n /** A Claude-format content block. Only `text` blocks are editable by closed actions. */\n export type ClaudeContentBlock = {\n type: "text";\n text: string;\n } | {\n type: "tool_use";\n id: string;\n name: string;\n input: unknown;\n } | {\n type: "tool_result";\n tool_use_id: string;\n content?: unknown;\n is_error?: boolean;\n } | {\n type: "thinking";\n thinking: string;\n signature?: string;\n } | {\n type: string;\n [k: string]: unknown;\n };\n export interface ClaudeMessage {\n role: "user" | "assistant";\n content: string | ReadonlyArray<ClaudeContentBlock>;\n }\n /**\n * In `request`, the request as the earlier steps of the hook chain left it. On\n * the response side and in `claims()`, the request chain\'s final view.\n */\n export interface RequestFacts {\n /** as Claude Code asked for it; frozen */\n readonly model: string;\n /** frozen */\n readonly stream: boolean;\n /** system prompt flattened to text, after earlier steps */\n readonly systemText: string;\n /** read-only view after earlier steps; change it through actions */\n readonly messages: ReadonlyArray<ClaudeMessage>;\n /**\n * read-only view after earlier steps; `description` includes earlier description actions as\n * stage B will apply them to the Claude-format tool (the provider copy may be summarised)\n */\n readonly tools: ReadonlyArray<ClaudeTool>;\n }\n /** Which session a proxy event belongs to, when claudish knows. */\n export interface ProxySessionRef {\n readonly kind: SessionKind;\n readonly id: string;\n readonly role: "slot" | "judge" | null;\n }\n /** One action an earlier step of this hook chain applied or handed on. */\n export interface PriorAction {\n readonly hookId: string;\n readonly action: HookAction;\n }\n interface BaseContext {\n readonly hookId: string;\n /** "warn" or "fix" (an "off" hook is never called) */\n readonly severity: Severity;\n /** writes to claudish\'s debug log; never to the terminal */\n log(message: string): void;\n /**\n * this step\'s own signal: aborted when its step timeout elapses (its own timeout, or the\n * event budget left, whichever is shorter) or when the dispatch is aborted. Never shared\n * with another hook\'s step.\n */\n readonly signal: AbortSignal;\n /**\n * actions earlier steps of this hook chain applied (or, for responseEnd/sessionStart/\n * sessionIdle, handed on), in order. Empty for the first step and in claims()/the toolCall\n * predicate. Never lists warn actions or anything a warn-severity hook returned.\n */\n readonly prior: ReadonlyArray<PriorAction>;\n }\n export interface ProxyContext extends BaseContext {\n readonly host: {\n mode: HostMode;\n };\n readonly route: RouteInfo;\n readonly request: RequestFacts;\n readonly harness: HarnessFacts;\n readonly session: ProxySessionRef | null;\n }\n export interface RequestContext extends ProxyContext {\n readonly event: "request";\n }\n export interface ToolCallContext extends ProxyContext {\n readonly event: "toolCall";\n readonly tool: {\n id: string;\n name: string;\n /** the arguments after every repair earlier hooks in the chain applied */\n args: Readonly<Record<string, unknown>>;\n /** the argument JSON exactly as the model produced it; never rewritten */\n rawArgs: string;\n };\n }\n export type ResponseBlock = {\n type: "text";\n text: string;\n } | {\n type: "thinking";\n thinking: string;\n } | {\n type: "tool_use";\n id: string;\n name: string;\n input: unknown;\n } | {\n type: "other";\n blockType: string;\n };\n export interface ResponseView {\n blocks: ReadonlyArray<ResponseBlock>;\n /** every text block, joined with "\\n\\n" */\n text: string;\n /** every thinking block, joined with "\\n\\n" */\n reasoning: string;\n toolNames: ReadonlyArray<string>;\n /** "tool_use" = an intermediate step of a tool loop; the turn continues after the tool runs */\n stopReason: string | null;\n }\n /** response = the held response after every text action earlier hooks in the chain applied */\n export interface ResponseRewriteContext extends ProxyContext {\n readonly event: "responseRewrite";\n readonly response: ResponseView;\n }\n /** response = the final bytes the client received: after any rewrite AND any raw `response` replacement */\n export interface ResponseEndContext extends ProxyContext {\n readonly event: "responseEnd";\n readonly response: ResponseView;\n }\n export type SessionKind = "interactive" | "channel" | "team";\n export interface SessionInfo {\n kind: SessionKind;\n /** team only; null otherwise */\n role: "slot" | "judge" | null;\n /** channel: the 8-hex session_id \xB7 team: "<run_id>:<slot id>" \xB7 interactive: the Claude Code session id */\n id: string;\n claudeSessionId: string | null;\n /** as the caller asked for it */\n model: string;\n cwd: string;\n /** a one-shot session stays "one-shot" through a hook-extended turn chain */\n shape: "interactive" | "one-shot";\n injection: "available" | "unavailable";\n }\n export interface SessionStartContext extends BaseContext {\n readonly event: "sessionStart";\n readonly session: SessionInfo;\n }\n export interface TurnAnnotation {\n hookId: string;\n key: string;\n value: JsonValue;\n }\n export interface SessionIdleContext extends BaseContext {\n readonly event: "sessionIdle";\n readonly session: SessionInfo;\n readonly turn: {\n /** 1-based within the session; a re-woken turn keeps its index */\n index: number;\n /** this turn\'s assistant text */\n answer: string;\n stopReason: string | null;\n apiError: boolean;\n /** this turn was started by an injection */\n hookCaused: boolean;\n /** annotateTurn actions from this turn\'s responses, in arrival order */\n annotations: ReadonlyArray<TurnAnnotation>;\n };\n readonly consecutiveHookTurns: number;\n /** caller/human input is queued; an injection returned now will be dropped as stale */\n readonly callerInputPending: boolean;\n }\n export interface SessionBlockedContext extends BaseContext {\n readonly event: "sessionBlocked";\n readonly session: SessionInfo;\n readonly block: {\n kind: "question" | "permission";\n text: string;\n };\n }\n export interface SessionEndContext extends BaseContext {\n readonly event: "sessionEnd";\n readonly session: SessionInfo;\n readonly outcome: {\n state: string;\n reason: string | null;\n exitCode: number | null;\n };\n }\n type TextMatch = {\n find: string;\n regex?: boolean;\n flags?: string;\n };\n /** default ["user"] */\n type MessageRoles = {\n roles?: ReadonlyArray<"user" | "assistant">;\n };\n export type InjectSystemNote = {\n type: "injectSystemNote";\n text: string;\n };\n export type AppendUserText = {\n type: "appendUserText";\n text: string;\n };\n export type ReplaceMessageText = {\n type: "replaceMessageText";\n replace: string;\n } & TextMatch & MessageRoles;\n export type RemoveMessageText = {\n type: "removeMessageText";\n } & TextMatch & MessageRoles;\n export type RewriteToolDescription = {\n type: "rewriteToolDescription";\n tool: string;\n append: string;\n };\n export type ReplaceToolDescription = {\n type: "replaceToolDescription";\n tool: string;\n description: string;\n };\n export type ReplaceToolSchema = {\n type: "replaceToolSchema";\n tool: string;\n inputSchema: {\n type: "object";\n [k: string]: unknown;\n };\n };\n export type RemoveTool = {\n type: "removeTool";\n tool: string;\n };\n export type RepairToolArgs = {\n type: "repairToolArgs";\n args: Record<string, unknown>;\n reason: string;\n };\n export type AppendText = {\n type: "appendText";\n text: string;\n };\n export type PrependText = {\n type: "prependText";\n text: string;\n };\n export type ReplaceText = {\n type: "replaceText";\n replace: string;\n } & TextMatch;\n export type RemoveText = {\n type: "removeText";\n } & TextMatch;\n export type InjectUserTurn = {\n type: "injectUserTurn";\n text: string;\n };\n export type AnnotateTurn = {\n type: "annotateTurn";\n key: string;\n value: JsonValue;\n };\n export type Warn = {\n type: "warn";\n message: string;\n };\n export type RequestAction = InjectSystemNote | AppendUserText | ReplaceMessageText | RemoveMessageText | RewriteToolDescription | ReplaceToolDescription | ReplaceToolSchema | RemoveTool | Warn;\n export type ToolCallAction = RepairToolArgs | Warn;\n export type RewriteAction = AppendText | PrependText | ReplaceText | RemoveText | Warn;\n export type ResponseEndAction = InjectSystemNote | InjectUserTurn | AnnotateTurn | Warn;\n export type SessionAction = InjectUserTurn | Warn;\n export type ObserveAction = Warn;\n export type HookAction = RequestAction | ToolCallAction | RewriteAction | ResponseEndAction | SessionAction;\n export type HookResult<A> = A[] | void | Promise<A[] | void>;\n export interface HookHandlers {\n request?(ctx: RequestContext): HookResult<RequestAction>;\n toolCall?: {\n /** tool names whose completed arguments this hook sees; "*" = every tool (costs streaming of all tool input) */\n tools: ReadonlyArray<string>;\n /** synchronous, per request; default true. false = not armed for this request */\n armed?(ctx: RequestContext): boolean;\n /** true = see the call after it was forwarded; can only warn; never holds the stream */\n observe?: boolean;\n handle(ctx: ToolCallContext): HookResult<ToolCallAction>;\n };\n responseRewrite?: {\n /** synchronous, per request, evaluated before the response starts; default true */\n claims?(ctx: RequestContext): boolean;\n handle(ctx: ResponseRewriteContext): HookResult<RewriteAction>;\n };\n responseEnd?(ctx: ResponseEndContext): HookResult<ResponseEndAction>;\n sessionStart?(ctx: SessionStartContext): HookResult<SessionAction>;\n sessionIdle?(ctx: SessionIdleContext): HookResult<SessionAction>;\n sessionBlocked?(ctx: SessionBlockedContext): HookResult<ObserveAction>;\n sessionEnd?(ctx: SessionEndContext): HookResult<ObserveAction>;\n }\n export interface RawProviderRequestContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n claudeRequest: any;\n messages: any[];\n tools: any[];\n }\n export interface RawProviderChunkContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n /** A clone of the parsed provider event. Whatever this field holds when the call returns is\n * what the parser reads from then on, so it may be edited in place or replaced. */\n chunk: any;\n /** The delta object inside `chunk` at call time (Responses wire: `chunk` itself). Edit it in\n * place; assigning a new object to this field has no effect. */\n delta: any;\n /** per-stream, shared across this hook\'s chunk calls; never cloned */\n metadata: Map<string, unknown>;\n }\n export interface RawProviderStreamEndContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n metadata: Map<string, unknown>;\n }\n export interface RawResponseContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n readonly request: RequestFacts;\n /** A replay of the current Claude-format response (SSE, or JSON for stream:false), read at the\n * hook\'s own pace. claudish drains the original itself, so leaving this unread delays nothing. */\n response: Response;\n }\n export interface RawMiddleware {\n /**\n * Receives clones. They replace the live request only when this call returns (or its promise\n * resolves) within its timeout. A throw, a rejection or a timeout discards every change.\n */\n providerRequest?(ctx: RawProviderRequestContext): void | Promise<void>;\n /**\n * MUST be synchronous. Called on the parser\'s loop, on a clone of the chunk. On a normal return\n * of anything but a thenable, the clone (whatever `ctx.chunk` holds then) is committed: it\n * becomes the object the parser reads, deletions included. On a throw nothing is committed.\n * A declared `async` function is rejected at load. Any other thenable return is an invalid\n * invocation: the clone is discarded even if the hook mutated it before returning, the call is\n * journaled `invalid` (`async_return`) and counts toward the circuit breaker, and a rejection\n * handler is attached, so a rejection is journaled `error` and never becomes an\n * unhandledRejection.\n */\n providerChunk?(ctx: RawProviderChunkContext): void;\n providerStreamEnd?(ctx: RawProviderStreamEndContext): void | Promise<void>;\n /**\n * Return a replacement Response, or nothing to keep the current one. A replacement is read\n * whole and forwarded only when it completes cleanly; on any failure the original is forwarded.\n * The client never sees a partial replacement. A replacement must close within this hook\'s\n * timeout after the later of this call\'s return and the end of the original; the original\'s end\n * never depends on whether `ctx.response` is read.\n */\n response?(ctx: RawResponseContext): Response | void | Promise<Response | void>;\n }\n interface HookBase {\n apiVersion: 1;\n id: string;\n description?: string;\n /** default "fix" for user hooks */\n defaultSeverity?: Severity;\n /** default "normal" */\n order?: HookOrder;\n /** globs on RouteInfo.modelId; default "*"; proxy events only */\n models?: string | ReadonlyArray<string>;\n /** default "all"; proxy events only */\n routes?: RouteScope;\n /** per call; clamped to the event\'s maximum and to the event budget left when the hook\'s turn comes */\n timeoutMs?: number;\n on?: HookHandlers;\n }\n export interface SafeHook extends HookBase {\n unsafe?: never;\n raw?: never;\n }\n export interface UnsafeHook extends HookBase {\n unsafe: true;\n raw: RawMiddleware;\n }\n /**\n * One hook. Module-level state is per process: in `create_session` and team\n * children, proxy events run in the pane child and session events in the MCP\n * server or CLI process. Pass per-turn data from proxy events to `sessionIdle`\n * with `annotateTurn`, never with module variables.\n */\n export type HookDefinition = SafeHook | UnsafeHook;\n /** Identity function: gives editor type-checking and inference. */\n export function defineHook<const H extends HookDefinition>(hook: H): H;\n /** Action constructors (plain data; equivalent to writing the object literal). */\n export const act: {\n injectSystemNote(text: string): InjectSystemNote;\n appendUserText(text: string): AppendUserText;\n replaceMessageText(find: string, replace: string, opts?: {\n regex?: boolean;\n flags?: string;\n roles?: ReadonlyArray<"user" | "assistant">;\n }): ReplaceMessageText;\n removeMessageText(find: string, opts?: {\n regex?: boolean;\n flags?: string;\n roles?: ReadonlyArray<"user" | "assistant">;\n }): RemoveMessageText;\n rewriteToolDescription(tool: string, append: string): RewriteToolDescription;\n replaceToolDescription(tool: string, description: string): ReplaceToolDescription;\n replaceToolSchema(tool: string, inputSchema: {\n type: "object";\n [k: string]: unknown;\n }): ReplaceToolSchema;\n removeTool(tool: string): RemoveTool;\n repairToolArgs(args: Record<string, unknown>, reason: string): RepairToolArgs;\n appendText(text: string): AppendText;\n prependText(text: string): PrependText;\n replaceText(find: string, replace: string, opts?: {\n regex?: boolean;\n flags?: string;\n }): ReplaceText;\n removeText(find: string, opts?: {\n regex?: boolean;\n flags?: string;\n }): RemoveText;\n injectUserTurn(text: string): InjectUserTurn;\n annotateTurn(key: string, value: JsonValue): AnnotateTurn;\n warn(message: string): Warn;\n };\n}\n';
110742
111520
 
110743
111521
  // src/hooks/observer/corpus.ts
110744
- import { appendFileSync as appendFileSync8, readFileSync as readFileSync50, readdirSync as readdirSync14, statSync as statSync25 } from "fs";
110745
- import { homedir as homedir41 } from "os";
110746
- import { join as join63 } from "path";
111522
+ import { appendFileSync as appendFileSync8, readFileSync as readFileSync51, readdirSync as readdirSync15, statSync as statSync26 } from "fs";
111523
+ import { homedir as homedir42 } from "os";
111524
+ import { join as join64 } from "path";
110747
111525
  function directoryOf2(filePath) {
110748
111526
  const slash = filePath.lastIndexOf("/");
110749
111527
  return slash > 0 ? filePath.slice(0, slash) : undefined;
@@ -110765,7 +111543,7 @@ function writeTargetsOf(row) {
110765
111543
  function replayTranscript(file) {
110766
111544
  let text;
110767
111545
  try {
110768
- text = readFileSync50(file, "utf8");
111546
+ text = readFileSync51(file, "utf8");
110769
111547
  } catch {
110770
111548
  return [];
110771
111549
  }
@@ -110817,31 +111595,31 @@ function listTranscripts(root) {
110817
111595
  const files = [];
110818
111596
  let projects;
110819
111597
  try {
110820
- projects = readdirSync14(root);
111598
+ projects = readdirSync15(root);
110821
111599
  } catch {
110822
111600
  return files;
110823
111601
  }
110824
111602
  for (const project of projects) {
110825
- const dir = join63(root, project);
111603
+ const dir = join64(root, project);
110826
111604
  try {
110827
- if (!statSync25(dir).isDirectory())
111605
+ if (!statSync26(dir).isDirectory())
110828
111606
  continue;
110829
- for (const f of readdirSync14(dir)) {
111607
+ for (const f of readdirSync15(dir)) {
110830
111608
  if (f.endsWith(".jsonl"))
110831
- files.push(join63(dir, f));
111609
+ files.push(join64(dir, f));
110832
111610
  }
110833
111611
  } catch {}
110834
111612
  }
110835
111613
  return files;
110836
111614
  }
110837
111615
  function buildCorpus(options = {}) {
110838
- const root = options.projectsRoot ?? join63(homedir41(), ".claude", "projects");
111616
+ const root = options.projectsRoot ?? join64(homedir42(), ".claude", "projects");
110839
111617
  const files = listTranscripts(root);
110840
111618
  const records = [];
110841
111619
  for (const f of files)
110842
111620
  records.push(...replayTranscript(f));
110843
111621
  if (options.write && records.length > 0) {
110844
- const outputPath = options.outputPath ?? join63(homedir41(), ".claudish", "behavior-divergences.jsonl");
111622
+ const outputPath = options.outputPath ?? join64(homedir42(), ".claudish", "behavior-divergences.jsonl");
110845
111623
  try {
110846
111624
  appendFileSync8(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
110847
111625
  `)}
@@ -110857,9 +111635,9 @@ var init_corpus = __esm(() => {
110857
111635
  });
110858
111636
 
110859
111637
  // src/hooks-command.ts
110860
- import { existsSync as existsSync45, mkdirSync as mkdirSync29, readFileSync as readFileSync51, writeFileSync as writeFileSync27 } from "fs";
110861
- import { homedir as homedir42 } from "os";
110862
- import { join as join64, resolve as resolve12 } from "path";
111638
+ import { existsSync as existsSync45, mkdirSync as mkdirSync30, readFileSync as readFileSync52, writeFileSync as writeFileSync28 } from "fs";
111639
+ import { homedir as homedir43 } from "os";
111640
+ import { join as join65, resolve as resolve12 } from "path";
110863
111641
  function severityColor(sev) {
110864
111642
  if (sev === "fix")
110865
111643
  return green(sev);
@@ -110982,10 +111760,10 @@ async function check(file, json) {
110982
111760
  return valid ? 0 : 1;
110983
111761
  }
110984
111762
  function init(dirArg) {
110985
- const dir = dirArg ? resolve12(process.cwd(), dirArg) : join64(homedir42(), ".claudish", "hooks");
111763
+ const dir = dirArg ? resolve12(process.cwd(), dirArg) : join65(homedir43(), ".claudish", "hooks");
110986
111764
  const files = [
110987
- [join64(dir, "example-hook.ts"), EXAMPLE_HOOK],
110988
- [join64(dir, "claudish-hooks.d.ts"), HOOKS_AMBIENT_DTS]
111765
+ [join65(dir, "example-hook.ts"), EXAMPLE_HOOK],
111766
+ [join65(dir, "claudish-hooks.d.ts"), HOOKS_AMBIENT_DTS]
110989
111767
  ];
110990
111768
  const existing = files.filter(([path]) => existsSync45(path)).map(([path]) => path);
110991
111769
  if (existing.length > 0) {
@@ -110993,9 +111771,9 @@ function init(dirArg) {
110993
111771
  console.error(`${path} already exists; not overwriting it.`);
110994
111772
  return 1;
110995
111773
  }
110996
- mkdirSync29(dir, { recursive: true });
111774
+ mkdirSync30(dir, { recursive: true });
110997
111775
  for (const [path, text] of files)
110998
- writeFileSync27(path, text, { flag: "wx" });
111776
+ writeFileSync28(path, text, { flag: "wx" });
110999
111777
  console.log(`
111000
111778
  wrote ${files.map(([p]) => p).join(`
111001
111779
  wrote `)}
@@ -111078,7 +111856,7 @@ function telemetry(action, json) {
111078
111856
  try {
111079
111857
  const path = outboxPath();
111080
111858
  if (existsSync45(path))
111081
- pending = readFileSync51(path, "utf8").split(`
111859
+ pending = readFileSync52(path, "utf8").split(`
111082
111860
  `).filter(Boolean).length;
111083
111861
  } catch {}
111084
111862
  if (json) {
@@ -111186,9 +111964,9 @@ var init_hooks_command = __esm(() => {
111186
111964
 
111187
111965
  // src/team-grid.ts
111188
111966
  import { spawn as spawn4 } from "child_process";
111189
- import { existsSync as existsSync46, readFileSync as readFileSync52, writeFileSync as writeFileSync28 } from "fs";
111967
+ import { existsSync as existsSync46, readFileSync as readFileSync53, writeFileSync as writeFileSync29 } from "fs";
111190
111968
  import { connect as netConnect3 } from "net";
111191
- import { join as join65 } from "path";
111969
+ import { join as join66 } from "path";
111192
111970
  import { setTimeout as wait } from "timers/promises";
111193
111971
  function paneRouteLine(explanation) {
111194
111972
  const origin = describeRouteExplanation(explanation);
@@ -111338,9 +112116,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
111338
112116
  const keep = opts?.keep ?? false;
111339
112117
  const manifest = setupSession(sessionPath, models, input);
111340
112118
  const startedAt = new Date().toISOString();
111341
- const gridfilePath = join65(sessionPath, "gridfile.txt");
111342
- const prompt = readFileSync52(join65(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
111343
- const rawPrompt = readFileSync52(join65(sessionPath, "input.md"), "utf-8");
112119
+ const gridfilePath = join66(sessionPath, "gridfile.txt");
112120
+ const prompt = readFileSync53(join66(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
112121
+ const rawPrompt = readFileSync53(join66(sessionPath, "input.md"), "utf-8");
111344
112122
  const usedBannerColors = new Set;
111345
112123
  const routeLines = mode === "interactive" ? new Map : await resolvePaneRouteLines(Object.values(manifest.models).map((entry) => entry.model));
111346
112124
  const gridLines = Object.entries(manifest.models).map(([anonId]) => {
@@ -111352,7 +112130,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
111352
112130
  const header = buildPaneHeader(model, routeLines.get(model) ?? "", rawPrompt, bg);
111353
112131
  return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
111354
112132
  });
111355
- writeFileSync28(gridfilePath, `${gridLines.join(`
112133
+ writeFileSync29(gridfilePath, `${gridLines.join(`
111356
112134
  `)}
111357
112135
  `, "utf-8");
111358
112136
  const magmuxPath = findMagmuxBinary();
@@ -111372,8 +112150,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
111372
112150
  });
111373
112151
  const [{ results }] = await Promise.all([subscription, procExit]);
111374
112152
  const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
111375
- const statusPath = join65(sessionPath, "status.json");
111376
- writeFileSync28(statusPath, JSON.stringify(status, null, 2), "utf-8");
112153
+ const statusPath = join66(sessionPath, "status.json");
112154
+ writeFileSync29(statusPath, JSON.stringify(status, null, 2), "utf-8");
111377
112155
  return status;
111378
112156
  }
111379
112157
  var BANNER_BG_COLORS;
@@ -111392,8 +112170,8 @@ var init_team_grid = __esm(() => {
111392
112170
  });
111393
112171
 
111394
112172
  // src/team-cli.ts
111395
- import { readFileSync as readFileSync53 } from "fs";
111396
- import { join as join66 } from "path";
112173
+ import { readFileSync as readFileSync54 } from "fs";
112174
+ import { join as join67 } from "path";
111397
112175
  async function runPaneTeam(sessionPath, models, input, opts) {
111398
112176
  installPaneShutdownHooks({ exitAfter: true });
111399
112177
  try {
@@ -111538,7 +112316,7 @@ async function teamCommand(args) {
111538
112316
  }
111539
112317
  case "judge": {
111540
112318
  await judgeResponses(sessionPath, { judges });
111541
- console.log(readFileSync53(join66(sessionPath, "verdict.md"), "utf-8"));
112319
+ console.log(readFileSync54(join67(sessionPath, "verdict.md"), "utf-8"));
111542
112320
  break;
111543
112321
  }
111544
112322
  case "run-and-judge": {
@@ -111554,7 +112332,7 @@ async function teamCommand(args) {
111554
112332
  });
111555
112333
  printStatus(status);
111556
112334
  await judgeResponses(sessionPath, { judges });
111557
- console.log(readFileSync53(join66(sessionPath, "verdict.md"), "utf-8"));
112335
+ console.log(readFileSync54(join67(sessionPath, "verdict.md"), "utf-8"));
111558
112336
  break;
111559
112337
  }
111560
112338
  case "status": {
@@ -113776,8 +114554,8 @@ var init_account_command = __esm(() => {
113776
114554
  // src/auth/antigravity-oauth.ts
113777
114555
  import { spawnSync as spawnSync3 } from "child_process";
113778
114556
  import { existsSync as existsSync47, unlinkSync as unlinkSync13 } from "fs";
113779
- import { homedir as homedir43 } from "os";
113780
- import { join as join67 } from "path";
114557
+ import { homedir as homedir44 } from "os";
114558
+ import { join as join68 } from "path";
113781
114559
  async function defaultSuggestModel() {
113782
114560
  try {
113783
114561
  const token = await getValidAntigravityAccessToken();
@@ -113896,7 +114674,7 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
113896
114674
  async logout(deps) {
113897
114675
  deleteSharedAntigravityToken(deps);
113898
114676
  try {
113899
- const tokenFile = join67(homedir43(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
114677
+ const tokenFile = join68(homedir44(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
113900
114678
  if (existsSync47(tokenFile))
113901
114679
  unlinkSync13(tokenFile);
113902
114680
  } catch {}
@@ -113929,13 +114707,13 @@ var init_antigravity_oauth = __esm(() => {
113929
114707
  });
113930
114708
 
113931
114709
  // src/auth/meta-muse-oauth.ts
113932
- import { execFile as execFile6 } from "child_process";
114710
+ import { execFile as execFile7 } from "child_process";
113933
114711
  function openInBrowser(url) {
113934
114712
  if (!/^https:\/\//i.test(url))
113935
114713
  return Promise.resolve();
113936
114714
  const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "explorer" : "xdg-open";
113937
114715
  return new Promise((resolve) => {
113938
- execFile6(command, [url], () => resolve());
114716
+ execFile7(command, [url], () => resolve());
113939
114717
  });
113940
114718
  }
113941
114719
  function describe2(answer, status) {
@@ -122095,18 +122873,18 @@ var init_tui = __esm(() => {
122095
122873
  });
122096
122874
 
122097
122875
  // src/diag-output.ts
122098
- import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync30, unlinkSync as unlinkSync14, writeFileSync as writeFileSync29 } from "fs";
122099
- import { homedir as homedir44 } from "os";
122100
- import { join as join68 } from "path";
122876
+ import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync31, unlinkSync as unlinkSync14, writeFileSync as writeFileSync30 } from "fs";
122877
+ import { homedir as homedir45 } from "os";
122878
+ import { join as join69 } from "path";
122101
122879
  function getClaudishDir() {
122102
- const dir = join68(homedir44(), ".claudish");
122880
+ const dir = join69(homedir45(), ".claudish");
122103
122881
  try {
122104
- mkdirSync30(dir, { recursive: true });
122882
+ mkdirSync31(dir, { recursive: true });
122105
122883
  } catch {}
122106
122884
  return dir;
122107
122885
  }
122108
122886
  function getDiagLogPath() {
122109
- return join68(getClaudishDir(), `diag-${process.pid}.log`);
122887
+ return join69(getClaudishDir(), `diag-${process.pid}.log`);
122110
122888
  }
122111
122889
 
122112
122890
  class LogFileDiagOutput {
@@ -122115,7 +122893,7 @@ class LogFileDiagOutput {
122115
122893
  constructor() {
122116
122894
  this.logPath = getDiagLogPath();
122117
122895
  try {
122118
- writeFileSync29(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
122896
+ writeFileSync30(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
122119
122897
  `);
122120
122898
  } catch {}
122121
122899
  this.stream = createWriteStream2(this.logPath, { flags: "a" });
@@ -122628,7 +123406,7 @@ var init_advisor_startup = __esm(() => {
122628
123406
  });
122629
123407
 
122630
123408
  // src/session/conversation.ts
122631
- import { closeSync as closeSync18, openSync as openSync17, readSync as readSync8, statSync as statSync26 } from "fs";
123409
+ import { closeSync as closeSync18, openSync as openSync17, readSync as readSync8, statSync as statSync27 } from "fs";
122632
123410
  import { StringDecoder } from "string_decoder";
122633
123411
  function looksLikeTurn(line) {
122634
123412
  const assistant = line.includes('"type":"assistant"');
@@ -122683,7 +123461,7 @@ function readConversation(file, opts = {}) {
122683
123461
  };
122684
123462
  let fd = null;
122685
123463
  try {
122686
- const size = statSync26(file).size;
123464
+ const size = statSync27(file).size;
122687
123465
  fd = openSync17(file, "r");
122688
123466
  const buf = Buffer.allocUnsafe(chunkBytes);
122689
123467
  const decoder = new StringDecoder("utf-8");
@@ -124342,11 +125120,11 @@ var exports_session_stats = {};
124342
125120
  __export(exports_session_stats, {
124343
125121
  readSessionStats: () => readSessionStats
124344
125122
  });
124345
- import { readFileSync as readFileSync54 } from "fs";
125123
+ import { readFileSync as readFileSync55 } from "fs";
124346
125124
  function readSessionStats(port, opts) {
124347
125125
  let raw;
124348
125126
  try {
124349
- raw = JSON.parse(readFileSync54(resolveTokenFilePath(port), "utf-8"));
125127
+ raw = JSON.parse(readFileSync55(resolveTokenFilePath(port), "utf-8"));
124350
125128
  } catch {
124351
125129
  return null;
124352
125130
  }
@@ -124724,8 +125502,8 @@ init_launch_env();
124724
125502
  init_op_source();
124725
125503
  init_startup_trace();
124726
125504
  init_picker_cancelled();
124727
- import { existsSync as existsSync48, readFileSync as readFileSync55 } from "fs";
124728
- import { join as join69, resolve as resolve13 } from "path";
125505
+ import { existsSync as existsSync48, readFileSync as readFileSync56 } from "fs";
125506
+ import { join as join70, resolve as resolve13 } from "path";
124729
125507
 
124730
125508
  // src/tui/runtime/should-open-picker.ts
124731
125509
  function noModelConfigured(gate) {
@@ -124742,7 +125520,7 @@ function requiresExplicitModel(gate, tty) {
124742
125520
  var autoloadDropped = [...droppedAtLaunch, ...takeLauncherDropped(process.env)];
124743
125521
  var dotenvText;
124744
125522
  try {
124745
- dotenvText = readFileSync55(join69(process.cwd(), ".env"));
125523
+ dotenvText = readFileSync56(join70(process.cwd(), ".env"));
124746
125524
  } catch {}
124747
125525
  if (dotenvText !== undefined) {
124748
125526
  await Promise.resolve().then(() => init_dotenv_allowlist());
@@ -125083,14 +125861,14 @@ async function runCli() {
125083
125861
  if (cliConfig.team && cliConfig.team.length > 0) {
125084
125862
  let prompt = cliConfig.claudeArgs.join(" ");
125085
125863
  if (cliConfig.inputFile) {
125086
- prompt = readFileSync55(cliConfig.inputFile, "utf-8");
125864
+ prompt = readFileSync56(cliConfig.inputFile, "utf-8");
125087
125865
  }
125088
125866
  if (!prompt.trim()) {
125089
125867
  console.error("Error: --team requires a prompt (positional args or -f <file>)");
125090
125868
  process.exit(1);
125091
125869
  }
125092
125870
  const mode = cliConfig.teamMode ?? "default";
125093
- const sessionPath = join69(process.cwd(), `.claudish-team-${Date.now()}`);
125871
+ const sessionPath = join70(process.cwd(), `.claudish-team-${Date.now()}`);
125094
125872
  if (mode === "json") {
125095
125873
  await Promise.resolve().then(() => init_pane());
125096
125874
  await Promise.resolve().then(() => init_team_orchestrator());
@@ -125110,9 +125888,9 @@ async function runCli() {
125110
125888
  const status = await runModels(sessionPath);
125111
125889
  const result = { ...status, responses: {} };
125112
125890
  for (const anonId of Object.keys(status.models)) {
125113
- const responsePath = join69(sessionPath, `response-${anonId}.md`);
125891
+ const responsePath = join70(sessionPath, `response-${anonId}.md`);
125114
125892
  try {
125115
- const raw = readFileSync55(responsePath, "utf-8").trim();
125893
+ const raw = readFileSync56(responsePath, "utf-8").trim();
125116
125894
  try {
125117
125895
  result.responses[anonId] = JSON.parse(raw);
125118
125896
  } catch {
@@ -125229,7 +126007,11 @@ Team Status`);
125229
126007
  hasProfileTiers
125230
126008
  });
125231
126009
  if (shouldOpenPicker(pickerGate(), pickerCanDraw)) {
125232
- cliConfig.model = await traceSpan("startup:model-select", () => selectModel({ freeOnly: cliConfig.freeOnly }).catch(handlePromptExit), { mayIncludeUserPrompt: true });
126010
+ const sizeIsGiven = cliConfig.contextWindow !== undefined || process.env.CLAUDISH_CONTEXT_WINDOW !== undefined;
126011
+ const onContextWindow = sizeIsGiven ? undefined : (size) => {
126012
+ cliConfig.contextWindow = size;
126013
+ };
126014
+ cliConfig.model = await traceSpan("startup:model-select", () => selectModel({ freeOnly: cliConfig.freeOnly, onContextWindow }).catch(handlePromptExit), { mayIncludeUserPrompt: true });
125233
126015
  console.log("");
125234
126016
  }
125235
126017
  if (requiresExplicitModel(pickerGate(), pickerCanDraw)) {
@@ -125374,6 +126156,9 @@ Team Status`);
125374
126156
  }
125375
126157
  }
125376
126158
  }
126159
+ if (cliConfig.contextWindow !== undefined) {
126160
+ process.env.CLAUDISH_CONTEXT_WINDOW = String(cliConfig.contextWindow);
126161
+ }
125377
126162
  const proxy = await traceSpan("startup:proxy-start", () => createProxyServer(port, cliConfig.monitor ? undefined : cliConfig.openrouterApiKey, cliConfig.monitor ? undefined : explicitModel, cliConfig.monitor, cliConfig.anthropicApiKey, modelMap, {
125378
126163
  summarizeTools: cliConfig.summarizeTools,
125379
126164
  quiet: cliConfig.quiet,