claude-code-handoff 1.5.1 → 1.7.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/README.md +20 -14
- package/cli.js +4 -3
- package/hooks/context-monitor.sh +52 -8
- package/install.sh +4 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ Instead of relying on lossy compression or starting from zero, **claude-code-han
|
|
|
49
49
|
|
|
50
50
|
The workflow becomes: work until context is full → `/handoff` → `/clear` → `/resume` → continue with full context. No degradation, no amnesia. Just clean handoffs.
|
|
51
51
|
|
|
52
|
-
**Auto-handoff** (since v1.4) monitors your context usage and **automatically triggers a handoff** when the transcript reaches a configurable threshold (default: **90%**) — so you never forget to save. Since v1.5, the threshold is configured as a **percentage of context** instead of fixed bytes
|
|
52
|
+
**Auto-handoff** (beta, since v1.4) monitors your context usage and **automatically triggers a handoff** when the transcript reaches a configurable threshold (default: **90%**) — so you never forget to save. Since v1.5, the threshold is configured as a **percentage of context** instead of fixed bytes. **Disabled by default** — enable it with `/auto-handoff` when you're ready to try it.
|
|
53
53
|
|
|
54
54
|
Session state is stored in `.claude/handoffs/` (gitignored) — each developer keeps their own context, no conflicts.
|
|
55
55
|
|
|
@@ -62,7 +62,7 @@ cd your-project
|
|
|
62
62
|
npx claude-code-handoff
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
That's it. Open Claude Code and your 6 commands are ready. Auto-handoff is
|
|
65
|
+
That's it. Open Claude Code and your 6 commands are ready. Auto-handoff is available but **disabled by default** (beta) — run `/auto-handoff` to enable it.
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
@@ -155,13 +155,15 @@ graph TD
|
|
|
155
155
|
|
|
156
156
|
---
|
|
157
157
|
|
|
158
|
-
## Auto-Handoff (Context Monitor)
|
|
158
|
+
## Auto-Handoff (Context Monitor) — Beta
|
|
159
159
|
|
|
160
160
|
The biggest risk with handoffs is **forgetting to save**. You're deep in a task, context fills up, and everything is lost. Auto-handoff eliminates this by monitoring your transcript size and **forcing Claude to save the handoff** before it's too late.
|
|
161
161
|
|
|
162
|
+
> **Note:** Auto-handoff is a beta feature and is **disabled by default**. Enable it with `/auto-handoff` inside Claude Code.
|
|
163
|
+
|
|
162
164
|
### How It Works
|
|
163
165
|
|
|
164
|
-
A [Claude Code hook](https://docs.anthropic.com/en/docs/claude-code/hooks) runs after every Claude response (Stop event). It
|
|
166
|
+
A [Claude Code hook](https://docs.anthropic.com/en/docs/claude-code/hooks) runs after every Claude response (Stop event). It reads the **actual token count** from Claude's API usage data in the JSONL transcript and compares it against the 200K token context window. When the threshold is exceeded, it **blocks** Claude's next action and forces an immediate handoff save.
|
|
165
167
|
|
|
166
168
|
```mermaid
|
|
167
169
|
flowchart TD
|
|
@@ -178,18 +180,21 @@ flowchart TD
|
|
|
178
180
|
|
|
179
181
|
### Threshold Configuration
|
|
180
182
|
|
|
181
|
-
The threshold is configured as a **percentage of the
|
|
183
|
+
The threshold is configured as a **percentage of the 200K token context window**. The hook reads the **actual token count** from Claude's API usage data in the transcript — no guesswork, no byte-to-token estimation.
|
|
182
184
|
|
|
183
185
|
| Preset | Value | Triggers at | Best for |
|
|
184
186
|
|--------|-------|-------------|----------|
|
|
185
|
-
| **90% (default)** | `THRESHOLD_PERCENT=90` |
|
|
186
|
-
| **80%** | `THRESHOLD_PERCENT=80` |
|
|
187
|
-
| **75%** | `THRESHOLD_PERCENT=75` |
|
|
187
|
+
| **90% (default)** | `THRESHOLD_PERCENT=90` | 180K tokens | Maximizing context usage |
|
|
188
|
+
| **80%** | `THRESHOLD_PERCENT=80` | 160K tokens | Balance between space and safety |
|
|
189
|
+
| **75%** | `THRESHOLD_PERCENT=75` | 150K tokens | Short sessions, early handoff |
|
|
188
190
|
|
|
189
|
-
The calculation
|
|
191
|
+
The calculation uses real data:
|
|
190
192
|
```
|
|
191
|
-
|
|
192
|
-
THRESHOLD =
|
|
193
|
+
MAX_CONTEXT_TOKENS = 200000 (Claude Code's context window)
|
|
194
|
+
THRESHOLD = MAX_CONTEXT_TOKENS × THRESHOLD_PERCENT / 100
|
|
195
|
+
|
|
196
|
+
# The hook reads input_tokens from the last assistant message in the JSONL
|
|
197
|
+
# This is the ACTUAL context size — not an estimate
|
|
193
198
|
```
|
|
194
199
|
|
|
195
200
|
### Three Ways to Configure
|
|
@@ -282,7 +287,8 @@ your-project/
|
|
|
282
287
|
│ └── auto-handoff.md ← Auto-handoff trigger rules
|
|
283
288
|
├── hooks/
|
|
284
289
|
│ ├── context-monitor.sh ← Stop hook (monitors context size)
|
|
285
|
-
│
|
|
290
|
+
│ ├── session-cleanup.sh ← SessionStart hook (cleans old flags)
|
|
291
|
+
│ └── .auto-handoff-disabled ← Disable flag (remove to enable)
|
|
286
292
|
├── settings.json ← Hook configuration
|
|
287
293
|
└── handoffs/ ← Session state (gitignored)
|
|
288
294
|
├── _active.md ← Current workstream
|
|
@@ -557,7 +563,7 @@ rm -rf .claude/handoffs/ # ⚠️ deletes all session history
|
|
|
557
563
|
A: Yes. Handoff files are gitignored, so each developer has their own session state. No conflicts.
|
|
558
564
|
|
|
559
565
|
**Q: What happens if I forget to `/handoff` before `/clear`?**
|
|
560
|
-
A:
|
|
566
|
+
A: If you've enabled auto-handoff (beta), Claude will automatically save the handoff when the context reaches the threshold. Without it, the context is lost for that session — the previous handoff is still there, but you won't have the latest session recorded.
|
|
561
567
|
|
|
562
568
|
**Q: Can I have unlimited workstreams?**
|
|
563
569
|
A: Yes. The `archive/` folder has no limit. Each workstream is a single `.md` file.
|
|
@@ -572,7 +578,7 @@ A: The commands automatically summarize older sessions into a "Prior Sessions Su
|
|
|
572
578
|
A: Absolutely. They're plain markdown. You can add notes, reorder next steps, or clean up history.
|
|
573
579
|
|
|
574
580
|
**Q: How does the auto-handoff threshold work?**
|
|
575
|
-
A: The threshold is a percentage of
|
|
581
|
+
A: The threshold is a percentage of Claude Code's 200K token context window. At 90% (default), the hook triggers at 180K tokens. The hook reads the **actual token count** from Claude's API usage data — not file size estimates. You can set any value from 1-100 via env var (`CLAUDE_CONTEXT_THRESHOLD=80`) or the `/auto-handoff` command.
|
|
576
582
|
|
|
577
583
|
**Q: Can I disable auto-handoff?**
|
|
578
584
|
A: Yes. Run `/auto-handoff` and select "Disable", or manually create the file `.claude/hooks/.auto-handoff-disabled`. Delete the file to re-enable.
|
package/cli.js
CHANGED
|
@@ -62,6 +62,8 @@ copyFile('hooks/context-monitor.sh', path.join(CLAUDE_DIR, 'hooks', 'context-mon
|
|
|
62
62
|
copyFile('hooks/session-cleanup.sh', path.join(CLAUDE_DIR, 'hooks', 'session-cleanup.sh'));
|
|
63
63
|
fs.chmodSync(path.join(CLAUDE_DIR, 'hooks', 'context-monitor.sh'), 0o755);
|
|
64
64
|
fs.chmodSync(path.join(CLAUDE_DIR, 'hooks', 'session-cleanup.sh'), 0o755);
|
|
65
|
+
// Auto-handoff disabled by default (beta feature)
|
|
66
|
+
fs.writeFileSync(path.join(CLAUDE_DIR, 'hooks', '.auto-handoff-disabled'), '');
|
|
65
67
|
|
|
66
68
|
// 5. Configure hooks in settings.json
|
|
67
69
|
console.log(` ${YELLOW}[5/10]${NC} Configuring hooks in settings.json...`);
|
|
@@ -177,9 +179,8 @@ console.log(` ${CYAN}/switch-context${NC} Switch workstream`);
|
|
|
177
179
|
console.log(` ${CYAN}/delete-handoff${NC} Delete handoff(s)`);
|
|
178
180
|
console.log(` ${CYAN}/auto-handoff${NC} Toggle auto-handoff on/off`);
|
|
179
181
|
console.log('');
|
|
180
|
-
console.log(
|
|
181
|
-
console.log(
|
|
182
|
-
console.log(` Use ${CYAN}/auto-handoff${NC} to enable/disable or adjust threshold`);
|
|
182
|
+
console.log(` Auto-handoff: ${YELLOW}(beta — disabled by default)${NC}`);
|
|
183
|
+
console.log(` Use ${CYAN}/auto-handoff${NC} to enable and configure threshold`);
|
|
183
184
|
console.log('');
|
|
184
185
|
console.log(' Files:');
|
|
185
186
|
console.log(' .claude/commands/ 6 command files');
|
package/hooks/context-monitor.sh
CHANGED
|
@@ -9,11 +9,11 @@ if [ -f "$SCRIPT_DIR/.auto-handoff-disabled" ]; then
|
|
|
9
9
|
exit 0
|
|
10
10
|
fi
|
|
11
11
|
|
|
12
|
-
# Contexto máximo
|
|
13
|
-
|
|
12
|
+
# Contexto máximo do Claude Code (tokens)
|
|
13
|
+
MAX_CONTEXT_TOKENS=200000
|
|
14
14
|
# Threshold configurável (% do contexto). 90% padrão — maximiza uso do contexto
|
|
15
15
|
THRESHOLD_PERCENT=${CLAUDE_CONTEXT_THRESHOLD:-90}
|
|
16
|
-
|
|
16
|
+
THRESHOLD_TOKENS=$((MAX_CONTEXT_TOKENS * THRESHOLD_PERCENT / 100))
|
|
17
17
|
|
|
18
18
|
INPUT=$(cat)
|
|
19
19
|
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty')
|
|
@@ -28,11 +28,52 @@ if [ -z "$SESSION_ID" ]; then
|
|
|
28
28
|
exit 0
|
|
29
29
|
fi
|
|
30
30
|
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
# Extrai o input_tokens da última mensagem do assistente no JSONL.
|
|
32
|
+
# Isso reflete o tamanho REAL do contexto que o Claude está usando.
|
|
33
|
+
# Campos: input_tokens + cache_read_input_tokens + cache_creation_input_tokens = total input
|
|
34
|
+
CURRENT_TOKENS=0
|
|
35
|
+
if command -v python3 &>/dev/null; then
|
|
36
|
+
CURRENT_TOKENS=$(python3 -c "
|
|
37
|
+
import json, sys
|
|
38
|
+
last = 0
|
|
39
|
+
with open('$TRANSCRIPT_PATH') as f:
|
|
40
|
+
for line in f:
|
|
41
|
+
try:
|
|
42
|
+
e = json.loads(line)
|
|
43
|
+
if e.get('type') == 'assistant':
|
|
44
|
+
u = e.get('message', {}).get('usage', {})
|
|
45
|
+
t = u.get('input_tokens', 0) + u.get('cache_read_input_tokens', 0) + u.get('cache_creation_input_tokens', 0)
|
|
46
|
+
if t > 0:
|
|
47
|
+
last = t
|
|
48
|
+
except:
|
|
49
|
+
pass
|
|
50
|
+
print(last)
|
|
51
|
+
" 2>/dev/null)
|
|
52
|
+
elif command -v node &>/dev/null; then
|
|
53
|
+
CURRENT_TOKENS=$(node -e "
|
|
54
|
+
const fs = require('fs');
|
|
55
|
+
const lines = fs.readFileSync('$TRANSCRIPT_PATH', 'utf-8').trim().split('\n');
|
|
56
|
+
let last = 0;
|
|
57
|
+
for (const line of lines) {
|
|
58
|
+
try {
|
|
59
|
+
const e = JSON.parse(line);
|
|
60
|
+
if (e.type === 'assistant' && e.message?.usage) {
|
|
61
|
+
const u = e.message.usage;
|
|
62
|
+
const t = (u.input_tokens || 0) + (u.cache_read_input_tokens || 0) + (u.cache_creation_input_tokens || 0);
|
|
63
|
+
if (t > 0) last = t;
|
|
64
|
+
}
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
console.log(last);
|
|
68
|
+
" 2>/dev/null)
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
CURRENT_TOKENS=$(echo "$CURRENT_TOKENS" | tr -d ' \n')
|
|
72
|
+
if [ -z "$CURRENT_TOKENS" ] || [ "$CURRENT_TOKENS" -eq 0 ] 2>/dev/null; then
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
34
75
|
|
|
35
|
-
if [ "$
|
|
76
|
+
if [ "$CURRENT_TOKENS" -lt "$THRESHOLD_TOKENS" ]; then
|
|
36
77
|
exit 0
|
|
37
78
|
fi
|
|
38
79
|
|
|
@@ -43,10 +84,13 @@ if [ -f "$FLAG" ]; then
|
|
|
43
84
|
fi
|
|
44
85
|
touch "$FLAG"
|
|
45
86
|
|
|
87
|
+
# Calcula % atual
|
|
88
|
+
CURRENT_PERCENT=$((CURRENT_TOKENS * 100 / MAX_CONTEXT_TOKENS))
|
|
89
|
+
|
|
46
90
|
# Bloqueia e força handoff
|
|
47
91
|
cat <<HOOKEOF
|
|
48
92
|
{
|
|
49
93
|
"decision": "block",
|
|
50
|
-
"reason": "⚠️ AUTO-HANDOFF: O contexto atingiu ${
|
|
94
|
+
"reason": "⚠️ AUTO-HANDOFF: O contexto atingiu ${CURRENT_PERCENT}% do limite (${CURRENT_TOKENS}/${MAX_CONTEXT_TOKENS} tokens). Você DEVE salvar o handoff AGORA.\n\nSiga estes passos IMEDIATAMENTE:\n1. Analise a conversa inteira e extraia: o que foi feito, próximos passos, arquivos-chave, decisões\n2. Escreva o handoff em .claude/handoffs/_active.md seguindo o template padrão\n3. Diga ao usuário: 'Handoff salvo automaticamente. Use /clear e depois /resume para continuar.'\n\nNÃO continue com outro trabalho até o handoff estar salvo."
|
|
51
95
|
}
|
|
52
96
|
HOOKEOF
|
package/install.sh
CHANGED
|
@@ -71,6 +71,8 @@ download_file "hooks/context-monitor.sh" "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
|
71
71
|
download_file "hooks/session-cleanup.sh" "$CLAUDE_DIR/hooks/session-cleanup.sh"
|
|
72
72
|
chmod +x "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
73
73
|
chmod +x "$CLAUDE_DIR/hooks/session-cleanup.sh"
|
|
74
|
+
# Auto-handoff disabled by default (beta feature)
|
|
75
|
+
touch "$CLAUDE_DIR/hooks/.auto-handoff-disabled"
|
|
74
76
|
|
|
75
77
|
# 5. Configure hooks in settings.json
|
|
76
78
|
echo -e " ${YELLOW}[5/10]${NC} Configuring hooks in settings.json..."
|
|
@@ -306,9 +308,8 @@ echo -e " ${CYAN}/switch-context${NC} Switch workstream"
|
|
|
306
308
|
echo -e " ${CYAN}/delete-handoff${NC} Delete handoff(s)"
|
|
307
309
|
echo -e " ${CYAN}/auto-handoff${NC} Toggle auto-handoff on/off"
|
|
308
310
|
echo ""
|
|
309
|
-
echo -e " Auto-handoff:"
|
|
310
|
-
echo -e "
|
|
311
|
-
echo -e " Use ${CYAN}/auto-handoff${NC} to enable/disable or adjust threshold"
|
|
311
|
+
echo -e " Auto-handoff: ${YELLOW}(beta — disabled by default)${NC}"
|
|
312
|
+
echo -e " Use ${CYAN}/auto-handoff${NC} to enable and configure threshold"
|
|
312
313
|
echo ""
|
|
313
314
|
echo -e " Files:"
|
|
314
315
|
echo -e " .claude/commands/ 6 command files"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-handoff",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Session continuity for Claude Code —
|
|
3
|
+
"version": "1.7.0",
|
|
4
|
+
"description": "Session continuity for Claude Code — 6 slash commands to save, resume, delete, and switch workstreams across /clear",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claude-code-handoff": "./cli.js"
|
|
7
7
|
},
|