# Handoff

import { Callout } from "nextra/components";

You started a task on your Mac, but the next step needs Windows. `runpane handoff` sends your note and starts a fresh agent in a new Pane on the destination machine, from your commit. You can also hand work to another agent on the same machine.

Use [Workspaces](/docs/runpane-workspaces) to run a command or read a file on another machine. Use Handoff when you want an agent there to take over the task.

## Before you start

1. Use the npm CLI (`npm i -g runpane`). The Python wrapper doesn't run Handoff. These instructions were checked against Pane and runpane **2.4.166**.
2. For another machine, set up [Workspaces over Tailscale](/docs/runpane-workspaces#turning-it-on). Open Pane on both machines and sign in to Tailscale with the same login.
3. Save a clone of the repository in Pane on the destination. It needs a Git remote for the same repository and permission to fetch your branch. Install and sign in to the receiving agent there.
4. Work from a native repository, not a WSL checkout. Check the [current limits](#current-limits) before sending.

## Send a task

1. Find the destination's name:

   ```bash
   runpane workspace list
   ```

2. From your repository, create a note outside the checkout:

   ```bash
   runpane handoff --template > ~/handoff.md
   ```

   Fill in all nine sections below. Leave the front matter alone. The CLI fills in the current Git state and adds instructions for the receiver when it sends.

3. Commit the files the task needs and push your branch. Leave unrelated changes out. The receiver starts from the commit, so uncommitted files won't travel with it.

4. Preview the destination. Replace `my-windows-pc` with the name from step 1:

   ```bash
   runpane handoff "codex on my-windows-pc" --note-file ~/handoff.md --dry-run
   ```

   This checks the destination text, note sections, and local Git state. It prints warnings for uncommitted or unpushed work. It doesn't commit, push, send the note, or start an agent. It also doesn't prove that the destination's repository or agent is ready.

5. Send the task by removing `--dry-run`:

   ```bash
   runpane handoff "codex on my-windows-pc" --note-file ~/handoff.md
   ```

   The CLI finds the saved repository with the matching remote, writes the note under `~/.pane/handoffs/` on the destination, and starts the agent in a new Pane from your commit. Use the `agents status` command it prints to check on that Pane. Stop editing the sending branch once the receiver takes over.

## Choose the agent and machine

The destination text names Claude, Codex, or Cursor. You can add a model, an effort level, and a machine name or unique prefix:

```bash
runpane handoff "claude opus on my-mac" --note-file ~/handoff.md --dry-run
runpane handoff "codex gpt-5 high on my-windows-pc" --note-file ~/handoff.md --dry-run
runpane handoff "cursor on this machine" --note-file ~/handoff.md --dry-run
```

Choose a model your installed agent can use. `--machine`, `--agent`, `--model`, and `--effort` override the text. Claude and Codex support effort selection. Cursor effort is rejected before anything is committed or sent. If several saved clones match, use `--repo <selector>` to pick the destination repository.

## What goes in the note

Keep the exact `##` headings from the template. Missing or empty sections are rejected. Write `None` when a section doesn't apply.

| Section | What to write |
| --- | --- |
| Goal | What you're trying to finish and what done means. Link the issue or PR. |
| Current state | Where the task stands now. |
| Done and verified | What you finished, the checks you ran, and their actual results. |
| In progress | Partial work, failing checks, and exact errors. |
| Next steps | Ordered actions, starting with one the receiver can do immediately. |
| Decisions and constraints | Your choices, reasons, permissions, and failed approaches. |
| Open questions | Unresolved questions and pending approvals. |
| How to verify | Commands to build, test, and see the result, with expected outcomes. |
| Git state | Repository, branch, commit, push status, and relevant uncommitted files. |

Don't put secrets in the note. Name the approved place to get them. Link evidence instead of claiming checks you haven't run.

## Let the CLI commit and push

If you've approved sending all remaining work, you can add `--push`:

```bash
runpane handoff "codex on my-windows-pc" --note-file ~/handoff.md --push
```

<Callout type="warning">
`--push` commits all remaining changes as WIP, except the note, and pushes the branch. It never force-pushes. Commit task files yourself first if the checkout contains unrelated work. A staged note must be unstaged before using `--push`.
</Callout>

Starting a receiving agent and pushing code are separate permissions. Asking an agent to hand off a task doesn't by itself authorize a push.

## How the receiver reports back

The CLI appends instructions to read the repository's `AGENTS.md`, check the starting commit, run your verification steps, and continue from your next steps. It tells the receiver to push to your original branch without forcing.

When you send from a Pane panel, the receiver gets a command like this, with your machine and panel filled in:

```bash
runpane workspace <origin_machine> panels submit --panel <origin_panel> --text "<result, commit or PR, and blockers>" --yes
```

If there's no sending panel, the instructions ask for a PR comment or a commit message on the branch instead. These are instructions for the receiving agent, not a guarantee that its work or checks succeeded.

## Current limits

- **WSL handoff isn't supported.** Explicit WSL destinations are rejected before committing or sending. Use a native repository. WSL reaching its own Windows host also has a known daemon-routing failure; that fix is pending.
- **Startup can need manual recovery.** Mac-to-Windows and Windows-to-Mac handoffs passed manual checks after startup recovery. Don't assume every launch completes unattended. If startup fails after the note is sent, inspect the destination's Sessions and existing Pane before retrying so you don't create a duplicate.
- **Pane must be running on the destination.** Tailscale connectivity alone isn't enough. A dry run doesn't test remote startup.
- **Remote shells are limited.** Bash, Zsh, Sh, Fish, and PowerShell are supported. Windows `cmd` isn't.

See [Workspaces](/docs/runpane-workspaces) for remote commands and [runpane CLI](/docs/runpane-cli) for the rest of the CLI.
