Print Mode vs Tmux: Hermes Orchestrates Claude Code
Two ways Hermes talks to Claude Code: claude -p print mode and tmux-backed PTY sessions. When to use each, what they cost, where they break.
Once you have decided to let Hermes delegate work to Claude Code, you hit a practical question: how exactly does Hermes talk to Claude Code? There are two supported transport mechanisms, and they are not interchangeable. Picking the right one matters — the wrong choice either wastes tokens rebuilding context you could have kept, or blocks a simple one-shot task behind a complicated persistent session.
This post is the technical deep-dive on both. If you have not read the positioning for why you would delegate in the first place, start with Spawning Claude Code as a Hermes Subagent. Here we are past that question and just figuring out which wire to talk on.
Key Takeaways
- Print mode uses
claude -p "prompt"— a single-shot, stateless invocation that returns Claude Code's final output on stdout. - Tmux mode spawns Claude Code inside a tmux session and keeps the PTY open — Hermes can send multiple turns and read responses interactively.
- Print mode is faster to spin up, cheap, and great for batched tasks with self-contained prompts.
- Tmux mode is slower and more expensive per task, but preserves Claude Code's in-session memory across turns.
- Print mode discards Claude Code's own working memory when the process exits. Plan accordingly.
- Tmux mode can hang if Claude Code waits for input — Hermes needs timeouts and watchdogs.
- Default to print mode. Upgrade to tmux only when the task genuinely requires back-and-forth.
The Two Modes At A Glance
| Aspect | Print mode | Tmux mode |
|---|---|---|
| Invocation | claude -p "prompt" | tmux new-session -d "claude" |
| Statefulness | Stateless (one shot) | Stateful across turns |
| Startup cost | ~1 process spawn | ~1 process + tmux overhead |
| Memory within session | None (Claude Code exits) | Preserved until session ends |
| Good for | Self-contained tasks | Iterative debugging, review cycles |
| Bad for | Multi-turn reasoning | Simple one-off tasks |
| Parallelism | Trivial (spawn N processes) | Harder (manage N tmux sessions) |
| Token cost per task | Lower | Higher (context accumulates) |
Print Mode: claude -p
Print mode is Claude Code's non-interactive flag. You pass a prompt as an argument (or via stdin), Claude Code spins up, reads the prompt, runs its agent loop, and prints the final answer to stdout before exiting.
From Hermes's side, it is a subprocess call:
# Conceptual — actual call is routed through the bundled skill
result = shell.run(
[
"claude", "-p",
"Refactor utils/dates.py to use Arrow instead of datetime. "
"Keep the public API the same. Run the tests. Return a summary."
],
cwd="/home/user/projects/billing-api",
timeout=600,
)
summary = result.stdout
What makes print mode attractive:
- Trivial parallelism. Want to run five refactors at once? Spawn five
claude -psubprocesses. They are fully independent. - No session cleanup. The process exits, the kernel reaps it, done.
- Low context overhead. Claude Code loads its own context, does the work, throws it away. No accumulated cruft.
- Easy logging. Redirect stdout to a file. That is your transcript.
What makes it limiting:
- Stateless. If the task needs "first do X, then based on the result do Y," you have to either cram both steps into the initial prompt or spawn a second
claude -p(which starts from scratch and won't remember step 1). - No interruption. You can't send a follow-up like "wait, that's not what I meant." You get one shot.
- Claude Code's in-session memory is gone. If Claude Code built up context about the repo during the run, that context dies with the process.
The guidance: use print mode when the task can be expressed as a single, self-contained prompt. "Implement this PRD," "refactor this file," "add tests for this module," "generate API docs from this schema." If you can write the full prompt in one shot and wait for the answer, use print mode.
Tmux Mode: Persistent PTY
Tmux mode is the other end of the spectrum. Hermes starts a tmux session, runs Claude Code inside it, and then uses tmux send-keys to inject input and tmux capture-pane to read output. The Claude Code process stays alive across many turns.
The outline of the mechanic:
# Start the session
tmux new-session -d -s hermes-cc -x 200 -y 50 "claude"
# Wait for Claude Code to prompt
# (Hermes polls capture-pane until it sees the prompt)
# Send input
tmux send-keys -t hermes-cc "Look at auth/middleware.py and tell me what it does" Enter
# Read response
tmux capture-pane -t hermes-cc -p
# Send follow-up
tmux send-keys -t hermes-cc "Now refactor it to use TokenValidator" Enter
# Read response
tmux capture-pane -t hermes-cc -p
# When done, kill the session
tmux kill-session -t hermes-cc
Hermes wraps all of that in its tooling. You do not type these commands yourself — the delegate skill handles the lifecycle. But this is what is happening under the hood.
What makes tmux mode attractive:
- Stateful. Claude Code remembers what it did in turn 1 at turn 7. You can iterate.
- Interruptible. If Claude Code is going down the wrong path, Hermes can send a correction mid-session.
- Real IDE-style workflow. The interaction pattern matches how a human uses Claude Code.
What makes it costly:
- Slower per task. Session setup, the polling loop waiting for prompts, capturing panes — it all adds up.
- Context accumulates. Each turn adds to Claude Code's context window. A long session gets expensive in tokens and eventually hits the window limit.
- Harder to parallelize. N sessions means N tmux servers, N window managers, N pane captures. Possible, but operationally heavier than N
claude -pprocesses. - Hang risk. If Claude Code is waiting for input that never comes (or waiting for a user confirmation Hermes did not provide), the session hangs. Hermes needs watchdogs.
The guidance: use tmux mode when the task has genuine iterative structure — you don't know step 3 until you see the output of step 2, and you need Claude Code to remember steps 1 and 2 when it does step 3.
A Decision Rubric
When you are writing a Hermes skill that calls Claude Code, ask:
- Can I describe the task in one prompt? If yes, print mode.
- Do I need Claude Code to remember earlier turns? If yes, tmux. Otherwise, print mode.
- Am I spawning many of these in parallel? If yes, strongly prefer print mode.
- Is this a scheduled job with a token budget? Print mode is cheaper; start there.
- Am I doing interactive debugging or live review? Tmux.
Nine times out of ten the answer is print mode. The Hermes bundled skill defaults to print mode for exactly this reason.
The Print Mode / Claude Code Memory Trap
This is the pitfall worth calling out explicitly. Claude Code maintains its own working context during a session — it remembers files it read, decisions it made, tests it ran. That context dies the moment claude -p exits.
If you do this:
claude -p "Read auth/middleware.py and understand its structure"
claude -p "Now refactor it"
...the second invocation has no idea what the first one did. It will read the file from scratch. You wasted the first call.
The fix is either to collapse them:
claude -p "Read auth/middleware.py and then refactor it to use TokenValidator. Return a summary."
...or switch to tmux mode where the same Claude Code process handles both turns.
Claude Code's CLAUDE.md file in the working directory helps a little — it gets loaded each time — so long-lived project facts can live there and be picked up by every print-mode invocation. This is related to what is portable from CLAUDE.md to Hermes memory and why both runtimes keep their own memory stores.
The Tmux Hang Trap
Tmux sessions can hang if Claude Code prompts for something Hermes does not know to answer. Classic examples: a tool confirmation, a "file already exists, overwrite?" prompt, a credential challenge.
Mitigations:
- Always set a timeout. If
capture-paneshows no new output for N seconds, kill the session. - Pre-authenticate. Hermes reuses Claude Code's credential store. Authenticate Claude Code interactively once, then Hermes delegations inherit the session.
- Use non-interactive flags where available.
--dangerously-skip-permissionsand similar switches exist for good reasons in autonomous contexts. Know the risk surface before using them. - Log everything. When a tmux session hangs, the captured pane history tells you where.
Recommended Default
Start every new delegation with print mode. Measure what you get. Only switch to tmux when you hit an explicit reason print mode cannot handle — and 80% of the time, rewriting the prompt to be self-contained eliminates that reason.
The Hermes bundled skill reflects this. The default mode is "print". Tmux is opt-in.