You lead. hand runs the crew.
Secondhand turns one coding-agent session into a supervisor for a fleet of coding agents.
You talk to one agent. It plans the work, writes briefs, dispatches workers into isolated git worktrees, watches them, steers them when needed, and brings the results back to you.
hand is the CLI underneath that workflow. It owns lifecycle, state, isolation, and process supervision so the supervising agent can focus on judgment and coordination.
flowchart LR
user["You"] --> supervisor["Supervising agent"]
supervisor --> hand["hand"]
hand --> worker1["Worker"]
hand --> worker2["Worker"]
hand --> scout["Scout"]
worker1 --> pr1["PR / branch"]
worker2 --> pr2["PR / branch"]
scout --> report["Report"]
pr1 --> supervisor
pr2 --> supervisor
report --> supervisor
Secondhand was inspired by firstmate, rebuilding the same agent-fleet idea as a focused Go CLI.
Coding agents are good at working on a task. Running several of them reliably is a different problem.
Someone still has to:
- give each worker enough context
- keep concurrent work isolated
- know which worker is running, blocked, or done
- steer a worker without restarting it
- preserve task state across supervising sessions
- decide when work is ready to merge or hand off
- clean up worktrees and processes without losing unfinished work
Secondhand splits those responsibilities cleanly: the supervisor handles judgment; hand handles mechanics.
From a release:
curl -fsSLO https://github.com/atqamz/hand/releases/latest/download/hand-linux-amd64.tar.gz
tar xzf hand-linux-amd64.tar.gz
install -m755 hand ~/.local/bin/handOr with Nix:
nix profile install github:atqamz/handSee Installation for every supported option.
A fleet home is the directory where the supervising agent lives and where Secondhand keeps fleet state.
mkdir ~/fleet
cd ~/fleet
hand inithand init is non-interactive. It creates the fleet structure and writes a managed block into AGENTS.md telling any supervising harness to run hand session start before acting, with a CLAUDE.md reference when that name is otherwise absent. This is a symlink on Unix and an @AGENTS.md pointer file on Windows.
hand project add https://github.com/you/projectSecondhand clones the repository under the fleet home and prepares it for isolated worker worktrees.
For Claude Code:
cd ~/fleet
claudeThe generated AGENTS.md block tells the harness to run hand session start before responding or acting; that command loads bounded fleet context and reports the first next action, and refuses outright inside a worker's isolated worktree. Any other supported harness reads the same instructions from AGENTS.md directly.
On the first session, the supervisor may ask which worker harness, model, or effort level you want. Your answers are persisted with hand config; nothing is guessed on your behalf.
Talk to the supervisor normally:
Fix the login regression. Also investigate why the integration tests are flaky, but do not change anything for that investigation yet.
The supervisor can dispatch the fix as a ship task and the investigation as a scout task, then coordinate both while you keep talking to one agent.
flowchart TD
request["Your request"] --> brief["Supervisor writes a brief"]
brief --> spawn["hand spawn"]
spawn --> worktree["Worker in an isolated worktree"]
worktree --> supervise["Watch and steer"]
supervise --> outcome{"Task kind"}
outcome -->|Ship| ship["PR or local branch"]
outcome -->|Scout| scout["Investigation report"]
ship --> finish["Merge or deliver"]
scout --> finish
finish --> teardown["hand teardown"]
Ship tasks make changes. A worker receives its own git worktree, works independently, and produces a pull request or local branch according to the project's delivery mode.
Scout tasks investigate without being expected to ship code. They return data/<id>/report.md, and a completed scout can later be promoted into a ship task.
Every worker operates in a git worktree leased through treehouse. Workers never edit the registered project clone directly.
Workers run interactively inside herdr, so the supervisor can observe semantic agent state, send follow-up instructions with hand send, and react to fleet events with hand watch without scraping a terminal for meaning.
Machine state lives in SQLite while operator context, briefs, reports, backlog history, and learnings remain plain files. The fleet survives the supervising agent's session, so a later session can pick up where the previous one stopped.
hand fails closed around destructive or irreversible transitions. Teardown refuses unlanded work unless it was explicitly delivered, and the generated supervisor rules prohibit merging without operator authorization.
hand is designed primarily for agent callers rather than as a terminal dashboard. Commands return compact structured TOON documents with named fields, aggregates, machine-readable states, and suggested next actions. Read commands that support it retain --json as an alternative.
Each registered project has a delivery mode:
| Mode | Workflow |
|---|---|
direct-pr |
Workers produce normal branches and pull requests. This is the default. |
no-mistakes |
Delivery is guarded by a no-mistakes validation pipeline. |
local-only |
Work stays local instead of using a remote pull-request workflow. |
Choose a mode when registering a project:
hand project add https://github.com/you/project --mode direct-prFor a fork, declare the upstream repository that receives pull requests:
hand project upstream project-name upstream-owner/projectSecondhand can launch workers through:
- Claude Code (
claude) - Codex (
codex) - Grok (
grok) - Pi (
pi) - OpenCode (
opencode)
Without an override, workers inherit the harness detected as the current supervisor; only when none can be detected does hand config report the harness as missing. Inspect and configure fleet defaults with:
hand config
hand config set harness claude
hand config set model claude-opus-5Model and effort support depends on the harness: hand config reports each as native-default, configured, or unsupported instead of silently storing a setting a harness cannot carry. Overrides are stored per harness, so switching harnesses never hands a worker a model or effort chosen for a different tool.
A task brief can also declare model and effort for that specific worker; explicit spawn or promote flags win over brief values, which win over these defaults.
A fleet home is deliberately separate from the repositories being worked on.
~/fleet/
├── AGENTS.md
├── CLAUDE.md
├── config/
├── data/
│ ├── backlog.md
│ ├── operator.md
│ ├── learnings.md
│ └── ...
├── projects/
└── state/
The important pieces are:
AGENTS.md- operating instructions for the supervising agentdata/operator.md- your standing constraints and preferencesdata/backlog.md- the supervisor's task queuedata/learnings.md- durable operational knowledge discovered by the fleetprojects/- registered project clonesstate/hand.db- authoritative machine state
You normally do not manage these by hand. The supervisor and hand own the workflow.
Every command resolves the fleet home from HAND_HOME when set, otherwise from the current directory or the nearest ancestor containing state/hand.db.
hand itself is a self-contained Go binary. Operating a fleet relies on a few external tools:
- herdr - interactive worker sessions and semantic agent state
- treehouse v2.1.0 or newer - isolated git worktree pools
- gh - GitHub pull-request and release operations
- at least one supported coding-agent harness
Optional:
- no-mistakes - required only by projects using
no-mistakesmode - qmd - semantic search over historical fleet context beyond
hand search
hand init reports checked tools it cannot find on PATH. hand doctor checks the fleet home's generated agent instructions and related drift.
Building from source additionally requires Go 1.26.5 or newer.
Release tar archives are available for Linux and macOS on AMD64 and ARM64. A ZIP archive is available for Windows AMD64. Every release includes checksums.txt.
curl -fsSLO https://github.com/atqamz/hand/releases/latest/download/hand-linux-amd64.tar.gz
tar xzf hand-linux-amd64.tar.gz
install -m755 hand ~/.local/bin/handOn Windows, download hand-windows-amd64.zip, extract hand.exe, and place it on PATH.
See the releases page for every asset.
Install into your profile:
nix profile install github:atqamz/handOr run it without installing:
nix shell github:atqamz/hand -c hand --versionThe flake covers aarch64-darwin, aarch64-linux, and x86_64-linux. On Intel macOS, use a release binary or go install.
go install github.com/atqamz/hand@latestgo install does not embed release-version metadata, so the binary reports dev and never checks for updates. Prefer a release binary or Nix installation for a versioned build.
To build a checkout for contributing to Secondhand itself, see CONTRIBUTING.md.
You normally let the supervising agent drive the CLI. The main lifecycle is:
| Command | Purpose |
|---|---|
hand init |
Create or refresh a fleet home. |
hand project add |
Register a repository with the fleet. |
hand spawn |
Dispatch a worker into an isolated worktree. |
hand status |
Read fleet or task state. |
hand watch |
Wait for actionable fleet events. |
hand send |
Steer a running worker. |
hand merge |
Merge completed work after authorization. |
hand deliver |
Mark work as handed off when landing is someone else's decision. |
hand teardown |
Clean up a completed task safely. |
Other commands cover session bootstrap, configuration, project sync and upstreams, holds, scout promotion, search, notifications, diagnostics, PR recording, and self-update.
Run hand --help for the authoritative command reference.
Running bare hand returns the resolved fleet home, worker configuration, and live fleet overview rather than a generic help screen.
Release installations on Linux and macOS can update themselves:
hand updateCheck without installing:
hand update --checkWhen run inside a fleet home, an update also refreshes the generated section of AGENTS.md without overwriting your own additions. Other commands check for a newer release at most once a day and print a one-line notice when one is available.
Self-update is not yet supported on Windows. Download the matching release archive and replace hand.exe manually.
Secondhand deliberately separates judgment from mechanics.
flowchart LR
user["You<br/>requests and irreversible decisions"] --> supervisor["Supervising agent<br/>planning and coordination"]
supervisor --> hand["hand<br/>lifecycle, state, isolation, supervision"]
hand --> worker1["Ship worker"]
hand --> worker2["Ship worker"]
hand --> scout["Scout worker"]
worker1 --> tree1["treehouse worktree"]
worker2 --> tree2["treehouse worktree"]
scout --> tree3["treehouse worktree"]
tree1 --> pr1["PR / branch"]
tree2 --> pr2["PR / branch"]
tree3 --> report["Report"]
pr1 --> supervisor
pr2 --> supervisor
report --> supervisor
supervisor --> user
The supervisor owns planning and judgment. hand owns lifecycle, state, isolation, and supervision. Workers own individual tasks. You remain the authority for irreversible decisions.
For durable architectural rationale, see docs/adr/. Behavioral command contracts live with their implementation, help, and focused tests.
See CONTRIBUTING.md.
The short path is:
git clone https://github.com/atqamz/hand
cd hand
nix develop
make build
make lint
make testRun make e2e when changing CLI behavior. Secondhand uses conventional commits and release-please for versioning and changelogs.