Install & access
How to install run-kit, keep it up to date, check your runtime, set up a development environment, and reach the dashboard over HTTPS.
Install
Install via the shll toolkit bootstrap:
curl -fsSL https://shll.ai/install | sh -s -- run-kit
This installs run-kit (plus the shll meta-CLI) via Homebrew, handling tap trust automatically, and puts the run-kit binary on your PATH. The formula also installs rk as a fully interchangeable short alias, so every command below works the same whether you type run-kit or rk. From there, a clean install to a working dashboard with one agent running is:
run-kit agent setup # optional, once per machine: agent busy/waiting/idle in the dashboard
run-kit daemon start # start the dashboard daemon on :3000
open http://localhost:3000 # open the dashboard in your browser
# in a tmux session (tmux new -s work if you aren't in one):
run-kit riff # spawn an agent workspace (--skill /name picks the slash-command)
On a Mac, the desktop app is an alternative front door: run-kit desktop install, then open Run Kit.app — its welcome page starts the daemon for you (one Start & connect click) and can also connect to run-kit on other machines over SSH or a URL, so the daemon start and open steps above collapse into opening the app.
The last step also needs wt and your agent CLI on PATH — see Prerequisites below.
run-kit agent setup installs agent-harness hooks into your user-global agent config (v1: Claude Code, ~/.claude/settings.json) so windows running an agent report live active/waiting/idle state in the dashboard. It shows the settings diff and asks before writing; re-running is idempotent, and run-kit agent setup --uninstall removes exactly the run-kit-owned entries. Until it’s run (and agent sessions are restarted so new sessions pick up the hooks), agent state shows —. See Agent state in the README for how the hooks work.
tmux version (≥ 3.4)
run-kit requires tmux 3.4 or newer. The version is checked at runtime against whatever tmux your PATH resolves: run-kit daemon start prints a one-line warning below the floor (and still starts), run-kit doctor reports the version on its tmux row, and run-kit remote connect refuses outright below 3.4 — its tunnel windows pass remote host input as tmux argv, which only ≥ 3.4 executes without going through a shell.
The recommended upgrade path is Homebrew on both platforms:
brew upgrade tmux # macOS
brew install tmux # Linux — your distro's tmux is too old on older LTS releases
Two caveats:
- PATH order matters. On Linux,
brew shellenvmust put Homebrew’s bin before/usr/bin, or the distro tmux keeps winning and the runtime check keeps warning — it probes thetmuxyourPATHactually resolves, which is exactly the binary run-kit uses. - Upgrades are latent. An upgraded binary takes effect only at the next
tmux kill-server— the running tmux server keeps its old binary, and the upgrade itself never kills your sessions.
Upgrade
run-kit update
run-kit update pulls the latest version via Homebrew and restarts the daemon so the new binary takes effect immediately. It covers the CLI and daemon only — the desktop app updates separately, via run-kit desktop update or the app’s Restart to Update menu item (see Desktop app (macOS)).
Upgrading from an earlier run-kit? Older installs had the agent-hook logic inlined in
~/.claude/settings.json. Runrun-kit agent setuponce more to swap in the new delegating wrapper, then restart your agent sessions. Future hook fixes ship in the binary and trackrun-kit updatewith no re-setup.
Desktop app (macOS)
The optional desktop shell wraps your dashboard in a native window and frees the browser-reserved ⌘ keyboard tier. Install and update it with the CLI:
run-kit desktop install # fetch the latest release DMG, install to /Applications
run-kit desktop update # same, but a no-op when already current
run-kit desktop status # installed vs latest version (read-only)
The CLI path is the primary one for a reason: the DMGs are ad-hoc signed (no notarization), so a browser download is stamped with com.apple.quarantine and Gatekeeper blocks the app on every install and update. Quarantine comes from the downloading application — command-line tools don’t apply it — so the CLI produces a quarantine-free install that opens cleanly every time, verifying the download itself (SHA256 against the release digest when available, plus codesign --verify --deep --strict) before installing. Use --path <dir> to install somewhere other than /Applications, and --version <tag> to pin a specific release.
Without the CLI, the fallback is manual: download the DMG for your architecture from GitHub Releases, drag Run Kit.app into Applications, and clear quarantine via System Settings → Privacy & Security → Open Anyway (or xattr -dr com.apple.quarantine "/Applications/Run Kit.app") — repeated on every manual update.
Inside the app, the welcome page offers three ways to connect, in descending order of “already have it here”: This Mac (detects the local install and daemon state; one Start & connect button starts the daemon when needed — post-connect control lives under Hosts → Local Daemon in the menu), over SSH (run-kit remote under the hood: registers the machine, installs run-kit there if missing, starts its daemon, opens a tunnel), and a URL (any reachable run-kit serve instance, e.g. the Tailscale HTTPS endpoint below). The app never starts or stops the daemon on its own — every daemon action is an explicit click, and your tmux sessions survive all of them.
Prerequisites
run-kit riff requires:
- A running tmux session (
$TMUXset). wton yourPATH— included with the full-toolkit install, orshll install wt.- The launcher (default
claude --dangerously-skip-permissions) available.
When something breaks, run:
run-kit doctor
run-kit doctor checks tmux, wt, the launcher binary, port availability, and prints per-dependency status. Run this first when something isn’t working.
Development
Run just doctor to check development prerequisites (Node 20+, pnpm, tmux, just, Go 1.22+, air, direnv), then:
just setup
just dev # watch mode (Go backend + Vite dev server)
just prod # run from built binary
Tailscale HTTPS
run-kit binds to 127.0.0.1 by default. Some browser features (e.g., copy to clipboard, and Web Push notifications — see below) require a secure context, and accessing run-kit from other machines on your tailnet does too. Tailscale Serve handles both with zero TLS config.
Web Push & secure contexts: the
run-kit notifycommand pushes OS-level notifications to subscribed browsers (opt in via theCmd+Kpalette → Notifications: Enable push). Web Push requires a secure context — HTTPS orlocalhost. Reaching run-kit onlocalhost:3000directly, or over the Tailscale HTTPS endpoint below, both qualify; plain HTTP to a remote host does not, and the browser will silently refuse to register the service worker.
Prerequisites
Enable HTTPS on your tailnet in the Tailscale admin console under DNS > HTTPS Certificates.
Then let your user manage Tailscale without sudo (one-time — tailscale serve needs root or the designated operator):
sudo tailscale set --operator=$USER
Quickstart
tailscale serve --bg http://localhost:3000
run-kit is now available at:
https://<machine>.<tailnet>.ts.net
To check status or stop:
tailscale serve status
tailscale serve off
Advanced: Custom hostname
Serve run-kit under a stable hostname like runner1.<tailnet>.ts.net instead of the machine name — the URL survives moving run-kit to another host.
Services need a tagged node. Do these in order:
-
Define the
tag:servertag. In Access controls, Visual editor → Tags → add a tag namedserver. Owners can be left empty. -
Re-register the node with the tag. Tags can only be requested via
tailscale up(there is notailscale set --advertise-tags), anduperrors unless every non-default pref is re-stated — so--operatoris repeated here, not newly set:sudo tailscale up --advertise-tags=tag:server --operator=$USER -
Add the HTTPS endpoint. In the machines console, open the
svc:runner1service and addtcp:443. Skip this and you’ll get “required ports are missing” even while the service advertises. -
Serve:
tailscale serve --bg --service=svc:runner1 http://localhost:3000 -
Approve the service. Open the Services page, find the pending
svc:runner1advertisement under Service hosts, and click Approve. The service is inactive until you do.
run-kit is now at https://runner1.<tailnet>.ts.net.
Note: Tagging a node drops its user-identity association — user-based ACL grants stop applying. Make sure your ACLs grant the tag what it needs.
Tip: If you advertise services often, you can skip the manual approval in step 5. In the Access controls JSON editor, add an
autoApproversblock as a top-level key (there’s no Visual editor control for service approval), then save — leave the existinggrantsblock untouched:"autoApprovers": { "services": { "svc:runner1": ["tag:server"] } },
Advanced: Public access (Funnel)
To expose run-kit to the public internet (not just your tailnet):
tailscale funnel --bg http://localhost:3000
Warning: Funnel makes your terminal relay publicly accessible. Only use this if you understand the security implications.