harnery 0.13.0 → 0.15.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.
Files changed (66) hide show
  1. package/README.md +2 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +4 -0
  4. package/dist/commands/supervisor.d.ts +4 -0
  5. package/dist/commands/supervisor.d.ts.map +1 -0
  6. package/dist/commands/supervisor.js +238 -0
  7. package/dist/commands/work.d.ts +4 -0
  8. package/dist/commands/work.d.ts.map +1 -0
  9. package/dist/commands/work.js +281 -0
  10. package/dist/core/supervisor/index.d.ts +3 -0
  11. package/dist/core/supervisor/index.d.ts.map +1 -0
  12. package/dist/core/supervisor/index.js +2 -0
  13. package/dist/core/supervisor/read.d.ts +2 -0
  14. package/dist/core/supervisor/read.d.ts.map +1 -0
  15. package/dist/core/supervisor/read.js +1 -0
  16. package/dist/core/supervisor/runner.d.ts +34 -0
  17. package/dist/core/supervisor/runner.d.ts.map +1 -0
  18. package/dist/core/supervisor/runner.js +198 -0
  19. package/dist/core/supervisor/state.d.ts +69 -0
  20. package/dist/core/supervisor/state.d.ts.map +1 -0
  21. package/dist/core/supervisor/state.js +413 -0
  22. package/dist/core/work/index.d.ts +3 -0
  23. package/dist/core/work/index.d.ts.map +1 -0
  24. package/dist/core/work/index.js +2 -0
  25. package/dist/core/work/read.d.ts +2 -0
  26. package/dist/core/work/read.d.ts.map +1 -0
  27. package/dist/core/work/read.js +1 -0
  28. package/dist/core/work/runner.d.ts +10 -0
  29. package/dist/core/work/runner.d.ts.map +1 -0
  30. package/dist/core/work/runner.js +63 -0
  31. package/dist/core/work/state.d.ts +109 -0
  32. package/dist/core/work/state.d.ts.map +1 -0
  33. package/dist/core/work/state.js +698 -0
  34. package/dist/core/workflow/engine.d.ts.map +1 -1
  35. package/dist/core/workflow/engine.js +41 -9
  36. package/dist/core/workflow/index.d.ts +1 -1
  37. package/dist/core/workflow/index.d.ts.map +1 -1
  38. package/dist/core/workflow/proof.d.ts +1 -0
  39. package/dist/core/workflow/proof.d.ts.map +1 -1
  40. package/dist/core/workflow/proof.js +2 -0
  41. package/dist/core/workflow/run-state.d.ts +3 -0
  42. package/dist/core/workflow/run-state.d.ts.map +1 -1
  43. package/dist/core/workflow/run-state.js +14 -0
  44. package/dist/core/workflow/specialists.d.ts +7 -0
  45. package/dist/core/workflow/specialists.d.ts.map +1 -0
  46. package/dist/core/workflow/specialists.js +78 -0
  47. package/dist/core/workflow/types.d.ts +24 -0
  48. package/dist/core/workflow/types.d.ts.map +1 -1
  49. package/package.json +21 -1
  50. package/src/commander.ts +4 -0
  51. package/src/commands/supervisor.ts +315 -0
  52. package/src/commands/work.ts +367 -0
  53. package/src/core/supervisor/index.ts +24 -0
  54. package/src/core/supervisor/read.ts +14 -0
  55. package/src/core/supervisor/runner.ts +278 -0
  56. package/src/core/supervisor/state.ts +552 -0
  57. package/src/core/work/index.ts +24 -0
  58. package/src/core/work/read.ts +15 -0
  59. package/src/core/work/runner.ts +81 -0
  60. package/src/core/work/state.ts +900 -0
  61. package/src/core/workflow/engine.ts +42 -9
  62. package/src/core/workflow/index.ts +1 -0
  63. package/src/core/workflow/proof.ts +3 -0
  64. package/src/core/workflow/run-state.ts +20 -0
  65. package/src/core/workflow/specialists.ts +97 -0
  66. package/src/core/workflow/types.ts +25 -0
