Skip to content

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.

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.

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 --draft and 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-pr without --draft writes 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.

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.

.chernabog/config.yaml
launcher: orca
allowedLaunchers: [orca, tmux, headless]

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}.

~/.config/chernabog/config.yaml
launcher: wezterm
launchers:
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.