herdr-turn-coordinator 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -13
- package/herdr-plugin.toml +1 -1
- package/herdr_turn.py +11 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Run one interactive coding-agent turn in Herdr without spending parent-model tokens on status polling.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Works with every agent kind supported by your installed Herdr version, including Codex, Claude Code, Grok, Gemini CLI, Kimi, Cursor, OpenCode, and GitHub Copilot.
|
|
6
|
+
|
|
7
|
+
The plugin keeps the downstream agent's native TUI, splits a dedicated pane without taking focus, waits in a local supervisor process, reads the final output once, and leaves the pane open for human takeover.
|
|
6
8
|
|
|
7
9
|
## Why
|
|
8
10
|
|
|
9
11
|
`herdr agent prompt --wait` can report `agent_prompt_stalled` even when a prompt was delivered and the agent continues working. A parent model that recovers by repeatedly calling `agent get`, `agent read`, or `agent wait` pays for every observation as another model turn.
|
|
10
12
|
|
|
11
|
-
Turn Coordinator moves that
|
|
13
|
+
Turn Coordinator moves that wait into a local process. On a false stall it checks for a new prompt on screen or a recovered `working` state, then waits. If it only sees 15 seconds of quiet pane output, it returns `unknown` for human takeover instead of declaring the turn done. It never resends the same prompt.
|
|
12
14
|
|
|
13
15
|
## Requirements
|
|
14
16
|
|
|
@@ -17,6 +19,22 @@ Turn Coordinator moves that recovery loop into an ordinary local process. On a f
|
|
|
17
19
|
- macOS or Linux
|
|
18
20
|
- A Herdr-supported interactive agent CLI
|
|
19
21
|
|
|
22
|
+
## Supported AI CLIs
|
|
23
|
+
|
|
24
|
+
`--kind` is passed directly to Herdr. Use the Herdr kind ID, not the product name.
|
|
25
|
+
|
|
26
|
+
| Product | `--kind` | Product | `--kind` |
|
|
27
|
+
| --- | --- | --- | --- |
|
|
28
|
+
| Codex | `codex` | Claude Code | `claude` |
|
|
29
|
+
| Grok | `grok` | Gemini CLI | `gemini` |
|
|
30
|
+
| Kimi Code CLI | `kimi` | Cursor Agent CLI | `cursor` |
|
|
31
|
+
| OpenCode | `opencode` | GitHub Copilot CLI | `copilot` |
|
|
32
|
+
| Cline | `cline` | Kiro CLI | `kiro` |
|
|
33
|
+
| Qwen Code | `qwen` | Qoder CLI | `qodercli` |
|
|
34
|
+
| Amp | `amp` | Droid | `droid` |
|
|
35
|
+
|
|
36
|
+
Any other kind accepted by your installed Herdr version also works, including kinds added after this plugin release. Availability and agent detection quality follow Herdr itself. The only extra agent-specific guard is Kimi's first-run folder-trust prompt.
|
|
37
|
+
|
|
20
38
|
## Install
|
|
21
39
|
|
|
22
40
|
Recommended Herdr plugin installation:
|
|
@@ -28,26 +46,32 @@ herdr plugin log list --plugin karthuslorin.turn-coordinator --limit 1
|
|
|
28
46
|
herdr-turn doctor
|
|
29
47
|
```
|
|
30
48
|
|
|
31
|
-
Plugin actions are asynchronous. Confirm the install action log says `succeeded` before running `doctor
|
|
49
|
+
Plugin actions are asynchronous. Confirm the install action log says `succeeded` before running `doctor`. Plugin install puts `herdr-turn` in `~/.local/bin`, so ensure that directory is on `PATH`.
|
|
32
50
|
|
|
33
51
|
Alternatively, install the CLI from npm:
|
|
34
52
|
|
|
35
53
|
```sh
|
|
36
|
-
npm install --global herdr-turn-coordinator
|
|
54
|
+
npm install --global herdr-turn-coordinator
|
|
37
55
|
herdr-turn doctor
|
|
38
56
|
```
|
|
39
57
|
|
|
58
|
+
Choose one installation method. An npm global install uses the npm prefix bin instead of `~/.local/bin`.
|
|
59
|
+
|
|
40
60
|
## Usage
|
|
41
61
|
|
|
42
|
-
|
|
62
|
+
`herdr-turn run` and `herdr-turn prompt` must run from a pane inside Herdr (`HERDR_ENV=1`). `herdr-turn doctor` can run outside Herdr.
|
|
63
|
+
|
|
64
|
+
Start a new interactive agent in a dedicated pane:
|
|
43
65
|
|
|
44
66
|
```sh
|
|
45
67
|
herdr-turn run \
|
|
46
|
-
--kind
|
|
68
|
+
--kind codex \
|
|
47
69
|
--name reviewer \
|
|
48
70
|
--prompt "Review the current diff and report only actionable findings."
|
|
49
71
|
```
|
|
50
72
|
|
|
73
|
+
For Claude Code, Grok, Gemini, or Kimi, use `--kind claude`, `--kind grok`, `--kind gemini`, or `--kind kimi`.
|
|
74
|
+
|
|
51
75
|
Continue an existing settled agent:
|
|
52
76
|
|
|
53
77
|
```sh
|
|
@@ -56,7 +80,19 @@ herdr-turn prompt \
|
|
|
56
80
|
--prompt "Now summarize the top three risks."
|
|
57
81
|
```
|
|
58
82
|
|
|
59
|
-
Both commands print one JSON
|
|
83
|
+
Both commands block until the turn settles or the timeout expires, then print one JSON object. The default timeout is 300000 ms. The created pane stays open and the agent remains fully interactive.
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"ok": true,
|
|
88
|
+
"pane_id": "w1:p2",
|
|
89
|
+
"agent_name": "reviewer",
|
|
90
|
+
"agent_status": "idle",
|
|
91
|
+
"text": "..."
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
On `ok: false`, a non-zero exit, or a status other than `idle`/`done`, stop for human takeover instead of polling Herdr from model turns.
|
|
60
96
|
|
|
61
97
|
## Suggested agent instruction
|
|
62
98
|
|
|
@@ -68,8 +104,9 @@ then consume its single final JSON result. Do not poll Herdr from model turns.
|
|
|
68
104
|
|
|
69
105
|
## Behavior
|
|
70
106
|
|
|
71
|
-
- Preserves
|
|
107
|
+
- Preserves each agent's native interactive TUI by using `herdr agent start`; it never substitutes a batch or non-interactive mode.
|
|
72
108
|
- Rejects prompts to agents reported as `working`, `blocked`, or `unknown`.
|
|
109
|
+
- Leaves Kimi's first-run folder-trust prompt untouched for manual confirmation.
|
|
73
110
|
- Uses Herdr's native blocking wait first.
|
|
74
111
|
- On `agent_prompt_stalled`, falls back only after a revision advance plus a new prompt anchor or a recovered `working` state.
|
|
75
112
|
- Uses native lifecycle waiting once Herdr reports `working`; otherwise a local 15-second revision-quiet heuristic returns `unknown` without declaring success.
|
|
@@ -78,7 +115,7 @@ then consume its single final JSON result. Do not poll Herdr from model turns.
|
|
|
78
115
|
|
|
79
116
|
## Local A/B result
|
|
80
117
|
|
|
81
|
-
One parent-Codex-to-Kimi review task
|
|
118
|
+
One parent-Codex-to-Kimi review task on macOS with Herdr 0.8.0 (`n=1`) produced the following result:
|
|
82
119
|
|
|
83
120
|
| Metric | Before | With plugin | Change |
|
|
84
121
|
| --- | ---: | ---: | ---: |
|
|
@@ -87,17 +124,19 @@ One parent-Codex-to-Kimi review task produced the following result on macOS with
|
|
|
87
124
|
| Output tokens | 2,950 | 1,638 | -44.5% |
|
|
88
125
|
| Wall time | 108 s | 62 s | -42.6% |
|
|
89
126
|
|
|
90
|
-
This is a single local comparison, not a universal performance guarantee.
|
|
127
|
+
Before the plugin, the parent recovered a false stall by polling Herdr. With the plugin, it made one blocking call. This is a single local comparison, not a universal performance guarantee, and it does not measure other agent pairings.
|
|
91
128
|
|
|
92
|
-
##
|
|
129
|
+
## Tests
|
|
93
130
|
|
|
94
131
|
```sh
|
|
95
132
|
python3 -m unittest -v
|
|
96
133
|
```
|
|
97
134
|
|
|
135
|
+
`npm test` runs the same command.
|
|
136
|
+
|
|
98
137
|
## Scope
|
|
99
138
|
|
|
100
|
-
This plugin coordinates interactive Herdr agents. Outside Herdr, use the downstream CLI's normal blocking non-interactive mode. It does not modify Herdr
|
|
139
|
+
This plugin coordinates interactive Herdr agents. Outside Herdr, use the downstream CLI's normal blocking non-interactive mode. It does not modify Herdr or replace agent TUIs. Plugin installation does not need npm; the npm package is an alternative way to install the same `herdr-turn` CLI.
|
|
101
140
|
|
|
102
141
|
## Uninstall
|
|
103
142
|
|
|
@@ -110,7 +149,7 @@ herdr plugin uninstall karthuslorin.turn-coordinator
|
|
|
110
149
|
For an npm installation:
|
|
111
150
|
|
|
112
151
|
```sh
|
|
113
|
-
npm uninstall --global herdr-turn-coordinator
|
|
152
|
+
npm uninstall --global herdr-turn-coordinator
|
|
114
153
|
```
|
|
115
154
|
|
|
116
155
|
## License
|
package/herdr-plugin.toml
CHANGED
package/herdr_turn.py
CHANGED
|
@@ -87,6 +87,13 @@ def contains_new_prompt(before, after, prompt):
|
|
|
87
87
|
return False
|
|
88
88
|
|
|
89
89
|
|
|
90
|
+
def requires_manual_setup(text):
|
|
91
|
+
text = " ".join(text.lower().split())
|
|
92
|
+
return "trust this folder?" in text and (
|
|
93
|
+
"don't trust" in text or "enable project mcp servers" in text
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
90
97
|
def wait_for_quiet(target, pane_id, delivered_revision, timeout):
|
|
91
98
|
deadline = time.monotonic() + max(0, timeout - 5000) / 1000
|
|
92
99
|
revision = delivered_revision
|
|
@@ -120,6 +127,10 @@ def wait_for_quiet(target, pane_id, delivered_revision, timeout):
|
|
|
120
127
|
|
|
121
128
|
def submit(target, prompt, timeout, lines, baseline_revision):
|
|
122
129
|
before = call("agent", "read", target, "--source", "visible")
|
|
130
|
+
if before.returncode:
|
|
131
|
+
fail("agent_preflight_read_failed", detail=payload(before))
|
|
132
|
+
if requires_manual_setup(before.stdout):
|
|
133
|
+
fail("agent_requires_manual_setup", target=target)
|
|
123
134
|
result = call("agent", "prompt", target, prompt, "--wait", "--timeout", str(timeout))
|
|
124
135
|
if result.returncode:
|
|
125
136
|
state = call("agent", "get", target)
|