# custom harnesses
Any agent CLI beyond the built-ins can be registered by dropping a harness.json next to the state file (~/Library/Application Support/hrdx/ on macOS, $XDG_CONFIG_HOME/hrdx/ on Linux). Registered harnesses appear everywhere the built-ins do: in the pickers, in agent cycling, in the sidebar agents list, and in settings.
[
{
"kind": "aider",
"binary": "aider",
"args": ["--no-auto-commits"],
"resume": ["--restore-chat-history"],
"busy": "Waiting for the model"
},
{ "kind": "goose" }
]| field | purpose |
|---|---|
| kind | identifier used in pickers and pane names (required) |
| binary | executable to launch (default: same as kind) |
| args | extra arguments passed on every launch |
| resume | arguments that resume the latest session on restore |
| resume_first | put the resume args before args (for subcommands) |
| busy | substring visible only while working, drives the spinner and finish sound; empty: braille spinner detection |
## busy detection
Agents that report their state through the Program Status Protocol (OSC 7501) are tracked from those reports instead of the screen: working is busy, blocked shows the attention dot, and idle, done, or error are idle. Reports outrank title markers and the screen scrape. Agents that never report fall back to the busy substring or spinner detection above.
| agent | busy detection |
|---|---|
| codex | OSC 7501 reports |
| zot, pi | OSC 7501 reports; panes start with ZOT_PROGRAM_STATUS=1 and PI_PROGRAM_STATUS=1 unless already set (set 0 before launching hrdx to opt out) |
| claude | terminal title: ◐/◑ while working, ✳ when idle; OSC 7501 reports win when they arrive |
## remote and container panes
Every pane is a real PTY, so a harness can just as well be an ssh, docker, or kubectl client running an agent at the target:
[
{
"kind": "remote-codex",
"binary": "ssh",
"args": ["-tt", "user@host", "cd /path/to/project && exec codex"]
},
{
"kind": "docker-codex",
"binary": "docker",
"args": ["exec", "-it", "-w", "/workspace", "container-name", "codex"]
}
]Wrapper scripts are useful when the host, container, namespace, or working directory is dynamic. Set the harness binary to the wrapper path and put fixed parameters in args.