Launchers
A launcher decides where an interactive Claude session runs. Nothing runs claude -p unless the launcher is headless.
| Launcher | A session is | Attach |
|---|---|---|
orca |
a terminal tab in Orca on the worktree | orca terminal switch |
tmux |
a detached tmux session, chernabog-<session> |
tmux attach-session |
headless |
claude -p, a child process of the run |
claude --resume |
| your own | launchers.<name> in machine config |
its attach, if it has one |
Only Claude has an interactive mode. Every other agent runs headless under any launcher.
Finishing a session
Section titled “Finishing a session”Under a launcher the prompt asks the agent to write its final answer as JSON to a file and stop. A Stop hook checks that file against the answer’s schema and sends the agent back until it is valid — three times at most, then the run fails. When the session is done, Chernabog closes it.
- A session that ends without an answer is resumed twice before the run fails.
- A session still running when the daemon restarts is waited on again, never started twice.
- The run log follows the session’s transcript.
- An expired login token is refreshed the same way: a one-line session under the repo’s launcher, closed once the token is fresh.
With a person
Section titled “With a person”On the hybrid path a person works in the session with the agent. A request with withPerson runs only with Claude under a launcher; headless, or another agent, fails with the reason. Such a session differs in four ways:
- The prompt adds a note that a person is here, so the agent talks things over with them instead of working unattended.
- The Stop hook never sends the agent back for its answer: stopping to wait for the person is the point. The session is done once a valid answer is written.
- In a hybrid session, the agent drafts the pull request with
chernabog open-pr --draftand asks the person with Claude’s question prompt whether to open it. A hook on that question writes the answer on their Yes, and refuses a question that doesn’t show the draft, or a draft the worktree has moved on from.chernabog open-prwithout--draftwrites it directly, for the person to run themselves. - In a hybrid session, the Stop hook reminds the agent to offer the pull request once for each new commit, when nothing is uncommitted, the commit isn’t pushed and there’s no draft for it yet.
- Chernabog leaves the session open after it answers, for the person to close. The next call on the session closes it first.
- A session the person closes before answering fails the call, rather than being resumed.
chernabog start <issue> brings the session up in the terminal it was run from, through the launcher’s attach. chernabog attach <run> brings it back later.
Who chooses
Section titled “Who chooses”The launcher describes a person’s own machine, so their choice beats the team’s default.
| Precedence | Layer | Key |
|---|---|---|
| 1 | the repo’s entry in machine config, or its persona’s | launcher |
| 2 | machine config | launcher, at the top level |
| 3 | .chernabog/config.yaml |
launcher |
| 4 | — | headless |
A team limits the choice with allowedLaunchers. A launcher outside that list fails the repo, naming the layer that chose it; Chernabog never falls back to another.
launcher: orcaallowedLaunchers: [orca, tmux, headless]Your own launcher
Section titled “Your own launcher”Only machine config can define one: a repo can name and limit launchers, but not define commands that run in your terminal.
| Key | Required | Does |
|---|---|---|
start |
yes | starts the session; prints its handle, or nothing to use {title} |
close |
yes | ends it |
alive |
no | exits 0 while the session runs; without it, running until done |
attach |
no | brings it up for a person |
Templates fill in {command} (the whole command, quoted for a shell), {cwd}, {title} and {handle}.
launcher: weztermlaunchers: wezterm: start: [wezterm, cli, spawn, --cwd, "{cwd}", --, sh, -c, "{command}"] close: [wezterm, cli, kill-pane, --pane-id, "{handle}"]Every launcher runs the same short command, chernabog __launch <spec>, which starts Claude with its account’s environment and the prompt from a file.