How rostr works

The short version

rostr assemble installs hooks into Claude Code and Codex. Each hook calls the rostr CLI, which keeps your rosters and who's drafted where: in a local SQLite database, or on the rostr API in cloud mode, so sessions on every machine draft from the same rosters.

On a session's first prompt, rostr drafts a name, tells the agent who it is, and puts the name in the session's title. While the session works, the hooks keep the name alive. When it ends, the name goes back to the bench.

Drafting a name

Each session is drafted from the roster linked to its project, else your default roster. The pick goes:

  1. Least recently drafted. The free member drafted longest ago, so names cycle through the whole roster.
  2. Take a resting name. If everyone's busy, the name of the session that has rested longest.
  3. Copies. If no one is resting either, a numbered copy like 🧙 Gandalf 2. A session always gets a name.

A resumed session gets its old name back, if no one else has taken it since.

In cloud mode, Claude Code sessions draft in the background as soon as they start, so the first prompt doesn't wait on the network.

Resting and benching

A member is drafted, resting, or on the bench.

Telling the agent who it is

The hook tells the agent its name, and to sign anything it writes outside the chat with it, like PR descriptions and Slack messages. After compaction, it's told again.

Commands the agent runs, like rostr task, need to know which session they're in. In Claude Code, the start hook appends export ROSTR_SESSION=<session ID> to the session's env file (the path Claude Code passes in CLAUDE_ENV_FILE), and Claude Code loads that file before every shell command the agent runs. Codex sets CODEX_THREAD_ID in its commands' environment itself, so rostr reads that. Therostr task command the agent is told to run also names the session with --session, so it works even where neither variable is set.

The hooks

Both agents get the same five hooks. Each one is a one-liner that runs rostr hook only if rostr is installed, so the logic lives in the binary and updates when you upgrade. After an upgrade, the first session reinstalls the hooks if they've changed.

SessionStart
Claude Code: records the session in ROSTR_SESSION and, in cloud mode, drafts ahead. Both: get the old name back on resume, and re-tell the name after compaction. Codex: drafts a forked thread.
UserPromptSubmit
First prompt: drafts, tells the agent who it is, and starts the title (below). Later prompts: end a rest, keep the name alive, and retitle the session if its task changed.
PostToolUse
Marks the session as working again. Claude Code: after a title call, records the summary as the task and tells the agent to carry on with its answer.
Stop
Records that the turn ended, which starts the 15 minutes until the session rests.
SessionEnd
Benches the name and clears the pane label.

Hooks never block a session. Network calls time out after 3 seconds, and anything slow runs in the background. If rostr can't draft, the session just starts unnamed.

Titles in Claude Code

The title is <name> · <3-5 word summary>. Who writes the summary depends on where the session runs:

Where the session runsHow the title gets there
TerminalThe first-prompt hook sets <name> · <start of your prompt>, so the name shows straight away. rostr summarizes your prompt in the background with claude -p --model haiku, on your own login, and puts the summary in the title on your next prompt
Desktop app and cloud sessionsBefore writing anything, the agent calls the app's set_session_title. In Local sessions it loads the tool with ToolSearch first

The summary is recorded as the session's task, which rostr stats shows. When the task changes, later prompts retitle the session to match.

Why the agent writes the summary in the app

Hooks can only set a title when a prompt arrives. In a terminal, that's the best there is: the summary shows up on your second prompt. The app can do better, because it gives the agent a title tool. The agent already knows the task, so it titles the session in its first reply.

The title tool is also the only option in Remote Control and cloud sessions, where a hook's title doesn't show up at all (a known Claude Code bug).

Why the title comes first

Recent models can turn text written just before a tool call into a progress update, a short summary of it. So an answer followed by a title call could show up twice: once as a summary, then again in full. The first thing in a reply is never turned into one, so the agent sets the title before writing anything.

Titles in Codex

The title is <name> · <Codex's own title>. On the first prompt, rostr drafts a name and tells the agent who it is, but leaves the thread unnamed. Codex's TUI and app then title the thread themselves, usually within a few seconds. rostr waits for that title in the background, makes it the session's task, and renames the thread to <name> · <title>.

Why rostr waits for Codex

Codex hooks can't set a title, so rostr names threads through the Codex app-server instead. Codex only titles a thread that has no name, and drops its title if the name changes while it's writing one. Naming the thread on the first prompt would mean no summary, so rostr waits and adds the name to Codex's title. The summary costs no extra tokens.

Token use

rostr adds a few hundred tokens to a session, almost all on the first prompt. Later prompts add nothing unless the session is renamed.

tmux and herdr

When a session is drafted or renamed, rostr labels its pane: herdr shows the name as the pane's agent, and in tmux a window with a single pane is renamed to it. The label is cleared when the session ends.

Claude Code runs its hooks inside the session's own pane, so rostr knows which pane to label. Codex runs hooks in a shared background process, whose pane is whichever terminal started it, and nothing ties a thread to the terminal showing it. So rostr works from the title instead: it has just named the thread, and Codex puts the thread's name in its terminal title. rostr labels the one Codex pane whose title shows the new name, and labels nothing if it finds none or more than one. If you set a custom tui.terminal_title in Codex, include thread-name.

Privacy and security

Local mode's only network call downloads the list of pre-built rosters. In cloud mode, tasks and repo names are encrypted on your machine before they're sent, and the server never sees your rostr key, prompts, or code.