Multi-headed AI agent session manager
Run multiple Claude, Codex, and Gemini agents in parallel, each in its own tmux session, managed from a single TUI.
- Sidebar + Preview layout — browse all agent sessions in a list, see live output in the preview pane
- Compose mode — press Enter to open compose, type a full message, press Enter to send, Esc to cancel (draft preserved). Prompt history with Up/Down arrows. Bracketed paste support for multiline input.
- Status indicators — green (idle), red (running), yellow (exited) dots per session, with auto-clearing status messages
- Task timer — tracks elapsed time for the current running task per agent
- Last message preview — shows the last parsed assistant response per session from provider logs
- Auto-generated names — sessions get NATO phonetic alphabet names (alpha, bravo, charlie, ...)
- Session persistence — sessions survive laptop shutdown; auto-revived on next launch using agent resume
- Session stats — live cost, token, and tool-call metrics per agent from provider logs
- Diff tree — sidebar shows per-file git diff stats grouped by directory
- Multi-agent support — Claude (
claude --dangerously-skip-permissions), Codex (codex --yolo), Gemini (gemini --yolo) - Mouse support — click to select sessions, scroll the preview pane
- Full scrollback — keyboard and mouse scrolling through complete session history (PgUp/PgDn, Home/End)
- Copy mode — press
cto release mouse capture for terminal text selection - Low resource usage — idle sessions skip pane captures, batch tmux queries, parallel agent resolution
- Rust (stable)
- tmux (installed and on PATH)
- At least one of: Claude Code, Codex, Gemini CLI
cargo install --locked --git https://github.com/rencryptofish/hydra.git hydraIf you don't have Rust installed yet:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal && . "$HOME/.cargo/env" && cargo install --locked --git https://github.com/rencryptofish/hydra.git hydraTo update later, run hydra update.
hydra # launch the TUI
hydra new AGENT NAME # create a new agent session (claude/codex/gemini)
hydra kill NAME # kill a session
hydra ls # list sessions for the current project
hydra update # update to the latest version from GitHubBrowse mode
| Key | Action |
|---|---|
j / k |
Navigate sessions |
PgUp / PgDn |
Scroll preview pane |
Home / End |
Jump to top / bottom of preview |
Enter |
Open compose mode |
n |
New session |
d |
Delete session |
c |
Toggle copy mode (release mouse for text selection) |
q |
Quit |
Compose mode
| Key | Action |
|---|---|
Enter |
Send message |
Shift+Enter |
Insert newline |
Up / Down |
Browse prompt history |
PgUp / PgDn |
Scroll preview pane |
Esc |
Cancel (draft preserved) |
Single-binary Rust TUI built on ratatui + crossterm + tokio.
src/
├── main.rs CLI parsing, terminal setup, event loop
├── app.rs UiApp state, mode machine, key/mouse handlers
├── backend.rs Backend actor (owns all I/O, communicates via channels)
├── backend/ Runtime sub-components (session, message, preview)
├── agent/ Per-provider log parsing and command builders
├── ui.rs Root UI rendering (layout, draw dispatch)
├── ui/ Rendering submodules (sidebar, preview, conversation, ...)
├── tmux.rs SessionManager trait + subprocess tmux manager
├── tmux_control.rs Persistent `tmux -C` control-mode manager
├── session.rs Session/AgentType data types
├── manifest.rs Session persistence (~/.hydra/<project>/sessions.json)
├── logs.rs Log readers + session/global stats + cost calculations
├── event.rs Async crossterm event reader
└── system/ Git diff parsing, process tree helpers
Key design decisions:
- Backend/UI actor model — Backend runs in
tokio::spawn, owns all I/O, and communicates with the UI viawatch(state snapshots) andmpsc(commands, previews). The UI event loop never blocks on I/O. SessionManagertrait — all tmux interaction is behind an async trait for testability (mock/noop impls in tests)- Hybrid status detection — prefers tmux
%outputnotifications and falls back to capture-based detection when needed - Session revival — manifest file persists session metadata; on startup, dead sessions are recreated with agent-specific resume commands
- Async I/O — all tmux subprocess calls and manifest file I/O use
tokioto avoid blocking the event loop - Nested session isolation — safely runs from within Claude Code by unsetting
CLAUDECODEenv vars in spawned sessions
490+ tests across unit, snapshot, CLI integration, and property-based:
cargo test # run all tests
cargo insta review # review snapshot diffs after UI changes
cargo llvm-cov # generate coverage report
cargo +nightly udeps --all-targets # detect unused dependencies| Module | Coverage |
|---|---|
session.rs |
94% |
ui.rs |
91% |
app.rs |
83% |
logs.rs |
26% |
main.rs |
22% |
tmux.rs |
4% |
event.rs |
0% |
| Total | 65% |
The low-coverage modules (
tmux.rs,event.rs,main.rs) are I/O-heavy code that shells out to tmux or reads terminal events. Core logic and UI rendering are well covered.
MIT