# rudder

<p>
  <a href="https://rudder.viraat.dev">
    <img src="https://rudder.viraat.dev/favicon.svg" width="36" height="36" alt="Rudder logo" />
  </a>
</p>

[![npm version](https://img.shields.io/npm/v/@viraatdas/rudder.svg)](https://www.npmjs.com/package/@viraatdas/rudder)
[![npm downloads](https://img.shields.io/npm/dm/@viraatdas/rudder.svg)](https://www.npmjs.com/package/@viraatdas/rudder)
[![Node >=20](https://img.shields.io/badge/node-%3E%3D20-43853d.svg)](https://nodejs.org/)
[![Website](https://img.shields.io/badge/site-rudder.viraat.dev-111111.svg)](https://rudder.viraat.dev)

Rudder runs coding agents the way they should be used: several at once,
isolated, reviewable, and easy to merge. It opens a native three-pane dashboard,
gives every task its own git worktree, and runs real Claude Code or Codex
processes in the worker pane.

## Install

```bash
npm install -g @viraatdas/rudder@latest
rudder
```

Upgrade with the same command. Run without a global install using
`npx @viraatdas/rudder@latest`.

## Requirements

- Node.js 20 or newer
- Git
- Claude Code and/or Codex installed and logged in
- macOS, Linux, or another Unix-like terminal

Check your setup at any time:

```bash
rudder doctor
```

## Quick start

```bash
rudder
```

With no arguments, `rudder` opens the dashboard. Type a task in the bottom input
and press `Enter`. Rudder creates a git worktree for it and starts your agent
(Claude Code or Codex) in the worker pane. Start more tasks the same way; each
gets its own worktree so they never step on each other.

You can also start a task directly from the shell:

```bash
rudder "fix the failing tests"
rudder claude "fix the auth redirect bug"
rudder codex --model gpt-5.5 "refactor the parser"
```

## Onboarding and auth

```bash
rudder onboard
```

Onboarding uses the auth you already have, so you usually do not need API keys:

- Claude Code auth from the macOS Keychain or `~/.claude/.credentials.json`
- Codex auth from `~/.codex/auth.json`
- `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` if you prefer keys

If auth is missing you can skip it and set up a backend later. Config is written
to `~/.rudder/config.json`.

## The dashboard

```text
┌───────────────┬────────────────────────────────────────────┐
│ agents        │ worker                                       │
│ task list     │ live Claude Code or Codex terminal           │
│ status/model  │ scrollback, review view, copy selection      │
├───────────────┴────────────────────────────────────────────┤
│ task input: new tasks, slash commands, cloud launch prompts  │
└──────────────────────────────────────────────────────────────┘
```

- **agents** (left): one row per task with its backend, model, effort, and status.
- **worker** (right): the real Claude Code or Codex terminal. When it is focused,
  your keystrokes go straight to the agent, so its prompts, slash commands,
  selection, and `Tab` all work normally.
- **task** (bottom): start the next agent without leaving the dashboard.

Mouse wheel and trackpad scroll the pane under the pointer. Over the worker or
review pane they scroll Rudder's captured scrollback.

## Keyboard shortcuts

**Direct (work from any pane):**

| Key | Action |
| --- | --- |
| `Option-1` / `Option-2` / `Option-3` | Focus the agents, worker, or task pane |
| `Option-v` | Toggle the selected agent's review view |
| `Cmd-C` | Copy the active Rudder selection |
| `Ctrl-C` | Quit (asks to confirm if agents are still running) |

`Option-1/2/3` work out of the box on macOS terminals, whether or not "Use Option
as Meta" is enabled.

**Leader: press `Ctrl-W`, then one key.** A reliable way to run a dashboard
command, even while typing inside the worker pane:

| Then press | Action |
| --- | --- |
| `1` / `2` / `3` | Focus agents / worker / task |
| `v` | Toggle review |
| `m` | Merge the selected completed worktree |
| `M` | Merge all completed worktrees |
| `R` | Review all completed worktrees (Codex review-all agent) |
| `r` | Rename the selected agent |
| `d` | Delete the selected agent and its worktree |
| `j` / `k` | Move the agent selection |
| `q` | Quit |
| `Esc` | Cancel the leader |

`Ctrl-G` toggles the same command set as a sticky "nav mode" (`Esc` exits) if you
prefer a held mode over the one-shot leader.

**In the worker pane:** keystrokes go to the agent. `Tab` / `Shift+Tab` are
forwarded to it, `Shift+Enter` inserts a newline, and `PageUp` / `PageDown`
scroll the pane.

**In the agents pane:** `j` / `k` or arrows move the selection, `Enter` focuses
the worker, `m` / `M` / `R` / `r` / `d` act on the selection, `x` stops a running
agent (keeping its worktree), and `g` toggles the nested DAG view.

**In the task pane:** `Enter` starts the task, `Up` / `Down` browse history,
`Alt-Left` / `Alt-Right` move by word, `Alt-Backspace` (or `Ctrl-Backspace`)
deletes the previous word, and `/` opens command suggestions.

## Task pane commands

Type `/` in the task pane to open suggestions. Move with `Up` / `Down`, choose
with `Enter`.

| Command | Action |
| --- | --- |
| `/model` | Pick provider, then model, then effort |
| `/main` or `/m` | Start a new main-branch agent |
| `/review-all` | Combine completed worktrees and start a Codex review-all agent |
| `/merge-all` | Merge all completed worktrees |
| `/login` | Browser login for Rudder Cloud |
| `/cloud` | Onload the current workspace or start a fresh cloud worker |
| `/cloud list` | List cloud workers |
| `/help` | Show the short command hint |

## Models

Run `/model` and pick the provider, then the model, then the effort level the
model supports. Claude offers aliases like `sonnet`, `opus`, `haiku` (and the
`[1m]` long-context variants); Codex offers `gpt-5.5`, `gpt-5.4-codex`, and other
discovered models. `auto` effort means Rudder passes no override.

Your last provider, model, and effort are saved in `~/.rudder/config.json` and
reused next time. Rudder refreshes model metadata from
`https://models.dev/api.json` and falls back to local caches when offline.

## Planning (the default)

Just type a task. Rudder runs the model in **plan mode** (Claude Code or Codex), streamed
live in the orchestrator pane. The flow stays entirely inside Rudder — you only ever talk to
Rudder, and the planner researches read-only and can never implement on its own:

1. **It asks first.** The planner inspects the repo and then asks at least one
   clarifying or confirmation question before the first DAG, shown as a numbered prompt:

   ```
   ❓ The planner needs your input
     1. Which time range: last 4 weeks, 6 months, or all time?
     2. Reuse the existing module contract, or rebuild from scratch?

   ↳ answer in the task box below (e.g. "1: ..., 2: ...") and press Enter
   ```

   Type your answer in the task box and press `Enter`; it continues the same planning
   conversation with your answer. Rudder enforces this first question round in code, so
   even a fully specified request pauses once before the first plan.
2. **It lays out a DAG.** When it is ready it shows the task DAG (a tree of worker tasks
   with their dependencies). Type to refine it (Rudder re-plans, the DAG updates in place),
   or press `Enter` on an empty input to approve and launch.
3. **The fleet runs.** The scheduler drains the DAG (todo → in-progress → review → done) as
   dependencies merge, each task in its own isolated worktree.

After launch, typing a new task folds it into the running DAG as a new node. When a worker
finishes, Rudder reads back what it did and what work it found remaining (reconstructing it
from the diff if the agent did not say), so the plan keeps growing on its own. Type a
sweeping change ("rewrite this in Rust instead") and the plan re-plans around the work
already done. The queued plan survives a restart, so quitting mid-plan resumes where you
left off.

## Worktrees and merging

Every dashboard task runs in its own git worktree under `.rudder-worktrees/` inside
your project (gitignored), so parallel agents never edit the same checkout and every
Rudder path stays within the project boundary. Run records live under `.rudder/runs/`.
If you quit Rudder, live workers stop but the agents stay listed the next time you open
Rudder in that repo.

- Press `m` to merge the selected completed agent back into its branch.
- Press `M` to merge all completed agents. Rudder confirms first.

Clean merges become merge commits. If git reports conflicts, Rudder leaves the
conflicted state in place and can open an agent in the main checkout to help
resolve it.

Choose the merge behavior in `~/.rudder/config.json`:

```json
{ "mergeStrategy": "rebase" }
```

- `"merge"` (default): `git merge --no-ff`.
- `"rebase"`: rebase the worktree onto the latest base, then `git merge --ff-only`.

Command-line equivalents:

```bash
rudder merge <runId>
rudder sync <runId>
rudder cleanup
```

## Review

Press `v` on an agent to toggle a review of its worktree, showing the run's diff.
Press `v` or `Esc` to return to the worker.

Press `R` to review all completed worktrees as one bundle: Rudder builds an
aggregate branch and starts a Codex review-all agent over the combined diff. When
that row is done, press `m` on it to merge the reviewed bundle into your checkout.

## Rudder Cloud

Rudder Cloud is an optional hosted worker mode. The local dashboard stays your
control surface; you decide whether a task runs locally or is handed to the cloud.

```bash
rudder login                 # connect this machine to Rudder Cloud
rudder cloud                 # onload the current workspace or start a worker
rudder cloud list            # list cloud workers
rudder cloud logs <id>       # worker status
rudder cloud onload [runId]  # upload the current workspace (or one run)
rudder sail <name>           # short alias for starting a cloud worker
```

Inside the dashboard, `/login` starts browser auth and `/cloud` opens a
confirmation pane: the default option onloads the current workspace (repo
snapshot plus selected auth/config) to a Fly worker; press Down to start a fresh
scratch worker instead. Completed cloud work returns through the same review and
merge path as local work.

Cloud comes in two shapes: a **sail** is an ephemeral, task-scoped worker (it goes away
when the task is done; idle sails pause and can resume), while a **workspace** is a
persistent, volume-backed dev environment you can come back to. Both restore the same
workspace snapshot.

Cloud workers use Fly Machines by default. To use your own server over SSH (Docker over
SSH; bring-your-own-compute can be stopped but not paused/resumed):

```bash
rudder cloud byoc <ssh-host>   # an entry from ~/.ssh/config, key auth + Docker
rudder cloud vm "task"         # run on that host
rudder cloud runtime [fly|byoc]
```

The CLI points at the hosted control plane `https://rudder-cloud-control.fly.dev`.
Set `RUDDER_CLOUD_URL` to use your own deployment. Rudder Cloud login is separate
from Claude Code and Codex login; provider auth stays in the official CLIs.

## Run management

```bash
rudder status
rudder runs
rudder watch <runId>
rudder logs <runId> --follow
rudder stop <runId>
rudder delete <runId>
rudder merge <runId>
rudder sync <runId>
rudder cleanup
```

## Other interfaces

The native dashboard is the default. Older interfaces remain available:

```bash
rudder tmux          # legacy tmux dashboard
rudder tui           # Ink-based interactive TUI
rudder --no-native   # skip the native binary
```

## Troubleshooting

- Stale behavior after an upgrade: check `rudder --version`, reinstall with
  `npm install -g @viraatdas/rudder@latest`, and restart any running Rudder
  dashboards so no old `rudder-native` process lingers.
- Trackpad scrolling: confirm your terminal sends scroll events with
  `rudder mouse-test parsed`. Set `RUDDER_WHEEL_SCROLL_ROWS=<n>` to change the
  scroll step, or `RUDDER_MOUSE_DEBUG=1` to inspect routing.

## Building from source

```bash
git clone https://github.com/viraatdas/rudder.git
cd rudder
./setup.sh
```

`setup.sh` checks prerequisites (Node >=20, git, npm, Rust/`cargo`), installs
dependencies, builds (`tsc` + `cargo build --release`), typechecks, and smoke
tests the CLI. It is safe to re-run after pulling. For architecture and
implementation details, see [`AGENTS.md`](./AGENTS.md).

## License

MIT
