@agimon-ai/po-team 0.0.0-alpha.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/LICENSE +25 -0
- package/README.md +156 -0
- package/dist/agentDiscovery-Whwzc4dP.cjs +1637 -0
- package/dist/agentDiscovery-Whwzc4dP.cjs.map +1 -0
- package/dist/agentDiscovery-ZQlFkKvB.mjs +1529 -0
- package/dist/agentDiscovery-ZQlFkKvB.mjs.map +1 -0
- package/dist/apiContracts.cjs +162 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +157 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/atomicJson-D0346bt5.cjs +178 -0
- package/dist/atomicJson-D0346bt5.cjs.map +1 -0
- package/dist/atomicJson-D2t0CDh9.mjs +137 -0
- package/dist/atomicJson-D2t0CDh9.mjs.map +1 -0
- package/dist/capabilityCeiling-C-Y7H8oC.cjs +191 -0
- package/dist/capabilityCeiling-C-Y7H8oC.cjs.map +1 -0
- package/dist/capabilityCeiling-CF7kAS18.mjs +156 -0
- package/dist/capabilityCeiling-CF7kAS18.mjs.map +1 -0
- package/dist/capabilityCeiling.cjs +10 -0
- package/dist/capabilityCeiling.d.mts +46 -0
- package/dist/capabilityCeiling.d.mts.map +1 -0
- package/dist/capabilityCeiling.mjs +3 -0
- package/dist/delegation.cjs +49 -0
- package/dist/delegation.cjs.map +1 -0
- package/dist/delegation.d.mts +269 -0
- package/dist/delegation.d.mts.map +1 -0
- package/dist/delegation.mjs +34 -0
- package/dist/delegation.mjs.map +1 -0
- package/dist/delegationApi.cjs +92 -0
- package/dist/delegationApi.d.mts +2 -0
- package/dist/delegationApi.mjs +2 -0
- package/dist/env.cjs +62 -0
- package/dist/env.d.mts +2 -0
- package/dist/env.mjs +2 -0
- package/dist/environment-CaCW3SgT.cjs +320 -0
- package/dist/environment-CaCW3SgT.cjs.map +1 -0
- package/dist/environment-DrqhrxG_.mjs +75 -0
- package/dist/environment-DrqhrxG_.mjs.map +1 -0
- package/dist/environment-ma5oQ7uM.d.mts +63 -0
- package/dist/environment-ma5oQ7uM.d.mts.map +1 -0
- package/dist/extensions/server.cjs +6940 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +6932 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +2308 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/externalProcessIpc-C-15lJrB.mjs +584 -0
- package/dist/externalProcessIpc-C-15lJrB.mjs.map +1 -0
- package/dist/externalProcessIpc-ojE0pvw0.cjs +690 -0
- package/dist/externalProcessIpc-ojE0pvw0.cjs.map +1 -0
- package/dist/fablePlan.cjs +17 -0
- package/dist/fablePlan.d.mts +2 -0
- package/dist/fablePlan.mjs +2 -0
- package/dist/fablePlanApi-BsHhgVFV.mjs +118 -0
- package/dist/fablePlanApi-BsHhgVFV.mjs.map +1 -0
- package/dist/fablePlanApi-CZ3uUcMi.d.mts +97 -0
- package/dist/fablePlanApi-CZ3uUcMi.d.mts.map +1 -0
- package/dist/fablePlanApi-wBu9bRXU.cjs +207 -0
- package/dist/fablePlanApi-wBu9bRXU.cjs.map +1 -0
- package/dist/fablePlanApi.cjs +17 -0
- package/dist/fablePlanApi.d.mts +2 -0
- package/dist/fablePlanApi.mjs +2 -0
- package/dist/index.cjs +49 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +160 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +45 -0
- package/dist/index.mjs.map +1 -0
- package/dist/runs/background/cliRunnerEntry.cjs +539 -0
- package/dist/runs/background/cliRunnerEntry.cjs.map +1 -0
- package/dist/runs/background/cliRunnerEntry.d.mts +1 -0
- package/dist/runs/background/cliRunnerEntry.mjs +537 -0
- package/dist/runs/background/cliRunnerEntry.mjs.map +1 -0
- package/dist/runtimeSubagentPolicy.cjs +5 -0
- package/dist/runtimeSubagentPolicy.d.mts +2 -0
- package/dist/runtimeSubagentPolicy.mjs +2 -0
- package/dist/runtimeSubagentTool.cjs +11 -0
- package/dist/runtimeSubagentTool.d.mts +2 -0
- package/dist/runtimeSubagentTool.mjs +2 -0
- package/dist/subagentPolicy-ALJam4GN.d.mts +33 -0
- package/dist/subagentPolicy-ALJam4GN.d.mts.map +1 -0
- package/dist/subagentPolicy-DQRyKDH-.cjs +39 -0
- package/dist/subagentPolicy-DQRyKDH-.cjs.map +1 -0
- package/dist/subagentPolicy-DxjsKeyj.mjs +22 -0
- package/dist/subagentPolicy-DxjsKeyj.mjs.map +1 -0
- package/dist/subagentPolicy.cjs +5 -0
- package/dist/subagentPolicy.d.mts +2 -0
- package/dist/subagentPolicy.mjs +2 -0
- package/dist/subagentTool-BTssGLw8.d.mts +103 -0
- package/dist/subagentTool-BTssGLw8.d.mts.map +1 -0
- package/dist/subagentTool-Ca2zQXKw.cjs +227 -0
- package/dist/subagentTool-Ca2zQXKw.cjs.map +1 -0
- package/dist/subagentTool-WOYrjxgT.mjs +186 -0
- package/dist/subagentTool-WOYrjxgT.mjs.map +1 -0
- package/dist/subagentTool.cjs +10 -0
- package/dist/subagentTool.d.mts +2 -0
- package/dist/subagentTool.mjs +2 -0
- package/dist/teamSnapshot-DgaANhBs.mjs +24 -0
- package/dist/teamSnapshot-DgaANhBs.mjs.map +1 -0
- package/dist/teamSnapshot-oKuGFdYc.cjs +35 -0
- package/dist/teamSnapshot-oKuGFdYc.cjs.map +1 -0
- package/dist/teamSnapshot.cjs +4 -0
- package/dist/teamSnapshot.d.mts +59 -0
- package/dist/teamSnapshot.d.mts.map +1 -0
- package/dist/teamSnapshot.mjs +2 -0
- package/package.json +201 -0
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
import { F as SUBAGENT_ROOT_SESSION_ENV, I as SUBAGENT_RUN_ID_ENV } from "../../environment-DrqhrxG_.mjs";
|
|
2
|
+
import { n as writePrivateAtomicJson, t as writeAtomicJson } from "../../atomicJson-D2t0CDh9.mjs";
|
|
3
|
+
import { c as cleanupClaudeFableLaunch, d as adoptSessionScopeFromEnv, i as parseExternalParentMessage, l as parseClaudeFableOutput, m as scopeRunsDir, o as sendRunnerMessage, s as CLAUDE_FABLE_PROFILE, t as EXTERNAL_IPC_CHANNEL } from "../../externalProcessIpc-C-15lJrB.mjs";
|
|
4
|
+
import * as fs from "node:fs";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import { createDoomTelemetry } from "@agimon-ai/po-telemetry";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
//#region src/services/statusWriter/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* Coalesced writer for a run's `status.json`.
|
|
11
|
+
*
|
|
12
|
+
* WHY THIS EXISTS:
|
|
13
|
+
* In the predecessor (`po-subagents/src/runs/background/subagent-runner.ts`)
|
|
14
|
+
* `status.json` was rewritten in full on every child event, and every rewrite
|
|
15
|
+
* `structuredClone`d the whole run graph first. On a fan-out run that makes the
|
|
16
|
+
* hot path quadratic: N events cost O(N) clones of an O(N)-sized graph. Its
|
|
17
|
+
* `recentTools` and `recentOutput` arrays were also appended to and never
|
|
18
|
+
* trimmed, so a long run's status file, and the cost of cloning it, grew
|
|
19
|
+
* without bound.
|
|
20
|
+
*
|
|
21
|
+
* DESIGN PATTERNS:
|
|
22
|
+
* - Coalescing: `update()` mutates the in-memory status and arms a trailing
|
|
23
|
+
* ~75ms timer. A burst of events inside that window costs one clone and one
|
|
24
|
+
* write, not one per event
|
|
25
|
+
* - The clone is gated by a dirty counter, not by the timer firing. A flush
|
|
26
|
+
* with nothing dirty since the last one performs no clone and no write at
|
|
27
|
+
* all, which is the specific fix for the quadratic behaviour above
|
|
28
|
+
* - `updateSync()` bypasses the timer for transitions that must not be lost if
|
|
29
|
+
* the process dies right after: terminal run status, and chain step
|
|
30
|
+
* transitions. Everything else can wait out the coalescing window
|
|
31
|
+
* - `recentTools` and `recentOutput` are capped at 50 entries, oldest dropped,
|
|
32
|
+
* on every append, so neither the in-memory status nor the cloned snapshot
|
|
33
|
+
* grows across a long run
|
|
34
|
+
*
|
|
35
|
+
* SINGLE WRITER CONTRACT (read this before adding another write site):
|
|
36
|
+
* `CoalescedStatusWriter` is the ONLY thing in this package that may write
|
|
37
|
+
* `status.json`. Not "the preferred way" - the only way. The predecessor had
|
|
38
|
+
* four unsynchronised writers to the same file, which is exactly how a run's
|
|
39
|
+
* displayed status ends up torn, stale, or overwritten by a slower writer
|
|
40
|
+
* racing a faster one; coalescing a single in-memory owner is what makes that
|
|
41
|
+
* class of bug structurally impossible instead of merely unlikely.
|
|
42
|
+
*
|
|
43
|
+
* Anything else that wants to influence a run's displayed status - pause a
|
|
44
|
+
* step, request a steer, ask a run to stop, report progress from a different
|
|
45
|
+
* process than the one that called `open()` - must NOT open or write
|
|
46
|
+
* `status.json` directly. It writes a sidecar/intent file instead, and the
|
|
47
|
+
* process holding this writer observes that file and folds it into its own
|
|
48
|
+
* `update()`. Readers for those intent files do not exist yet; that is a gap
|
|
49
|
+
* to fill, not a license to reach for `writeAtomicJson(statusPath, ...)`
|
|
50
|
+
* somewhere else. If you are about to write `status.json` from outside this
|
|
51
|
+
* class, stop - that is the bug this module exists to remove.
|
|
52
|
+
*
|
|
53
|
+
* AVOID:
|
|
54
|
+
* - Reading back `status.json` from disk to decide what to write next; the
|
|
55
|
+
* in-memory status held by `open()` is the only source of truth this class
|
|
56
|
+
* trusts
|
|
57
|
+
* - Adding a second writer of `status.json` anywhere else in the package,
|
|
58
|
+
* including "just this once" debug or recovery code
|
|
59
|
+
*/
|
|
60
|
+
/** How long a burst of updates may be buffered before a trailing flush. */
|
|
61
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 75;
|
|
62
|
+
/** Oldest-dropped cap for `recentTools` and `recentOutput`. */
|
|
63
|
+
const MAX_RECENT_ENTRIES = 50;
|
|
64
|
+
/**
|
|
65
|
+
* The one status filename.
|
|
66
|
+
*
|
|
67
|
+
* Exported because the reconciler and the steering reader both have to find
|
|
68
|
+
* this file without going through the writer. Two modules matching a literal
|
|
69
|
+
* by eye is how a rename silently orphans a reader.
|
|
70
|
+
*/
|
|
71
|
+
const STATUS_FILE_NAME = "status.json";
|
|
72
|
+
var CoalescedStatusWriter = class {
|
|
73
|
+
/**
|
|
74
|
+
* Runtime tuning seam for tests, kept out of the dependency constructor. A
|
|
75
|
+
* test subclass overrides this to avoid waiting
|
|
76
|
+
* out the real window when it does exercise the timer directly instead of
|
|
77
|
+
* using fake timers.
|
|
78
|
+
*/
|
|
79
|
+
flushIntervalMs = DEFAULT_FLUSH_INTERVAL_MS;
|
|
80
|
+
statusPath;
|
|
81
|
+
status;
|
|
82
|
+
dirtyCount = 0;
|
|
83
|
+
flushTimer;
|
|
84
|
+
open(scope, runId, initialStatus) {
|
|
85
|
+
if (this.flushTimer) {
|
|
86
|
+
clearTimeout(this.flushTimer);
|
|
87
|
+
this.flushTimer = void 0;
|
|
88
|
+
}
|
|
89
|
+
this.statusPath = path.join(scopeRunsDir(scope), runId, STATUS_FILE_NAME);
|
|
90
|
+
this.status = initialStatus;
|
|
91
|
+
this.dirtyCount = 0;
|
|
92
|
+
writeAtomicJson(this.statusPath, this.clone(initialStatus));
|
|
93
|
+
}
|
|
94
|
+
update(mutator) {
|
|
95
|
+
mutator(this.requireStatus());
|
|
96
|
+
this.dirtyCount++;
|
|
97
|
+
this.scheduleFlush();
|
|
98
|
+
}
|
|
99
|
+
updateSync(mutator) {
|
|
100
|
+
mutator(this.requireStatus());
|
|
101
|
+
this.dirtyCount++;
|
|
102
|
+
this.flush();
|
|
103
|
+
}
|
|
104
|
+
appendTool(entry) {
|
|
105
|
+
this.update((status) => appendCapped(status, "recentTools", entry));
|
|
106
|
+
}
|
|
107
|
+
appendOutput(entry) {
|
|
108
|
+
this.update((status) => appendCapped(status, "recentOutput", entry));
|
|
109
|
+
}
|
|
110
|
+
close() {
|
|
111
|
+
this.flush();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The clone-and-write step. Protected so a test can override `clone()`
|
|
115
|
+
* alone and assert it was never called across a run of no-op flushes,
|
|
116
|
+
* which is the direct, observable proof that the dirty-counter gate works.
|
|
117
|
+
*/
|
|
118
|
+
clone(value) {
|
|
119
|
+
return structuredClone(value);
|
|
120
|
+
}
|
|
121
|
+
flush() {
|
|
122
|
+
if (this.flushTimer) {
|
|
123
|
+
clearTimeout(this.flushTimer);
|
|
124
|
+
this.flushTimer = void 0;
|
|
125
|
+
}
|
|
126
|
+
if (this.dirtyCount === 0) return;
|
|
127
|
+
const status = this.status;
|
|
128
|
+
const statusPath = this.statusPath;
|
|
129
|
+
if (!status || !statusPath) return;
|
|
130
|
+
const snapshot = this.clone(status);
|
|
131
|
+
this.dirtyCount = 0;
|
|
132
|
+
writeAtomicJson(statusPath, snapshot);
|
|
133
|
+
}
|
|
134
|
+
scheduleFlush() {
|
|
135
|
+
if (this.flushTimer) return;
|
|
136
|
+
const timer = setTimeout(() => this.flush(), this.flushIntervalMs);
|
|
137
|
+
timer.unref?.();
|
|
138
|
+
this.flushTimer = timer;
|
|
139
|
+
}
|
|
140
|
+
requireStatus() {
|
|
141
|
+
if (!this.status) throw new Error("CoalescedStatusWriter used before open().");
|
|
142
|
+
return this.status;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
/** Push `entry` onto `status[field]`, dropping the oldest until at most 50 remain. */
|
|
146
|
+
function appendCapped(status, field, entry) {
|
|
147
|
+
const list = status[field] ?? [];
|
|
148
|
+
list.push(entry);
|
|
149
|
+
if (list.length > MAX_RECENT_ENTRIES) list.splice(0, list.length - MAX_RECENT_ENTRIES);
|
|
150
|
+
status[field] = list;
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/bin/cliRunner.ts
|
|
154
|
+
/**
|
|
155
|
+
* Detached child process for an explicitly selected external agent CLI.
|
|
156
|
+
*
|
|
157
|
+
* Launch, readiness, control, status, and completion use one bounded Node IPC
|
|
158
|
+
* protocol. Durable status and result files are output records only. They are
|
|
159
|
+
* never read to discover live state or coordinate the parent and child.
|
|
160
|
+
*/
|
|
161
|
+
const MAX_RESULT_BYTES = 65536;
|
|
162
|
+
const MAX_STDERR_BYTES = 8192;
|
|
163
|
+
const LAUNCH_TIMEOUT_MS = 15e3;
|
|
164
|
+
const PARENT_LOST_MESSAGE = "Parent process was lost.";
|
|
165
|
+
const FORCE_KILL_SIGNAL = "SIGKILL";
|
|
166
|
+
const STARTUP_ENVIRONMENT = Object.freeze({ ...process.env });
|
|
167
|
+
function errorMessage(error) {
|
|
168
|
+
return error instanceof Error ? error.message : String(error);
|
|
169
|
+
}
|
|
170
|
+
function isRecord(value) {
|
|
171
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
172
|
+
}
|
|
173
|
+
function validateLaunchConfig(value, runId) {
|
|
174
|
+
if (value.runId !== runId || typeof value.agent !== "string" || typeof value.task !== "string" || typeof value.runtime !== "string" || typeof value.command !== "string" || !Array.isArray(value.args) || !value.args.every((entry) => typeof entry === "string") || typeof value.cwd !== "string" || !isRecord(value.env) || typeof value.resultPath !== "string") throw new Error(`CLI launch config for run '${runId}' is invalid.`);
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
async function receiveLaunchConfig(scope, runId) {
|
|
178
|
+
return await new Promise((resolve, reject) => {
|
|
179
|
+
const finish = (error, config) => {
|
|
180
|
+
clearTimeout(timer);
|
|
181
|
+
process.off("message", onMessage);
|
|
182
|
+
process.off("disconnect", onDisconnect);
|
|
183
|
+
if (error) reject(error);
|
|
184
|
+
else resolve(config);
|
|
185
|
+
};
|
|
186
|
+
const onDisconnect = () => finish(/* @__PURE__ */ new Error(PARENT_LOST_MESSAGE));
|
|
187
|
+
const onMessage = (raw) => {
|
|
188
|
+
try {
|
|
189
|
+
const message = parseExternalParentMessage(raw, {
|
|
190
|
+
runId,
|
|
191
|
+
scopeKey: scope.scopeKey
|
|
192
|
+
});
|
|
193
|
+
if (!message || message.kind !== "launch") return;
|
|
194
|
+
finish(void 0, validateLaunchConfig(message.config, runId));
|
|
195
|
+
} catch (error) {
|
|
196
|
+
finish(error instanceof Error ? error : new Error(String(error)));
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const timer = setTimeout(() => finish(/* @__PURE__ */ new Error(`Timed out waiting for CLI launch config for run '${runId}'.`)), LAUNCH_TIMEOUT_MS);
|
|
200
|
+
timer.unref();
|
|
201
|
+
process.on("message", onMessage);
|
|
202
|
+
process.once("disconnect", onDisconnect);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function appendBounded(buffer, chunk, limit) {
|
|
206
|
+
let combined = buffer + chunk;
|
|
207
|
+
while (Buffer.byteLength(combined, "utf8") > limit && combined.length > 0) {
|
|
208
|
+
const excess = Buffer.byteLength(combined, "utf8") - limit;
|
|
209
|
+
combined = combined.slice(Math.max(1, Math.ceil(excess / 2)));
|
|
210
|
+
}
|
|
211
|
+
return combined;
|
|
212
|
+
}
|
|
213
|
+
let childTelemetry;
|
|
214
|
+
async function finishTelemetry(event, attributes, error) {
|
|
215
|
+
const telemetry = childTelemetry;
|
|
216
|
+
childTelemetry = void 0;
|
|
217
|
+
if (!telemetry) return;
|
|
218
|
+
if (error === void 0) await telemetry.recordEvent(event, attributes);
|
|
219
|
+
else await telemetry.recordError(event, error, attributes);
|
|
220
|
+
await telemetry.flush();
|
|
221
|
+
await telemetry.shutdown();
|
|
222
|
+
}
|
|
223
|
+
function projection(config, state, startedAt, fields = {}) {
|
|
224
|
+
return {
|
|
225
|
+
runId: config.runId,
|
|
226
|
+
agent: config.agent,
|
|
227
|
+
task: config.sensitiveTask ? "" : config.task,
|
|
228
|
+
runtime: config.runtime,
|
|
229
|
+
state,
|
|
230
|
+
startedAt,
|
|
231
|
+
updatedAt: Date.now(),
|
|
232
|
+
cwd: config.cwd,
|
|
233
|
+
...fields
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function resultFor(config, success, summary, exit) {
|
|
237
|
+
return {
|
|
238
|
+
runId: config.runId,
|
|
239
|
+
...config.operationId ? { operationId: config.operationId } : {},
|
|
240
|
+
...config.internal ? { internal: true } : {},
|
|
241
|
+
agent: config.agent,
|
|
242
|
+
runtime: config.runtime,
|
|
243
|
+
success,
|
|
244
|
+
summary,
|
|
245
|
+
...exit?.code === null || exit?.code === void 0 ? {} : { exitCode: exit.code },
|
|
246
|
+
...exit?.signal ? { signal: exit.signal } : {}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function runnerMessage(scope, runId, message) {
|
|
250
|
+
const base = {
|
|
251
|
+
channel: EXTERNAL_IPC_CHANNEL,
|
|
252
|
+
version: 1,
|
|
253
|
+
direction: "runner",
|
|
254
|
+
runId,
|
|
255
|
+
scopeKey: scope.scopeKey
|
|
256
|
+
};
|
|
257
|
+
if (message.kind === "ack") return {
|
|
258
|
+
...base,
|
|
259
|
+
...message,
|
|
260
|
+
command: "steer"
|
|
261
|
+
};
|
|
262
|
+
return {
|
|
263
|
+
...base,
|
|
264
|
+
...message
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function send(scope, runId, message) {
|
|
268
|
+
return sendRunnerMessage(runnerMessage(scope, runId, message));
|
|
269
|
+
}
|
|
270
|
+
async function run() {
|
|
271
|
+
const startedAt = Date.now();
|
|
272
|
+
const runId = STARTUP_ENVIRONMENT[SUBAGENT_RUN_ID_ENV]?.trim();
|
|
273
|
+
if (!runId) throw new Error(`${SUBAGENT_RUN_ID_ENV} is required.`);
|
|
274
|
+
const scope = adoptSessionScopeFromEnv(STARTUP_ENVIRONMENT);
|
|
275
|
+
if (!scope) throw new Error(`${SUBAGENT_ROOT_SESSION_ENV} is required: a child cannot resolve its session scope without it.`);
|
|
276
|
+
const config = await receiveLaunchConfig(scope, runId);
|
|
277
|
+
childTelemetry = createDoomTelemetry({
|
|
278
|
+
serviceName: "doom-team-cli-child",
|
|
279
|
+
packageName: "@agimon-ai/po-team",
|
|
280
|
+
env: config.env,
|
|
281
|
+
enableLogs: true,
|
|
282
|
+
enableTraces: true
|
|
283
|
+
});
|
|
284
|
+
const statusWriter = new CoalescedStatusWriter();
|
|
285
|
+
statusWriter.open(scope, runId, {
|
|
286
|
+
version: 1,
|
|
287
|
+
runId,
|
|
288
|
+
...config.operationId ? { operationId: config.operationId } : {},
|
|
289
|
+
agent: config.agent,
|
|
290
|
+
...config.sensitiveTask ? {} : { task: config.task },
|
|
291
|
+
cwd: config.cwd,
|
|
292
|
+
runtime: config.runtime,
|
|
293
|
+
state: "queued",
|
|
294
|
+
startedAt,
|
|
295
|
+
lastUpdate: startedAt
|
|
296
|
+
});
|
|
297
|
+
await childTelemetry.recordEvent("doom_team.child_started", {
|
|
298
|
+
runtime: config.runtime,
|
|
299
|
+
"agent.name": config.agent,
|
|
300
|
+
outcome: "started"
|
|
301
|
+
});
|
|
302
|
+
const profileLaunch = config.profile === CLAUDE_FABLE_PROFILE;
|
|
303
|
+
if (config.profile !== void 0 && !profileLaunch) throw new Error("Untrusted external profile.");
|
|
304
|
+
if (profileLaunch && (!config.stdinPath || !config.profileResultPath)) throw new Error("Fable profile launch config is incomplete.");
|
|
305
|
+
const stdinFd = profileLaunch ? fs.openSync(config.stdinPath, "r") : void 0;
|
|
306
|
+
let child;
|
|
307
|
+
try {
|
|
308
|
+
child = spawn(config.command, config.args, {
|
|
309
|
+
cwd: config.cwd,
|
|
310
|
+
env: config.env,
|
|
311
|
+
stdio: [
|
|
312
|
+
stdinFd ?? "ignore",
|
|
313
|
+
"pipe",
|
|
314
|
+
"pipe"
|
|
315
|
+
],
|
|
316
|
+
detached: true,
|
|
317
|
+
windowsHide: true
|
|
318
|
+
});
|
|
319
|
+
} finally {
|
|
320
|
+
if (stdinFd !== void 0) fs.closeSync(stdinFd);
|
|
321
|
+
}
|
|
322
|
+
const cleanupProfile = (removeResult) => {
|
|
323
|
+
if (!profileLaunch) return;
|
|
324
|
+
cleanupClaudeFableLaunch({ cleanupPaths: config.cleanupPaths ?? [] });
|
|
325
|
+
if (removeResult && config.profileResultPath) fs.rmSync(config.profileResultPath, { force: true });
|
|
326
|
+
};
|
|
327
|
+
let requestedSignal;
|
|
328
|
+
let finalizing = false;
|
|
329
|
+
const stopVendor = (signal) => {
|
|
330
|
+
requestedSignal = signal;
|
|
331
|
+
if (!child.pid) return;
|
|
332
|
+
try {
|
|
333
|
+
process.kill(-child.pid, signal);
|
|
334
|
+
} catch (error) {
|
|
335
|
+
process.stderr.write(`[doom-team cli runner] Could not signal vendor process: ${errorMessage(error)}\n`);
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
const onSigterm = () => stopVendor("SIGTERM");
|
|
339
|
+
const onSigint = () => stopVendor("SIGINT");
|
|
340
|
+
process.once("SIGTERM", onSigterm);
|
|
341
|
+
process.once("SIGINT", onSigint);
|
|
342
|
+
const onControl = (raw) => {
|
|
343
|
+
const message = parseExternalParentMessage(raw, {
|
|
344
|
+
runId,
|
|
345
|
+
scopeKey: scope.scopeKey
|
|
346
|
+
});
|
|
347
|
+
if (!message || message.kind !== "control") return;
|
|
348
|
+
if (message.command === "steer") {
|
|
349
|
+
send(scope, runId, {
|
|
350
|
+
kind: "ack",
|
|
351
|
+
requestId: message.requestId,
|
|
352
|
+
state: "failed",
|
|
353
|
+
message: `Runtime '${config.runtime}' does not support live steering.`
|
|
354
|
+
});
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
stopVendor(message.command === "interrupt" ? "SIGINT" : "SIGTERM");
|
|
358
|
+
};
|
|
359
|
+
process.on("message", onControl);
|
|
360
|
+
const onParentLost = () => {
|
|
361
|
+
if (finalizing) return;
|
|
362
|
+
finalizing = true;
|
|
363
|
+
stopVendor(FORCE_KILL_SIGNAL);
|
|
364
|
+
const endedAt = Date.now();
|
|
365
|
+
statusWriter.updateSync((status) => {
|
|
366
|
+
status.state = "stopped";
|
|
367
|
+
status.error = PARENT_LOST_MESSAGE;
|
|
368
|
+
status.lastUpdate = endedAt;
|
|
369
|
+
status.endedAt = endedAt;
|
|
370
|
+
});
|
|
371
|
+
writeAtomicJson(config.resultPath, {
|
|
372
|
+
...resultFor(config, false, PARENT_LOST_MESSAGE, {
|
|
373
|
+
code: null,
|
|
374
|
+
signal: FORCE_KILL_SIGNAL
|
|
375
|
+
}),
|
|
376
|
+
state: "stopped",
|
|
377
|
+
...config.internal ? { internal: true } : {}
|
|
378
|
+
});
|
|
379
|
+
statusWriter.close();
|
|
380
|
+
cleanupProfile(true);
|
|
381
|
+
finishTelemetry("doom_team.child_finished", {
|
|
382
|
+
runtime: config.runtime,
|
|
383
|
+
"agent.name": config.agent,
|
|
384
|
+
duration_ms: Date.now() - startedAt,
|
|
385
|
+
outcome: "parent_lost"
|
|
386
|
+
}).finally(() => process.exit(0));
|
|
387
|
+
};
|
|
388
|
+
process.once("disconnect", onParentLost);
|
|
389
|
+
try {
|
|
390
|
+
await new Promise((resolve, reject) => {
|
|
391
|
+
child.once("spawn", resolve);
|
|
392
|
+
child.once("error", reject);
|
|
393
|
+
});
|
|
394
|
+
const running = projection(config, "running", startedAt);
|
|
395
|
+
statusWriter.updateSync((status) => {
|
|
396
|
+
status.state = "running";
|
|
397
|
+
status.activityState = "working";
|
|
398
|
+
status.lastUpdate = Date.now();
|
|
399
|
+
});
|
|
400
|
+
await send(scope, runId, {
|
|
401
|
+
kind: "status",
|
|
402
|
+
status: running
|
|
403
|
+
});
|
|
404
|
+
await send(scope, runId, { kind: "ready" });
|
|
405
|
+
} catch (error) {
|
|
406
|
+
finalizing = true;
|
|
407
|
+
const message = errorMessage(error);
|
|
408
|
+
const endedAt = Date.now();
|
|
409
|
+
const result = {
|
|
410
|
+
...resultFor(config, false, profileLaunch ? "Fable Claude launch failed." : message),
|
|
411
|
+
state: "failed"
|
|
412
|
+
};
|
|
413
|
+
statusWriter.updateSync((status) => {
|
|
414
|
+
status.state = "failed";
|
|
415
|
+
status.error = message;
|
|
416
|
+
status.lastUpdate = endedAt;
|
|
417
|
+
status.endedAt = endedAt;
|
|
418
|
+
});
|
|
419
|
+
writeAtomicJson(config.resultPath, {
|
|
420
|
+
...result,
|
|
421
|
+
...config.internal ? { internal: true } : {}
|
|
422
|
+
});
|
|
423
|
+
await send(scope, runId, {
|
|
424
|
+
kind: "error",
|
|
425
|
+
error: message
|
|
426
|
+
});
|
|
427
|
+
await send(scope, runId, {
|
|
428
|
+
kind: "result",
|
|
429
|
+
result
|
|
430
|
+
});
|
|
431
|
+
statusWriter.close();
|
|
432
|
+
cleanupProfile(true);
|
|
433
|
+
await finishTelemetry("doom_team.child_failed", {
|
|
434
|
+
runtime: config.runtime,
|
|
435
|
+
"agent.name": config.agent,
|
|
436
|
+
duration_ms: Date.now() - startedAt,
|
|
437
|
+
outcome: "failed"
|
|
438
|
+
}, error);
|
|
439
|
+
process.exit(1);
|
|
440
|
+
}
|
|
441
|
+
let stdout = "";
|
|
442
|
+
let stderr = "";
|
|
443
|
+
child.stdout?.on("data", (chunk) => {
|
|
444
|
+
stdout = appendBounded(stdout, chunk.toString("utf8"), MAX_RESULT_BYTES);
|
|
445
|
+
});
|
|
446
|
+
child.stderr?.on("data", (chunk) => {
|
|
447
|
+
stderr = appendBounded(stderr, chunk.toString("utf8"), MAX_STDERR_BYTES);
|
|
448
|
+
});
|
|
449
|
+
const exit = await new Promise((resolve) => {
|
|
450
|
+
child.on("error", (error) => resolve({
|
|
451
|
+
code: null,
|
|
452
|
+
signal: null,
|
|
453
|
+
error
|
|
454
|
+
}));
|
|
455
|
+
child.on("close", (code, signal) => resolve({
|
|
456
|
+
code,
|
|
457
|
+
signal
|
|
458
|
+
}));
|
|
459
|
+
});
|
|
460
|
+
finalizing = true;
|
|
461
|
+
process.off("message", onControl);
|
|
462
|
+
process.off("disconnect", onParentLost);
|
|
463
|
+
process.off("SIGTERM", onSigterm);
|
|
464
|
+
process.off("SIGINT", onSigint);
|
|
465
|
+
const stopped = requestedSignal !== void 0;
|
|
466
|
+
let profileError;
|
|
467
|
+
if (profileLaunch && !stopped && exit.error === void 0 && exit.code === 0) try {
|
|
468
|
+
const parsed = parseClaudeFableOutput(stdout);
|
|
469
|
+
writePrivateAtomicJson(config.profileResultPath, {
|
|
470
|
+
text: parsed.text,
|
|
471
|
+
outputBytes: parsed.outputBytes
|
|
472
|
+
});
|
|
473
|
+
} catch (error) {
|
|
474
|
+
profileError = error instanceof Error ? error : new Error(String(error));
|
|
475
|
+
}
|
|
476
|
+
const success = !stopped && exit.error === void 0 && exit.code === 0 && profileError === void 0;
|
|
477
|
+
const failureDetail = profileLaunch ? profileError?.message ?? "Fable Claude launch failed." : stderr.trim() || `${config.runtime} exited with ${exit.signal ?? `code ${exit.code ?? "unknown"}`}.`;
|
|
478
|
+
const summary = stopped ? `Stopped by ${requestedSignal}.` : success ? profileLaunch ? "Fable profile completed." : stdout.trim() : exit.error?.message ?? failureDetail;
|
|
479
|
+
const endedAt = Date.now();
|
|
480
|
+
const state = stopped ? "stopped" : success ? "completed" : "failed";
|
|
481
|
+
const result = {
|
|
482
|
+
...resultFor(config, success, summary, exit),
|
|
483
|
+
state
|
|
484
|
+
};
|
|
485
|
+
statusWriter.updateSync((status) => {
|
|
486
|
+
status.state = state;
|
|
487
|
+
status.activityState = "finalizing";
|
|
488
|
+
status.summary = summary;
|
|
489
|
+
if (!success) status.error = summary;
|
|
490
|
+
status.lastUpdate = endedAt;
|
|
491
|
+
status.endedAt = endedAt;
|
|
492
|
+
});
|
|
493
|
+
writeAtomicJson(config.resultPath, {
|
|
494
|
+
...result,
|
|
495
|
+
...config.internal ? { internal: true } : {}
|
|
496
|
+
});
|
|
497
|
+
await send(scope, runId, {
|
|
498
|
+
kind: "status",
|
|
499
|
+
status: projection(config, state, startedAt, {
|
|
500
|
+
summary,
|
|
501
|
+
...!success ? { error: summary } : {}
|
|
502
|
+
})
|
|
503
|
+
});
|
|
504
|
+
await send(scope, runId, {
|
|
505
|
+
kind: "result",
|
|
506
|
+
result
|
|
507
|
+
});
|
|
508
|
+
statusWriter.close();
|
|
509
|
+
cleanupProfile(!success);
|
|
510
|
+
await finishTelemetry("doom_team.child_finished", {
|
|
511
|
+
runtime: config.runtime,
|
|
512
|
+
"agent.name": config.agent,
|
|
513
|
+
duration_ms: Date.now() - startedAt,
|
|
514
|
+
"runner.stdout_bytes": Buffer.byteLength(stdout, "utf8"),
|
|
515
|
+
"runner.stderr_bytes": Buffer.byteLength(stderr, "utf8"),
|
|
516
|
+
"runner.exit_code": exit.code ?? 0,
|
|
517
|
+
outcome: state
|
|
518
|
+
});
|
|
519
|
+
process.exit(0);
|
|
520
|
+
}
|
|
521
|
+
run().catch(async (error) => {
|
|
522
|
+
const runId = STARTUP_ENVIRONMENT[SUBAGENT_RUN_ID_ENV]?.trim();
|
|
523
|
+
const scope = adoptSessionScopeFromEnv(STARTUP_ENVIRONMENT);
|
|
524
|
+
if (runId && scope && process.connected) try {
|
|
525
|
+
await send(scope, runId, {
|
|
526
|
+
kind: "error",
|
|
527
|
+
error: errorMessage(error)
|
|
528
|
+
});
|
|
529
|
+
} catch {}
|
|
530
|
+
await finishTelemetry("doom_team.child_failed", { outcome: "failed" }, error);
|
|
531
|
+
process.stderr.write(`[doom-team cli runner] ${errorMessage(error)}\n`);
|
|
532
|
+
process.exitCode = 1;
|
|
533
|
+
});
|
|
534
|
+
//#endregion
|
|
535
|
+
export {};
|
|
536
|
+
|
|
537
|
+
//# sourceMappingURL=cliRunnerEntry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliRunnerEntry.mjs","names":[],"sources":["../../../src/services/statusWriter/index.ts","../../../src/bin/cliRunner.ts"],"sourcesContent":["/**\n * Coalesced writer for a run's `status.json`.\n *\n * WHY THIS EXISTS:\n * In the predecessor (`po-subagents/src/runs/background/subagent-runner.ts`)\n * `status.json` was rewritten in full on every child event, and every rewrite\n * `structuredClone`d the whole run graph first. On a fan-out run that makes the\n * hot path quadratic: N events cost O(N) clones of an O(N)-sized graph. Its\n * `recentTools` and `recentOutput` arrays were also appended to and never\n * trimmed, so a long run's status file, and the cost of cloning it, grew\n * without bound.\n *\n * DESIGN PATTERNS:\n * - Coalescing: `update()` mutates the in-memory status and arms a trailing\n * ~75ms timer. A burst of events inside that window costs one clone and one\n * write, not one per event\n * - The clone is gated by a dirty counter, not by the timer firing. A flush\n * with nothing dirty since the last one performs no clone and no write at\n * all, which is the specific fix for the quadratic behaviour above\n * - `updateSync()` bypasses the timer for transitions that must not be lost if\n * the process dies right after: terminal run status, and chain step\n * transitions. Everything else can wait out the coalescing window\n * - `recentTools` and `recentOutput` are capped at 50 entries, oldest dropped,\n * on every append, so neither the in-memory status nor the cloned snapshot\n * grows across a long run\n *\n * SINGLE WRITER CONTRACT (read this before adding another write site):\n * `CoalescedStatusWriter` is the ONLY thing in this package that may write\n * `status.json`. Not \"the preferred way\" - the only way. The predecessor had\n * four unsynchronised writers to the same file, which is exactly how a run's\n * displayed status ends up torn, stale, or overwritten by a slower writer\n * racing a faster one; coalescing a single in-memory owner is what makes that\n * class of bug structurally impossible instead of merely unlikely.\n *\n * Anything else that wants to influence a run's displayed status - pause a\n * step, request a steer, ask a run to stop, report progress from a different\n * process than the one that called `open()` - must NOT open or write\n * `status.json` directly. It writes a sidecar/intent file instead, and the\n * process holding this writer observes that file and folds it into its own\n * `update()`. Readers for those intent files do not exist yet; that is a gap\n * to fill, not a license to reach for `writeAtomicJson(statusPath, ...)`\n * somewhere else. If you are about to write `status.json` from outside this\n * class, stop - that is the bug this module exists to remove.\n *\n * AVOID:\n * - Reading back `status.json` from disk to decide what to write next; the\n * in-memory status held by `open()` is the only source of truth this class\n * trusts\n * - Adding a second writer of `status.json` anywhere else in the package,\n * including \"just this once\" debug or recovery code\n */\n\nimport * as path from 'node:path';\n\nimport { writeAtomicJson } from '../atomicJson';\nimport { scopeRunsDir, type SessionScope } from '../sessionPaths';\n\n/** How long a burst of updates may be buffered before a trailing flush. */\nconst DEFAULT_FLUSH_INTERVAL_MS = 75;\n\n/** Oldest-dropped cap for `recentTools` and `recentOutput`. */\nconst MAX_RECENT_ENTRIES = 50;\n\n/**\n * The one status filename.\n *\n * Exported because the reconciler and the steering reader both have to find\n * this file without going through the writer. Two modules matching a literal\n * by eye is how a rename silently orphans a reader.\n */\nexport const STATUS_FILE_NAME = 'status.json';\n\n/**\n * The minimum shape this writer needs to know about. Everything else in a\n * concrete run's status is opaque to it: capping `recentTools` and\n * `recentOutput` is the one piece of run semantics this module owns, because\n * it is the specific fix for the unbounded-growth bug above.\n */\nexport interface StatusWithRecentEntries {\n recentTools?: unknown[];\n recentOutput?: unknown[];\n}\n\nexport interface CoalescedStatusWriterContract<TStatus extends StatusWithRecentEntries = StatusWithRecentEntries> {\n /**\n * Start tracking a run's status and write it once, synchronously, so the\n * file exists before the caller does anything else.\n *\n * Calling this again, on the same or a different `runId`, is a reset, not\n * an error: it discards whatever was previously tracked, including any\n * mutation buffered by `update()` that had not flushed yet, cancels the\n * pending coalescing timer, and starts a fresh session against the new\n * status. This is deliberate so a runner that retries a bootstrap step can\n * just call `open()` again rather than having to detect and recover from a\n * half-initialized writer.\n */\n open(scope: SessionScope, runId: string, initialStatus: TStatus): void;\n /** Apply an in-memory mutation and let the trailing timer coalesce the write. */\n update(mutator: (status: TStatus) => void): void;\n /** Apply an in-memory mutation and flush synchronously, for transitions that must survive a crash. */\n updateSync(mutator: (status: TStatus) => void): void;\n /** Append one entry to `recentTools`, capped at 50, coalesced like `update()`. */\n appendTool(entry: unknown): void;\n /** Append one entry to `recentOutput`, capped at 50, coalesced like `update()`. */\n appendOutput(entry: unknown): void;\n /** Cancel any pending timer and flush whatever is dirty. Safe to call more than once. */\n close(): void;\n}\n\nexport class CoalescedStatusWriter<\n TStatus extends StatusWithRecentEntries = StatusWithRecentEntries,\n> implements CoalescedStatusWriterContract<TStatus> {\n /**\n * Runtime tuning seam for tests, kept out of the dependency constructor. A\n * test subclass overrides this to avoid waiting\n * out the real window when it does exercise the timer directly instead of\n * using fake timers.\n */\n protected readonly flushIntervalMs: number = DEFAULT_FLUSH_INTERVAL_MS;\n\n private statusPath: string | undefined;\n private status: TStatus | undefined;\n private dirtyCount = 0;\n private flushTimer: NodeJS.Timeout | undefined;\n\n open(scope: SessionScope, runId: string, initialStatus: TStatus): void {\n // A second open() is a reset: cancel whatever this instance was\n // previously tracking (including an unflushed dirty mutation) rather\n // than merging with it. See the doc comment on the interface method.\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = undefined;\n }\n this.statusPath = path.join(scopeRunsDir(scope), runId, STATUS_FILE_NAME);\n this.status = initialStatus;\n this.dirtyCount = 0;\n // The initial write is not a coalescing candidate: callers rely on the\n // file existing as soon as `open()` returns, so it always goes straight\n // to disk rather than waiting for a timer.\n writeAtomicJson(this.statusPath, this.clone(initialStatus));\n }\n\n update(mutator: (status: TStatus) => void): void {\n mutator(this.requireStatus());\n this.dirtyCount++;\n this.scheduleFlush();\n }\n\n updateSync(mutator: (status: TStatus) => void): void {\n mutator(this.requireStatus());\n this.dirtyCount++;\n this.flush();\n }\n\n appendTool(entry: unknown): void {\n this.update((status) => appendCapped(status, 'recentTools', entry));\n }\n\n appendOutput(entry: unknown): void {\n this.update((status) => appendCapped(status, 'recentOutput', entry));\n }\n\n close(): void {\n this.flush();\n }\n\n /**\n * The clone-and-write step. Protected so a test can override `clone()`\n * alone and assert it was never called across a run of no-op flushes,\n * which is the direct, observable proof that the dirty-counter gate works.\n */\n protected clone<T>(value: T): T {\n return structuredClone(value);\n }\n\n private flush(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = undefined;\n }\n if (this.dirtyCount === 0) return;\n const status = this.status;\n const statusPath = this.statusPath;\n if (!status || !statusPath) return;\n const snapshot = this.clone(status);\n this.dirtyCount = 0;\n writeAtomicJson(statusPath, snapshot);\n }\n\n private scheduleFlush(): void {\n if (this.flushTimer) return;\n const timer = setTimeout(() => this.flush(), this.flushIntervalMs);\n // A pending flush timer must never be the reason the process stays alive.\n timer.unref?.();\n this.flushTimer = timer;\n }\n\n private requireStatus(): TStatus {\n if (!this.status) throw new Error('CoalescedStatusWriter used before open().');\n return this.status;\n }\n}\n\n/** Push `entry` onto `status[field]`, dropping the oldest until at most 50 remain. */\nfunction appendCapped(status: StatusWithRecentEntries, field: 'recentTools' | 'recentOutput', entry: unknown): void {\n const list = status[field] ?? [];\n list.push(entry);\n if (list.length > MAX_RECENT_ENTRIES) list.splice(0, list.length - MAX_RECENT_ENTRIES);\n status[field] = list;\n}\n","/**\n * Detached child process for an explicitly selected external agent CLI.\n *\n * Launch, readiness, control, status, and completion use one bounded Node IPC\n * protocol. Durable status and result files are output records only. They are\n * never read to discover live state or coordinate the parent and child.\n */\n\nimport { spawn } from 'node:child_process';\nimport * as fs from 'node:fs';\n\nimport { createDoomTelemetry, type DoomTelemetry } from '@agimon-ai/po-telemetry';\n\nimport type { AsyncRunStatus } from '../services/asyncExecution';\nimport { writeAtomicJson, writePrivateAtomicJson } from '../services/atomicJson';\nimport { CLAUDE_FABLE_PROFILE, cleanupClaudeFableLaunch, parseClaudeFableOutput } from '../services/claudeFableProfile';\nimport type { CliLaunchConfig } from '../services/cliLaunchConfig';\nimport {\n EXTERNAL_IPC_CHANNEL,\n EXTERNAL_IPC_VERSION,\n parseExternalParentMessage,\n sendRunnerMessage,\n type ExternalRunProjection,\n type ExternalRunnerMessage,\n} from '../services/externalProcessIpc';\nimport { adoptSessionScopeFromEnv, type SessionScope } from '../services/sessionPaths';\nimport { CoalescedStatusWriter } from '../services/statusWriter';\nimport { SUBAGENT_ROOT_SESSION_ENV, SUBAGENT_RUN_ID_ENV } from '../types/environment';\n\nconst MAX_RESULT_BYTES = 64 * 1024;\nconst MAX_STDERR_BYTES = 8 * 1024;\nconst LAUNCH_TIMEOUT_MS = 15_000;\nconst PARENT_LOST_MESSAGE = 'Parent process was lost.';\nconst FORCE_KILL_SIGNAL: NodeJS.Signals = 'SIGKILL';\nconst STARTUP_ENVIRONMENT: Readonly<Record<string, string | undefined>> = Object.freeze({ ...process.env });\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction validateLaunchConfig(value: Record<string, unknown>, runId: string): CliLaunchConfig {\n if (\n value.runId !== runId ||\n typeof value.agent !== 'string' ||\n typeof value.task !== 'string' ||\n typeof value.runtime !== 'string' ||\n typeof value.command !== 'string' ||\n !Array.isArray(value.args) ||\n !value.args.every((entry) => typeof entry === 'string') ||\n typeof value.cwd !== 'string' ||\n !isRecord(value.env) ||\n typeof value.resultPath !== 'string'\n ) {\n throw new Error(`CLI launch config for run '${runId}' is invalid.`);\n }\n return value as unknown as CliLaunchConfig;\n}\n\nasync function receiveLaunchConfig(scope: SessionScope, runId: string): Promise<CliLaunchConfig> {\n return await new Promise<CliLaunchConfig>((resolve, reject) => {\n const finish = (error?: Error, config?: CliLaunchConfig): void => {\n clearTimeout(timer);\n process.off('message', onMessage);\n process.off('disconnect', onDisconnect);\n if (error) reject(error);\n else resolve(config!);\n };\n const onDisconnect = (): void => finish(new Error(PARENT_LOST_MESSAGE));\n const onMessage = (raw: unknown): void => {\n try {\n const message = parseExternalParentMessage(raw, { runId, scopeKey: scope.scopeKey });\n if (!message || message.kind !== 'launch') return;\n finish(undefined, validateLaunchConfig(message.config, runId));\n } catch (error) {\n finish(error instanceof Error ? error : new Error(String(error)));\n }\n };\n const timer = setTimeout(\n () => finish(new Error(`Timed out waiting for CLI launch config for run '${runId}'.`)),\n LAUNCH_TIMEOUT_MS,\n );\n timer.unref();\n process.on('message', onMessage);\n process.once('disconnect', onDisconnect);\n });\n}\n\nfunction appendBounded(buffer: string, chunk: string, limit: number): string {\n let combined = buffer + chunk;\n while (Buffer.byteLength(combined, 'utf8') > limit && combined.length > 0) {\n const excess = Buffer.byteLength(combined, 'utf8') - limit;\n combined = combined.slice(Math.max(1, Math.ceil(excess / 2)));\n }\n return combined;\n}\n\nlet childTelemetry: DoomTelemetry | undefined;\n\nasync function finishTelemetry(event: string, attributes: Record<string, unknown>, error?: unknown): Promise<void> {\n const telemetry = childTelemetry;\n childTelemetry = undefined;\n if (!telemetry) return;\n if (error === undefined) await telemetry.recordEvent(event, attributes);\n else await telemetry.recordError(event, error, attributes);\n await telemetry.flush();\n await telemetry.shutdown();\n}\n\nfunction projection(\n config: CliLaunchConfig,\n state: ExternalRunProjection['state'],\n startedAt: number,\n fields: Partial<Pick<ExternalRunProjection, 'summary' | 'error'>> = {},\n): ExternalRunProjection {\n return {\n runId: config.runId,\n agent: config.agent,\n task: config.sensitiveTask ? '' : config.task,\n runtime: config.runtime,\n state,\n startedAt,\n updatedAt: Date.now(),\n cwd: config.cwd,\n ...fields,\n };\n}\n\nfunction resultFor(\n config: CliLaunchConfig,\n success: boolean,\n summary: string,\n exit?: { code: number | null; signal: NodeJS.Signals | null },\n): Record<string, unknown> {\n return {\n runId: config.runId,\n ...(config.operationId ? { operationId: config.operationId } : {}),\n ...(config.internal ? { internal: true } : {}),\n agent: config.agent,\n runtime: config.runtime,\n success,\n summary,\n ...(exit?.code === null || exit?.code === undefined ? {} : { exitCode: exit.code }),\n ...(exit?.signal ? { signal: exit.signal } : {}),\n };\n}\n\nfunction runnerMessage(\n scope: SessionScope,\n runId: string,\n message:\n | { kind: 'ready' }\n | { kind: 'status'; status: ExternalRunProjection }\n | { kind: 'result'; result: Record<string, unknown> }\n | { kind: 'error'; error: string }\n | { kind: 'ack'; requestId: string; state: 'delivered' | 'failed'; message: string },\n): ExternalRunnerMessage {\n const base = {\n channel: EXTERNAL_IPC_CHANNEL,\n version: EXTERNAL_IPC_VERSION,\n direction: 'runner',\n runId,\n scopeKey: scope.scopeKey,\n } as const;\n if (message.kind === 'ack') return { ...base, ...message, command: 'steer' };\n return { ...base, ...message };\n}\n\nfunction send(scope: SessionScope, runId: string, message: Parameters<typeof runnerMessage>[2]): Promise<void> {\n return sendRunnerMessage(runnerMessage(scope, runId, message));\n}\n\nasync function run(): Promise<void> {\n const startedAt = Date.now();\n const runId = STARTUP_ENVIRONMENT[SUBAGENT_RUN_ID_ENV]?.trim();\n if (!runId) throw new Error(`${SUBAGENT_RUN_ID_ENV} is required.`);\n const scope = adoptSessionScopeFromEnv(STARTUP_ENVIRONMENT);\n if (!scope) {\n throw new Error(`${SUBAGENT_ROOT_SESSION_ENV} is required: a child cannot resolve its session scope without it.`);\n }\n const config = await receiveLaunchConfig(scope, runId);\n\n childTelemetry = createDoomTelemetry({\n serviceName: 'doom-team-cli-child',\n packageName: '@agimon-ai/po-team',\n env: config.env,\n enableLogs: true,\n enableTraces: true,\n });\n\n const statusWriter = new CoalescedStatusWriter<AsyncRunStatus>();\n statusWriter.open(scope, runId, {\n version: 1,\n runId,\n ...(config.operationId ? { operationId: config.operationId } : {}),\n agent: config.agent,\n ...(config.sensitiveTask ? {} : { task: config.task }),\n cwd: config.cwd,\n runtime: config.runtime,\n state: 'queued',\n startedAt,\n lastUpdate: startedAt,\n });\n\n await childTelemetry.recordEvent('doom_team.child_started', {\n runtime: config.runtime,\n 'agent.name': config.agent,\n outcome: 'started',\n });\n\n const profileLaunch = config.profile === CLAUDE_FABLE_PROFILE;\n if (config.profile !== undefined && !profileLaunch) throw new Error('Untrusted external profile.');\n if (profileLaunch && (!config.stdinPath || !config.profileResultPath)) {\n throw new Error('Fable profile launch config is incomplete.');\n }\n\n const stdinFd = profileLaunch ? fs.openSync(config.stdinPath!, 'r') : undefined;\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(config.command, config.args, {\n cwd: config.cwd,\n env: config.env,\n stdio: [stdinFd ?? 'ignore', 'pipe', 'pipe'],\n detached: true,\n windowsHide: true,\n });\n } finally {\n if (stdinFd !== undefined) fs.closeSync(stdinFd);\n }\n\n const cleanupProfile = (removeResult: boolean): void => {\n if (!profileLaunch) return;\n cleanupClaudeFableLaunch({ cleanupPaths: config.cleanupPaths ?? [] });\n if (removeResult && config.profileResultPath) fs.rmSync(config.profileResultPath, { force: true });\n };\n\n let requestedSignal: NodeJS.Signals | undefined;\n let finalizing = false;\n const stopVendor = (signal: NodeJS.Signals): void => {\n requestedSignal = signal;\n if (!child.pid) return;\n try {\n process.kill(-child.pid, signal);\n } catch (error) {\n process.stderr.write(`[doom-team cli runner] Could not signal vendor process: ${errorMessage(error)}\\n`);\n }\n };\n const onSigterm = (): void => stopVendor('SIGTERM');\n const onSigint = (): void => stopVendor('SIGINT');\n process.once('SIGTERM', onSigterm);\n process.once('SIGINT', onSigint);\n\n const onControl = (raw: unknown): void => {\n const message = parseExternalParentMessage(raw, { runId, scopeKey: scope.scopeKey });\n if (!message || message.kind !== 'control') return;\n if (message.command === 'steer') {\n void send(scope, runId, {\n kind: 'ack',\n requestId: message.requestId,\n state: 'failed',\n message: `Runtime '${config.runtime}' does not support live steering.`,\n });\n return;\n }\n stopVendor(message.command === 'interrupt' ? 'SIGINT' : 'SIGTERM');\n };\n process.on('message', onControl);\n\n const onParentLost = (): void => {\n if (finalizing) return;\n finalizing = true;\n stopVendor(FORCE_KILL_SIGNAL);\n const endedAt = Date.now();\n statusWriter.updateSync((status) => {\n status.state = 'stopped';\n status.error = PARENT_LOST_MESSAGE;\n status.lastUpdate = endedAt;\n status.endedAt = endedAt;\n });\n writeAtomicJson(config.resultPath, {\n ...resultFor(config, false, PARENT_LOST_MESSAGE, { code: null, signal: FORCE_KILL_SIGNAL }),\n state: 'stopped',\n ...(config.internal ? { internal: true } : {}),\n });\n statusWriter.close();\n cleanupProfile(true);\n void finishTelemetry('doom_team.child_finished', {\n runtime: config.runtime,\n 'agent.name': config.agent,\n duration_ms: Date.now() - startedAt,\n outcome: 'parent_lost',\n }).finally(() => process.exit(0));\n };\n process.once('disconnect', onParentLost);\n\n try {\n await new Promise<void>((resolve, reject) => {\n child.once('spawn', resolve);\n child.once('error', reject);\n });\n const running = projection(config, 'running', startedAt);\n statusWriter.updateSync((status) => {\n status.state = 'running';\n status.activityState = 'working';\n status.lastUpdate = Date.now();\n });\n await send(scope, runId, { kind: 'status', status: running });\n await send(scope, runId, { kind: 'ready' });\n } catch (error) {\n finalizing = true;\n const message = errorMessage(error);\n const endedAt = Date.now();\n const result = {\n ...resultFor(config, false, profileLaunch ? 'Fable Claude launch failed.' : message),\n state: 'failed',\n };\n statusWriter.updateSync((status) => {\n status.state = 'failed';\n status.error = message;\n status.lastUpdate = endedAt;\n status.endedAt = endedAt;\n });\n writeAtomicJson(config.resultPath, { ...result, ...(config.internal ? { internal: true } : {}) });\n await send(scope, runId, { kind: 'error', error: message });\n await send(scope, runId, { kind: 'result', result });\n statusWriter.close();\n cleanupProfile(true);\n await finishTelemetry(\n 'doom_team.child_failed',\n { runtime: config.runtime, 'agent.name': config.agent, duration_ms: Date.now() - startedAt, outcome: 'failed' },\n error,\n );\n process.exit(1);\n }\n\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout = appendBounded(stdout, chunk.toString('utf8'), MAX_RESULT_BYTES);\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr = appendBounded(stderr, chunk.toString('utf8'), MAX_STDERR_BYTES);\n });\n\n const exit = await new Promise<{ code: number | null; signal: NodeJS.Signals | null; error?: Error }>((resolve) => {\n child.on('error', (error) => resolve({ code: null, signal: null, error }));\n child.on('close', (code, signal) => resolve({ code, signal }));\n });\n finalizing = true;\n process.off('message', onControl);\n process.off('disconnect', onParentLost);\n process.off('SIGTERM', onSigterm);\n process.off('SIGINT', onSigint);\n\n const stopped = requestedSignal !== undefined;\n let profileError: Error | undefined;\n if (profileLaunch && !stopped && exit.error === undefined && exit.code === 0) {\n try {\n const parsed = parseClaudeFableOutput(stdout);\n writePrivateAtomicJson(config.profileResultPath!, { text: parsed.text, outputBytes: parsed.outputBytes });\n } catch (error) {\n profileError = error instanceof Error ? error : new Error(String(error));\n }\n }\n\n const success = !stopped && exit.error === undefined && exit.code === 0 && profileError === undefined;\n const failureDetail = profileLaunch\n ? (profileError?.message ?? 'Fable Claude launch failed.')\n : stderr.trim() || `${config.runtime} exited with ${exit.signal ?? `code ${exit.code ?? 'unknown'}`}.`;\n const summary = stopped\n ? `Stopped by ${requestedSignal}.`\n : success\n ? profileLaunch\n ? 'Fable profile completed.'\n : stdout.trim()\n : (exit.error?.message ?? failureDetail);\n const endedAt = Date.now();\n const state = stopped ? ('stopped' as const) : success ? ('completed' as const) : ('failed' as const);\n const result = { ...resultFor(config, success, summary, exit), state };\n\n statusWriter.updateSync((status) => {\n status.state = state;\n status.activityState = 'finalizing';\n status.summary = summary;\n if (!success) status.error = summary;\n status.lastUpdate = endedAt;\n status.endedAt = endedAt;\n });\n writeAtomicJson(config.resultPath, { ...result, ...(config.internal ? { internal: true } : {}) });\n await send(scope, runId, {\n kind: 'status',\n status: projection(config, state, startedAt, {\n summary,\n ...(!success ? { error: summary } : {}),\n }),\n });\n await send(scope, runId, { kind: 'result', result });\n\n statusWriter.close();\n cleanupProfile(!success);\n await finishTelemetry('doom_team.child_finished', {\n runtime: config.runtime,\n 'agent.name': config.agent,\n duration_ms: Date.now() - startedAt,\n 'runner.stdout_bytes': Buffer.byteLength(stdout, 'utf8'),\n 'runner.stderr_bytes': Buffer.byteLength(stderr, 'utf8'),\n 'runner.exit_code': exit.code ?? 0,\n outcome: state,\n });\n process.exit(0);\n}\n\nvoid run().catch(async (error: unknown) => {\n const runId = STARTUP_ENVIRONMENT[SUBAGENT_RUN_ID_ENV]?.trim();\n const scope = adoptSessionScopeFromEnv(STARTUP_ENVIRONMENT);\n if (runId && scope && process.connected) {\n try {\n await send(scope, runId, { kind: 'error', error: errorMessage(error) });\n } catch {\n // The parent channel is already gone, so stderr is the only remaining diagnostic.\n }\n }\n await finishTelemetry('doom_team.child_failed', { outcome: 'failed' }, error);\n process.stderr.write(`[doom-team cli runner] ${errorMessage(error)}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_subagentPolicy = require("./subagentPolicy-DQRyKDH-.cjs");
|
|
3
|
+
exports.DOOM_SUBAGENT_POLICY_SERVICE = require_subagentPolicy.DOOM_SUBAGENT_POLICY_SERVICE;
|
|
4
|
+
exports.SubagentPolicySchema = require_subagentPolicy.SubagentPolicySchema;
|
|
5
|
+
exports.readDoomSubagentPolicyService = require_subagentPolicy.readDoomSubagentPolicyService;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as SubagentPolicySchema, i as SubagentPolicyHandle, n as DoomSubagentPolicyService, o as readDoomSubagentPolicyService, r as SubagentPolicy, t as DOOM_SUBAGENT_POLICY_SERVICE } from "./subagentPolicy-ALJam4GN.mjs";
|
|
2
|
+
export { DOOM_SUBAGENT_POLICY_SERVICE, DoomSubagentPolicyService, SubagentPolicy, SubagentPolicyHandle, SubagentPolicySchema, readDoomSubagentPolicyService };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_subagentTool = require("./subagentTool-Ca2zQXKw.cjs");
|
|
3
|
+
let _agimon_ai_po_core_delegation = require("@agimon-ai/po-core/delegation");
|
|
4
|
+
exports.InlineAgentSchema = _agimon_ai_po_core_delegation.InlineAgentSchema;
|
|
5
|
+
exports.SUBAGENT_ACTIONS = require_subagentTool.SUBAGENT_ACTIONS;
|
|
6
|
+
exports.SUBAGENT_ACTION_FIELDS = require_subagentTool.SUBAGENT_ACTION_FIELDS;
|
|
7
|
+
exports.SubagentParams = require_subagentTool.SubagentParams;
|
|
8
|
+
exports.SubagentToolSchema = require_subagentTool.SubagentToolSchema;
|
|
9
|
+
exports.isSubagentAction = require_subagentTool.isSubagentAction;
|
|
10
|
+
exports.normalizeSubagentToolParams = require_subagentTool.normalizeSubagentToolParams;
|
|
11
|
+
exports.subagentActionAcceptsField = require_subagentTool.subagentActionAcceptsField;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as SubagentAction, c as SubagentToolSchema, d as subagentActionAcceptsField, i as SUBAGENT_ACTION_FIELDS, l as isSubagentAction, n as InlineAgentSchema, o as SubagentParams, r as SUBAGENT_ACTIONS, s as SubagentToolParams, t as InlineAgent, u as normalizeSubagentToolParams } from "./subagentTool-BTssGLw8.mjs";
|
|
2
|
+
export { type InlineAgent, InlineAgentSchema, SUBAGENT_ACTIONS, SUBAGENT_ACTION_FIELDS, SubagentAction, SubagentParams, SubagentToolParams, SubagentToolSchema, isSubagentAction, normalizeSubagentToolParams, subagentActionAcceptsField };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as SubagentToolSchema, c as subagentActionAcceptsField, i as SubagentParams, n as SUBAGENT_ACTIONS, o as isSubagentAction, r as SUBAGENT_ACTION_FIELDS, s as normalizeSubagentToolParams, t as InlineAgentSchema } from "./subagentTool-WOYrjxgT.mjs";
|
|
2
|
+
export { InlineAgentSchema, SUBAGENT_ACTIONS, SUBAGENT_ACTION_FIELDS, SubagentParams, SubagentToolSchema, isSubagentAction, normalizeSubagentToolParams, subagentActionAcceptsField };
|