Herdr Opencode
Native Herdr lifecycle reporting for OpenCode v1 and v2 — accurate agent state and pane session restore
0
76
12 in 7 days
30.8
Multi-signal model
21 days ago
2026-09-14
Install and configure
opencode.jsonWrites to this project's opencode.json — applies to this repository only.
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@phux/herdr-opencode@0.2.0"]
}Writes to ~/.config/opencode/opencode.json — applies to every project.
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@phux/herdr-opencode@0.2.0"]
}If you want to modify the plugin locally, install it into the project and reference the local path.
shell
pnpm add -D @phux/herdr-opencodeOpenCode loads npm dependencies through its embedded runtime on startup and caches them locally — no manual global install needed.
Native Herdr lifecycle reporting for OpenCode v1 and v2 from one plugin.
Inside a Herdr pane, OpenCode's actual state (working / blocked / idle) and
session identity are reported straight to the Herdr daemon over its socket —
no screen scraping, no heuristic manifest matching. Herdr's agent panel shows
the real state, and panes restore with opencode --session <id> after a
server restart.
┌─ herdr ──────────────────────────────────────┐
│ pane: opencode state: working ▮▮▮ │
│ pane: claude state: blocked ⏸ │
└──────────────────────────────────────────────┘
▲ pane.report_agent / pane.report_agent_session
│
opencode v1 or v2, running this plugin
Why this exists
Herdr ships an OpenCode integration (herdr integration install opencode),
but as of herdr 0.8.0 it has two problems this plugin fixes:
- It does not load on modern OpenCode. The stock plugin uses a named
export; OpenCode 1.18+ only invokes
export default(herdr#2548). - It never reports state even when hand-patched, because root sessions were misclassified as child sessions and swallowed (herdr#2548, defect 2).
- OpenCode 2 (
opencode2) is not recognized at all — herdr's process detector looks for theopencodeexecutable (discussion #1971).
This plugin speaks the same socket protocol, loads correctly on OpenCode
≥ 1.18.29 (v1) and on OpenCode 2 (opencode2), fixes the root/child
classification, and adds nothing else — no dependencies, no hooks into your
prompts.
Install
OpenCode v1
npm install -g @phux/herdr-opencode
// ~/.config/opencode/opencode.json
{
"plugin": ["@phux/herdr-opencode"]
}
OpenCode 2 (opencode2)
npm install -g @phux/herdr-opencode
// ~/.config/opencode/opencode.json — v2 reads the same file family
{
"plugins": ["@phux/herdr-opencode"]
}
Both hosts load the same entrypoint: v1 calls server(), v2 calls setup()
(the dual shape from OpenCode's plugin docs).
Local file (no npm)
curl -fsSL https://raw.githubusercontent.com/no-phux/herdr-opencode/main/src/index.ts \
-o ~/.config/opencode/plugins/herdr-opencode.ts
v1 discovers plugins/*.ts directly; v2 discovers direct files too
(child directories as packages need a reasonably current v2 build —
anomalyco/opencode#41530).
What it reports
| OpenCode event | Herdr |
|---|---|
session.created (root) |
pane.report_agent_session with session_start_source: new |
session.updated (changed root) |
pane.report_agent_session |
session.status → busy/running/streaming/… |
state working |
session.status → idle |
state idle |
session.status (unknown kind) |
bare session re-report |
tool.execute.*, permission.replied, session.compacted |
state working |
permission.asked, question.asked, session.error |
state blocked |
| subagent/child sessions | dropped — child prompts project state without stealing the pane's root session |
The wire protocol is Herdr's own: line-delimited JSON over
HERDR_SOCKET_PATH (\\.\pipe\ on Windows), methods pane.report_agent and
pane.report_agent_session, stamped with pane_id, source: herdr:opencode,
agent: opencode, and a monotonic seq. One short-lived connection per
report with a 500 ms timeout — a wedged daemon can never hang your session.
Notes for OpenCode 2 users
OpenCode 2 installs as
opencode2; Herdr's process detector currently keys on theopencodeexecutable name. Until Herdr ships native v2 detection (discussion #1971), launch v2 through an alias so the pane is recognized:target="$(readlink -f "$(command -v opencode2)")" mkdir -p ~/.local/opt/opencode2-herdr ln -sfn "$target" ~/.local/opt/opencode2-herdr/opencode # launch ~/.local/opt/opencode2-herdr/opencodeThis plugin reports
agent: opencodeeither way — that is the agent type Herdr's manifest already understands, and the v2 progress bar maps toworkingunder Herdr's screen fallback while the pane is undetected.
Debugging
HERDR_OPENCODE_DEBUG=1 opencode # reports to stderr as [herdr-opencode]
herdr agent list # agent_session should now be populated
If state never updates: check HERDR_ENV, HERDR_SOCKET_PATH, and
HERDR_PANE_ID are set in the pane (they are injected by Herdr itself), and
that the plugin is listed as loaded (/plugins in v2, or opencode's startup
logs in v1).
Compared to herdr integration install opencode
| stock integration | herdr-opencode | |
|---|---|---|
| OpenCode v1 ≥ 1.18.29 | ✗ (never loads) | ✓ |
| OpenCode v1 older | ✓ (named export) | ✓ |
OpenCode v2 (opencode2) |
✗ | ✓ |
| root/child classification | ✗ (swallows all events) | ✓ fixed |
| session restore | ✗ (no session reported) | ✓ |
| dependencies | none | none |
Keep the stock integration uninstalled while using this one — two reporters
would interleave conflicting seq streams on the same pane.
Development
npm ci
npm test # typecheck + build + node:test (classifier + real socket round-trip)
The classifier and wire protocol are pure and table-tested; the socket test stands up a real Unix socket server and asserts the exact JSON lines and their ordering.
License
MIT — published by no-phux for the Herdr community.
Similar plugins
Herdr Opencode
herdr-opencode
Native Herdr lifecycle reporting for OpenCode v1 and v2 — accurate agent state and pane session restore
Herdr
opencode-herdr
Route OpenCode agents through Herdr panes as herdr/<adapter>/<model> (Cursor, Claude, Codex, OpenCode)
Rmux
opencode-rmux
Opencode plugin that bridges AI coding agent sessions with RMUX terminal multiplexer — cross-platform subagent pane management and AI-driven RMUX control tools