HandCode 0.3.1 GitHub

Quickstart

You need git and one API key. A free OpenRouter or Gemini key works. The installer below brings Python 3.12 itself if you do not have it.

1. Install

HandCode is on PyPI as handcode. Install it with uv, which also fetches Python 3.12 if you do not have it.

1. Get uv, if you do not have it:

curl -LsSf https://astral.sh/uv/install.sh | sh          # macOS / Linux
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"   # Windows

2. Install HandCode:

uv tool install "handcode[openhands]"

This gives you the agentctl command (also installed as handcode) in its own environment, so it cannot clash with your projects' packages. Check it:

agentctl --version

If the shell says the command is not found, run uv tool update-shell and open a new terminal. Upgrade later with uv tool upgrade handcode.

To work on HandCode itself, install it from a clone instead (CONTRIBUTING.md).

Why uv: the install is about 140 packages, almost all of them pulled in by the OpenHands SDK. Measured on clean machines (docs/0051 §8):

pip uv
Linux 39 s 3 s
macOS 43 s 4 s
Windows 48 s 23 s
one Windows laptop 4–13 min 21 s

Plain pip install "handcode[openhands]" works too; it is only slower.

2. See what it is for (no key, no cost)

agentctl demo

An agent commits, its process is killed in the middle, and the run is resumed. Without agentctl the commit happens twice. With it, once. This takes about a minute, and uses a scripted model, so it needs no key and no network.

3. Set up one key

agentctl init

It uses a key you already have in your environment, or asks you to paste one; the key is not shown on screen. It stores it in ~/.agentctl/keys.env, outside every repository. Then it sends one tiny request to check the key, and remembers the model that answered.

4. Run a task

In any git repository:

cd your-project
agentctl run "the date parser rejects ISO dates with a Z suffix; fix it" --accept "python -m pytest -q"

--accept is your test command. agentctl runs it itself when the agent is done, and the report says PASS or FAIL. Without it, the report says not checked.

The run ends with a report, like this one:

  outcome     PASS   `python -m pytest -q` exited 0
  changed     2 files  +14 -3
  agent said  "Fixed the Z suffix handling and added a test."
  used        11 requests · 50.3K tokens · $0.00 (free-tier model) · 28s
  actions     16 actions: 9 commands, 6 reads, 1 file write
  needs you   nothing

5. When a run stops

agentctl status       # recent runs and what needs you
agentctl resume       # continue the last run here

agentctl is not a sandbox. In a container, an allowed command can reach the container and the one directory you mount, and nothing else on your machine.

Until the first release publishes the image to ghcr.io/csdeepak/handcode, build it from a clone (it needs Docker):

uv build --wheel
docker build -t handcode .

Then, from your project:

docker run --rm -it --user "$(id -u):$(id -g)" \
  -v "$PWD:/work" \
  -v handcode-home:/home/handcode \
  --env-file ~/.agentctl/keys.env \
  handcode run "<task>" --accept "<your tests>"
Part Why
--user "$(id -u):$(id -g)" Files the agent writes in your repo belong to you, not to root
-v "$PWD:/work" Your repository. The only part of your machine the agent can change
-v handcode-home:/home/handcode Keeps status, resume, init's config and the run index between containers
--env-file ~/.agentctl/keys.env Your keys, read at start; never copied into the image

Add -v ~/.gitconfig:/home/handcode/.gitconfig:ro to commit as yourself. Otherwise commits are authored by "HandCode agent". --pool starts in seconds here, because the pool's environment is built into the image.

On Windows (PowerShell), use -v "${PWD}:/work" and leave out --user.

7. More than one provider (optional)

With keys for several providers, route through a pool, so that a daily cap or an outage at one provider does not stop the run:

agentctl run "<task>" --pool

The first time, this sets up the pool's own environment (a few minutes). After that it starts in seconds. agentctl proxy status and agentctl proxy down manage it.