claudish 14.18.6 → 14.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1350 -558
  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.6";
5497
+ var VERSION = "14.19.1";
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
@@ -41763,7 +41783,7 @@ function resolveAntigravityModelId(requested, servedIds, defaultId, catalogDefau
41763
41783
  if (catalogDefault && servedIds.includes(catalogDefault))
41764
41784
  return catalogDefault;
41765
41785
  const familyPrefix = `${req}-`;
41766
- const variants = servedIds.filter((id) => id.startsWith(familyPrefix));
41786
+ const variants = servedIds.filter((id) => id.startsWith(familyPrefix) && Object.hasOwn(REASONING_TIER_RANK, id.slice(familyPrefix.length)));
41767
41787
  if (variants.length > 0) {
41768
41788
  if (defaultId && variants.includes(defaultId))
41769
41789
  return defaultId;
@@ -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;
@@ -50610,7 +51064,7 @@ function byCost(a, b) {
50610
51064
  return length !== 0 ? length : a.wireId.localeCompare(b.wireId);
50611
51065
  }
50612
51066
  function defaultOf(group) {
50613
- const declared = group.find((entry) => entry.isFamilyDefault);
51067
+ const declared = group.filter((entry) => entry.isFamilyDefault).sort(byCost)[0];
50614
51068
  if (declared)
50615
51069
  return declared;
50616
51070
  const plain = group.filter((entry) => !devinHasSpeedPremium(asConfig(entry)));
@@ -50701,15 +51155,22 @@ class DevinModelResolver {
50701
51155
  const family = nonEmpty(entry.family)?.toLowerCase();
50702
51156
  return label === lower || family === lower;
50703
51157
  });
50704
- const pool = named.length > 0 ? named : modelsCatalog.filter((entry) => entry.wireId.toLowerCase().startsWith(`${lower}-`));
51158
+ const pool = named.length > 0 ? named : effortSiblings(lower, modelsCatalog);
50705
51159
  if (pool.length === 0)
50706
51160
  return requested;
50707
- if (named.length === 0 && new Set(pool.map(keyOf)).size > 1)
50708
- return requested;
51161
+ if (named.length === 0)
51162
+ return pickForEffort(pool, ctx.effort).wireId;
50709
51163
  const chosen = pool.filter((entry) => entry.isFamilyDefault).sort(byCost)[0] ?? pool.slice().sort(byCost)[0];
50710
51164
  return pickForEffort(groups.get(keyOf(chosen)), ctx.effort).wireId;
50711
51165
  }
50712
51166
  }
