An open API service indexing awesome lists of open source software.

https://github.com/sahil87/run-kit

Web-based tmux orchestration dashboard for long-running AI agent tasks
https://github.com/sahil87/run-kit

agents claude-code cli dashboard developer-tools fab-kit mobile orchestration terminal tmux web-ui worktrees

Last synced: 7 days ago
JSON representation

Web-based tmux orchestration dashboard for long-running AI agent tasks

Awesome Lists containing this project

README

          

# run-kit logo run-kit

> Part of [@sahil87's open source toolkit](https://shll.ai) — see all projects there.

[![Latest release](https://img.shields.io/github/v/release/sahil87/run-kit)](https://github.com/sahil87/run-kit/releases) [![Downloads](https://img.shields.io/github/downloads/sahil87/run-kit/total)](https://github.com/sahil87/run-kit/releases) [![Stars](https://img.shields.io/github/stars/sahil87/run-kit?style=social)](https://github.com/sahil87/run-kit/stargazers)

`rk riff` spawns AI coding agents in parallel [git worktrees](https://github.com/sahil87/wt). The browser dashboard lets you watch them all — from your desk or your phone.

## Why run-kit?

- **One command per parallel agent** — `rk riff` creates a worktree, opens a tmux window in it, and launches Claude Code. `rk riff -N 3` spawns three workspaces in parallel; failures roll back cleanly.
- **Browser dashboard for tmux** — every tmux session and pane shows up in a sidebar. Click a pane for a live terminal in the browser; open the same dashboard on your phone over Tailscale.
- **Mobile-first, keyboard-first** — `Cmd+K` command palette is the primary discovery surface. Touch targets are tuned for mobile so you can drive an agent session from your phone while away from your desk.
- **No database, no daemon magic** — state is derived from tmux and the filesystem. Agent sessions survive `rk` restarts because the daemon never touches them.
- **The dashboard layer over [`fab-kit`](https://github.com/sahil87/fab-kit) and [`wt`](https://github.com/sahil87/wt)** — `rk riff --skill /fab-fff` launches a full fab-kit pipeline in an isolated worktree. Use rk when you have more parallel changes than you can watch in a single terminal.

## Screenshots

Desktop — terminal session with sidebar (servers, sessions, panes) and host stats


Mobile menu — drawer with servers, sessions, and panes
Mobile dashboard — session and window overview
Mobile terminal session

## The mental model

rk is two independent halves that compose:

```
rk riff rk serve
▼ ▼
spawns agent runs the
workspaces ─────► browser dashboard
(tmux + worktree) (watches tmux)
```

You can run either alone. Run `rk riff` in any tmux session without ever starting `rk serve` — you get the spawning behavior, no dashboard. Run `rk serve` and never call `rk riff` — you get a tmux browser dashboard for sessions you spawn manually. The two are designed to compose, not depend on each other.

## Quick start

From a clean install to a working dashboard with one agent running:

```bash
brew install sahil87/tap/rk # install
rk serve -d # start the dashboard daemon on :3000
open http://localhost:3000 # open the dashboard in your browser

# in any tmux session:
rk riff --skill /fab-discuss # spawn an agent workspace
```

The new workspace appears in the dashboard's sidebar; click into it to drive the agent from the browser.

To upgrade later, run `rk update` — pulls the latest version via Homebrew and restarts the daemon so the new binary takes effect immediately.

See the [install & access guide](docs/site/install.md) for prerequisites, `rk doctor`, development setup, and driving rk from your phone over Tailscale HTTPS.

## `rk riff` — the spawner

The headline command. One invocation gives you a git worktree, a tmux window inside it, and one or more Claude Code panes ready to go.

**Pane array model.** `--skill` and `--cmd` are repeatable. Each occurrence adds one pane; argv order (left to right) becomes pane order. Bare `--skill` opens a blank Claude session; bare `--cmd` drops into `$SHELL`.

**Layouts.** `auto` (default), `tiled`, `even-horizontal`, `even-vertical`, `main-horizontal`, `main-vertical`. Set with `--layout`.

**Presets.** Common pane/layout combos go in `fab/project/config.yaml` under `riff.presets.`. Invoke as `rk riff ` or `rk riff --preset `.

**Parallel.** `-N ` spawns N workspaces in parallel; failures roll back successful ones before exiting.

**wt passthrough.** Flags after `--` go to `wt create` verbatim (e.g. `--base`, `--reuse`, `--worktree-name`).

Examples:

```bash
rk riff # 1 pane, default skill (/fab-discuss)
rk riff --skill /fab-fff # 1 pane, specific slash-command
rk riff --skill /fab-fff --cmd "just dev" # 2 panes (agent + dev server)
rk riff --skill /a --cmd x --cmd y --layout main-vertical
rk riff ship # invoke the 'ship' preset
rk riff ship -N 3 # 3 parallel ship workspaces
rk riff -- --worktree-name pacing-canyon # name the worktree
```

**Prerequisites:** must be inside a tmux session, [`wt`](https://github.com/sahil87/wt) on `PATH`, and the launcher (default `claude --dangerously-skip-permissions`) available. Override the launcher per-project via `agent.spawn_command` in `fab/project/config.yaml`.

See the [riff guide](docs/site/workflows.md) for the full reference.

## `rk serve` — the dashboard daemon

Start the HTTP server. Configurable via `RK_HOST` (default `127.0.0.1`) and `RK_PORT` (default `3000`).

```bash
rk serve # foreground on 127.0.0.1:3000
RK_HOST=0.0.0.0 RK_PORT=8080 rk serve # bind all interfaces, port 8080
rk serve -d # background daemon in a tmux session
rk serve --restart # idempotent restart
rk serve --stop # graceful shutdown
```

The daemon runs in its own dedicated tmux server (`rk-daemon`), completely separate from your agent sessions. Restart the daemon and your agents keep running — the dashboard reconnects automatically.

## Boards — watch many panes at once

A **board** is a named, cross-server pane dashboard. Pin any tmux window from any server into a board, and the board renders all pinned panes side-by-side in a horizontally-scrollable layout — perfect for watching three parallel agent sessions, or comparing a `just dev` server's output against the agent that's editing it.

Three ways to pin a window to a board:

1. **Sidebar pin icon** — every window row in the sidebar has a pin icon. Click it to open a popover listing existing boards (click to pin/unpin), plus a "Pin to new board…" input that creates a new board on first pin.
2. **Command palette (`Cmd+K`)** — `Board: Pin Current Window`, `Board: Unpin Current Window`, `Board: Switch to `, `Board: Leave Board View`.
3. **Board pane header** — each pinned pane shows an unpin button in its header for one-click removal.

Inside a board:

- **`Cmd+]` / `Cmd+[`** cycles pane focus to the next / previous pane (wraps).
- **Click a pane** to focus it; keystrokes route to that pane's terminal.
- **Drag the pane edge** to resize (desktop only; widths persist per-board in `localStorage`).
- **On mobile**, panes render as a single-pane swipe carousel.

Pin state lives in tmux (via the `@rk_board` window option) so it follows the window, not the browser — open the same board URL on your phone and you see the same panes. Pane widths are intentionally local to each device.

## Drive it from your phone (HTTPS over Tailscale)

Some browser features (clipboard, secure context) require HTTPS. Accessing rk from another machine on your tailnet also requires HTTPS:

1. Enable HTTPS at [DNS > HTTPS Certificates](https://login.tailscale.com/admin/dns).
2. Run `tailscale serve --bg http://localhost:3000`.
3. Open `https://..ts.net` on your phone or another laptop.

For a stable custom hostname or public access via Funnel, see the [Tailscale guide](docs/site/install.md).

## Shell completion

`rk shell-init ` emits eval-safe tab-completion for your shell. Add this line to your rc file:

```sh
eval "$(rk shell-init zsh)" # in ~/.zshrc
eval "$(rk shell-init bash)" # in ~/.bashrc
```

Supports `zsh`, `bash`, `fish`, and `powershell`. Completion-only — rk has no shell function wrapper; every subcommand is reached via `rk `.

> 💡 Have other sahil87 tools? [`shll shell-install`](https://github.com/sahil87/shll#shll-shell-install--wire-the-rc-file-recommended) handles all of their shell integrations and autocompletions at once.

## Command reference

| Command | What it does |
|---------|--------------|
| `rk riff` | Create a worktree + tmux window + Claude Code pane(s). |
| `rk serve` | Start the HTTP server (foreground or daemon). |
| `rk status` | Show a tmux session summary. |
| `rk context` | Print agent-optimized environment info (server URL, ports, etc.) — designed to be read by AI agents inside an rk-spawned workspace. |
| `rk doctor` | Check runtime dependencies. Run this first when something breaks. |
| `rk init-conf` | Scaffold default `tmux.conf` and `tmux.d/` drop-in directory to `~/.rk/`. Optional. |
| `rk update` | Upgrade via Homebrew and restart the daemon. |
| `rk completion` | Generate shell completion scripts (or use `rk shell-init` for eval-safe output). |
| `rk help` | Help about any command. |

Run `rk --help` for full flag details, or see the [full command reference](https://shll.ai/tools/run-kit/commands/) for every command and flag.

## Troubleshooting

- **`rk riff` fails with "not in a tmux session"** — riff requires `$TMUX` to be set. Start tmux first (`tmux new -s work`), then run `rk riff` inside it.
- **`rk riff` fails with "wt not found"** — install `wt` via `brew install sahil87/tap/wt`, or via the toolkit meta-formula `brew install sahil87/tap/all`.
- **Anything else broken** — run `rk doctor`. It checks tmux, `wt`, the launcher binary, port availability, and prints per-dependency status.

## Architecture

rk's daemon runs in a dedicated tmux server (`rk-daemon`), separate from agent sessions (`runkit`). Restarts use kill-and-restart (no polling loop or signal files), are idempotent (`--restart` works whether or not a daemon is running), and never touch agent tmux sessions — agents survive daemon restarts unaffected.