yakka

Terminal multiplexer for coding agents · macOS & Linux

Claude Code left. Codex right. One screen.

yakka has one opinion about layout and gets out of the way after that. Each session runs in its own git worktree, so two agents can work at once without editing the same file — and in a detachable host, so leaving is not killing.

yakka — ~/code
Ctrl-a is the leader — press and release it, then a command key
Click in, then Ctrl+a then: hl half jk pane s split w close pane z zoom b sidebars Tab next session ? help

The split

The screen already told you who is waiting

Both sidebars are the same width, so the divider lands on the true centre of the window. Each side keeps its own session list, and every session carries one of three marks.

Working

It said something recently. Leave it alone.

Wants you

It went quiet, or rang the bell, while off screen.

Exited

The process is gone. Its last screen is kept, and Ctrl-a r restarts it.

▲ is the one to watch. It appears when an agent stops, not when it speaks — so it means "this one is waiting on you" rather than "this one is busy". Running several agents is only tolerable if you can tell, at a glance, which of them needs a human. That mark is the whole reason the sidebars exist.

In the list, is the session in the focused pane and · one that is on screen somewhere else.

Isolation

Two agents cannot edit the same file

Which is the point of running two at once. In the new-session picker, if the directory you have highlighted is inside a git repository, Tab switches to worktree mode.

yakka branches yakka/<agent>-N off the default branch, creates a worktree beside the repository, and starts the agent there. Two sessions on the same repo get two working trees and two branches, so neither can stand on the other's edits.

Killing a session removes its worktree — unless it has uncommitted changes, in which case yakka leaves it alone and says so. Nothing you have not committed is ever thrown away to tidy up.

The picker lists your scan roots and their immediate children, filtered as you type by fuzzy match. Recency only breaks ties between equally good matches, so the ordering never fights your typing.

~/code/ ├── atlas/ ← the repository ├── atlas.yakka-claude-1/ ← claude · atlasbranch yakka/claude-1 └── atlas.yakka-codex-1/ ← codex · atlas branch yakka/codex-1

Detaching

What --continue cannot do

The agents do not run inside the yakka you are looking at. They run in a per-user session host that yakka starts on first use and talks to over a unix socket.

So leaving is a detach rather than a kill. A resumed conversation replays what was said; reattaching finds the same process still running — mid-task, mid-output, with everything it had printed still on screen.

The host keeps the last couple of megabytes of each session's output. Past that the scrollback is dropped and reattaching restores the visible screen only.

If yakka cannot reach the host it says so and runs the agents itself, so a broken socket costs you detaching rather than the session. --no-server asks for that deliberately; either way quitting stops the agents, and yakka asks first.

Ctrl-a qLeave. The agents keep working.
yakkaCome back to them, screens and scrollback intact.
Ctrl-a QStop every agent and close the host.
yakka killThe same, from outside.
yakka --freshStart empty, ignoring the saved layout.

Quitting saves the layout to state.json, so the next launch rebuilds the same panes — reattaching to anything the host still has, and otherwise resuming with claude --continue or codex resume --last, both scoped to the session's directory so nothing picks up an unrelated conversation from another repo.

Keys

A leader, not a chord

Press and release Ctrl-a, then press the command key on its own. Everything else goes straight to the focused agent, so the agents keep all of their own bindings.

KeyAction
Ctrl-a h / lFocus the left / right half
Ctrl-a j / kFocus the pane below / above
Ctrl-a Tab / S-TabNext / previous session on this side
Ctrl-a 1–9Show the nth session of this side
Ctrl-a nNew session (directory picker)
Ctrl-a sSplit this half horizontally
Ctrl-a wClose this pane, leave the session running
Ctrl-a xKill this session
Ctrl-a zZoom this pane to the whole window
KeyAction
Ctrl-a bShow or hide the sidebars
Ctrl-a rRestart the process in this pane
Ctrl-a [Scroll back through history
Ctrl-a dShow what this session changed
Ctrl-a *Broadcast keys to every visible pane
Ctrl-a mMove this session to the other side
Ctrl-a ,Rename this session
Ctrl-a ?Help
Ctrl-a Ctrl-aSend a literal Ctrl-a to the agent

In scroll mode: j/k by line, Ctrl-d/Ctrl-u by half page, g/G for the ends, / to search back, q back to live. The prefix is configurable — any ctrl-, alt- or shift- combination, or f1f20.

10,209lines of Rust across 23 modules
254tests, unit and end-to-end
2–4panes per side, configurable
1session host per user
2agents built in, any number addable

Install

One binary, and two agents on your PATH

yakka runs claude and codex — it does not bundle them. Point it at anything else with an [[agents]] entry.

Recommended

Prebuilt binary

The macOS archive is universal — Apple Silicon and Intel. A Linux x86_64 build ships with every tag.

tar xzf yakka-macos-universal.tar.gz chmod +x yakka # unsigned, so clear the quarantine flag xattr -d com.apple.quarantine yakka mv yakka ~/.local/bin/
Latest release

Verify

Check the archive

Every release ships a .sha256 beside its archive.

shasum -a 256 -c yakka-macos-universal.tar.gz.sha256

Rust toolchain

Build it yourself

Then just run yakka.

cargo install --git https://github.com/romankhadka/yakka --root ~/.local

Optional

Configure

All of ~/.config/yakka/config.toml is optional. A side has a default agent, not a fixed one.

scan_roots = ["~/code"] prefix = "ctrl-a" max_panes = 2 left_agent = "claude" right_agent = "gemini" [[agents]] name = "gemini" command = "gemini" resume = ["--continue"]

Sidebars hide themselves below 100 columns; below 60×20 yakka says so rather than drawing something unusable. Where the terminal speaks the Kitty keyboard protocol — Ghostty, Kitty, WezTerm — key disambiguation is enabled so Shift-Enter reaches Claude Code as a soft newline. Hold Option on macOS, or Shift elsewhere, for your terminal's own selection while mouse capture is on.