package/README.md CHANGED
@@ -22,6 +22,8 @@
22
22
  - **Multi-agent coordination:** per-agent heartbeats in `.harnery/active/`, claim-time and commit-time guards, the canonical event stream, councils, a decision docket, per-agent scratchpads, and harness adapters for Claude Code / Cursor / Codex.
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
+ - **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 foreground scheduling cycles until success, human attention, no progress, or budget exhaustion. Specialist roles survive as configuration while every child remains a bounded process.
25
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)).
26
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).
27
29
 
@@ -1 +1 @@
1
- {"version":3,"file":"commander.d.ts","sourceRoot":"","sources":["../src/commander.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commander.d.ts","sourceRoot":"","sources":["../src/commander.ts"],"names":[],"mappings":"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"}
package/dist/commander.js CHANGED
@@ -47,11 +47,13 @@ import { registerReadCommand } from "./commands/read.js";
47
47
  import { registerRelayCommand } from "./commands/relay.js";
48
48
  import { registerScratchCommand } from "./commands/scratch.js";
49
49
  import { registerSessionCommand } from "./commands/session.js";
50
+ import { registerSupervisorCommand } from "./commands/supervisor.js";
50
51
  import { registerSyncCommand } from "./commands/sync.js";
51
52
  import { registerSectionCommand, registerTocCommand } from "./commands/toc.js";
52
53
  import { registerTokensCommand } from "./commands/tokens.js";
53
54
  import { registerTunnelCommand } from "./commands/tunnel.js";
54
55
  import { registerWebCommand } from "./commands/web.js";
56
+ import { registerWorkCommand } from "./commands/work.js";
55
57
  import { registerWorkflowCommand } from "./commands/workflow.js";
56
58
  export const defaultEmit = {
57
59
  config() {
@@ -132,6 +134,8 @@ export function createHarneryProgram(opts = {}) {
132
134
  registerClaudeDesktopCommand(program, emit);
133
135
  registerSyncCommand(program, emit);
134
136
  registerWorkflowCommand(program, emit);
137
+ registerWorkCommand(program, emit);
138
+ registerSupervisorCommand(program, emit);
135
139
  if (include("web"))
136
140
  registerWebCommand(program, emit);
137
141
  return program;
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import type { EmitContext } from "../commander.js";
3
+ export declare function registerSupervisorCommand(program: Command, emit: EmitContext): void;
4
+ //# sourceMappingURL=supervisor.d.ts.map
@@ -0,0 +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;AA4CnD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA0FnF"}
@@ -0,0 +1,238 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { workflowSubscriptionOnly } from "../core/config.js";
4
+ import { createBuiltinHarnessRegistry } from "../core/harnesses/index.js";
5
+ import { findCoordRoot } from "../core/hooks/resolve/coord-root.js";
6
+ import { loadPolicyFile } from "../core/policy/index.js";
7
+ import { createSupervisor, listSupervisors, readSupervisor, runSupervisor, } from "../core/supervisor/index.js";
8
+ export function registerSupervisorCommand(program, emit) {
9
+ const registry = createBuiltinHarnessRegistry();
10
+ const supervisor = program
11
+ .command("supervisor")
12
+ .description("Run a bounded specialist team over a durable-work dependency graph.");
13
+ supervisor
14
+ .command("create <root-work-id>")
15
+ .description("Freeze a goal, specialist team, automation policy, and execution limits.")
16
+ .requiredOption("--team <file>", "JSON object mapping specialist ids to profiles")
17
+ .option("--id <goal-id>", "Stable goal id (generated by default)")
18
+ .option("--title <text>", "Goal title (defaults to root work title)")
19
+ .option("--max-cycles <n>", "Foreground cycle ceiling (default 50)")
20
+ .option("--max-runtime-ms <n>", "Foreground wall-time ceiling (default 14400000)")
21
+ .option("--max-parallel-work <n>", "Concurrent work-item ceiling (default 1)")
22
+ .option("--max-total-attempts <n>", "Graph-wide attempt ceiling (default 100)")
23
+ .option("--max-agents-per-work <n>", "Child-agent ceiling per work item (default 20)")
24
+ .option("--agent-concurrency <n>", "Child concurrency per work item (default 4)")
25
+ .option("--accept-passing-proof", "Allow the supervisor to explicitly accept passing proof")
26
+ .option("--no-resume-approved", "Stop after an approval instead of resuming its parked run")
27
+ .option("--retry-blocked", "Allow bounded retry of blocked work")
28
+ .option("--json", "Emit the complete supervisor record as JSON")
29
+ .action((rootWorkId, opts) => {
30
+ withSupervisorRoot(emit, (coordRoot) => {
31
+ const specialists = readTeamFile(opts.team);
32
+ for (const [id, profile] of Object.entries(specialists)) {
33
+ if (profile.harness && !registry.get(profile.harness)) {
34
+ throw new Error(`specialist ${id} names unknown harness ${JSON.stringify(profile.harness)}`);
35
+ }
36
+ }
37
+ emitSupervisor(createSupervisor({
38
+ coordRoot,
39
+ rootWorkId,
40
+ specialists,
41
+ id: opts.id,
42
+ title: opts.title,
43
+ limits: {
44
+ max_cycles: integer(opts.maxCycles),
45
+ max_runtime_ms: integer(opts.maxRuntimeMs),
46
+ max_parallel_work: integer(opts.maxParallelWork),
47
+ max_total_attempts: integer(opts.maxTotalAttempts),
48
+ max_agents_per_work: integer(opts.maxAgentsPerWork),
49
+ agent_concurrency: integer(opts.agentConcurrency),
50
+ },
51
+ automation: {
52
+ accept_passing_proof: opts.acceptPassingProof,
53
+ resume_approved: opts.resumeApproved,
54
+ retry_blocked: opts.retryBlocked,
55
+ },
56
+ }), opts.json, emit, true);
57
+ });
58
+ });
59
+ supervisor
60
+ .command("list")
61
+ .description("List durable goals and their derived next action.")
62
+ .option("--json", "Emit complete supervisor records as JSON")
63
+ .action((opts) => {
64
+ withSupervisorRoot(emit, (coordRoot) => {
65
+ const records = listSupervisors(coordRoot);
66
+ if (opts.json) {
67
+ emit.config({ format: "json" });
68
+ emit.data(records);
69
+ }
70
+ else if (records.length === 0) {
71
+ emit.text("no durable supervisors\n");
72
+ }
73
+ else {
74
+ emit.text(`${records.map(renderSupervisorRow).join("\n")}\n`);
75
+ }
76
+ });
77
+ });
78
+ supervisor
79
+ .command("show <goal-id>")
80
+ .description("Show one goal, frozen team, bounds, graph state, and next action.")
81
+ .option("--json", "Emit the complete supervisor record as JSON")
82
+ .action((goalId, opts) => {
83
+ withSupervisorRoot(emit, (coordRoot) => {
84
+ emitSupervisor(readSupervisor(coordRoot, goalId), opts.json, emit, true);
85
+ });
86
+ });
87
+ registerRunCommand(supervisor, "tick", registry, emit);
88
+ registerRunCommand(supervisor, "run", registry, emit);
89
+ }
90
+ function registerRunCommand(supervisor, mode, registry, emit) {
91
+ supervisor
92
+ .command(`${mode} <goal-id>`)
93
+ .description(mode === "tick"
94
+ ? "Perform at most one bounded scheduling cycle."
95
+ : "Run bounded cycles until success, attention, no progress, or budget exhaustion.")
96
+ .option("--harness <name>", "Fallback harness for agent calls without a specialist")
97
+ .option("--cwd <dir>", "Working directory for child agents")
98
+ .option("--subscription-only", "Require stored harness-login billing")
99
+ .option("--allow-api-billing", "Permit API-key override billing")
100
+ .option("--policy <file>", "Host policy JSON/JSONC")
101
+ .option("--isolation <mode>", "shared | worktree | sandbox | remote")
102
+ .option("--approval-to <address>", "Address durable ASK requests")
103
+ .option("--actor <name>", "Actor recorded on supervisor work decisions")
104
+ .option("--json", "Emit the complete run report as JSON")
105
+ .action(async (goalId, opts) => {
106
+ await withSupervisorRootAsync(emit, async (coordRoot) => {
107
+ if (opts.harness && !registry.get(opts.harness)) {
108
+ throw new Error(`unknown harness ${JSON.stringify(opts.harness)}`);
109
+ }
110
+ const report = await runSupervisor({
111
+ coordRoot,
112
+ goalId,
113
+ mode,
114
+ actor: opts.actor,
115
+ onLog: opts.json ? undefined : (line) => emit.text(`${line}\n`),
116
+ engine: {
117
+ spawners: registry.spawners(),
118
+ defaultHarness: opts.harness,
119
+ cwd: opts.cwd,
120
+ subscriptionOnly: opts.subscriptionOnly === true ? true : workflowSubscriptionOnly(coordRoot),
121
+ allowApiBilling: opts.allowApiBilling,
122
+ harnessEvidence: Object.fromEntries(registry
123
+ .list()
124
+ .map((adapter) => [
125
+ adapter.profile.id,
126
+ { toolEvidence: adapter.profile.capabilities.toolEvidence },
127
+ ])),
128
+ policy: opts.policy ? loadPolicyFile(opts.policy) : undefined,
129
+ approvalMode: "park",
130
+ approvalAddressee: opts.approvalTo,
131
+ isolation: opts.isolation,
132
+ networkAccess: "enabled",
133
+ },
134
+ });
135
+ emitSupervisorReport(report, opts.json, emit);
136
+ });
137
+ });
138
+ }
139
+ function readTeamFile(path) {
140
+ const absolute = resolve(path);
141
+ let value;
142
+ try {
143
+ value = JSON.parse(readFileSync(absolute, "utf8"));
144
+ }
145
+ catch (error) {
146
+ throw new Error(`cannot read supervisor team at ${absolute}: ${error.message}`);
147
+ }
148
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
149
+ throw new Error("supervisor team must be a JSON object keyed by specialist id");
150
+ }
151
+ return value;
152
+ }
153
+ function emitSupervisor(record, json, emit, detail = false) {
154
+ if (json) {
155
+ emit.config({ format: "json" });
156
+ emit.data(record);
157
+ return;
158
+ }
159
+ if (!detail) {
160
+ emit.text(`${renderSupervisorRow(record)}\n`);
161
+ return;
162
+ }
163
+ const projection = record.projection;
164
+ const lines = [
165
+ `${record.intent.id}: ${record.intent.title}`,
166
+ `state: ${projection.state}`,
167
+ `root: ${record.intent.root_work_id}`,
168
+ `reason: ${projection.reason}`,
169
+ `next: ${projection.next_action}`,
170
+ `work: ${projection.work_ids.length}`,
171
+ `attempts: ${projection.attempts_used}/${record.intent.limits.max_total_attempts}`,
172
+ `specialists: ${projection.specialists.join(", ") || "none"}`,
173
+ `automation: accept=${record.intent.automation.accept_passing_proof}, ` +
174
+ `resume=${record.intent.automation.resume_approved}, retry=${record.intent.automation.retry_blocked}`,
175
+ ];
176
+ if (projection.attention_work.length) {
177
+ lines.push(`attention: ${projection.attention_work.join(", ")}`);
178
+ }
179
+ emit.text(`${lines.join("\n")}\n`);
180
+ }
181
+ function emitSupervisorReport(report, json, emit) {
182
+ if (json) {
183
+ emit.config({ format: "json" });
184
+ emit.data(report);
185
+ return;
186
+ }
187
+ emit.text(`supervisor ${report.goal_id}: ${report.stop_reason}\n` +
188
+ `reason: ${report.reason}\n` +
189
+ `cycles: ${report.cycles}; dispatches: ${report.dispatches}; acceptances: ${report.acceptances}\n` +
190
+ `state: ${report.projection.state}; next: ${report.projection.next_action}\n`);
191
+ }
192
+ function renderSupervisorRow(record) {
193
+ const projection = record.projection;
194
+ return `${record.intent.id} ${projection.state.padEnd(20)} ${projection.attempts_used}/${record.intent.limits.max_total_attempts} ${projection.next_action.padEnd(18)} ${record.intent.title}`;
195
+ }
196
+ function integer(value) {
197
+ if (value === undefined)
198
+ return undefined;
199
+ if (!/^\d+$/.test(value))
200
+ throw new Error(`expected a positive integer, got ${JSON.stringify(value)}`);
201
+ return Number.parseInt(value, 10);
202
+ }
203
+ function withSupervisorRoot(emit, fn) {
204
+ const coordRoot = findCoordRoot();
205
+ if (!coordRoot) {
206
+ emit.error({
207
+ code: "no_coord_root",
208
+ message: "no .harnery/ coordination root found; run `init` first",
209
+ });
210
+ emit.setExitCode(1);
211
+ return;
212
+ }
213
+ try {
214
+ fn(coordRoot);
215
+ }
216
+ catch (error) {
217
+ emit.error({ code: "supervisor_failed", message: error.message });
218
+ emit.setExitCode(1);
219
+ }
220
+ }
221
+ async function withSupervisorRootAsync(emit, fn) {
222
+ const coordRoot = findCoordRoot();
223
+ if (!coordRoot) {
224
+ emit.error({
225
+ code: "no_coord_root",
226
+ message: "no .harnery/ coordination root found; run `init` first",
227
+ });
228
+ emit.setExitCode(1);
229
+ return;
230
+ }
231
+ try {
232
+ await fn(coordRoot);
233
+ }
234
+ catch (error) {
235
+ emit.error({ code: "supervisor_failed", message: error.message });
236
+ emit.setExitCode(1);
237
+ }
238
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import type { EmitContext } from "../commander.js";
3
+ export declare function registerWorkCommand(program: Command, emit: EmitContext): void;
4
+ //# sourceMappingURL=work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work.d.ts","sourceRoot":"","sources":["../../src/commands/work.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAmDnD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA8F7E"}
@@ -0,0 +1,281 @@
1
+ import { workflowSubscriptionOnly } from "../core/config.js";
2
+ import { createBuiltinHarnessRegistry } from "../core/harnesses/index.js";
3
+ import { findCoordRoot } from "../core/hooks/resolve/coord-root.js";
4
+ import { loadPolicyFile } from "../core/policy/index.js";
5
+ import { acceptWorkItem, cancelWorkItem, createWorkItem, listWorkItems, readWorkItem, reconcileAllWorkItems, reconcileWorkItem, reopenWorkItem, runWorkItem, } from "../core/work/index.js";
6
+ import { WorkflowParkedError } from "../core/workflow/index.js";
7
+ export function registerWorkCommand(program, emit) {
8
+ const registry = createBuiltinHarnessRegistry();
9
+ const harnesses = registry.ids();
10
+ const work = program
11
+ .command("work")
12
+ .description("Track durable objectives across bounded workflow attempts.");
13
+ work
14
+ .command("create <title> <workflow>")
15
+ .description("Create an immutable durable-work intent linked to a workflow script.")
16
+ .requiredOption("--objective <text>", "Objective that must survive execution attempts")
17
+ .option("--id <work-id>", "Stable work id (generated by default)")
18
+ .option("--accept <text>", "Acceptance statement; repeat for more than one", collect, [])
19
+ .option("--depends-on <ids>", "Comma-separated prerequisite work ids")
20
+ .option("--max-attempts <n>", "Attempt ceiling (default 3)")
21
+ .option("--source-kind <kind>", "human | workflow | external", "human")
22
+ .option("--source-ref <ref>", "Bounded source reference")
23
+ .option("--actor <name>", "Actor recorded in the creation receipt")
24
+ .option("--json", "Emit the complete work record as JSON")
25
+ .action((title, workflowPath, opts) => {
26
+ withWorkRoot(emit, (coordRoot) => {
27
+ const record = createWorkItem({
28
+ coordRoot,
29
+ id: opts.id,
30
+ title,
31
+ objective: opts.objective,
32
+ workflowPath,
33
+ acceptance: opts.accept,
34
+ dependencies: splitIds(opts.dependsOn),
35
+ maxAttempts: opts.maxAttempts ? Number.parseInt(opts.maxAttempts, 10) : undefined,
36
+ source: opts.sourceKind ? { kind: opts.sourceKind, ref: opts.sourceRef } : undefined,
37
+ actor: opts.actor,
38
+ });
39
+ emitWork(record, opts.json, emit);
40
+ });
41
+ });
42
+ work
43
+ .command("list")
44
+ .description("List durable work with its currently derived state.")
45
+ .option("--state <state>", "Filter by derived state")
46
+ .option("--json", "Emit complete work records as JSON")
47
+ .action((opts) => {
48
+ withWorkRoot(emit, (coordRoot) => {
49
+ const records = listWorkItems(coordRoot).filter((record) => !opts.state || record.projection.state === opts.state);
50
+ if (opts.json) {
51
+ emit.config({ format: "json" });
52
+ emit.data(records);
53
+ }
54
+ else if (records.length === 0) {
55
+ emit.text("no durable work\n");
56
+ }
57
+ else {
58
+ emit.text(`${records.map(renderWorkRow).join("\n")}\n`);
59
+ }
60
+ });
61
+ });
62
+ work
63
+ .command("show <work-id>")
64
+ .description("Show one work item, its attempts, and the next explicit action.")
65
+ .option("--json", "Emit the complete work record as JSON")
66
+ .action((workId, opts) => {
67
+ withWorkRoot(emit, (coordRoot) => {
68
+ emitWork(readWorkItem(coordRoot, workId), opts.json, emit, true);
69
+ });
70
+ });
71
+ work
72
+ .command("reconcile [work-id]")
73
+ .description("Derive state from durable evidence without starting or retrying work.")
74
+ .option("--actor <name>", "Actor recorded on changed reconciliation receipts")
75
+ .option("--json", "Emit reconciled work records as JSON")
76
+ .action((workId, opts) => {
77
+ withWorkRoot(emit, (coordRoot) => {
78
+ const records = workId
79
+ ? [reconcileWorkItem(coordRoot, workId, opts.actor)]
80
+ : reconcileAllWorkItems(coordRoot, opts.actor);
81
+ if (opts.json) {
82
+ emit.config({ format: "json" });
83
+ emit.data(workId ? records[0] : records);
84
+ }
85
+ else if (records.length === 0) {
86
+ emit.text("no durable work\n");
87
+ }
88
+ else {
89
+ emit.text(`${records.map(renderWorkRow).join("\n")}\n`);
90
+ }
91
+ });
92
+ });
93
+ registerRunCommand(work, "run", false, registry, harnesses, emit);
94
+ registerRunCommand(work, "retry", true, registry, harnesses, emit);
95
+ registerGovernanceCommand(work, "accept", emit);
96
+ registerGovernanceCommand(work, "cancel", emit);
97
+ registerGovernanceCommand(work, "reopen", emit);
98
+ }
99
+ function registerRunCommand(work, name, retry, registry, harnesses, emit) {
100
+ work
101
+ .command(`${name} <work-id>`)
102
+ .description(retry
103
+ ? "Start a new bounded attempt after a blocked run."
104
+ : "Start ready work or resume its resolved parked attempt.")
105
+ .option("--max-agents <n>", "Total-agent ceiling for the workflow")
106
+ .option("--concurrency <n>", "Concurrent-subagent cap")
107
+ .option("--cwd <dir>", "Working directory children spawn in")
108
+ .option("--harness <name>", `Default harness: ${harnesses.join(" | ")}`)
109
+ .option("--subscription-only", "Require stored harness-login billing")
110
+ .option("--allow-api-billing", "Permit API-key override billing")
111
+ .option("--policy <file>", "Host policy JSON/JSONC")
112
+ .option("--isolation <mode>", "shared | worktree | sandbox | remote")
113
+ .option("--approval-to <address>", "Address durable ASK requests")
114
+ .option("--actor <name>", "Actor recorded in attempt receipts")
115
+ .option("--json", "Emit the workflow report or parked result as JSON")
116
+ .action(async (workId, opts) => {
117
+ await withWorkRootAsync(emit, async (coordRoot) => {
118
+ if (opts.harness && !registry.get(opts.harness)) {
119
+ throw new Error(`unknown harness ${JSON.stringify(opts.harness)}`);
120
+ }
121
+ try {
122
+ const report = await runWorkItem({
123
+ coordRoot,
124
+ workId,
125
+ retry,
126
+ actor: opts.actor,
127
+ engine: {
128
+ spawners: registry.spawners(),
129
+ defaultHarness: opts.harness,
130
+ maxAgents: opts.maxAgents ? Number.parseInt(opts.maxAgents, 10) : undefined,
131
+ concurrency: opts.concurrency ? Number.parseInt(opts.concurrency, 10) : undefined,
132
+ cwd: opts.cwd,
133
+ subscriptionOnly: opts.subscriptionOnly === true ? true : workflowSubscriptionOnly(coordRoot),
134
+ allowApiBilling: opts.allowApiBilling,
135
+ harnessEvidence: Object.fromEntries(registry
136
+ .list()
137
+ .map((adapter) => [
138
+ adapter.profile.id,
139
+ { toolEvidence: adapter.profile.capabilities.toolEvidence },
140
+ ])),
141
+ policy: opts.policy ? loadPolicyFile(opts.policy) : undefined,
142
+ approvalMode: "park",
143
+ approvalAddressee: opts.approvalTo,
144
+ isolation: opts.isolation,
145
+ networkAccess: "enabled",
146
+ },
147
+ });
148
+ if (opts.json) {
149
+ emit.config({ format: "json" });
150
+ emit.data(report);
151
+ }
152
+ else {
153
+ emit.text(`work ${workId}: run ${report.runId} finished\nproof: ${report.proofPath}\n` +
154
+ `next: harn work reconcile ${workId}\n`);
155
+ }
156
+ }
157
+ catch (error) {
158
+ if (error instanceof WorkflowParkedError) {
159
+ if (opts.json) {
160
+ emit.config({ format: "json" });
161
+ emit.data({
162
+ status: "parked",
163
+ workId,
164
+ runId: error.runId,
165
+ approvalId: error.approvalId,
166
+ journalPath: error.journalPath,
167
+ });
168
+ }
169
+ else {
170
+ emit.text(`work ${workId}: run ${error.runId} parked\napproval: ${error.approvalId}\n` +
171
+ `next: resolve the approval, then harn work run ${workId}\n`);
172
+ }
173
+ return;
174
+ }
175
+ throw error;
176
+ }
177
+ });
178
+ });
179
+ }
180
+ function registerGovernanceCommand(work, name, emit) {
181
+ work
182
+ .command(`${name} <work-id>`)
183
+ .description(name === "accept"
184
+ ? "Explicitly accept reviewed proof and complete the objective."
185
+ : name === "cancel"
186
+ ? "Explicitly cancel unfinished durable work."
187
+ : "Explicitly reopen terminal or blocked work for a future attempt.")
188
+ .option("--actor <name>", "Actor recorded in the governance receipt")
189
+ .option("--reason <text>", "Bounded decision reason")
190
+ .option("--json", "Emit the complete work record as JSON")
191
+ .action((workId, opts) => {
192
+ withWorkRoot(emit, (coordRoot) => {
193
+ const fn = name === "accept" ? acceptWorkItem : name === "cancel" ? cancelWorkItem : reopenWorkItem;
194
+ emitWork(fn(coordRoot, workId, opts), opts.json, emit, true);
195
+ });
196
+ });
197
+ }
198
+ function emitWork(record, json, emit, detail = false) {
199
+ if (json) {
200
+ emit.config({ format: "json" });
201
+ emit.data(record);
202
+ return;
203
+ }
204
+ if (!detail) {
205
+ emit.text(`${renderWorkRow(record)}\n`);
206
+ return;
207
+ }
208
+ const projection = record.projection;
209
+ const lines = [
210
+ `${record.intent.id}: ${record.intent.title}`,
211
+ `state: ${projection.state}`,
212
+ `objective: ${record.intent.objective}`,
213
+ `reason: ${projection.reason}`,
214
+ `next: ${projection.next_action}`,
215
+ `attempts: ${projection.attempts_used}/${record.intent.max_attempts}`,
216
+ ];
217
+ if (record.intent.dependencies.length)
218
+ lines.push(`depends on: ${record.intent.dependencies.join(", ")}`);
219
+ if (record.intent.acceptance.length) {
220
+ lines.push("acceptance:", ...record.intent.acceptance.map((item) => ` - ${item}`));
221
+ }
222
+ if (projection.attempts.length) {
223
+ lines.push("attempts:", ...projection.attempts.map((attempt) => ` ${attempt.number}. ${attempt.run_id} ${attempt.status}`));
224
+ }
225
+ if (projection.approval_id)
226
+ lines.push(`approval: ${projection.approval_id}`);
227
+ if (projection.proof_path)
228
+ lines.push(`proof: ${projection.proof_path}`);
229
+ emit.text(`${lines.join("\n")}\n`);
230
+ }
231
+ function renderWorkRow(record) {
232
+ const projection = record.projection;
233
+ return `${record.intent.id} ${projection.state.padEnd(17)} ${projection.attempts_used}/${record.intent.max_attempts} ${projection.next_action.padEnd(21)} ${record.intent.title}`;
234
+ }
235
+ function withWorkRoot(emit, fn) {
236
+ const coordRoot = findCoordRoot();
237
+ if (!coordRoot) {
238
+ emit.error({
239
+ code: "no_coord_root",
240
+ message: "no .harnery/ coordination root found; run `init` first",
241
+ });
242
+ emit.setExitCode(1);
243
+ return;
244
+ }
245
+ try {
246
+ fn(coordRoot);
247
+ }
248
+ catch (error) {
249
+ emit.error({ code: "work_failed", message: error.message });
250
+ emit.setExitCode(1);
251
+ }
252
+ }
253
+ async function withWorkRootAsync(emit, fn) {
254
+ const coordRoot = findCoordRoot();
255
+ if (!coordRoot) {
256
+ emit.error({
257
+ code: "no_coord_root",
258
+ message: "no .harnery/ coordination root found; run `init` first",
259
+ });
260
+ emit.setExitCode(1);
261
+ return;
262
+ }
263
+ try {
264
+ await fn(coordRoot);
265
+ }
266
+ catch (error) {
267
+ emit.error({ code: "work_failed", message: error.message });
268
+ emit.setExitCode(1);
269
+ }
270
+ }
271
+ function splitIds(value) {
272
+ return value
273
+ ? value
274
+ .split(",")
275
+ .map((item) => item.trim())
276
+ .filter(Boolean)
277
+ : [];
278
+ }
279
+ function collect(value, previous) {
280
+ return [...previous, value];
281
+ }
@@ -0,0 +1,3 @@
1
+ export { type RunSupervisorInput, runSupervisor, type SupervisorDispatchOutcome, type SupervisorRunReport, type SupervisorStopReason, } from "./runner.js";
2
+ 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
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ export { runSupervisor, } from "./runner.js";
2
+ export { assertSupervisorId, collectSupervisorWork, createSupervisor, listSupervisors, newSupervisorId, readSupervisor, SUPERVISOR_INTENT_SCHEMA_VERSION, } from "./state.js";
@@ -0,0 +1,2 @@
1
+ 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
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1 @@
1
+ export { assertSupervisorId, collectSupervisorWork, listSupervisors, readSupervisor, SUPERVISOR_INTENT_SCHEMA_VERSION, } from "./state.js";
@@ -0,0 +1,34 @@
1
+ import { type RunWorkItemInput } from "../work/index.js";
2
+ import { type SupervisorProjection } from "./state.js";
3
+ export type SupervisorStopReason = "succeeded" | "awaiting_attention" | "blocked" | "budget_exhausted" | "no_progress" | "tick_complete";
4
+ export interface SupervisorDispatchOutcome {
5
+ work_id: string;
6
+ action: "run" | "resume" | "retry";
7
+ status: "completed" | "parked" | "failed";
8
+ run_id?: string;
9
+ error?: string;
10
+ }
11
+ export interface SupervisorRunReport {
12
+ goal_id: string;
13
+ mode: "tick" | "run";
14
+ stop_reason: SupervisorStopReason;
15
+ reason: string;
16
+ started_at: string;
17
+ ended_at: string;
18
+ duration_ms: number;
19
+ cycles: number;
20
+ dispatches: number;
21
+ acceptances: number;
22
+ outcomes: SupervisorDispatchOutcome[];
23
+ projection: SupervisorProjection;
24
+ }
25
+ export interface RunSupervisorInput {
26
+ coordRoot: string;
27
+ goalId: string;
28
+ mode?: "tick" | "run";
29
+ actor?: string;
30
+ engine: Omit<RunWorkItemInput["engine"], "maxAgents" | "concurrency" | "specialists">;
31
+ onLog?: (line: string) => void;
32
+ }
33
+ export declare function runSupervisor(input: RunSupervisorInput): Promise<SupervisorRunReport>;
34
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/core/supervisor/runner.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,gBAAgB,EAItB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGL,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,oBAAoB,GAC5B,WAAW,GACX,oBAAoB,GACpB,SAAS,GACT,kBAAkB,GAClB,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACnC,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,WAAW,EAAE,oBAAoB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;IACtF,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAQD,wBAAsB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuJ3F"}