conclave — spawn agents on any harness and talk with them — the same seven verbs in every direction
2026·09 · active · python · markdown
the itch
by september there were three vocabularies for one job. summon-cc drove interactive claude code workers in tmux panes from any agent; cc-oc launched detached opencode runs from inside claude code; openai's codex plugin brokered an app-server. each spawned one harness from one harness, in its own words — and none of them let a codex child answer a claude parent, or an opencode session tell a codex session anything at all.
conclave is the one interface: an agent on claude code, codex or opencode spawns agents on claude code, codex or opencode, and messages go parent to child, child to parent, peer to peer. the verbs, the knobs and the output are the same whichever harness sits on either end. both predecessors are archived; their discipline — verbatim vocabularies, self-verifying spawn, detached process groups, a session-scoped ledger — carried over.
messages, not modals
a child is a real harness session, resumed one turn per message in its own detached process: claude -p then --resume, codex exec then exec resume, opencode run then --session. children never prompt — each runs in its harness's skip-permissions mode — and a child asks by ending its turn with the question. the parent answers with send. that one convention replaces question modals, permission relays and pane parsing.
a result reaches its parent once, by the first of three ways: whoever is waiting gets it; with nobody waiting it is pushed into the parent's own inbox — claude code's session socket, codex queue, opencode's server — as a message that starts a turn; and when no inbox is reachable it stays in the state directory for wait. no daemon, no server, no config file. the state is files, the whole thing is stdlib python, and the skill and the opencode plugin ship inside the wheel so they can never describe a binary they don't match.
the wrong self
conclave has to know who is calling it: the caller's address is where results get pushed. the first version took the first session variable it found, claude before codex. then a codex tui living in a tmux server that a claude code session had started called itself that claude session — a tmux session takes the tmux server's environment, and a harness run from another's shell inherits the outer one's variables the same way. every check passed; its results would have landed in the wrong window.
the fix walks the process ancestry — one ps — to the nearest ancestor named claude, codex or opencode, and reads that harness's variables only. no enclosing harness means no address, not a stale one. a second race went the same way: a wait attaching between "turn ended" and "pushed" would have lost the result to the push, so the runner now holds the waiter lock through the delivery. the first job conclave ever did was review its own release — a codex child, read-only, nineteen minutes — and five of its findings were real.
facts
status: active · v0.1.0
install: uv tool install agent-conclave · conclave install
verbs: 7 — spawn · send · wait · list · cancel · doctor · install
harnesses: claude code · codex · opencode — any parents any
delivery: once — waited, else pushed into the inbox, else kept
runtime: python ≥ 3.12, stdlib only · no daemon, no config file
size: 967 lines, skill and plugin included
license: MIT
links
github · pypi
← anfreire.dev · the interactive version needs javascript