claude-code-handoff 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hugo Capitelli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # claude-code-handoff
2
+
3
+ Session continuity for [Claude Code](https://docs.anthropic.com/en/docs/claude-code). Pick up exactly where you left off — across `/clear`, crashes, or context switches.
4
+
5
+ ## What it does
6
+
7
+ Adds 4 slash commands to any Claude Code project:
8
+
9
+ | Command | Description |
10
+ |---------|-------------|
11
+ | `/handoff` | Auto-save session state (no wizard, just save and go) |
12
+ | `/resume` | Resume from a saved session (interactive wizard) |
13
+ | `/save-handoff` | Save session state with options (interactive wizard) |
14
+ | `/switch-context <topic>` | Switch between parallel workstreams |
15
+
16
+ Session state is stored in `.claude/handoffs/` (gitignored by default) so each developer keeps their own context.
17
+
18
+ ## Install
19
+
20
+ ### Option A: npx (recommended)
21
+
22
+ ```bash
23
+ cd your-project
24
+ npx claude-code-handoff
25
+ ```
26
+
27
+ ### Option B: curl
28
+
29
+ ```bash
30
+ cd your-project
31
+ curl -fsSL https://raw.githubusercontent.com/hugocapitelli/claude-code-handoff/main/install.sh | bash
32
+ ```
33
+
34
+ ### Option C: clone & run
35
+
36
+ ```bash
37
+ git clone https://github.com/hugocapitelli/claude-code-handoff.git /tmp/claude-code-handoff
38
+ cd your-project
39
+ /tmp/claude-code-handoff/install.sh
40
+ ```
41
+
42
+ ## What gets installed
43
+
44
+ ```
45
+ your-project/
46
+ └── .claude/
47
+ ├── commands/
48
+ │ ├── handoff.md # /handoff command (auto-save)
49
+ │ ├── resume.md # /resume command
50
+ │ ├── save-handoff.md # /save-handoff command
51
+ │ └── switch-context.md # /switch-context command
52
+ ├── rules/
53
+ │ └── session-continuity.md # Auto-loaded rules for Claude
54
+ └── handoffs/ # Session state (gitignored)
55
+ ├── _active.md # Current workstream
56
+ └── archive/ # Paused workstreams
57
+ ```
58
+
59
+ The installer also:
60
+ - Adds `.claude/handoffs/` to `.gitignore`
61
+ - Adds a `Session Continuity` section to `.claude/CLAUDE.md` (creates one if missing)
62
+
63
+ ## Usage
64
+
65
+ ### Quick save before clearing
66
+
67
+ ```
68
+ > /handoff
69
+ # Claude auto-saves current context to .claude/handoffs/_active.md
70
+ > /clear
71
+ ```
72
+
73
+ ### Save with options
74
+
75
+ ```
76
+ > /save-handoff
77
+ # Interactive wizard: update active, save as new context, or replace
78
+ ```
79
+
80
+ ### Resume next session
81
+
82
+ ```
83
+ > /resume
84
+ # Interactive wizard shows available sessions
85
+ # Select one → Claude loads full context and shows next steps
86
+ ```
87
+
88
+ ### Switch workstreams
89
+
90
+ ```
91
+ > /switch-context auth-refactor
92
+ # Archives current session, loads auth-refactor context
93
+ ```
94
+
95
+ ## How it works
96
+
97
+ The handoff file (`.claude/handoffs/_active.md`) captures:
98
+
99
+ - **Active Workstream** — what you're working on
100
+ - **Active Agent(s)** — which agents/personas are active
101
+ - **What Was Done** — session-by-session log of completed work
102
+ - **What's Next** — prioritized pending items
103
+ - **Key Files** — important files for context reload
104
+ - **Decisions Registry** — architectural decisions made
105
+
106
+ When you `/resume`, Claude reads this file and presents a summary so you can continue exactly where you left off.
107
+
108
+ The `_active.md` file acts like `HEAD` in git — it points to your current workstream. The `archive/` folder holds paused workstreams you can switch to anytime with `/switch-context`.
109
+
110
+ ## Uninstall
111
+
112
+ ```bash
113
+ cd your-project
114
+ curl -fsSL https://raw.githubusercontent.com/hugocapitelli/claude-code-handoff/main/uninstall.sh | bash
115
+ ```
116
+
117
+ Or manually remove:
118
+ ```bash
119
+ rm -rf .claude/commands/handoff.md .claude/commands/resume.md .claude/commands/save-handoff.md .claude/commands/switch-context.md
120
+ rm -rf .claude/rules/session-continuity.md
121
+ rm -rf .claude/handoffs/
122
+ ```
123
+
124
+ ## Requirements
125
+
126
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI installed
127
+ - A project directory with (or without) an existing `.claude/` folder
128
+
129
+ ## License
130
+
131
+ MIT
package/cli.js ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const GREEN = '\x1b[32m';
7
+ const YELLOW = '\x1b[33m';
8
+ const CYAN = '\x1b[36m';
9
+ const NC = '\x1b[0m';
10
+
11
+ const PROJECT_DIR = process.cwd();
12
+ const CLAUDE_DIR = path.join(PROJECT_DIR, '.claude');
13
+ const SCRIPT_DIR = __dirname;
14
+
15
+ console.log('');
16
+ console.log(`${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
17
+ console.log(`${CYAN} claude-code-handoff — Session Continuity${NC}`);
18
+ console.log(`${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
19
+ console.log('');
20
+ console.log(` Project: ${GREEN}${PROJECT_DIR}${NC}`);
21
+ console.log('');
22
+
23
+ // Helper
24
+ function ensureDir(dir) {
25
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
26
+ }
27
+
28
+ function copyFile(src, dst) {
29
+ const srcPath = path.join(SCRIPT_DIR, src);
30
+ if (fs.existsSync(srcPath)) {
31
+ fs.copyFileSync(srcPath, dst);
32
+ } else {
33
+ console.error(` Error: ${src} not found in package`);
34
+ process.exit(1);
35
+ }
36
+ }
37
+
38
+ // 1. Create directories
39
+ console.log(` ${YELLOW}[1/7]${NC} Creating directories...`);
40
+ ensureDir(path.join(CLAUDE_DIR, 'commands'));
41
+ ensureDir(path.join(CLAUDE_DIR, 'rules'));
42
+ ensureDir(path.join(CLAUDE_DIR, 'handoffs', 'archive'));
43
+
44
+ // 2. Copy commands
45
+ console.log(` ${YELLOW}[2/7]${NC} Installing commands...`);
46
+ copyFile('commands/resume.md', path.join(CLAUDE_DIR, 'commands', 'resume.md'));
47
+ copyFile('commands/save-handoff.md', path.join(CLAUDE_DIR, 'commands', 'save-handoff.md'));
48
+ copyFile('commands/switch-context.md', path.join(CLAUDE_DIR, 'commands', 'switch-context.md'));
49
+ copyFile('commands/handoff.md', path.join(CLAUDE_DIR, 'commands', 'handoff.md'));
50
+
51
+ // 3. Copy rules
52
+ console.log(` ${YELLOW}[3/7]${NC} Installing rules...`);
53
+ copyFile('rules/session-continuity.md', path.join(CLAUDE_DIR, 'rules', 'session-continuity.md'));
54
+
55
+ // 4. Create initial _active.md
56
+ const activePath = path.join(CLAUDE_DIR, 'handoffs', '_active.md');
57
+ if (!fs.existsSync(activePath)) {
58
+ console.log(` ${YELLOW}[4/7]${NC} Creating initial handoff...`);
59
+ fs.writeFileSync(activePath, `# Session Handoff
60
+
61
+ > No active session yet. Use \`/handoff\` or \`/save-handoff\` to save your first session state.
62
+
63
+ ## Last Updated
64
+ (not started)
65
+
66
+ ## Active Workstream
67
+ (none)
68
+
69
+ ## Active Agent(s)
70
+ (none)
71
+
72
+ ## What Was Done
73
+ (nothing yet)
74
+
75
+ ## What's Next
76
+ (define your first task)
77
+
78
+ ## Key Files
79
+ (none)
80
+
81
+ ## Decisions Registry
82
+ (none)
83
+ `);
84
+ } else {
85
+ console.log(` ${YELLOW}[4/7]${NC} Handoff already exists, keeping it`);
86
+ }
87
+
88
+ // 5. Update .gitignore
89
+ console.log(` ${YELLOW}[5/7]${NC} Updating .gitignore...`);
90
+ const gitignorePath = path.join(PROJECT_DIR, '.gitignore');
91
+ if (fs.existsSync(gitignorePath)) {
92
+ const content = fs.readFileSync(gitignorePath, 'utf-8');
93
+ if (!content.includes('.claude/handoffs/')) {
94
+ fs.appendFileSync(gitignorePath, '\n# claude-code-handoff (personal session state)\n.claude/handoffs/\n');
95
+ }
96
+ } else {
97
+ fs.writeFileSync(gitignorePath, '# claude-code-handoff (personal session state)\n.claude/handoffs/\n');
98
+ }
99
+
100
+ // 6. Update CLAUDE.md
101
+ console.log(` ${YELLOW}[6/7]${NC} Updating CLAUDE.md...`);
102
+ const claudeMdPath = path.join(CLAUDE_DIR, 'CLAUDE.md');
103
+ const continuityBlock = `## Session Continuity (MANDATORY)
104
+
105
+ At the START of every session, read \`.claude/handoffs/_active.md\` to recover context from prior sessions.
106
+ During work, update the handoff proactively after significant milestones.
107
+ Use \`/handoff\` before \`/clear\`. Use \`/resume\` to pick up. Use \`/switch-context <topic>\` to switch workstreams.`;
108
+
109
+ if (fs.existsSync(claudeMdPath)) {
110
+ const content = fs.readFileSync(claudeMdPath, 'utf-8');
111
+ if (!content.includes('Session Continuity')) {
112
+ const lines = content.split('\n');
113
+ const firstHeadingIdx = lines.findIndex(l => l.startsWith('# '));
114
+ if (firstHeadingIdx >= 0) {
115
+ lines.splice(firstHeadingIdx + 1, 0, '', continuityBlock, '');
116
+ fs.writeFileSync(claudeMdPath, lines.join('\n'));
117
+ } else {
118
+ fs.appendFileSync(claudeMdPath, '\n' + continuityBlock + '\n');
119
+ }
120
+ }
121
+ } else {
122
+ fs.writeFileSync(claudeMdPath, `# Project Rules\n\n${continuityBlock}\n`);
123
+ }
124
+
125
+ // 7. Verify
126
+ console.log(` ${YELLOW}[7/7]${NC} Verifying installation...`);
127
+ let installed = 0;
128
+ for (const f of ['resume.md', 'save-handoff.md', 'switch-context.md', 'handoff.md']) {
129
+ if (fs.existsSync(path.join(CLAUDE_DIR, 'commands', f))) installed++;
130
+ }
131
+
132
+ console.log('');
133
+ if (installed === 4) {
134
+ console.log(`${GREEN} Installed successfully! (${installed}/4 commands)${NC}`);
135
+ } else {
136
+ console.log(`${YELLOW} Partial install: ${installed}/4 commands${NC}`);
137
+ }
138
+ console.log('');
139
+ console.log(' Commands available:');
140
+ console.log(` ${CYAN}/handoff${NC} Auto-save session (no wizard)`);
141
+ console.log(` ${CYAN}/resume${NC} Resume with wizard`);
142
+ console.log(` ${CYAN}/save-handoff${NC} Save session state (wizard)`);
143
+ console.log(` ${CYAN}/switch-context${NC} Switch workstream`);
144
+ console.log('');
145
+ console.log(' Files:');
146
+ console.log(' .claude/commands/ 4 command files');
147
+ console.log(' .claude/rules/ session-continuity.md');
148
+ console.log(' .claude/handoffs/ session state (gitignored)');
149
+ console.log('');
150
+ console.log(` ${YELLOW}Start Claude Code and use /resume to begin.${NC}`);
151
+ console.log('');
@@ -0,0 +1,118 @@
1
+ # Auto Handoff
2
+
3
+ Automatically save session state and prepare for context clear. No wizard — just save and go.
4
+
5
+ ## Instructions
6
+
7
+ ### Step 1: Analyze conversation
8
+
9
+ Scan the full conversation and extract:
10
+ - **Workstream name**: The project/feature/topic being worked on
11
+ - **Active Agent(s)**: Any agent personas active (e.g., @dev, @architect) or "none"
12
+ - **What Was Done**: All concrete actions completed THIS session (files created/modified, decisions made, features implemented, bugs fixed)
13
+ - **What's Next**: Unfinished work, pending items, logical next steps
14
+ - **Key Files**: Every file that was created, modified, or is essential to resume
15
+ - **Current Document**: The main file being worked on (if any)
16
+ - **Decisions**: Any architectural or design decisions made
17
+
18
+ Be thorough — this is the only record of the session.
19
+
20
+ ### Step 2: Determine save target
21
+
22
+ 1. Read `.claude/handoffs/_active.md` (if it exists)
23
+ 2. Check if it has real content (not the default placeholder)
24
+
25
+ **If active handoff exists with content:**
26
+ - Compare the active workstream name with what was worked on this session
27
+ - If same workstream: **append** to existing handoff (preserve session history)
28
+ - If different workstream: **archive** the old one, create new active
29
+
30
+ **If no active handoff or placeholder only:**
31
+ - Create new active handoff
32
+
33
+ **If `$ARGUMENTS` is provided:**
34
+ - Use it as the workstream name/slug
35
+ - Save directly without comparison logic
36
+
37
+ ### Step 3: Write the handoff
38
+
39
+ Ensure `.claude/handoffs/` and `.claude/handoffs/archive/` directories exist.
40
+
41
+ **When appending** to an existing handoff:
42
+ 1. Read the current `_active.md`
43
+ 2. Add a new session entry under "## What Was Done" with current date
44
+ 3. Update "## What's Next" (replace with current pending items)
45
+ 4. Merge new files into "## Key Files" (don't duplicate)
46
+ 5. Append any new decisions to "## Decisions Registry"
47
+ 6. Update "## Last Updated"
48
+
49
+ **When creating fresh:**
50
+ Write `.claude/handoffs/_active.md` with this template:
51
+
52
+ ```markdown
53
+ # Session Handoff
54
+
55
+ > Updated automatically. Read this to resume work after /clear.
56
+
57
+ ## Last Updated
58
+ [YYYY-MM-DD] — [brief description of session]
59
+
60
+ ## Active Workstream
61
+ **[workstream name]** — [one-line description]
62
+
63
+ ## Active Agent(s)
64
+ [agents or "none"]
65
+
66
+ ## Current Document
67
+ [main file path or "none"]
68
+
69
+ ## What Was Done
70
+
71
+ ### Session 1 ([YYYY-MM-DD])
72
+ - [concrete action 1]
73
+ - [concrete action 2]
74
+ - ...
75
+
76
+ ## What's Next
77
+ 1. [specific actionable item]
78
+ 2. [specific actionable item]
79
+ ...
80
+
81
+ ## Key Files
82
+ | File | Purpose |
83
+ |------|---------|
84
+ | path/to/file | what it does |
85
+
86
+ ## Decisions Registry
87
+ [decisions table or "(none)"]
88
+ ```
89
+
90
+ ### Step 4: Confirm and instruct
91
+
92
+ Output exactly this:
93
+
94
+ ```
95
+ ## Handoff saved
96
+
97
+ **Workstream:** [name]
98
+ **File:** `.claude/handoffs/_active.md`
99
+ **Recorded:** [count] actions done, [count] next steps
100
+
101
+ You can now type `/clear` to free context.
102
+ Then start a new session and use `/resume` to pick up where you left off.
103
+ ```
104
+
105
+ ## Design Rationale
106
+
107
+ This command exists because:
108
+ 1. **No wizard friction** — `/save-handoff` has a wizard for choosing where to save. `/handoff` just saves and goes.
109
+ 2. **Context-aware** — it appends to the active handoff if the workstream matches, or creates a new one if it doesn't.
110
+ 3. **Pre-clear workflow** — the natural flow is: work → `/handoff` → `/clear` → `/resume`.
111
+
112
+ ## Important
113
+ - Be THOROUGH — extract everything relevant from the conversation
114
+ - Be PRECISE — file paths, specific changes, exact error messages
115
+ - Be ACTIONABLE — next steps should be specific enough to execute cold
116
+ - NEVER delete existing handoff data — always append or archive
117
+ - Keep under 200 lines — summarize older sessions if handoff grows large
118
+ - If conversation is very short or trivial, still save (even a one-liner is better than nothing)
@@ -0,0 +1,75 @@
1
+ # Resume Session
2
+
3
+ Resume work from a previous session using the handoff system.
4
+
5
+ ## Instructions
6
+
7
+ ### Step 1: Discover all handoffs
8
+
9
+ 1. Check if `.claude/handoffs/_active.md` exists and has content (not the default placeholder)
10
+ 2. List all `.md` files in `.claude/handoffs/archive/`
11
+ 3. For each file found, read the first 10 lines to extract: **Active Workstream**, **Last Updated**, and the first line of **What's Next**
12
+
13
+ ### Step 2: Present wizard
14
+
15
+ Use the AskUserQuestion tool to present available handoffs as options.
16
+
17
+ Build the options list:
18
+ - If `_active.md` has content: add it as first option with label "(active) [workstream name]" and description showing last updated date + first pending item
19
+ - For each file in `archive/`: add as option with label "[workstream name]" and description showing last updated date + first pending item
20
+ - If NO handoffs exist at all, skip the wizard and tell the user: "No handoffs found. Use `/save-handoff` at the end of this session to create the first one."
21
+
22
+ Question: "Which session do you want to resume?"
23
+ Header: "Handoff"
24
+
25
+ ### Step 3: Load selected handoff
26
+
27
+ Once the user selects, read the full handoff file and extract:
28
+ - Active Workstream
29
+ - Active Agent(s)
30
+ - What Was Done (last session summary)
31
+ - What's Next (pending items)
32
+ - Key Files
33
+ - Decisions Registry (if any)
34
+
35
+ ### Step 4: Refresh context
36
+
37
+ If **Key Files** lists a main document (Current Document field), read the first 50 lines of it.
38
+
39
+ ### Step 5: Present context
40
+
41
+ ```
42
+ ## Resuming session
43
+
44
+ **Workstream:** [name]
45
+ **Agent(s):** [active agents]
46
+ **Document:** [main file]
47
+ **Last updated:** [date]
48
+
49
+ ### Last session summary
50
+ [3-5 lines from What Was Done, focusing on the MOST RECENT session entry]
51
+
52
+ ### Next steps
53
+ 1. [item from What's Next]
54
+ 2. [item]
55
+ ...
56
+
57
+ What would you like to do?
58
+ ```
59
+
60
+ ### Step 6: Wait
61
+
62
+ Wait for user instruction before proceeding.
63
+
64
+ ## Shortcut
65
+
66
+ If `$ARGUMENTS` is provided (e.g., `/resume auth-refactor`), skip the wizard:
67
+ - Look for `.claude/handoffs/archive/$ARGUMENTS.md` first
68
+ - If not found, check if `_active.md` workstream slug matches `$ARGUMENTS`
69
+ - If still not found, show the wizard with a note: "Handoff '$ARGUMENTS' not found. Choose from available:"
70
+
71
+ ## Important
72
+ - Do NOT activate any agent automatically — let the user decide
73
+ - Do NOT start working — only present context and wait
74
+ - If the handoff references an agent (e.g., @architect), mention it but don't activate
75
+ - The wizard should clearly show which is the ACTIVE handoff vs archived ones
@@ -0,0 +1,135 @@
1
+ # Save Handoff
2
+
3
+ Save the current session state for future resumption.
4
+
5
+ ## Instructions
6
+
7
+ ### Step 1: Analyze current session
8
+
9
+ Before showing the wizard, analyze the current conversation and extract:
10
+ - **Workstream name**: What project/feature/epic is being worked on
11
+ - **Active Agent(s)**: Which agent personas are active
12
+ - **What Was Done**: Concrete actions completed THIS session
13
+ - **What's Next**: Specific pending items
14
+ - **Key Files**: Files created, modified, or essential to read when resuming
15
+ - **Decisions Registry**: Any decisions made with IDs
16
+
17
+ ### Step 2: Present wizard
18
+
19
+ Use the AskUserQuestion tool to ask where to save.
20
+
21
+ **Discover existing handoffs first:**
22
+ 1. Check if `.claude/handoffs/_active.md` exists and extract its workstream name
23
+ 2. List files in `.claude/handoffs/archive/` to show existing contexts
24
+
25
+ **Present options:**
26
+
27
+ Question: "Where should this session's handoff be saved?"
28
+ Header: "Target"
29
+
30
+ Options (build dynamically):
31
+ 1. **Label:** "Update active ([workstream name])" — **Description:** "Append this session to the current active handoff. Use when working on the same context."
32
+ 2. **Label:** "Save as new context" — **Description:** "Create a separate handoff. Use when working on something different from the active context."
33
+ 3. **Label:** "Replace active" — **Description:** "Discard the active handoff and create a new one with this session. Use when the active context is obsolete."
34
+
35
+ If `_active.md` does NOT exist or is the default placeholder, show only:
36
+ 1. **Label:** "Create handoff" — **Description:** "Create the first handoff for this project."
37
+ 2. **Label:** "Create with specific name" — **Description:** "Create handoff with a custom name to organize by topic."
38
+
39
+ ### Step 3: Execute based on choice
40
+
41
+ #### Choice: "Update active"
42
+ 1. Read `.claude/handoffs/_active.md`
43
+ 2. Append new session entry to "What Was Done" (preserve history)
44
+ 3. Update "What's Next", "Key Files", "Decisions Registry", "Last Updated"
45
+ 4. Write back to `.claude/handoffs/_active.md`
46
+
47
+ #### Choice: "Save as new context"
48
+ 1. Ask the user for a name using AskUserQuestion:
49
+ - Question: "Context name (will be the filename)?"
50
+ - Header: "Name"
51
+ - Options: suggest 2-3 slugs based on what was discussed (e.g., "auth-refactor", "bugfix-login"), plus "Other" for custom input
52
+ 2. If `_active.md` has content, move it to `archive/{current-slug}.md` first
53
+ 3. Create new `.claude/handoffs/_active.md` with this session's data
54
+ 4. Also save a copy to `archive/{chosen-name}.md`
55
+
56
+ #### Choice: "Replace active"
57
+ 1. If `_active.md` has content, move it to `archive/{current-slug}.md` (never lose data)
58
+ 2. Create fresh `.claude/handoffs/_active.md` with only this session's data
59
+
60
+ #### Choice: "Create handoff" (first time)
61
+ 1. Create `.claude/handoffs/_active.md` with this session's data
62
+
63
+ #### Choice: "Create with specific name" (first time)
64
+ 1. Ask for name (same as "Save as new context")
65
+ 2. Create `.claude/handoffs/_active.md` with this session's data
66
+ 3. Also save copy to `archive/{chosen-name}.md`
67
+
68
+ ### Step 4: Write the handoff
69
+
70
+ Use this structure for the handoff content:
71
+
72
+ ```markdown
73
+ # Session Handoff
74
+
75
+ > Updated automatically. Read this to resume work after /clear.
76
+
77
+ ## Last Updated
78
+ [current date and brief description]
79
+
80
+ ## Active Workstream
81
+ [workstream name and brief context]
82
+
83
+ ## Active Agent(s)
84
+ [agent names and roles]
85
+
86
+ ## Current Document
87
+ [main file being worked on, if any]
88
+
89
+ ## What Was Done
90
+
91
+ ### Session [N] ([date])
92
+ [bullet points of concrete actions — be specific, not vague]
93
+
94
+ ### Session [N-1] ([date])
95
+ [preserve previous sessions — don't delete history]
96
+
97
+ ## What's Next
98
+ 1. [specific actionable item]
99
+ 2. [specific actionable item]
100
+ ...
101
+
102
+ ## Key Files
103
+ | File | Purpose |
104
+ |------|---------|
105
+ | path/to/file | what it is |
106
+
107
+ ## Decisions Registry
108
+ | # | Decision | Choice | Justification |
109
+ |---|----------|--------|---------------|
110
+ | D1 | ... | ... | ... |
111
+ ```
112
+
113
+ ### Step 5: Confirm
114
+
115
+ ```
116
+ Handoff saved to [path]
117
+ - [1-line summary of what was recorded]
118
+ - Next steps: [count] pending items
119
+ - Available contexts: [list of all handoff names]
120
+ ```
121
+
122
+ ## Shortcut
123
+
124
+ If `$ARGUMENTS` is provided:
125
+ - If it matches an existing archive name: update that specific archive file directly (skip wizard)
126
+ - Otherwise: treat as the name for a new context (skip wizard, go to "Save as new context" flow)
127
+
128
+ ## Important
129
+ - NEVER delete or overwrite without archiving first — always move to archive/
130
+ - PRESERVE session history — append, don't replace
131
+ - Be PRECISE — file paths, decision IDs, specific changes
132
+ - Be ACTIONABLE — someone reading cold should know exactly what to do
133
+ - Keep CONCISE — target <200 lines per handoff
134
+ - If a handoff exceeds 300 lines, summarize older sessions into "Prior Sessions Summary"
135
+ - Slug derivation: lowercase, trim, replace spaces/special chars with hyphens, max 40 chars
@@ -0,0 +1,65 @@
1
+ # Switch Context
2
+
3
+ Switch between workstreams by archiving the current handoff and loading another.
4
+
5
+ ## Instructions
6
+
7
+ **Argument required:** `$ARGUMENTS` must contain the target workstream name (e.g., `auth-refactor`).
8
+
9
+ If no argument provided, list available contexts and ask the user to choose:
10
+ 1. Read `.claude/handoffs/_active.md` and show its workstream name as "(active)"
11
+ 2. List all `.md` files in `.claude/handoffs/archive/` as available contexts
12
+ 3. Present as numbered list and wait for selection
13
+
14
+ ### Switch Flow
15
+
16
+ 1. **Read the current active handoff** at `.claude/handoffs/_active.md`
17
+ - Extract the workstream name from "## Active Workstream"
18
+ - Derive a slug from it (lowercase, spaces to hyphens, no special chars)
19
+ - Example: "Auth Refactor" → `auth-refactor`
20
+
21
+ 2. **Archive the current handoff:**
22
+ - Copy `.claude/handoffs/_active.md` → `.claude/handoffs/archive/{slug}.md`
23
+ - This preserves the current state before switching
24
+
25
+ 3. **Load the target handoff:**
26
+ - Look for `.claude/handoffs/archive/$ARGUMENTS.md`
27
+ - If found: copy it → `.claude/handoffs/_active.md` and delete the archive copy
28
+ - If NOT found: create a fresh `.claude/handoffs/_active.md` with the target name as Active Workstream (new context)
29
+
30
+ 4. **Present the switch result:**
31
+
32
+ ```
33
+ ## Context switched
34
+
35
+ **From:** [previous workstream] → archived to `.claude/handoffs/archive/{slug}.md`
36
+ **To:** [new workstream]
37
+
38
+ ### New context state
39
+ [summary from the loaded handoff — What Was Done + What's Next]
40
+
41
+ What would you like to do?
42
+ ```
43
+
44
+ 5. **Wait for user instruction.**
45
+
46
+ ## Examples
47
+
48
+ ```
49
+ /switch-context auth-refactor
50
+ → Archives current handoff
51
+ → Loads auth-refactor handoff
52
+ → Shows auth-refactor context
53
+
54
+ /switch-context new-feature-payments
55
+ → Archives current handoff
56
+ → No archive found for "new-feature-payments"
57
+ → Creates fresh handoff with that name
58
+ → Shows empty context, asks what to work on
59
+ ```
60
+
61
+ ## Important
62
+ - ALWAYS archive before switching — never lose state
63
+ - The archive acts as a "stack" of paused workstreams
64
+ - Users can have unlimited archived contexts
65
+ - Slug derivation: lowercase, trim, replace spaces/special chars with hyphens
package/install.sh ADDED
@@ -0,0 +1,178 @@
1
+ #!/bin/bash
2
+ # claude-code-handoff — Session continuity for Claude Code
3
+ # Install: curl -fsSL https://raw.githubusercontent.com/hugocapitelli/claude-code-handoff/main/install.sh | bash
4
+ #
5
+ # Or clone and run:
6
+ # git clone https://github.com/hugocapitelli/claude-code-handoff.git /tmp/claude-code-handoff
7
+ # cd /your/project && /tmp/claude-code-handoff/install.sh
8
+
9
+ set -e
10
+
11
+ # Colors
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ CYAN='\033[0;36m'
15
+ NC='\033[0m'
16
+
17
+ REPO="hugocapitelli/claude-code-handoff"
18
+ BRANCH="main"
19
+ RAW_BASE="https://raw.githubusercontent.com/$REPO/$BRANCH"
20
+ PROJECT_DIR="$(pwd)"
21
+ CLAUDE_DIR="$PROJECT_DIR/.claude"
22
+
23
+ echo ""
24
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
25
+ echo -e "${CYAN} claude-code-handoff — Session Continuity${NC}"
26
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
27
+ echo ""
28
+ echo -e " Project: ${GREEN}$PROJECT_DIR${NC}"
29
+ echo ""
30
+
31
+ # Detect if running from cloned repo or via curl
32
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" 2>/dev/null)" 2>/dev/null && pwd 2>/dev/null || echo "")"
33
+
34
+ download_file() {
35
+ local src="$1"
36
+ local dst="$2"
37
+
38
+ # If running from cloned repo, copy locally
39
+ if [ -n "$SCRIPT_DIR" ] && [ -f "$SCRIPT_DIR/$src" ]; then
40
+ cp "$SCRIPT_DIR/$src" "$dst"
41
+ else
42
+ # Download from GitHub
43
+ curl -fsSL "$RAW_BASE/$src" -o "$dst"
44
+ fi
45
+ }
46
+
47
+ # 1. Create directories
48
+ echo -e " ${YELLOW}[1/7]${NC} Creating directories..."
49
+ mkdir -p "$CLAUDE_DIR/commands"
50
+ mkdir -p "$CLAUDE_DIR/rules"
51
+ mkdir -p "$CLAUDE_DIR/handoffs/archive"
52
+
53
+ # 2. Download/copy commands
54
+ echo -e " ${YELLOW}[2/7]${NC} Installing commands..."
55
+ download_file "commands/resume.md" "$CLAUDE_DIR/commands/resume.md"
56
+ download_file "commands/save-handoff.md" "$CLAUDE_DIR/commands/save-handoff.md"
57
+ download_file "commands/switch-context.md" "$CLAUDE_DIR/commands/switch-context.md"
58
+ download_file "commands/handoff.md" "$CLAUDE_DIR/commands/handoff.md"
59
+
60
+ # 3. Download/copy rules
61
+ echo -e " ${YELLOW}[3/7]${NC} Installing rules..."
62
+ download_file "rules/session-continuity.md" "$CLAUDE_DIR/rules/session-continuity.md"
63
+
64
+ # 4. Create initial _active.md if not exists
65
+ if [ ! -f "$CLAUDE_DIR/handoffs/_active.md" ]; then
66
+ echo -e " ${YELLOW}[4/7]${NC} Creating initial handoff..."
67
+ cat > "$CLAUDE_DIR/handoffs/_active.md" << 'HANDOFF'
68
+ # Session Handoff
69
+
70
+ > No active session yet. Use `/handoff` or `/save-handoff` to save your first session state.
71
+
72
+ ## Last Updated
73
+ (not started)
74
+
75
+ ## Active Workstream
76
+ (none)
77
+
78
+ ## Active Agent(s)
79
+ (none)
80
+
81
+ ## What Was Done
82
+ (nothing yet)
83
+
84
+ ## What's Next
85
+ (define your first task)
86
+
87
+ ## Key Files
88
+ (none)
89
+
90
+ ## Decisions Registry
91
+ (none)
92
+ HANDOFF
93
+ else
94
+ echo -e " ${YELLOW}[4/7]${NC} Handoff already exists, keeping it"
95
+ fi
96
+
97
+ # 5. Add to .gitignore
98
+ echo -e " ${YELLOW}[5/7]${NC} Updating .gitignore..."
99
+ GITIGNORE="$PROJECT_DIR/.gitignore"
100
+ if [ -f "$GITIGNORE" ]; then
101
+ if ! grep -q ".claude/handoffs/" "$GITIGNORE" 2>/dev/null; then
102
+ echo "" >> "$GITIGNORE"
103
+ echo "# claude-code-handoff (personal session state)" >> "$GITIGNORE"
104
+ echo ".claude/handoffs/" >> "$GITIGNORE"
105
+ fi
106
+ else
107
+ echo "# claude-code-handoff (personal session state)" > "$GITIGNORE"
108
+ echo ".claude/handoffs/" >> "$GITIGNORE"
109
+ fi
110
+
111
+ # 6. Add to CLAUDE.md
112
+ echo -e " ${YELLOW}[6/7]${NC} Updating CLAUDE.md..."
113
+ CLAUDE_MD="$CLAUDE_DIR/CLAUDE.md"
114
+ CONTINUITY_BLOCK='## Session Continuity (MANDATORY)
115
+
116
+ At the START of every session, read `.claude/handoffs/_active.md` to recover context from prior sessions.
117
+ During work, update the handoff proactively after significant milestones.
118
+ Use `/handoff` before `/clear`. Use `/resume` to pick up. Use `/switch-context <topic>` to switch workstreams.'
119
+
120
+ if [ -f "$CLAUDE_MD" ]; then
121
+ if ! grep -q "Session Continuity" "$CLAUDE_MD" 2>/dev/null; then
122
+ TEMP_FILE=$(mktemp)
123
+ awk '
124
+ /^# / && !done {
125
+ print
126
+ print ""
127
+ print "## Session Continuity (MANDATORY)"
128
+ print ""
129
+ print "At the START of every session, read `.claude/handoffs/_active.md` to recover context from prior sessions."
130
+ print "During work, update the handoff proactively after significant milestones."
131
+ print "Use `/handoff` before `/clear`. Use `/resume` to pick up. Use `/switch-context <topic>` to switch workstreams."
132
+ print ""
133
+ done=1
134
+ next
135
+ }
136
+ { print }
137
+ ' "$CLAUDE_MD" > "$TEMP_FILE"
138
+ mv "$TEMP_FILE" "$CLAUDE_MD"
139
+ fi
140
+ else
141
+ cat > "$CLAUDE_MD" << 'CLAUDEMD'
142
+ # Project Rules
143
+
144
+ ## Session Continuity (MANDATORY)
145
+
146
+ At the START of every session, read `.claude/handoffs/_active.md` to recover context from prior sessions.
147
+ During work, update the handoff proactively after significant milestones.
148
+ Use `/handoff` before `/clear`. Use `/resume` to pick up. Use `/switch-context <topic>` to switch workstreams.
149
+ CLAUDEMD
150
+ fi
151
+
152
+ # 7. Summary
153
+ echo -e " ${YELLOW}[7/7]${NC} Verifying installation..."
154
+ INSTALLED=0
155
+ for f in resume.md save-handoff.md switch-context.md handoff.md; do
156
+ [ -f "$CLAUDE_DIR/commands/$f" ] && INSTALLED=$((INSTALLED + 1))
157
+ done
158
+
159
+ echo ""
160
+ if [ "$INSTALLED" -eq 4 ]; then
161
+ echo -e "${GREEN} Installed successfully! ($INSTALLED/4 commands)${NC}"
162
+ else
163
+ echo -e "${YELLOW} Partial install: $INSTALLED/4 commands${NC}"
164
+ fi
165
+ echo ""
166
+ echo -e " Commands available:"
167
+ echo -e " ${CYAN}/handoff${NC} Auto-save session (no wizard)"
168
+ echo -e " ${CYAN}/resume${NC} Resume with wizard"
169
+ echo -e " ${CYAN}/save-handoff${NC} Save session state (wizard)"
170
+ echo -e " ${CYAN}/switch-context${NC} Switch workstream"
171
+ echo ""
172
+ echo -e " Files:"
173
+ echo -e " .claude/commands/ 4 command files"
174
+ echo -e " .claude/rules/ session-continuity.md"
175
+ echo -e " .claude/handoffs/ session state (gitignored)"
176
+ echo ""
177
+ echo -e " ${YELLOW}Start Claude Code and use /resume to begin.${NC}"
178
+ echo ""
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "claude-code-handoff",
3
+ "version": "1.1.0",
4
+ "description": "Session continuity for Claude Code — 4 slash commands to save, resume, and switch workstreams across /clear",
5
+ "bin": {
6
+ "claude-code-handoff": "./cli.js"
7
+ },
8
+ "keywords": [
9
+ "claude",
10
+ "claude-code",
11
+ "handoff",
12
+ "session",
13
+ "continuity",
14
+ "ai",
15
+ "context"
16
+ ],
17
+ "author": "Hugo Capitelli",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/hugocapitelli/claude-code-handoff"
22
+ }
23
+ }
@@ -0,0 +1,27 @@
1
+ ---
2
+ paths: **/*
3
+ ---
4
+
5
+ # Session Continuity Rules
6
+
7
+ ## Handoff System
8
+
9
+ This project uses a handoff system for session continuity. Handoff files are stored in `.claude/handoffs/`.
10
+
11
+ ### On Session Start
12
+ - If `.claude/handoffs/_active.md` exists and has content, be aware of it but do NOT read it automatically unless the user invokes `/resume` or says "continue"/"resume"
13
+
14
+ ### During Work
15
+ - After completing significant milestones (major edits, decisions made, features implemented), proactively update the handoff by writing to `.claude/handoffs/_active.md`
16
+ - If the session has been going for a while and substantial work was done, remind the user: "Want me to save the handoff before continuing?"
17
+
18
+ ### Handoff Structure
19
+ - `_active.md` — current active workstream (the ONE thing being worked on now)
20
+ - `archive/` — paused or completed workstreams (switched via `/switch-context`)
21
+
22
+ ### Commands Available
23
+ - `/resume` — resume from active handoff (interactive wizard)
24
+ - `/resume <topic>` — resume from a specific archived handoff
25
+ - `/save-handoff` — save current state (interactive wizard)
26
+ - `/switch-context <topic>` — switch workstream (archives current, loads target)
27
+ - `/handoff` — auto-save session state (no wizard, just save and go)
package/uninstall.sh ADDED
@@ -0,0 +1,82 @@
1
+ #!/bin/bash
2
+ # claude-code-handoff — Uninstall
3
+ # Usage: curl -fsSL https://raw.githubusercontent.com/hugocapitelli/claude-code-handoff/main/uninstall.sh | bash
4
+
5
+ set -e
6
+
7
+ RED='\033[0;31m'
8
+ GREEN='\033[0;32m'
9
+ YELLOW='\033[1;33m'
10
+ CYAN='\033[0;36m'
11
+ NC='\033[0m'
12
+
13
+ PROJECT_DIR="$(pwd)"
14
+ CLAUDE_DIR="$PROJECT_DIR/.claude"
15
+
16
+ echo ""
17
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
18
+ echo -e "${CYAN} claude-code-handoff — Uninstall${NC}"
19
+ echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
20
+ echo ""
21
+ echo -e " Project: ${GREEN}$PROJECT_DIR${NC}"
22
+ echo ""
23
+
24
+ if [ ! -d "$CLAUDE_DIR" ]; then
25
+ echo -e " ${RED}No .claude/ directory found. Nothing to uninstall.${NC}"
26
+ exit 0
27
+ fi
28
+
29
+ # 1. Remove commands
30
+ echo -e " ${YELLOW}[1/4]${NC} Removing commands..."
31
+ rm -f "$CLAUDE_DIR/commands/handoff.md"
32
+ rm -f "$CLAUDE_DIR/commands/resume.md"
33
+ rm -f "$CLAUDE_DIR/commands/save-handoff.md"
34
+ rm -f "$CLAUDE_DIR/commands/switch-context.md"
35
+ # Also remove legacy Portuguese commands if present
36
+ rm -f "$CLAUDE_DIR/commands/retomar.md"
37
+ rm -f "$CLAUDE_DIR/commands/salvar-handoff.md"
38
+ rm -f "$CLAUDE_DIR/commands/trocar-contexto.md"
39
+
40
+ # 2. Remove rules
41
+ echo -e " ${YELLOW}[2/4]${NC} Removing rules..."
42
+ rm -f "$CLAUDE_DIR/rules/session-continuity.md"
43
+
44
+ # 3. Remove handoffs (with confirmation)
45
+ if [ -d "$CLAUDE_DIR/handoffs" ]; then
46
+ # Check if there's actual content
47
+ ACTIVE_CONTENT=$(cat "$CLAUDE_DIR/handoffs/_active.md" 2>/dev/null || echo "")
48
+ if echo "$ACTIVE_CONTENT" | grep -q "No active session yet\|not started"; then
49
+ echo -e " ${YELLOW}[3/4]${NC} Removing handoffs (no session data)..."
50
+ rm -rf "$CLAUDE_DIR/handoffs"
51
+ else
52
+ echo -e " ${YELLOW}[3/4]${NC} ${RED}Handoffs contain session data!${NC}"
53
+ echo -e " Kept: .claude/handoffs/"
54
+ echo -e " Remove manually with: rm -rf .claude/handoffs/"
55
+ fi
56
+ else
57
+ echo -e " ${YELLOW}[3/4]${NC} No handoffs directory found"
58
+ fi
59
+
60
+ # 4. Clean .gitignore
61
+ echo -e " ${YELLOW}[4/4]${NC} Cleaning .gitignore..."
62
+ GITIGNORE="$PROJECT_DIR/.gitignore"
63
+ if [ -f "$GITIGNORE" ]; then
64
+ # Remove the handoff lines
65
+ sed -i.bak '/# claude-code-handoff/d; /^\.claude\/handoffs\/$/d' "$GITIGNORE"
66
+ rm -f "$GITIGNORE.bak"
67
+ # Remove trailing blank lines
68
+ sed -i.bak -e :a -e '/^\n*$/{$d;N;ba' -e '}' "$GITIGNORE"
69
+ rm -f "$GITIGNORE.bak"
70
+ fi
71
+
72
+ # Clean up empty directories
73
+ rmdir "$CLAUDE_DIR/commands" 2>/dev/null || true
74
+ rmdir "$CLAUDE_DIR/rules" 2>/dev/null || true
75
+ rmdir "$CLAUDE_DIR" 2>/dev/null || true
76
+
77
+ echo ""
78
+ echo -e "${GREEN} Uninstalled successfully!${NC}"
79
+ echo ""
80
+ echo -e " Note: Session Continuity section in CLAUDE.md was NOT removed."
81
+ echo -e " Edit .claude/CLAUDE.md manually if you want to remove it."
82
+ echo ""