Skip to main content

Cross-Tool Handoff and Pickup

Out of tokens, or want a second opinion from another model? Hand off in one command, pick up in the next tool in one read.

Works across tools and accounts

Claude Code (including Projects threads), Codex, Grok Build, Cursor, GitHub Copilot, Gemini CLI, OpenCode and a second Claude subscription all read the same files: AGENTS.md, the increment's spec.md, its ledger and the handoff. None of them can read another tool's private transcript, so SpecWeave keeps what matters in git.

The problem​

No AI coding tool can read another's session. Each one keeps its transcript in its own store. When you hit a usage limit mid-task, the goal, the decisions and your uncommitted edits are stuck there. Claude Code project memory stays with one account, so even a second Claude subscription starts cold.

Hand off​

New to switching? Switch from Claude Code to Codex without losing your place is the step-by-step version, and Claude Code vs Codex covers what each tool reads and where its session lives.

Tell your agent "hand off", or run:

specweave handoff                     # the active increment
specweave handoff 0042 --reason "out of tokens" --next "restore on return"

handoff:

  • Releases your task claims, so the next tool is not locked out.
  • Writes handoff.md with where you stopped, the next step and repo-relative paths, so it resolves on any machine.
  • Pushes your work to git when the repo has an origin remote: your branch, and a snapshot of your uncommitted edits to a well-known handoff ref and to wip/<branch>. Your working tree, index and branch are left as they were.
  • Scrubs secrets from the free-text fields and the diff before writing anything.
  • Writes an HTML report of who did what on the increment to reports/handoff-report.html. specweave report writes it on demand.

--no-push keeps the handoff local and --keep-claims keeps your claims.

Because the handoff lives in git, a cloud session such as a Claude Code Projects thread or a Codex cloud task sees it the same way your laptop does. There is nothing to copy or paste.

Pick up​

In the next tool, from the project folder:

specweave pickup

pickup fetches the last handoff. When your checkout is clean and the history allows it, it fast-forwards your branch and applies the handed-off edits; otherwise it says in plain words what to do and changes nothing. A checkout on the default branch switches to the handed-off branch; any other branch, such as a cloud thread's own, carries on where it is. --no-apply only shows what is waiting. Then it prints everything a fresh session needs in one read: the active increment, the next task with the text of its acceptance criteria, its files and test, the branch, notes from other increments, and the project memory index.

The Claude Code SessionStart hook prints the same summary, and AGENTS.md tells every other tool to run pickup first. In 2.x, resuming meant finding and reading four or five files and pasting a prompt. Now it is one command.

Several handoffs waiting, for example from sessions that each ran out on one machine? specweave handoff list shows them newest first, each with a short id (an increment's number such as 0874, or a worktree's folder name). Say "pick up 0874" or "pick up the studio release" to take a specific one; plain "pick up" takes the newest and lists the rest. Auto-handoff rules has the details.

To leave a message for whoever works on an increment next:

specweave note "Draft restore works; expiry not started" 0042

Hand off everything at once​

Switching subscriptions with a dozen threads in flight is one command:

specweave handoff --all --reason "switching accounts"

It writes .specweave/handoffs/<date>-INDEX.md and index.json with one row per active increment: tasks done, open acceptance criteria, last activity, what it waits on, and a resume prompt to paste into a new thread. In an umbrella workspace it also scans every checkout under repositories/<org>/<repo> and their worktrees, and lists each one with uncommitted files, unpushed commits or a branch with no remote, with the open PR for that branch when the GitHub CLI is installed. A checkout whose path or branch carries an increment's four-digit id is listed in that increment's row.

--all changes nothing else: no claims are released, no ledger events are written, and nothing is committed or pushed in the umbrella or the nested repos. --dry-run prints the index instead of writing it.

An increment waits on a person when its ledger has a wait line, such as {"t":"*","e":"wait","by":"claude@mbp","at":"2026-10-03T05:00:00Z","note":"Anton: typed go for the cutover"}, or its handoff.md has a Waits on: line. A wait with the note resolved clears the earlier ones.

On the other side:

specweave pickup --all

prints the newest index with the increments you can act on now first, then the ones waiting on a person, then the checkouts with local-only work. Then specweave pickup <id> for the one you start with.

specweave handoff never overwrites a handoff.md a person wrote (one without the generated <!-- Doc format v2 --> marker); the generated doc goes to handoff.auto.md beside it. Anything between <!-- keep --> and <!-- /keep --> in a generated doc survives the next handoff.

Hand off automatically​

On your own machine, SpecWeave can hand off for you before a session runs out:

specweave auto-handoff on                 # heads-up at 95% of any usage window
specweave auto-handoff on --mode enforce # or hand off there by itself
specweave auto-handoff on --at 90 # or pick your own threshold
specweave auto-handoff status
specweave auto-handoff off # restores your previous setup

