{"id":50521915,"url":"https://github.com/robzilla1738/harness-terminal","last_synced_at":"2026-06-06T00:03:53.129Z","repository":{"id":360801914,"uuid":"1251734577","full_name":"robzilla1738/harness-terminal","owner":"robzilla1738","description":"The native macOS terminal that keeps your sessions running and tells you when a coding agent needs you. GPU-rendered, scriptable, agent-aware.","archived":false,"fork":false,"pushed_at":"2026-06-02T03:48:16.000Z","size":14811,"stargazers_count":70,"open_issues_count":4,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-02T05:08:56.296Z","etag":null,"topics":["ai-agents","coding-agents","developer-tools","gpu","macos","metal","sparkle","swift","terminal","terminal-emulator"],"latest_commit_sha":null,"homepage":"https://harnesscli.dev","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robzilla1738.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"robcourson","thanks_dev":null,"custom":null}},"created_at":"2026-05-27T21:37:13.000Z","updated_at":"2026-06-02T04:59:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/robzilla1738/harness-terminal","commit_stats":null,"previous_names":["robzilla1738/harness-cli","robzilla1738/harness-terminal"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/robzilla1738/harness-terminal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robzilla1738%2Fharness-terminal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robzilla1738%2Fharness-terminal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robzilla1738%2Fharness-terminal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robzilla1738%2Fharness-terminal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robzilla1738","download_url":"https://codeload.github.com/robzilla1738/harness-terminal/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robzilla1738%2Fharness-terminal/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33964367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","coding-agents","developer-tools","gpu","macos","metal","sparkle","swift","terminal","terminal-emulator"],"created_at":"2026-06-03T05:00:34.614Z","updated_at":"2026-06-06T00:03:53.124Z","avatar_url":"https://github.com/robzilla1738.png","language":"Swift","funding_links":["https://buymeacoffee.com/robcourson"],"categories":["Swift"],"sub_categories":[],"readme":"# Harness\n\n[![CI](https://github.com/robzilla1738/harness-terminal/actions/workflows/ci.yml/badge.svg)](https://github.com/robzilla1738/harness-terminal/actions/workflows/ci.yml)\n\nThe native macOS terminal that keeps your sessions running and tells you the moment a coding agent needs you.\n\nEvery pane renders on Harness's own GPU engine. Your splits and sessions live in a background daemon, so they survive quitting the app — and their scrollback survives a daemon restart. You can drive or attach to them from the command line, including a headless or remote daemon over SSH. And Harness watches the agents you run inside it (Claude Code, Codex, Cursor, and more), so an approval prompt never sits unseen behind another tab.\n\nOne self-contained app. The terminal engine, daemon, and CLI are all first-party Swift; the only external dependency is Sparkle (the macOS auto-update framework, GUI-only).\n\n## Download\n\n**[Download Harness for macOS →](https://github.com/robzilla1738/harness-terminal/releases/latest/download/Harness.dmg)**\n\nOpen the DMG, drag `Harness.app` to Applications, and launch it normally. The release is signed, notarized, and built for Apple silicon Macs running macOS 15 or later.\n\nVerify the SHA-256 checksum against the value published on the [GitHub release page](https://github.com/robzilla1738/harness-terminal/releases/latest).\n\nPrefer to build it yourself? Jump to [Build from source](#build-from-source).\n\n## Why Harness\n\n- **It's a real terminal first.** GPU rendering, accurate sRGB color by default, opt-in converted Display-P3 vivid color, ligatures, inline images (Sixel / Kitty / iTerm2), and 490 built-in themes with a muted Harness default. Block and box-drawing glyphs are drawn procedurally, so borders tile without seams at any font.\n- **Your work outlives the window.** Sessions, tabs, and splits are owned by a daemon. Quit and reopen and everything is exactly where you left it, scrollback included — history is persisted to disk and restored even if the daemon restarts. Attach the same session from a second window or another machine.\n- **It's scriptable, locally or remotely.** `harness-cli` drives the whole thing — open tabs, send keys, capture a pane, resize, swap, zoom — so your tooling can build the layout it needs. Point any command at a headless or remote daemon with `--host \u003cname\u003e`; the daemon and CLI run on Linux too, so a remote box can host your sessions.\n- **It watches your agents.** Harness detects Claude Code, Codex, Cursor, and others by their process tree, shows which session is running what, and pings you when an agent stops or asks for approval. `Cmd+Shift+U` jumps you to the one that's waiting and skips the ones still thinking.\n\n## How it feels\n\nHarness ranges from a plain, get-out-of-your-way terminal to a full session manager. Pick the level in **Settings → Terminal → Experience**:\n\n- **Plain Terminal** — fast and quiet. No command prefix, no status bar. Sessions close when you quit, like any terminal.\n- **Persistent Terminal** — the same clean look, but sessions survive quitting and you can attach to them from the CLI.\n- **Full Terminal** — everything: command prefix, status line, copy mode, paste buffers, panes, and the full `harness-cli` command set.\n- **Agent Workspace** — persistent project workspaces with agent detection and notifications turned up front.\n\nNew installs start in Plain. Moving over from another setup? See [docs/MIGRATION.md](docs/MIGRATION.md) — Harness can import an existing terminal config (colors, font, padding) on first run.\n\n## Features\n\n- GPU-accelerated rendering by Harness's own terminal engine — accurate sRGB output by default, opt-in converted Display-P3 vivid color, a themed translucent canvas, and program output left untouched unless you opt into theme recoloring\n- Mainstream-GPU-terminal polish: live re-wrap while resizing (with a grid-size overlay), word / line / block selection, middle-click paste, alternate-screen wheel scrolling, focus reporting, hollow unfocused cursor, minimum contrast, auto light/dark themes, bold-is-bright control, and paste protection\n- Sidebar sessions, per-session tabs, and horizontal / vertical splits\n- Session layout persists across quits (daemon-owned, attach from the CLI or over SSH)\n- Persistent scrollback: a pane's history is written to disk per surface and restored when the daemon restarts\n- Remote \u0026 headless daemon: run `HarnessDaemon` on a headless or remote box (Linux included) and drive it with `harness-cli --host \u003cname\u003e` over an SSH tunnel — register hosts with `harness-cli remote add`\n- `harness-cli` for automation and agent hooks\n- Color/theme diagnostics from the CLI: `harness-cli color-check` and `harness-cli theme-preview --theme \u003cname\u003e` print deterministic SGR pages for eyeballing fidelity in Harness itself\n- Command set: `send-keys`, `capture-pane`, `kill-pane`, `resize-pane`, `zoom-pane`, `swap-pane`, `rename-tab`, `attach`, and more\n- Command prefix keymap (default `Ctrl-A`) with a live cheatsheet (prefix `?`)\n- Agent detection for Claude Code, Codex, Cursor, Grok, Pi, Hermes, OpenClaw, OpenCode, Aider, Gemini, and Goose — each with a brand color and a sidebar chip\n- Agent alerts as desktop banners and a sidebar bell; `Cmd+Shift+U` jumps to whoever is waiting\n- One-line hook install: `harness-cli install-hooks \u003cagent\u003e`\n- Command palette (`Cmd+K`) and a native macOS Settings window (`Cmd+,`)\n- 490 built-in color themes with a muted Harness default, plus `.harnesstheme` export / import for sharing\n- Shell integration (OSC 133): prompt marks for jump-to-prompt and a command success / failure gutter — bash / zsh / fish snippets in [docs/shell-integration/](docs/shell-integration/README.md)\n- Inline images that stay put across reflow and scroll into history\n- Drag file-backed folders or images into a pane to insert shell-quoted paths\n- Set Harness as the default terminal for SSH/Telnet/man-page links and `.command` / `.tool` files from Settings \u003e Terminal\n- Automatic, signed background updates (Sparkle + EdDSA)\n\n## harness-cli\n\nHarness launches its daemon automatically; the CLI talks to it.\n\n```bash\nharness-cli list-surfaces\nharness-cli new-session --workspace Default --cwd ~/Code/myproject\nharness-cli new-tab --workspace Default --cwd ~/Code/myproject\nharness-cli send-keys --surface \"$HARNESS_SURFACE\" --keys \"ls -la Enter\"\nharness-cli notify --surface \"$HARNESS_SURFACE\" --title Agent --body \"Needs approval\"\nharness-cli color-check\nharness-cli theme-preview --theme \"Harness Default\"\n```\n\nInstall it onto your `PATH`:\n\n```bash\n# From the app bundle:\n/Applications/Harness.app/Contents/MacOS/harness-cli install\n\n# Or from a source build:\n.build/release/harness-cli install\n\n# Then add the printed path to your shell profile:\nexport PATH=\"$HOME/Library/Application Support/Harness/bin:$PATH\"\n```\n\nThe first-run setup in `Harness.app` performs the same local installation for new\nusers: it copies `harness-cli` and `HarnessDaemon`, registers the LaunchAgent,\nadds PATH blocks for zsh/bash/fish with backups, installs fish completions, asks\nfor notification permission, and offers detected agent hooks.\n\n## Remote \u0026 headless daemons\n\n`HarnessDaemon` can run on a headless box (no GUI) or a remote machine — including\nLinux — and you can drive it from any `harness-cli` command with a global\n`--host \u003cname\u003e` flag. The transport is an SSH tunnel that forwards the remote\ndaemon's control socket, so it reuses your existing SSH trust with no new\ncredentials.\n\n```bash\n# On the remote box: run the daemon and note its socket path (harness-cli doctor prints it).\n# On your machine: register the remote, then target it with --host on any command.\nharness-cli remote add --name devbox --ssh me@devbox --socket \"/home/me/.config/harness/harness.sock\"\nharness-cli remote list\nharness-cli ping --host devbox\nharness-cli new-session --host devbox --cwd ~/Code\nharness-cli send-keys --host devbox --surface \u003cid\u003e --keys \"ls -la Enter\"\nharness-cli capture-pane --host devbox --surface \u003cid\u003e\nharness-cli remote remove --name devbox\n```\n\nPass extra SSH options (port, identity file, jump host) with `--ssh-arg`, e.g.\n`--ssh-arg -p --ssh-arg 2222 --ssh-arg -i --ssh-arg ~/.ssh/devbox`.\n\n## Agent hooks\n\n`HARNESS_SURFACE` is set in every Harness pane, so an agent can ping the exact tab it's running in:\n\n```bash\nharness-cli install-hooks claude-code\nharness-cli notify --surface \"$HARNESS_SURFACE\" --body \"Approval required\"\n```\n\nPer-agent setup lives in [docs/agent-hooks/README.md](docs/agent-hooks/README.md). Agents without a hook mechanism still notify you through Harness's built-in activity detection once they're running.\n\n## Keyboard shortcuts\n\n| Action | Shortcut |\n|--------|----------|\n| New tab | `Cmd+T` |\n| New session | `Cmd+Shift+N` |\n| Close tab | `Cmd+W` |\n| Split horizontal / vertical | `Cmd+D` / `Cmd+Shift+D` |\n| Switch to tab 1–9 | `Cmd+1` … `Cmd+9` |\n| Previous / next tab | `Cmd+Shift+[` / `Cmd+Shift+]` |\n| Jump to waiting agent | `Cmd+Shift+U` |\n| Command palette | `Cmd+K` |\n| Settings | `Cmd+,` |\n| Toggle sidebar | `Cmd+\\` |\n\nThe command prefix (default `Ctrl-A`) adds the full pane / session keymap on top — press prefix then `?` for the cheatsheet.\n\n## Build from source\n\n```bash\ngit clone https://github.com/robzilla1738/harness-terminal.git harness\ncd harness\nmake release\nopen Harness.app\n```\n\nValidate a source checkout before shipping changes:\n\n```bash\nswift build\nswift test                              # fast, deterministic suite\nHARNESS_LIVE_DAEMON_TESTS=1 swift test  # adds the real socket / PTY / security tests\nmake bench\n```\n\nCI runs all three on every push: the deterministic suite, the live daemon tests, and a release build. The live tests spin up a real daemon over a Unix socket and a real PTY, so run them locally before changing the daemon, IPC, or PTY code.\n\n`make bench` runs opt-in release benchmarks and prints machine-readable JSON timing lines. Treat those as a structural baseline, not a pass/fail gate — GPU and timing numbers vary by machine.\n\nRenderer tests use structural offscreen readbacks by default. Set `HARNESS_WRITE_RENDER_SNAPSHOTS=1` when running `swift test --filter MetalRendererTests` to write PNGs under `/tmp/HarnessRenderSnapshots` for human debugging only.\n\n### Develop in Xcode\n\n`Harness.xcodeproj` is generated from `project.yml` with XcodeGen. The app target builds and bundles `HarnessDaemon` and `harness-cli` into `Harness.app/Contents/MacOS/`, so an Xcode run uses the same helper layout as the release app.\n\n```bash\nxcodegen generate\nopen Harness.xcodeproj\nxcodebuild -project Harness.xcodeproj -scheme Harness -configuration Debug \\\n  -destination 'platform=macOS,arch=arm64' build test\n```\n\n## Requirements\n\n- Apple silicon Mac running macOS 15.0 or later for the downloadable DMG\n- Xcode 16+ / Swift 6.0 (to build from source)\n- For a headless/remote daemon: any machine with Swift 6.0 (macOS or Linux) — build the daemon + CLI with `swift build -c release` (the GUI app, renderer, and Sparkle are macOS-only and are dropped from the Linux build)\n\n## Documentation\n\n- [Experience modes](docs/MODES.md) — Plain / Persistent / Full / Agent\n- [Sessions \u0026 panes guide](docs/MULTIPLEXER_GUIDE.md) — prefix, panes, sessions, copy mode, attach from anywhere\n- [tmux-style capabilities PDF](docs/HARNESS_TMUX_CAPABILITIES.pdf) — printable setup, shortcuts, commands, attach, copy mode, and troubleshooting\n- [Release runbook](docs/RELEASE.md) — signed/notarized DMG, GitHub Actions release workflow, and Sparkle appcast publishing\n- [Migration](docs/MIGRATION.md) — bringing your config and habits across\n- [Keybindings](docs/KEYBINDINGS.md) · [Commands](docs/COMMANDS.md) · [Shell integration](docs/shell-integration/README.md) · [Agent hooks](docs/agent-hooks/README.md)\n- [Changelog](CHANGELOG.md) — release history\n- [Third-party notices](docs/THIRD-PARTY-NOTICES.md)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobzilla1738%2Fharness-terminal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobzilla1738%2Fharness-terminal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobzilla1738%2Fharness-terminal/lists"}