Install & access
How to install HexoKit, 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://hexokit.com/install | sh -s -- run-kit
This installs HexoKit (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:
shll setup agent # 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 macOS and Linux, the desktop app is an alternative front door: run-kit desktop install, then open the app — its welcome page starts the daemon for you (one Start & connect click) and can also connect to HexoKit 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.
shll setup agent (which delegates to run-kit agent setup, and runs automatically at the end of a toolkit install) installs agent-harness hooks into your user-global agent configs — Claude Code, Codex, Gemini CLI, GitHub Copilot CLI, Kimi Code, OpenCode, and Antigravity CLI, each wired when its binary is on PATH — so windows running an agent report live active/waiting/idle state in the dashboard. It shows the diff and asks before writing; re-running is idempotent, and run-kit agent setup --uninstall removes exactly the HexoKit-owned entries. Codex additionally needs its native trust review (/hooks inside codex) before its hooks run. Until the setup has run (and agent sessions are restarted so new sessions pick up the hooks), agent state shows —. See the agent hook integrations page for the per-harness capability matrix and Agent state in the README for how the hooks work.
tmux version (≥ 3.4)
HexoKit 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 HexoKit 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).
Upgrading from an earlier HexoKit? 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.
Coming from the old
rkformula? run-kit was originally published assahil87/tap/rk. If brew warns thatsahil87/tap/rk was renamed to sahil87/tap/run-kit, you have a keg installed under the old name — remove it with a benignbrew uninstall sahil87/tap/rk(your config and therkcommand alias are unaffected), thenbrew install sahil87/tap/run-kitifrun-kitis no longer on yourPATH.
Desktop app
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 (macOS and Linux):
run-kit desktop install # fetch the latest release and install it
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. On macOS 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, plus codesign --verify --deep --strict) before installing. Use --path <dir> to install somewhere other than /Applications (macOS) or ~/.rk/desktop (Linux), and --version <tag> to pin a specific release.
On Linux the recommended path is the toolkit installer followed by the CLI:
curl -fsSL https://hexokit.com/install | sh -s -- run-kit # installs the CLI
run-kit desktop install # installs the app
run-kit desktop install downloads the AppImage for your architecture, verifies its release digest (a release without one is refused), extracts it once into ~/.rk/desktop/<version>/ with an atomically-flipped current symlink, and writes a launcher entry, the icon, and a run-kit-desktop symlink in ~/.local/bin. Updates arrive via run-kit desktop update or the app’s Restart to Update menu item — the running app is quit gracefully, swapped, and relaunched. run-kit desktop uninstall removes the install and its desktop integration (your app settings under ~/.config/run-kit-desktop are kept).
Without the CLI on Linux, the fallback is manual: download the AppImage for your architecture (x86_64 or arm64) from GitHub Releases, chmod +x it, and run it — with ./run-kit-desktop-<version>-<arch>.AppImage --appimage-extract-and-run when libfuse2 is missing. The manual path gets no launcher entry and no update notice. On macOS without the CLI: download the DMG, 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 / This Machine (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 HexoKit 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.
code-server (the code lens)
The daemon starts a managed code-server beside it (its own rk-code-server tmux session on the same socket), powering the dashboard’s code lens and CODE panel surface — a full editor at the window’s git root, served same-origin behind the stable /code/ route.
HexoKit owns the install: on first daemon start with no code-server anywhere, a code-server-install window in the rk-jobs session downloads the latest digest-verified standalone release into ~/.rk/code-server-bin/. The manual equivalent is run-kit code-server install; run-kit code-server update upgrades, and run-kit update runs that leg automatically. A code-server you installed yourself on PATH is respected and never touched.
It binds loopback-only on RK_PORT+2; set RK_CODE_SERVER_PORT only to point HexoKit at an externally managed instance instead. run-kit daemon stop deliberately leaves code-server running; run-kit doctor reports its presence and reachability.
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. - Optional — the GUI tile (the host’s desktop in the dashboard) needs a VNC X server and a window manager:
sudo apt install --no-install-recommends tigervnc-standalone-server icewmon Debian/Ubuntu;rk gui statusprints the line for your package manager. Desktops, resolution, and troubleshooting: the GUI guide. See the GUI guide.
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 # one-time: frontend deps, Playwright browsers, .env.local, tmux.conf embed staging
just dev # watch mode (Go backend + Vite dev server) on this worktree's derived port
just dev --port 4000 # same, on an explicit port (Vite on 4000, backend on 4001, code-server on 4002)
just prod # run from built binary
just dev defaults to the worktree’s derived e2e port triple, so parallel worktrees never collide; pass --port only when you need a specific port. Re-run just setup after pulling dependency changes.
Tailscale HTTPS
HexoKit 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 HexoKit 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 HexoKit 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
HexoKit is now available at:
https://<machine>.<tailnet>.ts.net
To check status or stop:
tailscale serve status
tailscale serve off
Advanced: Custom hostname
Serve HexoKit under a stable hostname like runner1.<tailnet>.ts.net instead of the machine name — the URL survives moving HexoKit 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.
HexoKit 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 HexoKit 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.