At 95% of the fullest usage window, Claude Code and Codex tell you once that you can say "hand off" (in enforce mode they stop and run specweave handoff); when a Claude Code or Grok Build turn hits the limit outright, a hook writes the handoff itself. Then you say "pick up" in the next tool. Auto-handoff rules has the details for each tool, including what happens mid-task and in cloud sessions.

Who holds a task​

A task claim records the tool and host that made it, for example codex@my-laptop. SpecWeave detects Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot and Grok; set SPECWEAVE_TOOL to name anything else. specweave handoff releases your claims, so the next tool can claim the same tasks straight away. A claim that was never released expires after the lease (2 hours by default); before that, specweave task claim <id> --force takes it over.

Using it without the CLI​

Install the self-contained handoff skill so the capability reaches whichever tool you switch to:

npx vskill i handoff

It needs only git and a shell. If specweave is on your PATH it uses it; otherwise it writes a compatible handoff from your git state and a short interview.

Cross-tool resume matrix​

Every tool stores its session differently. The handoff document is portable across all of them; this table is for optionally recovering a tool's own native transcript.

ToolSession storageFind current sessionNative resume commandExport / transferable
Claude Code~/.claude/projects/<munged-cwd>/<uuid>.jsonlls ~/.claude/projects/<munged-cwd>/ (see munge rule below)claude -r <uuid>Not readable by other tools — use the handoff doc
Codex~/.codex/sessions/<uuid>/ls ~/.codex/sessions/ (newest dir)codex resume <uuid> (or codex resume --last)Not readable by other tools — use the handoff doc
OpenCodeSQLite-backed session storeopencode sessions listopencode -s <id> (long form opencode --session <id>)Not readable by other tools — use the handoff doc
Gemini CLITagged saved chatsrun /chat list inside the session/chat resume <tag>Not readable by other tools — use the handoff doc
AntigravityEncrypted .pbopen the Agent Manager, pick the prior task threadresume the thread from the Antigravity Agent ManagerEncrypted — use the handoff doc
CursorApp-internal chat historyopen the chat panel historyreopen the prior chat in-appNot exportable — use the handoff doc
Aider.aider.chat.history.md in repo rootthe file is in the repo rootaider --restore-chat-historyMarkdown file, but Aider-specific — use the handoff doc
Cline / RooVS Code extension storageopen the task list in the side panelreopen the prior task in-panelNot portable — use the handoff doc
WindsurfApp-internal Cascade historyopen the Cascade historyreopen the prior conversation in-appNot portable — use the handoff doc
SpecWeave.specweave/increments/{id}/handoff.md + ledger.jsonl, in gitspecweave pickupspecweave pickupPortable by design: any tool, any account

The Claude Code munge rule​

Claude Code session files live under ~/.claude/projects/<munged-cwd>/, where the working directory is munged by replacing every non-alphanumeric character with -, and runs are not collapsed — so a leading slash and adjacent separators each become their own dash. For example:

/Users/antonabyzov/Projects/github/specweave-umb/.claude-worktrees/x
→ -Users-antonabyzov-Projects-github-specweave-umb--claude-worktrees-x

The /. between umb and claude-worktrees yields the double dash.

Evidence: a recorded handoff​

This is a real run of the 3.0 CLI across two clones of one repository, with nothing copied between them except through git. The first clone ran as a Claude Code cloud session: it finished T-01, started T-02, left a note and handed off.

$ specweave task done T-01 --run "npm test"
Done T-01 (1/2) — evidence: npm test → exit 0
$ specweave handoff --reason "out of tokens" --next "finish restore on return"
Handed off 0001-resumable-checkout (released T-02, pushed main, pushed your uncommitted edits).
To continue in any tool, machine or account, say "pick up" there (or run `specweave pickup`).

The second clone ran as Codex. One command brought in the handoff and printed the next task:

$ specweave pickup
Picked up the handoff from claude@cloud 0m ago (out of tokens): applied 7 uncommitted files.
SpecWeave pickup · you are codex@laptop
Increment 0001-resumable-checkout "Resumable checkout" (active) · tasks 1/2 done · ACs 0/2 met
Next: T-02 Restore the draft on return
AC-01: Returning within 24 hours restores the cart and shipping choice
AC-02: A paid order is never restored
Files: src/restore.js | Test: npm test
claim: specweave task claim T-02 0001-resumable-checkout
Spec: .specweave/increments/0001-resumable-checkout/spec.md
Branch: main @ 76b1964 · in sync with origin/main · 3 uncommitted files
Last handoff: claude@cloud 0m ago: out of tokens · next: finish restore on return
Notes:
- claude@cloud 0m ago: Payment thread: drafts must never store card data

Codex then claimed T-02, finished it with specweave task done T-02 --run "npm test", and specweave verify reported both acceptance criteria met. specweave report wrote an HTML timeline of the whole run from the ledger: open the recorded report.


See also​