51167
+ function effortSiblings(base, modelsCatalog) {
51168
+ const prefix = `${base}-`;
51169
+ return modelsCatalog.filter((entry) => {
51170
+ const wireId = entry.wireId.toLowerCase();
51171
+ return wireId.startsWith(prefix) && isEffortLevel(wireId.slice(prefix.length));
51172
+ });
51173
+ }
50713
51174
  function pickForEffort(group, effort) {
50714
51175
  if (!effort)
50715
51176
  return defaultOf(group);
@@ -51076,7 +51537,31 @@ function readCreatedDate(row) {
51076
51537
  const iso = new Date(seconds * 1000).toISOString();
51077
51538
  return iso.slice(0, 10);
51078
51539
  }
51079
- function parseOpenAIModelsList(body) {
51540
+ function readLMStudioContextWindow(row) {
51541
+ const loaded = positive(row.loaded_context_length);
51542
+ if (loaded !== undefined)
51543
+ return loaded;
51544
+ const max = positive(row.max_context_length);
51545
+ const wanted = getProviderByName("lmstudio")?.unknownContextWindow;
51546
+ return max !== undefined && wanted !== undefined && max < wanted ? max : undefined;
51547
+ }
51548
+ function ceilingOf(row) {
51549
+ const ceiling = positive(row.max_context_length);
51550
+ return ceiling === undefined ? {} : { contextCeiling: ceiling };
51551
+ }
51552
+ function positive(value) {
51553
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
51554
+ }
51555
+ async function withLMStudioMachines(models, baseUrl) {
51556
+ if (!isLoopbackUrl(baseUrl))
51557
+ return models;
51558
+ const machines = await readLMStudioMachines();
51559
+ if (!machines)
51560
+ return models;
51561
+ return expandModelsToMachines(models, machines, getProviderByName("lmstudio")?.unknownContextWindow);
51562
+ }
51563
+ function parseOpenAIModelsList(body, format) {
51564
+ const isLMStudio = format === "lmstudio-models";
51080
51565
  const data = body?.data;
51081
51566
  if (!Array.isArray(data))
51082
51567
  return { models: [], dropped: 0, total: null };
@@ -51097,8 +51582,10 @@ function parseOpenAIModelsList(body) {
51097
51582
  models.push({
51098
51583
  id,
51099
51584
  displayName,
51100
- contextWindow: readContextWindow(row),
51101
- releaseDate: readCreatedDate(row)
51585
+ contextWindow: isLMStudio ? readLMStudioContextWindow(row) : readContextWindow(row),
51586
+ releaseDate: readCreatedDate(row),
51587
+ ...isLMStudio ? { reported: lmStudioReported(row) } : {},
51588
+ ...isLMStudio ? ceilingOf(row) : {}
51102
51589
  });
51103
51590
  }
51104
51591
  return { models, dropped, total: data.length };
@@ -51223,9 +51710,10 @@ async function fetchServedModels(providerName) {
51223
51710
  const descriptor = def?.modelDiscovery;
51224
51711
  if (!def || !descriptor)
51225
51712
  return { kind: "unsupported", reason: "no-descriptor" };
51226
- if (descriptor.format !== "openai-models-list") {
51713
+ if (descriptor.format !== "openai-models-list" && descriptor.format !== "lmstudio-models") {
51227
51714
  return await discoverViaFetcher(providerName, descriptor.format);
51228
51715
  }
51716
+ const isLMStudio = descriptor.format === "lmstudio-models";
51229
51717
  const baseUrl = resolveBaseUrl(providerName);
51230
51718
  if (!baseUrl) {
51231
51719
  const overrides = (def.baseUrlEnvVars ?? []).join(", ");
@@ -51236,7 +51724,8 @@ async function fetchServedModels(providerName) {
51236
51724
  });
51237
51725
  }
51238
51726
  const definitionEndpoint = `${baseUrl}${descriptor.path}`;
51239
- let endpoint = registryModelsEndpoint(providerName, def) ?? definitionEndpoint;
51727
+ let endpoint = isLMStudio ? definitionEndpoint : registryModelsEndpoint(providerName, def) ?? definitionEndpoint;
51728
+ let bodyFormat = descriptor.format;
51240
51729
  let headers = {};
51241
51730
  if (def.isLocal) {
51242
51731
  const key = def.apiKeyEnvVar ? process.env[def.apiKeyEnvVar] : undefined;
@@ -51271,6 +51760,11 @@ async function fetchServedModels(providerName) {
51271
51760
  endpoint = definitionEndpoint;
51272
51761
  response = await fetchList(endpoint);
51273
51762
  }
51763
+ if (response.status === 404 && isLMStudio) {
51764
+ endpoint = `${baseUrl}/v1/models`;
51765
+ bodyFormat = "openai-models-list";
51766
+ response = await fetchList(endpoint);
51767
+ }
51274
51768
  } catch (e) {
51275
51769
  return recordFailure({
51276
51770
  kind: "unreachable",
@@ -51299,7 +51793,7 @@ async function fetchServedModels(providerName) {
51299
51793
  } catch {
51300
51794
  return recordFailure({ kind: "malformed", provider: providerName, endpoint });
51301
51795
  }
51302
- const parsed = parseOpenAIModelsList(body);
51796
+ const parsed = parseOpenAIModelsList(body, bodyFormat);
51303
51797
  const incomplete = describeIncompleteness(body, parsed);
51304
51798
  if (incomplete) {
51305
51799
  return recordFailure({
@@ -51309,7 +51803,7 @@ async function fetchServedModels(providerName) {
51309
51803
  detail: incomplete
51310
51804
  });
51311
51805
  }
51312
- const models = parsed.models;
51806
+ const models = isLMStudio ? await withLMStudioMachines(parsed.models, baseUrl) : parsed.models;
51313
51807
  _failures.delete(providerName);
51314
51808
  log(`[model-discovery:${providerName}] discovered ${models.length} models from ${endpoint}: ` + models.map((m) => `${m.id}(${m.contextWindow ?? "?"})`).join(", "));
51315
51809
  return { kind: "served", models };
@@ -51318,16 +51812,27 @@ async function discoverProviderModels(providerName) {
51318
51812
  const outcome = await discoverProviderModelsCatalog(providerName);
51319
51813
  return outcome.kind === "served" ? outcome.models : [];
51320
51814
  }
51321
- function windowOf(models, modelId) {
51815
+ function windowOf(models, modelId, upTo) {
51322
51816
  const needle = modelId.toLowerCase();
51323
- return models.find((m) => m.id.toLowerCase() === needle)?.contextWindow;
51817
+ const exact = models.find((m) => m.id.toLowerCase() === needle);
51818
+ if (exact)
51819
+ return rowWindow(exact, upTo);
51820
+ const windows = models.filter((m) => m.machine?.modelId.toLowerCase() === needle).map((m) => rowWindow(m, upTo)).filter((w) => w !== undefined);
51821
+ return windows.length > 0 ? Math.min(...windows) : undefined;
51822
+ }
51823
+ function rowWindow(model, upTo) {
51824
+ if (model.contextWindow !== undefined)
51825
+ return model.contextWindow;
51826
+ const ceiling = model.contextCeiling;
51827
+ return upTo !== undefined && ceiling !== undefined && ceiling < upTo ? ceiling : undefined;
51324
51828
  }
51325
51829
  async function discoverContextWindow(providerName, modelId, opts = {}) {
51830
+ const { upTo } = opts;
51326
51831
  if (opts.network === "cached-first") {
51327
51832
  await Promise.resolve().then(() => init_dynamic_models_catalog());
51328
51833
  const stored = await readAccountModelsList(providerName);
51329
51834
  if (stored)
51330
- return windowOf(stored.models, modelId);
51835
+ return windowOf(stored.models, modelId, upTo);
51331
51836
  coldRefresh(providerName);
51332
51837
  return;
51333
51838
  }
@@ -51337,13 +51842,13 @@ async function discoverContextWindow(providerName, modelId, opts = {}) {
51337
51842
  timer = setTimeout(() => resolve([]), LIVE_DISCOVERY_BOUND_MS);
51338
51843
  });
51339
51844
  try {
51340
- return windowOf(await Promise.race([coldRefresh(providerName), bound]), modelId);
51845
+ return windowOf(await Promise.race([coldRefresh(providerName), bound]), modelId, upTo);
51341
51846
  } finally {
51342
51847
  clearTimeout(timer);
51343
51848
  }
51344
51849
  }
51345
51850
  const { served, optIn } = await discoverProviderServedIds(providerName);
51346
- return windowOf([...served, ...optIn], modelId);
51851
+ return windowOf([...served, ...optIn], modelId, upTo);
51347
51852
  }
51348
51853
  function coldRefresh(providerName) {
51349
51854
  const running = coldRefreshes.get(providerName);
@@ -51379,7 +51884,9 @@ var init_model_discovery = __esm(() => {
51379
51884
  init_authority();
51380
51885
  init_logger();
51381
51886
  init_connection_resolver();
51887
+ init_lmstudio_devices();
51382
51888
  init_provider_definitions();
51889
+ init_probe_discovery();
51383
51890
  _fetchers = new Map;
51384
51891
  CACHE_TTL_MS2 = 5 * 60 * 1000;
51385
51892
  _cache2 = new Map;
@@ -51941,7 +52448,7 @@ var init_wire_markers = __esm(() => {
51941
52448
  });
51942
52449
 
51943
52450
  // src/providers/catalog-query.ts
51944
- import { statSync as statSync9 } from "fs";
52451
+ import { statSync as statSync10 } from "fs";
51945
52452
  function project(entry) {
51946
52453
  return {
51947
52454
  modelId: entry.modelId,
@@ -51955,7 +52462,7 @@ function project(entry) {
51955
52462
  function getCachedEntries() {
51956
52463
  let mtimeMs;
51957
52464
  try {
51958
- mtimeMs = statSync9(ALL_MODELS_CACHE_PATH).mtimeMs;
52465
+ mtimeMs = statSync10(ALL_MODELS_CACHE_PATH).mtimeMs;
51959
52466
  } catch {
51960
52467
  return null;
51961
52468
  }
@@ -52128,17 +52635,17 @@ var init_vision_proxy = __esm(() => {
52128
52635
  });
52129
52636
 
52130
52637
  // 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) {
52638
+ import { homedir as homedir29 } from "os";
52639
+ import { join as join30 } from "path";
52640
+ function userHomeFrom(env, homedirFn = homedir29) {
52134
52641
  const home = env.HOME;
52135
52642
  return home && home.length > 0 ? home : homedirFn();
52136
52643
  }
52137
- function sessionsDirFrom(env, homedirFn = homedir28) {
52644
+ function sessionsDirFrom(env, homedirFn = homedir29) {
52138
52645
  const explicit = env.CLAUDISH_SESSIONS_DIR;
52139
52646
  if (explicit && explicit.length > 0)
52140
52647
  return explicit;
52141
- return join29(userHomeFrom(env, homedirFn), ".claudish", "sessions");
52648
+ return join30(userHomeFrom(env, homedirFn), ".claudish", "sessions");
52142
52649
  }
52143
52650
  function claudeCodeStringHash(s) {
52144
52651
  let h = 0;
@@ -52229,7 +52736,7 @@ function reduceEvent(state, event) {
52229
52736
  }
52230
52737
 
52231
52738
  // src/session-events/transcript-tailer.ts
52232
- import { closeSync as closeSync9, openSync as openSync9, readSync as readSync2, statSync as statSync10 } from "fs";
52739
+ import { closeSync as closeSync9, openSync as openSync9, readSync as readSync2, statSync as statSync11 } from "fs";
52233
52740
 
52234
52741
  class TranscriptTailer {
52235
52742
  filePath;
@@ -52274,7 +52781,7 @@ class TranscriptTailer {
52274
52781
  if (this.disposed)
52275
52782
  return;
52276
52783
  try {
52277
- const size = statSync10(this.filePath).size;
52784
+ const size = statSync11(this.filePath).size;
52278
52785
  if (size < this.offset) {
52279
52786
  this.offset = 0;
52280
52787
  this.buffer = "";
@@ -52311,9 +52818,9 @@ var DEFAULT_POLL_INTERVAL_MS = 250;
52311
52818
  var init_transcript_tailer = () => {};
52312
52819
 
52313
52820
  // 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";
52821
+ import { existsSync as existsSync22, readFileSync as readFileSync30, readdirSync as readdirSync5 } from "fs";
52822
+ import { homedir as homedir30 } from "os";
52823
+ import { join as join31 } from "path";
52317
52824
  function extractSessionId2(metadata) {
52318
52825
  const userId = metadata?.user_id;
52319
52826
  if (typeof userId !== "string")
@@ -52338,7 +52845,7 @@ class SessionEventRegistry {
52338
52845
  claudeHome;
52339
52846
  pollIntervalMs;
52340
52847
  constructor(opts = {}) {
52341
- this.claudeHome = opts.claudeHome ?? join30(homedir29(), ".claude");
52848
+ this.claudeHome = opts.claudeHome ?? join31(homedir30(), ".claude");
52342
52849
  this.pollIntervalMs = opts.pollIntervalMs;
52343
52850
  }
52344
52851
  ensureSession(sessionId) {
@@ -52424,13 +52931,13 @@ class SessionEventRegistry {
52424
52931
  }
52425
52932
  }
52426
52933
  locateTranscript(sessionId) {
52427
- const projectsDir = join30(this.claudeHome, "projects");
52428
- const primary = join30(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
52934
+ const projectsDir = join31(this.claudeHome, "projects");
52935
+ const primary = join31(projectsDir, slugFromCwd(process.cwd()), `${sessionId}.jsonl`);
52429
52936
  if (existsSync22(primary))
52430
52937
  return primary;
52431
52938
  try {
52432
- for (const dir of readdirSync4(projectsDir)) {
52433
- const candidate = join30(projectsDir, dir, `${sessionId}.jsonl`);
52939
+ for (const dir of readdirSync5(projectsDir)) {
52940
+ const candidate = join31(projectsDir, dir, `${sessionId}.jsonl`);
52434
52941
  if (existsSync22(candidate))
52435
52942
  return candidate;
52436
52943
  }
@@ -52439,7 +52946,7 @@ class SessionEventRegistry {
52439
52946
  }
52440
52947
  readSettingsEffortLevel() {
52441
52948
  try {
52442
- const settings = JSON.parse(readFileSync29(join30(this.claudeHome, "settings.json"), "utf-8"));
52949
+ const settings = JSON.parse(readFileSync30(join31(this.claudeHome, "settings.json"), "utf-8"));
52443
52950
  return typeof settings.effortLevel === "string" ? settings.effortLevel : undefined;
52444
52951
  } catch {
52445
52952
  return;
@@ -52543,24 +53050,24 @@ var claimed = false;
52543
53050
  // src/stats-buffer.ts
52544
53051
  import {
52545
53052
  existsSync as existsSync23,
52546
- mkdirSync as mkdirSync16,
52547
- readFileSync as readFileSync30,
52548
- renameSync as renameSync8,
53053
+ mkdirSync as mkdirSync17,
53054
+ readFileSync as readFileSync31,
53055
+ renameSync as renameSync9,
52549
53056
  unlinkSync as unlinkSync8,
52550
- writeFileSync as writeFileSync11
53057
+ writeFileSync as writeFileSync12
52551
53058
  } from "fs";
52552
- import { homedir as homedir30 } from "os";
52553
- import { join as join31 } from "path";
53059
+ import { homedir as homedir31 } from "os";
53060
+ import { join as join32 } from "path";
52554
53061
  function ensureDir() {
52555
53062
  if (!existsSync23(CLAUDISH_DIR)) {
52556
- mkdirSync16(CLAUDISH_DIR, { recursive: true });
53063
+ mkdirSync17(CLAUDISH_DIR, { recursive: true });
52557
53064
  }
52558
53065
  }
52559
53066
  function readFromDisk() {
52560
53067
  try {
52561
53068
  if (!existsSync23(BUFFER_FILE))
52562
53069
  return [];
52563
- const raw = readFileSync30(BUFFER_FILE, "utf-8");
53070
+ const raw = readFileSync31(BUFFER_FILE, "utf-8");
52564
53071
  const parsed = JSON.parse(raw);
52565
53072
  if (!Array.isArray(parsed.events))
52566
53073
  return [];
@@ -52585,9 +53092,9 @@ function writeToDisk(events) {
52585
53092
  ensureDir();
52586
53093
  const trimmed = enforceSizeCap([...events]);
52587
53094
  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);
53095
+ const tmpFile = join32(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
53096
+ writeFileSync12(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
53097
+ renameSync9(tmpFile, BUFFER_FILE);
52591
53098
  memoryCache = trimmed;
52592
53099
  } catch {}
52593
53100
  }
@@ -52658,8 +53165,8 @@ function syncFlushOnExit() {
52658
53165
  var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false, SIGNAL_EXIT_CODE;
52659
53166
  var init_stats_buffer = __esm(() => {
52660
53167
  BUFFER_MAX_BYTES = 64 * 1024;
52661
- CLAUDISH_DIR = join31(homedir30(), ".claudish");
52662
- BUFFER_FILE = join31(CLAUDISH_DIR, "stats-buffer.json");
53168
+ CLAUDISH_DIR = join32(homedir31(), ".claudish");
53169
+ BUFFER_FILE = join32(CLAUDISH_DIR, "stats-buffer.json");
52663
53170
  process.on("exit", syncFlushOnExit);
52664
53171
  SIGNAL_EXIT_CODE = { SIGTERM: 143, SIGINT: 130 };
52665
53172
  for (const signal of ["SIGTERM", "SIGINT"]) {
@@ -56741,7 +57248,7 @@ var init_openai_responses_sse = __esm(() => {
56741
57248
  });
56742
57249
 
56743
57250
  // src/session/token-file.ts
56744
- import { join as join32 } from "path";
57251
+ import { join as join33 } from "path";
56745
57252
  function assignedTokenFile(env) {
56746
57253
  const f = env.CLAUDISH_TOKEN_FILE;
56747
57254
  if (!f || f === env.CLAUDISH_PUBLISHED_TOKEN_FILE)
@@ -56749,15 +57256,15 @@ function assignedTokenFile(env) {
56749
57256
  return f;
56750
57257
  }
56751
57258
  function resolveTokenFilePath(port, env = process.env) {
56752
- return assignedTokenFile(env) ?? join32(userHomeFrom(env), ".claudish", `tokens-${port}.json`);
57259
+ return assignedTokenFile(env) ?? join33(userHomeFrom(env), ".claudish", `tokens-${port}.json`);
56753
57260
  }
56754
57261
  var init_token_file = __esm(() => {
56755
57262
  init_home_dir();
56756
57263
  });
56757
57264
 
56758
57265
  // src/handlers/shared/token-tracker.ts
56759
- import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync12 } from "fs";
56760
- import { dirname as dirname14 } from "path";
57266
+ import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync13 } from "fs";
57267
+ import { dirname as dirname15 } from "path";
56761
57268
  function stripProviderPrefix(name) {
56762
57269
  if (!hasProviderPrefix(name))
56763
57270
  return name;
@@ -56998,8 +57505,8 @@ class TokenTracker {
56998
57505
  };
56999
57506
  }
57000
57507
  const outPath = resolveTokenFilePath(this.port);
57001
- mkdirSync17(dirname14(outPath), { recursive: true });
57002
- writeFileSync12(outPath, JSON.stringify(data), "utf-8");
57508
+ mkdirSync18(dirname15(outPath), { recursive: true });
57509
+ writeFileSync13(outPath, JSON.stringify(data), "utf-8");
57003
57510
  } catch (e) {
57004
57511
  log(`[TokenTracker] Error writing token file: ${e}`);
57005
57512
  }
@@ -59256,11 +59763,11 @@ var init_composed_handler = __esm(() => {
59256
59763
  });
59257
59764
 
59258
59765
  // 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";
59766
+ import { existsSync as existsSync24, readFileSync as readFileSync32 } from "fs";
59767
+ import { homedir as homedir32 } from "os";
59768
+ import { join as join34, resolve as resolve3 } from "path";
59262
59769
  function activeConfigPath() {
59263
- return activeGlobalConfigFile(join33(homedir31(), ".claudish", "config.json"));
59770
+ return activeGlobalConfigFile(join34(homedir32(), ".claudish", "config.json"));
59264
59771
  }
59265
59772
  function configLayerLabel() {
59266
59773
  return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
@@ -59387,7 +59894,7 @@ function readDotenvKey(envVars) {
59387
59894
  const dotenvPath = resolve3(".env");
59388
59895
  if (!existsSync24(dotenvPath))
59389
59896
  return null;
59390
- const parsed = readAllowedDotenv(readFileSync31(dotenvPath, "utf-8"));
59897
+ const parsed = readAllowedDotenv(readFileSync32(dotenvPath, "utf-8"));
59391
59898
  for (const v of envVars) {
59392
59899
  if (parsed[v])
59393
59900
  return parsed[v];
@@ -59402,7 +59909,7 @@ function readConfigKey(envVar) {
59402
59909
  const configPath = activeConfigPath();
59403
59910
  if (!existsSync24(configPath))
59404
59911
  return null;
59405
- const cfg = JSON.parse(readFileSync31(configPath, "utf-8"));
59912
+ const cfg = JSON.parse(readFileSync32(configPath, "utf-8"));
59406
59913
  return cfg.apiKeys?.[envVar] || null;
59407
59914
  } catch {
59408
59915
  return null;
@@ -61591,6 +62098,7 @@ var geminiHandler, antigravityHandler, devinHandler, grokSubscriptionHandler, mu
61591
62098
  var init_provider_definitions = __esm(() => {
61592
62099
  init_vertex_auth();
61593
62100
  init_profile_config();
62101
+ init_context_window_limit();
61594
62102
  init_runtime_providers();
61595
62103
  geminiHandler = lazyHandler((m) => m.geminiProfile);
61596
62104
  antigravityHandler = lazyHandler((m) => m.antigravityProfile);
@@ -62141,7 +62649,8 @@ var init_provider_definitions = __esm(() => {
62141
62649
  { prefix: "mlstudio:", stripPrefix: true }
62142
62650
  ],
62143
62651
  isLocal: true,
62144
- modelDiscovery: { path: "/v1/models", format: "openai-models-list" },
62652
+ modelDiscovery: { path: "/api/v0/models", format: "lmstudio-models" },
62653
+ unknownContextWindow: DEFAULT_LOCAL_CONTEXT_WINDOW,
62145
62654
  description: "Local LM Studio (lms@)"
62146
62655
  },
62147
62656
  {
@@ -73156,9 +73665,9 @@ function compareByConnectionPrice(a, b) {
73156
73665
  }
73157
73666
 
73158
73667
  // 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";
73668
+ import { existsSync as existsSync25, mkdirSync as mkdirSync19, readFileSync as readFileSync33, writeFileSync as writeFileSync14 } from "fs";
73669
+ import { homedir as homedir33 } from "os";
73670
+ import { dirname as dirname16, join as join35 } from "path";
73162
73671
  function describeProbeCatalogFailure(outcome) {
73163
73672
  switch (outcome.kind) {
73164
73673
  case "incompatible":
@@ -73178,15 +73687,15 @@ function readProbeModelsCache(path = PROBE_MODELS_CACHE_PATH) {
73178
73687
  return null;
73179
73688
  let raw;
73180
73689
  try {
73181
- raw = JSON.parse(readFileSync32(path, "utf-8"));
73690
+ raw = JSON.parse(readFileSync33(path, "utf-8"));
73182
73691
  } catch {
73183
73692
  return null;
73184
73693
  }
73185
73694
  return isValidResponse(raw) ? raw : null;
73186
73695
  }
73187
73696
  function writeProbeModelsCache(data, path = PROBE_MODELS_CACHE_PATH) {
73188
- mkdirSync18(dirname15(path), { recursive: true });
73189
- writeFileSync13(path, JSON.stringify(data), "utf-8");
73697
+ mkdirSync19(dirname16(path), { recursive: true });
73698
+ writeFileSync14(path, JSON.stringify(data), "utf-8");
73190
73699
  }
73191
73700
  function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
73192
73701
  if (!data)
@@ -73330,7 +73839,7 @@ var init_probe_catalog = __esm(() => {
73330
73839
  init_catalog_endpoints();
73331
73840
  init_catalog_route_bindings();
73332
73841
  CACHE_TTL_MS4 = 60 * 60 * 1000;
73333
- PROBE_MODELS_CACHE_PATH = join34(homedir32(), ".claudish", "probe-models.json");
73842
+ PROBE_MODELS_CACHE_PATH = join35(homedir33(), ".claudish", "probe-models.json");
73334
73843
  });
73335
73844
 
73336
73845
  // src/providers/route-candidates.ts
@@ -74812,10 +75321,10 @@ var init_prehydrate = __esm(() => {
74812
75321
 
74813
75322
  // src/auth/claude-code-facts.ts
74814
75323
  import { createHash as createHash17 } from "crypto";
74815
- import { homedir as homedir33 } from "os";
75324
+ import { homedir as homedir34 } from "os";
74816
75325
  import { isAbsolute as isAbsolute2, resolve as resolve4 } from "path";
74817
75326
  function defaultConfigDir(env) {
74818
- return resolve4(env.HOME || homedir33(), ".claude");
75327
+ return resolve4(env.HOME || homedir34(), ".claude");
74819
75328
  }
74820
75329
  function configDirHash(configDir) {
74821
75330
  return createHash17("sha256").update(configDir).digest("hex").slice(0, 8);
@@ -75683,7 +76192,7 @@ var init_magmux_client = __esm(() => {
75683
76192
  });
75684
76193
 
75685
76194
  // src/pane/own-pane.ts
75686
- import { execFile as execFile2 } from "child_process";
76195
+ import { execFile as execFile3 } from "child_process";
75687
76196
  import { promisify as promisify5 } from "util";
75688
76197
  async function ancestorPids(maxDepth = ANCESTRY_DEPTH) {
75689
76198
  const out = new Set([process.pid]);
@@ -75733,12 +76242,12 @@ async function findOwnPane(list, ancestors = () => ancestorPids()) {
75733
76242
  }
75734
76243
  var execFileAsync2, ANCESTRY_DEPTH = 6;
75735
76244
  var init_own_pane = __esm(() => {
75736
- execFileAsync2 = promisify5(execFile2);
76245
+ execFileAsync2 = promisify5(execFile3);
75737
76246
  });
75738
76247
 
75739
76248
  // src/pane/prompt-delivery.ts
75740
- import { writeFileSync as writeFileSync14 } from "fs";
75741
- import { join as join35 } from "path";
76249
+ import { writeFileSync as writeFileSync15 } from "fs";
76250
+ import { join as join36 } from "path";
75742
76251
  function stripControl(s) {
75743
76252
  let out = "";
75744
76253
  for (const ch of s) {
@@ -75805,7 +76314,7 @@ function renderTurnFile(text, limit = READ_LINE_LIMIT) {
75805
76314
  `), lines: out.length, marker };
75806
76315
  }
75807
76316
  function turnFilePath(turnDir, turnIndex) {
75808
- return join35(turnDir, `turn-${turnIndex}.md`);
76317
+ return join36(turnDir, `turn-${turnIndex}.md`);
75809
76318
  }
75810
76319
  function fileTemplate(file, marker) {
75811
76320
  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 +76385,7 @@ function deliveryRefusal(text, readAvailable) {
75876
76385
  }
75877
76386
  function writeTurnFile(d) {
75878
76387
  if ((d.mode === "file" || d.mode === "command") && d.file && d.fileContent !== undefined) {
75879
- writeFileSync14(d.file, d.fileContent, { mode: 384, flag: "wx" });
76388
+ writeFileSync15(d.file, d.fileContent, { mode: 384, flag: "wx" });
75880
76389
  }
75881
76390
  }
75882
76391
  var READ_LINE_LIMIT = 20000, MAX_TYPED_LINE = 512, SPLIT_MARKER = "\u21A9", ALT_SPLIT_MARKER = "\u2936", SLASH;
@@ -76485,11 +76994,11 @@ import {
76485
76994
  fstatSync as fstatSync3,
76486
76995
  openSync as openSync10,
76487
76996
  readSync as readSync3,
76488
- readdirSync as readdirSync5,
76997
+ readdirSync as readdirSync6,
76489
76998
  realpathSync as realpathSync4,
76490
- statSync as statSync11
76999
+ statSync as statSync12
76491
77000
  } from "fs";
76492
- import { join as join36 } from "path";
77001
+ import { join as join37 } from "path";
76493
77002
  function initialFollowerState(resolvePath = safeRealpath) {
76494
77003
  return {
76495
77004
  turns: [],
@@ -77053,7 +77562,7 @@ class TranscriptFollower {
77053
77562
  if (!existsSync26(this.subagentsDir))
77054
77563
  return [];
77055
77564
  try {
77056
- return readdirSync5(this.subagentsDir).filter((f) => f.endsWith(".jsonl"));
77565
+ return readdirSync6(this.subagentsDir).filter((f) => f.endsWith(".jsonl"));
77057
77566
  } catch {
77058
77567
  return [];
77059
77568
  }
@@ -77063,7 +77572,7 @@ class TranscriptFollower {
77063
77572
  for (const f of this.subagentFiles()) {
77064
77573
  let tail = this.subs.get(f);
77065
77574
  if (!tail) {
77066
- tail = new Tail(join36(this.subagentsDir, f));
77575
+ tail = new Tail(join37(this.subagentsDir, f));
77067
77576
  this.subs.set(f, tail);
77068
77577
  }
77069
77578
  for (const { line } of tail.read()) {
@@ -77138,7 +77647,7 @@ function lastHumanPromptOffset(path) {
77138
77647
  }
77139
77648
  function fileSize(p) {
77140
77649
  try {
77141
- return statSync11(p).size;
77650
+ return statSync12(p).size;
77142
77651
  } catch {
77143
77652
  return 0;
77144
77653
  }
@@ -77163,7 +77672,7 @@ var init_transcript_follower = __esm(() => {
77163
77672
 
77164
77673
  // src/mcp-session/parent-session.ts
77165
77674
  import { readFile as readFile7 } from "fs/promises";
77166
- import { join as join37 } from "path";
77675
+ import { join as join38 } from "path";
77167
77676
  function positiveInt(value) {
77168
77677
  if (value === undefined || !/^[1-9][0-9]*$/.test(value))
77169
77678
  return;
@@ -77187,11 +77696,11 @@ function parentSessionIdFrom(env) {
77187
77696
  }
77188
77697
  function claudeConfigDir(env) {
77189
77698
  const fromEnv = env.CLAUDE_CONFIG_DIR;
77190
- return fromEnv && fromEnv.length > 0 ? fromEnv : join37(userHomeFrom(env), ".claude");
77699
+ return fromEnv && fromEnv.length > 0 ? fromEnv : join38(userHomeFrom(env), ".claude");
77191
77700
  }
77192
77701
  async function readHostSessionRecord(opts) {
77193
77702
  try {
77194
- const raw = await readFile7(join37(opts.configDir, "sessions", `${opts.hostPid}.json`), "utf-8");
77703
+ const raw = await readFile7(join38(opts.configDir, "sessions", `${opts.hostPid}.json`), "utf-8");
77195
77704
  const parsed = JSON.parse(raw);
77196
77705
  if (!parsed || typeof parsed !== "object")
77197
77706
  return;
@@ -77235,11 +77744,11 @@ __export(exports_session_discovery, {
77235
77744
  sessionLabel: () => sessionLabel,
77236
77745
  transcriptPathFor: () => transcriptPathFor
77237
77746
  });
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";
77747
+ import { execFile as execFile4, execFileSync as execFileSync2 } from "child_process";
77748
+ import { closeSync as closeSync11, openSync as openSync11, readSync as readSync4, readdirSync as readdirSync7, realpathSync as realpathSync5, statSync as statSync13 } from "fs";
77749
+ import { basename as basename3, join as join39 } from "path";
77241
77750
  function projectsDir(env = process.env) {
77242
- return join38(claudeConfigDir(env), "projects");
77751
+ return join39(claudeConfigDir(env), "projects");
77243
77752
  }
77244
77753
  function slugForPath(absPath) {
77245
77754
  return projectDirNameFor(absPath);
@@ -77249,7 +77758,7 @@ function transcriptPathFor(cwd, sessionUuid, projectsRoot = projectsDir()) {
77249
77758
  try {
77250
77759
  real = realpathSync5(cwd);
77251
77760
  } catch {}
77252
- return join38(projectsRoot, slugForPath(real), `${sessionUuid}.jsonl`);
77761
+ return join39(projectsRoot, slugForPath(real), `${sessionUuid}.jsonl`);
77253
77762
  }
77254
77763
  function isAgentSession(row) {
77255
77764
  return row.entrypoint !== undefined && row.entrypoint !== "cli";
@@ -77290,28 +77799,28 @@ function getRepoContext(cwd = process.cwd()) {
77290
77799
  }
77291
77800
  function projectDirs() {
77292
77801
  try {
77293
- return readdirSync6(projectsDir(), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
77802
+ return readdirSync7(projectsDir(), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
77294
77803
  } catch {
77295
77804
  return [];
77296
77805
  }
77297
77806
  }
77298
77807
  function sessionsIn2(dirName) {
77299
- const dir = join38(projectsDir(), dirName);
77808
+ const dir = join39(projectsDir(), dirName);
77300
77809
  let names;
77301
77810
  try {
77302
- names = readdirSync6(dir).filter((n) => n.endsWith(".jsonl"));
77811
+ names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
77303
77812
  } catch {
77304
77813
  return [];
77305
77814
  }
77306
77815
  const rows = [];
77307
77816
  for (const n of names) {
77308
- const file = join38(dir, n);
77817
+ const file = join39(dir, n);
77309
77818
  try {
77310
- const st = statSync12(file);
77819
+ const st = statSync13(file);
77311
77820
  if (st.size === 0)
77312
77821
  continue;
77313
77822
  const row = {
77314
- id: basename2(n, ".jsonl"),
77823
+ id: basename3(n, ".jsonl"),
77315
77824
  file,
77316
77825
  mtimeMs: st.mtimeMs,
77317
77826
  birthtimeMs: st.birthtimeMs,
@@ -77328,7 +77837,7 @@ function sessionsIn2(dirName) {
77328
77837
  }
77329
77838
  async function enrichWorktreeGit(groups, repoRoot) {
77330
77839
  const run = (cwd, args) => new Promise((resolve) => {
77331
- execFile3("git", args, { cwd, encoding: "utf-8" }, (err, stdout) => resolve(err ? "" : stdout));
77840
+ execFile4("git", args, { cwd, encoding: "utf-8" }, (err, stdout) => resolve(err ? "" : stdout));
77332
77841
  });
77333
77842
  const trackByBranch = new Map;
77334
77843
  const refs = await run(repoRoot, [
@@ -77413,7 +77922,7 @@ function discoverWorktreeGroups(repo) {
77413
77922
  if (hit) {
77414
77923
  path = hit.path;
77415
77924
  live = true;
77416
- name = hit.path === repo.root ? "(root)" : basename2(hit.path);
77925
+ name = hit.path === repo.root ? "(root)" : basename3(hit.path);
77417
77926
  } else if (at !== -1 && dir.startsWith(rootSlug)) {
77418
77927
  path = null;
77419
77928
  live = false;
@@ -77468,7 +77977,7 @@ function discoverWorktreeGroups(repo) {
77468
77977
  g.activeNow = g.sessions.some((s) => isActive(s));
77469
77978
  if (g.path) {
77470
77979
  try {
77471
- g.createdMs = statSync12(g.path).birthtimeMs;
77980
+ g.createdMs = statSync13(g.path).birthtimeMs;
77472
77981
  } catch {}
77473
77982
  }
77474
77983
  if (!g.createdMs && g.sessions.length > 0) {
@@ -77556,7 +78065,7 @@ function hydrateSession(row) {
77556
78065
  row.hydrated = true;
77557
78066
  if (isActive(row)) {
77558
78067
  try {
77559
- row.sizeBytes = statSync12(row.file).size;
78068
+ row.sizeBytes = statSync13(row.file).size;
77560
78069
  } catch {}
77561
78070
  }
77562
78071
  const head = parseRecords(readChunk(row.file, 0, Math.min(HEAD_BYTES, row.sizeBytes)), false);
@@ -77771,8 +78280,8 @@ var init_queue = __esm(() => {
77771
78280
  });
77772
78281
 
77773
78282
  // src/hooks/session/interactive-driver.ts
77774
- import { existsSync as existsSync27, statSync as statSync13 } from "fs";
77775
- import { join as join39 } from "path";
78283
+ import { existsSync as existsSync27, statSync as statSync14 } from "fs";
78284
+ import { join as join40 } from "path";
77776
78285
  function nextDriverPhase(phase, ev) {
77777
78286
  const row = EDGES[phase];
77778
78287
  return row[ev] ?? null;
@@ -77990,7 +78499,7 @@ class InteractiveDriver {
77990
78499
  }
77991
78500
  follow(sid, offset) {
77992
78501
  const path = transcriptPathFor(this.o.cwd, sid, this.o.projectsRoot);
77993
- this.follower = new TranscriptFollower(path, join39(path.replace(/\.jsonl$/, ""), "subagents"));
78502
+ this.follower = new TranscriptFollower(path, join40(path.replace(/\.jsonl$/, ""), "subagents"));
77994
78503
  this.sessionId = sid;
77995
78504
  this.settledTurn = null;
77996
78505
  this.lastPollAt = Date.now();
@@ -78535,7 +79044,7 @@ function assertNeverPhase(p) {
78535
79044
  }
78536
79045
  function fileSizeOf(path) {
78537
79046
  try {
78538
- return statSync13(path).size;
79047
+ return statSync14(path).size;
78539
79048
  } catch {
78540
79049
  return 0;
78541
79050
  }
@@ -78707,16 +79216,16 @@ var init_host_routing_env = __esm(() => {
78707
79216
  // src/launcher/magmux-binary.ts
78708
79217
  import { execSync } from "child_process";
78709
79218
  import { existsSync as existsSync28 } from "fs";
78710
- import { dirname as dirname16, join as join40 } from "path";
79219
+ import { dirname as dirname17, join as join41 } from "path";
78711
79220
  import { fileURLToPath } from "url";
78712
79221
  function findMagmuxBinaryOrNull() {
78713
79222
  const thisFile = fileURLToPath(import.meta.url);
78714
- const thisDir = dirname16(thisFile);
78715
- const pkgRoots = [join40(thisDir, ".."), join40(thisDir, "..", "..")];
79223
+ const thisDir = dirname17(thisFile);
79224
+ const pkgRoots = [join41(thisDir, ".."), join41(thisDir, "..", "..")];
78716
79225
  const platform = process.platform;
78717
79226
  const arch = process.arch;
78718
79227
  for (const pkgRoot of pkgRoots) {
78719
- const bundled = join40(pkgRoot, "native", `magmux-${platform}-${arch}`);
79228
+ const bundled = join41(pkgRoot, "native", `magmux-${platform}-${arch}`);
78720
79229
  if (existsSync28(bundled))
78721
79230
  return bundled;
78722
79231
  }
@@ -78724,10 +79233,10 @@ function findMagmuxBinaryOrNull() {
78724
79233
  const pkgName = `@claudish/magmux-${platform}-${arch}`;
78725
79234
  let searchDir = pkgRoots[0];
78726
79235
  for (let i = 0;i < 5; i++) {
78727
- const candidate = join40(searchDir, "node_modules", pkgName, "bin", "magmux");
79236
+ const candidate = join41(searchDir, "node_modules", pkgName, "bin", "magmux");
78728
79237
  if (existsSync28(candidate))
78729
79238
  return candidate;
78730
- const parent = dirname16(searchDir);
79239
+ const parent = dirname17(searchDir);
78731
79240
  if (parent === searchDir)
78732
79241
  break;
78733
79242
  searchDir = parent;
@@ -78754,14 +79263,14 @@ import {
78754
79263
  chmodSync as chmodSync3,
78755
79264
  closeSync as closeSync12,
78756
79265
  existsSync as existsSync29,
78757
- mkdirSync as mkdirSync19,
79266
+ mkdirSync as mkdirSync20,
78758
79267
  mkdtempSync,
78759
79268
  openSync as openSync12,
78760
- rmSync as rmSync10,
78761
- writeFileSync as writeFileSync15
79269
+ rmSync as rmSync11,
79270
+ writeFileSync as writeFileSync16
78762
79271
  } from "fs";
78763
79272
  import { connect as netConnect } from "net";
78764
- import { join as join41 } from "path";
79273
+ import { join as join42 } from "path";
78765
79274
  function envDeltas(parentEnv, childEnv) {
78766
79275
  const set = [];
78767
79276
  const unset = [];
@@ -78826,15 +79335,15 @@ function planMagmuxWrap(input) {
78826
79335
  const id = `claudish-${pid}`;
78827
79336
  const controlSocket = `/tmp/magmux-${id}.sock`;
78828
79337
  const tmpRoot = input.tmpRoot ?? "/tmp";
78829
- mkdirSync19(tmpRoot, { recursive: true });
78830
- const scriptDir = mkdtempSync(join41(tmpRoot, "claudish-launch-"));
79338
+ mkdirSync20(tmpRoot, { recursive: true });
79339
+ const scriptDir = mkdtempSync(join42(tmpRoot, "claudish-launch-"));
78831
79340
  chmodSync3(scriptDir, 448);
78832
- const scriptPath = join41(scriptDir, "claude-launch.sh");
79341
+ const scriptPath = join42(scriptDir, "claude-launch.sh");
78833
79342
  const parentEnv = input.parentEnv ?? process.env;
78834
79343
  const deltas = envDeltas(parentEnv, input.childEnv);
78835
79344
  const fd = openSync12(scriptPath, "wx", 384);
78836
79345
  try {
78837
- writeFileSync15(fd, buildLauncherScript(input.claudeBinary, input.claudeArgs, deltas));
79346
+ writeFileSync16(fd, buildLauncherScript(input.claudeBinary, input.claudeArgs, deltas));
78838
79347
  } finally {
78839
79348
  closeSync12(fd);
78840
79349
  }
@@ -78866,11 +79375,11 @@ function planMagmuxWrap(input) {
78866
79375
  } catch {}
78867
79376
  control = null;
78868
79377
  try {
78869
- rmSync10(scriptDir, { recursive: true, force: true });
79378
+ rmSync11(scriptDir, { recursive: true, force: true });
78870
79379
  } catch {}
78871
79380
  try {
78872
79381
  if (existsSync29(controlSocket))
78873
- rmSync10(controlSocket, { force: true });
79382
+ rmSync11(controlSocket, { force: true });
78874
79383
  } catch {}
78875
79384
  };
78876
79385
  process.on("exit", cleanup);
@@ -78950,7 +79459,7 @@ var init_cache_ttl = __esm(() => {
78950
79459
  });
78951
79460
 
78952
79461
  // src/providers/effort-recommendations.ts
78953
- import { readFileSync as readFileSync33, statSync as statSync14 } from "fs";
79462
+ import { readFileSync as readFileSync34, statSync as statSync15 } from "fs";
78954
79463
  function effortRecommendationsPathFor(catalogPath) {
78955
79464
  return catalogPath.endsWith(".json") ? `${catalogPath.slice(0, -5)}.efforts.json` : `${catalogPath}.efforts.json`;
78956
79465
  }
@@ -79026,7 +79535,7 @@ function parseSidecar(raw) {
79026
79535
  }
79027
79536
  function statOrNull2(path) {
79028
79537
  try {
79029
- const { mtimeMs, size } = statSync14(path);
79538
+ const { mtimeMs, size } = statSync15(path);
79030
79539
  return { mtimeMs, size };
79031
79540
  } catch {
79032
79541
  return null;
@@ -79034,7 +79543,7 @@ function statOrNull2(path) {
79034
79543
  }
79035
79544
  function readSidecarFile(path) {
79036
79545
  try {
79037
- return parseSidecar(JSON.parse(readFileSync33(path, "utf-8")));
79546
+ return parseSidecar(JSON.parse(readFileSync34(path, "utf-8")));
79038
79547
  } catch (err) {
79039
79548
  if (err?.code !== "ENOENT") {
79040
79549
  log(`[effort] unreadable ${path}: ${err instanceof Error ? err.message : String(err)}`);
@@ -79044,7 +79553,7 @@ function readSidecarFile(path) {
79044
79553
  }
79045
79554
  function foreignSidecarFormat(path) {
79046
79555
  try {
79047
- const raw = JSON.parse(readFileSync33(path, "utf-8"));
79556
+ const raw = JSON.parse(readFileSync34(path, "utf-8"));
79048
79557
  if (isRecord4(raw) && raw.format !== SIDECAR_FORMAT)
79049
79558
  return raw.format ?? "none";
79050
79559
  } catch {}
@@ -79103,9 +79612,9 @@ var init_effort_recommendations = __esm(() => {
79103
79612
  });
79104
79613
 
79105
79614
  // 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";
79615
+ import { existsSync as existsSync30, readFileSync as readFileSync35 } from "fs";
79616
+ import { homedir as homedir35 } from "os";
79617
+ import { join as join43 } from "path";
79109
79618
  function isRecommendationTier(value) {
79110
79619
  return typeof value === "string" && RECOMMENDATION_TIER_INDEX.has(value);
79111
79620
  }
@@ -79310,7 +79819,7 @@ function readRecommendedModelsCacheFile() {
79310
79819
  return null;
79311
79820
  let parsed;
79312
79821
  try {
79313
- parsed = JSON.parse(readFileSync34(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
79822
+ parsed = JSON.parse(readFileSync35(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
79314
79823
  } catch (err) {
79315
79824
  log(`[recommended] unreadable ${RECOMMENDED_MODELS_CACHE_PATH}: ${err instanceof Error ? err.message : String(err)}`);
79316
79825
  return null;
@@ -79687,7 +80196,7 @@ var init_model_loader = __esm(() => {
79687
80196
  { recommendationTier: "subscription", title: "Subscription", quickPickEligible: true }
79688
80197
  ];
79689
80198
  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");
80199
+ RECOMMENDED_MODELS_CACHE_PATH = join43(homedir35(), ".claudish", "recommended-models-cache-v2.json");
79691
80200
  RECOMMENDED_ROUTE_TIER_ORDER = {
79692
80201
  native: 0,
79693
80202
  general: 1,
@@ -80989,9 +81498,9 @@ var init_DiscoveryNotice = __esm(() => {
80989
81498
  });
80990
81499
 
80991
81500
  // 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";
81501
+ import { existsSync as existsSync31, mkdirSync as mkdirSync21, readFileSync as readFileSync36, writeFileSync as writeFileSync17 } from "fs";
81502
+ import { homedir as homedir36 } from "os";
81503
+ import { dirname as dirname18, join as join44 } from "path";
80995
81504
  function emptyDescriptionIndex() {
80996
81505
  return EMPTY_INDEX;
80997
81506
  }
@@ -81013,7 +81522,7 @@ function readCache(path) {
81013
81522
  if (!existsSync31(path))
81014
81523
  return null;
81015
81524
  try {
81016
- const raw = JSON.parse(readFileSync35(path, "utf-8"));
81525
+ const raw = JSON.parse(readFileSync36(path, "utf-8"));
81017
81526
  if (!raw || typeof raw !== "object" || typeof raw.byId !== "object" || raw.byId === null) {
81018
81527
  return null;
81019
81528
  }
@@ -81029,8 +81538,8 @@ function readCache(path) {
81029
81538
  }
81030
81539
  function writeCache(path, cache) {
81031
81540
  try {
81032
- mkdirSync20(dirname17(path), { recursive: true });
81033
- writeFileSync16(path, JSON.stringify(cache), "utf-8");
81541
+ mkdirSync21(dirname18(path), { recursive: true });
81542
+ writeFileSync17(path, JSON.stringify(cache), "utf-8");
81034
81543
  } catch (e) {
81035
81544
  log(`[model-descriptions] cache write failed: ${e?.message ?? String(e)}`);
81036
81545
  }
@@ -81084,7 +81593,7 @@ var init_model_descriptions = __esm(() => {
81084
81593
  init_logger();
81085
81594
  init_model_loader();
81086
81595
  init_cache_ttl();
81087
- MODEL_DESCRIPTIONS_CACHE_PATH = join43(homedir35(), ".claudish", "model-descriptions.json");
81596
+ MODEL_DESCRIPTIONS_CACHE_PATH = join44(homedir36(), ".claudish", "model-descriptions.json");
81088
81597
  EMPTY_INDEX = { get: () => {
81089
81598
  return;
81090
81599
  }, size: 0 };
@@ -81100,7 +81609,7 @@ function discoveryShapeOf(provider) {
81100
81609
  const format = getProviderByName(provider)?.modelDiscovery?.format;
81101
81610
  if (!format)
81102
81611
  return "none";
81103
- return format === "openai-models-list" ? "deadline" : "elapsed";
81612
+ return format === "openai-models-list" || format === "lmstudio-models" ? "deadline" : "elapsed";
81104
81613
  }
81105
81614
  async function* inCompletionOrder(promises) {
81106
81615
  const live = new Map(promises.map((p, i) => [i, p.then((v) => ({ i, v }))]));
@@ -81527,6 +82036,20 @@ var init_chrome = __esm(() => {
81527
82036
  init_tokens();
81528
82037
  });
81529
82038
 
82039
+ // src/picker/context-window-choices.ts
82040
+ function contextWindowChoices(max, defaultSize) {
82041
+ const choices = COMMON_SIZES.filter((size) => size < max * NEAR_MAXIMUM).map((size) => ({ size, label: formatContextLength(size) }));
82042
+ choices.push({ size: max, label: `${formatContextLength(max)} (model maximum)` });
82043
+ const distance = (choice) => Math.abs(choice.size - defaultSize);
82044
+ const closest = choices.reduce((best, choice) => distance(choice) < distance(best) ? choice : best);
82045
+ return { choices, defaultIndex: choices.indexOf(closest) };
82046
+ }
82047
+ var COMMON_SIZES, NEAR_MAXIMUM = 0.9;
82048
+ var init_context_window_choices = __esm(() => {
82049
+ init_model_selector();
82050
+ COMMON_SIZES = [32000, 64000, 128000, 256000, 512000];
82051
+ });
82052
+
81530
82053
  // src/picker/layout.ts
81531
82054
  function deriveRowLayout(inner, opts = {}) {
81532
82055
  const cells = Number.isFinite(inner) ? Math.max(0, Math.floor(inner)) : 0;
@@ -81683,7 +82206,7 @@ function detailText(spec, model) {
81683
82206
  };
81684
82207
  }
81685
82208
  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";
82209
+ 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
82210
  const billingShort = facts.billing === "sub" ? "flat-rate plan" : facts.billing === "local" ? "local" : "metered";
81688
82211
  const auth = facts.envVar === "" ? "signs in \u2014 no API key variable" : facts.envVar;
81689
82212
  return { billing, billingShort, auth };
@@ -81962,7 +82485,13 @@ function ChipCell({
81962
82485
  ]
81963
82486
  }, undefined, true, undefined, this);
81964
82487
  }
81965
- function ColumnHeader({ layout }) {
82488
+ function lastColumnLabel(models) {
82489
+ return models.length > 0 && models.every((m) => m.machine) ? "machine" : "$/1M";
82490
+ }
82491
+ function ColumnHeader({
82492
+ layout,
82493
+ last = "$/1M"
82494
+ }) {
81966
82495
  return /* @__PURE__ */ jsxDEV9("box", {
81967
82496
  height: 1,
81968
82497
  flexShrink: 0,
@@ -81999,7 +82528,7 @@ function ColumnHeader({ layout }) {
81999
82528
  }, undefined, false, undefined, this),
82000
82529
  /* @__PURE__ */ jsxDEV9("span", {
82001
82530
  fg: tokens.trace,
82002
- children: padStartTo("$/1M", layout.price)
82531
+ children: padStartTo(last, layout.price)
82003
82532
  }, undefined, false, undefined, this),
82004
82533
  layout.mark > 0 ? /* @__PURE__ */ jsxDEV9("span", {
82005
82534
  fg: tokens.trace,
@@ -82044,7 +82573,7 @@ function ModelRow({
82044
82573
  }, undefined, true, undefined, this) : null,
82045
82574
  /* @__PURE__ */ jsxDEV9("span", {
82046
82575
  fg: idFg,
82047
- children: padTo(model.id, layout.id)
82576
+ children: padTo(model.machine?.modelId ?? model.id, layout.id)
82048
82577
  }, undefined, false, undefined, this),
82049
82578
  /* @__PURE__ */ jsxDEV9("span", {
82050
82579
  children: gap(GAPS.afterId)
@@ -82056,7 +82585,10 @@ function ModelRow({
82056
82585
  /* @__PURE__ */ jsxDEV9("span", {
82057
82586
  children: gap(GAPS.afterCtx)
82058
82587
  }, undefined, false, undefined, this),
82059
- chipBg === null ? /* @__PURE__ */ jsxDEV9("span", {
82588
+ model.machine ? /* @__PURE__ */ jsxDEV9("span", {
82589
+ fg: cursor ? C.strong : tokens.text,
82590
+ children: padStartTo(truncate(model.machine.name, layout.price), layout.price)
82591
+ }, undefined, false, undefined, this) : chipBg === null ? /* @__PURE__ */ jsxDEV9("span", {
82060
82592
  fg: priceFg(price),
82061
82593
  children: padStartTo(price, layout.price)
82062
82594
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9(ChipCell, {
@@ -82379,13 +82911,32 @@ function buildLoadTasks(input) {
82379
82911
  }
82380
82912
  return tasks;
82381
82913
  }
82382
- function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82914
+ function ModelPicker({
82915
+ source,
82916
+ onDone,
82917
+ askContextWindow = false,
82918
+ onDiscoveryFailure
82919
+ }) {
82383
82920
  const { width, height } = useTerminalDimensions();
82384
82921
  const providers = usePickerProviders(source);
82385
82922
  const [view, setView] = useState7("providers");
82386
- const [filter, setFilter] = useState7("");
82387
- const [typing, setTyping] = useState7(false);
82923
+ const [filter, setFilterState] = useState7("");
82924
+ const filterNow = useRef6(filter);
82925
+ filterNow.current = filter;
82926
+ const setFilter = (next) => {
82927
+ filterNow.current = typeof next === "function" ? next(filterNow.current) : next;
82928
+ setFilterState(filterNow.current);
82929
+ };
82930
+ const [typing, setTypingState] = useState7(false);
82931
+ const typingNow = useRef6(typing);
82932
+ typingNow.current = typing;
82933
+ const setTyping = (next) => {
82934
+ typingNow.current = next;
82935
+ setTypingState(next);
82936
+ };
82388
82937
  const [custom, setCustom] = useState7("");
82938
+ const [sizing, setSizing] = useState7(null);
82939
+ const [sizeCursor, setSizeCursor] = useState7(0);
82389
82940
  const [cursor, setCursor] = useState7(0);
82390
82941
  const [providerCursor, setProviderCursor] = useState7(0);
82391
82942
  const [revealKeyless, setRevealKeyless] = useState7(false);
@@ -82464,7 +83015,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82464
83015
  const needle = filter.trim().toLowerCase();
82465
83016
  if (!needle)
82466
83017
  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));
83018
+ 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
83019
  }, [list.rows, filter, labels]);
82469
83020
  const busy = providers.probing || catalog.phase === "loading" || discovery.busy;
82470
83021
  const frame = useAnimationFrame(busy);
@@ -82504,6 +83055,21 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82504
83055
  onDone(null);
82505
83056
  return;
82506
83057
  }
83058
+ if (view === "context") {
83059
+ if (name === "escape") {
83060
+ setView("models");
83061
+ return;
83062
+ }
83063
+ if (name === "up" || name === "down") {
83064
+ const last = (sizing?.choices.length ?? 1) - 1;
83065
+ setSizeCursor((c) => Math.max(0, Math.min(last, c + (name === "up" ? -1 : 1))));
83066
+ return;
83067
+ }
83068
+ if ((name === "return" || name === "enter") && sizing) {
83069
+ onDone(sizing.spec, sizing.choices[sizeCursor]?.size);
83070
+ }
83071
+ return;
83072
+ }
82507
83073
  if (view === "custom") {
82508
83074
  if (name === "escape") {
82509
83075
  setView("models");
@@ -82525,7 +83091,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82525
83091
  }
82526
83092
  if (view === "providers") {
82527
83093
  if (name === "escape") {
82528
- if (filter !== "" || typing) {
83094
+ if (filterNow.current !== "" || typingNow.current) {
82529
83095
  setFilter("");
82530
83096
  setTyping(false);
82531
83097
  setProviderCursor(0);
@@ -82568,7 +83134,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82568
83134
  setProviderCursor(0);
82569
83135
  return;
82570
83136
  }
82571
- const providerCommands = filter === "" && !typing;
83137
+ const providerCommands = filterNow.current === "" && !typingNow.current;
82572
83138
  if (providerCommands && key.raw === "a") {
82573
83139
  setScope(null);
82574
83140
  setFilter("");
@@ -82596,7 +83162,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82596
83162
  return;
82597
83163
  }
82598
83164
  if (name === "escape") {
82599
- if (filter !== "" || typing) {
83165
+ if (filterNow.current !== "" || typingNow.current) {
82600
83166
  setFilter("");
82601
83167
  setTyping(false);
82602
83168
  setCursor(0);
@@ -82624,8 +83190,17 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82624
83190
  return;
82625
83191
  }
82626
83192
  if (name === "return" || name === "enter") {
82627
- if (selected)
83193
+ if (!selected)
83194
+ return;
83195
+ const max = askContextWindow ? selected.model.maxContextLength : undefined;
83196
+ if (max === undefined) {
82628
83197
  onDone(selected.spec);
83198
+ return;
83199
+ }
83200
+ const { choices, defaultIndex } = contextWindowChoices(max, DEFAULT_LOCAL_CONTEXT_WINDOW);
83201
+ setSizing({ spec: selected.spec, choices });
83202
+ setSizeCursor(defaultIndex);
83203
+ setView("context");
82629
83204
  return;
82630
83205
  }
82631
83206
  if (name === "backspace") {
@@ -82633,7 +83208,7 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82633
83208
  setCursor(0);
82634
83209
  return;
82635
83210
  }
82636
- const commandsLive = filter === "" && !typing;
83211
+ const commandsLive = filterNow.current === "" && !typingNow.current;
82637
83212
  if (commandsLive && key.raw === "c") {
82638
83213
  setView("custom");
82639
83214
  return;
@@ -82655,6 +83230,44 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82655
83230
  }
82656
83231
  }
82657
83232
  });
83233
+ if (view === "context" && sizing) {
83234
+ return /* @__PURE__ */ jsxDEV10(Centred, {
83235
+ width,
83236
+ height,
83237
+ children: /* @__PURE__ */ jsxDEV10(Dialog, {
83238
+ title: "context window",
83239
+ status: sizing.spec,
83240
+ width: layout.width,
83241
+ marginLeft: 0,
83242
+ children: [
83243
+ sizing.choices.map((choice, index) => /* @__PURE__ */ jsxDEV10("box", {
83244
+ height: 1,
83245
+ flexShrink: 0,
83246
+ children: /* @__PURE__ */ jsxDEV10("text", {
83247
+ children: [
83248
+ /* @__PURE__ */ jsxDEV10("span", {
83249
+ fg: tokens.accent,
83250
+ children: index === sizeCursor ? "\u25B6 " : " "
83251
+ }, undefined, false, undefined, this),
83252
+ /* @__PURE__ */ jsxDEV10("span", {
83253
+ fg: tokens.text,
83254
+ children: choice.label
83255
+ }, undefined, false, undefined, this)
83256
+ ]
83257
+ }, undefined, true, undefined, this)
83258
+ }, choice.size, false, undefined, this)),
83259
+ /* @__PURE__ */ jsxDEV10(Rule, {}, undefined, false, undefined, this),
83260
+ /* @__PURE__ */ jsxDEV10(Hints, {
83261
+ hints: [
83262
+ { key: "\u2191\u2193", label: "move" },
83263
+ { key: "\u23CE", label: "launch it" },
83264
+ { key: "esc", label: "back" }
83265
+ ]
83266
+ }, undefined, false, undefined, this)
83267
+ ]
83268
+ }, "context", true, undefined, this)
83269
+ }, undefined, false, undefined, this);
83270
+ }
82658
83271
  if (view === "custom") {
82659
83272
  return /* @__PURE__ */ jsxDEV10(Centred, {
82660
83273
  width,
@@ -82831,7 +83444,8 @@ function ModelPicker({ source, onDone, onDiscoveryFailure }) {
82831
83444
  idle: orderedByProvider(storedShown ?? discovery.outcome) ? "" : undefined
82832
83445
  }, undefined, false, undefined, this),
82833
83446
  /* @__PURE__ */ jsxDEV10(ColumnHeader, {
82834
- layout: rowLayout
83447
+ layout: rowLayout,
83448
+ last: lastColumnLabel(list.rows.map((r) => r.model))
82835
83449
  }, undefined, false, undefined, this),
82836
83450
  /* @__PURE__ */ jsxDEV10("box", {
82837
83451
  flexDirection: "column",
@@ -82967,6 +83581,7 @@ function emptyLabel(loading, filter, total, scopedName, providers) {
82967
83581
  }
82968
83582
  var MAX_BANNER_ROWS = 5, HOUR_MS18;
82969
83583
  var init_ModelPicker = __esm(() => {
83584
+ init_context_window_limit();
82970
83585
  init_dynamic_models_catalog_store();
82971
83586
  init_dynamic_models_catalog();
82972
83587
  init_EmptyState();
@@ -82976,6 +83591,7 @@ var init_ModelPicker = __esm(() => {
82976
83591
  init_DiscoveryNotice();
82977
83592
  init_PickerDataSource();
82978
83593
  init_chrome();
83594
+ init_context_window_choices();
82979
83595
  init_detail();
82980
83596
  init_useModelDescriptions();
82981
83597
  init_usePickerModels();
@@ -83110,7 +83726,7 @@ async function resolveDataSource() {
83110
83726
  await Promise.resolve().then(() => init_fixture_source());
83111
83727
  return createFixtureDataSource(name);
83112
83728
  }
83113
- async function runModelPicker(_options = {}) {
83729
+ async function runModelPicker(options = {}) {
83114
83730
  ensureEndpointsRegistered();
83115
83731
  const source = await resolveDataSource();
83116
83732
  const deferred = [];
@@ -83123,18 +83739,21 @@ async function runModelPicker(_options = {}) {
83123
83739
  await applyRendererThemeMode(renderer);
83124
83740
  const root = createRoot(renderer);
83125
83741
  let chosen = null;
83742
+ let chosenContextWindow;
83126
83743
  try {
83127
83744
  await new Promise((resolve) => {
83128
83745
  let settled = false;
83129
- const done = (spec) => {
83746
+ const done = (spec, contextWindow) => {
83130
83747
  if (settled)
83131
83748
  return;
83132
83749
  settled = true;
83133
83750
  chosen = spec;
83751
+ chosenContextWindow = contextWindow;
83134
83752
  resolve();
83135
83753
  };
83136
83754
  root.render(/* @__PURE__ */ jsxDEV11(ModelPicker, {
83137
83755
  source,
83756
+ askContextWindow: options.onContextWindow !== undefined,
83138
83757
  onDone: done,
83139
83758
  onDiscoveryFailure: (provider, lines) => deferred.push({ provider, lines })
83140
83759
  }, undefined, false, undefined, this));
@@ -83152,7 +83771,7 @@ async function runModelPicker(_options = {}) {
83152
83771
  process.stderr.write(line);
83153
83772
  }
83154
83773
  }
83155
- return { model: chosen };
83774
+ return { model: chosen, contextWindow: chosenContextWindow };
83156
83775
  }
83157
83776
  var init_model_picker_run = __esm(() => {
83158
83777
  init_logger();
@@ -83473,6 +84092,8 @@ async function selectModel(options = {}) {
83473
84092
  const outcome = await selectModelInteractive(options);
83474
84093
  if (outcome.model === null)
83475
84094
  throw new PickerCancelled;
84095
+ if (outcome.contextWindow !== undefined)
84096
+ options.onContextWindow?.(outcome.contextWindow);
83476
84097
  return outcome.model;
83477
84098
  }
83478
84099
  async function selectModelInteractive(options = {}) {
@@ -83839,7 +84460,7 @@ function buildRowsFromDiscovered(provider, displayName, discovered, catalogRows)
83839
84460
  const discoveredById = new Map(discovered.map((m) => [m.id, m]));
83840
84461
  const rows = choices.map((c) => {
83841
84462
  const source = discoveredById.get(c.id);
83842
- const contextLength = source ? resolveDiscoveredContextLength(source) : c.contextWindow ?? 0;
84463
+ const contextLength = (source ? resolveDiscoveredContextLength(source) : c.contextWindow ?? 0) || (source?.maxContextWindow ?? 0);
83843
84464
  const parts = [c.displayName];
83844
84465
  if (contextLength)
83845
84466
  parts.push(`${formatContextLength(contextLength)} context`);
@@ -83857,6 +84478,8 @@ function buildRowsFromDiscovered(provider, displayName, discovered, catalogRows)
83857
84478
  pricing: subscription ? SUBSCRIPTION_PRICING : pricingById.get(c.id.toLowerCase()),
83858
84479
  context: formatContextLength(contextLength),
83859
84480
  contextLength,
84481
+ maxContextLength: source?.maxContextWindow,
84482
+ machine: source?.machine,
83860
84483
  supportsTools: lookupModelCapabilities(c.id)?.supportsTools ?? source?.supportsTools ?? true,
83861
84484
  isFree: flatRate,
83862
84485
  source: displayName
@@ -87577,24 +88200,24 @@ var init_branding = __esm(() => {
87577
88200
  });
87578
88201
 
87579
88202
  // 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";
88203
+ import { existsSync as existsSync32, mkdirSync as mkdirSync22, readFileSync as readFileSync37, unlinkSync as unlinkSync9, writeFileSync as writeFileSync18 } from "fs";
88204
+ import { homedir as homedir37, platform as platform2, tmpdir } from "os";
88205
+ import { join as join45 } from "path";
87583
88206
  function getCacheFilePath() {
87584
88207
  let cacheDir;
87585
88208
  if (isWindows) {
87586
- const localAppData = process.env.LOCALAPPDATA || join44(homedir36(), "AppData", "Local");
87587
- cacheDir = join44(localAppData, "claudish");
88209
+ const localAppData = process.env.LOCALAPPDATA || join45(homedir37(), "AppData", "Local");
88210
+ cacheDir = join45(localAppData, "claudish");
87588
88211
  } else {
87589
- cacheDir = join44(homedir36(), ".cache", "claudish");
88212
+ cacheDir = join45(homedir37(), ".cache", "claudish");
87590
88213
  }
87591
88214
  try {
87592
88215
  if (!existsSync32(cacheDir)) {
87593
- mkdirSync21(cacheDir, { recursive: true });
88216
+ mkdirSync22(cacheDir, { recursive: true });
87594
88217
  }
87595
- return join44(cacheDir, "update-check.json");
88218
+ return join45(cacheDir, "update-check.json");
87596
88219
  } catch {
87597
- return join44(tmpdir(), "claudish-update-check.json");
88220
+ return join45(tmpdir(), "claudish-update-check.json");
87598
88221
  }
87599
88222
  }
87600
88223
  function readCache2() {
@@ -87603,7 +88226,7 @@ function readCache2() {
87603
88226
  if (!existsSync32(cachePath)) {
87604
88227
  return null;
87605
88228
  }
87606
- const data = JSON.parse(readFileSync36(cachePath, "utf-8"));
88229
+ const data = JSON.parse(readFileSync37(cachePath, "utf-8"));
87607
88230
  return data;
87608
88231
  } catch {
87609
88232
  return null;
@@ -87616,7 +88239,7 @@ function writeCache2(latestVersion) {
87616
88239
  lastCheck: Date.now(),
87617
88240
  latestVersion
87618
88241
  };
87619
- writeFileSync17(cachePath, JSON.stringify(data), "utf-8");
88242
+ writeFileSync18(cachePath, JSON.stringify(data), "utf-8");
87620
88243
  } catch {}
87621
88244
  }
87622
88245
  function isCacheValid(cache) {
@@ -92569,6 +93192,13 @@ class LocalTransport {
92569
93192
  streamFormat = "openai-sse";
92570
93193
  config;
92571
93194
  modelName;
93195
+ lmStudioDevice;
93196
+ lmStudioInstance;
93197
+ lmStudioPlacedAt;
93198
+ lmStudioPlacementError;
93199
+ unplacedErrors = new Map;
93200
+ unplacedCount = 0;
93201
+ probeLeases = new Set;
92572
93202
  concurrency;
92573
93203
  healthChecked = false;
92574
93204
  isHealthy = false;
@@ -92578,17 +93208,21 @@ class LocalTransport {
92578
93208
  _isOllamaBackend;
92579
93209
  constructor(config, modelName, options) {
92580
93210
  this.config = config;
92581
- this.modelName = modelName;
93211
+ if (config.name === "lmstudio") {
93212
+ const { model, device } = splitLMStudioDevice(modelName);
93213
+ this.modelName = model;
93214
+ this.lmStudioDevice = device;
93215
+ } else {
93216
+ this.modelName = modelName;
93217
+ }
92582
93218
  this.name = config.name;
92583
93219
  this.displayName = DISPLAY_NAMES2[config.name] || "Local";
92584
93220
  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
- }
93221
+ this._contextWindow = getProviderByName(config.name)?.unknownContextWindow ?? 32768;
93222
+ const limit = contextWindowLimit();
93223
+ if (limit !== undefined) {
93224
+ this._contextWindow = limit;
93225
+ log(`[${this.displayName}] Context window limit: ${limit}`);
92592
93226
  }
92593
93227
  if (this.concurrency !== undefined) {
92594
93228
  log(`[${this.displayName}] Concurrency: ${this.concurrency === 0 ? "unlimited" : this.concurrency}`);
@@ -92635,6 +93269,16 @@ class LocalTransport {
92635
93269
  };
92636
93270
  }
92637
93271
  async getExtraPayloadFields() {
93272
+ if (this.lmStudioDevice) {
93273
+ this.lmStudioPlacementError = undefined;
93274
+ try {
93275
+ return { model: (await this.placeOnDevice()).instanceId };
93276
+ } catch (error) {
93277
+ this.lmStudioPlacementError = error;
93278
+ this.lmStudioInstance = undefined;
93279
+ return { model: this.markUnplaced(error) };
93280
+ }
93281
+ }
92638
93282
  if (await this.isOllamaBackend()) {
92639
93283
  const numCtx = Math.max(this._contextWindow, 32768);
92640
93284
  log(`[${this.displayName}] Setting num_ctx: ${numCtx} (detected: ${this._contextWindow})`);
@@ -92648,15 +93292,96 @@ class LocalTransport {
92648
93292
  return LocalModelQueue.getInstance().enqueue(fetchFn, this.name, this.concurrency, opts?.signal);
92649
93293
  }
92650
93294
  async refreshAuth() {
92651
- if (this.healthChecked)
93295
+ const lease = acquireSigningLease();
93296
+ this.probeLeases.add(lease);
93297
+ try {
93298
+ await this.refreshAuthUnderLease();
93299
+ } finally {
93300
+ this.probeLeases.delete(lease);
93301
+ lease.release();
93302
+ }
93303
+ }
93304
+ async refreshAuthUnderLease() {
93305
+ if (this.healthChecked) {
93306
+ await this.confirmPlacement();
92652
93307
  return;
93308
+ }
92653
93309
  const healthy = await this.checkHealth();
92654
93310
  if (!healthy) {
93311
+ if (this.lmStudioPlacementError !== undefined) {
93312
+ 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.`);
93313
+ }
92655
93314
  throw Object.assign(new Error(this.getConnectionErrorMessage(), {
92656
93315
  cause: this.lastProbeError
92657
93316
  }), { claudishEndpoint: this.lastProbeUrl ?? this.config.baseUrl });
92658
93317
  }
92659
93318
  await this.fetchContextWindow();
93319
+ await this.confirmPlacement();
93320
+ }
93321
+ placeOnDevice() {
93322
+ const placedAt = this.lmStudioPlacedAt;
93323
+ if (this.lmStudioInstance && placedAt !== undefined && Date.now() - placedAt > PLACEMENT_RECHECK_MS) {
93324
+ this.lmStudioInstance = undefined;
93325
+ }
93326
+ if (this.lmStudioInstance)
93327
+ return this.lmStudioInstance;
93328
+ this.lmStudioPlacedAt = undefined;
93329
+ const pending = this.getHeaders().then((headers) => ensureLMStudioInstance({
93330
+ baseUrl: this.config.baseUrl,
93331
+ model: this.modelName,
93332
+ device: this.lmStudioDevice,
93333
+ contextLength: contextWindowLimit() ?? getProviderByName(this.config.name)?.unknownContextWindow,
93334
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
93335
+ log
93336
+ })).then((instance) => {
93337
+ if (this.lmStudioInstance === pending)
93338
+ this.lmStudioPlacedAt = Date.now();
93339
+ return instance;
93340
+ });
93341
+ this.lmStudioInstance = pending;
93342
+ return pending;
93343
+ }
93344
+ async confirmPlacement() {
93345
+ if (!this.lmStudioDevice)
93346
+ return;
93347
+ if (this.lmStudioPlacementError !== undefined) {
93348
+ const error = this.lmStudioPlacementError;
93349
+ if (classifyConnectionError(error) === null)
93350
+ throw error;
93351
+ throw new Error(`LM Studio could not be reached while ${this.modelName} was placed on ${this.lmStudioDevice}. Send the message again.`);
93352
+ }
93353
+ let instance;
93354
+ try {
93355
+ instance = await this.placeOnDevice();
93356
+ } catch (error) {
93357
+ this.lmStudioInstance = undefined;
93358
+ throw error;
93359
+ }
93360
+ if (instance.contextLength) {
93361
+ this._contextWindow = Math.min(instance.contextLength, contextWindowLimit() ?? instance.contextLength);
93362
+ }
93363
+ }
93364
+ markUnplaced(error) {
93365
+ const marker = `${this.modelName}~${this.lmStudioDevice} (not placed #${++this.unplacedCount})`;
93366
+ this.unplacedErrors.set(marker, error);
93367
+ while (this.unplacedErrors.size > MAX_UNPLACED_ERRORS) {
93368
+ const oldest = this.unplacedErrors.keys().next().value;
93369
+ if (oldest === undefined)
93370
+ break;
93371
+ this.unplacedErrors.delete(oldest);
93372
+ }
93373
+ return marker;
93374
+ }
93375
+ transformPayload(payload) {
93376
+ const model = payload?.model;
93377
+ if (typeof model !== "string" || !model.endsWith(")") || !model.includes(" (not placed #")) {
93378
+ return payload;
93379
+ }
93380
+ const error = this.unplacedErrors.get(model);
93381
+ this.unplacedErrors.delete(model);
93382
+ if (error !== undefined && classifyConnectionError(error) === null)
93383
+ throw error;
93384
+ throw new Error(`LM Studio could not be reached while ${this.modelName} was placed on ${this.lmStudioDevice}. Send the message again.`);
92660
93385
  }
92661
93386
  getContextWindow() {
92662
93387
  return this._contextWindow;
@@ -92674,6 +93399,7 @@ class LocalTransport {
92674
93399
  try {
92675
93400
  const response = await fetch(`${this.config.baseUrl}/api/tags`, {
92676
93401
  method: "GET",
93402
+ headers: await this.probeHeaders(),
92677
93403
  signal: AbortSignal.timeout(5000)
92678
93404
  });
92679
93405
  this._isOllamaBackend = await hasOllamaTagsShape(response);
@@ -92683,6 +93409,13 @@ class LocalTransport {
92683
93409
  log(`[${this.displayName}] Ollama backend probe (${this.config.baseUrl}): ${this._isOllamaBackend}`);
92684
93410
  return this._isOllamaBackend;
92685
93411
  }
93412
+ async probeHeaders() {
93413
+ const headers = await this.getHeaders().catch(() => ({}));
93414
+ const values = credentialValuesFromRequest(headers);
93415
+ for (const lease of this.probeLeases)
93416
+ lease.add(values);
93417
+ return headers;
93418
+ }
92686
93419
  async checkHealth() {
92687
93420
  if (this.healthChecked)
92688
93421
  return this.isHealthy;
@@ -92693,6 +93426,7 @@ class LocalTransport {
92693
93426
  log(`[${this.displayName}] Trying health check: ${healthUrl}`);
92694
93427
  const response = await fetch(healthUrl, {
92695
93428
  method: "GET",
93429
+ headers: await this.probeHeaders(),
92696
93430
  signal: AbortSignal.timeout(5000)
92697
93431
  });
92698
93432
  this._isOllamaBackend ??= await hasOllamaTagsShape(response);
@@ -92713,6 +93447,7 @@ class LocalTransport {
92713
93447
  log(`[${this.displayName}] Trying health check: ${modelsUrl}`);
92714
93448
  const response = await fetch(modelsUrl, {
92715
93449
  method: "GET",
93450
+ headers: await this.probeHeaders(),
92716
93451
  signal: AbortSignal.timeout(5000)
92717
93452
  });
92718
93453
  if (response.ok) {
@@ -92732,11 +93467,13 @@ class LocalTransport {
92732
93467
  return false;
92733
93468
  }
92734
93469
  async fetchContextWindow() {
92735
- if (process.env.CLAUDISH_CONTEXT_WINDOW)
93470
+ if (contextWindowLimit() !== undefined)
92736
93471
  return;
92737
93472
  log(`[${this.displayName}] Fetching context window...`);
92738
93473
  if (await this.isOllamaBackend()) {
92739
93474
  await this.fetchOllamaContextWindow();
93475
+ } else if (this.lmStudioDevice) {
93476
+ log(`[${this.displayName}] Context window comes from the instance on ${this.lmStudioDevice}`);
92740
93477
  } else if (this.config.name === "lmstudio") {
92741
93478
  await this.fetchLMStudioContextWindow();
92742
93479
  } else {
@@ -92747,7 +93484,7 @@ class LocalTransport {
92747
93484
  try {
92748
93485
  const response = await fetch(`${this.config.baseUrl}/api/show`, {
92749
93486
  method: "POST",
92750
- headers: { "Content-Type": "application/json" },
93487
+ headers: { "Content-Type": "application/json", ...await this.probeHeaders() },
92751
93488
  body: JSON.stringify({ name: this.modelName }),
92752
93489
  signal: AbortSignal.timeout(3000)
92753
93490
  });
@@ -92778,8 +93515,9 @@ class LocalTransport {
92778
93515
  }
92779
93516
  async fetchLMStudioContextWindow() {
92780
93517
  try {
92781
- const response = await fetch(`${this.config.baseUrl}/v1/models`, {
93518
+ const response = await fetch(`${this.config.baseUrl}/api/v0/models`, {
92782
93519
  method: "GET",
93520
+ headers: await this.probeHeaders(),
92783
93521
  signal: AbortSignal.timeout(3000)
92784
93522
  });
92785
93523
  if (response.ok) {
@@ -92787,19 +93525,21 @@ class LocalTransport {
92787
93525
  log(`[${this.displayName}] Models response: ${JSON.stringify(data).slice(0, 500)}`);
92788
93526
  const models = data.data || [];
92789
93527
  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
- }
93528
+ const ctxLength = targetModel?.loaded_context_length;
93529
+ if (typeof ctxLength === "number" && ctxLength > 0) {
93530
+ this._contextWindow = ctxLength;
93531
+ log(`[${this.displayName}] Context window from model: ${this._contextWindow}`);
93532
+ return;
93533
+ }
93534
+ const maxLength = targetModel?.max_context_length;
93535
+ if (typeof maxLength === "number" && maxLength > 0 && maxLength < this._contextWindow) {
93536
+ this._contextWindow = maxLength;
93537
+ log(`[${this.displayName}] Context window from model maximum: ${maxLength}`);
93538
+ return;
92797
93539
  }
92798
- this._contextWindow = 32768;
92799
93540
  log(`[${this.displayName}] Using default context window: ${this._contextWindow}`);
92800
93541
  }
92801
93542
  } catch (e) {
92802
- this._contextWindow = 32768;
92803
93543
  log(`[${this.displayName}] Failed to fetch model info: ${e?.message || e}. Using default: ${this._contextWindow}`);
92804
93544
  }
92805
93545
  }
@@ -92816,12 +93556,17 @@ class LocalTransport {
92816
93556
  }
92817
93557
  }
92818
93558
  }
92819
- var localProviderAgent, DISPLAY_NAMES2;
93559
+ var MAX_UNPLACED_ERRORS = 64, localProviderAgent, DISPLAY_NAMES2, PLACEMENT_RECHECK_MS = 1e4;
92820
93560
  var init_local = __esm(() => {
92821
93561
  init_authority();
93562
+ init_call_context();
92822
93563
  init_connection_error();
92823
93564
  init_local_queue();
92824
93565
  init_logger();
93566
+ init_lmstudio_devices();
93567
+ init_provider_definitions();
93568
+ init_redact();
93569
+ init_context_window_limit();
92825
93570
  init_probe_discovery();
92826
93571
  localProviderAgent = new Agent({
92827
93572
  headersTimeout: 600000,
@@ -94064,9 +94809,9 @@ var init_response_seam = __esm(() => {
94064
94809
  });
94065
94810
 
94066
94811
  // 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";
94812
+ import { existsSync as existsSync33, readFileSync as readFileSync38, statSync as statSync16 } from "fs";
94813
+ import { homedir as homedir38 } from "os";
94814
+ import { join as join46 } from "path";
94070
94815
  function prefixMatch(modelName) {
94071
94816
  for (const [key, pricing] of pricingMap) {
94072
94817
  if (modelName.startsWith(key))
@@ -94106,10 +94851,10 @@ function loadDiskCache() {
94106
94851
  try {
94107
94852
  if (!existsSync33(CACHE_FILE))
94108
94853
  return false;
94109
- const stat = statSync15(CACHE_FILE);
94854
+ const stat = statSync16(CACHE_FILE);
94110
94855
  const age = Date.now() - stat.mtimeMs;
94111
94856
  const isFresh = age < CACHE_TTL_MS5;
94112
- const raw = readFileSync37(CACHE_FILE, "utf-8");
94857
+ const raw = readFileSync38(CACHE_FILE, "utf-8");
94113
94858
  const data = JSON.parse(raw);
94114
94859
  for (const [key, pricing] of Object.entries(data)) {
94115
94860
  pricingMap.set(key, pricing);
@@ -94126,14 +94871,14 @@ var init_pricing_cache = __esm(() => {
94126
94871
  init_logger();
94127
94872
  init_catalog_query();
94128
94873
  pricingMap = new Map;
94129
- CACHE_DIR = join45(homedir37(), ".claudish");
94130
- CACHE_FILE = join45(CACHE_DIR, "pricing-cache.json");
94874
+ CACHE_DIR = join46(homedir38(), ".claudish");
94875
+ CACHE_FILE = join46(CACHE_DIR, "pricing-cache.json");
94131
94876
  CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
94132
94877
  });
94133
94878
 
94134
94879
  // src/proxy-server.ts
94135
- import { appendFileSync as appendFileSync6, mkdirSync as mkdirSync22 } from "fs";
94136
- import { join as join46 } from "path";
94880
+ import { appendFileSync as appendFileSync6, mkdirSync as mkdirSync23 } from "fs";
94881
+ import { join as join47 } from "path";
94137
94882
  function isTerminalRoutingFailure(e) {
94138
94883
  return e instanceof RoutingError;
94139
94884
  }
@@ -94141,9 +94886,9 @@ function maybeCaptureClassifierRequest(c, body) {
94141
94886
  if (!process.env.CLAUDISH_CLASSIFIER_DEBUG)
94142
94887
  return;
94143
94888
  try {
94144
- const dir = join46(process.cwd(), "logs");
94889
+ const dir = join47(process.cwd(), "logs");
94145
94890
  if (!classifierCaptureDirReady) {
94146
- mkdirSync22(dir, { recursive: true });
94891
+ mkdirSync23(dir, { recursive: true });
94147
94892
  classifierCaptureDirReady = true;
94148
94893
  }
94149
94894
  const record = {
@@ -94166,7 +94911,7 @@ function maybeCaptureClassifierRequest(c, body) {
94166
94911
  "x-api-key": c.req.header("x-api-key") ? "<present>" : null
94167
94912
  }
94168
94913
  };
94169
- appendFileSync6(join46(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
94914
+ appendFileSync6(join47(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
94170
94915
  `);
94171
94916
  } catch {}
94172
94917
  }
@@ -94686,28 +95431,28 @@ var init_proxy_server = __esm(() => {
94686
95431
  import {
94687
95432
  copyFileSync as copyFileSync2,
94688
95433
  existsSync as existsSync34,
94689
- mkdirSync as mkdirSync23,
94690
- readFileSync as readFileSync38,
94691
- readdirSync as readdirSync7,
95434
+ mkdirSync as mkdirSync24,
95435
+ readFileSync as readFileSync39,
95436
+ readdirSync as readdirSync8,
94692
95437
  unlinkSync as unlinkSync10
94693
95438
  } from "fs";
94694
- import { homedir as homedir38 } from "os";
94695
- import { dirname as dirname18, join as join47 } from "path";
95439
+ import { homedir as homedir39 } from "os";
95440
+ import { dirname as dirname19, join as join48 } from "path";
94696
95441
  import { fileURLToPath as fileURLToPath2 } from "url";
94697
95442
  function getVersion3() {
94698
95443
  return VERSION;
94699
95444
  }
94700
95445
  function clearAllModelCaches() {
94701
- const cacheDir = join47(homedir38(), ".claudish");
95446
+ const cacheDir = join48(homedir39(), ".claudish");
94702
95447
  if (!existsSync34(cacheDir))
94703
95448
  return;
94704
95449
  const cachePatterns = ["pricing-cache.json", "recommended-models-cache-v2.json"];
94705
95450
  let cleared = 0;
94706
95451
  try {
94707
- const files = readdirSync7(cacheDir);
95452
+ const files = readdirSync8(cacheDir);
94708
95453
  for (const file of files) {
94709
95454
  if (cachePatterns.includes(file)) {
94710
- unlinkSync10(join47(cacheDir, file));
95455
+ unlinkSync10(join48(cacheDir, file));
94711
95456
  cleared++;
94712
95457
  }
94713
95458
  }
@@ -95045,6 +95790,13 @@ async function parseArgs(args) {
95045
95790
  process.exit(1);
95046
95791
  }
95047
95792
  config.effortOverride = effArg;
95793
+ } else if (arg === "--context-window") {
95794
+ const size = parseContextWindow(args[++i] ?? "");
95795
+ if (size === undefined) {
95796
+ console.error("--context-window requires a size in tokens (128000, 128k or 1m)");
95797
+ process.exit(1);
95798
+ }
95799
+ config.contextWindow = size;
95048
95800
  } else if (arg === "--pro-on-ultracode") {
95049
95801
  config.proOnUltracode = true;
95050
95802
  } else if (arg === "--no-pro-on-ultracode") {
@@ -95989,6 +96741,7 @@ ${h("OPTIONS")}
95989
96741
  ${green("--advisor")} ${yellow('"m1,m2[:collector]"')} Multi-model advisor replacement (works with any --model)
95990
96742
  ${green("--model-params")} ${yellow('"k=v,..."')} Extra request params merged into the payload (e.g. reasoning.mode=pro)
95991
96743
  ${green("--effort-override")} ${yellow("<level>")} Pin reasoning effort verbatim, skipping the per-model clamp
96744
+ ${green("--context-window")} ${yellow("<size>")} Largest context window (128000, 128k, 1m), for local models
95992
96745
  ${green("--pro-on-ultracode")} Apply the model's catalog preset while in ultracode (opt-in)
95993
96746
  ${green("--no-pro-on-ultracode")} Force that off for this run (when enabled in config/env)
95994
96747
  ${green("--code-mode")} ${yellow("<auto|on|off>")} cx@ tools as one exec script tool (default auto; env CLAUDISH_CODE_MODE)
@@ -96234,8 +96987,8 @@ ${h("MORE INFO")}
96234
96987
  }
96235
96988
  function printAIAgentGuide() {
96236
96989
  try {
96237
- const guidePath = join47(__dirname2, "../AI_AGENT_GUIDE.md");
96238
- const guideContent = readFileSync38(guidePath, "utf-8");
96990
+ const guidePath = join48(__dirname2, "../AI_AGENT_GUIDE.md");
96991
+ const guideContent = readFileSync39(guidePath, "utf-8");
96239
96992
  console.log(guideContent);
96240
96993
  } catch (error) {
96241
96994
  console.error("Error reading AI Agent Guide:");
@@ -96251,10 +97004,10 @@ async function initializeClaudishSkill() {
96251
97004
  console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
96252
97005
  `);
96253
97006
  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");
97007
+ const claudeDir = join48(cwd, ".claude");
97008
+ const skillsDir = join48(claudeDir, "skills");
97009
+ const claudishSkillDir = join48(skillsDir, "claudish-usage");
97010
+ const skillFile = join48(claudishSkillDir, "SKILL.md");
96258
97011
  if (existsSync34(skillFile)) {
96259
97012
  console.log("\u2705 Claudish skill already installed at:");
96260
97013
  console.log(` ${skillFile}
@@ -96262,7 +97015,7 @@ async function initializeClaudishSkill() {
96262
97015
  console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
96263
97016
  return;
96264
97017
  }
96265
- const sourceSkillPath = join47(__dirname2, "../skills/claudish-usage/SKILL.md");
97018
+ const sourceSkillPath = join48(__dirname2, "../skills/claudish-usage/SKILL.md");
96266
97019
  if (!existsSync34(sourceSkillPath)) {
96267
97020
  console.error("\u274C Error: Claudish skill file not found in installation.");
96268
97021
  console.error(` Expected at: ${sourceSkillPath}`);
@@ -96273,15 +97026,15 @@ async function initializeClaudishSkill() {
96273
97026
  }
96274
97027
  try {
96275
97028
  if (!existsSync34(claudeDir)) {
96276
- mkdirSync23(claudeDir, { recursive: true });
97029
+ mkdirSync24(claudeDir, { recursive: true });
96277
97030
  console.log("\uD83D\uDCC1 Created .claude/ directory");
96278
97031
  }
96279
97032
  if (!existsSync34(skillsDir)) {
96280
- mkdirSync23(skillsDir, { recursive: true });
97033
+ mkdirSync24(skillsDir, { recursive: true });
96281
97034
  console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
96282
97035
  }
96283
97036
  if (!existsSync34(claudishSkillDir)) {
96284
- mkdirSync23(claudishSkillDir, { recursive: true });
97037
+ mkdirSync24(claudishSkillDir, { recursive: true });
96285
97038
  console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
96286
97039
  }
96287
97040
  copyFileSync2(sourceSkillPath, skillFile);
@@ -96353,6 +97106,7 @@ var init_cli = __esm(() => {
96353
97106
  init_api_key_map();
96354
97107
  init_api_key_provenance();
96355
97108
  init_claude_code_aliases();
97109
+ init_context_window_limit();
96356
97110
  init_endpoint_registration();
96357
97111
  init_muse_credentials();
96358
97112
  init_model_parser();
@@ -96367,7 +97121,7 @@ var init_cli = __esm(() => {
96367
97121
  init_ansi();
96368
97122
  init_provider_resolver();
96369
97123
  __filename2 = fileURLToPath2(import.meta.url);
96370
- __dirname2 = dirname18(__filename2);
97124
+ __dirname2 = dirname19(__filename2);
96371
97125
  CLAUDISH_FLAG_ARITY = {
96372
97126
  "--model": "value",
96373
97127
  "-m": "value",
@@ -96409,6 +97163,7 @@ var init_cli = __esm(() => {
96409
97163
  "--classifier-provider": "value",
96410
97164
  "--model-params": "value",
96411
97165
  "--effort-override": "value",
97166
+ "--context-window": "value",
96412
97167
  "--pro-on-ultracode": "none",
96413
97168
  "--no-pro-on-ultracode": "none",
96414
97169
  "--code-mode": "value",
@@ -96485,9 +97240,9 @@ function samePaneSize(a, b) {
96485
97240
  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
97241
 
96487
97242
  // src/pane/process-identity.ts
96488
- import { execFile as execFile4, execFileSync as execFileSync3 } from "child_process";
97243
+ import { execFile as execFile5, execFileSync as execFileSync3 } from "child_process";
96489
97244
  import { lstatSync as lstatSync6 } from "fs";
96490
- import { basename as basename3, dirname as dirname19, isAbsolute as isAbsolute3, join as join48, normalize } from "path";
97245
+ import { basename as basename4, dirname as dirname20, isAbsolute as isAbsolute3, join as join49, normalize } from "path";
96491
97246
  function collapse(s) {
96492
97247
  return s.trim().replace(/\s+/g, " ");
96493
97248
  }
@@ -96698,7 +97453,7 @@ function parseGroupFile(text) {
96698
97453
  return withEscaped(pgid, members, escaped);
96699
97454
  }
96700
97455
  function isLaunchDirPath(root, p) {
96701
- if (dirname19(p) !== root || !LAUNCH_DIR_RE.test(basename3(p)))
97456
+ if (dirname20(p) !== root || !LAUNCH_DIR_RE.test(basename4(p)))
96702
97457
  return false;
96703
97458
  try {
96704
97459
  const st = lstatSync6(p);
@@ -96711,24 +97466,24 @@ function isValidPaneId(id) {
96711
97466
  return PANE_ID_RE.test(id) && !/^\d+$/.test(id);
96712
97467
  }
96713
97468
  function sockPathOf(root, paneId) {
96714
- return join48(root, `magmux-${paneId}.sock`);
97469
+ return join49(root, `magmux-${paneId}.sock`);
96715
97470
  }
96716
97471
  function recordPathOf(root, paneId) {
96717
- return join48(root, "panes", `${paneId}.json`);
97472
+ return join49(root, "panes", `${paneId}.json`);
96718
97473
  }
96719
97474
  function isPaneSockPath(root, p, paneId) {
96720
- return isValidPaneId(paneId) && dirname19(p) === root && basename3(p) === `magmux-${paneId}.sock`;
97475
+ return isValidPaneId(paneId) && dirname20(p) === root && basename4(p) === `magmux-${paneId}.sock`;
96721
97476
  }
96722
97477
  function isPaneRecordPath(root, p, paneId) {
96723
- return isValidPaneId(paneId) && dirname19(p) === join48(root, "panes") && basename3(p) === `${paneId}.json`;
97478
+ return isValidPaneId(paneId) && dirname20(p) === join49(root, "panes") && basename4(p) === `${paneId}.json`;
96724
97479
  }
96725
97480
  function isForkRecordPath(projectsRoot, p, uuid) {
96726
97481
  if (!isAbsolute3(projectsRoot) || normalize(projectsRoot) !== projectsRoot)
96727
97482
  return false;
96728
- if (basename3(projectsRoot) !== "projects" || !FORK_UUID_RE.test(uuid))
97483
+ if (basename4(projectsRoot) !== "projects" || !FORK_UUID_RE.test(uuid))
96729
97484
  return false;
96730
- const dir = dirname19(p);
96731
- return dirname19(dir) === projectsRoot && PROJECT_SLUG_RE.test(basename3(dir)) && basename3(p) === `${uuid}.jsonl`;
97485
+ const dir = dirname20(p);
97486
+ return dirname20(dir) === projectsRoot && PROJECT_SLUG_RE.test(basename4(dir)) && basename4(p) === `${uuid}.jsonl`;
96732
97487
  }
96733
97488
  function watcherArgv(a) {
96734
97489
  const fork = a.fork ? [a.fork.projectsRoot, a.fork.path, a.fork.removeProjectDir ? "1" : "0"] : [];
@@ -96843,7 +97598,7 @@ var init_process_identity = __esm(() => {
96843
97598
  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
97599
  PS_ENV = { PATH: "/bin:/usr/bin:/usr/sbin:/sbin", LC_ALL: "C" };
96845
97600
  PS_OPTIONS = { env: PS_ENV, encoding: "utf8", maxBuffer: 64 * 1024 * 1024 };
96846
- psSpawn = { execFile: execFile4, execFileSync: execFileSync3 };
97601
+ psSpawn = { execFile: execFile5, execFileSync: execFileSync3 };
96847
97602
  LAUNCH_DIR_RE = /^launch-[A-Za-z0-9]{6}$/;
96848
97603
  PANE_ID_RE = /^[A-Za-z0-9_-]{1,64}$/;
96849
97604
  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 +97607,18 @@ var init_process_identity = __esm(() => {
96852
97607
  });
96853
97608
 
96854
97609
  // src/pane/pane-launch.ts
96855
- import { execFile as execFile5, spawn } from "child_process";
97610
+ import { execFile as execFile6, spawn } from "child_process";
96856
97611
  import { randomBytes as randomBytes14 } from "crypto";
96857
97612
  import {
96858
97613
  chmodSync as chmodSync4,
96859
97614
  lstatSync as lstatSync7,
96860
- mkdirSync as mkdirSync24,
97615
+ mkdirSync as mkdirSync25,
96861
97616
  mkdtempSync as mkdtempSync2,
96862
- readFileSync as readFileSync39,
96863
- statSync as statSync16,
96864
- writeFileSync as writeFileSync18
97617
+ readFileSync as readFileSync40,
97618
+ statSync as statSync17,
97619
+ writeFileSync as writeFileSync19
96865
97620
  } from "fs";
96866
- import { join as join49, resolve as resolve5 } from "path";
97621
+ import { join as join50, resolve as resolve5 } from "path";
96867
97622
  function uid() {
96868
97623
  return typeof process.getuid === "function" ? process.getuid() : 0;
96869
97624
  }
@@ -96883,17 +97638,17 @@ function assertPrivateDir(p) {
96883
97638
  function ensureSockRoot(given = sockRootFor()) {
96884
97639
  const root = resolve5(given);
96885
97640
  try {
96886
- mkdirSync24(root, { mode: 448 });
97641
+ mkdirSync25(root, { mode: 448 });
96887
97642
  } catch (e) {
96888
97643
  if (e.code === "ENOENT")
96889
- mkdirSync24(root, { recursive: true, mode: 448 });
97644
+ mkdirSync25(root, { recursive: true, mode: 448 });
96890
97645
  else if (e.code !== "EEXIST")
96891
97646
  throw e;
96892
97647
  }
96893
97648
  assertPrivateDir(root);
96894
- const panes = join49(root, "panes");
97649
+ const panes = join50(root, "panes");
96895
97650
  try {
96896
- mkdirSync24(panes, { mode: 448 });
97651
+ mkdirSync25(panes, { mode: 448 });
96897
97652
  } catch (e) {
96898
97653
  if (e.code !== "EEXIST")
96899
97654
  throw e;
@@ -96945,7 +97700,7 @@ function buildPaneEnv(input) {
96945
97700
  if ((input.platform ?? process.platform) === "linux" && entryBytes > LINUX_ENV_STRING_LIMIT)
96946
97701
  throw new PaneEnvTooLargeError(`pane environment snapshot is ${entryBytes} bytes, over Linux's 131072-byte limit per variable`);
96947
97702
  env[ENV.CLAUDISH_PANE_ENV] = json;
96948
- env.SHELL = join49(input.ctlDir, "sh-shim");
97703
+ env.SHELL = join50(input.ctlDir, "sh-shim");
96949
97704
  return { magmuxEnv: env };
96950
97705
  }
96951
97706
  function buildReplayEnv(input) {
@@ -96957,7 +97712,7 @@ function buildReplayEnv(input) {
96957
97712
  }
96958
97713
  if (input.configDirOverride)
96959
97714
  env.CLAUDE_CONFIG_DIR = input.configDirOverride;
96960
- env.SHELL = join49(input.ctlDir, "sh-shim");
97715
+ env.SHELL = join50(input.ctlDir, "sh-shim");
96961
97716
  env[ENV.CLAUDISH_PANE_CHILD] = "1";
96962
97717
  env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
96963
97718
  env.CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL = "1";
@@ -96990,10 +97745,10 @@ function replaySettingsJson(statusLine) {
96990
97745
  }
96991
97746
  function readUserStatusLine(configDir) {
96992
97747
  try {
96993
- const path = join49(configDir, "settings.json");
96994
- if (statSync16(path).size > MAX_USER_SETTINGS_BYTES)
97748
+ const path = join50(configDir, "settings.json");
97749
+ if (statSync17(path).size > MAX_USER_SETTINGS_BYTES)
96995
97750
  return null;
96996
- const v = JSON.parse(readFileSync39(path, "utf8"))?.statusLine;
97751
+ const v = JSON.parse(readFileSync40(path, "utf8"))?.statusLine;
96997
97752
  return v && typeof v === "object" && !Array.isArray(v) ? v : null;
96998
97753
  } catch {
96999
97754
  return null;
@@ -97175,7 +97930,7 @@ function runMagmuxVersion(found, timeoutMs) {
97175
97930
  rejectRun(new MagmuxUnavailableError(`magmux_unavailable: ${found} --version failed: ${detail}`));
97176
97931
  };
97177
97932
  try {
97178
- child = execFile5(found, ["--version"], { encoding: "utf8" }, (error, stdout, stderr) => {
97933
+ child = execFile6(found, ["--version"], { encoding: "utf8" }, (error, stdout, stderr) => {
97179
97934
  if (error)
97180
97935
  return fail(error.message);
97181
97936
  if (settle())
@@ -97210,21 +97965,21 @@ function replayLauncherScript(realShell, cwd, launch, argv) {
97210
97965
  ${launcherScript(cwd, launch, argv)}`;
97211
97966
  }
97212
97967
  function paneCommand(ctlDir) {
97213
- const cmd = `. ${shq2(join49(ctlDir, "pane-launch.sh"))}`;
97968
+ const cmd = `. ${shq2(join50(ctlDir, "pane-launch.sh"))}`;
97214
97969
  if (/claude /.test(cmd) || /claude$/.test(cmd) || /(^|\/)claude['"]?$/.test(cmd))
97215
97970
  throw new Error(`pane command would attach magmux's Claude Code controller: ${cmd}`);
97216
97971
  return cmd;
97217
97972
  }
97218
97973
  function createLaunchDirs(root) {
97219
- const ctlDir = mkdtempSync2(join49(root, "launch-"));
97974
+ const ctlDir = mkdtempSync2(join50(root, "launch-"));
97220
97975
  chmodSync4(ctlDir, 448);
97221
- const turnDir = mkdtempSync2(join49(root, "launch-"));
97976
+ const turnDir = mkdtempSync2(join50(root, "launch-"));
97222
97977
  chmodSync4(turnDir, 448);
97223
97978
  return { ctlDir, turnDir };
97224
97979
  }
97225
97980
  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" });
97981
+ writeFileSync19(join50(ctlDir, "pane-launch.sh"), script, { mode: 384, flag: "wx" });
97982
+ writeFileSync19(join50(ctlDir, "sh-shim"), SHELL_SHIM, { mode: 448, flag: "wx" });
97228
97983
  }
97229
97984
  function spawnPaneWatcher(args) {
97230
97985
  const proc = spawn("/bin/sh", watcherArgv(args), {
@@ -97989,18 +98744,18 @@ import {
97989
98744
  chmodSync as chmodSync5,
97990
98745
  closeSync as closeSync13,
97991
98746
  existsSync as existsSync36,
97992
- mkdirSync as mkdirSync25,
98747
+ mkdirSync as mkdirSync26,
97993
98748
  mkdtempSync as mkdtempSync3,
97994
98749
  openSync as openSync13,
97995
- readFileSync as readFileSync40,
97996
- readdirSync as readdirSync8,
97997
- rmSync as rmSync11,
97998
- statSync as statSync17,
98750
+ readFileSync as readFileSync41,
98751
+ readdirSync as readdirSync9,
98752
+ rmSync as rmSync12,
98753
+ statSync as statSync18,
97999
98754
  unlinkSync as unlinkSync11,
98000
- writeFileSync as writeFileSync19
98755
+ writeFileSync as writeFileSync20
98001
98756
  } from "fs";
98002
- import { homedir as homedir39, tmpdir as tmpdir2 } from "os";
98003
- import { dirname as dirname20, join as join50 } from "path";
98757
+ import { homedir as homedir40, tmpdir as tmpdir2 } from "os";
98758
+ import { dirname as dirname21, join as join51 } from "path";
98004
98759
  import { isatty } from "tty";
98005
98760
  function releaseTerminalIsolation() {
98006
98761
  if (!restoreTerminal)
@@ -98078,7 +98833,7 @@ function hasResolvableAnthropicAuth(deps = {}) {
98078
98833
  if (isRealAnthropicEnvCredential(env, "ANTHROPIC_API_KEY") || isRealAnthropicEnvCredential(env, "ANTHROPIC_AUTH_TOKEN")) {
98079
98834
  return true;
98080
98835
  }
98081
- if (fileExists(join50(homedir39(), ".claude", ".credentials.json")))
98836
+ if (fileExists(join51(homedir40(), ".claude", ".credentials.json")))
98082
98837
  return true;
98083
98838
  return keychainProbe();
98084
98839
  }
@@ -98173,15 +98928,15 @@ function settingsAuthSource(settings) {
98173
98928
  return null;
98174
98929
  }
98175
98930
  function readableClaudeSettingsLayers(config, env, deps) {
98176
- const readFile = deps.readFile ?? ((path) => readFileSync40(path, "utf-8"));
98177
- const home = deps.home ?? homedir39();
98931
+ const readFile = deps.readFile ?? ((path) => readFileSync41(path, "utf-8"));
98932
+ const home = deps.home ?? homedir40();
98178
98933
  const cwd = deps.cwd ?? process.cwd();
98179
98934
  const files = [
98180
98935
  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")
98936
+ join51(home, ".claude", "settings.json"),
98937
+ ...env.CLAUDE_CONFIG_DIR ? [join51(env.CLAUDE_CONFIG_DIR, "settings.json")] : [],
98938
+ join51(cwd, ".claude", "settings.json"),
98939
+ join51(cwd, ".claude", "settings.local.json")
98185
98940
  ];
98186
98941
  const layers = [];
98187
98942
  for (const file of files) {
@@ -98213,14 +98968,14 @@ function readSettingsSource(source, readFile) {
98213
98968
  }
98214
98969
  function managedSettingsPath() {
98215
98970
  if (isWindows2()) {
98216
- return join50(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
98971
+ return join51(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
98217
98972
  }
98218
98973
  if (process.platform === "darwin") {
98219
98974
  return "/Library/Application Support/ClaudeCode/managed-settings.json";
98220
98975
  }
98221
98976
  return "/etc/claude-code/managed-settings.json";
98222
98977
  }
98223
- function managedSettingsForcesClaudeAi(readFile = readFileSync40) {
98978
+ function managedSettingsForcesClaudeAi(readFile = readFileSync41) {
98224
98979
  try {
98225
98980
  const raw = readFile(managedSettingsPath(), "utf-8");
98226
98981
  const parsed = JSON.parse(raw);
@@ -98234,8 +98989,8 @@ function isWindows2() {
98234
98989
  }
98235
98990
  function createStatusLineScript(tokenFilePath) {
98236
98991
  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`);
98992
+ const claudishDir = join51(homeDir, ".claudish");
98993
+ const scriptPath = join51(claudishDir, `status-${process.pid}-${Date.now()}.js`);
98239
98994
  const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
98240
98995
  const light = getThemeMode() === "light";
98241
98996
  const cyanCode = light ? "38;2;14;116;144" : "96";
@@ -98347,6 +99102,8 @@ process.stdin.on('end', () => {
98347
99102
  // gap is the whole reason this line exists.
98348
99103
  const clamped = effWindow < contextWindow ? ' of ' + formatTokens(contextWindow) : '';
98349
99104
  ctxDisplay = '[' + bar + '] ' + formatTokens(inputTokens) + '/' + formatTokens(effWindow) + clamped;
99105
+ } else if (effWindow > 0) {
99106
+ ctxDisplay = '[' + '\u2591'.repeat(15) + '] 0/' + formatTokens(effWindow);
98350
99107
  } else {
98351
99108
  ctxDisplay = ctx + '%';
98352
99109
  }
@@ -98390,13 +99147,13 @@ process.stdin.on('end', () => {
98390
99147
  }
98391
99148
  });
98392
99149
  `;
98393
- writeFileSync19(scriptPath, script, "utf-8");
99150
+ writeFileSync20(scriptPath, script, "utf-8");
98394
99151
  return scriptPath;
98395
99152
  }
98396
99153
  function initializeTokenFile(tokenFilePath) {
98397
99154
  try {
98398
- mkdirSync25(dirname20(tokenFilePath), { recursive: true });
98399
- writeFileSync19(tokenFilePath, JSON.stringify({
99155
+ mkdirSync26(dirname21(tokenFilePath), { recursive: true });
99156
+ writeFileSync20(tokenFilePath, JSON.stringify({
98400
99157
  input_tokens: 0,
98401
99158
  output_tokens: 0,
98402
99159
  total_tokens: 0,
@@ -98411,11 +99168,23 @@ function initializeTokenFile(tokenFilePath) {
98411
99168
  log(`[claude-runner] Could not initialize token file ${tokenFilePath}: ${e}`);
98412
99169
  }
98413
99170
  }
99171
+ function seedTokenFileWindow(tokenFilePath, window2) {
99172
+ if (!window2 || window2 <= 0)
99173
+ return;
99174
+ try {
99175
+ const record = JSON.parse(readFileSync41(tokenFilePath, "utf-8"));
99176
+ if (record.input_tokens !== 0 || record.context_window !== "unknown")
99177
+ return;
99178
+ writeFileSync20(tokenFilePath, JSON.stringify({ ...record, context_window: window2, context_left_percent: 100 }), "utf-8");
99179
+ } catch (e) {
99180
+ log(`[claude-runner] Could not seed token file ${tokenFilePath}: ${e}`);
99181
+ }
99182
+ }
98414
99183
  function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FILE_MS) {
98415
99184
  let removed = 0;
98416
99185
  let entries;
98417
99186
  try {
98418
- entries = readdirSync8(dir);
99187
+ entries = readdirSync9(dir);
98419
99188
  } catch {
98420
99189
  return 0;
98421
99190
  }
@@ -98427,9 +99196,9 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
98427
99196
  if (!name.startsWith("tokens-") || !name.endsWith(".json"))
98428
99197
  continue;
98429
99198
  scanned++;
98430
- const full = join50(dir, name);
99199
+ const full = join51(dir, name);
98431
99200
  try {
98432
- if (statSync17(full).mtimeMs >= cutoff)
99201
+ if (statSync18(full).mtimeMs >= cutoff)
98433
99202
  continue;
98434
99203
  unlinkSync11(full);
98435
99204
  removed++;
@@ -98444,7 +99213,7 @@ function parseSettingsArg(value) {
98444
99213
  if (value.trimStart().startsWith("{")) {
98445
99214
  return JSON.parse(value);
98446
99215
  }
98447
- return JSON.parse(readFileSync40(value, "utf-8"));
99216
+ return JSON.parse(readFileSync41(value, "utf-8"));
98448
99217
  }
98449
99218
  function parseSettingsArgSafe(value) {
98450
99219
  try {
@@ -98456,9 +99225,9 @@ function parseSettingsArgSafe(value) {
98456
99225
  }
98457
99226
  function userSettingsFileCandidates(cwd) {
98458
99227
  return [
98459
- join50(homedir39(), ".claude", "settings.json"),
98460
- join50(cwd, ".claude", "settings.json"),
98461
- join50(cwd, ".claude", "settings.local.json")
99228
+ join51(homedir40(), ".claude", "settings.json"),
99229
+ join51(cwd, ".claude", "settings.json"),
99230
+ join51(cwd, ".claude", "settings.local.json")
98462
99231
  ];
98463
99232
  }
98464
99233
  function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
@@ -98499,11 +99268,11 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
98499
99268
  }
98500
99269
  function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
98501
99270
  const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
98502
- const claudishDir = join50(homeDir, ".claudish");
99271
+ const claudishDir = join51(homeDir, ".claudish");
98503
99272
  try {
98504
- mkdirSync25(claudishDir, { recursive: true });
99273
+ mkdirSync26(claudishDir, { recursive: true });
98505
99274
  } catch {}
98506
- const tempPath = join50(claudishDir, `settings-${process.pid}-${Date.now()}.json`);
99275
+ const tempPath = join51(claudishDir, `settings-${process.pid}-${Date.now()}.json`);
98507
99276
  const assignedFile = assignedTokenFile(process.env) !== null;
98508
99277
  const tokenFilePath = resolveTokenFilePath(port);
98509
99278
  cleanupStaleTokenFiles(claudishDir);
@@ -98529,7 +99298,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
98529
99298
  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
99299
  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
99300
  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`;
99301
+ 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
99302
  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
99303
  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
99304
  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 +99312,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
98543
99312
  padding: 0
98544
99313
  };
98545
99314
  const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
98546
- writeFileSync19(tempPath, JSON.stringify(settings, null, 2), { encoding: "utf-8", mode: 384 });
99315
+ writeFileSync20(tempPath, JSON.stringify(settings, null, 2), { encoding: "utf-8", mode: 384 });
98547
99316
  return { path: tempPath, statusLine, tokenFilePath };
98548
99317
  }
98549
99318
  function scrubChildEnv(env, opts) {
@@ -98595,7 +99364,7 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
98595
99364
  userSettings.tui = "fullscreen";
98596
99365
  }
98597
99366
  chmodSync5(tempSettingsPath, 384);
98598
- writeFileSync19(tempSettingsPath, JSON.stringify(userSettings, null, 2), {
99367
+ writeFileSync20(tempSettingsPath, JSON.stringify(userSettings, null, 2), {
98599
99368
  encoding: "utf-8",
98600
99369
  mode: 384
98601
99370
  });
@@ -98617,10 +99386,24 @@ async function resolveLocalContextWindow(spec, cachePath) {
98617
99386
  provider = plan.primary.provider;
98618
99387
  wireId = parseModelSpec(plan.primary.modelSpec).model;
98619
99388
  }
99389
+ const definition = getProviderByName(provider);
99390
+ const limit = definition?.isLocal ? contextWindowLimit() : undefined;
99391
+ const capped = (window2) => Math.min(window2, limit ?? window2);
99392
+ if (definition?.unknownContextWindow !== undefined) {
99393
+ const served = await discoverContextWindow(provider, wireId, {
99394
+ network: "bounded",
99395
+ upTo: limit ?? definition.unknownContextWindow
99396
+ });
99397
+ return {
99398
+ modelId: parsed.model,
99399
+ window: capped(served ?? limit ?? definition.unknownContextWindow)
99400
+ };
99401
+ }
98620
99402
  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" });
99403
+ const known = typeof win === "number" && win > 0 ? win : undefined;
98621
99404
  return {
98622
99405
  modelId: parsed.model,
98623
- window: typeof win === "number" && win > 0 ? win : null
99406
+ window: known !== undefined ? capped(known) : limit ?? null
98624
99407
  };
98625
99408
  }
98626
99409
  async function computeMainThreadContextWindow(config, cachePath) {
@@ -98865,6 +99648,7 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
98865
99648
  applyHostRouting(env);
98866
99649
  const realWindow = await computeMainThreadContextWindow(config);
98867
99650
  const contextEnv = resolveContextWindowEnv(realWindow, process.env);
99651
+ seedTokenFileWindow(resolveTokenFilePath(port), realWindow);
98868
99652
  Object.assign(env, contextEnv.vars);
98869
99653
  try {
98870
99654
  await Promise.resolve().then(() => init_aggregate());
@@ -98914,8 +99698,8 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
98914
99698
  console.error("Install it from: https://claude.com/claude-code");
98915
99699
  console.error(`
98916
99700
  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");
99701
+ const home = homedir40();
99702
+ const localPath = isWindows2() ? join51(home, ".claude", "local", "claude.exe") : join51(home, ".claude", "local", "claude");
98919
99703
  console.error(` export CLAUDE_PATH=${localPath}`);
98920
99704
  process.exit(1);
98921
99705
  }
@@ -98950,7 +99734,7 @@ Or set CLAUDE_PATH to your custom installation:`);
98950
99734
  let driverLaunch = null;
98951
99735
  if (surfaces.driver) {
98952
99736
  const minted = sessionFlags.sessionId || sessionFlags.resumes ? null : randomUUID8();
98953
- const turnDir = mkdtempSync3(join50(tmpdir2(), "claudish-turns-"));
99737
+ const turnDir = mkdtempSync3(join51(tmpdir2(), "claudish-turns-"));
98954
99738
  chmodSync5(turnDir, 448);
98955
99739
  claudeArgs.unshift(...driverLeadingArgs({ mintedSessionId: minted, turnDir }));
98956
99740
  const sink = new InProcessSink;
@@ -99056,7 +99840,7 @@ Or set CLAUDE_PATH to your custom installation:`);
99056
99840
  if (driverLaunch) {
99057
99841
  setProcessSink(null);
99058
99842
  try {
99059
- rmSync11(driverLaunch.turnDir, { recursive: true, force: true });
99843
+ rmSync12(driverLaunch.turnDir, { recursive: true, force: true });
99060
99844
  } catch {}
99061
99845
  }
99062
99846
  log(exitSignal ? `[Claude Code] Exited from ${exitSignal} (exit code ${exitCode})` : `[Claude Code] Exited with code ${exitCode}`);
@@ -99154,16 +99938,16 @@ async function findClaudeBinary(env = process.env) {
99154
99938
  return env.CLAUDE_PATH;
99155
99939
  }
99156
99940
  }
99157
- const home = homedir39();
99158
- const localPath = isWindows ? join50(home, ".claude", "local", "claude.exe") : join50(home, ".claude", "local", "claude");
99941
+ const home = homedir40();
99942
+ const localPath = isWindows ? join51(home, ".claude", "local", "claude.exe") : join51(home, ".claude", "local", "claude");
99159
99943
  if (existsSync36(localPath)) {
99160
99944
  return localPath;
99161
99945
  }
99162
99946
  if (isWindows) {
99163
99947
  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")
99948
+ join51(home, "AppData", "Roaming", "npm", "claude.cmd"),
99949
+ join51(home, ".npm-global", "claude.cmd"),
99950
+ join51(home, "node_modules", ".bin", "claude.cmd")
99167
99951
  ];
99168
99952
  for (const path of windowsPaths) {
99169
99953
  if (existsSync36(path)) {
@@ -99174,11 +99958,11 @@ async function findClaudeBinary(env = process.env) {
99174
99958
  const commonPaths = [
99175
99959
  "/usr/local/bin/claude",
99176
99960
  "/opt/homebrew/bin/claude",
99177
- join50(home, ".npm-global/bin/claude"),
99178
- join50(home, ".local/bin/claude"),
99179
- join50(home, "node_modules/.bin/claude"),
99961
+ join51(home, ".npm-global/bin/claude"),
99962
+ join51(home, ".local/bin/claude"),
99963
+ join51(home, "node_modules/.bin/claude"),
99180
99964
  "/data/data/com.termux/files/usr/bin/claude",
99181
- join50(home, "../usr/bin/claude")
99965
+ join51(home, "../usr/bin/claude")
99182
99966
  ];
99183
99967
  for (const path of commonPaths) {
99184
99968
  if (existsSync36(path)) {
@@ -99264,6 +100048,7 @@ var init_claude_runner = __esm(() => {
99264
100048
  init_pane_launch();
99265
100049
  init_process_tree();
99266
100050
  init_profile_config();
100051
+ init_context_window_limit();
99267
100052
  init_model_discovery();
99268
100053
  init_model_parser();
99269
100054
  init_provider_definitions();
@@ -99506,19 +100291,19 @@ var init_slot_row = __esm(() => {
99506
100291
  });
99507
100292
 
99508
100293
  // src/team-stats.ts
99509
- import { existsSync as existsSync37, readFileSync as readFileSync41, writeFileSync as writeFileSync20 } from "fs";
99510
- import { join as join51 } from "path";
100294
+ import { existsSync as existsSync37, readFileSync as readFileSync42, writeFileSync as writeFileSync21 } from "fs";
100295
+ import { join as join52 } from "path";
99511
100296
  function statsDir(sessionPath) {
99512
- return join51(sessionPath, "stats");
100297
+ return join52(sessionPath, "stats");
99513
100298
  }
99514
100299
  function tokenFileFor(sessionPath, anonId) {
99515
- return join51(statsDir(sessionPath), `${anonId}.json`);
100300
+ return join52(statsDir(sessionPath), `${anonId}.json`);
99516
100301
  }
99517
100302
  function readTokenStatsAt(path) {
99518
100303
  if (!existsSync37(path))
99519
100304
  return null;
99520
100305
  try {
99521
- return JSON.parse(readFileSync41(path, "utf-8"));
100306
+ return JSON.parse(readFileSync42(path, "utf-8"));
99522
100307
  } catch {
99523
100308
  return null;
99524
100309
  }
@@ -99675,7 +100460,7 @@ ${segs.join(" \xB7 ")}`;
99675
100460
  }
99676
100461
  function writeStatusFile(sessionPath, manifest, status, opts) {
99677
100462
  try {
99678
- writeFileSync20(join51(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
100463
+ writeFileSync21(join52(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
99679
100464
  `, "utf-8");
99680
100465
  } catch {}
99681
100466
  }
@@ -99685,11 +100470,11 @@ var init_team_stats = __esm(() => {
99685
100470
  });
99686
100471
 
99687
100472
  // src/pane/accounting.ts
99688
- import { statSync as statSync18 } from "fs";
100473
+ import { statSync as statSync19 } from "fs";
99689
100474
  function readTokenFileCached(path) {
99690
100475
  let st;
99691
100476
  try {
99692
- const s = statSync18(path);
100477
+ const s = statSync19(path);
99693
100478
  st = { mtimeMs: s.mtimeMs, size: s.size };
99694
100479
  } catch {
99695
100480
  cache2.delete(path);
@@ -99762,15 +100547,15 @@ import {
99762
100547
  accessSync as accessSync2,
99763
100548
  existsSync as existsSync38,
99764
100549
  lstatSync as lstatSync8,
99765
- readFileSync as readFileSync42,
99766
- readdirSync as readdirSync9,
99767
- renameSync as renameSync9,
99768
- rmSync as rmSync12,
99769
- rmdirSync,
100550
+ readFileSync as readFileSync43,
100551
+ readdirSync as readdirSync10,
100552
+ renameSync as renameSync10,
100553
+ rmSync as rmSync13,
100554
+ rmdirSync as rmdirSync2,
99770
100555
  unlinkSync as unlinkSync12,
99771
- writeFileSync as writeFileSync21
100556
+ writeFileSync as writeFileSync22
99772
100557
  } from "fs";
99773
- import { dirname as dirname21, join as join52 } from "path";
100558
+ import { dirname as dirname22, join as join53 } from "path";
99774
100559
  function ownerStartOfSelf() {
99775
100560
  if (ownStart)
99776
100561
  return ownStart;
@@ -99791,20 +100576,20 @@ function ownerAlive(owner, table) {
99791
100576
  return !minted || startedAt(row, minted.startMs);
99792
100577
  }
99793
100578
  function recordsDir(root) {
99794
- return join52(root, "panes");
100579
+ return join53(root, "panes");
99795
100580
  }
99796
100581
  function writeRecord(root, rec) {
99797
100582
  const p = recordPathOf(root, rec.paneId);
99798
100583
  const tmp = `${p}.tmp-${process.pid}`;
99799
- writeFileSync21(tmp, `${JSON.stringify(rec)}
100584
+ writeFileSync22(tmp, `${JSON.stringify(rec)}
99800
100585
  `, { mode: 384 });
99801
- renameSync9(tmp, p);
100586
+ renameSync10(tmp, p);
99802
100587
  }
99803
100588
  function readRecord(root, paneId) {
99804
100589
  if (!isValidPaneId(paneId))
99805
100590
  return null;
99806
100591
  try {
99807
- return validRecord(JSON.parse(readFileSync42(recordPathOf(root, paneId), "utf8")), paneId);
100592
+ return validRecord(JSON.parse(readFileSync43(recordPathOf(root, paneId), "utf8")), paneId);
99808
100593
  } catch {
99809
100594
  return null;
99810
100595
  }
@@ -99861,7 +100646,7 @@ function validForkRef(v) {
99861
100646
  function readRecords(root) {
99862
100647
  let names;
99863
100648
  try {
99864
- names = readdirSync9(recordsDir(root)).filter((n) => n.endsWith(".json"));
100649
+ names = readdirSync10(recordsDir(root)).filter((n) => n.endsWith(".json"));
99865
100650
  } catch {
99866
100651
  return [];
99867
100652
  }
@@ -99875,36 +100660,36 @@ function readRecords(root) {
99875
100660
  }
99876
100661
  function readGroupFile(ctlDir) {
99877
100662
  try {
99878
- return parseGroupFile(readFileSync42(join52(ctlDir, "group"), "utf8"));
100663
+ return parseGroupFile(readFileSync43(join53(ctlDir, "group"), "utf8"));
99879
100664
  } catch {
99880
100665
  return null;
99881
100666
  }
99882
100667
  }
99883
100668
  function writeGroupFile(ctlDir, snap) {
99884
- const p = join52(ctlDir, "group");
100669
+ const p = join53(ctlDir, "group");
99885
100670
  const tmp = `${p}.tmp`;
99886
100671
  try {
99887
- writeFileSync21(tmp, formatGroupFile(snap), { mode: 384 });
99888
- renameSync9(tmp, p);
100672
+ writeFileSync22(tmp, formatGroupFile(snap), { mode: 384 });
100673
+ renameSync10(tmp, p);
99889
100674
  } catch {}
99890
100675
  }
99891
100676
  function removeForkRecord(fork, forkUuid) {
99892
100677
  if (!isForkRecordPath(fork.projectsRoot, fork.path, forkUuid))
99893
100678
  return;
99894
100679
  try {
99895
- rmSync12(fork.path, { force: true });
100680
+ rmSync13(fork.path, { force: true });
99896
100681
  if (fork.removeProjectDir)
99897
- rmdirSync(dirname21(fork.path));
100682
+ rmdirSync2(dirname22(fork.path));
99898
100683
  } catch {}
99899
100684
  }
99900
100685
  function removePaneFiles(root, f) {
99901
100686
  if (f.fork && f.sessionUuid)
99902
100687
  removeForkRecord(f.fork, f.sessionUuid);
99903
100688
  if (isPaneSockPath(root, f.sockPath, f.paneId))
99904
- rmSync12(f.sockPath, { force: true });
100689
+ rmSync13(f.sockPath, { force: true });
99905
100690
  for (const d of [f.launcherDir, f.turnDir])
99906
100691
  if (d && isLaunchDirPath(root, d))
99907
- rmSync12(d, { recursive: true, force: true });
100692
+ rmSync13(d, { recursive: true, force: true });
99908
100693
  const rec = recordPathOf(root, f.paneId);
99909
100694
  if (isPaneRecordPath(root, rec, f.paneId))
99910
100695
  deleteRecord(root, f.paneId);
@@ -100169,11 +100954,11 @@ async function sweepRecordlessSocket(root, name, out) {
100169
100954
  const owner = ownerOfSocketId(id);
100170
100955
  if (!owner || ownerAlive(owner, table))
100171
100956
  return;
100172
- const sockPath = join52(root, name);
100957
+ const sockPath = join53(root, name);
100173
100958
  const magmuxMayLive = !table || table.some((r) => isPaneMagmuxCommand(r.command, id));
100174
100959
  const probe = await probeSocket(sockPath, magmuxMayLive);
100175
100960
  if (probe.state === "stale") {
100176
- rmSync12(sockPath, { force: true });
100961
+ rmSync13(sockPath, { force: true });
100177
100962
  out.cleaned.push(id);
100178
100963
  return;
100179
100964
  }
@@ -100199,7 +100984,7 @@ async function sweepRecordlessSocket(root, name, out) {
100199
100984
  if (mag)
100200
100985
  signal(mag.pid, "SIGKILL");
100201
100986
  await Bun.sleep(300);
100202
- rmSync12(sockPath, { force: true });
100987
+ rmSync13(sockPath, { force: true });
100203
100988
  (mag ? out.reaped : out.kept).push(id);
100204
100989
  }
100205
100990
  async function ensureSwept(root) {
@@ -100218,7 +101003,7 @@ async function sweepOrphanPanes(root = sockRootFor()) {
100218
101003
  const known = new Set(readRecords(root).map((r) => r.paneId));
100219
101004
  let names = [];
100220
101005
  try {
100221
- names = readdirSync9(root).filter((n) => /^magmux-c\d+-[A-Za-z0-9_-]+\.sock$/.test(n));
101006
+ names = readdirSync10(root).filter((n) => /^magmux-c\d+-[A-Za-z0-9_-]+\.sock$/.test(n));
100222
101007
  } catch {
100223
101008
  names = [];
100224
101009
  }
@@ -100249,19 +101034,19 @@ var init_pane_registry = __esm(() => {
100249
101034
 
100250
101035
  // src/pane/gate-binding.ts
100251
101036
  import { realpathSync as realpathSync6 } from "fs";
100252
- import { basename as basename4, dirname as dirname22, join as join53, resolve as resolve6 } from "path";
101037
+ import { basename as basename5, dirname as dirname23, join as join54, resolve as resolve6 } from "path";
100253
101038
  function normaliseTranscriptPath(p) {
100254
101039
  const abs = resolve6(p);
100255
101040
  const tail = [];
100256
101041
  let cur = abs;
100257
101042
  for (;; ) {
100258
101043
  try {
100259
- return tail.length ? join53(realpathSync6(cur), ...tail.reverse()) : realpathSync6(cur);
101044
+ return tail.length ? join54(realpathSync6(cur), ...tail.reverse()) : realpathSync6(cur);
100260
101045
  } catch {
100261
- const parent = dirname22(cur);
101046
+ const parent = dirname23(cur);
100262
101047
  if (parent === cur)
100263
101048
  return abs;
100264
- tail.push(basename4(cur));
101049
+ tail.push(basename5(cur));
100265
101050
  cur = parent;
100266
101051
  }
100267
101052
  }
@@ -100456,8 +101241,8 @@ var init_scroll_input = __esm(() => {
100456
101241
  });
100457
101242
 
100458
101243
  // src/pane/session-registry.ts
100459
- import { readFileSync as readFileSync43, readdirSync as readdirSync10 } from "fs";
100460
- import { join as join54 } from "path";
101244
+ import { readFileSync as readFileSync44, readdirSync as readdirSync11 } from "fs";
101245
+ import { join as join55 } from "path";
100461
101246
  function parseRegistryRecord(raw) {
100462
101247
  let parsed;
100463
101248
  try {
@@ -100484,7 +101269,7 @@ function parseRegistryRecord(raw) {
100484
101269
  version: typeof r.version === "string" ? r.version : null
100485
101270
  };
100486
101271
  }
100487
- function pidAlive(pid) {
101272
+ function pidAlive2(pid) {
100488
101273
  try {
100489
101274
  process.kill(pid, 0);
100490
101275
  return true;
@@ -100502,9 +101287,9 @@ class SessionRegistry {
100502
101287
  isAlive;
100503
101288
  constructor(o) {
100504
101289
  this.o = o;
100505
- this.dir = join54(o.configDir, "sessions");
101290
+ this.dir = join55(o.configDir, "sessions");
100506
101291
  this.now = o.now ?? Date.now;
100507
- this.isAlive = o.isAlive ?? pidAlive;
101292
+ this.isAlive = o.isAlive ?? pidAlive2;
100508
101293
  }
100509
101294
  read() {
100510
101295
  if (this.pid !== null) {
@@ -100519,7 +101304,7 @@ class SessionRegistry {
100519
101304
  this.lastScanAt = now;
100520
101305
  let names;
100521
101306
  try {
100522
- names = readdirSync10(this.dir);
101307
+ names = readdirSync11(this.dir);
100523
101308
  } catch {
100524
101309
  return null;
100525
101310
  }
@@ -100538,7 +101323,7 @@ class SessionRegistry {
100538
101323
  readPid(pid) {
100539
101324
  let raw;
100540
101325
  try {
100541
- raw = readFileSync43(join54(this.dir, `${pid}.json`), "utf8");
101326
+ raw = readFileSync44(join55(this.dir, `${pid}.json`), "utf8");
100542
101327
  } catch {
100543
101328
  return null;
100544
101329
  }
@@ -100651,8 +101436,8 @@ var init_slot_state = __esm(() => {
100651
101436
  });
100652
101437
 
100653
101438
  // 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";
101439
+ import { readFileSync as readFileSync45, realpathSync as realpathSync7, rmSync as rmSync14, statSync as statSync20, writeFileSync as writeFileSync23 } from "fs";
101440
+ import { join as join56 } from "path";
100656
101441
  function iso3(ms) {
100657
101442
  return new Date(ms).toISOString();
100658
101443
  }
@@ -100801,7 +101586,7 @@ class PaneSessionImpl {
100801
101586
  });
100802
101587
  this.secondaryQuietMs = o.timings?.secondaryQuietMs ?? SECONDARY_QUIET_MS;
100803
101588
  this.corroborationMs = o.timings?.corroborationMs ?? CORROBORATION_MS;
100804
- this.follower = new TranscriptFollower(o.transcriptPath, join55(o.transcriptPath.replace(/\.jsonl$/, ""), "subagents"));
101589
+ this.follower = new TranscriptFollower(o.transcriptPath, join56(o.transcriptPath.replace(/\.jsonl$/, ""), "subagents"));
100805
101590
  this.registry = new SessionRegistry({
100806
101591
  configDir: claudeConfigDir(o.parentEnv ?? process.env),
100807
101592
  sessionUuid: o.sessionUuid
@@ -100848,7 +101633,7 @@ class PaneSessionImpl {
100848
101633
  return this.spawnFailed(new Error("magmux did not start"));
100849
101634
  this.magmux = proc;
100850
101635
  try {
100851
- writeFileSync22(join55(this.ctlDir, "magmux.pid"), `${proc.pid}
101636
+ writeFileSync23(join56(this.ctlDir, "magmux.pid"), `${proc.pid}
100852
101637
  `, { mode: 384 });
100853
101638
  } catch {}
100854
101639
  updateRecord(this.root, this.paneId, { magmuxPid: proc.pid });
@@ -102596,7 +103381,7 @@ ${screenTailOf(this.screen)}`
102596
103381
  if (!p)
102597
103382
  return 0;
102598
103383
  try {
102599
- return statSync19(p).size;
103384
+ return statSync20(p).size;
102600
103385
  } catch {
102601
103386
  return 0;
102602
103387
  }
@@ -102605,7 +103390,7 @@ ${screenTailOf(this.screen)}`
102605
103390
  const p = this.errorLogPath();
102606
103391
  if (p && this.errorLogSize() > st.errorLogSize) {
102607
103392
  try {
102608
- const text = readFileSync44(p, "utf8").slice(st.errorLogSize).trim();
103393
+ const text = readFileSync45(p, "utf8").slice(st.errorLogSize).trim();
102609
103394
  return { status: null, category: "upstream_error_log", text };
102610
103395
  } catch {}
102611
103396
  }
@@ -103240,7 +104025,7 @@ function preparePane(o, root, parentEnv) {
103240
104025
  } catch (e) {
103241
104026
  for (const d of dirs ? [dirs.ctlDir, dirs.turnDir] : [])
103242
104027
  if (isLaunchDirPath(root, d))
103243
- rmSync13(d, { recursive: true, force: true });
104028
+ rmSync14(d, { recursive: true, force: true });
103244
104029
  if (e.code)
103245
104030
  throw e;
103246
104031
  throw new PaneStartError("pane_lost", e instanceof Error ? e.message : String(e));
@@ -103361,8 +104146,8 @@ var init_pane_session = __esm(() => {
103361
104146
  });
103362
104147
 
103363
104148
  // src/pane/replay-pane.ts
103364
- import { rmSync as rmSync14, writeFileSync as writeFileSync23 } from "fs";
103365
- import { join as join56 } from "path";
104149
+ import { rmSync as rmSync15, writeFileSync as writeFileSync24 } from "fs";
104150
+ import { join as join57 } from "path";
103366
104151
  async function waitUntil(pred, ms) {
103367
104152
  const end = Date.now() + ms;
103368
104153
  while (!pred() && Date.now() < end)
@@ -103471,7 +104256,7 @@ class ReplayPane {
103471
104256
  return failed(new Error("magmux did not start"));
103472
104257
  this.magmuxProc = proc;
103473
104258
  try {
103474
- writeFileSync23(join56(this.ctlDir, "magmux.pid"), `${proc.pid}
104259
+ writeFileSync24(join57(this.ctlDir, "magmux.pid"), `${proc.pid}
103475
104260
  `, { mode: 384 });
103476
104261
  } catch {}
103477
104262
  updateRecord(this.root, this.paneId, { magmuxPid: proc.pid });
@@ -103921,7 +104706,7 @@ async function startReplayPane(o) {
103921
104706
  } catch (e) {
103922
104707
  for (const d of dirs ? [dirs.ctlDir, dirs.turnDir] : [])
103923
104708
  if (isLaunchDirPath(root, d))
103924
- rmSync14(d, { recursive: true, force: true });
104709
+ rmSync15(d, { recursive: true, force: true });
103925
104710
  throw e;
103926
104711
  }
103927
104712
  const pane = new ReplayPane(o, {
@@ -104370,12 +105155,12 @@ import {
104370
105155
  lstatSync as lstatSync9,
104371
105156
  openSync as openSync15,
104372
105157
  readSync as readSync6,
104373
- readdirSync as readdirSync11,
105158
+ readdirSync as readdirSync12,
104374
105159
  readlinkSync,
104375
105160
  realpathSync as realpathSync8,
104376
- statSync as statSync20
105161
+ statSync as statSync21
104377
105162
  } from "fs";
104378
- import { basename as basename5, dirname as dirname23, join as join57, sep } from "path";
105163
+ import { basename as basename6, dirname as dirname24, join as join58, sep } from "path";
104379
105164
  function isUuid(v) {
104380
105165
  return typeof v === "string" && UUID_RE.test(v);
104381
105166
  }
@@ -104519,15 +105304,15 @@ function locateTranscriptByUuid(projectsRoot, uuid) {
104519
105304
  return null;
104520
105305
  let dirs;
104521
105306
  try {
104522
- dirs = readdirSync11(projectsRoot);
105307
+ dirs = readdirSync12(projectsRoot);
104523
105308
  } catch {
104524
105309
  return null;
104525
105310
  }
104526
105311
  let hit = null;
104527
105312
  for (const d of dirs) {
104528
- const p = join57(projectsRoot, d, `${uuid}.jsonl`);
105313
+ const p = join58(projectsRoot, d, `${uuid}.jsonl`);
104529
105314
  try {
104530
- if (!statSync20(p).isFile())
105315
+ if (!statSync21(p).isFile())
104531
105316
  continue;
104532
105317
  } catch {
104533
105318
  continue;
@@ -104555,7 +105340,7 @@ function writerLiveness(pid) {
104555
105340
  }
104556
105341
  function fileAgeMs(path, now = Date.now()) {
104557
105342
  try {
104558
- return now - statSync20(path).mtimeMs;
105343
+ return now - statSync21(path).mtimeMs;
104559
105344
  } catch {
104560
105345
  return null;
104561
105346
  }
@@ -104580,7 +105365,7 @@ function errText(e) {
104580
105365
  return e instanceof Error ? e.message : String(e);
104581
105366
  }
104582
105367
  function openContainedTranscript(path, uuid, projectsRoot) {
104583
- if (basename5(path) !== `${uuid}.jsonl`) {
105368
+ if (basename6(path) !== `${uuid}.jsonl`) {
104584
105369
  logRejection(path, "basename is not the session uuid");
104585
105370
  return null;
104586
105371
  }
@@ -104615,7 +105400,7 @@ function openContainedTranscript(path, uuid, projectsRoot) {
104615
105400
  closeQuietly(fd);
104616
105401
  return null;
104617
105402
  }
104618
- const parent = dirname23(real);
105403
+ const parent = dirname24(real);
104619
105404
  const named = lstatSync9(real);
104620
105405
  if (realpathSync8(parent) !== parent || !named.isFile() || named.dev !== st.dev || named.ino !== st.ino || !kernelPathMatches(fd, real)) {
104621
105406
  logRejection(path, "the opened file is not the one under the projects directory");
@@ -104761,8 +105546,8 @@ var init_pane = __esm(() => {
104761
105546
 
104762
105547
  // src/mcp-session/replay-manager.ts
104763
105548
  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";
105549
+ import { constants as constants6, accessSync as accessSync3, closeSync as closeSync16, existsSync as existsSync39, realpathSync as realpathSync9, statSync as statSync22 } from "fs";
105550
+ import { dirname as dirname25, resolve as resolve7 } from "path";
104766
105551
  function unavailable2(reason, message) {
104767
105552
  return new ContractErrorException("replay_unavailable", message, reason);
104768
105553
  }
@@ -104772,7 +105557,7 @@ function unknownReplay(id) {
104772
105557
  function replayCwd(own) {
104773
105558
  if (own) {
104774
105559
  try {
104775
- if (statSync21(own).isDirectory())
105560
+ if (statSync22(own).isDirectory())
104776
105561
  return realpathSync9(own);
104777
105562
  } catch {}
104778
105563
  }
@@ -104782,7 +105567,7 @@ async function replayClaudeBinary(env) {
104782
105567
  const named = env.CLAUDE_PATH ? resolve7(env.CLAUDE_PATH) : "";
104783
105568
  if (named) {
104784
105569
  try {
104785
- if (!statSync21(named).isFile())
105570
+ if (!statSync22(named).isFile())
104786
105571
  throw new Error("not a file");
104787
105572
  accessSync3(named, constants6.X_OK);
104788
105573
  } catch {
@@ -104837,8 +105622,8 @@ class ReplayManager {
104837
105622
  cwd,
104838
105623
  projectsRoot,
104839
105624
  forkPath,
104840
- removeProjectDir: !existsSync39(dirname24(forkPath)),
104841
- configDir: dirname24(projectsRoot),
105625
+ removeProjectDir: !existsSync39(dirname25(forkPath)),
105626
+ configDir: dirname25(projectsRoot),
104842
105627
  cols: size.cols ?? DEFAULT_PANE_COLS,
104843
105628
  rows: size.rows ?? DEFAULT_PANE_ROWS
104844
105629
  });
@@ -105005,15 +105790,15 @@ import { randomBytes as randomBytes16, randomUUID as randomUUID10 } from "crypto
105005
105790
  import {
105006
105791
  existsSync as existsSync40,
105007
105792
  lstatSync as lstatSync10,
105008
- mkdirSync as mkdirSync26,
105009
- readFileSync as readFileSync45,
105010
- readdirSync as readdirSync12,
105793
+ mkdirSync as mkdirSync27,
105794
+ readFileSync as readFileSync46,
105795
+ readdirSync as readdirSync13,
105011
105796
  realpathSync as realpathSync10,
105012
- rmSync as rmSync15,
105013
- statSync as statSync22,
105014
- writeFileSync as writeFileSync24
105797
+ rmSync as rmSync16,
105798
+ statSync as statSync23,
105799
+ writeFileSync as writeFileSync25
105015
105800
  } from "fs";
105016
- import { basename as basename6, dirname as dirname25, join as join58, resolve as resolve8, sep as sep2 } from "path";
105801
+ import { basename as basename7, dirname as dirname26, join as join59, resolve as resolve8, sep as sep2 } from "path";
105017
105802
  function slotTerminal(e) {
105018
105803
  if (!e.session)
105019
105804
  return true;
@@ -105082,7 +105867,7 @@ function notableAnomalies(snap) {
105082
105867
  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
105868
  }
105084
105869
  function upstreamLogPath(path, id) {
105085
- return join58(path, "errors", `${id}-upstream.jsonl`);
105870
+ return join59(path, "errors", `${id}-upstream.jsonl`);
105086
105871
  }
105087
105872
  function neverSpawnedRow(e, m) {
105088
105873
  return {
@@ -105179,9 +105964,9 @@ function teamRunRowFromDisk(path, status) {
105179
105964
  const settled = slots.length > 0 && slots.every((s) => isTerminalState(s.state));
105180
105965
  const completions = Object.values(status.models ?? {}).map((m) => m?.completedAt ? Date.parse(m.completedAt) : Number.NaN).filter(Number.isFinite);
105181
105966
  return {
105182
- run_id: status.runId ?? basename6(path),
105967
+ run_id: status.runId ?? basename7(path),
105183
105968
  path,
105184
- kind: status.kind ?? (basename6(path) === "judging" ? "judge" : "run"),
105969
+ kind: status.kind ?? (basename7(path) === "judging" ? "judge" : "run"),
105185
105970
  started_at: status.startedAt,
105186
105971
  finished_at: settled ? new Date(completions.length ? Math.max(...completions) : statusMtimeMs(path) ?? Date.parse(status.startedAt)).toISOString() : null,
105187
105972
  state: settled ? "SETTLED" : "ACTIVE",
@@ -105191,14 +105976,14 @@ function teamRunRowFromDisk(path, status) {
105191
105976
  }
105192
105977
  function statusMtimeMs(path) {
105193
105978
  try {
105194
- return statSync22(join58(path, "status.json")).mtimeMs;
105979
+ return statSync23(join59(path, "status.json")).mtimeMs;
105195
105980
  } catch {
105196
105981
  return null;
105197
105982
  }
105198
105983
  }
105199
105984
  function readManifestOrNull(path) {
105200
105985
  try {
105201
- return JSON.parse(readFileSync45(join58(path, "manifest.json"), "utf-8"));
105986
+ return JSON.parse(readFileSync46(join59(path, "manifest.json"), "utf-8"));
105202
105987
  } catch {
105203
105988
  return null;
105204
105989
  }
@@ -105321,7 +106106,7 @@ function teamSlotTranscriptSource(path, slot, runId, opts) {
105321
106106
  }
105322
106107
  if (!status || typeof status !== "object" || !status.models || typeof status.models !== "object")
105323
106108
  throw unknownRun(path, runId);
105324
- const fileRunId = typeof status.runId === "string" && status.runId ? status.runId : basename6(resolved);
106109
+ const fileRunId = typeof status.runId === "string" && status.runId ? status.runId : basename7(resolved);
105325
106110
  if (runId !== undefined && runId !== fileRunId)
105326
106111
  throw unknownRun(path, runId);
105327
106112
  const m = Object.hasOwn(status.models, slot) ? status.models[slot] : undefined;
@@ -105486,12 +106271,12 @@ function readWrittenFile(path, root) {
105486
106271
  if (real !== realRoot && !real.startsWith(realRoot + sep2))
105487
106272
  return { skip: "outside the working directory" };
105488
106273
  try {
105489
- const st = statSync22(real);
106274
+ const st = statSync23(real);
105490
106275
  if (!st.isFile())
105491
106276
  return { skip: "not a regular file" };
105492
106277
  if (st.size > MAX_FILE_ANSWER_BYTES)
105493
106278
  return { skip: "larger than 1 MiB" };
105494
- const buf = readFileSync45(real);
106279
+ const buf = readFileSync46(real);
105495
106280
  if (buf.includes(0))
105496
106281
  return { skip: "binary" };
105497
106282
  return { text: buf.toString("utf8") };
@@ -105528,7 +106313,7 @@ function persistErrorLog(errorLogPath, header, sections) {
105528
106313
  parts.push(`--- ${title} ---`, body.trim() ? redactSecrets(body) : "(empty)", "");
105529
106314
  }
105530
106315
  try {
105531
- writeFileSync24(errorLogPath, parts.join(`
106316
+ writeFileSync25(errorLogPath, parts.join(`
105532
106317
  `), "utf-8");
105533
106318
  } catch {}
105534
106319
  }
@@ -105542,16 +106327,16 @@ function validateSessionPath(sessionPath) {
105542
106327
  lstatSync10(existing);
105543
106328
  break;
105544
106329
  } catch {
105545
- const parent = dirname25(existing);
106330
+ const parent = dirname26(existing);
105546
106331
  if (parent === existing)
105547
106332
  break;
105548
- tail.unshift(basename6(existing));
106333
+ tail.unshift(basename7(existing));
105549
106334
  existing = parent;
105550
106335
  }
105551
106336
  }
105552
106337
  let real;
105553
106338
  try {
105554
- real = join58(realpathSync10(existing), ...tail);
106339
+ real = join59(realpathSync10(existing), ...tail);
105555
106340
  } catch {
105556
106341
  throw outside();
105557
106342
  }
@@ -105570,7 +106355,7 @@ function readTeamInputFile(inputPath) {
105570
106355
  if (!existsSync40(resolved)) {
105571
106356
  throw new Error(`Input file not found: ${resolved}`);
105572
106357
  }
105573
- const text = readFileSync45(resolved, "utf-8");
106358
+ const text = readFileSync46(resolved, "utf-8");
105574
106359
  if (text.trim().length === 0) {
105575
106360
  throw new Error(`Input file is empty: ${resolved}`);
105576
106361
  }
@@ -105580,14 +106365,14 @@ function setupSession(sessionPath, models, input) {
105580
106365
  if (models.length === 0) {
105581
106366
  throw new Error("At least one model is required");
105582
106367
  }
105583
- if (existsSync40(join58(sessionPath, "manifest.json"))) {
106368
+ if (existsSync40(join59(sessionPath, "manifest.json"))) {
105584
106369
  throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
105585
106370
  }
105586
- mkdirSync26(join58(sessionPath, "work"), { recursive: true });
105587
- mkdirSync26(join58(sessionPath, "errors"), { recursive: true });
106371
+ mkdirSync27(join59(sessionPath, "work"), { recursive: true });
106372
+ mkdirSync27(join59(sessionPath, "errors"), { recursive: true });
105588
106373
  if (input !== undefined) {
105589
- writeFileSync24(join58(sessionPath, "input.md"), input, "utf-8");
105590
- } else if (!existsSync40(join58(sessionPath, "input.md"))) {
106374
+ writeFileSync25(join59(sessionPath, "input.md"), input, "utf-8");
106375
+ } else if (!existsSync40(join59(sessionPath, "input.md"))) {
105591
106376
  throw new Error(`No input.md found at ${sessionPath} and no input provided`);
105592
106377
  }
105593
106378
  const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
@@ -105604,9 +106389,9 @@ function setupSession(sessionPath, models, input) {
105604
106389
  model: models[i],
105605
106390
  assignedAt: now
105606
106391
  };
105607
- mkdirSync26(join58(sessionPath, "work", anonId), { recursive: true });
106392
+ mkdirSync27(join59(sessionPath, "work", anonId), { recursive: true });
105608
106393
  }
105609
- writeFileSync24(join58(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
106394
+ writeFileSync25(join59(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
105610
106395
  const status = {
105611
106396
  startedAt: now,
105612
106397
  models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
@@ -105621,7 +106406,7 @@ function setupSession(sessionPath, models, input) {
105621
106406
  }
105622
106407
  ]))
105623
106408
  };
105624
- writeFileAtomic(join58(sessionPath, "status.json"), JSON.stringify(status, null, 2));
106409
+ writeFileAtomic(join59(sessionPath, "status.json"), JSON.stringify(status, null, 2));
105625
106410
  return manifest;
105626
106411
  }
105627
106412
  function assertValidRequirePattern(pattern) {
@@ -105656,7 +106441,7 @@ async function preflightTeamRun(opts) {
105656
106441
  throw new Error(`pane_limit: ${live} live panes for this user, ${opts.slots} more would exceed ${MAX_LIVE_PANES}`);
105657
106442
  }
105658
106443
  function mintRunId(path, startMs) {
105659
- return `${basename6(path)}-${startMs.toString(36)}-${randomBytes16(3).toString("hex")}`;
106444
+ return `${basename7(path)}-${startMs.toString(36)}-${randomBytes16(3).toString("hex")}`;
105660
106445
  }
105661
106446
  function startModels(sessionPath, opts = {}) {
105662
106447
  const flight = { aborted: false };
@@ -105682,9 +106467,9 @@ async function startModelsIn(flight, sessionPath, opts) {
105682
106467
  throw new Error(`invalid_args: ${flagCheck.message}`);
105683
106468
  const agentRequested = requestedAgentOf(claudeFlags);
105684
106469
  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");
106470
+ const manifest = JSON.parse(readFileSync46(join59(path, "manifest.json"), "utf-8"));
106471
+ const statusPath = join59(path, "status.json");
106472
+ const inputContent = readFileSync46(join59(path, "input.md"), "utf-8");
105688
106473
  const readAvailable = !flagsRemoveRead(claudeFlags);
105689
106474
  const refusal = deliveryRefusal(inputContent, readAvailable);
105690
106475
  if (refusal)
@@ -105695,7 +106480,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105695
106480
  const hookEngine = await (opts.hookEngine ?? (() => loadHooksOnce()))().catch(() => null);
105696
106481
  const spawnPlan = await (opts.spawnPlanner ?? prehydrateCredentialsForSpawn)(Object.values(manifest.models).map((m) => m.model));
105697
106482
  await assertMagmuxAvailable();
105698
- const statusCache = JSON.parse(readFileSync45(statusPath, "utf-8"));
106483
+ const statusCache = JSON.parse(readFileSync46(statusPath, "utf-8"));
105699
106484
  const startMs = Date.now();
105700
106485
  const runId = mintRunId(path, startMs);
105701
106486
  statusCache.runId = runId;
@@ -105721,10 +106506,10 @@ async function startModelsIn(flight, sessionPath, opts) {
105721
106506
  const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
105722
106507
  const requirePattern = opts.requirePattern;
105723
106508
  const cwd = opts.cwd ?? process.cwd();
105724
- mkdirSync26(statsDir(path), { recursive: true });
106509
+ mkdirSync27(statsDir(path), { recursive: true });
105725
106510
  const entries = new Map;
105726
106511
  let run = null;
105727
- const errorLogPathOf = (id) => join58(path, "errors", `${id}.log`);
106512
+ const errorLogPathOf = (id) => join59(path, "errors", `${id}.log`);
105728
106513
  const upstreamLogOf = (id) => upstreamLogPath(path, id);
105729
106514
  const flagsOf = (e) => {
105730
106515
  const effort = opts.efforts?.[e.model];
@@ -105734,7 +106519,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105734
106519
  function writeResponse(e, text) {
105735
106520
  e.answer = text;
105736
106521
  try {
105737
- writeFileSync24(join58(path, `response-${e.id}.md`), text, "utf-8");
106522
+ writeFileSync25(join59(path, `response-${e.id}.md`), text, "utf-8");
105738
106523
  } catch (err) {
105739
106524
  persistErrorLog(errorLogPathOf(e.id), `response file not written: ${String(err)}`, []);
105740
106525
  }
@@ -105744,7 +106529,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105744
106529
  if (e.answer !== null || !e.session)
105745
106530
  return;
105746
106531
  try {
105747
- writeFileSync24(join58(path, `response-${e.id}.md`), e.session.chainText(), "utf-8");
106532
+ writeFileSync25(join59(path, `response-${e.id}.md`), e.session.chainText(), "utf-8");
105748
106533
  } catch (err) {
105749
106534
  persistErrorLog(errorLogPathOf(e.id), `response file not written: ${String(err)}`, []);
105750
106535
  }
@@ -105941,7 +106726,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105941
106726
  }
105942
106727
  async function startSlot(e, uuid, transcriptPath) {
105943
106728
  let session;
105944
- e.inboxPath = createHookInbox(join58(path, "work"), `${e.id}.hook-inbox.jsonl`);
106729
+ e.inboxPath = createHookInbox(join59(path, "work"), `${e.id}.hook-inbox.jsonl`);
105945
106730
  const binding = bindingFor(e, uuid);
105946
106731
  e.binding = binding;
105947
106732
  try {
@@ -105996,7 +106781,7 @@ async function startModelsIn(flight, sessionPath, opts) {
105996
106781
  if (!e.inboxPath)
105997
106782
  return;
105998
106783
  try {
105999
- rmSync15(e.inboxPath, { force: true });
106784
+ rmSync16(e.inboxPath, { force: true });
106000
106785
  } catch {}
106001
106786
  }
106002
106787
  const slotIds = Object.keys(manifest.models);
@@ -106161,7 +106946,7 @@ async function startModelsIn(flight, sessionPath, opts) {
106161
106946
  done.catch((err) => log(`[team] run failed at ${path}: ${err instanceof Error ? err.message : String(err)}`));
106162
106947
  return {
106163
106948
  runId,
106164
- teamSessionId: basename6(path),
106949
+ teamSessionId: basename7(path),
106165
106950
  sessionPath: path,
106166
106951
  slots: Object.fromEntries(Object.entries(manifest.models).map(([anonId, entry]) => [entry.model, anonId])),
106167
106952
  done
@@ -106175,21 +106960,21 @@ async function judgeResponses(sessionPath, opts = {}) {
106175
106960
  const active = activeRunAt(resolve8(sessionPath));
106176
106961
  if (active)
106177
106962
  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();
106963
+ const responseFiles = readdirSync13(sessionPath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
106179
106964
  if (responseFiles.length < 2) {
106180
106965
  throw new Error(`Need at least 2 responses to judge, found ${responseFiles.length}`);
106181
106966
  }
106182
106967
  const responses = {};
106183
106968
  for (const file of responseFiles) {
106184
106969
  const id = file.replace(/^response-/, "").replace(/\.md$/, "");
106185
- responses[id] = readFileSync45(join58(sessionPath, file), "utf-8");
106970
+ responses[id] = readFileSync46(join59(sessionPath, file), "utf-8");
106186
106971
  }
106187
- const input = readFileSync45(join58(sessionPath, "input.md"), "utf-8");
106972
+ const input = readFileSync46(join59(sessionPath, "input.md"), "utf-8");
106188
106973
  const judgePrompt = buildJudgePrompt(input, responses);
106189
- writeFileSync24(join58(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
106974
+ writeFileSync25(join59(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
106190
106975
  const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
106191
- const judgePath = join58(sessionPath, "judging");
106192
- mkdirSync26(judgePath, { recursive: true });
106976
+ const judgePath = join59(sessionPath, "judging");
106977
+ mkdirSync27(judgePath, { recursive: true });
106193
106978
  setupSession(judgePath, judgeModels, judgePrompt);
106194
106979
  await runModels(judgePath, {
106195
106980
  claudeFlags: opts.claudeFlags,
@@ -106200,11 +106985,11 @@ async function judgeResponses(sessionPath, opts = {}) {
106200
106985
  });
106201
106986
  const votes = parseJudgeVotes(judgePath, Object.keys(responses));
106202
106987
  const verdict = aggregateVerdict(votes, Object.keys(responses));
106203
- writeFileSync24(join58(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
106988
+ writeFileSync25(join59(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
106204
106989
  return verdict;
106205
106990
  }
106206
106991
  function getStatus(sessionPath) {
106207
- return JSON.parse(readFileSync45(join58(sessionPath, "status.json"), "utf-8"));
106992
+ return JSON.parse(readFileSync46(join59(sessionPath, "status.json"), "utf-8"));
106208
106993
  }
106209
106994
  function readTeamStatus(sessionPath) {
106210
106995
  try {
@@ -106244,7 +107029,7 @@ function fisherYatesShuffle(arr) {
106244
107029
  return arr;
106245
107030
  }
106246
107031
  function getDefaultJudgeModels(sessionPath) {
106247
- const manifest = JSON.parse(readFileSync45(join58(sessionPath, "manifest.json"), "utf-8"));
107032
+ const manifest = JSON.parse(readFileSync46(join59(sessionPath, "manifest.json"), "utf-8"));
106248
107033
  return Object.values(manifest.models).map((e) => e.model);
106249
107034
  }
106250
107035
  function buildJudgePrompt(input, responses) {
@@ -106302,12 +107087,12 @@ function buildJudgePrompt(input, responses) {
106302
107087
  }
106303
107088
  function parseJudgeVotes(judgePath, responseIds) {
106304
107089
  const votes = [];
106305
- const responseFiles = readdirSync12(judgePath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
107090
+ const responseFiles = readdirSync13(judgePath).filter((f) => f.startsWith("response-") && f.endsWith(".md")).sort();
106306
107091
  for (const file of responseFiles) {
106307
107092
  const judgeId = file.replace(/^response-/, "").replace(/\.md$/, "");
106308
107093
  let content;
106309
107094
  try {
106310
- content = readFileSync45(join58(judgePath, file), "utf-8");
107095
+ content = readFileSync46(join59(judgePath, file), "utf-8");
106311
107096
  } catch (err) {
106312
107097
  log(`[team] judge answer ${file} unreadable: ${err instanceof Error ? err.message : String(err)}`);
106313
107098
  continue;
@@ -106360,7 +107145,7 @@ function aggregateVerdict(votes, responseIds) {
106360
107145
  function formatVerdict(verdict, sessionPath) {
106361
107146
  let manifest = null;
106362
107147
  try {
106363
- manifest = JSON.parse(readFileSync45(join58(sessionPath, "manifest.json"), "utf-8"));
107148
+ manifest = JSON.parse(readFileSync46(join59(sessionPath, "manifest.json"), "utf-8"));
106364
107149
  } catch {}
106365
107150
  let output = `# Team Verdict
106366
107151
 
@@ -106416,8 +107201,8 @@ var init_team_orchestrator = __esm(() => {
106416
107201
  });
106417
107202
 
106418
107203
  // 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";
107204
+ import { existsSync as existsSync41, readFileSync as readFileSync47, statSync as statSync24 } from "fs";
107205
+ import { join as join60, resolve as resolve9 } from "path";
106421
107206
  function isPlainObject7(value) {
106422
107207
  return typeof value === "object" && value !== null && !Array.isArray(value);
106423
107208
  }
@@ -106462,7 +107247,7 @@ function readSettingsValue(value) {
106462
107247
  return parseLayer(value, value);
106463
107248
  let text;
106464
107249
  try {
106465
- text = readFileSync46(value, "utf-8");
107250
+ text = readFileSync47(value, "utf-8");
106466
107251
  } catch (err) {
106467
107252
  throw new Error(`invalid_args: settings ${value} cannot be read (${err.message})`);
106468
107253
  }
@@ -106471,10 +107256,10 @@ function readSettingsValue(value) {
106471
107256
  function buildInheritedSettingsLayer(setupFrom, callerFlags) {
106472
107257
  const layers = [];
106473
107258
  for (const name of ["settings.json", "settings.local.json"]) {
106474
- const file = join59(setupFrom, ".claude", name);
107259
+ const file = join60(setupFrom, ".claude", name);
106475
107260
  if (!existsSync41(file))
106476
107261
  continue;
106477
- layers.push(parseLayer(readFileSync46(file, "utf-8"), file));
107262
+ layers.push(parseLayer(readFileSync47(file, "utf-8"), file));
106478
107263
  }
106479
107264
  const restFlags = [];
106480
107265
  for (let i = 0;i < callerFlags.length; i++) {
@@ -106504,7 +107289,7 @@ function resolveSetupFrom(arg, workDir, serverCwd) {
106504
107289
  let setupFrom = serverCwd;
106505
107290
  if (typeof arg === "string") {
106506
107291
  setupFrom = resolve9(arg);
106507
- if (!statSync23(setupFrom, { throwIfNoEntry: false })?.isDirectory()) {
107292
+ if (!statSync24(setupFrom, { throwIfNoEntry: false })?.isDirectory()) {
106508
107293
  throw new Error(`invalid_args: setup_from ${setupFrom} is not an existing directory`);
106509
107294
  }
106510
107295
  } else if (arg !== undefined) {
@@ -106521,16 +107306,16 @@ import {
106521
107306
  closeSync as closeSync17,
106522
107307
  createWriteStream,
106523
107308
  existsSync as existsSync42,
106524
- mkdirSync as mkdirSync27,
107309
+ mkdirSync as mkdirSync28,
106525
107310
  openSync as openSync16,
106526
- readFileSync as readFileSync47,
107311
+ readFileSync as readFileSync48,
106527
107312
  readSync as readSync7,
106528
- renameSync as renameSync10,
106529
- rmSync as rmSync16,
106530
- statSync as statSync24,
106531
- writeFileSync as writeFileSync25
107313
+ renameSync as renameSync11,
107314
+ rmSync as rmSync17,
107315
+ statSync as statSync25,
107316
+ writeFileSync as writeFileSync26
106532
107317
  } from "fs";
106533
- import { join as join60, resolve as resolve10, sep as sep3 } from "path";
107318
+ import { join as join61, resolve as resolve10, sep as sep3 } from "path";
106534
107319
  function normaliseTimeoutSeconds(raw) {
106535
107320
  const n = typeof raw === "string" && raw.trim() !== "" ? Number(raw) : raw;
106536
107321
  if (typeof n !== "number" || !Number.isFinite(n))
@@ -106624,8 +107409,8 @@ function toMetaRecord(info, cwd) {
106624
107409
  }
106625
107410
  function writeJsonAtomic(path, value) {
106626
107411
  const tmp = `${path}.tmp`;
106627
- writeFileSync25(tmp, JSON.stringify(value, null, 2), "utf-8");
106628
- renameSync10(tmp, path);
107412
+ writeFileSync26(tmp, JSON.stringify(value, null, 2), "utf-8");
107413
+ renameSync11(tmp, path);
106629
107414
  }
106630
107415
  function anomalyKey(a) {
106631
107416
  const at = a.lastIndexOf(" \xD7");
@@ -106634,7 +107419,7 @@ function anomalyKey(a) {
106634
107419
  function readTailText(path, maxBytes) {
106635
107420
  let fd = null;
106636
107421
  try {
106637
- const size = statSync24(path).size;
107422
+ const size = statSync25(path).size;
106638
107423
  if (size === 0)
106639
107424
  return { text: "", truncated: false };
106640
107425
  const start = Math.max(0, size - maxBytes);
@@ -106665,7 +107450,7 @@ function readTailLines2(path, maxBytes) {
106665
107450
  }
106666
107451
  function fileSize2(path) {
106667
107452
  try {
106668
- return statSync24(path).size;
107453
+ return statSync25(path).size;
106669
107454
  } catch {
106670
107455
  return 0;
106671
107456
  }
@@ -106674,7 +107459,7 @@ function readJsonObject(path, maxBytes) {
106674
107459
  try {
106675
107460
  if (fileSize2(path) > maxBytes)
106676
107461
  return null;
106677
- const parsed = JSON.parse(readFileSync47(path, "utf-8"));
107462
+ const parsed = JSON.parse(readFileSync48(path, "utf-8"));
106678
107463
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
106679
107464
  return null;
106680
107465
  return parsed;
@@ -106700,7 +107485,7 @@ function dropLeadingFragment(tail) {
106700
107485
  return firstBreak === -1 ? tail.text : tail.text.slice(firstBreak + 1);
106701
107486
  }
106702
107487
  function diskAccounting(sessionDir) {
106703
- const stats = readTokenStatsAt(join60(sessionDir, "tokens.json"));
107488
+ const stats = readTokenStatsAt(join61(sessionDir, "tokens.json"));
106704
107489
  return {
106705
107490
  tokensIn: stats?.billed_input_tokens ?? null,
106706
107491
  tokensOut: stats?.output_tokens ?? null,
@@ -106780,14 +107565,14 @@ class SessionManager {
106780
107565
  return this._launcherPid;
106781
107566
  }
106782
107567
  recordTeamRun(opts) {
106783
- mkdirSync27(this.sessionsDir, { recursive: true });
107568
+ mkdirSync28(this.sessionsDir, { recursive: true });
106784
107569
  let id = "";
106785
107570
  let dir = "";
106786
107571
  for (let attempt = 0;; attempt++) {
106787
107572
  id = `team-${randomUUID11().replace(/-/g, "").slice(0, 8)}`;
106788
- dir = join60(this.sessionsDir, id);
107573
+ dir = join61(this.sessionsDir, id);
106789
107574
  try {
106790
- mkdirSync27(dir);
107575
+ mkdirSync28(dir);
106791
107576
  break;
106792
107577
  } catch (err) {
106793
107578
  if (err?.code !== "EEXIST" || attempt >= 4)
@@ -106817,9 +107602,9 @@ class SessionManager {
106817
107602
  if (dir === null)
106818
107603
  throw new Error("not a record id");
106819
107604
  const completedAt = new Date().toISOString();
106820
- const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(join60(dir, "spawn.json"), META_READ_LIMIT)?.startedAt) ?? completedAt;
107605
+ const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(join61(dir, "spawn.json"), META_READ_LIMIT)?.startedAt) ?? completedAt;
106821
107606
  const elapsedMs = Date.parse(completedAt) - Date.parse(startedAt);
106822
- writeJsonAtomic(join60(dir, "meta.json"), {
107607
+ writeJsonAtomic(join61(dir, "meta.json"), {
106823
107608
  kind: "team",
106824
107609
  status: outcome.status,
106825
107610
  startedAt,
@@ -106851,7 +107636,7 @@ class SessionManager {
106851
107636
  startedAt,
106852
107637
  ...rest
106853
107638
  };
106854
- writeJsonAtomic(join60(dir, "spawn.json"), body);
107639
+ writeJsonAtomic(join61(dir, "spawn.json"), body);
106855
107640
  }
106856
107641
  async createSession(opts) {
106857
107642
  if (this.activeSessions + this.starting >= this.maxSessions) {
@@ -106891,7 +107676,7 @@ class SessionManager {
106891
107676
  throw err;
106892
107677
  }
106893
107678
  if (inherited.layer) {
106894
- flags = [...inherited.restFlags, "--settings", join60(entry.sessionDir, INHERITED_SETTINGS)];
107679
+ flags = [...inherited.restFlags, "--settings", join61(entry.sessionDir, INHERITED_SETTINGS)];
106895
107680
  }
106896
107681
  this.sessions.set(entry.info.sessionId, entry);
106897
107682
  uncount();
@@ -106916,10 +107701,10 @@ class SessionManager {
106916
107701
  const timeout = normaliseTimeoutSeconds(opts.timeoutSeconds);
106917
107702
  const agentRequested = requestedAgentOf(opts.claudishFlags ?? []);
106918
107703
  const startedAt = new Date().toISOString();
106919
- const sessionDir = opts.sessionDir ?? join60(this.sessionsDir, sessionId);
106920
- mkdirSync27(sessionDir, { recursive: true });
107704
+ const sessionDir = opts.sessionDir ?? join61(this.sessionsDir, sessionId);
107705
+ mkdirSync28(sessionDir, { recursive: true });
106921
107706
  if (opts.prompt)
106922
- writeFileSync25(join60(sessionDir, "prompt.md"), opts.prompt, "utf-8");
107707
+ writeFileSync26(join61(sessionDir, "prompt.md"), opts.prompt, "utf-8");
106923
107708
  this.writeSpawnRecord(sessionDir, {
106924
107709
  kind: "session",
106925
107710
  sessionId,
@@ -106932,13 +107717,13 @@ class SessionManager {
106932
107717
  ...agentRequested ? { agentRequested } : {}
106933
107718
  });
106934
107719
  if (inheritedLayer) {
106935
- writeFileSync25(join60(sessionDir, INHERITED_SETTINGS), `${JSON.stringify(inheritedLayer, null, 2)}
107720
+ writeFileSync26(join61(sessionDir, INHERITED_SETTINGS), `${JSON.stringify(inheritedLayer, null, 2)}
106936
107721
  `, { encoding: "utf-8", mode: 384 });
106937
107722
  }
106938
107723
  const cwd = opts.cwd ?? process.cwd();
106939
107724
  const parentEnv = opts.parentEnv ?? this.parentEnv;
106940
107725
  const spawnModel = opts.spawnModel ?? null;
106941
- const tokenFile = opts.tokenFile ?? join60(sessionDir, "tokens.json");
107726
+ const tokenFile = opts.tokenFile ?? join61(sessionDir, "tokens.json");
106942
107727
  return {
106943
107728
  info: {
106944
107729
  sessionId,
@@ -106976,18 +107761,18 @@ class SessionManager {
106976
107761
  },
106977
107762
  session: null,
106978
107763
  scrollback: new ScrollbackBuffer(this.scrollbackCapacity),
106979
- outputLogStream: createWriteStream(join60(sessionDir, "output.log")),
107764
+ outputLogStream: createWriteStream(join61(sessionDir, "output.log")),
106980
107765
  sessionDir,
106981
107766
  cwd,
106982
107767
  tokenFile,
106983
- eventLogPath: join60(sessionDir, "events.jsonl"),
107768
+ eventLogPath: join61(sessionDir, "events.jsonl"),
106984
107769
  eventLogBytes: 0,
106985
- upstreamErrorLogPath: join60(sessionDir, "upstream-errors.jsonl"),
107770
+ upstreamErrorLogPath: join61(sessionDir, "upstream-errors.jsonl"),
106986
107771
  eventRing: [],
106987
107772
  proseBytes: 0,
106988
107773
  answeredTurns: new Map,
106989
107774
  inboxPath: null,
106990
- waitLogPath: join60(sessionDir, "waits.jsonl"),
107775
+ waitLogPath: join61(sessionDir, "waits.jsonl"),
106991
107776
  waitLogBytes: 0,
106992
107777
  waitSince: null,
106993
107778
  ended: false,
@@ -107089,7 +107874,7 @@ class SessionManager {
107089
107874
  if (!entry.inboxPath)
107090
107875
  return;
107091
107876
  try {
107092
- rmSync16(entry.inboxPath, { force: true });
107877
+ rmSync17(entry.inboxPath, { force: true });
107093
107878
  } catch {}
107094
107879
  }
107095
107880
  failNeverSpawned(entry, err) {
@@ -107182,7 +107967,7 @@ class SessionManager {
107182
107967
  try {
107183
107968
  const text = screenLines.join(`
107184
107969
  `).replace(/\s+$/, "");
107185
- writeFileSync25(join60(entry.sessionDir, "screen.txt"), `${redactSecrets(text)}
107970
+ writeFileSync26(join61(entry.sessionDir, "screen.txt"), `${redactSecrets(text)}
107186
107971
  `, "utf-8");
107187
107972
  } catch {}
107188
107973
  }
@@ -107196,7 +107981,7 @@ class SessionManager {
107196
107981
  entry.waitSince = null;
107197
107982
  }
107198
107983
  try {
107199
- writeJsonAtomic(join60(entry.sessionDir, "meta.json"), toMetaRecord(entry.info, entry.cwd));
107984
+ writeJsonAtomic(join61(entry.sessionDir, "meta.json"), toMetaRecord(entry.info, entry.cwd));
107200
107985
  } catch (err) {
107201
107986
  process.stderr.write(`[claudish] session ${entry.info.sessionId}: could not write meta.json: ` + `${err instanceof Error ? err.message : String(err)}
107202
107987
  `);
@@ -107448,13 +108233,13 @@ class SessionManager {
107448
108233
  if (sessionDir === null)
107449
108234
  return null;
107450
108235
  try {
107451
- if (!statSync24(sessionDir).isDirectory())
108236
+ if (!statSync25(sessionDir).isDirectory())
107452
108237
  return null;
107453
108238
  } catch {
107454
108239
  return null;
107455
108240
  }
107456
- const spawnPath = join60(sessionDir, "spawn.json");
107457
- const metaPath = join60(sessionDir, "meta.json");
108241
+ const spawnPath = join61(sessionDir, "spawn.json");
108242
+ const metaPath = join61(sessionDir, "meta.json");
107458
108243
  const spawnRecord = readJsonObject(spawnPath, META_READ_LIMIT);
107459
108244
  if (spawnRecord?.kind === "team")
107460
108245
  return null;
@@ -107548,7 +108333,7 @@ class SessionManager {
107548
108333
  return null;
107549
108334
  const root = resolve10(this.sessionsDir);
107550
108335
  const dir = resolve10(root, sessionId);
107551
- if (dir !== join60(root, sessionId))
108336
+ if (dir !== join61(root, sessionId))
107552
108337
  return null;
107553
108338
  if (!dir.startsWith(root + sep3))
107554
108339
  return null;
@@ -107560,17 +108345,17 @@ class SessionManager {
107560
108345
  return null;
107561
108346
  let dirMtimeMs;
107562
108347
  try {
107563
- const stat = statSync24(sessionDir);
108348
+ const stat = statSync25(sessionDir);
107564
108349
  if (!stat.isDirectory())
107565
108350
  return null;
107566
108351
  dirMtimeMs = stat.mtimeMs;
107567
108352
  } catch {
107568
108353
  return null;
107569
108354
  }
107570
- const spawnRecord = readJsonObject(join60(sessionDir, "spawn.json"), META_READ_LIMIT);
108355
+ const spawnRecord = readJsonObject(join61(sessionDir, "spawn.json"), META_READ_LIMIT);
107571
108356
  if (spawnRecord?.kind === "team")
107572
108357
  return null;
107573
- const meta = readJsonObject(join60(sessionDir, "meta.json"), META_READ_LIMIT);
108358
+ const meta = readJsonObject(join61(sessionDir, "meta.json"), META_READ_LIMIT);
107574
108359
  if (meta?.kind === "team")
107575
108360
  return null;
107576
108361
  const partial = meta === null;
@@ -107592,7 +108377,7 @@ class SessionManager {
107592
108377
  return stored;
107593
108378
  }
107594
108379
  diskOutput(record, tailLines) {
107595
- const tail = readTailText(join60(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
108380
+ const tail = readTailText(join61(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
107596
108381
  const buffer = new ScrollbackBuffer(this.scrollbackCapacity);
107597
108382
  if (tail?.text)
107598
108383
  buffer.append(dropLeadingFragment(tail));
@@ -107612,12 +108397,12 @@ class SessionManager {
107612
108397
  }
107613
108398
  diskDiagnostics(record, limit) {
107614
108399
  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");
108400
+ const eventLogPath = join61(sessionDir, "events.jsonl");
108401
+ const upstreamErrorLogPath = join61(sessionDir, "upstream-errors.jsonl");
108402
+ const outputLogPath = join61(sessionDir, "output.log");
107618
108403
  const events = readTailLines2(eventLogPath, EVENT_TAIL_BYTES);
107619
108404
  const outputTail = readTailText(outputLogPath, OUTPUT_TAIL_BYTES);
107620
- const screen = readTailText(join60(sessionDir, "screen.txt"), SCREEN_READ_BYTES);
108405
+ const screen = readTailText(join61(sessionDir, "screen.txt"), SCREEN_READ_BYTES);
107621
108406
  return {
107622
108407
  sessionId: info.sessionId,
107623
108408
  state: info.state,
@@ -108022,9 +108807,9 @@ var init_progress_heartbeat = __esm(() => {
108022
108807
 
108023
108808
  // src/mcp/run-prompt-claude-code.ts
108024
108809
  import { spawn as spawn3 } from "child_process";
108025
- import { mkdirSync as mkdirSync28, mkdtempSync as mkdtempSync4, rmSync as rmSync17, writeFileSync as writeFileSync26 } from "fs";
108810
+ import { mkdirSync as mkdirSync29, mkdtempSync as mkdtempSync4, rmSync as rmSync18, writeFileSync as writeFileSync27 } from "fs";
108026
108811
  import { tmpdir as tmpdir3 } from "os";
108027
- import { join as join61 } from "path";
108812
+ import { join as join62 } from "path";
108028
108813
  function claudeCodePrintArgv(model, systemPromptFile) {
108029
108814
  const head = [PRINT_FLAGS[0], "--model", model, ...PRINT_FLAGS.slice(1)];
108030
108815
  return systemPromptFile !== undefined ? [...head, "--system-prompt-file", systemPromptFile] : [...head, "--system-prompt", ""];
@@ -108144,14 +108929,14 @@ async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
108144
108929
  } catch (e) {
108145
108930
  throw new Error(`cannot start claudish (${parentEnv.CLAUDISH_BIN?.trim() || "claudish"}): ${e instanceof Error ? e.message : String(e)}`);
108146
108931
  }
108147
- const root = mkdtempSync4(join61(tmpdir3(), "claudish-run-prompt-"));
108932
+ const root = mkdtempSync4(join62(tmpdir3(), "claudish-run-prompt-"));
108148
108933
  try {
108149
- const cwd = join61(root, "cwd");
108150
- mkdirSync28(cwd, { mode: 448 });
108934
+ const cwd = join62(root, "cwd");
108935
+ mkdirSync29(cwd, { mode: 448 });
108151
108936
  let systemPromptFile;
108152
108937
  if (typeof systemPrompt === "string" && systemPrompt.length > 0) {
108153
- systemPromptFile = join61(root, "system-prompt.txt");
108154
- writeFileSync26(systemPromptFile, systemPrompt, { mode: 384 });
108938
+ systemPromptFile = join62(root, "system-prompt.txt");
108939
+ writeFileSync27(systemPromptFile, systemPrompt, { mode: 384 });
108155
108940
  }
108156
108941
  const argv = claudeCodePrintArgv(model, systemPromptFile);
108157
108942
  const outcome = await runChild(launch, argv, cwd, claudeCodePrintEnv(parentEnv), prompt, signal);
@@ -108178,7 +108963,7 @@ async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
108178
108963
  answer.auth = auth;
108179
108964
  return answer;
108180
108965
  } finally {
108181
- rmSync17(root, { recursive: true, force: true });
108966
+ rmSync18(root, { recursive: true, force: true });
108182
108967
  }
108183
108968
  }
108184
108969
  function runChild(launch, argv, cwd, env, prompt, signal) {
@@ -108451,14 +109236,14 @@ var init_preflight_chain = __esm(() => {
108451
109236
  });
108452
109237
 
108453
109238
  // 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";
109239
+ import { existsSync as existsSync43, readFileSync as readFileSync49, readdirSync as readdirSync14 } from "fs";
109240
+ import { homedir as homedir41 } from "os";
109241
+ import { dirname as dirname27, join as join63, resolve as resolve11 } from "path";
108457
109242
  import { fileURLToPath as fileURLToPath3 } from "url";
108458
109243
  async function loadAllModels(forceRefresh = false) {
108459
109244
  if (!forceRefresh && existsSync43(OPENROUTER_MODELS_CACHE_PATH)) {
108460
109245
  try {
108461
- const cacheData = JSON.parse(readFileSync48(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
109246
+ const cacheData = JSON.parse(readFileSync49(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
108462
109247
  const lastUpdated = new Date(cacheData.lastUpdated);
108463
109248
  const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
108464
109249
  if (ageInDays <= CACHE_MAX_AGE_DAYS) {
@@ -108482,7 +109267,7 @@ async function loadAllModels(forceRefresh = false) {
108482
109267
  log(`[mcp] OpenRouter models fetch failed: ${err instanceof Error ? err.message : String(err)}`);
108483
109268
  try {
108484
109269
  if (existsSync43(OPENROUTER_MODELS_CACHE_PATH)) {
108485
- const cacheData = JSON.parse(readFileSync48(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
109270
+ const cacheData = JSON.parse(readFileSync49(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
108486
109271
  return cacheData.models || [];
108487
109272
  }
108488
109273
  } catch (cacheErr) {
@@ -109661,8 +110446,8 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109661
110446
  const promptText = () => {
109662
110447
  if (input !== undefined)
109663
110448
  return input;
109664
- const existing = join62(resolved, "input.md");
109665
- return existsSync43(existing) ? readFileSync48(existing, "utf-8") : undefined;
110449
+ const existing = join63(resolved, "input.md");
110450
+ return existsSync43(existing) ? readFileSync49(existing, "utf-8") : undefined;
109666
110451
  };
109667
110452
  const choice = await modelChoiceStop([
109668
110453
  ...runsModels && givenModels && models ? givenModels.map((given, i) => ({ given, spec: models[i] })) : [],
@@ -109836,7 +110621,7 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109836
110621
  let stderrFull = stderr_snippet || "";
109837
110622
  if (error_log_path) {
109838
110623
  try {
109839
- stderrFull = readFileSync48(error_log_path, "utf-8");
110624
+ stderrFull = readFileSync49(error_log_path, "utf-8");
109840
110625
  } catch {}
109841
110626
  }
109842
110627
  const sessionData = {};
@@ -109844,26 +110629,26 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109844
110629
  const sp = session_path;
109845
110630
  for (const file of ["status.json", "manifest.json", "input.md"]) {
109846
110631
  try {
109847
- sessionData[file] = readFileSync48(join62(sp, file), "utf-8");
110632
+ sessionData[file] = readFileSync49(join63(sp, file), "utf-8");
109848
110633
  } catch {}
109849
110634
  }
109850
110635
  try {
109851
- const errorDir = join62(sp, "errors");
110636
+ const errorDir = join63(sp, "errors");
109852
110637
  if (existsSync43(errorDir)) {
109853
- for (const f of readdirSync13(errorDir)) {
110638
+ for (const f of readdirSync14(errorDir)) {
109854
110639
  if (f.endsWith(".log")) {
109855
110640
  try {
109856
- sessionData[`errors/${f}`] = readFileSync48(join62(errorDir, f), "utf-8");
110641
+ sessionData[`errors/${f}`] = readFileSync49(join63(errorDir, f), "utf-8");
109857
110642
  } catch {}
109858
110643
  }
109859
110644
  }
109860
110645
  }
109861
110646
  } catch {}
109862
110647
  try {
109863
- for (const f of readdirSync13(sp)) {
110648
+ for (const f of readdirSync14(sp)) {
109864
110649
  if (f.startsWith("response-") && f.endsWith(".md")) {
109865
110650
  try {
109866
- const content = readFileSync48(join62(sp, f), "utf-8");
110651
+ const content = readFileSync49(join63(sp, f), "utf-8");
109867
110652
  sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
109868
110653
  } catch {}
109869
110654
  }
@@ -109872,9 +110657,9 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
109872
110657
  }
109873
110658
  let version = "unknown";
109874
110659
  try {
109875
- const pkgPath = join62(__dirname3, "../package.json");
110660
+ const pkgPath = join63(__dirname3, "../package.json");
109876
110661
  if (existsSync43(pkgPath)) {
109877
- version = JSON.parse(readFileSync48(pkgPath, "utf-8")).version;
110662
+ version = JSON.parse(readFileSync49(pkgPath, "utf-8")).version;
109878
110663
  }
109879
110664
  } catch {}
109880
110665
  const report = {
@@ -110609,9 +111394,9 @@ var init_mcp_server = __esm(() => {
110609
111394
  init_team_orchestrator();
110610
111395
  init_preflight_chain();
110611
111396
  __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");
111397
+ __dirname3 = dirname27(__filename3);
111398
+ CLAUDISH_CACHE_DIR = join63(homedir41(), ".claudish");
111399
+ OPENROUTER_MODELS_CACHE_PATH = join63(CLAUDISH_CACHE_DIR, "openrouter-models.json");
110615
111400
  NEXT_STEP = {
110616
111401
  cancelled: "you stopped this slot; nothing is wrong with it. Re-run it if you still want its vote",
110617
111402
  timeout: "grid mode only \u2014 magmux ended the pane. The orchestrator has no deadline",
@@ -110636,7 +111421,7 @@ var init_mcp_server = __esm(() => {
110636
111421
  });
110637
111422
 
110638
111423
  // src/serve-command.ts
110639
- import { existsSync as existsSync44, readFileSync as readFileSync49 } from "fs";
111424
+ import { existsSync as existsSync44, readFileSync as readFileSync50 } from "fs";
110640
111425
  function parseServeArgs(args) {
110641
111426
  const out = {};
110642
111427
  for (let i = 0;i < args.length; i++) {
@@ -110660,7 +111445,7 @@ function loadModelMap(path) {
110660
111445
  }
110661
111446
  let raw;
110662
111447
  try {
110663
- raw = readFileSync49(path, "utf-8");
111448
+ raw = readFileSync50(path, "utf-8");
110664
111449
  } catch (e) {
110665
111450
  throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
110666
111451
  }
@@ -110741,9 +111526,9 @@ var init_serve_command = __esm(() => {
110741
111526
  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
111527
 
110743
111528
  // 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";
111529
+ import { appendFileSync as appendFileSync8, readFileSync as readFileSync51, readdirSync as readdirSync15, statSync as statSync26 } from "fs";
111530
+ import { homedir as homedir42 } from "os";
111531
+ import { join as join64 } from "path";
110747
111532
  function directoryOf2(filePath) {
110748
111533
  const slash = filePath.lastIndexOf("/");
110749
111534
  return slash > 0 ? filePath.slice(0, slash) : undefined;
@@ -110765,7 +111550,7 @@ function writeTargetsOf(row) {
110765
111550
  function replayTranscript(file) {
110766
111551
  let text;
110767
111552
  try {
110768
- text = readFileSync50(file, "utf8");
111553
+ text = readFileSync51(file, "utf8");
110769
111554
  } catch {
110770
111555
  return [];
110771
111556
  }
@@ -110817,31 +111602,31 @@ function listTranscripts(root) {
110817
111602
  const files = [];
110818
111603
  let projects;
110819
111604
  try {
110820
- projects = readdirSync14(root);
111605
+ projects = readdirSync15(root);
110821
111606
  } catch {
110822
111607
  return files;
110823
111608
  }
110824
111609
  for (const project of projects) {
110825
- const dir = join63(root, project);
111610
+ const dir = join64(root, project);
110826
111611
  try {
110827
- if (!statSync25(dir).isDirectory())
111612
+ if (!statSync26(dir).isDirectory())
110828
111613
  continue;
110829
- for (const f of readdirSync14(dir)) {
111614
+ for (const f of readdirSync15(dir)) {
110830
111615
  if (f.endsWith(".jsonl"))
110831
- files.push(join63(dir, f));
111616
+ files.push(join64(dir, f));
110832
111617
  }
110833
111618
  } catch {}
110834
111619
  }
110835
111620
  return files;
110836
111621
  }
110837
111622
  function buildCorpus(options = {}) {
110838
- const root = options.projectsRoot ?? join63(homedir41(), ".claude", "projects");
111623
+ const root = options.projectsRoot ?? join64(homedir42(), ".claude", "projects");
110839
111624
  const files = listTranscripts(root);
110840
111625
  const records = [];
110841
111626
  for (const f of files)
110842
111627
  records.push(...replayTranscript(f));
110843
111628
  if (options.write && records.length > 0) {
110844
- const outputPath = options.outputPath ?? join63(homedir41(), ".claudish", "behavior-divergences.jsonl");
111629
+ const outputPath = options.outputPath ?? join64(homedir42(), ".claudish", "behavior-divergences.jsonl");
110845
111630
  try {
110846
111631
  appendFileSync8(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
110847
111632
  `)}
@@ -110857,9 +111642,9 @@ var init_corpus = __esm(() => {
110857
111642
  });
110858
111643
 
110859
111644
  // 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";
111645
+ import { existsSync as existsSync45, mkdirSync as mkdirSync30, readFileSync as readFileSync52, writeFileSync as writeFileSync28 } from "fs";
111646
+ import { homedir as homedir43 } from "os";
111647
+ import { join as join65, resolve as resolve12 } from "path";
110863
111648
  function severityColor(sev) {
110864
111649
  if (sev === "fix")
110865
111650
  return green(sev);
@@ -110982,10 +111767,10 @@ async function check(file, json) {
110982
111767
  return valid ? 0 : 1;
110983
111768
  }
110984
111769
  function init(dirArg) {
110985
- const dir = dirArg ? resolve12(process.cwd(), dirArg) : join64(homedir42(), ".claudish", "hooks");
111770
+ const dir = dirArg ? resolve12(process.cwd(), dirArg) : join65(homedir43(), ".claudish", "hooks");
110986
111771
  const files = [
110987
- [join64(dir, "example-hook.ts"), EXAMPLE_HOOK],
110988
- [join64(dir, "claudish-hooks.d.ts"), HOOKS_AMBIENT_DTS]
111772
+ [join65(dir, "example-hook.ts"), EXAMPLE_HOOK],
111773
+ [join65(dir, "claudish-hooks.d.ts"), HOOKS_AMBIENT_DTS]
110989
111774
  ];
110990
111775
  const existing = files.filter(([path]) => existsSync45(path)).map(([path]) => path);
110991
111776
  if (existing.length > 0) {
@@ -110993,9 +111778,9 @@ function init(dirArg) {
110993
111778
  console.error(`${path} already exists; not overwriting it.`);
110994
111779
  return 1;
110995
111780
  }
110996
- mkdirSync29(dir, { recursive: true });
111781
+ mkdirSync30(dir, { recursive: true });
110997
111782
  for (const [path, text] of files)
110998
- writeFileSync27(path, text, { flag: "wx" });
111783
+ writeFileSync28(path, text, { flag: "wx" });
110999
111784
  console.log(`
111000
111785
  wrote ${files.map(([p]) => p).join(`
111001
111786
  wrote `)}
@@ -111078,7 +111863,7 @@ function telemetry(action, json) {
111078
111863
  try {
111079
111864
  const path = outboxPath();
111080
111865
  if (existsSync45(path))
111081
- pending = readFileSync51(path, "utf8").split(`
111866
+ pending = readFileSync52(path, "utf8").split(`
111082
111867
  `).filter(Boolean).length;
111083
111868
  } catch {}
111084
111869
  if (json) {
@@ -111186,9 +111971,9 @@ var init_hooks_command = __esm(() => {
111186
111971
 
111187
111972
  // src/team-grid.ts
111188
111973
  import { spawn as spawn4 } from "child_process";
111189
- import { existsSync as existsSync46, readFileSync as readFileSync52, writeFileSync as writeFileSync28 } from "fs";
111974
+ import { existsSync as existsSync46, readFileSync as readFileSync53, writeFileSync as writeFileSync29 } from "fs";
111190
111975
  import { connect as netConnect3 } from "net";
111191
- import { join as join65 } from "path";
111976
+ import { join as join66 } from "path";
111192
111977
  import { setTimeout as wait } from "timers/promises";
111193
111978
  function paneRouteLine(explanation) {
111194
111979
  const origin = describeRouteExplanation(explanation);
@@ -111338,9 +112123,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
111338
112123
  const keep = opts?.keep ?? false;
111339
112124
  const manifest = setupSession(sessionPath, models, input);
111340
112125
  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");
112126
+ const gridfilePath = join66(sessionPath, "gridfile.txt");
112127
+ const prompt = readFileSync53(join66(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
112128
+ const rawPrompt = readFileSync53(join66(sessionPath, "input.md"), "utf-8");
111344
112129
  const usedBannerColors = new Set;
111345
112130
  const routeLines = mode === "interactive" ? new Map : await resolvePaneRouteLines(Object.values(manifest.models).map((entry) => entry.model));
111346
112131
  const gridLines = Object.entries(manifest.models).map(([anonId]) => {
@@ -111352,7 +112137,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
111352
112137
  const header = buildPaneHeader(model, routeLines.get(model) ?? "", rawPrompt, bg);
111353
112138
  return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
111354
112139
  });
111355
- writeFileSync28(gridfilePath, `${gridLines.join(`
112140
+ writeFileSync29(gridfilePath, `${gridLines.join(`
111356
112141
  `)}
111357
112142
  `, "utf-8");
111358
112143
  const magmuxPath = findMagmuxBinary();
@@ -111372,8 +112157,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
111372
112157
  });
111373
112158
  const [{ results }] = await Promise.all([subscription, procExit]);
111374
112159
  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");
112160
+ const statusPath = join66(sessionPath, "status.json");
112161
+ writeFileSync29(statusPath, JSON.stringify(status, null, 2), "utf-8");
111377
112162
  return status;
111378
112163
  }
111379
112164
  var BANNER_BG_COLORS;
@@ -111392,8 +112177,8 @@ var init_team_grid = __esm(() => {
111392
112177
  });
111393
112178
 
111394
112179
  // src/team-cli.ts
111395
- import { readFileSync as readFileSync53 } from "fs";
111396
- import { join as join66 } from "path";
112180
+ import { readFileSync as readFileSync54 } from "fs";
112181
+ import { join as join67 } from "path";
111397
112182
  async function runPaneTeam(sessionPath, models, input, opts) {
111398
112183
  installPaneShutdownHooks({ exitAfter: true });
111399
112184
  try {
@@ -111538,7 +112323,7 @@ async function teamCommand(args) {
111538
112323
  }
111539
112324
  case "judge": {
111540
112325
  await judgeResponses(sessionPath, { judges });
111541
- console.log(readFileSync53(join66(sessionPath, "verdict.md"), "utf-8"));
112326
+ console.log(readFileSync54(join67(sessionPath, "verdict.md"), "utf-8"));
111542
112327
  break;
111543
112328
  }
111544
112329
  case "run-and-judge": {
@@ -111554,7 +112339,7 @@ async function teamCommand(args) {
111554
112339
  });
111555
112340
  printStatus(status);
111556
112341
  await judgeResponses(sessionPath, { judges });
111557
- console.log(readFileSync53(join66(sessionPath, "verdict.md"), "utf-8"));
112342
+ console.log(readFileSync54(join67(sessionPath, "verdict.md"), "utf-8"));
111558
112343
  break;
111559
112344
  }
111560
112345
  case "status": {
@@ -113776,8 +114561,8 @@ var init_account_command = __esm(() => {
113776
114561
  // src/auth/antigravity-oauth.ts
113777
114562
  import { spawnSync as spawnSync3 } from "child_process";
113778
114563
  import { existsSync as existsSync47, unlinkSync as unlinkSync13 } from "fs";
113779
- import { homedir as homedir43 } from "os";
113780
- import { join as join67 } from "path";
114564
+ import { homedir as homedir44 } from "os";
114565
+ import { join as join68 } from "path";
113781
114566
  async function defaultSuggestModel() {
113782
114567
  try {
113783
114568
  const token = await getValidAntigravityAccessToken();
@@ -113896,7 +114681,7 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
113896
114681
  async logout(deps) {
113897
114682
  deleteSharedAntigravityToken(deps);
113898
114683
  try {
113899
- const tokenFile = join67(homedir43(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
114684
+ const tokenFile = join68(homedir44(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
113900
114685
  if (existsSync47(tokenFile))
113901
114686
  unlinkSync13(tokenFile);
113902
114687
  } catch {}
@@ -113929,13 +114714,13 @@ var init_antigravity_oauth = __esm(() => {
113929
114714
  });
113930
114715
 
113931
114716
  // src/auth/meta-muse-oauth.ts
113932
- import { execFile as execFile6 } from "child_process";
114717
+ import { execFile as execFile7 } from "child_process";
113933
114718
  function openInBrowser(url) {
113934
114719
  if (!/^https:\/\//i.test(url))
113935
114720
  return Promise.resolve();
113936
114721
  const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "explorer" : "xdg-open";
113937
114722
  return new Promise((resolve) => {
113938
- execFile6(command, [url], () => resolve());
114723
+ execFile7(command, [url], () => resolve());
113939
114724
  });
113940
114725
  }
113941
114726
  function describe2(answer, status) {
@@ -122095,18 +122880,18 @@ var init_tui = __esm(() => {
122095
122880
  });
122096
122881
 
122097
122882
  // 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";
122883
+ import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync31, unlinkSync as unlinkSync14, writeFileSync as writeFileSync30 } from "fs";
122884
+ import { homedir as homedir45 } from "os";
122885
+ import { join as join69 } from "path";
122101
122886
  function getClaudishDir() {
122102
- const dir = join68(homedir44(), ".claudish");
122887
+ const dir = join69(homedir45(), ".claudish");
122103
122888
  try {
122104
- mkdirSync30(dir, { recursive: true });
122889
+ mkdirSync31(dir, { recursive: true });
122105
122890
  } catch {}
122106
122891
  return dir;
122107
122892
  }
122108
122893
  function getDiagLogPath() {
122109
- return join68(getClaudishDir(), `diag-${process.pid}.log`);
122894
+ return join69(getClaudishDir(), `diag-${process.pid}.log`);
122110
122895
  }
122111
122896
 
122112
122897
  class LogFileDiagOutput {
@@ -122115,7 +122900,7 @@ class LogFileDiagOutput {
122115
122900
  constructor() {
122116
122901
  this.logPath = getDiagLogPath();
122117
122902
  try {
122118
- writeFileSync29(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
122903
+ writeFileSync30(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
122119
122904
  `);
122120
122905
  } catch {}
122121
122906
  this.stream = createWriteStream2(this.logPath, { flags: "a" });
@@ -122628,7 +123413,7 @@ var init_advisor_startup = __esm(() => {
122628
123413
  });
122629
123414
 
122630
123415
  // src/session/conversation.ts
122631
- import { closeSync as closeSync18, openSync as openSync17, readSync as readSync8, statSync as statSync26 } from "fs";
123416
+ import { closeSync as closeSync18, openSync as openSync17, readSync as readSync8, statSync as statSync27 } from "fs";
122632
123417
  import { StringDecoder } from "string_decoder";
122633
123418
  function looksLikeTurn(line) {
122634
123419
  const assistant = line.includes('"type":"assistant"');
@@ -122683,7 +123468,7 @@ function readConversation(file, opts = {}) {
122683
123468
  };
122684
123469
  let fd = null;
122685
123470
  try {
122686
- const size = statSync26(file).size;
123471
+ const size = statSync27(file).size;
122687
123472
  fd = openSync17(file, "r");
122688
123473
  const buf = Buffer.allocUnsafe(chunkBytes);
122689
123474
  const decoder = new StringDecoder("utf-8");
@@ -124342,11 +125127,11 @@ var exports_session_stats = {};
124342
125127
  __export(exports_session_stats, {
124343
125128
  readSessionStats: () => readSessionStats
124344
125129
  });
124345
- import { readFileSync as readFileSync54 } from "fs";
125130
+ import { readFileSync as readFileSync55 } from "fs";
124346
125131
  function readSessionStats(port, opts) {
124347
125132
  let raw;
124348
125133
  try {
124349
- raw = JSON.parse(readFileSync54(resolveTokenFilePath(port), "utf-8"));
125134
+ raw = JSON.parse(readFileSync55(resolveTokenFilePath(port), "utf-8"));
124350
125135
  } catch {
124351
125136
  return null;
124352
125137
  }
@@ -124724,8 +125509,8 @@ init_launch_env();
124724
125509
  init_op_source();
124725
125510
  init_startup_trace();
124726
125511
  init_picker_cancelled();
124727
- import { existsSync as existsSync48, readFileSync as readFileSync55 } from "fs";
124728
- import { join as join69, resolve as resolve13 } from "path";
125512
+ import { existsSync as existsSync48, readFileSync as readFileSync56 } from "fs";
125513
+ import { join as join70, resolve as resolve13 } from "path";
124729
125514
 
124730
125515
  // src/tui/runtime/should-open-picker.ts
124731
125516
  function noModelConfigured(gate) {
@@ -124742,7 +125527,7 @@ function requiresExplicitModel(gate, tty) {
124742
125527
  var autoloadDropped = [...droppedAtLaunch, ...takeLauncherDropped(process.env)];
124743
125528
  var dotenvText;
124744
125529
  try {
124745
- dotenvText = readFileSync55(join69(process.cwd(), ".env"));
125530
+ dotenvText = readFileSync56(join70(process.cwd(), ".env"));
124746
125531
  } catch {}
124747
125532
  if (dotenvText !== undefined) {
124748
125533
  await Promise.resolve().then(() => init_dotenv_allowlist());
@@ -125083,14 +125868,14 @@ async function runCli() {
125083
125868
  if (cliConfig.team && cliConfig.team.length > 0) {
125084
125869
  let prompt = cliConfig.claudeArgs.join(" ");
125085
125870
  if (cliConfig.inputFile) {
125086
- prompt = readFileSync55(cliConfig.inputFile, "utf-8");
125871
+ prompt = readFileSync56(cliConfig.inputFile, "utf-8");
125087
125872
  }
125088
125873
  if (!prompt.trim()) {
125089
125874
  console.error("Error: --team requires a prompt (positional args or -f <file>)");
125090
125875
  process.exit(1);
125091
125876
  }
125092
125877
  const mode = cliConfig.teamMode ?? "default";
125093
- const sessionPath = join69(process.cwd(), `.claudish-team-${Date.now()}`);
125878
+ const sessionPath = join70(process.cwd(), `.claudish-team-${Date.now()}`);
125094
125879
  if (mode === "json") {
125095
125880
  await Promise.resolve().then(() => init_pane());
125096
125881
  await Promise.resolve().then(() => init_team_orchestrator());
@@ -125110,9 +125895,9 @@ async function runCli() {
125110
125895
  const status = await runModels(sessionPath);
125111
125896
  const result = { ...status, responses: {} };
125112
125897
  for (const anonId of Object.keys(status.models)) {
125113
- const responsePath = join69(sessionPath, `response-${anonId}.md`);
125898
+ const responsePath = join70(sessionPath, `response-${anonId}.md`);
125114
125899
  try {
125115
- const raw = readFileSync55(responsePath, "utf-8").trim();
125900
+ const raw = readFileSync56(responsePath, "utf-8").trim();
125116
125901
  try {
125117
125902
  result.responses[anonId] = JSON.parse(raw);
125118
125903
  } catch {
@@ -125229,7 +126014,11 @@ Team Status`);
125229
126014
  hasProfileTiers
125230
126015
  });
125231
126016
  if (shouldOpenPicker(pickerGate(), pickerCanDraw)) {
125232
- cliConfig.model = await traceSpan("startup:model-select", () => selectModel({ freeOnly: cliConfig.freeOnly }).catch(handlePromptExit), { mayIncludeUserPrompt: true });
126017
+ const sizeIsGiven = cliConfig.contextWindow !== undefined || process.env.CLAUDISH_CONTEXT_WINDOW !== undefined;
126018
+ const onContextWindow = sizeIsGiven ? undefined : (size) => {
126019
+ cliConfig.contextWindow = size;
126020
+ };
126021
+ cliConfig.model = await traceSpan("startup:model-select", () => selectModel({ freeOnly: cliConfig.freeOnly, onContextWindow }).catch(handlePromptExit), { mayIncludeUserPrompt: true });
125233
126022
  console.log("");
125234
126023
  }
125235
126024
  if (requiresExplicitModel(pickerGate(), pickerCanDraw)) {
@@ -125374,6 +126163,9 @@ Team Status`);
125374
126163
  }
125375
126164
  }
125376
126165
  }
126166
+ if (cliConfig.contextWindow !== undefined) {
126167
+ process.env.CLAUDISH_CONTEXT_WINDOW = String(cliConfig.contextWindow);
126168
+ }
125377
126169
  const proxy = await traceSpan("startup:proxy-start", () => createProxyServer(port, cliConfig.monitor ? undefined : cliConfig.openrouterApiKey, cliConfig.monitor ? undefined : explicitModel, cliConfig.monitor, cliConfig.anthropicApiKey, modelMap, {
125378
126170
  summarizeTools: cliConfig.summarizeTools,
125379
126171
  quiet: cliConfig.quiet,