claudish 7.25.0 → 7.26.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 +1022 -440
- 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.26.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();
|
|
4262
|
+
}
|
|
4263
|
+
function isLockedDenial(err, env = process.env) {
|
|
4264
|
+
return classifyLockedDenial(err, env) !== null;
|
|
4102
4265
|
}
|
|
4103
|
-
async function countdownForUnlock(round, rounds) {
|
|
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)) {
|
|
@@ -37720,7 +37962,7 @@ var init_openai = __esm(() => {
|
|
|
37720
37962
|
});
|
|
37721
37963
|
|
|
37722
37964
|
// src/providers/catalog-query.ts
|
|
37723
|
-
import { statSync } from "fs";
|
|
37965
|
+
import { statSync as statSync2 } from "fs";
|
|
37724
37966
|
function project(entry) {
|
|
37725
37967
|
return {
|
|
37726
37968
|
modelId: entry.modelId,
|
|
@@ -37733,7 +37975,7 @@ function project(entry) {
|
|
|
37733
37975
|
function getCachedEntries() {
|
|
37734
37976
|
let mtimeMs;
|
|
37735
37977
|
try {
|
|
37736
|
-
mtimeMs =
|
|
37978
|
+
mtimeMs = statSync2(ALL_MODELS_CACHE_PATH).mtimeMs;
|
|
37737
37979
|
} catch {
|
|
37738
37980
|
return null;
|
|
37739
37981
|
}
|
|
@@ -37908,24 +38150,24 @@ var init_vision_proxy = __esm(() => {
|
|
|
37908
38150
|
// src/stats-buffer.ts
|
|
37909
38151
|
import {
|
|
37910
38152
|
existsSync as existsSync14,
|
|
37911
|
-
mkdirSync as
|
|
37912
|
-
readFileSync as
|
|
38153
|
+
mkdirSync as mkdirSync9,
|
|
38154
|
+
readFileSync as readFileSync12,
|
|
37913
38155
|
renameSync,
|
|
37914
38156
|
unlinkSync as unlinkSync5,
|
|
37915
38157
|
writeFileSync as writeFileSync9
|
|
37916
38158
|
} from "fs";
|
|
37917
|
-
import { homedir as
|
|
37918
|
-
import { join as
|
|
38159
|
+
import { homedir as homedir17 } from "os";
|
|
38160
|
+
import { join as join17 } from "path";
|
|
37919
38161
|
function ensureDir() {
|
|
37920
38162
|
if (!existsSync14(CLAUDISH_DIR)) {
|
|
37921
|
-
|
|
38163
|
+
mkdirSync9(CLAUDISH_DIR, { recursive: true });
|
|
37922
38164
|
}
|
|
37923
38165
|
}
|
|
37924
38166
|
function readFromDisk() {
|
|
37925
38167
|
try {
|
|
37926
38168
|
if (!existsSync14(BUFFER_FILE))
|
|
37927
38169
|
return [];
|
|
37928
|
-
const raw2 =
|
|
38170
|
+
const raw2 = readFileSync12(BUFFER_FILE, "utf-8");
|
|
37929
38171
|
const parsed = JSON.parse(raw2);
|
|
37930
38172
|
if (!Array.isArray(parsed.events))
|
|
37931
38173
|
return [];
|
|
@@ -37950,7 +38192,7 @@ function writeToDisk(events) {
|
|
|
37950
38192
|
ensureDir();
|
|
37951
38193
|
const trimmed = enforceSizeCap([...events]);
|
|
37952
38194
|
const payload = { version: 1, events: trimmed };
|
|
37953
|
-
const tmpFile =
|
|
38195
|
+
const tmpFile = join17(CLAUDISH_DIR, `stats-buffer.tmp.${process.pid}.json`);
|
|
37954
38196
|
writeFileSync9(tmpFile, JSON.stringify(payload, null, 2), "utf-8");
|
|
37955
38197
|
renameSync(tmpFile, BUFFER_FILE);
|
|
37956
38198
|
memoryCache = trimmed;
|
|
@@ -38023,8 +38265,8 @@ function syncFlushOnExit() {
|
|
|
38023
38265
|
var BUFFER_MAX_BYTES, CLAUDISH_DIR, BUFFER_FILE, memoryCache = null, eventsSinceLastFlush = 0, flushScheduled = false;
|
|
38024
38266
|
var init_stats_buffer = __esm(() => {
|
|
38025
38267
|
BUFFER_MAX_BYTES = 64 * 1024;
|
|
38026
|
-
CLAUDISH_DIR =
|
|
38027
|
-
BUFFER_FILE =
|
|
38268
|
+
CLAUDISH_DIR = join17(homedir17(), ".claudish");
|
|
38269
|
+
BUFFER_FILE = join17(CLAUDISH_DIR, "stats-buffer.json");
|
|
38028
38270
|
process.on("exit", syncFlushOnExit);
|
|
38029
38271
|
process.on("SIGTERM", () => {
|
|
38030
38272
|
try {
|
|
@@ -40227,9 +40469,9 @@ var init_openai_responses_sse = __esm(() => {
|
|
|
40227
40469
|
});
|
|
40228
40470
|
|
|
40229
40471
|
// src/handlers/shared/token-tracker.ts
|
|
40230
|
-
import { mkdirSync as
|
|
40231
|
-
import { homedir as
|
|
40232
|
-
import { join as
|
|
40472
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
|
|
40473
|
+
import { homedir as homedir18 } from "os";
|
|
40474
|
+
import { dirname as dirname6, join as join18 } from "path";
|
|
40233
40475
|
|
|
40234
40476
|
class TokenTracker {
|
|
40235
40477
|
port;
|
|
@@ -40372,9 +40614,10 @@ class TokenTracker {
|
|
|
40372
40614
|
if (this.quotaRemaining !== undefined) {
|
|
40373
40615
|
data.quota_remaining = this.quotaRemaining;
|
|
40374
40616
|
}
|
|
40375
|
-
const
|
|
40376
|
-
|
|
40377
|
-
|
|
40617
|
+
const override = process.env.CLAUDISH_TOKEN_FILE;
|
|
40618
|
+
const outPath = override || join18(homedir18(), ".claudish", `tokens-${this.port}.json`);
|
|
40619
|
+
mkdirSync10(dirname6(outPath), { recursive: true });
|
|
40620
|
+
writeFileSync10(outPath, JSON.stringify(data), "utf-8");
|
|
40378
40621
|
} catch (e) {
|
|
40379
40622
|
log(`[TokenTracker] Error writing token file: ${e}`);
|
|
40380
40623
|
}
|
|
@@ -42871,11 +43114,11 @@ var init_ollama_api_format = __esm(() => {
|
|
|
42871
43114
|
});
|
|
42872
43115
|
|
|
42873
43116
|
// src/providers/api-key-provenance.ts
|
|
42874
|
-
import { existsSync as existsSync15, readFileSync as
|
|
42875
|
-
import { homedir as
|
|
42876
|
-
import { join as
|
|
43117
|
+
import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
|
|
43118
|
+
import { homedir as homedir19 } from "os";
|
|
43119
|
+
import { join as join19, resolve as resolve2 } from "path";
|
|
42877
43120
|
function activeConfigPath() {
|
|
42878
|
-
return activeGlobalConfigFile(
|
|
43121
|
+
return activeGlobalConfigFile(join19(homedir19(), ".claudish", "config.json"));
|
|
42879
43122
|
}
|
|
42880
43123
|
function configLayerLabel() {
|
|
42881
43124
|
return getConfigFileOverride() ? activeConfigPath() : "~/.claudish/config.json";
|
|
@@ -42954,7 +43197,7 @@ function readDotenvKey(envVars) {
|
|
|
42954
43197
|
const dotenvPath = resolve2(".env");
|
|
42955
43198
|
if (!existsSync15(dotenvPath))
|
|
42956
43199
|
return null;
|
|
42957
|
-
const parsed = import_dotenv.parse(
|
|
43200
|
+
const parsed = import_dotenv.parse(readFileSync13(dotenvPath, "utf-8"));
|
|
42958
43201
|
for (const v of envVars) {
|
|
42959
43202
|
if (parsed[v])
|
|
42960
43203
|
return parsed[v];
|
|
@@ -42969,7 +43212,7 @@ function readConfigKey(envVar) {
|
|
|
42969
43212
|
const configPath = activeConfigPath();
|
|
42970
43213
|
if (!existsSync15(configPath))
|
|
42971
43214
|
return null;
|
|
42972
|
-
const cfg = JSON.parse(
|
|
43215
|
+
const cfg = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
42973
43216
|
return cfg.apiKeys?.[envVar] || null;
|
|
42974
43217
|
} catch {
|
|
42975
43218
|
return null;
|
|
@@ -44527,9 +44770,9 @@ var init_poe = __esm(() => {
|
|
|
44527
44770
|
});
|
|
44528
44771
|
|
|
44529
44772
|
// src/services/pricing-cache.ts
|
|
44530
|
-
import { existsSync as existsSync16, readFileSync as
|
|
44531
|
-
import { homedir as
|
|
44532
|
-
import { join as
|
|
44773
|
+
import { existsSync as existsSync16, readFileSync as readFileSync14, statSync as statSync3 } from "fs";
|
|
44774
|
+
import { homedir as homedir20 } from "os";
|
|
44775
|
+
import { join as join20 } from "path";
|
|
44533
44776
|
function prefixMatch(modelName) {
|
|
44534
44777
|
for (const [key, pricing] of pricingMap) {
|
|
44535
44778
|
if (modelName.startsWith(key))
|
|
@@ -44569,10 +44812,10 @@ function loadDiskCache() {
|
|
|
44569
44812
|
try {
|
|
44570
44813
|
if (!existsSync16(CACHE_FILE))
|
|
44571
44814
|
return false;
|
|
44572
|
-
const stat =
|
|
44815
|
+
const stat = statSync3(CACHE_FILE);
|
|
44573
44816
|
const age = Date.now() - stat.mtimeMs;
|
|
44574
44817
|
const isFresh = age < CACHE_TTL_MS2;
|
|
44575
|
-
const raw2 =
|
|
44818
|
+
const raw2 = readFileSync14(CACHE_FILE, "utf-8");
|
|
44576
44819
|
const data = JSON.parse(raw2);
|
|
44577
44820
|
for (const [key, pricing] of Object.entries(data)) {
|
|
44578
44821
|
pricingMap.set(key, pricing);
|
|
@@ -44588,8 +44831,8 @@ var init_pricing_cache = __esm(() => {
|
|
|
44588
44831
|
init_logger();
|
|
44589
44832
|
init_catalog_query();
|
|
44590
44833
|
pricingMap = new Map;
|
|
44591
|
-
CACHE_DIR =
|
|
44592
|
-
CACHE_FILE =
|
|
44834
|
+
CACHE_DIR = join20(homedir20(), ".claudish");
|
|
44835
|
+
CACHE_FILE = join20(CACHE_DIR, "pricing-cache.json");
|
|
44593
44836
|
CACHE_TTL_MS2 = 24 * 60 * 60 * 1000;
|
|
44594
44837
|
});
|
|
44595
44838
|
|
|
@@ -45045,6 +45288,175 @@ var init_proxy_server = __esm(() => {
|
|
|
45045
45288
|
};
|
|
45046
45289
|
});
|
|
45047
45290
|
|
|
45291
|
+
// src/team-stats.ts
|
|
45292
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "fs";
|
|
45293
|
+
import { join as join21 } from "path";
|
|
45294
|
+
function statsDir(sessionPath) {
|
|
45295
|
+
return join21(sessionPath, "stats");
|
|
45296
|
+
}
|
|
45297
|
+
function tokenFileFor(sessionPath, anonId) {
|
|
45298
|
+
return join21(statsDir(sessionPath), `${anonId}.json`);
|
|
45299
|
+
}
|
|
45300
|
+
function readTokenStats(sessionPath, anonId) {
|
|
45301
|
+
const path = tokenFileFor(sessionPath, anonId);
|
|
45302
|
+
if (!existsSync17(path))
|
|
45303
|
+
return null;
|
|
45304
|
+
try {
|
|
45305
|
+
return JSON.parse(readFileSync15(path, "utf-8"));
|
|
45306
|
+
} catch {
|
|
45307
|
+
return null;
|
|
45308
|
+
}
|
|
45309
|
+
}
|
|
45310
|
+
function fmtTokens(n) {
|
|
45311
|
+
if (!n || n <= 0)
|
|
45312
|
+
return "0";
|
|
45313
|
+
if (n < 1000)
|
|
45314
|
+
return String(n);
|
|
45315
|
+
if (n < 1e6)
|
|
45316
|
+
return `${(n / 1000).toFixed(1)}k`;
|
|
45317
|
+
return `${(n / 1e6).toFixed(1)}M`;
|
|
45318
|
+
}
|
|
45319
|
+
function fmtCost(cost, isFree) {
|
|
45320
|
+
if (isFree)
|
|
45321
|
+
return "free";
|
|
45322
|
+
if (cost === undefined || cost <= 0)
|
|
45323
|
+
return "$0";
|
|
45324
|
+
return `$${cost.toFixed(3)}`;
|
|
45325
|
+
}
|
|
45326
|
+
function fmtBytes(n) {
|
|
45327
|
+
if (n <= 0)
|
|
45328
|
+
return "0B";
|
|
45329
|
+
if (n < 1024)
|
|
45330
|
+
return `${n}B`;
|
|
45331
|
+
if (n < 1024 * 1024)
|
|
45332
|
+
return `${(n / 1024).toFixed(1)}KB`;
|
|
45333
|
+
return `${(n / (1024 * 1024)).toFixed(1)}MB`;
|
|
45334
|
+
}
|
|
45335
|
+
function fmtState(state) {
|
|
45336
|
+
switch (state) {
|
|
45337
|
+
case "COMPLETED":
|
|
45338
|
+
return "done";
|
|
45339
|
+
case "RUNNING":
|
|
45340
|
+
return "run ";
|
|
45341
|
+
case "FAILED":
|
|
45342
|
+
return "FAIL";
|
|
45343
|
+
case "TIMEOUT":
|
|
45344
|
+
return "TIME";
|
|
45345
|
+
case "EMPTY":
|
|
45346
|
+
return "EMPT";
|
|
45347
|
+
case "PENDING":
|
|
45348
|
+
return "wait";
|
|
45349
|
+
default:
|
|
45350
|
+
return "? ";
|
|
45351
|
+
}
|
|
45352
|
+
}
|
|
45353
|
+
function renderTeamStats(sessionPath, manifest, status, opts) {
|
|
45354
|
+
const nameWidth = opts.modelNameWidth ?? 18;
|
|
45355
|
+
const ids = Object.keys(manifest.models).sort();
|
|
45356
|
+
let done = 0;
|
|
45357
|
+
let running = 0;
|
|
45358
|
+
let failed = 0;
|
|
45359
|
+
let totalTokens = 0;
|
|
45360
|
+
let totalCost = 0;
|
|
45361
|
+
let anyFree = false;
|
|
45362
|
+
const rows = [];
|
|
45363
|
+
for (const id of ids) {
|
|
45364
|
+
const m = status.models[id];
|
|
45365
|
+
if (!m)
|
|
45366
|
+
continue;
|
|
45367
|
+
const model = manifest.models[id]?.model ?? "unknown";
|
|
45368
|
+
const stats = readTokenStats(sessionPath, id);
|
|
45369
|
+
if (m.state === "COMPLETED")
|
|
45370
|
+
done++;
|
|
45371
|
+
else if (m.state === "RUNNING" || m.state === "PENDING")
|
|
45372
|
+
running++;
|
|
45373
|
+
else
|
|
45374
|
+
failed++;
|
|
45375
|
+
const inTok = stats?.input_tokens ?? 0;
|
|
45376
|
+
const outTok = stats?.output_tokens ?? 0;
|
|
45377
|
+
totalTokens += stats?.total_tokens ?? inTok + outTok;
|
|
45378
|
+
totalCost += stats?.total_cost ?? 0;
|
|
45379
|
+
if (stats?.is_free)
|
|
45380
|
+
anyFree = true;
|
|
45381
|
+
const name = model.length > nameWidth ? `${model.slice(0, nameWidth - 1)}\u2026` : model;
|
|
45382
|
+
const bytes = m.outputSize > 0 ? fmtBytes(m.outputSize) : "";
|
|
45383
|
+
const tokens = stats ? `${fmtTokens(inTok)}/${outTok > 0 ? fmtTokens(outTok) : "-"}` : "";
|
|
45384
|
+
const cost = stats ? fmtCost(stats.total_cost, stats.is_free) : "";
|
|
45385
|
+
rows.push(` ${id} ${name.padEnd(nameWidth)} ${fmtState(m.state)} ` + `${bytes.padStart(7)} ${tokens.padStart(12)} ${cost.padStart(7)}`.trimEnd());
|
|
45386
|
+
}
|
|
45387
|
+
const parts = [`${ids.length} models`];
|
|
45388
|
+
if (done)
|
|
45389
|
+
parts.push(`${done} done`);
|
|
45390
|
+
if (running)
|
|
45391
|
+
parts.push(`${running} running`);
|
|
45392
|
+
if (failed)
|
|
45393
|
+
parts.push(`${failed} failed`);
|
|
45394
|
+
parts.push(`${Math.round(opts.elapsedSeconds)}s`);
|
|
45395
|
+
if (totalTokens > 0)
|
|
45396
|
+
parts.push(`${fmtTokens(totalTokens)} tok`);
|
|
45397
|
+
if (totalCost > 0 || anyFree)
|
|
45398
|
+
parts.push(fmtCost(totalCost, anyFree && totalCost === 0));
|
|
45399
|
+
return [`team: ${parts.join(", ")}`, ...rows].join(`
|
|
45400
|
+
`);
|
|
45401
|
+
}
|
|
45402
|
+
function renderTeamStatsCompact(sessionPath, manifest, status, opts) {
|
|
45403
|
+
const ids = Object.keys(manifest.models).sort();
|
|
45404
|
+
let done = 0;
|
|
45405
|
+
let running = 0;
|
|
45406
|
+
let failed = 0;
|
|
45407
|
+
let totalTokens = 0;
|
|
45408
|
+
let totalCost = 0;
|
|
45409
|
+
const segs = [];
|
|
45410
|
+
for (const id of ids) {
|
|
45411
|
+
const m = status.models[id];
|
|
45412
|
+
if (!m)
|
|
45413
|
+
continue;
|
|
45414
|
+
const model = manifest.models[id]?.model ?? "unknown";
|
|
45415
|
+
const stats = readTokenStats(sessionPath, id);
|
|
45416
|
+
if (m.state === "COMPLETED")
|
|
45417
|
+
done++;
|
|
45418
|
+
else if (m.state === "RUNNING" || m.state === "PENDING")
|
|
45419
|
+
running++;
|
|
45420
|
+
else
|
|
45421
|
+
failed++;
|
|
45422
|
+
totalTokens += stats?.total_tokens ?? 0;
|
|
45423
|
+
totalCost += stats?.total_cost ?? 0;
|
|
45424
|
+
const bits = [id, model, fmtState(m.state).trim()];
|
|
45425
|
+
if (m.outputSize > 0)
|
|
45426
|
+
bits.push(fmtBytes(m.outputSize));
|
|
45427
|
+
else if (stats?.total_tokens)
|
|
45428
|
+
bits.push(`${fmtTokens(stats.total_tokens)} tok`);
|
|
45429
|
+
segs.push(bits.join(" "));
|
|
45430
|
+
}
|
|
45431
|
+
const counts = [];
|
|
45432
|
+
if (done)
|
|
45433
|
+
counts.push(`${done} done`);
|
|
45434
|
+
if (running)
|
|
45435
|
+
counts.push(`${running} run`);
|
|
45436
|
+
if (failed)
|
|
45437
|
+
counts.push(`${failed} fail`);
|
|
45438
|
+
const head = [`team ${ids.length}: ${counts.join(" ") || "starting"}`];
|
|
45439
|
+
head.push(`${Math.round(opts.elapsedSeconds)}s`);
|
|
45440
|
+
if (totalTokens > 0)
|
|
45441
|
+
head.push(`${fmtTokens(totalTokens)} tok`);
|
|
45442
|
+
if (totalCost > 0)
|
|
45443
|
+
head.push(fmtCost(totalCost));
|
|
45444
|
+
let line1 = head.join(" \xB7 ");
|
|
45445
|
+
if (line1.length > CHANNEL_LINE_BUDGET) {
|
|
45446
|
+
line1 = line1.replace(/^team \d+: /, `t${ids.length}: `);
|
|
45447
|
+
}
|
|
45448
|
+
return `${line1}
|
|
45449
|
+
${segs.join(" \xB7 ")}`;
|
|
45450
|
+
}
|
|
45451
|
+
function writeStatusFile(sessionPath, manifest, status, opts) {
|
|
45452
|
+
try {
|
|
45453
|
+
writeFileSync11(join21(sessionPath, "status.txt"), `${renderTeamStats(sessionPath, manifest, status, opts)}
|
|
45454
|
+
`, "utf-8");
|
|
45455
|
+
} catch {}
|
|
45456
|
+
}
|
|
45457
|
+
var CHANNEL_LINE_BUDGET = 58;
|
|
45458
|
+
var init_team_stats = () => {};
|
|
45459
|
+
|
|
45048
45460
|
// src/team-orchestrator.ts
|
|
45049
45461
|
var exports_team_orchestrator = {};
|
|
45050
45462
|
__export(exports_team_orchestrator, {
|
|
@@ -45055,19 +45467,62 @@ __export(exports_team_orchestrator, {
|
|
|
45055
45467
|
judgeResponses: () => judgeResponses,
|
|
45056
45468
|
getStatus: () => getStatus,
|
|
45057
45469
|
fisherYatesShuffle: () => fisherYatesShuffle,
|
|
45470
|
+
classifyRunOutput: () => classifyRunOutput,
|
|
45058
45471
|
buildJudgePrompt: () => buildJudgePrompt,
|
|
45059
|
-
aggregateVerdict: () => aggregateVerdict
|
|
45472
|
+
aggregateVerdict: () => aggregateVerdict,
|
|
45473
|
+
STDOUT_TAIL_LIMIT: () => STDOUT_TAIL_LIMIT,
|
|
45474
|
+
DEFAULT_MIN_OUTPUT_BYTES: () => DEFAULT_MIN_OUTPUT_BYTES
|
|
45060
45475
|
});
|
|
45061
45476
|
import { spawn as spawn2 } from "child_process";
|
|
45062
45477
|
import {
|
|
45063
45478
|
createWriteStream as createWriteStream2,
|
|
45064
|
-
existsSync as
|
|
45065
|
-
mkdirSync as
|
|
45066
|
-
readFileSync as
|
|
45479
|
+
existsSync as existsSync18,
|
|
45480
|
+
mkdirSync as mkdirSync11,
|
|
45481
|
+
readFileSync as readFileSync16,
|
|
45067
45482
|
readdirSync as readdirSync2,
|
|
45068
|
-
writeFileSync as
|
|
45483
|
+
writeFileSync as writeFileSync12
|
|
45069
45484
|
} from "fs";
|
|
45070
|
-
import { join as
|
|
45485
|
+
import { join as join22, resolve as resolve3 } from "path";
|
|
45486
|
+
function classifyRunOutput(opts) {
|
|
45487
|
+
const { outputSize, stdoutTail, stderr, minOutputBytes } = opts;
|
|
45488
|
+
const apiError = API_ERROR_RE.exec(stdoutTail);
|
|
45489
|
+
if (apiError) {
|
|
45490
|
+
return {
|
|
45491
|
+
reason: "api_error",
|
|
45492
|
+
detail: `Child exited 0 but stdout carries an API error: ${apiError[1]?.trim() || "unknown"}`
|
|
45493
|
+
};
|
|
45494
|
+
}
|
|
45495
|
+
const bgCeiling = BG_CEILING_RE.exec(stderr);
|
|
45496
|
+
if (bgCeiling) {
|
|
45497
|
+
return {
|
|
45498
|
+
reason: "background_task_ceiling",
|
|
45499
|
+
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.`
|
|
45500
|
+
};
|
|
45501
|
+
}
|
|
45502
|
+
const tailIsWholeOutput = outputSize <= STDOUT_TAIL_LIMIT;
|
|
45503
|
+
if (outputSize === 0 || tailIsWholeOutput && stdoutTail.trim().length === 0) {
|
|
45504
|
+
return {
|
|
45505
|
+
reason: "empty_output",
|
|
45506
|
+
detail: `Child exited 0 but produced no non-whitespace output (${outputSize} B).`
|
|
45507
|
+
};
|
|
45508
|
+
}
|
|
45509
|
+
if (minOutputBytes > 0 && outputSize < minOutputBytes) {
|
|
45510
|
+
return {
|
|
45511
|
+
reason: "empty_output",
|
|
45512
|
+
detail: `Child exited 0 but produced only ${outputSize} B of stdout ` + `(caller required at least ${minOutputBytes} B).`
|
|
45513
|
+
};
|
|
45514
|
+
}
|
|
45515
|
+
return null;
|
|
45516
|
+
}
|
|
45517
|
+
function persistErrorLog(errorLogPath, header, stderr, stdoutTail) {
|
|
45518
|
+
const parts = [`=== ${redactSecrets(header)} ===`, ""];
|
|
45519
|
+
parts.push("--- stderr ---", stderr.trim() ? redactSecrets(stderr) : "(empty)", "");
|
|
45520
|
+
parts.push("--- stdout (tail) ---", stdoutTail.trim() ? redactSecrets(stdoutTail) : "(empty)", "");
|
|
45521
|
+
try {
|
|
45522
|
+
writeFileSync12(errorLogPath, parts.join(`
|
|
45523
|
+
`), "utf-8");
|
|
45524
|
+
} catch {}
|
|
45525
|
+
}
|
|
45071
45526
|
function validateSessionPath(sessionPath) {
|
|
45072
45527
|
const resolved = resolve3(sessionPath);
|
|
45073
45528
|
const cwd = process.cwd();
|
|
@@ -45088,18 +45543,18 @@ function setupSession(sessionPath, models, input) {
|
|
|
45088
45543
|
if (models.length === 0) {
|
|
45089
45544
|
throw new Error("At least one model is required");
|
|
45090
45545
|
}
|
|
45091
|
-
if (
|
|
45546
|
+
if (existsSync18(join22(sessionPath, "manifest.json"))) {
|
|
45092
45547
|
throw new Error(`Session already exists at ${sessionPath}. Use a new directory path or delete the existing session first.`);
|
|
45093
45548
|
}
|
|
45094
45549
|
const sentinels = models.filter(isSentinelModel);
|
|
45095
45550
|
if (sentinels.length > 0) {
|
|
45096
45551
|
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
45552
|
}
|
|
45098
|
-
|
|
45099
|
-
|
|
45553
|
+
mkdirSync11(join22(sessionPath, "work"), { recursive: true });
|
|
45554
|
+
mkdirSync11(join22(sessionPath, "errors"), { recursive: true });
|
|
45100
45555
|
if (input !== undefined) {
|
|
45101
|
-
|
|
45102
|
-
} else if (!
|
|
45556
|
+
writeFileSync12(join22(sessionPath, "input.md"), input, "utf-8");
|
|
45557
|
+
} else if (!existsSync18(join22(sessionPath, "input.md"))) {
|
|
45103
45558
|
throw new Error(`No input.md found at ${sessionPath} and no input provided`);
|
|
45104
45559
|
}
|
|
45105
45560
|
const ids = models.map((_, i) => String(i + 1).padStart(2, "0"));
|
|
@@ -45116,9 +45571,9 @@ function setupSession(sessionPath, models, input) {
|
|
|
45116
45571
|
model: models[i],
|
|
45117
45572
|
assignedAt: now
|
|
45118
45573
|
};
|
|
45119
|
-
|
|
45574
|
+
mkdirSync11(join22(sessionPath, "work", anonId), { recursive: true });
|
|
45120
45575
|
}
|
|
45121
|
-
|
|
45576
|
+
writeFileSync12(join22(sessionPath, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
|
|
45122
45577
|
const status = {
|
|
45123
45578
|
startedAt: now,
|
|
45124
45579
|
models: Object.fromEntries(Object.keys(manifest.models).map((id) => [
|
|
@@ -45132,22 +45587,25 @@ function setupSession(sessionPath, models, input) {
|
|
|
45132
45587
|
}
|
|
45133
45588
|
]))
|
|
45134
45589
|
};
|
|
45135
|
-
|
|
45590
|
+
writeFileSync12(join22(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
|
|
45136
45591
|
return manifest;
|
|
45137
45592
|
}
|
|
45138
45593
|
async function runModels(sessionPath, opts = {}) {
|
|
45139
45594
|
const timeoutMs = (opts.timeout ?? 300) * 1000;
|
|
45140
|
-
const manifest = JSON.parse(
|
|
45141
|
-
const statusPath =
|
|
45142
|
-
const inputPath =
|
|
45143
|
-
const inputContent =
|
|
45595
|
+
const manifest = JSON.parse(readFileSync16(join22(sessionPath, "manifest.json"), "utf-8"));
|
|
45596
|
+
const statusPath = join22(sessionPath, "status.json");
|
|
45597
|
+
const inputPath = join22(sessionPath, "input.md");
|
|
45598
|
+
const inputContent = readFileSync16(inputPath, "utf-8");
|
|
45144
45599
|
await prehydrateCredentialsForSpawn(Object.values(manifest.models).map((m) => m.model));
|
|
45145
|
-
const statusCache = JSON.parse(
|
|
45600
|
+
const statusCache = JSON.parse(readFileSync16(statusPath, "utf-8"));
|
|
45146
45601
|
function updateModelStatus(id, update) {
|
|
45147
45602
|
statusCache.models[id] = { ...statusCache.models[id], ...update };
|
|
45148
|
-
|
|
45603
|
+
writeFileSync12(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
45149
45604
|
}
|
|
45605
|
+
const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
|
|
45606
|
+
mkdirSync11(statsDir(sessionPath), { recursive: true });
|
|
45150
45607
|
const processes = new Map;
|
|
45608
|
+
const runtimes = new Map;
|
|
45151
45609
|
const sigintHandler = () => {
|
|
45152
45610
|
for (const [, proc] of processes) {
|
|
45153
45611
|
if (!proc.killed)
|
|
@@ -45158,8 +45616,8 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45158
45616
|
process.on("SIGINT", sigintHandler);
|
|
45159
45617
|
const completionPromises = [];
|
|
45160
45618
|
for (const [anonId, entry] of Object.entries(manifest.models)) {
|
|
45161
|
-
const outputPath =
|
|
45162
|
-
const errorLogPath =
|
|
45619
|
+
const outputPath = join22(sessionPath, `response-${anonId}.md`);
|
|
45620
|
+
const errorLogPath = join22(sessionPath, "errors", `${anonId}.log`);
|
|
45163
45621
|
const args = ["--model", entry.model, "-y", "--stdin", "--quiet", ...opts.claudeFlags ?? []];
|
|
45164
45622
|
updateModelStatus(anonId, {
|
|
45165
45623
|
state: "RUNNING",
|
|
@@ -45167,11 +45625,17 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45167
45625
|
});
|
|
45168
45626
|
const proc = spawn2("claudish", args, {
|
|
45169
45627
|
stdio: ["pipe", "pipe", "pipe"],
|
|
45170
|
-
shell: false
|
|
45628
|
+
shell: false,
|
|
45629
|
+
env: {
|
|
45630
|
+
...process.env,
|
|
45631
|
+
CLAUDISH_TOKEN_FILE: tokenFileFor(sessionPath, anonId)
|
|
45632
|
+
}
|
|
45171
45633
|
});
|
|
45172
45634
|
let byteCount = 0;
|
|
45635
|
+
let stdoutTail = "";
|
|
45173
45636
|
proc.stdout?.on("data", (chunk) => {
|
|
45174
45637
|
byteCount += chunk.length;
|
|
45638
|
+
stdoutTail = (stdoutTail + chunk.toString()).slice(-STDOUT_TAIL_LIMIT);
|
|
45175
45639
|
});
|
|
45176
45640
|
const outputStream = createWriteStream2(outputPath);
|
|
45177
45641
|
proc.stdout?.pipe(outputStream);
|
|
@@ -45179,6 +45643,14 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45179
45643
|
proc.stderr?.on("data", (chunk) => {
|
|
45180
45644
|
stderr += chunk.toString();
|
|
45181
45645
|
});
|
|
45646
|
+
const command = `claudish ${args.join(" ")}`;
|
|
45647
|
+
runtimes.set(anonId, {
|
|
45648
|
+
command,
|
|
45649
|
+
errorLogPath,
|
|
45650
|
+
getStderr: () => stderr,
|
|
45651
|
+
getStdoutTail: () => stdoutTail,
|
|
45652
|
+
getByteCount: () => byteCount
|
|
45653
|
+
});
|
|
45182
45654
|
proc.stdin?.write(inputContent);
|
|
45183
45655
|
proc.stdin?.end();
|
|
45184
45656
|
const completionPromise = new Promise((resolve4) => {
|
|
@@ -45194,20 +45666,39 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45194
45666
|
}
|
|
45195
45667
|
resolved = true;
|
|
45196
45668
|
const outputSize = byteCount;
|
|
45197
|
-
const
|
|
45198
|
-
|
|
45199
|
-
|
|
45200
|
-
|
|
45201
|
-
|
|
45202
|
-
|
|
45203
|
-
|
|
45204
|
-
|
|
45205
|
-
|
|
45206
|
-
|
|
45207
|
-
|
|
45208
|
-
|
|
45209
|
-
|
|
45210
|
-
|
|
45669
|
+
const crashed = exitCode !== 0;
|
|
45670
|
+
const degraded = crashed ? null : classifyRunOutput({ outputSize, stdoutTail, stderr, minOutputBytes });
|
|
45671
|
+
const failed = crashed || degraded !== null;
|
|
45672
|
+
const state = crashed ? "FAILED" : degraded ? "EMPTY" : "COMPLETED";
|
|
45673
|
+
if (failed) {
|
|
45674
|
+
const reason = crashed ? "nonzero_exit" : degraded.reason;
|
|
45675
|
+
const detail = crashed ? `Child exited with code ${exitCode}.` : degraded.detail;
|
|
45676
|
+
persistErrorLog(errorLogPath, `${state}: ${detail}`, stderr, stdoutTail);
|
|
45677
|
+
updateModelStatus(anonId, {
|
|
45678
|
+
state,
|
|
45679
|
+
exitCode: exitCode ?? 1,
|
|
45680
|
+
completedAt: new Date().toISOString(),
|
|
45681
|
+
outputSize,
|
|
45682
|
+
error: {
|
|
45683
|
+
model: anonId,
|
|
45684
|
+
command,
|
|
45685
|
+
reason,
|
|
45686
|
+
detail,
|
|
45687
|
+
stderrSnippet: stderr ? redactSecrets(stderr).slice(-2000) : undefined,
|
|
45688
|
+
stdoutSnippet: stdoutTail ? redactSecrets(stdoutTail).slice(-2000) : undefined,
|
|
45689
|
+
errorLogPath,
|
|
45690
|
+
workDir: sessionPath
|
|
45691
|
+
}
|
|
45692
|
+
});
|
|
45693
|
+
} else {
|
|
45694
|
+
updateModelStatus(anonId, {
|
|
45695
|
+
state,
|
|
45696
|
+
exitCode: exitCode ?? 0,
|
|
45697
|
+
completedAt: new Date().toISOString(),
|
|
45698
|
+
outputSize,
|
|
45699
|
+
error: undefined
|
|
45700
|
+
});
|
|
45701
|
+
}
|
|
45211
45702
|
opts.onStatusChange?.(anonId, statusCache.models[anonId]);
|
|
45212
45703
|
resolve4();
|
|
45213
45704
|
};
|
|
@@ -45220,7 +45711,7 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45220
45711
|
return;
|
|
45221
45712
|
}
|
|
45222
45713
|
if (stderr) {
|
|
45223
|
-
|
|
45714
|
+
writeFileSync12(errorLogPath, redactSecrets(stderr), "utf-8");
|
|
45224
45715
|
}
|
|
45225
45716
|
exitCode = code;
|
|
45226
45717
|
if (outputStream.destroyed) {
|
|
@@ -45231,6 +45722,36 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45231
45722
|
processes.set(anonId, proc);
|
|
45232
45723
|
completionPromises.push(completionPromise);
|
|
45233
45724
|
}
|
|
45725
|
+
const runStartedMs = Date.now();
|
|
45726
|
+
const POLL_MS = 2000;
|
|
45727
|
+
const heartbeatMs = (opts.heartbeatSeconds ?? 60) * 1000;
|
|
45728
|
+
let lastSignature = "";
|
|
45729
|
+
let lastEmitMs = 0;
|
|
45730
|
+
const stateSignature = () => Object.entries(statusCache.models).sort(([a], [b]) => a.localeCompare(b)).map(([id, m]) => `${id}:${m.state}:${m.outputSize}`).join("|");
|
|
45731
|
+
const emitProgress = (phase = "running") => {
|
|
45732
|
+
const elapsedSeconds = (Date.now() - runStartedMs) / 1000;
|
|
45733
|
+
writeStatusFile(sessionPath, manifest, statusCache, { elapsedSeconds });
|
|
45734
|
+
if (!opts.onProgress)
|
|
45735
|
+
return;
|
|
45736
|
+
const signature = stateSignature();
|
|
45737
|
+
const changed = signature !== lastSignature;
|
|
45738
|
+
const heartbeatDue = Date.now() - lastEmitMs >= heartbeatMs;
|
|
45739
|
+
if (phase !== "settled" && !changed && !heartbeatDue)
|
|
45740
|
+
return;
|
|
45741
|
+
lastSignature = signature;
|
|
45742
|
+
lastEmitMs = Date.now();
|
|
45743
|
+
try {
|
|
45744
|
+
const models = Object.values(statusCache.models);
|
|
45745
|
+
opts.onProgress({
|
|
45746
|
+
rendered: renderTeamStatsCompact(sessionPath, manifest, statusCache, { elapsedSeconds }),
|
|
45747
|
+
phase,
|
|
45748
|
+
allFailed: models.length > 0 && models.every((m) => m.state !== "COMPLETED")
|
|
45749
|
+
});
|
|
45750
|
+
} catch {}
|
|
45751
|
+
};
|
|
45752
|
+
emitProgress();
|
|
45753
|
+
const progressHandle = setInterval(() => emitProgress("running"), POLL_MS);
|
|
45754
|
+
progressHandle.unref?.();
|
|
45234
45755
|
let timeoutHandle = null;
|
|
45235
45756
|
await Promise.race([
|
|
45236
45757
|
Promise.all(completionPromises),
|
|
@@ -45241,9 +45762,27 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45241
45762
|
if (current.state === "RUNNING") {
|
|
45242
45763
|
if (!proc.killed)
|
|
45243
45764
|
proc.kill("SIGTERM");
|
|
45765
|
+
const rt = runtimes.get(id);
|
|
45766
|
+
const stderr = rt?.getStderr() ?? "";
|
|
45767
|
+
const stdoutTail = rt?.getStdoutTail() ?? "";
|
|
45768
|
+
const bytes = rt?.getByteCount() ?? 0;
|
|
45769
|
+
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".`;
|
|
45770
|
+
if (rt)
|
|
45771
|
+
persistErrorLog(rt.errorLogPath, `TIMEOUT: ${detail}`, stderr, stdoutTail);
|
|
45244
45772
|
updateModelStatus(id, {
|
|
45245
45773
|
state: "TIMEOUT",
|
|
45246
|
-
completedAt: new Date().toISOString()
|
|
45774
|
+
completedAt: new Date().toISOString(),
|
|
45775
|
+
outputSize: bytes,
|
|
45776
|
+
error: rt ? {
|
|
45777
|
+
model: id,
|
|
45778
|
+
command: rt.command,
|
|
45779
|
+
reason: "timeout",
|
|
45780
|
+
detail,
|
|
45781
|
+
stderrSnippet: stderr ? redactSecrets(stderr).slice(-2000) : undefined,
|
|
45782
|
+
stdoutSnippet: stdoutTail ? redactSecrets(stdoutTail).slice(-2000) : undefined,
|
|
45783
|
+
errorLogPath: rt.errorLogPath,
|
|
45784
|
+
workDir: sessionPath
|
|
45785
|
+
} : undefined
|
|
45247
45786
|
});
|
|
45248
45787
|
opts.onStatusChange?.(id, statusCache.models[id]);
|
|
45249
45788
|
}
|
|
@@ -45254,6 +45793,8 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
45254
45793
|
]);
|
|
45255
45794
|
if (timeoutHandle !== null)
|
|
45256
45795
|
clearTimeout(timeoutHandle);
|
|
45796
|
+
clearInterval(progressHandle);
|
|
45797
|
+
emitProgress("settled");
|
|
45257
45798
|
process.off("SIGINT", sigintHandler);
|
|
45258
45799
|
return statusCache;
|
|
45259
45800
|
}
|
|
@@ -45265,23 +45806,23 @@ async function judgeResponses(sessionPath, opts = {}) {
|
|
|
45265
45806
|
const responses = {};
|
|
45266
45807
|
for (const file2 of responseFiles) {
|
|
45267
45808
|
const id = file2.replace(/^response-/, "").replace(/\.md$/, "");
|
|
45268
|
-
responses[id] =
|
|
45809
|
+
responses[id] = readFileSync16(join22(sessionPath, file2), "utf-8");
|
|
45269
45810
|
}
|
|
45270
|
-
const input =
|
|
45811
|
+
const input = readFileSync16(join22(sessionPath, "input.md"), "utf-8");
|
|
45271
45812
|
const judgePrompt = buildJudgePrompt(input, responses);
|
|
45272
|
-
|
|
45813
|
+
writeFileSync12(join22(sessionPath, "judge-prompt.md"), judgePrompt, "utf-8");
|
|
45273
45814
|
const judgeModels = opts.judges ?? getDefaultJudgeModels(sessionPath);
|
|
45274
|
-
const judgePath =
|
|
45275
|
-
|
|
45815
|
+
const judgePath = join22(sessionPath, "judging");
|
|
45816
|
+
mkdirSync11(judgePath, { recursive: true });
|
|
45276
45817
|
setupSession(judgePath, judgeModels, judgePrompt);
|
|
45277
45818
|
await runModels(judgePath, { claudeFlags: opts.claudeFlags });
|
|
45278
45819
|
const votes = parseJudgeVotes(judgePath, Object.keys(responses));
|
|
45279
45820
|
const verdict = aggregateVerdict(votes, Object.keys(responses));
|
|
45280
|
-
|
|
45821
|
+
writeFileSync12(join22(sessionPath, "verdict.md"), formatVerdict(verdict, sessionPath), "utf-8");
|
|
45281
45822
|
return verdict;
|
|
45282
45823
|
}
|
|
45283
45824
|
function getStatus(sessionPath) {
|
|
45284
|
-
return JSON.parse(
|
|
45825
|
+
return JSON.parse(readFileSync16(join22(sessionPath, "status.json"), "utf-8"));
|
|
45285
45826
|
}
|
|
45286
45827
|
function fisherYatesShuffle(arr) {
|
|
45287
45828
|
for (let i = arr.length - 1;i > 0; i--) {
|
|
@@ -45291,7 +45832,7 @@ function fisherYatesShuffle(arr) {
|
|
|
45291
45832
|
return arr;
|
|
45292
45833
|
}
|
|
45293
45834
|
function getDefaultJudgeModels(sessionPath) {
|
|
45294
|
-
const manifest = JSON.parse(
|
|
45835
|
+
const manifest = JSON.parse(readFileSync16(join22(sessionPath, "manifest.json"), "utf-8"));
|
|
45295
45836
|
return Object.values(manifest.models).map((e) => e.model);
|
|
45296
45837
|
}
|
|
45297
45838
|
function buildJudgePrompt(input, responses) {
|
|
@@ -45354,7 +45895,7 @@ function parseJudgeVotes(judgePath, responseIds) {
|
|
|
45354
45895
|
const judgeId = file2.replace(/^response-/, "").replace(/\.md$/, "");
|
|
45355
45896
|
let content;
|
|
45356
45897
|
try {
|
|
45357
|
-
content =
|
|
45898
|
+
content = readFileSync16(join22(judgePath, file2), "utf-8");
|
|
45358
45899
|
} catch {
|
|
45359
45900
|
continue;
|
|
45360
45901
|
}
|
|
@@ -45406,7 +45947,7 @@ function aggregateVerdict(votes, responseIds) {
|
|
|
45406
45947
|
function formatVerdict(verdict, sessionPath) {
|
|
45407
45948
|
let manifest = null;
|
|
45408
45949
|
try {
|
|
45409
|
-
manifest = JSON.parse(
|
|
45950
|
+
manifest = JSON.parse(readFileSync16(join22(sessionPath, "manifest.json"), "utf-8"));
|
|
45410
45951
|
} catch {}
|
|
45411
45952
|
let output = `# Team Verdict
|
|
45412
45953
|
|
|
@@ -45437,9 +45978,13 @@ function formatVerdict(verdict, sessionPath) {
|
|
|
45437
45978
|
}
|
|
45438
45979
|
return output;
|
|
45439
45980
|
}
|
|
45440
|
-
var SENTINEL_MODELS;
|
|
45981
|
+
var STDOUT_TAIL_LIMIT = 4000, API_ERROR_RE, BG_CEILING_RE, DEFAULT_MIN_OUTPUT_BYTES = 0, SENTINEL_MODELS;
|
|
45441
45982
|
var init_team_orchestrator = __esm(() => {
|
|
45442
45983
|
init_prehydrate();
|
|
45984
|
+
init_redact();
|
|
45985
|
+
init_team_stats();
|
|
45986
|
+
API_ERROR_RE = /\[API Error:\s*([^\]]{0,300})\]/i;
|
|
45987
|
+
BG_CEILING_RE = /Background tasks still running after (\d+)s; terminating/i;
|
|
45443
45988
|
SENTINEL_MODELS = new Set([
|
|
45444
45989
|
"internal",
|
|
45445
45990
|
"default",
|
|
@@ -45454,16 +45999,17 @@ var exports_mcp_server = {};
|
|
|
45454
45999
|
__export(exports_mcp_server, {
|
|
45455
46000
|
startMcpServer: () => startMcpServer,
|
|
45456
46001
|
runPromptViaProxy: () => runPromptViaProxy,
|
|
45457
|
-
parseAnthropicSse: () => parseAnthropicSse
|
|
46002
|
+
parseAnthropicSse: () => parseAnthropicSse,
|
|
46003
|
+
formatTeamResult: () => formatTeamResult
|
|
45458
46004
|
});
|
|
45459
|
-
import { existsSync as
|
|
45460
|
-
import { homedir as
|
|
45461
|
-
import { dirname as
|
|
46005
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync17, readdirSync as readdirSync3, writeFileSync as writeFileSync13 } from "fs";
|
|
46006
|
+
import { homedir as homedir21 } from "os";
|
|
46007
|
+
import { dirname as dirname7, join as join23 } from "path";
|
|
45462
46008
|
import { fileURLToPath } from "url";
|
|
45463
46009
|
async function loadAllModels(forceRefresh = false) {
|
|
45464
|
-
if (!forceRefresh &&
|
|
46010
|
+
if (!forceRefresh && existsSync19(ALL_MODELS_CACHE_PATH2)) {
|
|
45465
46011
|
try {
|
|
45466
|
-
const cacheData = JSON.parse(
|
|
46012
|
+
const cacheData = JSON.parse(readFileSync17(ALL_MODELS_CACHE_PATH2, "utf-8"));
|
|
45467
46013
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
45468
46014
|
const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
45469
46015
|
if (ageInDays <= CACHE_MAX_AGE_DAYS) {
|
|
@@ -45477,12 +46023,12 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
45477
46023
|
throw new Error(`API returned ${response.status}`);
|
|
45478
46024
|
const data = await response.json();
|
|
45479
46025
|
const models = data.data || [];
|
|
45480
|
-
|
|
45481
|
-
|
|
46026
|
+
mkdirSync12(CLAUDISH_CACHE_DIR, { recursive: true });
|
|
46027
|
+
writeFileSync13(ALL_MODELS_CACHE_PATH2, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
|
|
45482
46028
|
return models;
|
|
45483
46029
|
} catch {
|
|
45484
|
-
if (
|
|
45485
|
-
const cacheData = JSON.parse(
|
|
46030
|
+
if (existsSync19(ALL_MODELS_CACHE_PATH2)) {
|
|
46031
|
+
const cacheData = JSON.parse(readFileSync17(ALL_MODELS_CACHE_PATH2, "utf-8"));
|
|
45486
46032
|
return cacheData.models || [];
|
|
45487
46033
|
}
|
|
45488
46034
|
return [];
|
|
@@ -45578,63 +46124,53 @@ function fuzzyScore(text, query) {
|
|
|
45578
46124
|
}
|
|
45579
46125
|
return queryIndex === lowerQuery.length ? score / lowerText.length : 0;
|
|
45580
46126
|
}
|
|
46127
|
+
function fmtSize(n) {
|
|
46128
|
+
if (n <= 0)
|
|
46129
|
+
return "0B";
|
|
46130
|
+
if (n < 1024)
|
|
46131
|
+
return `${n}B`;
|
|
46132
|
+
if (n < 1024 * 1024)
|
|
46133
|
+
return `${(n / 1024).toFixed(1)}KB`;
|
|
46134
|
+
return `${(n / (1024 * 1024)).toFixed(1)}MB`;
|
|
46135
|
+
}
|
|
45581
46136
|
function formatTeamResult(status, sessionPath) {
|
|
45582
|
-
const entries = Object.entries(status.models);
|
|
45583
|
-
const failed = entries.filter(([, m]) => m.state === "FAILED" || m.state === "TIMEOUT");
|
|
46137
|
+
const entries = Object.entries(status.models).sort(([a], [b]) => a.localeCompare(b));
|
|
46138
|
+
const failed = entries.filter(([, m]) => m.state === "FAILED" || m.state === "TIMEOUT" || m.state === "EMPTY");
|
|
45584
46139
|
const succeeded = entries.filter(([, m]) => m.state === "COMPLETED");
|
|
45585
|
-
|
|
46140
|
+
const lines = [];
|
|
46141
|
+
lines.push(`<<<TEAM_RESULT path="${sessionPath}">>>`);
|
|
46142
|
+
lines.push(`status: ${failed.length === 0 ? "ok" : succeeded.length === 0 ? "all-failed" : "partial"}` + ` \u2014 ${succeeded.length}/${entries.length} succeeded`);
|
|
46143
|
+
if (succeeded.length > 0) {
|
|
46144
|
+
lines.push("succeeded:");
|
|
46145
|
+
for (const [id, m] of succeeded) {
|
|
46146
|
+
lines.push(` ${id} ${fmtSize(m.outputSize)} response-${id}.md`);
|
|
46147
|
+
}
|
|
46148
|
+
}
|
|
45586
46149
|
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
|
-
`;
|
|
46150
|
+
lines.push("failures:");
|
|
45596
46151
|
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
|
-
`;
|
|
46152
|
+
const reason = m.error?.reason ?? "unknown";
|
|
46153
|
+
const next = NEXT_STEP[reason] ?? "read the evidence log";
|
|
46154
|
+
lines.push(` ${id} ${m.state} reason=${reason}`);
|
|
46155
|
+
if (m.error?.detail)
|
|
46156
|
+
lines.push(` what: ${m.error.detail}`);
|
|
46157
|
+
lines.push(` next: ${next}`);
|
|
46158
|
+
if (m.error?.errorLogPath) {
|
|
46159
|
+
lines.push(` evidence: ${m.error.errorLogPath}`);
|
|
46160
|
+
} else {
|
|
46161
|
+
lines.push(" evidence: NONE CAPTURED \u2014 orchestrator bug, report via report_error");
|
|
45617
46162
|
}
|
|
45618
|
-
result += `
|
|
45619
|
-
`;
|
|
45620
46163
|
}
|
|
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";
|
|
46164
|
+
lines.push("actions:");
|
|
46165
|
+
lines.push(` full stderr/stdout for one failure \u2192 Read the evidence path above`);
|
|
46166
|
+
lines.push(` machine-readable status \u2192 team(mode="status", path="${sessionPath}")`);
|
|
46167
|
+
lines.push(` report a provider bug \u2192 report_error(session_path="${sessionPath}")`);
|
|
45629
46168
|
}
|
|
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, "***@***.***");
|
|
46169
|
+
lines.push("<<<END_TEAM_RESULT>>>");
|
|
46170
|
+
return lines.join(`
|
|
46171
|
+
`);
|
|
45636
46172
|
}
|
|
45637
|
-
function defineTools(sessionManager) {
|
|
46173
|
+
function defineTools(sessionManager, notifyChannel) {
|
|
45638
46174
|
const tools = [];
|
|
45639
46175
|
tools.push({
|
|
45640
46176
|
name: "run_prompt",
|
|
@@ -45965,12 +46501,25 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
45965
46501
|
const input = args.input;
|
|
45966
46502
|
const timeout = args.timeout;
|
|
45967
46503
|
const resolved = validateSessionPath(path);
|
|
46504
|
+
const teamSessionId = resolved.split("/").filter(Boolean).pop() ?? "team";
|
|
46505
|
+
const teamCreatedAt = new Date().toISOString();
|
|
46506
|
+
const runOpts = {
|
|
46507
|
+
timeout,
|
|
46508
|
+
onProgress: (u) => notifyChannel({
|
|
46509
|
+
content: u.rendered,
|
|
46510
|
+
sessionId: teamSessionId,
|
|
46511
|
+
event: u.phase === "settled" ? u.allFailed ? "failed" : "completed" : "running",
|
|
46512
|
+
model: "team",
|
|
46513
|
+
elapsedSeconds: (Date.now() - Date.parse(teamCreatedAt)) / 1000,
|
|
46514
|
+
createdAt: teamCreatedAt
|
|
46515
|
+
})
|
|
46516
|
+
};
|
|
45968
46517
|
switch (mode) {
|
|
45969
46518
|
case "run": {
|
|
45970
46519
|
if (!models?.length)
|
|
45971
46520
|
throw new Error("'models' is required for 'run' mode");
|
|
45972
46521
|
setupSession(resolved, models, input);
|
|
45973
|
-
const status = await runModels(resolved,
|
|
46522
|
+
const status = await runModels(resolved, runOpts);
|
|
45974
46523
|
return {
|
|
45975
46524
|
content: [{ type: "text", text: formatTeamResult(status, resolved) }]
|
|
45976
46525
|
};
|
|
@@ -45983,7 +46532,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
45983
46532
|
if (!models?.length)
|
|
45984
46533
|
throw new Error("'models' is required for 'run-and-judge' mode");
|
|
45985
46534
|
setupSession(resolved, models, input);
|
|
45986
|
-
await runModels(resolved,
|
|
46535
|
+
await runModels(resolved, runOpts);
|
|
45987
46536
|
const verdict = await judgeResponses(resolved, { judges });
|
|
45988
46537
|
return { content: [{ type: "text", text: JSON.stringify(verdict, null, 2) }] };
|
|
45989
46538
|
}
|
|
@@ -46046,7 +46595,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46046
46595
|
let stderrFull = stderr_snippet || "";
|
|
46047
46596
|
if (error_log_path) {
|
|
46048
46597
|
try {
|
|
46049
|
-
stderrFull =
|
|
46598
|
+
stderrFull = readFileSync17(error_log_path, "utf-8");
|
|
46050
46599
|
} catch {}
|
|
46051
46600
|
}
|
|
46052
46601
|
const sessionData = {};
|
|
@@ -46054,16 +46603,16 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46054
46603
|
const sp = session_path;
|
|
46055
46604
|
for (const file2 of ["status.json", "manifest.json", "input.md"]) {
|
|
46056
46605
|
try {
|
|
46057
|
-
sessionData[file2] =
|
|
46606
|
+
sessionData[file2] = readFileSync17(join23(sp, file2), "utf-8");
|
|
46058
46607
|
} catch {}
|
|
46059
46608
|
}
|
|
46060
46609
|
try {
|
|
46061
|
-
const errorDir =
|
|
46062
|
-
if (
|
|
46610
|
+
const errorDir = join23(sp, "errors");
|
|
46611
|
+
if (existsSync19(errorDir)) {
|
|
46063
46612
|
for (const f of readdirSync3(errorDir)) {
|
|
46064
46613
|
if (f.endsWith(".log")) {
|
|
46065
46614
|
try {
|
|
46066
|
-
sessionData[`errors/${f}`] =
|
|
46615
|
+
sessionData[`errors/${f}`] = readFileSync17(join23(errorDir, f), "utf-8");
|
|
46067
46616
|
} catch {}
|
|
46068
46617
|
}
|
|
46069
46618
|
}
|
|
@@ -46073,7 +46622,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46073
46622
|
for (const f of readdirSync3(sp)) {
|
|
46074
46623
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
46075
46624
|
try {
|
|
46076
|
-
const content =
|
|
46625
|
+
const content = readFileSync17(join23(sp, f), "utf-8");
|
|
46077
46626
|
sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
|
|
46078
46627
|
} catch {}
|
|
46079
46628
|
}
|
|
@@ -46082,9 +46631,9 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
46082
46631
|
}
|
|
46083
46632
|
let version2 = "unknown";
|
|
46084
46633
|
try {
|
|
46085
|
-
const pkgPath =
|
|
46086
|
-
if (
|
|
46087
|
-
version2 = JSON.parse(
|
|
46634
|
+
const pkgPath = join23(__dirname2, "../package.json");
|
|
46635
|
+
if (existsSync19(pkgPath)) {
|
|
46636
|
+
version2 = JSON.parse(readFileSync17(pkgPath, "utf-8")).version;
|
|
46088
46637
|
}
|
|
46089
46638
|
} catch {}
|
|
46090
46639
|
const report = {
|
|
@@ -46369,7 +46918,31 @@ To report this error, use the report_error tool with error_type: "provider_failu
|
|
|
46369
46918
|
watchNotificationResult(result, { sessionId: sessionId2, eventType: event.type });
|
|
46370
46919
|
})
|
|
46371
46920
|
});
|
|
46372
|
-
const
|
|
46921
|
+
const channelEnabled = enabledGroups.has("channel");
|
|
46922
|
+
const notifyChannel = (p) => {
|
|
46923
|
+
if (!channelEnabled)
|
|
46924
|
+
return;
|
|
46925
|
+
try {
|
|
46926
|
+
const result = server.notification({
|
|
46927
|
+
method: "notifications/claude/channel",
|
|
46928
|
+
params: {
|
|
46929
|
+
content: p.content,
|
|
46930
|
+
meta: {
|
|
46931
|
+
session_id: p.sessionId,
|
|
46932
|
+
event: p.event,
|
|
46933
|
+
model: p.model,
|
|
46934
|
+
elapsed_seconds: String(Math.round(p.elapsedSeconds)),
|
|
46935
|
+
task_id: p.sessionId,
|
|
46936
|
+
status: mapEventToTaskStatus(p.event),
|
|
46937
|
+
created_at: p.createdAt,
|
|
46938
|
+
last_updated_at: new Date().toISOString()
|
|
46939
|
+
}
|
|
46940
|
+
}
|
|
46941
|
+
});
|
|
46942
|
+
watchNotificationResult(result, { sessionId: p.sessionId, eventType: p.event });
|
|
46943
|
+
} catch {}
|
|
46944
|
+
};
|
|
46945
|
+
const allTools = defineTools(sessionManager, notifyChannel);
|
|
46373
46946
|
const enabledTools = allTools.filter((t) => enabledGroups.has(t.group));
|
|
46374
46947
|
const toolMap = new Map(enabledTools.map((t) => [t.name, t]));
|
|
46375
46948
|
console.error(`[claudish] MCP server started (tools: ${toolMode}, ${enabledTools.length} tools)`);
|
|
@@ -46440,7 +47013,7 @@ When channel mode is active, you receive <channel source="claudish" ...> notific
|
|
|
46440
47013
|
5. Use list_sessions to see all active/completed sessions.
|
|
46441
47014
|
6. Use cancel_session to stop a running session.
|
|
46442
47015
|
|
|
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;
|
|
47016
|
+
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
47017
|
var init_mcp_server = __esm(() => {
|
|
46445
47018
|
init_server2();
|
|
46446
47019
|
init_stdio2();
|
|
@@ -46450,15 +47023,24 @@ var init_mcp_server = __esm(() => {
|
|
|
46450
47023
|
init_channel();
|
|
46451
47024
|
init_model_loader();
|
|
46452
47025
|
init_port_manager();
|
|
47026
|
+
init_redact();
|
|
46453
47027
|
init_provider_definitions();
|
|
46454
47028
|
init_proxy_server();
|
|
46455
47029
|
init_team_orchestrator();
|
|
46456
47030
|
import_dotenv2 = __toESM(require_main(), 1);
|
|
46457
47031
|
import_dotenv2.config({ quiet: true });
|
|
46458
47032
|
__filename2 = fileURLToPath(import.meta.url);
|
|
46459
|
-
__dirname2 =
|
|
46460
|
-
CLAUDISH_CACHE_DIR =
|
|
46461
|
-
ALL_MODELS_CACHE_PATH2 =
|
|
47033
|
+
__dirname2 = dirname7(__filename2);
|
|
47034
|
+
CLAUDISH_CACHE_DIR = join23(homedir21(), ".claudish");
|
|
47035
|
+
ALL_MODELS_CACHE_PATH2 = join23(CLAUDISH_CACHE_DIR, "all-models.json");
|
|
47036
|
+
NEXT_STEP = {
|
|
47037
|
+
nonzero_exit: "read the evidence log, then retry or drop the model",
|
|
47038
|
+
timeout: "raise `timeout`, or pick a faster model",
|
|
47039
|
+
api_error: "retry once, or route via a different provider (or@<model>)",
|
|
47040
|
+
background_task_ceiling: "set CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 for children, or forbid background work in the prompt",
|
|
47041
|
+
empty_output: "retry once; if it repeats, drop the model"
|
|
47042
|
+
};
|
|
47043
|
+
sanitize = sanitizeForReport;
|
|
46462
47044
|
EVENT_TO_TASK_STATUS = new Map([
|
|
46463
47045
|
["starting", "working"],
|
|
46464
47046
|
["running", "working"],
|
|
@@ -46475,7 +47057,7 @@ var exports_serve_command = {};
|
|
|
46475
47057
|
__export(exports_serve_command, {
|
|
46476
47058
|
serveCommand: () => serveCommand
|
|
46477
47059
|
});
|
|
46478
|
-
import { existsSync as
|
|
47060
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
|
|
46479
47061
|
function parseServeArgs(args) {
|
|
46480
47062
|
const out = {};
|
|
46481
47063
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -46494,12 +47076,12 @@ function parseServeArgs(args) {
|
|
|
46494
47076
|
return out;
|
|
46495
47077
|
}
|
|
46496
47078
|
function loadModelMap(path) {
|
|
46497
|
-
if (!
|
|
47079
|
+
if (!existsSync20(path)) {
|
|
46498
47080
|
throw new Error(`--models file not found: ${path}`);
|
|
46499
47081
|
}
|
|
46500
47082
|
let raw2;
|
|
46501
47083
|
try {
|
|
46502
|
-
raw2 =
|
|
47084
|
+
raw2 = readFileSync18(path, "utf-8");
|
|
46503
47085
|
} catch (e) {
|
|
46504
47086
|
throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
46505
47087
|
}
|
|
@@ -57971,7 +58553,7 @@ var init_RemoveFileError = __esm(() => {
|
|
|
57971
58553
|
|
|
57972
58554
|
// ../../node_modules/.bun/@inquirer+external-editor@2.0.1+04f2146be16c61ef/node_modules/@inquirer/external-editor/dist/index.js
|
|
57973
58555
|
import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
|
|
57974
|
-
import { readFileSync as
|
|
58556
|
+
import { readFileSync as readFileSync19, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
|
|
57975
58557
|
import path from "path";
|
|
57976
58558
|
import os from "os";
|
|
57977
58559
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
@@ -58080,14 +58662,14 @@ class ExternalEditor {
|
|
|
58080
58662
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
58081
58663
|
opt.mode = this.fileOptions.mode;
|
|
58082
58664
|
}
|
|
58083
|
-
|
|
58665
|
+
writeFileSync14(this.tempFile, this.text, opt);
|
|
58084
58666
|
} catch (createFileError) {
|
|
58085
58667
|
throw new CreateFileError(createFileError);
|
|
58086
58668
|
}
|
|
58087
58669
|
}
|
|
58088
58670
|
readTemporaryFile() {
|
|
58089
58671
|
try {
|
|
58090
|
-
const tempFileBuffer =
|
|
58672
|
+
const tempFileBuffer = readFileSync19(this.tempFile);
|
|
58091
58673
|
if (tempFileBuffer.length === 0) {
|
|
58092
58674
|
this.text = "";
|
|
58093
58675
|
} else {
|
|
@@ -59282,15 +59864,15 @@ async function geminiQuotaHandler() {
|
|
|
59282
59864
|
}
|
|
59283
59865
|
}
|
|
59284
59866
|
async function codexQuotaHandler() {
|
|
59285
|
-
const { readFileSync:
|
|
59286
|
-
const { join:
|
|
59287
|
-
const { homedir:
|
|
59288
|
-
const credPath =
|
|
59289
|
-
if (!
|
|
59867
|
+
const { readFileSync: readFileSync20, existsSync: existsSync21 } = await import("fs");
|
|
59868
|
+
const { join: join24 } = await import("path");
|
|
59869
|
+
const { homedir: homedir22 } = await import("os");
|
|
59870
|
+
const credPath = join24(homedir22(), ".claudish", "codex-oauth.json");
|
|
59871
|
+
if (!existsSync21(credPath)) {
|
|
59290
59872
|
console.error(`${RED}No Codex credentials found.${R} Run: ${B}claudish login codex${R}`);
|
|
59291
59873
|
process.exit(1);
|
|
59292
59874
|
}
|
|
59293
|
-
const creds = JSON.parse(
|
|
59875
|
+
const creds = JSON.parse(readFileSync20(credPath, "utf-8"));
|
|
59294
59876
|
let email3 = "";
|
|
59295
59877
|
try {
|
|
59296
59878
|
const parts = creds.access_token.split(".");
|
|
@@ -59342,9 +59924,9 @@ async function codexQuotaHandler() {
|
|
|
59342
59924
|
}
|
|
59343
59925
|
let modelSlugs = [];
|
|
59344
59926
|
try {
|
|
59345
|
-
const modelsPath =
|
|
59346
|
-
if (
|
|
59347
|
-
const cache2 = JSON.parse(
|
|
59927
|
+
const modelsPath = join24(homedir22(), ".codex", "models_cache.json");
|
|
59928
|
+
if (existsSync21(modelsPath)) {
|
|
59929
|
+
const cache2 = JSON.parse(readFileSync20(modelsPath, "utf-8"));
|
|
59348
59930
|
modelSlugs = (cache2.models || []).map((m) => m.slug || m.id).filter(Boolean);
|
|
59349
59931
|
}
|
|
59350
59932
|
} catch {}
|
|
@@ -60692,19 +61274,19 @@ async function probeLink(proxyUrl, link, timeoutMs) {
|
|
|
60692
61274
|
}
|
|
60693
61275
|
const streamResult = await consumeProbeStream(response, timeoutMs, startedAt);
|
|
60694
61276
|
const totalMs = Date.now() - startedAt;
|
|
60695
|
-
let
|
|
61277
|
+
let timing2;
|
|
60696
61278
|
if (streamResult.state === "live" && streamResult.ttftMs !== undefined && !streamResult.truncated) {
|
|
60697
61279
|
const ttftMs = streamResult.ttftMs;
|
|
60698
61280
|
const tokens = streamResult.tokens ?? 0;
|
|
60699
61281
|
const streamMs = Math.max(STREAM_MS_FLOOR, totalMs - ttftMs);
|
|
60700
61282
|
const tokensPerSec = tokens > 0 ? tokens / streamMs * 1000 : 0;
|
|
60701
|
-
|
|
61283
|
+
timing2 = { ttfbMs, ttftMs, totalMs, tokens, tokensPerSec };
|
|
60702
61284
|
}
|
|
60703
61285
|
const { ttftMs: _ttft, tokens: _tok, truncated: _trunc, ...rest } = streamResult;
|
|
60704
61286
|
return annotateOAuthHint({
|
|
60705
61287
|
...rest,
|
|
60706
61288
|
latencyMs: totalMs,
|
|
60707
|
-
timing
|
|
61289
|
+
timing: timing2
|
|
60708
61290
|
}, link.provider, isOAuth);
|
|
60709
61291
|
}
|
|
60710
61292
|
function annotateOAuthHint(result, provider, isOAuth) {
|
|
@@ -61301,8 +61883,8 @@ function breakdownNum(ms) {
|
|
|
61301
61883
|
return formatLatency(ms);
|
|
61302
61884
|
return `${Math.round(Math.max(0, ms))}`;
|
|
61303
61885
|
}
|
|
61304
|
-
function buildBarsLine(
|
|
61305
|
-
const t =
|
|
61886
|
+
function buildBarsLine(timing2, scales, isFastest, usable) {
|
|
61887
|
+
const t = timing2;
|
|
61306
61888
|
const showTokBar = usable >= PRINTER_BARS_FULL_WIDTH;
|
|
61307
61889
|
const showBreakdown = usable >= PRINTER_BARS_FULL_WIDTH || usable >= PRINTER_BARS_NOTOK_WIDTH;
|
|
61308
61890
|
const barCells = timelineBarCells(t.totalMs, scales.maxTotalMs, PRINTER_BAR_WIDTH);
|
|
@@ -63307,22 +63889,22 @@ __export(exports_cli, {
|
|
|
63307
63889
|
});
|
|
63308
63890
|
import {
|
|
63309
63891
|
copyFileSync as copyFileSync2,
|
|
63310
|
-
existsSync as
|
|
63311
|
-
mkdirSync as
|
|
63312
|
-
readFileSync as
|
|
63892
|
+
existsSync as existsSync21,
|
|
63893
|
+
mkdirSync as mkdirSync13,
|
|
63894
|
+
readFileSync as readFileSync20,
|
|
63313
63895
|
readdirSync as readdirSync4,
|
|
63314
63896
|
unlinkSync as unlinkSync7,
|
|
63315
|
-
writeFileSync as
|
|
63897
|
+
writeFileSync as writeFileSync15
|
|
63316
63898
|
} from "fs";
|
|
63317
|
-
import { homedir as
|
|
63318
|
-
import { dirname as
|
|
63899
|
+
import { homedir as homedir22 } from "os";
|
|
63900
|
+
import { dirname as dirname8, join as join24 } from "path";
|
|
63319
63901
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
63320
63902
|
function getVersion3() {
|
|
63321
63903
|
return VERSION;
|
|
63322
63904
|
}
|
|
63323
63905
|
function clearAllModelCaches() {
|
|
63324
|
-
const cacheDir =
|
|
63325
|
-
if (!
|
|
63906
|
+
const cacheDir = join24(homedir22(), ".claudish");
|
|
63907
|
+
if (!existsSync21(cacheDir))
|
|
63326
63908
|
return;
|
|
63327
63909
|
const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
|
|
63328
63910
|
let cleared = 0;
|
|
@@ -63330,7 +63912,7 @@ function clearAllModelCaches() {
|
|
|
63330
63912
|
const files = readdirSync4(cacheDir);
|
|
63331
63913
|
for (const file2 of files) {
|
|
63332
63914
|
if (cachePatterns.includes(file2)) {
|
|
63333
|
-
unlinkSync7(
|
|
63915
|
+
unlinkSync7(join24(cacheDir, file2));
|
|
63334
63916
|
cleared++;
|
|
63335
63917
|
}
|
|
63336
63918
|
}
|
|
@@ -63740,15 +64322,15 @@ Usage: claudish --models --provider <slug>`);
|
|
|
63740
64322
|
});
|
|
63741
64323
|
config3.resolvedDefaultProvider = resolved;
|
|
63742
64324
|
if (resolved.legacyAutoPromoted && !config3.quiet) {
|
|
63743
|
-
const markerFile =
|
|
63744
|
-
if (!
|
|
64325
|
+
const markerFile = join24(homedir22(), ".claudish", ".legacy-litellm-hint-shown");
|
|
64326
|
+
if (!existsSync21(markerFile)) {
|
|
63745
64327
|
const hint = buildLegacyHint(resolved);
|
|
63746
64328
|
if (hint) {
|
|
63747
64329
|
console.error(hint);
|
|
63748
64330
|
}
|
|
63749
64331
|
try {
|
|
63750
|
-
|
|
63751
|
-
|
|
64332
|
+
mkdirSync13(dirname8(markerFile), { recursive: true });
|
|
64333
|
+
writeFileSync15(markerFile, new Date().toISOString(), "utf-8");
|
|
63752
64334
|
} catch {}
|
|
63753
64335
|
}
|
|
63754
64336
|
}
|
|
@@ -64808,8 +65390,8 @@ ${h("MORE INFO")}
|
|
|
64808
65390
|
}
|
|
64809
65391
|
function printAIAgentGuide() {
|
|
64810
65392
|
try {
|
|
64811
|
-
const guidePath =
|
|
64812
|
-
const guideContent =
|
|
65393
|
+
const guidePath = join24(__dirname3, "../AI_AGENT_GUIDE.md");
|
|
65394
|
+
const guideContent = readFileSync20(guidePath, "utf-8");
|
|
64813
65395
|
console.log(guideContent);
|
|
64814
65396
|
} catch (error46) {
|
|
64815
65397
|
console.error("Error reading AI Agent Guide:");
|
|
@@ -64825,19 +65407,19 @@ async function initializeClaudishSkill() {
|
|
|
64825
65407
|
console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
|
|
64826
65408
|
`);
|
|
64827
65409
|
const cwd = process.cwd();
|
|
64828
|
-
const claudeDir =
|
|
64829
|
-
const skillsDir =
|
|
64830
|
-
const claudishSkillDir =
|
|
64831
|
-
const skillFile =
|
|
64832
|
-
if (
|
|
65410
|
+
const claudeDir = join24(cwd, ".claude");
|
|
65411
|
+
const skillsDir = join24(claudeDir, "skills");
|
|
65412
|
+
const claudishSkillDir = join24(skillsDir, "claudish-usage");
|
|
65413
|
+
const skillFile = join24(claudishSkillDir, "SKILL.md");
|
|
65414
|
+
if (existsSync21(skillFile)) {
|
|
64833
65415
|
console.log("\u2705 Claudish skill already installed at:");
|
|
64834
65416
|
console.log(` ${skillFile}
|
|
64835
65417
|
`);
|
|
64836
65418
|
console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
|
|
64837
65419
|
return;
|
|
64838
65420
|
}
|
|
64839
|
-
const sourceSkillPath =
|
|
64840
|
-
if (!
|
|
65421
|
+
const sourceSkillPath = join24(__dirname3, "../skills/claudish-usage/SKILL.md");
|
|
65422
|
+
if (!existsSync21(sourceSkillPath)) {
|
|
64841
65423
|
console.error("\u274C Error: Claudish skill file not found in installation.");
|
|
64842
65424
|
console.error(` Expected at: ${sourceSkillPath}`);
|
|
64843
65425
|
console.error(`
|
|
@@ -64846,16 +65428,16 @@ async function initializeClaudishSkill() {
|
|
|
64846
65428
|
process.exit(1);
|
|
64847
65429
|
}
|
|
64848
65430
|
try {
|
|
64849
|
-
if (!
|
|
64850
|
-
|
|
65431
|
+
if (!existsSync21(claudeDir)) {
|
|
65432
|
+
mkdirSync13(claudeDir, { recursive: true });
|
|
64851
65433
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
64852
65434
|
}
|
|
64853
|
-
if (!
|
|
64854
|
-
|
|
65435
|
+
if (!existsSync21(skillsDir)) {
|
|
65436
|
+
mkdirSync13(skillsDir, { recursive: true });
|
|
64855
65437
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
64856
65438
|
}
|
|
64857
|
-
if (!
|
|
64858
|
-
|
|
65439
|
+
if (!existsSync21(claudishSkillDir)) {
|
|
65440
|
+
mkdirSync13(claudishSkillDir, { recursive: true });
|
|
64859
65441
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
64860
65442
|
}
|
|
64861
65443
|
copyFileSync2(sourceSkillPath, skillFile);
|
|
@@ -64927,7 +65509,7 @@ var init_cli = __esm(() => {
|
|
|
64927
65509
|
init_routing_rules();
|
|
64928
65510
|
init_provider_resolver();
|
|
64929
65511
|
__filename3 = fileURLToPath2(import.meta.url);
|
|
64930
|
-
__dirname3 =
|
|
65512
|
+
__dirname3 = dirname8(__filename3);
|
|
64931
65513
|
});
|
|
64932
65514
|
|
|
64933
65515
|
// src/update-checker.ts
|
|
@@ -64939,33 +65521,33 @@ __export(exports_update_checker, {
|
|
|
64939
65521
|
clearCache: () => clearCache,
|
|
64940
65522
|
checkForUpdates: () => checkForUpdates
|
|
64941
65523
|
});
|
|
64942
|
-
import { existsSync as
|
|
64943
|
-
import { homedir as
|
|
64944
|
-
import { join as
|
|
65524
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync14, readFileSync as readFileSync21, unlinkSync as unlinkSync8, writeFileSync as writeFileSync16 } from "fs";
|
|
65525
|
+
import { homedir as homedir23, platform as platform2, tmpdir } from "os";
|
|
65526
|
+
import { join as join25 } from "path";
|
|
64945
65527
|
function getCacheFilePath() {
|
|
64946
65528
|
let cacheDir;
|
|
64947
65529
|
if (isWindows) {
|
|
64948
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
64949
|
-
cacheDir =
|
|
65530
|
+
const localAppData = process.env.LOCALAPPDATA || join25(homedir23(), "AppData", "Local");
|
|
65531
|
+
cacheDir = join25(localAppData, "claudish");
|
|
64950
65532
|
} else {
|
|
64951
|
-
cacheDir =
|
|
65533
|
+
cacheDir = join25(homedir23(), ".cache", "claudish");
|
|
64952
65534
|
}
|
|
64953
65535
|
try {
|
|
64954
|
-
if (!
|
|
64955
|
-
|
|
65536
|
+
if (!existsSync22(cacheDir)) {
|
|
65537
|
+
mkdirSync14(cacheDir, { recursive: true });
|
|
64956
65538
|
}
|
|
64957
|
-
return
|
|
65539
|
+
return join25(cacheDir, "update-check.json");
|
|
64958
65540
|
} catch {
|
|
64959
|
-
return
|
|
65541
|
+
return join25(tmpdir(), "claudish-update-check.json");
|
|
64960
65542
|
}
|
|
64961
65543
|
}
|
|
64962
65544
|
function readCache() {
|
|
64963
65545
|
try {
|
|
64964
65546
|
const cachePath = getCacheFilePath();
|
|
64965
|
-
if (!
|
|
65547
|
+
if (!existsSync22(cachePath)) {
|
|
64966
65548
|
return null;
|
|
64967
65549
|
}
|
|
64968
|
-
const data = JSON.parse(
|
|
65550
|
+
const data = JSON.parse(readFileSync21(cachePath, "utf-8"));
|
|
64969
65551
|
return data;
|
|
64970
65552
|
} catch {
|
|
64971
65553
|
return null;
|
|
@@ -64978,7 +65560,7 @@ function writeCache(latestVersion) {
|
|
|
64978
65560
|
lastCheck: Date.now(),
|
|
64979
65561
|
latestVersion
|
|
64980
65562
|
};
|
|
64981
|
-
|
|
65563
|
+
writeFileSync16(cachePath, JSON.stringify(data), "utf-8");
|
|
64982
65564
|
} catch {}
|
|
64983
65565
|
}
|
|
64984
65566
|
function isCacheValid(cache2) {
|
|
@@ -64988,7 +65570,7 @@ function isCacheValid(cache2) {
|
|
|
64988
65570
|
function clearCache() {
|
|
64989
65571
|
try {
|
|
64990
65572
|
const cachePath = getCacheFilePath();
|
|
64991
|
-
if (
|
|
65573
|
+
if (existsSync22(cachePath)) {
|
|
64992
65574
|
unlinkSync8(cachePath);
|
|
64993
65575
|
}
|
|
64994
65576
|
} catch {}
|
|
@@ -65867,15 +66449,15 @@ var init_local_liveness = __esm(() => {
|
|
|
65867
66449
|
});
|
|
65868
66450
|
|
|
65869
66451
|
// src/providers/probe-catalog.ts
|
|
65870
|
-
import { existsSync as
|
|
65871
|
-
import { homedir as
|
|
65872
|
-
import { dirname as
|
|
66452
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync15, readFileSync as readFileSync22, writeFileSync as writeFileSync17 } from "fs";
|
|
66453
|
+
import { homedir as homedir24 } from "os";
|
|
66454
|
+
import { dirname as dirname9, join as join26 } from "path";
|
|
65873
66455
|
function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
|
|
65874
|
-
if (!
|
|
66456
|
+
if (!existsSync23(path2))
|
|
65875
66457
|
return null;
|
|
65876
66458
|
let raw2;
|
|
65877
66459
|
try {
|
|
65878
|
-
raw2 = JSON.parse(
|
|
66460
|
+
raw2 = JSON.parse(readFileSync22(path2, "utf-8"));
|
|
65879
66461
|
} catch {
|
|
65880
66462
|
return null;
|
|
65881
66463
|
}
|
|
@@ -65884,8 +66466,8 @@ function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
|
|
|
65884
66466
|
return raw2;
|
|
65885
66467
|
}
|
|
65886
66468
|
function writeProbeModelsCache(data, path2 = PROBE_MODELS_CACHE_PATH) {
|
|
65887
|
-
|
|
65888
|
-
|
|
66469
|
+
mkdirSync15(dirname9(path2), { recursive: true });
|
|
66470
|
+
writeFileSync17(path2, JSON.stringify(data), "utf-8");
|
|
65889
66471
|
}
|
|
65890
66472
|
function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
|
|
65891
66473
|
if (!data?.generatedAt)
|
|
@@ -66004,7 +66586,7 @@ function isValidResponse(raw2) {
|
|
|
66004
66586
|
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
66587
|
var init_probe_catalog = __esm(() => {
|
|
66006
66588
|
CACHE_TTL_MS4 = 60 * 60 * 1000;
|
|
66007
|
-
PROBE_MODELS_CACHE_PATH =
|
|
66589
|
+
PROBE_MODELS_CACHE_PATH = join26(homedir24(), ".claudish", "probe-models.json");
|
|
66008
66590
|
});
|
|
66009
66591
|
|
|
66010
66592
|
// src/tui/constants.ts
|
|
@@ -72337,16 +72919,16 @@ __export(exports_claude_runner, {
|
|
|
72337
72919
|
});
|
|
72338
72920
|
import { spawn as spawn4 } from "child_process";
|
|
72339
72921
|
import {
|
|
72340
|
-
closeSync as
|
|
72341
|
-
existsSync as
|
|
72342
|
-
mkdirSync as
|
|
72343
|
-
openSync as
|
|
72344
|
-
readFileSync as
|
|
72922
|
+
closeSync as closeSync5,
|
|
72923
|
+
existsSync as existsSync24,
|
|
72924
|
+
mkdirSync as mkdirSync16,
|
|
72925
|
+
openSync as openSync5,
|
|
72926
|
+
readFileSync as readFileSync23,
|
|
72345
72927
|
unlinkSync as unlinkSync9,
|
|
72346
|
-
writeFileSync as
|
|
72928
|
+
writeFileSync as writeFileSync18
|
|
72347
72929
|
} from "fs";
|
|
72348
|
-
import { homedir as
|
|
72349
|
-
import { join as
|
|
72930
|
+
import { homedir as homedir25, tmpdir as tmpdir2 } from "os";
|
|
72931
|
+
import { join as join27 } from "path";
|
|
72350
72932
|
import { isatty } from "tty";
|
|
72351
72933
|
function releaseTerminalIsolation() {
|
|
72352
72934
|
if (!restoreTerminal)
|
|
@@ -72381,14 +72963,14 @@ function isProxyAuthMode(config3) {
|
|
|
72381
72963
|
}
|
|
72382
72964
|
function managedSettingsPath() {
|
|
72383
72965
|
if (isWindows2()) {
|
|
72384
|
-
return
|
|
72966
|
+
return join27(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
|
|
72385
72967
|
}
|
|
72386
72968
|
if (process.platform === "darwin") {
|
|
72387
72969
|
return "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
72388
72970
|
}
|
|
72389
72971
|
return "/etc/claude-code/managed-settings.json";
|
|
72390
72972
|
}
|
|
72391
|
-
function managedSettingsForcesClaudeAi(readFile =
|
|
72973
|
+
function managedSettingsForcesClaudeAi(readFile = readFileSync23) {
|
|
72392
72974
|
try {
|
|
72393
72975
|
const raw2 = readFile(managedSettingsPath(), "utf-8");
|
|
72394
72976
|
const parsed = JSON.parse(raw2);
|
|
@@ -72402,9 +72984,9 @@ function isWindows2() {
|
|
|
72402
72984
|
}
|
|
72403
72985
|
function createStatusLineScript(tokenFilePath) {
|
|
72404
72986
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
72405
|
-
const claudishDir =
|
|
72987
|
+
const claudishDir = join27(homeDir, ".claudish");
|
|
72406
72988
|
const timestamp = Date.now();
|
|
72407
|
-
const scriptPath =
|
|
72989
|
+
const scriptPath = join27(claudishDir, `status-${timestamp}.js`);
|
|
72408
72990
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
72409
72991
|
const script = `
|
|
72410
72992
|
const fs = require('fs');
|
|
@@ -72496,18 +73078,18 @@ process.stdin.on('end', () => {
|
|
|
72496
73078
|
}
|
|
72497
73079
|
});
|
|
72498
73080
|
`;
|
|
72499
|
-
|
|
73081
|
+
writeFileSync18(scriptPath, script, "utf-8");
|
|
72500
73082
|
return scriptPath;
|
|
72501
73083
|
}
|
|
72502
73084
|
function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
|
|
72503
73085
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
72504
|
-
const claudishDir =
|
|
73086
|
+
const claudishDir = join27(homeDir, ".claudish");
|
|
72505
73087
|
try {
|
|
72506
|
-
|
|
73088
|
+
mkdirSync16(claudishDir, { recursive: true });
|
|
72507
73089
|
} catch {}
|
|
72508
73090
|
const timestamp = Date.now();
|
|
72509
|
-
const tempPath =
|
|
72510
|
-
const tokenFilePath =
|
|
73091
|
+
const tempPath = join27(claudishDir, `settings-${timestamp}.json`);
|
|
73092
|
+
const tokenFilePath = join27(claudishDir, `tokens-${port}.json`);
|
|
72511
73093
|
let statusCommand;
|
|
72512
73094
|
if (isWindows2()) {
|
|
72513
73095
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
@@ -72529,7 +73111,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
|
|
|
72529
73111
|
padding: 0
|
|
72530
73112
|
};
|
|
72531
73113
|
const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
|
|
72532
|
-
|
|
73114
|
+
writeFileSync18(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
72533
73115
|
return { path: tempPath, statusLine };
|
|
72534
73116
|
}
|
|
72535
73117
|
function buildClaudishSettingsOverlay(statusLine, proxyAuthMode) {
|
|
@@ -72550,7 +73132,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
|
|
|
72550
73132
|
if (userSettingsValue.trimStart().startsWith("{")) {
|
|
72551
73133
|
userSettings = JSON.parse(userSettingsValue);
|
|
72552
73134
|
} else {
|
|
72553
|
-
const rawUserSettings =
|
|
73135
|
+
const rawUserSettings = readFileSync23(userSettingsValue, "utf-8");
|
|
72554
73136
|
userSettings = JSON.parse(rawUserSettings);
|
|
72555
73137
|
}
|
|
72556
73138
|
userSettings.statusLine = statusLine;
|
|
@@ -72560,7 +73142,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
|
|
|
72560
73142
|
if (proxyAuthMode && !("forceLoginMethod" in userSettings)) {
|
|
72561
73143
|
userSettings.forceLoginMethod = "console";
|
|
72562
73144
|
}
|
|
72563
|
-
|
|
73145
|
+
writeFileSync18(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
72564
73146
|
} catch {
|
|
72565
73147
|
if (!config3.quiet) {
|
|
72566
73148
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -72721,8 +73303,8 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
72721
73303
|
console.error("Install it from: https://claude.com/claude-code");
|
|
72722
73304
|
console.error(`
|
|
72723
73305
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
72724
|
-
const home =
|
|
72725
|
-
const localPath = isWindows2() ?
|
|
73306
|
+
const home = homedir25();
|
|
73307
|
+
const localPath = isWindows2() ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
|
|
72726
73308
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
72727
73309
|
process.exit(1);
|
|
72728
73310
|
}
|
|
@@ -72733,11 +73315,11 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
72733
73315
|
const childWantsTty = config3.interactive && !process.stdout.isTTY && Boolean(process.stdin.isTTY);
|
|
72734
73316
|
if (childWantsTty) {
|
|
72735
73317
|
try {
|
|
72736
|
-
const fd =
|
|
73318
|
+
const fd = openSync5("/dev/fd/0", "r+");
|
|
72737
73319
|
if (isatty(fd)) {
|
|
72738
73320
|
ttyFd = fd;
|
|
72739
73321
|
} else {
|
|
72740
|
-
|
|
73322
|
+
closeSync5(fd);
|
|
72741
73323
|
}
|
|
72742
73324
|
} catch {
|
|
72743
73325
|
ttyFd = undefined;
|
|
@@ -72760,7 +73342,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
72760
73342
|
const fdToClose = ttyFd;
|
|
72761
73343
|
proc.on("spawn", () => {
|
|
72762
73344
|
try {
|
|
72763
|
-
|
|
73345
|
+
closeSync5(fdToClose);
|
|
72764
73346
|
} catch {}
|
|
72765
73347
|
});
|
|
72766
73348
|
}
|
|
@@ -72802,23 +73384,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
72802
73384
|
async function findClaudeBinary() {
|
|
72803
73385
|
const isWindows3 = process.platform === "win32";
|
|
72804
73386
|
if (process.env.CLAUDE_PATH) {
|
|
72805
|
-
if (
|
|
73387
|
+
if (existsSync24(process.env.CLAUDE_PATH)) {
|
|
72806
73388
|
return process.env.CLAUDE_PATH;
|
|
72807
73389
|
}
|
|
72808
73390
|
}
|
|
72809
|
-
const home =
|
|
72810
|
-
const localPath = isWindows3 ?
|
|
72811
|
-
if (
|
|
73391
|
+
const home = homedir25();
|
|
73392
|
+
const localPath = isWindows3 ? join27(home, ".claude", "local", "claude.exe") : join27(home, ".claude", "local", "claude");
|
|
73393
|
+
if (existsSync24(localPath)) {
|
|
72812
73394
|
return localPath;
|
|
72813
73395
|
}
|
|
72814
73396
|
if (isWindows3) {
|
|
72815
73397
|
const windowsPaths = [
|
|
72816
|
-
|
|
72817
|
-
|
|
72818
|
-
|
|
73398
|
+
join27(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
73399
|
+
join27(home, ".npm-global", "claude.cmd"),
|
|
73400
|
+
join27(home, "node_modules", ".bin", "claude.cmd")
|
|
72819
73401
|
];
|
|
72820
73402
|
for (const path2 of windowsPaths) {
|
|
72821
|
-
if (
|
|
73403
|
+
if (existsSync24(path2)) {
|
|
72822
73404
|
return path2;
|
|
72823
73405
|
}
|
|
72824
73406
|
}
|
|
@@ -72826,14 +73408,14 @@ async function findClaudeBinary() {
|
|
|
72826
73408
|
const commonPaths = [
|
|
72827
73409
|
"/usr/local/bin/claude",
|
|
72828
73410
|
"/opt/homebrew/bin/claude",
|
|
72829
|
-
|
|
72830
|
-
|
|
72831
|
-
|
|
73411
|
+
join27(home, ".npm-global/bin/claude"),
|
|
73412
|
+
join27(home, ".local/bin/claude"),
|
|
73413
|
+
join27(home, "node_modules/.bin/claude"),
|
|
72832
73414
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
72833
|
-
|
|
73415
|
+
join27(home, "../usr/bin/claude")
|
|
72834
73416
|
];
|
|
72835
73417
|
for (const path2 of commonPaths) {
|
|
72836
|
-
if (
|
|
73418
|
+
if (existsSync24(path2)) {
|
|
72837
73419
|
return path2;
|
|
72838
73420
|
}
|
|
72839
73421
|
}
|
|
@@ -72890,18 +73472,18 @@ __export(exports_diag_output, {
|
|
|
72890
73472
|
NullDiagOutput: () => NullDiagOutput,
|
|
72891
73473
|
LogFileDiagOutput: () => LogFileDiagOutput
|
|
72892
73474
|
});
|
|
72893
|
-
import { createWriteStream as createWriteStream3, mkdirSync as
|
|
72894
|
-
import { homedir as
|
|
72895
|
-
import { join as
|
|
73475
|
+
import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync17, unlinkSync as unlinkSync10, writeFileSync as writeFileSync19 } from "fs";
|
|
73476
|
+
import { homedir as homedir26 } from "os";
|
|
73477
|
+
import { join as join28 } from "path";
|
|
72896
73478
|
function getClaudishDir() {
|
|
72897
|
-
const dir =
|
|
73479
|
+
const dir = join28(homedir26(), ".claudish");
|
|
72898
73480
|
try {
|
|
72899
|
-
|
|
73481
|
+
mkdirSync17(dir, { recursive: true });
|
|
72900
73482
|
} catch {}
|
|
72901
73483
|
return dir;
|
|
72902
73484
|
}
|
|
72903
73485
|
function getDiagLogPath() {
|
|
72904
|
-
return
|
|
73486
|
+
return join28(getClaudishDir(), `diag-${process.pid}.log`);
|
|
72905
73487
|
}
|
|
72906
73488
|
|
|
72907
73489
|
class LogFileDiagOutput {
|
|
@@ -72910,7 +73492,7 @@ class LogFileDiagOutput {
|
|
|
72910
73492
|
constructor() {
|
|
72911
73493
|
this.logPath = getDiagLogPath();
|
|
72912
73494
|
try {
|
|
72913
|
-
|
|
73495
|
+
writeFileSync19(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
72914
73496
|
`);
|
|
72915
73497
|
} catch {}
|
|
72916
73498
|
this.stream = createWriteStream3(this.logPath, { flags: "a" });
|
|
@@ -73112,9 +73694,9 @@ __export(exports_team_grid, {
|
|
|
73112
73694
|
});
|
|
73113
73695
|
import { spawn as spawn5 } from "child_process";
|
|
73114
73696
|
import { execSync as execSync2 } from "child_process";
|
|
73115
|
-
import { existsSync as
|
|
73697
|
+
import { existsSync as existsSync25, readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "fs";
|
|
73116
73698
|
import { connect as netConnect } from "net";
|
|
73117
|
-
import { dirname as
|
|
73699
|
+
import { dirname as dirname10, join as join29 } from "path";
|
|
73118
73700
|
import { setTimeout as wait } from "timers/promises";
|
|
73119
73701
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
73120
73702
|
function resolveRouteInfo(modelId) {
|
|
@@ -73207,21 +73789,21 @@ function buildPaneHeader(model, prompt, bg) {
|
|
|
73207
73789
|
}
|
|
73208
73790
|
function findMagmuxBinary() {
|
|
73209
73791
|
const thisFile = fileURLToPath3(import.meta.url);
|
|
73210
|
-
const thisDir =
|
|
73211
|
-
const pkgRoot =
|
|
73792
|
+
const thisDir = dirname10(thisFile);
|
|
73793
|
+
const pkgRoot = join29(thisDir, "..");
|
|
73212
73794
|
const platform3 = process.platform;
|
|
73213
73795
|
const arch = process.arch;
|
|
73214
|
-
const bundledMagmux =
|
|
73215
|
-
if (
|
|
73796
|
+
const bundledMagmux = join29(pkgRoot, "native", `magmux-${platform3}-${arch}`);
|
|
73797
|
+
if (existsSync25(bundledMagmux))
|
|
73216
73798
|
return bundledMagmux;
|
|
73217
73799
|
try {
|
|
73218
73800
|
const pkgName = `@claudish/magmux-${platform3}-${arch}`;
|
|
73219
73801
|
let searchDir = pkgRoot;
|
|
73220
73802
|
for (let i = 0;i < 5; i++) {
|
|
73221
|
-
const candidate =
|
|
73222
|
-
if (
|
|
73803
|
+
const candidate = join29(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
73804
|
+
if (existsSync25(candidate))
|
|
73223
73805
|
return candidate;
|
|
73224
|
-
const parent =
|
|
73806
|
+
const parent = dirname10(searchDir);
|
|
73225
73807
|
if (parent === searchDir)
|
|
73226
73808
|
break;
|
|
73227
73809
|
searchDir = parent;
|
|
@@ -73238,7 +73820,7 @@ function findMagmuxBinary() {
|
|
|
73238
73820
|
async function subscribeToMagmux(sockPath, onEvent) {
|
|
73239
73821
|
let client = null;
|
|
73240
73822
|
for (let attempt = 0;attempt < 40; attempt++) {
|
|
73241
|
-
if (
|
|
73823
|
+
if (existsSync25(sockPath)) {
|
|
73242
73824
|
try {
|
|
73243
73825
|
client = await new Promise((resolve4, reject) => {
|
|
73244
73826
|
const s = netConnect(sockPath);
|
|
@@ -73325,9 +73907,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
73325
73907
|
const keep = opts?.keep ?? false;
|
|
73326
73908
|
const manifest = setupSession(sessionPath, models, input);
|
|
73327
73909
|
const startedAt = new Date().toISOString();
|
|
73328
|
-
const gridfilePath =
|
|
73329
|
-
const prompt =
|
|
73330
|
-
const rawPrompt =
|
|
73910
|
+
const gridfilePath = join29(sessionPath, "gridfile.txt");
|
|
73911
|
+
const prompt = readFileSync24(join29(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
73912
|
+
const rawPrompt = readFileSync24(join29(sessionPath, "input.md"), "utf-8");
|
|
73331
73913
|
const usedBannerColors = new Set;
|
|
73332
73914
|
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
73333
73915
|
const model = manifest.models[anonId].model;
|
|
@@ -73338,7 +73920,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
73338
73920
|
const header = buildPaneHeader(model, rawPrompt, bg);
|
|
73339
73921
|
return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
|
|
73340
73922
|
});
|
|
73341
|
-
|
|
73923
|
+
writeFileSync20(gridfilePath, `${gridLines.join(`
|
|
73342
73924
|
`)}
|
|
73343
73925
|
`, "utf-8");
|
|
73344
73926
|
const magmuxPath = findMagmuxBinary();
|
|
@@ -73358,8 +73940,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
73358
73940
|
});
|
|
73359
73941
|
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
73360
73942
|
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
73361
|
-
const statusPath =
|
|
73362
|
-
|
|
73943
|
+
const statusPath = join29(sessionPath, "status.json");
|
|
73944
|
+
writeFileSync20(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
73363
73945
|
return status;
|
|
73364
73946
|
}
|
|
73365
73947
|
var BANNER_BG_COLORS;
|
|
@@ -73382,8 +73964,8 @@ var init_team_grid = __esm(() => {
|
|
|
73382
73964
|
init_op_source();
|
|
73383
73965
|
init_startup_trace();
|
|
73384
73966
|
var import_dotenv3 = __toESM(require_main(), 1);
|
|
73385
|
-
import { existsSync as
|
|
73386
|
-
import { join as
|
|
73967
|
+
import { existsSync as existsSync26, readFileSync as readFileSync25 } from "fs";
|
|
73968
|
+
import { join as join30, resolve as resolve4 } from "path";
|
|
73387
73969
|
import_dotenv3.config({ quiet: true });
|
|
73388
73970
|
function classifyStartupKind() {
|
|
73389
73971
|
const argv = process.argv.slice(2);
|
|
@@ -73482,7 +74064,7 @@ async function applyConfigOverride() {
|
|
|
73482
74064
|
const { planConfigOverride: planConfigOverride2, setConfigFileOverride: setConfigFileOverride2 } = await Promise.resolve().then(() => exports_config_override);
|
|
73483
74065
|
const plan = planConfigOverride2(process.argv.slice(2), process.env, {
|
|
73484
74066
|
resolve: resolve4,
|
|
73485
|
-
exists:
|
|
74067
|
+
exists: existsSync26
|
|
73486
74068
|
});
|
|
73487
74069
|
if (plan.kind === "none")
|
|
73488
74070
|
return;
|
|
@@ -73617,14 +74199,14 @@ async function runCli() {
|
|
|
73617
74199
|
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
73618
74200
|
let prompt = cliConfig.claudeArgs.join(" ");
|
|
73619
74201
|
if (cliConfig.inputFile) {
|
|
73620
|
-
prompt =
|
|
74202
|
+
prompt = readFileSync25(cliConfig.inputFile, "utf-8");
|
|
73621
74203
|
}
|
|
73622
74204
|
if (!prompt.trim()) {
|
|
73623
74205
|
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
73624
74206
|
process.exit(1);
|
|
73625
74207
|
}
|
|
73626
74208
|
const mode = cliConfig.teamMode ?? "default";
|
|
73627
|
-
const sessionPath =
|
|
74209
|
+
const sessionPath = join30(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
73628
74210
|
if (mode === "json") {
|
|
73629
74211
|
const { setupSession: setupSession2, runModels: runModels2 } = await Promise.resolve().then(() => (init_team_orchestrator(), exports_team_orchestrator));
|
|
73630
74212
|
setupSession2(sessionPath, cliConfig.team, prompt);
|
|
@@ -73634,9 +74216,9 @@ async function runCli() {
|
|
|
73634
74216
|
});
|
|
73635
74217
|
const result = { ...status2, responses: {} };
|
|
73636
74218
|
for (const anonId of Object.keys(status2.models)) {
|
|
73637
|
-
const responsePath =
|
|
74219
|
+
const responsePath = join30(sessionPath, `response-${anonId}.md`);
|
|
73638
74220
|
try {
|
|
73639
|
-
const raw2 =
|
|
74221
|
+
const raw2 = readFileSync25(responsePath, "utf-8").trim();
|
|
73640
74222
|
try {
|
|
73641
74223
|
result.responses[anonId] = JSON.parse(raw2);
|
|
73642
74224
|
} catch {
|