Quickstart
Install RimZ, open a tmux or Zellij control room, launch coding agents in isolated worktrees, and reconnect remotely.
Get started
# 1. Install
curl -fsSL https://raw.githubusercontent.com/rimio-ai/rimz/main/scripts/install.sh | sh
# 2. Open the room
cd ~/code/query-engine
rimz
# 3. Launch agents and work; the sidebar surfaces whoever needs you
claude
codex
# 4. Worktrees, dynamic layouts, agent teams
rimz agents claude,codex --worktree=feat-x # Claude + Codex, side by side
rimz agents 'vim,claude+term' --worktree=feat-y # editor, agent, shell in one tab
# 5. Native SSH remote, with self-healing reconnect
rimz remote connect dev-box:~/code/query-engineOther ways to install
brew install rimio-ai/rimz/rimz # Homebrew
cargo install --locked rimz # Cargo, from crates.io
rimz update # later: update in place, whichever way you installedOn macOS, the install script's default latest-release install uses Homebrew automatically when brew is available. Prebuilt binaries, building from source, and uninstalling are in the installation guide. For a self-contained room with RimZ, both multiplexers, ttyd, and the priority agent CLIs preinstalled, run the Docker image.
Hooks
Hooks are how agents report to the room. The first rimz run offers to install them, with a summary of every file it touches and your consent, and rimz hooks install does the same on demand:
rimz hooks install --dry-run # per-agent summary plus a unified diff; writes nothing
rimz hooks install # every agent detected on the machine
rimz doctor # verify backend, hooks, and room healthThe install is additive (your existing hooks stay), and rimz hooks uninstall undoes it. → set up your machine · enable dynamic shell completion · security and trust
Everyday moves
The commands below run from any pane in the room, and from any script or CI job that reaches it. They compose: a profile becomes a team, the team lands in a worktree, the worktree's agents take messages, and a schedule fires the whole thing while you sleep.
Start agents
Run the official CLIs, untouched. Every supported agent joins the room the same way: type its own command into any pane, exactly as you do today. The stock binary runs with your flags, your config, and its own session files; the hooks you approved at setup report it to the sidebar, and nothing sits between you and the CLI.
claude
codexrimz agents earns its keystrokes when you want more than the default. A -auto or -yolo suffix sets the permission mode, and a Markdown definition under ~/.rimz/agents/ pins a model, effort, craft, and tools behind one word, so a planner that reasons hard and edits nothing is a name you reuse.
rimz agents claude # stock agent, own pane
rimz agents codex-yolo # permission modes: -auto, -ask, -plan, -yolo
rimz agents planner # your profile: model, effort, system promptLaunch layouts into worktrees. One spec describes the shape: , splits, + tiles, / stacks. Add -w and the whole layout lands in an isolated RimZ-owned Git worktree, seeded with the untracked files it needs, so two lines of work run side by side without touching each other or your main checkout.
rimz agents claude,codex -w feat-a # two agents, side by side
rimz agents planner,coder+reviewer -w feat-b # profiles compose like kinds
rimz agents 'vim,codex+term' -w feat-c # editor | agent tiled over a shell
rimz agents 'claude/codex/term' -w feat-d # one stack of three rows (a Zellij stack; tmux tiles them)
rimz agents codex --from-pr 42 # worktree checked out from a pull requestCombine models as teams. A named team in ~/.rimz/teams/<name>.md gives each role a handle and launches the whole set in its layout, each role in its own context window, cooperating over messages. Pair model strengths across providers: one plans, another writes the code, a third reviews the diff blind. A staged team tracks its progress on blackboard.md in the worktree, and rimz teams flip hands a stage to the next role. RimZ is built this way; examples/teams/ ships the forge team it uses, plus mill for refactors and spot for small fixes.
rimz agents claude:planner,codex:coder -w feat-once # one-off roles without a saved team
rimz teams install forge # release-matched shipped team
rimz teams forge -w feat-complex # planner, coder, reviewer on one feature
rimz teams spot -w fix-expiry # coder and reviewer on a small fix
rimz teams show forge#feat-complex # roles, status, and where the run stands
rimz teams wait forge#feat-complex # block until the board reaches Done
rimz agents attribution --md # credit the lane's agents and models in a PR footnoteSteer the fleet
Message agents like teammates. Every agent answers to a handle, named by kind, profile, or team role: @codex reaches the one in your channel, @codex#feat-a reaches across the workspace. Every message becomes a durable record you can read back and steer: parked at the turn boundary by default, --steer to write into the live turn now, --schedule to deliver later. The same command serves you, your scripts, and the agents themselves, which use it to talk to each other.
# Park at the next turn boundary; address by kind, profile, or team role
rimz message @claude "add coverage for the expiry edge cases"
rimz message @planner "draft the implementation plan"
rimz message @coder --after @planner "planner's done: read plan-notes.md and start"
# Ask and print the reply from the agent's own context
rimz message @coder --wait "did the migration land? one line"
rimz message @all --wait --json "status? one line" # a labeled reply map for the whole channel
# Write into the live turn now, or schedule for later
rimz message --steer @claude "stop: the parser test comes first"
rimz message --interrupt @claude "stop: the user changed direction" # stop the turn, then deliver fresh
rimz message --schedule 60m @codex#feat-b "run the smoke test"
# Pipe context in, or broadcast to everyone
git diff main | rimz message @reviewer --stdin "review this"
rimz message @all "summarize what changed at the next boundary"Answer a blocked agent without finding its pane. rimz asks lists the prompts that currently block agents, with each question's own text and options, and rimz answer submits a choice in the agent's native UI.
rimz asks # open prompts in this channel; --all for every channel
rimz asks show @planner # one prompt with its context and choices
rimz answer @planner allow # submit a choice by label
rimz answer @coder 2 # or by positionAutomate the routine
Script an agent like any CLI. rimz agents -p is claude -p with one grammar for every agent that can run headless: one prompt, supervision until the work ends, one exit code a script or CI job branches on, and swapping the provider behind a pipeline is a one-word change. It still runs in a real pane you can watch, answer, and steer while the pipeline waits on it.
# One supervised run, one exit code, one JSON result to branch on
rimz agents codex "Prepare the release checklist." -p --timeout 30m --output-format json
# stdin appends to the prompt
cat build-error.txt | rimz agents claude -p --stdin 'explain the root cause'
# Fire in the background; it returns now and prints the run's name
rimz agents claude "Run the migration audit." -p --bg
# Block on that run later and tail the answer
rimz agents wait swift-otter --stream
# Race several runs; the first to finish wins and prints its result
rimz agents wait otter fox --anyLet agents launch agents. rimz subagents is the same path packaged for an agent RimZ launched: one command, the parent's checkout and channel inherited, and a petname printed for a later join. Each child is a full agent with its own pane beside the parent's, a nested row in the sidebar, a run record and transcript that outlive the turn, and a question that routes to you instead of failing silently. Launches return at once and the children work in parallel; a parent that does not join gets one report once every child has settled.
# From inside an agent's turn
rimz subagents codex "review this diff for correctness; report concrete findings"
rimz subagents wait @otter @fox # collect named children's results
rimz subagents stop --all # stop every live child
# Fan one audit across providers, then join all of it
rimz subagents fanout --wait <<'JSON'
[
{"profile":"codex","prompt":"review correctness; report concrete findings"},
{"profile":"claude","prompt":"review the interface; report concrete findings"}
]
JSONRun the fleet on a schedule. rimz loop fires agent turns on a clock: daily at a set time, on an interval, from a cron line, or once after a delay. Add --check and the task becomes a watchdog, running the script first and waking the agent only on its result. There is no scheduler daemon: an open room keeps time, and rimz loop timer install adds a systemd or launchd timer for the hours when none is open. Switch on auto-continue and smart compaction and the loop runs hands-off; add --budget-per-day 20 to bound what hands-off work costs.
# 07:00 every weekday: overnight changes, summarized before you sit down
rimz loop add standup --agent claude --every weekday --at 07:00 \
--prompt "Summarize what landed on main since yesterday and flag anything that needs review"
# Watchdog: run the check first, wake the agent only on failure
rimz loop add watchdog --check "cargo test" --on fail \
--agent codex --prompt "fix the failing test" --every 15mWait without a pane. rimz wait is the alarm an agent sets for itself instead of holding its turn open on sleep: it ends the turn, and when the delay elapses, the command finishes, or the file changes, RimZ delivers a message back into the same conversation naming what fired and on what.
rimz wait --in 30m # one-shot wait after a delay
rimz wait --check 'nc -z localhost 3000' # poll until the service answers
rimz wait --file build.log --grep 'READY' # a new matching line in a file
rimz wait --pid 16776 # an existing process exits
rimz wait --run 'gh run watch --exit-status' # a command exits, with its output in the messageWake on a signal. A timer guesses when something will happen; a signal is the thing itself. RimZ emits ci.passed and ci.failed, pr.opened, pr.merged and pr.closed, trunk.moved, worktree.created and worktree.removed, and agent and team lifecycle signals from what the room already watches, and anything can emit its own. A CI or pull request subscription follows the calling agent's own worktree branch.
The GitHub-only signals pr.behind and pr.conflicted report an open PR falling behind its base or gaining confirmed conflicts, including on first sight. They fire on entry or a changed PR head while the state persists, not on repeated readings of the same head. Their PR payload has state: "open" and adds pr_head, base when known, and behind_by for pr.behind.
GitHub's merge queue runs CI on its own commit, so a PR it rejects stays green. pr.queued and pr.dequeued, also GitHub-only, report an open PR entering the queue and leaving it without merging; pr.dequeued carries GitHub's reason and a queue_checks_url to the queue commit's checks when GitHub provides them.
# Wake me when CI fails on the branch this agent is working on
rimz loop add ci-red --signal ci.failed --wait
# Wake me once, on the next merge
rimz loop add merged --signal pr.merged --wait --once
# Your own signal: a git hook, a deploy script, or another agent emits it
rimz events emit deploy.finished --json '{"env":"prod","version":"1.4.2"}'Step away
Work from anywhere. A room is plain Zellij or tmux under SSH: save an alias and reconnect over a link that heals itself, or tunnel the room into a local browser, which needs ttyd on the machine that serves the room. Close the laptop mid-run, reattach from another machine, and every agent is where you left it.
rimz remote add dev dev-box:~/code/query-engine
rimz remote connect dev # the room rebuilds, every agent where you left it
rimz remote connect dev --web # the same room in your browser at 127.0.0.1Answer from your phone. A fleet that runs while you are out still stops to ask: a permission prompt, a plan approval, a question only you can decide. Claude Code and Codex ship remote control, the bridge behind their official mobile apps, and two toggles keep that bridge up with every room. For remotely reachable sessions, the ask reaches your phone as a push from the provider's own app, your answer lands in the same session on the machine running the room, and the turn moves on as if you had typed it there. The Codex toggle keeps its daemon up for sessions started from the phone or outside RimZ; Codex agents RimZ launches run embedded (--no-daemon) and do not appear in the app. RimZ stays out of the path: each toggle starts the provider's own command with the room and nothing more.
rimz config set remote_control.claude true # keep `claude remote-control` up with the room
rimz config set remote_control.codex true # ensure codex's remote-control daemon, once per machineBoth are off by default, and setting one back to false undoes it. The remote guide shows exactly what each toggle runs. For every other agent, a notification handler pushes the ask anywhere a shell command can reach.
Configuration
RimZ runs with zero configuration, and everything you can tune is a plain file you own: no config daemon, no bespoke language. rimz setup detects the machine and writes commented defaults under ~/.rimz/ (config.toml, theme.toml, loop.toml, remote.toml), so the files are their own reference. Agent profiles, teams, and skills are Markdown beside them, under ~/.rimz/agents/, ~/.rimz/teams/, and ~/.rimz/skills/. After setup, rimz config set routes any dotted key to the owning file, validates the value, and writes it durably.
For the best experience, we recommend one pass of these:
rimz setup # once: detect the machine, write the commented defaults
# Appearance: truecolor, sharper glyphs, a companion
rimz config set theme.style modern # truecolor + Nerd Font icons
rimz config set theme.pets.enabled true # an animated pet; `rimz list-pets` previews them
# Hands-off work: recover and keep going while you're away
rimz config set resume.auto_continue true # resume rate-limit and API-error parks
rimz config set harness.smart_compact 200k # compact before a message once context passes 200k tokens (a percentage like "70%" works too)
rimz config set harness.budget 50/day # cap what the room spends in a day
# Answer asks from your phone (the move above)
rimz config set remote_control.claude true
rimz config set remote_control.codex trueWhat each group does, with the depth one link away:
- The modern look wants a truecolor terminal (Ghostty, WezTerm, Kitty, Alacritty) and a Nerd Font, inside RimZ tmux rooms and over
rimz remotetoo. The color scheme defaults to TokyoNight Night;rimz config set theme "Catppuccin Mocha"picks any bundled scheme fromrimz list-themes. Pets render as crisp pixels in Ghostty and kitty (tmux additionally needs 3.6+ withallow-passthrough on) and as cell art everywhere else, Zellij included. → theming · pets - Auto-continue resumes a parked agent the moment the provider's budget window resets and retries transient API errors on a backoff ramp; smart compaction sends the agent's compact command ahead of your text once context passes the threshold, so a long turn lands on a fresh window. Between them the pauses that would have stalled the fleet until morning clear themselves, and you are left with the decisions that actually need you. The room budget caps what that freedom costs, and the same cap exists per turn, per agent, per loop task, and per provider account. → loops → keep the fleet moving · budgets
- The remote-control toggles are the answer-from-your-phone move above; the remote guide shows exactly what each one runs.
Two more settings change what a room launches under:
rimz accounts add claude work # declare an account, share provider settings, install hooks
rimz start --account claude=work # a room whose Claude agents all run under `work`
rimz config set agents.isolation sandbox # Linux: a bubblewrap mount view for every agent pane- A provider account has its own login and limits; its sessions, spend, and budget are shared with the provider's own account unless you declare it standalone. Pin a room's account with
rimz start --accountorrimz accounts use, or leave it unpinned to follow trusted project and machine defaults live.rimz accounts use --reset claudeunpins Claude;rimz accounts use claude defaultpins Claude's own home instead. Agents already running keep their account; the guide covers child and loop-task overrides. - Sandbox isolation gives each agent the room's own
/tmpand the RimZ skill library merged into its provider's skill root, with a profile'sskills:list deciding which skills the model may call on its own. It is a mount view and not containment: the host filesystem stays writable and your credentials stay readable.rimz startrefuses to launch when bubblewrap is missing or unusable, and--isolation host|sandboxoverrides the setting for one launch.
The setup guide walks the whole first pass, agent hooks included; the Zellij and tmux guide has a modern baseline with ready-to-adopt example configs, and the full key catalog is the configuration guide.