claudish 10.6.3 → 10.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI_AGENT_GUIDE.md +13 -5
- package/dist/index.js +688 -464
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -901,7 +901,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
901
901
|
});
|
|
902
902
|
|
|
903
903
|
// src/version.ts
|
|
904
|
-
var VERSION = "10.
|
|
904
|
+
var VERSION = "10.7.1";
|
|
905
905
|
|
|
906
906
|
// src/logger.ts
|
|
907
907
|
import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -18828,6 +18828,10 @@ function lookupModelReasoningStatus(modelId, cachePath) {
|
|
|
18828
18828
|
const entry = findCacheEntry(modelId, cachePath);
|
|
18829
18829
|
return entry ? reasoningStatusOf(entry) : undefined;
|
|
18830
18830
|
}
|
|
18831
|
+
function lookupModelMaxOutputTokens(modelId, cachePath) {
|
|
18832
|
+
const value = findCacheEntry(modelId, cachePath)?.maxOutputTokens;
|
|
18833
|
+
return typeof value === "number" && value > 0 ? value : undefined;
|
|
18834
|
+
}
|
|
18831
18835
|
function lookupRouteReasoningMode(modelId, provider, cachePath) {
|
|
18832
18836
|
return findCacheEntry(modelId, cachePath)?.aggregators?.find((aggregator) => catalogRouteMatchesProvider(aggregator.route, provider))?.reasoning?.mode;
|
|
18833
18837
|
}
|
|
@@ -20945,6 +20949,7 @@ ${merged}`;
|
|
|
20945
20949
|
var AnthropicAPIFormat;
|
|
20946
20950
|
var init_anthropic_api_format = __esm(() => {
|
|
20947
20951
|
init_base_api_format();
|
|
20952
|
+
init_model_catalog();
|
|
20948
20953
|
AnthropicAPIFormat = class AnthropicAPIFormat extends BaseAPIFormat {
|
|
20949
20954
|
constructor(modelId, _providerName) {
|
|
20950
20955
|
super(modelId);
|
|
@@ -20985,14 +20990,24 @@ var init_anthropic_api_format = __esm(() => {
|
|
|
20985
20990
|
convertTools(claudeRequest, _summarize) {
|
|
20986
20991
|
return claudeRequest.tools || [];
|
|
20987
20992
|
}
|
|
20993
|
+
outputLimitFor(claudeRequest) {
|
|
20994
|
+
const inbound = claudeRequest?.max_tokens;
|
|
20995
|
+
if (typeof inbound === "number")
|
|
20996
|
+
return inbound;
|
|
20997
|
+
if (this.modelId.includes("@"))
|
|
20998
|
+
return;
|
|
20999
|
+
return lookupModelMaxOutputTokens(this.modelId);
|
|
21000
|
+
}
|
|
20988
21001
|
buildPayload(claudeRequest, messages, tools) {
|
|
20989
21002
|
const { messages: cleanMessages, hoisted } = hoistInlineSystem(messages);
|
|
20990
21003
|
const payload = {
|
|
20991
21004
|
model: this.modelId,
|
|
20992
21005
|
messages: cleanMessages,
|
|
20993
|
-
max_tokens: claudeRequest.max_tokens || 4096,
|
|
20994
21006
|
stream: true
|
|
20995
21007
|
};
|
|
21008
|
+
const maxTokens = this.outputLimitFor(claudeRequest);
|
|
21009
|
+
if (maxTokens !== undefined)
|
|
21010
|
+
payload.max_tokens = maxTokens;
|
|
20996
21011
|
const system = mergeSystem(claudeRequest.system, hoisted);
|
|
20997
21012
|
if (system !== undefined) {
|
|
20998
21013
|
payload.system = system;
|
|
@@ -31135,6 +31150,7 @@ function resolveConnection(provider, modelName, cachePath = ALL_MODELS_CACHE_PAT
|
|
|
31135
31150
|
wire: found.connection.wire,
|
|
31136
31151
|
profile,
|
|
31137
31152
|
generationId: cache.routeRegistry.generationId,
|
|
31153
|
+
...typeof found.entry.maxOutputTokens === "number" && found.entry.maxOutputTokens > 0 ? { maxOutputTokens: found.entry.maxOutputTokens } : {},
|
|
31138
31154
|
...ownerWire ? { ownerWire } : {}
|
|
31139
31155
|
}
|
|
31140
31156
|
};
|
|
@@ -32575,6 +32591,19 @@ function wireChoicesFromClaudeRequest(claudeRequest, pinnedEffort) {
|
|
|
32575
32591
|
maxTokens: typeof claudeRequest?.max_tokens === "number" ? claudeRequest.max_tokens : undefined
|
|
32576
32592
|
};
|
|
32577
32593
|
}
|
|
32594
|
+
function outputLimitToSend(wire, choices, result) {
|
|
32595
|
+
if (typeof choices.maxTokens === "number")
|
|
32596
|
+
return choices.maxTokens;
|
|
32597
|
+
if (!LIMIT_REQUIRED_APIS.has(wire.api))
|
|
32598
|
+
return;
|
|
32599
|
+
const ceiling = choices.catalogMaxOutputTokens;
|
|
32600
|
+
if (typeof ceiling === "number" && ceiling > 0) {
|
|
32601
|
+
result.notes.push(`request has no output limit: sent the catalog's maxOutputTokens ${ceiling}`);
|
|
32602
|
+
return ceiling;
|
|
32603
|
+
}
|
|
32604
|
+
result.notes.push("request has no output limit and the catalog publishes no maxOutputTokens: none sent");
|
|
32605
|
+
return;
|
|
32606
|
+
}
|
|
32578
32607
|
function shapeRequestFromWire(body, wire, choices, owner) {
|
|
32579
32608
|
const result = { headers: [], notes: [], borrowed: [] };
|
|
32580
32609
|
stripWireDecisions(body, wire.api);
|
|
@@ -32585,12 +32614,13 @@ function shapeRequestFromWire(body, wire, choices, owner) {
|
|
|
32585
32614
|
result.borrowed.push(path);
|
|
32586
32615
|
};
|
|
32587
32616
|
const sameApiOwner = owner && owner !== wire && owner.api === wire.api ? owner : undefined;
|
|
32617
|
+
const maxTokens = outputLimitToSend(wire, choices, result);
|
|
32588
32618
|
if (typeof wire.tokenParam === "string") {
|
|
32589
|
-
if (typeof
|
|
32590
|
-
body[wire.tokenParam] =
|
|
32619
|
+
if (typeof maxTokens === "number")
|
|
32620
|
+
body[wire.tokenParam] = maxTokens;
|
|
32591
32621
|
} else if (wire.api !== "gemini") {
|
|
32592
|
-
if (wire.tokenParam.status === "unknown" && sameApiOwner && typeof sameApiOwner.tokenParam === "string" && typeof
|
|
32593
|
-
borrow(`/${sameApiOwner.tokenParam}`,
|
|
32622
|
+
if (wire.tokenParam.status === "unknown" && sameApiOwner && typeof sameApiOwner.tokenParam === "string" && typeof maxTokens === "number") {
|
|
32623
|
+
borrow(`/${sameApiOwner.tokenParam}`, maxTokens);
|
|
32594
32624
|
result.notes.push(`tokenParam ${wire.tokenParam.status}: trying the owner's ${sameApiOwner.tokenParam}`);
|
|
32595
32625
|
} else {
|
|
32596
32626
|
result.notes.push(`tokenParam ${wire.tokenParam.status}: no output limit sent`);
|
|
@@ -32641,7 +32671,7 @@ function mergeWireHeaders(headers, extra) {
|
|
|
32641
32671
|
headers[key] = `${existing},${header.value}`;
|
|
32642
32672
|
}
|
|
32643
32673
|
}
|
|
32644
|
-
var WIRE_EFFORT_ORDER, WIRE_SPEEDS, TOKEN_LIMIT_FIELDS, DECISION_POINTERS;
|
|
32674
|
+
var WIRE_EFFORT_ORDER, WIRE_SPEEDS, TOKEN_LIMIT_FIELDS, DECISION_POINTERS, LIMIT_REQUIRED_APIS;
|
|
32645
32675
|
var init_wire_request = __esm(() => {
|
|
32646
32676
|
WIRE_EFFORT_ORDER = [
|
|
32647
32677
|
"none",
|
|
@@ -32673,6 +32703,7 @@ var init_wire_request = __esm(() => {
|
|
|
32673
32703
|
"/service_tier",
|
|
32674
32704
|
"/speed"
|
|
32675
32705
|
];
|
|
32706
|
+
LIMIT_REQUIRED_APIS = new Set(["anthropic-messages"]);
|
|
32676
32707
|
});
|
|
32677
32708
|
|
|
32678
32709
|
// src/providers/wire-markers.ts
|
|
@@ -32921,7 +32952,7 @@ var init_vision_proxy = __esm(() => {
|
|
|
32921
32952
|
init_catalog_query();
|
|
32922
32953
|
});
|
|
32923
32954
|
|
|
32924
|
-
// src/
|
|
32955
|
+
// src/mcp-session/home-dir.ts
|
|
32925
32956
|
import { homedir as homedir23 } from "os";
|
|
32926
32957
|
import { join as join23 } from "path";
|
|
32927
32958
|
function userHomeFrom(env, homedirFn = homedir23) {
|
|
@@ -33251,8 +33282,8 @@ class SessionEventRegistry {
|
|
|
33251
33282
|
}
|
|
33252
33283
|
var MISS_TTL_MS = 5000, MAX_MISSES = 5, IDLE_SWEEP_MS, sessionEvents;
|
|
33253
33284
|
var init_session_events = __esm(() => {
|
|
33254
|
-
init_home_dir();
|
|
33255
33285
|
init_logger();
|
|
33286
|
+
init_home_dir();
|
|
33256
33287
|
init_event_translator();
|
|
33257
33288
|
init_transcript_tailer();
|
|
33258
33289
|
IDLE_SWEEP_MS = 30 * 60 * 1000;
|
|
@@ -37481,6 +37512,7 @@ class ComposedHandler {
|
|
|
37481
37512
|
if (wire?.status === "known") {
|
|
37482
37513
|
const choices = {
|
|
37483
37514
|
...wireChoicesFromClaudeRequest(claudeRequest, this.options.effortOverride),
|
|
37515
|
+
catalogMaxOutputTokens: this.options.connection?.maxOutputTokens,
|
|
37484
37516
|
acceptServedModelChange: process.env.CLAUDISH_ACCEPT_SERVED_MODEL === "1"
|
|
37485
37517
|
};
|
|
37486
37518
|
const markers = wireMarkerContext.getStore();
|
|
@@ -43917,67 +43949,7 @@ var init_prehydrate = __esm(() => {
|
|
|
43917
43949
|
init_op_source();
|
|
43918
43950
|
});
|
|
43919
43951
|
|
|
43920
|
-
// src/
|
|
43921
|
-
import { appendFileSync as appendFileSync5 } from "fs";
|
|
43922
|
-
function traceEnabled() {
|
|
43923
|
-
return process.env[TRACE_ENV] === "1";
|
|
43924
|
-
}
|
|
43925
|
-
function emit(line) {
|
|
43926
|
-
const formatted = `[channel-trace] ${line}
|
|
43927
|
-
`;
|
|
43928
|
-
process.stderr.write(formatted);
|
|
43929
|
-
const filePath = process.env[TRACE_FILE_ENV];
|
|
43930
|
-
if (filePath) {
|
|
43931
|
-
try {
|
|
43932
|
-
appendFileSync5(filePath, formatted);
|
|
43933
|
-
} catch {}
|
|
43934
|
-
}
|
|
43935
|
-
}
|
|
43936
|
-
function wrapStateChange(fn) {
|
|
43937
|
-
if (!traceEnabled())
|
|
43938
|
-
return fn;
|
|
43939
|
-
return (sessionId, event) => {
|
|
43940
|
-
emit(`fired sid=${sessionId} type=${event.type} model=${event.model} elapsed=${event.elapsedSeconds}s`);
|
|
43941
|
-
try {
|
|
43942
|
-
fn(sessionId, event);
|
|
43943
|
-
emit(`callback returned sid=${sessionId} type=${event.type}`);
|
|
43944
|
-
} catch (err) {
|
|
43945
|
-
emit(`callback THREW sid=${sessionId} type=${event.type} err=${err?.message ?? err}`);
|
|
43946
|
-
throw err;
|
|
43947
|
-
}
|
|
43948
|
-
};
|
|
43949
|
-
}
|
|
43950
|
-
function watchNotificationResult(result, context) {
|
|
43951
|
-
if (!traceEnabled())
|
|
43952
|
-
return;
|
|
43953
|
-
if (result && typeof result.then === "function") {
|
|
43954
|
-
result.catch((err) => {
|
|
43955
|
-
emit(`notification REJECTED sid=${context.sessionId} type=${context.eventType} err=${err?.message ?? err}`);
|
|
43956
|
-
});
|
|
43957
|
-
}
|
|
43958
|
-
}
|
|
43959
|
-
function installWireTap() {
|
|
43960
|
-
if (!traceEnabled())
|
|
43961
|
-
return;
|
|
43962
|
-
if (wireTapInstalled)
|
|
43963
|
-
return;
|
|
43964
|
-
wireTapInstalled = true;
|
|
43965
|
-
const originalWrite = process.stdout.write.bind(process.stdout);
|
|
43966
|
-
process.stdout.write = (chunk, ...rest) => {
|
|
43967
|
-
try {
|
|
43968
|
-
const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf-8");
|
|
43969
|
-
if (text.includes('"notifications/claude/channel"')) {
|
|
43970
|
-
emit(`WIRE-OUT ${text.trim()}`);
|
|
43971
|
-
}
|
|
43972
|
-
} catch {}
|
|
43973
|
-
return originalWrite(chunk, ...rest);
|
|
43974
|
-
};
|
|
43975
|
-
emit("wire tap installed");
|
|
43976
|
-
}
|
|
43977
|
-
var TRACE_ENV = "CLAUDISH_CHANNEL_TRACE", TRACE_FILE_ENV = "CLAUDISH_CHANNEL_TRACE_FILE", wireTapInstalled = false;
|
|
43978
|
-
var init_diagnostics = () => {};
|
|
43979
|
-
|
|
43980
|
-
// src/channel/scrollback-buffer.ts
|
|
43952
|
+
// src/mcp-session/scrollback-buffer.ts
|
|
43981
43953
|
class ScrollbackBuffer {
|
|
43982
43954
|
lines;
|
|
43983
43955
|
head;
|
|
@@ -44098,8 +44070,116 @@ var init_contract = __esm(() => {
|
|
|
44098
44070
|
};
|
|
44099
44071
|
});
|
|
44100
44072
|
|
|
44073
|
+
// src/pane/reason-detail.ts
|
|
44074
|
+
import { closeSync as closeSync6, fstatSync, openSync as openSync6, readSync as readSync2 } from "fs";
|
|
44075
|
+
function reasonDetail(input, upstreamRecords = []) {
|
|
44076
|
+
if (!isTerminalState(input.state) || input.state === "COMPLETED")
|
|
44077
|
+
return null;
|
|
44078
|
+
if (input.reason === "api_error") {
|
|
44079
|
+
const last = upstreamRecords.length ? upstreamRecords[upstreamRecords.length - 1] : undefined;
|
|
44080
|
+
const upstream = last === undefined ? null : upstreamMessage(last);
|
|
44081
|
+
if (upstream)
|
|
44082
|
+
return oneLine4(upstream);
|
|
44083
|
+
const child = firstLine(input.detail);
|
|
44084
|
+
return child ? oneLine4(apiErrorText(child)) : null;
|
|
44085
|
+
}
|
|
44086
|
+
const first = firstLine(input.detail);
|
|
44087
|
+
return first ? oneLine4(first) : null;
|
|
44088
|
+
}
|
|
44089
|
+
function upstreamRecordsFor(input, upstreamLogPath) {
|
|
44090
|
+
if (!upstreamLogPath || input.reason !== "api_error" || !isTerminalState(input.state))
|
|
44091
|
+
return [];
|
|
44092
|
+
return readTailLines(upstreamLogPath, UPSTREAM_TAIL_BYTES);
|
|
44093
|
+
}
|
|
44094
|
+
function firstLine(text) {
|
|
44095
|
+
if (!text)
|
|
44096
|
+
return null;
|
|
44097
|
+
const line = text.split(/\r?\n/).find((l) => l.trim().length > 0);
|
|
44098
|
+
return line ? line.trim() : null;
|
|
44099
|
+
}
|
|
44100
|
+
function oneLine4(text) {
|
|
44101
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
44102
|
+
if (!flat)
|
|
44103
|
+
return null;
|
|
44104
|
+
return flat.length > REASON_DETAIL_MAX_CHARS ? `${flat.slice(0, REASON_DETAIL_MAX_CHARS - 1).trimEnd()}\u2026` : flat;
|
|
44105
|
+
}
|
|
44106
|
+
function apiErrorText(detail) {
|
|
44107
|
+
const text = detail.split(" \xB7 ")[0].replace(/^The turn ended in an API error(?:\s*\(status \d+\))?:\s*/i, "").replace(/^API Error:?\s*(?:\d{3}\b)?\s*/i, "").trim();
|
|
44108
|
+
if (/^[[{]/.test(text))
|
|
44109
|
+
return messageOfJsonText(text) ?? "";
|
|
44110
|
+
return text;
|
|
44111
|
+
}
|
|
44112
|
+
function upstreamMessage(record) {
|
|
44113
|
+
let parsed;
|
|
44114
|
+
try {
|
|
44115
|
+
parsed = JSON.parse(record);
|
|
44116
|
+
} catch {
|
|
44117
|
+
return null;
|
|
44118
|
+
}
|
|
44119
|
+
if (!isObject3(parsed))
|
|
44120
|
+
return null;
|
|
44121
|
+
const body = parsed.body;
|
|
44122
|
+
if (typeof body === "string")
|
|
44123
|
+
return messageOfJsonText(body);
|
|
44124
|
+
return messageOf(body);
|
|
44125
|
+
}
|
|
44126
|
+
function messageOfJsonText(text) {
|
|
44127
|
+
try {
|
|
44128
|
+
return messageOf(JSON.parse(text));
|
|
44129
|
+
} catch {
|
|
44130
|
+
const m = /"error"\s*:\s*\{[^{}]*?"message"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(text);
|
|
44131
|
+
if (!m)
|
|
44132
|
+
return null;
|
|
44133
|
+
try {
|
|
44134
|
+
return nonEmpty2(JSON.parse(`"${m[1]}"`));
|
|
44135
|
+
} catch {
|
|
44136
|
+
return null;
|
|
44137
|
+
}
|
|
44138
|
+
}
|
|
44139
|
+
}
|
|
44140
|
+
function messageOf(value) {
|
|
44141
|
+
const v = Array.isArray(value) ? value[0] : value;
|
|
44142
|
+
if (!isObject3(v) || !isObject3(v.error))
|
|
44143
|
+
return null;
|
|
44144
|
+
return nonEmpty2(v.error.message);
|
|
44145
|
+
}
|
|
44146
|
+
function nonEmpty2(v) {
|
|
44147
|
+
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
44148
|
+
}
|
|
44149
|
+
function isObject3(v) {
|
|
44150
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
44151
|
+
}
|
|
44152
|
+
function readTailLines(path, maxBytes) {
|
|
44153
|
+
let fd = null;
|
|
44154
|
+
try {
|
|
44155
|
+
fd = openSync6(path, "r");
|
|
44156
|
+
const size = fstatSync(fd).size;
|
|
44157
|
+
const start = Math.max(0, size - maxBytes);
|
|
44158
|
+
const buf = Buffer.alloc(size - start);
|
|
44159
|
+
readSync2(fd, buf, 0, buf.length, start);
|
|
44160
|
+
const lines = buf.toString("utf-8").split(`
|
|
44161
|
+
`);
|
|
44162
|
+
if (start > 0)
|
|
44163
|
+
lines.shift();
|
|
44164
|
+
return lines.filter((l) => l.trim().length > 0);
|
|
44165
|
+
} catch {
|
|
44166
|
+
return [];
|
|
44167
|
+
} finally {
|
|
44168
|
+
if (fd !== null) {
|
|
44169
|
+
try {
|
|
44170
|
+
closeSync6(fd);
|
|
44171
|
+
} catch {}
|
|
44172
|
+
}
|
|
44173
|
+
}
|
|
44174
|
+
}
|
|
44175
|
+
var REASON_DETAIL_MAX_CHARS = 160, UPSTREAM_TAIL_BYTES;
|
|
44176
|
+
var init_reason_detail = __esm(() => {
|
|
44177
|
+
init_contract();
|
|
44178
|
+
UPSTREAM_TAIL_BYTES = 16 * 1024;
|
|
44179
|
+
});
|
|
44180
|
+
|
|
44101
44181
|
// src/pane/slot-row.ts
|
|
44102
|
-
function toSlotRow(id, snap, acct, now = Date.now()) {
|
|
44182
|
+
function toSlotRow(id, snap, acct, now = Date.now(), upstreamRecords = []) {
|
|
44103
44183
|
const terminal = isTerminalState(snap.state);
|
|
44104
44184
|
let idle = null;
|
|
44105
44185
|
if (!terminal && snap.lastActivityAt) {
|
|
@@ -44113,6 +44193,7 @@ function toSlotRow(id, snap, acct, now = Date.now()) {
|
|
|
44113
44193
|
provider: acct.provider,
|
|
44114
44194
|
state: snap.state,
|
|
44115
44195
|
reason: snap.state === "COMPLETED" || !terminal ? null : snap.reason,
|
|
44196
|
+
reason_detail: reasonDetail({ state: snap.state, reason: snap.reason, detail: snap.detail }, upstreamRecords),
|
|
44116
44197
|
tokens_in: acct.tokensIn,
|
|
44117
44198
|
tokens_out: acct.tokensOut,
|
|
44118
44199
|
cost_usd: acct.costUsd,
|
|
@@ -44126,6 +44207,7 @@ function toSlotRow(id, snap, acct, now = Date.now()) {
|
|
|
44126
44207
|
}
|
|
44127
44208
|
var init_slot_row = __esm(() => {
|
|
44128
44209
|
init_contract();
|
|
44210
|
+
init_reason_detail();
|
|
44129
44211
|
});
|
|
44130
44212
|
|
|
44131
44213
|
// src/pane/prompt-delivery.ts
|
|
@@ -51963,7 +52045,7 @@ function truncateKeepingLink(text, max = 400) {
|
|
|
51963
52045
|
const prose = (lastSpace > room * 0.5 ? head.slice(0, lastSpace) : head).trimEnd();
|
|
51964
52046
|
return `${prose}... ${url}`;
|
|
51965
52047
|
}
|
|
51966
|
-
function
|
|
52048
|
+
function oneLine5(text) {
|
|
51967
52049
|
return text.replace(/\s+/g, " ").trim();
|
|
51968
52050
|
}
|
|
51969
52051
|
function messageFromJson(text) {
|
|
@@ -51986,9 +52068,9 @@ function extractErrorMessage(body) {
|
|
|
51986
52068
|
return;
|
|
51987
52069
|
const direct = messageFromJson(body);
|
|
51988
52070
|
if (direct)
|
|
51989
|
-
return truncateKeepingLink(
|
|
52071
|
+
return truncateKeepingLink(oneLine5(unwrapFrame(direct)));
|
|
51990
52072
|
const unwrapped = unwrapFrame(body);
|
|
51991
|
-
const trimmed =
|
|
52073
|
+
const trimmed = oneLine5(unwrapped);
|
|
51992
52074
|
if (!trimmed)
|
|
51993
52075
|
return;
|
|
51994
52076
|
return truncateKeepingLink(trimmed);
|
|
@@ -57035,7 +57117,7 @@ If you cannot use structured tool_calls, format as JSON:
|
|
|
57035
57117
|
});
|
|
57036
57118
|
|
|
57037
57119
|
// src/handlers/native-handler-advisor.ts
|
|
57038
|
-
import { appendFileSync as
|
|
57120
|
+
import { appendFileSync as appendFileSync5 } from "fs";
|
|
57039
57121
|
function loadAdvisorSwapConfig(cliModels, cliCollector) {
|
|
57040
57122
|
return {
|
|
57041
57123
|
enabled: process.env.CLAUDISH_SWAP_ADVISOR === "1" || (cliModels?.length ?? 0) > 0,
|
|
@@ -57130,7 +57212,7 @@ function appendLine(path, line) {
|
|
|
57130
57212
|
if (!path)
|
|
57131
57213
|
return;
|
|
57132
57214
|
try {
|
|
57133
|
-
|
|
57215
|
+
appendFileSync5(path, `${line}
|
|
57134
57216
|
`);
|
|
57135
57217
|
} catch {}
|
|
57136
57218
|
}
|
|
@@ -59501,7 +59583,7 @@ var init_pricing_cache = __esm(() => {
|
|
|
59501
59583
|
});
|
|
59502
59584
|
|
|
59503
59585
|
// src/proxy-server.ts
|
|
59504
|
-
import { appendFileSync as
|
|
59586
|
+
import { appendFileSync as appendFileSync6, mkdirSync as mkdirSync15 } from "fs";
|
|
59505
59587
|
import { join as join35 } from "path";
|
|
59506
59588
|
function isTerminalRoutingFailure(e) {
|
|
59507
59589
|
return e instanceof RoutingError;
|
|
@@ -59535,7 +59617,7 @@ function maybeCaptureClassifierRequest(c, body) {
|
|
|
59535
59617
|
"x-api-key": c.req.header("x-api-key") ? "<present>" : null
|
|
59536
59618
|
}
|
|
59537
59619
|
};
|
|
59538
|
-
|
|
59620
|
+
appendFileSync6(join35(dir, "classifier-capture.jsonl"), `${JSON.stringify(record)}
|
|
59539
59621
|
`);
|
|
59540
59622
|
} catch {}
|
|
59541
59623
|
}
|
|
@@ -61565,7 +61647,7 @@ ${h("ENVIRONMENT VARIABLES")}
|
|
|
61565
61647
|
${blue("CLAUDISH_DIAG_MODE")} Diagnostic output: auto / logfile / off
|
|
61566
61648
|
${blue("CLAUDISH_DEBUG")} Always enable debug logging: 1 / true ${dim("(same as -d)")}
|
|
61567
61649
|
${blue("CLAUDISH_ANTHROPIC_API_BILLING")} Bill native Claude to your API key ${dim("(see --anthropic-api-billing)")}
|
|
61568
|
-
${blue("CLAUDISH_MCP_TOOLS")} MCP tool gating: all / low-level / agentic /
|
|
61650
|
+
${blue("CLAUDISH_MCP_TOOLS")} MCP tool gating: all / low-level / agentic / session / debug
|
|
61569
61651
|
${blue("CLAUDISH_MODEL_OPUS")} Override model for Opus role
|
|
61570
61652
|
${blue("CLAUDISH_MODEL_SONNET")} Override model for Sonnet role
|
|
61571
61653
|
${blue("CLAUDISH_MODEL_HAIKU")} Override model for Haiku role
|
|
@@ -61875,11 +61957,11 @@ var init_magmux_binary = () => {};
|
|
|
61875
61957
|
// src/launcher/magmux-wrapper.ts
|
|
61876
61958
|
import {
|
|
61877
61959
|
chmodSync,
|
|
61878
|
-
closeSync as
|
|
61960
|
+
closeSync as closeSync7,
|
|
61879
61961
|
existsSync as existsSync27,
|
|
61880
61962
|
mkdirSync as mkdirSync17,
|
|
61881
61963
|
mkdtempSync,
|
|
61882
|
-
openSync as
|
|
61964
|
+
openSync as openSync7,
|
|
61883
61965
|
rmSync as rmSync2,
|
|
61884
61966
|
writeFileSync as writeFileSync16
|
|
61885
61967
|
} from "fs";
|
|
@@ -61955,11 +62037,11 @@ function planMagmuxWrap(input) {
|
|
|
61955
62037
|
const scriptPath = join38(scriptDir, "claude-launch.sh");
|
|
61956
62038
|
const parentEnv = input.parentEnv ?? process.env;
|
|
61957
62039
|
const deltas = envDeltas(parentEnv, input.childEnv);
|
|
61958
|
-
const fd =
|
|
62040
|
+
const fd = openSync7(scriptPath, "wx", 384);
|
|
61959
62041
|
try {
|
|
61960
62042
|
writeFileSync16(fd, buildLauncherScript(input.claudeBinary, input.claudeArgs, deltas));
|
|
61961
62043
|
} finally {
|
|
61962
|
-
|
|
62044
|
+
closeSync7(fd);
|
|
61963
62045
|
}
|
|
61964
62046
|
const env = { ...input.childEnv };
|
|
61965
62047
|
for (const k of STRIPPED_CHILD_VARS)
|
|
@@ -62427,13 +62509,13 @@ function sockPathFor(root, id) {
|
|
|
62427
62509
|
throw new PaneRootError(`pane socket path ${p} is ${Buffer.byteLength(p)} bytes; it must be < 100`);
|
|
62428
62510
|
return p;
|
|
62429
62511
|
}
|
|
62430
|
-
function
|
|
62512
|
+
function isStrippedFromChildEnv(key) {
|
|
62431
62513
|
return STRIPPED_CHILD_VARS.includes(key) || key.startsWith("MAGMUX_") || TERMINAL_IDENTITY_VARS.includes(key) || TERMINAL_IDENTITY_PREFIXES.some((p) => key.startsWith(p)) || HOST_IDENTITY_VARS.includes(key);
|
|
62432
62514
|
}
|
|
62433
62515
|
function buildPaneEnv(input) {
|
|
62434
62516
|
const env = {};
|
|
62435
62517
|
for (const [k, v] of Object.entries(input.parentEnv)) {
|
|
62436
|
-
if (v === undefined ||
|
|
62518
|
+
if (v === undefined || isStrippedFromChildEnv(k))
|
|
62437
62519
|
continue;
|
|
62438
62520
|
env[k] = v;
|
|
62439
62521
|
}
|
|
@@ -63364,7 +63446,7 @@ var init_pane_registry = __esm(() => {
|
|
|
63364
63446
|
sweptRoots = new Set;
|
|
63365
63447
|
});
|
|
63366
63448
|
|
|
63367
|
-
// src/
|
|
63449
|
+
// src/mcp-session/parent-session.ts
|
|
63368
63450
|
import { readFile as readFile4 } from "fs/promises";
|
|
63369
63451
|
import { join as join42 } from "path";
|
|
63370
63452
|
function positiveInt(value) {
|
|
@@ -64013,11 +64095,11 @@ var init_slot_state = __esm(() => {
|
|
|
64013
64095
|
|
|
64014
64096
|
// src/pane/transcript-follower.ts
|
|
64015
64097
|
import {
|
|
64016
|
-
closeSync as
|
|
64098
|
+
closeSync as closeSync8,
|
|
64017
64099
|
existsSync as existsSync29,
|
|
64018
|
-
fstatSync,
|
|
64019
|
-
openSync as
|
|
64020
|
-
readSync as
|
|
64100
|
+
fstatSync as fstatSync2,
|
|
64101
|
+
openSync as openSync8,
|
|
64102
|
+
readSync as readSync3,
|
|
64021
64103
|
readdirSync as readdirSync7,
|
|
64022
64104
|
realpathSync as realpathSync2,
|
|
64023
64105
|
statSync as statSync8
|
|
@@ -64452,16 +64534,16 @@ class Tail {
|
|
|
64452
64534
|
read() {
|
|
64453
64535
|
let fd;
|
|
64454
64536
|
try {
|
|
64455
|
-
fd =
|
|
64537
|
+
fd = openSync8(this.path, "r");
|
|
64456
64538
|
} catch {
|
|
64457
64539
|
return [];
|
|
64458
64540
|
}
|
|
64459
64541
|
try {
|
|
64460
|
-
const size =
|
|
64542
|
+
const size = fstatSync2(fd).size;
|
|
64461
64543
|
if (size <= this.offset)
|
|
64462
64544
|
return [];
|
|
64463
64545
|
const chunk = Buffer.alloc(size - this.offset);
|
|
64464
|
-
const got =
|
|
64546
|
+
const got = readSync3(fd, chunk, 0, chunk.length, this.offset);
|
|
64465
64547
|
this.offset += got;
|
|
64466
64548
|
const fresh = chunk.subarray(0, got);
|
|
64467
64549
|
const buf = this.rest.length ? Buffer.concat([this.rest, fresh]) : fresh;
|
|
@@ -64478,7 +64560,7 @@ class Tail {
|
|
|
64478
64560
|
this.rest = Buffer.from(buf.subarray(start));
|
|
64479
64561
|
return out;
|
|
64480
64562
|
} finally {
|
|
64481
|
-
|
|
64563
|
+
closeSync8(fd);
|
|
64482
64564
|
}
|
|
64483
64565
|
}
|
|
64484
64566
|
}
|
|
@@ -65204,9 +65286,12 @@ class PaneSessionImpl {
|
|
|
65204
65286
|
this.deliver(this.admission);
|
|
65205
65287
|
}
|
|
65206
65288
|
async deliver(adm) {
|
|
65207
|
-
|
|
65289
|
+
if (await this.typeAndSubmit(adm.plan))
|
|
65290
|
+
adm.deliveredAt = Date.now();
|
|
65291
|
+
}
|
|
65292
|
+
async typeAndSubmit(plan) {
|
|
65208
65293
|
if (plan.mode !== "typed" && plan.mode !== "file" && plan.mode !== "command")
|
|
65209
|
-
return;
|
|
65294
|
+
return false;
|
|
65210
65295
|
if (plan.mode === "command") {
|
|
65211
65296
|
await this.typeLine(plan.line, false);
|
|
65212
65297
|
await this.nextFrame(500);
|
|
@@ -65218,7 +65303,7 @@ class PaneSessionImpl {
|
|
|
65218
65303
|
} else {
|
|
65219
65304
|
await this.typeLine(plan.line, true);
|
|
65220
65305
|
}
|
|
65221
|
-
|
|
65306
|
+
return true;
|
|
65222
65307
|
}
|
|
65223
65308
|
async typeLine(text, enter) {
|
|
65224
65309
|
let why = "disconnected";
|
|
@@ -65322,16 +65407,44 @@ class PaneSessionImpl {
|
|
|
65322
65407
|
this.fire("admit_abandoned");
|
|
65323
65408
|
return true;
|
|
65324
65409
|
}
|
|
65410
|
+
async awaitClearedBox(adm, head) {
|
|
65411
|
+
const end = Date.now() + this.t("nudgeClearDeadlineMs", NUDGE_CLEAR_DEADLINE_MS);
|
|
65412
|
+
for (;; ) {
|
|
65413
|
+
if (this.admission !== adm || this.phase !== "ADMITTING")
|
|
65414
|
+
return "gone";
|
|
65415
|
+
const box = inputBox(this.screen);
|
|
65416
|
+
if (box && box.text === "")
|
|
65417
|
+
return "empty";
|
|
65418
|
+
if (box && !box.text.startsWith(head))
|
|
65419
|
+
return "other";
|
|
65420
|
+
const left = end - Date.now();
|
|
65421
|
+
if (left <= 0)
|
|
65422
|
+
return box ? "line" : "other";
|
|
65423
|
+
await this.nextFrame(left);
|
|
65424
|
+
}
|
|
65425
|
+
}
|
|
65325
65426
|
nudge(adm) {
|
|
65326
65427
|
const box = inputBox(this.screen);
|
|
65327
65428
|
const line = adm.plan.mode === "control" || adm.plan.mode === "refused" ? "" : adm.plan.line;
|
|
65328
|
-
|
|
65429
|
+
const head = line.slice(0, 40);
|
|
65430
|
+
if (!adm.resent && box && line && box.text.startsWith(head)) {
|
|
65329
65431
|
adm.resent = true;
|
|
65330
65432
|
this.anomaly("resent_enter");
|
|
65331
65433
|
(async () => {
|
|
65332
65434
|
if (box.menuOpen)
|
|
65333
65435
|
await this.key("escape");
|
|
65334
|
-
await this.key("
|
|
65436
|
+
await this.key("ctrl-u");
|
|
65437
|
+
const after = await this.awaitClearedBox(adm, head);
|
|
65438
|
+
if (after === "gone")
|
|
65439
|
+
return;
|
|
65440
|
+
if (after === "empty") {
|
|
65441
|
+
this.anomaly("retyped_prompt");
|
|
65442
|
+
await this.typeAndSubmit(adm.plan);
|
|
65443
|
+
} else if (after === "line") {
|
|
65444
|
+
await this.key("enter");
|
|
65445
|
+
} else {
|
|
65446
|
+
this.anomaly("clear_failed");
|
|
65447
|
+
}
|
|
65335
65448
|
})();
|
|
65336
65449
|
return;
|
|
65337
65450
|
}
|
|
@@ -66045,7 +66158,7 @@ async function startPaneSession(o) {
|
|
|
66045
66158
|
await session.start({ magmuxBinary: magmux.binary, env: p.magmuxEnv, cwd: p.cwd });
|
|
66046
66159
|
return session;
|
|
66047
66160
|
}
|
|
66048
|
-
var BOOT_TIMEOUT_MS = 90000, ADMIT_TIMEOUT_MS = 30000, RESEND_AFTER_MS = 1e4, DEGRADED_ENTRY_MS = 1e4, SCREEN_SETTLE_QUIET_MS = 3000, PANEL_SETTLE_MS = 500, REPL_STABLE_MS =
|
|
66161
|
+
var BOOT_TIMEOUT_MS = 90000, ADMIT_TIMEOUT_MS = 30000, RESEND_AFTER_MS = 1e4, DEGRADED_ENTRY_MS = 1e4, SCREEN_SETTLE_QUIET_MS = 3000, PANEL_SETTLE_MS = 500, REPL_STABLE_MS = 3000, NUDGE_CLEAR_DEADLINE_MS = 3000, BOOT_STATIC_MS = 5000, TICK_MS = 250, WATCH_FPS = 4, POLL_BACKSTOP_MS = 1000, TURN_END_MISSING_FACTOR = 3, REGISTRY_READ_MS = 250, REGISTRY_DISAGREE_MS = 2000, REGISTRY_MISSING_MS = 5000, MAX_ANOMALY_KEYS = 64, KEPT_ANSWERS = 4, EVENT_REASON, VERDICT_EVENT, PaneStartError;
|
|
66049
66162
|
var init_pane_session = __esm(() => {
|
|
66050
66163
|
init_parent_session();
|
|
66051
66164
|
init_process_tree();
|
|
@@ -66085,6 +66198,7 @@ var init_pane_session = __esm(() => {
|
|
|
66085
66198
|
// src/pane/index.ts
|
|
66086
66199
|
var init_pane = __esm(() => {
|
|
66087
66200
|
init_slot_row();
|
|
66201
|
+
init_reason_detail();
|
|
66088
66202
|
init_prompt_delivery();
|
|
66089
66203
|
init_accounting();
|
|
66090
66204
|
init_pane_launch();
|
|
@@ -66110,7 +66224,7 @@ __export(exports_session_discovery, {
|
|
|
66110
66224
|
transcriptPathFor: () => transcriptPathFor
|
|
66111
66225
|
});
|
|
66112
66226
|
import { execFile as execFile3, execFileSync as execFileSync3 } from "child_process";
|
|
66113
|
-
import { closeSync as
|
|
66227
|
+
import { closeSync as closeSync9, openSync as openSync9, readSync as readSync4, readdirSync as readdirSync8, realpathSync as realpathSync4, statSync as statSync10 } from "fs";
|
|
66114
66228
|
import { basename as basename2, join as join46 } from "path";
|
|
66115
66229
|
function projectsDir(env = process.env) {
|
|
66116
66230
|
return join46(claudeConfigDir(env), "projects");
|
|
@@ -66360,16 +66474,16 @@ function readChunk(file, pos, len) {
|
|
|
66360
66474
|
return "";
|
|
66361
66475
|
let fd = null;
|
|
66362
66476
|
try {
|
|
66363
|
-
fd =
|
|
66477
|
+
fd = openSync9(file, "r");
|
|
66364
66478
|
const buf = Buffer.allocUnsafe(len);
|
|
66365
|
-
const n =
|
|
66479
|
+
const n = readSync4(fd, buf, 0, len, pos);
|
|
66366
66480
|
return buf.subarray(0, n).toString("utf-8");
|
|
66367
66481
|
} catch {
|
|
66368
66482
|
return "";
|
|
66369
66483
|
} finally {
|
|
66370
66484
|
if (fd !== null) {
|
|
66371
66485
|
try {
|
|
66372
|
-
|
|
66486
|
+
closeSync9(fd);
|
|
66373
66487
|
} catch {}
|
|
66374
66488
|
}
|
|
66375
66489
|
}
|
|
@@ -66625,6 +66739,9 @@ function refreshAccounting(e, snap) {
|
|
|
66625
66739
|
function notableAnomalies(snap) {
|
|
66626
66740
|
return snap.anomalies.filter((a) => a.startsWith("background_shell_open") || a.startsWith("turn_end_record_missing") || a.startsWith("prompt_not_read"));
|
|
66627
66741
|
}
|
|
66742
|
+
function upstreamLogPath(path, id) {
|
|
66743
|
+
return join47(path, "errors", `${id}-upstream.jsonl`);
|
|
66744
|
+
}
|
|
66628
66745
|
function neverSpawnedRow(e, m) {
|
|
66629
66746
|
return {
|
|
66630
66747
|
slot: e.id,
|
|
@@ -66632,6 +66749,11 @@ function neverSpawnedRow(e, m) {
|
|
|
66632
66749
|
provider: e.acct.provider,
|
|
66633
66750
|
state: m?.state ?? "FAILED",
|
|
66634
66751
|
reason: m?.error?.reason ?? "pane_lost",
|
|
66752
|
+
reason_detail: reasonDetail({
|
|
66753
|
+
state: m?.state ?? "FAILED",
|
|
66754
|
+
reason: m?.error?.reason ?? "pane_lost",
|
|
66755
|
+
detail: m?.error?.detail
|
|
66756
|
+
}),
|
|
66635
66757
|
tokens_in: null,
|
|
66636
66758
|
tokens_out: null,
|
|
66637
66759
|
cost_usd: null,
|
|
@@ -66647,7 +66769,7 @@ function liveSlotRow(run, e) {
|
|
|
66647
66769
|
if (!e.session)
|
|
66648
66770
|
return neverSpawnedRow(e, run.status.models[e.id]);
|
|
66649
66771
|
const snap = e.session.snapshot();
|
|
66650
|
-
return toSlotRow({ slot: e.id, model: e.model, spawnModel: e.spawnModel }, snap, refreshAccounting(e, snap));
|
|
66772
|
+
return toSlotRow({ slot: e.id, model: e.model, spawnModel: e.spawnModel }, snap, refreshAccounting(e, snap), Date.now(), upstreamRecordsFor(snap, upstreamLogPath(run.path, e.id)));
|
|
66651
66773
|
}
|
|
66652
66774
|
function outcomeOf(states) {
|
|
66653
66775
|
const ok = states.filter((s) => s === "COMPLETED").length;
|
|
@@ -66686,12 +66808,15 @@ function teamRunRowFromDisk(path, status) {
|
|
|
66686
66808
|
const slots = Object.entries(status.models ?? {}).sort(([a], [b]) => a.localeCompare(b)).map(([id, m]) => {
|
|
66687
66809
|
const { state, known } = closedState(m?.state);
|
|
66688
66810
|
const terminal = isTerminalState(state);
|
|
66811
|
+
const reason = !known || !terminal || state === "COMPLETED" ? null : m?.error?.reason ?? null;
|
|
66812
|
+
const why = { state, reason, detail: m?.error?.detail };
|
|
66689
66813
|
return {
|
|
66690
66814
|
slot: id,
|
|
66691
66815
|
model: m?.model ?? manifest?.models[id]?.model ?? "unknown",
|
|
66692
66816
|
provider: m?.provider ?? null,
|
|
66693
66817
|
state,
|
|
66694
|
-
reason
|
|
66818
|
+
reason,
|
|
66819
|
+
reason_detail: reasonDetail(why, upstreamRecordsFor(why, upstreamLogPath(path, id))),
|
|
66695
66820
|
tokens_in: m?.tokensIn ?? null,
|
|
66696
66821
|
tokens_out: m?.tokensOut ?? null,
|
|
66697
66822
|
cost_usd: m?.costUsd ?? null,
|
|
@@ -67085,7 +67210,7 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
67085
67210
|
const entries = new Map;
|
|
67086
67211
|
let run = null;
|
|
67087
67212
|
const errorLogPathOf = (id) => join47(path, "errors", `${id}.log`);
|
|
67088
|
-
const upstreamLogOf = (id) =>
|
|
67213
|
+
const upstreamLogOf = (id) => upstreamLogPath(path, id);
|
|
67089
67214
|
const commandOf = (e) => ["claudish", "-i", "--model", e.spawnModel ?? e.model, "-y", "--quiet", ...claudeFlags].join(" ");
|
|
67090
67215
|
function writeResponse(e, text) {
|
|
67091
67216
|
e.answer = text;
|
|
@@ -67647,17 +67772,17 @@ var init_team_orchestrator = __esm(() => {
|
|
|
67647
67772
|
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.";
|
|
67648
67773
|
});
|
|
67649
67774
|
|
|
67650
|
-
// src/
|
|
67775
|
+
// src/mcp-session/session-manager.ts
|
|
67651
67776
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
67652
67777
|
import {
|
|
67653
|
-
appendFileSync as
|
|
67654
|
-
closeSync as
|
|
67778
|
+
appendFileSync as appendFileSync7,
|
|
67779
|
+
closeSync as closeSync10,
|
|
67655
67780
|
createWriteStream,
|
|
67656
67781
|
existsSync as existsSync31,
|
|
67657
67782
|
mkdirSync as mkdirSync20,
|
|
67658
|
-
openSync as
|
|
67783
|
+
openSync as openSync10,
|
|
67659
67784
|
readFileSync as readFileSync30,
|
|
67660
|
-
readSync as
|
|
67785
|
+
readSync as readSync5,
|
|
67661
67786
|
renameSync as renameSync4,
|
|
67662
67787
|
statSync as statSync12,
|
|
67663
67788
|
writeFileSync as writeFileSync21
|
|
@@ -67669,7 +67794,7 @@ function normaliseTimeoutSeconds(raw) {
|
|
|
67669
67794
|
return DEFAULT_TIMEOUT;
|
|
67670
67795
|
return Math.min(MAX_TIMEOUT, Math.max(1, Math.round(n)));
|
|
67671
67796
|
}
|
|
67672
|
-
function
|
|
67797
|
+
function sessionEventFor(snap) {
|
|
67673
67798
|
switch (snap.state) {
|
|
67674
67799
|
case "STARTING":
|
|
67675
67800
|
return { event: "starting", tool: null };
|
|
@@ -67691,7 +67816,7 @@ function channelEventFor(snap) {
|
|
|
67691
67816
|
return { event: "failed", tool: null };
|
|
67692
67817
|
}
|
|
67693
67818
|
}
|
|
67694
|
-
function sessionRowOf(info) {
|
|
67819
|
+
function sessionRowOf(info, upstreamRecords = []) {
|
|
67695
67820
|
const terminal = isTerminalState(info.state);
|
|
67696
67821
|
return {
|
|
67697
67822
|
slot: info.sessionId,
|
|
@@ -67699,6 +67824,7 @@ function sessionRowOf(info) {
|
|
|
67699
67824
|
provider: info.provider,
|
|
67700
67825
|
state: info.state,
|
|
67701
67826
|
reason: info.state === "COMPLETED" || !terminal ? null : info.reason,
|
|
67827
|
+
reason_detail: reasonDetail(info, upstreamRecords),
|
|
67702
67828
|
tokens_in: info.tokensIn,
|
|
67703
67829
|
tokens_out: info.tokensOut,
|
|
67704
67830
|
cost_usd: info.costUsd,
|
|
@@ -67753,15 +67879,6 @@ function writeJsonAtomic(path, value) {
|
|
|
67753
67879
|
writeFileSync21(tmp, JSON.stringify(value, null, 2), "utf-8");
|
|
67754
67880
|
renameSync4(tmp, path);
|
|
67755
67881
|
}
|
|
67756
|
-
function anomalyCount(anomalies, key) {
|
|
67757
|
-
for (const a of anomalies) {
|
|
67758
|
-
if (a === key)
|
|
67759
|
-
return 1;
|
|
67760
|
-
if (a.startsWith(`${key} \xD7`))
|
|
67761
|
-
return Number(a.slice(key.length + 2)) || 1;
|
|
67762
|
-
}
|
|
67763
|
-
return 0;
|
|
67764
|
-
}
|
|
67765
67882
|
function anomalyKey(a) {
|
|
67766
67883
|
const at = a.lastIndexOf(" \xD7");
|
|
67767
67884
|
return at > 0 ? a.slice(0, at) : a;
|
|
@@ -67775,20 +67892,20 @@ function readTailText(path, maxBytes) {
|
|
|
67775
67892
|
const start = Math.max(0, size - maxBytes);
|
|
67776
67893
|
const length = size - start;
|
|
67777
67894
|
const buf = Buffer.alloc(length);
|
|
67778
|
-
fd =
|
|
67779
|
-
|
|
67895
|
+
fd = openSync10(path, "r");
|
|
67896
|
+
readSync5(fd, buf, 0, length, start);
|
|
67780
67897
|
return { text: buf.toString("utf-8"), truncated: start > 0 };
|
|
67781
67898
|
} catch {
|
|
67782
67899
|
return null;
|
|
67783
67900
|
} finally {
|
|
67784
67901
|
if (fd !== null) {
|
|
67785
67902
|
try {
|
|
67786
|
-
|
|
67903
|
+
closeSync10(fd);
|
|
67787
67904
|
} catch {}
|
|
67788
67905
|
}
|
|
67789
67906
|
}
|
|
67790
67907
|
}
|
|
67791
|
-
function
|
|
67908
|
+
function readTailLines2(path, maxBytes) {
|
|
67792
67909
|
const tail = readTailText(path, maxBytes);
|
|
67793
67910
|
if (!tail)
|
|
67794
67911
|
return [];
|
|
@@ -67875,7 +67992,6 @@ class SessionManager {
|
|
|
67875
67992
|
scrollbackCapacity;
|
|
67876
67993
|
sessionsDir;
|
|
67877
67994
|
terminalRetentionMs;
|
|
67878
|
-
onStateChange;
|
|
67879
67995
|
parentEnv;
|
|
67880
67996
|
paneTimings;
|
|
67881
67997
|
starting = 0;
|
|
@@ -67892,7 +68008,6 @@ class SessionManager {
|
|
|
67892
68008
|
this.scrollbackCapacity = options?.scrollbackCapacity ?? DEFAULT_SCROLLBACK;
|
|
67893
68009
|
this.terminalRetentionMs = options?.terminalRetentionMs ?? TERMINAL_RETENTION_MS;
|
|
67894
68010
|
this.sessionsDir = options?.sessionsDir ?? sessionsDirFrom(process.env);
|
|
67895
|
-
this.onStateChange = options?.onStateChange;
|
|
67896
68011
|
this.parentEnv = options?.parentEnv ?? process.env;
|
|
67897
68012
|
this.paneTimings = options?.paneTimings;
|
|
67898
68013
|
}
|
|
@@ -68099,16 +68214,9 @@ class SessionManager {
|
|
|
68099
68214
|
waitSince: null,
|
|
68100
68215
|
ended: false,
|
|
68101
68216
|
evictHandle: null,
|
|
68102
|
-
lastEvent: "starting",
|
|
68103
|
-
lastFrameTool: null,
|
|
68104
|
-
lastFrameToolCount: 0,
|
|
68105
|
-
lastToolFrameAt: 0,
|
|
68106
68217
|
lastLoggedTool: null,
|
|
68107
68218
|
assistantIdsLogged: 0,
|
|
68108
|
-
anomaliesLogged: new Set
|
|
68109
|
-
sendRejectedSeen: 0,
|
|
68110
|
-
pendingMeta: {},
|
|
68111
|
-
blockText: null
|
|
68219
|
+
anomaliesLogged: new Set
|
|
68112
68220
|
};
|
|
68113
68221
|
}
|
|
68114
68222
|
async startPane(entry, opts, p) {
|
|
@@ -68157,7 +68265,6 @@ class SessionManager {
|
|
|
68157
68265
|
info.elapsedSeconds = elapsedSecondsBetween(info.startedAt, Date.parse(at));
|
|
68158
68266
|
this.appendEvent(entry, { type: "state", from: "STARTING", to: "FAILED", at });
|
|
68159
68267
|
this.endRecords(entry, null);
|
|
68160
|
-
this.emitFrame(entry, { state: "FAILED", activity: null, toolCalls: 0 });
|
|
68161
68268
|
}
|
|
68162
68269
|
decide(entry, turn) {
|
|
68163
68270
|
this.appendAnswer(entry, turn.index, turn.answer);
|
|
@@ -68178,7 +68285,6 @@ class SessionManager {
|
|
|
68178
68285
|
return { state: "FAILED", reason: "api_error", detail: v?.detail ?? "API error" };
|
|
68179
68286
|
}
|
|
68180
68287
|
if (turn.delivery.complete === false) {
|
|
68181
|
-
entry.pendingMeta.prompt_not_read = "true";
|
|
68182
68288
|
this.appendEvent(entry, {
|
|
68183
68289
|
type: "anomaly",
|
|
68184
68290
|
key: "prompt_not_read",
|
|
@@ -68190,8 +68296,7 @@ class SessionManager {
|
|
|
68190
68296
|
}
|
|
68191
68297
|
return "continue";
|
|
68192
68298
|
}
|
|
68193
|
-
onBlocked(
|
|
68194
|
-
entry.blockText = b.text;
|
|
68299
|
+
onBlocked(_entry, _b) {
|
|
68195
68300
|
return "wait";
|
|
68196
68301
|
}
|
|
68197
68302
|
onPaneTransition(entry, t) {
|
|
@@ -68202,18 +68307,14 @@ class SessionManager {
|
|
|
68202
68307
|
this.recordWaitTransition(entry, t.from, t.to, t.at, snap);
|
|
68203
68308
|
this.appendEvent(entry, { type: "state", from: t.from, to: t.to, at: t.at });
|
|
68204
68309
|
this.logPaneFacts(entry, snap);
|
|
68205
|
-
if (!isWaiting(t.to))
|
|
68206
|
-
entry.blockText = null;
|
|
68207
68310
|
if (isTerminalState(t.to))
|
|
68208
68311
|
this.onTerminal(entry, snap);
|
|
68209
|
-
this.emitFrame(entry, snap);
|
|
68210
68312
|
}
|
|
68211
68313
|
onPaneChange(entry, snap) {
|
|
68212
68314
|
if (entry.ended)
|
|
68213
68315
|
return;
|
|
68214
68316
|
this.applySnapshot(entry, snap);
|
|
68215
68317
|
this.logPaneFacts(entry, snap);
|
|
68216
|
-
this.emitFrame(entry, snap);
|
|
68217
68318
|
}
|
|
68218
68319
|
onTerminal(entry, snap) {
|
|
68219
68320
|
const session = entry.session;
|
|
@@ -68251,7 +68352,7 @@ class SessionManager {
|
|
|
68251
68352
|
wait: "closed",
|
|
68252
68353
|
since: entry.waitSince,
|
|
68253
68354
|
at: entry.info.completedAt ?? new Date().toISOString(),
|
|
68254
|
-
to:
|
|
68355
|
+
to: sessionEventFor(entry.info).event
|
|
68255
68356
|
});
|
|
68256
68357
|
entry.waitSince = null;
|
|
68257
68358
|
}
|
|
@@ -68301,7 +68402,7 @@ class SessionManager {
|
|
|
68301
68402
|
at
|
|
68302
68403
|
});
|
|
68303
68404
|
}
|
|
68304
|
-
const { tool } =
|
|
68405
|
+
const { tool } = sessionEventFor(snap);
|
|
68305
68406
|
if (tool && tool !== entry.lastLoggedTool)
|
|
68306
68407
|
this.appendEvent(entry, { type: "tool", name: tool, at });
|
|
68307
68408
|
entry.lastLoggedTool = tool;
|
|
@@ -68312,66 +68413,6 @@ class SessionManager {
|
|
|
68312
68413
|
entry.anomaliesLogged.add(key);
|
|
68313
68414
|
this.appendEvent(entry, { type: "anomaly", key, at });
|
|
68314
68415
|
}
|
|
68315
|
-
const rejected = anomalyCount(snap.anomalies, "send_not_accepted");
|
|
68316
|
-
if (rejected > entry.sendRejectedSeen) {
|
|
68317
|
-
entry.sendRejectedSeen = rejected;
|
|
68318
|
-
entry.pendingMeta.send_rejected = "true";
|
|
68319
|
-
}
|
|
68320
|
-
}
|
|
68321
|
-
emitFrame(entry, snap) {
|
|
68322
|
-
const { event, tool } = channelEventFor(snap);
|
|
68323
|
-
const now = Date.now();
|
|
68324
|
-
const changed = event !== entry.lastEvent;
|
|
68325
|
-
const toolRepeat = !changed && event === "tool_executing" && (tool !== entry.lastFrameTool || snap.toolCalls !== entry.lastFrameToolCount) && now - entry.lastToolFrameAt >= 1000;
|
|
68326
|
-
if (!changed && !toolRepeat)
|
|
68327
|
-
return;
|
|
68328
|
-
entry.lastEvent = event;
|
|
68329
|
-
if (event === "tool_executing") {
|
|
68330
|
-
entry.lastFrameTool = tool;
|
|
68331
|
-
entry.lastFrameToolCount = snap.toolCalls;
|
|
68332
|
-
entry.lastToolFrameAt = now;
|
|
68333
|
-
}
|
|
68334
|
-
const extraMeta = {
|
|
68335
|
-
...tool ? { tool, tool_count: String(snap.toolCalls) } : {},
|
|
68336
|
-
...snap.activity ? { activity: snap.activity } : {},
|
|
68337
|
-
...entry.pendingMeta
|
|
68338
|
-
};
|
|
68339
|
-
entry.pendingMeta = {};
|
|
68340
|
-
try {
|
|
68341
|
-
this.onStateChange?.(entry.info.sessionId, {
|
|
68342
|
-
type: event,
|
|
68343
|
-
model: entry.info.model,
|
|
68344
|
-
content: this.frameContent(entry, event, tool),
|
|
68345
|
-
elapsedSeconds: entry.info.elapsedSeconds,
|
|
68346
|
-
createdAt: entry.info.startedAt,
|
|
68347
|
-
extraMeta
|
|
68348
|
-
});
|
|
68349
|
-
} catch {}
|
|
68350
|
-
}
|
|
68351
|
-
frameContent(entry, event, tool) {
|
|
68352
|
-
const info = entry.info;
|
|
68353
|
-
switch (event) {
|
|
68354
|
-
case "running":
|
|
68355
|
-
return "The turn is running.";
|
|
68356
|
-
case "tool_executing":
|
|
68357
|
-
return `Using ${tool}.`;
|
|
68358
|
-
case "waiting_for_input":
|
|
68359
|
-
return entry.blockText ? `The model asked a question; send_input declines it and becomes the next prompt.
|
|
68360
|
-
${entry.blockText}` : "The turn finished; waiting for send_input.";
|
|
68361
|
-
case "awaiting_permission":
|
|
68362
|
-
return `A permission dialog is open for ${info.activity ?? "a tool"}; send_input declines it and becomes the next prompt.${entry.blockText ? `
|
|
68363
|
-
${entry.blockText}` : ""}`;
|
|
68364
|
-
case "completed":
|
|
68365
|
-
return `Session completed (${info.turnsCompleted} turn(s)). Call get_output for the answer.`;
|
|
68366
|
-
case "cancelled":
|
|
68367
|
-
return "Session cancelled.";
|
|
68368
|
-
case "timeout":
|
|
68369
|
-
return `Timeout after ${info.timeoutSeconds}s; the pane was closed.`;
|
|
68370
|
-
case "failed":
|
|
68371
|
-
return `${info.state} ${info.reason ?? ""}${info.detail ? `: ${info.detail}` : ""}`.trim();
|
|
68372
|
-
default:
|
|
68373
|
-
return "";
|
|
68374
|
-
}
|
|
68375
68416
|
}
|
|
68376
68417
|
sendInput(sessionId, text) {
|
|
68377
68418
|
const entry = this.liveEntry(sessionId);
|
|
@@ -68415,7 +68456,7 @@ ${entry.blockText}` : ""}`;
|
|
|
68415
68456
|
return {
|
|
68416
68457
|
sessionId,
|
|
68417
68458
|
state: info.state,
|
|
68418
|
-
event:
|
|
68459
|
+
event: sessionEventFor(info).event,
|
|
68419
68460
|
reason: isTerminalState(info.state) && info.state !== "COMPLETED" ? info.reason : null,
|
|
68420
68461
|
detail: info.detail,
|
|
68421
68462
|
model: info.model,
|
|
@@ -68439,7 +68480,7 @@ ${entry.blockText}` : ""}`;
|
|
|
68439
68480
|
...this.paneFacts(entry),
|
|
68440
68481
|
recentEvents: limit === 0 ? [] : entry.eventRing.slice(-limit),
|
|
68441
68482
|
eventsTotal: entry.eventRing.length,
|
|
68442
|
-
upstreamErrors:
|
|
68483
|
+
upstreamErrors: readTailLines2(entry.upstreamErrorLogPath, UPSTREAM_ERROR_TAIL_BYTES),
|
|
68443
68484
|
claudeSessionId: info.claudeSessionId,
|
|
68444
68485
|
transcriptPath: info.transcriptPath,
|
|
68445
68486
|
sessionDir: entry.sessionDir,
|
|
@@ -68505,7 +68546,15 @@ ${entry.blockText}` : ""}`;
|
|
|
68505
68546
|
return sessions;
|
|
68506
68547
|
}
|
|
68507
68548
|
listSessionRows(includeCompleted = false) {
|
|
68508
|
-
|
|
68549
|
+
const rows = [];
|
|
68550
|
+
for (const entry of this.sessions.values()) {
|
|
68551
|
+
this.refresh(entry);
|
|
68552
|
+
if (!includeCompleted && isTerminalState(entry.info.state))
|
|
68553
|
+
continue;
|
|
68554
|
+
const info = { ...entry.info };
|
|
68555
|
+
rows.push(sessionRowOf(info, upstreamRecordsFor(info, entry.upstreamErrorLogPath)));
|
|
68556
|
+
}
|
|
68557
|
+
return rows;
|
|
68509
68558
|
}
|
|
68510
68559
|
getSession(sessionId) {
|
|
68511
68560
|
const entry = this.sessions.get(sessionId);
|
|
@@ -68610,13 +68659,13 @@ ${entry.blockText}` : ""}`;
|
|
|
68610
68659
|
const eventLogPath = join48(sessionDir, "events.jsonl");
|
|
68611
68660
|
const upstreamErrorLogPath = join48(sessionDir, "upstream-errors.jsonl");
|
|
68612
68661
|
const outputLogPath = join48(sessionDir, "output.log");
|
|
68613
|
-
const events =
|
|
68662
|
+
const events = readTailLines2(eventLogPath, EVENT_TAIL_BYTES);
|
|
68614
68663
|
const outputTail = readTailText(outputLogPath, OUTPUT_TAIL_BYTES);
|
|
68615
68664
|
const screen = readTailText(join48(sessionDir, "screen.txt"), SCREEN_READ_BYTES);
|
|
68616
68665
|
return {
|
|
68617
68666
|
sessionId: info.sessionId,
|
|
68618
68667
|
state: info.state,
|
|
68619
|
-
event:
|
|
68668
|
+
event: sessionEventFor(info).event,
|
|
68620
68669
|
reason: info.reason,
|
|
68621
68670
|
detail: info.detail,
|
|
68622
68671
|
model: info.model,
|
|
@@ -68666,7 +68715,7 @@ ${entry.blockText}` : ""}`;
|
|
|
68666
68715
|
};
|
|
68667
68716
|
}),
|
|
68668
68717
|
eventsTotal: events.length,
|
|
68669
|
-
upstreamErrors:
|
|
68718
|
+
upstreamErrors: readTailLines2(upstreamErrorLogPath, UPSTREAM_ERROR_TAIL_BYTES),
|
|
68670
68719
|
claudeSessionId: info.claudeSessionId || null,
|
|
68671
68720
|
transcriptPath: info.transcriptPath || null,
|
|
68672
68721
|
sessionDir,
|
|
@@ -68720,7 +68769,7 @@ ${entry.blockText}` : ""}`;
|
|
|
68720
68769
|
entry.eventLogBytes += Buffer.byteLength(payload, "utf-8");
|
|
68721
68770
|
const capped = entry.eventLogBytes >= EVENT_LOG_LIMIT;
|
|
68722
68771
|
try {
|
|
68723
|
-
|
|
68772
|
+
appendFileSync7(entry.eventLogPath, capped ? `${payload}{"type":"claudish_truncated","limit_bytes":${EVENT_LOG_LIMIT}}
|
|
68724
68773
|
` : payload);
|
|
68725
68774
|
} catch {}
|
|
68726
68775
|
}
|
|
@@ -68737,7 +68786,7 @@ ${entry.blockText}` : ""}`;
|
|
|
68737
68786
|
wait: "closed",
|
|
68738
68787
|
since: entry.waitSince ?? at,
|
|
68739
68788
|
at,
|
|
68740
|
-
to:
|
|
68789
|
+
to: sessionEventFor(snap).event
|
|
68741
68790
|
});
|
|
68742
68791
|
entry.waitSince = null;
|
|
68743
68792
|
}
|
|
@@ -68749,7 +68798,7 @@ ${entry.blockText}` : ""}`;
|
|
|
68749
68798
|
`;
|
|
68750
68799
|
entry.waitLogBytes += Buffer.byteLength(payload, "utf-8");
|
|
68751
68800
|
try {
|
|
68752
|
-
|
|
68801
|
+
appendFileSync7(entry.waitLogPath, payload);
|
|
68753
68802
|
} catch (err) {
|
|
68754
68803
|
process.stderr.write(`[claudish] session ${entry.info.sessionId}: could not append to waits.jsonl: ` + `${err instanceof Error ? err.message : String(err)}
|
|
68755
68804
|
`);
|
|
@@ -68883,11 +68932,11 @@ var init_session_manager = __esm(() => {
|
|
|
68883
68932
|
SCREEN_READ_BYTES = 64 * 1024;
|
|
68884
68933
|
});
|
|
68885
68934
|
|
|
68886
|
-
// src/
|
|
68935
|
+
// src/mcp-session/types.ts
|
|
68887
68936
|
var init_types3 = () => {};
|
|
68888
68937
|
|
|
68889
|
-
// src/
|
|
68890
|
-
var
|
|
68938
|
+
// src/mcp-session/index.ts
|
|
68939
|
+
var init_mcp_session = __esm(() => {
|
|
68891
68940
|
init_scrollback_buffer();
|
|
68892
68941
|
init_session_manager();
|
|
68893
68942
|
init_types3();
|
|
@@ -68903,7 +68952,9 @@ This server runs inside a session that a claudish MCP server started (CLAUDISH_P
|
|
|
68903
68952
|
- run_prompt or compare_models: a one-shot answer from another model.
|
|
68904
68953
|
- list_models, search_models: find a model.
|
|
68905
68954
|
|
|
68906
|
-
Do not start a claudish session another way: \`claudish -p\`, an interactive claudish or \`claudish team\` run from this session's shell exits 64 with "nested session refused"
|
|
68955
|
+
Do not start a claudish session another way: \`claudish -p\`, an interactive claudish or \`claudish team\` run from this session's shell exits 64 with "nested session refused".
|
|
68956
|
+
|
|
68957
|
+
You are the delegate: do the task with your own tools; a workflow step that says to delegate is satisfied by you running it. The claudish-usage skill's section "Inside a claudish session (child mode)" has the details.`;
|
|
68907
68958
|
var init_nested_mode = __esm(() => {
|
|
68908
68959
|
NESTED_MCP_TOOL_NAMES = [
|
|
68909
68960
|
"run_prompt",
|
|
@@ -68990,10 +69041,243 @@ var init_progress_heartbeat = __esm(() => {
|
|
|
68990
69041
|
});
|
|
68991
69042
|
});
|
|
68992
69043
|
|
|
69044
|
+
// src/mcp/run-prompt-claude-code.ts
|
|
69045
|
+
import { spawn as spawn2 } from "child_process";
|
|
69046
|
+
import { mkdirSync as mkdirSync21, mkdtempSync as mkdtempSync3, rmSync as rmSync5, writeFileSync as writeFileSync22 } from "fs";
|
|
69047
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
69048
|
+
import { join as join49 } from "path";
|
|
69049
|
+
function claudeCodePrintArgv(model, systemPromptFile) {
|
|
69050
|
+
const head = [PRINT_FLAGS[0], "--model", model, ...PRINT_FLAGS.slice(1)];
|
|
69051
|
+
return systemPromptFile !== undefined ? [...head, "--system-prompt-file", systemPromptFile] : [...head, "--system-prompt", ""];
|
|
69052
|
+
}
|
|
69053
|
+
function claudeCodePrintEnv(parent) {
|
|
69054
|
+
const env = {};
|
|
69055
|
+
for (const [k, v] of Object.entries(parent)) {
|
|
69056
|
+
if (v === undefined || isStrippedFromChildEnv(k))
|
|
69057
|
+
continue;
|
|
69058
|
+
if (PRINT_CHILD_DROPPED_MARKERS.includes(k))
|
|
69059
|
+
continue;
|
|
69060
|
+
env[k] = v;
|
|
69061
|
+
}
|
|
69062
|
+
delete env.ANTHROPIC_API_KEY;
|
|
69063
|
+
delete env.ANTHROPIC_AUTH_TOKEN;
|
|
69064
|
+
delete env.ANTHROPIC_BASE_URL;
|
|
69065
|
+
return env;
|
|
69066
|
+
}
|
|
69067
|
+
function isFrame(v) {
|
|
69068
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
69069
|
+
}
|
|
69070
|
+
function parseJsonDocument(stdout) {
|
|
69071
|
+
const text = stdout.trim();
|
|
69072
|
+
if (!text)
|
|
69073
|
+
return;
|
|
69074
|
+
try {
|
|
69075
|
+
return JSON.parse(text);
|
|
69076
|
+
} catch {
|
|
69077
|
+
const lines = text.split(`
|
|
69078
|
+
`);
|
|
69079
|
+
for (let i = lines.length - 1;i >= 0; i--) {
|
|
69080
|
+
const line = lines[i].trim();
|
|
69081
|
+
if (!line.startsWith("[") && !line.startsWith("{"))
|
|
69082
|
+
continue;
|
|
69083
|
+
try {
|
|
69084
|
+
return JSON.parse(line);
|
|
69085
|
+
} catch {}
|
|
69086
|
+
}
|
|
69087
|
+
return;
|
|
69088
|
+
}
|
|
69089
|
+
}
|
|
69090
|
+
function num(v) {
|
|
69091
|
+
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
69092
|
+
}
|
|
69093
|
+
function parseClaudeCodePrintOutput(stdout) {
|
|
69094
|
+
const doc = parseJsonDocument(stdout);
|
|
69095
|
+
const frames = Array.isArray(doc) ? doc.filter(isFrame) : isFrame(doc) ? [doc] : [];
|
|
69096
|
+
let result;
|
|
69097
|
+
let init;
|
|
69098
|
+
for (const f of frames) {
|
|
69099
|
+
if (f.type === "result")
|
|
69100
|
+
result = f;
|
|
69101
|
+
else if (f.type === "system" && f.subtype === "init" && init === undefined)
|
|
69102
|
+
init = f;
|
|
69103
|
+
}
|
|
69104
|
+
if (!result)
|
|
69105
|
+
return null;
|
|
69106
|
+
const parsed = {
|
|
69107
|
+
result: typeof result.result === "string" ? result.result : "",
|
|
69108
|
+
isError: result.is_error === true,
|
|
69109
|
+
apiErrorStatus: typeof result.api_error_status === "number" ? result.api_error_status : null
|
|
69110
|
+
};
|
|
69111
|
+
if (typeof result.terminal_reason === "string")
|
|
69112
|
+
parsed.terminalReason = result.terminal_reason;
|
|
69113
|
+
if (isFrame(result.usage)) {
|
|
69114
|
+
const u = result.usage;
|
|
69115
|
+
parsed.usage = {
|
|
69116
|
+
input: num(u.input_tokens) + num(u.cache_creation_input_tokens) + num(u.cache_read_input_tokens),
|
|
69117
|
+
output: num(u.output_tokens)
|
|
69118
|
+
};
|
|
69119
|
+
}
|
|
69120
|
+
if (init && typeof init.apiKeySource === "string")
|
|
69121
|
+
parsed.apiKeySource = init.apiKeySource;
|
|
69122
|
+
return parsed;
|
|
69123
|
+
}
|
|
69124
|
+
function authFrom(apiKeySource) {
|
|
69125
|
+
if (apiKeySource === undefined)
|
|
69126
|
+
return;
|
|
69127
|
+
return apiKeySource === "none" ? "subscription" : apiKeySource;
|
|
69128
|
+
}
|
|
69129
|
+
function killGroup(proc) {
|
|
69130
|
+
const send = (sig) => {
|
|
69131
|
+
if (proc.exitCode !== null || proc.signalCode !== null)
|
|
69132
|
+
return;
|
|
69133
|
+
try {
|
|
69134
|
+
if (proc.pid !== undefined)
|
|
69135
|
+
process.kill(-proc.pid, sig);
|
|
69136
|
+
else
|
|
69137
|
+
proc.kill(sig);
|
|
69138
|
+
} catch {
|
|
69139
|
+
try {
|
|
69140
|
+
proc.kill(sig);
|
|
69141
|
+
} catch {}
|
|
69142
|
+
}
|
|
69143
|
+
};
|
|
69144
|
+
send("SIGTERM");
|
|
69145
|
+
const timer = setTimeout(() => send("SIGKILL"), KILL_GRACE_MS);
|
|
69146
|
+
timer.unref?.();
|
|
69147
|
+
}
|
|
69148
|
+
function stopAllClaudeCodePrintChildren() {
|
|
69149
|
+
for (const proc of inFlight2)
|
|
69150
|
+
killGroup(proc);
|
|
69151
|
+
}
|
|
69152
|
+
function stderrTail(stderr) {
|
|
69153
|
+
return sanitizeForReport(stderr.slice(-STDERR_TAIL_CHARS).trim());
|
|
69154
|
+
}
|
|
69155
|
+
async function runPromptViaClaudeCode(model, prompt, systemPrompt, opts = {}) {
|
|
69156
|
+
const signal = opts.signal;
|
|
69157
|
+
if (signal?.aborted)
|
|
69158
|
+
throw new Error("cancelled");
|
|
69159
|
+
const parentEnv = opts.parentEnv ?? process.env;
|
|
69160
|
+
let launch;
|
|
69161
|
+
try {
|
|
69162
|
+
launch = resolveClaudishLaunch(parentEnv);
|
|
69163
|
+
} catch (e) {
|
|
69164
|
+
throw new Error(`cannot start claudish (${parentEnv.CLAUDISH_BIN?.trim() || "claudish"}): ${e instanceof Error ? e.message : String(e)}`);
|
|
69165
|
+
}
|
|
69166
|
+
const root = mkdtempSync3(join49(tmpdir2(), "claudish-run-prompt-"));
|
|
69167
|
+
try {
|
|
69168
|
+
const cwd = join49(root, "cwd");
|
|
69169
|
+
mkdirSync21(cwd, { mode: 448 });
|
|
69170
|
+
let systemPromptFile;
|
|
69171
|
+
if (typeof systemPrompt === "string" && systemPrompt.length > 0) {
|
|
69172
|
+
systemPromptFile = join49(root, "system-prompt.txt");
|
|
69173
|
+
writeFileSync22(systemPromptFile, systemPrompt, { mode: 384 });
|
|
69174
|
+
}
|
|
69175
|
+
const argv = claudeCodePrintArgv(model, systemPromptFile);
|
|
69176
|
+
const outcome = await runChild(launch, argv, cwd, claudeCodePrintEnv(parentEnv), prompt, signal);
|
|
69177
|
+
if (signal?.aborted)
|
|
69178
|
+
throw new Error("cancelled");
|
|
69179
|
+
const parsed = parseClaudeCodePrintOutput(outcome.stdout);
|
|
69180
|
+
if (parsed === null) {
|
|
69181
|
+
const how = outcome.code !== null ? `exited ${outcome.code}` : `exited ${outcome.signal ?? "?"}`;
|
|
69182
|
+
const tail = stderrTail(outcome.stderr);
|
|
69183
|
+
const noFrame = outcome.code === 0 ? " with no result frame in its output" : "";
|
|
69184
|
+
throw new Error(`claudish -p ${how}${noFrame}${tail ? `: ${tail}` : ""}`);
|
|
69185
|
+
}
|
|
69186
|
+
if (parsed.isError) {
|
|
69187
|
+
const status = parsed.apiErrorStatus !== null ? ` (HTTP ${parsed.apiErrorStatus})` : "";
|
|
69188
|
+
throw new Error(`Claude Code: ${parsed.result || parsed.terminalReason || "error"}${status}`);
|
|
69189
|
+
}
|
|
69190
|
+
if (parsed.result === "")
|
|
69191
|
+
throw new Error("Model returned empty response");
|
|
69192
|
+
const answer = { content: parsed.result };
|
|
69193
|
+
if (parsed.usage)
|
|
69194
|
+
answer.usage = parsed.usage;
|
|
69195
|
+
const auth = authFrom(parsed.apiKeySource);
|
|
69196
|
+
if (auth !== undefined)
|
|
69197
|
+
answer.auth = auth;
|
|
69198
|
+
return answer;
|
|
69199
|
+
} finally {
|
|
69200
|
+
rmSync5(root, { recursive: true, force: true });
|
|
69201
|
+
}
|
|
69202
|
+
}
|
|
69203
|
+
function runChild(launch, argv, cwd, env, prompt, signal) {
|
|
69204
|
+
return new Promise((resolvePromise, reject) => {
|
|
69205
|
+
let proc;
|
|
69206
|
+
try {
|
|
69207
|
+
proc = spawn2(launch.command, [...launch.prefixArgs, ...argv], {
|
|
69208
|
+
cwd,
|
|
69209
|
+
env,
|
|
69210
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
69211
|
+
detached: true
|
|
69212
|
+
});
|
|
69213
|
+
} catch (e) {
|
|
69214
|
+
reject(startError(launch.command, e));
|
|
69215
|
+
return;
|
|
69216
|
+
}
|
|
69217
|
+
let stdout = "";
|
|
69218
|
+
let stderr = "";
|
|
69219
|
+
let settled = false;
|
|
69220
|
+
const onAbort = () => killGroup(proc);
|
|
69221
|
+
const finish = (fn) => {
|
|
69222
|
+
if (settled)
|
|
69223
|
+
return;
|
|
69224
|
+
settled = true;
|
|
69225
|
+
inFlight2.delete(proc);
|
|
69226
|
+
signal?.removeEventListener("abort", onAbort);
|
|
69227
|
+
fn();
|
|
69228
|
+
};
|
|
69229
|
+
proc.stdout?.setEncoding("utf8");
|
|
69230
|
+
proc.stderr?.setEncoding("utf8");
|
|
69231
|
+
proc.stdout?.on("data", (chunk) => {
|
|
69232
|
+
stdout += chunk;
|
|
69233
|
+
});
|
|
69234
|
+
proc.stderr?.on("data", (chunk) => {
|
|
69235
|
+
stderr += chunk;
|
|
69236
|
+
});
|
|
69237
|
+
proc.stdin?.on("error", () => {});
|
|
69238
|
+
proc.on("error", (e) => finish(() => reject(startError(launch.command, e))));
|
|
69239
|
+
proc.on("close", (code, sig) => finish(() => resolvePromise({ code, signal: sig, stdout, stderr })));
|
|
69240
|
+
inFlight2.add(proc);
|
|
69241
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
69242
|
+
if (signal?.aborted)
|
|
69243
|
+
onAbort();
|
|
69244
|
+
proc.stdin?.end(prompt);
|
|
69245
|
+
});
|
|
69246
|
+
}
|
|
69247
|
+
function startError(command, e) {
|
|
69248
|
+
const code = e?.code;
|
|
69249
|
+
const detail = typeof code === "string" ? code : e instanceof Error ? e.message : String(e ?? "unknown");
|
|
69250
|
+
return new Error(`cannot start claudish (${command}): ${detail}`);
|
|
69251
|
+
}
|
|
69252
|
+
var PRINT_FLAGS, PRINT_CHILD_DROPPED_MARKERS, inFlight2, KILL_GRACE_MS = 5000, STDERR_TAIL_CHARS = 2000;
|
|
69253
|
+
var init_run_prompt_claude_code = __esm(() => {
|
|
69254
|
+
init_config();
|
|
69255
|
+
init_child_env();
|
|
69256
|
+
init_pane_launch();
|
|
69257
|
+
init_redact();
|
|
69258
|
+
PRINT_FLAGS = [
|
|
69259
|
+
"-p",
|
|
69260
|
+
"--output-format",
|
|
69261
|
+
"json",
|
|
69262
|
+
"--tools",
|
|
69263
|
+
"",
|
|
69264
|
+
"--strict-mcp-config",
|
|
69265
|
+
"--setting-sources",
|
|
69266
|
+
"",
|
|
69267
|
+
"--disable-slash-commands",
|
|
69268
|
+
"--no-session-persistence"
|
|
69269
|
+
];
|
|
69270
|
+
PRINT_CHILD_DROPPED_MARKERS = [
|
|
69271
|
+
...PANE_LAUNCH_VARS,
|
|
69272
|
+
ENV.CLAUDISH_PANE_CHILD
|
|
69273
|
+
];
|
|
69274
|
+
inFlight2 = new Set;
|
|
69275
|
+
});
|
|
69276
|
+
|
|
68993
69277
|
// src/mcp-server.ts
|
|
68994
|
-
import { existsSync as existsSync32, mkdirSync as
|
|
69278
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync22, readFileSync as readFileSync31, readdirSync as readdirSync10, writeFileSync as writeFileSync23 } from "fs";
|
|
68995
69279
|
import { homedir as homedir33 } from "os";
|
|
68996
|
-
import { dirname as dirname14, join as
|
|
69280
|
+
import { dirname as dirname14, join as join50, resolve as resolve6 } from "path";
|
|
68997
69281
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
68998
69282
|
async function loadAllModels(forceRefresh = false) {
|
|
68999
69283
|
if (!forceRefresh && existsSync32(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
@@ -69012,8 +69296,8 @@ async function loadAllModels(forceRefresh = false) {
|
|
|
69012
69296
|
throw new Error(`API returned ${response.status}`);
|
|
69013
69297
|
const data = await response.json();
|
|
69014
69298
|
const models = data.data || [];
|
|
69015
|
-
|
|
69016
|
-
|
|
69299
|
+
mkdirSync22(CLAUDISH_CACHE_DIR, { recursive: true });
|
|
69300
|
+
writeFileSync23(OPENROUTER_MODELS_CACHE_PATH, JSON.stringify({ lastUpdated: new Date().toISOString(), models }), "utf-8");
|
|
69017
69301
|
return models;
|
|
69018
69302
|
} catch {
|
|
69019
69303
|
if (existsSync32(OPENROUTER_MODELS_CACHE_PATH)) {
|
|
@@ -69069,12 +69353,11 @@ function parseAnthropicSse(raw) {
|
|
|
69069
69353
|
}
|
|
69070
69354
|
return { text, usage: hasUsage ? { input: inputTokens, output: outputTokens } : undefined };
|
|
69071
69355
|
}
|
|
69072
|
-
async function runPromptViaProxy(model, prompt, systemPrompt
|
|
69356
|
+
async function runPromptViaProxy(model, prompt, systemPrompt) {
|
|
69073
69357
|
const proxy = await getProxy();
|
|
69074
69358
|
const body = {
|
|
69075
69359
|
model,
|
|
69076
69360
|
messages: [{ role: "user", content: prompt }],
|
|
69077
|
-
max_tokens: maxTokens || 4096,
|
|
69078
69361
|
stream: true
|
|
69079
69362
|
};
|
|
69080
69363
|
if (systemPrompt) {
|
|
@@ -69096,6 +69379,26 @@ async function runPromptViaProxy(model, prompt, systemPrompt, maxTokens) {
|
|
|
69096
69379
|
}
|
|
69097
69380
|
return { content: parsed.text, usage: parsed.usage };
|
|
69098
69381
|
}
|
|
69382
|
+
async function runPrompt(model, prompt, systemPrompt, signal) {
|
|
69383
|
+
if (nativeRouteFor(model) !== null) {
|
|
69384
|
+
return runPromptViaClaudeCode(model, prompt, systemPrompt, { signal });
|
|
69385
|
+
}
|
|
69386
|
+
return runPromptViaProxy(model, prompt, systemPrompt);
|
|
69387
|
+
}
|
|
69388
|
+
function formatRunPromptResult(result) {
|
|
69389
|
+
const footer = [];
|
|
69390
|
+
if (result.usage) {
|
|
69391
|
+
footer.push(`Tokens: ${result.usage.input} input, ${result.usage.output} output`);
|
|
69392
|
+
}
|
|
69393
|
+
if (result.auth !== undefined) {
|
|
69394
|
+
footer.push(result.auth === "subscription" ? "Auth: Claude Code login (subscription)" : `Auth: ${result.auth}`);
|
|
69395
|
+
}
|
|
69396
|
+
return footer.length > 0 ? `${result.content}
|
|
69397
|
+
|
|
69398
|
+
---
|
|
69399
|
+
${footer.join(`
|
|
69400
|
+
`)}` : result.content;
|
|
69401
|
+
}
|
|
69099
69402
|
function fuzzyScore(text, query) {
|
|
69100
69403
|
const lowerText = text.toLowerCase();
|
|
69101
69404
|
const lowerQuery = query.toLowerCase();
|
|
@@ -69310,7 +69613,7 @@ async function teamContractVerb(mode, args) {
|
|
|
69310
69613
|
return contractErrorAnswer(e);
|
|
69311
69614
|
}
|
|
69312
69615
|
}
|
|
69313
|
-
function defineTools(sessionManager,
|
|
69616
|
+
function defineTools(sessionManager, nested) {
|
|
69314
69617
|
const tools = [];
|
|
69315
69618
|
const reportHint = (text) => nested ? "" : text;
|
|
69316
69619
|
function withOpFailureContext(message, subject) {
|
|
@@ -69322,33 +69625,25 @@ ${block.join(`
|
|
|
69322
69625
|
}
|
|
69323
69626
|
tools.push({
|
|
69324
69627
|
name: "run_prompt",
|
|
69325
|
-
description: "
|
|
69628
|
+
description: "One quick prompt, straight to one model's API: a single request and its answer. No " + "Claude Code session, no tools, no files, no conversation state \u2014 this is not subagent " + "work. For a task that needs tools, files or more than one turn, use create_session " + "(one model) or team (several models). Non-Claude models (Kimi, GLM, Qwen, MiniMax, " + "Gemini, GPT, Grok, \u2026) go through claudish's routing straight to the provider's API. " + "A Claude model name (claude-*, opus, sonnet, haiku) runs as one Claude Code " + "print-mode call on the user's own Claude Code login, with tools, MCP servers and " + "settings off.",
|
|
69326
69629
|
inputSchema: {
|
|
69327
69630
|
type: "object",
|
|
69328
69631
|
properties: {
|
|
69329
69632
|
model: {
|
|
69330
69633
|
type: "string",
|
|
69331
|
-
description: "Model name or
|
|
69634
|
+
description: "Model name or model spec. A bare name auto-routes to the best provider; " + "'provider@model' pins the provider (e.g. 'google@gemini-4-argon', " + "'or@x-ai/grok-4.7'). A bare Claude name (claude-*, opus, sonnet, haiku) runs on " + "Claude Code's own login."
|
|
69332
69635
|
},
|
|
69333
69636
|
prompt: { type: "string", description: "The prompt to send to the model" },
|
|
69334
|
-
system_prompt: { type: "string", description: "Optional system prompt" }
|
|
69335
|
-
max_tokens: { type: "number", description: "Maximum tokens in response (default: 4096)" }
|
|
69637
|
+
system_prompt: { type: "string", description: "Optional system prompt" }
|
|
69336
69638
|
},
|
|
69337
69639
|
required: ["model", "prompt"]
|
|
69338
69640
|
},
|
|
69339
69641
|
group: "low-level",
|
|
69340
69642
|
heartbeat: true,
|
|
69341
|
-
handler: async (args) => {
|
|
69643
|
+
handler: async (args, ctx) => {
|
|
69342
69644
|
try {
|
|
69343
|
-
const result = await
|
|
69344
|
-
|
|
69345
|
-
if (result.usage) {
|
|
69346
|
-
response += `
|
|
69347
|
-
|
|
69348
|
-
---
|
|
69349
|
-
Tokens: ${result.usage.input} input, ${result.usage.output} output`;
|
|
69350
|
-
}
|
|
69351
|
-
return { content: [{ type: "text", text: response }] };
|
|
69645
|
+
const result = await runPrompt(args.model, args.prompt, args.system_prompt, ctx.signal);
|
|
69646
|
+
return { content: [{ type: "text", text: formatRunPromptResult(result) }] };
|
|
69352
69647
|
} catch (error) {
|
|
69353
69648
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
69354
69649
|
return {
|
|
@@ -69500,35 +69795,30 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
69500
69795
|
});
|
|
69501
69796
|
tools.push({
|
|
69502
69797
|
name: "compare_models",
|
|
69503
|
-
description: "
|
|
69798
|
+
description: "DEBUG. Send the same single prompt to several models, one after another, and show " + "their answers side by side \u2014 to check that routes answer or to eyeball raw answers. " + "Each model gets exactly what run_prompt sends: one request, no tools, no Claude Code " + "session. Not for real work: use team for a blind-judged multi-model run, or " + "create_session for one model doing a task.",
|
|
69504
69799
|
inputSchema: {
|
|
69505
69800
|
type: "object",
|
|
69506
69801
|
properties: {
|
|
69507
69802
|
models: {
|
|
69508
69803
|
type: "array",
|
|
69509
69804
|
items: { type: "string" },
|
|
69510
|
-
description: "List of model
|
|
69805
|
+
description: "List of model names or model specs to compare, in the order to run them"
|
|
69511
69806
|
},
|
|
69512
69807
|
prompt: { type: "string", description: "The prompt to send to all models" },
|
|
69513
|
-
system_prompt: { type: "string", description: "Optional system prompt" }
|
|
69514
|
-
max_tokens: {
|
|
69515
|
-
type: "number",
|
|
69516
|
-
description: "Maximum tokens in response (omit to let model decide)"
|
|
69517
|
-
}
|
|
69808
|
+
system_prompt: { type: "string", description: "Optional system prompt" }
|
|
69518
69809
|
},
|
|
69519
69810
|
required: ["models", "prompt"]
|
|
69520
69811
|
},
|
|
69521
|
-
group: "
|
|
69812
|
+
group: "debug",
|
|
69522
69813
|
heartbeat: true,
|
|
69523
69814
|
handler: async (args, ctx) => {
|
|
69524
69815
|
const modelIds = args.models;
|
|
69525
69816
|
const prompt = args.prompt;
|
|
69526
69817
|
const systemPrompt = args.system_prompt;
|
|
69527
|
-
const maxTokens = args.max_tokens;
|
|
69528
69818
|
const results = [];
|
|
69529
69819
|
for (const model of modelIds) {
|
|
69530
69820
|
try {
|
|
69531
|
-
const result = await
|
|
69821
|
+
const result = await runPrompt(model, prompt, systemPrompt, ctx.signal);
|
|
69532
69822
|
results.push({ model, response: result.content, tokens: result.usage });
|
|
69533
69823
|
} catch (error) {
|
|
69534
69824
|
results.push({
|
|
@@ -69782,28 +70072,18 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
69782
70072
|
const minOutputBytes = args.min_output_bytes;
|
|
69783
70073
|
const childFlags = buildChildClaudeFlags(args.agent, args.claude_flags) ?? [];
|
|
69784
70074
|
const resolved = validateSessionPath(path);
|
|
69785
|
-
const teamSessionId = resolved.split("/").filter(Boolean).pop() ?? "team";
|
|
69786
|
-
const teamCreatedAt = new Date().toISOString();
|
|
69787
70075
|
const runOpts = {
|
|
69788
70076
|
requirePattern,
|
|
69789
70077
|
minOutputBytes,
|
|
69790
70078
|
claudeFlags: childFlags,
|
|
69791
70079
|
onProgress: (u) => {
|
|
69792
70080
|
ctx.reportProgress(`team: ${u.phase}`);
|
|
69793
|
-
notifyChannel({
|
|
69794
|
-
content: u.rendered,
|
|
69795
|
-
sessionId: teamSessionId,
|
|
69796
|
-
event: u.phase === "settled" ? u.allFailed ? "failed" : "completed" : "running",
|
|
69797
|
-
model: "team",
|
|
69798
|
-
elapsedSeconds: (Date.now() - Date.parse(teamCreatedAt)) / 1000,
|
|
69799
|
-
createdAt: teamCreatedAt
|
|
69800
|
-
});
|
|
69801
70081
|
}
|
|
69802
70082
|
};
|
|
69803
70083
|
const promptText = () => {
|
|
69804
70084
|
if (input !== undefined)
|
|
69805
70085
|
return input;
|
|
69806
|
-
const existing =
|
|
70086
|
+
const existing = join50(resolved, "input.md");
|
|
69807
70087
|
return existsSync32(existing) ? readFileSync31(existing, "utf-8") : undefined;
|
|
69808
70088
|
};
|
|
69809
70089
|
switch (mode) {
|
|
@@ -69962,16 +70242,16 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
69962
70242
|
const sp = session_path;
|
|
69963
70243
|
for (const file of ["status.json", "manifest.json", "input.md"]) {
|
|
69964
70244
|
try {
|
|
69965
|
-
sessionData[file] = readFileSync31(
|
|
70245
|
+
sessionData[file] = readFileSync31(join50(sp, file), "utf-8");
|
|
69966
70246
|
} catch {}
|
|
69967
70247
|
}
|
|
69968
70248
|
try {
|
|
69969
|
-
const errorDir =
|
|
70249
|
+
const errorDir = join50(sp, "errors");
|
|
69970
70250
|
if (existsSync32(errorDir)) {
|
|
69971
70251
|
for (const f of readdirSync10(errorDir)) {
|
|
69972
70252
|
if (f.endsWith(".log")) {
|
|
69973
70253
|
try {
|
|
69974
|
-
sessionData[`errors/${f}`] = readFileSync31(
|
|
70254
|
+
sessionData[`errors/${f}`] = readFileSync31(join50(errorDir, f), "utf-8");
|
|
69975
70255
|
} catch {}
|
|
69976
70256
|
}
|
|
69977
70257
|
}
|
|
@@ -69981,7 +70261,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
69981
70261
|
for (const f of readdirSync10(sp)) {
|
|
69982
70262
|
if (f.startsWith("response-") && f.endsWith(".md")) {
|
|
69983
70263
|
try {
|
|
69984
|
-
const content = readFileSync31(
|
|
70264
|
+
const content = readFileSync31(join50(sp, f), "utf-8");
|
|
69985
70265
|
sessionData[f] = content.slice(0, 200) + (content.length > 200 ? "... (truncated)" : "");
|
|
69986
70266
|
} catch {}
|
|
69987
70267
|
}
|
|
@@ -69990,7 +70270,7 @@ Use with: run_prompt(model="${suggested}", prompt="your prompt")`;
|
|
|
69990
70270
|
}
|
|
69991
70271
|
let version = "unknown";
|
|
69992
70272
|
try {
|
|
69993
|
-
const pkgPath =
|
|
70273
|
+
const pkgPath = join50(__dirname3, "../package.json");
|
|
69994
70274
|
if (existsSync32(pkgPath)) {
|
|
69995
70275
|
version = JSON.parse(readFileSync31(pkgPath, "utf-8")).version;
|
|
69996
70276
|
}
|
|
@@ -70070,7 +70350,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70070
70350
|
});
|
|
70071
70351
|
tools.push({
|
|
70072
70352
|
name: "create_session",
|
|
70073
|
-
description: "Create a new claudish proxy session for an external model: an interactive Claude Code running " + "it in its own headless magmux pane. Returns at once with state STARTING;
|
|
70353
|
+
description: "Create a new claudish proxy session for an external model: an interactive Claude Code running " + "it in its own headless magmux pane. Returns at once with state STARTING; nothing is " + "pushed while it runs: poll list_sessions (about once every 10 s) for its state, then " + "call get_output once it is COMPLETED. With a prompt it is one-shot (it ends when that turn " + "settles); without one it is interactive and waits for send_input. Needs magmux >= 0.14.0 " + "(darwin and linux).",
|
|
70074
70354
|
inputSchema: {
|
|
70075
70355
|
type: "object",
|
|
70076
70356
|
properties: {
|
|
@@ -70103,7 +70383,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70103
70383
|
},
|
|
70104
70384
|
required: ["model"]
|
|
70105
70385
|
},
|
|
70106
|
-
group: "
|
|
70386
|
+
group: "session",
|
|
70107
70387
|
handler: async (args) => {
|
|
70108
70388
|
try {
|
|
70109
70389
|
const claudishFlags = buildChildClaudeFlags(args.agent, args.claude_flags) ?? [];
|
|
@@ -70171,7 +70451,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70171
70451
|
},
|
|
70172
70452
|
required: ["session_id", "text"]
|
|
70173
70453
|
},
|
|
70174
|
-
group: "
|
|
70454
|
+
group: "session",
|
|
70175
70455
|
handler: async (args) => {
|
|
70176
70456
|
const result = sessionManager.sendInput(args.session_id, args.text);
|
|
70177
70457
|
return {
|
|
@@ -70181,7 +70461,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70181
70461
|
});
|
|
70182
70462
|
tools.push({
|
|
70183
70463
|
name: "get_output",
|
|
70184
|
-
description: "Get a session's answer prose (each settled turn's assistant text, from its transcript). " + "Call
|
|
70464
|
+
description: "Get a session's answer prose (each settled turn's assistant text, from its transcript). " + "Call once list_sessions shows the session COMPLETED (or between turns of an " + "interactive session).",
|
|
70185
70465
|
inputSchema: {
|
|
70186
70466
|
type: "object",
|
|
70187
70467
|
properties: {
|
|
@@ -70193,7 +70473,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70193
70473
|
},
|
|
70194
70474
|
required: ["session_id"]
|
|
70195
70475
|
},
|
|
70196
|
-
group: "
|
|
70476
|
+
group: "session",
|
|
70197
70477
|
handler: async (args) => {
|
|
70198
70478
|
try {
|
|
70199
70479
|
const output = sessionManager.getOutput(args.session_id, args.tail_lines);
|
|
@@ -70223,7 +70503,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70223
70503
|
},
|
|
70224
70504
|
required: ["session_id"]
|
|
70225
70505
|
},
|
|
70226
|
-
group: "
|
|
70506
|
+
group: "session",
|
|
70227
70507
|
handler: async (args) => {
|
|
70228
70508
|
try {
|
|
70229
70509
|
const sessionId = optionalString(args.session_id, "session_id");
|
|
@@ -70237,7 +70517,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70237
70517
|
});
|
|
70238
70518
|
tools.push({
|
|
70239
70519
|
name: "list_sessions",
|
|
70240
|
-
description: "List
|
|
70520
|
+
description: "List sessions: {contract_version, capabilities, sessions}. Optionally include " + "finished ones. Each row reports `state`, `activity` and `idle_seconds`: how long since " + "the session's screen or transcript last changed. Nothing kills a session for being " + "idle \u2014 a child inside a long Bash call is silent and working \u2014 so this is yours to " + "judge against the task you set, and `cancel_session` is yours to call if the answer is no. " + "A failed row's `reason_detail` is one line saying why (for api_error, the provider's " + "own error message); it is null while the session is live and on COMPLETED.",
|
|
70241
70521
|
inputSchema: {
|
|
70242
70522
|
type: "object",
|
|
70243
70523
|
properties: {
|
|
@@ -70247,7 +70527,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70247
70527
|
}
|
|
70248
70528
|
}
|
|
70249
70529
|
},
|
|
70250
|
-
group: "
|
|
70530
|
+
group: "session",
|
|
70251
70531
|
handler: async (args) => {
|
|
70252
70532
|
try {
|
|
70253
70533
|
const includeCompleted = optionalBoolean(args.include_completed, "include_completed");
|
|
@@ -70262,7 +70542,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70262
70542
|
});
|
|
70263
70543
|
tools.push({
|
|
70264
70544
|
name: "get_diagnostics",
|
|
70265
|
-
description: "Explain what a
|
|
70545
|
+
description: "Explain what a session actually did \u2014 its final screen, upstream error bodies, " + "the recent state records, anomalies, the resolved model chain, accounting, and the paths " + "to the full records (transcript included). Call this FIRST whenever a session fails, times " + "out, or completes with empty or surprising output; it needs no re-run and no debug flag. " + "`idleSeconds` reports how long since the screen or transcript last changed, and is null " + "once the session is no longer live. It is information, never a verdict: claudish does " + "not terminate a session for silence.",
|
|
70266
70546
|
inputSchema: {
|
|
70267
70547
|
type: "object",
|
|
70268
70548
|
properties: {
|
|
@@ -70274,7 +70554,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70274
70554
|
},
|
|
70275
70555
|
required: ["session_id"]
|
|
70276
70556
|
},
|
|
70277
|
-
group: "
|
|
70557
|
+
group: "session",
|
|
70278
70558
|
handler: async (args) => {
|
|
70279
70559
|
try {
|
|
70280
70560
|
const diagnostics = sessionManager.getDiagnostics(args.session_id, args.event_limit);
|
|
@@ -70312,7 +70592,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
70312
70592
|
},
|
|
70313
70593
|
required: ["session_id"]
|
|
70314
70594
|
},
|
|
70315
|
-
group: "
|
|
70595
|
+
group: "session",
|
|
70316
70596
|
handler: async (args) => {
|
|
70317
70597
|
try {
|
|
70318
70598
|
const sessionId = optionalString(args.session_id, "session_id");
|
|
@@ -70334,77 +70614,34 @@ function resolveToolGroups(mode) {
|
|
|
70334
70614
|
return new Set(["low-level"]);
|
|
70335
70615
|
case "agentic":
|
|
70336
70616
|
return new Set(["agentic"]);
|
|
70337
|
-
case "
|
|
70338
|
-
return new Set(["
|
|
70617
|
+
case "session":
|
|
70618
|
+
return new Set(["session"]);
|
|
70619
|
+
case "debug":
|
|
70620
|
+
return new Set(["debug"]);
|
|
70339
70621
|
default:
|
|
70340
|
-
return new Set(["low-level", "agentic", "
|
|
70622
|
+
return new Set(["low-level", "agentic", "session", "debug"]);
|
|
70341
70623
|
}
|
|
70342
70624
|
}
|
|
70343
|
-
function
|
|
70344
|
-
|
|
70625
|
+
function unknownToolModeWarning(mode) {
|
|
70626
|
+
if (TOOL_MODES.includes(mode))
|
|
70627
|
+
return;
|
|
70628
|
+
const renamed = mode === "channel" ? " (`channel` was renamed to `session`)" : "";
|
|
70629
|
+
return `[claudish] CLAUDISH_MCP_TOOLS=${JSON.stringify(mode)} is not a tool mode${renamed}; selecting all tools. Valid values: ${TOOL_MODES.join(", ")}`;
|
|
70345
70630
|
}
|
|
70346
70631
|
async function main() {
|
|
70347
70632
|
const toolMode = (process.env.CLAUDISH_MCP_TOOLS || "all").toLowerCase();
|
|
70348
70633
|
const nested = inMcpSession();
|
|
70349
70634
|
const enabledGroups = resolveToolGroups(toolMode);
|
|
70350
|
-
const
|
|
70351
|
-
|
|
70352
|
-
|
|
70353
|
-
|
|
70354
|
-
|
|
70355
|
-
},
|
|
70635
|
+
const toolModeWarning = unknownToolModeWarning(toolMode);
|
|
70636
|
+
if (toolModeWarning)
|
|
70637
|
+
console.error(toolModeWarning);
|
|
70638
|
+
const server = new Server({ name: "claudish", version: VERSION }, {
|
|
70639
|
+
capabilities: { tools: {} },
|
|
70356
70640
|
instructions: nested ? NESTED_INSTRUCTIONS : INSTRUCTIONS
|
|
70357
70641
|
});
|
|
70358
|
-
const sessionManager = new SessionManager
|
|
70359
|
-
onStateChange: wrapStateChange((sessionId, event) => {
|
|
70360
|
-
const notificationContent = event.type === "failed" || event.type === "timeout" ? `${event.content}
|
|
70361
|
-
|
|
70362
|
-
Call get_diagnostics with session_id: "${sessionId}" for the final screen, the upstream error bodies and the transcript path. To report it, use the report_error tool with error_type: "provider_failure" and model: "${event.model}".` : event.content;
|
|
70363
|
-
const result = server.notification({
|
|
70364
|
-
method: "notifications/claude/channel",
|
|
70365
|
-
params: {
|
|
70366
|
-
content: notificationContent,
|
|
70367
|
-
meta: {
|
|
70368
|
-
session_id: sessionId,
|
|
70369
|
-
event: event.type,
|
|
70370
|
-
model: event.model,
|
|
70371
|
-
elapsed_seconds: String(event.elapsedSeconds),
|
|
70372
|
-
task_id: sessionId,
|
|
70373
|
-
status: mapEventToTaskStatus(event.type),
|
|
70374
|
-
created_at: event.createdAt,
|
|
70375
|
-
last_updated_at: new Date().toISOString(),
|
|
70376
|
-
...event.extraMeta
|
|
70377
|
-
}
|
|
70378
|
-
}
|
|
70379
|
-
});
|
|
70380
|
-
watchNotificationResult(result, { sessionId, eventType: event.type });
|
|
70381
|
-
})
|
|
70382
|
-
});
|
|
70383
|
-
const notifyChannel = (p) => {
|
|
70384
|
-
if (!channelEnabled)
|
|
70385
|
-
return;
|
|
70386
|
-
try {
|
|
70387
|
-
const result = server.notification({
|
|
70388
|
-
method: "notifications/claude/channel",
|
|
70389
|
-
params: {
|
|
70390
|
-
content: p.content,
|
|
70391
|
-
meta: {
|
|
70392
|
-
session_id: p.sessionId,
|
|
70393
|
-
event: p.event,
|
|
70394
|
-
model: p.model,
|
|
70395
|
-
elapsed_seconds: String(Math.round(p.elapsedSeconds)),
|
|
70396
|
-
task_id: p.sessionId,
|
|
70397
|
-
status: mapEventToTaskStatus(p.event),
|
|
70398
|
-
created_at: p.createdAt,
|
|
70399
|
-
last_updated_at: new Date().toISOString()
|
|
70400
|
-
}
|
|
70401
|
-
}
|
|
70402
|
-
});
|
|
70403
|
-
watchNotificationResult(result, { sessionId: p.sessionId, eventType: p.event });
|
|
70404
|
-
} catch {}
|
|
70405
|
-
};
|
|
70642
|
+
const sessionManager = new SessionManager;
|
|
70406
70643
|
const progressIntervalMs = resolveProgressIntervalMs();
|
|
70407
|
-
const allTools = defineTools(sessionManager,
|
|
70644
|
+
const allTools = defineTools(sessionManager, nested);
|
|
70408
70645
|
const nestedNames = NESTED_MCP_TOOL_NAMES;
|
|
70409
70646
|
const enabledTools = allTools.filter((t) => enabledGroups.has(t.group) && (!nested || nestedNames.includes(t.name)));
|
|
70410
70647
|
const toolMap = new Map(enabledTools.map((t) => [t.name, t]));
|
|
@@ -70432,7 +70669,8 @@ Call get_diagnostics with session_id: "${sessionId}" for the final screen, the u
|
|
|
70432
70669
|
send: (frame) => extra.sendNotification({ method: "notifications/progress", params: frame })
|
|
70433
70670
|
}) : NOOP_HEARTBEAT;
|
|
70434
70671
|
const ctx = {
|
|
70435
|
-
reportProgress: (message) => heartbeat.tick(message)
|
|
70672
|
+
reportProgress: (message) => heartbeat.tick(message),
|
|
70673
|
+
signal: extra.signal
|
|
70436
70674
|
};
|
|
70437
70675
|
try {
|
|
70438
70676
|
return await tool.handler(args ?? {}, ctx);
|
|
@@ -70451,7 +70689,6 @@ Call get_diagnostics with session_id: "${sessionId}" for the final screen, the u
|
|
|
70451
70689
|
}
|
|
70452
70690
|
});
|
|
70453
70691
|
const transport = new StdioServerTransport;
|
|
70454
|
-
installWireTap();
|
|
70455
70692
|
await server.connect(transport);
|
|
70456
70693
|
installMcpShutdown(sessionManager);
|
|
70457
70694
|
ensureSwept(sockRootFor()).catch(() => {
|
|
@@ -70460,6 +70697,7 @@ Call get_diagnostics with session_id: "${sessionId}" for the final screen, the u
|
|
|
70460
70697
|
}
|
|
70461
70698
|
function installMcpShutdown(sessionManager) {
|
|
70462
70699
|
const before = async () => {
|
|
70700
|
+
stopAllClaudeCodePrintChildren();
|
|
70463
70701
|
await Promise.allSettled([shutdownAllTeamRuns(), sessionManager.shutdownAll()]);
|
|
70464
70702
|
};
|
|
70465
70703
|
installPaneShutdownHooks({ stdin: true, before });
|
|
@@ -70470,50 +70708,43 @@ function startMcpServer() {
|
|
|
70470
70708
|
process.exit(1);
|
|
70471
70709
|
});
|
|
70472
70710
|
}
|
|
70473
|
-
var import_dotenv2, __filename3, __dirname3, CLAUDISH_CACHE_DIR, OPENROUTER_MODELS_CACHE_PATH, CACHE_MAX_AGE_DAYS = 2, INSTRUCTIONS = `Claudish MCP server
|
|
70474
|
-
|
|
70475
|
-
## Channel Mode \u2014 External Model Sessions
|
|
70711
|
+
var import_dotenv2, __filename3, __dirname3, CLAUDISH_CACHE_DIR, OPENROUTER_MODELS_CACHE_PATH, CACHE_MAX_AGE_DAYS = 2, INSTRUCTIONS = `Claudish MCP server gives you access to external AI models (OpenRouter, Ollama, LM Studio and every claudish provider), and to Claude models on the user's own Claude Code login.
|
|
70476
70712
|
|
|
70477
|
-
|
|
70713
|
+
## Which tool
|
|
70478
70714
|
|
|
70479
|
-
|
|
70715
|
+
- run_prompt: one quick prompt to one model's API. One request, one answer; no tools, no files, no session.
|
|
70716
|
+
- create_session: one model doing a task as a full Claude Code session (tools, files, several turns).
|
|
70717
|
+
- team: several models on the same task, each a full Claude Code session, with optional blind judging.
|
|
70480
70718
|
|
|
70481
|
-
|
|
70482
|
-
- tool_executing: The model is using a tool (Read, Write, Bash, etc.). Carries tool and tool_count.
|
|
70483
|
-
- input_required (event waiting_for_input): The session waits for send_input: an interactive session between turns, or a session stopped on a question (meta activity "AskUserQuestion"). A send declines a question and becomes the next prompt.
|
|
70484
|
-
- input_required (event awaiting_permission): A permission or plan-approval dialog is open. A send declines it and becomes the next prompt.
|
|
70485
|
-
- completed: The session finished successfully. Call get_output to retrieve the full output.
|
|
70486
|
-
- failed: The session failed (boot, prompt not accepted or not read, child exited, API error, pane lost). Call get_diagnostics for the cause.
|
|
70487
|
-
- timeout: The session hit its timeout_seconds; the pane was closed. Call get_diagnostics to see how far it got.
|
|
70488
|
-
- cancelled: The session was cancelled via cancel_session.
|
|
70719
|
+
## Sessions
|
|
70489
70720
|
|
|
70490
|
-
|
|
70721
|
+
Each session is an interactive Claude Code running the model in its own headless terminal pane. Nothing is pushed to you while it runs: poll.
|
|
70491
70722
|
|
|
70492
|
-
1.
|
|
70493
|
-
2.
|
|
70494
|
-
|
|
70495
|
-
|
|
70496
|
-
|
|
70497
|
-
|
|
70498
|
-
|
|
70499
|
-
|
|
70500
|
-
|
|
70501
|
-
|
|
70502
|
-
|
|
70723
|
+
1. create_session returns {session_id, state: "STARTING"} at once while Claude Code boots.
|
|
70724
|
+
2. Poll list_sessions (include_completed: true), about once every 10 seconds. Each row has state, activity, idle_seconds and accounting.
|
|
70725
|
+
- STARTING: booting, or the first prompt is not yet accepted.
|
|
70726
|
+
- RUNNING: a turn is in progress (activity names the tool in use).
|
|
70727
|
+
- AWAITING_INPUT: waiting for send_input \u2014 an interactive session between turns, or a turn stopped on a question (activity "AskUserQuestion"). A send declines a question and becomes the next prompt.
|
|
70728
|
+
- AWAITING_PERMISSION: a permission or plan-approval dialog is open. A send declines it and becomes the next prompt.
|
|
70729
|
+
- COMPLETED, FAILED, TIMEOUT, CANCELLED, EMPTY: finished.
|
|
70730
|
+
3. send_input may be called at any time; it is queued until the session is idle.
|
|
70731
|
+
4. COMPLETED: call get_output for the answer.
|
|
70732
|
+
5. FAILED or TIMEOUT \u2014 or COMPLETED with an empty or surprising answer \u2014 call get_diagnostics. It returns the child's final screen, the upstream error bodies, the recent state records, the resolved model chain and the paths to the full records. It needs no re-run and no debug flag.
|
|
70733
|
+
6. capture_session reads a session's current screen; cancel_session stops it. Nothing stops a session for being idle: a child inside a long build is silent and working.
|
|
70503
70734
|
|
|
70504
|
-
The session_id
|
|
70735
|
+
The session_id from create_session is the key for every session tool.`, proxyInstance = null, proxyStarting = null, SCORE_TIE_EPSILON = 0.000001, NEXT_STEP, sanitize2, TOOL_MODES;
|
|
70505
70736
|
var init_mcp_server = __esm(() => {
|
|
70506
70737
|
init_server2();
|
|
70507
70738
|
init_stdio2();
|
|
70508
70739
|
init_types();
|
|
70509
70740
|
init_model_catalog();
|
|
70510
70741
|
init_prehydrate();
|
|
70511
|
-
init_diagnostics();
|
|
70512
|
-
init_channel();
|
|
70513
|
-
init_parent_session();
|
|
70514
70742
|
init_remote_provider_types();
|
|
70743
|
+
init_mcp_session();
|
|
70744
|
+
init_parent_session();
|
|
70515
70745
|
init_nested_mode();
|
|
70516
70746
|
init_progress_heartbeat();
|
|
70747
|
+
init_run_prompt_claude_code();
|
|
70517
70748
|
init_model_loader();
|
|
70518
70749
|
init_child_env();
|
|
70519
70750
|
init_pane();
|
|
@@ -70532,8 +70763,8 @@ var init_mcp_server = __esm(() => {
|
|
|
70532
70763
|
import_dotenv2.config({ quiet: true });
|
|
70533
70764
|
__filename3 = fileURLToPath3(import.meta.url);
|
|
70534
70765
|
__dirname3 = dirname14(__filename3);
|
|
70535
|
-
CLAUDISH_CACHE_DIR =
|
|
70536
|
-
OPENROUTER_MODELS_CACHE_PATH =
|
|
70766
|
+
CLAUDISH_CACHE_DIR = join50(homedir33(), ".claudish");
|
|
70767
|
+
OPENROUTER_MODELS_CACHE_PATH = join50(CLAUDISH_CACHE_DIR, "openrouter-models.json");
|
|
70537
70768
|
NEXT_STEP = {
|
|
70538
70769
|
cancelled: "you stopped this slot; nothing is wrong with it. Re-run it if you still want its vote",
|
|
70539
70770
|
timeout: "grid mode only \u2014 magmux ended the pane. The orchestrator has no deadline",
|
|
@@ -70552,18 +70783,7 @@ var init_mcp_server = __esm(() => {
|
|
|
70552
70783
|
shape_mismatch: "the answer (assistant text after the task was read) did not match. Every assistant " + "message of the turn was read from the transcript, so nothing was lost in transit \u2014 " + "the model did not produce it. Re-prompt with the required format restated; do NOT " + "count this slot as a vote"
|
|
70553
70784
|
};
|
|
70554
70785
|
sanitize2 = sanitizeForReport;
|
|
70555
|
-
|
|
70556
|
-
starting: "working",
|
|
70557
|
-
running: "working",
|
|
70558
|
-
tool_executing: "working",
|
|
70559
|
-
waiting_for_input: "input_required",
|
|
70560
|
-
awaiting_permission: "input_required",
|
|
70561
|
-
completed: "completed",
|
|
70562
|
-
failed: "failed",
|
|
70563
|
-
cancelled: "cancelled",
|
|
70564
|
-
timeout: "failed"
|
|
70565
|
-
};
|
|
70566
|
-
EVENT_TO_TASK_STATUS = new Map(Object.entries(TASK_STATUS_BY_EVENT));
|
|
70786
|
+
TOOL_MODES = ["all", "low-level", "agentic", "session", "debug"];
|
|
70567
70787
|
});
|
|
70568
70788
|
|
|
70569
70789
|
// src/serve-command.ts
|
|
@@ -70666,7 +70886,7 @@ var init_serve_command = __esm(() => {
|
|
|
70666
70886
|
});
|
|
70667
70887
|
|
|
70668
70888
|
// src/behavior-command.ts
|
|
70669
|
-
import { existsSync as existsSync34, readFileSync as readFileSync33, writeFileSync as
|
|
70889
|
+
import { existsSync as existsSync34, readFileSync as readFileSync33, writeFileSync as writeFileSync24 } from "fs";
|
|
70670
70890
|
function severityColor(sev) {
|
|
70671
70891
|
if (sev === "fix")
|
|
70672
70892
|
return green(sev);
|
|
@@ -70774,7 +70994,7 @@ function setTelemetryEnabled(value) {
|
|
|
70774
70994
|
const behavior = cfg.behavior && typeof cfg.behavior === "object" && !Array.isArray(cfg.behavior) ? { ...cfg.behavior } : {};
|
|
70775
70995
|
behavior.telemetry = { enabled: value };
|
|
70776
70996
|
cfg.behavior = behavior;
|
|
70777
|
-
|
|
70997
|
+
writeFileSync24(path, `${JSON.stringify(cfg, null, 2)}
|
|
70778
70998
|
`, "utf-8");
|
|
70779
70999
|
}
|
|
70780
71000
|
function showTelemetry(action, json) {
|
|
@@ -70866,10 +71086,10 @@ var init_behavior_command = __esm(() => {
|
|
|
70866
71086
|
});
|
|
70867
71087
|
|
|
70868
71088
|
// src/team-grid.ts
|
|
70869
|
-
import { spawn as
|
|
70870
|
-
import { existsSync as existsSync35, readFileSync as readFileSync34, writeFileSync as
|
|
71089
|
+
import { spawn as spawn3 } from "child_process";
|
|
71090
|
+
import { existsSync as existsSync35, readFileSync as readFileSync34, writeFileSync as writeFileSync25 } from "fs";
|
|
70871
71091
|
import { connect as netConnect2 } from "net";
|
|
70872
|
-
import { join as
|
|
71092
|
+
import { join as join51 } from "path";
|
|
70873
71093
|
import { setTimeout as wait } from "timers/promises";
|
|
70874
71094
|
function paneRouteLine(explanation) {
|
|
70875
71095
|
const origin = describeRouteExplanation(explanation);
|
|
@@ -71019,9 +71239,9 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
71019
71239
|
const keep = opts?.keep ?? false;
|
|
71020
71240
|
const manifest = setupSession(sessionPath, models, input);
|
|
71021
71241
|
const startedAt = new Date().toISOString();
|
|
71022
|
-
const gridfilePath =
|
|
71023
|
-
const prompt = readFileSync34(
|
|
71024
|
-
const rawPrompt = readFileSync34(
|
|
71242
|
+
const gridfilePath = join51(sessionPath, "gridfile.txt");
|
|
71243
|
+
const prompt = readFileSync34(join51(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
71244
|
+
const rawPrompt = readFileSync34(join51(sessionPath, "input.md"), "utf-8");
|
|
71025
71245
|
const usedBannerColors = new Set;
|
|
71026
71246
|
const routeLines = mode === "interactive" ? new Map : await resolvePaneRouteLines(Object.values(manifest.models).map((entry) => entry.model));
|
|
71027
71247
|
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
@@ -71033,7 +71253,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
71033
71253
|
const header = buildPaneHeader(model, routeLines.get(model) ?? "", rawPrompt, bg);
|
|
71034
71254
|
return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
|
|
71035
71255
|
});
|
|
71036
|
-
|
|
71256
|
+
writeFileSync25(gridfilePath, `${gridLines.join(`
|
|
71037
71257
|
`)}
|
|
71038
71258
|
`, "utf-8");
|
|
71039
71259
|
const magmuxPath = findMagmuxBinary();
|
|
@@ -71041,7 +71261,7 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
71041
71261
|
if (!keep && mode === "default") {
|
|
71042
71262
|
spawnArgs.push("-w");
|
|
71043
71263
|
}
|
|
71044
|
-
const proc =
|
|
71264
|
+
const proc = spawn3(magmuxPath, spawnArgs, {
|
|
71045
71265
|
stdio: "inherit",
|
|
71046
71266
|
env: { ...process.env }
|
|
71047
71267
|
});
|
|
@@ -71053,8 +71273,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
71053
71273
|
});
|
|
71054
71274
|
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
71055
71275
|
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
71056
|
-
const statusPath =
|
|
71057
|
-
|
|
71276
|
+
const statusPath = join51(sessionPath, "status.json");
|
|
71277
|
+
writeFileSync25(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
71058
71278
|
return status;
|
|
71059
71279
|
}
|
|
71060
71280
|
var BANNER_BG_COLORS;
|
|
@@ -71074,7 +71294,7 @@ var init_team_grid = __esm(() => {
|
|
|
71074
71294
|
|
|
71075
71295
|
// src/team-cli.ts
|
|
71076
71296
|
import { readFileSync as readFileSync35 } from "fs";
|
|
71077
|
-
import { join as
|
|
71297
|
+
import { join as join52 } from "path";
|
|
71078
71298
|
async function runPaneTeam(sessionPath, models, input, opts) {
|
|
71079
71299
|
installPaneShutdownHooks({ exitAfter: true });
|
|
71080
71300
|
try {
|
|
@@ -71212,7 +71432,7 @@ async function teamCommand(args) {
|
|
|
71212
71432
|
}
|
|
71213
71433
|
case "judge": {
|
|
71214
71434
|
await judgeResponses(sessionPath, { judges });
|
|
71215
|
-
console.log(readFileSync35(
|
|
71435
|
+
console.log(readFileSync35(join52(sessionPath, "verdict.md"), "utf-8"));
|
|
71216
71436
|
break;
|
|
71217
71437
|
}
|
|
71218
71438
|
case "run-and-judge": {
|
|
@@ -71228,7 +71448,7 @@ async function teamCommand(args) {
|
|
|
71228
71448
|
});
|
|
71229
71449
|
printStatus(status);
|
|
71230
71450
|
await judgeResponses(sessionPath, { judges });
|
|
71231
|
-
console.log(readFileSync35(
|
|
71451
|
+
console.log(readFileSync35(join52(sessionPath, "verdict.md"), "utf-8"));
|
|
71232
71452
|
break;
|
|
71233
71453
|
}
|
|
71234
71454
|
case "status": {
|
|
@@ -71802,7 +72022,7 @@ var init_keychain_command = __esm(() => {
|
|
|
71802
72022
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
71803
72023
|
import { existsSync as existsSync36, unlinkSync as unlinkSync9 } from "fs";
|
|
71804
72024
|
import { homedir as homedir34 } from "os";
|
|
71805
|
-
import { join as
|
|
72025
|
+
import { join as join53 } from "path";
|
|
71806
72026
|
async function defaultSuggestModel() {
|
|
71807
72027
|
try {
|
|
71808
72028
|
const tok = readSharedAntigravityToken();
|
|
@@ -71923,7 +72143,7 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
|
|
|
71923
72143
|
async logout(deps) {
|
|
71924
72144
|
deleteSharedAntigravityToken(deps);
|
|
71925
72145
|
try {
|
|
71926
|
-
const tokenFile =
|
|
72146
|
+
const tokenFile = join53(homedir34(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
|
|
71927
72147
|
if (existsSync36(tokenFile))
|
|
71928
72148
|
unlinkSync9(tokenFile);
|
|
71929
72149
|
} catch {}
|
|
@@ -80185,20 +80405,20 @@ var init_terminal_isolation = __esm(() => {
|
|
|
80185
80405
|
});
|
|
80186
80406
|
|
|
80187
80407
|
// src/claude-runner.ts
|
|
80188
|
-
import { spawn as
|
|
80408
|
+
import { spawn as spawn4, spawnSync as spawnSync4 } from "child_process";
|
|
80189
80409
|
import {
|
|
80190
|
-
closeSync as
|
|
80410
|
+
closeSync as closeSync11,
|
|
80191
80411
|
existsSync as existsSync38,
|
|
80192
|
-
mkdirSync as
|
|
80193
|
-
openSync as
|
|
80412
|
+
mkdirSync as mkdirSync23,
|
|
80413
|
+
openSync as openSync11,
|
|
80194
80414
|
readFileSync as readFileSync36,
|
|
80195
80415
|
readdirSync as readdirSync11,
|
|
80196
80416
|
statSync as statSync13,
|
|
80197
80417
|
unlinkSync as unlinkSync10,
|
|
80198
|
-
writeFileSync as
|
|
80418
|
+
writeFileSync as writeFileSync26
|
|
80199
80419
|
} from "fs";
|
|
80200
|
-
import { homedir as homedir35, tmpdir as
|
|
80201
|
-
import { dirname as dirname15, join as
|
|
80420
|
+
import { homedir as homedir35, tmpdir as tmpdir3 } from "os";
|
|
80421
|
+
import { dirname as dirname15, join as join54 } from "path";
|
|
80202
80422
|
import { isatty } from "tty";
|
|
80203
80423
|
function releaseTerminalIsolation() {
|
|
80204
80424
|
if (!restoreTerminal)
|
|
@@ -80263,7 +80483,7 @@ function hasResolvableAnthropicAuth(deps = {}) {
|
|
|
80263
80483
|
if (isRealAnthropicEnvCredential(env, "ANTHROPIC_API_KEY") || isRealAnthropicEnvCredential(env, "ANTHROPIC_AUTH_TOKEN")) {
|
|
80264
80484
|
return true;
|
|
80265
80485
|
}
|
|
80266
|
-
if (fileExists(
|
|
80486
|
+
if (fileExists(join54(homedir35(), ".claude", ".credentials.json")))
|
|
80267
80487
|
return true;
|
|
80268
80488
|
return keychainProbe();
|
|
80269
80489
|
}
|
|
@@ -80278,7 +80498,7 @@ function isProxyAuthMode(config) {
|
|
|
80278
80498
|
}
|
|
80279
80499
|
function managedSettingsPath() {
|
|
80280
80500
|
if (isWindows2()) {
|
|
80281
|
-
return
|
|
80501
|
+
return join54(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
|
|
80282
80502
|
}
|
|
80283
80503
|
if (process.platform === "darwin") {
|
|
80284
80504
|
return "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
@@ -80298,10 +80518,10 @@ function isWindows2() {
|
|
|
80298
80518
|
return process.platform === "win32";
|
|
80299
80519
|
}
|
|
80300
80520
|
function createStatusLineScript(tokenFilePath) {
|
|
80301
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE ||
|
|
80302
|
-
const claudishDir =
|
|
80521
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir3();
|
|
80522
|
+
const claudishDir = join54(homeDir, ".claudish");
|
|
80303
80523
|
const timestamp = Date.now();
|
|
80304
|
-
const scriptPath =
|
|
80524
|
+
const scriptPath = join54(claudishDir, `status-${timestamp}.js`);
|
|
80305
80525
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
80306
80526
|
const light = getThemeMode() === "light";
|
|
80307
80527
|
const cyanCode = light ? "38;2;14;116;144" : "96";
|
|
@@ -80434,13 +80654,13 @@ process.stdin.on('end', () => {
|
|
|
80434
80654
|
}
|
|
80435
80655
|
});
|
|
80436
80656
|
`;
|
|
80437
|
-
|
|
80657
|
+
writeFileSync26(scriptPath, script, "utf-8");
|
|
80438
80658
|
return scriptPath;
|
|
80439
80659
|
}
|
|
80440
80660
|
function initializeTokenFile(tokenFilePath) {
|
|
80441
80661
|
try {
|
|
80442
|
-
|
|
80443
|
-
|
|
80662
|
+
mkdirSync23(dirname15(tokenFilePath), { recursive: true });
|
|
80663
|
+
writeFileSync26(tokenFilePath, JSON.stringify({
|
|
80444
80664
|
input_tokens: 0,
|
|
80445
80665
|
output_tokens: 0,
|
|
80446
80666
|
total_tokens: 0,
|
|
@@ -80471,7 +80691,7 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
|
|
|
80471
80691
|
if (!name.startsWith("tokens-") || !name.endsWith(".json"))
|
|
80472
80692
|
continue;
|
|
80473
80693
|
scanned++;
|
|
80474
|
-
const full =
|
|
80694
|
+
const full = join54(dir, name);
|
|
80475
80695
|
try {
|
|
80476
80696
|
if (statSync13(full).mtimeMs >= cutoff)
|
|
80477
80697
|
continue;
|
|
@@ -80500,9 +80720,9 @@ function parseSettingsArgSafe(value) {
|
|
|
80500
80720
|
}
|
|
80501
80721
|
function userSettingsFileCandidates(cwd) {
|
|
80502
80722
|
return [
|
|
80503
|
-
|
|
80504
|
-
|
|
80505
|
-
|
|
80723
|
+
join54(homedir35(), ".claude", "settings.json"),
|
|
80724
|
+
join54(cwd, ".claude", "settings.json"),
|
|
80725
|
+
join54(cwd, ".claude", "settings.local.json")
|
|
80506
80726
|
];
|
|
80507
80727
|
}
|
|
80508
80728
|
function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
|
|
@@ -80542,13 +80762,13 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
|
|
|
80542
80762
|
return `JSON=$(cat); ${runUser}; ${claudishBody}; SEG=$(${claudishSegment}); ${separator}; ${emit}`;
|
|
80543
80763
|
}
|
|
80544
80764
|
function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
|
|
80545
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE ||
|
|
80546
|
-
const claudishDir =
|
|
80765
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir3();
|
|
80766
|
+
const claudishDir = join54(homeDir, ".claudish");
|
|
80547
80767
|
try {
|
|
80548
|
-
|
|
80768
|
+
mkdirSync23(claudishDir, { recursive: true });
|
|
80549
80769
|
} catch {}
|
|
80550
80770
|
const timestamp = Date.now();
|
|
80551
|
-
const tempPath =
|
|
80771
|
+
const tempPath = join54(claudishDir, `settings-${timestamp}.json`);
|
|
80552
80772
|
const assignedFile = assignedTokenFile(process.env) !== null;
|
|
80553
80773
|
const tokenFilePath = resolveTokenFilePath(port);
|
|
80554
80774
|
cleanupStaleTokenFiles(claudishDir);
|
|
@@ -80585,7 +80805,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
|
|
|
80585
80805
|
padding: 0
|
|
80586
80806
|
};
|
|
80587
80807
|
const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
|
|
80588
|
-
|
|
80808
|
+
writeFileSync26(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
80589
80809
|
return { path: tempPath, statusLine, tokenFilePath };
|
|
80590
80810
|
}
|
|
80591
80811
|
function scrubChildEnv(env, opts) {
|
|
@@ -80603,6 +80823,7 @@ function buildClaudishSettingsOverlay(statusLine, proxyAuthMode, paneChild = isP
|
|
|
80603
80823
|
}
|
|
80604
80824
|
if (paneChild) {
|
|
80605
80825
|
settings.skipDangerousModePermissionPrompt = true;
|
|
80826
|
+
settings.editorMode = "normal";
|
|
80606
80827
|
}
|
|
80607
80828
|
return settings;
|
|
80608
80829
|
}
|
|
@@ -80624,7 +80845,10 @@ function mergeUserSettingsIfPresent(config, tempSettingsPath, statusLine, proxyA
|
|
|
80624
80845
|
if (paneChild && !("skipDangerousModePermissionPrompt" in userSettings)) {
|
|
80625
80846
|
userSettings.skipDangerousModePermissionPrompt = true;
|
|
80626
80847
|
}
|
|
80627
|
-
|
|
80848
|
+
if (paneChild) {
|
|
80849
|
+
userSettings.editorMode = "normal";
|
|
80850
|
+
}
|
|
80851
|
+
writeFileSync26(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
80628
80852
|
} catch {
|
|
80629
80853
|
if (!config.quiet) {
|
|
80630
80854
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -80923,7 +81147,7 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
|
|
|
80923
81147
|
console.error(`
|
|
80924
81148
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
80925
81149
|
const home = homedir35();
|
|
80926
|
-
const localPath = isWindows2() ?
|
|
81150
|
+
const localPath = isWindows2() ? join54(home, ".claude", "local", "claude.exe") : join54(home, ".claude", "local", "claude");
|
|
80927
81151
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
80928
81152
|
process.exit(1);
|
|
80929
81153
|
}
|
|
@@ -80934,11 +81158,11 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
80934
81158
|
const childWantsTty = config.interactive && !process.stdout.isTTY && Boolean(process.stdin.isTTY);
|
|
80935
81159
|
if (childWantsTty) {
|
|
80936
81160
|
try {
|
|
80937
|
-
const fd =
|
|
81161
|
+
const fd = openSync11("/dev/fd/0", "r+");
|
|
80938
81162
|
if (isatty(fd)) {
|
|
80939
81163
|
ttyFd = fd;
|
|
80940
81164
|
} else {
|
|
80941
|
-
|
|
81165
|
+
closeSync11(fd);
|
|
80942
81166
|
}
|
|
80943
81167
|
} catch {
|
|
80944
81168
|
ttyFd = undefined;
|
|
@@ -80957,7 +81181,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
80957
81181
|
stdoutIsTty: Boolean(process.stdout.isTTY),
|
|
80958
81182
|
magmuxBinary: paneCapability.magmux
|
|
80959
81183
|
}) : null;
|
|
80960
|
-
const proc = wrap ?
|
|
81184
|
+
const proc = wrap ? spawn4(wrap.command, wrap.args, { env: wrap.env, stdio, shell: false }) : spawn4(spawnCommand, claudeArgs, {
|
|
80961
81185
|
env,
|
|
80962
81186
|
stdio,
|
|
80963
81187
|
shell: needsShell
|
|
@@ -80983,7 +81207,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
80983
81207
|
const fdToClose = ttyFd;
|
|
80984
81208
|
proc.on("spawn", () => {
|
|
80985
81209
|
try {
|
|
80986
|
-
|
|
81210
|
+
closeSync11(fdToClose);
|
|
80987
81211
|
} catch {}
|
|
80988
81212
|
});
|
|
80989
81213
|
}
|
|
@@ -81036,15 +81260,15 @@ async function findClaudeBinary() {
|
|
|
81036
81260
|
}
|
|
81037
81261
|
}
|
|
81038
81262
|
const home = homedir35();
|
|
81039
|
-
const localPath = isWindows ?
|
|
81263
|
+
const localPath = isWindows ? join54(home, ".claude", "local", "claude.exe") : join54(home, ".claude", "local", "claude");
|
|
81040
81264
|
if (existsSync38(localPath)) {
|
|
81041
81265
|
return localPath;
|
|
81042
81266
|
}
|
|
81043
81267
|
if (isWindows) {
|
|
81044
81268
|
const windowsPaths = [
|
|
81045
|
-
|
|
81046
|
-
|
|
81047
|
-
|
|
81269
|
+
join54(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
81270
|
+
join54(home, ".npm-global", "claude.cmd"),
|
|
81271
|
+
join54(home, "node_modules", ".bin", "claude.cmd")
|
|
81048
81272
|
];
|
|
81049
81273
|
for (const path of windowsPaths) {
|
|
81050
81274
|
if (existsSync38(path)) {
|
|
@@ -81055,11 +81279,11 @@ async function findClaudeBinary() {
|
|
|
81055
81279
|
const commonPaths = [
|
|
81056
81280
|
"/usr/local/bin/claude",
|
|
81057
81281
|
"/opt/homebrew/bin/claude",
|
|
81058
|
-
|
|
81059
|
-
|
|
81060
|
-
|
|
81282
|
+
join54(home, ".npm-global/bin/claude"),
|
|
81283
|
+
join54(home, ".local/bin/claude"),
|
|
81284
|
+
join54(home, "node_modules/.bin/claude"),
|
|
81061
81285
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
81062
|
-
|
|
81286
|
+
join54(home, "../usr/bin/claude")
|
|
81063
81287
|
];
|
|
81064
81288
|
for (const path of commonPaths) {
|
|
81065
81289
|
if (existsSync38(path)) {
|
|
@@ -81069,7 +81293,7 @@ async function findClaudeBinary() {
|
|
|
81069
81293
|
}
|
|
81070
81294
|
try {
|
|
81071
81295
|
const shellCommand = isWindows ? "where claude" : "command -v claude";
|
|
81072
|
-
const proc =
|
|
81296
|
+
const proc = spawn4(shellCommand, [], {
|
|
81073
81297
|
stdio: "pipe",
|
|
81074
81298
|
shell: true
|
|
81075
81299
|
});
|
|
@@ -81142,18 +81366,18 @@ var init_claude_runner = __esm(() => {
|
|
|
81142
81366
|
});
|
|
81143
81367
|
|
|
81144
81368
|
// src/diag-output.ts
|
|
81145
|
-
import { createWriteStream as createWriteStream2, mkdirSync as
|
|
81369
|
+
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync24, unlinkSync as unlinkSync11, writeFileSync as writeFileSync27 } from "fs";
|
|
81146
81370
|
import { homedir as homedir36 } from "os";
|
|
81147
|
-
import { join as
|
|
81371
|
+
import { join as join55 } from "path";
|
|
81148
81372
|
function getClaudishDir() {
|
|
81149
|
-
const dir =
|
|
81373
|
+
const dir = join55(homedir36(), ".claudish");
|
|
81150
81374
|
try {
|
|
81151
|
-
|
|
81375
|
+
mkdirSync24(dir, { recursive: true });
|
|
81152
81376
|
} catch {}
|
|
81153
81377
|
return dir;
|
|
81154
81378
|
}
|
|
81155
81379
|
function getDiagLogPath() {
|
|
81156
|
-
return
|
|
81380
|
+
return join55(getClaudishDir(), `diag-${process.pid}.log`);
|
|
81157
81381
|
}
|
|
81158
81382
|
|
|
81159
81383
|
class LogFileDiagOutput {
|
|
@@ -81162,7 +81386,7 @@ class LogFileDiagOutput {
|
|
|
81162
81386
|
constructor() {
|
|
81163
81387
|
this.logPath = getDiagLogPath();
|
|
81164
81388
|
try {
|
|
81165
|
-
|
|
81389
|
+
writeFileSync27(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
81166
81390
|
`);
|
|
81167
81391
|
} catch {}
|
|
81168
81392
|
this.stream = createWriteStream2(this.logPath, { flags: "a" });
|
|
@@ -81643,7 +81867,7 @@ var init_advisor_startup = __esm(() => {
|
|
|
81643
81867
|
});
|
|
81644
81868
|
|
|
81645
81869
|
// src/session/conversation.ts
|
|
81646
|
-
import { closeSync as
|
|
81870
|
+
import { closeSync as closeSync12, openSync as openSync12, readSync as readSync6, statSync as statSync14 } from "fs";
|
|
81647
81871
|
import { StringDecoder } from "string_decoder";
|
|
81648
81872
|
function looksLikeTurn(line) {
|
|
81649
81873
|
const assistant = line.includes('"type":"assistant"');
|
|
@@ -81699,7 +81923,7 @@ function readConversation(file, opts = {}) {
|
|
|
81699
81923
|
let fd = null;
|
|
81700
81924
|
try {
|
|
81701
81925
|
const size = statSync14(file).size;
|
|
81702
|
-
fd =
|
|
81926
|
+
fd = openSync12(file, "r");
|
|
81703
81927
|
const buf = Buffer.allocUnsafe(chunkBytes);
|
|
81704
81928
|
const decoder = new StringDecoder("utf-8");
|
|
81705
81929
|
let pending = "";
|
|
@@ -81731,7 +81955,7 @@ function readConversation(file, opts = {}) {
|
|
|
81731
81955
|
take({ role: raw.role, text, elided });
|
|
81732
81956
|
};
|
|
81733
81957
|
while (pos < size) {
|
|
81734
|
-
const n =
|
|
81958
|
+
const n = readSync6(fd, buf, 0, Math.min(chunkBytes, size - pos), pos);
|
|
81735
81959
|
if (n <= 0)
|
|
81736
81960
|
break;
|
|
81737
81961
|
pos += n;
|
|
@@ -81755,7 +81979,7 @@ function readConversation(file, opts = {}) {
|
|
|
81755
81979
|
} catch {} finally {
|
|
81756
81980
|
if (fd !== null) {
|
|
81757
81981
|
try {
|
|
81758
|
-
|
|
81982
|
+
closeSync12(fd);
|
|
81759
81983
|
} catch {}
|
|
81760
81984
|
}
|
|
81761
81985
|
}
|
|
@@ -83369,30 +83593,30 @@ function readSessionStats(port, opts) {
|
|
|
83369
83593
|
return null;
|
|
83370
83594
|
const d = raw;
|
|
83371
83595
|
const processStartMs = opts?.processStartMs ?? Date.now() - Math.round(process.uptime() * 1000);
|
|
83372
|
-
const trackerStartedAt =
|
|
83596
|
+
const trackerStartedAt = num2(d.started_at);
|
|
83373
83597
|
if (trackerStartedAt <= 0 || trackerStartedAt < processStartMs)
|
|
83374
83598
|
return null;
|
|
83375
|
-
const inputTokens =
|
|
83376
|
-
const outputTokens =
|
|
83599
|
+
const inputTokens = num2(d.input_tokens);
|
|
83600
|
+
const outputTokens = num2(d.output_tokens);
|
|
83377
83601
|
if (inputTokens <= 0 && outputTokens <= 0)
|
|
83378
83602
|
return null;
|
|
83379
|
-
const costUsd =
|
|
83603
|
+
const costUsd = num2(d.total_cost);
|
|
83380
83604
|
const isFree = d.is_free === true;
|
|
83381
83605
|
const contextWindow = typeof d.context_window === "number" ? d.context_window : null;
|
|
83382
83606
|
const contextUsed = contextWindow && contextWindow > 0 ? Math.min(1, Math.max(0, inputTokens / contextWindow)) : null;
|
|
83383
|
-
const toolCalls = Array.isArray(d.tool_calls) ? d.tool_calls.map((t) => t).filter((t) => typeof t?.name === "string" &&
|
|
83384
|
-
const startedAt =
|
|
83385
|
-
const updatedAt =
|
|
83607
|
+
const toolCalls = Array.isArray(d.tool_calls) ? d.tool_calls.map((t) => t).filter((t) => typeof t?.name === "string" && num2(t.count) > 0).map((t) => ({ name: String(t.name), count: num2(t.count) })) : [];
|
|
83608
|
+
const startedAt = num2(d.started_at);
|
|
83609
|
+
const updatedAt = num2(d.updated_at);
|
|
83386
83610
|
const durationMs = startedAt > 0 && updatedAt > startedAt ? updatedAt - startedAt : 0;
|
|
83387
|
-
const billedInputTokens =
|
|
83388
|
-
const rawIn = billedInputTokens / 1e6 *
|
|
83389
|
-
const rawOut = outputTokens / 1e6 *
|
|
83611
|
+
const billedInputTokens = num2(d.billed_input_tokens) || inputTokens;
|
|
83612
|
+
const rawIn = billedInputTokens / 1e6 * num2(d.input_per_m);
|
|
83613
|
+
const rawOut = outputTokens / 1e6 * num2(d.output_per_m);
|
|
83390
83614
|
const rawTotal = rawIn + rawOut;
|
|
83391
83615
|
const scale = rawTotal > 0 && costUsd > 0 ? costUsd / rawTotal : 0;
|
|
83392
83616
|
return {
|
|
83393
83617
|
inputTokens,
|
|
83394
83618
|
outputTokens,
|
|
83395
|
-
totalTokens:
|
|
83619
|
+
totalTokens: num2(d.total_tokens) || inputTokens + outputTokens,
|
|
83396
83620
|
costUsd,
|
|
83397
83621
|
isFree,
|
|
83398
83622
|
isEstimated: d.is_estimated === true,
|
|
@@ -83420,7 +83644,7 @@ function computeSavings(inputTokens, outputTokens, actualUsd) {
|
|
|
83420
83644
|
};
|
|
83421
83645
|
});
|
|
83422
83646
|
}
|
|
83423
|
-
var
|
|
83647
|
+
var num2 = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
83424
83648
|
var init_session_stats = __esm(() => {
|
|
83425
83649
|
init_baseline_pricing();
|
|
83426
83650
|
init_token_file();
|
|
@@ -83722,7 +83946,7 @@ init_startup_trace();
|
|
|
83722
83946
|
init_picker_cancelled();
|
|
83723
83947
|
var import_dotenv3 = __toESM(require_main(), 1);
|
|
83724
83948
|
import { existsSync as existsSync39, readFileSync as readFileSync38 } from "fs";
|
|
83725
|
-
import { join as
|
|
83949
|
+
import { join as join56, resolve as resolve7 } from "path";
|
|
83726
83950
|
|
|
83727
83951
|
// src/tui/runtime/should-open-picker.ts
|
|
83728
83952
|
function noModelConfigured(gate) {
|
|
@@ -84030,7 +84254,7 @@ async function runCli() {
|
|
|
84030
84254
|
process.exit(1);
|
|
84031
84255
|
}
|
|
84032
84256
|
const mode = cliConfig.teamMode ?? "default";
|
|
84033
|
-
const sessionPath =
|
|
84257
|
+
const sessionPath = join56(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
84034
84258
|
if (mode === "json") {
|
|
84035
84259
|
await Promise.resolve().then(() => init_pane());
|
|
84036
84260
|
await Promise.resolve().then(() => init_team_orchestrator());
|
|
@@ -84050,7 +84274,7 @@ async function runCli() {
|
|
|
84050
84274
|
const status = await runModels(sessionPath);
|
|
84051
84275
|
const result = { ...status, responses: {} };
|
|
84052
84276
|
for (const anonId of Object.keys(status.models)) {
|
|
84053
|
-
const responsePath =
|
|
84277
|
+
const responsePath = join56(sessionPath, `response-${anonId}.md`);
|
|
84054
84278
|
try {
|
|
84055
84279
|
const raw = readFileSync38(responsePath, "utf-8").trim();
|
|
84056
84280
|
try {
|