Documentation

Get Harness running

Harness is a macOS app plus a CLI you can script. Build it, install the CLI, and you can choose a plain terminal, persistent sessions, a full multiplexer, or an agent workspace in a few minutes.

Install

Nothing to resolve first. Clone it and build. You need Xcode's Swift toolchain on macOS 14 or later.

build from source
# Clone and build the release app
$ git clone https://github.com/robzilla1738/harness-cli.git harness
$ cd harness
$ make release
$ open Harness.app

Then run the bundled CLI installer. It copies harness-cli, installs shell completions, and wires the launchd agent that keeps HarnessDaemon alive:

install the CLI
$ Harness.app/Contents/MacOS/harness-cli install
# Add the printed bin directory to your shell PATH
$ export PATH="$HOME/Library/Application Support/Harness/bin:$PATH"
$ harness-cli ping
pong

Quick start

Open the app and a fresh install starts in Plain Terminal mode: fast native panes, normal macOS shortcuts, no prefix key or status bar until you opt into Multiplexer mode.

New tab⌘T
Split horizontally / vertically⌘D / ⇧⌘D
Command palette⌘K
Command prompt⌘;
Switch to tab 1–9⌘1 … ⌘9
Toggle sidebar⌘\
Choose an experience modeSettings ▸ Appearance

Switch to Multiplexer or Agent Workspace when you want the status line, prefix key, copy mode, attach/detach, and persistent sessions foregrounded.

The CLI

harness-cli talks to the session daemon over a local socket. Query state, change layout, and pipe panes from a script, a hook, or another machine.

harness-cli
# Inspect what's running
$ harness-cli list-workspaces
$ harness-cli list-surfaces
# Build a layout
$ harness-cli new-session --workspace Default --cwd ~
$ harness-cli new-tab --workspace Default
$ harness-cli new-split --tab <uuid> --direction horizontal
# Drive a pane
$ harness-cli send-keys --surface <uuid> --keys "C-c Enter"
$ harness-cli capture-pane --surface <uuid> --scrollback -S -100 -J

Run harness-cli with no arguments for the full list, or see the command reference.

The compositor

Render a tab's whole split layout — borders, status line, live panes, the active cursor — into any plain terminal, even over SSH. No tmux server involved.

attach-window
# Composite the active session into this terminal
$ harness-cli attach-window
# Or target a specific session / tab / window
$ harness-cli attach-window --session Default
# Detach with the prefix: Ctrl-A then d

Inside an attached window the prefix runs the multiplexer: %/" split, x kill, z zoom, hjkl select a pane, c new tab, n/p change tab, d detach. Several clients can attach the same surface; HarnessDaemon sizes shared clients to the smallest attached view, the way tmux does.

Agents

Harness reads the process tree and tells you when a coding agent finishes or stalls. Detection needs no setup; hooks add richer, explicit notifications.

agents
# What's running in this pane?
$ harness-cli detect-agent --surface <uuid>
claude-code · working
# Add richer hooks (deep-merges, idempotent)
$ harness-cli install-hooks claude-code
# Post a notification from your own tooling
$ harness-cli notify --surface "$HARNESS_SURFACE" --body "Approval required"

Installable hooks ship for Codex, Claude Code, Cursor, Pi, Hermes, and OpenClaw. OpenCode, Aider, Gemini, Goose, and other detected agents use the hook-independent activity path.

Keybindings

In Multiplexer mode, the prefix is Ctrl-A by default, and you can change or disable it in Settings. After the prefix, these run the multiplexer.

Split — side by side / stackedCtrl-A % / Ctrl-A "
Kill paneCtrl-A x
Zoom paneCtrl-A z
Select pane (GUI arrows · compositor hjkl)Ctrl-A ←↑↓→
Cycle panesCtrl-A o
Display pane numbersCtrl-A q
New tab · prev / nextCtrl-A c · Ctrl-A p / n
Command promptCtrl-A :

Rebind anything with harness-cli bind-key or by editing keybindings.json. Overrides merge over the defaults.

Themes

485 themes ship in the box, and the chrome paints the exact terminal color so the window reads as one surface.

Open the palette⌘K
Re-import a terminal configCtrl-A r in Multiplexer mode
Import a .harnessthemeSettings ▸ Appearance

Coming from Ghostty? Harness reads ~/.config/ghostty on first run, so your colors and font come with you.