claudish 7.48.0 → 7.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/claudish.cjs +69 -25
- package/dist/index.js +1246 -429
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -729,7 +729,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
729
729
|
});
|
|
730
730
|
|
|
731
731
|
// src/version.ts
|
|
732
|
-
var VERSION = "7.
|
|
732
|
+
var VERSION = "7.50.0";
|
|
733
733
|
|
|
734
734
|
// src/logger.ts
|
|
735
735
|
var exports_logger = {};
|
|
@@ -28142,7 +28142,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28142
28142
|
name: "minimax",
|
|
28143
28143
|
displayName: "MiniMax",
|
|
28144
28144
|
transport: "anthropic",
|
|
28145
|
-
baseUrl: "https://api.
|
|
28145
|
+
baseUrl: "https://api.minimaxi.com",
|
|
28146
28146
|
baseUrlEnvVars: ["MINIMAX_BASE_URL"],
|
|
28147
28147
|
apiPath: "/anthropic/v1/messages",
|
|
28148
28148
|
apiKeyEnvVar: "MINIMAX_API_KEY",
|
|
@@ -29640,6 +29640,48 @@ var init_base_api_format = __esm(() => {
|
|
|
29640
29640
|
});
|
|
29641
29641
|
|
|
29642
29642
|
// src/adapters/anthropic-api-format.ts
|
|
29643
|
+
function systemText(content) {
|
|
29644
|
+
if (typeof content === "string")
|
|
29645
|
+
return content;
|
|
29646
|
+
if (Array.isArray(content)) {
|
|
29647
|
+
return content.map((block) => typeof block?.text === "string" ? block.text : "").filter(Boolean).join(`
|
|
29648
|
+
`);
|
|
29649
|
+
}
|
|
29650
|
+
return "";
|
|
29651
|
+
}
|
|
29652
|
+
function hoistInlineSystem(messages) {
|
|
29653
|
+
if (!Array.isArray(messages) || !messages.some((m) => m?.role === "system")) {
|
|
29654
|
+
return { messages, hoisted: [] };
|
|
29655
|
+
}
|
|
29656
|
+
const kept = [];
|
|
29657
|
+
const hoisted = [];
|
|
29658
|
+
for (const msg of messages) {
|
|
29659
|
+
if (msg?.role === "system") {
|
|
29660
|
+
const text = systemText(msg.content);
|
|
29661
|
+
if (text)
|
|
29662
|
+
hoisted.push(text);
|
|
29663
|
+
continue;
|
|
29664
|
+
}
|
|
29665
|
+
kept.push(msg);
|
|
29666
|
+
}
|
|
29667
|
+
return { messages: kept, hoisted };
|
|
29668
|
+
}
|
|
29669
|
+
function mergeSystem(existing, hoisted) {
|
|
29670
|
+
if (hoisted.length === 0)
|
|
29671
|
+
return existing;
|
|
29672
|
+
const merged = hoisted.join(`
|
|
29673
|
+
|
|
29674
|
+
`);
|
|
29675
|
+
if (existing === undefined || existing === null || existing === "")
|
|
29676
|
+
return merged;
|
|
29677
|
+
if (Array.isArray(existing))
|
|
29678
|
+
return [...existing, { type: "text", text: merged }];
|
|
29679
|
+
if (typeof existing === "string")
|
|
29680
|
+
return `${existing}
|
|
29681
|
+
|
|
29682
|
+
${merged}`;
|
|
29683
|
+
return existing;
|
|
29684
|
+
}
|
|
29643
29685
|
var AnthropicAPIFormat;
|
|
29644
29686
|
var init_anthropic_api_format = __esm(() => {
|
|
29645
29687
|
init_base_api_format();
|
|
@@ -29684,14 +29726,16 @@ var init_anthropic_api_format = __esm(() => {
|
|
|
29684
29726
|
return claudeRequest.tools || [];
|
|
29685
29727
|
}
|
|
29686
29728
|
buildPayload(claudeRequest, messages, tools) {
|
|
29729
|
+
const { messages: cleanMessages, hoisted } = hoistInlineSystem(messages);
|
|
29687
29730
|
const payload = {
|
|
29688
29731
|
model: this.modelId,
|
|
29689
|
-
messages,
|
|
29732
|
+
messages: cleanMessages,
|
|
29690
29733
|
max_tokens: claudeRequest.max_tokens || 4096,
|
|
29691
29734
|
stream: true
|
|
29692
29735
|
};
|
|
29693
|
-
|
|
29694
|
-
|
|
29736
|
+
const system = mergeSystem(claudeRequest.system, hoisted);
|
|
29737
|
+
if (system !== undefined) {
|
|
29738
|
+
payload.system = system;
|
|
29695
29739
|
}
|
|
29696
29740
|
if (tools.length > 0) {
|
|
29697
29741
|
payload.tools = tools;
|
|
@@ -34884,14 +34928,14 @@ var init_config = __esm(() => {
|
|
|
34884
34928
|
});
|
|
34885
34929
|
|
|
34886
34930
|
// src/behavior/harness.ts
|
|
34887
|
-
function extractAvailableSkills(
|
|
34888
|
-
if (!
|
|
34931
|
+
function extractAvailableSkills(systemText2) {
|
|
34932
|
+
if (!systemText2)
|
|
34889
34933
|
return [];
|
|
34890
|
-
const start = SKILL_SECTION.exec(
|
|
34934
|
+
const start = SKILL_SECTION.exec(systemText2);
|
|
34891
34935
|
if (!start)
|
|
34892
34936
|
return [];
|
|
34893
34937
|
const out = [];
|
|
34894
|
-
const body =
|
|
34938
|
+
const body = systemText2.slice(start.index + start[0].length);
|
|
34895
34939
|
for (const line of body.split(`
|
|
34896
34940
|
`)) {
|
|
34897
34941
|
const trimmed2 = line.trim();
|
|
@@ -38024,6 +38068,170 @@ var init_anthropic_error = __esm(() => {
|
|
|
38024
38068
|
CONTROL_CHARS = /[\x00-\x1F\x7F]/g;
|
|
38025
38069
|
});
|
|
38026
38070
|
|
|
38071
|
+
// src/handlers/shared/collect-sse-message.ts
|
|
38072
|
+
function finalizeBlock(block) {
|
|
38073
|
+
if (block.type === "text") {
|
|
38074
|
+
return { type: "text", text: block.text ?? "" };
|
|
38075
|
+
}
|
|
38076
|
+
if (block.type === "thinking") {
|
|
38077
|
+
return {
|
|
38078
|
+
type: "thinking",
|
|
38079
|
+
thinking: block.thinking ?? "",
|
|
38080
|
+
...block.signature ? { signature: block.signature } : {}
|
|
38081
|
+
};
|
|
38082
|
+
}
|
|
38083
|
+
let input = block.input ?? {};
|
|
38084
|
+
if (block.partialJson !== undefined && block.partialJson !== "") {
|
|
38085
|
+
try {
|
|
38086
|
+
input = JSON.parse(block.partialJson);
|
|
38087
|
+
} catch {
|
|
38088
|
+
log(`[CollectSSE] tool_use ${block.name ?? "?"} had unparseable input, emitting empty object`);
|
|
38089
|
+
input = {};
|
|
38090
|
+
}
|
|
38091
|
+
}
|
|
38092
|
+
return {
|
|
38093
|
+
type: "tool_use",
|
|
38094
|
+
id: block.id ?? "",
|
|
38095
|
+
name: block.name ?? "",
|
|
38096
|
+
input
|
|
38097
|
+
};
|
|
38098
|
+
}
|
|
38099
|
+
async function collectSseMessage(sse, fallbackModel, opts = {}) {
|
|
38100
|
+
const message = {
|
|
38101
|
+
id: `msg_${Date.now()}`,
|
|
38102
|
+
type: "message",
|
|
38103
|
+
role: "assistant",
|
|
38104
|
+
model: fallbackModel,
|
|
38105
|
+
content: [],
|
|
38106
|
+
stop_reason: null,
|
|
38107
|
+
stop_sequence: null,
|
|
38108
|
+
usage: { input_tokens: 0, output_tokens: 0 }
|
|
38109
|
+
};
|
|
38110
|
+
const blocks = new Map;
|
|
38111
|
+
const blockAt = (index) => {
|
|
38112
|
+
let block = blocks.get(index);
|
|
38113
|
+
if (!block) {
|
|
38114
|
+
block = { type: "text", text: "" };
|
|
38115
|
+
blocks.set(index, block);
|
|
38116
|
+
}
|
|
38117
|
+
return block;
|
|
38118
|
+
};
|
|
38119
|
+
if (!sse.body)
|
|
38120
|
+
return message;
|
|
38121
|
+
const reader = sse.body.getReader();
|
|
38122
|
+
const decoder = new TextDecoder;
|
|
38123
|
+
const stallMs = opts.stallTimeoutMs ?? STALL_TIMEOUT_MS;
|
|
38124
|
+
let buffer = "";
|
|
38125
|
+
const handle = (data) => {
|
|
38126
|
+
switch (data?.type) {
|
|
38127
|
+
case "message_start": {
|
|
38128
|
+
const m = data.message ?? {};
|
|
38129
|
+
if (m.id)
|
|
38130
|
+
message.id = m.id;
|
|
38131
|
+
if (m.model)
|
|
38132
|
+
message.model = m.model;
|
|
38133
|
+
if (m.usage?.input_tokens != null)
|
|
38134
|
+
message.usage.input_tokens = m.usage.input_tokens;
|
|
38135
|
+
if (m.usage?.output_tokens != null)
|
|
38136
|
+
message.usage.output_tokens = m.usage.output_tokens;
|
|
38137
|
+
break;
|
|
38138
|
+
}
|
|
38139
|
+
case "content_block_start": {
|
|
38140
|
+
const cb = data.content_block ?? {};
|
|
38141
|
+
const kind = cb.type === "thinking" ? "thinking" : cb.type === "tool_use" ? "tool_use" : "text";
|
|
38142
|
+
blocks.set(data.index, {
|
|
38143
|
+
type: kind,
|
|
38144
|
+
text: kind === "text" ? cb.text ?? "" : undefined,
|
|
38145
|
+
thinking: kind === "thinking" ? cb.thinking ?? "" : undefined,
|
|
38146
|
+
id: cb.id,
|
|
38147
|
+
name: cb.name,
|
|
38148
|
+
partialJson: kind === "tool_use" ? "" : undefined
|
|
38149
|
+
});
|
|
38150
|
+
break;
|
|
38151
|
+
}
|
|
38152
|
+
case "content_block_delta": {
|
|
38153
|
+
const block = blockAt(data.index);
|
|
38154
|
+
const d = data.delta ?? {};
|
|
38155
|
+
if (d.type === "text_delta")
|
|
38156
|
+
block.text = (block.text ?? "") + (d.text ?? "");
|
|
38157
|
+
else if (d.type === "thinking_delta")
|
|
38158
|
+
block.thinking = (block.thinking ?? "") + (d.thinking ?? "");
|
|
38159
|
+
else if (d.type === "signature_delta")
|
|
38160
|
+
block.signature = d.signature;
|
|
38161
|
+
else if (d.type === "input_json_delta")
|
|
38162
|
+
block.partialJson = (block.partialJson ?? "") + (d.partial_json ?? "");
|
|
38163
|
+
break;
|
|
38164
|
+
}
|
|
38165
|
+
case "message_delta": {
|
|
38166
|
+
if (data.delta?.stop_reason !== undefined)
|
|
38167
|
+
message.stop_reason = data.delta.stop_reason;
|
|
38168
|
+
if (data.delta?.stop_sequence !== undefined)
|
|
38169
|
+
message.stop_sequence = data.delta.stop_sequence;
|
|
38170
|
+
if (data.usage?.input_tokens != null)
|
|
38171
|
+
message.usage.input_tokens = data.usage.input_tokens;
|
|
38172
|
+
if (data.usage?.output_tokens != null)
|
|
38173
|
+
message.usage.output_tokens = data.usage.output_tokens;
|
|
38174
|
+
break;
|
|
38175
|
+
}
|
|
38176
|
+
default:
|
|
38177
|
+
break;
|
|
38178
|
+
}
|
|
38179
|
+
};
|
|
38180
|
+
try {
|
|
38181
|
+
while (true) {
|
|
38182
|
+
let timer;
|
|
38183
|
+
const chunk = await Promise.race([
|
|
38184
|
+
reader.read(),
|
|
38185
|
+
new Promise((resolve2) => {
|
|
38186
|
+
timer = setTimeout(() => resolve2("stalled"), stallMs);
|
|
38187
|
+
})
|
|
38188
|
+
]);
|
|
38189
|
+
clearTimeout(timer);
|
|
38190
|
+
if (chunk === "stalled") {
|
|
38191
|
+
log(`[CollectSSE] no data for ${stallMs}ms \u2014 returning ${blocks.size} block(s) collected so far`);
|
|
38192
|
+
await reader.cancel().catch(() => {});
|
|
38193
|
+
break;
|
|
38194
|
+
}
|
|
38195
|
+
if (chunk.done)
|
|
38196
|
+
break;
|
|
38197
|
+
buffer += decoder.decode(chunk.value, { stream: true });
|
|
38198
|
+
const lines = buffer.split(`
|
|
38199
|
+
`);
|
|
38200
|
+
buffer = lines.pop() ?? "";
|
|
38201
|
+
for (const line of lines) {
|
|
38202
|
+
if (!line.startsWith("data:"))
|
|
38203
|
+
continue;
|
|
38204
|
+
const payload = line.slice(5).trim();
|
|
38205
|
+
if (!payload || payload === "[DONE]")
|
|
38206
|
+
continue;
|
|
38207
|
+
try {
|
|
38208
|
+
handle(JSON.parse(payload));
|
|
38209
|
+
} catch {}
|
|
38210
|
+
}
|
|
38211
|
+
}
|
|
38212
|
+
} catch (e) {
|
|
38213
|
+
log(`[CollectSSE] read failed, keeping ${blocks.size} block(s): ${e}`);
|
|
38214
|
+
}
|
|
38215
|
+
for (const index of Array.from(blocks.keys()).sort((a, b) => a - b)) {
|
|
38216
|
+
message.content.push(finalizeBlock(blocks.get(index)));
|
|
38217
|
+
}
|
|
38218
|
+
if (message.stop_reason === null) {
|
|
38219
|
+
message.stop_reason = message.content.some((b) => b.type === "tool_use") ? "tool_use" : "end_turn";
|
|
38220
|
+
}
|
|
38221
|
+
return message;
|
|
38222
|
+
}
|
|
38223
|
+
async function sseResponseToJson(sse, fallbackModel, opts = {}) {
|
|
38224
|
+
const message = await collectSseMessage(sse, fallbackModel, opts);
|
|
38225
|
+
return new Response(JSON.stringify(message), {
|
|
38226
|
+
status: 200,
|
|
38227
|
+
headers: { "Content-Type": "application/json" }
|
|
38228
|
+
});
|
|
38229
|
+
}
|
|
38230
|
+
var STALL_TIMEOUT_MS = 120000;
|
|
38231
|
+
var init_collect_sse_message = __esm(() => {
|
|
38232
|
+
init_logger();
|
|
38233
|
+
});
|
|
38234
|
+
|
|
38027
38235
|
// src/handlers/shared/connection-error.ts
|
|
38028
38236
|
function findConnectionCode(error46) {
|
|
38029
38237
|
let e = error46;
|
|
@@ -38584,6 +38792,31 @@ function createAnthropicPassthroughStream(c, response, opts) {
|
|
|
38584
38792
|
const filterThinking = opts.adapter?.shouldFilterThinking() ?? false;
|
|
38585
38793
|
const interceptToolFrame = createToolRepairInterceptor(opts);
|
|
38586
38794
|
let pendingEventLine = null;
|
|
38795
|
+
let inputTokens = 0;
|
|
38796
|
+
let outputTokens = 0;
|
|
38797
|
+
let stopReason = null;
|
|
38798
|
+
let sawMessageStart = false;
|
|
38799
|
+
let sawMessageStop = false;
|
|
38800
|
+
let openBlockIndex = null;
|
|
38801
|
+
const noteLifecycle = (data, emittedIndex) => {
|
|
38802
|
+
switch (data?.type) {
|
|
38803
|
+
case "message_start":
|
|
38804
|
+
sawMessageStart = true;
|
|
38805
|
+
break;
|
|
38806
|
+
case "message_stop":
|
|
38807
|
+
sawMessageStop = true;
|
|
38808
|
+
break;
|
|
38809
|
+
case "content_block_start":
|
|
38810
|
+
if (emittedIndex !== null)
|
|
38811
|
+
openBlockIndex = emittedIndex;
|
|
38812
|
+
break;
|
|
38813
|
+
case "content_block_stop":
|
|
38814
|
+
openBlockIndex = null;
|
|
38815
|
+
break;
|
|
38816
|
+
default:
|
|
38817
|
+
break;
|
|
38818
|
+
}
|
|
38819
|
+
};
|
|
38587
38820
|
const flushPendingEvent = (controller) => {
|
|
38588
38821
|
if (pendingEventLine !== null && !isClosed) {
|
|
38589
38822
|
controller.enqueue(encoder.encode(`${pendingEventLine}
|
|
@@ -38601,6 +38834,48 @@ function createAnthropicPassthroughStream(c, response, opts) {
|
|
|
38601
38834
|
}
|
|
38602
38835
|
flushPendingEvent(controller);
|
|
38603
38836
|
controller.enqueue(encoder.encode(out));
|
|
38837
|
+
noteLifecycle(data, typeof data?.index === "number" ? data.index : null);
|
|
38838
|
+
};
|
|
38839
|
+
const finalizeAbandonedStream = (controller) => {
|
|
38840
|
+
if (isClosed || sawMessageStop)
|
|
38841
|
+
return;
|
|
38842
|
+
const send = (event, data) => {
|
|
38843
|
+
controller.enqueue(encoder.encode(`event: ${event}
|
|
38844
|
+
data: ${JSON.stringify(data)}
|
|
38845
|
+
|
|
38846
|
+
`));
|
|
38847
|
+
};
|
|
38848
|
+
try {
|
|
38849
|
+
if (!sawMessageStart) {
|
|
38850
|
+
send("message_start", {
|
|
38851
|
+
type: "message_start",
|
|
38852
|
+
message: {
|
|
38853
|
+
id: `msg_${Date.now()}`,
|
|
38854
|
+
type: "message",
|
|
38855
|
+
role: "assistant",
|
|
38856
|
+
content: [],
|
|
38857
|
+
model: opts.modelName,
|
|
38858
|
+
stop_reason: null,
|
|
38859
|
+
stop_sequence: null,
|
|
38860
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens }
|
|
38861
|
+
}
|
|
38862
|
+
});
|
|
38863
|
+
}
|
|
38864
|
+
if (openBlockIndex !== null) {
|
|
38865
|
+
send("content_block_stop", { type: "content_block_stop", index: openBlockIndex });
|
|
38866
|
+
openBlockIndex = null;
|
|
38867
|
+
}
|
|
38868
|
+
send("message_delta", {
|
|
38869
|
+
type: "message_delta",
|
|
38870
|
+
delta: { stop_reason: stopReason ?? "end_turn", stop_sequence: null },
|
|
38871
|
+
usage: {
|
|
38872
|
+
...inputTokens > 0 ? { input_tokens: inputTokens } : {},
|
|
38873
|
+
output_tokens: outputTokens
|
|
38874
|
+
}
|
|
38875
|
+
});
|
|
38876
|
+
send("message_stop", { type: "message_stop" });
|
|
38877
|
+
sawMessageStop = true;
|
|
38878
|
+
} catch {}
|
|
38604
38879
|
};
|
|
38605
38880
|
return c.body(new ReadableStream({
|
|
38606
38881
|
async start(controller) {
|
|
@@ -38621,12 +38896,9 @@ data: {"type":"ping"}
|
|
|
38621
38896
|
try {
|
|
38622
38897
|
const reader = response.body.getReader();
|
|
38623
38898
|
let buffer = "";
|
|
38624
|
-
let inputTokens = 0;
|
|
38625
|
-
let outputTokens = 0;
|
|
38626
38899
|
let totalLines = 0;
|
|
38627
38900
|
let textChunks = 0;
|
|
38628
38901
|
let toolUseBlocks = 0;
|
|
38629
|
-
let stopReason = null;
|
|
38630
38902
|
let insideThinkingBlock = false;
|
|
38631
38903
|
let thinkingBlocksSuppressed = 0;
|
|
38632
38904
|
let suppressedFrame = false;
|
|
@@ -38691,6 +38963,7 @@ data: ${JSON.stringify({
|
|
|
38691
38963
|
flushPendingEvent(controller);
|
|
38692
38964
|
controller.enqueue(encoder.encode(`${modifiedLine}
|
|
38693
38965
|
`));
|
|
38966
|
+
noteLifecycle(data, reindexed);
|
|
38694
38967
|
}
|
|
38695
38968
|
} else {
|
|
38696
38969
|
enqueueData(controller, data, line);
|
|
@@ -38813,6 +39086,13 @@ data: ${JSON.stringify({
|
|
|
38813
39086
|
}
|
|
38814
39087
|
} catch (e) {
|
|
38815
39088
|
log(`[AnthropicSSE] Stream error: ${e}`);
|
|
39089
|
+
finalizeAbandonedStream(controller);
|
|
39090
|
+
try {
|
|
39091
|
+
opts.onTurnEnd?.();
|
|
39092
|
+
} catch {}
|
|
39093
|
+
try {
|
|
39094
|
+
opts.onTokenUpdate?.(inputTokens, outputTokens);
|
|
39095
|
+
} catch {}
|
|
38816
39096
|
if (!isClosed) {
|
|
38817
39097
|
isClosed = true;
|
|
38818
39098
|
if (pingInterval) {
|
|
@@ -40773,9 +41053,12 @@ class ComposedHandler {
|
|
|
40773
41053
|
behaviorSession?.noteTurnComplete(this.tokenTracker.getInputTokens());
|
|
40774
41054
|
} catch {}
|
|
40775
41055
|
};
|
|
40776
|
-
|
|
41056
|
+
const streamed = this.handleStream(c, response, adapter, claudeRequest, toolNameMap, onStreamComplete, (code, message) => {
|
|
40777
41057
|
streamApiError = { code, message };
|
|
40778
41058
|
}, behaviorSession);
|
|
41059
|
+
if (payload?.stream === true)
|
|
41060
|
+
return streamed;
|
|
41061
|
+
return sseResponseToJson(streamed, this.bareModelName);
|
|
40779
41062
|
}
|
|
40780
41063
|
async settleResponsesStreamHead(initial, reissue) {
|
|
40781
41064
|
let response = initial;
|
|
@@ -41084,6 +41367,7 @@ var init_composed_handler = __esm(() => {
|
|
|
41084
41367
|
init_telemetry();
|
|
41085
41368
|
init_transform();
|
|
41086
41369
|
init_anthropic_error();
|
|
41370
|
+
init_collect_sse_message();
|
|
41087
41371
|
init_connection_error();
|
|
41088
41372
|
init_devin_stream_head_sniffer();
|
|
41089
41373
|
init_openai_compat();
|
|
@@ -44029,6 +44313,83 @@ var init_channel = __esm(() => {
|
|
|
44029
44313
|
init_session_manager();
|
|
44030
44314
|
});
|
|
44031
44315
|
|
|
44316
|
+
// src/mcp/progress-heartbeat.ts
|
|
44317
|
+
function isProgressToken(v) {
|
|
44318
|
+
return typeof v === "string" || typeof v === "number" && Number.isFinite(v);
|
|
44319
|
+
}
|
|
44320
|
+
function clampInterval(ms) {
|
|
44321
|
+
if (ms < MIN_PROGRESS_INTERVAL_MS)
|
|
44322
|
+
return MIN_PROGRESS_INTERVAL_MS;
|
|
44323
|
+
if (ms > MAX_PROGRESS_INTERVAL_MS)
|
|
44324
|
+
return MAX_PROGRESS_INTERVAL_MS;
|
|
44325
|
+
return ms;
|
|
44326
|
+
}
|
|
44327
|
+
function resolveProgressIntervalMs(env = process.env) {
|
|
44328
|
+
const raw = env[PROGRESS_INTERVAL_ENV_VAR];
|
|
44329
|
+
if (raw === undefined || raw === null || raw.trim() === "")
|
|
44330
|
+
return DEFAULT_PROGRESS_INTERVAL_MS;
|
|
44331
|
+
const parsed = Number(raw);
|
|
44332
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
44333
|
+
return DEFAULT_PROGRESS_INTERVAL_MS;
|
|
44334
|
+
return clampInterval(parsed);
|
|
44335
|
+
}
|
|
44336
|
+
function resolveExplicitIntervalMs(ms) {
|
|
44337
|
+
if (ms === undefined)
|
|
44338
|
+
return DEFAULT_PROGRESS_INTERVAL_MS;
|
|
44339
|
+
if (!Number.isFinite(ms) || ms <= 0)
|
|
44340
|
+
return DEFAULT_PROGRESS_INTERVAL_MS;
|
|
44341
|
+
return Math.min(ms, MAX_PROGRESS_INTERVAL_MS);
|
|
44342
|
+
}
|
|
44343
|
+
function startHeartbeat(opts) {
|
|
44344
|
+
const { token, send, label } = opts;
|
|
44345
|
+
if (!isProgressToken(token))
|
|
44346
|
+
return NOOP_HEARTBEAT;
|
|
44347
|
+
const intervalMs = resolveExplicitIntervalMs(opts.intervalMs);
|
|
44348
|
+
const startedAt = Date.now();
|
|
44349
|
+
let progress = 0;
|
|
44350
|
+
let stopped = false;
|
|
44351
|
+
const emit2 = (message) => {
|
|
44352
|
+
if (stopped)
|
|
44353
|
+
return;
|
|
44354
|
+
progress += 1;
|
|
44355
|
+
try {
|
|
44356
|
+
const elapsedSeconds = Math.round((Date.now() - startedAt) / 1000);
|
|
44357
|
+
const result = send({
|
|
44358
|
+
progressToken: token,
|
|
44359
|
+
progress,
|
|
44360
|
+
message: message ?? `${label}: working (${elapsedSeconds}s)`
|
|
44361
|
+
});
|
|
44362
|
+
if (result && typeof result.then === "function") {
|
|
44363
|
+
result.catch(() => {});
|
|
44364
|
+
}
|
|
44365
|
+
} catch {}
|
|
44366
|
+
};
|
|
44367
|
+
const timer = setInterval(() => emit2(), intervalMs);
|
|
44368
|
+
timer.unref?.();
|
|
44369
|
+
return {
|
|
44370
|
+
tick: (message) => emit2(message),
|
|
44371
|
+
stop: () => {
|
|
44372
|
+
stopped = true;
|
|
44373
|
+
clearInterval(timer);
|
|
44374
|
+
},
|
|
44375
|
+
get active() {
|
|
44376
|
+
return !stopped;
|
|
44377
|
+
},
|
|
44378
|
+
get emitted() {
|
|
44379
|
+
return progress;
|
|
44380
|
+
}
|
|
44381
|
+
};
|
|
44382
|
+
}
|
|
44383
|
+
var DEFAULT_PROGRESS_INTERVAL_MS = 1e4, MIN_PROGRESS_INTERVAL_MS = 1000, MAX_PROGRESS_INTERVAL_MS = 60000, PROGRESS_INTERVAL_ENV_VAR = "CLAUDISH_MCP_PROGRESS_INTERVAL_MS", NOOP_HEARTBEAT;
|
|
44384
|
+
var init_progress_heartbeat = __esm(() => {
|
|
44385
|
+
NOOP_HEARTBEAT = Object.freeze({
|
|
44386
|
+
tick(_message) {},
|
|
44387
|
+
stop() {},
|
|
44388
|
+
active: false,
|
|
44389
|
+
emitted: 0
|
|
44390
|
+
});
|
|
44391
|
+
});
|
|
44392
|
+
|
|
44032
44393
|
// src/providers/cache-ttl.ts
|
|
44033
44394
|
var FIREBASE_CACHE_TTL_HOURS = 24, FIREBASE_CACHE_TTL_MS;
|
|
44034
44395
|
var init_cache_ttl = __esm(() => {
|
|
@@ -46892,6 +47253,34 @@ var init_native_handler_advisor = __esm(() => {
|
|
|
46892
47253
|
advisorToolUseIds = new Set;
|
|
46893
47254
|
});
|
|
46894
47255
|
|
|
47256
|
+
// src/handlers/shared/thinking-signature.ts
|
|
47257
|
+
function isUnsignedThinking(block) {
|
|
47258
|
+
if (!block || typeof block !== "object")
|
|
47259
|
+
return false;
|
|
47260
|
+
const b = block;
|
|
47261
|
+
if (b.type !== "thinking")
|
|
47262
|
+
return false;
|
|
47263
|
+
return typeof b.signature !== "string" || b.signature.length === 0;
|
|
47264
|
+
}
|
|
47265
|
+
function stripUnsignedThinkingBlocks(messages) {
|
|
47266
|
+
if (!Array.isArray(messages))
|
|
47267
|
+
return 0;
|
|
47268
|
+
let removed = 0;
|
|
47269
|
+
for (const message of messages) {
|
|
47270
|
+
if (!message || typeof message !== "object")
|
|
47271
|
+
continue;
|
|
47272
|
+
const content = message.content;
|
|
47273
|
+
if (!Array.isArray(content))
|
|
47274
|
+
continue;
|
|
47275
|
+
const kept = content.filter((block) => !isUnsignedThinking(block));
|
|
47276
|
+
if (kept.length !== content.length) {
|
|
47277
|
+
removed += content.length - kept.length;
|
|
47278
|
+
message.content = kept;
|
|
47279
|
+
}
|
|
47280
|
+
}
|
|
47281
|
+
return removed;
|
|
47282
|
+
}
|
|
47283
|
+
|
|
46895
47284
|
// src/handlers/native-handler.ts
|
|
46896
47285
|
async function resolveAdvisorKeys() {
|
|
46897
47286
|
const keyFromAuthority = async (name) => {
|
|
@@ -46937,6 +47326,10 @@ class NativeHandler {
|
|
|
46937
47326
|
async handle(c, payload) {
|
|
46938
47327
|
const originalHeaders = c.req.header();
|
|
46939
47328
|
const target = payload.model;
|
|
47329
|
+
const strippedThinking = stripUnsignedThinkingBlocks(payload.messages);
|
|
47330
|
+
if (strippedThinking > 0) {
|
|
47331
|
+
log(`[Native] stripped ${strippedThinking} unsigned thinking block(s) from history for ${target} (foreign-provider origin)`);
|
|
47332
|
+
}
|
|
46940
47333
|
const advisorCfg = loadAdvisorSwapConfig(this.advisorModels, this.advisorCollector);
|
|
46941
47334
|
let advisorSwapped = null;
|
|
46942
47335
|
let advisorRewrittenIds = [];
|
|
@@ -47958,7 +48351,8 @@ var init_vertex_oauth = __esm(() => {
|
|
|
47958
48351
|
|
|
47959
48352
|
// src/providers/provider-profiles.ts
|
|
47960
48353
|
function requiresResponsesApi(modelName) {
|
|
47961
|
-
|
|
48354
|
+
const name = modelName.toLowerCase();
|
|
48355
|
+
return /^gpt-5\.6/.test(name) || name.includes("codex");
|
|
47962
48356
|
}
|
|
47963
48357
|
function createHandlerForProvider(ctx) {
|
|
47964
48358
|
const profile = PROVIDER_PROFILES[ctx.provider.name] ?? getRuntimeProfiles().get(ctx.provider.name);
|
|
@@ -49693,12 +50087,132 @@ function writeStatusFile(sessionPath, manifest, status, opts) {
|
|
|
49693
50087
|
var CHANNEL_LINE_BUDGET = 58;
|
|
49694
50088
|
var init_team_stats = () => {};
|
|
49695
50089
|
|
|
50090
|
+
// src/team-stream-capture.ts
|
|
50091
|
+
function extractAssistantText(event) {
|
|
50092
|
+
if (event.type !== "assistant")
|
|
50093
|
+
return [];
|
|
50094
|
+
const message = event.message;
|
|
50095
|
+
const content = message?.content;
|
|
50096
|
+
if (typeof content === "string") {
|
|
50097
|
+
return content.length > 0 ? [content] : [];
|
|
50098
|
+
}
|
|
50099
|
+
if (!Array.isArray(content))
|
|
50100
|
+
return [];
|
|
50101
|
+
const out = [];
|
|
50102
|
+
for (const raw2 of content) {
|
|
50103
|
+
const block = raw2;
|
|
50104
|
+
if (block?.type !== "text")
|
|
50105
|
+
continue;
|
|
50106
|
+
if (typeof block.text !== "string" || block.text.length === 0)
|
|
50107
|
+
continue;
|
|
50108
|
+
out.push(block.text);
|
|
50109
|
+
}
|
|
50110
|
+
return out;
|
|
50111
|
+
}
|
|
50112
|
+
function createAssistantTextCapture() {
|
|
50113
|
+
let pending = "";
|
|
50114
|
+
let emittedAny = false;
|
|
50115
|
+
let endsWithNewline = false;
|
|
50116
|
+
let dedupeTail = "";
|
|
50117
|
+
let lastWasMessage = false;
|
|
50118
|
+
const record4 = (text, kind) => {
|
|
50119
|
+
emittedAny = true;
|
|
50120
|
+
lastWasMessage = kind === "message";
|
|
50121
|
+
endsWithNewline = text.endsWith(`
|
|
50122
|
+
`);
|
|
50123
|
+
dedupeTail = (dedupeTail + text).slice(-DEDUPE_TAIL_LIMIT);
|
|
50124
|
+
};
|
|
50125
|
+
const messageSeparator = () => {
|
|
50126
|
+
if (!emittedAny)
|
|
50127
|
+
return "";
|
|
50128
|
+
return endsWithNewline ? `
|
|
50129
|
+
` : `
|
|
50130
|
+
|
|
50131
|
+
`;
|
|
50132
|
+
};
|
|
50133
|
+
const rawSeparator = () => {
|
|
50134
|
+
if (!emittedAny || endsWithNewline)
|
|
50135
|
+
return "";
|
|
50136
|
+
return `
|
|
50137
|
+
`;
|
|
50138
|
+
};
|
|
50139
|
+
const consumeLine = (line, terminated) => {
|
|
50140
|
+
if (line.trim().length === 0)
|
|
50141
|
+
return "";
|
|
50142
|
+
const passthrough = () => {
|
|
50143
|
+
const out = `${rawSeparator()}${line}${terminated ? `
|
|
50144
|
+
` : ""}`;
|
|
50145
|
+
record4(out, "raw");
|
|
50146
|
+
return out;
|
|
50147
|
+
};
|
|
50148
|
+
let event;
|
|
50149
|
+
try {
|
|
50150
|
+
event = JSON.parse(line);
|
|
50151
|
+
} catch {
|
|
50152
|
+
return passthrough();
|
|
50153
|
+
}
|
|
50154
|
+
if (typeof event.type !== "string" || !STREAM_JSON_EVENT_TYPES.has(event.type)) {
|
|
50155
|
+
return passthrough();
|
|
50156
|
+
}
|
|
50157
|
+
const texts = extractAssistantText(event);
|
|
50158
|
+
if (texts.length > 0) {
|
|
50159
|
+
let out = "";
|
|
50160
|
+
for (const text of texts) {
|
|
50161
|
+
const piece = `${messageSeparator()}${text}`;
|
|
50162
|
+
out += piece;
|
|
50163
|
+
record4(piece, "message");
|
|
50164
|
+
}
|
|
50165
|
+
return out;
|
|
50166
|
+
}
|
|
50167
|
+
if (event.type === "result" && event.is_error === true) {
|
|
50168
|
+
const result = typeof event.result === "string" ? event.result : "";
|
|
50169
|
+
if (result.trim().length > 0 && !dedupeTail.includes(result)) {
|
|
50170
|
+
const out = `${messageSeparator()}${result}`;
|
|
50171
|
+
record4(out, "message");
|
|
50172
|
+
return out;
|
|
50173
|
+
}
|
|
50174
|
+
}
|
|
50175
|
+
return "";
|
|
50176
|
+
};
|
|
50177
|
+
return {
|
|
50178
|
+
write(chunk) {
|
|
50179
|
+
pending += chunk;
|
|
50180
|
+
let out = "";
|
|
50181
|
+
let newlineAt = pending.indexOf(`
|
|
50182
|
+
`);
|
|
50183
|
+
while (newlineAt !== -1) {
|
|
50184
|
+
const line = pending.slice(0, newlineAt);
|
|
50185
|
+
pending = pending.slice(newlineAt + 1);
|
|
50186
|
+
out += consumeLine(line, true);
|
|
50187
|
+
newlineAt = pending.indexOf(`
|
|
50188
|
+
`);
|
|
50189
|
+
}
|
|
50190
|
+
return out;
|
|
50191
|
+
},
|
|
50192
|
+
end() {
|
|
50193
|
+
let out = pending.length > 0 ? consumeLine(pending, false) : "";
|
|
50194
|
+
pending = "";
|
|
50195
|
+
if (emittedAny && !endsWithNewline && lastWasMessage) {
|
|
50196
|
+
out += `
|
|
50197
|
+
`;
|
|
50198
|
+
endsWithNewline = true;
|
|
50199
|
+
}
|
|
50200
|
+
return out;
|
|
50201
|
+
}
|
|
50202
|
+
};
|
|
50203
|
+
}
|
|
50204
|
+
var DEDUPE_TAIL_LIMIT = 4096, STREAM_JSON_EVENT_TYPES;
|
|
50205
|
+
var init_team_stream_capture = __esm(() => {
|
|
50206
|
+
STREAM_JSON_EVENT_TYPES = new Set(["system", "assistant", "user", "result"]);
|
|
50207
|
+
});
|
|
50208
|
+
|
|
49696
50209
|
// src/team-orchestrator.ts
|
|
49697
50210
|
var exports_team_orchestrator = {};
|
|
49698
50211
|
__export(exports_team_orchestrator, {
|
|
49699
50212
|
validateSessionPath: () => validateSessionPath,
|
|
49700
50213
|
setupSession: () => setupSession,
|
|
49701
50214
|
runModels: () => runModels,
|
|
50215
|
+
resolveCaptureMode: () => resolveCaptureMode,
|
|
49702
50216
|
parseJudgeVotes: () => parseJudgeVotes,
|
|
49703
50217
|
judgeResponses: () => judgeResponses,
|
|
49704
50218
|
getStatus: () => getStatus,
|
|
@@ -49706,6 +50220,7 @@ __export(exports_team_orchestrator, {
|
|
|
49706
50220
|
classifyRunOutput: () => classifyRunOutput,
|
|
49707
50221
|
buildJudgePrompt: () => buildJudgePrompt,
|
|
49708
50222
|
aggregateVerdict: () => aggregateVerdict,
|
|
50223
|
+
TEAM_CAPTURE_ENV_VAR: () => TEAM_CAPTURE_ENV_VAR,
|
|
49709
50224
|
STDOUT_TAIL_LIMIT: () => STDOUT_TAIL_LIMIT,
|
|
49710
50225
|
DEFAULT_MIN_OUTPUT_BYTES: () => DEFAULT_MIN_OUTPUT_BYTES
|
|
49711
50226
|
});
|
|
@@ -49719,8 +50234,21 @@ import {
|
|
|
49719
50234
|
writeFileSync as writeFileSync12
|
|
49720
50235
|
} from "fs";
|
|
49721
50236
|
import { join as join28, resolve as resolve3 } from "path";
|
|
50237
|
+
function resolveCaptureMode(explicit, env = process.env) {
|
|
50238
|
+
if (explicit)
|
|
50239
|
+
return explicit;
|
|
50240
|
+
return env[TEAM_CAPTURE_ENV_VAR]?.trim().toLowerCase() === "print" ? "print" : "stream-json";
|
|
50241
|
+
}
|
|
49722
50242
|
function classifyRunOutput(opts) {
|
|
49723
|
-
const {
|
|
50243
|
+
const {
|
|
50244
|
+
outputSize,
|
|
50245
|
+
stdoutTail,
|
|
50246
|
+
stderr,
|
|
50247
|
+
minOutputBytes,
|
|
50248
|
+
requirePattern,
|
|
50249
|
+
fullOutput,
|
|
50250
|
+
captureMode = "print"
|
|
50251
|
+
} = opts;
|
|
49724
50252
|
const apiError = API_ERROR_RE.exec(stdoutTail);
|
|
49725
50253
|
if (apiError) {
|
|
49726
50254
|
return {
|
|
@@ -49748,6 +50276,22 @@ function classifyRunOutput(opts) {
|
|
|
49748
50276
|
detail: `Child exited 0 but produced only ${outputSize} B of stdout ` + `(caller required at least ${minOutputBytes} B).`
|
|
49749
50277
|
};
|
|
49750
50278
|
}
|
|
50279
|
+
if (requirePattern) {
|
|
50280
|
+
const haystack = fullOutput ?? stdoutTail;
|
|
50281
|
+
let re = null;
|
|
50282
|
+
try {
|
|
50283
|
+
re = new RegExp(requirePattern);
|
|
50284
|
+
} catch {
|
|
50285
|
+
re = null;
|
|
50286
|
+
}
|
|
50287
|
+
if (re && !re.test(haystack)) {
|
|
50288
|
+
const cause = captureMode === "stream-json" ? "Every assistant message this child produced was captured and concatenated, " + "so this is not the print-mode dropout: the model genuinely never emitted the " + "required shape. Re-prompt it, or relax the contract." : "This is the signature of a child that answered and then took one more turn: " + "`claude -p` prints only the FINAL assistant message, so a background task " + "completing (or any late notification) replaces the real answer with an " + "epilogue about it. The answer was generated, it just was not the last thing " + "said \u2014 re-run with the default stream-json capture to keep it.";
|
|
50289
|
+
return {
|
|
50290
|
+
reason: "shape_mismatch",
|
|
50291
|
+
detail: `Child exited 0 with ${outputSize} B, but the response does not match the ` + `required pattern /${requirePattern}/. ${cause}`
|
|
50292
|
+
};
|
|
50293
|
+
}
|
|
50294
|
+
}
|
|
49751
50295
|
return null;
|
|
49752
50296
|
}
|
|
49753
50297
|
function persistErrorLog(errorLogPath, header, stderr, stdoutTail) {
|
|
@@ -49826,8 +50370,28 @@ function setupSession(sessionPath, models, input) {
|
|
|
49826
50370
|
writeFileSync12(join28(sessionPath, "status.json"), JSON.stringify(status, null, 2), "utf-8");
|
|
49827
50371
|
return manifest;
|
|
49828
50372
|
}
|
|
50373
|
+
function assertValidRequirePattern(pattern) {
|
|
50374
|
+
if (pattern === undefined)
|
|
50375
|
+
return;
|
|
50376
|
+
try {
|
|
50377
|
+
new RegExp(pattern);
|
|
50378
|
+
} catch (err) {
|
|
50379
|
+
throw new Error(`Invalid requirePattern /${pattern}/: ${err instanceof Error ? err.message : String(err)}`);
|
|
50380
|
+
}
|
|
50381
|
+
}
|
|
50382
|
+
function readFullOutputIfNeeded(opts) {
|
|
50383
|
+
const { crashed, requirePattern, outputSize, outputPath } = opts;
|
|
50384
|
+
if (crashed || !requirePattern || outputSize <= STDOUT_TAIL_LIMIT)
|
|
50385
|
+
return;
|
|
50386
|
+
try {
|
|
50387
|
+
return readFileSync18(outputPath, "utf-8");
|
|
50388
|
+
} catch {
|
|
50389
|
+
return;
|
|
50390
|
+
}
|
|
50391
|
+
}
|
|
49829
50392
|
async function runModels(sessionPath, opts = {}) {
|
|
49830
50393
|
const timeoutMs = (opts.timeout ?? 300) * 1000;
|
|
50394
|
+
assertValidRequirePattern(opts.requirePattern);
|
|
49831
50395
|
const manifest = JSON.parse(readFileSync18(join28(sessionPath, "manifest.json"), "utf-8"));
|
|
49832
50396
|
const statusPath = join28(sessionPath, "status.json");
|
|
49833
50397
|
const inputPath = join28(sessionPath, "input.md");
|
|
@@ -49839,6 +50403,8 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
49839
50403
|
writeFileSync12(statusPath, JSON.stringify(statusCache, null, 2), "utf-8");
|
|
49840
50404
|
}
|
|
49841
50405
|
const minOutputBytes = opts.minOutputBytes ?? DEFAULT_MIN_OUTPUT_BYTES;
|
|
50406
|
+
const requirePattern = opts.requirePattern;
|
|
50407
|
+
const captureMode = resolveCaptureMode(opts.captureMode);
|
|
49842
50408
|
mkdirSync12(statsDir(sessionPath), { recursive: true });
|
|
49843
50409
|
const processes = new Map;
|
|
49844
50410
|
const runtimes = new Map;
|
|
@@ -49855,7 +50421,14 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
49855
50421
|
const outputPath = join28(sessionPath, `response-${anonId}.md`);
|
|
49856
50422
|
const errorLogPath = join28(sessionPath, "errors", `${anonId}.log`);
|
|
49857
50423
|
const spawnModel = spawnPlan.pinned.get(entry.model) ?? entry.model;
|
|
49858
|
-
const args = [
|
|
50424
|
+
const args = [
|
|
50425
|
+
"--model",
|
|
50426
|
+
spawnModel,
|
|
50427
|
+
"-y",
|
|
50428
|
+
"--stdin",
|
|
50429
|
+
...captureMode === "stream-json" ? ["--verbose", "--quiet", "--output-format", "stream-json"] : ["--quiet"],
|
|
50430
|
+
...opts.claudeFlags ?? []
|
|
50431
|
+
];
|
|
49859
50432
|
updateModelStatus(anonId, {
|
|
49860
50433
|
state: "RUNNING",
|
|
49861
50434
|
startedAt: new Date().toISOString()
|
|
@@ -49871,12 +50444,36 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
49871
50444
|
});
|
|
49872
50445
|
let byteCount = 0;
|
|
49873
50446
|
let stdoutTail = "";
|
|
49874
|
-
proc.stdout?.on("data", (chunk) => {
|
|
49875
|
-
byteCount += chunk.length;
|
|
49876
|
-
stdoutTail = (stdoutTail + chunk.toString()).slice(-STDOUT_TAIL_LIMIT);
|
|
49877
|
-
});
|
|
49878
50447
|
const outputStream = createWriteStream2(outputPath);
|
|
49879
|
-
|
|
50448
|
+
let flushPartial = () => {};
|
|
50449
|
+
if (captureMode === "print") {
|
|
50450
|
+
proc.stdout?.on("data", (chunk) => {
|
|
50451
|
+
byteCount += chunk.length;
|
|
50452
|
+
stdoutTail = (stdoutTail + chunk.toString()).slice(-STDOUT_TAIL_LIMIT);
|
|
50453
|
+
});
|
|
50454
|
+
proc.stdout?.pipe(outputStream);
|
|
50455
|
+
} else {
|
|
50456
|
+
const capture = createAssistantTextCapture();
|
|
50457
|
+
const absorb = (text) => {
|
|
50458
|
+
if (text.length === 0)
|
|
50459
|
+
return;
|
|
50460
|
+
byteCount += Buffer.byteLength(text);
|
|
50461
|
+
stdoutTail = (stdoutTail + text).slice(-STDOUT_TAIL_LIMIT);
|
|
50462
|
+
outputStream.write(text);
|
|
50463
|
+
};
|
|
50464
|
+
proc.stdout?.on("data", (chunk) => absorb(capture.write(chunk.toString())));
|
|
50465
|
+
flushPartial = () => absorb(capture.end());
|
|
50466
|
+
let captureFinalized = false;
|
|
50467
|
+
const finalizeCapture = () => {
|
|
50468
|
+
if (captureFinalized)
|
|
50469
|
+
return;
|
|
50470
|
+
captureFinalized = true;
|
|
50471
|
+
absorb(capture.end());
|
|
50472
|
+
outputStream.end();
|
|
50473
|
+
};
|
|
50474
|
+
proc.stdout?.on("end", finalizeCapture);
|
|
50475
|
+
proc.stdout?.on("close", finalizeCapture);
|
|
50476
|
+
}
|
|
49880
50477
|
let stderr = "";
|
|
49881
50478
|
proc.stderr?.on("data", (chunk) => {
|
|
49882
50479
|
stderr += chunk.toString();
|
|
@@ -49887,7 +50484,8 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
49887
50484
|
errorLogPath,
|
|
49888
50485
|
getStderr: () => stderr,
|
|
49889
50486
|
getStdoutTail: () => stdoutTail,
|
|
49890
|
-
getByteCount: () => byteCount
|
|
50487
|
+
getByteCount: () => byteCount,
|
|
50488
|
+
flushPartial: () => flushPartial()
|
|
49891
50489
|
});
|
|
49892
50490
|
proc.stdin?.write(inputContent);
|
|
49893
50491
|
proc.stdin?.end();
|
|
@@ -49905,7 +50503,21 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
49905
50503
|
resolved = true;
|
|
49906
50504
|
const outputSize = byteCount;
|
|
49907
50505
|
const crashed = exitCode !== 0;
|
|
49908
|
-
const
|
|
50506
|
+
const fullOutput = readFullOutputIfNeeded({
|
|
50507
|
+
crashed,
|
|
50508
|
+
requirePattern,
|
|
50509
|
+
outputSize,
|
|
50510
|
+
outputPath
|
|
50511
|
+
});
|
|
50512
|
+
const degraded = crashed ? null : classifyRunOutput({
|
|
50513
|
+
outputSize,
|
|
50514
|
+
stdoutTail,
|
|
50515
|
+
stderr,
|
|
50516
|
+
minOutputBytes,
|
|
50517
|
+
requirePattern,
|
|
50518
|
+
fullOutput,
|
|
50519
|
+
captureMode
|
|
50520
|
+
});
|
|
49909
50521
|
const failed = crashed || degraded !== null;
|
|
49910
50522
|
const state = crashed ? "FAILED" : degraded ? "EMPTY" : "COMPLETED";
|
|
49911
50523
|
if (failed) {
|
|
@@ -50001,10 +50613,11 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
50001
50613
|
if (!proc.killed)
|
|
50002
50614
|
proc.kill("SIGTERM");
|
|
50003
50615
|
const rt = runtimes.get(id);
|
|
50616
|
+
rt?.flushPartial();
|
|
50004
50617
|
const stderr = rt?.getStderr() ?? "";
|
|
50005
50618
|
const stdoutTail = rt?.getStdoutTail() ?? "";
|
|
50006
50619
|
const bytes2 = rt?.getByteCount() ?? 0;
|
|
50007
|
-
const detail = `Killed by the orchestrator after ${timeoutMs / 1000}s with ${bytes2} B of stdout. ` + "
|
|
50620
|
+
const detail = `Killed by the orchestrator after ${timeoutMs / 1000}s with ${bytes2} B of stdout. ` + "That figure counts the ANSWER, not the wire format, so 0 B means the child had " + `not produced an assistant message yet \u2014 "did not finish", not "produced nothing".`;
|
|
50008
50621
|
if (rt)
|
|
50009
50622
|
persistErrorLog(rt.errorLogPath, `TIMEOUT: ${detail}`, stderr, stdoutTail);
|
|
50010
50623
|
updateModelStatus(id, {
|
|
@@ -50216,11 +50829,12 @@ function formatVerdict(verdict, sessionPath) {
|
|
|
50216
50829
|
}
|
|
50217
50830
|
return output;
|
|
50218
50831
|
}
|
|
50219
|
-
var STDOUT_TAIL_LIMIT = 4000, API_ERROR_RE, BG_CEILING_RE, DEFAULT_MIN_OUTPUT_BYTES = 0, SENTINEL_MODELS;
|
|
50832
|
+
var TEAM_CAPTURE_ENV_VAR = "CLAUDISH_TEAM_CAPTURE", STDOUT_TAIL_LIMIT = 4000, API_ERROR_RE, BG_CEILING_RE, DEFAULT_MIN_OUTPUT_BYTES = 0, SENTINEL_MODELS;
|
|
50220
50833
|
var init_team_orchestrator = __esm(() => {
|
|
50221
50834
|
init_prehydrate();
|
|
50222
50835
|
init_redact();
|
|
50223
50836
|
init_team_stats();
|
|
50837
|
+
init_team_stream_capture();
|
|
50224
50838
|
API_ERROR_RE = /\[API Error:\s*([^\]]{0,300})\]/i;
|
|
50225
50839
|
BG_CEILING_RE = /Background tasks still running after (\d+)s; terminating/i;
|
|
50226
50840
|
SENTINEL_MODELS = new Set([
|
|
@@ -50438,6 +51052,7 @@ ${block.join(`
|
|
|
50438
51052
|
required: ["model", "prompt"]
|
|
50439
51053
|
},
|
|
50440
51054
|
group: "low-level",
|
|
51055
|
+
heartbeat: true,
|
|
50441
51056
|
handler: async (args) => {
|
|
50442
51057
|
try {
|
|
50443
51058
|
const result = await runPromptViaProxy(args.model, args.prompt, args.system_prompt, args.max_tokens);
|
|
@@ -50658,7 +51273,8 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
50658
51273
|
required: ["models", "prompt"]
|
|
50659
51274
|
},
|
|
50660
51275
|
group: "low-level",
|
|
50661
|
-
|
|
51276
|
+
heartbeat: true,
|
|
51277
|
+
handler: async (args, ctx) => {
|
|
50662
51278
|
const modelIds = args.models;
|
|
50663
51279
|
const prompt = args.prompt;
|
|
50664
51280
|
const systemPrompt = args.system_prompt;
|
|
@@ -50675,6 +51291,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
50675
51291
|
error: error46 instanceof Error ? error46.message : String(error46)
|
|
50676
51292
|
});
|
|
50677
51293
|
}
|
|
51294
|
+
ctx.reportProgress(`compare_models: ${results.length}/${modelIds.length} models done`);
|
|
50678
51295
|
}
|
|
50679
51296
|
let output = `# Model Comparison
|
|
50680
51297
|
|
|
@@ -50740,12 +51357,21 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
50740
51357
|
type: "string",
|
|
50741
51358
|
description: "Task prompt text (or place input.md in the session directory before calling)"
|
|
50742
51359
|
},
|
|
50743
|
-
timeout: { type: "number", description: "Per-model timeout in seconds (default: 300)" }
|
|
51360
|
+
timeout: { type: "number", description: "Per-model timeout in seconds (default: 300)" },
|
|
51361
|
+
require_pattern: {
|
|
51362
|
+
type: "string",
|
|
51363
|
+
description: "Regex the response MUST match, or the slot is reported FAILED (state EMPTY, " + "reason 'shape_mismatch') instead of succeeded. Strongly recommended whenever " + "your prompt mandates an output shape \u2014 e.g. '```vote' for a voting panel. " + "Exit code 0 is not a success oracle: it is 0 on API errors and on a child " + "that simply never followed the format. Answers are no longer LOST to print " + "mode (every assistant message is captured), so a mismatch now means the model " + "did not produce the shape, not that the shape was discarded."
|
|
51364
|
+
},
|
|
51365
|
+
min_output_bytes: {
|
|
51366
|
+
type: "number",
|
|
51367
|
+
description: "Report a slot FAILED if it produced fewer than this many bytes (default 0 = " + "off). A blunter instrument than require_pattern \u2014 short answers can be " + "legitimate \u2014 so prefer require_pattern when you know the expected shape."
|
|
51368
|
+
}
|
|
50744
51369
|
},
|
|
50745
51370
|
required: ["mode", "path"]
|
|
50746
51371
|
},
|
|
50747
51372
|
group: "agentic",
|
|
50748
|
-
|
|
51373
|
+
heartbeat: true,
|
|
51374
|
+
handler: async (args, ctx) => {
|
|
50749
51375
|
try {
|
|
50750
51376
|
const mode = args.mode;
|
|
50751
51377
|
const path = args.path;
|
|
@@ -50753,19 +51379,26 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
50753
51379
|
const judges = args.judges;
|
|
50754
51380
|
const input = args.input;
|
|
50755
51381
|
const timeout = args.timeout;
|
|
51382
|
+
const requirePattern = args.require_pattern;
|
|
51383
|
+
const minOutputBytes = args.min_output_bytes;
|
|
50756
51384
|
const resolved = validateSessionPath(path);
|
|
50757
51385
|
const teamSessionId = resolved.split("/").filter(Boolean).pop() ?? "team";
|
|
50758
51386
|
const teamCreatedAt = new Date().toISOString();
|
|
50759
51387
|
const runOpts = {
|
|
50760
51388
|
timeout,
|
|
50761
|
-
|
|
50762
|
-
|
|
50763
|
-
|
|
50764
|
-
|
|
50765
|
-
|
|
50766
|
-
|
|
50767
|
-
|
|
50768
|
-
|
|
51389
|
+
requirePattern,
|
|
51390
|
+
minOutputBytes,
|
|
51391
|
+
onProgress: (u) => {
|
|
51392
|
+
ctx.reportProgress(`team: ${u.phase}`);
|
|
51393
|
+
notifyChannel({
|
|
51394
|
+
content: u.rendered,
|
|
51395
|
+
sessionId: teamSessionId,
|
|
51396
|
+
event: u.phase === "settled" ? u.allFailed ? "failed" : "completed" : "running",
|
|
51397
|
+
model: "team",
|
|
51398
|
+
elapsedSeconds: (Date.now() - Date.parse(teamCreatedAt)) / 1000,
|
|
51399
|
+
createdAt: teamCreatedAt
|
|
51400
|
+
});
|
|
51401
|
+
}
|
|
50769
51402
|
};
|
|
50770
51403
|
switch (mode) {
|
|
50771
51404
|
case "run": {
|
|
@@ -51200,6 +51833,7 @@ To report this error, use the report_error tool with error_type: "provider_failu
|
|
|
51200
51833
|
watchNotificationResult(result, { sessionId: p.sessionId, eventType: p.event });
|
|
51201
51834
|
} catch {}
|
|
51202
51835
|
};
|
|
51836
|
+
const progressIntervalMs = resolveProgressIntervalMs();
|
|
51203
51837
|
const allTools = defineTools(sessionManager, notifyChannel);
|
|
51204
51838
|
const enabledTools = allTools.filter((t) => enabledGroups.has(t.group));
|
|
51205
51839
|
const toolMap = new Map(enabledTools.map((t) => [t.name, t]));
|
|
@@ -51211,7 +51845,7 @@ To report this error, use the report_error tool with error_type: "provider_failu
|
|
|
51211
51845
|
inputSchema: t.inputSchema
|
|
51212
51846
|
}))
|
|
51213
51847
|
}));
|
|
51214
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
51848
|
+
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
51215
51849
|
const { name, arguments: args } = request.params;
|
|
51216
51850
|
const tool = toolMap.get(name);
|
|
51217
51851
|
if (!tool) {
|
|
@@ -51220,8 +51854,15 @@ To report this error, use the report_error tool with error_type: "provider_failu
|
|
|
51220
51854
|
isError: true
|
|
51221
51855
|
};
|
|
51222
51856
|
}
|
|
51857
|
+
const heartbeat = tool.heartbeat ? startHeartbeat({
|
|
51858
|
+
token: extra._meta?.progressToken,
|
|
51859
|
+
label: name,
|
|
51860
|
+
intervalMs: progressIntervalMs,
|
|
51861
|
+
send: (frame) => extra.sendNotification({ method: "notifications/progress", params: frame })
|
|
51862
|
+
}) : NOOP_HEARTBEAT;
|
|
51863
|
+
const ctx = { reportProgress: (message) => heartbeat.tick(message) };
|
|
51223
51864
|
try {
|
|
51224
|
-
return await tool.handler(args ?? {});
|
|
51865
|
+
return await tool.handler(args ?? {}, ctx);
|
|
51225
51866
|
} catch (error46) {
|
|
51226
51867
|
return {
|
|
51227
51868
|
content: [
|
|
@@ -51232,6 +51873,8 @@ To report this error, use the report_error tool with error_type: "provider_failu
|
|
|
51232
51873
|
],
|
|
51233
51874
|
isError: true
|
|
51234
51875
|
};
|
|
51876
|
+
} finally {
|
|
51877
|
+
heartbeat.stop();
|
|
51235
51878
|
}
|
|
51236
51879
|
});
|
|
51237
51880
|
const transport = new StdioServerTransport;
|
|
@@ -51279,6 +51922,7 @@ var init_mcp_server = __esm(() => {
|
|
|
51279
51922
|
init_prehydrate();
|
|
51280
51923
|
init_diagnostics();
|
|
51281
51924
|
init_channel();
|
|
51925
|
+
init_progress_heartbeat();
|
|
51282
51926
|
init_model_loader();
|
|
51283
51927
|
init_port_manager();
|
|
51284
51928
|
init_onepassword();
|
|
@@ -51297,7 +51941,8 @@ var init_mcp_server = __esm(() => {
|
|
|
51297
51941
|
timeout: "raise `timeout`, or pick a faster model",
|
|
51298
51942
|
api_error: "retry once, or route via a different provider (or@<model>)",
|
|
51299
51943
|
background_task_ceiling: "set CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 for children, or forbid background work in the prompt",
|
|
51300
|
-
empty_output: "retry once; if it repeats, drop the model"
|
|
51944
|
+
empty_output: "retry once; if it repeats, drop the model",
|
|
51945
|
+
shape_mismatch: "the response does not carry the shape you required. Every assistant message the " + "child emitted was captured, 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"
|
|
51301
51946
|
};
|
|
51302
51947
|
sanitize = sanitizeForReport;
|
|
51303
51948
|
EVENT_TO_TASK_STATUS = new Map([
|
|
@@ -51603,6 +52248,440 @@ var init_behavior_command = __esm(() => {
|
|
|
51603
52248
|
init_profile_config();
|
|
51604
52249
|
});
|
|
51605
52250
|
|
|
52251
|
+
// src/team-grid.ts
|
|
52252
|
+
var exports_team_grid = {};
|
|
52253
|
+
__export(exports_team_grid, {
|
|
52254
|
+
runWithGrid: () => runWithGrid
|
|
52255
|
+
});
|
|
52256
|
+
import { spawn as spawn3 } from "child_process";
|
|
52257
|
+
import { execSync } from "child_process";
|
|
52258
|
+
import { existsSync as existsSync23, readFileSync as readFileSync22, writeFileSync as writeFileSync15 } from "fs";
|
|
52259
|
+
import { connect as netConnect } from "net";
|
|
52260
|
+
import { dirname as dirname10, join as join30 } from "path";
|
|
52261
|
+
import { setTimeout as wait } from "timers/promises";
|
|
52262
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
52263
|
+
function resolveRouteInfo(modelId) {
|
|
52264
|
+
const parsed = parseModelSpec(modelId);
|
|
52265
|
+
if (parsed.isExplicitProvider) {
|
|
52266
|
+
return { chain: [parsed.provider], source: "direct" };
|
|
52267
|
+
}
|
|
52268
|
+
const local = loadLocalConfig();
|
|
52269
|
+
if (local?.routing && Object.keys(local.routing).length > 0) {
|
|
52270
|
+
const matched2 = matchRoutingRule(parsed.model, local.routing);
|
|
52271
|
+
if (matched2) {
|
|
52272
|
+
const routes = buildRoutingChain(matched2, parsed.model);
|
|
52273
|
+
const pattern = Object.keys(local.routing).find((k) => {
|
|
52274
|
+
if (k === parsed.model)
|
|
52275
|
+
return true;
|
|
52276
|
+
if (k.includes("*")) {
|
|
52277
|
+
const star = k.indexOf("*");
|
|
52278
|
+
return parsed.model.startsWith(k.slice(0, star)) && parsed.model.endsWith(k.slice(star + 1));
|
|
52279
|
+
}
|
|
52280
|
+
return false;
|
|
52281
|
+
});
|
|
52282
|
+
return {
|
|
52283
|
+
chain: routes.map((r) => r.displayName),
|
|
52284
|
+
source: "project routing",
|
|
52285
|
+
sourceDetail: pattern
|
|
52286
|
+
};
|
|
52287
|
+
}
|
|
52288
|
+
}
|
|
52289
|
+
const global_ = loadConfig();
|
|
52290
|
+
if (global_.routing && Object.keys(global_.routing).length > 0) {
|
|
52291
|
+
const matched2 = matchRoutingRule(parsed.model, global_.routing);
|
|
52292
|
+
if (matched2) {
|
|
52293
|
+
const routes = buildRoutingChain(matched2, parsed.model);
|
|
52294
|
+
const pattern = Object.keys(global_.routing).find((k) => {
|
|
52295
|
+
if (k === parsed.model)
|
|
52296
|
+
return true;
|
|
52297
|
+
if (k.includes("*")) {
|
|
52298
|
+
const star = k.indexOf("*");
|
|
52299
|
+
return parsed.model.startsWith(k.slice(0, star)) && parsed.model.endsWith(k.slice(star + 1));
|
|
52300
|
+
}
|
|
52301
|
+
return false;
|
|
52302
|
+
});
|
|
52303
|
+
return {
|
|
52304
|
+
chain: routes.map((r) => r.displayName),
|
|
52305
|
+
source: "user routing",
|
|
52306
|
+
sourceDetail: pattern
|
|
52307
|
+
};
|
|
52308
|
+
}
|
|
52309
|
+
}
|
|
52310
|
+
const merged = loadRoutingRules();
|
|
52311
|
+
const matched = matchRoutingRule(parsed.model, merged);
|
|
52312
|
+
if (matched) {
|
|
52313
|
+
const routes = buildRoutingChain(matched, parsed.model);
|
|
52314
|
+
return {
|
|
52315
|
+
chain: routes.map((r) => r.displayName),
|
|
52316
|
+
source: "auto"
|
|
52317
|
+
};
|
|
52318
|
+
}
|
|
52319
|
+
return {
|
|
52320
|
+
chain: [],
|
|
52321
|
+
source: "auto"
|
|
52322
|
+
};
|
|
52323
|
+
}
|
|
52324
|
+
function pickBannerColor(model, used) {
|
|
52325
|
+
let hash2 = 0;
|
|
52326
|
+
for (let i = 0;i < model.length; i++)
|
|
52327
|
+
hash2 = (hash2 << 5) - hash2 + model.charCodeAt(i) | 0;
|
|
52328
|
+
const start = Math.abs(hash2) % BANNER_BG_COLORS.length;
|
|
52329
|
+
let idx = start;
|
|
52330
|
+
if (used.size < BANNER_BG_COLORS.length) {
|
|
52331
|
+
while (used.has(idx))
|
|
52332
|
+
idx = (idx + 1) % BANNER_BG_COLORS.length;
|
|
52333
|
+
}
|
|
52334
|
+
used.add(idx);
|
|
52335
|
+
return BANNER_BG_COLORS[idx];
|
|
52336
|
+
}
|
|
52337
|
+
function buildPaneHeader(model, prompt, bg) {
|
|
52338
|
+
const route2 = resolveRouteInfo(model);
|
|
52339
|
+
const esc2 = (s) => s.replace(/'/g, "'\\''");
|
|
52340
|
+
const chainStr = route2.chain.join(" \u2192 ");
|
|
52341
|
+
const sourceLabel = route2.sourceDetail ? `${route2.source}: ${route2.sourceDetail}` : route2.source;
|
|
52342
|
+
const lines = [];
|
|
52343
|
+
lines.push(`printf '\\033[1;97;${bg}m %s \\033[0m\\n' '${esc2(model)}';`);
|
|
52344
|
+
lines.push(`printf '\\033[2m route: ${esc2(chainStr)} (${esc2(sourceLabel)})\\033[0m\\n' ;`);
|
|
52345
|
+
lines.push(`printf '\\033[2m %s\\033[0m\\n' '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500';`);
|
|
52346
|
+
const promptForShell = esc2(prompt).replace(/\n/g, "\\n");
|
|
52347
|
+
lines.push(`printf '%b\\n' '${promptForShell}' | fold -s -w 78 | sed 's/^/ /';`);
|
|
52348
|
+
lines.push(`printf '\\033[2m %s\\033[0m\\n\\n' '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500';`);
|
|
52349
|
+
return lines.join(" ");
|
|
52350
|
+
}
|
|
52351
|
+
function findMagmuxBinary() {
|
|
52352
|
+
const thisFile = fileURLToPath2(import.meta.url);
|
|
52353
|
+
const thisDir = dirname10(thisFile);
|
|
52354
|
+
const pkgRoot = join30(thisDir, "..");
|
|
52355
|
+
const platform2 = process.platform;
|
|
52356
|
+
const arch = process.arch;
|
|
52357
|
+
const bundledMagmux = join30(pkgRoot, "native", `magmux-${platform2}-${arch}`);
|
|
52358
|
+
if (existsSync23(bundledMagmux))
|
|
52359
|
+
return bundledMagmux;
|
|
52360
|
+
try {
|
|
52361
|
+
const pkgName = `@claudish/magmux-${platform2}-${arch}`;
|
|
52362
|
+
let searchDir = pkgRoot;
|
|
52363
|
+
for (let i = 0;i < 5; i++) {
|
|
52364
|
+
const candidate = join30(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
52365
|
+
if (existsSync23(candidate))
|
|
52366
|
+
return candidate;
|
|
52367
|
+
const parent = dirname10(searchDir);
|
|
52368
|
+
if (parent === searchDir)
|
|
52369
|
+
break;
|
|
52370
|
+
searchDir = parent;
|
|
52371
|
+
}
|
|
52372
|
+
} catch {}
|
|
52373
|
+
try {
|
|
52374
|
+
const result = execSync("which magmux", { encoding: "utf-8" }).trim();
|
|
52375
|
+
if (result)
|
|
52376
|
+
return result;
|
|
52377
|
+
} catch {}
|
|
52378
|
+
throw new Error(`magmux not found. Install it:
|
|
52379
|
+
brew install MadAppGang/tap/magmux`);
|
|
52380
|
+
}
|
|
52381
|
+
async function subscribeToMagmux(sockPath, onEvent) {
|
|
52382
|
+
let client = null;
|
|
52383
|
+
for (let attempt = 0;attempt < 40; attempt++) {
|
|
52384
|
+
if (existsSync23(sockPath)) {
|
|
52385
|
+
try {
|
|
52386
|
+
client = await new Promise((resolve5, reject) => {
|
|
52387
|
+
const s = netConnect(sockPath);
|
|
52388
|
+
s.once("connect", () => resolve5(s));
|
|
52389
|
+
s.once("error", reject);
|
|
52390
|
+
});
|
|
52391
|
+
break;
|
|
52392
|
+
} catch {}
|
|
52393
|
+
}
|
|
52394
|
+
await wait(50);
|
|
52395
|
+
}
|
|
52396
|
+
if (!client) {
|
|
52397
|
+
return { results: null, client: null };
|
|
52398
|
+
}
|
|
52399
|
+
return await new Promise((resolve5) => {
|
|
52400
|
+
let buf = "";
|
|
52401
|
+
let finalResults = null;
|
|
52402
|
+
client.on("data", (chunk) => {
|
|
52403
|
+
buf += chunk.toString("utf-8");
|
|
52404
|
+
let nl = buf.indexOf(`
|
|
52405
|
+
`);
|
|
52406
|
+
while (nl >= 0) {
|
|
52407
|
+
const line = buf.slice(0, nl).trim();
|
|
52408
|
+
buf = buf.slice(nl + 1);
|
|
52409
|
+
nl = buf.indexOf(`
|
|
52410
|
+
`);
|
|
52411
|
+
if (!line)
|
|
52412
|
+
continue;
|
|
52413
|
+
try {
|
|
52414
|
+
const evt = JSON.parse(line);
|
|
52415
|
+
onEvent?.(evt);
|
|
52416
|
+
if (evt.type === "results") {
|
|
52417
|
+
finalResults = evt;
|
|
52418
|
+
}
|
|
52419
|
+
} catch {}
|
|
52420
|
+
}
|
|
52421
|
+
});
|
|
52422
|
+
const done = () => resolve5({ results: finalResults, client });
|
|
52423
|
+
client.once("end", done);
|
|
52424
|
+
client.once("close", done);
|
|
52425
|
+
client.once("error", done);
|
|
52426
|
+
});
|
|
52427
|
+
}
|
|
52428
|
+
function buildTeamStatus(manifest, startedAt, results) {
|
|
52429
|
+
const anonIds = Object.keys(manifest.models);
|
|
52430
|
+
const models = {};
|
|
52431
|
+
for (let i = 0;i < anonIds.length; i++) {
|
|
52432
|
+
const anonId = anonIds[i];
|
|
52433
|
+
const result = results?.find((r) => r.pane === i);
|
|
52434
|
+
if (!result) {
|
|
52435
|
+
models[anonId] = {
|
|
52436
|
+
state: "TIMEOUT",
|
|
52437
|
+
exitCode: null,
|
|
52438
|
+
startedAt,
|
|
52439
|
+
completedAt: null,
|
|
52440
|
+
outputSize: 0
|
|
52441
|
+
};
|
|
52442
|
+
continue;
|
|
52443
|
+
}
|
|
52444
|
+
let state;
|
|
52445
|
+
switch (result.state) {
|
|
52446
|
+
case "completed":
|
|
52447
|
+
case "awaiting_input":
|
|
52448
|
+
state = "COMPLETED";
|
|
52449
|
+
break;
|
|
52450
|
+
case "failed":
|
|
52451
|
+
state = "FAILED";
|
|
52452
|
+
break;
|
|
52453
|
+
default:
|
|
52454
|
+
state = "TIMEOUT";
|
|
52455
|
+
}
|
|
52456
|
+
models[anonId] = {
|
|
52457
|
+
state,
|
|
52458
|
+
exitCode: result.exitCode,
|
|
52459
|
+
startedAt: result.startedAt ?? startedAt,
|
|
52460
|
+
completedAt: result.completedAt ?? new Date().toISOString(),
|
|
52461
|
+
outputSize: result.response?.length ?? 0
|
|
52462
|
+
};
|
|
52463
|
+
}
|
|
52464
|
+
return { startedAt, models };
|
|
52465
|
+
}
|
|
52466
|
+
async function runWithGrid(sessionPath, models, input, opts) {
|
|
52467
|
+
const mode = opts?.mode ?? "default";
|
|
52468
|
+
const keep = opts?.keep ?? false;
|
|
52469
|
+
const manifest = setupSession(sessionPath, models, input);
|
|
52470
|
+
const startedAt = new Date().toISOString();
|
|
52471
|
+
const gridfilePath = join30(sessionPath, "gridfile.txt");
|
|
52472
|
+
const prompt = readFileSync22(join30(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
52473
|
+
const rawPrompt = readFileSync22(join30(sessionPath, "input.md"), "utf-8");
|
|
52474
|
+
const usedBannerColors = new Set;
|
|
52475
|
+
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
52476
|
+
const model = manifest.models[anonId].model;
|
|
52477
|
+
if (mode === "interactive") {
|
|
52478
|
+
return `claudish --model ${model} -i --dangerously-skip-permissions '${prompt}'`;
|
|
52479
|
+
}
|
|
52480
|
+
const bg = pickBannerColor(model, usedBannerColors);
|
|
52481
|
+
const header = buildPaneHeader(model, rawPrompt, bg);
|
|
52482
|
+
return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
|
|
52483
|
+
});
|
|
52484
|
+
writeFileSync15(gridfilePath, `${gridLines.join(`
|
|
52485
|
+
`)}
|
|
52486
|
+
`, "utf-8");
|
|
52487
|
+
const magmuxPath = findMagmuxBinary();
|
|
52488
|
+
const spawnArgs = ["-g", gridfilePath];
|
|
52489
|
+
if (!keep && mode === "default") {
|
|
52490
|
+
spawnArgs.push("-w");
|
|
52491
|
+
}
|
|
52492
|
+
const proc = spawn3(magmuxPath, spawnArgs, {
|
|
52493
|
+
stdio: "inherit",
|
|
52494
|
+
env: { ...process.env }
|
|
52495
|
+
});
|
|
52496
|
+
const sockPath = `/tmp/magmux-${proc.pid}.sock`;
|
|
52497
|
+
const subscription = subscribeToMagmux(sockPath);
|
|
52498
|
+
const procExit = new Promise((resolve5) => {
|
|
52499
|
+
proc.on("exit", () => resolve5());
|
|
52500
|
+
proc.on("error", () => resolve5());
|
|
52501
|
+
});
|
|
52502
|
+
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
52503
|
+
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
52504
|
+
const statusPath = join30(sessionPath, "status.json");
|
|
52505
|
+
writeFileSync15(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
52506
|
+
return status;
|
|
52507
|
+
}
|
|
52508
|
+
var BANNER_BG_COLORS;
|
|
52509
|
+
var init_team_grid = __esm(() => {
|
|
52510
|
+
init_profile_config();
|
|
52511
|
+
init_model_parser();
|
|
52512
|
+
init_routing_rules();
|
|
52513
|
+
init_team_orchestrator();
|
|
52514
|
+
BANNER_BG_COLORS = [
|
|
52515
|
+
"48;2;40;90;180",
|
|
52516
|
+
"48;2;140;60;160",
|
|
52517
|
+
"48;2;30;130;100",
|
|
52518
|
+
"48;2;160;80;40",
|
|
52519
|
+
"48;2;60;120;60",
|
|
52520
|
+
"48;2;160;50;70"
|
|
52521
|
+
];
|
|
52522
|
+
});
|
|
52523
|
+
|
|
52524
|
+
// src/team-cli.ts
|
|
52525
|
+
var exports_team_cli = {};
|
|
52526
|
+
__export(exports_team_cli, {
|
|
52527
|
+
teamCommand: () => teamCommand
|
|
52528
|
+
});
|
|
52529
|
+
import { readFileSync as readFileSync23 } from "fs";
|
|
52530
|
+
import { join as join31 } from "path";
|
|
52531
|
+
function getFlag(args, flag) {
|
|
52532
|
+
const idx = args.indexOf(flag);
|
|
52533
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
52534
|
+
return;
|
|
52535
|
+
return args[idx + 1];
|
|
52536
|
+
}
|
|
52537
|
+
function hasFlag(args, flag) {
|
|
52538
|
+
return args.includes(flag);
|
|
52539
|
+
}
|
|
52540
|
+
function printStatus(status) {
|
|
52541
|
+
const modelIds = Object.keys(status.models).sort();
|
|
52542
|
+
console.log(`
|
|
52543
|
+
Team Status (started: ${status.startedAt})`);
|
|
52544
|
+
console.log("\u2500".repeat(60));
|
|
52545
|
+
for (const id of modelIds) {
|
|
52546
|
+
const m = status.models[id];
|
|
52547
|
+
const duration3 = m.startedAt && m.completedAt ? `${Math.round((new Date(m.completedAt).getTime() - new Date(m.startedAt).getTime()) / 1000)}s` : m.startedAt ? "running" : "pending";
|
|
52548
|
+
const size = m.outputSize > 0 ? ` (${m.outputSize} bytes)` : "";
|
|
52549
|
+
console.log(` ${id} ${m.state.padEnd(10)} ${duration3}${size}`);
|
|
52550
|
+
}
|
|
52551
|
+
console.log("");
|
|
52552
|
+
}
|
|
52553
|
+
function printHelp() {
|
|
52554
|
+
console.log(`
|
|
52555
|
+
Usage: claudish team <subcommand> [options]
|
|
52556
|
+
|
|
52557
|
+
Subcommands:
|
|
52558
|
+
run Run multiple models on a task in parallel
|
|
52559
|
+
judge Blind-judge existing model outputs
|
|
52560
|
+
run-and-judge Run models then judge their outputs
|
|
52561
|
+
status Show current session status
|
|
52562
|
+
|
|
52563
|
+
Options (run / run-and-judge):
|
|
52564
|
+
--path <dir> Session directory (default: .)
|
|
52565
|
+
--models <a,b,...> Comma-separated model IDs to run
|
|
52566
|
+
--input <text> Task prompt (or create input.md in --path beforehand)
|
|
52567
|
+
--timeout <secs> Timeout per model in seconds (default: 300)
|
|
52568
|
+
--grid Show all models in a magmux grid with live output + status bar
|
|
52569
|
+
|
|
52570
|
+
Options (judge / run-and-judge):
|
|
52571
|
+
--judges <a,b,...> Comma-separated judge model IDs (default: same as runners)
|
|
52572
|
+
|
|
52573
|
+
Options (status):
|
|
52574
|
+
--path <dir> Session directory (default: .)
|
|
52575
|
+
|
|
52576
|
+
Examples:
|
|
52577
|
+
claudish team run --path ./review --models minimax-m2.5,kimi-k2.5 --input "Review this code"
|
|
52578
|
+
claudish team run --grid --models kimi-k2.5,gpt-5.4,gemini-3.1-pro --input "Solve this"
|
|
52579
|
+
claudish team judge --path ./review
|
|
52580
|
+
claudish team run-and-judge --path ./review --models gpt-5.4,gemini-3.1-pro-preview --input "Evaluate this design"
|
|
52581
|
+
claudish team status --path ./review
|
|
52582
|
+
`);
|
|
52583
|
+
}
|
|
52584
|
+
async function teamCommand(args) {
|
|
52585
|
+
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
52586
|
+
printHelp();
|
|
52587
|
+
process.exit(0);
|
|
52588
|
+
}
|
|
52589
|
+
const firstArg = args[0] ?? "";
|
|
52590
|
+
const legacySubs = ["run", "judge", "run-and-judge", "status"];
|
|
52591
|
+
const subcommand = legacySubs.includes(firstArg) ? firstArg : "run";
|
|
52592
|
+
const rawSessionPath = getFlag(args, "--path") ?? ".";
|
|
52593
|
+
let sessionPath;
|
|
52594
|
+
try {
|
|
52595
|
+
sessionPath = validateSessionPath(rawSessionPath);
|
|
52596
|
+
} catch (err) {
|
|
52597
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
52598
|
+
process.exit(1);
|
|
52599
|
+
}
|
|
52600
|
+
const modelsRaw = getFlag(args, "--models");
|
|
52601
|
+
const judgesRaw = getFlag(args, "--judges");
|
|
52602
|
+
const mode = getFlag(args, "--mode") ?? "default";
|
|
52603
|
+
const timeoutStr = getFlag(args, "--timeout");
|
|
52604
|
+
const timeout = timeoutStr ? Number.parseInt(timeoutStr, 10) : 300;
|
|
52605
|
+
let input = getFlag(args, "--input");
|
|
52606
|
+
if (!input) {
|
|
52607
|
+
const flagsWithValues = ["--models", "--judges", "--mode", "--path", "--timeout", "--input"];
|
|
52608
|
+
const positionals = args.filter((a, i) => {
|
|
52609
|
+
if (legacySubs.includes(a) && i === 0)
|
|
52610
|
+
return false;
|
|
52611
|
+
if (a.startsWith("--"))
|
|
52612
|
+
return false;
|
|
52613
|
+
const prev = args[i - 1];
|
|
52614
|
+
if (prev && flagsWithValues.includes(prev))
|
|
52615
|
+
return false;
|
|
52616
|
+
return true;
|
|
52617
|
+
});
|
|
52618
|
+
if (positionals.length > 0)
|
|
52619
|
+
input = positionals.join(" ");
|
|
52620
|
+
}
|
|
52621
|
+
const models = modelsRaw ? modelsRaw.split(",").map((m) => m.trim()).filter(Boolean) : [];
|
|
52622
|
+
const judges = judgesRaw ? judgesRaw.split(",").map((m) => m.trim()).filter(Boolean) : undefined;
|
|
52623
|
+
const effectiveMode = hasFlag(args, "--interactive") ? "interactive" : hasFlag(args, "--grid") ? "default" : mode;
|
|
52624
|
+
switch (subcommand) {
|
|
52625
|
+
case "run": {
|
|
52626
|
+
if (models.length === 0) {
|
|
52627
|
+
console.error("Error: --models is required");
|
|
52628
|
+
printHelp();
|
|
52629
|
+
process.exit(1);
|
|
52630
|
+
}
|
|
52631
|
+
if (effectiveMode === "json") {
|
|
52632
|
+
setupSession(sessionPath, models, input);
|
|
52633
|
+
const runStatus = await runModels(sessionPath, {
|
|
52634
|
+
timeout,
|
|
52635
|
+
onStatusChange: (id, s) => {
|
|
52636
|
+
process.stderr.write(`[team] ${id}: ${s.state}
|
|
52637
|
+
`);
|
|
52638
|
+
}
|
|
52639
|
+
});
|
|
52640
|
+
printStatus(runStatus);
|
|
52641
|
+
} else {
|
|
52642
|
+
const { runWithGrid: runWithGrid2 } = await Promise.resolve().then(() => (init_team_grid(), exports_team_grid));
|
|
52643
|
+
const gridStatus = await runWithGrid2(sessionPath, models, input ?? "", {
|
|
52644
|
+
timeout,
|
|
52645
|
+
mode: effectiveMode === "interactive" ? "interactive" : "default"
|
|
52646
|
+
});
|
|
52647
|
+
printStatus(gridStatus);
|
|
52648
|
+
}
|
|
52649
|
+
break;
|
|
52650
|
+
}
|
|
52651
|
+
case "judge": {
|
|
52652
|
+
await judgeResponses(sessionPath, { judges });
|
|
52653
|
+
console.log(readFileSync23(join31(sessionPath, "verdict.md"), "utf-8"));
|
|
52654
|
+
break;
|
|
52655
|
+
}
|
|
52656
|
+
case "run-and-judge": {
|
|
52657
|
+
if (models.length === 0) {
|
|
52658
|
+
console.error("Error: --models is required");
|
|
52659
|
+
process.exit(1);
|
|
52660
|
+
}
|
|
52661
|
+
setupSession(sessionPath, models, input);
|
|
52662
|
+
const status = await runModels(sessionPath, {
|
|
52663
|
+
timeout,
|
|
52664
|
+
onStatusChange: (id, s) => {
|
|
52665
|
+
process.stderr.write(`[team] ${id}: ${s.state}
|
|
52666
|
+
`);
|
|
52667
|
+
}
|
|
52668
|
+
});
|
|
52669
|
+
printStatus(status);
|
|
52670
|
+
await judgeResponses(sessionPath, { judges });
|
|
52671
|
+
console.log(readFileSync23(join31(sessionPath, "verdict.md"), "utf-8"));
|
|
52672
|
+
break;
|
|
52673
|
+
}
|
|
52674
|
+
case "status": {
|
|
52675
|
+
const statusResult = getStatus(sessionPath);
|
|
52676
|
+
printStatus(statusResult);
|
|
52677
|
+
break;
|
|
52678
|
+
}
|
|
52679
|
+
}
|
|
52680
|
+
}
|
|
52681
|
+
var init_team_cli = __esm(() => {
|
|
52682
|
+
init_team_orchestrator();
|
|
52683
|
+
});
|
|
52684
|
+
|
|
51606
52685
|
// src/auth/credentials/source.ts
|
|
51607
52686
|
function describeSourceSync(p, config3) {
|
|
51608
52687
|
if (p.isLocal)
|
|
@@ -63014,8 +64093,8 @@ var init_RemoveFileError = __esm(() => {
|
|
|
63014
64093
|
});
|
|
63015
64094
|
|
|
63016
64095
|
// ../../node_modules/.bun/@inquirer+external-editor@2.0.1+04f2146be16c61ef/node_modules/@inquirer/external-editor/dist/index.js
|
|
63017
|
-
import { spawn as
|
|
63018
|
-
import { readFileSync as
|
|
64096
|
+
import { spawn as spawn4, spawnSync as spawnSync2 } from "child_process";
|
|
64097
|
+
import { readFileSync as readFileSync24, unlinkSync as unlinkSync5, writeFileSync as writeFileSync16 } from "fs";
|
|
63019
64098
|
import path from "path";
|
|
63020
64099
|
import os from "os";
|
|
63021
64100
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
@@ -63124,14 +64203,14 @@ class ExternalEditor {
|
|
|
63124
64203
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
63125
64204
|
opt.mode = this.fileOptions.mode;
|
|
63126
64205
|
}
|
|
63127
|
-
|
|
64206
|
+
writeFileSync16(this.tempFile, this.text, opt);
|
|
63128
64207
|
} catch (createFileError) {
|
|
63129
64208
|
throw new CreateFileError(createFileError);
|
|
63130
64209
|
}
|
|
63131
64210
|
}
|
|
63132
64211
|
readTemporaryFile() {
|
|
63133
64212
|
try {
|
|
63134
|
-
const tempFileBuffer =
|
|
64213
|
+
const tempFileBuffer = readFileSync24(this.tempFile);
|
|
63135
64214
|
if (tempFileBuffer.length === 0) {
|
|
63136
64215
|
this.text = "";
|
|
63137
64216
|
} else {
|
|
@@ -63162,7 +64241,7 @@ class ExternalEditor {
|
|
|
63162
64241
|
}
|
|
63163
64242
|
launchEditorAsync(callback) {
|
|
63164
64243
|
try {
|
|
63165
|
-
const editorProcess =
|
|
64244
|
+
const editorProcess = spawn4(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
|
|
63166
64245
|
editorProcess.on("exit", (code) => {
|
|
63167
64246
|
this.lastExitStatus = code;
|
|
63168
64247
|
setImmediate(callback);
|
|
@@ -64112,9 +65191,9 @@ var init_dist16 = __esm(() => {
|
|
|
64112
65191
|
|
|
64113
65192
|
// src/auth/antigravity-oauth.ts
|
|
64114
65193
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
64115
|
-
import { existsSync as
|
|
65194
|
+
import { existsSync as existsSync24, unlinkSync as unlinkSync6 } from "fs";
|
|
64116
65195
|
import { homedir as homedir28 } from "os";
|
|
64117
|
-
import { join as
|
|
65196
|
+
import { join as join32 } from "path";
|
|
64118
65197
|
async function defaultSuggestModel() {
|
|
64119
65198
|
try {
|
|
64120
65199
|
const tok = readSharedAntigravityToken();
|
|
@@ -64235,8 +65314,8 @@ No session detected yet. Starting the Antigravity CLI interactively \u2014
|
|
|
64235
65314
|
async logout(deps) {
|
|
64236
65315
|
deleteSharedAntigravityToken(deps);
|
|
64237
65316
|
try {
|
|
64238
|
-
const tokenFile =
|
|
64239
|
-
if (
|
|
65317
|
+
const tokenFile = join32(homedir28(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
|
|
65318
|
+
if (existsSync24(tokenFile))
|
|
64240
65319
|
unlinkSync6(tokenFile);
|
|
64241
65320
|
} catch {}
|
|
64242
65321
|
log("[AntigravityOAuth] Antigravity session cleared (keychain + agy token file)");
|
|
@@ -68322,22 +69401,22 @@ __export(exports_cli, {
|
|
|
68322
69401
|
});
|
|
68323
69402
|
import {
|
|
68324
69403
|
copyFileSync as copyFileSync2,
|
|
68325
|
-
existsSync as
|
|
69404
|
+
existsSync as existsSync25,
|
|
68326
69405
|
mkdirSync as mkdirSync14,
|
|
68327
|
-
readFileSync as
|
|
69406
|
+
readFileSync as readFileSync25,
|
|
68328
69407
|
readdirSync as readdirSync5,
|
|
68329
69408
|
unlinkSync as unlinkSync7,
|
|
68330
|
-
writeFileSync as
|
|
69409
|
+
writeFileSync as writeFileSync17
|
|
68331
69410
|
} from "fs";
|
|
68332
69411
|
import { homedir as homedir29 } from "os";
|
|
68333
|
-
import { dirname as
|
|
68334
|
-
import { fileURLToPath as
|
|
69412
|
+
import { dirname as dirname11, join as join33 } from "path";
|
|
69413
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
68335
69414
|
function getVersion3() {
|
|
68336
69415
|
return VERSION;
|
|
68337
69416
|
}
|
|
68338
69417
|
function clearAllModelCaches() {
|
|
68339
|
-
const cacheDir =
|
|
68340
|
-
if (!
|
|
69418
|
+
const cacheDir = join33(homedir29(), ".claudish");
|
|
69419
|
+
if (!existsSync25(cacheDir))
|
|
68341
69420
|
return;
|
|
68342
69421
|
const cachePatterns = ["pricing-cache.json", "recommended-models-cache.json"];
|
|
68343
69422
|
let cleared = 0;
|
|
@@ -68345,7 +69424,7 @@ function clearAllModelCaches() {
|
|
|
68345
69424
|
const files = readdirSync5(cacheDir);
|
|
68346
69425
|
for (const file2 of files) {
|
|
68347
69426
|
if (cachePatterns.includes(file2)) {
|
|
68348
|
-
unlinkSync7(
|
|
69427
|
+
unlinkSync7(join33(cacheDir, file2));
|
|
68349
69428
|
cleared++;
|
|
68350
69429
|
}
|
|
68351
69430
|
}
|
|
@@ -68578,7 +69657,7 @@ async function parseArgs(args) {
|
|
|
68578
69657
|
printVersion();
|
|
68579
69658
|
process.exit(0);
|
|
68580
69659
|
} else if (arg === "--help" || arg === "-h") {
|
|
68581
|
-
|
|
69660
|
+
printHelp2();
|
|
68582
69661
|
process.exit(0);
|
|
68583
69662
|
} else if (arg === "--help-ai") {
|
|
68584
69663
|
printAIAgentGuide();
|
|
@@ -68760,15 +69839,15 @@ Usage: claudish --models --provider <slug>`);
|
|
|
68760
69839
|
});
|
|
68761
69840
|
config3.resolvedDefaultProvider = resolved;
|
|
68762
69841
|
if (resolved.legacyAutoPromoted && !config3.quiet) {
|
|
68763
|
-
const markerFile =
|
|
68764
|
-
if (!
|
|
69842
|
+
const markerFile = join33(homedir29(), ".claudish", ".legacy-litellm-hint-shown");
|
|
69843
|
+
if (!existsSync25(markerFile)) {
|
|
68765
69844
|
const hint = buildLegacyHint(resolved);
|
|
68766
69845
|
if (hint) {
|
|
68767
69846
|
console.error(hint);
|
|
68768
69847
|
}
|
|
68769
69848
|
try {
|
|
68770
|
-
mkdirSync14(
|
|
68771
|
-
|
|
69849
|
+
mkdirSync14(dirname11(markerFile), { recursive: true });
|
|
69850
|
+
writeFileSync17(markerFile, new Date().toISOString(), "utf-8");
|
|
68772
69851
|
} catch {}
|
|
68773
69852
|
}
|
|
68774
69853
|
}
|
|
@@ -69535,7 +70614,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
69535
70614
|
await tui.shutdown();
|
|
69536
70615
|
}
|
|
69537
70616
|
}
|
|
69538
|
-
function
|
|
70617
|
+
function printHelp2() {
|
|
69539
70618
|
const useColor = !!process.stdout.isTTY && !process.env.NO_COLOR;
|
|
69540
70619
|
const c = (code) => (s) => useColor ? `\x1B[${code}m${s}\x1B[0m` : s;
|
|
69541
70620
|
const bold4 = c("1");
|
|
@@ -69838,8 +70917,8 @@ ${h("MORE INFO")}
|
|
|
69838
70917
|
}
|
|
69839
70918
|
function printAIAgentGuide() {
|
|
69840
70919
|
try {
|
|
69841
|
-
const guidePath =
|
|
69842
|
-
const guideContent =
|
|
70920
|
+
const guidePath = join33(__dirname3, "../AI_AGENT_GUIDE.md");
|
|
70921
|
+
const guideContent = readFileSync25(guidePath, "utf-8");
|
|
69843
70922
|
console.log(guideContent);
|
|
69844
70923
|
} catch (error46) {
|
|
69845
70924
|
console.error("Error reading AI Agent Guide:");
|
|
@@ -69855,19 +70934,19 @@ async function initializeClaudishSkill() {
|
|
|
69855
70934
|
console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
|
|
69856
70935
|
`);
|
|
69857
70936
|
const cwd = process.cwd();
|
|
69858
|
-
const claudeDir =
|
|
69859
|
-
const skillsDir =
|
|
69860
|
-
const claudishSkillDir =
|
|
69861
|
-
const skillFile =
|
|
69862
|
-
if (
|
|
70937
|
+
const claudeDir = join33(cwd, ".claude");
|
|
70938
|
+
const skillsDir = join33(claudeDir, "skills");
|
|
70939
|
+
const claudishSkillDir = join33(skillsDir, "claudish-usage");
|
|
70940
|
+
const skillFile = join33(claudishSkillDir, "SKILL.md");
|
|
70941
|
+
if (existsSync25(skillFile)) {
|
|
69863
70942
|
console.log("\u2705 Claudish skill already installed at:");
|
|
69864
70943
|
console.log(` ${skillFile}
|
|
69865
70944
|
`);
|
|
69866
70945
|
console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
|
|
69867
70946
|
return;
|
|
69868
70947
|
}
|
|
69869
|
-
const sourceSkillPath =
|
|
69870
|
-
if (!
|
|
70948
|
+
const sourceSkillPath = join33(__dirname3, "../skills/claudish-usage/SKILL.md");
|
|
70949
|
+
if (!existsSync25(sourceSkillPath)) {
|
|
69871
70950
|
console.error("\u274C Error: Claudish skill file not found in installation.");
|
|
69872
70951
|
console.error(` Expected at: ${sourceSkillPath}`);
|
|
69873
70952
|
console.error(`
|
|
@@ -69876,15 +70955,15 @@ async function initializeClaudishSkill() {
|
|
|
69876
70955
|
process.exit(1);
|
|
69877
70956
|
}
|
|
69878
70957
|
try {
|
|
69879
|
-
if (!
|
|
70958
|
+
if (!existsSync25(claudeDir)) {
|
|
69880
70959
|
mkdirSync14(claudeDir, { recursive: true });
|
|
69881
70960
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
69882
70961
|
}
|
|
69883
|
-
if (!
|
|
70962
|
+
if (!existsSync25(skillsDir)) {
|
|
69884
70963
|
mkdirSync14(skillsDir, { recursive: true });
|
|
69885
70964
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
69886
70965
|
}
|
|
69887
|
-
if (!
|
|
70966
|
+
if (!existsSync25(claudishSkillDir)) {
|
|
69888
70967
|
mkdirSync14(claudishSkillDir, { recursive: true });
|
|
69889
70968
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
69890
70969
|
}
|
|
@@ -69956,8 +71035,8 @@ var init_cli = __esm(() => {
|
|
|
69956
71035
|
init_provider_definitions();
|
|
69957
71036
|
init_routing_rules();
|
|
69958
71037
|
init_provider_resolver();
|
|
69959
|
-
__filename3 =
|
|
69960
|
-
__dirname3 =
|
|
71038
|
+
__filename3 = fileURLToPath3(import.meta.url);
|
|
71039
|
+
__dirname3 = dirname11(__filename3);
|
|
69961
71040
|
});
|
|
69962
71041
|
|
|
69963
71042
|
// src/update-checker.ts
|
|
@@ -69969,33 +71048,33 @@ __export(exports_update_checker, {
|
|
|
69969
71048
|
clearCache: () => clearCache,
|
|
69970
71049
|
checkForUpdates: () => checkForUpdates
|
|
69971
71050
|
});
|
|
69972
|
-
import { existsSync as
|
|
71051
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync15, readFileSync as readFileSync26, unlinkSync as unlinkSync8, writeFileSync as writeFileSync18 } from "fs";
|
|
69973
71052
|
import { homedir as homedir30, platform as platform2, tmpdir } from "os";
|
|
69974
|
-
import { join as
|
|
71053
|
+
import { join as join34 } from "path";
|
|
69975
71054
|
function getCacheFilePath() {
|
|
69976
71055
|
let cacheDir;
|
|
69977
71056
|
if (isWindows) {
|
|
69978
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
69979
|
-
cacheDir =
|
|
71057
|
+
const localAppData = process.env.LOCALAPPDATA || join34(homedir30(), "AppData", "Local");
|
|
71058
|
+
cacheDir = join34(localAppData, "claudish");
|
|
69980
71059
|
} else {
|
|
69981
|
-
cacheDir =
|
|
71060
|
+
cacheDir = join34(homedir30(), ".cache", "claudish");
|
|
69982
71061
|
}
|
|
69983
71062
|
try {
|
|
69984
|
-
if (!
|
|
71063
|
+
if (!existsSync26(cacheDir)) {
|
|
69985
71064
|
mkdirSync15(cacheDir, { recursive: true });
|
|
69986
71065
|
}
|
|
69987
|
-
return
|
|
71066
|
+
return join34(cacheDir, "update-check.json");
|
|
69988
71067
|
} catch {
|
|
69989
|
-
return
|
|
71068
|
+
return join34(tmpdir(), "claudish-update-check.json");
|
|
69990
71069
|
}
|
|
69991
71070
|
}
|
|
69992
71071
|
function readCache() {
|
|
69993
71072
|
try {
|
|
69994
71073
|
const cachePath = getCacheFilePath();
|
|
69995
|
-
if (!
|
|
71074
|
+
if (!existsSync26(cachePath)) {
|
|
69996
71075
|
return null;
|
|
69997
71076
|
}
|
|
69998
|
-
const data = JSON.parse(
|
|
71077
|
+
const data = JSON.parse(readFileSync26(cachePath, "utf-8"));
|
|
69999
71078
|
return data;
|
|
70000
71079
|
} catch {
|
|
70001
71080
|
return null;
|
|
@@ -70008,7 +71087,7 @@ function writeCache(latestVersion) {
|
|
|
70008
71087
|
lastCheck: Date.now(),
|
|
70009
71088
|
latestVersion
|
|
70010
71089
|
};
|
|
70011
|
-
|
|
71090
|
+
writeFileSync18(cachePath, JSON.stringify(data), "utf-8");
|
|
70012
71091
|
} catch {}
|
|
70013
71092
|
}
|
|
70014
71093
|
function isCacheValid(cache2) {
|
|
@@ -70018,7 +71097,7 @@ function isCacheValid(cache2) {
|
|
|
70018
71097
|
function clearCache() {
|
|
70019
71098
|
try {
|
|
70020
71099
|
const cachePath = getCacheFilePath();
|
|
70021
|
-
if (
|
|
71100
|
+
if (existsSync26(cachePath)) {
|
|
70022
71101
|
unlinkSync8(cachePath);
|
|
70023
71102
|
}
|
|
70024
71103
|
} catch {}
|
|
@@ -70106,7 +71185,7 @@ var exports_update_command = {};
|
|
|
70106
71185
|
__export(exports_update_command, {
|
|
70107
71186
|
updateCommand: () => updateCommand
|
|
70108
71187
|
});
|
|
70109
|
-
import { execSync } from "child_process";
|
|
71188
|
+
import { execSync as execSync2 } from "child_process";
|
|
70110
71189
|
function detectInstallationMethod() {
|
|
70111
71190
|
const scriptPath = process.argv[1] || "";
|
|
70112
71191
|
if (scriptPath.includes("/opt/homebrew/") || scriptPath.includes("/usr/local/Cellar/")) {
|
|
@@ -70134,7 +71213,7 @@ function getUpdateCommand(method) {
|
|
|
70134
71213
|
}
|
|
70135
71214
|
async function executeUpdate(command) {
|
|
70136
71215
|
try {
|
|
70137
|
-
|
|
71216
|
+
execSync2(command, {
|
|
70138
71217
|
stdio: "inherit",
|
|
70139
71218
|
shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
|
|
70140
71219
|
});
|
|
@@ -70271,7 +71350,7 @@ ${BOLD2}Unable to detect installation method.${RESET2}`);
|
|
|
70271
71350
|
}
|
|
70272
71351
|
function fetchLatestVersionViaNpm() {
|
|
70273
71352
|
try {
|
|
70274
|
-
const output =
|
|
71353
|
+
const output = execSync2("npm view claudish version", {
|
|
70275
71354
|
encoding: "utf-8",
|
|
70276
71355
|
timeout: 20000,
|
|
70277
71356
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -70903,15 +71982,15 @@ var init_local_liveness = __esm(() => {
|
|
|
70903
71982
|
});
|
|
70904
71983
|
|
|
70905
71984
|
// src/providers/probe-catalog.ts
|
|
70906
|
-
import { existsSync as
|
|
71985
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync27, writeFileSync as writeFileSync19 } from "fs";
|
|
70907
71986
|
import { homedir as homedir31 } from "os";
|
|
70908
|
-
import { dirname as
|
|
71987
|
+
import { dirname as dirname12, join as join35 } from "path";
|
|
70909
71988
|
function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
|
|
70910
|
-
if (!
|
|
71989
|
+
if (!existsSync27(path2))
|
|
70911
71990
|
return null;
|
|
70912
71991
|
let raw2;
|
|
70913
71992
|
try {
|
|
70914
|
-
raw2 = JSON.parse(
|
|
71993
|
+
raw2 = JSON.parse(readFileSync27(path2, "utf-8"));
|
|
70915
71994
|
} catch {
|
|
70916
71995
|
return null;
|
|
70917
71996
|
}
|
|
@@ -70920,8 +71999,8 @@ function readProbeModelsCache(path2 = PROBE_MODELS_CACHE_PATH) {
|
|
|
70920
71999
|
return raw2;
|
|
70921
72000
|
}
|
|
70922
72001
|
function writeProbeModelsCache(data, path2 = PROBE_MODELS_CACHE_PATH) {
|
|
70923
|
-
mkdirSync16(
|
|
70924
|
-
|
|
72002
|
+
mkdirSync16(dirname12(path2), { recursive: true });
|
|
72003
|
+
writeFileSync19(path2, JSON.stringify(data), "utf-8");
|
|
70925
72004
|
}
|
|
70926
72005
|
function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
|
|
70927
72006
|
if (!data?.generatedAt)
|
|
@@ -71040,7 +72119,7 @@ function isValidResponse(raw2) {
|
|
|
71040
72119
|
var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels", CACHE_TTL_MS4, FETCH_TIMEOUT_MS3 = 15000, PROBE_MODELS_CACHE_PATH, _inFlight = null;
|
|
71041
72120
|
var init_probe_catalog = __esm(() => {
|
|
71042
72121
|
CACHE_TTL_MS4 = 60 * 60 * 1000;
|
|
71043
|
-
PROBE_MODELS_CACHE_PATH =
|
|
72122
|
+
PROBE_MODELS_CACHE_PATH = join35(homedir31(), ".claudish", "probe-models.json");
|
|
71044
72123
|
});
|
|
71045
72124
|
|
|
71046
72125
|
// src/tui/constants.ts
|
|
@@ -77387,20 +78466,20 @@ __export(exports_claude_runner, {
|
|
|
77387
78466
|
MIN_AUTO_COMPACT_WINDOW: () => MIN_AUTO_COMPACT_WINDOW,
|
|
77388
78467
|
CLAUDE_CODE_DEFAULT_MAX_CONTEXT: () => CLAUDE_CODE_DEFAULT_MAX_CONTEXT
|
|
77389
78468
|
});
|
|
77390
|
-
import { spawn as
|
|
78469
|
+
import { spawn as spawn5 } from "child_process";
|
|
77391
78470
|
import {
|
|
77392
78471
|
closeSync as closeSync4,
|
|
77393
|
-
existsSync as
|
|
78472
|
+
existsSync as existsSync28,
|
|
77394
78473
|
mkdirSync as mkdirSync17,
|
|
77395
78474
|
openSync as openSync4,
|
|
77396
|
-
readFileSync as
|
|
78475
|
+
readFileSync as readFileSync28,
|
|
77397
78476
|
readdirSync as readdirSync6,
|
|
77398
78477
|
statSync as statSync5,
|
|
77399
78478
|
unlinkSync as unlinkSync9,
|
|
77400
|
-
writeFileSync as
|
|
78479
|
+
writeFileSync as writeFileSync20
|
|
77401
78480
|
} from "fs";
|
|
77402
78481
|
import { homedir as homedir32, tmpdir as tmpdir2 } from "os";
|
|
77403
|
-
import { dirname as
|
|
78482
|
+
import { dirname as dirname13, join as join36 } from "path";
|
|
77404
78483
|
import { isatty } from "tty";
|
|
77405
78484
|
function releaseTerminalIsolation() {
|
|
77406
78485
|
if (!restoreTerminal)
|
|
@@ -77435,14 +78514,14 @@ function isProxyAuthMode(config3) {
|
|
|
77435
78514
|
}
|
|
77436
78515
|
function managedSettingsPath() {
|
|
77437
78516
|
if (isWindows2()) {
|
|
77438
|
-
return
|
|
78517
|
+
return join36(process.env.PROGRAMDATA || "C:\\ProgramData", "ClaudeCode", "managed-settings.json");
|
|
77439
78518
|
}
|
|
77440
78519
|
if (process.platform === "darwin") {
|
|
77441
78520
|
return "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
77442
78521
|
}
|
|
77443
78522
|
return "/etc/claude-code/managed-settings.json";
|
|
77444
78523
|
}
|
|
77445
|
-
function managedSettingsForcesClaudeAi(readFile3 =
|
|
78524
|
+
function managedSettingsForcesClaudeAi(readFile3 = readFileSync28) {
|
|
77446
78525
|
try {
|
|
77447
78526
|
const raw2 = readFile3(managedSettingsPath(), "utf-8");
|
|
77448
78527
|
const parsed = JSON.parse(raw2);
|
|
@@ -77456,9 +78535,9 @@ function isWindows2() {
|
|
|
77456
78535
|
}
|
|
77457
78536
|
function createStatusLineScript(tokenFilePath) {
|
|
77458
78537
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
77459
|
-
const claudishDir =
|
|
78538
|
+
const claudishDir = join36(homeDir, ".claudish");
|
|
77460
78539
|
const timestamp = Date.now();
|
|
77461
|
-
const scriptPath =
|
|
78540
|
+
const scriptPath = join36(claudishDir, `status-${timestamp}.js`);
|
|
77462
78541
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
77463
78542
|
const script = `
|
|
77464
78543
|
const fs = require('fs');
|
|
@@ -77585,13 +78664,13 @@ process.stdin.on('end', () => {
|
|
|
77585
78664
|
}
|
|
77586
78665
|
});
|
|
77587
78666
|
`;
|
|
77588
|
-
|
|
78667
|
+
writeFileSync20(scriptPath, script, "utf-8");
|
|
77589
78668
|
return scriptPath;
|
|
77590
78669
|
}
|
|
77591
78670
|
function initializeTokenFile(tokenFilePath) {
|
|
77592
78671
|
try {
|
|
77593
|
-
mkdirSync17(
|
|
77594
|
-
|
|
78672
|
+
mkdirSync17(dirname13(tokenFilePath), { recursive: true });
|
|
78673
|
+
writeFileSync20(tokenFilePath, JSON.stringify({
|
|
77595
78674
|
input_tokens: 0,
|
|
77596
78675
|
output_tokens: 0,
|
|
77597
78676
|
total_tokens: 0,
|
|
@@ -77622,7 +78701,7 @@ function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FI
|
|
|
77622
78701
|
if (!name.startsWith("tokens-") || !name.endsWith(".json"))
|
|
77623
78702
|
continue;
|
|
77624
78703
|
scanned++;
|
|
77625
|
-
const full =
|
|
78704
|
+
const full = join36(dir, name);
|
|
77626
78705
|
try {
|
|
77627
78706
|
if (statSync5(full).mtimeMs >= cutoff)
|
|
77628
78707
|
continue;
|
|
@@ -77639,7 +78718,7 @@ function parseSettingsArg(value) {
|
|
|
77639
78718
|
if (value.trimStart().startsWith("{")) {
|
|
77640
78719
|
return JSON.parse(value);
|
|
77641
78720
|
}
|
|
77642
|
-
return JSON.parse(
|
|
78721
|
+
return JSON.parse(readFileSync28(value, "utf-8"));
|
|
77643
78722
|
}
|
|
77644
78723
|
function parseSettingsArgSafe(value) {
|
|
77645
78724
|
try {
|
|
@@ -77651,13 +78730,13 @@ function parseSettingsArgSafe(value) {
|
|
|
77651
78730
|
}
|
|
77652
78731
|
function userSettingsFileCandidates(cwd) {
|
|
77653
78732
|
return [
|
|
77654
|
-
|
|
77655
|
-
|
|
77656
|
-
|
|
78733
|
+
join36(homedir32(), ".claude", "settings.json"),
|
|
78734
|
+
join36(cwd, ".claude", "settings.json"),
|
|
78735
|
+
join36(cwd, ".claude", "settings.local.json")
|
|
77657
78736
|
];
|
|
77658
78737
|
}
|
|
77659
78738
|
function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
|
|
77660
|
-
const sources = userSettingsFileCandidates(cwd).filter((file2) =>
|
|
78739
|
+
const sources = userSettingsFileCandidates(cwd).filter((file2) => existsSync28(file2));
|
|
77661
78740
|
const idx = claudeArgs.indexOf("--settings");
|
|
77662
78741
|
const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
|
|
77663
78742
|
if (settingsArg)
|
|
@@ -77694,13 +78773,13 @@ function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
|
|
|
77694
78773
|
}
|
|
77695
78774
|
function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
|
|
77696
78775
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
77697
|
-
const claudishDir =
|
|
78776
|
+
const claudishDir = join36(homeDir, ".claudish");
|
|
77698
78777
|
try {
|
|
77699
78778
|
mkdirSync17(claudishDir, { recursive: true });
|
|
77700
78779
|
} catch {}
|
|
77701
78780
|
const timestamp = Date.now();
|
|
77702
|
-
const tempPath =
|
|
77703
|
-
const tokenFilePath =
|
|
78781
|
+
const tempPath = join36(claudishDir, `settings-${timestamp}.json`);
|
|
78782
|
+
const tokenFilePath = join36(claudishDir, `tokens-${port}.json`);
|
|
77704
78783
|
cleanupStaleTokenFiles(claudishDir);
|
|
77705
78784
|
initializeTokenFile(tokenFilePath);
|
|
77706
78785
|
let statusCommand;
|
|
@@ -77733,7 +78812,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLi
|
|
|
77733
78812
|
padding: 0
|
|
77734
78813
|
};
|
|
77735
78814
|
const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
|
|
77736
|
-
|
|
78815
|
+
writeFileSync20(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
77737
78816
|
return { path: tempPath, statusLine, tokenFilePath };
|
|
77738
78817
|
}
|
|
77739
78818
|
function buildClaudishSettingsOverlay(statusLine, proxyAuthMode) {
|
|
@@ -77758,7 +78837,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
|
|
|
77758
78837
|
if (proxyAuthMode && !("forceLoginMethod" in userSettings)) {
|
|
77759
78838
|
userSettings.forceLoginMethod = "console";
|
|
77760
78839
|
}
|
|
77761
|
-
|
|
78840
|
+
writeFileSync20(tempSettingsPath, JSON.stringify(userSettings, null, 2), "utf-8");
|
|
77762
78841
|
} catch {
|
|
77763
78842
|
if (!config3.quiet) {
|
|
77764
78843
|
console.warn(`[claudish] Warning: could not merge user settings: ${userSettingsValue}`);
|
|
@@ -77951,7 +79030,7 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
77951
79030
|
console.error(`
|
|
77952
79031
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
77953
79032
|
const home = homedir32();
|
|
77954
|
-
const localPath = isWindows2() ?
|
|
79033
|
+
const localPath = isWindows2() ? join36(home, ".claude", "local", "claude.exe") : join36(home, ".claude", "local", "claude");
|
|
77955
79034
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
77956
79035
|
process.exit(1);
|
|
77957
79036
|
}
|
|
@@ -77975,7 +79054,7 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
77975
79054
|
console.error("[claudish] An interactive session was requested but no terminal is attached (stdin and stdout are both non-TTY). Pass a prompt argument, or use --stdin / -p for non-interactive mode.");
|
|
77976
79055
|
}
|
|
77977
79056
|
const stdio = ttyFd !== undefined ? [0, ttyFd, ttyFd] : "inherit";
|
|
77978
|
-
const proc =
|
|
79057
|
+
const proc = spawn5(spawnCommand, claudeArgs, {
|
|
77979
79058
|
env,
|
|
77980
79059
|
stdio,
|
|
77981
79060
|
shell: needsShell
|
|
@@ -78031,23 +79110,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet, onCleanup) {
|
|
|
78031
79110
|
async function findClaudeBinary() {
|
|
78032
79111
|
const isWindows3 = process.platform === "win32";
|
|
78033
79112
|
if (process.env.CLAUDE_PATH) {
|
|
78034
|
-
if (
|
|
79113
|
+
if (existsSync28(process.env.CLAUDE_PATH)) {
|
|
78035
79114
|
return process.env.CLAUDE_PATH;
|
|
78036
79115
|
}
|
|
78037
79116
|
}
|
|
78038
79117
|
const home = homedir32();
|
|
78039
|
-
const localPath = isWindows3 ?
|
|
78040
|
-
if (
|
|
79118
|
+
const localPath = isWindows3 ? join36(home, ".claude", "local", "claude.exe") : join36(home, ".claude", "local", "claude");
|
|
79119
|
+
if (existsSync28(localPath)) {
|
|
78041
79120
|
return localPath;
|
|
78042
79121
|
}
|
|
78043
79122
|
if (isWindows3) {
|
|
78044
79123
|
const windowsPaths = [
|
|
78045
|
-
|
|
78046
|
-
|
|
78047
|
-
|
|
79124
|
+
join36(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
79125
|
+
join36(home, ".npm-global", "claude.cmd"),
|
|
79126
|
+
join36(home, "node_modules", ".bin", "claude.cmd")
|
|
78048
79127
|
];
|
|
78049
79128
|
for (const path2 of windowsPaths) {
|
|
78050
|
-
if (
|
|
79129
|
+
if (existsSync28(path2)) {
|
|
78051
79130
|
return path2;
|
|
78052
79131
|
}
|
|
78053
79132
|
}
|
|
@@ -78055,21 +79134,21 @@ async function findClaudeBinary() {
|
|
|
78055
79134
|
const commonPaths = [
|
|
78056
79135
|
"/usr/local/bin/claude",
|
|
78057
79136
|
"/opt/homebrew/bin/claude",
|
|
78058
|
-
|
|
78059
|
-
|
|
78060
|
-
|
|
79137
|
+
join36(home, ".npm-global/bin/claude"),
|
|
79138
|
+
join36(home, ".local/bin/claude"),
|
|
79139
|
+
join36(home, "node_modules/.bin/claude"),
|
|
78061
79140
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
78062
|
-
|
|
79141
|
+
join36(home, "../usr/bin/claude")
|
|
78063
79142
|
];
|
|
78064
79143
|
for (const path2 of commonPaths) {
|
|
78065
|
-
if (
|
|
79144
|
+
if (existsSync28(path2)) {
|
|
78066
79145
|
return path2;
|
|
78067
79146
|
}
|
|
78068
79147
|
}
|
|
78069
79148
|
}
|
|
78070
79149
|
try {
|
|
78071
79150
|
const shellCommand = isWindows3 ? "where claude" : "command -v claude";
|
|
78072
|
-
const proc =
|
|
79151
|
+
const proc = spawn5(shellCommand, [], {
|
|
78073
79152
|
stdio: "pipe",
|
|
78074
79153
|
shell: true
|
|
78075
79154
|
});
|
|
@@ -78121,18 +79200,18 @@ __export(exports_diag_output, {
|
|
|
78121
79200
|
NullDiagOutput: () => NullDiagOutput,
|
|
78122
79201
|
LogFileDiagOutput: () => LogFileDiagOutput
|
|
78123
79202
|
});
|
|
78124
|
-
import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync18, unlinkSync as unlinkSync10, writeFileSync as
|
|
79203
|
+
import { createWriteStream as createWriteStream3, mkdirSync as mkdirSync18, unlinkSync as unlinkSync10, writeFileSync as writeFileSync21 } from "fs";
|
|
78125
79204
|
import { homedir as homedir33 } from "os";
|
|
78126
|
-
import { join as
|
|
79205
|
+
import { join as join37 } from "path";
|
|
78127
79206
|
function getClaudishDir() {
|
|
78128
|
-
const dir =
|
|
79207
|
+
const dir = join37(homedir33(), ".claudish");
|
|
78129
79208
|
try {
|
|
78130
79209
|
mkdirSync18(dir, { recursive: true });
|
|
78131
79210
|
} catch {}
|
|
78132
79211
|
return dir;
|
|
78133
79212
|
}
|
|
78134
79213
|
function getDiagLogPath() {
|
|
78135
|
-
return
|
|
79214
|
+
return join37(getClaudishDir(), `diag-${process.pid}.log`);
|
|
78136
79215
|
}
|
|
78137
79216
|
|
|
78138
79217
|
class LogFileDiagOutput {
|
|
@@ -78141,7 +79220,7 @@ class LogFileDiagOutput {
|
|
|
78141
79220
|
constructor() {
|
|
78142
79221
|
this.logPath = getDiagLogPath();
|
|
78143
79222
|
try {
|
|
78144
|
-
|
|
79223
|
+
writeFileSync21(this.logPath, `--- claudish diag session ${new Date().toISOString()} ---
|
|
78145
79224
|
`);
|
|
78146
79225
|
} catch {}
|
|
78147
79226
|
this.stream = createWriteStream3(this.logPath, { flags: "a" });
|
|
@@ -78328,279 +79407,6 @@ var init_catalog_warm = __esm(() => {
|
|
|
78328
79407
|
];
|
|
78329
79408
|
});
|
|
78330
79409
|
|
|
78331
|
-
// src/team-grid.ts
|
|
78332
|
-
var exports_team_grid = {};
|
|
78333
|
-
__export(exports_team_grid, {
|
|
78334
|
-
runWithGrid: () => runWithGrid
|
|
78335
|
-
});
|
|
78336
|
-
import { spawn as spawn5 } from "child_process";
|
|
78337
|
-
import { execSync as execSync2 } from "child_process";
|
|
78338
|
-
import { existsSync as existsSync28, readFileSync as readFileSync27, writeFileSync as writeFileSync21 } from "fs";
|
|
78339
|
-
import { connect as netConnect } from "net";
|
|
78340
|
-
import { dirname as dirname13, join as join36 } from "path";
|
|
78341
|
-
import { setTimeout as wait } from "timers/promises";
|
|
78342
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
78343
|
-
function resolveRouteInfo(modelId) {
|
|
78344
|
-
const parsed = parseModelSpec(modelId);
|
|
78345
|
-
if (parsed.isExplicitProvider) {
|
|
78346
|
-
return { chain: [parsed.provider], source: "direct" };
|
|
78347
|
-
}
|
|
78348
|
-
const local = loadLocalConfig();
|
|
78349
|
-
if (local?.routing && Object.keys(local.routing).length > 0) {
|
|
78350
|
-
const matched2 = matchRoutingRule(parsed.model, local.routing);
|
|
78351
|
-
if (matched2) {
|
|
78352
|
-
const routes = buildRoutingChain(matched2, parsed.model);
|
|
78353
|
-
const pattern = Object.keys(local.routing).find((k) => {
|
|
78354
|
-
if (k === parsed.model)
|
|
78355
|
-
return true;
|
|
78356
|
-
if (k.includes("*")) {
|
|
78357
|
-
const star = k.indexOf("*");
|
|
78358
|
-
return parsed.model.startsWith(k.slice(0, star)) && parsed.model.endsWith(k.slice(star + 1));
|
|
78359
|
-
}
|
|
78360
|
-
return false;
|
|
78361
|
-
});
|
|
78362
|
-
return {
|
|
78363
|
-
chain: routes.map((r) => r.displayName),
|
|
78364
|
-
source: "project routing",
|
|
78365
|
-
sourceDetail: pattern
|
|
78366
|
-
};
|
|
78367
|
-
}
|
|
78368
|
-
}
|
|
78369
|
-
const global_ = loadConfig();
|
|
78370
|
-
if (global_.routing && Object.keys(global_.routing).length > 0) {
|
|
78371
|
-
const matched2 = matchRoutingRule(parsed.model, global_.routing);
|
|
78372
|
-
if (matched2) {
|
|
78373
|
-
const routes = buildRoutingChain(matched2, parsed.model);
|
|
78374
|
-
const pattern = Object.keys(global_.routing).find((k) => {
|
|
78375
|
-
if (k === parsed.model)
|
|
78376
|
-
return true;
|
|
78377
|
-
if (k.includes("*")) {
|
|
78378
|
-
const star = k.indexOf("*");
|
|
78379
|
-
return parsed.model.startsWith(k.slice(0, star)) && parsed.model.endsWith(k.slice(star + 1));
|
|
78380
|
-
}
|
|
78381
|
-
return false;
|
|
78382
|
-
});
|
|
78383
|
-
return {
|
|
78384
|
-
chain: routes.map((r) => r.displayName),
|
|
78385
|
-
source: "user routing",
|
|
78386
|
-
sourceDetail: pattern
|
|
78387
|
-
};
|
|
78388
|
-
}
|
|
78389
|
-
}
|
|
78390
|
-
const merged = loadRoutingRules();
|
|
78391
|
-
const matched = matchRoutingRule(parsed.model, merged);
|
|
78392
|
-
if (matched) {
|
|
78393
|
-
const routes = buildRoutingChain(matched, parsed.model);
|
|
78394
|
-
return {
|
|
78395
|
-
chain: routes.map((r) => r.displayName),
|
|
78396
|
-
source: "auto"
|
|
78397
|
-
};
|
|
78398
|
-
}
|
|
78399
|
-
return {
|
|
78400
|
-
chain: [],
|
|
78401
|
-
source: "auto"
|
|
78402
|
-
};
|
|
78403
|
-
}
|
|
78404
|
-
function pickBannerColor(model, used) {
|
|
78405
|
-
let hash2 = 0;
|
|
78406
|
-
for (let i = 0;i < model.length; i++)
|
|
78407
|
-
hash2 = (hash2 << 5) - hash2 + model.charCodeAt(i) | 0;
|
|
78408
|
-
const start = Math.abs(hash2) % BANNER_BG_COLORS.length;
|
|
78409
|
-
let idx = start;
|
|
78410
|
-
if (used.size < BANNER_BG_COLORS.length) {
|
|
78411
|
-
while (used.has(idx))
|
|
78412
|
-
idx = (idx + 1) % BANNER_BG_COLORS.length;
|
|
78413
|
-
}
|
|
78414
|
-
used.add(idx);
|
|
78415
|
-
return BANNER_BG_COLORS[idx];
|
|
78416
|
-
}
|
|
78417
|
-
function buildPaneHeader(model, prompt, bg) {
|
|
78418
|
-
const route2 = resolveRouteInfo(model);
|
|
78419
|
-
const esc2 = (s) => s.replace(/'/g, "'\\''");
|
|
78420
|
-
const chainStr2 = route2.chain.join(" \u2192 ");
|
|
78421
|
-
const sourceLabel = route2.sourceDetail ? `${route2.source}: ${route2.sourceDetail}` : route2.source;
|
|
78422
|
-
const lines = [];
|
|
78423
|
-
lines.push(`printf '\\033[1;97;${bg}m %s \\033[0m\\n' '${esc2(model)}';`);
|
|
78424
|
-
lines.push(`printf '\\033[2m route: ${esc2(chainStr2)} (${esc2(sourceLabel)})\\033[0m\\n' ;`);
|
|
78425
|
-
lines.push(`printf '\\033[2m %s\\033[0m\\n' '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500';`);
|
|
78426
|
-
const promptForShell = esc2(prompt).replace(/\n/g, "\\n");
|
|
78427
|
-
lines.push(`printf '%b\\n' '${promptForShell}' | fold -s -w 78 | sed 's/^/ /';`);
|
|
78428
|
-
lines.push(`printf '\\033[2m %s\\033[0m\\n\\n' '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500';`);
|
|
78429
|
-
return lines.join(" ");
|
|
78430
|
-
}
|
|
78431
|
-
function findMagmuxBinary() {
|
|
78432
|
-
const thisFile = fileURLToPath3(import.meta.url);
|
|
78433
|
-
const thisDir = dirname13(thisFile);
|
|
78434
|
-
const pkgRoot = join36(thisDir, "..");
|
|
78435
|
-
const platform3 = process.platform;
|
|
78436
|
-
const arch = process.arch;
|
|
78437
|
-
const bundledMagmux = join36(pkgRoot, "native", `magmux-${platform3}-${arch}`);
|
|
78438
|
-
if (existsSync28(bundledMagmux))
|
|
78439
|
-
return bundledMagmux;
|
|
78440
|
-
try {
|
|
78441
|
-
const pkgName = `@claudish/magmux-${platform3}-${arch}`;
|
|
78442
|
-
let searchDir = pkgRoot;
|
|
78443
|
-
for (let i = 0;i < 5; i++) {
|
|
78444
|
-
const candidate = join36(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
78445
|
-
if (existsSync28(candidate))
|
|
78446
|
-
return candidate;
|
|
78447
|
-
const parent = dirname13(searchDir);
|
|
78448
|
-
if (parent === searchDir)
|
|
78449
|
-
break;
|
|
78450
|
-
searchDir = parent;
|
|
78451
|
-
}
|
|
78452
|
-
} catch {}
|
|
78453
|
-
try {
|
|
78454
|
-
const result = execSync2("which magmux", { encoding: "utf-8" }).trim();
|
|
78455
|
-
if (result)
|
|
78456
|
-
return result;
|
|
78457
|
-
} catch {}
|
|
78458
|
-
throw new Error(`magmux not found. Install it:
|
|
78459
|
-
brew install MadAppGang/tap/magmux`);
|
|
78460
|
-
}
|
|
78461
|
-
async function subscribeToMagmux(sockPath, onEvent) {
|
|
78462
|
-
let client = null;
|
|
78463
|
-
for (let attempt = 0;attempt < 40; attempt++) {
|
|
78464
|
-
if (existsSync28(sockPath)) {
|
|
78465
|
-
try {
|
|
78466
|
-
client = await new Promise((resolve5, reject) => {
|
|
78467
|
-
const s = netConnect(sockPath);
|
|
78468
|
-
s.once("connect", () => resolve5(s));
|
|
78469
|
-
s.once("error", reject);
|
|
78470
|
-
});
|
|
78471
|
-
break;
|
|
78472
|
-
} catch {}
|
|
78473
|
-
}
|
|
78474
|
-
await wait(50);
|
|
78475
|
-
}
|
|
78476
|
-
if (!client) {
|
|
78477
|
-
return { results: null, client: null };
|
|
78478
|
-
}
|
|
78479
|
-
return await new Promise((resolve5) => {
|
|
78480
|
-
let buf = "";
|
|
78481
|
-
let finalResults = null;
|
|
78482
|
-
client.on("data", (chunk) => {
|
|
78483
|
-
buf += chunk.toString("utf-8");
|
|
78484
|
-
let nl = buf.indexOf(`
|
|
78485
|
-
`);
|
|
78486
|
-
while (nl >= 0) {
|
|
78487
|
-
const line = buf.slice(0, nl).trim();
|
|
78488
|
-
buf = buf.slice(nl + 1);
|
|
78489
|
-
nl = buf.indexOf(`
|
|
78490
|
-
`);
|
|
78491
|
-
if (!line)
|
|
78492
|
-
continue;
|
|
78493
|
-
try {
|
|
78494
|
-
const evt = JSON.parse(line);
|
|
78495
|
-
onEvent?.(evt);
|
|
78496
|
-
if (evt.type === "results") {
|
|
78497
|
-
finalResults = evt;
|
|
78498
|
-
}
|
|
78499
|
-
} catch {}
|
|
78500
|
-
}
|
|
78501
|
-
});
|
|
78502
|
-
const done = () => resolve5({ results: finalResults, client });
|
|
78503
|
-
client.once("end", done);
|
|
78504
|
-
client.once("close", done);
|
|
78505
|
-
client.once("error", done);
|
|
78506
|
-
});
|
|
78507
|
-
}
|
|
78508
|
-
function buildTeamStatus(manifest, startedAt, results) {
|
|
78509
|
-
const anonIds = Object.keys(manifest.models);
|
|
78510
|
-
const models = {};
|
|
78511
|
-
for (let i = 0;i < anonIds.length; i++) {
|
|
78512
|
-
const anonId = anonIds[i];
|
|
78513
|
-
const result = results?.find((r) => r.pane === i);
|
|
78514
|
-
if (!result) {
|
|
78515
|
-
models[anonId] = {
|
|
78516
|
-
state: "TIMEOUT",
|
|
78517
|
-
exitCode: null,
|
|
78518
|
-
startedAt,
|
|
78519
|
-
completedAt: null,
|
|
78520
|
-
outputSize: 0
|
|
78521
|
-
};
|
|
78522
|
-
continue;
|
|
78523
|
-
}
|
|
78524
|
-
let state;
|
|
78525
|
-
switch (result.state) {
|
|
78526
|
-
case "completed":
|
|
78527
|
-
case "awaiting_input":
|
|
78528
|
-
state = "COMPLETED";
|
|
78529
|
-
break;
|
|
78530
|
-
case "failed":
|
|
78531
|
-
state = "FAILED";
|
|
78532
|
-
break;
|
|
78533
|
-
default:
|
|
78534
|
-
state = "TIMEOUT";
|
|
78535
|
-
}
|
|
78536
|
-
models[anonId] = {
|
|
78537
|
-
state,
|
|
78538
|
-
exitCode: result.exitCode,
|
|
78539
|
-
startedAt: result.startedAt ?? startedAt,
|
|
78540
|
-
completedAt: result.completedAt ?? new Date().toISOString(),
|
|
78541
|
-
outputSize: result.response?.length ?? 0
|
|
78542
|
-
};
|
|
78543
|
-
}
|
|
78544
|
-
return { startedAt, models };
|
|
78545
|
-
}
|
|
78546
|
-
async function runWithGrid(sessionPath, models, input, opts) {
|
|
78547
|
-
const mode = opts?.mode ?? "default";
|
|
78548
|
-
const keep = opts?.keep ?? false;
|
|
78549
|
-
const manifest = setupSession(sessionPath, models, input);
|
|
78550
|
-
const startedAt = new Date().toISOString();
|
|
78551
|
-
const gridfilePath = join36(sessionPath, "gridfile.txt");
|
|
78552
|
-
const prompt = readFileSync27(join36(sessionPath, "input.md"), "utf-8").replace(/'/g, "'\\''").replace(/\n/g, " ");
|
|
78553
|
-
const rawPrompt = readFileSync27(join36(sessionPath, "input.md"), "utf-8");
|
|
78554
|
-
const usedBannerColors = new Set;
|
|
78555
|
-
const gridLines = Object.entries(manifest.models).map(([anonId]) => {
|
|
78556
|
-
const model = manifest.models[anonId].model;
|
|
78557
|
-
if (mode === "interactive") {
|
|
78558
|
-
return `claudish --model ${model} -i --dangerously-skip-permissions '${prompt}'`;
|
|
78559
|
-
}
|
|
78560
|
-
const bg = pickBannerColor(model, usedBannerColors);
|
|
78561
|
-
const header = buildPaneHeader(model, rawPrompt, bg);
|
|
78562
|
-
return `${header} claudish --model ${model} -y --quiet '${prompt}'`;
|
|
78563
|
-
});
|
|
78564
|
-
writeFileSync21(gridfilePath, `${gridLines.join(`
|
|
78565
|
-
`)}
|
|
78566
|
-
`, "utf-8");
|
|
78567
|
-
const magmuxPath = findMagmuxBinary();
|
|
78568
|
-
const spawnArgs = ["-g", gridfilePath];
|
|
78569
|
-
if (!keep && mode === "default") {
|
|
78570
|
-
spawnArgs.push("-w");
|
|
78571
|
-
}
|
|
78572
|
-
const proc = spawn5(magmuxPath, spawnArgs, {
|
|
78573
|
-
stdio: "inherit",
|
|
78574
|
-
env: { ...process.env }
|
|
78575
|
-
});
|
|
78576
|
-
const sockPath = `/tmp/magmux-${proc.pid}.sock`;
|
|
78577
|
-
const subscription = subscribeToMagmux(sockPath);
|
|
78578
|
-
const procExit = new Promise((resolve5) => {
|
|
78579
|
-
proc.on("exit", () => resolve5());
|
|
78580
|
-
proc.on("error", () => resolve5());
|
|
78581
|
-
});
|
|
78582
|
-
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
78583
|
-
const status = buildTeamStatus(manifest, startedAt, results?.panes ?? null);
|
|
78584
|
-
const statusPath = join36(sessionPath, "status.json");
|
|
78585
|
-
writeFileSync21(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
78586
|
-
return status;
|
|
78587
|
-
}
|
|
78588
|
-
var BANNER_BG_COLORS;
|
|
78589
|
-
var init_team_grid = __esm(() => {
|
|
78590
|
-
init_profile_config();
|
|
78591
|
-
init_model_parser();
|
|
78592
|
-
init_routing_rules();
|
|
78593
|
-
init_team_orchestrator();
|
|
78594
|
-
BANNER_BG_COLORS = [
|
|
78595
|
-
"48;2;40;90;180",
|
|
78596
|
-
"48;2;140;60;160",
|
|
78597
|
-
"48;2;30;130;100",
|
|
78598
|
-
"48;2;160;80;40",
|
|
78599
|
-
"48;2;60;120;60",
|
|
78600
|
-
"48;2;160;50;70"
|
|
78601
|
-
];
|
|
78602
|
-
});
|
|
78603
|
-
|
|
78604
79410
|
// src/tui/viz/text.ts
|
|
78605
79411
|
function columns(n, fn, arg = "width") {
|
|
78606
79412
|
if (!Number.isFinite(n))
|
|
@@ -79003,7 +79809,7 @@ __export(exports_session_discovery, {
|
|
|
79003
79809
|
import { execFile, execFileSync as execFileSync2 } from "child_process";
|
|
79004
79810
|
import { closeSync as closeSync5, openSync as openSync5, readSync, readdirSync as readdirSync7, statSync as statSync6 } from "fs";
|
|
79005
79811
|
import { homedir as homedir34 } from "os";
|
|
79006
|
-
import { basename, join as
|
|
79812
|
+
import { basename, join as join38 } from "path";
|
|
79007
79813
|
function slugForPath(absPath) {
|
|
79008
79814
|
return absPath.replace(/[/.]/g, "-");
|
|
79009
79815
|
}
|
|
@@ -79052,7 +79858,7 @@ function projectDirs() {
|
|
|
79052
79858
|
}
|
|
79053
79859
|
}
|
|
79054
79860
|
function sessionsIn(dirName) {
|
|
79055
|
-
const dir =
|
|
79861
|
+
const dir = join38(PROJECTS_DIR, dirName);
|
|
79056
79862
|
let names;
|
|
79057
79863
|
try {
|
|
79058
79864
|
names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
|
|
@@ -79061,7 +79867,7 @@ function sessionsIn(dirName) {
|
|
|
79061
79867
|
}
|
|
79062
79868
|
const rows = [];
|
|
79063
79869
|
for (const n of names) {
|
|
79064
|
-
const file2 =
|
|
79870
|
+
const file2 = join38(dir, n);
|
|
79065
79871
|
try {
|
|
79066
79872
|
const st = statSync6(file2);
|
|
79067
79873
|
if (st.size === 0)
|
|
@@ -79420,7 +80226,7 @@ function findLatestSessionId(cwd = process.cwd(), sinceMs = 0) {
|
|
|
79420
80226
|
}
|
|
79421
80227
|
var ENTRYPOINT_BYTES = 8192, PROJECTS_DIR, ACTIVE_WINDOW_MS = 120000, HEAD_BYTES, TAIL_BYTES, HARNESS_ENVELOPES, DEEP_TAIL_BYTES, RECENT_AI_TURNS = 5, RECENT_USER_TURNS = 1;
|
|
79422
80228
|
var init_session_discovery = __esm(() => {
|
|
79423
|
-
PROJECTS_DIR =
|
|
80229
|
+
PROJECTS_DIR = join38(homedir34(), ".claude", "projects");
|
|
79424
80230
|
HEAD_BYTES = 64 * 1024;
|
|
79425
80231
|
TAIL_BYTES = 128 * 1024;
|
|
79426
80232
|
HARNESS_ENVELOPES = [
|
|
@@ -81112,22 +81918,26 @@ __export(exports_session_stats, {
|
|
|
81112
81918
|
readSessionStats: () => readSessionStats,
|
|
81113
81919
|
computeSavings: () => computeSavings
|
|
81114
81920
|
});
|
|
81115
|
-
import { readFileSync as
|
|
81921
|
+
import { readFileSync as readFileSync29 } from "fs";
|
|
81116
81922
|
import { homedir as homedir35 } from "os";
|
|
81117
|
-
import { join as
|
|
81923
|
+
import { join as join39 } from "path";
|
|
81118
81924
|
function tokenFilePath(port) {
|
|
81119
|
-
return process.env.CLAUDISH_TOKEN_FILE ||
|
|
81925
|
+
return process.env.CLAUDISH_TOKEN_FILE || join39(homedir35(), ".claudish", `tokens-${port}.json`);
|
|
81120
81926
|
}
|
|
81121
|
-
function readSessionStats(port) {
|
|
81927
|
+
function readSessionStats(port, opts) {
|
|
81122
81928
|
let raw2;
|
|
81123
81929
|
try {
|
|
81124
|
-
raw2 = JSON.parse(
|
|
81930
|
+
raw2 = JSON.parse(readFileSync29(tokenFilePath(port), "utf-8"));
|
|
81125
81931
|
} catch {
|
|
81126
81932
|
return null;
|
|
81127
81933
|
}
|
|
81128
81934
|
if (!raw2 || typeof raw2 !== "object")
|
|
81129
81935
|
return null;
|
|
81130
81936
|
const d = raw2;
|
|
81937
|
+
const processStartMs = opts?.processStartMs ?? Date.now() - Math.round(process.uptime() * 1000);
|
|
81938
|
+
const trackerStartedAt = num(d.started_at);
|
|
81939
|
+
if (trackerStartedAt <= 0 || trackerStartedAt < processStartMs)
|
|
81940
|
+
return null;
|
|
81131
81941
|
const inputTokens = num(d.input_tokens);
|
|
81132
81942
|
const outputTokens = num(d.output_tokens);
|
|
81133
81943
|
if (inputTokens <= 0 && outputTokens <= 0)
|
|
@@ -81457,8 +82267,8 @@ var init_session_summary = __esm(() => {
|
|
|
81457
82267
|
init_op_source();
|
|
81458
82268
|
init_startup_trace();
|
|
81459
82269
|
var import_dotenv3 = __toESM(require_main(), 1);
|
|
81460
|
-
import { existsSync as existsSync29, readFileSync as
|
|
81461
|
-
import { join as
|
|
82270
|
+
import { existsSync as existsSync29, readFileSync as readFileSync30 } from "fs";
|
|
82271
|
+
import { join as join40, resolve as resolve5 } from "path";
|
|
81462
82272
|
import_dotenv3.config({ quiet: true });
|
|
81463
82273
|
function classifyStartupKind() {
|
|
81464
82274
|
const argv = process.argv.slice(2);
|
|
@@ -81592,6 +82402,7 @@ var isConfigCommand = firstPositional === "config";
|
|
|
81592
82402
|
var isServeCommand = firstPositional === "serve";
|
|
81593
82403
|
var isProvidersCommand = firstPositional === "providers";
|
|
81594
82404
|
var isBehaviorCommand = firstPositional === "behavior";
|
|
82405
|
+
var isTeamCommand = firstPositional === "team";
|
|
81595
82406
|
var isLoginCommand = firstPositional === "login";
|
|
81596
82407
|
var isLogoutCommand = firstPositional === "logout";
|
|
81597
82408
|
var isQuotaCommand = firstPositional === "quota" || firstPositional === "usage";
|
|
@@ -81617,6 +82428,12 @@ if (isMcpMode) {
|
|
|
81617
82428
|
console.error(`[claudish behavior] ${e instanceof Error ? e.message : String(e)}`);
|
|
81618
82429
|
process.exit(1);
|
|
81619
82430
|
}));
|
|
82431
|
+
} else if (isTeamCommand) {
|
|
82432
|
+
const teamArgIndex = args.indexOf("team");
|
|
82433
|
+
Promise.resolve().then(() => (init_team_cli(), exports_team_cli)).then((m) => m.teamCommand(args.slice(teamArgIndex + 1)).catch((e) => {
|
|
82434
|
+
console.error(`[claudish team] ${e instanceof Error ? e.message : String(e)}`);
|
|
82435
|
+
process.exit(1);
|
|
82436
|
+
}));
|
|
81620
82437
|
} else if (isProvidersCommand) {
|
|
81621
82438
|
const json2 = args.includes("--json");
|
|
81622
82439
|
Promise.resolve().then(() => (init_providers_command(), exports_providers_command)).then((m) => m.providersCommand({ json: json2 }).catch((e) => {
|
|
@@ -81701,14 +82518,14 @@ async function runCli() {
|
|
|
81701
82518
|
if (cliConfig.team && cliConfig.team.length > 0) {
|
|
81702
82519
|
let prompt = cliConfig.claudeArgs.join(" ");
|
|
81703
82520
|
if (cliConfig.inputFile) {
|
|
81704
|
-
prompt =
|
|
82521
|
+
prompt = readFileSync30(cliConfig.inputFile, "utf-8");
|
|
81705
82522
|
}
|
|
81706
82523
|
if (!prompt.trim()) {
|
|
81707
82524
|
console.error("Error: --team requires a prompt (positional args or -f <file>)");
|
|
81708
82525
|
process.exit(1);
|
|
81709
82526
|
}
|
|
81710
82527
|
const mode = cliConfig.teamMode ?? "default";
|
|
81711
|
-
const sessionPath =
|
|
82528
|
+
const sessionPath = join40(process.cwd(), `.claudish-team-${Date.now()}`);
|
|
81712
82529
|
if (mode === "json") {
|
|
81713
82530
|
const { setupSession: setupSession2, runModels: runModels2 } = await Promise.resolve().then(() => (init_team_orchestrator(), exports_team_orchestrator));
|
|
81714
82531
|
setupSession2(sessionPath, cliConfig.team, prompt);
|
|
@@ -81718,9 +82535,9 @@ async function runCli() {
|
|
|
81718
82535
|
});
|
|
81719
82536
|
const result = { ...status2, responses: {} };
|
|
81720
82537
|
for (const anonId of Object.keys(status2.models)) {
|
|
81721
|
-
const responsePath =
|
|
82538
|
+
const responsePath = join40(sessionPath, `response-${anonId}.md`);
|
|
81722
82539
|
try {
|
|
81723
|
-
const raw2 =
|
|
82540
|
+
const raw2 = readFileSync30(responsePath, "utf-8").trim();
|
|
81724
82541
|
try {
|
|
81725
82542
|
result.responses[anonId] = JSON.parse(raw2);
|
|
81726
82543
|
} catch {
|