@schilderlabs/pitown-core 0.2.1 → 0.2.7

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.
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,236 @@
1
+ import { A as getLatestAgentSession, C as createAgentState, F as writeAgentState, P as readAgentState, S as createAgentSessionRecord, h as updateTaskRecordStatus, o as resumeAgentTurnDetached, r as notifyTaskDelegator, w as getAgentDir, x as appendAgentMessage } from "./orchestration-D6XeSl8s.mjs";
2
+ import { createWriteStream, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
+ import { spawn } from "node:child_process";
4
+ import { finished } from "node:stream/promises";
5
+
6
+ //#region src/agent-runner.ts
7
+ async function waitForChild(child) {
8
+ return new Promise((resolve) => {
9
+ let error = null;
10
+ child.once("error", (value) => {
11
+ error = value;
12
+ });
13
+ child.once("close", (code) => {
14
+ resolve({
15
+ exitCode: code ?? 1,
16
+ error
17
+ });
18
+ });
19
+ });
20
+ }
21
+ async function runDetachedAgent(payload) {
22
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
23
+ const agentArtifactsDir = getAgentDir(payload.artifactsDir, payload.agentId);
24
+ const stdoutPath = `${agentArtifactsDir}/latest-stdout.txt`;
25
+ const stderrPath = `${agentArtifactsDir}/latest-stderr.txt`;
26
+ const invocationPath = `${agentArtifactsDir}/latest-invocation.json`;
27
+ mkdirSync(agentArtifactsDir, { recursive: true });
28
+ const stdoutStream = createWriteStream(stdoutPath, { encoding: "utf-8" });
29
+ const stderrStream = createWriteStream(stderrPath, { encoding: "utf-8" });
30
+ const child = spawn("pi", payload.piArgs, {
31
+ cwd: payload.repoRoot,
32
+ env: process.env,
33
+ stdio: [
34
+ "ignore",
35
+ "pipe",
36
+ "pipe"
37
+ ]
38
+ });
39
+ if (child.stdout) child.stdout.pipe(stdoutStream);
40
+ if (child.stderr) child.stderr.pipe(stderrStream);
41
+ const currentState = readAgentState(payload.artifactsDir, payload.agentId);
42
+ if (currentState) writeAgentState(payload.artifactsDir, createAgentState({
43
+ ...currentState,
44
+ status: "running",
45
+ lastMessage: payload.task ? `Running ${payload.role} task: ${payload.task}` : `Running ${payload.role} agent`,
46
+ waitingOn: null,
47
+ blocked: false,
48
+ session: createAgentSessionRecord({
49
+ sessionDir: payload.sessionDir,
50
+ sessionId: currentState.session.sessionId,
51
+ sessionPath: currentState.session.sessionPath,
52
+ processId: child.pid ?? null,
53
+ lastAttachedAt: currentState.session.lastAttachedAt
54
+ })
55
+ }));
56
+ writeFileSync(invocationPath, `${JSON.stringify({
57
+ command: "pi",
58
+ args: payload.piArgs,
59
+ exitCode: null,
60
+ sessionDir: payload.sessionDir,
61
+ sessionPath: null,
62
+ sessionId: null,
63
+ processId: child.pid ?? null,
64
+ startedAt
65
+ }, null, 2)}\n`, "utf-8");
66
+ const { exitCode, error } = await waitForChild(child);
67
+ if (!stdoutStream.writableEnded) stdoutStream.end();
68
+ if (!stderrStream.writableEnded) stderrStream.end();
69
+ await Promise.all([finished(stdoutStream), finished(stderrStream)]);
70
+ const stdout = readFileSync(stdoutPath, "utf-8");
71
+ const stderr = readFileSync(stderrPath, "utf-8");
72
+ const latestSession = getLatestAgentSession(payload.artifactsDir, payload.agentId);
73
+ const completionMessage = stdout.trim() || (error?.message?.trim() ?? "") || (exitCode === 0 ? `${payload.role} run completed` : `${payload.role} run exited with code ${exitCode}`);
74
+ if (error) writeFileSync(stderrPath, `${stderr}${stderr.endsWith("\n") || stderr.length === 0 ? "" : "\n"}${error.message}\n`, "utf-8");
75
+ writeFileSync(invocationPath, `${JSON.stringify({
76
+ command: "pi",
77
+ args: payload.piArgs,
78
+ exitCode,
79
+ sessionDir: latestSession.sessionDir ?? payload.sessionDir,
80
+ sessionPath: latestSession.sessionPath,
81
+ sessionId: latestSession.sessionId,
82
+ processId: child.pid ?? null,
83
+ startedAt,
84
+ endedAt: (/* @__PURE__ */ new Date()).toISOString()
85
+ }, null, 2)}\n`, "utf-8");
86
+ appendAgentMessage({
87
+ artifactsDir: payload.artifactsDir,
88
+ agentId: payload.agentId,
89
+ box: "outbox",
90
+ from: payload.agentId,
91
+ body: completionMessage
92
+ });
93
+ if (payload.taskId) {
94
+ updateTaskRecordStatus(payload.artifactsDir, payload.taskId, exitCode === 0 ? "completed" : "blocked");
95
+ notifyTaskDelegator({
96
+ artifactsDir: payload.artifactsDir,
97
+ agentId: payload.agentId,
98
+ taskId: payload.taskId,
99
+ completionMessage,
100
+ outcome: exitCode === 0 ? "completed" : "blocked"
101
+ });
102
+ if (payload.autoResumeTarget) resumeAgentTurnDetached({
103
+ repoRoot: payload.repoRoot,
104
+ artifactsDir: payload.artifactsDir,
105
+ agentId: payload.autoResumeTarget.agentId,
106
+ message: payload.autoResumeTarget.message,
107
+ from: payload.agentId,
108
+ appendedSystemPrompt: payload.autoResumeTarget.appendedSystemPrompt,
109
+ extensionPath: payload.autoResumeTarget.extensionPath
110
+ });
111
+ }
112
+ const finalState = readAgentState(payload.artifactsDir, payload.agentId);
113
+ if (finalState) writeAgentState(payload.artifactsDir, createAgentState({
114
+ ...finalState,
115
+ status: exitCode === 0 ? "idle" : "blocked",
116
+ lastMessage: completionMessage,
117
+ waitingOn: exitCode === 0 ? null : "human-or-follow-up-run",
118
+ blocked: exitCode !== 0,
119
+ session: createAgentSessionRecord({
120
+ sessionDir: latestSession.sessionDir ?? payload.sessionDir,
121
+ sessionId: latestSession.sessionId,
122
+ sessionPath: latestSession.sessionPath,
123
+ processId: null,
124
+ lastAttachedAt: finalState.session.lastAttachedAt
125
+ })
126
+ }));
127
+ }
128
+ async function runDetachedTurn(payload) {
129
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
130
+ const agentArtifactsDir = getAgentDir(payload.artifactsDir, payload.agentId);
131
+ const stdoutPath = `${agentArtifactsDir}/latest-stdout.txt`;
132
+ const stderrPath = `${agentArtifactsDir}/latest-stderr.txt`;
133
+ const invocationPath = `${agentArtifactsDir}/latest-invocation.json`;
134
+ mkdirSync(agentArtifactsDir, { recursive: true });
135
+ const stdoutStream = createWriteStream(stdoutPath, { encoding: "utf-8" });
136
+ const stderrStream = createWriteStream(stderrPath, { encoding: "utf-8" });
137
+ const child = spawn("pi", payload.piArgs, {
138
+ cwd: payload.repoRoot,
139
+ env: process.env,
140
+ stdio: [
141
+ "ignore",
142
+ "pipe",
143
+ "pipe"
144
+ ]
145
+ });
146
+ if (child.stdout) child.stdout.pipe(stdoutStream);
147
+ if (child.stderr) child.stderr.pipe(stderrStream);
148
+ const currentState = readAgentState(payload.artifactsDir, payload.agentId);
149
+ if (currentState) writeAgentState(payload.artifactsDir, createAgentState({
150
+ ...currentState,
151
+ status: "running",
152
+ lastMessage: `Responding to ${payload.from}: ${payload.message}`,
153
+ waitingOn: null,
154
+ blocked: false,
155
+ session: createAgentSessionRecord({
156
+ sessionDir: currentState.session.sessionDir,
157
+ sessionId: currentState.session.sessionId,
158
+ sessionPath: currentState.session.sessionPath,
159
+ processId: child.pid ?? null,
160
+ lastAttachedAt: currentState.session.lastAttachedAt
161
+ })
162
+ }));
163
+ writeFileSync(invocationPath, `${JSON.stringify({
164
+ command: "pi",
165
+ args: payload.piArgs,
166
+ exitCode: null,
167
+ sessionDir: currentState?.session.sessionDir ?? null,
168
+ sessionPath: currentState?.session.sessionPath ?? null,
169
+ sessionId: currentState?.session.sessionId ?? null,
170
+ processId: child.pid ?? null,
171
+ startedAt
172
+ }, null, 2)}\n`, "utf-8");
173
+ const { exitCode, error } = await waitForChild(child);
174
+ if (!stdoutStream.writableEnded) stdoutStream.end();
175
+ if (!stderrStream.writableEnded) stderrStream.end();
176
+ await Promise.all([finished(stdoutStream), finished(stderrStream)]);
177
+ const stdout = readFileSync(stdoutPath, "utf-8");
178
+ const stderr = readFileSync(stderrPath, "utf-8");
179
+ const latestSession = getLatestAgentSession(payload.artifactsDir, payload.agentId);
180
+ const completionMessage = stdout.trim() || (error?.message?.trim() ?? "") || (exitCode === 0 ? `${payload.role} turn completed` : `${payload.role} turn exited with code ${exitCode}`);
181
+ if (error) writeFileSync(stderrPath, `${stderr}${stderr.endsWith("\n") || stderr.length === 0 ? "" : "\n"}${error.message}\n`, "utf-8");
182
+ writeFileSync(invocationPath, `${JSON.stringify({
183
+ command: "pi",
184
+ args: payload.piArgs,
185
+ exitCode,
186
+ sessionDir: latestSession.sessionDir,
187
+ sessionPath: latestSession.sessionPath,
188
+ sessionId: latestSession.sessionId,
189
+ processId: child.pid ?? null,
190
+ startedAt,
191
+ endedAt: (/* @__PURE__ */ new Date()).toISOString()
192
+ }, null, 2)}\n`, "utf-8");
193
+ appendAgentMessage({
194
+ artifactsDir: payload.artifactsDir,
195
+ agentId: payload.agentId,
196
+ box: "outbox",
197
+ from: payload.agentId,
198
+ body: completionMessage
199
+ });
200
+ const finalState = readAgentState(payload.artifactsDir, payload.agentId);
201
+ if (finalState) writeAgentState(payload.artifactsDir, createAgentState({
202
+ ...finalState,
203
+ status: exitCode === 0 ? "idle" : "blocked",
204
+ lastMessage: completionMessage,
205
+ waitingOn: exitCode === 0 ? null : "human-or-follow-up-run",
206
+ blocked: exitCode !== 0,
207
+ session: createAgentSessionRecord({
208
+ sessionDir: latestSession.sessionDir,
209
+ sessionId: latestSession.sessionId,
210
+ sessionPath: latestSession.sessionPath,
211
+ processId: null,
212
+ lastAttachedAt: finalState.session.lastAttachedAt
213
+ })
214
+ }));
215
+ try {
216
+ rmSync(payload.wakeLockPath, { force: true });
217
+ } catch {}
218
+ }
219
+ async function main() {
220
+ const [encodedPayload] = process.argv.slice(2);
221
+ if (!encodedPayload) throw new Error("Missing detached agent payload");
222
+ const payload = JSON.parse(Buffer.from(encodedPayload, "base64url").toString("utf-8"));
223
+ if (payload.kind === "turn") {
224
+ await runDetachedTurn(payload);
225
+ return;
226
+ }
227
+ await runDetachedAgent(payload);
228
+ }
229
+ main().catch((error) => {
230
+ console.error(error instanceof Error ? error.stack ?? error.message : String(error));
231
+ process.exitCode = 1;
232
+ });
233
+
234
+ //#endregion
235
+ export { };
236
+ //# sourceMappingURL=agent-runner.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.mjs","names":[],"sources":["../src/agent-runner.ts"],"sourcesContent":["import { spawn } from \"node:child_process\"\nimport { createWriteStream, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\"\nimport { finished } from \"node:stream/promises\"\nimport {\n\tappendAgentMessage,\n\tcreateAgentSessionRecord,\n\tcreateAgentState,\n\tgetAgentDir,\n\tgetLatestAgentSession,\n\treadAgentState,\n\twriteAgentState,\n} from \"./agents.js\"\nimport { notifyTaskDelegator, resumeAgentTurnDetached } from \"./orchestration.js\"\nimport { updateTaskRecordStatus } from \"./tasks.js\"\n\ninterface DetachedAgentRunPayload {\n\tkind?: \"spawn\"\n\trepoRoot: string\n\tartifactsDir: string\n\tagentId: string\n\trole: string\n\ttask: string | null\n\ttaskId: string | null\n\tsessionDir: string\n\tpiArgs: string[]\n\tautoResumeTarget?: {\n\t\tagentId: string\n\t\tmessage: string\n\t\tappendedSystemPrompt?: string | null\n\t\textensionPath?: string | null\n\t} | null\n}\n\ninterface DetachedAgentTurnPayload {\n\tkind: \"turn\"\n\trepoRoot: string\n\tartifactsDir: string\n\tagentId: string\n\trole: string\n\tmessage: string\n\tfrom: string\n\tpiArgs: string[]\n\twakeLockPath: string\n}\n\ninterface ChildCompletion {\n\texitCode: number\n\terror: Error | null\n}\n\nasync function waitForChild(child: ReturnType<typeof spawn>): Promise<ChildCompletion> {\n\treturn new Promise((resolve) => {\n\t\tlet error: Error | null = null\n\t\tchild.once(\"error\", (value) => {\n\t\t\terror = value\n\t\t})\n\t\tchild.once(\"close\", (code) => {\n\t\t\tresolve({\n\t\t\t\texitCode: code ?? 1,\n\t\t\t\terror,\n\t\t\t})\n\t\t})\n\t})\n}\n\nasync function runDetachedAgent(payload: DetachedAgentRunPayload) {\n\tconst startedAt = new Date().toISOString()\n\tconst agentArtifactsDir = getAgentDir(payload.artifactsDir, payload.agentId)\n\tconst stdoutPath = `${agentArtifactsDir}/latest-stdout.txt`\n\tconst stderrPath = `${agentArtifactsDir}/latest-stderr.txt`\n\tconst invocationPath = `${agentArtifactsDir}/latest-invocation.json`\n\tmkdirSync(agentArtifactsDir, { recursive: true })\n\n\tconst stdoutStream = createWriteStream(stdoutPath, { encoding: \"utf-8\" })\n\tconst stderrStream = createWriteStream(stderrPath, { encoding: \"utf-8\" })\n\tconst child = spawn(\"pi\", payload.piArgs, {\n\t\tcwd: payload.repoRoot,\n\t\tenv: process.env,\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t})\n\n\tif (child.stdout) child.stdout.pipe(stdoutStream)\n\tif (child.stderr) child.stderr.pipe(stderrStream)\n\n\tconst currentState = readAgentState(payload.artifactsDir, payload.agentId)\n\tif (currentState) {\n\t\twriteAgentState(\n\t\t\tpayload.artifactsDir,\n\t\t\tcreateAgentState({\n\t\t\t\t...currentState,\n\t\t\t\tstatus: \"running\",\n\t\t\t\tlastMessage: payload.task ? `Running ${payload.role} task: ${payload.task}` : `Running ${payload.role} agent`,\n\t\t\t\twaitingOn: null,\n\t\t\t\tblocked: false,\n\t\t\t\tsession: createAgentSessionRecord({\n\t\t\t\t\tsessionDir: payload.sessionDir,\n\t\t\t\t\tsessionId: currentState.session.sessionId,\n\t\t\t\t\tsessionPath: currentState.session.sessionPath,\n\t\t\t\t\tprocessId: child.pid ?? null,\n\t\t\t\t\tlastAttachedAt: currentState.session.lastAttachedAt,\n\t\t\t\t}),\n\t\t\t}),\n\t\t)\n\t}\n\n\twriteFileSync(\n\t\tinvocationPath,\n\t\t`${JSON.stringify(\n\t\t\t{\n\t\t\t\tcommand: \"pi\",\n\t\t\t\targs: payload.piArgs,\n\t\t\t\texitCode: null,\n\t\t\t\tsessionDir: payload.sessionDir,\n\t\t\t\tsessionPath: null,\n\t\t\t\tsessionId: null,\n\t\t\t\tprocessId: child.pid ?? null,\n\t\t\t\tstartedAt,\n\t\t\t},\n\t\t\tnull,\n\t\t\t2,\n\t\t)}\\n`,\n\t\t\"utf-8\",\n\t)\n\n\tconst { exitCode, error } = await waitForChild(child)\n\tif (!stdoutStream.writableEnded) stdoutStream.end()\n\tif (!stderrStream.writableEnded) stderrStream.end()\n\tawait Promise.all([finished(stdoutStream), finished(stderrStream)])\n\n\tconst stdout = readFileSync(stdoutPath, \"utf-8\")\n\tconst stderr = readFileSync(stderrPath, \"utf-8\")\n\tconst latestSession = getLatestAgentSession(payload.artifactsDir, payload.agentId)\n\tconst completionMessage =\n\t\tstdout.trim() ||\n\t\t(error?.message?.trim() ?? \"\") ||\n\t\t(exitCode === 0 ? `${payload.role} run completed` : `${payload.role} run exited with code ${exitCode}`)\n\n\tif (error) {\n\t\twriteFileSync(stderrPath, `${stderr}${stderr.endsWith(\"\\n\") || stderr.length === 0 ? \"\" : \"\\n\"}${error.message}\\n`, \"utf-8\")\n\t}\n\n\twriteFileSync(\n\t\tinvocationPath,\n\t\t`${JSON.stringify(\n\t\t\t{\n\t\t\t\tcommand: \"pi\",\n\t\t\t\targs: payload.piArgs,\n\t\t\t\texitCode,\n\t\t\t\tsessionDir: latestSession.sessionDir ?? payload.sessionDir,\n\t\t\t\tsessionPath: latestSession.sessionPath,\n\t\t\t\tsessionId: latestSession.sessionId,\n\t\t\t\tprocessId: child.pid ?? null,\n\t\t\t\tstartedAt,\n\t\t\t\tendedAt: new Date().toISOString(),\n\t\t\t},\n\t\t\tnull,\n\t\t\t2,\n\t\t)}\\n`,\n\t\t\"utf-8\",\n\t)\n\n\tappendAgentMessage({\n\t\tartifactsDir: payload.artifactsDir,\n\t\tagentId: payload.agentId,\n\t\tbox: \"outbox\",\n\t\tfrom: payload.agentId,\n\t\tbody: completionMessage,\n\t})\n\n\tif (payload.taskId) {\n\t\tupdateTaskRecordStatus(payload.artifactsDir, payload.taskId, exitCode === 0 ? \"completed\" : \"blocked\")\n\t\tnotifyTaskDelegator({\n\t\t\tartifactsDir: payload.artifactsDir,\n\t\t\tagentId: payload.agentId,\n\t\t\ttaskId: payload.taskId,\n\t\t\tcompletionMessage,\n\t\t\toutcome: exitCode === 0 ? \"completed\" : \"blocked\",\n\t\t})\n\t\tif (payload.autoResumeTarget) {\n\t\t\tresumeAgentTurnDetached({\n\t\t\t\trepoRoot: payload.repoRoot,\n\t\t\t\tartifactsDir: payload.artifactsDir,\n\t\t\t\tagentId: payload.autoResumeTarget.agentId,\n\t\t\t\tmessage: payload.autoResumeTarget.message,\n\t\t\t\tfrom: payload.agentId,\n\t\t\t\tappendedSystemPrompt: payload.autoResumeTarget.appendedSystemPrompt,\n\t\t\t\textensionPath: payload.autoResumeTarget.extensionPath,\n\t\t\t})\n\t\t}\n\t}\n\n\tconst finalState = readAgentState(payload.artifactsDir, payload.agentId)\n\tif (finalState) {\n\t\twriteAgentState(\n\t\t\tpayload.artifactsDir,\n\t\t\tcreateAgentState({\n\t\t\t\t...finalState,\n\t\t\t\tstatus: exitCode === 0 ? \"idle\" : \"blocked\",\n\t\t\t\tlastMessage: completionMessage,\n\t\t\t\twaitingOn: exitCode === 0 ? null : \"human-or-follow-up-run\",\n\t\t\t\tblocked: exitCode !== 0,\n\t\t\t\tsession: createAgentSessionRecord({\n\t\t\t\t\tsessionDir: latestSession.sessionDir ?? payload.sessionDir,\n\t\t\t\t\tsessionId: latestSession.sessionId,\n\t\t\t\t\tsessionPath: latestSession.sessionPath,\n\t\t\t\t\tprocessId: null,\n\t\t\t\t\tlastAttachedAt: finalState.session.lastAttachedAt,\n\t\t\t\t}),\n\t\t\t}),\n\t\t)\n\t}\n}\n\nasync function runDetachedTurn(payload: DetachedAgentTurnPayload) {\n\tconst startedAt = new Date().toISOString()\n\tconst agentArtifactsDir = getAgentDir(payload.artifactsDir, payload.agentId)\n\tconst stdoutPath = `${agentArtifactsDir}/latest-stdout.txt`\n\tconst stderrPath = `${agentArtifactsDir}/latest-stderr.txt`\n\tconst invocationPath = `${agentArtifactsDir}/latest-invocation.json`\n\tmkdirSync(agentArtifactsDir, { recursive: true })\n\n\tconst stdoutStream = createWriteStream(stdoutPath, { encoding: \"utf-8\" })\n\tconst stderrStream = createWriteStream(stderrPath, { encoding: \"utf-8\" })\n\tconst child = spawn(\"pi\", payload.piArgs, {\n\t\tcwd: payload.repoRoot,\n\t\tenv: process.env,\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t})\n\n\tif (child.stdout) child.stdout.pipe(stdoutStream)\n\tif (child.stderr) child.stderr.pipe(stderrStream)\n\n\tconst currentState = readAgentState(payload.artifactsDir, payload.agentId)\n\tif (currentState) {\n\t\twriteAgentState(\n\t\t\tpayload.artifactsDir,\n\t\t\tcreateAgentState({\n\t\t\t\t...currentState,\n\t\t\t\tstatus: \"running\",\n\t\t\t\tlastMessage: `Responding to ${payload.from}: ${payload.message}`,\n\t\t\t\twaitingOn: null,\n\t\t\t\tblocked: false,\n\t\t\t\tsession: createAgentSessionRecord({\n\t\t\t\t\tsessionDir: currentState.session.sessionDir,\n\t\t\t\t\tsessionId: currentState.session.sessionId,\n\t\t\t\t\tsessionPath: currentState.session.sessionPath,\n\t\t\t\t\tprocessId: child.pid ?? null,\n\t\t\t\t\tlastAttachedAt: currentState.session.lastAttachedAt,\n\t\t\t\t}),\n\t\t\t}),\n\t\t)\n\t}\n\n\twriteFileSync(\n\t\tinvocationPath,\n\t\t`${JSON.stringify(\n\t\t\t{\n\t\t\t\tcommand: \"pi\",\n\t\t\t\targs: payload.piArgs,\n\t\t\t\texitCode: null,\n\t\t\t\tsessionDir: currentState?.session.sessionDir ?? null,\n\t\t\t\tsessionPath: currentState?.session.sessionPath ?? null,\n\t\t\t\tsessionId: currentState?.session.sessionId ?? null,\n\t\t\t\tprocessId: child.pid ?? null,\n\t\t\t\tstartedAt,\n\t\t\t},\n\t\t\tnull,\n\t\t\t2,\n\t\t)}\\n`,\n\t\t\"utf-8\",\n\t)\n\n\tconst { exitCode, error } = await waitForChild(child)\n\tif (!stdoutStream.writableEnded) stdoutStream.end()\n\tif (!stderrStream.writableEnded) stderrStream.end()\n\tawait Promise.all([finished(stdoutStream), finished(stderrStream)])\n\n\tconst stdout = readFileSync(stdoutPath, \"utf-8\")\n\tconst stderr = readFileSync(stderrPath, \"utf-8\")\n\tconst latestSession = getLatestAgentSession(payload.artifactsDir, payload.agentId)\n\tconst completionMessage =\n\t\tstdout.trim() ||\n\t\t(error?.message?.trim() ?? \"\") ||\n\t\t(exitCode === 0 ? `${payload.role} turn completed` : `${payload.role} turn exited with code ${exitCode}`)\n\n\tif (error) {\n\t\twriteFileSync(stderrPath, `${stderr}${stderr.endsWith(\"\\n\") || stderr.length === 0 ? \"\" : \"\\n\"}${error.message}\\n`, \"utf-8\")\n\t}\n\n\twriteFileSync(\n\t\tinvocationPath,\n\t\t`${JSON.stringify(\n\t\t\t{\n\t\t\t\tcommand: \"pi\",\n\t\t\t\targs: payload.piArgs,\n\t\t\t\texitCode,\n\t\t\t\tsessionDir: latestSession.sessionDir,\n\t\t\t\tsessionPath: latestSession.sessionPath,\n\t\t\t\tsessionId: latestSession.sessionId,\n\t\t\t\tprocessId: child.pid ?? null,\n\t\t\t\tstartedAt,\n\t\t\t\tendedAt: new Date().toISOString(),\n\t\t\t},\n\t\t\tnull,\n\t\t\t2,\n\t\t)}\\n`,\n\t\t\"utf-8\",\n\t)\n\n\tappendAgentMessage({\n\t\tartifactsDir: payload.artifactsDir,\n\t\tagentId: payload.agentId,\n\t\tbox: \"outbox\",\n\t\tfrom: payload.agentId,\n\t\tbody: completionMessage,\n\t})\n\n\tconst finalState = readAgentState(payload.artifactsDir, payload.agentId)\n\tif (finalState) {\n\t\twriteAgentState(\n\t\t\tpayload.artifactsDir,\n\t\t\tcreateAgentState({\n\t\t\t\t...finalState,\n\t\t\t\tstatus: exitCode === 0 ? \"idle\" : \"blocked\",\n\t\t\t\tlastMessage: completionMessage,\n\t\t\t\twaitingOn: exitCode === 0 ? null : \"human-or-follow-up-run\",\n\t\t\t\tblocked: exitCode !== 0,\n\t\t\t\tsession: createAgentSessionRecord({\n\t\t\t\t\tsessionDir: latestSession.sessionDir,\n\t\t\t\t\tsessionId: latestSession.sessionId,\n\t\t\t\t\tsessionPath: latestSession.sessionPath,\n\t\t\t\t\tprocessId: null,\n\t\t\t\t\tlastAttachedAt: finalState.session.lastAttachedAt,\n\t\t\t\t}),\n\t\t\t}),\n\t\t)\n\t}\n\n\ttry {\n\t\trmSync(payload.wakeLockPath, { force: true })\n\t} catch {\n\t\t// ignore wake lock cleanup failures\n\t}\n}\n\nasync function main() {\n\tconst [encodedPayload] = process.argv.slice(2)\n\tif (!encodedPayload) {\n\t\tthrow new Error(\"Missing detached agent payload\")\n\t}\n\n\tconst payload = JSON.parse(Buffer.from(encodedPayload, \"base64url\").toString(\"utf-8\")) as DetachedAgentRunPayload | DetachedAgentTurnPayload\n\tif (payload.kind === \"turn\") {\n\t\tawait runDetachedTurn(payload)\n\t\treturn\n\t}\n\n\tawait runDetachedAgent(payload)\n}\n\nvoid main().catch((error) => {\n\tconsole.error(error instanceof Error ? error.stack ?? error.message : String(error))\n\tprocess.exitCode = 1\n})\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -2,15 +2,16 @@
2
2
  type InterruptCategory = "missing-context" | "spec-gap" | "policy-gap" | "validation-gap" | "tooling-failure" | "external-blocker";
3
3
  type FixType = "adr" | "docs" | "policy" | "prompt" | "skill" | "tooling" | "validation";
4
4
  type RunMode = "single-pi";
5
- type AgentStatus = "queued" | "starting" | "running" | "idle" | "blocked" | "completed" | "failed";
5
+ type AgentStatus = "queued" | "starting" | "running" | "idle" | "blocked" | "completed" | "failed" | "stopped";
6
6
  type AgentMailbox = "inbox" | "outbox";
7
- type TaskStatus = "queued" | "running" | "blocked" | "completed";
7
+ type TaskStatus = "queued" | "running" | "blocked" | "completed" | "aborted";
8
8
  interface AgentSessionRecord {
9
9
  runtime: "pi";
10
10
  persisted: boolean;
11
11
  sessionDir: string | null;
12
12
  sessionId: string | null;
13
13
  sessionPath: string | null;
14
+ processId: number | null;
14
15
  lastAttachedAt: string | null;
15
16
  }
16
17
  interface AgentStateSnapshot {
@@ -146,12 +147,13 @@ interface ControllerRunResult {
146
147
  summary: RunSummary;
147
148
  piInvocation: PiInvocationRecord;
148
149
  }
149
- type LoopStopReason = "all-tasks-completed" | "all-remaining-tasks-blocked" | "leader-blocked" | "max-iterations-reached" | "max-wall-time-reached" | "pi-exit-nonzero" | "high-interrupt-rate";
150
+ type LoopStopReason = "all-tasks-completed" | "all-remaining-tasks-blocked" | "mayor-blocked" | "mayor-idle-no-work" | "max-iterations-reached" | "max-wall-time-reached" | "pi-exit-nonzero" | "high-interrupt-rate";
150
151
  interface LoopOptions {
151
152
  runOptions: RunOptions;
152
153
  maxIterations?: number;
153
154
  maxWallTimeMs?: number;
154
155
  stopOnPiFailure?: boolean;
156
+ stopOnMayorIdleNoWork?: boolean;
155
157
  interruptRateThreshold?: number | null;
156
158
  onIterationComplete?: (iteration: LoopIterationResult) => void;
157
159
  }
@@ -167,7 +169,7 @@ interface BoardSnapshot {
167
169
  }>;
168
170
  allTasksCompleted: boolean;
169
171
  allRemainingTasksBlocked: boolean;
170
- leaderBlocked: boolean;
172
+ mayorBlocked: boolean;
171
173
  hasQueuedOrRunningWork: boolean;
172
174
  }
173
175
  interface LoopIterationResult {
@@ -197,7 +199,7 @@ declare function getAgentSessionPath(artifactsDir: string, agentId: string): str
197
199
  declare function getAgentMailboxPath(artifactsDir: string, agentId: string, box: AgentMailbox): string;
198
200
  declare function getAgentSessionsDir(artifactsDir: string, agentId: string): string;
199
201
  declare function getSessionIdFromPath(sessionPath: string | null | undefined): string | null;
200
- declare function createAgentSessionRecord(input?: Partial<Pick<AgentSessionRecord, "sessionDir" | "sessionId" | "sessionPath" | "lastAttachedAt">>): AgentSessionRecord;
202
+ declare function createAgentSessionRecord(input?: Partial<Pick<AgentSessionRecord, "sessionDir" | "sessionId" | "sessionPath" | "processId" | "lastAttachedAt">>): AgentSessionRecord;
201
203
  declare function createAgentState(input: {
202
204
  agentId: string;
203
205
  role: string;
@@ -259,6 +261,7 @@ declare function evaluateStopCondition(input: {
259
261
  maxWallTimeMs: number;
260
262
  piExitCode: number;
261
263
  stopOnPiFailure: boolean;
264
+ stopOnMayorIdleNoWork: boolean;
262
265
  board: BoardSnapshot;
263
266
  metrics: MetricsSnapshot;
264
267
  interruptRateThreshold: number | null;
@@ -287,43 +290,54 @@ interface SpawnAgentRunOptions {
287
290
  role: string;
288
291
  agentId: string;
289
292
  task: string | null;
290
- appendedSystemPrompt?: string | null;
291
- extensionPath?: string | null;
292
- taskId?: string | null;
293
+ appendedSystemPrompt?: string | null | undefined;
294
+ extensionPath?: string | null | undefined;
295
+ taskId?: string | null | undefined;
296
+ autoResumeTarget?: AutoResumeTarget | null | undefined;
293
297
  }
294
298
  interface SpawnAgentRunResult {
295
- piResult: {
296
- stdout: string;
297
- stderr: string;
298
- exitCode: number;
299
+ launch: {
300
+ processId: number;
301
+ startedAt: string;
299
302
  };
300
303
  latestSession: AgentSessionRecord;
301
- completionMessage: string;
302
304
  }
303
305
  interface DelegateTaskOptions {
304
306
  repoRoot: string;
305
307
  artifactsDir: string;
306
308
  fromAgentId: string;
307
309
  role: string;
308
- agentId?: string | null;
309
- appendedSystemPrompt?: string | null;
310
- extensionPath?: string | null;
310
+ agentId?: string | null | undefined;
311
+ appendedSystemPrompt?: string | null | undefined;
312
+ extensionPath?: string | null | undefined;
313
+ completionAutoResumeTarget?: AutoResumeTarget | null | undefined;
311
314
  task: string;
312
315
  }
313
316
  interface DelegateTaskResult {
314
317
  task: TaskRecord;
315
318
  agentId: string;
316
- piResult: {
317
- stdout: string;
318
- stderr: string;
319
- exitCode: number;
320
- };
319
+ launch: SpawnAgentRunResult["launch"];
321
320
  latestSession: AgentSessionRecord;
322
321
  }
323
322
  interface ResolvedAgentSession {
324
323
  state: AgentStateSnapshot;
325
324
  session: AgentSessionRecord;
326
325
  }
326
+ interface AutoResumeTarget {
327
+ agentId: string;
328
+ message: string;
329
+ appendedSystemPrompt?: string | null | undefined;
330
+ extensionPath?: string | null | undefined;
331
+ }
332
+ interface ResumeAgentTurnDetachedOptions {
333
+ repoRoot: string;
334
+ artifactsDir: string;
335
+ agentId: string;
336
+ message: string;
337
+ from?: string;
338
+ appendedSystemPrompt?: string | null | undefined;
339
+ extensionPath?: string | null | undefined;
340
+ }
327
341
  interface RunAgentTurnOptions {
328
342
  repoRoot: string;
329
343
  artifactsDir: string;
@@ -347,16 +361,24 @@ declare function createRolePrompt(input: {
347
361
  repoRoot: string;
348
362
  }): string;
349
363
  declare function resolveAgentSession(agentId: string, artifactsDir: string): ResolvedAgentSession;
364
+ declare function resumeAgentTurnDetached(options: ResumeAgentTurnDetachedOptions): SpawnAgentRunResult | null;
350
365
  declare function queueAgentMessage(input: {
351
366
  artifactsDir: string;
352
367
  agentId: string;
353
368
  from: string;
354
369
  body: string;
355
370
  }): void;
371
+ declare function notifyTaskDelegator(input: {
372
+ artifactsDir: string;
373
+ agentId: string;
374
+ taskId: string | null;
375
+ completionMessage: string;
376
+ outcome: "completed" | "blocked";
377
+ }): void;
356
378
  declare function updateAgentStatus(input: {
357
379
  artifactsDir: string;
358
380
  agentId: string;
359
- status: "queued" | "running" | "idle" | "blocked" | "completed" | "failed";
381
+ status: "queued" | "running" | "idle" | "blocked" | "completed" | "failed" | "stopped";
360
382
  lastMessage?: string | null;
361
383
  waitingOn?: string | null;
362
384
  blocked?: boolean;
@@ -393,6 +415,62 @@ declare function runCommandInteractive(command: string, args: string[], options?
393
415
  }): number;
394
416
  declare function assertSuccess(result: CommandResult, context: string): void;
395
417
  //#endregion
418
+ //#region src/stop.d.ts
419
+ interface LeaseData {
420
+ runId: string;
421
+ repoId: string;
422
+ branch: string;
423
+ pid: number;
424
+ hostname: string;
425
+ startedAt: string;
426
+ }
427
+ interface StopManagedAgentsOptions {
428
+ artifactsDir: string;
429
+ agentId?: string | null;
430
+ excludeAgentIds?: string[];
431
+ actorId?: string | null;
432
+ reason?: string | null;
433
+ force?: boolean;
434
+ graceMs?: number;
435
+ }
436
+ interface StopAgentResult {
437
+ agentId: string;
438
+ previousStatus: AgentStateSnapshot["status"];
439
+ nextStatus: AgentStateSnapshot["status"];
440
+ processId: number | null;
441
+ signal: "SIGTERM" | "SIGKILL" | null;
442
+ exited: boolean;
443
+ }
444
+ interface StopManagedAgentsResult {
445
+ results: StopAgentResult[];
446
+ stoppedAgents: number;
447
+ signaledProcesses: number;
448
+ }
449
+ interface RepoLeaseRecord extends LeaseData {
450
+ path: string;
451
+ }
452
+ interface StopRepoLeasesOptions {
453
+ repoId?: string | null;
454
+ force?: boolean;
455
+ graceMs?: number;
456
+ }
457
+ interface StopRepoLeaseResult {
458
+ path: string;
459
+ runId: string;
460
+ repoId: string;
461
+ branch: string;
462
+ processId: number;
463
+ signal: "SIGTERM" | "SIGKILL" | null;
464
+ exited: boolean;
465
+ }
466
+ interface StopRepoLeasesResult {
467
+ results: StopRepoLeaseResult[];
468
+ signaledProcesses: number;
469
+ }
470
+ declare function listRepoLeases(repoId?: string | null): RepoLeaseRecord[];
471
+ declare function stopRepoLeases(options: StopRepoLeasesOptions): StopRepoLeasesResult;
472
+ declare function stopManagedAgents(options: StopManagedAgentsOptions): StopManagedAgentsResult;
473
+ //#endregion
396
474
  //#region src/tasks.d.ts
397
475
  declare function getTasksDir(artifactsDir: string): string;
398
476
  declare function getTaskPath(artifactsDir: string, taskId: string): string;
@@ -409,5 +487,5 @@ declare function updateTaskRecordStatus(artifactsDir: string, taskId: string, st
409
487
  declare function readTaskRecord(artifactsDir: string, taskId: string): TaskRecord | null;
410
488
  declare function listTaskRecords(artifactsDir: string): TaskRecord[];
411
489
  //#endregion
412
- export { AgentMailbox, AgentMessageRecord, AgentSessionRecord, AgentStateSnapshot, AgentStatus, BoardSnapshot, CommandResult, ControllerRunResult, CreateInterruptInput, DelegateTaskOptions, DelegateTaskResult, FeedbackCycle, FixType, InterruptCategory, InterruptRecord, LoopIterationResult, LoopOptions, LoopRunResult, LoopStopReason, MetricsSnapshot, PiInvocationRecord, ResolvedAgentSession, RunAgentTurnOptions, RunAgentTurnResult, RunManifest, RunMode, RunOptions, RunSummary, SpawnAgentRunOptions, SpawnAgentRunResult, TaskAttempt, TaskRecord, TaskStatus, acquireRepoLease, appendAgentMessage, appendJsonl, assertCommandAvailable, assertSuccess, computeAutonomousCompletionRate, computeContextCoverageScore, computeFeedbackToDemoCycleTime, computeInterruptRate, computeMeanTimeToCorrect, computeMetrics, createAgentSessionRecord, createAgentState, createInterruptRecord, createPiAuthHelpMessage, createRepoSlug, createRolePrompt, createTaskRecord, delegateTask, detectPiAuthFailure, evaluateStopCondition, getAgentDir, getAgentMailboxPath, getAgentSessionPath, getAgentSessionsDir, getAgentStatePath, getAgentsDir, getCurrentBranch, getLatestAgentSession, getRepoIdentity, getRepoRoot, getSessionIdFromPath, getTaskPath, getTasksDir, isGitRepo, listAgentStates, listTaskRecords, queueAgentMessage, readAgentMessages, readAgentState, readJsonl, readTaskRecord, resolveAgentSession, resolveInterrupt, runAgentTurn, runCommandInteractive, runCommandSync, runController, runLoop, snapshotBoard, spawnAgentRun, updateAgentStatus, updateTaskRecordStatus, writeAgentState, writeTaskRecord };
490
+ export { AgentMailbox, AgentMessageRecord, AgentSessionRecord, AgentStateSnapshot, AgentStatus, AutoResumeTarget, BoardSnapshot, CommandResult, ControllerRunResult, CreateInterruptInput, DelegateTaskOptions, DelegateTaskResult, FeedbackCycle, FixType, InterruptCategory, InterruptRecord, LoopIterationResult, LoopOptions, LoopRunResult, LoopStopReason, MetricsSnapshot, PiInvocationRecord, RepoLeaseRecord, ResolvedAgentSession, ResumeAgentTurnDetachedOptions, RunAgentTurnOptions, RunAgentTurnResult, RunManifest, RunMode, RunOptions, RunSummary, SpawnAgentRunOptions, SpawnAgentRunResult, StopAgentResult, StopManagedAgentsOptions, StopManagedAgentsResult, StopRepoLeaseResult, StopRepoLeasesOptions, StopRepoLeasesResult, TaskAttempt, TaskRecord, TaskStatus, acquireRepoLease, appendAgentMessage, appendJsonl, assertCommandAvailable, assertSuccess, computeAutonomousCompletionRate, computeContextCoverageScore, computeFeedbackToDemoCycleTime, computeInterruptRate, computeMeanTimeToCorrect, computeMetrics, createAgentSessionRecord, createAgentState, createInterruptRecord, createPiAuthHelpMessage, createRepoSlug, createRolePrompt, createTaskRecord, delegateTask, detectPiAuthFailure, evaluateStopCondition, getAgentDir, getAgentMailboxPath, getAgentSessionPath, getAgentSessionsDir, getAgentStatePath, getAgentsDir, getCurrentBranch, getLatestAgentSession, getRepoIdentity, getRepoRoot, getSessionIdFromPath, getTaskPath, getTasksDir, isGitRepo, listAgentStates, listRepoLeases, listTaskRecords, notifyTaskDelegator, queueAgentMessage, readAgentMessages, readAgentState, readJsonl, readTaskRecord, resolveAgentSession, resolveInterrupt, resumeAgentTurnDetached, runAgentTurn, runCommandInteractive, runCommandSync, runController, runLoop, snapshotBoard, spawnAgentRun, stopManagedAgents, stopRepoLeases, updateAgentStatus, updateTaskRecordStatus, writeAgentState, writeTaskRecord };
413
491
  //# sourceMappingURL=index.d.mts.map