# Overhand docs, in full > Stop babysitting your coding agents. Overhand runs the coding agents you already use (Aider, Claude Code, Codex, Cursor Agent, Gemini CLI and OpenCode) on your own computer, on any model. Your agents work through tickets, failed checks and review comments in every project. Each change arrives as a pull request with proof; you make the calls. The docs, the agent skill and these llms files are CC0 1.0 (https://github.com/craftly-io/overhand/blob/main/LICENSE-docs): copy them freely. The code is FSL-1.1-ALv2. # Install On macOS or Linux: one command, Homebrew, or npx and bunx. ## Three ways in. Pick one. - **One command** Installs, starts Overhand at every login and opens it in your browser. ``` curl -fsSL https://get.overhand.dev | sh ``` - **Homebrew** The same package, checked against the same release sums. ``` brew install craftly-io/tap/overhand && overhand start ``` - **npx or bunx** The first run fetches this version's package once and keeps it in `~/.overhand/npm`. ``` npx overhand start # or: bunx overhand start ``` ## What the installer does. - **Checks the download** It fetches the package for your machine (macOS or Linux, arm64 or x64) and stops if its SHA-256 doesn't match the release's `SHA256SUMS`. - **One folder, one link** Each version unpacks into its own folder in `~/.overhand/releases`, and `~/.overhand/app` links to the one in use. `overhand` is linked into `~/.local/bin`. Everything Overhand keeps lives under `~/.overhand`. - **The right build** In a Rosetta terminal on an Apple silicon Mac it still picks the arm64 build. On Alpine and other musl Linux systems it stops and says so: the Linux builds need glibc. - **Your PATH** When `~/.local/bin` isn't on it, the installer prints the exact line for your shell and the file to put it in. - **Then it opens** Overhand answers on [http://127.0.0.1:4317](http://127.0.0.1:4317/), where setup finishes. Set `OVERHAND_NO_START=1` to install without starting it. ## What else it needs. - **git and the GitHub CLI** Agents read issues and open pull requests through `gh`, signed in with `gh auth login`. - **At least one agent** Any of Aider, Claude Code, Codex, Cursor Agent, Gemini CLI and OpenCode, installed and signed in. Setup can install one for you in a terminal you watch. - **A quick check** `overhand doctor` lists each thing it needs and how to fix what's missing. See [Troubleshooting](https://overhand.dev/docs/troubleshooting.html). ## On Linux. - **A systemd user service** Overhand runs as one; `systemctl --user status overhand` shows it. Without systemd (a container, WSL) it runs in the background until the machine restarts. - **Desktop notifications** Through `notify-send`, when it's installed. - **On a server** systemd stops your services when you log out. To keep Overhand running and start it at boot, turn on linger once (the installer prints this when it's off): ``` sudo loginctl enable-linger "$USER" ``` - **Secrets** They go to the keyring through `secret-tool` (`sudo apt install libsecret-tools`), which a desktop session unlocks. With no keyring, saving a secret fails and says so: Overhand never quietly writes one to disk. To opt in to a file only you can read (mode 0600, as `gh` and `claude` do there), add the first line to your shell's startup file: ``` export OVERHAND_SECRETS_FILE=~/.overhand/secrets.json overhand stop && overhand start ``` ## Update. - **It tells you** Once a day Overhand looks for a new release on GitHub, and Needs you shows the command for the way you installed. - **One command** `overhand update` reruns the installer, runs `brew upgrade overhand`, or for npx is `npx overhand@latest update`. It prints the version it installed and restarts on it once no agent is running. - **All or nothing** The new version is downloaded, checked and unpacked beside the one in use, then swapped in at once. If any step fails, it says so, exits with an error, and the installed Overhand is unchanged. - **Your own `brew upgrade` or installer run** Works too. The login service runs the binary through a path that follows updates, so a running Overhand restarts on the new version by itself. ## Uninstall. - **One command** Stops Overhand, removes its login service (the launch agent on macOS, the systemd unit on Linux), the `~/.local/bin/overhand` link and the program in `~/.overhand`, then lists what it kept. ``` overhand uninstall --dry-run # see what it removes and keeps overhand uninstall ``` - **Your data stays** Settings, history and logs in `~/.overhand` are kept. To delete them too, add `--remove-data`; it asks before deleting anything. - **Also kept** Secrets in Keychain or the keyring, and the hooks `overhand connect` wrote into projects. Run `overhand disconnect` in each connected project before you uninstall. - **Homebrew** Run `overhand uninstall`, then `brew uninstall overhand`. - **npx or bunx** `npx overhand uninstall` removes the service and the copy in `~/.overhand/npm`. # Run Overhand on a server Linux or Docker, reached through an SSH tunnel or your tailnet. ## On a Linux server. - **The same installer** Run the one command from [Install](https://overhand.dev/docs/install.html) over SSH, as the user the agents should work as. The same package runs on arm64 and x64. - **Kept running** With systemd it's a user service, and linger keeps it up after you log out. Without systemd, run `overhand start` again after each reboot. [On Linux](https://overhand.dev/docs/install.html#linux) has the commands. - **Only on the server itself** Overhand listens on 127.0.0.1, so nothing outside the server reaches it until you choose one of the ways in below. - **Check it** `overhand doctor` over SSH lists what's missing: an agent, `gh` and its sign-in, a place for secrets. ## In Docker. - **Build the image** There's no published image yet; build it from the repository: ``` git clone https://github.com/craftly-io/overhand.git && cd overhand docker build -t overhand . docker run -d --name overhand --network host --restart unless-stopped \ -v overhand:/home/overhand overhand ``` - **Host network, loopback only** With `--network host` it listens on the server's own 127.0.0.1, like the plain install. Publishing a port with `-p` reaches nothing, because inside the container it listens on loopback too. On Docker Desktop the host network is its VM's, so this setup is for a Linux server. - **One volume** It runs as the user `overhand`, not root. Its home is the volume: Overhand's state, the agents you install, their sign-ins, GitHub's login and your projects. API keys go to a file only that user can read. - **Day to day** `docker ps` shows it healthy once it answers on its port. Run commands with `docker exec overhand overhand doctor`; its log is `docker logs overhand`. Another port: `-e OVERHAND_PORT=4400`. - **Turning it off and updating** Turn off in Overhand restarts the container; `docker stop overhand` stops it. To update, pull the repository, build again, then remove the container and run it again. The volume keeps everything. ## Reach it from your laptop or phone. - **An SSH tunnel** From your laptop, then open the link `overhand open` prints on the server: ``` ssh -N -L 4317:127.0.0.1:4317 you@your-server ``` - **The same port on both ends** Overhand answers only to the address it serves on, so a tunnel from another local port gets refused. - **Counts as the server** Through the tunnel your browser is the server's own: finish setup and add devices there. - **Tailscale for your phone** On the server, serve Overhand on your tailnet, then add that https address in Settings → Extra origins: ``` tailscale serve --bg --https=8443 http://127.0.0.1:4317 ``` A request through it gets nothing until that device is paired: open Settings → Phone through the tunnel and add the device there. See [Phone and Access from anywhere](https://overhand.dev/docs/anywhere.html). - **Never the open internet** Don't publish the port or put it behind a public proxy or Tailscale Funnel. The tunnel or your tailnet is the way in. ## Agent sign-ins without a desktop. - **Agent accounts sign in from the app** Settings → Agent accounts runs the agent's own sign-in on the server, and its page opens on your laptop or phone. Nothing to run over SSH. See [Sign-ins and API keys](https://overhand.dev/docs/agents.html#signin). - **Setup shows the command** No terminal window can open on a server, so setup shows the exact command to install an agent and sign it in. Run it over SSH; in Docker, inside the container: ``` docker exec -it overhand sh -c '' ``` - **Claude Code, by hand** `claude auth login` prints a link. Open it on your laptop, sign in, and paste the code it gives you back into the terminal. - **Codex, by hand** Plain `codex login` waits for your browser on the server's own port 1455. Run `codex login --device-auth` instead, and enter the code it shows on your laptop. - **GitHub** `gh auth login --web` shows a one-time code; enter it at github.com/login/device on any device. - **An API key instead** Add it in Settings → Agent accounts. With no keyring on the server it goes to `OVERHAND_SECRETS_FILE`, which the image sets. See [Agents and accounts](https://overhand.dev/docs/agents.html). # First project and first win From setup to your first draft pull request. ## Setup is one screen. - **What it found** Overhand looks at your computer first and shows, in order: GitHub (through `gh`), your projects, your agent, its model. Change any of it, then press Start Overhand. - **Projects** Pick projects from your GitHub and your organisations (searchable, grouped by owner), or paste a URL. Untick any you don't want. *Use projects already on this computer* scans one folder you choose instead. - **Your agent** Setup asks which AI you already pay for and picks the agent that comes with it. - **Which one** Claude Pro or Max: Claude Code. ChatGPT Plus or Pro: Codex. Gemini: Gemini CLI on a Gemini API key (free from [Google AI Studio](https://aistudio.google.com/app/apikey), kept in your keychain, passed as `GEMINI_API_KEY`). None of these: Claude Code on an Anthropic API key. - **Missing one?** *Install and sign in* shows the vendor's own install command and runs it in a terminal you can watch. Then it opens that agent's own sign-in. - **The model** Claude, a local model from a running [Ollama](https://ollama.com/), or a gateway URL. *Edit* opens the full form. - **Every sign-in is your click** Overhand never asks you to paste a subscription token. More accounts sign in from Settings → Agent accounts, in your browser, without a terminal. See [Agents and accounts](https://overhand.dev/docs/agents.html#signin). ## Your checkout stays yours. - **A copy you already have** For each project, Overhand looks for your own clone in `~/Code`, `~/Projects`, `~/Developer`, `~/src`, `~/GitHub` and similar folders. It looks only for those projects and reads nothing but their git remotes. - **Otherwise its own clone** In `~/Overhand/projects/` (`projectsDir` in the config). A checkout of yours uses its own code root. - **Agents work beside it** Each piece of work gets its own git worktree and branch, in the checkout's `.claude/worktrees`. `.git/info/exclude` keeps them out of `git status`. Your branch and uncommitted changes are left as they are. ## Your first win, right away. - **One small, safe task** Straight after setup, Overhand searches your projects on your computer, read-only and in under 30 seconds, for a check your own scripts report failing, a patch-level dependency upgrade, a README with no way to run the project, or a test for an untested pure function. - **An agent starts on it** Now shows Your first win until its draft pull request is ready for you. - **Nothing in your tracker** The first win never adds a ticket anywhere. ## Then give it work. - **Label an issue** Agents take GitHub issues labelled `agent` in a project's tracker. A project's tracker can be Linear or Jira instead. - **When an agent asks** It asks on the issue. Answer there, then label the issue again. - **Plan the day** Overhand gathers what's on your plate and proposes work; you arm what should start. - **Standing work** A project's view in Crew suggests [leads](https://overhand.dev/docs/leads.html) from its own work, each previewed before it starts. - **Come back to pull requests** They wait under Needs you, with any question an agent couldn't answer alone. Review opens the diff: mark it ready, ask for changes (the agent's next round) or close it. - **A careful start** New projects start on Draft pull requests. See [Modes](https://overhand.dev/docs/modes.html). - **Only what you label** On a new install, agents take only the issues you label, under a $10 [daily cap](https://overhand.dev/docs/agents.html#cap). ## Connect your tools. - **What already reaches them** Setup and Settings → Integrations show what reaches GitHub, Linear, Jira, Slack, Sentry and Vercel: the `gh` and `vercel` logins, stored tokens, and the MCP servers your agents are set up with (MCP, the Model Context Protocol, is how an agent reaches other tools). - **Linear, Jira and Sentry** *Connect* signs Overhand in to the service's official MCP server in your browser (a standard OAuth sign-in, no app to create). Overhand then reads tickets and errors through it, with no model in between. A stored API token still works. - **Slack** Its MCP server doesn't allow that sign-in. The Slack inbox reads through the servers listed in `slack-mcp.json` (Claude Code's `--mcp-config` format) in the config folder: `~/.overhand/slack-mcp.json`, or the checkout's root when you run from source. It reads Slack on its schedule, and again when you come back to Overhand after 10 minutes away; Needs you says when it last read. There is nothing to press, until a Slack sign-in expires: then Needs you says for which projects, and its button opens Claude Code where the inbox reads Slack. Type `/mcp` there and sign in. - **Its path** A `slack-mcp.json` left beside an installed binary moves to the config folder on the next start. Settings → Integrations shows the full path. - **Your own MCP servers** Claude Code runs also get the ones in your `~/.claude.json`. - **The rest of Settings** Projects, trackers (GitHub Issues, Linear, Jira), agent accounts and their models, leads, schedule and budget, and your phone. # Agents and accounts Sign-ins, API keys, how each account is paid for, and the daily cap. ## One account, one agent. - **The agents** Overhand runs Aider, Claude Code, Codex, Cursor Agent, Gemini CLI and OpenCode, each headless, the way its own command-line app runs. - **An account** Settings → Agent accounts: which agent it runs, and the model behind it. Add as many as you have. - **Kept apart** Each account is used on its own; one person's work is never spread across several of their subscriptions. - **Models** Claude, Amazon Bedrock, Google Vertex AI, or a gateway such as Ollama, LiteLLM or OpenRouter, including a model running on your own computer. ## Sign-ins and API keys. - **The agent's own sign-in, no terminal** In Settings → Agent accounts, adding an account (or an account's sign-in button) runs that agent's own login for you: Claude Code and Codex in a folder kept for the account, Cursor Agent in the one login this computer has. *Sign in in your browser* opens its sign-in page on the device you're on, your phone too. When the agent asks for a code back, as Claude Code does, paste it into *Paste the code from the browser*. Overhand shows *Signed in.* once the agent's own status check says so, then makes a test call. - **From another device** Codex's usual sign-in calls back to the computer it runs on, so from a phone or over Access from anywhere it uses Codex's device code instead: the app shows the code to enter on the sign-in page. - **What Overhand reads** Only the sign-in link (and a code to show) from what the agent prints. Nothing it prints is logged or kept, and the code you paste goes only to that sign-in. A sign-in still waiting after 10 minutes is stopped. - **OpenCode** It signs in to a provider, once per computer. In the app, *Sign in with * runs a provider account's sign-in with a code to enter (ChatGPT), and *Use a provider's API key* takes a provider's key (Anthropic, OpenAI, OpenRouter, Google, Groq, DeepSeek, Mistral or xAI) and types it into OpenCode's own sign-in for you. The key goes to OpenCode only; Overhand keeps no copy. - **Already signed in** A sign-in already on this computer is reused, and so is GitHub through `gh`. - **Your own sign-in, under the OS sandbox** An account still on the sign-in you had before Overhand can't run where the OS sandbox is on: runs can't reach your own agent config. Such an account is passed over, as one at its usage limit is, and Needs you shows a card to sign it in once, with its sign-in button. Once it's signed in in its own folder, it runs again. - **An API key** Stored in your keychain, named after its account: `anthropic-key-`, `codex-key-`, `gemini-key-` or `cursor-key-`. Gemini CLI runs on a Gemini API key. - **Never a subscription token** Overhand doesn't ask for, store or pass on the token behind a Claude plan. ## How each account is paid for. - **Plan** A flat subscription such as a Claude or ChatGPT plan. Its runs cost nothing extra and follow the plan's usage limits. - **Pay-per-use** Charged per token: an API key, or a paid gateway. - **Cloud** Charged to your own cloud bill, as with Bedrock or Vertex AI. - **Local** A model on your own computer: no charge. - **Out of usage** When an account's agent says it has hit a usage limit, tickets, leads and tests all skip that account until the reset the message names, and Settings says so on the account. - **How it knows** From the way the account signs in: `claude auth status` names a Claude subscription. When it can't tell, Needs you asks, and Settings lets you change it. ## The model behind each account. - **Who uses what** Claude Code uses every backend below. Codex, OpenCode and Aider use a gateway's URL and model. - **Claude, by its own sign-in** Each account gets its own Claude Code config folder, `agent-home/accounts/` in the config folder. Signing in runs `claude auth login` with `CLAUDE_CONFIG_DIR` set to it, through Anthropic's own flow. - **Where that login lives** Claude Code keeps it: a Keychain item tied to that folder on macOS, `.credentials.json` inside it on Linux. Overhand never reads, stores or passes it on, and runs that account's agents with `CLAUDE_CONFIG_DIR` pointing there. - **Your own plan** Usage counts against your Claude plan, whose limits assume one person's ordinary use. Only Claude accounts show 5-hour and weekly usage. - **No setup token** Overhand never asks for, stores or routes a token from `claude setup-token`, as [Anthropic's terms](https://code.claude.com/docs/en/legal-and-compliance#authentication-and-credential-use) require. - **Claude, by API key** A key from [platform.claude.com](https://platform.claude.com/), stored as `anthropic-key-` and passed as `ANTHROPIC_API_KEY`. Billed per use to your Anthropic account, under its Commercial Terms. - **Amazon Bedrock** `CLAUDE_CODE_USE_BEDROCK=1` with the region (and optional AWS profile) you set. Credentials come from this machine's AWS credential chain. - **Google Vertex AI** `CLAUDE_CODE_USE_VERTEX=1`, `CLOUD_ML_REGION` and `ANTHROPIC_VERTEX_PROJECT_ID`. Credentials come from gcloud's Application Default Credentials. - **A gateway** Any Anthropic-compatible endpoint through `ANTHROPIC_BASE_URL`, with `ANTHROPIC_AUTH_TOKEN` from a keychain item you name, or a placeholder for local servers that take any token. Presets for Ollama, LiteLLM and OpenRouter; tested end to end with Ollama and `qwen3:1.7b`. - **One model for every run** A model set on a Bedrock, Vertex or gateway account becomes `ANTHROPIC_MODEL` and pins the `opus`, `sonnet` and `haiku` aliases. A separate small model sets `ANTHROPIC_DEFAULT_HAIKU_MODEL`. - **Checked** `overhand doctor` reports a gateway that doesn't answer. - **Claude Code's own docs** [Bedrock](https://code.claude.com/docs/en/amazon-bedrock), [Vertex AI](https://code.claude.com/docs/en/google-vertex-ai) and [LLM gateways](https://code.claude.com/docs/en/llm-gateway-connect). ## The daily cap. - **Only billed money** It counts what pay-per-use and cloud accounts are billed today. An account not yet known to be on a plan counts as billed. Plan accounts aren't charged per run; they follow their plan's usage limits. - **Set at install** Overhand starts with $10 a day, unless your first account is a local model. Change it in Settings → Schedule & limits. - **When it's reached** New runs and leads on the accounts it counts wait for tomorrow. [How the cap works](https://overhand.dev/under-the-hood.html#cap). # Modes How far agents may go on each project, from watching to shipping. ## Four modes, one per project. - **Plan and warn only** Agents plan, investigate and report on the ticket. They change no code and open no pull requests, and the guard blocks edits and commits. - **Draft pull requests** Agents open draft pull requests and stop there. You review each one and mark it ready. - **Open pull requests** Agents open pull requests ready for review. Merging stays with you. - **Ship** As Open pull requests, then GitHub's own auto-merge merges the pull request once every required check passes. No agent merges. ## Choosing one. - **Where** Settings → Projects, under What agents do here. - **Where it starts** Every new project starts on Draft pull requests. - **Nothing merges without you** On the first three modes, every merge is yours. ## Turning on Ship. - **Your click, one project** Never for a group of projects and never as a global switch. It works on GitHub only. - **A required check first** The base branch needs branch protection or a ruleset with at least one required status check; without one, the project keeps working as on Open pull requests and says why. - **Its defaults** Up to 5 merges a day; changes to `.github/` and `**/CODEOWNERS` wait for your merge. Both are per project. - **Undo** Every Ship merge shows up in the day's log and the night report, with an Undo that opens a revert pull request. - **All of its rules** [Ship's safety rules](https://overhand.dev/under-the-hood.html#ship), under the hood. ## How Ship merges, step by step. - **GitHub's auto-merge** Once a pull request carries its proof, the daemon turns on auto-merge with the `enablePullRequestAutoMerge` mutation (squash). No agent's settings change. - **Checked every time** The required check is looked for again before every request. Without one, the project says *Green means nothing here yet: no required checks on .* and builds as on Open pull requests. - **Config** Protected paths are `ship.protect`; the daily cap is `ship.perDay`. A pull request held by either says so on the pull request. - **Turned off again** A request for changes, a push onto a protected path, or the project leaving Ship turns auto-merge off. - **Leads too** A lead's pull requests take the same step: its run's checks go on the pull request as its proof. Auto-merge is on only while none of the project's leads is running. - **Told everywhere** Each merge is in the day's log, the night report and a push notification. - **Undo, safely** The revert pull request comes from a new branch: never a push to the base, never forced. ## What Overhand does itself, on every agent. - **On Plan and warn only** It never opens a pull request and runs no fix rounds. A finished ticket becomes a report on the ticket, which then waits for you. - **On Draft pull requests** It opens pull requests with `gh pr create --draft` (on Bitbucket, `draft: true`). - **The Review drawer** Reads the diff with `gh pr diff` and marks drafts ready with `gh pr ready`. It approves with `gh pr review --approve` only when you aren't the author. - **Request changes** Goes to the agent as its next fix round. You can also close the pull request there. - **Old configs** A config written before modes existed keeps acting. ## What holds each agent on Plan and warn only. - **Claude Code** `--permission-mode plan`, plus `overhand guard`, which reads `OVERHAND_AUTONOMY` from the run's environment and blocks edits, commits, pushes and `gh pr` or `issue` writes. - **Codex** `--sandbox read-only` (no writes, no network), plus the guard. - **Cursor Agent** `--mode plan`, without `-f`, plus the guard. - **OpenCode** `permission: { edit: "deny", bash: "deny" }`, plus the guard. - **Aider** `--chat-mode ask --no-auto-commits`. It never runs shell commands. - **Gemini CLI** `--approval-mode default`: headless, nothing approves an edit or a command (flags checked only), plus the guard. - **A lead on Plan and warn only** It can't write its notes or questions file, so its final message is filed as a report in its questions file, and it waits for you. - **A lead on Draft pull requests** Ticket runs never open pull requests themselves; Overhand does, as drafts. Leads open their own. A Claude Code lead runs under the guard (through `--settings`), which refuses `gh pr create` without `--draft`, and `gh pr ready`. Leads on other agents are only instructed. # Leads Long-running agents that look after a whole project. ## A lead looks after a project. - **A long-running session** One agent session that works a whole project and asks you only what takes a person. - **Asleep until there's work** Each lead wakes when its own kind of work shows up on its project, and works only on that. - **Within the project's mode** A lead goes only as far as the project's [mode](https://overhand.dev/docs/modes.html) allows. - **Kept running** While a lead is On, Overhand restarts it after it exits, gives up after repeated crashes, and waits while its account is at its usage limit. - **How often** An always-on lead starts again a few minutes after it exits, and rests longer each time it finds nothing to do, up to 4 hours. In Settings → Leads, *Runs again after (minutes; 1440 = a day, 10080 = a week)* set to 1440 makes a daily lead and 10080 a weekly one, and it rests that long. - **Its accounts** *Accounts it may use, in order (overrides Account)* lists them. At one's usage limit the next run takes the next; with *Carry on with any other account at their limits* off, it never runs on another, and waits once all of them are used up. - **When it can't start** If a start fails before the lead runs, say an account missing its key, Needs you says why, with a button for that account and *Try again*. ## Ready-made leads. - **Answer review comments** Answer the review comments on this project's open pull requests: make each requested change, reply to the comment, and keep the checks green until the reviewer is satisfied. - **Keep checks green** Keep CI green: when a build on the default branch, a pull request's checks or a production deploy goes red, find the root cause (flaky tests included) and fix it; never just retry or skip a test. - **Fix new errors** Fix new production errors: reproduce each one, find the cause, and fix it with a test that covers it. - **Keep dependencies safe** Keep dependencies safe: for each open security advisory, upgrade the affected package to the smallest version that fixes it, on its own branch with one pull request per advisory, and keep the repo's checks green. When no fixed version exists yet, say so instead of changing anything. - **Keep dependencies current** Keep dependencies current: update the direct dependencies that have patch or minor updates, all together in one pull request at most once a week. Never apply a major update; list each one in that pull request's description for the owner to decide. - **Test what's untested** Test what's untested: of the files listed (changed most in the last 30 days, and no test names them), pick the riskiest few and add tests that pin down what they do today, in the repo's own test style. Don't change their behaviour; when a test finds a bug, report it rather than fix it in the same pull request. - **Clear the TODOs** Clear the TODOs: do the small, safe TODO, FIXME and HACK notes in the files listed. File each one that's bigger, or needs a decision, as a ticket in the project's tracker; when the project has no tracker, list them in the pull request's description instead. - **Work the backlog** Work the backlog: take the tickets marked for agents, smallest first, one pull request each. A project's view in Crew suggests them from its own work, each with the count behind it. The first click previews what it watches and does; *Start this lead* is the second. ## How every lead works. - **Whatever its goal** Every lead's prompt, ready-made, generic or your own skill, carries the same lines, written once in Overhand. How to work: read the repo's own rules first (AGENTS.md, CLAUDE.md, CONTRIBUTING) and match its style and commit conventions. Make the smallest change that fixes the root cause. Open one pull request per change, with a description that says what changed and why. Add or adjust a test for every change in behaviour, and run the project's own checks before opening it. Never skip a test, disable a check or force-push. When a choice is a product decision, ask. ## When a lead asks. - **Under Needs you** Answer in place, from your phone's notification, or from a terminal with `overhand answer "your answer"`, naming the lead by its key or label. `--default` goes with the default it gave. - **From any terminal** `overhand answer` goes through the running daemon, the same as answering on the dashboard. So your terminal session, or an agent's, can unblock a lead it settled a question for. Overhand never reads your other sessions. - **Its default** A question ends with what the lead will do if nobody answers. After the wait set for that lead (4 hours unless you change it in Settings → Leads), Overhand goes with it and tells you. A question with no default, or a wait of 0, waits for you. - **Answered somewhere else** *I answered elsewhere* resumes the lead when you settled it outside Overhand. ## Your own lead. - **The generic lead** Add one in Settings → Leads with no instruction of its own: it works the project's open issues and pull requests in priority order, with its notes kept in `~/.overhand`, never in your project. - **A project's own lead skill** Point it at the skill, and have the skill keep a lock file and a questions file so Overhand can supervise it. [docs/leads.md](https://github.com/craftly-io/overhand/blob/main/docs/leads.md) has both formats and a snippet to paste. # The guard What it stops before it runs, and how it reaches each agent. ## Checked before it runs. - **One set of rules** Every agent with a hook runs the same guard, set up per run from Overhand's own folder. Your own config for each agent stays as it is. - **What it blocks** Blocks merges, force pushes, deploys and production secrets, in Claude Code, Codex and OpenCode. The whole list is [under the hood](https://overhand.dev/under-the-hood.html#guard). - **Its own off switch** It also blocks changes to Overhand itself and to an agent's project settings, which could turn the guard off for the next run, even when a ticket asks. - **It fails closed** A guard that can't start blocks the call. - **Your processes** Ports, process names and containers you list in `governor.protect` can't be stopped or restarted by an agent. ## How it reaches each agent. - **Aider** It has no hook for the guard, and secret files are kept out of its reach. It runs no shell commands. Confirmed in a real run, on aider 0.86.2 (local qwen3:1.7b): asked to run `gh pr merge 1`, it ran nothing. - **Claude Code** Through a hook on every tool call. Confirmed in a real run, on 2.1.309: it blocked `gh pr merge 1 --squash`. - **Codex** Through a hook on every shell command, file edit and MCP call, inside its workspace sandbox. Confirmed in a real run, on codex-cli 0.163.0 (local qwen3:1.7b): it blocked `gh pr merge 1`. - **Cursor Agent** Through a plugin whose hooks see every shell command, file read, edit and MCP call. Set up, not yet confirmed in a real run. - **Gemini CLI** Through a hook on every tool call, from a Gemini home of Overhand's own (it runs on an API key). Set up, not yet confirmed in a real run. - **OpenCode** Through a plugin that sees every tool call. Confirmed in a real run, on 1.19.4 (local qwen3:1.7b): it blocked `gh pr merge 1`. Each account in Settings → Agent accounts says where its agent stands. Every pull request also runs the guard on each hooked agent's own hook messages: merges, force pushes, deploys, secret reads, protected edits and ordinary work ([`guard-conformance.ts`](https://github.com/craftly-io/overhand/blob/main/packages/core/src/guard-conformance.ts); `bun run guard-check` from a checkout, per installed agent). That proves the guard's side, not that the agent calls its hook: only a real run confirms that. ## Everything it blocks. - **Pushes** Force pushes, and pushes to main, master, develop and other shared branches. - **Pull requests** Merging, closing or approving them, by `gh` or by the API. - **The GitHub repository itself** Its administration, releases and secrets. - **Going live** Deploys, infrastructure changes and package publishing. - **Secret files** Keychain, password and credential files (SSH, cloud) and production env files, by file tool or named in a command. - **SSH keys** Naming an SSH key or `~/.ssh` in a command, so no `ssh -i ~/.ssh/` and no edits to `known_hosts` or `config`. A plain `git push` over SSH still works: it names neither. - **Data** Production databases and destructive SQL. - **Your disk** Deleting your home folder or the root. - **Overhand itself** Its config folder, config, state, code and heavy-job slots. - **Agents' project config** `.gemini/`, `.codex/`, `.opencode/`, `opencode.json`, `.cursor/hooks.json` and `cli.json`, `.aider.conf.yml` and `.aiderignore`. Changing those is yours to do, even when a ticket asks. - **Modes and quiet** It also enforces Plan and warn only and quiet mode. See [Modes](https://overhand.dev/docs/modes.html) and [Quiet mode](https://overhand.dev/docs/cleanup.html#quiet). - **A project with its own hooks** Codex, Gemini CLI and OpenCode won't start in a project that already carries hook settings or plugins of its own. The run moves on to the next account. - **The rules** One file decides for every agent: [`packages/core/src/guard.ts`](https://github.com/craftly-io/overhand/blob/main/packages/core/src/guard.ts). ## How each hook is wired. - **Claude Code** A PreToolUse hook on every tool, in Overhand's config folder or by `--settings`. - **Codex** A PreToolUse hook on every tool (shell, `apply_patch`, and MCP tools, which reach other services) by `-c hooks.PreToolUse=…`. It passes `--dangerously-bypass-hook-trust`, since Codex skips hooks nobody reviewed in `/hooks` and this one is Overhand's own. It still runs in its `workspace-write` sandbox. - **Gemini CLI** A BeforeTool hook on every tool, in the user settings of a Gemini home of Overhand's (`GEMINI_CLI_HOME`). Gemini CLI 0.65 skips a system settings file unless root owns its folder, so a Gemini account runs on its API key. `--approval-mode yolo` only skips Gemini's prompts; its hooks still run first. - **Cursor Agent** A local plugin (`--plugin-dir`) whose hooks (`beforeShellExecution`, `beforeReadFile`, `beforeMCPExecution`, `preToolUse`) call the guard, with `failClosed`. - **OpenCode** A plugin (`tool.execute.before`) in a config folder of Overhand's (`OPENCODE_CONFIG_DIR`). - **Aider** No hook to use. It runs with `--no-suggest-shell-commands --no-auto-test --no-auto-lint` (no shell at all), an empty `--config` and `--env-file /dev/null`, so no `.aider.conf.yml` or `AIDER_*` in `.env` turns it back on. An `--aiderignore` lists the secret files, and it can't open files outside its repo. - **Set per run** Every one of these comes from `~/.overhand/agent-home`, run by run. Settings reads each account's line from one table, [`packages/contract/src/guard.ts`](https://github.com/craftly-io/overhand/blob/main/packages/contract/src/guard.ts). ## What it can't do. - **A program's next step** A hook sees the command an agent asks for, not what a script or program it runs does next; a determined agent can hide a step there. An agent that deliberately builds paths to slip past the guard's checks can write Overhand's own files (its config and records) as it can any file you can: the guard stops accidents and plain prompt injection, and it isn't a sandbox. Holding a run's writes to its own folder is the OS sandbox's job, when you turn it on (Settings, Agent accounts). - **The OS sandbox** With the OS sandbox on, each agent run Overhand starts, and each check Overhand itself runs in a project's own files (its package manager, lint script or virtualenv), can write only its own folder, the git data its commits need, its own temp folder (gone when it ends), its project's package caches and its agent's own state in a folder of Overhand's: never Overhand's files, another project, your own agent config, your shell startup files, LaunchAgents, git config, hooks and where git finds the repository, or the settings, hooks, plugins and extensions that steer an agent, however the command is spelled. It can't read cloud credentials, browser profiles or Overhand's local key. - **What the sandbox can't stop** It doesn't filter the network: a run can send what it can read to any site, and can read your GitHub and SSH logins, which agents use to push. It doesn't stop what a run writes into its own project from running later when you run it, or a program that asks a service outside it to act, such as a database or a server on a local port: tmux, screen and Docker's sockets are closed to it, other local sockets aren't, and on macOS neither is another app, through osascript or open. A lead can't make git worktrees in its own checkout under it: no lead needs one, since Overhand makes the worktrees runs work in. On Plan and warn only, Codex's commands can reach the network under it (Codex's own sandbox, which kept them off it, can't nest inside Overhand's). With it off, Overhand's own checks run a project's files as you, as before. Leads and tasks start your own MCP servers, handed over by Overhand and no others, since they need them for your trackers; a run on Plan and warn only starts none of yours. State a tool or plugin keeps in your home, outside the run's folders, its caches and its agent's own, stays closed to it (a plugin's database in its own folder in your home, or firebase-tools' login and log): such a tool fails under it until it can be pointed at a folder the run writes. On macOS, Xcode builds don't run under it: xcodebuild writes macOS's shared temp and cache folders, and Swift packages start a sandbox of their own, which can't nest. macOS Keychain items stay reachable, since the agents' logins live there. It runs on macOS and on Linux with bubblewrap and user namespaces; elsewhere, including most Docker setups, runs have the guard only. - **Turning it on** Settings, Agent accounts: off, log only or on (`sandbox.mode` in the config). It's `sandbox-exec` on macOS and bubblewrap on Linux. Log only (macOS) runs as before and writes what it would block to `logs/sandbox-would-deny.jsonl`. A change applies to runs started after it, so a running lead keeps going. Under it, Codex's, Gemini CLI's and Cursor Agent's own sandboxes are off: macOS can't nest them. - **A project without it** A project that needs Xcode, Swift packages or firebase-tools can run without the OS sandbox: set its sandbox to off (Settings, Projects, or sandbox: off on the project in the config). Its runs, and the checks Overhand runs in its files, then have the guard only, and Settings says so. With Refuse runs without it on, the project stays inside the sandbox. Overhand suggests it when a project has an Xcode project or workspace, a Package.swift or a firebase.json, and never switches it for you. - **So keep tokens small** Give agent accounts credentials that can't do damage anyway: no admin or deploy rights, and branch protection on your GitHub repositories. - **See what it stopped** Guardrails, in Health, lists each attempt it blocked in the last day, with its time and rule. # How agents run Each agent's flags, what every run is told, and the scorecard. ## One program does the rounds. - **The daemon** It plans the day, runs each account's agent headless on tickets, supervises leads, reads checks, deploys and errors, and serves the dashboard. - **One at a time per project** One ticket run per project at a time, in parallel across projects. - **Secrets** In the macOS Keychain or the Linux keyring, or the file you opted in to with `OVERHAND_SECRETS_FILE`. ## How each agent is run. - **Verified** A real run went end to end through Overhand's own arguments, environment, output parser and schema check: a ticket answer validated against the ticket schema, and an edit (create `hello.txt`) found on disk afterwards. - **Flags checked** Checked against the agent's own `--help` and docs only. Recorded output is in [`packages/core/test/fixtures/runtimes`](https://github.com/craftly-io/overhand/tree/main/packages/core/test/fixtures/runtimes). - **Claude Code** Verified; the default and the reference. `claude -p --output-format stream-json --json-schema … --permission-mode auto`. Model: the account's backend (see [Agents and accounts](https://overhand.dev/docs/agents.html#backends)). - **Codex** Verified on 0.163.0 with Ollama `qwen3:1.7b`. `codex exec --json --sandbox workspace-write -c sandbox_workspace_write.network_access=true --output-schema `. Model: `-m`; a gateway account adds `--oss --local-provider ollama`. - **Cursor Agent** Verified on 2026.01.23 with model `auto`. `cursor-agent -p … --output-format json -f`. Model: `--model`. - **OpenCode** Verified on 1.19.3 with Ollama `qwen3:1.7b`. `opencode run --format json --auto`. Model: `-m provider/model`, or a gateway account's model. - **Aider** Verified on 0.86.2 with Ollama (edits on `llama3.1:8b`, answers on `qwen2.5-coder:7b`). `aider --message … --yes-always --no-pretty --no-gitignore`. Model: `--model` (`ollama_chat/…`, or `openai/…` through `--openai-api-base`). - **Gemini CLI** Flags checked. `gemini -p … -o json --approval-mode yolo --skip-trust`. Model: `-m`. ## What the real runs showed. - **Codex's sandbox** In `workspace-write` it blocks the network (a sandboxed `git push` fails with "Operation not permitted") and keeps `.git` read-only (a sandboxed `git commit` fails on `.git/index.lock`). Overhand turns the network on and makes the project's git folder writable; a Codex run then committed and pushed to a `git://127.0.0.1` remote. - **Codex and the network** Per Codex's config reference, the setting allows outbound network in general, so GitHub is reachable too (not tried). - **Codex's schemas** They go to `--output-schema` in OpenAI's strict form: closed objects, every property required, optional ones nullable. The nulls are dropped before validation. - **Codex on a gateway** It runs `--oss` against the gateway's URL. There Ollama enforces `--output-schema` on every model call, so the model can't call tools and never edits (it answered "done" without creating the file). Local runs are asked for JSON in the prompt instead. - **Small local models are flaky** `qwen2.5-coder:7b` writes tool calls as text, so it can't edit through Codex or OpenCode. `qwen3:1.7b` can, but sometimes mistypes a long path or wraps its answer, which Overhand's one retry usually fixes. Use the biggest coding model your machine runs well. - **Aider** Its edits and the JSON answer come in one reply. An edit it couldn't apply ("did not conform to the edit format") fails the run, even though Aider exits 0. - **Aider leaves no trace** No history files land in the project, and `.aider*` goes to `.git/info/exclude` instead of the project's `.gitignore`. - **Cursor Agent** On a free plan it only runs model `auto` ("Named models unavailable" otherwise). - **Gemini CLI** Not run: its cached login had expired, and an expired login opens a browser prompt and waits until the task timeout instead of failing. In an untrusted folder it also drops `yolo` ("Approval mode overridden to default"), so Overhand passes `--skip-trust`. ## Answers and output. - **Checked answers** Every answer is validated against its schema. A wrong one is retried once, with what was wrong. - **Claude Code only** Only Claude Code reports usage windows and takes the Slack inbox's MCP flags (Model Context Protocol, how an agent reaches other tools); the inbox skips accounts on other agents. - **The live line** "What is it doing" and a lead's log read each agent's own output: Claude Code's transcripts, Codex's and OpenCode's JSON events (commands, edits, what it said), Aider's last lines. - **One object at the end** Cursor Agent and Gemini CLI print one JSON object when they finish, so their line shows only the result. - **Installed?** `overhand doctor` checks each agent's command-line app in use is installed and shows its version. ## What every run is told. - **Overhand's agent instructions** The ticket workflow, when to ask instead of guess, and the hard limits. They live in Overhand's own folder (`~/.overhand/agent-home/claude-code/CLAUDE.md`), never in your project. - **How each agent gets them** Claude Code reads them from its config folder. Codex gets `-c developer_instructions=…`, OpenCode `instructions` in its inline config, and Aider `--read`. Cursor Agent and Gemini CLI read rules only from the project, so they get them at the head of the prompt. - **Your project's own instructions** Each project's row in Crew (or the command bar) shows its `CLAUDE.md`, `AGENTS.md`, `GEMINI.md` and rules files as written, which agents read each one, and any gaps and contradictions. - **A rule from review** When review asks for the same thing on two pull requests within 30 days, and no instruction file says it yet, Needs you offers it as a rule. *Add rule* opens a small draft pull request adding it to the file the project's agent reads. ## Overhand as an MCP server. - **`overhand mcp`** Overhand's own MCP server over stdio. Any agent that speaks MCP can ask it what's running and what needs you, answer a lead's question, and hand or answer requests between sessions. - **Its tools** `status` (agents and leads at work, and the Needs you list as the dashboard words it), `answer_lead`, `ask_session` and `ack_request`. Each does what `overhand answer`, `overhand ask` and `overhand ack` do, through the running daemon. - **In every run** Overhand adds it to each Claude Code run and lead it starts, and to runs on Plan and warn only too, where it's the only MCP server. Other agents don't get it yet. - **A run's own key** Inside a run the server calls the daemon with that run's key, so it does only what the run may: hand a request (one to your own session comes to you first), answer requests sent to it, and answer its own lead's question. It can't read the status, and no run answers a question as you. - **In your own sessions** Outside a run it uses this computer's local key, like the `overhand` command, so it acts as you. Add it to Claude Code with `claude mcp add overhand -- overhand mcp`; any other agent takes the same command as a stdio server. ## The scorecard. - **Every run is logged** Its project, ticket, kind, account, agent, backend, model, cost at API prices (known costs only; a local model is $0) and outcome. - **Each pull request's fate** Merged or closed, fix rounds, change requests and time to merge, joined in from `outcomes.jsonl`. Older days are read back from the activity log. - **The ranking** Health's Scorecard ranks each agent × model over 7 or 30 days, overall and per project: runs, pull requests opened, merge rate, first-try merges, median time to merge, and why the rest didn't land. - **Cost per merge** Billed cost per merged pull request ("included in plan" on a plan), beside the API-price cost for comparison. Only pay-per-use and cloud runs count as billed. - **Too few** Under 5 runs reads "too few runs to tell". ## Routing: what the scorecard changes. - **`routing.mode`** Set in the config; a new install has `suggest`. - **`suggest`** When another agent and model you've set up merges clearly more often on a project (both with 5+ runs, at least 1.5× and 15 points better), Needs you says so and opens that project's accounts. Nothing changes by itself. - **`auto`** Each new ticket runs on the project's allowed account (`accounts`, else all) that scores clearly best. While samples are thin it keeps today's order, and it moves to the next allowed account when one is cooling down or its agent or gateway doesn't answer. - **Never spread** It never spreads work over several accounts of the same agent and backend (your subscriptions), and leaves projects on Plan and warn only alone. - **`off`** Today's order. # Phone and Access from anywhere Your Overhand on your phone: free over Tailscale, from anywhere on Pro and Team. ## Free: your phone over Tailscale. - **Your own network** Settings → Phone serves Overhand on your [Tailscale](https://tailscale.com/) network with `tailscale serve`, so only your own devices reach it. - **Pair the phone** Scan the QR code or type the one-time code, valid for 10 minutes. The computer's own browser needs no pairing: `overhand open` opens it signed in. - **Push** Set up an [ntfy](https://ntfy.sh/) topic (its URL in your keychain, its name under Settings → Integrations) and questions and alerts reach your phone. When your phone can reach Overhand, a lead's question carries answer buttons that work once. ## Pro and Team: from any device. - **No network setup** Open app.overhand.dev on any device and sign in. Your browser connects straight to your computer; when the computer is off, so are your agents. - **Push from your computer** Your computer encrypts each notification and sends it through your browser's own push service. - **The plan** Access from anywhere and push come with [Pro and Team](https://overhand.dev/pricing.html). Everything on your computer works without them. ## How linking works. - **Signed up first?** Until a computer is linked, app.overhand.dev shows the install line first, then how to link, and says *Linked* by itself once your computer is. Linking needs no plan; reaching it from anywhere does. - **1. Set it up** Settings → Phone → Access from anywhere → *Set it up*. Your computer makes a key of its own and opens app.overhand.dev in your browser. - **2. Confirm it's yours** Sign in, then check the computer's name and key fingerprint. The relay signs a link certificate for that key and hands it back to your computer. - **3. Only its own** Your computer takes the certificate only for its own key and its own one-time request. - **4. Kept on** While your plan is active, your computer renews its access every few hours, and a short outage at the relay doesn't turn hosted features off. - **What the relay sees** It introduces your browser to your computer and never carries the traffic. [How the connection is secured](https://overhand.dev/under-the-hood.html#anywhere). # Teams Each person's agents side by side, and questions that find the right person. ## Set up a team. - **Each person runs their own** Everyone on the team runs Overhand on their own computer, linked as on [Access from anywhere](https://overhand.dev/docs/anywhere.html). - **Settings → Team** Create the team, invite people with a link, give roles, set each project's owner and backup, see your seats, and choose whether your results share pull request links. - **Roles** The owner holds the Team plan. Admins invite and remove people and set project owners. Members see the team, answer, claim, comment and hand off. - **The plan** Team is priced per seat; see [Pricing](https://overhand.dev/pricing.html). ## Working side by side. - **Me and Team** Now gets a switch between your own view and the team's, where each person has their own rings and only what waits on you is orange. - **Follow someone** Click a face in the header. - **Claim it** *I'm on it* says you've got an item, so nobody does it twice. - **Hand it off** Drag an item onto a teammate, or use *Hand off to…*. It waits in their crew until they give it to an agent. - **Mention** @name in a comment notifies that one person. ## Questions find their person. - **The project's owner first** An agent's question goes to its project's owner. After 30 minutes without an answer it goes to the backup too. - **Only metadata** The team sees status, questions, results and hand-offs, never code, diffs, keys or transcripts. [What the relay keeps on Team](https://overhand.dev/under-the-hood.html#relay). - **In depth** How teams work, what is shared, security and cost: [docs/teams.md](https://github.com/craftly-io/overhand/blob/main/docs/teams.md). # Cleanup and quiet mode Disk space back, and your laptop back when you need it. ## Clean up disk. - **Where** *Clean up disk* in the actions menu, or *Find space* under Health → This machine. - **You see it first** A list of what can go, with sizes and when each was last used. Nothing is removed until you press the button, and each item is checked again just before it goes. - **What it finds** Caches, old versions of agent apps, agent apps nothing runs, local AI models and agent history long unused, Docker leftovers and old logs, finished and forgotten agent worktrees, and dependencies in worktrees that sat idle. - **Never your work** Nothing with uncommitted, untracked, unpushed or stashed changes, and never one of your own checkouts without asking. - **From a terminal** `overhand cleanup plan` lists, `overhand cleanup run` removes what's ticked. ## Or let it run by itself. - **Off until you choose** Set `cleanup.auto.schedule` to `daily` or `weekly`. It then also cleans early when free disk runs low. - **Only when idle** It starts only while no agent or lead is running, and takes only the items safe to remove without you. - **Low disk** When space runs short, Needs you warns first; then heavy jobs wait, and then new agents and leads don't start. ## Quiet mode: "I need my laptop". - **What it does** Holds builds, full test runs and dev servers while you need the laptop, in Claude Code, Codex and OpenCode. Edits and targeted tests carry on, and held work starts again when it ends. - **Turn it on** The Quiet mode row in the actions menu, or `overhand quiet 3h` (or `90m`, up to 72 hours). `overhand quiet off` ends it. - **Held anyway** Heavy jobs also wait while the machine is busy, the battery is low, the Mac is throttling for heat, or disk is short. - **From a script** `POST /api/quiet {"hours": 3}` does the same. The header shows the time left. ## What the cleanup looks at, in detail. - **Finished worktrees** Agent worktrees whose branch is merged or deleted on the remote, or whose pull request was merged or closed, when they're clean. - **Idle dependencies** `node_modules` and test artifacts (screenshots, `test-results`, reports) in agent worktrees idle 5 days (`cleanup.categories.worktrees.depsIdleDays`). The agent reinstalls on its next run there. - **Duplicate clones** Full clones of a remote you already have, clean and fully pushed. They're listed unticked and go only when you confirm each one; worktrees of one clone are far cheaper. - **Old simulators** Simulator runtimes older than the newest per platform, listed unticked. - **Measured, not guessed** Freed space is the volume's free space before and after, since `du` overcounts APFS clones. - **Disk thresholds** Under 15 GB free (`governor.warnFreeGb`) Needs you warns. Under 8 GB (`governor.pauseHeavyBelowGb`) heavy jobs wait. Under 3 GB (`cleanup.minFreeGb`) new agents and leads don't start. ## Heavy jobs share the machine. - **Why** Several agents on one laptop can bury it with screenshot sweeps, full test suites and simulators at once. - **Light work goes through** The guard sorts every shell command. Edits, git, and a test run that names files or a test go straight through. - **`browser`** Playwright, Puppeteer, Lighthouse, axe, screenshot sweeps: 1 at a time, up to 20 minutes. - **`suite`** `bun test`, `npm test`, `pytest`, `go test ./...` with no file or name filter: 1 at a time, up to 30 minutes. - **`simulator`** xcodebuild, `simctl boot`, Maestro, Detox, `expo run:ios`: 1 at a time, up to 45 minutes. - **`build`** `bun run build`, `next build`, `cargo build`, `docker build`: 2 at a time, up to 30 minutes. - **`devserver`** `bun run dev`, `next dev`, `expo start`: 2 at a time, up to 240 minutes. - **When it waits** While the 1-minute load per core is over 1.5, on battery under 30%, while macOS reports thermal throttling, when disk is short, or in quiet mode. - **What waiting means** The agent is told why, and to do other work and retry. Each wait is logged in Health → Guardrails. - **When it may start** It runs inside `overhand heavy -- `. Claude Code's hook rewrites the command; the other agents' hooks can't, so their agent is told to run the wrapped command itself. - **The slot** A lock file under `slots/` holds the job's pid, so a slot whose holder died frees itself. Output passes straight through. - **Stopped when stuck** The job's whole process tree is killed past its limit, or after 10 minutes printing nothing. - **Orphaned browsers** Every minute the daemon stops headless browsers whose parent died and whose environment carries `OVERHAND_RUN`. Never your own. - **Config** All of it is `governor` in the config: `slots`, `maxLoadPerCore`, `minBatteryPct`, `thermal`, `pauseHeavyBelowGb`, `warnFreeGb`, `timeoutMin`, `silentMin`. - **Protected processes** `governor.protect` lists ports (Overhand's own 4317 by default), process names and Docker container name prefixes, for example `{"ports": [4317, 4100], "containerPrefixes": ["demo-"]}`. - **What that blocks** `kill`, `pkill`, `killall`, `docker stop|rm|restart`, `compose down`, `launchctl`, `systemctl`, `pm2` and `brew services` commands that name one, or whose target listens on a protected port. - **Every agent but Aider** The governor works through the guard's hook. Aider runs no shell commands, so it starts no heavy jobs. # Day to day Focus, the menu bar item, the night report, share cards, updates, feedback and what's new. ## Focus: outcomes only. - **What stays** What needs you, what finished and what broke. What agents are saying, subagents and the day's in-between beats fold behind *Show steps*. - **Turn it on** The Focus switch in Quick settings, the F key, or `focus` in the command bar. Each browser keeps its own choice. - **Its default** On for a new install. An install in use before Focus existed starts with it off. ## The menu bar item. - **What it shows** On a Mac, the Overhand mark in the menu bar, with the count of what needs you beside it: amber, or red when something is broken. Click it for who's at work, what needs you, Quiet mode, *Open Overhand* and *Night report*. - **What a click opens** A card or a sentence opens its place in the full dashboard, in your browser, signed in. - **Turn it off** *Hide from the menu bar* on it, or the Menu bar item switch in Quick settings, which turns it back on. It comes with the installed Overhand on a Mac; a source checkout builds it with `bun run menubar`. ## The night report. - **Every morning** One notification a day, from the hour you set in Settings → Schedule & limits: what merged and opened, what waits on you, and what yesterday was billed. With an [ntfy](https://ntfy.sh/) topic it reaches your phone too. - **Night report** In the actions menu or the command bar, and in the header when nothing else is next. It reads where things stand aloud and writes it down. - **Stop** While it reads, its button turns into Stop. Esc, closing the report or leaving the page stops it as well. ## Share cards. - **What it is** *Share* in the actions menu makes an image of what got done: the night, today or the week. - **Where it goes** Download it, or hand it to your device's share sheet where the browser offers one. ## Status updates and work reports. - **Chat updates** Settings → Integrations → Status updates: each channel on Discord, Slack or Teams gets a summary of the projects you pick, on the schedule you pick. A test message checks it first. - **Work reports** Health → Work reports: per project, for the last week, month or any dates. Print it, or export Markdown or CSV. A weekly report can go to your channels too. ## Suggest or report. - **Where** *Suggest or report* in the actions menu, or `feedback` in the command bar. - **You see it first** It becomes a public GitHub issue, and the preview is exactly what goes. A diagnostics summary is yours to add. Anything private it spots stops the send until you edit it out. - **Sent by you** With `gh` signed in it posts as you; otherwise it opens on GitHub, filled in, for you to submit. ## What's new. - **The list** *What's new* in the actions menu lists every feature, newest first, each with a link to its page here. - **Tips** When a feature is newer than what your browser has seen, one quiet line sits beside it: one a day at most, never on your first day, gone for good once you close it. - **Off** Settings → Look & sound → Tips about new features. # Privacy and what leaves your machine What stays on your computer, and the little that doesn't. ## What stays. - **Your code and your agents' work** Repos, diffs, transcripts and logs stay on your computer, under `~/.overhand` and your own folders. - **Your keys** In your keychain, or the file you opted in to. [Where things run](https://overhand.dev/under-the-hood.html#machine). ## What leaves, and where to. - **To your model** What your agents send to the model provider you chose, just as they do without Overhand. A local model's prompts stay on your computer. - **To GitHub and your tools** Through your own sign-ins: `gh` for pull requests and issues, and any tracker, error service or notification you connect, such as ntfy or a status update's webhook. - **A release check** Once a day Overhand asks GitHub whether a newer release is out. - **On Pro and Team** Your sign-in, your computer's link and your plan go to the relay at app.overhand.dev; on Team, the team's metadata too. [What the relay does and doesn't see](https://overhand.dev/under-the-hood.html#relay). - **On this website** Cookieless page counts from Cloudflare Web Analytics, with no personal data. What the hosted services keep, and your rights, are in the [privacy policy](https://overhand.dev/privacy.html). # Troubleshooting What to run, and what the messages mean. ## Start with these. - **`overhand doctor`** Each thing Overhand needs, ticked or crossed, with the fix under every cross. It exits non-zero while something required is missing. - **`overhand status`** Whether it's running, on which port and version, its last heartbeat, agents at work and free disk. - **`overhand logs -f`** Follows its log; without `-f`, the last lines. - **Needs you** Overhand also checks itself every quarter of an hour, and a problem it finds shows there. Every problem there comes with its fix as a button: one that fixes it, or opens exactly where the fix is. A red line under the story opens its ticket or its lead. ## Installing. - **`Checksum mismatch for`** The download didn't match the release's sums, so nothing was installed. Run the installer again; if it repeats, [tell us](https://overhand.dev/contact.html). - **`Download failed:`** The release files couldn't be reached from here. Check the connection, or a proxy in the way. - **`Overhand runs on macOS and Linux; this is`** There's no package for this system. - **`isn't installed yet; the setup page shows how to get it.`** `git` or `gh` is missing. Install it; Overhand itself is installed. - **`Overhand didn't start.`** The lines above it say why; `overhand logs` has the rest. ## Running. - **`is in use; is Overhand already running? (overhand status)`** Something already listens on Overhand's port, often Overhand itself. `overhand status` says which. - **`Overhand isn't running (nothing answers on port`** Start it with `overhand start`. - **`Overhand didn't come up on port`** It started but never answered. The message names its log; read it with `overhand logs`. - **`No daemon log yet at`** The log appears once the login service has run; `overhand start` sets it up. - **`Not set up yet: run overhand start and finish the setup in the browser`** Setup hasn't been finished; open [http://127.0.0.1:4317](http://127.0.0.1:4317/). ## Accounts and tools. - **`agents open pull requests and read issues through it`** The GitHub CLI isn't signed in. Run `gh auth login` yourself. - **`doesn't look like an Anthropic API key`** The stored key isn't one; store a key from platform.claude.com again. - **`nothing answers there: start the gateway or fix its URL`** A gateway account's address gives no answer: start the gateway, or fix its URL in Settings. - **`Tailscale isn't running on this Mac.`** Open Tailscale and sign in, then try Settings → Phone again. - **Saving a secret fails on Linux** There's no unlocked keyring. See [On Linux](https://overhand.dev/docs/install.html#linux). ## Updating. - **`The update didn't install; Overhand is unchanged.`** The line above it says why (no network, a checksum that didn't match, a full disk). The message ends with the command to update by hand for the way you installed. - **`This Linux uses musl`** Alpine and other musl systems can't run the Linux builds. Use a glibc system such as Debian or Ubuntu. - **From the app** When a new version is out, Needs you offers *Update and restart*: it runs the same update as `overhand update`, then restarts once no agent is running. - **Still on the old version** It restarts on the new one once no agent is running. To restart now: `overhand stop && overhand start`. # Command reference Every overhand command, from its own help. ## Commands. - `overhand start`: run Overhand in the background (at every login) and open it in your browser - `overhand stop`: stop it and don't start it at login - `overhand open`: open it in your browser, signed in (a browser on this computer needs this once); --reset makes a new local key first, which signs every browser out - `overhand status`: whether it's running: port, version, last heartbeat, agents at work, free disk - `overhand logs`: the daemon's log (-f keeps following it) - `overhand update`: update to the latest release - `overhand uninstall stop it and remove the program; --remove-data also deletes ~/.overhand (asks first),`: --dry-run only lists what it would remove and keep - `overhand doctor`: check what Overhand needs on this machine - `overhand version`: print the version - `overhand answer ""`: answer a lead's open question (--default: go with the default it gave) - `overhand daemon`: run in the foreground (what the login service runs) - `overhand plan | work | inbox | ui`: one step by hand - `overhand cleanup plan | run | auto`: one disk cleanup pass (Overhand's own cleanup runs these) - `overhand quiet 3h | 90m | off`: "I need my laptop": agents start no browsers, suites, builds, simulators or dev servers - `overhand connect []`: your own Claude Code sessions in that project join the control room and follow the house rules (writes .claude/settings.local.json; --global: every project, asks first) - `overhand disconnect []`: undo it - `overhand ask "" [--by HH:MM]`: a typed request, handed to that session at its next tool call - `overhand ack [done | refuse "why"]`: answer a request handed to this session - `overhand mcp`: Overhand's MCP server over stdio, for an agent: status, answer, ask and ack as tools This list is what `overhand help` prints. Every command exits non-zero when it fails, so scripts can rely on it. Two more, `overhand guard` and `overhand heavy`, are run by agents' hooks, never by you. ## Settings from the environment. - **`OVERHAND_NO_START=1`** The installer installs without starting Overhand. - **`OVERHAND_SECRETS_FILE`** Keep secrets in a file only you can read, where there's no keyring. - **`NO_COLOR`** The installer prints without colour. # What's next What isn't built yet. ## Not built yet. - **One-click cloud templates** Ready-made templates to run Overhand on Railway and Fly.io in one click. Today it runs on a Linux server you set up yourself, as [Run Overhand on a server](https://overhand.dev/docs/server.html) shows. - **Hosted runners** Agents that run on machines we host, for when your own computer is off. - **SSO for Business** Single sign-on through your company's identity provider. - **More add-on looks** More looks for Overhand, to add when you want them. Every word stays the same in each. Nothing on this list works today, and none of it has a date. Everything on the rest of this site does work.