EXPERIMENTAL companion of compact-handoff: supplies the replacement message for the compactions compact-handoff starts (a plugin cannot answer its own). Does…

<img src="https://github.com/REMvisual/claude-handoff/releases/download/v1.6.0/banner.png" alt="claude-handoff" width="900"/>
Never lose context between AI coding sessions.
Two skills for Claude Code that capture decisions, failed approaches, measurements, and next steps — so your next session picks up exactly where you left off. Stop wasting 20-40% of each session rediscovering what was already tried.
Now a Claude Code mod: /compact-handoff writes the handoff, swaps the conversation for it, and keeps working in the same terminal. No new window, no paste. Jump to the mod ↓
git clone https://github.com/REMvisual/claude-handoff.git
cp -r claude-handoff/skills/handoff ~/.claude/skills/
cp -r claude-handoff/skills/handoffplan ~/.claude/skills/
Verify: type /handoff in Claude Code — it should appear in autocomplete.
/handoff # Capture session context — next session explores
/handoffplan # Capture context + write a plan — next session executes
No arguments needed. The skill mines your full conversation, gathers git state, validates the output, and gives you a ready-to-paste resume prompt:
Read `plans/handoffs/HANDOFF_fix-auth-bug_2026-03-19.md` (seq 2, PROJ-abc1)
and continue from "Where We're Going".
Paste that into a fresh Claude Code session. It picks up the chain and starts working.
Every handoff captures a structured snapshot of your session:
┌─────────────────────────────────────────────────────┐
│ HANDOFF_fix-auth-bug_2026-03-19.md │
├─────────────────────────────────────────────────────┤
│ The Goal — what we're solving and why │
│ Where We Are — 15-25 bullets of current state│
│ What We Tried — every approach, chronological │
│ Key Decisions — what was chosen AND rejected │
│ Evidence & Data — real numbers, not summaries │
│ User Feedback — preferences, corrections, tone│
│ Where We're Going — ordered next steps │
│ Quick Start — exact commands for next session│
└─────────────────────────────────────────────────────┘
"What We Tried" is the most valuable section. Failed approaches are the most expensive thing to rediscover. This section captures every attempt — what was tried, what happened, why it was kept or abandoned — so the next session never repeats work.
/handoff vs /handoffplanBoth capture your session. The difference is what the next session does:
/handoff | /handoffplan | |
|---|---|---|
| When to use | Pausing mid-work | Done with research, ready to build |
| What it writes | Handoff file | Handoff + phased plan + tracked tasks |
| Next session | Reads handoff, onboards, explores | Reads plan, claims Phase 1, starts coding |
| Paste prompt | "Continue from Where We're Going" | "Execute the plan starting at Phase 1" |
/handoffplan creates beads (or tasks in your tracker) with dependency chains between phases, anti-goals from failed approaches, rollback strategies, and success criteria tied to real numbers from the session.
Handoffs link across sessions automatically:
HANDOFF_fix-auth_2026-03-17.md (seq 1)
└─ HANDOFF_fix-auth_2026-03-18.md (seq 2)
└─ HANDOFF_fix-auth_2026-03-19.md (seq 3)
Your third session on a feature knows about the first two.
Claude already generates session summaries when context compresses. They look like handoffs — but they lack chain tracking, self-validation, evidence mining, and comprehension gates. In controlled A/B testing (same bug, same codebase, fresh sessions), the skill-based session:
Without this, Claude may generate freeform "handoffs" when sessions end — documents that look right but skip the process. Add to your CLAUDE.md:
When ending a session or saving progress:
- ALWAYS use the /handoff skill. NEVER generate handoff summaries without it.
The skills work standalone. They unlock more when paired with:
bd (beads) as default — swap in Linear, Jira CLI, or GitHub Issues.Runs the handoff, then replaces the conversation with it and keeps going in the same terminal, with no new session and no paste. It works like /compact, but the summary is your validated handoff.
claude plugin marketplace add REMvisual/claude-handoff
claude plugin install compact-handoff@claude-handoff
This also installs its small companion, compact-handoff-answer (see below). The skills above must be installed too, from v2.1.0 or later.
/compact-handoff [note] # /handoff, then continue from "Where We're Going"
/compact-handoffplan [note] # /handoffplan, then start executing Phase 1
/compact-handoff cancel # drop a run that's stuck
What happens:
compact-mode: it asks nothing, commits the session's work, and writes the handoff (and plan).The mod also shows a one-time toast when context passes 70%, suggesting /compact-handoff.
Why two plugins: Claude Code doesn't let a plugin answer a compaction it started itself. compact-handoff-answer is about 20 lines. It answers only compactions marked compact-handoff:v1 and leaves every other compaction alone.
Caveats:
PreCompact hooks (including the one below) don't run on these compactions. SessionStart hooks with the compact matcher still do.Safety net that runs before context compaction, capturing ~50 lines of git state and active tasks.
cp claude-handoff/hooks/precompact-handoff.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/precompact-handoff.sh
rm -rf ~/.claude/skills/handoff ~/.claude/skills/handoffplan
claude plugin uninstall compact-handoff@claude-handoff
claude plugin prune # removes compact-handoff-answer, installed as its dependency
MIT — If this saved you time, give it a star.
hooks/register.ts 14 lines1// compact-handoff-answer: answers the compactions compact-handoff starts. The engine skips a
2// plugin's own hooks on an event that plugin raised, so the answer has to come from a second plugin.
3import type { Register } from 'claude-code'
4
5import { answerFor } from './answer'
6
7export const register: Register = on => {
8 on('session.compact', async ($, e, next) => {
9 const text = answerFor(e)
10 if (text === null) return next(e)
11 return { messages: [{ role: 'user', text, toolUses: [] }] }
12 }).catch(($, e, next) => next(e))
13}
14hooks/answer.ts 12 lines1// The whole protocol with compact-handoff: instructions = MARKER line + the message to install.
2export const MARKER = 'compact-handoff:v1'
3
4/** The message to install for this compaction, or null to leave it to the engine. */
5export function answerFor(e: { agentId?: string; instructions?: string }): string | null {
6 if (e.agentId || !e.instructions) return null
7 const [first = '', ...rest] =e.instructions.split('\n')
8 if (first.trim() !== MARKER) return null
9 const body = rest.join('\n').trim()
10 return body || null
11}
12