Work on multiple features in parallel with coding agents, pairing a jujutsu workspace with a tmux window per feature.
agentmux add <feature> create a jj workspace + tmux window, start the agent
agentmux remove [-f] [name] tear a feature down (defaults to the current one)
agentmux list show feature workspaces and their tmux windows
Run inside tmux, anywhere in a jj repo (ideally colocated with git):
- Creates a jj workspace named
<feature>in a sibling directory../<repo>-<feature>, based ontrunk(). - Opens a tmux window named
<feature>in that directory. The window's name is pinned (automatic-rename off) and tagged with the custom option@agentmux-featureso agentmux can find it again even if it gets renamed. - Types the configured agent command into the window and presses Enter, then switches to it. If the agent exits, the window's shell survives for inspection.
- Resolves the feature: the argument, else the workspace your cwd is in,
else the current window's
@agentmux-featuretag.defaultis refused. - If the workspace's working-copy commit has changes, asks for confirmation
(
-f/-forceskips). Note thatjj workspace forgetnever deletes commits — described work stays in the repo either way. - Forgets the jj workspace, deletes the directory, and kills the tmux
window — in that order, so running
removefrom inside the feature's own window still completes the cleanup (the final message disappears with the window).
Cleanup is idempotent: stale state (directory deleted by hand, window closed, etc.) is skipped, and it only errors if nothing at all was found.
Global ~/.config/agentmux/config.toml, overridden per-key by
.agentmux.toml at the main repo root:
agent = "claude" # command to run; "{feature}" is substituted if present
select_window = true # switch to the new window after add
base_revision = "trunk()" # revset new workspaces are based on
window_prefix = "" # prepended to tmux window namesExample with a starting prompt:
agent = "claude 'Work on the {feature} feature'"Note on base_revision: jj's builtin trunk() resolves via remote
bookmarks (main@origin etc.) and falls back to root() in a repo with no
remote — set base_revision = "main" (or similar) for local-only repos.
Note on colocation: depending on your jj version, secondary workspaces may
not contain a .git directory even when the main repo is colocated, so
agents should use jj commands inside the workspace.
go install github.com/richardcase/agentmux@latest