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 +21 -0
- package/README.md +131 -0
- package/cli.js +151 -0
- package/commands/handoff.md +118 -0
- package/commands/resume.md +75 -0
- package/commands/save-handoff.md +135 -0
- package/commands/switch-context.md +65 -0
- package/install.sh +178 -0
- package/package.json +23 -0
- package/rules/session-continuity.md +27 -0
- package/uninstall.sh +82 -0
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 ""
|