| name | handoff-to-worktree |
| description | Packages the current chat (or one or more specific issues/topics) into self-contained handoff files and launches each in its own fresh `claude` session with a dedicated, meaningfully named git worktree — so work continues without manual context copy-paste. Each child claude inherits the CALLER session's permission mode (no hardcoded bypass). Requires cmux: by default each handoff opens as a new cmux workspace; with `--tabs` (or "in this/the same workspace", "as tabs") they open as tabs in the current workspace. Use when the user wants to hand off work to a fresh Claude in its own worktree instead of continuing inline. Trigger phrases: "handoff to worktree", "handoff-to-worktree", "spin this off into its own claude", "fork this into a worktree", "run it in a separate claude". No argument = handoff the whole chat (one worktree); argument(s) = one handoff/worktree per issue or topic.
|
| argument-hint | [--tabs] [issue-code|topic ...] (empty = whole chat; --tabs = tabs in the current workspace) |
| arguments | ["target","placement"] |
Handoff to worktree
Packages context (the whole chat, or a specific issue/topic) into a self-contained
handoff file in the OS temp dir, and for each handoff launches a fresh claude
with its own meaningfully named git worktree and an opening prompt that loads the
handoff and continues the work. No manual copy-paste of context.
Permissions — inherit the caller, never hardcode a bypass. The child claude
must run with the SAME permission posture as the session this skill runs in. If
the caller bypasses permissions, the child does too; if the caller runs in normal
(prompted) mode, the child prompts too. See step 4 for how to detect it.
Placement (where the child claude opens):
- Default — a new workspace per handoff (
cmux new-workspace --command …).
Each handoff is its own workspace in the sidebar.
--tabs — new tabs in the current workspace. When the user says "in the
same / in this workspace", "as tabs", or passes --tabs, open each handoff as a
new terminal surface (tab) in the caller's workspace (new-surface + send
send-key Enter, see step 4b).
MUST run inline — it needs the context of the current conversation. Do not fork.
Requirements
- cmux (the launch mechanism —
new-workspace, new-surface, send).
- A git repository with worktree support (
claude --worktree).
Inputs
$target: (Optional) One or more issue codes or topics (e.g. ABC-123 or
cache invalidation). Empty = handoff of the whole chat (one worktree).
$placement: (Optional) Default = a new workspace per handoff. If the user
passes --tabs (or says so verbally, see above), open the handoffs as tabs in
the current workspace. Treat --tabs as a mode switch, NOT as an issue/topic.
Goal
Each handoff produces: (1) a self-contained .md in the OS temp dir, and (2) a
running fresh claude with its own worktree — either as a new workspace (default) or
as a new tab in the current workspace (--tabs).
Steps
1. Determine scope, placement, and build the handoff list
- Placement: default = a new workspace per handoff (4a). If the arguments
contain
--tabs, or the user said so verbally, switch to tabs in the current
workspace (4b) and drop --tabs from $target.
- No
$target → one handoff = the whole chat.
- With
$target → one handoff per issue/topic (there can be several at once).
- For each, derive a meaningful kebab-case worktree name (short, descriptive;
if an issue code exists, include its short form — e.g.
abc-123-auth-retry,
cache-invalidation). Slug = [a-z0-9-] only, no shell metacharacters.
- Collision check: the slug must NOT be in
git worktree list AND no directory
$REPO/.claude/worktrees/<slug> may exist (verify with test -d). On collision
add a short suffix (-2, -3) — never overwrite an existing worktree.
- Keep
label (for cmux --name) short, ASCII, no quotes/$/backticks/newline.
Success criteria: You have the placement (workspace vs --tabs) and a list of
{label, slug, temp-path} for each handoff; every slug is unique and
collision-free.
2. Write the handoff file(s) to the OS temp dir
For each item, write an .md to the OS temp dir with a unique name so an older
handoff isn't overwritten:
${TMPDIR:-/tmp}/handoff-<slug>-$(date +%Y%m%d-%H%M%S).md.
Outline:
- Whole chat: a compact summary of the conversation for a fresh agent + a
"Suggested skills" section. Don't duplicate content already captured elsewhere
(plan, PR description, commit, diff) — link to it by path/URL.
- Issue/topic: a self-contained assignment — link to the issue (tracker URL),
what's being asked, what's already verified / what is NOT the cause, a root-cause
hypothesis, candidate files with line numbers, recommended approach, and
suggested skills.
- Redact PII (emails, personal names). Keep internal IDs (record/entity IDs) —
they're needed to reproduce.
- Carry over any project constraints that live in the repo's
CLAUDE.md or the
user's global preferences (e.g. required checks before committing, edit-scope
rules, writing conventions). Reference them; don't invent project-specific ones.
Success criteria: Each handoff file is readable standalone, without knowledge
of this chat.
Artifacts: absolute paths to the handoff files.
3. Confirm the plan [human checkpoint]
Via AskUserQuestion, show the list: which handoffs + worktree names will be
created, the placement (new workspaces vs tabs), the permission mode the
children will inherit (step 4), and how many claude instances will launch.
Launching multiple claude instances costs tokens — let the user confirm or adjust
names/scope/placement.
Success criteria: The user approved the plan.
Human checkpoint: Always, before spawning.
4. Launch claude + worktree per handoff
Find the canonical root of the main repo (not the worktree you may be running
in):
REPO=$(dirname "$(git rev-parse --git-common-dir)")
When you run inside .claude/worktrees/<something>, this returns the original repo
root; git rev-parse --show-toplevel would return the worktree path (wrong).
Detect the caller's permission posture — do NOT hardcode --dangerously-skip-permissions.
cmux records the current claude's launch argv (null-separated) in
CMUX_AGENT_LAUNCH_ARGV_B64. Decode it and reuse the same permission flag for the
child:
PERM=""
ARGV=$(printf '%s' "${CMUX_AGENT_LAUNCH_ARGV_B64:-}" | base64 -d 2>/dev/null | tr '\0' ' ')
case " $ARGV " in
*" --dangerously-skip-permissions "*)
PERM="--dangerously-skip-permissions" ;;
*--permission-mode*)
PERM="--permission-mode $(printf '%s' "$ARGV" | sed -E 's/.*--permission-mode[ =]+([A-Za-z]+).*/\1/')" ;;
esac
echo "PERM=${PERM:-<none, prompted mode>}"
Now substitute the detected PERM literally into the launch command below
(use the concrete value, e.g. --dangerously-skip-permissions,
--permission-mode plan, or nothing when empty). If CMUX_AGENT_LAUNCH_ARGV_B64
is unset and you can't tell, default to no bypass flag (safe, prompted) and say
so in step 3.
Then, per the placement (step 1), choose 4a (default) or 4b (--tabs).
With multiple handoffs, launch sequentially with a short pause (sleep 6-8)
between them and --focus false — a burst of fresh claude instances at once can
overload cmux. Verify after each (step 5).
4a. Default — a new workspace per handoff
cmux new-workspace --name "<label>" --cwd "$REPO" --focus false \
--command 'claude <PERM> --worktree <slug> "Read the handoff file <temp-path> and continue per its instructions. Start by reading the handoff."'
Gotchas (verified):
- Replace
<PERM> with the literal flag from the detection above (omit entirely
when empty).
claude -w/--worktree <name> creates a worktree under .claude/worktrees/<name>.
The positional prompt in claude "…" is sent automatically in interactive mode.
cmux --command sends ONE line + Enter. Wrap the whole claude … in single
quotes, the prompt in double quotes.
--cwd "$REPO" (canonical root), so --worktree is created correctly.
--focus false, so it doesn't interrupt the user.
- To keep them in the current window, add
--window "<current>" (ref from
cmux current-window).
Success criteria: cmux new-workspace returns OK workspace:N for each handoff.
4b. --tabs — new tabs in the current workspace
new-surface has no --command, so send the command into the new terminal tab via
send + send-key Enter. First find the caller's workspace from cmux identify (.caller.workspace_ref). For each handoff:
SURF=$(cmux new-surface --type terminal --workspace "$WS" --focus false | grep -oE 'surface:[0-9]+' | head -1)
cmux rename-tab --surface "$SURF" "<label>"
sleep 2
cmux send --surface "$SURF" 'cd <REPO-abs> && claude <PERM> --worktree <slug> "Read the handoff file <temp-path> and continue per its instructions. Start by reading the handoff."'
cmux send-key --surface "$SURF" Enter
Gotchas (verified):
- Replace
<PERM> with the literal flag from the detection above (omit when empty).
new-surface returns OK surface:N pane:M workspace:K; capture surface:N.
send types text literally; send-key Enter submits it (if Enter doesn't
work, try Return or C-m).
- Put
cd <REPO-abs> inside — new-surface has no --cwd; the new shell
starts in the workspace cwd, not necessarily the repo. claude --worktree then
creates the worktree itself.
- Wrap the whole
send command in single quotes, the prompt in double
quotes. Keep the prompt static (only the safe absolute <temp-path> varies);
it must NOT contain ' " ` $ \ or a newline.
--focus false, so the new tab doesn't switch you away mid-work.
Success criteria: read-screen --surface "$SURF" shows a running claude; the
worktree exists (step 5).
5. Verify it came up
After ~10s (sleep 10) check:
git worktree list → the new worktrees exist (primary proof, both placements).
- 4a (workspaces):
cmux list-workspaces → workspace:N with the given name is
running.
- 4b (tabs):
cmux list-pane-surfaces --workspace "$WS" or read-screen --surface "$SURF" → claude is running in the tab. If the command fails, the
surface ref + worktree existence is enough.
Report a table: issue/topic → worktree → workspace:N / surface:N → handoff path.
Success criteria: Worktrees exist and the claude instances are running; the
user has an overview of where everything is.
Rules
- Inline only — without the chat context the handoff can't be assembled.
- Always a human checkpoint before spawning (step 3).
- Inherit the caller's permission mode (detect via
CMUX_AGENT_LAUNCH_ARGV_B64);
never hardcode --dangerously-skip-permissions. When undetectable, default to no
bypass.
- Meaningful, unique kebab-case worktree names (
[a-z0-9-] only). Check collisions
before spawning (git worktree list + test -d).
- Handoff = self-contained; reference artifacts by path/URL, don't duplicate.
- Redact PII, keep internal IDs.
--command (4a) / send (4b): claude cmd in single quotes, prompt in double
quotes. Keep the prompt static (only the safe temp-path), without ' " `
$ \ or a newline.
REPO = canonical root via dirname "$(git rev-parse --git-common-dir)", not
--show-toplevel (it may run inside a worktree).
- Launch multiple handoffs sequentially with a
sleep between them and
--focus false (protection against overloading cmux).