claudish 7.25.0 → 7.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1140 -458
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -651,7 +651,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
651
651
|
});
|
|
652
652
|
|
|
653
653
|
// src/version.ts
|
|
654
|
-
var VERSION = "7.
|
|
654
|
+
var VERSION = "7.27.0";
|
|
655
655
|
|
|
656
656
|
// src/logger.ts
|
|
657
657
|
var exports_logger = {};
|
|
@@ -1173,6 +1173,122 @@ var init_startup_trace = __esm(() => {
|
|
|
1173
1173
|
spans = [];
|
|
1174
1174
|
});
|
|
1175
1175
|
|
|
1176
|
+
// src/providers/onepassword-handshake-lock.ts
|
|
1177
|
+
import { closeSync, mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync3, rmSync, statSync, writeSync } from "fs";
|
|
1178
|
+
import { homedir as homedir4 } from "os";
|
|
1179
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
1180
|
+
function defaultLockPath() {
|
|
1181
|
+
return join4(homedir4(), ".claudish", "op-handshake.lock");
|
|
1182
|
+
}
|
|
1183
|
+
function currentLockPath() {
|
|
1184
|
+
return lockPath ?? defaultLockPath();
|
|
1185
|
+
}
|
|
1186
|
+
function trace(message) {
|
|
1187
|
+
if (process.env.CLAUDISH_OP_LOCK_TRACE !== "1")
|
|
1188
|
+
return;
|
|
1189
|
+
console.error(`[op-lock] pid=${process.pid} ${message}`);
|
|
1190
|
+
}
|
|
1191
|
+
function readHolder(path) {
|
|
1192
|
+
try {
|
|
1193
|
+
const [pidRaw, atRaw] = readFileSync3(path, "utf-8").trim().split(/\s+/);
|
|
1194
|
+
const pid = Number(pidRaw);
|
|
1195
|
+
const at = Number(atRaw);
|
|
1196
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
1197
|
+
return null;
|
|
1198
|
+
return { pid, at: Number.isFinite(at) ? at : 0 };
|
|
1199
|
+
} catch {
|
|
1200
|
+
return null;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
function holderAlive(pid) {
|
|
1204
|
+
try {
|
|
1205
|
+
process.kill(pid, 0);
|
|
1206
|
+
return true;
|
|
1207
|
+
} catch (err) {
|
|
1208
|
+
return err?.code === "EPERM";
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
function isAbandoned(path) {
|
|
1212
|
+
const holder = readHolder(path);
|
|
1213
|
+
if (!holder) {
|
|
1214
|
+
try {
|
|
1215
|
+
return Date.now() - statSync(path).mtimeMs > timing.staleMs;
|
|
1216
|
+
} catch {
|
|
1217
|
+
return false;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
if (holder.pid !== process.pid && !holderAlive(holder.pid))
|
|
1221
|
+
return true;
|
|
1222
|
+
return Date.now() - holder.at > timing.staleMs;
|
|
1223
|
+
}
|
|
1224
|
+
async function acquire(path) {
|
|
1225
|
+
const deadline = Date.now() + timing.timeoutMs;
|
|
1226
|
+
let madeDir = false;
|
|
1227
|
+
for (;; ) {
|
|
1228
|
+
try {
|
|
1229
|
+
if (!madeDir) {
|
|
1230
|
+
mkdirSync3(dirname2(path), { recursive: true });
|
|
1231
|
+
madeDir = true;
|
|
1232
|
+
}
|
|
1233
|
+
const fd = openSync(path, "wx");
|
|
1234
|
+
try {
|
|
1235
|
+
writeSync(fd, `${process.pid} ${Date.now()}`);
|
|
1236
|
+
} finally {
|
|
1237
|
+
closeSync(fd);
|
|
1238
|
+
}
|
|
1239
|
+
return true;
|
|
1240
|
+
} catch (err) {
|
|
1241
|
+
if (err?.code !== "EEXIST")
|
|
1242
|
+
return false;
|
|
1243
|
+
if (isAbandoned(path)) {
|
|
1244
|
+
try {
|
|
1245
|
+
rmSync(path, { force: true });
|
|
1246
|
+
} catch {}
|
|
1247
|
+
continue;
|
|
1248
|
+
}
|
|
1249
|
+
if (Date.now() >= deadline)
|
|
1250
|
+
return false;
|
|
1251
|
+
await sleep(timing.pollMs + Math.floor(Math.random() * timing.pollMs));
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
function release(path) {
|
|
1256
|
+
try {
|
|
1257
|
+
if (readHolder(path)?.pid === process.pid)
|
|
1258
|
+
rmSync(path, { force: true });
|
|
1259
|
+
} catch {}
|
|
1260
|
+
}
|
|
1261
|
+
async function withHandshakeLock(handshake) {
|
|
1262
|
+
if (process.env.CLAUDISH_NO_OP_HANDSHAKE_LOCK === "1") {
|
|
1263
|
+
trace("bypassed (CLAUDISH_NO_OP_HANDSHAKE_LOCK=1)");
|
|
1264
|
+
return handshake();
|
|
1265
|
+
}
|
|
1266
|
+
const path = currentLockPath();
|
|
1267
|
+
const t0 = Date.now();
|
|
1268
|
+
let held = false;
|
|
1269
|
+
try {
|
|
1270
|
+
held = await acquire(path);
|
|
1271
|
+
} catch {
|
|
1272
|
+
held = false;
|
|
1273
|
+
}
|
|
1274
|
+
trace(`${held ? "acquired" : "NOT held (timeout or unwritable)"} after ${Date.now() - t0}ms`);
|
|
1275
|
+
try {
|
|
1276
|
+
return await handshake();
|
|
1277
|
+
} finally {
|
|
1278
|
+
if (held)
|
|
1279
|
+
release(path);
|
|
1280
|
+
trace(`handshake done after ${Date.now() - t0}ms${held ? ", released" : ""}`);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
var DEFAULT_STALE_MS = 120000, DEFAULT_TIMEOUT_MS = 45000, DEFAULT_POLL_MS = 60, timing, lockPath, sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
1284
|
+
var init_onepassword_handshake_lock = __esm(() => {
|
|
1285
|
+
timing = {
|
|
1286
|
+
staleMs: DEFAULT_STALE_MS,
|
|
1287
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
1288
|
+
pollMs: DEFAULT_POLL_MS
|
|
1289
|
+
};
|
|
1290
|
+
});
|
|
1291
|
+
|
|
1176
1292
|
// src/providers/onepassword-wasm.ts
|
|
1177
1293
|
var exports_onepassword_wasm = {};
|
|
1178
1294
|
__export(exports_onepassword_wasm, {
|
|
@@ -1185,17 +1301,17 @@ __export(exports_onepassword_wasm, {
|
|
|
1185
1301
|
SDK_CORE_INTEGRITY: () => SDK_CORE_INTEGRITY
|
|
1186
1302
|
});
|
|
1187
1303
|
import { createHash } from "crypto";
|
|
1188
|
-
import { copyFileSync, existsSync as existsSync3, mkdirSync as
|
|
1304
|
+
import { copyFileSync, existsSync as existsSync3, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
1189
1305
|
import { createRequire } from "module";
|
|
1190
|
-
import { homedir as
|
|
1191
|
-
import { dirname as
|
|
1306
|
+
import { homedir as homedir5 } from "os";
|
|
1307
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
1192
1308
|
import { gunzipSync } from "zlib";
|
|
1193
1309
|
function tarballUrl() {
|
|
1194
1310
|
return `https://registry.npmjs.org/@1password/sdk-core/-/sdk-core-${SDK_CORE_VERSION}.tgz`;
|
|
1195
1311
|
}
|
|
1196
1312
|
function cacheWasmPath() {
|
|
1197
|
-
const root = cacheRootOverride ??
|
|
1198
|
-
return
|
|
1313
|
+
const root = cacheRootOverride ?? join5(homedir5(), ".claudish");
|
|
1314
|
+
return join5(root, "cache", "1password", WASM_FILENAME);
|
|
1199
1315
|
}
|
|
1200
1316
|
function verifyIntegrity(bytes) {
|
|
1201
1317
|
const [algo, expected] = SDK_CORE_INTEGRITY.split("-", 2);
|
|
@@ -1236,7 +1352,7 @@ function installReadFileSyncIntercept() {
|
|
|
1236
1352
|
}
|
|
1237
1353
|
if (existsSync3(path)) {
|
|
1238
1354
|
try {
|
|
1239
|
-
|
|
1355
|
+
mkdirSync4(dirname3(cached), { recursive: true });
|
|
1240
1356
|
copyFileSync(path, cached);
|
|
1241
1357
|
} catch {}
|
|
1242
1358
|
}
|
|
@@ -1259,7 +1375,7 @@ async function downloadAndCacheWasm() {
|
|
|
1259
1375
|
if (!wasm) {
|
|
1260
1376
|
throw new Error(`1Password runtime archive did not contain ${WASM_TARBALL_ENTRY}`);
|
|
1261
1377
|
}
|
|
1262
|
-
|
|
1378
|
+
mkdirSync4(dirname3(cached), { recursive: true });
|
|
1263
1379
|
const tmp = `${cached}.tmp`;
|
|
1264
1380
|
writeFileSync4(tmp, wasm);
|
|
1265
1381
|
createRequire(import.meta.url)("node:fs").renameSync(tmp, cached);
|
|
@@ -1292,7 +1408,7 @@ function resolveNearbyWasmPath() {
|
|
|
1292
1408
|
try {
|
|
1293
1409
|
const require2 = createRequire(import.meta.url);
|
|
1294
1410
|
const coreJs = require2.resolve("@1password/sdk-core/nodejs/core.js");
|
|
1295
|
-
const wasm =
|
|
1411
|
+
const wasm = join5(dirname3(coreJs), WASM_FILENAME);
|
|
1296
1412
|
return existsSync3(wasm) ? wasm : null;
|
|
1297
1413
|
} catch {
|
|
1298
1414
|
return null;
|
|
@@ -1304,7 +1420,7 @@ function seedCacheFromNearbyWasm() {
|
|
|
1304
1420
|
return false;
|
|
1305
1421
|
try {
|
|
1306
1422
|
const cached = cacheWasmPath();
|
|
1307
|
-
|
|
1423
|
+
mkdirSync4(dirname3(cached), { recursive: true });
|
|
1308
1424
|
copyFileSync(real, cached);
|
|
1309
1425
|
return true;
|
|
1310
1426
|
} catch {
|
|
@@ -3658,6 +3774,7 @@ __export(exports_onepassword, {
|
|
|
3658
3774
|
valueTail: () => valueTail,
|
|
3659
3775
|
setScreenLockProbe: () => setScreenLockProbe,
|
|
3660
3776
|
setLockRetryTiming: () => setLockRetryTiming,
|
|
3777
|
+
setAppLockProbe: () => setAppLockProbe,
|
|
3661
3778
|
resolveSecretsPartial: () => resolveSecretsPartial,
|
|
3662
3779
|
resolveSecrets: () => resolveSecrets,
|
|
3663
3780
|
resolveSdkAuth: () => resolveSdkAuth,
|
|
@@ -3682,6 +3799,7 @@ __export(exports_onepassword, {
|
|
|
3682
3799
|
isOpHydratedVar: () => isOpHydratedVar,
|
|
3683
3800
|
isLockedDenial: () => isLockedDenial,
|
|
3684
3801
|
isGlobImport: () => isGlobImport,
|
|
3802
|
+
isAppLocked: () => isAppLocked,
|
|
3685
3803
|
globToRegExp: () => globToRegExp,
|
|
3686
3804
|
getOpFailures: () => getOpFailures,
|
|
3687
3805
|
filterGlobFields: () => filterGlobFields,
|
|
@@ -3692,8 +3810,12 @@ __export(exports_onepassword, {
|
|
|
3692
3810
|
defaultSdkClientFactory: () => defaultSdkClientFactory,
|
|
3693
3811
|
defaultScreenLockProbe: () => defaultScreenLockProbe,
|
|
3694
3812
|
defaultOpAccountLister: () => defaultOpAccountLister,
|
|
3813
|
+
defaultAppLockProbe: () => defaultAppLockProbe,
|
|
3814
|
+
currentLockCause: () => currentLockCause,
|
|
3695
3815
|
collectConfigImports: () => collectConfigImports,
|
|
3816
|
+
classifyLockedDenial: () => classifyLockedDenial,
|
|
3696
3817
|
buildAuthError: () => buildAuthError,
|
|
3818
|
+
appLockedFromSettings: () => appLockedFromSettings,
|
|
3697
3819
|
acquireSdkClient: () => acquireSdkClient,
|
|
3698
3820
|
OP_REF_RE: () => OP_REF_RE
|
|
3699
3821
|
});
|
|
@@ -3735,11 +3857,24 @@ function renderOpFailureNotice(envVar) {
|
|
|
3735
3857
|
}
|
|
3736
3858
|
lines.push("");
|
|
3737
3859
|
if (wasOpAuthorizationDenied()) {
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3860
|
+
const cause = currentLockCause();
|
|
3861
|
+
if (cause === "screen") {
|
|
3862
|
+
lines.push(" Your Mac is locked, so the 1Password approval prompt cannot be shown.");
|
|
3863
|
+
lines.push("");
|
|
3864
|
+
lines.push(" Fix: unlock the Mac, approve the prompt, and re-run.");
|
|
3865
|
+
} else if (cause === "app") {
|
|
3866
|
+
lines.push(" The 1Password app is LOCKED. With shared lock state (the default) a locked");
|
|
3867
|
+
lines.push(" app refuses the SDK outright \u2014 no approval prompt is ever shown, which is");
|
|
3868
|
+
lines.push(" why nothing appeared on screen.");
|
|
3869
|
+
lines.push("");
|
|
3870
|
+
lines.push(" Fix: unlock 1Password (Touch ID is enough) and re-run.");
|
|
3871
|
+
lines.push(" To stop it re-locking mid-session, raise Settings \u2192 Security \u2192 auto-lock.");
|
|
3872
|
+
} else {
|
|
3873
|
+
lines.push(" The 1Password desktop app declined to release secrets. The approval prompt");
|
|
3874
|
+
lines.push(" was most likely dismissed.");
|
|
3875
|
+
lines.push("");
|
|
3876
|
+
lines.push(" Fix: re-run and approve the 1Password prompt.");
|
|
3877
|
+
}
|
|
3743
3878
|
lines.push(" Headless (no desktop app): export OP_SERVICE_ACCOUNT_TOKEN='ops_...'");
|
|
3744
3879
|
} else {
|
|
3745
3880
|
lines.push(" Fix: check the reference resolves \u2014 claudish config \u2192 1Password tab.");
|
|
@@ -4092,25 +4227,57 @@ function setScreenLockProbe(probe) {
|
|
|
4092
4227
|
function isScreenLocked() {
|
|
4093
4228
|
return screenLockProbe();
|
|
4094
4229
|
}
|
|
4095
|
-
function
|
|
4230
|
+
function appLockedFromSettings(settings, nowSeconds) {
|
|
4231
|
+
if (typeof settings !== "object" || settings === null)
|
|
4232
|
+
return false;
|
|
4233
|
+
const s = settings;
|
|
4234
|
+
if (s["developers.sdkSharedLockState.enabled"] !== true)
|
|
4235
|
+
return false;
|
|
4236
|
+
const last = s["security.authenticatedUnlock.deviceBasedUnlock.lastUnlock"];
|
|
4237
|
+
const after = s["security.authenticatedUnlock.deviceBasedUnlock.askUnlockAfter"];
|
|
4238
|
+
if (typeof last !== "number" || typeof after !== "number")
|
|
4239
|
+
return false;
|
|
4240
|
+
return nowSeconds - last > after;
|
|
4241
|
+
}
|
|
4242
|
+
function setAppLockProbe(probe) {
|
|
4243
|
+
appLockProbe = probe ?? defaultAppLockProbe;
|
|
4244
|
+
}
|
|
4245
|
+
function isAppLocked() {
|
|
4246
|
+
return appLockProbe();
|
|
4247
|
+
}
|
|
4248
|
+
function currentLockCause() {
|
|
4249
|
+
if (isScreenLocked())
|
|
4250
|
+
return "screen";
|
|
4251
|
+
if (isAppLocked())
|
|
4252
|
+
return "app";
|
|
4253
|
+
return null;
|
|
4254
|
+
}
|
|
4255
|
+
function classifyLockedDenial(err, env = process.env) {
|
|
4096
4256
|
const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
|
|
4097
4257
|
if (!msg.includes("denied authorization"))
|
|
4098
|
-
return
|
|
4258
|
+
return null;
|
|
4099
4259
|
if (env.OP_SERVICE_ACCOUNT_TOKEN)
|
|
4100
|
-
return
|
|
4101
|
-
return
|
|
4260
|
+
return null;
|
|
4261
|
+
return currentLockCause();
|
|
4102
4262
|
}
|
|
4103
|
-
|
|
4263
|
+
function isLockedDenial(err, env = process.env) {
|
|
4264
|
+
return classifyLockedDenial(err, env) !== null;
|
|
4265
|
+
}
|
|
4266
|
+
async function countdownForUnlock(round, rounds, cause) {
|
|
4104
4267
|
const ttyOut = process.stderr.isTTY === true;
|
|
4105
4268
|
const ttyIn = process.stdin.isTTY === true;
|
|
4106
4269
|
let cancelled = false;
|
|
4107
4270
|
if (round === 1) {
|
|
4271
|
+
const explain = cause === "screen" ? `${bold("\uD83D\uDD10 1Password needs your OK \u2014 but your Mac is locked, so it can't ask.")}
|
|
4272
|
+
Unlock your Mac and approve the popup. Claudish picks it up from there.` : `${bold("\uD83D\uDD10 1Password is locked, so it turned claudish away without asking you.")}
|
|
4273
|
+
Unlock 1Password (Touch ID is enough). Claudish retries on its own \u2014
|
|
4274
|
+
no popup will appear until it's unlocked.`;
|
|
4108
4275
|
process.stderr.write(`
|
|
4109
|
-
${
|
|
4110
|
-
Unlock your Mac and approve the popup. Claudish picks it up from there.
|
|
4276
|
+
${explain}
|
|
4111
4277
|
|
|
4112
4278
|
`);
|
|
4113
4279
|
}
|
|
4280
|
+
const stillLocked = () => cause === "screen" ? isScreenLocked() : isAppLocked();
|
|
4114
4281
|
let restoreInput = () => {};
|
|
4115
4282
|
if (ttyIn) {
|
|
4116
4283
|
const onKey = (buf) => {
|
|
@@ -4141,7 +4308,7 @@ ${bold("\uD83D\uDD10 1Password needs your OK \u2014 but your Mac is locked, so i
|
|
|
4141
4308
|
for (let remaining = lockRetrySeconds;remaining > 0; remaining--) {
|
|
4142
4309
|
if (cancelled)
|
|
4143
4310
|
break;
|
|
4144
|
-
if (!
|
|
4311
|
+
if (!stillLocked())
|
|
4145
4312
|
break;
|
|
4146
4313
|
if (ttyOut)
|
|
4147
4314
|
process.stderr.write(`\r\x1B[2K${line(remaining)}`);
|
|
@@ -4164,9 +4331,10 @@ async function withSdkRetry(op, label = "op:sdk-op") {
|
|
|
4164
4331
|
try {
|
|
4165
4332
|
return await withSdkTransientRetry(op, label);
|
|
4166
4333
|
} catch (err) {
|
|
4167
|
-
|
|
4334
|
+
const cause = classifyLockedDenial(err);
|
|
4335
|
+
if (round > LOCK_RETRY_ROUNDS || cause === null)
|
|
4168
4336
|
throw err;
|
|
4169
|
-
if (await countdownForUnlock(round, LOCK_RETRY_ROUNDS) === "cancel")
|
|
4337
|
+
if (await countdownForUnlock(round, LOCK_RETRY_ROUNDS, cause) === "cancel")
|
|
4170
4338
|
throw err;
|
|
4171
4339
|
resetSdkClientCache();
|
|
4172
4340
|
}
|
|
@@ -4359,11 +4527,12 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
|
|
|
4359
4527
|
await ensureOpWasmAvailable2();
|
|
4360
4528
|
return Promise.resolve().then(() => __toESM(require_sdk(), 1));
|
|
4361
4529
|
});
|
|
4362
|
-
const
|
|
4530
|
+
const build2 = () => createClient({
|
|
4363
4531
|
auth: auth.kind === "token" ? auth.token : new DesktopAuth(auth.accountName),
|
|
4364
4532
|
integrationName: "claudish",
|
|
4365
4533
|
integrationVersion: VERSION || "1.0.0"
|
|
4366
|
-
})
|
|
4534
|
+
});
|
|
4535
|
+
const client = await traceSpan("op:client-handshake", () => auth.kind === "token" ? build2() : withHandshakeLock(build2), { mayIncludeUserPrompt: true, authKind: auth.kind });
|
|
4367
4536
|
return client;
|
|
4368
4537
|
})();
|
|
4369
4538
|
sdkClientCache.set(key, build);
|
|
@@ -4383,7 +4552,7 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
|
|
|
4383
4552
|
} catch {
|
|
4384
4553
|
return false;
|
|
4385
4554
|
}
|
|
4386
|
-
}, screenLockProbe, defaultOpAccountLister = () => {
|
|
4555
|
+
}, screenLockProbe, defaultAppLockProbe = () => false, appLockProbe, defaultOpAccountLister = () => {
|
|
4387
4556
|
try {
|
|
4388
4557
|
const res = spawnSync("op", ["account", "list", "--format=json"], { encoding: "utf-8" });
|
|
4389
4558
|
if (res.error || res.status !== 0)
|
|
@@ -4412,6 +4581,7 @@ var OP_REF_RE, opHydratedVars, opSourceFailures, ENV_VAR_NAME_RE, sdkClientCache
|
|
|
4412
4581
|
};
|
|
4413
4582
|
var init_onepassword = __esm(() => {
|
|
4414
4583
|
init_startup_trace();
|
|
4584
|
+
init_onepassword_handshake_lock();
|
|
4415
4585
|
OP_REF_RE = /^op:\/\/[^\s]+$/;
|
|
4416
4586
|
opHydratedVars = new Set;
|
|
4417
4587
|
opSourceFailures = [];
|
|
@@ -4420,18 +4590,34 @@ var init_onepassword = __esm(() => {
|
|
|
4420
4590
|
sdkQueue = Promise.resolve();
|
|
4421
4591
|
lockRetrySeconds = LOCK_RETRY_SECONDS;
|
|
4422
4592
|
screenLockProbe = defaultScreenLockProbe;
|
|
4593
|
+
appLockProbe = defaultAppLockProbe;
|
|
4423
4594
|
});
|
|
4424
4595
|
|
|
4425
4596
|
// src/auth/credentials/op-source.ts
|
|
4426
|
-
import { existsSync as existsSync4, readFileSync as
|
|
4427
|
-
import { homedir as
|
|
4428
|
-
import { join as
|
|
4597
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
4598
|
+
import { homedir as homedir6 } from "os";
|
|
4599
|
+
import { join as join6 } from "path";
|
|
4429
4600
|
function warnOnce(message) {
|
|
4430
4601
|
if (warnedMessages.has(message))
|
|
4431
4602
|
return;
|
|
4432
4603
|
warnedMessages.add(message);
|
|
4433
4604
|
console.error(message);
|
|
4434
4605
|
}
|
|
4606
|
+
function recordOpUnavailableVars(names) {
|
|
4607
|
+
for (const n of names) {
|
|
4608
|
+
if (typeof n === "string" && n.length > 0)
|
|
4609
|
+
opUnavailableVars.add(n);
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
function getOpUnavailableVars() {
|
|
4613
|
+
return [...opUnavailableVars].sort();
|
|
4614
|
+
}
|
|
4615
|
+
function inheritedUnavailable() {
|
|
4616
|
+
const raw = process.env[OP_UNAVAILABLE_ENV];
|
|
4617
|
+
if (!raw)
|
|
4618
|
+
return new Set;
|
|
4619
|
+
return new Set(raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0));
|
|
4620
|
+
}
|
|
4435
4621
|
function saveAccount(accountUrl, scope) {
|
|
4436
4622
|
try {
|
|
4437
4623
|
saveOnepasswordAccount(accountUrl, scope);
|
|
@@ -4517,10 +4703,10 @@ function readConfigRaw() {
|
|
|
4517
4703
|
if (testSeams?.config)
|
|
4518
4704
|
return testSeams.config;
|
|
4519
4705
|
try {
|
|
4520
|
-
const configPath = activeGlobalConfigFile(
|
|
4706
|
+
const configPath = activeGlobalConfigFile(join6(homedir6(), ".claudish", "config.json"));
|
|
4521
4707
|
if (!existsSync4(configPath))
|
|
4522
4708
|
return {};
|
|
4523
|
-
return JSON.parse(
|
|
4709
|
+
return JSON.parse(readFileSync4(configPath, "utf-8"));
|
|
4524
4710
|
} catch {
|
|
4525
4711
|
return {};
|
|
4526
4712
|
}
|
|
@@ -4623,12 +4809,12 @@ async function resolveGlobShared(globPath, auth) {
|
|
|
4623
4809
|
return { resolved: await existing, cacheHit: true };
|
|
4624
4810
|
const spanName = `op:glob-resolve(${maskGlobForTrace(globPath)})`;
|
|
4625
4811
|
const promise = (async () => {
|
|
4626
|
-
const { resolveGlobImportAll: resolveGlobImportAll2, recordOpHydratedVars: recordOpHydratedVars2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
|
|
4627
|
-
const resolved = await traceSpan(spanName, () => resolveGlobImportAll2(globPath, {
|
|
4812
|
+
const { resolveGlobImportAll: resolveGlobImportAll2, recordOpHydratedVars: recordOpHydratedVars2, withSdkRetry: withSdkRetry2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
|
|
4813
|
+
const resolved = await traceSpan(spanName, () => withSdkRetry2(() => resolveGlobImportAll2(globPath, {
|
|
4628
4814
|
auth,
|
|
4629
4815
|
sdkFactory: testSeams?.sdkFactory,
|
|
4630
4816
|
warn: (m) => console.error(m)
|
|
4631
|
-
}));
|
|
4817
|
+
}), spanName));
|
|
4632
4818
|
addSpanMeta(spanName, { vars: Object.keys(resolved).length });
|
|
4633
4819
|
for (const [k, v] of Object.entries(resolved)) {
|
|
4634
4820
|
resolvedCache.set(k, v);
|
|
@@ -4650,8 +4836,8 @@ async function resolveEnvironmentShared(envId, auth) {
|
|
|
4650
4836
|
return { resolved: await existing, cacheHit: true };
|
|
4651
4837
|
const spanName = `op:env-resolve(${envId})`;
|
|
4652
4838
|
const promise = (async () => {
|
|
4653
|
-
const { readEnvironment: readEnvironment2, recordOpHydratedVars: recordOpHydratedVars2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
|
|
4654
|
-
const resolved = await traceSpan(spanName, () => readEnvironment2(envId, { auth, sdkFactory: testSeams?.sdkFactory }));
|
|
4839
|
+
const { readEnvironment: readEnvironment2, recordOpHydratedVars: recordOpHydratedVars2, withSdkRetry: withSdkRetry2 } = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
|
|
4840
|
+
const resolved = await traceSpan(spanName, () => withSdkRetry2(() => readEnvironment2(envId, { auth, sdkFactory: testSeams?.sdkFactory }), spanName));
|
|
4655
4841
|
addSpanMeta(spanName, { vars: Object.keys(resolved).length });
|
|
4656
4842
|
for (const [k, v] of Object.entries(resolved)) {
|
|
4657
4843
|
resolvedCache.set(k, v);
|
|
@@ -4686,6 +4872,8 @@ async function resolveOpKeyForEnvVars(wanted, opts = {}) {
|
|
|
4686
4872
|
else
|
|
4687
4873
|
stillWanted.add(w);
|
|
4688
4874
|
}
|
|
4875
|
+
for (const skip of inheritedUnavailable())
|
|
4876
|
+
stillWanted.delete(skip);
|
|
4689
4877
|
if (stillWanted.size === 0)
|
|
4690
4878
|
return cached;
|
|
4691
4879
|
const label = `op:resolve(${[...stillWanted].sort().join(",")})`;
|
|
@@ -4712,6 +4900,7 @@ async function resolveOpKeyForEnvVars(wanted, opts = {}) {
|
|
|
4712
4900
|
resolvedCache.set(k, v);
|
|
4713
4901
|
out[k] = v;
|
|
4714
4902
|
}
|
|
4903
|
+
recordOpUnavailableVars([...wantNow].filter((w) => !(w in resolved)));
|
|
4715
4904
|
return out;
|
|
4716
4905
|
}, label);
|
|
4717
4906
|
}
|
|
@@ -4738,7 +4927,13 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
|
|
|
4738
4927
|
throw err;
|
|
4739
4928
|
}
|
|
4740
4929
|
}
|
|
4741
|
-
const {
|
|
4930
|
+
const {
|
|
4931
|
+
collectConfigImports: collectConfigImports2,
|
|
4932
|
+
resolveSecrets: resolveSecrets2,
|
|
4933
|
+
recordOpHydratedVars: recordOpHydratedVars2,
|
|
4934
|
+
recordOpFailure: recordOpFailure2,
|
|
4935
|
+
withSdkRetry: withSdkRetry2
|
|
4936
|
+
} = await Promise.resolve().then(() => (init_onepassword(), exports_onepassword));
|
|
4742
4937
|
const cfg = readConfigRaw();
|
|
4743
4938
|
const out = {};
|
|
4744
4939
|
try {
|
|
@@ -4751,10 +4946,7 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
|
|
|
4751
4946
|
wantedRefs[envVar] = ref;
|
|
4752
4947
|
}
|
|
4753
4948
|
if (Object.keys(wantedRefs).length > 0) {
|
|
4754
|
-
const resolved = await resolveSecrets2(wantedRefs, {
|
|
4755
|
-
auth,
|
|
4756
|
-
sdkFactory: testSeams?.sdkFactory
|
|
4757
|
-
});
|
|
4949
|
+
const resolved = await withSdkRetry2(() => resolveSecrets2(wantedRefs, { auth, sdkFactory: testSeams?.sdkFactory }), "op:resolve-refs");
|
|
4758
4950
|
Object.assign(out, resolved);
|
|
4759
4951
|
}
|
|
4760
4952
|
const stillWanted = new Set([...wanted].filter((w) => !(w in out)));
|
|
@@ -4791,10 +4983,7 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
|
|
|
4791
4983
|
customRefs[envVar] = apiKey;
|
|
4792
4984
|
}
|
|
4793
4985
|
if (Object.keys(customRefs).length > 0) {
|
|
4794
|
-
const resolved = await resolveSecrets2(customRefs, {
|
|
4795
|
-
auth,
|
|
4796
|
-
sdkFactory: testSeams?.sdkFactory
|
|
4797
|
-
});
|
|
4986
|
+
const resolved = await withSdkRetry2(() => resolveSecrets2(customRefs, { auth, sdkFactory: testSeams?.sdkFactory }), "op:resolve-custom-endpoint-refs");
|
|
4798
4987
|
Object.assign(out, resolved);
|
|
4799
4988
|
}
|
|
4800
4989
|
}
|
|
@@ -4837,11 +5026,12 @@ async function resolveOpKeyForEnvVarsInner(wanted, opts = {}, span) {
|
|
|
4837
5026
|
recordOpHydratedVars2(Object.keys(out));
|
|
4838
5027
|
return out;
|
|
4839
5028
|
}
|
|
4840
|
-
var warnedMessages, OpAuthError, cachedSdkAuth, sdkAuthResolved = false, authInFlight, testSeams, sniffed, opQueue, resolvedCache, globResolutions, globResolvedVars, environmentResolutions;
|
|
5029
|
+
var warnedMessages, opUnavailableVars, OP_UNAVAILABLE_ENV = "CLAUDISH_OP_UNAVAILABLE", OpAuthError, cachedSdkAuth, sdkAuthResolved = false, authInFlight, testSeams, sniffed, opQueue, resolvedCache, globResolutions, globResolvedVars, environmentResolutions;
|
|
4841
5030
|
var init_op_source = __esm(() => {
|
|
4842
5031
|
init_onepassword_config();
|
|
4843
5032
|
init_startup_trace();
|
|
4844
5033
|
warnedMessages = new Set;
|
|
5034
|
+
opUnavailableVars = new Set;
|
|
4845
5035
|
OpAuthError = class OpAuthError extends Error {
|
|
4846
5036
|
constructor(message) {
|
|
4847
5037
|
super(message);
|
|
@@ -26938,15 +27128,15 @@ __export(exports_profile_config, {
|
|
|
26938
27128
|
configExists: () => configExists,
|
|
26939
27129
|
activeConfigFile: () => activeConfigFile
|
|
26940
27130
|
});
|
|
26941
|
-
import { existsSync as existsSync5, mkdirSync as
|
|
26942
|
-
import { homedir as
|
|
26943
|
-
import { dirname as
|
|
27131
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
27132
|
+
import { homedir as homedir7 } from "os";
|
|
27133
|
+
import { dirname as dirname4, join as join7, parse as parse6 } from "path";
|
|
26944
27134
|
function activeConfigFile() {
|
|
26945
27135
|
return activeGlobalConfigFile(CONFIG_FILE);
|
|
26946
27136
|
}
|
|
26947
27137
|
function ensureConfigDir() {
|
|
26948
27138
|
if (!existsSync5(CONFIG_DIR)) {
|
|
26949
|
-
|
|
27139
|
+
mkdirSync5(CONFIG_DIR, { recursive: true });
|
|
26950
27140
|
}
|
|
26951
27141
|
}
|
|
26952
27142
|
function loadConfig() {
|
|
@@ -26957,7 +27147,7 @@ function loadConfig() {
|
|
|
26957
27147
|
return { ...DEFAULT_CONFIG };
|
|
26958
27148
|
}
|
|
26959
27149
|
try {
|
|
26960
|
-
const content =
|
|
27150
|
+
const content = readFileSync5(activeFile, "utf-8");
|
|
26961
27151
|
const config2 = JSON.parse(content);
|
|
26962
27152
|
const merged = {
|
|
26963
27153
|
version: config2.version || DEFAULT_CONFIG.version,
|
|
@@ -27027,26 +27217,26 @@ function getConfigPath() {
|
|
|
27027
27217
|
return CONFIG_FILE;
|
|
27028
27218
|
}
|
|
27029
27219
|
function getLocalConfigPath() {
|
|
27030
|
-
const home =
|
|
27220
|
+
const home = homedir7();
|
|
27031
27221
|
let dir = process.cwd();
|
|
27032
27222
|
const root = parse6(dir).root;
|
|
27033
27223
|
while (dir !== root && dir !== home) {
|
|
27034
|
-
const candidate =
|
|
27224
|
+
const candidate = join7(dir, LOCAL_CONFIG_FILENAME);
|
|
27035
27225
|
if (existsSync5(candidate))
|
|
27036
27226
|
return candidate;
|
|
27037
|
-
if (existsSync5(
|
|
27227
|
+
if (existsSync5(join7(dir, ".git"))) {
|
|
27038
27228
|
return candidate;
|
|
27039
27229
|
}
|
|
27040
|
-
dir =
|
|
27230
|
+
dir = dirname4(dir);
|
|
27041
27231
|
}
|
|
27042
|
-
return
|
|
27232
|
+
return join7(process.cwd(), LOCAL_CONFIG_FILENAME);
|
|
27043
27233
|
}
|
|
27044
27234
|
function localConfigExists() {
|
|
27045
27235
|
return existsSync5(getLocalConfigPath());
|
|
27046
27236
|
}
|
|
27047
27237
|
function isProjectDirectory() {
|
|
27048
27238
|
const cwd = process.cwd();
|
|
27049
|
-
return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) => existsSync5(
|
|
27239
|
+
return [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".claudish.json"].some((f) => existsSync5(join7(cwd, f)));
|
|
27050
27240
|
}
|
|
27051
27241
|
function loadLocalConfig() {
|
|
27052
27242
|
if (getConfigFileOverride())
|
|
@@ -27056,7 +27246,7 @@ function loadLocalConfig() {
|
|
|
27056
27246
|
return null;
|
|
27057
27247
|
}
|
|
27058
27248
|
try {
|
|
27059
|
-
const content =
|
|
27249
|
+
const content = readFileSync5(localPath, "utf-8");
|
|
27060
27250
|
const config2 = JSON.parse(content);
|
|
27061
27251
|
return {
|
|
27062
27252
|
...config2,
|
|
@@ -27315,8 +27505,8 @@ function disableLocalProvider(providerName) {
|
|
|
27315
27505
|
}
|
|
27316
27506
|
var CONFIG_DIR, CONFIG_FILE, LOCAL_CONFIG_FILENAME = ".claudish.json", DEFAULT_CONFIG;
|
|
27317
27507
|
var init_profile_config = __esm(() => {
|
|
27318
|
-
CONFIG_DIR =
|
|
27319
|
-
CONFIG_FILE =
|
|
27508
|
+
CONFIG_DIR = join7(homedir7(), ".claudish");
|
|
27509
|
+
CONFIG_FILE = join7(CONFIG_DIR, "config.json");
|
|
27320
27510
|
DEFAULT_CONFIG = {
|
|
27321
27511
|
version: "1.0.0",
|
|
27322
27512
|
defaultProfile: "default",
|
|
@@ -28043,8 +28233,8 @@ var init_provider_definitions = __esm(() => {
|
|
|
28043
28233
|
|
|
28044
28234
|
// src/auth/credentials/api-key-credential.ts
|
|
28045
28235
|
import { existsSync as existsSync6 } from "fs";
|
|
28046
|
-
import { homedir as
|
|
28047
|
-
import { join as
|
|
28236
|
+
import { homedir as homedir8 } from "os";
|
|
28237
|
+
import { join as join8 } from "path";
|
|
28048
28238
|
function realValue(v) {
|
|
28049
28239
|
if (!v)
|
|
28050
28240
|
return;
|
|
@@ -28086,7 +28276,7 @@ class ApiKeyCredentialProvider {
|
|
|
28086
28276
|
if (!this.oauthFallback)
|
|
28087
28277
|
return false;
|
|
28088
28278
|
try {
|
|
28089
|
-
return existsSync6(
|
|
28279
|
+
return existsSync6(join8(homedir8(), ".claudish", this.oauthFallback));
|
|
28090
28280
|
} catch {
|
|
28091
28281
|
return false;
|
|
28092
28282
|
}
|
|
@@ -28162,10 +28352,10 @@ var init_api_key_credential = __esm(() => {
|
|
|
28162
28352
|
// src/auth/codex-oauth.ts
|
|
28163
28353
|
import { exec } from "child_process";
|
|
28164
28354
|
import { createHash as createHash2, randomBytes } from "crypto";
|
|
28165
|
-
import { closeSync, existsSync as existsSync7, openSync, readFileSync as
|
|
28355
|
+
import { closeSync as closeSync2, existsSync as existsSync7, openSync as openSync2, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeSync as writeSync2 } from "fs";
|
|
28166
28356
|
import { createServer } from "http";
|
|
28167
|
-
import { homedir as
|
|
28168
|
-
import { join as
|
|
28357
|
+
import { homedir as homedir9 } from "os";
|
|
28358
|
+
import { join as join9 } from "path";
|
|
28169
28359
|
import { promisify } from "util";
|
|
28170
28360
|
|
|
28171
28361
|
class CodexOAuth {
|
|
@@ -28191,8 +28381,8 @@ class CodexOAuth {
|
|
|
28191
28381
|
return this.credentials !== null && !!this.credentials.refresh_token;
|
|
28192
28382
|
}
|
|
28193
28383
|
getCredentialsPath() {
|
|
28194
|
-
const claudishDir =
|
|
28195
|
-
return
|
|
28384
|
+
const claudishDir = join9(homedir9(), ".claudish");
|
|
28385
|
+
return join9(claudishDir, "codex-oauth.json");
|
|
28196
28386
|
}
|
|
28197
28387
|
async login() {
|
|
28198
28388
|
log("[CodexOAuth] Starting OAuth login flow");
|
|
@@ -28300,7 +28490,7 @@ Details: ${e.message}`);
|
|
|
28300
28490
|
return null;
|
|
28301
28491
|
}
|
|
28302
28492
|
try {
|
|
28303
|
-
const data =
|
|
28493
|
+
const data = readFileSync6(credPath, "utf-8");
|
|
28304
28494
|
const credentials = JSON.parse(data);
|
|
28305
28495
|
if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at) {
|
|
28306
28496
|
log("[CodexOAuth] Invalid credentials file structure");
|
|
@@ -28315,17 +28505,17 @@ Details: ${e.message}`);
|
|
|
28315
28505
|
}
|
|
28316
28506
|
saveCredentials(credentials) {
|
|
28317
28507
|
const credPath = this.getCredentialsPath();
|
|
28318
|
-
const claudishDir =
|
|
28508
|
+
const claudishDir = join9(homedir9(), ".claudish");
|
|
28319
28509
|
if (!existsSync7(claudishDir)) {
|
|
28320
|
-
const { mkdirSync:
|
|
28321
|
-
|
|
28510
|
+
const { mkdirSync: mkdirSync6 } = __require("fs");
|
|
28511
|
+
mkdirSync6(claudishDir, { recursive: true });
|
|
28322
28512
|
}
|
|
28323
|
-
const fd =
|
|
28513
|
+
const fd = openSync2(credPath, "w", 384);
|
|
28324
28514
|
try {
|
|
28325
28515
|
const data = JSON.stringify(credentials, null, 2);
|
|
28326
|
-
|
|
28516
|
+
writeSync2(fd, data, 0, "utf-8");
|
|
28327
28517
|
} finally {
|
|
28328
|
-
|
|
28518
|
+
closeSync2(fd);
|
|
28329
28519
|
}
|
|
28330
28520
|
log(`[CodexOAuth] Credentials saved to ${credPath}`);
|
|
28331
28521
|
}
|
|
@@ -28626,10 +28816,10 @@ var init_codex_credential = __esm(() => {
|
|
|
28626
28816
|
// src/auth/gemini-oauth.ts
|
|
28627
28817
|
import { exec as exec2 } from "child_process";
|
|
28628
28818
|
import { createHash as createHash3, randomBytes as randomBytes2 } from "crypto";
|
|
28629
|
-
import { closeSync as
|
|
28819
|
+
import { closeSync as closeSync3, existsSync as existsSync8, openSync as openSync3, readFileSync as readFileSync7, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "fs";
|
|
28630
28820
|
import { createServer as createServer2 } from "http";
|
|
28631
|
-
import { homedir as
|
|
28632
|
-
import { join as
|
|
28821
|
+
import { homedir as homedir10 } from "os";
|
|
28822
|
+
import { join as join10 } from "path";
|
|
28633
28823
|
import { promisify as promisify2 } from "util";
|
|
28634
28824
|
|
|
28635
28825
|
class GeminiOAuth {
|
|
@@ -28655,8 +28845,8 @@ class GeminiOAuth {
|
|
|
28655
28845
|
return this.credentials !== null && !!this.credentials.refresh_token;
|
|
28656
28846
|
}
|
|
28657
28847
|
getCredentialsPath() {
|
|
28658
|
-
const claudishDir =
|
|
28659
|
-
return
|
|
28848
|
+
const claudishDir = join10(homedir10(), ".claudish");
|
|
28849
|
+
return join10(claudishDir, "gemini-oauth.json");
|
|
28660
28850
|
}
|
|
28661
28851
|
async login() {
|
|
28662
28852
|
log("[GeminiOAuth] Starting OAuth login flow");
|
|
@@ -28758,7 +28948,7 @@ Details: ${e.message}`);
|
|
|
28758
28948
|
return null;
|
|
28759
28949
|
}
|
|
28760
28950
|
try {
|
|
28761
|
-
const data =
|
|
28951
|
+
const data = readFileSync7(credPath, "utf-8");
|
|
28762
28952
|
const credentials = JSON.parse(data);
|
|
28763
28953
|
if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at) {
|
|
28764
28954
|
log("[GeminiOAuth] Invalid credentials file structure");
|
|
@@ -28773,17 +28963,17 @@ Details: ${e.message}`);
|
|
|
28773
28963
|
}
|
|
28774
28964
|
saveCredentials(credentials) {
|
|
28775
28965
|
const credPath = this.getCredentialsPath();
|
|
28776
|
-
const claudishDir =
|
|
28966
|
+
const claudishDir = join10(homedir10(), ".claudish");
|
|
28777
28967
|
if (!existsSync8(claudishDir)) {
|
|
28778
|
-
const { mkdirSync:
|
|
28779
|
-
|
|
28968
|
+
const { mkdirSync: mkdirSync6 } = __require("fs");
|
|
28969
|
+
mkdirSync6(claudishDir, { recursive: true });
|
|
28780
28970
|
}
|
|
28781
|
-
const fd =
|
|
28971
|
+
const fd = openSync3(credPath, "w", 384);
|
|
28782
28972
|
try {
|
|
28783
28973
|
const data = JSON.stringify(credentials, null, 2);
|
|
28784
|
-
|
|
28974
|
+
writeSync3(fd, data, 0, "utf-8");
|
|
28785
28975
|
} finally {
|
|
28786
|
-
|
|
28976
|
+
closeSync3(fd);
|
|
28787
28977
|
}
|
|
28788
28978
|
log(`[GeminiOAuth] Credentials saved to ${credPath}`);
|
|
28789
28979
|
}
|
|
@@ -29137,18 +29327,18 @@ var init_gemini_oauth = __esm(() => {
|
|
|
29137
29327
|
});
|
|
29138
29328
|
|
|
29139
29329
|
// src/auth/oauth-registry.ts
|
|
29140
|
-
import { existsSync as existsSync9, readFileSync as
|
|
29141
|
-
import { homedir as
|
|
29142
|
-
import { join as
|
|
29330
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
|
|
29331
|
+
import { homedir as homedir11 } from "os";
|
|
29332
|
+
import { join as join11 } from "path";
|
|
29143
29333
|
function hasValidOAuthCredentials(descriptor) {
|
|
29144
|
-
const credPath =
|
|
29334
|
+
const credPath = join11(homedir11(), ".claudish", descriptor.credentialFile);
|
|
29145
29335
|
if (!existsSync9(credPath))
|
|
29146
29336
|
return false;
|
|
29147
29337
|
if (descriptor.validationMode === "file-exists") {
|
|
29148
29338
|
return true;
|
|
29149
29339
|
}
|
|
29150
29340
|
try {
|
|
29151
|
-
const data = JSON.parse(
|
|
29341
|
+
const data = JSON.parse(readFileSync8(credPath, "utf-8"));
|
|
29152
29342
|
if (!data.access_token)
|
|
29153
29343
|
return false;
|
|
29154
29344
|
if (data.refresh_token)
|
|
@@ -29258,9 +29448,9 @@ var init_gemini_credential = __esm(() => {
|
|
|
29258
29448
|
// src/auth/kimi-oauth.ts
|
|
29259
29449
|
import { exec as exec3 } from "child_process";
|
|
29260
29450
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
29261
|
-
import { closeSync as
|
|
29262
|
-
import { homedir as
|
|
29263
|
-
import { join as
|
|
29451
|
+
import { closeSync as closeSync4, existsSync as existsSync10, openSync as openSync4, readFileSync as readFileSync9, unlinkSync as unlinkSync4, writeSync as writeSync4 } from "fs";
|
|
29452
|
+
import { homedir as homedir12, hostname as hostname3, platform, release as release2 } from "os";
|
|
29453
|
+
import { join as join12 } from "path";
|
|
29264
29454
|
import { promisify as promisify3 } from "util";
|
|
29265
29455
|
|
|
29266
29456
|
class KimiOAuth {
|
|
@@ -29288,23 +29478,23 @@ class KimiOAuth {
|
|
|
29288
29478
|
return this.credentials !== null && !!this.credentials.refresh_token;
|
|
29289
29479
|
}
|
|
29290
29480
|
getCredentialsPath() {
|
|
29291
|
-
const claudishDir =
|
|
29292
|
-
return
|
|
29481
|
+
const claudishDir = join12(homedir12(), ".claudish");
|
|
29482
|
+
return join12(claudishDir, "kimi-oauth.json");
|
|
29293
29483
|
}
|
|
29294
29484
|
getDeviceIdPath() {
|
|
29295
|
-
const claudishDir =
|
|
29296
|
-
return
|
|
29485
|
+
const claudishDir = join12(homedir12(), ".claudish");
|
|
29486
|
+
return join12(claudishDir, "kimi-device-id");
|
|
29297
29487
|
}
|
|
29298
29488
|
loadOrCreateDeviceId() {
|
|
29299
29489
|
const deviceIdPath = this.getDeviceIdPath();
|
|
29300
|
-
const claudishDir =
|
|
29490
|
+
const claudishDir = join12(homedir12(), ".claudish");
|
|
29301
29491
|
if (!existsSync10(claudishDir)) {
|
|
29302
|
-
const { mkdirSync:
|
|
29303
|
-
|
|
29492
|
+
const { mkdirSync: mkdirSync6 } = __require("fs");
|
|
29493
|
+
mkdirSync6(claudishDir, { recursive: true });
|
|
29304
29494
|
}
|
|
29305
29495
|
if (existsSync10(deviceIdPath)) {
|
|
29306
29496
|
try {
|
|
29307
|
-
const deviceId2 =
|
|
29497
|
+
const deviceId2 = readFileSync9(deviceIdPath, "utf-8").trim();
|
|
29308
29498
|
if (deviceId2) {
|
|
29309
29499
|
return deviceId2;
|
|
29310
29500
|
}
|
|
@@ -29314,11 +29504,11 @@ class KimiOAuth {
|
|
|
29314
29504
|
}
|
|
29315
29505
|
const deviceId = randomBytes3(16).toString("hex").replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, "$1-$2-$3-$4-$5");
|
|
29316
29506
|
try {
|
|
29317
|
-
const fd =
|
|
29507
|
+
const fd = openSync4(deviceIdPath, "w", 384);
|
|
29318
29508
|
try {
|
|
29319
|
-
|
|
29509
|
+
writeSync4(fd, deviceId, 0, "utf-8");
|
|
29320
29510
|
} finally {
|
|
29321
|
-
|
|
29511
|
+
closeSync4(fd);
|
|
29322
29512
|
}
|
|
29323
29513
|
log(`[KimiOAuth] New device ID created: ${deviceId}`);
|
|
29324
29514
|
} catch (e) {
|
|
@@ -29335,7 +29525,7 @@ class KimiOAuth {
|
|
|
29335
29525
|
"X-Msh-Version": this.getVersion(),
|
|
29336
29526
|
"X-Msh-Device-Name": hostname3(),
|
|
29337
29527
|
"X-Msh-Device-Model": `${platform()}-${process.arch}`,
|
|
29338
|
-
"X-Msh-Os-Version":
|
|
29528
|
+
"X-Msh-Os-Version": release2(),
|
|
29339
29529
|
"X-Msh-Device-Id": this.deviceId
|
|
29340
29530
|
};
|
|
29341
29531
|
}
|
|
@@ -29563,7 +29753,7 @@ Details: ${e.message}`);
|
|
|
29563
29753
|
return null;
|
|
29564
29754
|
}
|
|
29565
29755
|
try {
|
|
29566
|
-
const data =
|
|
29756
|
+
const data = readFileSync9(credPath, "utf-8");
|
|
29567
29757
|
const credentials = JSON.parse(data);
|
|
29568
29758
|
if (!credentials.access_token || !credentials.refresh_token || !credentials.expires_at || !credentials.scope || !credentials.token_type) {
|
|
29569
29759
|
log("[KimiOAuth] Invalid credentials file structure");
|
|
@@ -29578,17 +29768,17 @@ Details: ${e.message}`);
|
|
|
29578
29768
|
}
|
|
29579
29769
|
saveCredentials(credentials) {
|
|
29580
29770
|
const credPath = this.getCredentialsPath();
|
|
29581
|
-
const claudishDir =
|
|
29771
|
+
const claudishDir = join12(homedir12(), ".claudish");
|
|
29582
29772
|
if (!existsSync10(claudishDir)) {
|
|
29583
|
-
const { mkdirSync:
|
|
29584
|
-
|
|
29773
|
+
const { mkdirSync: mkdirSync6 } = __require("fs");
|
|
29774
|
+
mkdirSync6(claudishDir, { recursive: true });
|
|
29585
29775
|
}
|
|
29586
|
-
const fd =
|
|
29776
|
+
const fd = openSync4(credPath, "w", 384);
|
|
29587
29777
|
try {
|
|
29588
29778
|
const data = JSON.stringify(credentials, null, 2);
|
|
29589
|
-
|
|
29779
|
+
writeSync4(fd, data, 0, "utf-8");
|
|
29590
29780
|
} finally {
|
|
29591
|
-
|
|
29781
|
+
closeSync4(fd);
|
|
29592
29782
|
}
|
|
29593
29783
|
log(`[KimiOAuth] Credentials saved to ${credPath}`);
|
|
29594
29784
|
}
|
|
@@ -29754,8 +29944,8 @@ var init_native_anthropic_credential = __esm(() => {
|
|
|
29754
29944
|
// src/auth/vertex-auth.ts
|
|
29755
29945
|
import { exec as exec4 } from "child_process";
|
|
29756
29946
|
import { existsSync as existsSync11 } from "fs";
|
|
29757
|
-
import { homedir as
|
|
29758
|
-
import { join as
|
|
29947
|
+
import { homedir as homedir13 } from "os";
|
|
29948
|
+
import { join as join13 } from "path";
|
|
29759
29949
|
import { promisify as promisify4 } from "util";
|
|
29760
29950
|
|
|
29761
29951
|
class VertexAuthManager {
|
|
@@ -29810,7 +30000,7 @@ class VertexAuthManager {
|
|
|
29810
30000
|
}
|
|
29811
30001
|
async tryADC() {
|
|
29812
30002
|
try {
|
|
29813
|
-
const adcPath =
|
|
30003
|
+
const adcPath = join13(homedir13(), ".config/gcloud/application_default_credentials.json");
|
|
29814
30004
|
if (!existsSync11(adcPath)) {
|
|
29815
30005
|
log("[VertexAuth] ADC credentials file not found");
|
|
29816
30006
|
return null;
|
|
@@ -29874,7 +30064,7 @@ function validateVertexOAuthConfig() {
|
|
|
29874
30064
|
` + ` export VERTEX_PROJECT='your-gcp-project-id'
|
|
29875
30065
|
` + " export VERTEX_LOCATION='us-central1' # optional";
|
|
29876
30066
|
}
|
|
29877
|
-
const adcPath =
|
|
30067
|
+
const adcPath = join13(homedir13(), ".config/gcloud/application_default_credentials.json");
|
|
29878
30068
|
const hasADC = existsSync11(adcPath);
|
|
29879
30069
|
const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
29880
30070
|
if (!hasADC && !hasServiceAccount) {
|
|
@@ -30422,15 +30612,15 @@ var init_routing_hints = __esm(() => {
|
|
|
30422
30612
|
});
|
|
30423
30613
|
|
|
30424
30614
|
// src/providers/all-models-cache.ts
|
|
30425
|
-
import { existsSync as existsSync12, mkdirSync as
|
|
30426
|
-
import { homedir as
|
|
30427
|
-
import { dirname as
|
|
30615
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
|
|
30616
|
+
import { homedir as homedir14 } from "os";
|
|
30617
|
+
import { dirname as dirname5, join as join14 } from "path";
|
|
30428
30618
|
function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
|
|
30429
30619
|
if (!existsSync12(path))
|
|
30430
30620
|
return null;
|
|
30431
30621
|
let raw;
|
|
30432
30622
|
try {
|
|
30433
|
-
raw = JSON.parse(
|
|
30623
|
+
raw = JSON.parse(readFileSync10(path, "utf-8"));
|
|
30434
30624
|
} catch {
|
|
30435
30625
|
return null;
|
|
30436
30626
|
}
|
|
@@ -30455,12 +30645,12 @@ function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
|
|
|
30455
30645
|
entries: data.entries ?? existing?.entries ?? [],
|
|
30456
30646
|
models: data.models ?? existing?.models ?? []
|
|
30457
30647
|
};
|
|
30458
|
-
|
|
30648
|
+
mkdirSync6(dirname5(path), { recursive: true });
|
|
30459
30649
|
writeFileSync6(path, JSON.stringify(merged), "utf-8");
|
|
30460
30650
|
}
|
|
30461
30651
|
var ALL_MODELS_CACHE_PATH;
|
|
30462
30652
|
var init_all_models_cache = __esm(() => {
|
|
30463
|
-
ALL_MODELS_CACHE_PATH =
|
|
30653
|
+
ALL_MODELS_CACHE_PATH = join14(homedir14(), ".claudish", "all-models.json");
|
|
30464
30654
|
});
|
|
30465
30655
|
|
|
30466
30656
|
// src/adapters/model-catalog.ts
|
|
@@ -31287,10 +31477,21 @@ async function prehydrateCredentialsForSpawn(models) {
|
|
|
31287
31477
|
return;
|
|
31288
31478
|
try {
|
|
31289
31479
|
await validateApiKeysForModels(wanted);
|
|
31480
|
+
publishOpSkipList();
|
|
31290
31481
|
} catch {}
|
|
31291
31482
|
}
|
|
31483
|
+
function publishOpSkipList() {
|
|
31484
|
+
if (getOpFailures().length > 0)
|
|
31485
|
+
return;
|
|
31486
|
+
const unavailable = getOpUnavailableVars();
|
|
31487
|
+
if (unavailable.length === 0)
|
|
31488
|
+
return;
|
|
31489
|
+
process.env[OP_UNAVAILABLE_ENV] = unavailable.join(",");
|
|
31490
|
+
}
|
|
31292
31491
|
var init_prehydrate = __esm(() => {
|
|
31492
|
+
init_onepassword();
|
|
31293
31493
|
init_provider_resolver();
|
|
31494
|
+
init_op_source();
|
|
31294
31495
|
});
|
|
31295
31496
|
|
|
31296
31497
|
// src/channel/diagnostics.ts
|
|
@@ -31545,9 +31746,9 @@ var init_signal_watcher = __esm(() => {
|
|
|
31545
31746
|
// src/channel/session-manager.ts
|
|
31546
31747
|
import { spawn } from "child_process";
|
|
31547
31748
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
31548
|
-
import { createWriteStream, mkdirSync as
|
|
31549
|
-
import { homedir as
|
|
31550
|
-
import { join as
|
|
31749
|
+
import { createWriteStream, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "fs";
|
|
31750
|
+
import { homedir as homedir15 } from "os";
|
|
31751
|
+
import { join as join15 } from "path";
|
|
31551
31752
|
|
|
31552
31753
|
class SessionManager {
|
|
31553
31754
|
sessions = new Map;
|
|
@@ -31567,10 +31768,10 @@ class SessionManager {
|
|
|
31567
31768
|
const sessionId = randomUUID2().slice(0, 8);
|
|
31568
31769
|
const timeout = Math.min(opts.timeoutSeconds ?? DEFAULT_TIMEOUT, MAX_TIMEOUT);
|
|
31569
31770
|
const startedAt = new Date().toISOString();
|
|
31570
|
-
const sessionDir =
|
|
31571
|
-
|
|
31771
|
+
const sessionDir = join15(homedir15(), ".claudish", "sessions", sessionId);
|
|
31772
|
+
mkdirSync7(sessionDir, { recursive: true });
|
|
31572
31773
|
if (opts.prompt) {
|
|
31573
|
-
writeFileSync7(
|
|
31774
|
+
writeFileSync7(join15(sessionDir, "prompt.md"), opts.prompt, "utf-8");
|
|
31574
31775
|
}
|
|
31575
31776
|
const args = ["--model", opts.model, "-y", "--stdin", "--quiet", ...opts.claudishFlags ?? []];
|
|
31576
31777
|
const proc = spawn("claudish", args, {
|
|
@@ -31597,7 +31798,7 @@ class SessionManager {
|
|
|
31597
31798
|
});
|
|
31598
31799
|
}
|
|
31599
31800
|
});
|
|
31600
|
-
const outputLogStream = createWriteStream(
|
|
31801
|
+
const outputLogStream = createWriteStream(join15(sessionDir, "output.log"));
|
|
31601
31802
|
const entry = {
|
|
31602
31803
|
info: {
|
|
31603
31804
|
sessionId,
|
|
@@ -31644,9 +31845,9 @@ class SessionManager {
|
|
|
31644
31845
|
watcher.processExited(code);
|
|
31645
31846
|
outputLogStream.end();
|
|
31646
31847
|
if (entry.stderr) {
|
|
31647
|
-
writeFileSync7(
|
|
31848
|
+
writeFileSync7(join15(sessionDir, "stderr.log"), entry.stderr, "utf-8");
|
|
31648
31849
|
}
|
|
31649
|
-
writeFileSync7(
|
|
31850
|
+
writeFileSync7(join15(sessionDir, "meta.json"), JSON.stringify(entry.info, null, 2), "utf-8");
|
|
31650
31851
|
this.cleanupSigint();
|
|
31651
31852
|
});
|
|
31652
31853
|
proc.on("error", (err) => {
|
|
@@ -31819,9 +32020,9 @@ var init_cache_ttl = __esm(() => {
|
|
|
31819
32020
|
});
|
|
31820
32021
|
|
|
31821
32022
|
// src/model-loader.ts
|
|
31822
|
-
import { existsSync as existsSync13, mkdirSync as
|
|
31823
|
-
import { homedir as
|
|
31824
|
-
import { join as
|
|
32023
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
32024
|
+
import { homedir as homedir16 } from "os";
|
|
32025
|
+
import { join as join16 } from "path";
|
|
31825
32026
|
function groupRecommendedModels(entries) {
|
|
31826
32027
|
const byId = new Map;
|
|
31827
32028
|
for (const entry of entries) {
|
|
@@ -31919,7 +32120,7 @@ async function getRecommendedModels(opts = {}) {
|
|
|
31919
32120
|
}
|
|
31920
32121
|
if (!forceRefresh && existsSync13(RECOMMENDED_MODELS_CACHE_PATH)) {
|
|
31921
32122
|
try {
|
|
31922
|
-
const cacheData = JSON.parse(
|
|
32123
|
+
const cacheData = JSON.parse(readFileSync11(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
|
|
31923
32124
|
if (cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
|
|
31924
32125
|
_cachedRecommendedModels = cacheData;
|
|
31925
32126
|
return cacheData;
|
|
@@ -31935,8 +32136,8 @@ async function getRecommendedModels(opts = {}) {
|
|
|
31935
32136
|
if (data.models && data.models.length > 0) {
|
|
31936
32137
|
_cachedRecommendedModels = data;
|
|
31937
32138
|
try {
|
|
31938
|
-
const cacheDir =
|
|
31939
|
-
|
|
32139
|
+
const cacheDir = join16(homedir16(), ".claudish");
|
|
32140
|
+
mkdirSync8(cacheDir, { recursive: true });
|
|
31940
32141
|
writeFileSync8(RECOMMENDED_MODELS_CACHE_PATH, JSON.stringify(data), "utf-8");
|
|
31941
32142
|
} catch {}
|
|
31942
32143
|
return data;
|
|
@@ -31950,7 +32151,7 @@ function getRecommendedModelsSync() {
|
|
|
31950
32151
|
return _cachedRecommendedModels;
|
|
31951
32152
|
if (existsSync13(RECOMMENDED_MODELS_CACHE_PATH)) {
|
|
31952
32153
|
try {
|
|
31953
|
-
const cacheData = JSON.parse(
|
|
32154
|
+
const cacheData = JSON.parse(readFileSync11(RECOMMENDED_MODELS_CACHE_PATH, "utf-8"));
|
|
31954
32155
|
if (cacheData.models && cacheData.models.length > 0 && isFreshEnough(cacheData)) {
|
|
31955
32156
|
_cachedRecommendedModels = cacheData;
|
|
31956
32157
|
return cacheData;
|
|
@@ -32074,7 +32275,7 @@ var _cachedModelInfo = null, _cachedModelIds = null, _cachedRecommendedModels =
|
|
|
32074
32275
|
var init_model_loader = __esm(() => {
|
|
32075
32276
|
init_cache_ttl();
|
|
32076
32277
|
FIREBASE_RECOMMENDED_URL = `${FIREBASE_BASE_URL}?catalog=recommended`;
|
|
32077
|
-
RECOMMENDED_MODELS_CACHE_PATH =
|
|
32278
|
+
RECOMMENDED_MODELS_CACHE_PATH = join16(homedir16(), ".claudish", "recommended-models-cache.json");
|
|
32078
32279
|
FIREBASE_SLUG_TO_PROVIDER_NAME = {
|
|
32079
32280
|
openai: "openai",
|
|
32080
32281
|
google: "google",
|
|
@@ -32122,6 +32323,44 @@ async function isPortAvailable(port) {
|
|
|
32122
32323
|
}
|
|
32123
32324
|
var init_port_manager = () => {};
|
|
32124
32325
|
|
|
32326
|
+
// src/redact.ts
|
|
32327
|
+
function isPlaceholder(value) {
|
|
32328
|
+
return PLACEHOLDER.test(value.trim());
|
|
32329
|
+
}
|
|
32330
|
+
function redactSecrets(text) {
|
|
32331
|
+
if (!text)
|
|
32332
|
+
return "";
|
|
32333
|
+
let out = text;
|
|
32334
|
+
out = out.replace(ASSIGNMENT_RE, (match, lhs, value) => isPlaceholder(value) ? match : `${lhs}${MASK}`);
|
|
32335
|
+
for (const { re } of TOKEN_PATTERNS) {
|
|
32336
|
+
out = out.replace(re, (match) => {
|
|
32337
|
+
const scheme = /^(Bearer|Basic|Token)\s/.exec(match);
|
|
32338
|
+
return scheme ? `${scheme[1]} ${MASK}` : MASK;
|
|
32339
|
+
});
|
|
32340
|
+
}
|
|
32341
|
+
return out;
|
|
32342
|
+
}
|
|
32343
|
+
function sanitizeForReport(text) {
|
|
32344
|
+
if (!text)
|
|
32345
|
+
return "";
|
|
32346
|
+
return redactSecrets(text).replace(/\/Users\/[^/\s]+/g, "/Users/***").replace(/\/home\/[^/\s]+/g, "/home/***").replace(/[A-Z]:\\Users\\[^\\\s]+/gi, "C:\\Users\\***").replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, "***@***.***");
|
|
32347
|
+
}
|
|
32348
|
+
var MASK = "***REDACTED***", PLACEHOLDER, ASSIGNMENT_RE, TOKEN_PATTERNS;
|
|
32349
|
+
var init_redact = __esm(() => {
|
|
32350
|
+
PLACEHOLDER = /^(['"`]?)(your[-_a-z0-9]*|<[^>]*>|\.\.\.|x{3,}|\*{3,}|REDACTED|CHANGEME|TODO|\$\{[^}]*\}|)(['"`]?)$/i;
|
|
32351
|
+
ASSIGNMENT_RE = /(["']?\b[A-Z][A-Z0-9_]*(?:_API_KEY|_KEY|_TOKEN|_SECRET|_PASSWORD)\b["']?\s*[:=]\s*)(["'`]?\$\{[^}]*\}["'`]?|["'`]?[^\s"'`,}]+["'`]?)/g;
|
|
32352
|
+
TOKEN_PATTERNS = [
|
|
32353
|
+
{ name: "sk", re: /\bsk-[A-Za-z0-9_-]{16,}/g },
|
|
32354
|
+
{ name: "google", re: /\bAIza[A-Za-z0-9_-]{20,}/g },
|
|
32355
|
+
{ name: "xai", re: /\bxai-[A-Za-z0-9_-]{16,}/g },
|
|
32356
|
+
{ name: "github", re: /\bgh[posur]_[A-Za-z0-9]{20,}/g },
|
|
32357
|
+
{ name: "aws", re: /\bAKIA[0-9A-Z]{12,}/g },
|
|
32358
|
+
{ name: "jwt", re: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g },
|
|
32359
|
+
{ name: "zhipu", re: /\b[0-9a-f]{32}\.[A-Za-z0-9]{16}\b/g },
|
|
32360
|
+
{ name: "bearer", re: /\b(?:Bearer|Basic|Token)\s+[A-Za-z0-9_.\-+/=]{12,}/g }
|
|
32361
|
+
];
|
|
32362
|
+
});
|
|
32363
|
+
|
|
32125
32364
|
// ../../node_modules/.bun/hono@4.10.6/node_modules/hono/dist/compose.js
|
|
32126
32365
|
var compose = (middleware, onError, onNotFound) => {
|
|
32127
32366
|
return (context, next) => {
|
|
@@ -34115,9 +34354,12 @@ function transformOpenAIToClaude(claudeRequestInput) {
|
|
|
34115
34354
|
var init_transform = () => {};
|
|
34116
34355
|
|
|
34117
34356
|
// src/handlers/shared/format/openai-tools.ts
|
|
34357
|
+
function emptyParamsSchema() {
|
|
34358
|
+
return { type: "object", properties: {} };
|
|
34359
|
+
}
|
|
34118
34360
|
function sanitizeSchemaForOpenAI(schema) {
|
|
34119
34361
|
if (!schema || typeof schema !== "object") {
|
|
34120
|
-
return
|
|
34362
|
+
return emptyParamsSchema();
|
|
34121
34363
|
}
|
|
34122
34364
|
let root = { ...schema };
|
|
34123
34365
|
const combinerKey = ["oneOf", "anyOf", "allOf"].find((k) => Array.isArray(root[k]) && root[k].length > 0);
|
|
@@ -34159,8 +34401,8 @@ function summarizeToolDescription(name, description) {
|
|
|
34159
34401
|
return firstSentence;
|
|
34160
34402
|
}
|
|
34161
34403
|
function summarizeToolParameters(schema) {
|
|
34162
|
-
if (!schema)
|
|
34163
|
-
return
|
|
34404
|
+
if (!schema || typeof schema !== "object")
|
|
34405
|
+
return emptyParamsSchema();
|
|
34164
34406
|
const summarized = sanitizeSchemaForOpenAI({ ...schema });
|
|
34165
34407
|
if (summarized.properties) {
|
|
34166
34408
|
for (const prop of Object.values(summarized.properties)) {
|
|
@@ -35122,7 +35364,21 @@ function createStreamingState() {
|
|
|
35122
35364
|
accumulatedText: ""
|
|
35123
35365
|
};
|
|
35124
35366
|
}
|
|
35125
|
-
function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap, priorInputTokens) {
|
|
35367
|
+
function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap, priorInputTokens, behavior) {
|
|
35368
|
+
const repairArgs = (toolName, argsJson) => {
|
|
35369
|
+
if (!behavior?.onToolCall)
|
|
35370
|
+
return argsJson;
|
|
35371
|
+
try {
|
|
35372
|
+
const repaired = behavior.onToolCall(toolName, argsJson);
|
|
35373
|
+
if (typeof repaired === "string" && repaired !== argsJson) {
|
|
35374
|
+
log(`[Streaming] tool call repaired by behavior layer: ${toolName}`);
|
|
35375
|
+
return repaired;
|
|
35376
|
+
}
|
|
35377
|
+
} catch (err) {
|
|
35378
|
+
log(`[Streaming] behavior onToolCall threw for ${toolName}: ${err}`);
|
|
35379
|
+
}
|
|
35380
|
+
return argsJson;
|
|
35381
|
+
};
|
|
35126
35382
|
log(`[Streaming] ===== HANDLER STARTED for ${target} =====`);
|
|
35127
35383
|
let isClosed = false;
|
|
35128
35384
|
let ping = null;
|
|
@@ -35187,7 +35443,10 @@ data: ${JSON.stringify(d)}
|
|
|
35187
35443
|
send("content_block_delta", {
|
|
35188
35444
|
type: "content_block_delta",
|
|
35189
35445
|
index: toolIdx,
|
|
35190
|
-
delta: {
|
|
35446
|
+
delta: {
|
|
35447
|
+
type: "input_json_delta",
|
|
35448
|
+
partial_json: repairArgs(tc.name, JSON.stringify(tc.arguments))
|
|
35449
|
+
}
|
|
35191
35450
|
});
|
|
35192
35451
|
send("content_block_stop", { type: "content_block_stop", index: toolIdx });
|
|
35193
35452
|
}
|
|
@@ -35203,7 +35462,7 @@ data: ${JSON.stringify(d)}
|
|
|
35203
35462
|
if (toolSchemas && toolSchemas.length > 0) {
|
|
35204
35463
|
const validation = validateToolArguments(t.name, t.arguments, toolSchemas, state.accumulatedText);
|
|
35205
35464
|
if (validation.valid || validation.repaired && validation.repairedArgs) {
|
|
35206
|
-
const argsJson = JSON.stringify(validation.repaired ? validation.repairedArgs : validation.parsedArgs);
|
|
35465
|
+
const argsJson = repairArgs(t.name, JSON.stringify(validation.repaired ? validation.repairedArgs : validation.parsedArgs));
|
|
35207
35466
|
log(`[Streaming] Sending buffered tool call (finish_reason!=tool_calls): ${t.name} with args: ${argsJson}`);
|
|
35208
35467
|
send("content_block_start", {
|
|
35209
35468
|
type: "content_block_start",
|
|
@@ -35226,7 +35485,7 @@ data: ${JSON.stringify(d)}
|
|
|
35226
35485
|
t.closed = true;
|
|
35227
35486
|
}
|
|
35228
35487
|
} else {
|
|
35229
|
-
const argsJson = t.arguments || "{}";
|
|
35488
|
+
const argsJson = repairArgs(t.name, t.arguments || "{}");
|
|
35230
35489
|
log(`[Streaming] Sending buffered tool call (no validation): ${t.name} with args: ${argsJson}`);
|
|
35231
35490
|
send("content_block_start", {
|
|
35232
35491
|
type: "content_block_start",
|
|
@@ -35423,7 +35682,7 @@ data: ${JSON.stringify(d)}
|
|
|
35423
35682
|
started: false,
|
|
35424
35683
|
closed: false,
|
|
35425
35684
|
arguments: "",
|
|
35426
|
-
buffered: !!toolSchemas && toolSchemas.length > 0
|
|
35685
|
+
buffered: !!toolSchemas && toolSchemas.length > 0 || behavior?.shouldBufferTool?.(restoredName) === true
|
|
35427
35686
|
};
|
|
35428
35687
|
state.tools.set(idx, t);
|
|
35429
35688
|
if (isWebSearchToolCall(restoredName)) {
|
|
@@ -35462,7 +35721,7 @@ data: ${JSON.stringify(d)}
|
|
|
35462
35721
|
const validation = validateToolArguments(t.name, t.arguments, toolSchemas, state.accumulatedText);
|
|
35463
35722
|
if (validation.repaired && validation.repairedArgs) {
|
|
35464
35723
|
log(`[Streaming] Tool call ${t.name} was repaired with inferred parameters`);
|
|
35465
|
-
const repairedJson = JSON.stringify(validation.repairedArgs);
|
|
35724
|
+
const repairedJson = repairArgs(t.name, JSON.stringify(validation.repairedArgs));
|
|
35466
35725
|
log(`[Streaming] Sending repaired tool call: ${t.name} with args: ${repairedJson}`);
|
|
35467
35726
|
if (t.buffered && !t.started) {
|
|
35468
35727
|
send("content_block_start", {
|
|
@@ -35538,7 +35797,7 @@ data: ${JSON.stringify(d)}
|
|
|
35538
35797
|
continue;
|
|
35539
35798
|
}
|
|
35540
35799
|
if (t.buffered && !t.started) {
|
|
35541
|
-
const argsJson = JSON.stringify(validation.parsedArgs);
|
|
35800
|
+
const argsJson = repairArgs(t.name, JSON.stringify(validation.parsedArgs));
|
|
35542
35801
|
send("content_block_start", {
|
|
35543
35802
|
type: "content_block_start",
|
|
35544
35803
|
index: t.blockIndex,
|
|
@@ -37720,7 +37979,7 @@ var init_openai = __esm(() => {
|
|
|
37720
37979
|
});
|
|
37721
37980
|
|
|
37722
37981
|
// src/providers/catalog-query.ts
|
|
37723
|
-
import { statSync } from "fs";
|
|
37982
|
+
import { statSync as statSync2 } from "fs";
|
|
37724
37983
|
function project(entry) {
|
|
37725
37984
|
return {
|
|
37726
37985
|
modelId: entry.modelId,
|
|
@@ -37733,7 +37992,7 @@ function project(entry) {
|
|
|
37733
37992
|
function getCachedEntries() {
|
|
37734
37993
|
let mtimeMs;
|
|
37735
37994
|
try {
|
|
37736
|
-
mtimeMs =
|
|
37995
|
+
mtimeMs = statSync2(ALL_MODELS_CACHE_PATH).mtimeMs;
|
|
37737
37996
|
} catch {
|
|
37738
37997
|
return null;
|
|
37739
37998
|
}
|
|
@@ -37908,24 +38167,24 @@ var init_vision_proxy = __esm(() => {
|
|
|
37908
38167
|
// src/stats-buffer.ts
|
|
37909
38168
|
import {
|
|
37910
38169
|
existsSync as existsSync14,
|
|
37911
|
-
mkdirSync as
|
|
37912
|
-
readFileSync as
|
|
38170
|
+
mkdirSync as mkdirSync9,
|
|
38171
|
+
readFileSync as readFileSync12,
|
|
37913
38172
|
renameSync,
|
|
37914
38173
|
unlinkSync as unlinkSync5,
|
|
37915
38174
|
writeFileSync as writeFileSync9
|
|
37916
38175
|
} from "fs";
|
|
37917
|
-
import { homedir as
|
|
37918
|
-
import { join as
|
|
38176
|
+
import { homedir as homedir17 } from "os";
|
|
38177
|
+
import { join as join17 } from "path";
|
|
37919
38178
|
function ensureDir() {
|
|
37920
38179
|
if (!existsSync14(CLAUDISH_DIR)) {
|
|
37921
|
-
|
|
38180
|
+
mkdirSync9(CLAUDISH_DIR, { recursive: true });
|
|
37922
38181
|
}
|
|
37923
38182
|
}
|
|
37924
38183
|
function readFromDisk() {
|
|
37925
38184
|
try {
|
|
37926
38185
|
if (!existsSync14(BUFFER_FILE))
|
|
37927
38186
|
return [];
|
|
37928
|
-
const raw2 =
|
|
38187
|
+
const raw2 = readFileSync12(BUFFER_FILE, "utf-8");
|
|
37929
38188
|
const parsed = JSON.parse(raw2);
|
|
37930
38189
|
if (!Array.isArray(parsed.events))
|
|
37931
38190
|
return [];
|
|
@@ -37950,7 +38209,7 @@ function writeToDisk(events) {
|
|
|
37950
38209
|
ensureDir();
|
|
37951
38210
|
const trimmed = enforceSizeCap([...events]);
|
|
37952
38211
|
const payload = { version: 1, events: trimmed };
|
|
37953
|
-
const tmpFile =
|
|
38212
|
+
const tmpFile = join17(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
|
|
37954
38213
|
writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
|
|
37955
38214
|
renameSync(tmpFile, BUFFER_FILE);
|
|
37956
38215
|
memoryCache = trimmed;
|
|
@@ -38023,8 +38282,8 @@ function syncFlushOnExit() {
|
|
|
38023
38282
|
var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false;
|
|
38024
38283
|
var init_stats_buffer = __esm(() => {
|
|
38025
38284
|
BUFFER_MAX_BYTES = 64 * 1024;
|
|
38026
|
-
CLAUDISH_DIR =
|
|
38027
|
-
BUFFER_FILE =
|
|
38285
|
+
CLAUDISH_DIR = join17(homedir17(), ".claudish");
|
|
38286
|
+
BUFFER_FILE = join17(CLAUDISH_DIR, "stats-buffer.json");
|
|
38028
38287
|
process.on("exit", syncFlushOnExit);
|
|
38029
38288
|
process.on("SIGTERM", () => {
|
|
38030
38289
|
try {
|
|
@@ -39206,6 +39465,70 @@ var init_stream_head_sniffer = __esm(() => {
|
|
|
39206
39465
|
});
|
|
39207
39466
|
|
|
39208
39467
|
// src/handlers/shared/stream-parsers/anthropic-sse.ts
|
|
39468
|
+
function createToolRepairInterceptor(opts) {
|
|
39469
|
+
const heldTools = new Map;
|
|
39470
|
+
const flush = (index, stopFrame) => {
|
|
39471
|
+
const held = heldTools.get(index);
|
|
39472
|
+
if (!held)
|
|
39473
|
+
return stopFrame;
|
|
39474
|
+
heldTools.delete(index);
|
|
39475
|
+
let finalArgs = held.args;
|
|
39476
|
+
try {
|
|
39477
|
+
const repaired = opts.repairToolArgs?.(held.name, finalArgs);
|
|
39478
|
+
if (typeof repaired === "string" && repaired !== finalArgs) {
|
|
39479
|
+
log(`[AnthropicSSE] tool call repaired: ${held.name}`);
|
|
39480
|
+
finalArgs = repaired;
|
|
39481
|
+
}
|
|
39482
|
+
} catch (err) {
|
|
39483
|
+
log(`[AnthropicSSE] repairToolArgs threw for ${held.name}: ${err}`);
|
|
39484
|
+
}
|
|
39485
|
+
const deltaFrame = `event: content_block_delta
|
|
39486
|
+
data: ${JSON.stringify({
|
|
39487
|
+
type: "content_block_delta",
|
|
39488
|
+
index,
|
|
39489
|
+
delta: { type: "input_json_delta", partial_json: finalArgs }
|
|
39490
|
+
})}
|
|
39491
|
+
|
|
39492
|
+
`;
|
|
39493
|
+
return `${deltaFrame}${stopFrame}`;
|
|
39494
|
+
};
|
|
39495
|
+
const noteToolStart = (data) => {
|
|
39496
|
+
if (data.content_block?.type !== "tool_use")
|
|
39497
|
+
return;
|
|
39498
|
+
const name = data.content_block.name;
|
|
39499
|
+
if (typeof name !== "string")
|
|
39500
|
+
return;
|
|
39501
|
+
if (!opts.shouldBufferTool?.(name))
|
|
39502
|
+
return;
|
|
39503
|
+
heldTools.set(data.index, { name, args: "" });
|
|
39504
|
+
};
|
|
39505
|
+
const absorbFragment = (data) => {
|
|
39506
|
+
if (data.delta?.type !== "input_json_delta")
|
|
39507
|
+
return false;
|
|
39508
|
+
const held = heldTools.get(data.index);
|
|
39509
|
+
if (!held)
|
|
39510
|
+
return false;
|
|
39511
|
+
held.args += data.delta.partial_json ?? "";
|
|
39512
|
+
return true;
|
|
39513
|
+
};
|
|
39514
|
+
return (data, line) => {
|
|
39515
|
+
const asIs = `${line}
|
|
39516
|
+
`;
|
|
39517
|
+
if (!opts.repairToolArgs || !opts.shouldBufferTool)
|
|
39518
|
+
return asIs;
|
|
39519
|
+
switch (data?.type) {
|
|
39520
|
+
case "content_block_start":
|
|
39521
|
+
noteToolStart(data);
|
|
39522
|
+
return asIs;
|
|
39523
|
+
case "content_block_delta":
|
|
39524
|
+
return absorbFragment(data) ? null : asIs;
|
|
39525
|
+
case "content_block_stop":
|
|
39526
|
+
return heldTools.has(data.index) ? flush(data.index, asIs) : asIs;
|
|
39527
|
+
default:
|
|
39528
|
+
return asIs;
|
|
39529
|
+
}
|
|
39530
|
+
};
|
|
39531
|
+
}
|
|
39209
39532
|
function createAnthropicPassthroughStream(c, response, opts) {
|
|
39210
39533
|
const encoder = new TextEncoder;
|
|
39211
39534
|
const decoder = new TextDecoder;
|
|
@@ -39213,6 +39536,14 @@ function createAnthropicPassthroughStream(c, response, opts) {
|
|
|
39213
39536
|
let lastActivity = Date.now();
|
|
39214
39537
|
let pingInterval = null;
|
|
39215
39538
|
const filterThinking = opts.adapter?.shouldFilterThinking() ?? false;
|
|
39539
|
+
const interceptToolFrame = createToolRepairInterceptor(opts);
|
|
39540
|
+
const enqueueData = (controller, data, line) => {
|
|
39541
|
+
if (isClosed)
|
|
39542
|
+
return;
|
|
39543
|
+
const out = interceptToolFrame(data, line);
|
|
39544
|
+
if (out !== null)
|
|
39545
|
+
controller.enqueue(encoder.encode(out));
|
|
39546
|
+
};
|
|
39216
39547
|
return c.body(new ReadableStream({
|
|
39217
39548
|
async start(controller) {
|
|
39218
39549
|
const sendPing = () => {
|
|
@@ -39295,10 +39626,7 @@ data: ${JSON.stringify({
|
|
|
39295
39626
|
`));
|
|
39296
39627
|
}
|
|
39297
39628
|
} else {
|
|
39298
|
-
|
|
39299
|
-
controller.enqueue(encoder.encode(`${line}
|
|
39300
|
-
`));
|
|
39301
|
-
}
|
|
39629
|
+
enqueueData(controller, data, line);
|
|
39302
39630
|
}
|
|
39303
39631
|
} catch {
|
|
39304
39632
|
if (!isClosed) {
|
|
@@ -39330,10 +39658,7 @@ data: ${JSON.stringify({
|
|
|
39330
39658
|
}
|
|
39331
39659
|
return;
|
|
39332
39660
|
}
|
|
39333
|
-
|
|
39334
|
-
controller.enqueue(encoder.encode(`${line}
|
|
39335
|
-
`));
|
|
39336
|
-
}
|
|
39661
|
+
enqueueData(controller, data, line);
|
|
39337
39662
|
if (data.message?.usage) {
|
|
39338
39663
|
inputTokens = data.message.usage.input_tokens || inputTokens;
|
|
39339
39664
|
outputTokens = data.message.usage.output_tokens || outputTokens;
|
|
@@ -39628,7 +39953,18 @@ data: ${JSON.stringify(data)}
|
|
|
39628
39953
|
const toolIdx = toolCalls.size;
|
|
39629
39954
|
const toolId = `toolu_${Date.now()}_${toolIdx}`;
|
|
39630
39955
|
const blockIndex = curIdx++;
|
|
39631
|
-
|
|
39956
|
+
let args = JSON.stringify(part.functionCall.args || {});
|
|
39957
|
+
if (opts.repairToolArgs) {
|
|
39958
|
+
try {
|
|
39959
|
+
const repaired = opts.repairToolArgs(part.functionCall.name, args);
|
|
39960
|
+
if (typeof repaired === "string" && repaired !== args) {
|
|
39961
|
+
log(`[GeminiSSE] tool call repaired: ${part.functionCall.name}`);
|
|
39962
|
+
args = repaired;
|
|
39963
|
+
}
|
|
39964
|
+
} catch (err) {
|
|
39965
|
+
log(`[GeminiSSE] repairToolArgs threw for ${part.functionCall.name}: ${err}`);
|
|
39966
|
+
}
|
|
39967
|
+
}
|
|
39632
39968
|
const t = {
|
|
39633
39969
|
id: toolId,
|
|
39634
39970
|
name: part.functionCall.name,
|
|
@@ -40227,9 +40563,9 @@ var init_openai_responses_sse = __esm(() => {
|
|
|
40227
40563
|
});
|
|
40228
40564
|
|
|
40229
40565
|
// src/handlers/shared/token-tracker.ts
|
|
40230
|
-
import { mkdirSync as
|
|
40231
|
-
import { homedir as
|
|
40232
|
-
import { join as
|
|
40566
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
|
|
40567
|
+
import { homedir as homedir18 } from "os";
|
|
40568
|
+
import { dirname as dirname6, join as join18 } from "path";
|
|
40233
40569
|
|
|
40234
40570
|
class TokenTracker {
|
|
40235
40571
|
port;
|
|
@@ -40372,9 +40708,10 @@ class TokenTracker {
|
|
|
40372
40708
|
if (this.quotaRemaining !== undefined) {
|
|
40373
40709
|
data.quota_remaining = this.quotaRemaining;
|
|
40374
40710
|
}
|
|
40375
|
-
const
|
|
40376
|
-
|
|
40377
|
-
|
|
40711
|
+
const override = process.env.CLAUDISH_TOKEN_FILE;
|
|
40712
|
+
const outPath = override || join18(homedir18(), ".claudish", `tokens-${this.port}.json`);
|
|
40713
|
+
mkdirSync10(dirname6(outPath), { recursive: true });
|
|
40714
|
+
writeFileSync10(outPath, JSON.stringify(data), "utf-8");
|
|
40378
40715
|
} catch (e) {
|
|
40379
40716
|
log(`[TokenTracker] Error writing token file: ${e}`);
|
|
40380
40717
|
}
|
|
@@ -40960,7 +41297,10 @@ class ComposedHandler {
|
|
|
40960
41297
|
const priorInputTokens = this.tokenTracker.getLastInputTokens();
|
|
40961
41298
|
switch (streamFormat) {
|
|
40962
41299
|
case "openai-sse":
|
|
40963
|
-
return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap, priorInputTokens
|
|
41300
|
+
return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap, priorInputTokens, behaviorSession && {
|
|
41301
|
+
shouldBufferTool: (name) => behaviorSession.interceptsTool(name),
|
|
41302
|
+
onToolCall: (name, argsJson) => behaviorSession.repairToolCall(name, argsJson)
|
|
41303
|
+
});
|
|
40964
41304
|
case "openai-responses-sse":
|
|
40965
41305
|
return createResponsesStreamHandler(c, response, {
|
|
40966
41306
|
modelName: this.bareModelName,
|
|
@@ -40977,7 +41317,9 @@ class ComposedHandler {
|
|
|
40977
41317
|
return createAnthropicPassthroughStream(c, response, {
|
|
40978
41318
|
modelName: this.bareModelName,
|
|
40979
41319
|
onTokenUpdate,
|
|
40980
|
-
adapter
|
|
41320
|
+
adapter,
|
|
41321
|
+
shouldBufferTool: (name) => behaviorSession?.interceptsTool(name) ?? false,
|
|
41322
|
+
repairToolArgs: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null
|
|
40981
41323
|
});
|
|
40982
41324
|
case "gemini-sse": {
|
|
40983
41325
|
const onToolCall = (toolId, name, thoughtSignature) => {
|
|
@@ -40991,6 +41333,7 @@ class ComposedHandler {
|
|
|
40991
41333
|
middlewareManager: this.middlewareManager,
|
|
40992
41334
|
onTokenUpdate,
|
|
40993
41335
|
onToolCall,
|
|
41336
|
+
repairToolArgs: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null,
|
|
40994
41337
|
unwrapResponse: this.options.unwrapGeminiResponse,
|
|
40995
41338
|
priorInputTokens
|
|
40996
41339
|
});
|
|
@@ -42871,11 +43214,11 @@ var init_ollama_api_format = __esm(() => {
|
|
|
42871
43214
|
});
|
|
42872
43215
|
|
|
42873
43216
|
// src/providers/api-key-provenance.ts
|
|
42874
|
-
import { existsSync as existsSync15, readFileSync as
|
|
42875
|
-
import { homedir as
|
|
42876
|
-
import { join as
|
|
43217
|
+
import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
|
|
43218
|
+
import { homedir as homedir19 } from "os";
|
|
43219
|
+
import { join as join19, resolve as resolve2 } from "path";
|
|
42877
43220
|
function activeConfigPath() {
|
|
42878
|
-
return activeGlobalConfigFile(
|
|
43221
|
+
return activeGlobalConfigFile(join19(homedir19(), ".claudish", "config.json"));
|
|
42879
43222
|
}
|
|
42880
43223
|
function configLayerLabel() {
|
|
42881
43224
|
return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
|
|
@@ -42954,7 +43297,7 @@ function readDotenvKey(envVars) {
|
|
|
42954
43297
|
const dotenvPath = resolve2(".env");
|
|
42955
43298
|
if (!existsSync15(dotenvPath))
|
|
42956
43299
|
return null;
|
|
42957
|
-
const parsed = import_dotenv.parse(
|
|
43300
|
+
const parsed = import_dotenv.parse(readFileSync13(dotenvPath, "utf-8"));
|
|
42958
43301
|
for (const v of envVars) {
|
|
42959
43302
|
if (parsed[v])
|
|
42960
43303
|
return parsed[v];
|
|
@@ -42969,7 +43312,7 @@ function readConfigKey(envVar) {
|
|
|
42969
43312
|
const configPath = activeConfigPath();
|
|
42970
43313
|
if (!existsSync15(configPath))
|
|
42971
43314
|
return null;
|
|
42972
|
-
const cfg = JSON.parse(
|
|
43315
|
+
const cfg = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
42973
43316
|
return cfg.apiKeys?.[envVar] || null;
|
|
42974
43317
|
} catch {
|
|
42975
43318
|
return null;
|
|
@@ -44527,9 +44870,9 @@ var init_poe = __esm(() => {
|
|
|
44527
44870
|
});
|
|
44528
44871
|
|
|
44529
44872
|
// src/services/pricing-cache.ts
|
|
44530
|
-
import { existsSync as existsSync16, readFileSync as
|
|
44531
|
-
import { homedir as
|
|
44532
|
-
import { join as
|
|
44873
|
+
import { existsSync as existsSync16, readFileSync as readFileSync14, statSync as statSync3 } from "fs";
|
|
44874
|
+
import { homedir as homedir20 } from "os";
|
|
44875
|
+
import { join as join20 } from "path";
|
|
44533
44876
|
function prefixMatch(modelName) {
|
|
44534
44877
|
for (const [key, pricing] of pricingMap) {
|
|
44535
44878
|
if (modelName.startsWith(key))
|
|
@@ -44569,10 +44912,10 @@ function loadDiskCache() {
|
|
|
44569
44912
|
try {
|
|
44570
44913
|
if (!existsSync16(CACHE_FILE))
|
|
44571
44914
|
return false;
|
|
44572
|
-
const stat =
|
|
44915
|
+
const stat = statSync3(CACHE_FILE);
|
|
44573
44916
|
const age = Date.now() - stat.mtimeMs;
|
|
44574
44917
|
const isFresh = age < CACHE_TTL_MS2;
|
|
44575
|
-
const raw2 =
|
|
44918
|
+
const raw2 = readFileSync14(CACHE_FILE, "utf-8");
|
|
44576
44919
|
const data = JSON.parse(raw2);
|
|
44577
44920
|
for (const [key, pricing] of Object.entries(data)) {
|
|
44578
44921
|
pricingMap.set(key, pricing);
|
|
@@ -44588,8 +44931,8 @@ var init_pricing_cache = __esm(() => {
|
|
|
44588
44931
|
init_logger();
|
|
44589
44932
|
init_catalog_query();
|
|
44590
44933
|
pricingMap = new Map;
|
|
44591
|
-
CACHE_DIR =
|
|
44592
|
-
CACHE_FILE =
|
|
44934
|
+
CACHE_DIR = join20(homedir20(), ".claudish");
|
|
44935
|
+
CACHE_FILE = join20(CACHE_DIR, "pricing-cache.json");
|
|
44593
44936
|
CACHE_TTL_MS2 = 24 * 60 * 60 * 1000;
|
|
44594
44937
|
});
|
|
44595
44938
|
|
|
@@ -45045,6 +45388,175 @@ var init_proxy_server = __esm(() => {
|
|
|
45045
45388
|
};
|
|
45046
45389
|
});
|
|
45047
45390
|
|
|
45391
|
+
// src/team-stats.ts
|
|
45392
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "fs";
|
|
45393
|
+
import { join as join21 } from "path";
|
|
45394
|
+
function statsDir(sessionPath) {
|
|
45395
|
+
return join21(sessionPath, "stats");
|
|
45396
|
+
}
|
|
45397
|
+
function tokenFileFor(sessionPath, anonId) {
|
|
45398
|
+
return join21(statsDir(sessionPath), `${anonId}.json`);
|
|
45399
|
+
}
|
|
45400
|
+
function readTokenStats(sessionPath, anonId) {
|
|
45401
|
+
const path = tokenFileFor(sessionPath, anonId);
|
|
45402
|
+
if (!existsSync17(path))
|
|
45403
|
+
return null;
|
|
45404
|
+
try {
|
|
45405
|
+
return JSON.parse(readFileSync15(path, "utf-8"));
|
|
45406
|
+
} catch {
|
|
45407
|
+
return null;
|
|
45408
|
+
}
|
|
45409
|
+
}
|
|
45410
|
+
function fmtTokens(n) {
|
|
45411
|
+
if (!n || n <= 0)
|
|
45412
|
+
return "0";
|
|
45413
|
+
if (n < 1000)
|
|
45414
|
+
return String(n);
|
|
45415
|
+
if (n < 1e6)
|
|
45416
|
+
return `${(n / 1000).toFixed(1)}k`;
|
|
45417
|
+
return `${(n / 1e6).toFixed(1)}M`;
|
|
45418
|
+
}
|
|
45419
|
+
function fmtCost(cost, isFree) {
|
|
45420
|
+
if (isFree)
|
|
45421
|
+
return "free";
|
|
45422
|
+
if (cost === undefined || cost <= 0)
|
|
45423
|
+
return "$0";
|
|
45424
|
+
return `$${cost.toFixed(3)}`;
|
|
45425
|
+
}
|
|
45426
|
+
function fmtBytes(n) {
|
|
45427
|
+
if (n <= 0)
|
|
45428
|
+
return "0B";
|
|
45429
|
+
if (n < 1024)
|
|
45430
|
+
return `${n}B`;
|
|
45431
|
+
if (n < 1024 * 1024)
|
|
45432
|
+
return `${(n / 1024).toFixed(1)}KB`;
|
|
45433
|
+
return `${(n / (1024 * 1024)).toFixed(1)}MB`;
|
|
45434
|
+
}
|
|
45435
|
+
function fmtState(state) {
|
|
45436
|
+
switch (state) {
|
|
45437
|
+
case "COMPLETED":
|
|
45438
|
+
return "done";
|
|
45439
|
+
case "RUNNING":
|
|
45440
|
+
return "run ";
|
|
45441
|
+
case "FAILED":
|
|
45442
|
+
return "FAIL";
|
|
45443
|
+
case "TIMEOUT":
|
|
45444
|
+
return "TIME";
|
|
45445
|
+
case "EMPTY":
|
|
45446
|
+
return "EMPT";
|
|
45447
|
+
case "PENDING":
|
|
45448
|
+
return "wait";
|
|
45449
|
+
default:
|
|
45450
|
+
return "? ";
|
|
45451
|
+
}
|
|
45452
|
+
}
|
|
45453
|
+
function renderTeamStats(sessionPath, manifest, status, opts) {
|
|
45454
|
+
const nameWidth = opts.modelNameWidth ?? 18;
|
|
45455
|
+
const ids = Object.keys(manifest.models).sort();
|
|
45456
|
+
let done = 0;
|
|
45457
|
+
let running = 0;
|
|
45458
|
+
let failed = 0;
|
|
45459
|
+
let totalTokens = 0;
|
|
45460
|
+
let totalCost = 0;
|
|
45461
|
+
let anyFree = false;
|
|
45462
|
+
const rows = [];
|
|
45463
|
+
for (const id of ids) {
|
|
45464
|
+
const m = status.models[id];
|
|
45465
|
+
if (!m)
|
|
45466
|
+
continue;
|
|
45467
|
+
const model = manifest.models[id]?.model ?? "unknown";
|
|
45468
|
+
const stats = readTokenStats(sessionPath, id);
|
|
45469
|
+
if (m.state === "COMPLETED")
|
|
45470
|
+
done++;
|
|
45471
|
+
else if (m.state === "RUNNING" || m.state === "PENDING")
|
|
45472
|
+
running++;
|
|
45473
|
+
else
|
|
45474
|
+
failed++;
|
|
45475
|
+
const inTok = stats?.input_tokens ?? 0;
|
|
45476
|
+
const outTok = stats?.output_tokens ?? 0;
|
|
45477
|
+
totalTokens += stats?.total_tokens ?? inTok + outTok;
|
|
45478
|
+
totalCost += stats?.total_cost ?? 0;
|
|
45479
|
+
if (stats?.is_free)
|
|
45480
|
+
anyFree = true;
|
|
45481
|
+
const name = model.length > nameWidth ? `${model.slice(0, nameWidth - 1)}\u2026` : model;
|
|
45482
|
+
const bytes = m.outputSize > 0 ? fmtBytes(m.outputSize) : "";
|
|
45483
|
+
const tokens = stats ? `${fmtTokens(inTok)}/${outTok > 0 ? fmtTokens(outTok) : "-"}` : "";
|
|
45484
|
+
const cost = stats ? fmtCost(stats.total_cost, stats.is_free) : "";
|
|
45485
|
+
rows.push(` ${id} ${name.padEnd(nameWidth)} ${fmtState(m.state)} ` + `${bytes.padStart(7)} ${tokens.padStart(12)} ${cost.padStart(7)}`.trimEnd());
|
|
45486
|
+
}
|
|
45487
|
+
const parts = [`${ids.length} models`];
|
|
45488
|
+
if (done)
|
|
45489
|
+
parts.push(`${done} done`);
|
|
45490
|
+
if (running)
|
|
45491
|
+
parts.push(`${running} running`);
|
|
45492
|
+
if (failed)
|
|
45493
|
+
parts.push(`${failed} failed`);
|
|
45494
|
+
parts.push(`${Math.round(opts.elapsedSeconds)}s`);
|
|
45495
|
+
if (totalTokens > 0)
|
|
45496
|
+
parts.push(`${fmtTokens(totalTokens)} tok`);
|
|
45497
|
+
if (totalCost > 0 || anyFree)
|
|
45498
|
+
parts.push(fmtCost(totalCost, anyFree && totalCost === 0));
|
|
45499
|
+
return [`team: ${parts.join(", ")}`, ...rows].join(`
|
|
45500
|
+
`);
|
|
45501
|
+
}
|
|
45502
|
+
function renderTeamStatsCompact(sessionPath, manifest, status, opts) {
|
|
45503
|
+
const ids = Object.keys(manifest.models).sort();
|
|
45504
|
+
let done = 0;
|
|
45505
|
+
let running = 0;
|
|
45506
|
+
let failed = 0;
|
|
45507
|
+
let totalTokens = 0;
|
|
45508
|
+
let totalCost = 0;
|
|
45509
|
+
const segs = [];
|
|
45510
|
+
for (const id of ids) {
|
|
45511
|
+
const m = status.models[id];
|
|
45512
|
+
if (!m)
|
|
45513
|
+
continue;
|
|
45514
|
+
const model = manifest.models[id]?.model ?? "unknown";
|
|
45515
|
+
const stats = readTokenStats(sessionPath, id);
|
|
45516
|
+
if (m.state === "COMPLETED")
|
|
45517
|
+
done++;
|
|
45518
|
+
else if (m.state === "RUNNING" || m.state === "PENDING")
|
|
45519
|
+
running++;
|
|
45520
|
+
else
|
|
45521
|
+
failed++;
|
|
45522
|
+
totalTokens += stats?.total_tokens ?? 0;
|
|
45523
|
+
totalCost += stats?.total_cost ?? 0;
|
|
45524
|
+
const bits = [id, model, fmtState(m.state).trim()];
|
|
45525
|
+
if (m.outputSize > 0)
|
|
45526
|
+
bits.push(fmtBytes(m.outputSize));
|
|
45527
|
+
else if (stats?.total_tokens)
|
|
45528
|
+
bits.push(`${fmtTokens(stats.total_tokens)} tok`);
|
|
45529
|
+
segs.push(bits.join(" "));
|
|
45530
|
+
}
|
|
45531
|
+
const counts = [];
|
|
45532
|
+
if (done)
|
|
45533
|
+
counts.push(`${done} done`);
|
|
45534
|
+
if (running)
|
|
45535
|
+
counts.push(`${running} run`);
|
|
45536
|
+
if (failed)
|
|
45537
|
+
counts.push(`${failed} fail`);
|
|
45538
|
+
const head = [`team ${ids.length}: ${counts.join(" ") || "starting"}`];
|
|
45539
|
+
head.push(`${Math.round(opts.elapsedSeconds)}s`);
|
|
45540
|
+
if (totalTokens > 0)
|
|
45541
|
+
head.push(`${fmtTokens(totalTokens)} tok`);
|
|
45542
|
+
if (totalCost > 0)
|
|
45543
|
+
head.push(fmtCost(totalCost));
|
|
45544
|
+
let line1 = head.join(" \xB7 ");
|
|
45545
|
+
if (line1.length > CHANNEL_LINE_BUDGET) {
|
|
45546
|
+
line1 = line1.replace(/^team \d+: /, `t${ids.length}: `);
|
|
45547
|
+
}
|
|
45548
|
+
return `${line1}
|
|
45549
|
+
${segs.join(" \xB7 ")}`;
|
|
45550
|
+
}
|
|
45551
|
+
function writeStatusFile(sessionPath, manifest, status, opts) {
|
|
45552
|
+
try {
|
|
45553
|
+
writeFileSync11(join21(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
|
|
45554
|
+
`, "utf-8");
|
|
45555
|
+
} catch {}
|
|
45556
|
+
}
|
|
45557
|
+
var CHANNEL_LINE_BUDGET = 58;
|
|
45558
|
+
var init_team_stats = () => {};
|
|
45559
|
+
|
|
45048
45560
|
// src/team-orchestrator.ts
|
|
45049
45561
|
var exports_team_orchestrator = {};
|
|
45050
45562
|
__export(exports_team_orchestrator, {
|
|
@@ -45055,19 +45567,62 @@ __export(exports_team_orchestrator, {
|
|
|
45055
45567
|
judgeResponses: () => judgeResponses,
|
|
45056
45568
|
getStatus: () => getStatus,
|
|
45057
45569
|
fisherYatesShuffle: () => fisherYatesShuffle,
|
|
45570
|
+
classifyRunOutput: () => classifyRunOutput,
|
|
45058
45571
|
buildJudgePrompt: () => buildJudgePrompt,
|
|
45059
|
-
aggregateVerdict: () => aggregateVerdict
|
|
45572
|
+
aggregateVerdict: () => aggregateVerdict,
|
|
45573
|
+
STDOUT_TAIL_LIMIT: () => STDOUT_TAIL_LIMIT,
|
|
45574
|
+
DEFAULT_MIN_OUTPUT_BYTES: () => DEFAULT_MIN_OUTPUT_BYTES
|
|
45060
45575
|
});
|
|
45061
45576
|
import { spawn as spawn2 } from "child_process";
|
|
45062
45577
|
import {
|
|
45063
45578
|
createWriteStream as createWriteStream2,
|
|
45064
|
-
existsSync as
|
|
45065
|
-
mkdirSync as
|
|
45066
|
-
readFileSync as
|
|
45579
|
+
existsSync as existsSync18,
|
|
45580
|
+
mkdirSync as mkdirSync11,
|
|
45581
|
+
readFileSync as readFileSync16,
|
|
45067
45582
|
readdirSync as readdirSync2,
|
|
45068
|
-
writeFileSync as
|
|
45583
|
+
writeFileSync as writeFileSync12
|
|
45069
45584
|
} from "fs";
|
|
45070
|
-
import { join as
|
|
45585
|
+
import { join as join22, resolve as resolve3 } from "path";
|
|
45586
|
+
function classifyRunOutput(opts) {
|
|
45587
|
+
const { outputSize, stdoutTail, stderr, minOutputBytes } = opts;
|
|
45588
|
+
const apiError = API_ERROR_RE.exec(stdoutTail);
|
|
45589
|
+
if (apiError) {
|
|
45590
|
+
return {
|
|
45591
|
+
reason: "api_error",
|
|
45592
|
+
detail: `Child exited 0 but stdout carries an API error: ${apiError[1]?.trim() || "unknown"}`
|
|
45593
|
+
};
|
|
45594
|
+
}
|
|
45595
|
+
const bgCeiling = BG_CEILING_RE.exec(stderr);
|
|
45596
|
+
if (bgCeiling) {
|
|
45597
|
+
return {
|
|
45598
|
+
reason: "background_task_ceiling",
|
|
45599
|
+
detail: `Claude Code terminated the turn after ${bgCeiling[1]}s waiting on background tasks, ` + `flushing only partial output. Set CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 in the child ` + `environment to wait indefinitely, or tell the model not to spawn background work.`
|
|
45600
|
+
};
|
|
45601
|
+
}
|
|
45602
|
+
const tailIsWholeOutput = outputSize <= STDOUT_TAIL_LIMIT;
|
|
45603
|
+
if (outputSize === 0 || tailIsWholeOutput && stdoutTail.trim().length === 0) {
|
|
45604
|
+
return {
|
|
45605
|
+
reason: "empty_output",
|
|
45606
|
+
detail: `Child exited 0 but produced no non-whitespace output (${outputSize} B).`
|
|
45607
|
+
};
|
|
45608
|
+
}
|
|
45609
|
+
if (minOutputBytes > 0 && outputSize < minOutputBytes) {
|
|
45610
|
+
return {
|
|
45611
|
+
reason: "empty_output",
|
|
45612
|
+
detail: `Child exited 0 but produced only ${outputSize} B of stdout ` + `(caller required at least ${minOutputBytes} B).`
|
|
45613
|
+
};
|
|
45614
|
+
}
|
|
45615
|
+
return null;
|
|
45616
|
+
}
|
|
45617
|
+
function persistErrorLog(errorLogPath, header, stderr, stdoutTail) {
|
|
45618
|
+
const parts = [`=== ${redactSecrets(header)} ===`, ""];
|
|
45619
|
+
parts.push("--- stderr ---", stderr.trim() ? redactSecrets(stderr) : "(empty)", "");
|
|
45620
|
+
parts.push("--- stdout (tail) ---", stdoutTail.trim() ? redactSecrets(stdoutTail) : "(empty)", "");
|
|
45621
|
+
try {
|
|
45622
|
+
writeFileSync12(errorLogPath, parts.join(`
|
|
45623
|
+
`), "utf-8");
|
|
45624
|
+
} catch {}
|
|
45625
|
+
}
|
|
45071
45626
|
function validateSessionPath(sessionPath) {
|
|
45072
45627
|
const resolved = resolve3(sessionPath);
|
|
45073
45628
|
const cwd = process.cwd();
|
|
@@ -45088,18 +45643,18 @@ function setupSession(sessionPath, models, input) {
|
|
|
45088
45643
|
if (models.length === 0) {
|
|
45089
45644
|
throw new Error("At least one model is required");
|
|
45090
45645
|
}
|
|
45091
|
-
if (
|
|
45646
|
+
if (existsSync18(join22(sessionPath, "manifest.json"))) {
|
|
45092
45647
|
throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
|
|
45093
45648
|
}
|
|
45094
45649
|
const sentinels = models.filter(isSentinelModel);
|
|
45095
45650
|
if (sentinels.length > 0) {
|
|
45096
45651
|
throw new Error(`Invalid model(s) for team run: ${sentinels.join(", ")}. These are Claude Code agent selectors, not external model IDs. Use real external models (e.g., "gemini-2.0-flash", "gpt-4o", "or@deepseek/deepseek-r1"). For Claude models, use a Task agent instead of the team tool.`);
|
|
45097
45652
|
}
|
|
45098
|
-
|
|
45099
|
-
|
|
45653
|
+
mkdirSync11(join22(sessionPath, "work"), { recursive: true });
|
|
45654
|
+
mkdirSync11(join22(sessionPath, "errors"), { recursive: true });
|
|
45100
45655
|
if (input !== undefined) {
|
|
45101
|
-
|
|
45102
|
-
} else if (!
|
|
45656
|
+
writeFileSync12(join22(sessionPath, "input.md"), input, "utf-8");
|
|
45657
|
+
} else if (!existsSync18(join22(sessionPath, "input.md"))) {
|
|
45103
45658
|
throw new Error(`No input.md found at ${sessionPath} and no input provided`);
|
|
45104
45659
|
}
|
|
45105
45660
|
const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
|
|
@@ -45116,9 +45671,9 @@ function setupSession(sessionPath, models, input) {
|
|
|
45116
45671
|
model: models[i],
|
|
45117
45672
|
assignedAt: now
|
|
45118
45673
|
};
|
|
45119
|
-
|
|
45674
|
+
mkdirSync11(join22(sessionPath, "work", anonId), { recursive: true });
|
|
45120
45675
|
}
|
|
45121
|
-
|
|
45676
|
+
writeFileSync12(join22(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
|
|
45122
45677
|
const status = {
|
|
45123
45678
|
startedAt: now,
|
|
45124
45679
|
models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
|
|
@@ -45132,22 +45687,25 @@ function setupSession(sessionPath, models, input) {
|
|
|
45132
45687
|
}
|
|
45133
45688
|
]))
|
|
45134
45689
|
};
|
|
45135
|
-
|
|
45690
|
+
writeFileSync12(join22(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
|
|
45136
45691
|
return manifest;
|
|
45137
45692
|
}
|
|
45138
45693
|
async function runModels(sessionPath, opts = {}) {
|
|
45139
45694
|
const timeoutMs = (opts.timeout ?? 300) * 1000;
|
|
45140
|
-
const manifest = JSON.parse(
|
|
45141
|
-
const statusPath =
|
|
45142
|
-
const inputPath =
|
|
45143
|
-
const inputContent =
|
|
45695
|
+
const manifest = JSON.parse(readFileSync16(join22(sessionPath, "manifest.json"), "utf-8"));
|
|
45696
|
+
const statusPath = join22(sessionPath, "status.json");
|
|
45697
|
+
const inputPath = join22(sessionPath, "input.md");
|
|
45698
|
+
const inputContent = readFileSync16(inputPath, "utf-8");
|
|
45144
45699
|
await prehydrateCredentialsForSpawn(Object.values(manifest.models).map((m) => m.model));
|
|
45145
|
-
const statusCache = JSON.parse(
|
|
45700
|
+
const statusCache = JSON.parse(readFileSync16(statusPath, "utf-8"));
|
|
45146
45701
|
function updateModelStatus(id, update) {
|
|
45147
45702
|
statusCache.models[id] = { ...statusCache.models[id], ...update };
|
|
45148
|
-
|
|
45703
|
+
writeFileSync12(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
45149
45704
|
}
|
|
45705
|
+
const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
|
|
45706
|
+
mkdirSync11(statsDir(sessionPath), { recursive: true });
|
|
45150
45707
|
const processes = new Map;
|
|
45708
|
+
const runtimes = new Map;
|
|
45151
45709
|
const sigintHandler = () => {
|
|
45152
45710
|
for (const [, proc] of processes) {
|
|
45153
45711
|
if (!proc.killed)
|
|
@@ -45158,8 +45716,8 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45158
45716
|
process.on("SIGINT", sigintHandler);
|
|
45159
45717
|
const completionPromises = [];
|
|
45160
45718
|
for (const [anonId, entry] of Object.entries(manifest.models)) {
|
|
45161
|
-
const outputPath =
|
|
45162
|
-
const errorLogPath =
|
|
45719
|
+
const outputPath = join22(sessionPath, `response-${anonId}.md`);
|
|
45720
|
+
const errorLogPath = join22(sessionPath, "errors", `${anonId}.log`);
|
|
45163
45721
|
const args = ["--model", entry.model, "-y", "--stdin", "--quiet", ...opts.claudeFlags ?? []];
|
|
45164
45722
|
updateModelStatus(anonId, {
|
|
45165
45723
|
state: "RUNNING",
|
|
@@ -45167,11 +45725,17 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45167
45725
|
});
|
|
45168
45726
|
const proc = spawn2("claudish", args, {
|
|
45169
45727
|
stdio: ["pipe", "pipe", "pipe"],
|
|
45170
|
-
shell: false
|
|
45728
|
+
shell: false,
|
|
45729
|
+
env: {
|
|
45730
|
+
...process.env,
|
|
45731
|
+
CLAUDISH_TOKEN_FILE: tokenFileFor(sessionPath, anonId)
|
|
45732
|
+
}
|
|
45171
45733
|
});
|
|
45172
45734
|
let byteCount = 0;
|
|
45735
|
+
let stdoutTail = "";
|
|
45173
45736
|
proc.stdout?.on("data", (chunk) => {
|
|
45174
45737
|
byteCount += chunk.length;
|
|
45738
|
+
stdoutTail = (stdoutTail + chunk.toString()).slice(-STDOUT_TAIL_LIMIT);
|
|
45175
45739
|
});
|
|
45176
45740
|
const outputStream = createWriteStream2(outputPath);
|
|
45177
45741
|
proc.stdout?.pipe(outputStream);
|
|
@@ -45179,6 +45743,14 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45179
45743
|
proc.stderr?.on("data", (chunk) => {
|
|
45180
45744
|
stderr += chunk.toString();
|
|
45181
45745
|
});
|
|
45746
|
+
const command = `claudish ${args.join(" ")}`;
|
|
45747
|
+
runtimes.set(anonId, {
|
|
45748
|
+
command,
|
|
45749
|
+
errorLogPath,
|
|
45750
|
+
getStderr: () => stderr,
|
|
45751
|
+
getStdoutTail: () => stdoutTail,
|
|
45752
|
+
getByteCount: () => byteCount
|
|
45753
|
+
});
|
|
45182
45754
|
proc.stdin?.write(inputContent);
|
|
45183
45755
|
proc.stdin?.end();
|
|
45184
45756
|
const completionPromise = new Promise((resolve4) => {
|
|
@@ -45194,20 +45766,39 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45194
45766
|
}
|
|
45195
45767
|
resolved = true;
|
|
45196
45768
|
const outputSize = byteCount;
|
|
45197
|
-
const
|
|
45198
|
-
|
|
45199
|
-
|
|
45200
|
-
|
|
45201
|
-
|
|
45202
|
-
|
|
45203
|
-
|
|
45204
|
-
|
|
45205
|
-
|
|
45206
|
-
|
|
45207
|
-
|
|
45208
|
-
|
|
45209
|
-
|
|
45210
|
-
|
|
45769
|
+
const crashed = exitCode !== 0;
|
|
45770
|
+
const degraded = crashed ? null : classifyRunOutput({ outputSize, stdoutTail, stderr, minOutputBytes });
|
|
45771
|
+
const failed = crashed || degraded !== null;
|
|
45772
|
+
const state = crashed ? "FAILED" : degraded ? "EMPTY" : "COMPLETED";
|
|
45773
|
+
if (failed) {
|
|
45774
|
+
const reason = crashed ? "nonzero_exit" : degraded.reason;
|
|
45775
|
+
const detail = crashed ? `Child exited with code ${exitCode}.` : degraded.detail;
|
|
45776
|
+
persistErrorLog(errorLogPath, `${state}: ${detail}`, stderr, stdoutTail);
|
|
45777
|
+
updateModelStatus(anonId, {
|
|
45778
|
+
state,
|
|
45779
|
+
exitCode: exitCode ?? 1,
|
|
45780
|
+
completedAt: new Date().toISOString(),
|
|
45781
|
+
outputSize,
|
|
45782
|
+
error: {
|
|
45783
|
+
model: anonId,
|
|
45784
|
+
command,
|
|
45785
|
+
reason,
|
|
45786
|
+
detail,
|
|
45787
|
+
stderrSnippet: stderr ? redactSecrets(stderr).slice(-2000) : undefined,
|
|
45788
|
+
stdoutSnippet: stdoutTail ? redactSecrets(stdoutTail).slice(-2000) : undefined,
|
|
45789
|
+
errorLogPath,
|
|
45790
|
+
workDir: sessionPath
|
|
45791
|
+
}
|
|
45792
|
+
});
|
|
45793
|
+
} else {
|
|
45794
|
+
updateModelStatus(anonId, {
|
|
45795
|
+
state,
|
|
45796
|
+
exitCode: exitCode ?? 0,
|
|
45797
|
+
completedAt: new Date().toISOString(),
|
|
45798
|
+
outputSize,
|
|
45799
|
+
error: undefined
|
|
45800
|
+
});
|
|
45801
|
+
}
|
|
45211
45802
|
opts.onStatusChange?.(anonId, statusCache.models[anonId]);
|
|
45212
45803
|
resolve4();
|
|
45213
45804
|
};
|
|
@@ -45220,7 +45811,7 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45220
45811
|
return;
|
|
45221
45812
|
}
|
|
45222
45813
|
if (stderr) {
|
|
45223
|
-
|
|
45814
|
+
writeFileSync12(errorLogPath, redactSecrets(stderr), "utf-8");
|
|
45224
45815
|
}
|
|
45225
45816
|
exitCode = code;
|
|
45226
45817
|
if (outputStream.destroyed) {
|
|
@@ -45231,6 +45822,36 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45231
45822
|
processes.set(anonId, proc);
|
|
45232
45823
|
completionPromises.push(completionPromise);
|
|
45233
45824
|
}
|
|
45825
|
+
const runStartedMs = Date.now();
|
|
45826
|
+
const POLL_MS = 2000;
|
|
45827
|
+
const heartbeatMs = (opts.heartbeatSeconds ?? 60) * 1000;
|
|
45828
|
+
let lastSignature = "";
|
|
45829
|
+
let lastEmitMs = 0;
|
|
45830
|
+
const stateSignature = () => Object.entries(statusCache.models).sort(([a], [b]) => a.localeCompare(b)).map(([id, m]) => `${id}:${m.state}:${m.outputSize}`).join("|");
|
|
45831
|
+
const emitProgress = (phase = "running") => {
|
|
45832
|
+
const elapsedSeconds = (Date.now() - runStartedMs) / 1000;
|
|
45833
|
+
writeStatusFile(sessionPath, manifest, statusCache, { elapsedSeconds });
|
|
45834
|
+
if (!opts.onProgress)
|
|
45835
|
+
return;
|
|
45836
|
+
const signature = stateSignature();
|
|
45837
|
+
const changed = signature !== lastSignature;
|
|
45838
|
+
const heartbeatDue = Date.now() - lastEmitMs >= heartbeatMs;
|
|
45839
|
+
if (phase !== "settled" && !changed && !heartbeatDue)
|
|
45840
|
+
return;
|
|
45841
|
+
lastSignature = signature;
|
|
45842
|
+
lastEmitMs = Date.now();
|
|
45843
|
+
try {
|
|
45844
|
+
const models = Object.values(statusCache.models);
|
|
45845
|
+
opts.onProgress({
|
|
45846
|
+
rendered: renderTeamStatsCompact(sessionPath, manifest, statusCache, { elapsedSeconds }),
|
|
45847
|
+
phase,
|
|
45848
|
+
allFailed: models.length > 0 && models.every((m) => m.state !== "COMPLETED")
|
|
45849
|
+
});
|
|
45850
|
+
} catch {}
|
|
45851
|
+
};
|
|
45852
|
+
emitProgress();
|
|
45853
|
+
const progressHandle = setInterval(() => emitProgress("running"), POLL_MS);
|
|
45854
|
+
progressHandle.unref?.();
|
|
45234
45855
|
let timeoutHandle = null;
|
|
45235
45856
|
await Promise.race([
|
|
45236
45857
|
Promise.all(completionPromises),
|
|
@@ -45241,9 +45862,27 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45241
45862
|
if (current.state === "RUNNING") {
|
|
45242
45863
|
if (!proc.killed)
|
|
45243
45864
|
proc.kill("SIGTERM");
|
|
45865
|
+
const rt = runtimes.get(id);
|
|
45866
|
+
const stderr = rt?.getStderr() ?? "";
|
|
45867
|
+
const stdoutTail = rt?.getStdoutTail() ?? "";
|
|
45868
|
+
const bytes = rt?.getByteCount() ?? 0;
|
|
45869
|
+
const detail = `Killed by the orchestrator after ${timeoutMs / 1000}s with ${bytes} B of stdout. ` + `In --quiet print mode the child emits its answer only at the end, so 0 B means ` + `"did not finish", not "produced nothing".`;
|
|
45870
|
+
if (rt)
|
|
45871
|
+
persistErrorLog(rt.errorLogPath, `TIMEOUT: ${detail}`, stderr, stdoutTail);
|
|
45244
45872
|
updateModelStatus(id, {
|
|
45245
45873
|
state: "TIMEOUT",
|
|
45246
|
-
completedAt: new Date().toISOString()
|
|
45874
|
+
completedAt: new Date().toISOString(),
|
|
45875
|
+
outputSize: bytes,
|
|
45876
|
+
error: rt ? {
|
|
45877
|
+
model: id,
|
|
45878
|
+
command: rt.command,
|
|
45879
|
+
reason: "timeout",
|
|
45880
|
+
detail,
|
|
45881
|
+
stderrSnippet: stderr ? redactSecrets(stderr).slice(-2000) : undefined,
|
|
45882
|
+
stdoutSnippet: stdoutTail ? redactSecrets(stdoutTail).slice(-2000) : undefined,
|
|
45883
|
+
errorLogPath: rt.errorLogPath,
|
|
45884
|
+
workDir: sessionPath
|
|
45885
|
+
} : undefined
|
|
45247
45886
|
});
|
|
45248
45887
|
opts.onStatusChange?.(id, statusCache.models[id]);
|
|
45249
45888
|
}
|
|
@@ -45254,6 +45893,8 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45254
45893
|
]);
|
|
45255
45894
|
if (timeoutHandle !== null)
|
|
45256
45895
|
clearTimeout(timeoutHandle);
|
|
45896
|
+
clearInterval(progressHandle);
|
|
45897
|
+
emitProgress("settled");
|
|
45257
45898
|
process.off("SIGINT", sigintHandler);
|
|
45258
45899
|
return statusCache;
|
|
45259
45900
|
}
|
|
@@ -45265,23 +45906,23 @@ async function judgeResponses(sessionPath, opts = {}) {
|
|
|
45265
45906
|
const responses = {};
|
|
45266
45907
|
for (const file2 of responseFiles) {
|
|
45267
45908
|
const id = file2.replace(/^response-/, "").replace(/\.md$/, "");
|
|
45268
|
-
responses[id] =
|
|
45909
|
+
responses[id] = readFileSync16(join22(sessionPath, file2), "utf-8");
|
|
45269
45910
|
}
|
|
45270
|
-
const input =
|
|
45911
|
+
const input = readFileSync16(join22(sessionPath, "input.md"), "utf-8");
|
|
45271
45912
|
const judgePrompt = buildJudgePrompt(input, responses);
|
|
45272
|
-
|
|
45913
|
+
writeFileSync12(join22(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
|
|
45273
45914
|
const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
|
|
45274
|
-
const judgePath =
|
|
45275
|
-
|
|
45915
|
+
const judgePath = join22(sessionPath, "judging");
|
|
45916
|
+
mkdirSync11(judgePath, { recursive: true });
|
|
45276
45917
|
setupSession(judgePath, judgeModels, judgePrompt);
|
|
45277
45918
|
await runModels(judgePath, { claudeFlags: opts.claudeFlags });
|
|
45278
45919
|
const votes = parseJudgeVotes(judgePath, Object.keys(responses));
|
|
45279
45920
|
const verdict = aggregateVerdict(votes, Object.keys(responses));
|
|
45280
|
-
|
|
45921
|
+
writeFileSync12(join22(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
|
|
45281
45922
|
return verdict;
|
|
45282
45923
|
}
|
|
45283
45924
|
function getStatus(sessionPath) {
|
|
45284
|
-
return JSON.parse(
|
|
45925
|
+
return JSON.parse(readFileSync16(join22(sessionPath, "status.json"), "utf-8"));
|
|
45285
45926
|
}
|
|
45286
45927
|
function fisherYatesShuffle(arr) {
|
|
45287
45928
|
for (let i = arr.length - 1;i > 0; i--) {
|
|
@@ -45291,7 +45932,7 @@ function fisherYatesShuffle(arr) {
|
|
|
45291
45932
|
return arr;
|
|
45292
45933
|
}
|
|
45293
45934
|
function getDefaultJudgeModels(sessionPath) {
|
|
45294
|
-
const manifest = JSON.parse(
|
|
45935
|
+
const manifest = JSON.parse(readFileSync16(join22(sessionPath, "manifest.json"), "utf-8"));
|
|
45295
45936
|
return Object.values(manifest.models).map((e) => e.model);
|
|
45296
45937
|
}
|
|
45297
45938
|
function buildJudgePrompt(input, responses) {
|
|
@@ -45354,7 +45995,7 @@ function parseJudgeVotes(judgePath, responseIds) {
|
|
|
45354
45995
|
const judgeId = file2.replace(/^response-/, "").replace(/\.md$/, "");
|
|
45355
45996
|
let content;
|
|
45356
45997
|
try {
|
|
45357
|
-
content =
|
|
45998
|
+
content = readFileSync16(join22(judgePath, file2), "utf-8");
|
|
45358
45999
|
} catch {
|
|
45359
46000
|
continue;
|
|
45360
46001
|
}
|
|
@@ -45406,7 +46047,7 @@ function aggregateVerdict(votes, responseIds) {
|
|
|
45406
46047
|
function formatVerdict(verdict, sessionPath) {
|
|
45407
46048
|
let manifest = null;
|
|
45408
46049
|
try {
|
|
45409
|
-
manifest = JSON.parse(
|
|
46050
|
+
manifest = JSON.parse(readFileSync16(join22(sessionPath, "manifest.json"), "utf-8"));
|
|
45410
46051
|
} catch {}
|
|
45411
46052
|
let output = `# Team Verdict
|
|
45412
46053
|
|
|
@@ -45437,9 +46078,13 @@ function formatVerdict(verdict, sessionPath) {
|
|
|
45437
46078
|
}
|
|
45438
46079
|
return output;
|
|
45439
46080
|
}
|
|
45440
|
-
var SENTINEL_MODELS;
|
|
46081
|
+
var STDOUT_TAIL_LIMIT = 4000, API_ERROR_RE, BG_CEILING_RE, DEFAULT_MIN_OUTPUT_BYTES = 0, SENTINEL_MODELS;
|
|
45441
46082
|
var init_team_orchestrator = __esm(() => {
|
|
45442
46083
|
init_prehydrate();
|
|
46084
|
+
init_redact();
|
|
46085
|
+
init_team_stats();
|
|
46086
|
+
API_ERROR_RE = /\[API Error:\s*([^\]]{0,300})\]/i;
|
|
46087
|
+
BG_CEILING_RE = /Background tasks still running after (\d+)s; terminating/i;
|
|
45443
46088
|
SENTINEL_MODELS = new Set([
|
|
45444
46089
|
"internal",
|
|
45445
46090
|
"default",
|
|
@@ -45454,16 +46099,17 @@ var exports_mcp_server = {};
|
|
|
45454
46099
|
__export(exports_mcp_server, {
|
|
45455
46100
|
startMcpServer: () => startMcpServer,
|
|
45456
46101
|
runPromptViaProxy: () => runPromptViaProxy,
|
|
45457
|
-
parseAnthropicSse: () => parseAnthropicSse
|
|
46102
|
+
parseAnthropicSse: () => parseAnthropicSse,
|
|
46103
|
+
formatTeamResult: () => formatTeamResult
|
|
45458
46104
|
});
|
|
45459
|
-
import { existsSync as
|
|
45460
|
-
import { homedir as
|
|
45461
|
-
import { dirname as
|
|
46105
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync17, readdirSync as readdirSync3, writeFileSync as writeFileSync13 } from "fs";
|
|
46106
|
+
import { homedir as homedir21 } from "os";
|
|
46107
|
+
import { dirname as dirname7, join as join23 } from "path";
|
|
45462
46108
|
import { fileURLToPath } from "url";
|
|
45463
46109
|
async function loadAllModels(forceRefresh = false) {
|
|
45464
|
-
if (!forceRefresh &&
|
|
46110
|
+
if (!forceRefresh && existsSync19(ALL_MODELS_CACHE_PATH2)) {
|
|
45465
46111
|
try {
|
|
45466
|
-
const cacheData = JSON.parse(
|
|
46112
|
+
const cacheData = JSON.parse(readFileSync17(ALL_MODELS_CACHE_PATH2, "utf-8"));
|
|
45467
46113
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
45468
46114
|
const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
45469
46115
|
if (ageInDays <= CACHE_MAX_AGE_DAYS) {
|
|
@@ -45477,12 +46123,12 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
45477
46123
|
throw new Error(`API returned ${response.status}`);
|
|
45478
46124
|
const data = await response.json();
|
|
45479
46125
|
const models = data.data || [];
|
|
45480
|
-
|
|
45481
|
-
|
|
46126
|
+
mkdirSync12(CLAUDISH_CACHE_DIR, { recursive: true });
|
|
46127
|
+
writeFileSync13(ALL_MODELS_CACHE_PATH2, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
|
|
45482
46128
|
return models;
|
|
45483
46129
|
} catch {
|
|
45484
|
-
if (
|
|
45485
|
-
const cacheData = JSON.parse(
|
|
46130
|
+
if (existsSync19(ALL_MODELS_CACHE_PATH2)) {
|
|
46131
|
+
const cacheData = JSON.parse(readFileSync17(ALL_MODELS_CACHE_PATH2, "utf-8"));
|
|
45486
46132
|
return cacheData.models || [];
|
|
45487
46133
|
}
|
|
45488
46134
|
return [];
|
|
@@ -45578,63 +46224,53 @@ function fuzzyScore(text, query) {
|
|
|
45578
46224
|
}
|
|
45579
46225
|
return queryIndex === lowerQuery.length ? score / lowerText.length : 0;
|
|
45580
46226
|
}
|
|
46227
|
+
function fmtSize(n) {
|
|
46228
|
+
if (n <= 0)
|
|
46229
|
+
return "0B";
|
|
46230
|
+
if (n < 1024)
|
|
46231
|
+
return `${n}B`;
|
|
46232
|
+
if (n < 1024 * 1024)
|
|
46233
|
+
return `${(n / 1024).toFixed(1)}KB`;
|
|
46234
|
+
return `${(n / (1024 * 1024)).toFixed(1)}MB`;
|
|
46235
|
+
}
|
|
45581
46236
|
function formatTeamResult(status, sessionPath) {
|
|
45582
|
-
const entries = Object.entries(status.models);
|
|
45583
|
-
const failed = entries.filter(([, m]) => m.state === "FAILED" || m.state === "TIMEOUT");
|
|
46237
|
+
const entries = Object.entries(status.models).sort(([a], [b]) => a.localeCompare(b));
|
|
46238
|
+
const failed = entries.filter(([, m]) => m.state === "FAILED" || m.state === "TIMEOUT" || m.state === "EMPTY");
|
|
45584
46239
|
const succeeded = entries.filter(([, m]) => m.state === "COMPLETED");
|
|
45585
|
-
|
|
46240
|
+
const lines = [];
|
|
46241
|
+
lines.push(`<<<TEAM_RESULT path="${sessionPath}">>>`);
|
|
46242
|
+
lines.push(`status: ${failed.length === 0 ? "ok" : succeeded.length === 0 ? "all-failed" : "partial"}` + ` \u2014 ${succeeded.length}/${entries.length} succeeded`);
|
|
46243
|
+
if (succeeded.length > 0) {
|
|
46244
|
+
lines.push("succeeded:");
|
|
46245
|
+
for (const [id, m] of succeeded) {
|
|
46246
|
+
lines.push(` ${id} ${fmtSize(m.outputSize)} response-${id}.md`);
|
|
46247
|
+
}
|
|
46248
|
+
}
|
|
45586
46249
|
if (failed.length > 0) {
|
|
45587
|
-
|
|
45588
|
-
|
|
45589
|
-
---
|
|
45590
|
-
## Failures Detected
|
|
45591
|
-
|
|
45592
|
-
`;
|
|
45593
|
-
result += `${succeeded.length}/${entries.length} models succeeded, ${failed.length} failed.
|
|
45594
|
-
|
|
45595
|
-
`;
|
|
46250
|
+
lines.push("failures:");
|
|
45596
46251
|
for (const [id, m] of failed) {
|
|
45597
|
-
|
|
45598
|
-
|
|
45599
|
-
|
|
45600
|
-
|
|
45601
|
-
|
|
45602
|
-
|
|
45603
|
-
|
|
45604
|
-
|
|
45605
|
-
|
|
45606
|
-
|
|
45607
|
-
result += `- **Error output:**
|
|
45608
|
-
\`\`\`
|
|
45609
|
-
${m.error.stderrSnippet}
|
|
45610
|
-
\`\`\`
|
|
45611
|
-
`;
|
|
45612
|
-
}
|
|
45613
|
-
result += `- **Full error log:** ${m.error.errorLogPath}
|
|
45614
|
-
`;
|
|
45615
|
-
result += `- **Working directory:** ${m.error.workDir}
|
|
45616
|
-
`;
|
|
46252
|
+
const reason = m.error?.reason ?? "unknown";
|
|
46253
|
+
const next = NEXT_STEP[reason] ?? "read the evidence log";
|
|
46254
|
+
lines.push(` ${id} ${m.state} reason=${reason}`);
|
|
46255
|
+
if (m.error?.detail)
|
|
46256
|
+
lines.push(` what: ${m.error.detail}`);
|
|
46257
|
+
lines.push(` next: ${next}`);
|
|
46258
|
+
if (m.error?.errorLogPath) {
|
|
46259
|
+
lines.push(` evidence: ${m.error.errorLogPath}`);
|
|
46260
|
+
} else {
|
|
46261
|
+
lines.push(" evidence: NONE CAPTURED \u2014 orchestrator bug, report via report_error");
|
|
45617
46262
|
}
|
|
45618
|
-
result += `
|
|
45619
|
-
`;
|
|
45620
46263
|
}
|
|
45621
|
-
|
|
45622
|
-
|
|
45623
|
-
|
|
45624
|
-
|
|
45625
|
-
result += `- \`session_path\`: "${sessionPath}"
|
|
45626
|
-
`;
|
|
45627
|
-
result += "- Copy the stderr snippet above into `stderr_snippet`\n";
|
|
45628
|
-
result += "- Set `auto_send: true` to suggest enabling automatic reporting\n";
|
|
46264
|
+
lines.push("actions:");
|
|
46265
|
+
lines.push(` full stderr/stdout for one failure \u2192 Read the evidence path above`);
|
|
46266
|
+
lines.push(` machine-readable status \u2192 team(mode="status", path="${sessionPath}")`);
|
|
46267
|
+
lines.push(` report a provider bug \u2192 report_error(session_path="${sessionPath}")`);
|
|
45629
46268
|
}
|
|
45630
|
-
|
|
45631
|
-
|
|
45632
|
-
|
|
45633
|
-
if (!text)
|
|
45634
|
-
return "";
|
|
45635
|
-
return text.replace(/sk-[a-zA-Z0-9_-]{10,}/g, "sk-***REDACTED***").replace(/Bearer [a-zA-Z0-9_.-]+/g, "Bearer ***REDACTED***").replace(/\/Users\/[^/\s]+/g, "/Users/***").replace(/\/home\/[^/\s]+/g, "/home/***").replace(/[A-Z_]+_API_KEY=[^\s]+/g, "***_API_KEY=REDACTED").replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, "***@***.***");
|
|
46269
|
+
lines.push("<<<END_TEAM_RESULT>>>");
|
|
46270
|
+
return lines.join(`
|
|
46271
|
+
`);
|
|
45636
46272
|
}
|
|
45637
|
-
function defineTools(sessionManager) {
|
|
46273
|
+
function defineTools(sessionManager, notifyChannel) {
|
|
45638
46274
|
const tools = [];
|
|
45639
46275
|
tools.push({
|
|
45640
46276
|
name: "run_prompt",
|
|
@@ -45965,12 +46601,25 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
45965
46601
|
const input = args.input;
|
|
45966
46602
|
const timeout = args.timeout;
|
|
45967
46603
|
const resolved = validateSessionPath(path);
|
|
46604
|
+
const teamSessionId = resolved.split("/").filter(Boolean).pop() ?? "team";
|
|
46605
|
+
const teamCreatedAt = new Date().toISOString();
|
|
46606
|
+
const runOpts = {
|
|
46607
|
+
timeout,
|
|
46608
|
+
onProgress: (u) => notifyChannel({
|
|
46609
|
+
content: u.rendered,
|
|
46610
|
+
sessionId: teamSessionId,
|
|
46611
|
+
event: u.phase === "settled" ? u.allFailed ? "failed" : "completed" : "running",
|
|
46612
|
+
model: "team",
|
|
46613
|
+
elapsedSeconds: (Date.now() - Date.parse(teamCreatedAt)) / 1000,
|
|
46614
|
+
createdAt: teamCreatedAt
|
|
46615
|
+
})
|
|
46616
|
+
};
|
|
45968
46617
|
switch (mode) {
|
|
45969
46618
|
case "run": {
|
|
45970
46619
|
if (!models?.length)
|
|
45971
46620
|
throw new Error("'models' is required for 'run' mode");
|
|
45972
46621
|
setupSession(resolved, models, input);
|
|
45973
|
-
const status = await runModels(resolved,
|
|
46622
|
+
const status = await runModels(resolved, runOpts);
|
|
45974
46623
|
return {
|
|
45975
46624
|
content: [{ type: "text", text: formatTeamResult(status, resolved) }]
|
|
45976
46625
|
};
|
|
@@ -45983,7 +46632,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
45983
46632
|
if (!models?.length)
|
|
45984
46633
|
throw new Error("'models' is required for 'run-and-judge' mode");
|
|
45985
46634
|
setupSession(resolved, models, input);
|
|
45986
|
-
await runModels(resolved,
|
|
46635
|
+
await runModels(resolved, runOpts);
|
|
45987
46636
|
const verdict = await judgeResponses(resolved, { judges });
|
|
45988
46637
|
return { content: [{ type: "text", text: JSON.stringify(verdict, null, 2) }] };
|
|
45989
46638
|
}
|
|
@@ -46046,7 +46695,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46046
46695
|
let stderrFull = stderr_snippet || "";
|
|
46047
46696
|
if (error_log_path) {
|
|
46048
46697
|
try {
|
|
46049
|
-
stderrFull =
|
|
46698
|
+
stderrFull = readFileSync17(error_log_path, "utf-8");
|
|
46050
46699
|
} catch {}
|
|
46051
46700
|
}
|
|
46052
46701
|
const sessionData = {};
|
|
@@ -46054,16 +46703,16 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46054
46703
|
const sp = session_path;
|
|
46055
46704
|
for (const file2 of ["status.json", "manifest.json", "input.md"]) {
|
|
46056
46705
|
try {
|
|
46057
|
-
sessionData[file2] =
|
|
46706
|
+
sessionData[file2] = readFileSync17(join23(sp, file2), "utf-8");
|
|
46058
46707
|
} catch {}
|
|
46059
46708
|
}
|
|
46060
46709
|
try {
|
|
46061
|
-
const errorDir =
|
|
46062
|
-
if (
|
|
46710
|
+
const errorDir = join23(sp, "errors");
|
|
46711
|
+
if (existsSync19(errorDir)) {
|
|
46063
46712
|
for (const f of readdirSync3(errorDir)) {
|
|
46064
46713
|
if (f.endsWith(".log")) {
|
|
46065
46714
|
try {
|
|
46066
|
-
sessionData[`errors/${f}`] =
|
|
46715
|
+
sessionData[`errors/${f}`] = readFileSync17(join23(errorDir, f), "utf-8");
|
|
46067
46716
|
} catch {}
|
|
46068
46717
|
}
|
|
46069
46718
|
}
|
|
@@ -46073,7 +46722,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46073
46722
|
for (const f of readdirSync3(sp)) {
|
|
46074
46723
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
46075
46724
|
try {
|
|
46076
|
-
const content =
|
|
46725
|
+
const content = readFileSync17(join23(sp, f), "utf-8");
|
|
46077
46726
|
sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
|
|
46078
46727
|
} catch {}
|
|
46079
46728
|
}
|
|
@@ -46082,9 +46731,9 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46082
46731
|
}
|
|
46083
46732
|
let version2 = "unknown";
|
|
46084
46733
|
try {
|
|
46085
|
-
const pkgPath =
|
|
46086
|
-
if (
|
|
46087
|
-
version2 = JSON.parse(
|
|
46734
|
+
const pkgPath = join23(__dirname2, "../package.json");
|
|
46735
|
+
if (existsSync19(pkgPath)) {
|
|
46736
|
+
version2 = JSON.parse(readFileSync17(pkgPath, "utf-8")).version;
|
|
46088
46737
|
}
|
|
46089
46738
|
} catch {}
|
|
46090
46739
|
const report = {
|
|
@@ -46369,7 +47018,31 @@ To report this error, use the report_error tool with error_type: "provider_failu
|
|
|
46369
47018
|
watchNotificationResult(result, { sessionId: sessionId2, eventType: event.type });
|
|
46370
47019
|
})
|
|
46371
47020
|
});
|
|
46372
|
-
const
|
|
47021
|
+
const channelEnabled = enabledGroups.has("channel");
|
|
47022
|
+
const notifyChannel = (p) => {
|
|
47023
|
+
if (!channelEnabled)
|
|
47024
|
+
return;
|
|
47025
|
+
try {
|
|
47026
|
+
const result = server.notification({
|
|
47027
|
+
method: "notifications/claude/channel",
|
|
47028
|
+
params: {
|
|
47029
|
+
content: p.content,
|
|
47030
|
+
meta: {
|
|
47031
|
+
session_id: p.sessionId,
|
|
47032
|
+
event: p.event,
|
|
47033
|
+
model: p.model,
|
|
47034
|
+
elapsed_seconds: String(Math.round(p.elapsedSeconds)),
|
|
47035
|
+
task_id: p.sessionId,
|
|
47036
|
+
status: mapEventToTaskStatus(p.event),
|
|
47037
|
+
created_at: p.createdAt,
|
|
47038
|
+
last_updated_at: new Date().toISOString()
|
|
47039
|
+
}
|
|
47040
|
+
}
|
|
47041
|
+
});
|
|
47042
|
+
watchNotificationResult(result, { sessionId: p.sessionId, eventType: p.event });
|
|
47043
|
+
} catch {}
|
|
47044
|
+
};
|
|
47045
|
+
const allTools = defineTools(sessionManager, notifyChannel);
|
|
46373
47046
|
const enabledTools = allTools.filter((t) => enabledGroups.has(t.group));
|
|
46374
47047
|
const toolMap = new Map(enabledTools.map((t) => [t.name, t]));
|
|
46375
47048
|
console.error(`[claudish] MCP server started (tools: ${toolMode}, ${enabledTools.length} tools)`);
|
|
@@ -46440,7 +47113,7 @@ When channel mode is active, you receive <channel source="claudish" ...> notific
|
|
|
46440
47113
|
5. Use list_sessions to see all active/completed sessions.
|
|
46441
47114
|
6. Use cancel_session to stop a running session.
|
|
46442
47115
|
|
|
46443
|
-
The session_id in the channel tag's meta attributes is the key for all tool calls.`, proxyInstance = null, proxyStarting = null, EVENT_TO_TASK_STATUS;
|
|
47116
|
+
The session_id in the channel tag's meta attributes is the key for all tool calls.`, proxyInstance = null, proxyStarting = null, NEXT_STEP, sanitize, EVENT_TO_TASK_STATUS;
|
|
46444
47117
|
var init_mcp_server = __esm(() => {
|
|
46445
47118
|
init_server2();
|
|
46446
47119
|
init_stdio2();
|
|
@@ -46450,15 +47123,24 @@ var init_mcp_server = __esm(() => {
|
|
|
46450
47123
|
init_channel();
|
|
46451
47124
|
init_model_loader();
|
|
46452
47125
|
init_port_manager();
|
|
47126
|
+
init_redact();
|
|
46453
47127
|
init_provider_definitions();
|
|
46454
47128
|
init_proxy_server();
|
|
46455
47129
|
init_team_orchestrator();
|
|
46456
47130
|
import_dotenv2 = __toESM(require_main(), 1);
|
|
46457
47131
|
import_dotenv2.config({ quiet: true });
|
|
46458
47132
|
__filename2 = fileURLToPath(import.meta.url);
|
|
46459
|
-
__dirname2 =
|
|
46460
|
-
CLAUDISH_CACHE_DIR =
|
|
46461
|
-
ALL_MODELS_CACHE_PATH2 =
|
|
47133
|
+
__dirname2 = dirname7(__filename2);
|
|
47134
|
+
CLAUDISH_CACHE_DIR = join23(homedir21(), ".claudish");
|
|
47135
|
+
ALL_MODELS_CACHE_PATH2 = join23(CLAUDISH_CACHE_DIR, "all-models.json");
|
|
47136
|
+
NEXT_STEP = {
|
|
47137
|
+
nonzero_exit: "read the evidence log, then retry or drop the model",
|
|
47138
|
+
timeout: "raise `timeout`, or pick a faster model",
|
|
47139
|
+
api_error: "retry once, or route via a different provider (or@<model>)",
|
|
47140
|
+
background_task_ceiling: "set CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 for children, or forbid background work in the prompt",
|
|
47141
|
+
empty_output: "retry once; if it repeats, drop the model"
|
|
47142
|
+
};
|
|
47143
|
+
sanitize = sanitizeForReport;
|
|
46462
47144
|
EVENT_TO_TASK_STATUS = new Map([
|
|
46463
47145
|
["starting", "working"],
|
|
46464
47146
|
["running", "working"],
|
|
@@ -46475,7 +47157,7 @@ var exports_serve_command = {};
|
|
|
46475
47157
|
__export(exports_serve_command, {
|
|
46476
47158
|
serveCommand: () => serveCommand
|
|
46477
47159
|
});
|
|
46478
|
-
import { existsSync as
|
|
47160
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
|
|
46479
47161
|
function parseServeArgs(args) {
|
|
46480
47162
|
const out = {};
|
|
46481
47163
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -46494,12 +47176,12 @@ function parseServeArgs(args) {
|
|
|
46494
47176
|
return out;
|
|
46495
47177
|
}
|
|
46496
47178
|
function loadModelMap(path) {
|
|
46497
|
-
if (!
|
|
47179
|
+
if (!existsSync20(path)) {
|
|
46498
47180
|
throw new Error(`--models file not found: ${path}`);
|
|
46499
47181
|
}
|
|
46500
47182
|
let raw2;
|
|
46501
47183
|
try {
|
|
46502
|
-
raw2 =
|
|
47184
|
+
raw2 = readFileSync18(path, "utf-8");
|
|
46503
47185
|
} catch (e) {
|
|
46504
47186
|
throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
46505
47187
|
}
|
|
@@ -57971,7 +58653,7 @@ var init_RemoveFileError = __esm(() => {
|
|
|
57971
58653
|
|
|
57972
58654
|
// ../../node_modules/.bun/@inquirer+external-editor@2.0.1+04f2146be16c61ef/node_modules/@inquirer/external-editor/dist/index.js
|
|
57973
58655
|
import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
|
|
57974
|
-
import { readFileSync as
|
|
58656
|
+
import { readFileSync as readFileSync19, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
|
|
57975
58657
|
import path from "path";
|
|
57976
58658
|
import os from "os";
|
|
57977
58659
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
@@ -58080,14 +58762,14 @@ class ExternalEditor {
|
|
|
58080
58762
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
58081
58763
|
opt.mode = this.fileOptions.mode;
|
|
58082
58764
|
}
|
|
58083
|
-
|
|
58765
|
+
writeFileSync14(this.tempFile, this.text, opt);
|
|
58084
58766
|
} catch (createFileError) {
|
|
58085
58767
|
throw new CreateFileError(createFileError);
|
|
58086
58768
|
}
|
|
58087
58769
|
}
|
|
58088
58770
|
readTemporaryFile() {
|
|
58089
58771
|
try {
|
|
58090
|
-
const tempFileBuffer =
|
|
58772
|
+
const tempFileBuffer = readFileSync19(this.tempFile);
|
|
58091
58773
|
if (tempFileBuffer.length === 0) {
|
|
58092
58774
|
this.text = "";
|
|
58093
58775
|
} else {
|
|
@@ -59282,15 +59964,15 @@ async function geminiQuotaHandler() {
|
|
|
59282
59964
|
}
|
|
59283
59965
|
}
|
|
59284
59966
|
async function codexQuotaHandler() {
|
|
59285
|
-
const { readFileSync:
|
|
59286
|
-
const { join:
|
|
59287
|
-
const { homedir:
|
|
59288
|
-
const credPath =
|
|
59289
|
-
if (!
|
|
59967
|
+
const { readFileSync: readFileSync20, existsSync: existsSync21 } = await import("fs");
|
|
59968
|
+
const { join: join24 } = await import("path");
|
|
59969
|
+
const { homedir: homedir22 } = await import("os");
|
|
59970
|
+
const credPath = join24(homedir22(), ".claudish", "codex-oauth.json");
|
|
59971
|
+
if (!existsSync21(credPath)) {
|
|
59290
59972
|
console.error(`${RED}No Codex credentials found.${R} Run: ${B}claudish login codex${R}`);
|
|
59291
59973
|
process.exit(1);
|
|
59292
59974
|
}
|
|
59293
|
-
const creds = JSON.parse(
|
|
59975
|
+
const creds = JSON.parse(readFileSync20(credPath, "utf-8"));
|
|
59294
59976
|
let email3 = "";
|
|
59295
59977
|
try {
|
|
59296
59978
|
const parts = creds.access_token.split(".");
|
|
@@ -59342,9 +60024,9 @@ async function codexQuotaHandler() {
|
|
|
59342
60024
|
}
|
|
59343
60025
|
let modelSlugs = [];
|
|
59344
60026
|
try {
|
|
59345
|
-
const modelsPath =
|
|
59346
|
-
if (
|
|
59347
|
-
const cache2 = JSON.parse(
|
|
60027
|
+
const modelsPath = join24(homedir22(), ".codex", "models_cache.json");
|
|
60028
|
+
if (existsSync21(modelsPath)) {
|
|
60029
|
+
const cache2 = JSON.parse(readFileSync20(modelsPath, "utf-8"));
|
|
59348
60030
|
modelSlugs = (cache2.models || []).map((m) => m.slug || m.id).filter(Boolean);
|
|
59349
60031
|
}
|
|
59350
60032
|
} catch {}
|
|
@@ -60692,19 +61374,19 @@ async function probeLink(proxyUrl, link, timeoutMs) {
|
|
|
60692
61374
|
}
|
|
60693
61375
|
const streamResult = await consumeProbeStream(response, timeoutMs, startedAt);
|
|
60694
61376
|
const totalMs = Date.now() - startedAt;
|
|
60695
|
-
let
|
|
61377
|
+
let timing2;
|
|
60696
61378
|
if (streamResult.state === "live" && streamResult.ttftMs !== undefined && !streamResult.truncated) {
|
|
60697
61379
|
const ttftMs = streamResult.ttftMs;
|
|
60698
61380
|
const tokens = streamResult.tokens ?? 0;
|
|
60699
61381
|
const streamMs = Math.max(STREAM_MS_FLOOR, totalMs - ttftMs);
|
|
60700
61382
|
const tokensPerSec = tokens > 0 ? tokens / streamMs * 1000 : 0;
|
|
60701
|
-
|
|
61383
|
+
timing2 = { ttfbMs, ttftMs, totalMs, tokens, tokensPerSec };
|
|
60702
61384
|
}
|
|
60703
61385
|
const { ttftMs: _ttft, tokens: _tok, truncated: _trunc, ...rest } = streamResult;
|
|
60704
61386
|
return annotateOAuthHint({
|
|
60705
61387
|
...rest,
|
|
60706
61388
|
latencyMs: totalMs,
|
|
60707
|
-
timing
|
|
61389
|
+
timing: timing2
|
|
60708
61390
|
}, link.provider, isOAuth);
|
|
60709
61391
|
}
|
|
60710
61392
|
function annotateOAuthHint(result, provider, isOAuth) {
|
|
@@ -61301,8 +61983,8 @@ function breakdownNum(ms) {
|
|
|
61301
61983
|
return formatLatency(ms);
|
|
61302
61984
|
return `${Math.round(Math.max(0, ms))}`;
|
|
61303
61985
|
}
|
|
61304
|
-
function buildBarsLine(
|
|
61305
|
-
const t =
|
|
61986
|
+
function buildBarsLine(timing2, scales, isFastest, usable) {
|
|
61987
|
+
const t = timing2;
|
|
61306
61988
|
const showTokBar = usable >= PRINTER_BARS_FULL_WIDTH;
|
|
61307
61989
|
const showBreakdown = usable >= PRINTER_BARS_FULL_WIDTH || usable >= PRINTER_BARS_NOTOK_WIDTH;
|
|
61308
61990
|
const barCells = timelineBarCells(t.totalMs, scales.maxTotalMs, PRINTER_BAR_WIDTH);
|
|
@@ -63307,22 +63989,22 @@ __export(exports_cli, {
|
|
|
63307
63989
|
});
|
|
63308
63990
|
import {
|
|
63309
63991
|
copyFileSync as copyFileSync2,
|
|
63310
|
-
existsSync as
|
|
63311
|
-
mkdirSync as
|
|
63312
|
-
readFileSync as
|
|
63992
|
+
existsSync as existsSync21,
|
|
63993
|
+
mkdirSync as mkdirSync13,
|
|
63994
|
+
readFileSync as readFileSync20,
|
|
63313
63995
|
readdirSync as readdirSync4,
|
|
63314
63996
|
unlinkSync as unlinkSync7,
|
|
63315
|
-
writeFileSync as
|
|
63997
|
+
writeFileSync as writeFileSync15
|
|
63316
63998
|
} from "fs";
|
|
63317
|
-
import { homedir as
|
|
63318
|
-
import { dirname as
|
|
63999
|
+
import { homedir as homedir22 } from "os";
|
|
64000
|
+
import { dirname as dirname8, join as join24 } from "path";
|
|
63319
64001
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
63320
64002
|
function getVersion3() {
|
|
63321
64003
|
return VERSION;
|
|
63322
64004
|
}
|
|
63323
64005
|
function clearAllModelCaches() {
|
|
63324
|
-
const cacheDir =
|
|
63325
|
-
if (!
|
|
64006
|
+
const cacheDir = join24(homedir22(), ".claudish");
|
|
64007
|
+
if (!existsSync21(cacheDir))
|
|
63326
64008
|
return;
|
|
63327
64009
|
const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
|
|
63328
64010
|
let cleared = 0;
|
|
@@ -63330,7 +64012,7 @@ function clearAllModelCaches() {
|
|
|
63330
64012
|
const files = readdirSync4(cacheDir);
|
|
63331
64013
|
for (const file2 of files) {
|
|
63332
64014
|
if (cachePatterns.includes(file2)) {
|
|
63333
|
-
unlinkSync7(
|
|
64015
|
+
unlinkSync7(join24(cacheDir, file2));
|
|
63334
64016
|
cleared++;
|
|
63335
64017
|
}
|
|
63336
64018
|
}
|
|
@@ -63740,15 +64422,15 @@ Usage: claudish --models --provider <slug>`);
|
|
|
63740
64422
|
});
|
|
63741
64423
|
config3.resolvedDefaultProvider = resolved;
|
|
63742
64424
|
if (resolved.legacyAutoPromoted && !config3.quiet) {
|
|
63743
|
-
const markerFile =
|
|
63744
|
-
if (!
|
|
64425
|
+
const markerFile = join24(homedir22(), ".claudish", ".legacy-litellm-hint-shown");
|
|
64426
|
+
if (!existsSync21(markerFile)) {
|
|
63745
64427
|
const hint = buildLegacyHint(resolved);
|
|
63746
64428
|
if (hint) {
|
|
63747
64429
|
console.error(hint);
|
|
63748
64430
|
}
|
|
63749
64431
|
try {
|
|
63750
|
-
|
|
63751
|
-
|
|
64432
|
+
mkdirSync13(dirname8(markerFile), { recursive: true });
|
|
64433
|
+
writeFileSync15(markerFile, new Date().toISOString(), "utf-8");
|
|
63752
64434
|
} catch {}
|
|
63753
64435
|
}
|
|
63754
64436
|
}
|
|
@@ -64808,8 +65490,8 @@ ${h("MORE INFO")}
|
|
|
64808
65490
|
}
|
|
64809
65491
|
function printAIAgentGuide() {
|
|
64810
65492
|
try {
|
|
64811
|
-
const guidePath =
|
|
64812
|
-
const guideContent =
|
|
65493
|
+
const guidePath = join24(__dirname3, "../AI_AGENT_GUIDE.md");
|
|
65494
|
+
const guideContent = readFileSync20(guidePath, "utf-8");
|
|
64813
65495
|
console.log(guideContent);
|
|
64814
65496
|
} catch (error46) {
|
|
64815
65497
|
console.error("Error reading AI Agent Guide:");
|
|
@@ -64825,19 +65507,19 @@ async function initializeClaudishSkill() {
|
|
|
64825
65507
|
console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
|
|
64826
65508
|
`);
|
|
64827
65509
|
const cwd = process.cwd();
|
|
64828
|
-
const claudeDir =
|
|
64829
|
-
const skillsDir =
|
|
64830
|
-
const claudishSkillDir =
|
|
64831
|
-
const skillFile =
|
|
64832
|
-
if (
|
|
65510
|
+
const claudeDir = join24(cwd, ".claude");
|
|
65511
|
+
const skillsDir = join24(claudeDir, "skills");
|
|
65512
|
+
const claudishSkillDir = join24(skillsDir, "claudish-usage");
|
|
65513
|
+
const skillFile = join24(claudishSkillDir, "SKILL.md");
|
|
65514
|
+
if (existsSync21(skillFile)) {
|
|
64833
65515
|
console.log("\u2705 Claudish skill already installed at:");
|
|
64834
65516
|
console.log(` ${skillFile}
|
|
64835
65517
|
`);
|
|
64836
65518
|
console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
|
|
64837
65519
|
return;
|
|
64838
65520
|
}
|
|
64839
|
-
const sourceSkillPath =
|
|
64840
|
-
if (!
|
|
65521
|
+
const sourceSkillPath = join24(__dirname3, "../skills/claudish-usage/SKILL.md");
|
|
65522
|
+
if (!existsSync21(sourceSkillPath)) {
|
|
64841
65523
|
console.error("\u274C Error: Claudish skill file not found in installation.");
|
|
64842
65524
|
console.error(` Expected at: ${sourceSkillPath}`);
|
|
64843
65525
|
console.error(`
|
|
@@ -64846,16 +65528,16 @@ async function initializeClaudishSkill() {
|
|
|
64846
65528
|
process.exit(1);
|
|
64847
65529
|
}
|
|
64848
65530
|
try {
|
|
64849
|
-
if (!
|
|
64850
|
-
|
|
65531
|
+
if (!existsSync21(claudeDir)) {
|
|
65532
|
+
mkdirSync13(claudeDir, { recursive: true });
|
|
64851
65533
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
64852
65534
|
}
|
|
64853
|
-
if (!
|
|
64854
|
-
|
|
65535
|
+
if (!existsSync21(skillsDir)) {
|
|
65536
|
+
mkdirSync13(skillsDir, { recursive: true });
|
|
64855
65537
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
64856
65538
|
}
|
|
64857
|
-
if (!
|
|
64858
|
-
|
|
65539
|
+
if (!existsSync21(claudishSkillDir)) {
|
|
65540
|
+
mkdirSync13(claudishSkillDir, { recursive: true });
|
|
64859
65541
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
64860
65542
|
}
|
|
64861
65543
|
copyFileSync2(sourceSkillPath, skillFile);
|
|
@@ -64927,7 +65609,7 @@ var init_cli = __esm(() => {
|
|
|
64927
65609
|
init_routing_rules();
|
|
64928
65610
|
init_provider_resolver();
|
|
64929
65611
|
__filename3 = fileURLToPath2(import.meta.url);
|
|
64930
|
-
__dirname3 =
|
|
65612
|
+
__dirname3 = dirname8(__filename3);
|
|
64931
65613
|
});
|
|
64932
65614
|
|
|
64933
65615
|
// src/update-checker.ts
|
|
@@ -64939,33 +65621,33 @@ __export(exports_update_checker, {
|
|
|
64939
65621
|
clearCache: () => clearCache,
|
|
64940
65622
|
checkForUpdates: () => checkForUpdates
|
|
64941
65623
|
});
|
|
64942
|
-
import { existsSync as
|
|
64943
|
-
import { homedir as
|
|
64944
|
-
import { join as
|
|
65624
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync14, readFileSync as readFileSync21, unlinkSync as unlinkSync8, writeFileSync as writeFileSync16 } from "fs";
|
|
65625
|
+
import { homedir as homedir23, platform as platform2, tmpdir } from "os";
|
|
65626
|
+
import { join as join25 } from "path";
|
|
64945
65627
|
function getCacheFilePath() {
|
|
64946
65628
|
let cacheDir;
|
|
64947
65629
|
if (isWindows) {
|
|
64948
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
64949
|
-
cacheDir =
|
|
65630
|
+
const localAppData = process.env.LOCALAPPDATA || join25(homedir23(), "AppData", "Local");
|
|
65631
|
+
cacheDir = join25(localAppData, "claudish");
|
|
64950
65632
|
} else {
|
|
64951
|
-
cacheDir =
|
|
65633
|
+
cacheDir = join25(homedir23(), ".cache", "claudish");
|
|
64952
65634
|
}
|
|
64953
65635
|
try {
|
|
64954
|
-
if (!
|
|
64955
|
-
|
|
65636
|
+
if (!existsSync22(cacheDir)) {
|
|
65637
|
+
mkdirSync14(cacheDir, { recursive: true });
|
|
64956
65638
|
}
|
|
64957
|
-
return
|
|
65639
|
+
return join25(cacheDir, "update-check.json");
|
|
64958
65640
|
} catch {
|
|
64959
|
-
return
|
|
65641
|
+
return join25(tmpdir(), "claudish-update-check.json");
|
|
64960
65642
|
}
|
|
64961
65643
|
}
|
|
64962
65644
|
function readCache() {
|
|
64963
65645
|
try {
|
|
64964
65646
|
const cachePath = getCacheFilePath();
|
|
64965
|
-
if (!
|
|
65647
|
+
if (!existsSync22(cachePath)) {
|
|
64966
65648
|
return null;
|
|
64967
65649
|
}
|
|
64968
|
-
const data = JSON.parse(
|
|
65650
|
+
const data = JSON.parse(readFileSync21(cachePath, "utf-8"));
|
|
64969
65651
|
return data;
|
|
64970
65652
|
} catch {
|
|
64971
65653
|
return null;
|
|
@@ -64978,7 +65660,7 @@ function writeCache(latestVersion) {
|
|
|
64978
65660
|
lastCheck: Date.now(),
|
|
64979
65661
|
latestVersion
|
|
64980
65662
|
};
|
|
64981
|
-
|
|
65663
|
+
writeFileSync16(cachePath, JSON.stringify(data), "utf-8");
|
|
64982
65664
|
} catch {}
|
|
64983
65665
|
}
|
|
64984
65666
|
function isCacheValid(cache2) {
|
|
@@ -64988,7 +65670,7 @@ function isCacheValid(cache2) {
|
|
|
64988
65670
|
function clearCache() {
|
|
64989
65671
|
try {
|
|
64990
65672
|
const cachePath = getCacheFilePath();
|
|
64991
|
-
if (
|
|
65673
|
+
if (existsSync22(cachePath)) {
|
|
64992
65674
|
unlinkSync8(cachePath);
|
|
64993
65675
|
}
|
|
64994
65676
|
} catch {}
|
|
@@ -65867,15 +66549,15 @@ var init_local_liveness = __esm(() => {
|
|
|
65867
66549
|
});
|
|
65868
66550
|
|
|
65869
66551
|
// src/providers/probe-catalog.ts
|
|
65870
|
-
import { existsSync as
|
|
65871
|
-
import { homedir as
|
|
65872
|
-
import { dirname as
|
|
66552
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync15, readFileSync as readFileSync22, writeFileSync as writeFileSync17 } from "fs";
|
|
66553
|
+
import { homedir as homedir24 } from "os";
|
|
66554
|
+
import { dirname as dirname9, join as join26 } from "path";
|
|
65873
66555
|
function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
|
|
65874
|
-
if (!
|
|
66556
|
+
if (!existsSync23(path2))
|
|
65875
66557
|
return null;
|
|
65876
66558
|
let raw2;
|
|
65877
66559
|
try {
|
|
65878
|
-
raw2 = JSON.parse(
|
|
66560
|
+
raw2 = JSON.parse(readFileSync22(path2, "utf-8"));
|
|
65879
66561
|
} catch {
|
|
65880
66562
|
return null;
|
|
65881
66563
|
}
|
|
@@ -65884,8 +66566,8 @@ function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
|
|
|
65884
66566
|
return raw2;
|
|
65885
66567
|
}
|
|
65886
66568
|
function writeProbeModelsCache(data, path2 = PROBE_MODELS_CACHE_PATH) {
|
|
65887
|
-
|
|
65888
|
-
|
|
66569
|
+
mkdirSync15(dirname9(path2), { recursive: true });
|
|
66570
|
+
writeFileSync17(path2, JSON.stringify(data), "utf-8");
|
|
65889
66571
|
}
|
|
65890
66572
|
function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
|
|
65891
66573
|
if (!data?.generatedAt)
|
|
@@ -66004,7 +66686,7 @@ function isValidResponse(raw2) {
|
|
|
66004
66686
|
var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels", CACHE_TTL_MS4, FETCH_TIMEOUT_MS3 = 15000, PROBE_MODELS_CACHE_PATH, _inFlight = null;
|
|
66005
66687
|
var init_probe_catalog = __esm(() => {
|
|
66006
66688
|
CACHE_TTL_MS4 = 60 * 60 * 1000;
|
|
66007
|
-
PROBE_MODELS_CACHE_PATH =
|
|
66689
|
+
PROBE_MODELS_CACHE_PATH = join26(homedir24(), ".claudish", "probe-models.json");
|
|
66008
66690
|
});
|
|
66009
66691
|
|
|
66010
66692
|
// src/tui/constants.ts
|
|
@@ -72337,16 +73019,16 @@ __export(exports_claude_runner, {
|
|
|
72337
73019
|
});
|
|
72338
73020
|
import { spawn as spawn4 } from "child_process";
|
|
72339
73021
|
import {
|
|
72340
|
-
closeSync as
|
|
72341
|
-
existsSync as
|
|
72342
|
-
mkdirSync as
|
|
72343
|
-
openSync as
|
|
72344
|
-
readFileSync as
|
|
73022
|
+
closeSync as closeSync5,
|
|
73023
|
+
existsSync as existsSync24,
|
|
73024
|
+
mkdirSync as mkdirSync16,
|
|
73025
|
+
openSync as openSync5,
|
|
73026
|
+
readFileSync as readFileSync23,
|
|
72345
73027
|
unlinkSync as unlinkSync9,
|
|
72346
|
-
writeFileSync as
|
|
73028
|
+
writeFileSync as writeFileSync18
|
|
72347
73029
|
} from "fs";
|
|
72348
|
-
import { homedir as
|
|
72349
|
-
import { join as
|
|
73030
|
+
import { homedir as homedir25, tmpdir as tmpdir2 } from "os";
|
|
73031
|
+
import { join as join27 } from "path";
|
|
72350
73032
|
import { isatty } from "tty";
|
|
72351
73033
|
function releaseTerminalIsolation() {
|
|
72352
73034
|
if (!restoreTerminal)
|
|
@@ -72381,14 +73063,14 @@ function isProxyAuthMode(config3) {
|
|
|
72381
73063
|
}
|
|
72382
73064
|
function managedSettingsPath() {
|
|
72383
73065
|
if (isWindows2()) {
|
|
72384
|
-
return
|
|
73066
|
+
return join27(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
|
|
72385
73067
|
}
|
|
72386
73068
|
if (process.platform === "darwin") {
|
|
72387
73069
|
return "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
72388
73070
|
}
|
|
72389
73071
|
return "/etc/claude-code/managed-settings.json";
|
|
72390
73072
|
}
|
|
72391
|
-
function managedSettingsForcesClaudeAi(readFile =
|
|
73073
|
+
function managedSettingsForcesClaudeAi(readFile = readFileSync23) {
|
|
72392
73074
|
try {
|
|
72393
73075
|
const raw2 = readFile(managedSettingsPath(), "utf-8");
|
|
72394
73076
|
const parsed = JSON.parse(raw2);
|
|
@@ -72402,9 +73084,9 @@ function isWindows2() {
|
|
|
72402
73084
|
}
|
|
72403
73085
|
function createStatusLineScript(tokenFilePath) {
|
|
72404
73086
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
72405
|
-
const claudishDir =
|
|
73087
|
+
const claudishDir = join27(homeDir, ".claudish");
|
|
72406
73088
|
const timestamp = Date.now();
|
|
72407
|
-
const scriptPath =
|
|
73089
|
+
const scriptPath = join27(claudishDir, `status-${timestamp}.js`);
|
|
72408
73090
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
72409
73091
|
const script = `
|
|
72410
73092
|
const fs = require('fs');
|
|
@@ -72496,18 +73178,18 @@ process.stdin.on('end', () => {
|
|
|
72496
73178
|
}
|
|
72497
73179
|
});
|
|
72498
73180
|
`;
|
|
72499
|
-
|
|
73181
|
+
writeFileSync18(scriptPath, script, "utf-8");
|
|
72500
73182
|
return scriptPath;
|
|
72501
73183
|
}
|
|
72502
73184
|
function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
|
|
72503
73185
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
72504
|
-
const claudishDir =
|
|
73186
|
+
const claudishDir = join27(homeDir, ".claudish");
|
|
72505
73187
|
try {
|
|
72506
|
-
|
|
73188
|
+
mkdirSync16(claudishDir, { recursive: true });
|
|
72507
73189
|
} catch {}
|
|
72508
73190
|
const timestamp = Date.now();
|
|
72509
|
-
const tempPath =
|
|
72510
|
-
const tokenFilePath =
|
|
73191
|
+
const tempPath = join27(claudishDir, `settings-${timestamp}.json`);
|
|
73192
|
+
const tokenFilePath = join27(claudishDir, `tokens-${port}.json`);
|
|
72511
73193
|
let statusCommand;
|
|
72512
73194
|
if (isWindows2()) {
|
|
72513
73195
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
@@ -72529,7 +73211,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
|
|
|
72529
73211
|
padding: 0
|
|
72530
73212
|
};
|
|
72531
73213
|
const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
|
|
72532
|
-
|
|
73214
|
+
writeFileSync18(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
72533
73215
|
return { path: tempPath, statusLine };
|
|
72534
73216
|
}
|
|
72535
73217
|
function buildClaudishSettingsOverlay(statusLine, proxyAuthMode) {
|
|
@@ -72550,7 +73232,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
|
|
|
72550
73232
|
if (userSettingsValue.trimStart().startsWith("{")) {
|
|
72551
73233
|
userSettings = JSON.parse(userSettingsValue);
|
|
72552
73234
|
} else {
|
|
72553
|
-
const rawUserSettings =
|
|
73235
|
+
const rawUserSettings = readFileSync23(userSettingsValue, "utf-8");
|
|
72554
73236
|
userSettings = JSON.parse(rawUserSettings);
|
|
72555
73237
|
}
|
|
72556
73238
|
userSettings.statusLine = statusLine;
|
|
@@ -72560,7 +73242,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
|
|
|
72560
73242
|
if (proxyAuthMode && !("forceLoginMethod" in userSettings)) {
|
|
72561
73243
|
userSettings.forceLoginMethod = "console";
|
|
72562
73244
|
}
|
|
72563
|
-
|
|
73245
|
+
writeFileSync18(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
72564
73246
|
} catch {
|
|
72565
73247
|
if (!config3.quiet) {
|
|
72566
73248
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -72721,8 +73403,8 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
72721
73403
|
console.error("Install it from: https://claude.com/claude-code");
|
|
72722
73404
|
console.error(`
|
|
72723
73405
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
72724
|
-
const home =
|
|
72725
|
-
const localPath = isWindows2() ?
|
|
73406
|
+
const home = homedir25();
|
|
73407
|
+
const localPath = isWindows2() ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
|
|
72726
73408
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
72727
73409
|
process.exit(1);
|
|
72728
73410
|
}
|
|
@@ -72733,11 +73415,11 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
72733
73415
|
const childWantsTty = config3.interactive && !process.stdout.isTTY && Boolean(process.stdin.isTTY);
|
|
72734
73416
|
if (childWantsTty) {
|
|
72735
73417
|
try {
|
|
72736
|
-
const fd =
|
|
73418
|
+
const fd = openSync5("/dev/fd/0", "r+");
|
|
72737
73419
|
if (isatty(fd)) {
|
|
72738
73420
|
ttyFd = fd;
|
|
72739
73421
|
} else {
|
|
72740
|
-
|
|
73422
|
+
closeSync5(fd);
|
|
72741
73423
|
}
|
|
72742
73424
|
} catch {
|
|
72743
73425
|
ttyFd = undefined;
|
|
@@ -72760,7 +73442,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
72760
73442
|
const fdToClose = ttyFd;
|
|
72761
73443
|
proc.on("spawn", () => {
|
|
72762
73444
|
try {
|
|
72763
|
-
|
|
73445
|
+
closeSync5(fdToClose);
|
|
72764
73446
|
} catch {}
|
|
72765
73447
|
});
|
|
72766
73448
|
}
|
|
@@ -72802,23 +73484,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
72802
73484
|
async function findClaudeBinary() {
|
|
72803
73485
|
const isWindows3 = process.platform === "win32";
|
|
72804
73486
|
if (process.env.CLAUDE_PATH) {
|
|
72805
|
-
if (
|
|
73487
|
+
if (existsSync24(process.env.CLAUDE_PATH)) {
|
|
72806
73488
|
return process.env.CLAUDE_PATH;
|
|
72807
73489
|
}
|
|
72808
73490
|
}
|
|
72809
|
-
const home =
|
|
72810
|
-
const localPath = isWindows3 ?
|
|
72811
|
-
if (
|
|
73491
|
+
const home = homedir25();
|
|
73492
|
+
const localPath = isWindows3 ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
|
|
73493
|
+
if (existsSync24(localPath)) {
|
|
72812
73494
|
return localPath;
|
|
72813
73495
|
}
|
|
72814
73496
|
if (isWindows3) {
|
|
72815
73497
|
const windowsPaths = [
|
|
72816
|
-
|
|
72817
|
-
|
|
72818
|
-
|
|
73498
|
+
join27(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
73499
|
+
join27(home, ".npm-global", "claude.cmd"),
|
|
73500
|
+
join27(home, "node_modules", ".bin", "claude.cmd")
|
|
72819
73501
|
];
|
|
72820
73502
|
for (const path2 of windowsPaths) {
|
|
72821
|
-
if (
|
|
73503
|
+
if (existsSync24(path2)) {
|
|
72822
73504
|
return path2;
|
|
72823
73505
|
}
|
|
72824
73506
|
}
|
|
@@ -72826,14 +73508,14 @@ async function findClaudeBinary() {
|
|
|
72826
73508
|
const commonPaths = [
|
|
72827
73509
|
"/usr/local/bin/claude",
|
|
72828
73510
|
"/opt/homebrew/bin/claude",
|
|
72829
|
-
|
|
72830
|
-
|
|
72831
|
-
|
|
73511
|
+
join27(home, ".npm-global/bin/claude"),
|
|
73512
|
+
join27(home, ".local/bin/claude"),
|
|
73513
|
+
join27(home, "node_modules/.bin/claude"),
|
|
72832
73514
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
72833
|
-
|
|
73515
|
+
join27(home, "../usr/bin/claude")
|
|
72834
73516
|
];
|
|
72835
73517
|
for (const path2 of commonPaths) {
|
|
72836
|
-
if (
|
|
73518
|
+
if (existsSync24(path2)) {
|
|
72837
73519
|
return path2;
|
|
72838
73520
|
}
|
|
72839
73521
|
}
|
|
@@ -72890,18 +73572,18 @@ __export(exports_diag_output, {
|
|
|
72890
73572
|
NullDiagOutput: () => NullDiagOutput,
|
|
72891
73573
|
LogFileDiagOutput: () => LogFileDiagOutput
|
|
72892
73574
|
});
|
|
72893
|
-
import { createWriteStream as createWriteStream3, mkdirSync as
|
|
72894
|
-
import { homedir as
|
|
72895
|
-
import { join as
|
|
73575
|
+
import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync17, unlinkSync as unlinkSync10, writeFileSync as writeFileSync19 } from "fs";
|
|
73576
|
+
import { homedir as homedir26 } from "os";
|
|
73577
|
+
import { join as join28 } from "path";
|
|
72896
73578
|
function getClaudishDir() {
|
|
72897
|
-
const dir =
|
|
73579
|
+
const dir = join28(homedir26(), ".claudish");
|
|
72898
73580
|
try {
|
|
72899
|
-
|
|
73581
|
+
mkdirSync17(dir, { recursive: true });
|
|
72900
73582
|
} catch {}
|
|
72901
73583
|
return dir;
|
|
72902
73584
|
}
|
|
72903
73585
|
function getDiagLogPath() {
|
|
72904
|
-
return
|
|
73586
|
+
return join28(getClaudishDir(), `diag-${process.pid}.log`);
|
|
72905
73587
|
}
|
|
72906
73588
|
|
|
72907
73589
|
class LogFileDiagOutput {
|
|
@@ -72910,7 +73592,7 @@ class LogFileDiagOutput {
|
|
|
72910
73592
|
constructor() {
|
|
72911
73593
|
this.logPath = getDiagLogPath();
|
|
72912
73594
|
try {
|
|
72913
|
-
|
|
73595
|
+
writeFileSync19(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
72914
73596
|
`);
|
|
72915
73597
|
} catch {}
|
|
72916
73598
|
this.stream = createWriteStream3(this.logPath, { flags: "a" });
|
|
@@ -73112,9 +73794,9 @@ __export(exports_team_grid, {
|
|
|
73112
73794
|
});
|
|
73113
73795
|
import { spawn as spawn5 } from "child_process";
|
|
73114
73796
|
import { execSync as execSync2 } from "child_process";
|
|
73115
|
-
import { existsSync as
|
|
73797
|
+
import { existsSync as existsSync25, readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "fs";
|
|
73116
73798
|
import { connect as netConnect } from "net";
|
|
73117
|
-
import { dirname as
|
|
73799
|
+
import { dirname as dirname10, join as join29 } from "path";
|
|
73118
73800
|
import { setTimeout as wait } from "timers/promises";
|
|
73119
73801
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
73120
73802
|
function resolveRouteInfo(modelId) {
|
|
@@ -73207,21 +73889,21 @@ function buildPaneHeader(model, prompt, bg) {
|
|
|
73207
73889
|
}
|
|
73208
73890
|
function findMagmuxBinary() {
|
|
73209
73891
|
const thisFile = fileURLToPath3(import.meta.url);
|
|
73210
|
-
const thisDir =
|
|
73211
|
-
const pkgRoot =
|
|
73892
|
+
const thisDir = dirname10(thisFile);
|
|
73893
|
+
const pkgRoot = join29(thisDir, "..");
|
|
73212
73894
|
const platform3 = process.platform;
|
|
73213
73895
|
const arch = process.arch;
|
|
73214
|
-
const bundledMagmux =
|
|
73215
|
-
if (
|
|
73896
|
+
const bundledMagmux = join29(pkgRoot, "native", `magmux-${platform3}-${arch}`);
|
|
73897
|
+
if (existsSync25(bundledMagmux))
|
|
73216
73898
|
return bundledMagmux;
|
|
73217
73899
|
try {
|
|
73218
73900
|
const pkgName = `@claudish/magmux-${platform3}-${arch}`;
|
|
73219
73901
|
let searchDir = pkgRoot;
|
|
73220
73902
|
for (let i = 0;i < 5; i++) {
|
|
73221
|
-
const candidate =
|
|
73222
|
-
if (
|
|
73903
|
+
const candidate = join29(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
73904
|
+
if (existsSync25(candidate))
|
|
73223
73905
|
return candidate;
|
|
73224
|
-
const parent =
|
|
73906
|
+
const parent = dirname10(searchDir);
|
|
73225
73907
|
if (parent === searchDir)
|
|
73226
73908
|
break;
|
|
73227
73909
|
searchDir = parent;
|
|
@@ -73238,7 +73920,7 @@ function findMagmuxBinary() {
|
|
|
73238
73920
|
async function subscribeToMagmux(sockPath, onEvent) {
|
|
73239
73921
|
let client = null;
|
|
73240
73922
|
for (let attempt = 0;attempt < 40; attempt++) {
|
|
73241
|
-
if (
|
|
73923
|
+
if (existsSync25(sockPath)) {
|
|
73242
73924
|
try {
|
|
73243
73925
|
client = await new Promise((resolve4, reject) => {
|
|
73244
73926
|
const s = netConnect(sockPath);
|
|
@@ -73325,9 +74007,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
73325
74007
|
const keep = opts?.keep ?? false;
|
|
73326
74008
|
const manifest = setupSession(sessionPath, models, input);
|
|
73327
74009
|
const startedAt = new Date().toISOString();
|
|
73328
|
-
const gridfilePath =
|
|
73329
|
-
const prompt =
|
|
73330
|
-
const rawPrompt =
|
|
74010
|
+
const gridfilePath = join29(sessionPath, "gridfile.txt");
|
|
74011
|
+
const prompt = readFileSync24(join29(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
74012
|
+
const rawPrompt = readFileSync24(join29(sessionPath, "input.md"), "utf-8");
|
|
73331
74013
|
const usedBannerColors = new Set;
|
|
73332
74014
|
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
73333
74015
|
const model = manifest.models[anonId].model;
|
|
@@ -73338,7 +74020,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
73338
74020
|
const header = buildPaneHeader(model, rawPrompt, bg);
|
|
73339
74021
|
return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
|
|
73340
74022
|
});
|
|
73341
|
-
|
|
74023
|
+
writeFileSync20(gridfilePath, `${gridLines.join(`
|
|
73342
74024
|
`)}
|
|
73343
74025
|
`, "utf-8");
|
|
73344
74026
|
const magmuxPath = findMagmuxBinary();
|
|
@@ -73358,8 +74040,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
73358
74040
|
});
|
|
73359
74041
|
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
73360
74042
|
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
73361
|
-
const statusPath =
|
|
73362
|
-
|
|
74043
|
+
const statusPath = join29(sessionPath, "status.json");
|
|
74044
|
+
writeFileSync20(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
73363
74045
|
return status;
|
|
73364
74046
|
}
|
|
73365
74047
|
var BANNER_BG_COLORS;
|
|
@@ -73382,8 +74064,8 @@ var init_team_grid = __esm(() => {
|
|
|
73382
74064
|
init_op_source();
|
|
73383
74065
|
init_startup_trace();
|
|
73384
74066
|
var import_dotenv3 = __toESM(require_main(), 1);
|
|
73385
|
-
import { existsSync as
|
|
73386
|
-
import { join as
|
|
74067
|
+
import { existsSync as existsSync26, readFileSync as readFileSync25 } from "fs";
|
|
74068
|
+
import { join as join30, resolve as resolve4 } from "path";
|
|
73387
74069
|
import_dotenv3.config({ quiet: true });
|
|
73388
74070
|
function classifyStartupKind() {
|
|
73389
74071
|
const argv = process.argv.slice(2);
|
|
@@ -73482,7 +74164,7 @@ async function applyConfigOverride() {
|
|
|
73482
74164
|
const { planConfigOverride: planConfigOverride2, setConfigFileOverride: setConfigFileOverride2 } = await Promise.resolve().then(() => exports_config_override);
|
|
73483
74165
|
const plan = planConfigOverride2(process.argv.slice(2), process.env, {
|
|
73484
74166
|
resolve: resolve4,
|
|
73485
|
-
exists:
|
|
74167
|
+
exists: existsSync26
|
|
73486
74168
|
});
|
|
73487
74169
|
if (plan.kind === "none")
|
|
73488
74170
|
return;
|
|
@@ -73617,14 +74299,14 @@ async function runCli() {
|
|
|
73617
74299
|
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
73618
74300
|
let prompt = cliConfig.claudeArgs.join(" ");
|
|
73619
74301
|
if (cliConfig.inputFile) {
|
|
73620
|
-
prompt =
|
|
74302
|
+
prompt = readFileSync25(cliConfig.inputFile, "utf-8");
|
|
73621
74303
|
}
|
|
73622
74304
|
if (!prompt.trim()) {
|
|
73623
74305
|
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
73624
74306
|
process.exit(1);
|
|
73625
74307
|
}
|
|
73626
74308
|
const mode = cliConfig.teamMode ?? "default";
|
|
73627
|
-
const sessionPath =
|
|
74309
|
+
const sessionPath = join30(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
73628
74310
|
if (mode === "json") {
|
|
73629
74311
|
const { setupSession: setupSession2, runModels: runModels2 } = await Promise.resolve().then(() => (init_team_orchestrator(), exports_team_orchestrator));
|
|
73630
74312
|
setupSession2(sessionPath, cliConfig.team, prompt);
|
|
@@ -73634,9 +74316,9 @@ async function runCli() {
|
|
|
73634
74316
|
});
|
|
73635
74317
|
const result = { ...status2, responses: {} };
|
|
73636
74318
|
for (const anonId of Object.keys(status2.models)) {
|
|
73637
|
-
const responsePath =
|
|
74319
|
+
const responsePath = join30(sessionPath, `response-${anonId}.md`);
|
|
73638
74320
|
try {
|
|
73639
|
-
const raw2 =
|
|
74321
|
+
const raw2 = readFileSync25(responsePath, "utf-8").trim();
|
|
73640
74322
|
try {
|
|
73641
74323
|
result.responses[anonId] = JSON.parse(raw2);
|
|
73642
74324
|
} catch {
|