claudish 13.3.0 → 13.4.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 +277 -161
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -575,7 +575,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
575
575
|
});
|
|
576
576
|
|
|
577
577
|
// src/version.ts
|
|
578
|
-
var VERSION = "13.
|
|
578
|
+
var VERSION = "13.4.0";
|
|
579
579
|
|
|
580
580
|
// src/logger.ts
|
|
581
581
|
import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -76472,23 +76472,122 @@ var init_team_orchestrator = __esm(() => {
|
|
|
76472
76472
|
CANCELLED_DETAIL = `Stopped on the caller's instruction via team(mode:"cancel"). ` + "Whatever the child had written up to that point is in its response file.";
|
|
76473
76473
|
});
|
|
76474
76474
|
|
|
76475
|
+
// src/mcp-session/inherited-settings.ts
|
|
76476
|
+
import { existsSync as existsSync34, readFileSync as readFileSync33, statSync as statSync13 } from "fs";
|
|
76477
|
+
import { join as join51, resolve as resolve6 } from "path";
|
|
76478
|
+
function isPlainObject6(value) {
|
|
76479
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
76480
|
+
}
|
|
76481
|
+
function uniqueByJson(values) {
|
|
76482
|
+
const seen = new Set;
|
|
76483
|
+
return values.filter((value) => {
|
|
76484
|
+
const key = JSON.stringify(value);
|
|
76485
|
+
if (seen.has(key))
|
|
76486
|
+
return false;
|
|
76487
|
+
seen.add(key);
|
|
76488
|
+
return true;
|
|
76489
|
+
});
|
|
76490
|
+
}
|
|
76491
|
+
function mergeSettingsLayers(base, over) {
|
|
76492
|
+
const merged = structuredClone(base);
|
|
76493
|
+
for (const [key, value] of Object.entries(over)) {
|
|
76494
|
+
const current = merged[key];
|
|
76495
|
+
if (isPlainObject6(current) && isPlainObject6(value)) {
|
|
76496
|
+
merged[key] = mergeSettingsLayers(current, value);
|
|
76497
|
+
} else if (Array.isArray(current) && Array.isArray(value)) {
|
|
76498
|
+
merged[key] = uniqueByJson([...current, ...structuredClone(value)]);
|
|
76499
|
+
} else {
|
|
76500
|
+
merged[key] = structuredClone(value);
|
|
76501
|
+
}
|
|
76502
|
+
}
|
|
76503
|
+
return merged;
|
|
76504
|
+
}
|
|
76505
|
+
function parseLayer(text, source) {
|
|
76506
|
+
let parsed;
|
|
76507
|
+
try {
|
|
76508
|
+
parsed = JSON.parse(text);
|
|
76509
|
+
} catch (err) {
|
|
76510
|
+
throw new Error(`invalid_args: settings ${source} is not valid JSON (${err.message})`);
|
|
76511
|
+
}
|
|
76512
|
+
if (!isPlainObject6(parsed)) {
|
|
76513
|
+
throw new Error(`invalid_args: settings ${source} is not a JSON object`);
|
|
76514
|
+
}
|
|
76515
|
+
return parsed;
|
|
76516
|
+
}
|
|
76517
|
+
function readSettingsValue(value) {
|
|
76518
|
+
if (value.trim().startsWith("{"))
|
|
76519
|
+
return parseLayer(value, value);
|
|
76520
|
+
let text;
|
|
76521
|
+
try {
|
|
76522
|
+
text = readFileSync33(value, "utf-8");
|
|
76523
|
+
} catch (err) {
|
|
76524
|
+
throw new Error(`invalid_args: settings ${value} cannot be read (${err.message})`);
|
|
76525
|
+
}
|
|
76526
|
+
return parseLayer(text, value);
|
|
76527
|
+
}
|
|
76528
|
+
function buildInheritedSettingsLayer(setupFrom, callerFlags) {
|
|
76529
|
+
const layers = [];
|
|
76530
|
+
for (const name of ["settings.json", "settings.local.json"]) {
|
|
76531
|
+
const file = join51(setupFrom, ".claude", name);
|
|
76532
|
+
if (!existsSync34(file))
|
|
76533
|
+
continue;
|
|
76534
|
+
layers.push(parseLayer(readFileSync33(file, "utf-8"), file));
|
|
76535
|
+
}
|
|
76536
|
+
const restFlags = [];
|
|
76537
|
+
for (let i = 0;i < callerFlags.length; i++) {
|
|
76538
|
+
const flag = callerFlags[i];
|
|
76539
|
+
if (flag === "--settings") {
|
|
76540
|
+
const value = callerFlags[i + 1];
|
|
76541
|
+
if (value === undefined)
|
|
76542
|
+
throw new Error("invalid_args: --settings needs a value");
|
|
76543
|
+
layers.push(readSettingsValue(value));
|
|
76544
|
+
i++;
|
|
76545
|
+
} else if (flag.startsWith("--settings=")) {
|
|
76546
|
+
layers.push(readSettingsValue(flag.slice("--settings=".length)));
|
|
76547
|
+
} else {
|
|
76548
|
+
restFlags.push(flag);
|
|
76549
|
+
}
|
|
76550
|
+
}
|
|
76551
|
+
if (layers.length === 0)
|
|
76552
|
+
return { layer: null, restFlags };
|
|
76553
|
+
const layer = layers.reduce((acc, next) => mergeSettingsLayers(acc, next), {});
|
|
76554
|
+
if (isPlainObject6(layer.permissions))
|
|
76555
|
+
delete layer.permissions.additionalDirectories;
|
|
76556
|
+
return { layer, restFlags };
|
|
76557
|
+
}
|
|
76558
|
+
function resolveSetupFrom(arg, workDir, serverCwd) {
|
|
76559
|
+
if (arg === null)
|
|
76560
|
+
return;
|
|
76561
|
+
let setupFrom = serverCwd;
|
|
76562
|
+
if (typeof arg === "string") {
|
|
76563
|
+
setupFrom = resolve6(arg);
|
|
76564
|
+
if (!statSync13(setupFrom, { throwIfNoEntry: false })?.isDirectory()) {
|
|
76565
|
+
throw new Error(`invalid_args: setup_from ${setupFrom} is not an existing directory`);
|
|
76566
|
+
}
|
|
76567
|
+
} else if (arg !== undefined) {
|
|
76568
|
+
throw new Error("invalid_args: setup_from must be a directory path or null");
|
|
76569
|
+
}
|
|
76570
|
+
return setupFrom === resolve6(workDir ?? serverCwd) ? undefined : setupFrom;
|
|
76571
|
+
}
|
|
76572
|
+
var init_inherited_settings = () => {};
|
|
76573
|
+
|
|
76475
76574
|
// src/mcp-session/session-manager.ts
|
|
76476
76575
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
76477
76576
|
import {
|
|
76478
76577
|
appendFileSync as appendFileSync7,
|
|
76479
76578
|
closeSync as closeSync11,
|
|
76480
76579
|
createWriteStream,
|
|
76481
|
-
existsSync as
|
|
76580
|
+
existsSync as existsSync35,
|
|
76482
76581
|
mkdirSync as mkdirSync22,
|
|
76483
76582
|
openSync as openSync11,
|
|
76484
|
-
readFileSync as
|
|
76583
|
+
readFileSync as readFileSync34,
|
|
76485
76584
|
readSync as readSync6,
|
|
76486
76585
|
renameSync as renameSync5,
|
|
76487
76586
|
rmSync as rmSync9,
|
|
76488
|
-
statSync as
|
|
76587
|
+
statSync as statSync14,
|
|
76489
76588
|
writeFileSync as writeFileSync23
|
|
76490
76589
|
} from "fs";
|
|
76491
|
-
import { join as
|
|
76590
|
+
import { join as join52, resolve as resolve7, sep as sep2 } from "path";
|
|
76492
76591
|
function normaliseTimeoutSeconds(raw) {
|
|
76493
76592
|
const n = typeof raw === "string" && raw.trim() !== "" ? Number(raw) : raw;
|
|
76494
76593
|
if (typeof n !== "number" || !Number.isFinite(n))
|
|
@@ -76588,7 +76687,7 @@ function anomalyKey(a) {
|
|
|
76588
76687
|
function readTailText(path, maxBytes) {
|
|
76589
76688
|
let fd = null;
|
|
76590
76689
|
try {
|
|
76591
|
-
const size =
|
|
76690
|
+
const size = statSync14(path).size;
|
|
76592
76691
|
if (size === 0)
|
|
76593
76692
|
return { text: "", truncated: false };
|
|
76594
76693
|
const start = Math.max(0, size - maxBytes);
|
|
@@ -76619,7 +76718,7 @@ function readTailLines2(path, maxBytes) {
|
|
|
76619
76718
|
}
|
|
76620
76719
|
function fileSize2(path) {
|
|
76621
76720
|
try {
|
|
76622
|
-
return
|
|
76721
|
+
return statSync14(path).size;
|
|
76623
76722
|
} catch {
|
|
76624
76723
|
return 0;
|
|
76625
76724
|
}
|
|
@@ -76628,7 +76727,7 @@ function readJsonObject(path, maxBytes) {
|
|
|
76628
76727
|
try {
|
|
76629
76728
|
if (fileSize2(path) > maxBytes)
|
|
76630
76729
|
return null;
|
|
76631
|
-
const parsed = JSON.parse(
|
|
76730
|
+
const parsed = JSON.parse(readFileSync34(path, "utf-8"));
|
|
76632
76731
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
76633
76732
|
return null;
|
|
76634
76733
|
return parsed;
|
|
@@ -76654,7 +76753,7 @@ function dropLeadingFragment(tail) {
|
|
|
76654
76753
|
return firstBreak === -1 ? tail.text : tail.text.slice(firstBreak + 1);
|
|
76655
76754
|
}
|
|
76656
76755
|
function diskAccounting(sessionDir) {
|
|
76657
|
-
const stats = readTokenStatsAt(
|
|
76756
|
+
const stats = readTokenStatsAt(join52(sessionDir, "tokens.json"));
|
|
76658
76757
|
return {
|
|
76659
76758
|
tokensIn: stats?.billed_input_tokens ?? null,
|
|
76660
76759
|
tokensOut: stats?.output_tokens ?? null,
|
|
@@ -76737,7 +76836,7 @@ class SessionManager {
|
|
|
76737
76836
|
let dir = "";
|
|
76738
76837
|
for (let attempt = 0;; attempt++) {
|
|
76739
76838
|
id = `team-${randomUUID7().replace(/-/g, "").slice(0, 8)}`;
|
|
76740
|
-
dir =
|
|
76839
|
+
dir = join52(this.sessionsDir, id);
|
|
76741
76840
|
try {
|
|
76742
76841
|
mkdirSync22(dir);
|
|
76743
76842
|
break;
|
|
@@ -76752,7 +76851,7 @@ class SessionManager {
|
|
|
76752
76851
|
sessionId: id,
|
|
76753
76852
|
parentClaudeSessionId: opts.parentClaudeSessionId,
|
|
76754
76853
|
startedAt,
|
|
76755
|
-
teamPath:
|
|
76854
|
+
teamPath: resolve7(opts.teamPath),
|
|
76756
76855
|
slots: opts.slots
|
|
76757
76856
|
});
|
|
76758
76857
|
this.teamRunStarts.set(id, startedAt);
|
|
@@ -76769,9 +76868,9 @@ class SessionManager {
|
|
|
76769
76868
|
if (dir === null)
|
|
76770
76869
|
throw new Error("not a record id");
|
|
76771
76870
|
const completedAt = new Date().toISOString();
|
|
76772
|
-
const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(
|
|
76871
|
+
const startedAt = this.teamRunStarts.get(record) ?? metaString(readJsonObject(join52(dir, "spawn.json"), META_READ_LIMIT)?.startedAt) ?? completedAt;
|
|
76773
76872
|
const elapsedMs = Date.parse(completedAt) - Date.parse(startedAt);
|
|
76774
|
-
writeJsonAtomic(
|
|
76873
|
+
writeJsonAtomic(join52(dir, "meta.json"), {
|
|
76775
76874
|
kind: "team",
|
|
76776
76875
|
status: outcome.status,
|
|
76777
76876
|
startedAt,
|
|
@@ -76803,7 +76902,7 @@ class SessionManager {
|
|
|
76803
76902
|
startedAt,
|
|
76804
76903
|
...rest
|
|
76805
76904
|
};
|
|
76806
|
-
writeJsonAtomic(
|
|
76905
|
+
writeJsonAtomic(join52(dir, "spawn.json"), body);
|
|
76807
76906
|
}
|
|
76808
76907
|
async createSession(opts) {
|
|
76809
76908
|
if (this.activeSessions + this.starting >= this.maxSessions) {
|
|
@@ -76812,10 +76911,12 @@ class SessionManager {
|
|
|
76812
76911
|
if (opts.sessionId !== undefined && this.sessions.has(opts.sessionId)) {
|
|
76813
76912
|
throw new Error(`Session id already in use: ${opts.sessionId}`);
|
|
76814
76913
|
}
|
|
76815
|
-
const
|
|
76816
|
-
const flagCheck = checkChildFlags(
|
|
76914
|
+
const callerFlags = opts.claudishFlags ?? [];
|
|
76915
|
+
const flagCheck = checkChildFlags(callerFlags);
|
|
76817
76916
|
if (!flagCheck.ok)
|
|
76818
76917
|
throw new Error(`invalid_args: ${flagCheck.message}`);
|
|
76918
|
+
const inherited = opts.setupFrom ? buildInheritedSettingsLayer(opts.setupFrom, callerFlags) : { layer: null, restFlags: callerFlags };
|
|
76919
|
+
let flags = callerFlags;
|
|
76819
76920
|
const readAvailable = !flagsRemoveRead(flags);
|
|
76820
76921
|
if (opts.prompt) {
|
|
76821
76922
|
const refusal = deliveryRefusal(opts.prompt, readAvailable);
|
|
@@ -76835,11 +76936,14 @@ class SessionManager {
|
|
|
76835
76936
|
reservePanes(1, sockRootFor(parentEnv));
|
|
76836
76937
|
let entry;
|
|
76837
76938
|
try {
|
|
76838
|
-
entry = this.recordSession(opts);
|
|
76939
|
+
entry = this.recordSession(opts, inherited.layer);
|
|
76839
76940
|
} catch (err) {
|
|
76840
76941
|
releasePaneReservations(1);
|
|
76841
76942
|
throw err;
|
|
76842
76943
|
}
|
|
76944
|
+
if (inherited.layer) {
|
|
76945
|
+
flags = [...inherited.restFlags, "--settings", join52(entry.sessionDir, INHERITED_SETTINGS)];
|
|
76946
|
+
}
|
|
76843
76947
|
this.sessions.set(entry.info.sessionId, entry);
|
|
76844
76948
|
uncount();
|
|
76845
76949
|
const started = this.startPane(entry, opts, { flags, readAvailable, parentEnv });
|
|
@@ -76857,15 +76961,15 @@ class SessionManager {
|
|
|
76857
76961
|
uncount();
|
|
76858
76962
|
}
|
|
76859
76963
|
}
|
|
76860
|
-
recordSession(opts) {
|
|
76964
|
+
recordSession(opts, inheritedLayer) {
|
|
76861
76965
|
const sessionId = opts.sessionId ?? randomUUID7().slice(0, 8);
|
|
76862
76966
|
const claudeSessionId = randomUUID7();
|
|
76863
76967
|
const timeout = normaliseTimeoutSeconds(opts.timeoutSeconds);
|
|
76864
76968
|
const startedAt = new Date().toISOString();
|
|
76865
|
-
const sessionDir = opts.sessionDir ??
|
|
76969
|
+
const sessionDir = opts.sessionDir ?? join52(this.sessionsDir, sessionId);
|
|
76866
76970
|
mkdirSync22(sessionDir, { recursive: true });
|
|
76867
76971
|
if (opts.prompt)
|
|
76868
|
-
writeFileSync23(
|
|
76972
|
+
writeFileSync23(join52(sessionDir, "prompt.md"), opts.prompt, "utf-8");
|
|
76869
76973
|
this.writeSpawnRecord(sessionDir, {
|
|
76870
76974
|
kind: "session",
|
|
76871
76975
|
sessionId,
|
|
@@ -76873,12 +76977,17 @@ class SessionManager {
|
|
|
76873
76977
|
startedAt,
|
|
76874
76978
|
model: opts.model,
|
|
76875
76979
|
timeoutSeconds: timeout,
|
|
76876
|
-
claudeSessionId
|
|
76980
|
+
claudeSessionId,
|
|
76981
|
+
...opts.setupFrom ? { setupFrom: opts.setupFrom } : {}
|
|
76877
76982
|
});
|
|
76983
|
+
if (inheritedLayer) {
|
|
76984
|
+
writeFileSync23(join52(sessionDir, INHERITED_SETTINGS), `${JSON.stringify(inheritedLayer, null, 2)}
|
|
76985
|
+
`, { encoding: "utf-8", mode: 384 });
|
|
76986
|
+
}
|
|
76878
76987
|
const cwd = opts.cwd ?? process.cwd();
|
|
76879
76988
|
const parentEnv = opts.parentEnv ?? this.parentEnv;
|
|
76880
76989
|
const spawnModel = opts.spawnModel ?? null;
|
|
76881
|
-
const tokenFile = opts.tokenFile ??
|
|
76990
|
+
const tokenFile = opts.tokenFile ?? join52(sessionDir, "tokens.json");
|
|
76882
76991
|
return {
|
|
76883
76992
|
info: {
|
|
76884
76993
|
sessionId,
|
|
@@ -76914,18 +77023,18 @@ class SessionManager {
|
|
|
76914
77023
|
},
|
|
76915
77024
|
session: null,
|
|
76916
77025
|
scrollback: new ScrollbackBuffer(this.scrollbackCapacity),
|
|
76917
|
-
outputLogStream: createWriteStream(
|
|
77026
|
+
outputLogStream: createWriteStream(join52(sessionDir, "output.log")),
|
|
76918
77027
|
sessionDir,
|
|
76919
77028
|
cwd,
|
|
76920
77029
|
tokenFile,
|
|
76921
|
-
eventLogPath:
|
|
77030
|
+
eventLogPath: join52(sessionDir, "events.jsonl"),
|
|
76922
77031
|
eventLogBytes: 0,
|
|
76923
|
-
upstreamErrorLogPath:
|
|
77032
|
+
upstreamErrorLogPath: join52(sessionDir, "upstream-errors.jsonl"),
|
|
76924
77033
|
eventRing: [],
|
|
76925
77034
|
proseBytes: 0,
|
|
76926
77035
|
answeredTurns: new Map,
|
|
76927
77036
|
inboxPath: null,
|
|
76928
|
-
waitLogPath:
|
|
77037
|
+
waitLogPath: join52(sessionDir, "waits.jsonl"),
|
|
76929
77038
|
waitLogBytes: 0,
|
|
76930
77039
|
waitSince: null,
|
|
76931
77040
|
ended: false,
|
|
@@ -77114,7 +77223,7 @@ class SessionManager {
|
|
|
77114
77223
|
try {
|
|
77115
77224
|
const text = screenLines.join(`
|
|
77116
77225
|
`).replace(/\s+$/, "");
|
|
77117
|
-
writeFileSync23(
|
|
77226
|
+
writeFileSync23(join52(entry.sessionDir, "screen.txt"), `${redactSecrets2(text)}
|
|
77118
77227
|
`, "utf-8");
|
|
77119
77228
|
} catch {}
|
|
77120
77229
|
}
|
|
@@ -77128,7 +77237,7 @@ class SessionManager {
|
|
|
77128
77237
|
entry.waitSince = null;
|
|
77129
77238
|
}
|
|
77130
77239
|
try {
|
|
77131
|
-
writeJsonAtomic(
|
|
77240
|
+
writeJsonAtomic(join52(entry.sessionDir, "meta.json"), toMetaRecord(entry.info, entry.cwd));
|
|
77132
77241
|
} catch (err) {
|
|
77133
77242
|
process.stderr.write(`[claudish] session ${entry.info.sessionId}: could not write meta.json: ` + `${err instanceof Error ? err.message : String(err)}
|
|
77134
77243
|
`);
|
|
@@ -77387,9 +77496,9 @@ class SessionManager {
|
|
|
77387
77496
|
diskSessionDir(sessionId) {
|
|
77388
77497
|
if (!SESSION_ID_RE.test(sessionId))
|
|
77389
77498
|
return null;
|
|
77390
|
-
const root =
|
|
77391
|
-
const dir =
|
|
77392
|
-
if (dir !==
|
|
77499
|
+
const root = resolve7(this.sessionsDir);
|
|
77500
|
+
const dir = resolve7(root, sessionId);
|
|
77501
|
+
if (dir !== join52(root, sessionId))
|
|
77393
77502
|
return null;
|
|
77394
77503
|
if (!dir.startsWith(root + sep2))
|
|
77395
77504
|
return null;
|
|
@@ -77401,17 +77510,17 @@ class SessionManager {
|
|
|
77401
77510
|
return null;
|
|
77402
77511
|
let dirMtimeMs;
|
|
77403
77512
|
try {
|
|
77404
|
-
const stat =
|
|
77513
|
+
const stat = statSync14(sessionDir);
|
|
77405
77514
|
if (!stat.isDirectory())
|
|
77406
77515
|
return null;
|
|
77407
77516
|
dirMtimeMs = stat.mtimeMs;
|
|
77408
77517
|
} catch {
|
|
77409
77518
|
return null;
|
|
77410
77519
|
}
|
|
77411
|
-
const spawnRecord = readJsonObject(
|
|
77520
|
+
const spawnRecord = readJsonObject(join52(sessionDir, "spawn.json"), META_READ_LIMIT);
|
|
77412
77521
|
if (spawnRecord?.kind === "team")
|
|
77413
77522
|
return null;
|
|
77414
|
-
const meta = readJsonObject(
|
|
77523
|
+
const meta = readJsonObject(join52(sessionDir, "meta.json"), META_READ_LIMIT);
|
|
77415
77524
|
if (meta?.kind === "team")
|
|
77416
77525
|
return null;
|
|
77417
77526
|
const partial = meta === null;
|
|
@@ -77426,14 +77535,14 @@ class SessionManager {
|
|
|
77426
77535
|
diskTranscriptPath(meta, uuid) {
|
|
77427
77536
|
const stored = metaString(meta?.transcriptPath) ?? "";
|
|
77428
77537
|
const cwd = metaString(meta?.cwd);
|
|
77429
|
-
if (stored &&
|
|
77538
|
+
if (stored && existsSync35(stored))
|
|
77430
77539
|
return stored;
|
|
77431
77540
|
if (cwd && uuid)
|
|
77432
77541
|
return transcriptPathFor(cwd, uuid, projectsDir(this.parentEnv));
|
|
77433
77542
|
return stored;
|
|
77434
77543
|
}
|
|
77435
77544
|
diskOutput(record, tailLines) {
|
|
77436
|
-
const tail = readTailText(
|
|
77545
|
+
const tail = readTailText(join52(record.sessionDir, "output.log"), OUTPUT_TAIL_BYTES);
|
|
77437
77546
|
const buffer = new ScrollbackBuffer(this.scrollbackCapacity);
|
|
77438
77547
|
if (tail?.text)
|
|
77439
77548
|
buffer.append(dropLeadingFragment(tail));
|
|
@@ -77453,12 +77562,12 @@ class SessionManager {
|
|
|
77453
77562
|
}
|
|
77454
77563
|
diskDiagnostics(record, limit) {
|
|
77455
77564
|
const { sessionDir, info } = record;
|
|
77456
|
-
const eventLogPath =
|
|
77457
|
-
const upstreamErrorLogPath =
|
|
77458
|
-
const outputLogPath =
|
|
77565
|
+
const eventLogPath = join52(sessionDir, "events.jsonl");
|
|
77566
|
+
const upstreamErrorLogPath = join52(sessionDir, "upstream-errors.jsonl");
|
|
77567
|
+
const outputLogPath = join52(sessionDir, "output.log");
|
|
77459
77568
|
const events = readTailLines2(eventLogPath, EVENT_TAIL_BYTES);
|
|
77460
77569
|
const outputTail = readTailText(outputLogPath, OUTPUT_TAIL_BYTES);
|
|
77461
|
-
const screen = readTailText(
|
|
77570
|
+
const screen = readTailText(join52(sessionDir, "screen.txt"), SCREEN_READ_BYTES);
|
|
77462
77571
|
return {
|
|
77463
77572
|
sessionId: info.sessionId,
|
|
77464
77573
|
state: info.state,
|
|
@@ -77695,7 +77804,7 @@ function diskInfo(d) {
|
|
|
77695
77804
|
function diskCaptureSource(v) {
|
|
77696
77805
|
return v === "transcript" || v === "screen" || v === "none" ? v : null;
|
|
77697
77806
|
}
|
|
77698
|
-
var DEFAULT_MAX_SESSIONS = 20, DEFAULT_SCROLLBACK = 2000, DEFAULT_TIMEOUT = 600, MAX_TIMEOUT = 3600, TERMINAL_RETENTION_MS, MAX_TERMINAL_SESSIONS = 50, EVENT_LOG_LIMIT, WAIT_LOG_LIMIT, EVENT_RING_SIZE = 200, EVENT_PREVIEW_CHARS = 800, DEFAULT_EVENT_LIMIT = 40, UPSTREAM_ERROR_TAIL_BYTES, SPAWN_RECORD_SCHEMA = 1, NON_TOOL_ACTIVITY, META_STATUS, STATE_OF_10_4_STATUS, SESSION_ID_RE, META_READ_LIMIT, OUTPUT_TAIL_BYTES, EVENT_TAIL_BYTES, SCREEN_READ_BYTES, NO_TERMINAL_RECORD = "claudish_no_terminal_record", CLAUDISH_NOTE_PREFIX = "[claudish] ", metaString = (v) => typeof v === "string" && v.length > 0 ? v : null, optionalParent = (id) => id ? { parentClaudeSessionId: id } : {}, metaNumber = (v) => typeof v === "number" && Number.isFinite(v) ? v : null, metaReason = (v) => typeof v === "string" && FAILURE_REASONS.includes(v) ? v : null;
|
|
77807
|
+
var DEFAULT_MAX_SESSIONS = 20, DEFAULT_SCROLLBACK = 2000, DEFAULT_TIMEOUT = 600, MAX_TIMEOUT = 3600, TERMINAL_RETENTION_MS, MAX_TERMINAL_SESSIONS = 50, EVENT_LOG_LIMIT, WAIT_LOG_LIMIT, EVENT_RING_SIZE = 200, EVENT_PREVIEW_CHARS = 800, DEFAULT_EVENT_LIMIT = 40, UPSTREAM_ERROR_TAIL_BYTES, SPAWN_RECORD_SCHEMA = 1, INHERITED_SETTINGS = "inherited-settings.json", NON_TOOL_ACTIVITY, META_STATUS, STATE_OF_10_4_STATUS, SESSION_ID_RE, META_READ_LIMIT, OUTPUT_TAIL_BYTES, EVENT_TAIL_BYTES, SCREEN_READ_BYTES, NO_TERMINAL_RECORD = "claudish_no_terminal_record", CLAUDISH_NOTE_PREFIX = "[claudish] ", metaString = (v) => typeof v === "string" && v.length > 0 ? v : null, optionalParent = (id) => id ? { parentClaudeSessionId: id } : {}, metaNumber = (v) => typeof v === "number" && Number.isFinite(v) ? v : null, metaReason = (v) => typeof v === "string" && FAILURE_REASONS.includes(v) ? v : null;
|
|
77699
77808
|
var init_session_manager = __esm(() => {
|
|
77700
77809
|
init_config();
|
|
77701
77810
|
init_upstream_error_capture();
|
|
@@ -77710,6 +77819,7 @@ var init_session_manager = __esm(() => {
|
|
|
77710
77819
|
init_team_orchestrator();
|
|
77711
77820
|
init_team_stats();
|
|
77712
77821
|
init_home_dir();
|
|
77822
|
+
init_inherited_settings();
|
|
77713
77823
|
init_parent_session();
|
|
77714
77824
|
init_scrollback_buffer();
|
|
77715
77825
|
TERMINAL_RETENTION_MS = 30 * 60000;
|
|
@@ -77854,7 +77964,7 @@ var init_progress_heartbeat = __esm(() => {
|
|
|
77854
77964
|
import { spawn as spawn2 } from "child_process";
|
|
77855
77965
|
import { mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync10, writeFileSync as writeFileSync24 } from "fs";
|
|
77856
77966
|
import { tmpdir as tmpdir2 } from "os";
|
|
77857
|
-
import { join as
|
|
77967
|
+
import { join as join53 } from "path";
|
|
77858
77968
|
function claudeCodePrintArgv(model, systemPromptFile) {
|
|
77859
77969
|
const head = [PRINT_FLAGS[0], "--model", model, ...PRINT_FLAGS.slice(1)];
|
|
77860
77970
|
return systemPromptFile !== undefined ? [...head, "--system-prompt-file", systemPromptFile] : [...head, "--system-prompt", ""];
|
|
@@ -77972,13 +78082,13 @@ async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
|
|
|
77972
78082
|
} catch (e) {
|
|
77973
78083
|
throw new Error(`cannot start claudish (${parentEnv.CLAUDISH_BIN?.trim() || "claudish"}): ${e instanceof Error ? e.message : String(e)}`);
|
|
77974
78084
|
}
|
|
77975
|
-
const root = mkdtempSync3(
|
|
78085
|
+
const root = mkdtempSync3(join53(tmpdir2(), "claudish-run-prompt-"));
|
|
77976
78086
|
try {
|
|
77977
|
-
const cwd =
|
|
78087
|
+
const cwd = join53(root, "cwd");
|
|
77978
78088
|
mkdirSync23(cwd, { mode: 448 });
|
|
77979
78089
|
let systemPromptFile;
|
|
77980
78090
|
if (typeof systemPrompt === "string" && systemPrompt.length > 0) {
|
|
77981
|
-
systemPromptFile =
|
|
78091
|
+
systemPromptFile = join53(root, "system-prompt.txt");
|
|
77982
78092
|
writeFileSync24(systemPromptFile, systemPrompt, { mode: 384 });
|
|
77983
78093
|
}
|
|
77984
78094
|
const argv = claudeCodePrintArgv(model, systemPromptFile);
|
|
@@ -78084,14 +78194,14 @@ var init_run_prompt_claude_code = __esm(() => {
|
|
|
78084
78194
|
});
|
|
78085
78195
|
|
|
78086
78196
|
// src/mcp-server.ts
|
|
78087
|
-
import { existsSync as
|
|
78197
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync24, readFileSync as readFileSync35, readdirSync as readdirSync9, writeFileSync as writeFileSync25 } from "fs";
|
|
78088
78198
|
import { homedir as homedir35 } from "os";
|
|
78089
|
-
import { dirname as dirname17, join as
|
|
78199
|
+
import { dirname as dirname17, join as join54, resolve as resolve8 } from "path";
|
|
78090
78200
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
78091
78201
|
async function loadAllModels(forceRefresh = false) {
|
|
78092
|
-
if (!forceRefresh &&
|
|
78202
|
+
if (!forceRefresh && existsSync36(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
78093
78203
|
try {
|
|
78094
|
-
const cacheData = JSON.parse(
|
|
78204
|
+
const cacheData = JSON.parse(readFileSync35(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
|
|
78095
78205
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
78096
78206
|
const ageInDays = (Date.now() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
78097
78207
|
if (ageInDays <= CACHE_MAX_AGE_DAYS) {
|
|
@@ -78109,8 +78219,8 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
78109
78219
|
writeFileSync25(OPENROUTER_MODELS_CACHE_PATH, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
|
|
78110
78220
|
return models;
|
|
78111
78221
|
} catch {
|
|
78112
|
-
if (
|
|
78113
|
-
const cacheData = JSON.parse(
|
|
78222
|
+
if (existsSync36(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
78223
|
+
const cacheData = JSON.parse(readFileSync35(OPENROUTER_MODELS_CACHE_PATH, "utf-8"));
|
|
78114
78224
|
return cacheData.models || [];
|
|
78115
78225
|
}
|
|
78116
78226
|
return [];
|
|
@@ -78926,8 +79036,8 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
78926
79036
|
const promptText = () => {
|
|
78927
79037
|
if (input !== undefined)
|
|
78928
79038
|
return input;
|
|
78929
|
-
const existing =
|
|
78930
|
-
return
|
|
79039
|
+
const existing = join54(resolved, "input.md");
|
|
79040
|
+
return existsSync36(existing) ? readFileSync35(existing, "utf-8") : undefined;
|
|
78931
79041
|
};
|
|
78932
79042
|
switch (mode) {
|
|
78933
79043
|
case "run": {
|
|
@@ -79077,7 +79187,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79077
79187
|
let stderrFull = stderr_snippet || "";
|
|
79078
79188
|
if (error_log_path) {
|
|
79079
79189
|
try {
|
|
79080
|
-
stderrFull =
|
|
79190
|
+
stderrFull = readFileSync35(error_log_path, "utf-8");
|
|
79081
79191
|
} catch {}
|
|
79082
79192
|
}
|
|
79083
79193
|
const sessionData = {};
|
|
@@ -79085,16 +79195,16 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79085
79195
|
const sp = session_path;
|
|
79086
79196
|
for (const file of ["status.json", "manifest.json", "input.md"]) {
|
|
79087
79197
|
try {
|
|
79088
|
-
sessionData[file] =
|
|
79198
|
+
sessionData[file] = readFileSync35(join54(sp, file), "utf-8");
|
|
79089
79199
|
} catch {}
|
|
79090
79200
|
}
|
|
79091
79201
|
try {
|
|
79092
|
-
const errorDir =
|
|
79093
|
-
if (
|
|
79202
|
+
const errorDir = join54(sp, "errors");
|
|
79203
|
+
if (existsSync36(errorDir)) {
|
|
79094
79204
|
for (const f of readdirSync9(errorDir)) {
|
|
79095
79205
|
if (f.endsWith(".log")) {
|
|
79096
79206
|
try {
|
|
79097
|
-
sessionData[`errors/${f}`] =
|
|
79207
|
+
sessionData[`errors/${f}`] = readFileSync35(join54(errorDir, f), "utf-8");
|
|
79098
79208
|
} catch {}
|
|
79099
79209
|
}
|
|
79100
79210
|
}
|
|
@@ -79104,7 +79214,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79104
79214
|
for (const f of readdirSync9(sp)) {
|
|
79105
79215
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
79106
79216
|
try {
|
|
79107
|
-
const content =
|
|
79217
|
+
const content = readFileSync35(join54(sp, f), "utf-8");
|
|
79108
79218
|
sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
|
|
79109
79219
|
} catch {}
|
|
79110
79220
|
}
|
|
@@ -79113,9 +79223,9 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
79113
79223
|
}
|
|
79114
79224
|
let version = "unknown";
|
|
79115
79225
|
try {
|
|
79116
|
-
const pkgPath =
|
|
79117
|
-
if (
|
|
79118
|
-
version = JSON.parse(
|
|
79226
|
+
const pkgPath = join54(__dirname3, "../package.json");
|
|
79227
|
+
if (existsSync36(pkgPath)) {
|
|
79228
|
+
version = JSON.parse(readFileSync35(pkgPath, "utf-8")).version;
|
|
79119
79229
|
}
|
|
79120
79230
|
} catch {}
|
|
79121
79231
|
const report = {
|
|
@@ -79222,6 +79332,10 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
79222
79332
|
work_dir: {
|
|
79223
79333
|
type: "string",
|
|
79224
79334
|
description: "Working directory for the session (default: current directory)"
|
|
79335
|
+
},
|
|
79336
|
+
setup_from: {
|
|
79337
|
+
type: ["string", "null"],
|
|
79338
|
+
description: "Directory whose .claude/settings.json and settings.local.json the session " + "inherits (enabled plugins, permissions, env), so a session in another work_dir " + "keeps the caller's plugins and agents; an explicit path must be an existing " + "directory. Default: the caller's project directory, " + "when work_dir differs from it. null keeps the session on work_dir's own settings only."
|
|
79225
79339
|
}
|
|
79226
79340
|
},
|
|
79227
79341
|
required: ["model"]
|
|
@@ -79237,7 +79351,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
79237
79351
|
const requestedModel = args.model;
|
|
79238
79352
|
const workDir = args.work_dir;
|
|
79239
79353
|
const plan = await prehydrateCredentialsForSpawn([requestedModel], {
|
|
79240
|
-
pin: workDir === undefined ||
|
|
79354
|
+
pin: workDir === undefined || resolve8(workDir) === process.cwd()
|
|
79241
79355
|
});
|
|
79242
79356
|
const parentClaudeSessionId = await parentSessionForCall({
|
|
79243
79357
|
hostPid: sessionManager.hostPid
|
|
@@ -79249,6 +79363,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
79249
79363
|
timeoutSeconds: args.timeout_seconds,
|
|
79250
79364
|
claudishFlags,
|
|
79251
79365
|
cwd: workDir,
|
|
79366
|
+
setupFrom: resolveSetupFrom(args.setup_from, workDir, process.cwd()),
|
|
79252
79367
|
parentClaudeSessionId
|
|
79253
79368
|
});
|
|
79254
79369
|
return {
|
|
@@ -79638,6 +79753,7 @@ var init_mcp_server = __esm(() => {
|
|
|
79638
79753
|
init_output_capture();
|
|
79639
79754
|
init_logger();
|
|
79640
79755
|
init_mcp_session();
|
|
79756
|
+
init_inherited_settings();
|
|
79641
79757
|
init_parent_session();
|
|
79642
79758
|
init_nested_mode();
|
|
79643
79759
|
init_progress_heartbeat();
|
|
@@ -79658,8 +79774,8 @@ var init_mcp_server = __esm(() => {
|
|
|
79658
79774
|
init_team_orchestrator();
|
|
79659
79775
|
__filename3 = fileURLToPath3(import.meta.url);
|
|
79660
79776
|
__dirname3 = dirname17(__filename3);
|
|
79661
|
-
CLAUDISH_CACHE_DIR =
|
|
79662
|
-
OPENROUTER_MODELS_CACHE_PATH =
|
|
79777
|
+
CLAUDISH_CACHE_DIR = join54(homedir35(), ".claudish");
|
|
79778
|
+
OPENROUTER_MODELS_CACHE_PATH = join54(CLAUDISH_CACHE_DIR, "openrouter-models.json");
|
|
79663
79779
|
NEXT_STEP = {
|
|
79664
79780
|
cancelled: "you stopped this slot; nothing is wrong with it. Re-run it if you still want its vote",
|
|
79665
79781
|
timeout: "grid mode only \u2014 magmux ended the pane. The orchestrator has no deadline",
|
|
@@ -79682,7 +79798,7 @@ var init_mcp_server = __esm(() => {
|
|
|
79682
79798
|
});
|
|
79683
79799
|
|
|
79684
79800
|
// src/serve-command.ts
|
|
79685
|
-
import { existsSync as
|
|
79801
|
+
import { existsSync as existsSync37, readFileSync as readFileSync36 } from "fs";
|
|
79686
79802
|
function parseServeArgs(args) {
|
|
79687
79803
|
const out = {};
|
|
79688
79804
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -79701,12 +79817,12 @@ function parseServeArgs(args) {
|
|
|
79701
79817
|
return out;
|
|
79702
79818
|
}
|
|
79703
79819
|
function loadModelMap(path) {
|
|
79704
|
-
if (!
|
|
79820
|
+
if (!existsSync37(path)) {
|
|
79705
79821
|
throw new Error(`--models file not found: ${path}`);
|
|
79706
79822
|
}
|
|
79707
79823
|
let raw;
|
|
79708
79824
|
try {
|
|
79709
|
-
raw =
|
|
79825
|
+
raw = readFileSync36(path, "utf-8");
|
|
79710
79826
|
} catch (e) {
|
|
79711
79827
|
throw new Error(`failed to read --models file ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
79712
79828
|
}
|
|
@@ -79787,9 +79903,9 @@ var init_serve_command = __esm(() => {
|
|
|
79787
79903
|
var HOOKS_AMBIENT_DTS = '// claudish hook types \u2014 written by `claudish hooks init`. Do not edit: run\n// `claudish hooks init` from a newer claudish to refresh it.\n// With this file beside your hook, `import type { HookDefinition } from\n// "claudish/hooks"` type-checks with nothing installed.\ndeclare module "claudish/hooks" {\n /**\n * claudish/hooks \u2014 the public hook contract.\n *\n * Everything a hook author can import lives here, and nothing else does. This\n * file imports nothing from the rest of claudish and has no side effects, so it\n * can be built on its own into `dist/hooks.js` + `dist/hooks.d.ts` and served to\n * user modules as the `claudish/hooks` virtual module (see `loader.ts`).\n *\n * Every internal hooks module takes its types from here, so the contract has a\n * single source.\n *\n * ## Process isolation\n *\n * A hook module\'s top-level state is PER PROCESS. In the interactive launcher,\n * proxy events (`request` \u2026 `responseEnd`, raw) and session events\n * (`sessionStart` \u2026 `sessionEnd`) run in one process. In `create_session` and\n * team children they do not: proxy events run in the pane child, and session\n * events run in the MCP server or the CLI process that drives the pane. Pass\n * per-turn data from a proxy event to `sessionIdle` with `annotateTurn`, never\n * with module variables.\n *\n * ## Execution: a hook chain\n *\n * The hooks of one event run one after another, in effective order. Each hook\'s\n * actions are applied before the next hook is called, so `ctx.request`,\n * `ctx.tool.args` and `ctx.response` show what the earlier hooks did, and\n * `ctx.prior` lists it. A warn-severity or failing hook changes nothing for the\n * next one. Each event has a budget for all its hooks together; a hook\'s timeout\n * is cut to what is left of it.\n *\n * ## Output\n *\n * Log with `ctx.log`. `console.*` and `process.stdout`/`stderr` writes made by a\n * hook are routed to claudish\'s debug log, never to the terminal or the MCP\n * protocol stream.\n */\n export const HOOK_API_VERSION = 1;\n export type Severity = "off" | "warn" | "fix";\n export type HookOrder = "pre" | "normal" | "post";\n /** native = RouteInfo.native true; foreign = RouteInfo.native false; all = both */\n export type RouteScope = "foreign" | "native" | "all";\n export type HostMode = "interactive" | "pane-child" | "serve" | "mcp" | "other";\n export type JsonValue = string | number | boolean | null | ReadonlyArray<JsonValue> | {\n readonly [k: string]: JsonValue;\n };\n export interface HarnessFacts {\n readonly planModeActive: boolean;\n readonly planFilePath?: string;\n readonly planDir?: string;\n /** Claude Code session id from request metadata */\n readonly sessionId?: string;\n /** empty = no listing found, not "no skills" */\n readonly skills?: ReadonlyArray<{\n name: string;\n description: string;\n }>;\n }\n export interface RouteInfo {\n /** bare model name the handler serves, e.g. "glm-5" */\n readonly modelId: string;\n /** claudish provider name, e.g. "openrouter"; "anthropic" for native */\n readonly provider: string;\n /**\n * true when the request is served by the native Anthropic handler, OR when\n * !forceForeignModel && (/^claude[-.]/i.test(modelId) || provider === "anthropic")\n * where forceForeignModel is the provider profile\'s opt-in override. This is the exact\n * rule the plan-mode built-in has always used (a claude-* uid on an aggregator that sets\n * forceForeignModel is foreign).\n */\n readonly native: boolean;\n }\n export interface ClaudeTool {\n name: string;\n description?: string;\n input_schema?: unknown;\n }\n /** A Claude-format content block. Only `text` blocks are editable by closed actions. */\n export type ClaudeContentBlock = {\n type: "text";\n text: string;\n } | {\n type: "tool_use";\n id: string;\n name: string;\n input: unknown;\n } | {\n type: "tool_result";\n tool_use_id: string;\n content?: unknown;\n is_error?: boolean;\n } | {\n type: "thinking";\n thinking: string;\n signature?: string;\n } | {\n type: string;\n [k: string]: unknown;\n };\n export interface ClaudeMessage {\n role: "user" | "assistant";\n content: string | ReadonlyArray<ClaudeContentBlock>;\n }\n /**\n * In `request`, the request as the earlier steps of the hook chain left it. On\n * the response side and in `claims()`, the request chain\'s final view.\n */\n export interface RequestFacts {\n /** as Claude Code asked for it; frozen */\n readonly model: string;\n /** frozen */\n readonly stream: boolean;\n /** system prompt flattened to text, after earlier steps */\n readonly systemText: string;\n /** read-only view after earlier steps; change it through actions */\n readonly messages: ReadonlyArray<ClaudeMessage>;\n /**\n * read-only view after earlier steps; `description` includes earlier description actions as\n * stage B will apply them to the Claude-format tool (the provider copy may be summarised)\n */\n readonly tools: ReadonlyArray<ClaudeTool>;\n }\n /** Which session a proxy event belongs to, when claudish knows. */\n export interface ProxySessionRef {\n readonly kind: SessionKind;\n readonly id: string;\n readonly role: "slot" | "judge" | null;\n }\n /** One action an earlier step of this hook chain applied or handed on. */\n export interface PriorAction {\n readonly hookId: string;\n readonly action: HookAction;\n }\n interface BaseContext {\n readonly hookId: string;\n /** "warn" or "fix" (an "off" hook is never called) */\n readonly severity: Severity;\n /** writes to claudish\'s debug log; never to the terminal */\n log(message: string): void;\n /**\n * this step\'s own signal: aborted when its step timeout elapses (its own timeout, or the\n * event budget left, whichever is shorter) or when the dispatch is aborted. Never shared\n * with another hook\'s step.\n */\n readonly signal: AbortSignal;\n /**\n * actions earlier steps of this hook chain applied (or, for responseEnd/sessionStart/\n * sessionIdle, handed on), in order. Empty for the first step and in claims()/the toolCall\n * predicate. Never lists warn actions or anything a warn-severity hook returned.\n */\n readonly prior: ReadonlyArray<PriorAction>;\n }\n export interface ProxyContext extends BaseContext {\n readonly host: {\n mode: HostMode;\n };\n readonly route: RouteInfo;\n readonly request: RequestFacts;\n readonly harness: HarnessFacts;\n readonly session: ProxySessionRef | null;\n }\n export interface RequestContext extends ProxyContext {\n readonly event: "request";\n }\n export interface ToolCallContext extends ProxyContext {\n readonly event: "toolCall";\n readonly tool: {\n id: string;\n name: string;\n /** the arguments after every repair earlier hooks in the chain applied */\n args: Readonly<Record<string, unknown>>;\n /** the argument JSON exactly as the model produced it; never rewritten */\n rawArgs: string;\n };\n }\n export type ResponseBlock = {\n type: "text";\n text: string;\n } | {\n type: "thinking";\n thinking: string;\n } | {\n type: "tool_use";\n id: string;\n name: string;\n input: unknown;\n } | {\n type: "other";\n blockType: string;\n };\n export interface ResponseView {\n blocks: ReadonlyArray<ResponseBlock>;\n /** every text block, joined with "\\n\\n" */\n text: string;\n /** every thinking block, joined with "\\n\\n" */\n reasoning: string;\n toolNames: ReadonlyArray<string>;\n /** "tool_use" = an intermediate step of a tool loop; the turn continues after the tool runs */\n stopReason: string | null;\n }\n /** response = the held response after every text action earlier hooks in the chain applied */\n export interface ResponseRewriteContext extends ProxyContext {\n readonly event: "responseRewrite";\n readonly response: ResponseView;\n }\n /** response = the final bytes the client received: after any rewrite AND any raw `response` replacement */\n export interface ResponseEndContext extends ProxyContext {\n readonly event: "responseEnd";\n readonly response: ResponseView;\n }\n export type SessionKind = "interactive" | "channel" | "team";\n export interface SessionInfo {\n kind: SessionKind;\n /** team only; null otherwise */\n role: "slot" | "judge" | null;\n /** channel: the 8-hex session_id \xB7 team: "<run_id>:<slot id>" \xB7 interactive: the Claude Code session id */\n id: string;\n claudeSessionId: string | null;\n /** as the caller asked for it */\n model: string;\n cwd: string;\n /** a one-shot session stays "one-shot" through a hook-extended turn chain */\n shape: "interactive" | "one-shot";\n injection: "available" | "unavailable";\n }\n export interface SessionStartContext extends BaseContext {\n readonly event: "sessionStart";\n readonly session: SessionInfo;\n }\n export interface TurnAnnotation {\n hookId: string;\n key: string;\n value: JsonValue;\n }\n export interface SessionIdleContext extends BaseContext {\n readonly event: "sessionIdle";\n readonly session: SessionInfo;\n readonly turn: {\n /** 1-based within the session; a re-woken turn keeps its index */\n index: number;\n /** this turn\'s assistant text */\n answer: string;\n stopReason: string | null;\n apiError: boolean;\n /** this turn was started by an injection */\n hookCaused: boolean;\n /** annotateTurn actions from this turn\'s responses, in arrival order */\n annotations: ReadonlyArray<TurnAnnotation>;\n };\n readonly consecutiveHookTurns: number;\n /** caller/human input is queued; an injection returned now will be dropped as stale */\n readonly callerInputPending: boolean;\n }\n export interface SessionBlockedContext extends BaseContext {\n readonly event: "sessionBlocked";\n readonly session: SessionInfo;\n readonly block: {\n kind: "question" | "permission";\n text: string;\n };\n }\n export interface SessionEndContext extends BaseContext {\n readonly event: "sessionEnd";\n readonly session: SessionInfo;\n readonly outcome: {\n state: string;\n reason: string | null;\n exitCode: number | null;\n };\n }\n type TextMatch = {\n find: string;\n regex?: boolean;\n flags?: string;\n };\n /** default ["user"] */\n type MessageRoles = {\n roles?: ReadonlyArray<"user" | "assistant">;\n };\n export type InjectSystemNote = {\n type: "injectSystemNote";\n text: string;\n };\n export type AppendUserText = {\n type: "appendUserText";\n text: string;\n };\n export type ReplaceMessageText = {\n type: "replaceMessageText";\n replace: string;\n } & TextMatch & MessageRoles;\n export type RemoveMessageText = {\n type: "removeMessageText";\n } & TextMatch & MessageRoles;\n export type RewriteToolDescription = {\n type: "rewriteToolDescription";\n tool: string;\n append: string;\n };\n export type ReplaceToolDescription = {\n type: "replaceToolDescription";\n tool: string;\n description: string;\n };\n export type ReplaceToolSchema = {\n type: "replaceToolSchema";\n tool: string;\n inputSchema: {\n type: "object";\n [k: string]: unknown;\n };\n };\n export type RemoveTool = {\n type: "removeTool";\n tool: string;\n };\n export type RepairToolArgs = {\n type: "repairToolArgs";\n args: Record<string, unknown>;\n reason: string;\n };\n export type AppendText = {\n type: "appendText";\n text: string;\n };\n export type PrependText = {\n type: "prependText";\n text: string;\n };\n export type ReplaceText = {\n type: "replaceText";\n replace: string;\n } & TextMatch;\n export type RemoveText = {\n type: "removeText";\n } & TextMatch;\n export type InjectUserTurn = {\n type: "injectUserTurn";\n text: string;\n };\n export type AnnotateTurn = {\n type: "annotateTurn";\n key: string;\n value: JsonValue;\n };\n export type Warn = {\n type: "warn";\n message: string;\n };\n export type RequestAction = InjectSystemNote | AppendUserText | ReplaceMessageText | RemoveMessageText | RewriteToolDescription | ReplaceToolDescription | ReplaceToolSchema | RemoveTool | Warn;\n export type ToolCallAction = RepairToolArgs | Warn;\n export type RewriteAction = AppendText | PrependText | ReplaceText | RemoveText | Warn;\n export type ResponseEndAction = InjectSystemNote | InjectUserTurn | AnnotateTurn | Warn;\n export type SessionAction = InjectUserTurn | Warn;\n export type ObserveAction = Warn;\n export type HookAction = RequestAction | ToolCallAction | RewriteAction | ResponseEndAction | SessionAction;\n export type HookResult<A> = A[] | void | Promise<A[] | void>;\n export interface HookHandlers {\n request?(ctx: RequestContext): HookResult<RequestAction>;\n toolCall?: {\n /** tool names whose completed arguments this hook sees; "*" = every tool (costs streaming of all tool input) */\n tools: ReadonlyArray<string>;\n /** synchronous, per request; default true. false = not armed for this request */\n armed?(ctx: RequestContext): boolean;\n /** true = see the call after it was forwarded; can only warn; never holds the stream */\n observe?: boolean;\n handle(ctx: ToolCallContext): HookResult<ToolCallAction>;\n };\n responseRewrite?: {\n /** synchronous, per request, evaluated before the response starts; default true */\n claims?(ctx: RequestContext): boolean;\n handle(ctx: ResponseRewriteContext): HookResult<RewriteAction>;\n };\n responseEnd?(ctx: ResponseEndContext): HookResult<ResponseEndAction>;\n sessionStart?(ctx: SessionStartContext): HookResult<SessionAction>;\n sessionIdle?(ctx: SessionIdleContext): HookResult<SessionAction>;\n sessionBlocked?(ctx: SessionBlockedContext): HookResult<ObserveAction>;\n sessionEnd?(ctx: SessionEndContext): HookResult<ObserveAction>;\n }\n export interface RawProviderRequestContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n claudeRequest: any;\n messages: any[];\n tools: any[];\n }\n export interface RawProviderChunkContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n /** A clone of the parsed provider event. Whatever this field holds when the call returns is\n * what the parser reads from then on, so it may be edited in place or replaced. */\n chunk: any;\n /** The delta object inside `chunk` at call time (Responses wire: `chunk` itself). Edit it in\n * place; assigning a new object to this field has no effect. */\n delta: any;\n /** per-stream, shared across this hook\'s chunk calls; never cloned */\n metadata: Map<string, unknown>;\n }\n export interface RawProviderStreamEndContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n metadata: Map<string, unknown>;\n }\n export interface RawResponseContext {\n readonly hookId: string;\n readonly route: RouteInfo;\n readonly request: RequestFacts;\n /** A replay of the current Claude-format response (SSE, or JSON for stream:false), read at the\n * hook\'s own pace. claudish drains the original itself, so leaving this unread delays nothing. */\n response: Response;\n }\n export interface RawMiddleware {\n /**\n * Receives clones. They replace the live request only when this call returns (or its promise\n * resolves) within its timeout. A throw, a rejection or a timeout discards every change.\n */\n providerRequest?(ctx: RawProviderRequestContext): void | Promise<void>;\n /**\n * MUST be synchronous. Called on the parser\'s loop, on a clone of the chunk. On a normal return\n * of anything but a thenable, the clone (whatever `ctx.chunk` holds then) is committed: it\n * becomes the object the parser reads, deletions included. On a throw nothing is committed.\n * A declared `async` function is rejected at load. Any other thenable return is an invalid\n * invocation: the clone is discarded even if the hook mutated it before returning, the call is\n * journaled `invalid` (`async_return`) and counts toward the circuit breaker, and a rejection\n * handler is attached, so a rejection is journaled `error` and never becomes an\n * unhandledRejection.\n */\n providerChunk?(ctx: RawProviderChunkContext): void;\n providerStreamEnd?(ctx: RawProviderStreamEndContext): void | Promise<void>;\n /**\n * Return a replacement Response, or nothing to keep the current one. A replacement is read\n * whole and forwarded only when it completes cleanly; on any failure the original is forwarded.\n * The client never sees a partial replacement. A replacement must close within this hook\'s\n * timeout after the later of this call\'s return and the end of the original; the original\'s end\n * never depends on whether `ctx.response` is read.\n */\n response?(ctx: RawResponseContext): Response | void | Promise<Response | void>;\n }\n interface HookBase {\n apiVersion: 1;\n id: string;\n description?: string;\n /** default "fix" for user hooks */\n defaultSeverity?: Severity;\n /** default "normal" */\n order?: HookOrder;\n /** globs on RouteInfo.modelId; default "*"; proxy events only */\n models?: string | ReadonlyArray<string>;\n /** default "all"; proxy events only */\n routes?: RouteScope;\n /** per call; clamped to the event\'s maximum and to the event budget left when the hook\'s turn comes */\n timeoutMs?: number;\n on?: HookHandlers;\n }\n export interface SafeHook extends HookBase {\n unsafe?: never;\n raw?: never;\n }\n export interface UnsafeHook extends HookBase {\n unsafe: true;\n raw: RawMiddleware;\n }\n /**\n * One hook. Module-level state is per process: in `create_session` and team\n * children, proxy events run in the pane child and session events in the MCP\n * server or CLI process. Pass per-turn data from proxy events to `sessionIdle`\n * with `annotateTurn`, never with module variables.\n */\n export type HookDefinition = SafeHook | UnsafeHook;\n /** Identity function: gives editor type-checking and inference. */\n export function defineHook<const H extends HookDefinition>(hook: H): H;\n /** Action constructors (plain data; equivalent to writing the object literal). */\n export const act: {\n injectSystemNote(text: string): InjectSystemNote;\n appendUserText(text: string): AppendUserText;\n replaceMessageText(find: string, replace: string, opts?: {\n regex?: boolean;\n flags?: string;\n roles?: ReadonlyArray<"user" | "assistant">;\n }): ReplaceMessageText;\n removeMessageText(find: string, opts?: {\n regex?: boolean;\n flags?: string;\n roles?: ReadonlyArray<"user" | "assistant">;\n }): RemoveMessageText;\n rewriteToolDescription(tool: string, append: string): RewriteToolDescription;\n replaceToolDescription(tool: string, description: string): ReplaceToolDescription;\n replaceToolSchema(tool: string, inputSchema: {\n type: "object";\n [k: string]: unknown;\n }): ReplaceToolSchema;\n removeTool(tool: string): RemoveTool;\n repairToolArgs(args: Record<string, unknown>, reason: string): RepairToolArgs;\n appendText(text: string): AppendText;\n prependText(text: string): PrependText;\n replaceText(find: string, replace: string, opts?: {\n regex?: boolean;\n flags?: string;\n }): ReplaceText;\n removeText(find: string, opts?: {\n regex?: boolean;\n flags?: string;\n }): RemoveText;\n injectUserTurn(text: string): InjectUserTurn;\n annotateTurn(key: string, value: JsonValue): AnnotateTurn;\n warn(message: string): Warn;\n };\n}\n';
|
|
79788
79904
|
|
|
79789
79905
|
// src/hooks/observer/corpus.ts
|
|
79790
|
-
import { appendFileSync as appendFileSync8, readFileSync as
|
|
79906
|
+
import { appendFileSync as appendFileSync8, readFileSync as readFileSync37, readdirSync as readdirSync10, statSync as statSync15 } from "fs";
|
|
79791
79907
|
import { homedir as homedir36 } from "os";
|
|
79792
|
-
import { join as
|
|
79908
|
+
import { join as join55 } from "path";
|
|
79793
79909
|
function directoryOf2(filePath) {
|
|
79794
79910
|
const slash = filePath.lastIndexOf("/");
|
|
79795
79911
|
return slash > 0 ? filePath.slice(0, slash) : undefined;
|
|
@@ -79811,7 +79927,7 @@ function writeTargetsOf(row) {
|
|
|
79811
79927
|
function replayTranscript(file) {
|
|
79812
79928
|
let text;
|
|
79813
79929
|
try {
|
|
79814
|
-
text =
|
|
79930
|
+
text = readFileSync37(file, "utf8");
|
|
79815
79931
|
} catch {
|
|
79816
79932
|
return [];
|
|
79817
79933
|
}
|
|
@@ -79868,26 +79984,26 @@ function listTranscripts(root) {
|
|
|
79868
79984
|
return files;
|
|
79869
79985
|
}
|
|
79870
79986
|
for (const project of projects) {
|
|
79871
|
-
const dir =
|
|
79987
|
+
const dir = join55(root, project);
|
|
79872
79988
|
try {
|
|
79873
|
-
if (!
|
|
79989
|
+
if (!statSync15(dir).isDirectory())
|
|
79874
79990
|
continue;
|
|
79875
79991
|
for (const f of readdirSync10(dir)) {
|
|
79876
79992
|
if (f.endsWith(".jsonl"))
|
|
79877
|
-
files.push(
|
|
79993
|
+
files.push(join55(dir, f));
|
|
79878
79994
|
}
|
|
79879
79995
|
} catch {}
|
|
79880
79996
|
}
|
|
79881
79997
|
return files;
|
|
79882
79998
|
}
|
|
79883
79999
|
function buildCorpus(options = {}) {
|
|
79884
|
-
const root = options.projectsRoot ??
|
|
80000
|
+
const root = options.projectsRoot ?? join55(homedir36(), ".claude", "projects");
|
|
79885
80001
|
const files = listTranscripts(root);
|
|
79886
80002
|
const records = [];
|
|
79887
80003
|
for (const f of files)
|
|
79888
80004
|
records.push(...replayTranscript(f));
|
|
79889
80005
|
if (options.write && records.length > 0) {
|
|
79890
|
-
const outputPath = options.outputPath ??
|
|
80006
|
+
const outputPath = options.outputPath ?? join55(homedir36(), ".claudish", "behavior-divergences.jsonl");
|
|
79891
80007
|
try {
|
|
79892
80008
|
appendFileSync8(outputPath, `${records.map((r) => JSON.stringify(r)).join(`
|
|
79893
80009
|
`)}
|
|
@@ -79903,9 +80019,9 @@ var init_corpus = __esm(() => {
|
|
|
79903
80019
|
});
|
|
79904
80020
|
|
|
79905
80021
|
// src/hooks-command.ts
|
|
79906
|
-
import { existsSync as
|
|
80022
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync25, readFileSync as readFileSync38, writeFileSync as writeFileSync26 } from "fs";
|
|
79907
80023
|
import { homedir as homedir37 } from "os";
|
|
79908
|
-
import { join as
|
|
80024
|
+
import { join as join56, resolve as resolve9 } from "path";
|
|
79909
80025
|
function severityColor(sev) {
|
|
79910
80026
|
if (sev === "fix")
|
|
79911
80027
|
return green(sev);
|
|
@@ -79995,7 +80111,7 @@ async function check(file, json) {
|
|
|
79995
80111
|
console.error("Usage: claudish hooks check <file> [--json]");
|
|
79996
80112
|
return 1;
|
|
79997
80113
|
}
|
|
79998
|
-
const path =
|
|
80114
|
+
const path = resolve9(process.cwd(), file);
|
|
79999
80115
|
const notes = [];
|
|
80000
80116
|
const loaded = await loadUserHooks({
|
|
80001
80117
|
modules: [path],
|
|
@@ -80028,12 +80144,12 @@ async function check(file, json) {
|
|
|
80028
80144
|
return valid ? 0 : 1;
|
|
80029
80145
|
}
|
|
80030
80146
|
function init(dirArg) {
|
|
80031
|
-
const dir = dirArg ?
|
|
80147
|
+
const dir = dirArg ? resolve9(process.cwd(), dirArg) : join56(homedir37(), ".claudish", "hooks");
|
|
80032
80148
|
const files = [
|
|
80033
|
-
[
|
|
80034
|
-
[
|
|
80149
|
+
[join56(dir, "example-hook.ts"), EXAMPLE_HOOK],
|
|
80150
|
+
[join56(dir, "claudish-hooks.d.ts"), HOOKS_AMBIENT_DTS]
|
|
80035
80151
|
];
|
|
80036
|
-
const existing = files.filter(([path]) =>
|
|
80152
|
+
const existing = files.filter(([path]) => existsSync38(path)).map(([path]) => path);
|
|
80037
80153
|
if (existing.length > 0) {
|
|
80038
80154
|
for (const path of existing)
|
|
80039
80155
|
console.error(`${path} already exists; not overwriting it.`);
|
|
@@ -80106,8 +80222,8 @@ function setTelemetryEnabled(value) {
|
|
|
80106
80222
|
const path = activeConfigFile();
|
|
80107
80223
|
let cfg = {};
|
|
80108
80224
|
try {
|
|
80109
|
-
if (
|
|
80110
|
-
const parsed = JSON.parse(
|
|
80225
|
+
if (existsSync38(path)) {
|
|
80226
|
+
const parsed = JSON.parse(readFileSync38(path, "utf-8"));
|
|
80111
80227
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
80112
80228
|
cfg = parsed;
|
|
80113
80229
|
}
|
|
@@ -80126,8 +80242,8 @@ function telemetry(action, json) {
|
|
|
80126
80242
|
let pending = 0;
|
|
80127
80243
|
try {
|
|
80128
80244
|
const path = outboxPath();
|
|
80129
|
-
if (
|
|
80130
|
-
pending =
|
|
80245
|
+
if (existsSync38(path))
|
|
80246
|
+
pending = readFileSync38(path, "utf8").split(`
|
|
80131
80247
|
`).filter(Boolean).length;
|
|
80132
80248
|
} catch {}
|
|
80133
80249
|
if (json) {
|
|
@@ -80234,9 +80350,9 @@ var init_hooks_command = __esm(() => {
|
|
|
80234
80350
|
|
|
80235
80351
|
// src/team-grid.ts
|
|
80236
80352
|
import { spawn as spawn3 } from "child_process";
|
|
80237
|
-
import { existsSync as
|
|
80353
|
+
import { existsSync as existsSync39, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "fs";
|
|
80238
80354
|
import { connect as netConnect2 } from "net";
|
|
80239
|
-
import { join as
|
|
80355
|
+
import { join as join57 } from "path";
|
|
80240
80356
|
import { setTimeout as wait } from "timers/promises";
|
|
80241
80357
|
function paneRouteLine(explanation) {
|
|
80242
80358
|
const origin = describeRouteExplanation(explanation);
|
|
@@ -80291,7 +80407,7 @@ function withoutControlPanes(evt) {
|
|
|
80291
80407
|
async function subscribeToMagmux(sockPath, onEvent) {
|
|
80292
80408
|
let client = null;
|
|
80293
80409
|
for (let attempt = 0;attempt < 40; attempt++) {
|
|
80294
|
-
if (
|
|
80410
|
+
if (existsSync39(sockPath)) {
|
|
80295
80411
|
try {
|
|
80296
80412
|
client = await new Promise((resolve, reject) => {
|
|
80297
80413
|
const s = netConnect2(sockPath);
|
|
@@ -80386,9 +80502,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
80386
80502
|
const keep = opts?.keep ?? false;
|
|
80387
80503
|
const manifest = setupSession(sessionPath, models, input);
|
|
80388
80504
|
const startedAt = new Date().toISOString();
|
|
80389
|
-
const gridfilePath =
|
|
80390
|
-
const prompt =
|
|
80391
|
-
const rawPrompt =
|
|
80505
|
+
const gridfilePath = join57(sessionPath, "gridfile.txt");
|
|
80506
|
+
const prompt = readFileSync39(join57(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
80507
|
+
const rawPrompt = readFileSync39(join57(sessionPath, "input.md"), "utf-8");
|
|
80392
80508
|
const usedBannerColors = new Set;
|
|
80393
80509
|
const routeLines = mode === "interactive" ? new Map : await resolvePaneRouteLines(Object.values(manifest.models).map((entry) => entry.model));
|
|
80394
80510
|
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
@@ -80420,7 +80536,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
80420
80536
|
});
|
|
80421
80537
|
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
80422
80538
|
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
80423
|
-
const statusPath =
|
|
80539
|
+
const statusPath = join57(sessionPath, "status.json");
|
|
80424
80540
|
writeFileSync27(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
80425
80541
|
return status;
|
|
80426
80542
|
}
|
|
@@ -80440,8 +80556,8 @@ var init_team_grid = __esm(() => {
|
|
|
80440
80556
|
});
|
|
80441
80557
|
|
|
80442
80558
|
// src/team-cli.ts
|
|
80443
|
-
import { readFileSync as
|
|
80444
|
-
import { join as
|
|
80559
|
+
import { readFileSync as readFileSync40 } from "fs";
|
|
80560
|
+
import { join as join58 } from "path";
|
|
80445
80561
|
async function runPaneTeam(sessionPath, models, input, opts) {
|
|
80446
80562
|
installPaneShutdownHooks({ exitAfter: true });
|
|
80447
80563
|
try {
|
|
@@ -80586,7 +80702,7 @@ async function teamCommand(args) {
|
|
|
80586
80702
|
}
|
|
80587
80703
|
case "judge": {
|
|
80588
80704
|
await judgeResponses(sessionPath, { judges });
|
|
80589
|
-
console.log(
|
|
80705
|
+
console.log(readFileSync40(join58(sessionPath, "verdict.md"), "utf-8"));
|
|
80590
80706
|
break;
|
|
80591
80707
|
}
|
|
80592
80708
|
case "run-and-judge": {
|
|
@@ -80602,7 +80718,7 @@ async function teamCommand(args) {
|
|
|
80602
80718
|
});
|
|
80603
80719
|
printStatus(status);
|
|
80604
80720
|
await judgeResponses(sessionPath, { judges });
|
|
80605
|
-
console.log(
|
|
80721
|
+
console.log(readFileSync40(join58(sessionPath, "verdict.md"), "utf-8"));
|
|
80606
80722
|
break;
|
|
80607
80723
|
}
|
|
80608
80724
|
case "status": {
|
|
@@ -81557,9 +81673,9 @@ var init_subscription_models_command = __esm(() => {
|
|
|
81557
81673
|
|
|
81558
81674
|
// src/auth/antigravity-oauth.ts
|
|
81559
81675
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
81560
|
-
import { existsSync as
|
|
81676
|
+
import { existsSync as existsSync40, unlinkSync as unlinkSync9 } from "fs";
|
|
81561
81677
|
import { homedir as homedir38 } from "os";
|
|
81562
|
-
import { join as
|
|
81678
|
+
import { join as join59 } from "path";
|
|
81563
81679
|
async function defaultSuggestModel() {
|
|
81564
81680
|
try {
|
|
81565
81681
|
const token = await getValidAntigravityAccessToken();
|
|
@@ -81678,8 +81794,8 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
|
|
|
81678
81794
|
async logout(deps) {
|
|
81679
81795
|
deleteSharedAntigravityToken(deps);
|
|
81680
81796
|
try {
|
|
81681
|
-
const tokenFile =
|
|
81682
|
-
if (
|
|
81797
|
+
const tokenFile = join59(homedir38(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
|
|
81798
|
+
if (existsSync40(tokenFile))
|
|
81683
81799
|
unlinkSync9(tokenFile);
|
|
81684
81800
|
} catch {}
|
|
81685
81801
|
log("[AntigravityOAuth] Antigravity session cleared (keychain + agy token file)");
|
|
@@ -89825,8 +89941,8 @@ var init_own_pane = __esm(() => {
|
|
|
89825
89941
|
});
|
|
89826
89942
|
|
|
89827
89943
|
// src/hooks/session/interactive-driver.ts
|
|
89828
|
-
import { existsSync as
|
|
89829
|
-
import { join as
|
|
89944
|
+
import { existsSync as existsSync41, statSync as statSync16 } from "fs";
|
|
89945
|
+
import { join as join60 } from "path";
|
|
89830
89946
|
function nextDriverPhase(phase, ev) {
|
|
89831
89947
|
const row = EDGES[phase];
|
|
89832
89948
|
return row[ev] ?? null;
|
|
@@ -90044,7 +90160,7 @@ class InteractiveDriver {
|
|
|
90044
90160
|
}
|
|
90045
90161
|
follow(sid, offset) {
|
|
90046
90162
|
const path = transcriptPathFor(this.o.cwd, sid, this.o.projectsRoot);
|
|
90047
|
-
this.follower = new TranscriptFollower(path,
|
|
90163
|
+
this.follower = new TranscriptFollower(path, join60(path.replace(/\.jsonl$/, ""), "subagents"));
|
|
90048
90164
|
this.sessionId = sid;
|
|
90049
90165
|
this.settledTurn = null;
|
|
90050
90166
|
this.lastPollAt = Date.now();
|
|
@@ -90065,7 +90181,7 @@ class InteractiveDriver {
|
|
|
90065
90181
|
if (!p)
|
|
90066
90182
|
return;
|
|
90067
90183
|
const path = transcriptPathFor(this.o.cwd, p.id, this.o.projectsRoot);
|
|
90068
|
-
if (!
|
|
90184
|
+
if (!existsSync41(path)) {
|
|
90069
90185
|
if (Date.now() - p.since > RETARGET_WAIT_MS) {
|
|
90070
90186
|
log(`[hooks] interactive driver: no transcript for session ${p.id}; not following it`);
|
|
90071
90187
|
this.pendingSid = null;
|
|
@@ -90589,7 +90705,7 @@ function assertNeverPhase(p) {
|
|
|
90589
90705
|
}
|
|
90590
90706
|
function fileSizeOf(path) {
|
|
90591
90707
|
try {
|
|
90592
|
-
return
|
|
90708
|
+
return statSync16(path).size;
|
|
90593
90709
|
} catch {
|
|
90594
90710
|
return 0;
|
|
90595
90711
|
}
|
|
@@ -90734,14 +90850,14 @@ var init_no_surface = __esm(() => {
|
|
|
90734
90850
|
var UI_LEASE_MS = 1e4, FRAME_TICK_MS = 1000;
|
|
90735
90851
|
|
|
90736
90852
|
// src/recovery/magmux-ui.ts
|
|
90737
|
-
import { existsSync as
|
|
90853
|
+
import { existsSync as existsSync42 } from "fs";
|
|
90738
90854
|
import { connect as netConnect3 } from "net";
|
|
90739
90855
|
function resolveControlEndpoint() {
|
|
90740
|
-
if (explicitControlSock &&
|
|
90856
|
+
if (explicitControlSock && existsSync42(explicitControlSock)) {
|
|
90741
90857
|
return { sock: explicitControlSock, wrapped: true };
|
|
90742
90858
|
}
|
|
90743
90859
|
const ambient = process.env.MAGMUX_SOCK;
|
|
90744
|
-
if (ambient &&
|
|
90860
|
+
if (ambient && existsSync42(ambient))
|
|
90745
90861
|
return { sock: ambient, wrapped: false };
|
|
90746
90862
|
return null;
|
|
90747
90863
|
}
|
|
@@ -91147,19 +91263,19 @@ import { randomUUID as randomUUID8 } from "crypto";
|
|
|
91147
91263
|
import {
|
|
91148
91264
|
chmodSync as chmodSync4,
|
|
91149
91265
|
closeSync as closeSync12,
|
|
91150
|
-
existsSync as
|
|
91266
|
+
existsSync as existsSync43,
|
|
91151
91267
|
mkdirSync as mkdirSync26,
|
|
91152
91268
|
mkdtempSync as mkdtempSync4,
|
|
91153
91269
|
openSync as openSync12,
|
|
91154
|
-
readFileSync as
|
|
91270
|
+
readFileSync as readFileSync41,
|
|
91155
91271
|
readdirSync as readdirSync11,
|
|
91156
91272
|
rmSync as rmSync11,
|
|
91157
|
-
statSync as
|
|
91273
|
+
statSync as statSync17,
|
|
91158
91274
|
unlinkSync as unlinkSync10,
|
|
91159
91275
|
writeFileSync as writeFileSync28
|
|
91160
91276
|
} from "fs";
|
|
91161
91277
|
import { homedir as homedir39, tmpdir as tmpdir3 } from "os";
|
|
91162
|
-
import { dirname as dirname18, join as
|
|
91278
|
+
import { dirname as dirname18, join as join61 } from "path";
|
|
91163
91279
|
import { isatty } from "tty";
|
|
91164
91280
|
function releaseTerminalIsolation() {
|
|
91165
91281
|
if (!restoreTerminal)
|
|
@@ -91226,12 +91342,12 @@ function isRealAnthropicEnvCredential(env, name) {
|
|
|
91226
91342
|
}
|
|
91227
91343
|
function hasResolvableAnthropicAuth(deps = {}) {
|
|
91228
91344
|
const env = deps.env ?? process.env;
|
|
91229
|
-
const fileExists = deps.fileExists ??
|
|
91345
|
+
const fileExists = deps.fileExists ?? existsSync43;
|
|
91230
91346
|
const keychainProbe = deps.keychainProbe ?? defaultKeychainAnthropicProbe;
|
|
91231
91347
|
if (isRealAnthropicEnvCredential(env, "ANTHROPIC_API_KEY") || isRealAnthropicEnvCredential(env, "ANTHROPIC_AUTH_TOKEN")) {
|
|
91232
91348
|
return true;
|
|
91233
91349
|
}
|
|
91234
|
-
if (fileExists(
|
|
91350
|
+
if (fileExists(join61(homedir39(), ".claude", ".credentials.json")))
|
|
91235
91351
|
return true;
|
|
91236
91352
|
return keychainProbe();
|
|
91237
91353
|
}
|
|
@@ -91246,14 +91362,14 @@ function isProxyAuthMode(config) {
|
|
|
91246
91362
|
}
|
|
91247
91363
|
function managedSettingsPath() {
|
|
91248
91364
|
if (isWindows2()) {
|
|
91249
|
-
return
|
|
91365
|
+
return join61(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
|
|
91250
91366
|
}
|
|
91251
91367
|
if (process.platform === "darwin") {
|
|
91252
91368
|
return "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
91253
91369
|
}
|
|
91254
91370
|
return "/etc/claude-code/managed-settings.json";
|
|
91255
91371
|
}
|
|
91256
|
-
function managedSettingsForcesClaudeAi(readFile =
|
|
91372
|
+
function managedSettingsForcesClaudeAi(readFile = readFileSync41) {
|
|
91257
91373
|
try {
|
|
91258
91374
|
const raw = readFile(managedSettingsPath(), "utf-8");
|
|
91259
91375
|
const parsed = JSON.parse(raw);
|
|
@@ -91267,9 +91383,9 @@ function isWindows2() {
|
|
|
91267
91383
|
}
|
|
91268
91384
|
function createStatusLineScript(tokenFilePath) {
|
|
91269
91385
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir3();
|
|
91270
|
-
const claudishDir =
|
|
91386
|
+
const claudishDir = join61(homeDir, ".claudish");
|
|
91271
91387
|
const timestamp = Date.now();
|
|
91272
|
-
const scriptPath =
|
|
91388
|
+
const scriptPath = join61(claudishDir, `status-${timestamp}.js`);
|
|
91273
91389
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
91274
91390
|
const light = getThemeMode() === "light";
|
|
91275
91391
|
const cyanCode = light ? "38;2;14;116;144" : "96";
|
|
@@ -91439,9 +91555,9 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
|
|
|
91439
91555
|
if (!name.startsWith("tokens-") || !name.endsWith(".json"))
|
|
91440
91556
|
continue;
|
|
91441
91557
|
scanned++;
|
|
91442
|
-
const full =
|
|
91558
|
+
const full = join61(dir, name);
|
|
91443
91559
|
try {
|
|
91444
|
-
if (
|
|
91560
|
+
if (statSync17(full).mtimeMs >= cutoff)
|
|
91445
91561
|
continue;
|
|
91446
91562
|
unlinkSync10(full);
|
|
91447
91563
|
removed++;
|
|
@@ -91456,7 +91572,7 @@ function parseSettingsArg(value) {
|
|
|
91456
91572
|
if (value.trimStart().startsWith("{")) {
|
|
91457
91573
|
return JSON.parse(value);
|
|
91458
91574
|
}
|
|
91459
|
-
return JSON.parse(
|
|
91575
|
+
return JSON.parse(readFileSync41(value, "utf-8"));
|
|
91460
91576
|
}
|
|
91461
91577
|
function parseSettingsArgSafe(value) {
|
|
91462
91578
|
try {
|
|
@@ -91468,13 +91584,13 @@ function parseSettingsArgSafe(value) {
|
|
|
91468
91584
|
}
|
|
91469
91585
|
function userSettingsFileCandidates(cwd) {
|
|
91470
91586
|
return [
|
|
91471
|
-
|
|
91472
|
-
|
|
91473
|
-
|
|
91587
|
+
join61(homedir39(), ".claude", "settings.json"),
|
|
91588
|
+
join61(cwd, ".claude", "settings.json"),
|
|
91589
|
+
join61(cwd, ".claude", "settings.local.json")
|
|
91474
91590
|
];
|
|
91475
91591
|
}
|
|
91476
91592
|
function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
|
|
91477
|
-
const sources = userSettingsFileCandidates(cwd).filter((file) =>
|
|
91593
|
+
const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync43(file));
|
|
91478
91594
|
const idx = claudeArgs.indexOf("--settings");
|
|
91479
91595
|
const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
|
|
91480
91596
|
if (settingsArg)
|
|
@@ -91511,12 +91627,12 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
|
|
|
91511
91627
|
}
|
|
91512
91628
|
function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
|
|
91513
91629
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir3();
|
|
91514
|
-
const claudishDir =
|
|
91630
|
+
const claudishDir = join61(homeDir, ".claudish");
|
|
91515
91631
|
try {
|
|
91516
91632
|
mkdirSync26(claudishDir, { recursive: true });
|
|
91517
91633
|
} catch {}
|
|
91518
91634
|
const timestamp = Date.now();
|
|
91519
|
-
const tempPath =
|
|
91635
|
+
const tempPath = join61(claudishDir, `settings-${timestamp}.json`);
|
|
91520
91636
|
const assignedFile = assignedTokenFile(process.env) !== null;
|
|
91521
91637
|
const tokenFilePath = resolveTokenFilePath(port);
|
|
91522
91638
|
cleanupStaleTokenFiles(claudishDir);
|
|
@@ -91669,13 +91785,13 @@ function resolveAdvisorToolEnv(config, processEnv = process.env) {
|
|
|
91669
91785
|
return { vars: { [ADVISOR_TOOL_ENV_VAR]: "1" }, source: "claudish" };
|
|
91670
91786
|
}
|
|
91671
91787
|
function discoverUserAdvisorModel(claudeArgs = [], cwd = process.cwd()) {
|
|
91672
|
-
const sources = userSettingsFileCandidates(cwd).filter((file) =>
|
|
91788
|
+
const sources = userSettingsFileCandidates(cwd).filter((file) => existsSync43(file));
|
|
91673
91789
|
const idx = claudeArgs.indexOf("--settings");
|
|
91674
91790
|
const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
|
|
91675
91791
|
if (settingsArg)
|
|
91676
91792
|
sources.push(settingsArg);
|
|
91677
91793
|
const managed = managedSettingsPath();
|
|
91678
|
-
if (
|
|
91794
|
+
if (existsSync43(managed))
|
|
91679
91795
|
sources.push(managed);
|
|
91680
91796
|
let effective;
|
|
91681
91797
|
for (const source of sources) {
|
|
@@ -91896,7 +92012,7 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
|
|
|
91896
92012
|
console.error(`
|
|
91897
92013
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
91898
92014
|
const home = homedir39();
|
|
91899
|
-
const localPath = isWindows2() ?
|
|
92015
|
+
const localPath = isWindows2() ? join61(home, ".claude", "local", "claude.exe") : join61(home, ".claude", "local", "claude");
|
|
91900
92016
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
91901
92017
|
process.exit(1);
|
|
91902
92018
|
}
|
|
@@ -91931,7 +92047,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
91931
92047
|
let driverLaunch = null;
|
|
91932
92048
|
if (surfaces.driver) {
|
|
91933
92049
|
const minted = sessionFlags.sessionId || sessionFlags.resumes ? null : randomUUID8();
|
|
91934
|
-
const turnDir = mkdtempSync4(
|
|
92050
|
+
const turnDir = mkdtempSync4(join61(tmpdir3(), "claudish-turns-"));
|
|
91935
92051
|
chmodSync4(turnDir, 448);
|
|
91936
92052
|
claudeArgs.unshift(...driverLeadingArgs({ mintedSessionId: minted, turnDir }));
|
|
91937
92053
|
const sink = new InProcessSink;
|
|
@@ -92075,23 +92191,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
92075
92191
|
async function findClaudeBinary() {
|
|
92076
92192
|
const isWindows = process.platform === "win32";
|
|
92077
92193
|
if (process.env.CLAUDE_PATH) {
|
|
92078
|
-
if (
|
|
92194
|
+
if (existsSync43(process.env.CLAUDE_PATH)) {
|
|
92079
92195
|
return process.env.CLAUDE_PATH;
|
|
92080
92196
|
}
|
|
92081
92197
|
}
|
|
92082
92198
|
const home = homedir39();
|
|
92083
|
-
const localPath = isWindows ?
|
|
92084
|
-
if (
|
|
92199
|
+
const localPath = isWindows ? join61(home, ".claude", "local", "claude.exe") : join61(home, ".claude", "local", "claude");
|
|
92200
|
+
if (existsSync43(localPath)) {
|
|
92085
92201
|
return localPath;
|
|
92086
92202
|
}
|
|
92087
92203
|
if (isWindows) {
|
|
92088
92204
|
const windowsPaths = [
|
|
92089
|
-
|
|
92090
|
-
|
|
92091
|
-
|
|
92205
|
+
join61(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
92206
|
+
join61(home, ".npm-global", "claude.cmd"),
|
|
92207
|
+
join61(home, "node_modules", ".bin", "claude.cmd")
|
|
92092
92208
|
];
|
|
92093
92209
|
for (const path of windowsPaths) {
|
|
92094
|
-
if (
|
|
92210
|
+
if (existsSync43(path)) {
|
|
92095
92211
|
return path;
|
|
92096
92212
|
}
|
|
92097
92213
|
}
|
|
@@ -92099,14 +92215,14 @@ async function findClaudeBinary() {
|
|
|
92099
92215
|
const commonPaths = [
|
|
92100
92216
|
"/usr/local/bin/claude",
|
|
92101
92217
|
"/opt/homebrew/bin/claude",
|
|
92102
|
-
|
|
92103
|
-
|
|
92104
|
-
|
|
92218
|
+
join61(home, ".npm-global/bin/claude"),
|
|
92219
|
+
join61(home, ".local/bin/claude"),
|
|
92220
|
+
join61(home, "node_modules/.bin/claude"),
|
|
92105
92221
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
92106
|
-
|
|
92222
|
+
join61(home, "../usr/bin/claude")
|
|
92107
92223
|
];
|
|
92108
92224
|
for (const path of commonPaths) {
|
|
92109
|
-
if (
|
|
92225
|
+
if (existsSync43(path)) {
|
|
92110
92226
|
return path;
|
|
92111
92227
|
}
|
|
92112
92228
|
}
|
|
@@ -92196,16 +92312,16 @@ var init_claude_runner = __esm(() => {
|
|
|
92196
92312
|
// src/diag-output.ts
|
|
92197
92313
|
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync27, unlinkSync as unlinkSync11, writeFileSync as writeFileSync29 } from "fs";
|
|
92198
92314
|
import { homedir as homedir40 } from "os";
|
|
92199
|
-
import { join as
|
|
92315
|
+
import { join as join62 } from "path";
|
|
92200
92316
|
function getClaudishDir() {
|
|
92201
|
-
const dir =
|
|
92317
|
+
const dir = join62(homedir40(), ".claudish");
|
|
92202
92318
|
try {
|
|
92203
92319
|
mkdirSync27(dir, { recursive: true });
|
|
92204
92320
|
} catch {}
|
|
92205
92321
|
return dir;
|
|
92206
92322
|
}
|
|
92207
92323
|
function getDiagLogPath() {
|
|
92208
|
-
return
|
|
92324
|
+
return join62(getClaudishDir(), `diag-${process.pid}.log`);
|
|
92209
92325
|
}
|
|
92210
92326
|
|
|
92211
92327
|
class LogFileDiagOutput {
|
|
@@ -92741,7 +92857,7 @@ var init_advisor_startup = __esm(() => {
|
|
|
92741
92857
|
});
|
|
92742
92858
|
|
|
92743
92859
|
// src/session/conversation.ts
|
|
92744
|
-
import { closeSync as closeSync13, openSync as openSync13, readSync as readSync7, statSync as
|
|
92860
|
+
import { closeSync as closeSync13, openSync as openSync13, readSync as readSync7, statSync as statSync18 } from "fs";
|
|
92745
92861
|
import { StringDecoder } from "string_decoder";
|
|
92746
92862
|
function looksLikeTurn(line) {
|
|
92747
92863
|
const assistant = line.includes('"type":"assistant"');
|
|
@@ -92796,7 +92912,7 @@ function readConversation(file, opts = {}) {
|
|
|
92796
92912
|
};
|
|
92797
92913
|
let fd = null;
|
|
92798
92914
|
try {
|
|
92799
|
-
const size =
|
|
92915
|
+
const size = statSync18(file).size;
|
|
92800
92916
|
fd = openSync13(file, "r");
|
|
92801
92917
|
const buf = Buffer.allocUnsafe(chunkBytes);
|
|
92802
92918
|
const decoder = new StringDecoder("utf-8");
|
|
@@ -94455,11 +94571,11 @@ var exports_session_stats = {};
|
|
|
94455
94571
|
__export(exports_session_stats, {
|
|
94456
94572
|
readSessionStats: () => readSessionStats
|
|
94457
94573
|
});
|
|
94458
|
-
import { readFileSync as
|
|
94574
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
94459
94575
|
function readSessionStats(port, opts) {
|
|
94460
94576
|
let raw;
|
|
94461
94577
|
try {
|
|
94462
|
-
raw = JSON.parse(
|
|
94578
|
+
raw = JSON.parse(readFileSync42(resolveTokenFilePath(port), "utf-8"));
|
|
94463
94579
|
} catch {
|
|
94464
94580
|
return null;
|
|
94465
94581
|
}
|
|
@@ -94837,8 +94953,8 @@ init_launch_env();
|
|
|
94837
94953
|
init_op_source();
|
|
94838
94954
|
init_startup_trace();
|
|
94839
94955
|
init_picker_cancelled();
|
|
94840
|
-
import { existsSync as
|
|
94841
|
-
import { join as
|
|
94956
|
+
import { existsSync as existsSync44, readFileSync as readFileSync43 } from "fs";
|
|
94957
|
+
import { join as join63, resolve as resolve10 } from "path";
|
|
94842
94958
|
|
|
94843
94959
|
// src/tui/runtime/should-open-picker.ts
|
|
94844
94960
|
function noModelConfigured(gate) {
|
|
@@ -94855,7 +94971,7 @@ function requiresExplicitModel(gate, tty) {
|
|
|
94855
94971
|
var autoloadDropped = [...droppedAtLaunch, ...takeLauncherDropped(process.env)];
|
|
94856
94972
|
var dotenvText;
|
|
94857
94973
|
try {
|
|
94858
|
-
dotenvText =
|
|
94974
|
+
dotenvText = readFileSync43(join63(process.cwd(), ".env"));
|
|
94859
94975
|
} catch {}
|
|
94860
94976
|
if (dotenvText !== undefined) {
|
|
94861
94977
|
await Promise.resolve().then(() => init_dotenv_allowlist());
|
|
@@ -94970,8 +95086,8 @@ async function applyOpImport() {
|
|
|
94970
95086
|
async function applyConfigOverride() {
|
|
94971
95087
|
await Promise.resolve();
|
|
94972
95088
|
const plan = planConfigOverride(process.argv.slice(2), process.env, {
|
|
94973
|
-
resolve:
|
|
94974
|
-
exists:
|
|
95089
|
+
resolve: resolve10,
|
|
95090
|
+
exists: existsSync44
|
|
94975
95091
|
});
|
|
94976
95092
|
if (plan.kind === "none")
|
|
94977
95093
|
return;
|
|
@@ -95176,14 +95292,14 @@ async function runCli() {
|
|
|
95176
95292
|
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
95177
95293
|
let prompt = cliConfig.claudeArgs.join(" ");
|
|
95178
95294
|
if (cliConfig.inputFile) {
|
|
95179
|
-
prompt =
|
|
95295
|
+
prompt = readFileSync43(cliConfig.inputFile, "utf-8");
|
|
95180
95296
|
}
|
|
95181
95297
|
if (!prompt.trim()) {
|
|
95182
95298
|
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
95183
95299
|
process.exit(1);
|
|
95184
95300
|
}
|
|
95185
95301
|
const mode = cliConfig.teamMode ?? "default";
|
|
95186
|
-
const sessionPath =
|
|
95302
|
+
const sessionPath = join63(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
95187
95303
|
if (mode === "json") {
|
|
95188
95304
|
await Promise.resolve().then(() => init_pane());
|
|
95189
95305
|
await Promise.resolve().then(() => init_team_orchestrator());
|
|
@@ -95203,9 +95319,9 @@ async function runCli() {
|
|
|
95203
95319
|
const status = await runModels(sessionPath);
|
|
95204
95320
|
const result = { ...status, responses: {} };
|
|
95205
95321
|
for (const anonId of Object.keys(status.models)) {
|
|
95206
|
-
const responsePath =
|
|
95322
|
+
const responsePath = join63(sessionPath, `response-${anonId}.md`);
|
|
95207
95323
|
try {
|
|
95208
|
-
const raw =
|
|
95324
|
+
const raw = readFileSync43(responsePath, "utf-8").trim();
|
|
95209
95325
|
try {
|
|
95210
95326
|
result.responses[anonId] = JSON.parse(raw);
|
|
95211
95327
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.4.0",
|
|
4
4
|
"description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"ai"
|
|
70
70
|
],
|
|
71
71
|
"optionalDependencies": {
|
|
72
|
-
"@claudish/magmux-darwin-arm64": "13.
|
|
73
|
-
"@claudish/magmux-darwin-x64": "13.
|
|
74
|
-
"@claudish/magmux-linux-arm64": "13.
|
|
75
|
-
"@claudish/magmux-linux-x64": "13.
|
|
72
|
+
"@claudish/magmux-darwin-arm64": "13.4.0",
|
|
73
|
+
"@claudish/magmux-darwin-x64": "13.4.0",
|
|
74
|
+
"@claudish/magmux-linux-arm64": "13.4.0",
|
|
75
|
+
"@claudish/magmux-linux-x64": "13.4.0"
|
|
76
76
|
},
|
|
77
77
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
78
78
|
"license": "MIT",
|