harnex 0.3.3 → 0.3.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/TECHNICAL.md +23 -26
- data/lib/harnex/commands/skills.rb +30 -10
- data/lib/harnex/version.rb +2 -2
- data/skills/harnex/SKILL.md +9 -337
- data/skills/harnex-buddy/SKILL.md +15 -15
- data/skills/harnex-chain/SKILL.md +90 -192
- data/skills/harnex-dispatch/SKILL.md +99 -9
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e5db22a80eebc5f0441437c96a2f949f0dd117cf78a2cc0810f24172c7af7cd4
|
|
4
|
+
data.tar.gz: 3ad9ed119b373258b1e8c56ea80b27ea49dad028031e19bd4ee0697996a45046
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1dd3ad5ef1cf5bb17d6a92ea6b27b746ef47a8e1a8e58b1e2a98936946f63f58d8d297d7493ffc3ab3968e25ac26415ae73c44524423a83f36c5951b4e729813
|
|
7
|
+
data.tar.gz: 39cf0ed49b278a10ff57767d6cc166232e7c30ca9eed31853d079a2a437dcd0ee4709a8a13959e91bd106d8ce7b1e1b043b64a6df0fd24988a925266c488769a
|
data/TECHNICAL.md
CHANGED
|
@@ -503,19 +503,21 @@ and `Inbox` classes use `ConditionVariable` for signaling.
|
|
|
503
503
|
|
|
504
504
|
## Skill Files
|
|
505
505
|
|
|
506
|
-
Harnex ships
|
|
507
|
-
|
|
506
|
+
Harnex ships bundled skills that teach agents the orchestration workflow and
|
|
507
|
+
dispatch discipline. The canonical collaboration skill is:
|
|
508
508
|
|
|
509
509
|
```
|
|
510
|
-
skills/harnex/SKILL.md
|
|
510
|
+
skills/harnex-dispatch/SKILL.md
|
|
511
511
|
```
|
|
512
512
|
|
|
513
513
|
### What's in the skill
|
|
514
514
|
|
|
515
|
-
The skill tells agents:
|
|
515
|
+
The dispatch skill tells agents:
|
|
516
516
|
|
|
517
517
|
- How to detect they're inside a harnex session (env vars)
|
|
518
|
-
- How to
|
|
518
|
+
- How to define return channels before delegation
|
|
519
|
+
- How to send short, file-referenced tasks with explicit reply instructions
|
|
520
|
+
- How to send messages, check status, spawn workers, and stop safely
|
|
519
521
|
- How to use `--context`, `--force`, `--no-wait`
|
|
520
522
|
- Relay header format and behavior
|
|
521
523
|
- Collaboration patterns (reply, supervisor, file watch)
|
|
@@ -531,8 +533,8 @@ Skill files use YAML frontmatter:
|
|
|
531
533
|
|
|
532
534
|
```yaml
|
|
533
535
|
---
|
|
534
|
-
name: harnex
|
|
535
|
-
description:
|
|
536
|
+
name: harnex-dispatch
|
|
537
|
+
description: Fire & Watch dispatch pattern...
|
|
536
538
|
allowed-tools: Bash(harnex *)
|
|
537
539
|
---
|
|
538
540
|
```
|
|
@@ -540,41 +542,36 @@ allowed-tools: Bash(harnex *)
|
|
|
540
542
|
The `allowed-tools` field grants the agent permission to run
|
|
541
543
|
`harnex` commands without asking for approval each time.
|
|
542
544
|
|
|
543
|
-
###
|
|
545
|
+
### Installing bundled skills
|
|
544
546
|
|
|
545
|
-
|
|
546
|
-
repo), symlink it into each agent's skill directory:
|
|
547
|
+
Use the installer command instead of manual symlinks:
|
|
547
548
|
|
|
548
549
|
```bash
|
|
549
|
-
#
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
# For Codex
|
|
554
|
-
ln -s /path/to/harnex/skills/harnex \
|
|
555
|
-
~/.codex/skills/harnex
|
|
550
|
+
harnex skills install # all canonical skills
|
|
551
|
+
harnex skills install harnex # compatibility alias -> harnex-dispatch
|
|
552
|
+
harnex skills install --local # install into current repo only
|
|
556
553
|
```
|
|
557
554
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
555
|
+
Compatibility aliases accepted by the installer:
|
|
556
|
+
|
|
557
|
+
- `harnex` -> `harnex-dispatch`
|
|
558
|
+
- `dispatch` -> `harnex-dispatch`
|
|
559
|
+
- `chain-implement` -> `harnex-chain`
|
|
562
560
|
|
|
563
561
|
### Skill directory structure
|
|
564
562
|
|
|
565
563
|
```
|
|
566
564
|
~/.claude/skills/
|
|
567
|
-
└── harnex
|
|
565
|
+
└── harnex-dispatch
|
|
568
566
|
└── SKILL.md
|
|
569
567
|
|
|
570
568
|
~/.codex/skills/
|
|
571
|
-
└── harnex -> /
|
|
569
|
+
└── harnex-dispatch -> ~/.claude/skills/harnex-dispatch
|
|
572
570
|
└── SKILL.md
|
|
573
571
|
```
|
|
574
572
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
picked up immediately.
|
|
573
|
+
Deprecated installed names (`harnex`, `dispatch`, `chain-implement`) are
|
|
574
|
+
cleaned automatically during install and uninstall.
|
|
578
575
|
|
|
579
576
|
## Known Limitations
|
|
580
577
|
|
|
@@ -4,20 +4,26 @@ module Harnex
|
|
|
4
4
|
class Skills
|
|
5
5
|
SKILLS_ROOT = File.expand_path("../../../../skills", __FILE__)
|
|
6
6
|
INSTALL_SKILLS = %w[harnex-dispatch harnex-chain harnex-buddy].freeze
|
|
7
|
-
DEPRECATED_SKILLS = %w[dispatch chain-implement].freeze
|
|
7
|
+
DEPRECATED_SKILLS = %w[harnex dispatch chain-implement].freeze
|
|
8
|
+
SKILL_ALIASES = {
|
|
9
|
+
"harnex" => "harnex-dispatch",
|
|
10
|
+
"dispatch" => "harnex-dispatch",
|
|
11
|
+
"chain-implement" => "harnex-chain"
|
|
12
|
+
}.freeze
|
|
8
13
|
|
|
9
14
|
def self.usage
|
|
10
15
|
<<~TEXT
|
|
11
|
-
Usage: harnex skills <subcommand> [--local]
|
|
16
|
+
Usage: harnex skills <subcommand> [SKILL...] [--local]
|
|
12
17
|
|
|
13
18
|
Subcommands:
|
|
14
|
-
install Install bundled skills (globally by default)
|
|
19
|
+
install Install bundled skills (globally by default; optional skill names)
|
|
15
20
|
uninstall Remove installed skills (globally by default)
|
|
16
21
|
|
|
17
22
|
Options:
|
|
18
23
|
--local Target the current repo instead of global ~/.claude/
|
|
19
24
|
|
|
20
25
|
Installs: #{INSTALL_SKILLS.join(', ')}
|
|
26
|
+
Aliases: harnex|dispatch -> harnex-dispatch, chain-implement -> harnex-chain
|
|
21
27
|
|
|
22
28
|
By default, copies each skill to ~/.claude/skills/<skill>/
|
|
23
29
|
and symlinks ~/.codex/skills/<skill> to it.
|
|
@@ -35,12 +41,13 @@ module Harnex
|
|
|
35
41
|
subcommand = @argv.shift
|
|
36
42
|
case subcommand
|
|
37
43
|
when "install"
|
|
38
|
-
local, help = parse_args(@argv)
|
|
44
|
+
local, help, requested_skills = parse_args(@argv, allow_positional: true)
|
|
39
45
|
return (puts self.class.usage; 0) if help
|
|
40
46
|
|
|
41
47
|
remove_deprecated(local)
|
|
48
|
+
install_skills = requested_skills.empty? ? INSTALL_SKILLS : canonical_skill_names(requested_skills)
|
|
42
49
|
|
|
43
|
-
|
|
50
|
+
install_skills.each do |skill_name|
|
|
44
51
|
skill_source = resolve_skill_source(skill_name)
|
|
45
52
|
unless skill_source
|
|
46
53
|
return missing_skill(skill_name)
|
|
@@ -51,7 +58,7 @@ module Harnex
|
|
|
51
58
|
end
|
|
52
59
|
0
|
|
53
60
|
when "uninstall"
|
|
54
|
-
local, help = parse_args(@argv)
|
|
61
|
+
local, help, = parse_args(@argv)
|
|
55
62
|
return (puts self.class.usage; 0) if help
|
|
56
63
|
|
|
57
64
|
(INSTALL_SKILLS + DEPRECATED_SKILLS).each do |skill_name|
|
|
@@ -70,9 +77,10 @@ module Harnex
|
|
|
70
77
|
|
|
71
78
|
private
|
|
72
79
|
|
|
73
|
-
def parse_args(args)
|
|
80
|
+
def parse_args(args, allow_positional: false)
|
|
74
81
|
local = false
|
|
75
82
|
help = false
|
|
83
|
+
positional = []
|
|
76
84
|
|
|
77
85
|
args.each do |arg|
|
|
78
86
|
case arg
|
|
@@ -83,12 +91,16 @@ module Harnex
|
|
|
83
91
|
when /\A-/
|
|
84
92
|
raise "harnex skills: unknown option #{arg.inspect}"
|
|
85
93
|
else
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
if allow_positional
|
|
95
|
+
positional << arg
|
|
96
|
+
else
|
|
97
|
+
warn("harnex skills: unexpected argument #{arg.inspect}")
|
|
98
|
+
raise "harnex skills takes no positional arguments"
|
|
99
|
+
end
|
|
88
100
|
end
|
|
89
101
|
end
|
|
90
102
|
|
|
91
|
-
[local, help]
|
|
103
|
+
[local, help, positional]
|
|
92
104
|
end
|
|
93
105
|
|
|
94
106
|
def resolve_skill_source(skill_name)
|
|
@@ -107,6 +119,14 @@ module Harnex
|
|
|
107
119
|
end
|
|
108
120
|
end
|
|
109
121
|
|
|
122
|
+
def canonical_skill_names(skill_names)
|
|
123
|
+
skill_names.map { |name| canonical_skill_name(name) }.uniq
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def canonical_skill_name(skill_name)
|
|
127
|
+
SKILL_ALIASES.fetch(skill_name, skill_name)
|
|
128
|
+
end
|
|
129
|
+
|
|
110
130
|
def install_local(skill_name, skill_source)
|
|
111
131
|
repo_root = Harnex.resolve_repo_root(Dir.pwd)
|
|
112
132
|
claude_dir = File.join(repo_root, ".claude", "skills", skill_name)
|
data/lib/harnex/version.rb
CHANGED
data/skills/harnex/SKILL.md
CHANGED
|
@@ -1,348 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: harnex
|
|
3
|
-
description:
|
|
4
|
-
allowed-tools: Bash(harnex *)
|
|
3
|
+
description: Deprecated alias for harnex-dispatch. Use harnex-dispatch for active harnex collaboration guidance.
|
|
5
4
|
---
|
|
6
5
|
|
|
7
|
-
#
|
|
6
|
+
# Deprecated Skill Alias
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
getting started walkthrough, and `harnex recipes` for tested workflow patterns.
|
|
8
|
+
`harnex` is deprecated.
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
messages to a peer agent**, **check session status**, **spawn worker sessions**,
|
|
15
|
-
and **wait for them to finish**.
|
|
10
|
+
Use `harnex-dispatch` as the canonical skill for harnex collaboration,
|
|
11
|
+
Fire & Watch dispatching, relay handling, and return-channel discipline.
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Check environment variables to understand your role:
|
|
20
|
-
|
|
21
|
-
| Variable | Meaning |
|
|
22
|
-
|----------|---------|
|
|
23
|
-
| `HARNEX_SESSION_CLI` | Which CLI you are (`claude` or `codex`) |
|
|
24
|
-
| `HARNEX_ID` | Your session ID |
|
|
25
|
-
| `HARNEX_SESSION_REPO_ROOT` | Repo root this session is scoped to |
|
|
26
|
-
| `HARNEX_SESSION_ID` | Internal instance identifier |
|
|
27
|
-
| `HARNEX_SPAWNER_PANE` | Tmux pane ID (`%N`) of whoever spawned this session |
|
|
28
|
-
|
|
29
|
-
If these are set, you are **inside a harnex session** and can send messages to
|
|
30
|
-
peer sessions or spawn new worker sessions.
|
|
31
|
-
|
|
32
|
-
`HARNEX_SPAWNER_PANE` is the stable tmux pane ID of the invoker — use it to
|
|
33
|
-
reach back to the session that launched you, even if that session is not
|
|
34
|
-
harnex-managed:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
# Read the invoker's screen
|
|
38
|
-
tmux capture-pane -t "$HARNEX_SPAWNER_PANE" -p
|
|
39
|
-
|
|
40
|
-
# Type into the invoker
|
|
41
|
-
tmux send-keys -t "$HARNEX_SPAWNER_PANE" "done — results in /tmp/result.md" Enter
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Mode preference
|
|
45
|
-
|
|
46
|
-
When starting another agent session for the user, default to a visible tmux
|
|
47
|
-
session via `harnex run <cli> --tmux`. That is the preferred interactive mode
|
|
48
|
-
because the user can watch the peer's work live.
|
|
49
|
-
|
|
50
|
-
Use other modes only when the user asks for them or when visibility is not
|
|
51
|
-
wanted:
|
|
52
|
-
|
|
53
|
-
- prefer `--tmux` over a hidden foreground PTY for peer-agent work
|
|
54
|
-
- use plain foreground `harnex run` only when the current terminal is meant to
|
|
55
|
-
become that peer's UI
|
|
56
|
-
- use `--detach` only for explicitly headless/background workflows
|
|
57
|
-
|
|
58
|
-
## Return channel first
|
|
59
|
-
|
|
60
|
-
Before you start a peer session or send it work, decide how the result will get
|
|
61
|
-
back to you.
|
|
62
|
-
|
|
63
|
-
Preferred pattern when you are inside harnex:
|
|
64
|
-
- Use your own `HARNEX_ID` as the return address
|
|
65
|
-
- Tell the peer to send its final result back with `harnex send --id <YOUR_ID>`
|
|
66
|
-
- Wait for the peer's reply; do not rely on scraping logs or tmux panes as the
|
|
67
|
-
primary way to collect the answer
|
|
68
|
-
|
|
69
|
-
Fallback when you are not inside harnex:
|
|
70
|
-
- Define another explicit return channel before delegating, such as a known file
|
|
71
|
-
path in the repo
|
|
72
|
-
|
|
73
|
-
Do not launch a worker/reviewer without an explicit completion contract.
|
|
74
|
-
|
|
75
|
-
## Two rules for every send
|
|
76
|
-
|
|
77
|
-
**1. Keep messages short — use file references for long prompts.**
|
|
78
|
-
Long inline prompts can stall delivery (PTY buffer limits) and break shell
|
|
79
|
-
quoting. Instead, write the full task to a file and tell the peer to read it:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
# Write the task to a file
|
|
83
|
-
cat > /tmp/task-impl1.md <<'EOF'
|
|
84
|
-
Implement phase 2 from koder/plans/03_output_streaming.md.
|
|
85
|
-
... detailed instructions ...
|
|
86
|
-
EOF
|
|
87
|
-
|
|
88
|
-
# Send a short message pointing to it
|
|
89
|
-
harnex send --id impl-1 --message "Read and execute /tmp/task-impl1.md. When done, send results back: harnex send --id $HARNEX_ID --message '<summary>'"
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
If the task is already written down (a plan file, issue, koder doc), just
|
|
93
|
-
reference it directly — no need for a temp file.
|
|
94
|
-
|
|
95
|
-
**2. Always tell the peer how to reply.**
|
|
96
|
-
Every delegated task must include a return path. Without it, the peer finishes
|
|
97
|
-
silently and you have no way to collect the result:
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
# Always end with the reply instruction
|
|
101
|
-
harnex send --id impl-1 --message "Review src/auth.rb. When done: harnex send --id $HARNEX_ID --message '<your findings>'"
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Core commands
|
|
105
|
-
|
|
106
|
-
### Send a message to a peer agent
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
harnex send --id <ID> --message "<text>"
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
- `--id` targets a specific session by its unique ID
|
|
113
|
-
- `--message` is the prompt text injected into the peer's terminal
|
|
114
|
-
- Message is auto-submitted (peer receives it as a prompt)
|
|
115
|
-
- `--no-submit` types without pressing Enter
|
|
116
|
-
- `--force` sends even if peer UI is not at a prompt (bypasses queue)
|
|
117
|
-
- `--submit-only` sends only Enter (submit what's already in the input box)
|
|
118
|
-
- `--wait-for-idle` blocks until the agent finishes processing (prompt→busy→prompt)
|
|
119
|
-
- `--no-wait` returns immediately with a message_id (don't wait for delivery)
|
|
120
|
-
- `--cli` filters by CLI type when multiple sessions share resolution scope
|
|
121
|
-
|
|
122
|
-
When the target agent is busy, the message is **queued** (HTTP 202) and
|
|
123
|
-
delivered automatically when the agent returns to a prompt. The sender polls
|
|
124
|
-
until delivery completes using one overall `--timeout` budget (default 120s).
|
|
125
|
-
|
|
126
|
-
### Atomic send+wait (recommended for orchestration)
|
|
127
|
-
|
|
128
|
-
Use `--wait-for-idle` instead of separate `send` + `sleep` + `wait` commands:
|
|
13
|
+
If you are installing skills, use:
|
|
129
14
|
|
|
130
15
|
```bash
|
|
131
|
-
|
|
132
|
-
harnex send --id cx-1 --message "implement the plan"
|
|
133
|
-
sleep 5
|
|
134
|
-
harnex wait --id cx-1 --until prompt --timeout 600
|
|
135
|
-
|
|
136
|
-
# Use:
|
|
137
|
-
harnex send --id cx-1 --message "implement the plan" --wait-for-idle --timeout 600
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
This eliminates the race condition where `wait --until prompt` sees the stale
|
|
141
|
-
prompt state before the agent starts working. The `--timeout` budget covers
|
|
142
|
-
the entire lifecycle (lookup + send + idle wait).
|
|
143
|
-
|
|
144
|
-
**Multi-line messages** (when a file reference isn't practical): use a heredoc:
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
harnex send --id worker-1 --message "$(cat <<'EOF'
|
|
148
|
-
Line one of the message.
|
|
149
|
-
Line two of the message.
|
|
150
|
-
EOF
|
|
151
|
-
)"
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### Check session status
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
harnex status # sessions for current repo
|
|
158
|
-
harnex status --all # sessions across all repos
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Shows live sessions with their ID, CLI, port, PID, age, and input state.
|
|
162
|
-
|
|
163
|
-
### Inspect a specific session
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
harnex status --id <ID> --json
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
Returns JSON with input state, agent state, inbox stats, description,
|
|
170
|
-
watch config, and timestamps.
|
|
171
|
-
|
|
172
|
-
### Only when explicitly requested: spawn a detached worker session
|
|
173
|
-
|
|
174
|
-
```bash
|
|
175
|
-
# Headless (no terminal)
|
|
176
|
-
harnex run codex --id impl-1 --detach -- --cd /path/to/worktree
|
|
177
|
-
|
|
178
|
-
# In a tmux window (observable)
|
|
179
|
-
harnex run codex --id impl-1 --tmux cx-p1 -- --cd /path/to/worktree
|
|
16
|
+
harnex skills install harnex-dispatch
|
|
180
17
|
```
|
|
181
18
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- `--tmux NAME` sets a custom window title (keep names terse: `cx-p3`, `cl-r3`)
|
|
185
|
-
- `--context TEXT` sets an initial prompt with session ID auto-included
|
|
186
|
-
- `--description TEXT` stores a short session description in the registry/API
|
|
187
|
-
- Returns immediately; use `harnex send` to inject work, `harnex wait` to block
|
|
188
|
-
|
|
189
|
-
Do this only if the user explicitly asks for detached/background execution.
|
|
190
|
-
|
|
191
|
-
#### Using `--context` to orient spawned agents
|
|
192
|
-
|
|
193
|
-
`--context` prepends a context string as the agent's initial prompt, with the
|
|
194
|
-
session ID automatically included as `[harnex session id=<ID>]`. The spawner
|
|
195
|
-
decides what context to provide — harnex only adds the session ID.
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
# Fire-and-forget: give the task upfront
|
|
199
|
-
harnex run codex --id impl-1 --tmux cx-p1 \
|
|
200
|
-
--context "Implement the feature in koder/plans/03_auth.md. Commit when done." \
|
|
201
|
-
-- --cd /path/to/worktree
|
|
202
|
-
|
|
203
|
-
# Fire-and-wait: give context, then send work separately
|
|
204
|
-
harnex run codex --id reviewer --tmux cx-rv \
|
|
205
|
-
--context "You are a code reviewer. Wait for instructions via harnex relay messages." \
|
|
206
|
-
-- --cd /path/to/repo
|
|
207
|
-
harnex send --id reviewer --message "Review the changes in src/auth.rb"
|
|
208
|
-
harnex wait --id reviewer
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
The context string is the spawner's responsibility — tailor it to the use case.
|
|
212
|
-
|
|
213
|
-
### Wait for a session to exit
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
harnex wait --id impl-1
|
|
217
|
-
harnex wait --id impl-1 --timeout 300
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
Blocks until the session process exits. Returns JSON with exit code and timing.
|
|
221
|
-
Exit code 124 on timeout.
|
|
222
|
-
|
|
223
|
-
## Relay headers
|
|
224
|
-
|
|
225
|
-
When you send from inside a harnex session to a **different** session, harnex
|
|
226
|
-
automatically prepends a relay header:
|
|
227
|
-
|
|
228
|
-
```
|
|
229
|
-
[harnex relay from=claude id=supervisor at=2026-03-14T12:00:00+04:00]
|
|
230
|
-
<your message>
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
The peer sees this header and knows the message came from another agent. When
|
|
234
|
-
you **receive** a message with a `[harnex relay ...]` header, treat it as a
|
|
235
|
-
prompt from the peer agent — read the body and respond to it.
|
|
236
|
-
|
|
237
|
-
Control relay behavior:
|
|
238
|
-
- `--relay` forces the header even outside a session
|
|
239
|
-
- `--no-relay` suppresses the header
|
|
240
|
-
|
|
241
|
-
## Collaboration patterns
|
|
242
|
-
|
|
243
|
-
### Reply to a peer
|
|
244
|
-
|
|
245
|
-
When the user (or a relay message) asks you to reply to the other agent:
|
|
246
|
-
|
|
247
|
-
```bash
|
|
248
|
-
harnex send --id <TARGET_ID> --message "Your response here"
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### Delegate work and get the answer back
|
|
252
|
-
|
|
253
|
-
When you ask a peer agent to do work, include the return path in the task
|
|
254
|
-
itself.
|
|
255
|
-
|
|
256
|
-
Preferred when you are inside harnex:
|
|
257
|
-
|
|
258
|
-
```bash
|
|
259
|
-
harnex send --id reviewer --message "$(cat <<EOF
|
|
260
|
-
Review the current working tree.
|
|
261
|
-
|
|
262
|
-
Return your final findings to me with:
|
|
263
|
-
harnex send --id $HARNEX_ID --message '<findings>'
|
|
264
|
-
|
|
265
|
-
Use findings-first format with file paths and line numbers where possible.
|
|
266
|
-
EOF
|
|
267
|
-
)"
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
Then wait for the peer to answer you. Do not assume you can reconstruct the
|
|
271
|
-
result later from detached logs or tmux capture.
|
|
272
|
-
|
|
273
|
-
### Supervisor pattern
|
|
274
|
-
|
|
275
|
-
Use this only when the user explicitly wants detached/background workers.
|
|
276
|
-
|
|
277
|
-
A supervisor session spawns workers, sends them tasks, and waits for completion:
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
# Spawn workers
|
|
281
|
-
harnex run codex --id impl-1 --tmux cx-p1 -- --cd ~/repo/wt-feature-a
|
|
282
|
-
harnex run codex --id impl-2 --tmux cx-p2 -- --cd ~/repo/wt-feature-b
|
|
283
|
-
|
|
284
|
-
# Send work and wait for completion (atomic)
|
|
285
|
-
harnex send --id impl-1 --message "implement plan 150" --wait-for-idle --timeout 600
|
|
286
|
-
harnex send --id impl-2 --message "implement plan 151" --wait-for-idle --timeout 600
|
|
287
|
-
|
|
288
|
-
# Review phase
|
|
289
|
-
harnex run claude --id review-1 --tmux cl-r1
|
|
290
|
-
harnex send --id review-1 --message "review changes in wt-feature-a"
|
|
291
|
-
harnex wait --id review-1
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### File watch hook
|
|
295
|
-
|
|
296
|
-
Sessions can watch a shared file (e.g. `--watch ./tmp/tick.jsonl`). When the
|
|
297
|
-
file changes, harnex injects a `file-change-hook: read <path>` message. If you
|
|
298
|
-
receive this hook, read the file and act on its contents.
|
|
299
|
-
|
|
300
|
-
## Buddy pattern — accountability for long-running work
|
|
301
|
-
|
|
302
|
-
For any work that will take a long time (overnight pipelines, multi-hour
|
|
303
|
-
implementations, unattended batch jobs), spawn a **buddy** — a second harnex
|
|
304
|
-
session that watches the worker and nudges it if it stalls.
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
# Spawn the worker
|
|
308
|
-
harnex run codex --id worker-42 --tmux worker-42
|
|
309
|
-
harnex send --id worker-42 --message "Read and execute /tmp/task-42.md"
|
|
310
|
-
|
|
311
|
-
# Spawn a buddy to watch it
|
|
312
|
-
harnex run claude --id buddy-42 --tmux buddy-42
|
|
313
|
-
harnex send --id buddy-42 --message "Read and execute /tmp/buddy-42.md"
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
The buddy's prompt tells it: poll `harnex pane` and `harnex status` every N
|
|
317
|
-
minutes, nudge with `harnex send` if the worker stalls, report back to
|
|
318
|
-
`$HARNEX_SPAWNER_PANE` when done.
|
|
319
|
-
|
|
320
|
-
See `recipes/03_buddy.md` for the full pattern.
|
|
321
|
-
|
|
322
|
-
**When to spawn a buddy:**
|
|
323
|
-
- The user says "do this overnight" or "run this while I'm away"
|
|
324
|
-
- The task is expected to take more than 30 minutes unattended
|
|
325
|
-
- The user explicitly asks for a buddy or accountability partner
|
|
326
|
-
|
|
327
|
-
**When NOT to spawn a buddy:**
|
|
328
|
-
- Short tasks you're actively watching
|
|
329
|
-
- The user hasn't asked for long-running autonomy
|
|
330
|
-
|
|
331
|
-
## Important rules
|
|
332
|
-
|
|
333
|
-
1. **Always confirm with the user before sending** unless they explicitly asked
|
|
334
|
-
you to send a specific message. Sending injects a prompt into the peer's
|
|
335
|
-
terminal — it's an action visible to others.
|
|
336
|
-
2. **Never auto-loop** relay conversations. One send per user request unless
|
|
337
|
-
told otherwise.
|
|
338
|
-
3. **Check status first** if unsure whether a peer is running: `harnex status`
|
|
339
|
-
4. **Use `--force` sparingly** — it bypasses the inbox queue and adapter
|
|
340
|
-
readiness checks. Can corrupt peer input if it's mid-response.
|
|
341
|
-
5. **Relay headers are automatic** when sending from inside a session. Don't
|
|
342
|
-
manually prepend them.
|
|
343
|
-
6. When composing a message to send, be concise and actionable — the peer agent
|
|
344
|
-
receives it as a prompt and will act on it.
|
|
345
|
-
7. Do not spawn detached or tmux-backed sessions unless the user explicitly
|
|
346
|
-
asked for detached/background execution.
|
|
347
|
-
8. Before delegating work, define the result return path. Prefer a reply back to
|
|
348
|
-
your own `HARNEX_ID` over logs, pane capture, or other indirect collection.
|
|
19
|
+
Compatibility note: `harnex skills install harnex` remains supported and
|
|
20
|
+
installs `harnex-dispatch`.
|
|
@@ -11,6 +11,9 @@ agent that watches the worker and nudges it if it stalls.
|
|
|
11
11
|
The buddy is an LLM, so it has intelligence for free. It reads the worker's
|
|
12
12
|
screen, reasons about whether it's stuck, and composes a meaningful nudge.
|
|
13
13
|
|
|
14
|
+
Dispatch workers via `harnex-dispatch` first. This skill owns only buddy
|
|
15
|
+
behavior after the worker is already running.
|
|
16
|
+
|
|
14
17
|
## When to activate
|
|
15
18
|
|
|
16
19
|
- User says "do this overnight" or "run this while I'm away"
|
|
@@ -20,12 +23,11 @@ screen, reasons about whether it's stuck, and composes a meaningful nudge.
|
|
|
20
23
|
|
|
21
24
|
## Spawn the buddy
|
|
22
25
|
|
|
23
|
-
After dispatching the worker
|
|
26
|
+
After dispatching the worker with `harnex-dispatch`, spawn a buddy alongside
|
|
27
|
+
it. Keep ID/tmux naming consistent with `harnex-dispatch` (`--tmux` matches
|
|
28
|
+
`--id`):
|
|
24
29
|
|
|
25
30
|
```bash
|
|
26
|
-
# Worker already running
|
|
27
|
-
harnex run codex --id worker-42 --tmux worker-42
|
|
28
|
-
|
|
29
31
|
# Spawn its buddy
|
|
30
32
|
harnex run claude --id buddy-42 --tmux buddy-42
|
|
31
33
|
```
|
|
@@ -36,17 +38,17 @@ Write a task file with the watching instructions, then send it:
|
|
|
36
38
|
|
|
37
39
|
```bash
|
|
38
40
|
cat > /tmp/buddy-42.md <<'EOF'
|
|
39
|
-
You are an accountability partner for harnex session `
|
|
41
|
+
You are an accountability partner for harnex session `cx-impl-42`.
|
|
40
42
|
|
|
41
43
|
Your job:
|
|
42
44
|
1. Every 5 minutes, check on the worker:
|
|
43
|
-
- `harnex pane --id
|
|
44
|
-
- `harnex status --id
|
|
45
|
+
- `harnex pane --id cx-impl-42 --lines 20`
|
|
46
|
+
- `harnex status --id cx-impl-42 --json`
|
|
45
47
|
2. If the worker appears stuck at a prompt for more than 10 minutes
|
|
46
48
|
with no progress, nudge it:
|
|
47
|
-
- `harnex send --id
|
|
49
|
+
- `harnex send --id cx-impl-42 --message "You appear to have stalled. Continue with your current task."`
|
|
48
50
|
3. If the worker has exited, report back to the invoker:
|
|
49
|
-
- `tmux send-keys -t "$HARNEX_SPAWNER_PANE" "
|
|
51
|
+
- `tmux send-keys -t "$HARNEX_SPAWNER_PANE" "cx-impl-42 has exited. Check results." Enter`
|
|
50
52
|
4. Keep watching until the worker finishes or is stopped.
|
|
51
53
|
|
|
52
54
|
Do not interfere with work in progress. Only nudge when clearly stalled.
|
|
@@ -76,12 +78,8 @@ The invoker does NOT need to be a harnex session. It just needs to be in tmux.
|
|
|
76
78
|
|
|
77
79
|
## Naming convention
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
| Worker | `worker-NN` | `worker-42` |
|
|
82
|
-
| Buddy | `buddy-NN` | `buddy-42` |
|
|
83
|
-
|
|
84
|
-
Match the buddy ID to the worker it watches.
|
|
81
|
+
Use naming from `harnex-dispatch`: set `--tmux <same-as-id>` for every
|
|
82
|
+
session and keep the buddy ID paired with the worker step ID.
|
|
85
83
|
|
|
86
84
|
## Cleanup
|
|
87
85
|
|
|
@@ -93,6 +91,8 @@ harnex stop --id buddy-42
|
|
|
93
91
|
|
|
94
92
|
## Notes
|
|
95
93
|
|
|
94
|
+
- For chain orchestration, phase gates, and the 5-concurrent parallel planning
|
|
95
|
+
cap, see `harnex-chain`.
|
|
96
96
|
- One buddy per worker, or one buddy watching multiple sessions
|
|
97
97
|
- The buddy is a regular harnex session — stop, inspect, log it like any other
|
|
98
98
|
- Tune polling and thresholds in the buddy's prompt, not in harnex config
|
|
@@ -1,234 +1,132 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: harnex-chain
|
|
3
|
-
description: End-to-end workflow from issue to shipped plans via harnex agents. Covers mapping, plan extraction, and the serial plan
|
|
3
|
+
description: End-to-end workflow from issue to shipped plans via harnex agents. Covers mapping, plan extraction, and the serial plan -> review -> implement -> review -> fix loop.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Chain Implement
|
|
7
7
|
|
|
8
|
-
Take an issue from design through to shipped code via harnex agents.
|
|
9
|
-
|
|
8
|
+
Take an issue from design through to shipped code via harnex agents. This
|
|
9
|
+
skill defines chain semantics (phase order, quality gates, escalation), while
|
|
10
|
+
spawn/watch/stop mechanics come from `harnex-dispatch`.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
For naming (`--tmux <same-as-id>`) and worktree operational rules, use
|
|
13
|
+
`harnex-dispatch`.
|
|
14
|
+
|
|
15
|
+
## Orchestrator Role
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
- Claude is the orchestrator only: dispatches sessions, watches progress,
|
|
18
|
+
decides stop/resume/escalate, and enforces phase gates.
|
|
19
|
+
- Codex performs all production work: plan writing, plan reviews,
|
|
20
|
+
implementation, code reviews, and fixes.
|
|
21
|
+
- The orchestrator does not implement or review directly except emergency
|
|
22
|
+
intervention to recover a blocked chain.
|
|
23
|
+
|
|
24
|
+
## Guiding Principle
|
|
16
25
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Large issue, many files/seams/sequencing → mapping plan + extracted plans
|
|
26
|
+
Keep each agent invocation inside its safe context zone (< 40% of context
|
|
27
|
+
window). Large issues should be split into smaller plans so each worker has a
|
|
28
|
+
narrow, testable scope.
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
Scale to the issue size:
|
|
31
|
+
- Small issue: skip mapping, one plan, one serial loop.
|
|
32
|
+
- Medium issue: one phased plan is usually enough.
|
|
33
|
+
- Large issue: mapping plus extracted thin-layer plans.
|
|
23
34
|
|
|
24
|
-
## Workflow Overview
|
|
35
|
+
## Workflow Overview (Serial Default)
|
|
25
36
|
|
|
26
37
|
```
|
|
27
|
-
Issue (user +
|
|
38
|
+
Issue (user + orchestrator chat)
|
|
28
39
|
↓
|
|
29
|
-
[Mapping Plan]
|
|
40
|
+
[Mapping Plan] -> [Map Review] -> [Fix Map] <- optional for large scope
|
|
30
41
|
↓
|
|
31
|
-
[Plan Extraction]
|
|
42
|
+
[Plan Extraction] -> thin-layer plans <- optional if one plan suffices
|
|
32
43
|
↓
|
|
33
|
-
Per plan (serial):
|
|
34
|
-
Plan
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
Per plan (serial on main):
|
|
45
|
+
Plan -> Plan Review -> Fix Plan
|
|
46
|
+
-> Implement -> Code Review -> Fix Code
|
|
47
|
+
-> Commit -> next plan
|
|
37
48
|
```
|
|
38
49
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
The plan review catches design problems before code is written. The code review
|
|
42
|
-
catches implementation problems after. Skipping plan review leads to wasted
|
|
43
|
-
implementation cycles when the plan itself is flawed. This was validated in
|
|
44
|
-
production — adversarial plan/review cycles consistently produce better outcomes
|
|
45
|
-
than jumping straight to implementation.
|
|
50
|
+
The serial loop is the default path. For each step, use `harnex-dispatch`
|
|
51
|
+
Fire & Watch for lifecycle operations and stop-after-commit timing.
|
|
46
52
|
|
|
47
53
|
## Phase 1: Issue
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
The issue captures:
|
|
53
|
-
- The problem and motivation
|
|
55
|
+
User and orchestrator converge on a concrete issue document
|
|
56
|
+
(e.g., `koder/issues/NN_label/INDEX.md`) with:
|
|
57
|
+
- Problem and motivation
|
|
54
58
|
- Design decisions and trade-offs
|
|
55
59
|
- Acceptance criteria
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
This phase is interactive — the user is present and driving.
|
|
59
|
-
|
|
60
|
-
## Phase 2: Mapping Plan (optional — for large issues)
|
|
60
|
+
- Open questions
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
the scope crosses many files, involves sequencing constraints, or has open
|
|
64
|
-
design questions that would block an away user.
|
|
62
|
+
## Phase 2: Mapping Plan (Optional)
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
- Sequencing constraints (what depends on what)
|
|
69
|
-
- Questions that need user input before implementation
|
|
64
|
+
Use when scope is broad, has sequencing constraints, or still contains
|
|
65
|
+
user-blocking questions. Skip for small, coherent issues.
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
- **Creates shared context** — the mapping plan becomes the reference for all
|
|
76
|
-
subsequent plans
|
|
77
|
-
- **Separates research from decomposition** — mapping agent focuses on
|
|
78
|
-
understanding, extraction focuses on scoping
|
|
79
|
-
|
|
80
|
-
### Dispatch
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
harnex run codex --id cx-map-NN --tmux cx-map-NN \
|
|
84
|
-
--context "Write a mapping plan for koder/issues/NN_label/INDEX.md. \
|
|
85
|
-
Produce a detailed technical map: files, seams, sequencing, open questions. \
|
|
86
|
-
Write to koder/plans/NN_mapping.md."
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Poll every 30s with `harnex pane --id cx-map-NN --lines 20`.
|
|
90
|
-
|
|
91
|
-
### Map Review
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
harnex run claude --id cl-rev-map-NN --tmux cl-rev-map-NN \
|
|
95
|
-
--context "Review koder/plans/NN_mapping.md. Check: unresolved user questions? \
|
|
96
|
-
Accurate file/function analysis? Sequencing constraints identified? \
|
|
97
|
-
Write review to koder/reviews/NN_mapping.md"
|
|
98
|
-
```
|
|
67
|
+
Outputs:
|
|
68
|
+
- Technical map of files/functions/seams
|
|
69
|
+
- Sequencing constraints
|
|
70
|
+
- Explicit user-blocking questions
|
|
99
71
|
|
|
100
|
-
|
|
72
|
+
Gate:
|
|
73
|
+
- If map review finds user-blocking questions, stop the chain and return to
|
|
74
|
+
user.
|
|
101
75
|
|
|
102
|
-
## Phase 3: Plan Extraction (
|
|
76
|
+
## Phase 3: Plan Extraction (Optional)
|
|
103
77
|
|
|
104
|
-
|
|
105
|
-
|
|
78
|
+
Use when the mapping plan should be decomposed into thin-layer plans.
|
|
79
|
+
Each extracted plan must be one independently testable capability and ordered
|
|
80
|
+
by dependency.
|
|
106
81
|
|
|
107
|
-
|
|
108
|
-
- **One capability** — testable independently
|
|
109
|
-
- **Self-contained** — the implementing agent reads only that plan file
|
|
110
|
-
- **Ordered** — respects sequencing constraints from the mapping plan
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
harnex run codex --id cx-extract-NN --tmux cx-extract-NN \
|
|
114
|
-
--context "Read koder/plans/NN_mapping.md. Extract thin-layer plans. \
|
|
115
|
-
Each plan is one independently testable capability. Write to koder/plans/."
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Phase 4: Serial Plan Loop
|
|
119
|
-
|
|
120
|
-
Each plan goes through the full cycle. This is the walk-away part.
|
|
121
|
-
|
|
122
|
-
### Per-plan cycle
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
1. Plan (codex) — write/refine the plan if not already extracted
|
|
126
|
-
2. Plan Review (claude) — check plan against codebase, flag issues
|
|
127
|
-
3. Fix Plan (codex) — address review findings
|
|
128
|
-
4. Implement (codex) — write code, run tests, commit per phase
|
|
129
|
-
5. Code Review (claude) — review implementation against plan
|
|
130
|
-
6. Fix Code (codex) — address review findings if needed
|
|
131
|
-
7. Commit — final state on master
|
|
132
|
-
8. → next plan
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Steps 1-3 can be skipped if the plan was already extracted and reviewed during
|
|
136
|
-
the mapping phase, or if the issue is simple enough that the plan is obviously
|
|
137
|
-
correct.
|
|
138
|
-
|
|
139
|
-
### Dispatch pattern
|
|
140
|
-
|
|
141
|
-
For each plan NN, use the Fire & Watch pattern from the `harnex-dispatch` skill:
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
# Steps 1-3: Plan convergence (skip if plan already extracted and reviewed)
|
|
145
|
-
harnex run codex --id cx-plan-NN --tmux cx-plan-NN \
|
|
146
|
-
--context "Refine koder/plans/NN_label.md based on current codebase state."
|
|
147
|
-
# Poll every 30s: harnex pane --id cx-plan-NN --lines 20
|
|
148
|
-
# When done: harnex stop --id cx-plan-NN
|
|
149
|
-
|
|
150
|
-
harnex run claude --id cl-rev-plan-NN --tmux cl-rev-plan-NN \
|
|
151
|
-
--context "Review koder/plans/NN_label.md. Check: accurate file/function refs? \
|
|
152
|
-
Sequencing correct? Acceptance criteria testable? \
|
|
153
|
-
Write review to koder/reviews/NN_label.md"
|
|
154
|
-
# Poll → stop → if NEEDS FIXES, dispatch cx-fix-plan-NN
|
|
155
|
-
|
|
156
|
-
# Step 4: Implement
|
|
157
|
-
harnex run codex --id cx-impl-NN --tmux cx-impl-NN \
|
|
158
|
-
--context "Implement koder/plans/NN_label.md. Run tests when done. Commit after each phase."
|
|
159
|
-
# Poll every 30s: harnex pane --id cx-impl-NN --lines 20
|
|
160
|
-
# When done: harnex stop --id cx-impl-NN
|
|
161
|
-
|
|
162
|
-
# Steps 5-6: Code review + fix
|
|
163
|
-
harnex run claude --id cl-rev-NN --tmux cl-rev-NN \
|
|
164
|
-
--context "Review implementation of plan NN against koder/plans/NN_label.md. \
|
|
165
|
-
Write review to koder/reviews/NN_label.md"
|
|
166
|
-
# Poll every 30s: harnex pane --id cl-rev-NN --lines 20
|
|
167
|
-
# When done: harnex stop --id cl-rev-NN
|
|
168
|
-
# If NEEDS FIXES → dispatch cx-fix-NN
|
|
169
|
-
# If PASS → next plan
|
|
170
|
-
|
|
171
|
-
# Fix (if needed)
|
|
172
|
-
harnex run codex --id cx-fix-NN --tmux cx-fix-NN \
|
|
173
|
-
--context "Fix findings in koder/reviews/NN_label.md for plan NN. Run tests. Commit."
|
|
174
|
-
# Poll, stop, re-review if needed
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Poll cadence
|
|
178
|
-
|
|
179
|
-
Checking is cheap — 20 lines is a few hundred bytes:
|
|
180
|
-
|
|
181
|
-
| Elapsed | Interval | Rationale |
|
|
182
|
-
|---------|----------|-----------|
|
|
183
|
-
| 0–2 min | 30s | Catch fast completions and early errors |
|
|
184
|
-
| 2–10 min | 60s | Steady state for typical work |
|
|
185
|
-
| 10+ min | 120s | Long-running, reduce noise |
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
harnex pane --id cx-impl-NN --lines 20
|
|
189
|
-
```
|
|
82
|
+
## Phase 4: Serial Plan Loop (Default)
|
|
190
83
|
|
|
191
|
-
|
|
84
|
+
Per plan:
|
|
85
|
+
1. Plan (Codex)
|
|
86
|
+
2. Plan Review (Codex)
|
|
87
|
+
3. Fix Plan (Codex) when review finds issues
|
|
88
|
+
4. Implement (Codex)
|
|
89
|
+
5. Code Review (Codex)
|
|
90
|
+
6. Fix Code (Codex) when review finds issues
|
|
91
|
+
7. Commit and advance to next plan
|
|
192
92
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
| Plan extraction | `cx-extract-NN` | `cx-extract-42` |
|
|
198
|
-
| Plan write/refine | `cx-plan-NN` | `cx-plan-184` |
|
|
199
|
-
| Plan review | `cl-rev-plan-NN` | `cl-rev-plan-184` |
|
|
200
|
-
| Plan fix | `cx-fix-plan-NN` | `cx-fix-plan-184` |
|
|
201
|
-
| Implement | `cx-impl-NN` | `cx-impl-184` |
|
|
202
|
-
| Code review | `cl-rev-NN` | `cl-rev-184` |
|
|
203
|
-
| Code fix | `cx-fix-NN` | `cx-fix-184` |
|
|
93
|
+
Gating rules:
|
|
94
|
+
- Do not start implementation with unresolved P1 plan-review findings.
|
|
95
|
+
- Do not advance to the next plan with unresolved P1 code-review findings.
|
|
96
|
+
- Keep plan-fix and code-fix loops active until the review gate passes.
|
|
204
97
|
|
|
205
|
-
|
|
206
|
-
context avoids bleed.
|
|
98
|
+
## Parallel Variant
|
|
207
99
|
|
|
208
|
-
|
|
100
|
+
Parallelism is allowed only for planning passes. Keep implementation serial
|
|
101
|
+
on `main` unless the user explicitly requests worktrees.
|
|
209
102
|
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
103
|
+
Approved parallel lanes:
|
|
104
|
+
- Parallel plan-writing sessions (one plan file per Codex session)
|
|
105
|
+
- Parallel plan-review sessions (one review file per Codex session)
|
|
213
106
|
|
|
214
|
-
|
|
107
|
+
Capacity rule:
|
|
108
|
+
- Run at most 5 concurrent Codex sessions total across all active lanes
|
|
109
|
+
(global cap, not per lane).
|
|
215
110
|
|
|
216
|
-
|
|
111
|
+
Lifecycle rule:
|
|
112
|
+
- Use `harnex-dispatch` Fire & Watch, including poll cadence and stop timing.
|
|
217
113
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
114
|
+
Implementation rule:
|
|
115
|
+
- Serial implementation on `main` is the default.
|
|
116
|
+
- Parallel implementation is allowed only with explicit user request and
|
|
117
|
+
worktree isolation (see `harnex-dispatch` worktree guidance).
|
|
221
118
|
|
|
222
|
-
|
|
223
|
-
Re-review the plan. Do not proceed to implementation with unresolved P1s.
|
|
119
|
+
## Unattended Monitoring
|
|
224
120
|
|
|
225
|
-
|
|
226
|
-
|
|
121
|
+
For overnight, unattended, or >30-minute steps, use `harnex-buddy`.
|
|
122
|
+
Buddy activation criteria, monitoring loop (poll/stall/nudge), return channel
|
|
123
|
+
via `$HARNEX_SPAWNER_PANE`, and buddy cleanup are canonical in
|
|
124
|
+
`harnex-buddy`.
|
|
227
125
|
|
|
228
|
-
|
|
229
|
-
is wrong. If the divergence is minor (P3), note it and continue. If major,
|
|
230
|
-
stop and re-plan.
|
|
126
|
+
## Failure and Escalation
|
|
231
127
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
128
|
+
- User-blocking question in plan/map review: stop and ask user; do not guess.
|
|
129
|
+
- Review returns P1: dispatch the corresponding fix step and re-review.
|
|
130
|
+
- Implementation diverges materially from plan: stop and re-plan.
|
|
131
|
+
- Worker is stuck or blocked by prompt/dialog: intervene, then continue with a
|
|
132
|
+
fresh worker if needed.
|
|
@@ -1,11 +1,96 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: harnex-dispatch
|
|
3
3
|
description: Fire & Watch — the standard pattern for launching and monitoring harnex agent sessions. Use when dispatching implementation, review, or fix agents.
|
|
4
|
+
allowed-tools: Bash(harnex *)
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Dispatch — Fire & Watch
|
|
7
8
|
|
|
8
9
|
Every harnex agent dispatch follows three phases: **spawn**, **watch**, **stop**.
|
|
10
|
+
Before spawn, always decide the return channel and message contract.
|
|
11
|
+
|
|
12
|
+
`harnex-dispatch` is the canonical home for lifecycle mechanics only.
|
|
13
|
+
For orchestrator role boundaries, phase gates, and chain-level parallel policy,
|
|
14
|
+
see `harnex-chain`.
|
|
15
|
+
|
|
16
|
+
## Detect your context
|
|
17
|
+
|
|
18
|
+
Check env vars first to know whether you are inside a harnex-managed session:
|
|
19
|
+
|
|
20
|
+
| Variable | Meaning |
|
|
21
|
+
|----------|---------|
|
|
22
|
+
| `HARNEX_SESSION_CLI` | Which CLI this session is (`claude` or `codex`) |
|
|
23
|
+
| `HARNEX_ID` | Your session ID |
|
|
24
|
+
| `HARNEX_SESSION_REPO_ROOT` | Repo root the session is scoped to |
|
|
25
|
+
| `HARNEX_SESSION_ID` | Internal harnex instance ID |
|
|
26
|
+
| `HARNEX_SPAWNER_PANE` | tmux pane ID (`%N`) of the invoker |
|
|
27
|
+
|
|
28
|
+
If these are present, you can coordinate peers directly with `harnex send`,
|
|
29
|
+
`harnex status`, and `harnex wait`. `HARNEX_SPAWNER_PANE` is the fallback
|
|
30
|
+
return channel to the invoker via `tmux send-keys`.
|
|
31
|
+
|
|
32
|
+
## Return Channel First
|
|
33
|
+
|
|
34
|
+
Define how results come back before delegating work.
|
|
35
|
+
|
|
36
|
+
- Inside harnex: require peers to send final results back to your own
|
|
37
|
+
`HARNEX_ID` via `harnex send --id "$HARNEX_ID" ...`
|
|
38
|
+
- Outside harnex: require a concrete return path (for example a specific file
|
|
39
|
+
in the repo or an explicit tmux pane message)
|
|
40
|
+
|
|
41
|
+
Do not delegate work without an explicit completion contract.
|
|
42
|
+
|
|
43
|
+
## Send Hygiene
|
|
44
|
+
|
|
45
|
+
### Keep prompts short; reference files for long instructions
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cat > /tmp/task-impl-NN.md <<'EOF'
|
|
49
|
+
Detailed instructions here...
|
|
50
|
+
EOF
|
|
51
|
+
|
|
52
|
+
harnex send --id cx-impl-NN --message "Read /tmp/task-impl-NN.md. Reply with final status to harnex id $HARNEX_ID."
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Long inline messages are brittle in PTYs. Use plan/issue files or temp files.
|
|
56
|
+
|
|
57
|
+
### Require explicit reply instruction in every delegated task
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
harnex send --id cl-rev-NN --message "Review koder/plans/NN_name.md. When done send findings to harnex id $HARNEX_ID."
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Relay Headers
|
|
64
|
+
|
|
65
|
+
Messages sent from one harnex session to another are auto-wrapped:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
[harnex relay from=<cli> id=<sender_id> at=<timestamp>]
|
|
69
|
+
<message body>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
When you receive a relay header, treat it as an actionable prompt from the
|
|
73
|
+
peer. Respond using `harnex send --id <sender_id> ...` unless instructed
|
|
74
|
+
otherwise.
|
|
75
|
+
|
|
76
|
+
## Practical Reply/Delegate Patterns
|
|
77
|
+
|
|
78
|
+
Reply to a peer:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
harnex send --id <TARGET_ID> --message "<result>"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Delegate and force a return path:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
harnex send --id cx-impl-NN --message "$(cat <<EOF
|
|
88
|
+
Implement koder/plans/NN_name.md.
|
|
89
|
+
Run tests before finishing.
|
|
90
|
+
When done, send one summary line back to harnex id $HARNEX_ID.
|
|
91
|
+
EOF
|
|
92
|
+
)"
|
|
93
|
+
```
|
|
9
94
|
|
|
10
95
|
## 1. Spawn
|
|
11
96
|
|
|
@@ -81,6 +166,8 @@ harnex pane --id cx-impl-NN --lines 20 --follow
|
|
|
81
166
|
|
|
82
167
|
When the agent is done (at prompt, work committed):
|
|
83
168
|
|
|
169
|
+
Stop each completed session as soon as its commit lands.
|
|
170
|
+
|
|
84
171
|
```bash
|
|
85
172
|
harnex stop --id cx-impl-NN
|
|
86
173
|
```
|
|
@@ -100,11 +187,16 @@ harnex stop --id cx-impl-NN
|
|
|
100
187
|
|
|
101
188
|
| Step | ID pattern | tmux window | Example |
|
|
102
189
|
|------|-----------|-------------|---------|
|
|
190
|
+
| Mapping | `cx-map-NN` | `cx-map-NN` | `cx-map-42` |
|
|
191
|
+
| Map review | `cx-rev-map-NN` | `cx-rev-map-NN` | `cx-rev-map-42` |
|
|
192
|
+
| Map fix | `cx-fix-map-NN` | `cx-fix-map-NN` | `cx-fix-map-42` |
|
|
103
193
|
| Implement | `cx-impl-NN` | `cx-impl-NN` | `cx-impl-42` |
|
|
104
194
|
| Review | `cl-rev-NN` | `cl-rev-NN` | `cl-rev-42` |
|
|
105
195
|
| Fix | `cx-fix-NN` | `cx-fix-NN` | `cx-fix-42` |
|
|
106
196
|
| Plan write | `cx-plan-NN` | `cx-plan-NN` | `cx-plan-42` |
|
|
197
|
+
| Plan review | `cx-rev-plan-NN` | `cx-rev-plan-NN` | `cx-rev-plan-42` |
|
|
107
198
|
| Plan fix | `cx-fix-plan-NN` | `cx-fix-plan-NN` | `cx-fix-plan-42` |
|
|
199
|
+
| Buddy | `buddy-NN` | `buddy-NN` | `buddy-42` |
|
|
108
200
|
|
|
109
201
|
**Rule**: Always use `--tmux <same-as-id>` so the tmux window name matches
|
|
110
202
|
the session ID. Never use a different tmux name.
|
|
@@ -139,7 +231,7 @@ git commit -m "docs(plan-NN): add plan"
|
|
|
139
231
|
|
|
140
232
|
# Create worktree
|
|
141
233
|
WORKTREE="$(pwd)/../$(basename $(pwd))-plan-NN"
|
|
142
|
-
git worktree add ${WORKTREE} -b plan/NN_name
|
|
234
|
+
git worktree add ${WORKTREE} -b plan/NN_name main
|
|
143
235
|
|
|
144
236
|
# Launch from worktree
|
|
145
237
|
cd ${WORKTREE}
|
|
@@ -164,19 +256,17 @@ harnex status --all # all repos
|
|
|
164
256
|
## Buddy for Long-Running Dispatches
|
|
165
257
|
|
|
166
258
|
If the dispatched work is expected to take a long time (overnight, multi-hour)
|
|
167
|
-
or the user asks for unattended execution, spawn a buddy alongside the worker
|
|
259
|
+
or the user asks for unattended execution, spawn a buddy alongside the worker.
|
|
260
|
+
Dispatch mechanics stay here; buddy monitoring mechanics live in
|
|
261
|
+
`harnex-buddy`.
|
|
168
262
|
|
|
169
263
|
```bash
|
|
170
|
-
# Worker
|
|
171
|
-
harnex run codex --id cx-impl-NN --tmux cx-impl-NN \
|
|
172
|
-
--context "Implement koder/plans/NN_name.md. Run tests when done."
|
|
173
|
-
|
|
174
|
-
# Buddy to watch it
|
|
175
264
|
harnex run claude --id buddy-NN --tmux buddy-NN
|
|
176
|
-
harnex send --id buddy-NN --message "Watch session cx-impl-NN.
|
|
265
|
+
harnex send --id buddy-NN --message "Watch session cx-impl-NN. Follow skills/harnex-buddy/SKILL.md and report completion to \$HARNEX_SPAWNER_PANE."
|
|
177
266
|
```
|
|
178
267
|
|
|
179
|
-
|
|
268
|
+
For activation conditions, poll/stall/nudge loop, return channel details, and
|
|
269
|
+
buddy cleanup, use `harnex-buddy`.
|
|
180
270
|
|
|
181
271
|
## What NOT to Do
|
|
182
272
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: harnex
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jikku Jose
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A local PTY harness that wraps terminal AI agents (Claude, Codex) and
|
|
14
14
|
adds a control plane for discovery, messaging, and coordination.
|