harnex 0.6.5 → 0.7.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +158 -0
- data/README.md +102 -33
- data/TECHNICAL.md +23 -0
- data/guides/01_dispatch.md +24 -21
- data/guides/02_chain.md +6 -3
- data/guides/03_buddy.md +12 -11
- data/guides/04_monitoring.md +17 -16
- data/guides/05_naming.md +16 -15
- data/lib/harnex/adapters/base.rb +36 -2
- data/lib/harnex/adapters/claude.rb +4 -0
- data/lib/harnex/adapters/codex.rb +4 -0
- data/lib/harnex/adapters/codex_appserver.rb +56 -230
- data/lib/harnex/adapters/opencode.rb +132 -0
- data/lib/harnex/adapters/pi.rb +512 -0
- data/lib/harnex/adapters.rb +5 -1
- data/lib/harnex/cli.rb +9 -2
- data/lib/harnex/codex/app_server/client.rb +348 -0
- data/lib/harnex/commands/doctor.rb +95 -2
- data/lib/harnex/commands/history.rb +149 -0
- data/lib/harnex/commands/run.rb +47 -9
- data/lib/harnex/commands/wait.rb +77 -36
- data/lib/harnex/core.rb +3 -3
- data/lib/harnex/dispatch_history.rb +112 -0
- data/lib/harnex/runtime/session.rb +326 -44
- data/lib/harnex/version.rb +2 -2
- data/lib/harnex.rb +2 -0
- metadata +9 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e99b85fa8112b666665da16757d871098867e0b05c9521c3507fc2092616f825
|
|
4
|
+
data.tar.gz: 78a5190335ee968c77d75531d23998c34272d24a3b6a8d6a53d5e9a8922c87da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4c32673867f2b86ee84fa1768ee4fee82a3ddb0fb69abd5c369349d59fe9feef3cc468ee71776115da19ca2997b1f647678b413f8c93d02538f56c17daf316d4
|
|
7
|
+
data.tar.gz: bf049097af8736c25991af1894dd15b6cc8159393f99eb215a0dc7ddd67f9716b1864589664fdd08671edc6859899c9cb84c46852b940323b8f11f42d5f8ee29
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,164 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.7.4] - 2026-05-25 | 08:45 AM | IST
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- First-class `pi` structured adapter (`Harnex::Adapters::Pi`) for
|
|
10
|
+
`pi --mode rpc` JSONL transport. `harnex run pi` now supports
|
|
11
|
+
structured completion (`agent_end` -> `task_complete`), stop/abort,
|
|
12
|
+
extension-UI dialog auto-cancel in RPC mode, streamed output/tool
|
|
13
|
+
synthesis, and Pi session-stats telemetry capture.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Structured transport handling in `Session` now supports both Codex
|
|
18
|
+
JSON-RPC (`:stdio_jsonrpc`) and Pi JSONL RPC (`:stdio_jsonl_rpc`).
|
|
19
|
+
- DISPATCH telemetry restores `actual.cost_usd` (adapter-reported
|
|
20
|
+
approximate USD when available). Pi sessions populate it from
|
|
21
|
+
`get_session_stats.cost`; adapters without reliable cost stay `null`.
|
|
22
|
+
- README, dispatch telemetry docs, and dispatch guide now document Pi RPC
|
|
23
|
+
usage and the `--` child-flag pattern.
|
|
24
|
+
|
|
25
|
+
## [0.7.3] - 2026-05-13 | 01:43 PM | IST
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- `harnex run codex --fast` now opts Codex app-server runs into
|
|
30
|
+
`service_tier="fast"`. Default Codex runs now inject
|
|
31
|
+
`service_tier="flex"` unless the child CLI args already supply an
|
|
32
|
+
explicit `service_tier` config.
|
|
33
|
+
- First-class `opencode` PTY adapter. `harnex run opencode` now uses
|
|
34
|
+
`Harnex::Adapters::Opencode` instead of the generic fallback, with
|
|
35
|
+
an OpenCode-specific stop sequence (double Ctrl+C), repo path
|
|
36
|
+
inference (`--dir` or positional project path), and session-id
|
|
37
|
+
extraction from transcript tails (`Continue opencode -s ...`).
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `harnex run` now rejects unknown long flags before spawning the
|
|
42
|
+
agent process, with a clear error pointing at `harnex run --help`.
|
|
43
|
+
Anything past the `--` separator continues to forward unchanged
|
|
44
|
+
to the agent CLI. Closes the trigger that correlated with the F23
|
|
45
|
+
auto-stop teardown leak. Closes harnex issue #38.
|
|
46
|
+
- Codex app-server contract fixtures are refreshed against
|
|
47
|
+
`codex-cli 0.130.0`; response builders now include the required
|
|
48
|
+
`thread.sessionId` field.
|
|
49
|
+
- Internal Codex app-server code now has the extracted
|
|
50
|
+
`Harnex::Codex::AppServer::Client` namespace and the subprocess
|
|
51
|
+
restart primitive needed by the deployment-fallback plan. No
|
|
52
|
+
public fallback CLI flag is exposed yet.
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- `harnex run` now defaults dispatch summaries to
|
|
57
|
+
`<repo>/.harnex/dispatch.jsonl` for every resolved repo, regardless
|
|
58
|
+
of whether a legacy `koder/` directory exists. Closes harnex issue
|
|
59
|
+
#39.
|
|
60
|
+
- `harnex run` with `--auto-stop` now exits within a bounded grace
|
|
61
|
+
(default 5s, override via `HARNEX_AUTOSTOP_TEARDOWN_GRACE_SECONDS`)
|
|
62
|
+
after `task_complete`. Closes a leak where the wrapping Ruby parent
|
|
63
|
+
process could sleep on `futex_wait_queue` indefinitely during
|
|
64
|
+
teardown, surviving as `orphan_tmux` until manually swept (F09
|
|
65
|
+
detected; F23 remediates). Closes harnex issue #37.
|
|
66
|
+
|
|
67
|
+
## [0.7.2] - 2026-05-08
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- `harnex run` now resolves the repo-local
|
|
72
|
+
`<repo>/.harnex/dispatch.jsonl` write path from the supervisor's
|
|
73
|
+
launch cwd (captured at invocation time), not from the agent's
|
|
74
|
+
runtime cwd. Closes a regression where cross-repo dispatches
|
|
75
|
+
(supervisor in repo A, agent `cd`'s into repo B) wrote their
|
|
76
|
+
terminal row only to the global fallback, never to repo A.
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- `harnex doctor --sweep` reports read-only harnex/tmux session drift,
|
|
81
|
+
including active registry rows, matching `cx-*` tmux windows, orphan
|
|
82
|
+
tmux windows, and stale session log files whose owning pid is gone.
|
|
83
|
+
|
|
84
|
+
## [0.7.1] - 2026-05-08
|
|
85
|
+
|
|
86
|
+
### Fixed
|
|
87
|
+
|
|
88
|
+
- `harnex run --auto-stop` now observes the terminal `task_complete`
|
|
89
|
+
event after the agent subprocess exits before tearing down, closing
|
|
90
|
+
a race where one-shot dispatches could report `timeout` even when
|
|
91
|
+
the agent finished the task cleanly. Adds a regression test that
|
|
92
|
+
exercises the post-exit event drain path.
|
|
93
|
+
|
|
94
|
+
- `harnex wait` predicates now classify dispatch progress by
|
|
95
|
+
structured event-record fields instead of regex-matching the
|
|
96
|
+
human-readable transcript, with the prior exact-marker text as a
|
|
97
|
+
legacy fallback. Eliminates a class of spurious matches where
|
|
98
|
+
prose containing a marker word was misread as a state transition.
|
|
99
|
+
|
|
100
|
+
### Added
|
|
101
|
+
|
|
102
|
+
- Dispatch summaries now preserve declared brief budget metadata
|
|
103
|
+
(`read_budget_lines`, `output_ceiling_lines`) from `--meta` and
|
|
104
|
+
record rough terminal measurements (`lines_changed`, `output_lines`,
|
|
105
|
+
`output_bytes`, `event_records`) for downstream budget enforcement.
|
|
106
|
+
|
|
107
|
+
## [0.7.0] - 2026-05-08
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
|
|
111
|
+
- `harnex run` now appends one terminal dispatch record to
|
|
112
|
+
`<repo>/.harnex/dispatch.jsonl`, falling back to
|
|
113
|
+
`~/.local/state/harnex/dispatch.jsonl` outside git repos. New
|
|
114
|
+
`harnex history` reads that log with `--limit`, `--since`, `--id`,
|
|
115
|
+
`--global`, `--json`, and `--all` filters.
|
|
116
|
+
- DISPATCH row `actual` now includes `turn_count`, `tool_calls`,
|
|
117
|
+
`commands_executed`, `rate_limits`, `output_log_path`, and
|
|
118
|
+
`events_log_path` — surfacing data harnex already tracked but did
|
|
119
|
+
not persist. `meta.parent_dispatch_id` now auto-derives from
|
|
120
|
+
`$HARNEX_ID` when not supplied via `--meta`. (#35 Tier 2)
|
|
121
|
+
- DISPATCH row `meta.agent_provider` and `meta.agent_version` now
|
|
122
|
+
populated. `provider` is a per-adapter constant
|
|
123
|
+
(claude → `anthropic`, codex → `openai`, generic → nil).
|
|
124
|
+
`agent_version` lazily probes `<base_command.first> --version`
|
|
125
|
+
with a 2s timeout, memoizes per adapter, and falls back to nil if
|
|
126
|
+
the binary is missing or stalls. (#35 Tier 3)
|
|
127
|
+
|
|
128
|
+
### Removed
|
|
129
|
+
|
|
130
|
+
- DISPATCH row dropped four always-null fields with no code path
|
|
131
|
+
populating them: `actual.cost_usd`, `actual.tests_run`,
|
|
132
|
+
`actual.tests_passed`, `actual.tests_failed`, and
|
|
133
|
+
`meta.agent_deployment`. Cost computation belongs to downstream
|
|
134
|
+
consumers (per-model rate tables change frequently); test-result
|
|
135
|
+
aggregation belongs to CI integrations, not the harness; and the
|
|
136
|
+
`agent_deployment` concept had no source of truth. JSON Lines
|
|
137
|
+
consumers should update column readers — schema is now stable but
|
|
138
|
+
smaller. (#35 Tier 3)
|
|
139
|
+
|
|
140
|
+
### Fixed
|
|
141
|
+
|
|
142
|
+
- `harnex wait` (default exit-watch mode) now blocks until the
|
|
143
|
+
exit-status file is on disk after the agent subprocess dies, with
|
|
144
|
+
a 5s grace bound (override via `HARNEX_EXIT_STATUS_GRACE_SECONDS`).
|
|
145
|
+
The exit-status file is written *after* the DISPATCH row in the
|
|
146
|
+
parent's teardown ensure block, so its presence guarantees the row
|
|
147
|
+
is on disk. Closes the race where `wait` could return between
|
|
148
|
+
`Process.wait2` unblocking and `Session#finalize_session!`
|
|
149
|
+
appending the row, which made dispatch-poll orchestrators flake
|
|
150
|
+
on "missing telemetry". (#36)
|
|
151
|
+
|
|
152
|
+
### Changed
|
|
153
|
+
|
|
154
|
+
- `koder/STATE.md` is now a thin past / present / future handoff
|
|
155
|
+
instead of a long-running project history. Durable change history
|
|
156
|
+
belongs in `CHANGELOG.md`, release verification in `koder/releases/`,
|
|
157
|
+
and issue or implementation detail in `koder/issues/` or
|
|
158
|
+
`koder/plans/`.
|
|
159
|
+
- Agent orientation and the repo-local `open` / `close` skills now
|
|
160
|
+
explicitly tell future sessions to keep `STATE.md` concise and route
|
|
161
|
+
detailed notes to the durable tracking document that owns them.
|
|
162
|
+
|
|
5
163
|
## [0.6.5] — 2026-05-07
|
|
6
164
|
|
|
7
165
|
### Added
|
data/README.md
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Run multiple AI coding agents from your terminal and coordinate them.
|
|
4
4
|
|
|
5
|
-
Harnex wraps Claude Code
|
|
6
|
-
local harness so you can launch agents, send them tasks,
|
|
7
|
-
|
|
5
|
+
Harnex wraps Claude Code, OpenAI Codex, Pi, OpenCode, or any terminal CLI in a
|
|
6
|
+
local harness so you can launch agents, send them tasks, inspect panes,
|
|
7
|
+
transcripts, and events, and stop them cleanly -- all from the command line.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
gem install harnex
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Harnex itself requires **Ruby 3.x** and uses only the Ruby standard
|
|
14
|
+
library. Install the CLIs you want to wrap separately; Codex JSON-RPC
|
|
15
|
+
support requires Codex CLI **0.128.0 or newer**, and tmux-backed
|
|
16
|
+
workflows require `tmux`.
|
|
14
17
|
|
|
15
18
|
Then ask the CLI what to do next:
|
|
16
19
|
|
|
@@ -20,6 +23,9 @@ harnex --help
|
|
|
20
23
|
harnex agents-guide
|
|
21
24
|
```
|
|
22
25
|
|
|
26
|
+
If you use Codex, run `harnex doctor` after installing or upgrading the
|
|
27
|
+
Codex CLI. It verifies the local `codex app-server` prerequisite.
|
|
28
|
+
|
|
23
29
|
`harnex agents-guide` is the agent-facing reference for dispatch, chain,
|
|
24
30
|
buddy, monitoring, and naming patterns. It is packaged in the gem; no skills
|
|
25
31
|
or project-local docs are required.
|
|
@@ -28,7 +34,7 @@ or project-local docs are required.
|
|
|
28
34
|
|
|
29
35
|
```bash
|
|
30
36
|
# Start an agent in tmux
|
|
31
|
-
harnex run
|
|
37
|
+
harnex run pi --id planner --tmux planner
|
|
32
38
|
|
|
33
39
|
# Send it a task and wait for it to finish
|
|
34
40
|
harnex send --id planner --message "Write a plan to /tmp/plan.md" --wait-for-idle
|
|
@@ -46,11 +52,12 @@ job, watch it work, stop it when done.
|
|
|
46
52
|
## Why use this
|
|
47
53
|
|
|
48
54
|
- **You want agents to plan, implement, review, and fix — in sequence.**
|
|
49
|
-
|
|
55
|
+
Pi writes code. Claude reviews it. Pi (or another adapter) fixes the review
|
|
50
56
|
findings. Each step is a fresh agent with clean context.
|
|
51
57
|
|
|
52
|
-
- **You want to see what agents are doing.** `harnex pane`
|
|
53
|
-
|
|
58
|
+
- **You want to see what agents are doing.** `harnex pane` captures a
|
|
59
|
+
tmux-backed terminal, `harnex logs` tails the persisted transcript, and
|
|
60
|
+
`harnex events` streams structured JSONL lifecycle events.
|
|
54
61
|
|
|
55
62
|
- **You don't want to babysit.** Send a task with `--wait-for-idle`,
|
|
56
63
|
walk away, check back when it's done.
|
|
@@ -68,31 +75,51 @@ job, watch it work, stop it when done.
|
|
|
68
75
|
|
|
69
76
|
| Agent | Support |
|
|
70
77
|
|-------|---------|
|
|
71
|
-
| Claude Code |
|
|
72
|
-
| OpenAI Codex |
|
|
73
|
-
|
|
|
78
|
+
| Claude Code | PTY adapter with prompt detection, stop sequence, workspace trust, and vim mode handling |
|
|
79
|
+
| OpenAI Codex | JSON-RPC `codex app-server` adapter by default; PTY mode remains supported for TUI/interactive use via `--legacy-pty` |
|
|
80
|
+
| Pi | JSONL RPC adapter (`pi --mode rpc`) with structured completion, tool events, extension-UI auto-cancel, and session stats telemetry |
|
|
81
|
+
| OpenCode | PTY adapter with native Ctrl+C stop handling and OpenCode-specific prompt/readiness heuristics |
|
|
82
|
+
| Any terminal CLI | Generic PTY wrapping with local API, logs, status, and best-effort prompt detection |
|
|
83
|
+
|
|
84
|
+
`harnex run codex` uses JSON-RPC by default. That path provides
|
|
85
|
+
structured task-completion events, approval mediation, and token usage
|
|
86
|
+
capture. Default JSON-RPC Codex does not accept `-m` / `--model`; pass
|
|
87
|
+
model settings as child CLI config, for example `harnex run codex -- -c model=NAME`.
|
|
88
|
+
Harnex forces Codex app-server `service_tier="flex"` unless you opt into
|
|
89
|
+
`service_tier="fast"` with `harnex run codex --fast`.
|
|
90
|
+
Use `harnex run codex --legacy-pty` when you specifically want Codex's
|
|
91
|
+
terminal UI or PTY-only Codex flags. The flag name is historical; the PTY path
|
|
92
|
+
is still supported.
|
|
93
|
+
|
|
94
|
+
`harnex run pi` launches `pi --mode rpc` and sends `--context` as a structured
|
|
95
|
+
`prompt` command (not a CLI positional argument). Pass Pi child flags after the
|
|
96
|
+
separator, for example:
|
|
97
|
+
`harnex run pi --context "Implement X" -- --model anthropic/claude-sonnet-4-5 --thinking high`.
|
|
74
98
|
|
|
75
99
|
## Multi-agent workflows
|
|
76
100
|
|
|
77
101
|
The real power is chaining agents together:
|
|
78
102
|
|
|
79
103
|
```bash
|
|
80
|
-
# 1.
|
|
81
|
-
harnex run
|
|
82
|
-
harnex send --id
|
|
83
|
-
harnex stop --id
|
|
104
|
+
# 1. Pi writes a plan
|
|
105
|
+
harnex run pi --id pi-plan --tmux pi-plan
|
|
106
|
+
harnex send --id pi-plan --message "Plan the auth module, write to /tmp/plan.md" --wait-for-idle
|
|
107
|
+
harnex stop --id pi-plan
|
|
84
108
|
|
|
85
|
-
# 2. Fresh
|
|
86
|
-
harnex run
|
|
87
|
-
harnex send --id
|
|
88
|
-
harnex stop --id
|
|
109
|
+
# 2. Fresh Pi implements the plan
|
|
110
|
+
harnex run pi --id pi-impl --tmux pi-impl
|
|
111
|
+
harnex send --id pi-impl --message "Implement /tmp/plan.md, run tests" --wait-for-idle
|
|
112
|
+
harnex stop --id pi-impl
|
|
89
113
|
|
|
90
114
|
# 3. Claude reviews the implementation
|
|
91
|
-
harnex run claude --id cl-review --tmux
|
|
115
|
+
harnex run claude --id cl-review --tmux cl-review
|
|
92
116
|
harnex send --id cl-review --message "Review changes against /tmp/plan.md, write /tmp/review.md" --wait-for-idle
|
|
93
117
|
harnex stop --id cl-review
|
|
94
118
|
```
|
|
95
119
|
|
|
120
|
+
For delegated work, pass the same value to `--id` and `--tmux` so
|
|
121
|
+
`harnex status`, `harnex pane`, logs, and the tmux window name all line up.
|
|
122
|
+
|
|
96
123
|
Harnex ships CLI-readable agent guides for this pattern:
|
|
97
124
|
|
|
98
125
|
- **[Dispatch](guides/01_dispatch.md)** — the fire-and-watch pattern:
|
|
@@ -117,13 +144,15 @@ harnex agents-guide monitoring
|
|
|
117
144
|
For unattended dispatches, use `--watch` instead of writing a bash poll loop:
|
|
118
145
|
|
|
119
146
|
```bash
|
|
120
|
-
harnex run
|
|
147
|
+
harnex run pi --id pi-impl-42 --watch --preset impl \
|
|
121
148
|
--context "Implement koder/plans/42_plan.md. Run tests and commit when done."
|
|
122
149
|
```
|
|
123
150
|
|
|
124
151
|
`--watch` runs a foreground babysitter that checks session activity every 60s,
|
|
125
152
|
force-resumes on stall up to a cap, and exits when the target session exits or
|
|
126
|
-
the resume cap is reached.
|
|
153
|
+
the resume cap is reached. It is foreground-only; use `--tmux` or `--detach`
|
|
154
|
+
for visible/background sessions, and `--watch` when the current command should
|
|
155
|
+
block as the monitor.
|
|
127
156
|
|
|
128
157
|
Presets map to stall policy defaults:
|
|
129
158
|
|
|
@@ -133,19 +162,57 @@ Presets map to stall policy defaults:
|
|
|
133
162
|
|
|
134
163
|
Explicit `--stall-after` and `--max-resumes` flags override preset defaults.
|
|
135
164
|
|
|
165
|
+
For file-change hooks, use `--watch-file PATH`. The older
|
|
166
|
+
`--watch PATH`/`--watch=PATH` form is still accepted for compatibility, while
|
|
167
|
+
bare `--watch` means babysitter mode.
|
|
168
|
+
|
|
169
|
+
For one-shot startup prompts, add `--auto-stop`. It requires `--context`
|
|
170
|
+
and stops the session after the first task completion or PTY prompt return.
|
|
171
|
+
|
|
136
172
|
For structured subscriptions, stream JSONL events:
|
|
137
173
|
|
|
138
174
|
```bash
|
|
139
|
-
harnex events --id
|
|
175
|
+
harnex events --id pi-impl-42
|
|
140
176
|
```
|
|
141
177
|
|
|
142
178
|
Schema details and compatibility policy are documented in
|
|
143
179
|
[docs/events.md](docs/events.md).
|
|
144
180
|
|
|
181
|
+
## Dispatch history
|
|
182
|
+
|
|
183
|
+
Every finished `harnex run` writes dispatch records. In a git repo, the
|
|
184
|
+
default path is `<repo>/.harnex/dispatch.jsonl`; outside a git repo, the
|
|
185
|
+
compact history record falls back to `~/.local/state/harnex/dispatch.jsonl`.
|
|
186
|
+
`harnex history` reads the compact records from that location.
|
|
187
|
+
|
|
188
|
+
Use `harnex history` to inspect it:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
harnex history
|
|
192
|
+
harnex history --json | jq .
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Dispatch briefs can declare soft budget metadata through `--meta`:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
harnex run pi --meta '{"read_budget_lines":2000,"output_ceiling_lines":800}' ...
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Those declared values are copied into summary `meta`. Terminal summary
|
|
202
|
+
`actual` records timing, exit classification, token usage when the adapter can
|
|
203
|
+
capture it, adapter-reported `cost_usd` when reliably available, git deltas,
|
|
204
|
+
task-completion state, operational counters (`stalls`, `force_resumes`,
|
|
205
|
+
`disconnections`, `tool_calls`, `commands_executed`), output/event log paths,
|
|
206
|
+
and rough volume measurements such as `lines_changed`, `output_lines`,
|
|
207
|
+
`output_bytes`, and `event_records`.
|
|
208
|
+
Harnex records the data only; consumers decide whether to fail closed. See
|
|
209
|
+
[docs/dispatch-telemetry.md](docs/dispatch-telemetry.md) for the field
|
|
210
|
+
contract.
|
|
211
|
+
|
|
145
212
|
## Long-running and overnight work
|
|
146
213
|
|
|
147
214
|
For plain "force-resume on stall" recovery, use
|
|
148
|
-
`harnex run --watch --preset impl`.
|
|
215
|
+
`harnex run pi --watch --preset impl --context "Read /tmp/task.md"`.
|
|
149
216
|
|
|
150
217
|
A **buddy** is for richer reasoning: doc drift checks, semantic sanity checks,
|
|
151
218
|
and multi-session correlation. It's still just another harnex session.
|
|
@@ -155,8 +222,8 @@ and multi-session correlation. It's still just another harnex session.
|
|
|
155
222
|
Spawn a buddy alongside a long-running implementation worker:
|
|
156
223
|
|
|
157
224
|
```bash
|
|
158
|
-
harnex run
|
|
159
|
-
harnex run
|
|
225
|
+
harnex run pi --id worker-42 --tmux worker-42
|
|
226
|
+
harnex run pi --id buddy-42 --tmux buddy-42
|
|
160
227
|
harnex send --id buddy-42 --message "$(cat <<'EOF'
|
|
161
228
|
Watch harnex session worker-42.
|
|
162
229
|
Every 5 minutes: run `harnex pane --id worker-42 --lines 30`.
|
|
@@ -165,7 +232,7 @@ nudge it: `harnex send --id worker-42 --message "Continue your task."`.
|
|
|
165
232
|
When it exits, report back:
|
|
166
233
|
tmux send-keys -t "$HARNEX_SPAWNER_PANE" "worker-42 done" Enter
|
|
167
234
|
EOF
|
|
168
|
-
"
|
|
235
|
+
)"
|
|
169
236
|
```
|
|
170
237
|
|
|
171
238
|
### Example: watch for doc drift during implementation
|
|
@@ -174,8 +241,8 @@ A buddy that checks whether a worker's code changes have left
|
|
|
174
241
|
docs out of date:
|
|
175
242
|
|
|
176
243
|
```bash
|
|
177
|
-
harnex run
|
|
178
|
-
harnex run
|
|
244
|
+
harnex run pi --id worker-99 --tmux worker-99
|
|
245
|
+
harnex run pi --id buddy-99 --tmux buddy-99
|
|
179
246
|
harnex send --id buddy-99 --message "$(cat <<'EOF'
|
|
180
247
|
Watch harnex session worker-99.
|
|
181
248
|
Every 5 minutes: run `harnex pane --id worker-99 --lines 30`.
|
|
@@ -187,7 +254,7 @@ inline comments) that are now stale. If so, nudge the worker:
|
|
|
187
254
|
When the worker exits, report a summary to the invoker:
|
|
188
255
|
tmux send-keys -t "$HARNEX_SPAWNER_PANE" "worker-99 done. Doc drift: <yes/no>" Enter
|
|
189
256
|
EOF
|
|
190
|
-
"
|
|
257
|
+
)"
|
|
191
258
|
```
|
|
192
259
|
|
|
193
260
|
### The invoker doesn't need to be a harnex session
|
|
@@ -210,13 +277,15 @@ See [recipes/03_buddy.md](recipes/03_buddy.md) for the full pattern.
|
|
|
210
277
|
| `harnex send --id <id>` | Send a message (queues if busy, `--wait-for-idle` to block until done) |
|
|
211
278
|
| `harnex stop --id <id>` | Send the agent's native exit sequence |
|
|
212
279
|
| `harnex status` | List running sessions (`--json` for full payloads) |
|
|
213
|
-
| `harnex pane --id <id>` | Capture
|
|
280
|
+
| `harnex pane --id <id>` | Capture a tmux-backed session's screen (`--follow` for live) |
|
|
214
281
|
| `harnex logs --id <id>` | Read session transcript (`--follow` to tail) |
|
|
215
282
|
| `harnex events --id <id>` | Stream structured session events (`--snapshot` for non-blocking dump) |
|
|
216
|
-
| `harnex
|
|
283
|
+
| `harnex history` | List completed dispatches from `.harnex/dispatch.jsonl` |
|
|
284
|
+
| `harnex wait --id <id>` | Block until exit, a target state, or `--until task_complete` |
|
|
285
|
+
| `harnex doctor` | Run adapter dependency preflight checks; add `--sweep` for read-only session drift diagnostics |
|
|
217
286
|
| `harnex guide` | Getting started walkthrough |
|
|
218
287
|
| `harnex agents-guide` | Agent-facing dispatch, chain, buddy, monitoring, and naming guides |
|
|
219
|
-
| `harnex recipes` |
|
|
288
|
+
| `harnex recipes` | List and read tested workflow patterns (`show 01`, `show buddy`) |
|
|
220
289
|
|
|
221
290
|
## Uninstalling
|
|
222
291
|
|
data/TECHNICAL.md
CHANGED
|
@@ -29,6 +29,7 @@ harnex run codex -- --cd ~/other/repo
|
|
|
29
29
|
| `--watch-file PATH` | Auto-send a file-change hook (`--watch PATH`/`--watch=PATH` legacy) |
|
|
30
30
|
| `--context TXT` | Give the agent a task on startup |
|
|
31
31
|
| `--auto-stop` | With `--context`, stop after the first task completion |
|
|
32
|
+
| `--fast` | For Codex, use `service_tier="fast"` instead of default `flex` |
|
|
32
33
|
| `--timeout SEC` | Wait budget for detached registration |
|
|
33
34
|
|
|
34
35
|
### `harnex send` — Talk to a running agent
|
|
@@ -88,6 +89,16 @@ harnex wait --id worker
|
|
|
88
89
|
harnex wait --id worker --until prompt --timeout 300
|
|
89
90
|
```
|
|
90
91
|
|
|
92
|
+
### `harnex history` — List completed dispatches
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
harnex history
|
|
96
|
+
harnex history --json | jq .
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Reads `<repo>/.harnex/dispatch.jsonl`, where `<repo>` is found by walking up
|
|
100
|
+
until `.git/` is present. Use `--global` for the no-repo fallback file.
|
|
101
|
+
|
|
91
102
|
### `harnex logs` — Read session transcripts
|
|
92
103
|
|
|
93
104
|
```bash
|
|
@@ -247,6 +258,7 @@ Schema details and compatibility guarantees are in [docs/events.md](docs/events.
|
|
|
247
258
|
├── base.rb adapter interface
|
|
248
259
|
├── generic.rb fallback adapter for any CLI
|
|
249
260
|
├── codex.rb codex-specific behavior
|
|
261
|
+
├── opencode.rb opencode-specific behavior
|
|
250
262
|
└── claude.rb claude-specific behavior
|
|
251
263
|
```
|
|
252
264
|
|
|
@@ -365,6 +377,17 @@ The adapter reads the screen and returns a state hash:
|
|
|
365
377
|
- Multi-step submit: types text, then sends Enter after a
|
|
366
378
|
short delay so pasted prompts are actually submitted
|
|
367
379
|
|
|
380
|
+
### OpenCode Adapter
|
|
381
|
+
|
|
382
|
+
- Uses optimistic PTY prompt detection to avoid inbox deadlock
|
|
383
|
+
when OpenCode's alternate-screen TUI omits stable plain-text
|
|
384
|
+
prompt markers in snapshots.
|
|
385
|
+
- Stop sequence sends a double Ctrl+C to match OpenCode's native
|
|
386
|
+
terminal shutdown path (interrupt first, force-quit second if
|
|
387
|
+
needed).
|
|
388
|
+
- Multi-step submit mirrors Claude/Codex PTY behavior: text first,
|
|
389
|
+
then Enter with a short delay.
|
|
390
|
+
|
|
368
391
|
## State Machine
|
|
369
392
|
|
|
370
393
|
`SessionState` tracks the agent's readiness:
|
data/guides/01_dispatch.md
CHANGED
|
@@ -17,7 +17,7 @@ Inside a harnex-managed session, these environment variables are available:
|
|
|
17
17
|
|
|
18
18
|
| Variable | Meaning |
|
|
19
19
|
| --- | --- |
|
|
20
|
-
| `HARNEX_SESSION_CLI` | Wrapped CLI name, such as `codex
|
|
20
|
+
| `HARNEX_SESSION_CLI` | Wrapped CLI name, such as `pi`, `codex`, or `claude` |
|
|
21
21
|
| `HARNEX_ID` | Current harnex session ID |
|
|
22
22
|
| `HARNEX_SESSION_REPO_ROOT` | Repo root for the session |
|
|
23
23
|
| `HARNEX_SESSION_ID` | Internal harnex instance ID |
|
|
@@ -34,13 +34,13 @@ Decide how results come back before you delegate work.
|
|
|
34
34
|
Inside harnex, instruct the peer to reply to your own session:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
harnex send --id
|
|
37
|
+
harnex send --id pi-i-NN --message "Read /tmp/task-impl-NN.md. When done, send one summary line back to harnex id $HARNEX_ID."
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Outside harnex, require a file or another explicit return path:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
harnex send --id
|
|
43
|
+
harnex send --id pi-i-NN --message "Read /tmp/task-impl-NN.md. Write final status to /tmp/pi-i-NN-done.txt."
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Do not delegate work without an explicit completion contract.
|
|
@@ -48,18 +48,18 @@ Do not delegate work without an explicit completion contract.
|
|
|
48
48
|
## Spawn
|
|
49
49
|
|
|
50
50
|
Launch worker sessions in tmux when a user or orchestrator may need to inspect
|
|
51
|
-
them live:
|
|
51
|
+
them live. Default to Pi unless a task explicitly requires another adapter:
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
harnex run
|
|
54
|
+
harnex run pi --id pi-i-NN --tmux pi-i-NN \
|
|
55
55
|
--context "Implement the project plan in /tmp/task-impl-NN.md. Run tests when done."
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
For long prompts, write the details into a file and reference it.
|
|
59
|
-
reliable with short injected messages.
|
|
58
|
+
For long prompts, write the details into a file and reference it. Structured
|
|
59
|
+
sends are more reliable with short injected messages.
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
harnex run
|
|
62
|
+
harnex run pi --id pi-i-NN --tmux pi-i-NN \
|
|
63
63
|
--context "Read and execute /tmp/task-impl-NN.md"
|
|
64
64
|
```
|
|
65
65
|
|
|
@@ -70,7 +70,7 @@ parallel orchestration compact:
|
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
72
|
for i in 1 2 3; do
|
|
73
|
-
harnex run
|
|
73
|
+
harnex run pi --id w-$i --tmux w-$i --detach \
|
|
74
74
|
--context "Read and execute /tmp/task-$i.md" --auto-stop &
|
|
75
75
|
done
|
|
76
76
|
for i in 1 2 3; do harnex wait --id w-$i & done
|
|
@@ -81,25 +81,28 @@ Rule: when you use `--tmux`, pass the same name as `--id`. If you pass only
|
|
|
81
81
|
`--tmux NAME`, harnex creates a random session ID and the pane name no longer
|
|
82
82
|
matches `harnex status` or `harnex pane --id`.
|
|
83
83
|
|
|
84
|
+
Pi runs use structured RPC (`pi --mode rpc`). Pass Pi child flags after `--`
|
|
85
|
+
(e.g. `harnex run pi --context "..." -- --model anthropic/claude-sonnet-4-5 --thinking high`).
|
|
86
|
+
|
|
84
87
|
Codex flag forms differ between transports. The default JSON-RPC adapter
|
|
85
88
|
(`codex app-server`) does not accept `-m`/`--model`; pass the model as
|
|
86
89
|
`-c model="<name>"` instead. The legacy PTY adapter (`harnex run codex
|
|
87
|
-
--legacy-pty`) still accepts `-m`.
|
|
88
|
-
|
|
90
|
+
--legacy-pty`) still accepts `-m`. Codex app-server runs also default to
|
|
91
|
+
`service_tier="flex"`; add `--fast` to use `service_tier="fast"`.
|
|
89
92
|
|
|
90
93
|
## Send
|
|
91
94
|
|
|
92
95
|
Use `--message` for short instructions and file references:
|
|
93
96
|
|
|
94
97
|
```bash
|
|
95
|
-
harnex send --id
|
|
98
|
+
harnex send --id pi-i-NN --message "Continue with /tmp/task-impl-NN.md. Report final status to $HARNEX_ID."
|
|
96
99
|
```
|
|
97
100
|
|
|
98
101
|
Use `--wait-for-idle` only as a turn fence. It proves that one send returned to
|
|
99
102
|
an idle state; it is not a full work-completion signal.
|
|
100
103
|
|
|
101
104
|
```bash
|
|
102
|
-
harnex send --id
|
|
105
|
+
harnex send --id pi-i-NN --message "Run the acceptance test." --wait-for-idle --timeout 900
|
|
103
106
|
```
|
|
104
107
|
|
|
105
108
|
Messages sent from one harnex session to another include a relay header:
|
|
@@ -118,16 +121,16 @@ Use the lightest primitive that gives the signal you need:
|
|
|
118
121
|
|
|
119
122
|
| Need | Command |
|
|
120
123
|
| --- | --- |
|
|
121
|
-
| Current live screen | `harnex pane --id
|
|
122
|
-
| Continuous pane view | `harnex pane --id
|
|
123
|
-
| Transcript tail | `harnex logs --id
|
|
124
|
-
| Structured events | `harnex events --id
|
|
125
|
-
| Native turn completion | `harnex wait --id
|
|
124
|
+
| Current live screen | `harnex pane --id pi-i-NN --lines 40` |
|
|
125
|
+
| Continuous pane view | `harnex pane --id pi-i-NN --follow` |
|
|
126
|
+
| Transcript tail | `harnex logs --id pi-i-NN --lines 80` |
|
|
127
|
+
| Structured events | `harnex events --id pi-i-NN --snapshot` |
|
|
128
|
+
| Native turn completion | `harnex wait --id pi-i-NN --until task_complete` |
|
|
126
129
|
|
|
127
130
|
For unattended policy-only stall recovery, use built-in watch mode:
|
|
128
131
|
|
|
129
132
|
```bash
|
|
130
|
-
harnex run
|
|
133
|
+
harnex run pi --id pi-i-NN --watch --preset impl --context "Read /tmp/task-impl-NN.md"
|
|
131
134
|
```
|
|
132
135
|
|
|
133
136
|
`--watch` is foreground-blocking. Use it when a single process should launch
|
|
@@ -140,10 +143,10 @@ Before stopping a worker, verify the expected artifact, test result, commit,
|
|
|
140
143
|
or review output exists:
|
|
141
144
|
|
|
142
145
|
```bash
|
|
143
|
-
harnex pane --id
|
|
146
|
+
harnex pane --id pi-i-NN --lines 60
|
|
144
147
|
git status --short
|
|
145
148
|
git log --oneline -5
|
|
146
|
-
harnex stop --id
|
|
149
|
+
harnex stop --id pi-i-NN
|
|
147
150
|
```
|
|
148
151
|
|
|
149
152
|
Stop completed sessions promptly. Fresh workers are easier to reason about
|
data/guides/02_chain.md
CHANGED
|
@@ -39,6 +39,9 @@ Issue or request
|
|
|
39
39
|
Each arrow is a fresh harnex worker when delegated. Pass state through files:
|
|
40
40
|
the issue, plan, review file, fix summary, test log, or done marker.
|
|
41
41
|
|
|
42
|
+
Default adapter choice for autonomous chain steps is Pi (`harnex run pi ...`).
|
|
43
|
+
Use another adapter only when the task explicitly requires it.
|
|
44
|
+
|
|
42
45
|
## Per-Plan Loop
|
|
43
46
|
|
|
44
47
|
For each independently testable plan:
|
|
@@ -72,8 +75,8 @@ Recommended limits:
|
|
|
72
75
|
| Code review/fix | Serial per implementation |
|
|
73
76
|
|
|
74
77
|
When parallelizing, cap the number of active workers to what the machine and
|
|
75
|
-
CLI provider can handle. A practical upper bound is five
|
|
76
|
-
all
|
|
78
|
+
CLI provider can handle. A practical upper bound is five active sessions across
|
|
79
|
+
all lanes unless the user requested more.
|
|
77
80
|
|
|
78
81
|
## Worktrees
|
|
79
82
|
|
|
@@ -84,7 +87,7 @@ untracked files do not carry over.
|
|
|
84
87
|
```bash
|
|
85
88
|
git worktree add ../project-plan-NN -b plan/NN main
|
|
86
89
|
cd ../project-plan-NN
|
|
87
|
-
harnex run
|
|
90
|
+
harnex run pi --id pi-i-NN --tmux pi-i-NN \
|
|
88
91
|
--context "Read the project plan and implement this isolated lane."
|
|
89
92
|
```
|
|
90
93
|
|