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.
- package/dist/index.js +1350 -558
- 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.
|
|
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.
|
|
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 :
|
|
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
|
|
50708
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
52132
|
-
import { join as
|
|
52133
|
-
function userHomeFrom(env, homedirFn =
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
52315
|
-
import { homedir as
|
|
52316
|
-
import { join as
|
|
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 ??
|
|
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 =
|
|
52428
|
-
const primary =
|
|
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
|
|
52433
|
-
const candidate =
|
|
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(
|
|
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
|
|
52547
|
-
readFileSync as
|
|
52548
|
-
renameSync as
|
|
53053
|
+
mkdirSync as mkdirSync17,
|
|
53054
|
+
readFileSync as readFileSync31,
|
|
53055
|
+
renameSync as renameSync9,
|
|
52549
53056
|
unlinkSync as unlinkSync8,
|
|
52550
|
-
writeFileSync as
|
|
53057
|
+
writeFileSync as writeFileSync12
|
|
52551
53058
|
} from "fs";
|
|
52552
|
-
import { homedir as
|
|
52553
|
-
import { join as
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
52589
|
-
|
|
52590
|
-
|
|
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 =
|
|
52662
|
-
BUFFER_FILE =
|
|
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
|
|
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) ??
|
|
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
|
|
56760
|
-
import { dirname as
|
|
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
|
-
|
|
57002
|
-
|
|
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
|
|
59260
|
-
import { homedir as
|
|
59261
|
-
import { join as
|
|
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(
|
|
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(
|
|
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(
|
|
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: "/
|
|
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
|
|
73160
|
-
import { homedir as
|
|
73161
|
-
import { dirname as
|
|
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(
|
|
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
|
-
|
|
73189
|
-
|
|
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 =
|
|
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
|
|
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 ||
|
|
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
|
|
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(
|
|
76245
|
+
execFileAsync2 = promisify5(execFile3);
|
|
75737
76246
|
});
|
|
75738
76247
|
|
|
75739
76248
|
// src/pane/prompt-delivery.ts
|
|
75740
|
-
import { writeFileSync as
|
|
75741
|
-
import { join as
|
|
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
|
|
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
|
-
|
|
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
|
|
76997
|
+
readdirSync as readdirSync6,
|
|
76489
76998
|
realpathSync as realpathSync4,
|
|
76490
|
-
statSync as
|
|
76999
|
+
statSync as statSync12
|
|
76491
77000
|
} from "fs";
|
|
76492
|
-
import { join as
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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 :
|
|
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(
|
|
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
|
|
77239
|
-
import { closeSync as closeSync11, openSync as openSync11, readSync as readSync4, readdirSync as
|
|
77240
|
-
import { basename as
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
77808
|
+
const dir = join39(projectsDir(), dirName);
|
|
77300
77809
|
let names;
|
|
77301
77810
|
try {
|
|
77302
|
-
names =
|
|
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 =
|
|
77817
|
+
const file = join39(dir, n);
|
|
77309
77818
|
try {
|
|
77310
|
-
const st =
|
|
77819
|
+
const st = statSync13(file);
|
|
77311
77820
|
if (st.size === 0)
|
|
77312
77821
|
continue;
|
|
77313
77822
|
const row = {
|
|
77314
|
-
id:
|
|
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
|
-
|
|
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)" :
|
|
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 =
|
|
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 =
|
|
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
|
|
77775
|
-
import { join as
|
|
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,
|
|
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
|
|
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
|
|
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 =
|
|
78715
|
-
const pkgRoots = [
|
|
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 =
|
|
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 =
|
|
79236
|
+
const candidate = join41(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
78728
79237
|
if (existsSync28(candidate))
|
|
78729
79238
|
return candidate;
|
|
78730
|
-
const parent =
|
|
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
|
|
79266
|
+
mkdirSync as mkdirSync20,
|
|
78758
79267
|
mkdtempSync,
|
|
78759
79268
|
openSync as openSync12,
|
|
78760
|
-
rmSync as
|
|
78761
|
-
writeFileSync as
|
|
79269
|
+
rmSync as rmSync11,
|
|
79270
|
+
writeFileSync as writeFileSync16
|
|
78762
79271
|
} from "fs";
|
|
78763
79272
|
import { connect as netConnect } from "net";
|
|
78764
|
-
import { join as
|
|
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
|
-
|
|
78830
|
-
const scriptDir = mkdtempSync(
|
|
79338
|
+
mkdirSync20(tmpRoot, { recursive: true });
|
|
79339
|
+
const scriptDir = mkdtempSync(join42(tmpRoot, "claudish-launch-"));
|
|
78831
79340
|
chmodSync3(scriptDir, 448);
|
|
78832
|
-
const scriptPath =
|
|
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
|
-
|
|
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
|
-
|
|
79378
|
+
rmSync11(scriptDir, { recursive: true, force: true });
|
|
78870
79379
|
} catch {}
|
|
78871
79380
|
try {
|
|
78872
79381
|
if (existsSync29(controlSocket))
|
|
78873
|
-
|
|
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
|
|
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 } =
|
|
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(
|
|
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(
|
|
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
|
|
79107
|
-
import { homedir as
|
|
79108
|
-
import { join as
|
|
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(
|
|
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 =
|
|
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
|
|
80993
|
-
import { homedir as
|
|
80994
|
-
import { dirname as
|
|
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(
|
|
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
|
-
|
|
81033
|
-
|
|
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 =
|
|
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" ? "
|
|
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
|
|
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(
|
|
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
|
-
|
|
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({
|
|
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,
|
|
82387
|
-
const
|
|
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 (
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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(
|
|
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
|
|
87581
|
-
import { homedir as
|
|
87582
|
-
import { join as
|
|
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 ||
|
|
87587
|
-
cacheDir =
|
|
88209
|
+
const localAppData = process.env.LOCALAPPDATA || join45(homedir37(), "AppData", "Local");
|
|
88210
|
+
cacheDir = join45(localAppData, "claudish");
|
|
87588
88211
|
} else {
|
|
87589
|
-
cacheDir =
|
|
88212
|
+
cacheDir = join45(homedir37(), ".cache", "claudish");
|
|
87590
88213
|
}
|
|
87591
88214
|
try {
|
|
87592
88215
|
if (!existsSync32(cacheDir)) {
|
|
87593
|
-
|
|
88216
|
+
mkdirSync22(cacheDir, { recursive: true });
|
|
87594
88217
|
}
|
|
87595
|
-
return
|
|
88218
|
+
return join45(cacheDir, "update-check.json");
|
|
87596
88219
|
} catch {
|
|
87597
|
-
return
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
92586
|
-
|
|
92587
|
-
|
|
92588
|
-
|
|
92589
|
-
|
|
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
|
-
|
|
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 (
|
|
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}/
|
|
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
|
-
|
|
92791
|
-
|
|
92792
|
-
|
|
92793
|
-
|
|
92794
|
-
|
|
92795
|
-
|
|
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
|
|
94068
|
-
import { homedir as
|
|
94069
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
94130
|
-
CACHE_FILE =
|
|
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
|
|
94136
|
-
import { join as
|
|
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 =
|
|
94889
|
+
const dir = join47(process.cwd(), "logs");
|
|
94145
94890
|
if (!classifierCaptureDirReady) {
|
|
94146
|
-
|
|
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(
|
|
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
|
|
94690
|
-
readFileSync as
|
|
94691
|
-
readdirSync as
|
|
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
|
|
94695
|
-
import { dirname as
|
|
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 =
|
|
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 =
|
|
95452
|
+
const files = readdirSync8(cacheDir);
|
|
94708
95453
|
for (const file of files) {
|
|
94709
95454
|
if (cachePatterns.includes(file)) {
|
|
94710
|
-
unlinkSync10(
|
|
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 =
|
|
96238
|
-
const guideContent =
|
|
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 =
|
|
96255
|
-
const skillsDir =
|
|
96256
|
-
const claudishSkillDir =
|
|
96257
|
-
const skillFile =
|
|
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 =
|
|
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
|
-
|
|
97029
|
+
mkdirSync24(claudeDir, { recursive: true });
|
|
96277
97030
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
96278
97031
|
}
|
|
96279
97032
|
if (!existsSync34(skillsDir)) {
|
|
96280
|
-
|
|
97033
|
+
mkdirSync24(skillsDir, { recursive: true });
|
|
96281
97034
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
96282
97035
|
}
|
|
96283
97036
|
if (!existsSync34(claudishSkillDir)) {
|
|
96284
|
-
|
|
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 =
|
|
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
|
|
97243
|
+
import { execFile as execFile5, execFileSync as execFileSync3 } from "child_process";
|
|
96489
97244
|
import { lstatSync as lstatSync6 } from "fs";
|
|
96490
|
-
import { basename as
|
|
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 (
|
|
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
|
|
97469
|
+
return join49(root, `magmux-${paneId}.sock`);
|
|
96715
97470
|
}
|
|
96716
97471
|
function recordPathOf(root, paneId) {
|
|
96717
|
-
return
|
|
97472
|
+
return join49(root, "panes", `${paneId}.json`);
|
|
96718
97473
|
}
|
|
96719
97474
|
function isPaneSockPath(root, p, paneId) {
|
|
96720
|
-
return isValidPaneId(paneId) &&
|
|
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) &&
|
|
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 (
|
|
97483
|
+
if (basename4(projectsRoot) !== "projects" || !FORK_UUID_RE.test(uuid))
|
|
96729
97484
|
return false;
|
|
96730
|
-
const dir =
|
|
96731
|
-
return
|
|
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:
|
|
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
|
|
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
|
|
97615
|
+
mkdirSync as mkdirSync25,
|
|
96861
97616
|
mkdtempSync as mkdtempSync2,
|
|
96862
|
-
readFileSync as
|
|
96863
|
-
statSync as
|
|
96864
|
-
writeFileSync as
|
|
97617
|
+
readFileSync as readFileSync40,
|
|
97618
|
+
statSync as statSync17,
|
|
97619
|
+
writeFileSync as writeFileSync19
|
|
96865
97620
|
} from "fs";
|
|
96866
|
-
import { join as
|
|
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
|
-
|
|
97641
|
+
mkdirSync25(root, { mode: 448 });
|
|
96887
97642
|
} catch (e) {
|
|
96888
97643
|
if (e.code === "ENOENT")
|
|
96889
|
-
|
|
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 =
|
|
97649
|
+
const panes = join50(root, "panes");
|
|
96895
97650
|
try {
|
|
96896
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
96994
|
-
if (
|
|
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(
|
|
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 =
|
|
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(
|
|
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(
|
|
97974
|
+
const ctlDir = mkdtempSync2(join50(root, "launch-"));
|
|
97220
97975
|
chmodSync4(ctlDir, 448);
|
|
97221
|
-
const turnDir = mkdtempSync2(
|
|
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
|
-
|
|
97227
|
-
|
|
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
|
|
98747
|
+
mkdirSync as mkdirSync26,
|
|
97993
98748
|
mkdtempSync as mkdtempSync3,
|
|
97994
98749
|
openSync as openSync13,
|
|
97995
|
-
readFileSync as
|
|
97996
|
-
readdirSync as
|
|
97997
|
-
rmSync as
|
|
97998
|
-
statSync as
|
|
98750
|
+
readFileSync as readFileSync41,
|
|
98751
|
+
readdirSync as readdirSync9,
|
|
98752
|
+
rmSync as rmSync12,
|
|
98753
|
+
statSync as statSync18,
|
|
97999
98754
|
unlinkSync as unlinkSync11,
|
|
98000
|
-
writeFileSync as
|
|
98755
|
+
writeFileSync as writeFileSync20
|
|
98001
98756
|
} from "fs";
|
|
98002
|
-
import { homedir as
|
|
98003
|
-
import { dirname as
|
|
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(
|
|
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) =>
|
|
98177
|
-
const home = deps.home ??
|
|
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
|
-
|
|
98182
|
-
...env.CLAUDE_CONFIG_DIR ? [
|
|
98183
|
-
|
|
98184
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
98238
|
-
const scriptPath =
|
|
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
|
-
|
|
99150
|
+
writeFileSync20(scriptPath, script, "utf-8");
|
|
98394
99151
|
return scriptPath;
|
|
98395
99152
|
}
|
|
98396
99153
|
function initializeTokenFile(tokenFilePath) {
|
|
98397
99154
|
try {
|
|
98398
|
-
|
|
98399
|
-
|
|
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 =
|
|
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 =
|
|
99199
|
+
const full = join51(dir, name);
|
|
98431
99200
|
try {
|
|
98432
|
-
if (
|
|
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(
|
|
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
|
-
|
|
98460
|
-
|
|
98461
|
-
|
|
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 =
|
|
99271
|
+
const claudishDir = join51(homeDir, ".claudish");
|
|
98503
99272
|
try {
|
|
98504
|
-
|
|
99273
|
+
mkdirSync26(claudishDir, { recursive: true });
|
|
98505
99274
|
} catch {}
|
|
98506
|
-
const tempPath =
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
98918
|
-
const localPath = isWindows2() ?
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
99158
|
-
const localPath = isWindows ?
|
|
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
|
-
|
|
99165
|
-
|
|
99166
|
-
|
|
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
|
-
|
|
99178
|
-
|
|
99179
|
-
|
|
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
|
-
|
|
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
|
|
99510
|
-
import { join as
|
|
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
|
|
100297
|
+
return join52(sessionPath, "stats");
|
|
99513
100298
|
}
|
|
99514
100299
|
function tokenFileFor(sessionPath, anonId) {
|
|
99515
|
-
return
|
|
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(
|
|
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
|
-
|
|
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
|
|
100473
|
+
import { statSync as statSync19 } from "fs";
|
|
99689
100474
|
function readTokenFileCached(path) {
|
|
99690
100475
|
let st;
|
|
99691
100476
|
try {
|
|
99692
|
-
const s =
|
|
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
|
|
99766
|
-
readdirSync as
|
|
99767
|
-
renameSync as
|
|
99768
|
-
rmSync as
|
|
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
|
|
100556
|
+
writeFileSync as writeFileSync22
|
|
99772
100557
|
} from "fs";
|
|
99773
|
-
import { dirname as
|
|
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
|
|
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
|
-
|
|
100584
|
+
writeFileSync22(tmp, `${JSON.stringify(rec)}
|
|
99800
100585
|
`, { mode: 384 });
|
|
99801
|
-
|
|
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(
|
|
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 =
|
|
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(
|
|
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 =
|
|
100669
|
+
const p = join53(ctlDir, "group");
|
|
99885
100670
|
const tmp = `${p}.tmp`;
|
|
99886
100671
|
try {
|
|
99887
|
-
|
|
99888
|
-
|
|
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
|
-
|
|
100680
|
+
rmSync13(fork.path, { force: true });
|
|
99896
100681
|
if (fork.removeProjectDir)
|
|
99897
|
-
|
|
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
|
-
|
|
100689
|
+
rmSync13(f.sockPath, { force: true });
|
|
99905
100690
|
for (const d of [f.launcherDir, f.turnDir])
|
|
99906
100691
|
if (d && isLaunchDirPath(root, d))
|
|
99907
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 ?
|
|
101044
|
+
return tail.length ? join54(realpathSync6(cur), ...tail.reverse()) : realpathSync6(cur);
|
|
100260
101045
|
} catch {
|
|
100261
|
-
const parent =
|
|
101046
|
+
const parent = dirname23(cur);
|
|
100262
101047
|
if (parent === cur)
|
|
100263
101048
|
return abs;
|
|
100264
|
-
tail.push(
|
|
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
|
|
100460
|
-
import { join as
|
|
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
|
|
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 =
|
|
101290
|
+
this.dir = join55(o.configDir, "sessions");
|
|
100506
101291
|
this.now = o.now ?? Date.now;
|
|
100507
|
-
this.isAlive = o.isAlive ??
|
|
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 =
|
|
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 =
|
|
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
|
|
100655
|
-
import { join as
|
|
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,
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
103365
|
-
import { join as
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
105158
|
+
readdirSync as readdirSync12,
|
|
104374
105159
|
readlinkSync,
|
|
104375
105160
|
realpathSync as realpathSync8,
|
|
104376
|
-
statSync as
|
|
105161
|
+
statSync as statSync21
|
|
104377
105162
|
} from "fs";
|
|
104378
|
-
import { basename as
|
|
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 =
|
|
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 =
|
|
105313
|
+
const p = join58(projectsRoot, d, `${uuid}.jsonl`);
|
|
104529
105314
|
try {
|
|
104530
|
-
if (!
|
|
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 -
|
|
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 (
|
|
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 =
|
|
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
|
|
104765
|
-
import { dirname as
|
|
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 (
|
|
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 (!
|
|
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(
|
|
104841
|
-
configDir:
|
|
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
|
|
105009
|
-
readFileSync as
|
|
105010
|
-
readdirSync as
|
|
105793
|
+
mkdirSync as mkdirSync27,
|
|
105794
|
+
readFileSync as readFileSync46,
|
|
105795
|
+
readdirSync as readdirSync13,
|
|
105011
105796
|
realpathSync as realpathSync10,
|
|
105012
|
-
rmSync as
|
|
105013
|
-
statSync as
|
|
105014
|
-
writeFileSync as
|
|
105797
|
+
rmSync as rmSync16,
|
|
105798
|
+
statSync as statSync23,
|
|
105799
|
+
writeFileSync as writeFileSync25
|
|
105015
105800
|
} from "fs";
|
|
105016
|
-
import { basename as
|
|
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
|
|
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 ??
|
|
105967
|
+
run_id: status.runId ?? basename7(path),
|
|
105183
105968
|
path,
|
|
105184
|
-
kind: status.kind ?? (
|
|
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
|
|
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(
|
|
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 :
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
106330
|
+
const parent = dirname26(existing);
|
|
105546
106331
|
if (parent === existing)
|
|
105547
106332
|
break;
|
|
105548
|
-
tail.unshift(
|
|
106333
|
+
tail.unshift(basename7(existing));
|
|
105549
106334
|
existing = parent;
|
|
105550
106335
|
}
|
|
105551
106336
|
}
|
|
105552
106337
|
let real;
|
|
105553
106338
|
try {
|
|
105554
|
-
real =
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
105587
|
-
|
|
106371
|
+
mkdirSync27(join59(sessionPath, "work"), { recursive: true });
|
|
106372
|
+
mkdirSync27(join59(sessionPath, "errors"), { recursive: true });
|
|
105588
106373
|
if (input !== undefined) {
|
|
105589
|
-
|
|
105590
|
-
} else if (!existsSync40(
|
|
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
|
-
|
|
106392
|
+
mkdirSync27(join59(sessionPath, "work", anonId), { recursive: true });
|
|
105608
106393
|
}
|
|
105609
|
-
|
|
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(
|
|
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 `${
|
|
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(
|
|
105686
|
-
const statusPath =
|
|
105687
|
-
const inputContent =
|
|
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(
|
|
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
|
-
|
|
106509
|
+
mkdirSync27(statsDir(path), { recursive: true });
|
|
105725
106510
|
const entries = new Map;
|
|
105726
106511
|
let run = null;
|
|
105727
|
-
const errorLogPathOf = (id) =>
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
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] =
|
|
106970
|
+
responses[id] = readFileSync46(join59(sessionPath, file), "utf-8");
|
|
106186
106971
|
}
|
|
106187
|
-
const input =
|
|
106972
|
+
const input = readFileSync46(join59(sessionPath, "input.md"), "utf-8");
|
|
106188
106973
|
const judgePrompt = buildJudgePrompt(input, responses);
|
|
106189
|
-
|
|
106974
|
+
writeFileSync25(join59(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
|
|
106190
106975
|
const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
|
|
106191
|
-
const judgePath =
|
|
106192
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
106420
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
107259
|
+
const file = join60(setupFrom, ".claude", name);
|
|
106475
107260
|
if (!existsSync41(file))
|
|
106476
107261
|
continue;
|
|
106477
|
-
layers.push(parseLayer(
|
|
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 (!
|
|
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
|
|
107309
|
+
mkdirSync as mkdirSync28,
|
|
106525
107310
|
openSync as openSync16,
|
|
106526
|
-
readFileSync as
|
|
107311
|
+
readFileSync as readFileSync48,
|
|
106527
107312
|
readSync as readSync7,
|
|
106528
|
-
renameSync as
|
|
106529
|
-
rmSync as
|
|
106530
|
-
statSync as
|
|
106531
|
-
writeFileSync as
|
|
107313
|
+
renameSync as renameSync11,
|
|
107314
|
+
rmSync as rmSync17,
|
|
107315
|
+
statSync as statSync25,
|
|
107316
|
+
writeFileSync as writeFileSync26
|
|
106532
107317
|
} from "fs";
|
|
106533
|
-
import { join as
|
|
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
|
-
|
|
106628
|
-
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
107573
|
+
dir = join61(this.sessionsDir, id);
|
|
106789
107574
|
try {
|
|
106790
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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",
|
|
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 ??
|
|
106920
|
-
|
|
107704
|
+
const sessionDir = opts.sessionDir ?? join61(this.sessionsDir, sessionId);
|
|
107705
|
+
mkdirSync28(sessionDir, { recursive: true });
|
|
106921
107706
|
if (opts.prompt)
|
|
106922
|
-
|
|
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
|
-
|
|
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 ??
|
|
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(
|
|
107764
|
+
outputLogStream: createWriteStream(join61(sessionDir, "output.log")),
|
|
106980
107765
|
sessionDir,
|
|
106981
107766
|
cwd,
|
|
106982
107767
|
tokenFile,
|
|
106983
|
-
eventLogPath:
|
|
107768
|
+
eventLogPath: join61(sessionDir, "events.jsonl"),
|
|
106984
107769
|
eventLogBytes: 0,
|
|
106985
|
-
upstreamErrorLogPath:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 (!
|
|
108236
|
+
if (!statSync25(sessionDir).isDirectory())
|
|
107452
108237
|
return null;
|
|
107453
108238
|
} catch {
|
|
107454
108239
|
return null;
|
|
107455
108240
|
}
|
|
107456
|
-
const spawnPath =
|
|
107457
|
-
const metaPath =
|
|
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 !==
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
107616
|
-
const upstreamErrorLogPath =
|
|
107617
|
-
const outputLogPath =
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
108932
|
+
const root = mkdtempSync4(join62(tmpdir3(), "claudish-run-prompt-"));
|
|
108148
108933
|
try {
|
|
108149
|
-
const cwd =
|
|
108150
|
-
|
|
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 =
|
|
108154
|
-
|
|
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
|
-
|
|
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
|
|
108455
|
-
import { homedir as
|
|
108456
|
-
import { dirname as
|
|
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(
|
|
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(
|
|
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 =
|
|
109665
|
-
return existsSync43(existing) ?
|
|
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 =
|
|
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] =
|
|
110632
|
+
sessionData[file] = readFileSync49(join63(sp, file), "utf-8");
|
|
109848
110633
|
} catch {}
|
|
109849
110634
|
}
|
|
109850
110635
|
try {
|
|
109851
|
-
const errorDir =
|
|
110636
|
+
const errorDir = join63(sp, "errors");
|
|
109852
110637
|
if (existsSync43(errorDir)) {
|
|
109853
|
-
for (const f of
|
|
110638
|
+
for (const f of readdirSync14(errorDir)) {
|
|
109854
110639
|
if (f.endsWith(".log")) {
|
|
109855
110640
|
try {
|
|
109856
|
-
sessionData[`errors/${f}`] =
|
|
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
|
|
110648
|
+
for (const f of readdirSync14(sp)) {
|
|
109864
110649
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
109865
110650
|
try {
|
|
109866
|
-
const content =
|
|
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 =
|
|
110660
|
+
const pkgPath = join63(__dirname3, "../package.json");
|
|
109876
110661
|
if (existsSync43(pkgPath)) {
|
|
109877
|
-
version = JSON.parse(
|
|
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 =
|
|
110613
|
-
CLAUDISH_CACHE_DIR =
|
|
110614
|
-
OPENROUTER_MODELS_CACHE_PATH =
|
|
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
|
|
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 =
|
|
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
|
|
110745
|
-
import { homedir as
|
|
110746
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
111605
|
+
projects = readdirSync15(root);
|
|
110821
111606
|
} catch {
|
|
110822
111607
|
return files;
|
|
110823
111608
|
}
|
|
110824
111609
|
for (const project of projects) {
|
|
110825
|
-
const dir =
|
|
111610
|
+
const dir = join64(root, project);
|
|
110826
111611
|
try {
|
|
110827
|
-
if (!
|
|
111612
|
+
if (!statSync26(dir).isDirectory())
|
|
110828
111613
|
continue;
|
|
110829
|
-
for (const f of
|
|
111614
|
+
for (const f of readdirSync15(dir)) {
|
|
110830
111615
|
if (f.endsWith(".jsonl"))
|
|
110831
|
-
files.push(
|
|
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 ??
|
|
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 ??
|
|
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
|
|
110861
|
-
import { homedir as
|
|
110862
|
-
import { join as
|
|
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) :
|
|
111770
|
+
const dir = dirArg ? resolve12(process.cwd(), dirArg) : join65(homedir43(), ".claudish", "hooks");
|
|
110986
111771
|
const files = [
|
|
110987
|
-
[
|
|
110988
|
-
[
|
|
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
|
-
|
|
111781
|
+
mkdirSync30(dir, { recursive: true });
|
|
110997
111782
|
for (const [path, text] of files)
|
|
110998
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
111342
|
-
const prompt =
|
|
111343
|
-
const rawPrompt =
|
|
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
|
-
|
|
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 =
|
|
111376
|
-
|
|
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
|
|
111396
|
-
import { join as
|
|
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(
|
|
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(
|
|
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
|
|
113780
|
-
import { join as
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
122099
|
-
import { homedir as
|
|
122100
|
-
import { join as
|
|
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 =
|
|
122887
|
+
const dir = join69(homedir45(), ".claudish");
|
|
122103
122888
|
try {
|
|
122104
|
-
|
|
122889
|
+
mkdirSync31(dir, { recursive: true });
|
|
122105
122890
|
} catch {}
|
|
122106
122891
|
return dir;
|
|
122107
122892
|
}
|
|
122108
122893
|
function getDiagLogPath() {
|
|
122109
|
-
return
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
125130
|
+
import { readFileSync as readFileSync55 } from "fs";
|
|
124346
125131
|
function readSessionStats(port, opts) {
|
|
124347
125132
|
let raw;
|
|
124348
125133
|
try {
|
|
124349
|
-
raw = JSON.parse(
|
|
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
|
|
124728
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
125898
|
+
const responsePath = join70(sessionPath, `response-${anonId}.md`);
|
|
125114
125899
|
try {
|
|
125115
|
-
const raw =
|
|
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
|
-
|
|
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,
|