@founderos/runner 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/dist/api.d.ts +137 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +148 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +182 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +68 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +42 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +237 -0
- package/dist/main.js.map +1 -0
- package/dist/spawn.d.ts +86 -0
- package/dist/spawn.d.ts.map +1 -0
- package/dist/spawn.js +264 -0
- package/dist/spawn.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +48 -0
package/dist/spawn.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn `claude` CLI for a claimed runner job. Streams stream-json from
|
|
3
|
+
* stdout, parses each line into a typed event, and emits events via the
|
|
4
|
+
* caller's `onEvent` callback. The caller is responsible for batching and
|
|
5
|
+
* shipping events back to the cloud (see api.ts appendEvents).
|
|
6
|
+
*
|
|
7
|
+
* Why we don't use `claude --output-format=stream-json` for everything:
|
|
8
|
+
* `claude --print -` accepts the prompt on stdin and writes mixed stdout —
|
|
9
|
+
* stream-json events when `--output-format=stream-json` is set, plain text
|
|
10
|
+
* otherwise. We always set stream-json so parsing is uniform. Lines that
|
|
11
|
+
* fail JSON.parse are surfaced as `stdout_line` raw text events (so noisy
|
|
12
|
+
* stderr output from claude's setup phase is still visible to ops).
|
|
13
|
+
*
|
|
14
|
+
* Result extraction: the LAST `claude_result` event (kind `result` in
|
|
15
|
+
* stream-json terms) carries the cost + sessionId. We snapshot it so the
|
|
16
|
+
* caller can read it after the child exits.
|
|
17
|
+
*/
|
|
18
|
+
import { spawn } from "node:child_process";
|
|
19
|
+
import { type RunnerEvent } from "./api.js";
|
|
20
|
+
export interface SpawnArgs {
|
|
21
|
+
binary: string;
|
|
22
|
+
prompt: string;
|
|
23
|
+
sessionId?: string | null;
|
|
24
|
+
model?: string | null;
|
|
25
|
+
maxTurns?: number | null;
|
|
26
|
+
/** Base64 contents of the agent's append-system-prompt file. */
|
|
27
|
+
instructionsBase64?: string | null;
|
|
28
|
+
/** Hard timeout — if claude doesn't exit by then, we SIGTERM then SIGKILL. */
|
|
29
|
+
timeoutSec: number;
|
|
30
|
+
/** Working directory for the spawned claude. Defaults to cwd. */
|
|
31
|
+
cwd?: string;
|
|
32
|
+
/** Optional --add-dir entries the cloud suggested. */
|
|
33
|
+
addDirs?: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface SpawnResult {
|
|
36
|
+
exitCode: number;
|
|
37
|
+
signal: string | null;
|
|
38
|
+
elapsedSec: number;
|
|
39
|
+
/** True iff we killed the process due to the timeout. */
|
|
40
|
+
timedOut: boolean;
|
|
41
|
+
/** Captured `result` event from stream-json — null if claude never emitted one. */
|
|
42
|
+
finalResult: {
|
|
43
|
+
sessionId?: string | null;
|
|
44
|
+
costUsd?: number | null;
|
|
45
|
+
raw: Record<string, unknown>;
|
|
46
|
+
} | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build the claude CLI argv. Kept pure so it's unit-testable without
|
|
50
|
+
* actually spawning a child.
|
|
51
|
+
*/
|
|
52
|
+
export declare function buildClaudeArgs(args: {
|
|
53
|
+
sessionId?: string | null;
|
|
54
|
+
model?: string | null;
|
|
55
|
+
maxTurns?: number | null;
|
|
56
|
+
instructionsFilePath?: string | null;
|
|
57
|
+
addDirs?: string[];
|
|
58
|
+
}): string[];
|
|
59
|
+
/**
|
|
60
|
+
* Parse one line of claude stream-json into a RunnerEvent. The mapping
|
|
61
|
+
* follows ADR-011 § "Event taxonomy":
|
|
62
|
+
* - `assistant` / `user` messages → claude_message
|
|
63
|
+
* - `tool_use` blocks → claude_tool_use
|
|
64
|
+
* - `tool_result` blocks → claude_tool_result
|
|
65
|
+
* - `result` (final stats) → claude_result
|
|
66
|
+
* - anything else → stdout_line (raw)
|
|
67
|
+
*/
|
|
68
|
+
export declare function parseStreamJsonLine(line: string): RunnerEvent | null;
|
|
69
|
+
/**
|
|
70
|
+
* Materialize the base64 instructions blob to a tempfile so claude can
|
|
71
|
+
* `--append-system-prompt-file` it. Returns the path; caller is responsible
|
|
72
|
+
* for cleanup (we surface the cleanup function to keep this composable).
|
|
73
|
+
*/
|
|
74
|
+
export declare function materializeInstructions(base64: string): Promise<{
|
|
75
|
+
path: string;
|
|
76
|
+
cleanup: () => Promise<void>;
|
|
77
|
+
}>;
|
|
78
|
+
/**
|
|
79
|
+
* Run claude end-to-end. Streams events, enforces timeout, returns the
|
|
80
|
+
* captured final result. Tests can substitute `spawnImpl` to run a mock
|
|
81
|
+
* binary that prints scripted stream-json.
|
|
82
|
+
*/
|
|
83
|
+
export declare function runClaude(args: SpawnArgs, hooks: {
|
|
84
|
+
onEvent: (evt: RunnerEvent) => void | Promise<void>;
|
|
85
|
+
}, spawnImpl?: typeof spawn): Promise<SpawnResult>;
|
|
86
|
+
//# sourceMappingURL=spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../src/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAO9D,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,mFAAmF;IACnF,WAAW,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1G;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,MAAM,EAAE,CAkBX;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAmEpE;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAezD;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,SAAS,EACf,KAAK,EAAE;IACL,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD,EACD,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,WAAW,CAAC,CAwHtB"}
|
package/dist/spawn.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn `claude` CLI for a claimed runner job. Streams stream-json from
|
|
3
|
+
* stdout, parses each line into a typed event, and emits events via the
|
|
4
|
+
* caller's `onEvent` callback. The caller is responsible for batching and
|
|
5
|
+
* shipping events back to the cloud (see api.ts appendEvents).
|
|
6
|
+
*
|
|
7
|
+
* Why we don't use `claude --output-format=stream-json` for everything:
|
|
8
|
+
* `claude --print -` accepts the prompt on stdin and writes mixed stdout —
|
|
9
|
+
* stream-json events when `--output-format=stream-json` is set, plain text
|
|
10
|
+
* otherwise. We always set stream-json so parsing is uniform. Lines that
|
|
11
|
+
* fail JSON.parse are surfaced as `stdout_line` raw text events (so noisy
|
|
12
|
+
* stderr output from claude's setup phase is still visible to ops).
|
|
13
|
+
*
|
|
14
|
+
* Result extraction: the LAST `claude_result` event (kind `result` in
|
|
15
|
+
* stream-json terms) carries the cost + sessionId. We snapshot it so the
|
|
16
|
+
* caller can read it after the child exits.
|
|
17
|
+
*/
|
|
18
|
+
import { spawn } from "node:child_process";
|
|
19
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
20
|
+
import { writeFile, mkdtemp, rm } from "node:fs/promises";
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
import os from "node:os";
|
|
23
|
+
import { performance } from "node:perf_hooks";
|
|
24
|
+
import { makeEventId } from "./api.js";
|
|
25
|
+
/**
|
|
26
|
+
* Build the claude CLI argv. Kept pure so it's unit-testable without
|
|
27
|
+
* actually spawning a child.
|
|
28
|
+
*/
|
|
29
|
+
export function buildClaudeArgs(args) {
|
|
30
|
+
const argv = ["--print", "-", "--output-format", "stream-json", "--verbose"];
|
|
31
|
+
if (args.sessionId) {
|
|
32
|
+
argv.push("--resume", args.sessionId);
|
|
33
|
+
}
|
|
34
|
+
if (args.model) {
|
|
35
|
+
argv.push("--model", args.model);
|
|
36
|
+
}
|
|
37
|
+
if (typeof args.maxTurns === "number" && args.maxTurns > 0) {
|
|
38
|
+
argv.push("--max-turns", String(args.maxTurns));
|
|
39
|
+
}
|
|
40
|
+
if (args.instructionsFilePath) {
|
|
41
|
+
argv.push("--append-system-prompt-file", args.instructionsFilePath);
|
|
42
|
+
}
|
|
43
|
+
for (const dir of args.addDirs ?? []) {
|
|
44
|
+
argv.push("--add-dir", dir);
|
|
45
|
+
}
|
|
46
|
+
return argv;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse one line of claude stream-json into a RunnerEvent. The mapping
|
|
50
|
+
* follows ADR-011 § "Event taxonomy":
|
|
51
|
+
* - `assistant` / `user` messages → claude_message
|
|
52
|
+
* - `tool_use` blocks → claude_tool_use
|
|
53
|
+
* - `tool_result` blocks → claude_tool_result
|
|
54
|
+
* - `result` (final stats) → claude_result
|
|
55
|
+
* - anything else → stdout_line (raw)
|
|
56
|
+
*/
|
|
57
|
+
export function parseStreamJsonLine(line) {
|
|
58
|
+
const trimmed = line.trim();
|
|
59
|
+
if (!trimmed)
|
|
60
|
+
return null;
|
|
61
|
+
// Try strict JSON first.
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = JSON.parse(trimmed);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return {
|
|
68
|
+
eventId: makeEventId(),
|
|
69
|
+
kind: "stdout_line",
|
|
70
|
+
ts: new Date().toISOString(),
|
|
71
|
+
payload: trimmed,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (!parsed || typeof parsed !== "object") {
|
|
75
|
+
return {
|
|
76
|
+
eventId: makeEventId(),
|
|
77
|
+
kind: "stdout_line",
|
|
78
|
+
ts: new Date().toISOString(),
|
|
79
|
+
payload: trimmed,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const obj = parsed;
|
|
83
|
+
const type = typeof obj.type === "string" ? obj.type : "";
|
|
84
|
+
if (type === "result") {
|
|
85
|
+
return {
|
|
86
|
+
eventId: makeEventId(),
|
|
87
|
+
kind: "claude_result",
|
|
88
|
+
ts: new Date().toISOString(),
|
|
89
|
+
payload: obj,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (type === "assistant" || type === "user" || type === "system") {
|
|
93
|
+
return {
|
|
94
|
+
eventId: makeEventId(),
|
|
95
|
+
kind: "claude_message",
|
|
96
|
+
ts: new Date().toISOString(),
|
|
97
|
+
payload: obj,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (type === "tool_use") {
|
|
101
|
+
return {
|
|
102
|
+
eventId: makeEventId(),
|
|
103
|
+
kind: "claude_tool_use",
|
|
104
|
+
ts: new Date().toISOString(),
|
|
105
|
+
payload: obj,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (type === "tool_result") {
|
|
109
|
+
return {
|
|
110
|
+
eventId: makeEventId(),
|
|
111
|
+
kind: "claude_tool_result",
|
|
112
|
+
ts: new Date().toISOString(),
|
|
113
|
+
payload: obj,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
eventId: makeEventId(),
|
|
118
|
+
kind: "stdout_line",
|
|
119
|
+
ts: new Date().toISOString(),
|
|
120
|
+
payload: obj,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Materialize the base64 instructions blob to a tempfile so claude can
|
|
125
|
+
* `--append-system-prompt-file` it. Returns the path; caller is responsible
|
|
126
|
+
* for cleanup (we surface the cleanup function to keep this composable).
|
|
127
|
+
*/
|
|
128
|
+
export async function materializeInstructions(base64) {
|
|
129
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "founderos-runner-"));
|
|
130
|
+
const filePath = path.join(dir, "instructions.md");
|
|
131
|
+
const buf = Buffer.from(base64, "base64");
|
|
132
|
+
await writeFile(filePath, buf);
|
|
133
|
+
return {
|
|
134
|
+
path: filePath,
|
|
135
|
+
cleanup: async () => {
|
|
136
|
+
try {
|
|
137
|
+
await rm(dir, { recursive: true, force: true });
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
/* best-effort */
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Run claude end-to-end. Streams events, enforces timeout, returns the
|
|
147
|
+
* captured final result. Tests can substitute `spawnImpl` to run a mock
|
|
148
|
+
* binary that prints scripted stream-json.
|
|
149
|
+
*/
|
|
150
|
+
export async function runClaude(args, hooks, spawnImpl = spawn) {
|
|
151
|
+
let cleanup = null;
|
|
152
|
+
let instructionsPath = null;
|
|
153
|
+
if (args.instructionsBase64) {
|
|
154
|
+
const m = await materializeInstructions(args.instructionsBase64);
|
|
155
|
+
instructionsPath = m.path;
|
|
156
|
+
cleanup = m.cleanup;
|
|
157
|
+
}
|
|
158
|
+
const argv = buildClaudeArgs({
|
|
159
|
+
sessionId: args.sessionId,
|
|
160
|
+
model: args.model,
|
|
161
|
+
maxTurns: args.maxTurns,
|
|
162
|
+
instructionsFilePath: instructionsPath,
|
|
163
|
+
addDirs: args.addDirs,
|
|
164
|
+
});
|
|
165
|
+
const startedAt = performance.now();
|
|
166
|
+
const child = spawnImpl(args.binary, argv, {
|
|
167
|
+
cwd: args.cwd,
|
|
168
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
169
|
+
env: process.env,
|
|
170
|
+
});
|
|
171
|
+
let timedOut = false;
|
|
172
|
+
let finalResult = null;
|
|
173
|
+
// Hard kill after 1.5x timeout if SIGTERM didn't land.
|
|
174
|
+
const termTimer = setTimeout(() => {
|
|
175
|
+
timedOut = true;
|
|
176
|
+
if (!child.killed)
|
|
177
|
+
child.kill("SIGTERM");
|
|
178
|
+
}, args.timeoutSec * 1000);
|
|
179
|
+
const killTimer = setTimeout(() => {
|
|
180
|
+
if (!child.killed)
|
|
181
|
+
child.kill("SIGKILL");
|
|
182
|
+
}, args.timeoutSec * 1000 * 1.5);
|
|
183
|
+
// stdin: write the prompt then close.
|
|
184
|
+
if (child.stdin) {
|
|
185
|
+
child.stdin.write(args.prompt);
|
|
186
|
+
child.stdin.end();
|
|
187
|
+
}
|
|
188
|
+
// Line-buffer stdout. claude emits one JSON object per line in
|
|
189
|
+
// stream-json mode; partial lines accumulate until the next \n.
|
|
190
|
+
let stdoutBuf = "";
|
|
191
|
+
child.stdout?.setEncoding("utf-8");
|
|
192
|
+
child.stdout?.on("data", (chunk) => {
|
|
193
|
+
stdoutBuf += chunk;
|
|
194
|
+
let nl;
|
|
195
|
+
while ((nl = stdoutBuf.indexOf("\n")) >= 0) {
|
|
196
|
+
const line = stdoutBuf.slice(0, nl);
|
|
197
|
+
stdoutBuf = stdoutBuf.slice(nl + 1);
|
|
198
|
+
const evt = parseStreamJsonLine(line);
|
|
199
|
+
if (!evt)
|
|
200
|
+
continue;
|
|
201
|
+
if (evt.kind === "claude_result" && typeof evt.payload === "object" && evt.payload) {
|
|
202
|
+
const p = evt.payload;
|
|
203
|
+
finalResult = {
|
|
204
|
+
sessionId: typeof p.session_id === "string" ? p.session_id : null,
|
|
205
|
+
costUsd: typeof p.total_cost_usd === "number" ? p.total_cost_usd : null,
|
|
206
|
+
raw: p,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
void hooks.onEvent(evt);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
// stderr: surface as raw stderr_line events. Don't try to parse —
|
|
213
|
+
// claude's stderr is human-readable diagnostics, not stream-json.
|
|
214
|
+
let stderrBuf = "";
|
|
215
|
+
child.stderr?.setEncoding("utf-8");
|
|
216
|
+
child.stderr?.on("data", (chunk) => {
|
|
217
|
+
stderrBuf += chunk;
|
|
218
|
+
let nl;
|
|
219
|
+
while ((nl = stderrBuf.indexOf("\n")) >= 0) {
|
|
220
|
+
const line = stderrBuf.slice(0, nl);
|
|
221
|
+
stderrBuf = stderrBuf.slice(nl + 1);
|
|
222
|
+
if (!line.trim())
|
|
223
|
+
continue;
|
|
224
|
+
void hooks.onEvent({
|
|
225
|
+
eventId: makeEventId(),
|
|
226
|
+
kind: "stderr_line",
|
|
227
|
+
ts: new Date().toISOString(),
|
|
228
|
+
payload: line,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
const exit = await new Promise((resolve) => {
|
|
233
|
+
child.once("exit", (code, signal) => resolve({ code: code ?? -1, signal }));
|
|
234
|
+
child.once("error", () => resolve({ code: -1, signal: null }));
|
|
235
|
+
});
|
|
236
|
+
// Drain any trailing partial line.
|
|
237
|
+
if (stdoutBuf.trim()) {
|
|
238
|
+
const evt = parseStreamJsonLine(stdoutBuf);
|
|
239
|
+
if (evt)
|
|
240
|
+
await hooks.onEvent(evt);
|
|
241
|
+
}
|
|
242
|
+
if (stderrBuf.trim()) {
|
|
243
|
+
await hooks.onEvent({
|
|
244
|
+
eventId: makeEventId(),
|
|
245
|
+
kind: "stderr_line",
|
|
246
|
+
ts: new Date().toISOString(),
|
|
247
|
+
payload: stderrBuf,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
clearTimeout(termTimer);
|
|
251
|
+
clearTimeout(killTimer);
|
|
252
|
+
if (cleanup)
|
|
253
|
+
await cleanup();
|
|
254
|
+
// Tiny sleep to let any straggler stream events flush through onEvent.
|
|
255
|
+
await sleep(10);
|
|
256
|
+
return {
|
|
257
|
+
exitCode: exit.code,
|
|
258
|
+
signal: exit.signal,
|
|
259
|
+
elapsedSec: (performance.now() - startedAt) / 1000,
|
|
260
|
+
timedOut,
|
|
261
|
+
finalResult,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../src/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAoB,MAAM,UAAU,CAAC;AA4BzD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAM/B;IACC,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IAC7E,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,6BAA6B,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACtE,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,yBAAyB;IACzB,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,WAAW,EAAE;YACtB,IAAI,EAAE,aAAa;YACnB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO,EAAE,OAAO;SACjB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO;YACL,OAAO,EAAE,WAAW,EAAE;YACtB,IAAI,EAAE,aAAa;YACnB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO,EAAE,OAAO;SACjB,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1D,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,WAAW,EAAE;YACtB,IAAI,EAAE,eAAe;YACrB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO,EAAE,GAAG;SACb,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO;YACL,OAAO,EAAE,WAAW,EAAE;YACtB,IAAI,EAAE,gBAAgB;YACtB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO,EAAE,GAAG;SACb,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,WAAW,EAAE;YACtB,IAAI,EAAE,iBAAiB;YACvB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO,EAAE,GAAG;SACb,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,WAAW,EAAE;YACtB,IAAI,EAAE,oBAAoB;YAC1B,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO,EAAE,GAAG;SACb,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,WAAW,EAAE;QACtB,IAAI,EAAE,aAAa;QACnB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,OAAO,EAAE,GAAG;KACb,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAc;IAEd,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC/B,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC;gBACP,iBAAiB;YACnB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAe,EACf,KAEC,EACD,YAA0B,KAAK;IAE/B,IAAI,OAAO,GAAiC,IAAI,CAAC;IACjD,IAAI,gBAAgB,GAAkB,IAAI,CAAC;IAE3C,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjE,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;QAC1B,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,MAAM,IAAI,GAAG,eAAe,CAAC;QAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,oBAAoB,EAAE,gBAAgB;QACtC,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,KAAK,GAAiB,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;QACvD,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,WAAW,GAA+B,IAAI,CAAC;IAEnD,uDAAuD;IACvD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;QAChC,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC,EAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC3B,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;QAChC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC,EAAE,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;IAEjC,sCAAsC;IACtC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,+DAA+D;IAC/D,gEAAgE;IAChE,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACzC,SAAS,IAAI,KAAK,CAAC;QACnB,IAAI,EAAU,CAAC;QACf,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,IAAI,GAAG,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBACnF,MAAM,CAAC,GAAG,GAAG,CAAC,OAAkC,CAAC;gBACjD,WAAW,GAAG;oBACZ,SAAS,EAAE,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;oBACjE,OAAO,EAAE,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI;oBACvE,GAAG,EAAE,CAAC;iBACP,CAAC;YACJ,CAAC;YACD,KAAK,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,kEAAkE;IAClE,kEAAkE;IAClE,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACzC,SAAS,IAAI,KAAK,CAAC;QACnB,IAAI,EAAU,CAAC;QACf,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,KAAK,KAAK,CAAC,OAAO,CAAC;gBACjB,OAAO,EAAE,WAAW,EAAE;gBACtB,IAAI,EAAE,aAAa;gBACnB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBAC5B,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,IAAI,OAAO,CAAkD,CAAC,OAAO,EAAE,EAAE;QAC1F,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5E,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,GAAG;YAAE,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACrB,MAAM,KAAK,CAAC,OAAO,CAAC;YAClB,OAAO,EAAE,WAAW,EAAE;YACtB,IAAI,EAAE,aAAa;YACnB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;IACL,CAAC;IAED,YAAY,CAAC,SAAS,CAAC,CAAC;IACxB,YAAY,CAAC,SAAS,CAAC,CAAC;IACxB,IAAI,OAAO;QAAE,MAAM,OAAO,EAAE,CAAC;IAE7B,uEAAuE;IACvE,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,IAAI;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI;QAClD,QAAQ;QACR,WAAW;KACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Sourced from package.json at install time. Bumping this should match a
|
|
2
|
+
// `npm version` so the runner identifies itself accurately to the cloud
|
|
3
|
+
// (used in `cliVersion` field of /jobs/:id/complete).
|
|
4
|
+
export const RUNNER_VERSION = "0.1.1";
|
|
5
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,wEAAwE;AACxE,sDAAsD;AACtD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@founderos/runner",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "FounderOS local runner — polls cloud, spawns claude CLI under your Pro session, streams events back. ADR-011.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://github.com/founderos-ai/founderos",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/founderos-ai/founderos/issues"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/founderos-ai/founderos",
|
|
13
|
+
"directory": "packages/runner"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"bin": {
|
|
17
|
+
"founderos-runner": "./dist/cli.js"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc",
|
|
35
|
+
"clean": "rm -rf dist",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^24.6.0",
|
|
45
|
+
"typescript": "^5.7.3",
|
|
46
|
+
"vitest": "^3.2.4"
|
|
47
|
+
}
|
|
48
|
+
}
|