harnery 0.15.0 → 0.16.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/README.md +1 -1
- package/dist/commands/supervisor.d.ts.map +1 -1
- package/dist/commands/supervisor.js +210 -2
- package/dist/core/supervisor/index.d.ts +1 -0
- package/dist/core/supervisor/index.d.ts.map +1 -1
- package/dist/core/supervisor/index.js +1 -0
- package/dist/core/supervisor/read.d.ts +2 -0
- package/dist/core/supervisor/read.d.ts.map +1 -1
- package/dist/core/supervisor/read.js +1 -0
- package/dist/core/supervisor/service-read.d.ts +6 -0
- package/dist/core/supervisor/service-read.d.ts.map +1 -0
- package/dist/core/supervisor/service-read.js +127 -0
- package/dist/core/supervisor/service.d.ts +114 -0
- package/dist/core/supervisor/service.d.ts.map +1 -0
- package/dist/core/supervisor/service.js +699 -0
- package/dist/lib/tunnel/gate.d.ts.map +1 -1
- package/dist/lib/tunnel/gate.js +6 -1
- package/package.json +1 -1
- package/src/commands/supervisor.ts +261 -1
- package/src/core/supervisor/index.ts +27 -0
- package/src/core/supervisor/read.ts +15 -0
- package/src/core/supervisor/service-read.ts +144 -0
- package/src/core/supervisor/service.ts +920 -0
- package/src/lib/tunnel/gate.ts +7 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
- **Cross-machine presence:** sessions on every machine that shares a repo see each other, labeled by machine. Zero-config over the repo's own git remote (presence refs), with an optional live-socket upgrade via an end-to-end-encrypted relay — the public `relay.harnery.com`, or self-host with `harn relay serve` / the bundled Cloudflare Worker (`relay/worker/`). The relay sees only ciphertext in opaquely-named rooms.
|
|
24
24
|
- **Coordination-aware workflows:** `harn workflow run <script>` executes bounded, schema-gated multi-subagent workflow scripts — plain JS stages fanning out to headless harness-CLI subagents that are born coordination-registered (heartbeats, events, claim guards), with deterministic code deciding the routing between stages. An optional host-owned policy gates dispatch and declared external mutations with `ALLOW`, `ASK`, and `DENY`; CLI `ASK` requests park durably for an explicit approve/deny and same-run resume, while library callers remain fail-closed by default.
|
|
25
25
|
- **Durable work above attempts:** `harn work` preserves an objective across bounded workflow attempts, dependencies, approval parks, failures, and review. Its one-shot reconciler derives state from append-only local evidence and reports the next explicit action without silently spawning, retrying, or accepting work.
|
|
26
|
-
- **Bounded goal supervision:** `harn supervisor` freezes a specialist team and safety limits around a root durable-work graph, then runs
|
|
26
|
+
- **Bounded goal supervision:** `harn supervisor` freezes a specialist team and safety limits around a root durable-work graph, then runs scheduling cycles until success, human attention, no progress, or budget exhaustion. Use explicit foreground ticks or enroll goals in the optional heartbeat-backed background service; specialist roles survive as configuration while every child remains a bounded process.
|
|
27
27
|
- **Standalone web UI:** `harn web up` boots a local Next.js dashboard for the coord layer, councils, per-project state, and a local coding-agent status view (Claude Code / Codex / Cursor usage, backed by `harn devtools`). Ships with the git clone, not the npm package (see [Install](#install)).
|
|
28
28
|
- **Backup + sync:** `harn backup` snapshots `.harnery/` via [restic](https://restic.net/); `harn sync` keeps a curated subset live across machines via [rclone](https://rclone.org/) (Google Drive or any rclone remote).
|
|
29
29
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/commands/supervisor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/commands/supervisor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA4DnD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA2FnF"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { workflowSubscriptionOnly } from "../core/config.js";
|
|
4
4
|
import { createBuiltinHarnessRegistry } from "../core/harnesses/index.js";
|
|
5
5
|
import { findCoordRoot } from "../core/hooks/resolve/coord-root.js";
|
|
6
6
|
import { loadPolicyFile } from "../core/policy/index.js";
|
|
7
|
-
import { createSupervisor, listSupervisors, readSupervisor, runSupervisor, } from "../core/supervisor/index.js";
|
|
7
|
+
import { configureSupervisorService, createSupervisor, listSupervisors, readSupervisor, readSupervisorServiceConfig, readSupervisorServiceStatus, requestSupervisorServiceStop, runSupervisor, runSupervisorServiceDaemon, spawnSupervisorService, supervisorServiceLogPath, } from "../core/supervisor/index.js";
|
|
8
8
|
export function registerSupervisorCommand(program, emit) {
|
|
9
9
|
const registry = createBuiltinHarnessRegistry();
|
|
10
10
|
const supervisor = program
|
|
@@ -84,9 +84,214 @@ export function registerSupervisorCommand(program, emit) {
|
|
|
84
84
|
emitSupervisor(readSupervisor(coordRoot, goalId), opts.json, emit, true);
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
|
+
registerServiceCommand(supervisor, registry, emit);
|
|
87
88
|
registerRunCommand(supervisor, "tick", registry, emit);
|
|
88
89
|
registerRunCommand(supervisor, "run", registry, emit);
|
|
89
90
|
}
|
|
91
|
+
function registerServiceCommand(supervisor, registry, emit) {
|
|
92
|
+
const service = supervisor
|
|
93
|
+
.command("service")
|
|
94
|
+
.description("Run explicitly enrolled durable goals in a restartable background service.");
|
|
95
|
+
addServiceOptions(service
|
|
96
|
+
.command("start [goal-ids...]")
|
|
97
|
+
.description("Configure and start the detached per-repository supervisor service."))
|
|
98
|
+
.option("--json", "Emit complete service status as JSON")
|
|
99
|
+
.action(async (goalIds, opts) => {
|
|
100
|
+
await withSupervisorRootAsync(emit, async (coordRoot) => {
|
|
101
|
+
prepareServiceConfig(coordRoot, goalIds, opts, registry);
|
|
102
|
+
const status = await spawnSupervisorService(coordRoot);
|
|
103
|
+
emitServiceStatus(status, opts.json, emit);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
addServiceOptions(service
|
|
107
|
+
.command("run [goal-ids...]")
|
|
108
|
+
.description("Run the persistent service loop in the foreground for a process manager."))
|
|
109
|
+
.option("--json", "Emit terminal service status as JSON")
|
|
110
|
+
.action(async (goalIds, opts) => {
|
|
111
|
+
await withSupervisorRootAsync(emit, async (coordRoot) => {
|
|
112
|
+
const config = prepareServiceConfig(coordRoot, goalIds, opts, registry);
|
|
113
|
+
const status = await runSupervisorServiceDaemon({
|
|
114
|
+
coordRoot,
|
|
115
|
+
engine: serviceEngine(config, registry),
|
|
116
|
+
onLog: opts.json ? undefined : (line) => emit.text(`${line}\n`),
|
|
117
|
+
});
|
|
118
|
+
if (opts.json) {
|
|
119
|
+
emit.config({ format: "json" });
|
|
120
|
+
emit.data(status);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
service
|
|
125
|
+
.command("status")
|
|
126
|
+
.description("Show service liveness, heartbeat, enrolled goals, and durable wake state.")
|
|
127
|
+
.option("--json", "Emit complete service status as JSON")
|
|
128
|
+
.action((opts) => {
|
|
129
|
+
withSupervisorRoot(emit, (coordRoot) => {
|
|
130
|
+
emitServiceStatus(readSupervisorServiceStatus(coordRoot), opts.json, emit);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
service
|
|
134
|
+
.command("stop")
|
|
135
|
+
.description("Request a graceful stop; an active goal tick is allowed to finish safely.")
|
|
136
|
+
.option("--json", "Emit complete service status as JSON")
|
|
137
|
+
.action(async (opts) => {
|
|
138
|
+
await withSupervisorRootAsync(emit, async (coordRoot) => {
|
|
139
|
+
let status = requestSupervisorServiceStop(coordRoot);
|
|
140
|
+
const deadline = Date.now() + 5_000;
|
|
141
|
+
while (status.running && Date.now() < deadline) {
|
|
142
|
+
await delay(50);
|
|
143
|
+
status = readSupervisorServiceStatus(coordRoot);
|
|
144
|
+
}
|
|
145
|
+
emitServiceStatus(status, opts.json, emit);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
service
|
|
149
|
+
.command("logs")
|
|
150
|
+
.description("Show the tail of the private background-service log.")
|
|
151
|
+
.option("--lines <n>", "Number of lines to show (default 50)", "50")
|
|
152
|
+
.action((opts) => {
|
|
153
|
+
withSupervisorRoot(emit, (coordRoot) => {
|
|
154
|
+
const lines = integer(opts.lines) ?? 50;
|
|
155
|
+
if (lines > 10_000)
|
|
156
|
+
throw new Error("service log lines must not exceed 10000");
|
|
157
|
+
const path = supervisorServiceLogPath(coordRoot);
|
|
158
|
+
if (!existsSync(path)) {
|
|
159
|
+
emit.text("no supervisor service log\n");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const selected = readFileSync(path, "utf8")
|
|
163
|
+
.split("\n")
|
|
164
|
+
.slice(-(lines + 1))
|
|
165
|
+
.join("\n");
|
|
166
|
+
emit.text(selected.endsWith("\n") ? selected : `${selected}\n`);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
service
|
|
170
|
+
.command("daemon", { hidden: true })
|
|
171
|
+
.description("Internal detached service entrypoint.")
|
|
172
|
+
.action(async () => {
|
|
173
|
+
await withSupervisorRootAsync(emit, async (coordRoot) => {
|
|
174
|
+
const config = readSupervisorServiceConfig(coordRoot);
|
|
175
|
+
await runSupervisorServiceDaemon({
|
|
176
|
+
coordRoot,
|
|
177
|
+
engine: serviceEngine(config, registry),
|
|
178
|
+
onLog: (line) => emit.text(`${line}\n`),
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function addServiceOptions(command) {
|
|
184
|
+
return command
|
|
185
|
+
.option("--wake-interval-ms <n>", "State-change poll interval (default 5000)")
|
|
186
|
+
.option("--heartbeat-interval-ms <n>", "Heartbeat interval (default 2000)")
|
|
187
|
+
.option("--error-backoff-base-ms <n>", "Initial service-error backoff (default 2000)")
|
|
188
|
+
.option("--error-backoff-max-ms <n>", "Maximum service-error backoff (default 300000)")
|
|
189
|
+
.option("--harness <name>", "Fallback harness for agent calls without a specialist")
|
|
190
|
+
.option("--cwd <dir>", "Working directory for child agents")
|
|
191
|
+
.option("--subscription-only", "Require stored harness-login billing")
|
|
192
|
+
.option("--allow-api-billing", "Permit API-key override billing")
|
|
193
|
+
.option("--policy <file>", "Host policy JSON/JSONC")
|
|
194
|
+
.option("--isolation <mode>", "shared | worktree | sandbox | remote")
|
|
195
|
+
.option("--approval-to <address>", "Address durable ASK requests");
|
|
196
|
+
}
|
|
197
|
+
function prepareServiceConfig(coordRoot, goalIds, opts, registry) {
|
|
198
|
+
if (goalIds.length === 0) {
|
|
199
|
+
if (hasServiceConfigOverrides(opts)) {
|
|
200
|
+
throw new Error("goal ids are required when changing supervisor service options");
|
|
201
|
+
}
|
|
202
|
+
return readSupervisorServiceConfig(coordRoot);
|
|
203
|
+
}
|
|
204
|
+
if (opts.harness && !registry.get(opts.harness)) {
|
|
205
|
+
throw new Error(`unknown harness ${JSON.stringify(opts.harness)}`);
|
|
206
|
+
}
|
|
207
|
+
const policy = opts.policy ? loadPolicyFile(opts.policy) : undefined;
|
|
208
|
+
return configureSupervisorService({
|
|
209
|
+
coordRoot,
|
|
210
|
+
goalIds,
|
|
211
|
+
wakeIntervalMs: integer(opts.wakeIntervalMs),
|
|
212
|
+
heartbeatIntervalMs: integer(opts.heartbeatIntervalMs),
|
|
213
|
+
errorBackoffBaseMs: integer(opts.errorBackoffBaseMs),
|
|
214
|
+
errorBackoffMaxMs: integer(opts.errorBackoffMaxMs),
|
|
215
|
+
engine: {
|
|
216
|
+
default_harness: opts.harness,
|
|
217
|
+
cwd: opts.cwd,
|
|
218
|
+
subscription_only: opts.subscriptionOnly === true ? true : workflowSubscriptionOnly(coordRoot),
|
|
219
|
+
allow_api_billing: opts.allowApiBilling,
|
|
220
|
+
policy,
|
|
221
|
+
isolation: opts.isolation,
|
|
222
|
+
approval_addressee: opts.approvalTo,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function hasServiceConfigOverrides(opts) {
|
|
227
|
+
return Boolean(opts.wakeIntervalMs ||
|
|
228
|
+
opts.heartbeatIntervalMs ||
|
|
229
|
+
opts.errorBackoffBaseMs ||
|
|
230
|
+
opts.errorBackoffMaxMs ||
|
|
231
|
+
opts.harness ||
|
|
232
|
+
opts.cwd ||
|
|
233
|
+
opts.subscriptionOnly ||
|
|
234
|
+
opts.allowApiBilling ||
|
|
235
|
+
opts.policy ||
|
|
236
|
+
opts.isolation ||
|
|
237
|
+
opts.approvalTo);
|
|
238
|
+
}
|
|
239
|
+
function serviceEngine(config, registry) {
|
|
240
|
+
return {
|
|
241
|
+
spawners: registry.spawners(),
|
|
242
|
+
defaultHarness: config.engine.default_harness,
|
|
243
|
+
cwd: config.engine.cwd,
|
|
244
|
+
subscriptionOnly: config.engine.subscription_only,
|
|
245
|
+
allowApiBilling: config.engine.allow_api_billing,
|
|
246
|
+
harnessEvidence: Object.fromEntries(registry
|
|
247
|
+
.list()
|
|
248
|
+
.map((adapter) => [
|
|
249
|
+
adapter.profile.id,
|
|
250
|
+
{ toolEvidence: adapter.profile.capabilities.toolEvidence },
|
|
251
|
+
])),
|
|
252
|
+
policy: config.engine.policy,
|
|
253
|
+
approvalMode: "park",
|
|
254
|
+
approvalAddressee: config.engine.approval_addressee,
|
|
255
|
+
isolation: config.engine.isolation,
|
|
256
|
+
networkAccess: "enabled",
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function emitServiceStatus(status, json, emit) {
|
|
260
|
+
if (json) {
|
|
261
|
+
emit.config({ format: "json" });
|
|
262
|
+
emit.data(status);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (!status.config && !status.record) {
|
|
266
|
+
emit.text("supervisor service: unconfigured\n");
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const state = status.running
|
|
270
|
+
? (status.record?.state ?? "running")
|
|
271
|
+
: status.stale
|
|
272
|
+
? "stale"
|
|
273
|
+
: "stopped";
|
|
274
|
+
const lines = [
|
|
275
|
+
`supervisor service: ${state}`,
|
|
276
|
+
`goals: ${status.config?.goal_ids.join(", ") || "none"}`,
|
|
277
|
+
];
|
|
278
|
+
if (status.record) {
|
|
279
|
+
lines.push(`pid: ${status.record.pid} on ${status.record.host}`);
|
|
280
|
+
lines.push(`heartbeat: ${status.record.heartbeat_at}`);
|
|
281
|
+
lines.push(`sweeps: ${status.record.sweep_count}`);
|
|
282
|
+
if (status.record.active_goal_id)
|
|
283
|
+
lines.push(`active: ${status.record.active_goal_id}`);
|
|
284
|
+
if (status.record.next_wake_at)
|
|
285
|
+
lines.push(`next wake: ${status.record.next_wake_at}`);
|
|
286
|
+
if (status.record.last_error)
|
|
287
|
+
lines.push(`error: ${status.record.last_error}`);
|
|
288
|
+
}
|
|
289
|
+
const backingOff = Object.entries(status.runtime?.goals ?? {}).filter(([, runtime]) => runtime.state === "backoff");
|
|
290
|
+
if (backingOff.length) {
|
|
291
|
+
lines.push(`backoff: ${backingOff.map(([goalId]) => goalId).join(", ")}`);
|
|
292
|
+
}
|
|
293
|
+
emit.text(`${lines.join("\n")}\n`);
|
|
294
|
+
}
|
|
90
295
|
function registerRunCommand(supervisor, mode, registry, emit) {
|
|
91
296
|
supervisor
|
|
92
297
|
.command(`${mode} <goal-id>`)
|
|
@@ -200,6 +405,9 @@ function integer(value) {
|
|
|
200
405
|
throw new Error(`expected a positive integer, got ${JSON.stringify(value)}`);
|
|
201
406
|
return Number.parseInt(value, 10);
|
|
202
407
|
}
|
|
408
|
+
function delay(ms) {
|
|
409
|
+
return new Promise((resolveDelay) => setTimeout(resolveDelay, ms));
|
|
410
|
+
}
|
|
203
411
|
function withSupervisorRoot(emit, fn) {
|
|
204
412
|
const coordRoot = findCoordRoot();
|
|
205
413
|
if (!coordRoot) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { type RunSupervisorInput, runSupervisor, type SupervisorDispatchOutcome, type SupervisorRunReport, type SupervisorStopReason, } from "./runner.js";
|
|
2
|
+
export { type ConfigureSupervisorServiceInput, configureSupervisorService, type RunSupervisorServiceDaemonInput, type RunSupervisorServiceSweepInput, readSupervisorServiceConfig, readSupervisorServiceRuntime, readSupervisorServiceStatus, requestSupervisorServiceStop, runSupervisorServiceDaemon, runSupervisorServiceSweep, SUPERVISOR_SERVICE_CONFIG_SCHEMA_VERSION, SUPERVISOR_SERVICE_RUNTIME_SCHEMA_VERSION, SUPERVISOR_SERVICE_STATUS_SCHEMA_VERSION, type SupervisorServiceConfig, type SupervisorServiceEngineConfig, type SupervisorServiceGoalRuntime, type SupervisorServiceGoalState, type SupervisorServiceProcessState, type SupervisorServiceRuntime, type SupervisorServiceStatus, type SupervisorServiceStatusRecord, type SupervisorServiceSweepOutcome, type SupervisorServiceSweepReport, spawnSupervisorService, supervisorServiceLogPath, } from "./service.js";
|
|
2
3
|
export { assertSupervisorId, type CreateSupervisorInput, collectSupervisorWork, createSupervisor, listSupervisors, newSupervisorId, readSupervisor, SUPERVISOR_INTENT_SCHEMA_VERSION, type SupervisorAutomationPolicy, type SupervisorIntent, type SupervisorLimits, type SupervisorNextAction, type SupervisorProjection, type SupervisorRecord, type SupervisorState, } from "./state.js";
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,aAAa,EACb,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,gCAAgC,EAChC,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,aAAa,EACb,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,+BAA+B,EACpC,0BAA0B,EAC1B,KAAK,+BAA+B,EACpC,KAAK,8BAA8B,EACnC,2BAA2B,EAC3B,4BAA4B,EAC5B,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,wCAAwC,EACxC,yCAAyC,EACzC,wCAAwC,EACxC,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EAClC,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,gCAAgC,EAChC,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { runSupervisor, } from "./runner.js";
|
|
2
|
+
export { configureSupervisorService, readSupervisorServiceConfig, readSupervisorServiceRuntime, readSupervisorServiceStatus, requestSupervisorServiceStop, runSupervisorServiceDaemon, runSupervisorServiceSweep, SUPERVISOR_SERVICE_CONFIG_SCHEMA_VERSION, SUPERVISOR_SERVICE_RUNTIME_SCHEMA_VERSION, SUPERVISOR_SERVICE_STATUS_SCHEMA_VERSION, spawnSupervisorService, supervisorServiceLogPath, } from "./service.js";
|
|
2
3
|
export { assertSupervisorId, collectSupervisorWork, createSupervisor, listSupervisors, newSupervisorId, readSupervisor, SUPERVISOR_INTENT_SCHEMA_VERSION, } from "./state.js";
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
export type { SupervisorServiceConfig, SupervisorServiceGoalRuntime, SupervisorServiceGoalState, SupervisorServiceProcessState, SupervisorServiceRuntime, SupervisorServiceStatus, SupervisorServiceStatusRecord, } from "./service.js";
|
|
2
|
+
export { readSupervisorServiceConfig, readSupervisorServiceRuntime, readSupervisorServiceStatus, supervisorServiceLogPath, } from "./service-read.js";
|
|
1
3
|
export { assertSupervisorId, collectSupervisorWork, listSupervisors, readSupervisor, SUPERVISOR_INTENT_SCHEMA_VERSION, type SupervisorAutomationPolicy, type SupervisorIntent, type SupervisorLimits, type SupervisorNextAction, type SupervisorProjection, type SupervisorRecord, type SupervisorState, } from "./state.js";
|
|
2
4
|
//# sourceMappingURL=read.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/read.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,gCAAgC,EAChC,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/read.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,EAC1B,6BAA6B,EAC7B,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,gCAAgC,EAChC,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
+
export { readSupervisorServiceConfig, readSupervisorServiceRuntime, readSupervisorServiceStatus, supervisorServiceLogPath, } from "./service-read.js";
|
|
1
2
|
export { assertSupervisorId, collectSupervisorWork, listSupervisors, readSupervisor, SUPERVISOR_INTENT_SCHEMA_VERSION, } from "./state.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SupervisorServiceConfig, SupervisorServiceRuntime, SupervisorServiceStatus } from "./service.js";
|
|
2
|
+
export declare function readSupervisorServiceConfig(coordRootRaw: string): SupervisorServiceConfig;
|
|
3
|
+
export declare function readSupervisorServiceRuntime(coordRootRaw: string): SupervisorServiceRuntime | undefined;
|
|
4
|
+
export declare function readSupervisorServiceStatus(coordRootRaw: string): SupervisorServiceStatus;
|
|
5
|
+
export declare function supervisorServiceLogPath(coordRoot: string): string;
|
|
6
|
+
//# sourceMappingURL=service-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-read.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/service-read.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EAExB,MAAM,cAAc,CAAC;AAMtB,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,uBAAuB,CA0BzF;AAED,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,GACnB,wBAAwB,GAAG,SAAS,CAgBtC;AAED,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,uBAAuB,CAkBzF;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAElE"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { hostname } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
const MAX_FILE_BYTES = 512 * 1024;
|
|
5
|
+
const MAX_GOALS = 100;
|
|
6
|
+
const FOREIGN_STATUS_STALE_MS = 30_000;
|
|
7
|
+
export function readSupervisorServiceConfig(coordRootRaw) {
|
|
8
|
+
const coordRoot = resolve(coordRootRaw);
|
|
9
|
+
const config = readBoundedJson(join(serviceDir(coordRoot), "config.json"), "supervisor service configuration");
|
|
10
|
+
if (config.schema_version !== 1 ||
|
|
11
|
+
!validTimestamp(config.created_at) ||
|
|
12
|
+
!Array.isArray(config.goal_ids) ||
|
|
13
|
+
config.goal_ids.length < 1 ||
|
|
14
|
+
config.goal_ids.length > MAX_GOALS ||
|
|
15
|
+
config.goal_ids.some((goalId) => typeof goalId !== "string" || !goalId.trim()) ||
|
|
16
|
+
!positive(config.wake_interval_ms) ||
|
|
17
|
+
!positive(config.heartbeat_interval_ms) ||
|
|
18
|
+
!positive(config.error_backoff_base_ms) ||
|
|
19
|
+
!positive(config.error_backoff_max_ms) ||
|
|
20
|
+
config.error_backoff_max_ms < config.error_backoff_base_ms ||
|
|
21
|
+
!config.engine ||
|
|
22
|
+
typeof config.engine !== "object" ||
|
|
23
|
+
typeof config.engine.subscription_only !== "boolean" ||
|
|
24
|
+
typeof config.engine.allow_api_billing !== "boolean") {
|
|
25
|
+
throw new Error("supervisor service configuration has an unsupported schema");
|
|
26
|
+
}
|
|
27
|
+
return config;
|
|
28
|
+
}
|
|
29
|
+
export function readSupervisorServiceRuntime(coordRootRaw) {
|
|
30
|
+
const coordRoot = resolve(coordRootRaw);
|
|
31
|
+
const path = join(serviceDir(coordRoot), "runtime.json");
|
|
32
|
+
if (!existsSync(path))
|
|
33
|
+
return undefined;
|
|
34
|
+
const runtime = readBoundedJson(path, "supervisor service runtime");
|
|
35
|
+
if (runtime.schema_version !== 1 ||
|
|
36
|
+
!validTimestamp(runtime.config_created_at) ||
|
|
37
|
+
!validTimestamp(runtime.updated_at) ||
|
|
38
|
+
!runtime.goals ||
|
|
39
|
+
typeof runtime.goals !== "object" ||
|
|
40
|
+
Array.isArray(runtime.goals)) {
|
|
41
|
+
throw new Error("supervisor service runtime has an unsupported schema");
|
|
42
|
+
}
|
|
43
|
+
return runtime;
|
|
44
|
+
}
|
|
45
|
+
export function readSupervisorServiceStatus(coordRootRaw) {
|
|
46
|
+
const coordRoot = resolve(coordRootRaw);
|
|
47
|
+
const record = readStatusRecord(coordRoot);
|
|
48
|
+
let config;
|
|
49
|
+
let runtime;
|
|
50
|
+
try {
|
|
51
|
+
config = readSupervisorServiceConfig(coordRoot);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Unconfigured or corrupt service state is represented without throwing.
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
runtime = readSupervisorServiceRuntime(coordRoot);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Runtime is recoverable and must not make the dashboard unreadable.
|
|
61
|
+
}
|
|
62
|
+
if (!record)
|
|
63
|
+
return { running: false, stale: false, config, runtime };
|
|
64
|
+
const running = statusOwnerIsLive(record);
|
|
65
|
+
return { running, stale: !running && record.state !== "stopped", record, config, runtime };
|
|
66
|
+
}
|
|
67
|
+
export function supervisorServiceLogPath(coordRoot) {
|
|
68
|
+
return join(serviceDir(resolve(coordRoot)), "service.log");
|
|
69
|
+
}
|
|
70
|
+
function readStatusRecord(coordRoot) {
|
|
71
|
+
const path = join(serviceDir(coordRoot), "status.json");
|
|
72
|
+
if (!existsSync(path))
|
|
73
|
+
return undefined;
|
|
74
|
+
try {
|
|
75
|
+
const value = readBoundedJson(path, "supervisor service status");
|
|
76
|
+
if (value.schema_version !== 1 ||
|
|
77
|
+
!Number.isSafeInteger(value.pid) ||
|
|
78
|
+
value.pid < 1 ||
|
|
79
|
+
typeof value.host !== "string" ||
|
|
80
|
+
typeof value.nonce !== "string" ||
|
|
81
|
+
!validTimestamp(value.started_at) ||
|
|
82
|
+
!validTimestamp(value.heartbeat_at)) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function statusOwnerIsLive(record) {
|
|
92
|
+
if (record.state === "stopped")
|
|
93
|
+
return false;
|
|
94
|
+
if (record.host === hostname()) {
|
|
95
|
+
try {
|
|
96
|
+
process.kill(record.pid, 0);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
return error.code === "EPERM";
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const age = Date.now() - Date.parse(record.heartbeat_at);
|
|
104
|
+
return Number.isFinite(age) && age < FOREIGN_STATUS_STALE_MS;
|
|
105
|
+
}
|
|
106
|
+
function readBoundedJson(path, label) {
|
|
107
|
+
if (!existsSync(path))
|
|
108
|
+
throw new Error(`${label} does not exist`);
|
|
109
|
+
const size = statSync(path).size;
|
|
110
|
+
if (size <= 0 || size > MAX_FILE_BYTES)
|
|
111
|
+
throw new Error(`${label} has invalid size ${size}`);
|
|
112
|
+
try {
|
|
113
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`cannot parse ${label}: ${error.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function serviceDir(coordRoot) {
|
|
120
|
+
return join(coordRoot, ".harnery", "supervisor-service");
|
|
121
|
+
}
|
|
122
|
+
function positive(value) {
|
|
123
|
+
return Number.isSafeInteger(value) && value > 0;
|
|
124
|
+
}
|
|
125
|
+
function validTimestamp(value) {
|
|
126
|
+
return typeof value === "string" && value.length <= 40 && Number.isFinite(Date.parse(value));
|
|
127
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type NormalizedPolicy, type PolicyIsolation } from "../policy/index.js";
|
|
2
|
+
import type { RunWorkItemInput } from "../work/index.js";
|
|
3
|
+
import { type SupervisorRunReport, type SupervisorStopReason } from "./runner.js";
|
|
4
|
+
import { type SupervisorRecord } from "./state.js";
|
|
5
|
+
export declare const SUPERVISOR_SERVICE_CONFIG_SCHEMA_VERSION: 1;
|
|
6
|
+
export declare const SUPERVISOR_SERVICE_RUNTIME_SCHEMA_VERSION: 1;
|
|
7
|
+
export declare const SUPERVISOR_SERVICE_STATUS_SCHEMA_VERSION: 1;
|
|
8
|
+
export interface SupervisorServiceEngineConfig {
|
|
9
|
+
default_harness?: string;
|
|
10
|
+
cwd?: string;
|
|
11
|
+
subscription_only: boolean;
|
|
12
|
+
allow_api_billing: boolean;
|
|
13
|
+
policy?: NormalizedPolicy;
|
|
14
|
+
isolation?: PolicyIsolation;
|
|
15
|
+
approval_addressee?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SupervisorServiceConfig {
|
|
18
|
+
schema_version: typeof SUPERVISOR_SERVICE_CONFIG_SCHEMA_VERSION;
|
|
19
|
+
goal_ids: string[];
|
|
20
|
+
wake_interval_ms: number;
|
|
21
|
+
heartbeat_interval_ms: number;
|
|
22
|
+
error_backoff_base_ms: number;
|
|
23
|
+
error_backoff_max_ms: number;
|
|
24
|
+
engine: SupervisorServiceEngineConfig;
|
|
25
|
+
created_at: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ConfigureSupervisorServiceInput {
|
|
28
|
+
coordRoot: string;
|
|
29
|
+
goalIds: readonly string[];
|
|
30
|
+
wakeIntervalMs?: number;
|
|
31
|
+
heartbeatIntervalMs?: number;
|
|
32
|
+
errorBackoffBaseMs?: number;
|
|
33
|
+
errorBackoffMaxMs?: number;
|
|
34
|
+
engine?: Partial<SupervisorServiceEngineConfig>;
|
|
35
|
+
}
|
|
36
|
+
export type SupervisorServiceGoalState = "idle" | "backoff" | "awaiting_change";
|
|
37
|
+
export interface SupervisorServiceGoalRuntime {
|
|
38
|
+
state: SupervisorServiceGoalState;
|
|
39
|
+
consecutive_errors: number;
|
|
40
|
+
observed_fingerprint?: string;
|
|
41
|
+
next_wake_at?: string;
|
|
42
|
+
last_tick_at?: string;
|
|
43
|
+
last_stop_reason?: SupervisorStopReason;
|
|
44
|
+
last_error?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface SupervisorServiceRuntime {
|
|
47
|
+
schema_version: typeof SUPERVISOR_SERVICE_RUNTIME_SCHEMA_VERSION;
|
|
48
|
+
config_created_at: string;
|
|
49
|
+
updated_at: string;
|
|
50
|
+
goals: Record<string, SupervisorServiceGoalRuntime>;
|
|
51
|
+
}
|
|
52
|
+
export type SupervisorServiceProcessState = "starting" | "running" | "stopping" | "stopped";
|
|
53
|
+
export interface SupervisorServiceStatusRecord {
|
|
54
|
+
schema_version: typeof SUPERVISOR_SERVICE_STATUS_SCHEMA_VERSION;
|
|
55
|
+
pid: number;
|
|
56
|
+
host: string;
|
|
57
|
+
nonce: string;
|
|
58
|
+
state: SupervisorServiceProcessState;
|
|
59
|
+
started_at: string;
|
|
60
|
+
heartbeat_at: string;
|
|
61
|
+
config_created_at: string;
|
|
62
|
+
sweep_count: number;
|
|
63
|
+
active_goal_id?: string;
|
|
64
|
+
last_sweep_at?: string;
|
|
65
|
+
next_wake_at?: string;
|
|
66
|
+
last_error?: string;
|
|
67
|
+
stopped_at?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface SupervisorServiceStatus {
|
|
70
|
+
running: boolean;
|
|
71
|
+
stale: boolean;
|
|
72
|
+
record?: SupervisorServiceStatusRecord;
|
|
73
|
+
config?: SupervisorServiceConfig;
|
|
74
|
+
runtime?: SupervisorServiceRuntime;
|
|
75
|
+
}
|
|
76
|
+
export interface SupervisorServiceSweepOutcome {
|
|
77
|
+
goal_id: string;
|
|
78
|
+
action: "tick" | "skip" | "backoff";
|
|
79
|
+
reason: string;
|
|
80
|
+
stop_reason?: SupervisorStopReason;
|
|
81
|
+
next_wake_at?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface SupervisorServiceSweepReport {
|
|
84
|
+
started_at: string;
|
|
85
|
+
ended_at: string;
|
|
86
|
+
outcomes: SupervisorServiceSweepOutcome[];
|
|
87
|
+
}
|
|
88
|
+
export interface RunSupervisorServiceSweepInput {
|
|
89
|
+
coordRoot: string;
|
|
90
|
+
config: SupervisorServiceConfig;
|
|
91
|
+
engine?: Omit<RunWorkItemInput["engine"], "maxAgents" | "concurrency" | "specialists">;
|
|
92
|
+
actor?: string;
|
|
93
|
+
now?: () => number;
|
|
94
|
+
readGoal?: (coordRoot: string, goalId: string) => SupervisorRecord;
|
|
95
|
+
runGoal?: (goalId: string) => Promise<SupervisorRunReport>;
|
|
96
|
+
onGoalStart?: (goalId: string) => void;
|
|
97
|
+
}
|
|
98
|
+
export interface RunSupervisorServiceDaemonInput {
|
|
99
|
+
coordRoot: string;
|
|
100
|
+
engine: Omit<RunWorkItemInput["engine"], "maxAgents" | "concurrency" | "specialists">;
|
|
101
|
+
actor?: string;
|
|
102
|
+
maxSweeps?: number;
|
|
103
|
+
onLog?: (line: string) => void;
|
|
104
|
+
}
|
|
105
|
+
export declare function configureSupervisorService(input: ConfigureSupervisorServiceInput): SupervisorServiceConfig;
|
|
106
|
+
export declare function readSupervisorServiceConfig(coordRootRaw: string): SupervisorServiceConfig;
|
|
107
|
+
export declare function readSupervisorServiceRuntime(coordRootRaw: string): SupervisorServiceRuntime | undefined;
|
|
108
|
+
export declare function readSupervisorServiceStatus(coordRootRaw: string): SupervisorServiceStatus;
|
|
109
|
+
export declare function spawnSupervisorService(coordRootRaw: string): Promise<SupervisorServiceStatus>;
|
|
110
|
+
export declare function requestSupervisorServiceStop(coordRootRaw: string): SupervisorServiceStatus;
|
|
111
|
+
export declare function runSupervisorServiceSweep(input: RunSupervisorServiceSweepInput): Promise<SupervisorServiceSweepReport>;
|
|
112
|
+
export declare function runSupervisorServiceDaemon(input: RunSupervisorServiceDaemonInput): Promise<SupervisorServiceStatusRecord>;
|
|
113
|
+
export declare function supervisorServiceLogPath(coordRoot: string): string;
|
|
114
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/service.ts"],"names":[],"mappings":"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"}
|