@spinabot/brigade 1.23.0 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/agent-loop.d.ts.map +1 -1
- package/dist/agents/agent-loop.js +73 -3
- package/dist/agents/agent-loop.js.map +1 -1
- package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -1
- package/dist/agents/channels/inbound-pipeline.js +6 -0
- package/dist/agents/channels/inbound-pipeline.js.map +1 -1
- package/dist/agents/claude-cli/availability.d.ts +12 -0
- package/dist/agents/claude-cli/availability.d.ts.map +1 -0
- package/dist/agents/claude-cli/availability.js +79 -0
- package/dist/agents/claude-cli/availability.js.map +1 -0
- package/dist/agents/claude-cli/catalog.d.ts +91 -0
- package/dist/agents/claude-cli/catalog.d.ts.map +1 -0
- package/dist/agents/claude-cli/catalog.js +260 -0
- package/dist/agents/claude-cli/catalog.js.map +1 -0
- package/dist/agents/claude-cli/claude-config.d.ts +38 -0
- package/dist/agents/claude-cli/claude-config.d.ts.map +1 -0
- package/dist/agents/claude-cli/claude-config.js +111 -0
- package/dist/agents/claude-cli/claude-config.js.map +1 -0
- package/dist/agents/claude-cli/register.d.ts +32 -0
- package/dist/agents/claude-cli/register.d.ts.map +1 -0
- package/dist/agents/claude-cli/register.js +68 -0
- package/dist/agents/claude-cli/register.js.map +1 -0
- package/dist/agents/claude-cli/spawn.d.ts +42 -0
- package/dist/agents/claude-cli/spawn.d.ts.map +1 -0
- package/dist/agents/claude-cli/spawn.js +179 -0
- package/dist/agents/claude-cli/spawn.js.map +1 -0
- package/dist/agents/claude-cli/stream-json.d.ts +129 -0
- package/dist/agents/claude-cli/stream-json.d.ts.map +1 -0
- package/dist/agents/claude-cli/stream-json.js +84 -0
- package/dist/agents/claude-cli/stream-json.js.map +1 -0
- package/dist/agents/claude-cli/stream.d.ts +27 -0
- package/dist/agents/claude-cli/stream.d.ts.map +1 -0
- package/dist/agents/claude-cli/stream.js +380 -0
- package/dist/agents/claude-cli/stream.js.map +1 -0
- package/dist/agents/error-classifier.d.ts +2 -2
- package/dist/agents/error-classifier.d.ts.map +1 -1
- package/dist/agents/error-classifier.js +43 -0
- package/dist/agents/error-classifier.js.map +1 -1
- package/dist/agents/model-resolution.d.ts +36 -0
- package/dist/agents/model-resolution.d.ts.map +1 -1
- package/dist/agents/model-resolution.js +59 -0
- package/dist/agents/model-resolution.js.map +1 -1
- package/dist/agents/retry-policy.d.ts.map +1 -1
- package/dist/agents/retry-policy.js +25 -1
- package/dist/agents/retry-policy.js.map +1 -1
- package/dist/auth/auth-health.d.ts +89 -0
- package/dist/auth/auth-health.d.ts.map +1 -1
- package/dist/auth/auth-health.js +207 -1
- package/dist/auth/auth-health.js.map +1 -1
- package/dist/buildstamp.json +1 -1
- package/dist/cli/commands/auth.js +18 -0
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +46 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/gateway.d.ts +4 -0
- package/dist/cli/commands/gateway.d.ts.map +1 -1
- package/dist/cli/commands/gateway.js +44 -2
- package/dist/cli/commands/gateway.js.map +1 -1
- package/dist/cli/commands/login.d.ts.map +1 -1
- package/dist/cli/commands/login.js +107 -19
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/core/auth-bridge.d.ts.map +1 -1
- package/dist/core/auth-bridge.js +16 -0
- package/dist/core/auth-bridge.js.map +1 -1
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +13 -0
- package/dist/core/server.js.map +1 -1
- package/dist/providers/catalog.d.ts.map +1 -1
- package/dist/providers/catalog.js +18 -0
- package/dist/providers/catalog.js.map +1 -1
- package/dist/ui/onboarding.d.ts +11 -0
- package/dist/ui/onboarding.d.ts.map +1 -1
- package/dist/ui/onboarding.js +343 -4
- package/dist/ui/onboarding.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// Subprocess plumbing for the claude-cli backend: spawn the `claude` binary,
|
|
2
|
+
// stream its stdout as parsed NDJSON frames, and enforce a no-output watchdog
|
|
3
|
+
// that hard-kills a wedged process. Kept separate from `stream.ts` so the
|
|
4
|
+
// Pi-event mapping and the OS-process concerns test independently.
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
6
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { buildClaudeCliEnv, resolveClaudeCliCommand } from "./catalog.js";
|
|
10
|
+
import { hasBrigadeClaudeLogin, resolveBrigadeClaudeConfigDir } from "./claude-config.js";
|
|
11
|
+
import { parseClaudeCliLine } from "./stream-json.js";
|
|
12
|
+
/**
|
|
13
|
+
* No-output watchdog. The timer is reset on every stdout/stderr chunk, so a
|
|
14
|
+
* slow-but-streaming turn survives while a genuinely wedged process (waiting on
|
|
15
|
+
* an interactive prompt that can never arrive, or hung on the network) trips it
|
|
16
|
+
* and is SIGKILL'd. Fresh runs get a longer grace (CLI startup + auth); we have
|
|
17
|
+
* no resume path in v1 so a single profile suffices.
|
|
18
|
+
*/
|
|
19
|
+
export const CLAUDE_CLI_NO_OUTPUT_TIMEOUT_MS = 180_000;
|
|
20
|
+
/** Hard ceiling on a single turn regardless of trickle output. */
|
|
21
|
+
export const CLAUDE_CLI_OVERALL_TIMEOUT_MS = 600_000;
|
|
22
|
+
/**
|
|
23
|
+
* Spawn `claude` with the given argv, feed `stdin`, and stream parsed frames.
|
|
24
|
+
* The isolated empty temp cwd contains the CLI's tool blast radius: even under
|
|
25
|
+
* `bypassPermissions` any file/read tool it reaches acts on a throwaway dir,
|
|
26
|
+
* never the operator's project. The dir is removed when the process exits.
|
|
27
|
+
*/
|
|
28
|
+
export function spawnClaudeCli(args) {
|
|
29
|
+
const command = resolveClaudeCliCommand();
|
|
30
|
+
const noOutputMs = args.noOutputTimeoutMs ?? CLAUDE_CLI_NO_OUTPUT_TIMEOUT_MS;
|
|
31
|
+
const overallMs = args.overallTimeoutMs ?? CLAUDE_CLI_OVERALL_TIMEOUT_MS;
|
|
32
|
+
const doSpawn = args.spawnFn ?? spawn;
|
|
33
|
+
// Isolated, empty working dir — the tool-containment boundary.
|
|
34
|
+
let cwd;
|
|
35
|
+
try {
|
|
36
|
+
cwd = mkdtempSync(path.join(tmpdir(), "brigade-claude-cli-"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
cwd = tmpdir();
|
|
40
|
+
}
|
|
41
|
+
// Prefer Brigade's OWN Claude login (dedicated grant in its managed config
|
|
42
|
+
// dir) when present — the binary auths + refreshes there, isolated from the
|
|
43
|
+
// operator's personal ~/.claude. Absent it, leave CLAUDE_CONFIG_DIR unset so
|
|
44
|
+
// the binary uses its default (the operator's own login).
|
|
45
|
+
const configDir = hasBrigadeClaudeLogin() ? resolveBrigadeClaudeConfigDir() : undefined;
|
|
46
|
+
const child = doSpawn(command, args.args, {
|
|
47
|
+
cwd,
|
|
48
|
+
env: buildClaudeCliEnv(process.env, { configDir }),
|
|
49
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
50
|
+
// No shell — argv is passed verbatim so nothing is word-split or expanded.
|
|
51
|
+
shell: false,
|
|
52
|
+
});
|
|
53
|
+
let killReason;
|
|
54
|
+
let settled = false;
|
|
55
|
+
let stderr = "";
|
|
56
|
+
const STDERR_CAP = 8_000;
|
|
57
|
+
// ── watchdog timers ──
|
|
58
|
+
let noOutputTimer;
|
|
59
|
+
let overallTimer;
|
|
60
|
+
const clearTimers = () => {
|
|
61
|
+
if (noOutputTimer)
|
|
62
|
+
clearTimeout(noOutputTimer);
|
|
63
|
+
if (overallTimer)
|
|
64
|
+
clearTimeout(overallTimer);
|
|
65
|
+
noOutputTimer = undefined;
|
|
66
|
+
overallTimer = undefined;
|
|
67
|
+
};
|
|
68
|
+
const kill = (reason) => {
|
|
69
|
+
if (settled || killReason)
|
|
70
|
+
return;
|
|
71
|
+
killReason = reason;
|
|
72
|
+
try {
|
|
73
|
+
child.kill("SIGKILL");
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
/* already gone */
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const armNoOutput = () => {
|
|
80
|
+
if (noOutputTimer)
|
|
81
|
+
clearTimeout(noOutputTimer);
|
|
82
|
+
noOutputTimer = setTimeout(() => kill("no-output-timeout"), noOutputMs);
|
|
83
|
+
// Don't keep the event loop alive purely for the watchdog.
|
|
84
|
+
noOutputTimer.unref?.();
|
|
85
|
+
};
|
|
86
|
+
overallTimer = setTimeout(() => kill("overall-timeout"), overallMs);
|
|
87
|
+
overallTimer.unref?.();
|
|
88
|
+
armNoOutput();
|
|
89
|
+
const onAbort = () => kill("aborted");
|
|
90
|
+
if (args.signal) {
|
|
91
|
+
if (args.signal.aborted)
|
|
92
|
+
onAbort();
|
|
93
|
+
else
|
|
94
|
+
args.signal.addEventListener("abort", onAbort, { once: true });
|
|
95
|
+
}
|
|
96
|
+
// ── stderr capture (bounded) ──
|
|
97
|
+
child.stderr.setEncoding("utf8");
|
|
98
|
+
child.stderr.on("data", (chunk) => {
|
|
99
|
+
armNoOutput(); // stderr progress also counts as "alive"
|
|
100
|
+
if (stderr.length < STDERR_CAP)
|
|
101
|
+
stderr += chunk;
|
|
102
|
+
});
|
|
103
|
+
// ── stdout → line-buffered frame queue ──
|
|
104
|
+
// A small async queue bridges the 'data'/'close' events to the generator.
|
|
105
|
+
const queue = [];
|
|
106
|
+
let resolveNext;
|
|
107
|
+
let closed = false;
|
|
108
|
+
let buffer = "";
|
|
109
|
+
const pump = () => {
|
|
110
|
+
if (resolveNext) {
|
|
111
|
+
const r = resolveNext;
|
|
112
|
+
resolveNext = undefined;
|
|
113
|
+
r();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
child.stdout.setEncoding("utf8");
|
|
117
|
+
child.stdout.on("data", (chunk) => {
|
|
118
|
+
armNoOutput();
|
|
119
|
+
buffer += chunk;
|
|
120
|
+
const lines = buffer.split("\n");
|
|
121
|
+
buffer = lines.pop() ?? "";
|
|
122
|
+
for (const line of lines) {
|
|
123
|
+
const frame = parseClaudeCliLine(line);
|
|
124
|
+
if (frame)
|
|
125
|
+
queue.push(frame);
|
|
126
|
+
}
|
|
127
|
+
pump();
|
|
128
|
+
});
|
|
129
|
+
const exit = new Promise((resolve) => {
|
|
130
|
+
const finish = (code) => {
|
|
131
|
+
if (settled)
|
|
132
|
+
return;
|
|
133
|
+
settled = true;
|
|
134
|
+
clearTimers();
|
|
135
|
+
if (args.signal)
|
|
136
|
+
args.signal.removeEventListener("abort", onAbort);
|
|
137
|
+
// Flush a final unterminated line.
|
|
138
|
+
const tail = parseClaudeCliLine(buffer);
|
|
139
|
+
if (tail)
|
|
140
|
+
queue.push(tail);
|
|
141
|
+
buffer = "";
|
|
142
|
+
closed = true;
|
|
143
|
+
pump();
|
|
144
|
+
// Best-effort cleanup of the throwaway cwd.
|
|
145
|
+
try {
|
|
146
|
+
rmSync(cwd, { recursive: true, force: true });
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
/* leave it for the OS temp reaper */
|
|
150
|
+
}
|
|
151
|
+
resolve({ code, killReason, stderr });
|
|
152
|
+
};
|
|
153
|
+
child.on("close", (code) => finish(code));
|
|
154
|
+
child.on("error", () => finish(null)); // spawn failure (binary missing, etc.)
|
|
155
|
+
});
|
|
156
|
+
// Feed stdin, then close it so the CLI starts generating.
|
|
157
|
+
try {
|
|
158
|
+
child.stdin.write(args.stdin);
|
|
159
|
+
child.stdin.end();
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
/* the 'error' handler above will settle the run */
|
|
163
|
+
}
|
|
164
|
+
async function* frames() {
|
|
165
|
+
while (true) {
|
|
166
|
+
if (queue.length > 0) {
|
|
167
|
+
yield queue.shift();
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (closed)
|
|
171
|
+
return;
|
|
172
|
+
await new Promise((r) => {
|
|
173
|
+
resolveNext = r;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { frames: frames(), done: exit };
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/agents/claude-cli/spawn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/** A raw Anthropic streaming SSE event, as wrapped in a `stream_event` frame. */
|
|
2
|
+
export interface AnthropicStreamEvent {
|
|
3
|
+
type?: string;
|
|
4
|
+
message?: {
|
|
5
|
+
usage?: AnthropicUsage;
|
|
6
|
+
[k: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
index?: number;
|
|
9
|
+
content_block?: {
|
|
10
|
+
type?: "text" | "thinking" | "tool_use" | string;
|
|
11
|
+
id?: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
input?: unknown;
|
|
14
|
+
[k: string]: unknown;
|
|
15
|
+
};
|
|
16
|
+
delta?: {
|
|
17
|
+
type?: "text_delta" | "thinking_delta" | "input_json_delta" | "signature_delta" | string;
|
|
18
|
+
text?: string;
|
|
19
|
+
thinking?: string;
|
|
20
|
+
partial_json?: string;
|
|
21
|
+
signature?: string;
|
|
22
|
+
stop_reason?: string | null;
|
|
23
|
+
[k: string]: unknown;
|
|
24
|
+
};
|
|
25
|
+
usage?: AnthropicUsage;
|
|
26
|
+
}
|
|
27
|
+
export interface AnthropicUsage {
|
|
28
|
+
input_tokens?: number;
|
|
29
|
+
output_tokens?: number;
|
|
30
|
+
cache_read_input_tokens?: number;
|
|
31
|
+
cache_creation_input_tokens?: number;
|
|
32
|
+
[k: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
/** A complete assistant message block (`type:"assistant"`). */
|
|
35
|
+
export interface AssistantFrameMessage {
|
|
36
|
+
id?: string;
|
|
37
|
+
role?: string;
|
|
38
|
+
model?: string;
|
|
39
|
+
stop_reason?: string | null;
|
|
40
|
+
content?: Array<{
|
|
41
|
+
type?: "text" | "thinking" | "tool_use" | string;
|
|
42
|
+
text?: string;
|
|
43
|
+
thinking?: string;
|
|
44
|
+
signature?: string;
|
|
45
|
+
id?: string;
|
|
46
|
+
name?: string;
|
|
47
|
+
input?: unknown;
|
|
48
|
+
[k: string]: unknown;
|
|
49
|
+
}>;
|
|
50
|
+
usage?: AnthropicUsage;
|
|
51
|
+
[k: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
/** The terminal `type:"result"` frame. */
|
|
54
|
+
export interface ResultFrame {
|
|
55
|
+
type: "result";
|
|
56
|
+
subtype?: string;
|
|
57
|
+
is_error?: boolean;
|
|
58
|
+
result?: string;
|
|
59
|
+
stop_reason?: string | null;
|
|
60
|
+
session_id?: string;
|
|
61
|
+
total_cost_usd?: number;
|
|
62
|
+
usage?: AnthropicUsage & {
|
|
63
|
+
service_tier?: string;
|
|
64
|
+
};
|
|
65
|
+
error?: string;
|
|
66
|
+
message?: string;
|
|
67
|
+
[k: string]: unknown;
|
|
68
|
+
}
|
|
69
|
+
/** Discriminated union of every frame `stream.ts` acts on. */
|
|
70
|
+
export type ClaudeCliFrame = {
|
|
71
|
+
type: "system";
|
|
72
|
+
subtype?: string;
|
|
73
|
+
session_id?: string;
|
|
74
|
+
[k: string]: unknown;
|
|
75
|
+
} | {
|
|
76
|
+
type: "stream_event";
|
|
77
|
+
event?: AnthropicStreamEvent;
|
|
78
|
+
session_id?: string;
|
|
79
|
+
[k: string]: unknown;
|
|
80
|
+
} | {
|
|
81
|
+
type: "assistant";
|
|
82
|
+
message?: AssistantFrameMessage;
|
|
83
|
+
session_id?: string;
|
|
84
|
+
[k: string]: unknown;
|
|
85
|
+
} | {
|
|
86
|
+
type: "rate_limit_event";
|
|
87
|
+
rate_limit_info?: RateLimitInfo;
|
|
88
|
+
[k: string]: unknown;
|
|
89
|
+
} | ResultFrame | {
|
|
90
|
+
type: string;
|
|
91
|
+
[k: string]: unknown;
|
|
92
|
+
};
|
|
93
|
+
export interface RateLimitInfo {
|
|
94
|
+
status?: string;
|
|
95
|
+
resetsAt?: number;
|
|
96
|
+
rateLimitType?: string;
|
|
97
|
+
overageStatus?: string;
|
|
98
|
+
overageDisabledReason?: string;
|
|
99
|
+
isUsingOverage?: boolean;
|
|
100
|
+
[k: string]: unknown;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Parse a single stdout line into a typed frame, or `null` for a blank or
|
|
104
|
+
* unparseable line (never throws — a stray non-JSON diagnostic line must not
|
|
105
|
+
* abort the turn). The CLI occasionally prefixes debug text on stderr, but on
|
|
106
|
+
* stdout with `--output-format stream-json` every meaningful line is a JSON
|
|
107
|
+
* object; anything else is skipped.
|
|
108
|
+
*/
|
|
109
|
+
export declare function parseClaudeCliLine(line: string): ClaudeCliFrame | null;
|
|
110
|
+
/** Extract the session id from any frame that carries one (system/result/stream). */
|
|
111
|
+
export declare function frameSessionId(frame: ClaudeCliFrame): string | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Classify the terminal `result` frame. Returns:
|
|
114
|
+
* - "success" — a normal completion.
|
|
115
|
+
* - "limit" — a plan-usage / overage rejection ("out of extra usage",
|
|
116
|
+
* usage-limit reached). Callers map this to the
|
|
117
|
+
* subscription_limit retry reason.
|
|
118
|
+
* - "auth" — the login is dead: expired/revoked token, needs re-auth.
|
|
119
|
+
* Callers surface a "re-run `brigade login claude-cli`" hint.
|
|
120
|
+
* - "error" — any other failure subtype.
|
|
121
|
+
* Pure — inspects subtype + is_error + any embedded message text.
|
|
122
|
+
*/
|
|
123
|
+
export declare function classifyResultFrame(frame: ResultFrame): "success" | "limit" | "auth" | "error";
|
|
124
|
+
/** Sum an Anthropic usage block into {input,output} totals (cache folded into input). */
|
|
125
|
+
export declare function foldUsage(usage: AnthropicUsage | undefined): {
|
|
126
|
+
input: number;
|
|
127
|
+
output: number;
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=stream-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-json.d.ts","sourceRoot":"","sources":["../../../src/agents/claude-cli/stream-json.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Wire types + a line parser for the Claude Code CLI's `--output-format
|
|
2
|
+
// stream-json --include-partial-messages --verbose` protocol.
|
|
3
|
+
//
|
|
4
|
+
// The CLI emits one JSON object per line (NDJSON) on stdout. The frames we
|
|
5
|
+
// care about, in the order a normal turn produces them:
|
|
6
|
+
//
|
|
7
|
+
// {"type":"system","subtype":"init", ...} — session bootstrap (carries session_id)
|
|
8
|
+
// {"type":"stream_event","event":{...}} — a raw Anthropic SSE event (partial streaming)
|
|
9
|
+
// {"type":"assistant","message":{...}} — a COMPLETE assistant message block
|
|
10
|
+
// {"type":"rate_limit_event","rate_limit_info":{}} — plan-window telemetry (informational)
|
|
11
|
+
// {"type":"result","subtype":"success"|"error_*",} — terminal frame (final text, usage, cost)
|
|
12
|
+
//
|
|
13
|
+
// The `stream_event.event` payloads are the SAME shapes the Anthropic
|
|
14
|
+
// Messages streaming API emits (message_start / content_block_start /
|
|
15
|
+
// content_block_delta / content_block_stop / message_delta / message_stop),
|
|
16
|
+
// so the delta handling in `stream.ts` mirrors pi-ai's own anthropic
|
|
17
|
+
// provider. When partial frames are unavailable we fall back to the whole
|
|
18
|
+
// `assistant`/`result` message — the parser surfaces both so the consumer
|
|
19
|
+
// can degrade gracefully.
|
|
20
|
+
/* ─────────────────────────── line parser ─────────────────────────── */
|
|
21
|
+
/**
|
|
22
|
+
* Parse a single stdout line into a typed frame, or `null` for a blank or
|
|
23
|
+
* unparseable line (never throws — a stray non-JSON diagnostic line must not
|
|
24
|
+
* abort the turn). The CLI occasionally prefixes debug text on stderr, but on
|
|
25
|
+
* stdout with `--output-format stream-json` every meaningful line is a JSON
|
|
26
|
+
* object; anything else is skipped.
|
|
27
|
+
*/
|
|
28
|
+
export function parseClaudeCliLine(line) {
|
|
29
|
+
const trimmed = line.trim();
|
|
30
|
+
if (!trimmed || trimmed[0] !== "{")
|
|
31
|
+
return null;
|
|
32
|
+
try {
|
|
33
|
+
const obj = JSON.parse(trimmed);
|
|
34
|
+
if (!obj || typeof obj !== "object" || typeof obj.type !== "string")
|
|
35
|
+
return null;
|
|
36
|
+
return obj;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/* ─────────────────────────── frame helpers ─────────────────────────── */
|
|
43
|
+
/** Extract the session id from any frame that carries one (system/result/stream). */
|
|
44
|
+
export function frameSessionId(frame) {
|
|
45
|
+
const sid = frame.session_id;
|
|
46
|
+
return typeof sid === "string" && sid.length > 0 ? sid : undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Classify the terminal `result` frame. Returns:
|
|
50
|
+
* - "success" — a normal completion.
|
|
51
|
+
* - "limit" — a plan-usage / overage rejection ("out of extra usage",
|
|
52
|
+
* usage-limit reached). Callers map this to the
|
|
53
|
+
* subscription_limit retry reason.
|
|
54
|
+
* - "auth" — the login is dead: expired/revoked token, needs re-auth.
|
|
55
|
+
* Callers surface a "re-run `brigade login claude-cli`" hint.
|
|
56
|
+
* - "error" — any other failure subtype.
|
|
57
|
+
* Pure — inspects subtype + is_error + any embedded message text.
|
|
58
|
+
*/
|
|
59
|
+
export function classifyResultFrame(frame) {
|
|
60
|
+
const isError = frame.is_error === true || (frame.subtype ?? "").startsWith("error");
|
|
61
|
+
if (!isError && (frame.subtype === "success" || frame.subtype === undefined))
|
|
62
|
+
return "success";
|
|
63
|
+
const text = `${frame.subtype ?? ""} ${frame.error ?? ""} ${frame.message ?? ""} ${frame.result ?? ""}`;
|
|
64
|
+
if (/out of extra usage|usage limit|claude\.ai\/settings\/usage|limit will reset/i.test(text)) {
|
|
65
|
+
return "limit";
|
|
66
|
+
}
|
|
67
|
+
// Dead-login signals: the binary's own login has expired/been revoked and it
|
|
68
|
+
// can't refresh headlessly. Distinct from a usage limit — the fix is re-auth,
|
|
69
|
+
// not waiting for a reset.
|
|
70
|
+
if (/\b401\b|unauthori[sz]ed|authenticat(?:e|ion)|invalid[_ ]grant|token (?:expired|revoked|invalid)|refresh[_ ]token|(?:please )?(?:re-?)?login|not (?:logged|signed) in|run `?claude`? login|session (?:expired|invalid)/i.test(text)) {
|
|
71
|
+
return "auth";
|
|
72
|
+
}
|
|
73
|
+
return isError ? "error" : "success";
|
|
74
|
+
}
|
|
75
|
+
/** Sum an Anthropic usage block into {input,output} totals (cache folded into input). */
|
|
76
|
+
export function foldUsage(usage) {
|
|
77
|
+
if (!usage)
|
|
78
|
+
return { input: 0, output: 0 };
|
|
79
|
+
const input = (usage.input_tokens ?? 0) +
|
|
80
|
+
(usage.cache_read_input_tokens ?? 0) +
|
|
81
|
+
(usage.cache_creation_input_tokens ?? 0);
|
|
82
|
+
return { input, output: usage.output_tokens ?? 0 };
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=stream-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-json.js","sourceRoot":"","sources":["../../../src/agents/claude-cli/stream-json.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,8DAA8D;AAC9D,EAAE;AACF,2EAA2E;AAC3E,wDAAwD;AACxD,EAAE;AACF,8FAA8F;AAC9F,qGAAqG;AACrG,0FAA0F;AAC1F,6FAA6F;AAC7F,gGAAgG;AAChG,EAAE;AACF,sEAAsE;AACtE,sEAAsE;AACtE,4EAA4E;AAC5E,qEAAqE;AACrE,0EAA0E;AAC1E,0EAA0E;AAC1E,0BAA0B;AAkG1B,yEAAyE;AAEzE;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;QAClD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACjF,OAAO,GAAG,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,2EAA2E;AAE3E,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAC,KAAqB;IACnD,MAAM,GAAG,GAAI,KAAkC,CAAC,UAAU,CAAC;IAC3D,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACpE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAkB;IACrD,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACrF,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/F,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;IACxG,IAAI,8EAA8E,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/F,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,6EAA6E;IAC7E,8EAA8E;IAC9E,2BAA2B;IAC3B,IACC,wNAAwN,CAAC,IAAI,CAC5N,IAAI,CACJ,EACA,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,KAAiC;IAC1D,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC3C,MAAM,KAAK,GACV,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC;QACzB,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC;QACpC,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,aAAa,IAAI,CAAC,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { StreamFn } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import { type SpawnClaudeCliArgs } from "./spawn.js";
|
|
3
|
+
interface CtxMessage {
|
|
4
|
+
role: string;
|
|
5
|
+
content: unknown;
|
|
6
|
+
toolName?: unknown;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Serialize the conversation into a single stdin prompt. The current (final)
|
|
10
|
+
* user message is the live request; everything before it is rendered as a
|
|
11
|
+
* labelled transcript so the CLI has the multi-turn context Brigade would
|
|
12
|
+
* otherwise pass as a messages array. The system prompt travels separately via
|
|
13
|
+
* `--append-system-prompt`, so it's not duplicated here.
|
|
14
|
+
*/
|
|
15
|
+
export declare function serializeConversationPrompt(messages: CtxMessage[]): string;
|
|
16
|
+
export interface CreateClaudeCliStreamFnOpts {
|
|
17
|
+
/** Injectable spawn for tests. */
|
|
18
|
+
spawnFn?: SpawnClaudeCliArgs["spawnFn"];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build the Pi `StreamFn` for claude-cli models. Reads `model`, `context`
|
|
22
|
+
* (systemPrompt + messages), and `options` (signal), spawns the CLI, and fills
|
|
23
|
+
* the returned event stream from the parsed frames.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createClaudeCliStreamFn(opts?: CreateClaudeCliStreamFnOpts): StreamFn;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/agents/claude-cli/stream.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAG9D,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAWrE,UAAU,UAAU;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAqBD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CA2B1E;AA8DD,MAAM,WAAW,2BAA2B;IAC3C,kCAAkC;IAClC,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,2BAAgC,GAAG,QAAQ,CAiPxF"}
|