claude-code-handoff 1.8.0 → 1.9.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 +3 -3
- package/cli.js +36 -4
- package/commands/auto-handoff.md +7 -5
- package/hooks/context-monitor.sh +2 -2
- package/install.sh +29 -2
- package/package.json +1 -1
- package/uninstall.sh +1 -0
- package/update.sh +23 -1
package/README.md
CHANGED
|
@@ -253,7 +253,7 @@ THRESHOLD_PERCENT=${CLAUDE_CONTEXT_THRESHOLD:-90} # change 90 to your value
|
|
|
253
253
|
|
|
254
254
|
- **One-shot trigger**: A flag file in `/tmp` (per session ID) prevents infinite loops — the hook triggers exactly once per session, even if Claude's handoff response pushes the transcript further
|
|
255
255
|
- **Session cleanup**: A `SessionStart` hook automatically cleans up stale flag files older than 24 hours
|
|
256
|
-
- **
|
|
256
|
+
- **Opt-in design**: Auto-handoff only runs when `.claude/hooks/.auto-handoff-enabled` exists (created by `/auto-handoff`). No file = disabled by default
|
|
257
257
|
- **Non-destructive**: The hook only blocks and instructs — it never modifies files directly. Claude performs the actual handoff save
|
|
258
258
|
|
|
259
259
|
### What Happens When It Triggers
|
|
@@ -311,7 +311,7 @@ your-project/
|
|
|
311
311
|
├── hooks/
|
|
312
312
|
│ ├── context-monitor.sh ← Stop hook (monitors context size)
|
|
313
313
|
│ ├── session-cleanup.sh ← SessionStart hook (cleans old flags)
|
|
314
|
-
│ └── .auto-handoff-
|
|
314
|
+
│ └── .auto-handoff-enabled ← Enable flag (created by /auto-handoff)
|
|
315
315
|
├── settings.json ← Hook configuration
|
|
316
316
|
└── handoffs/ ← Session state (gitignored)
|
|
317
317
|
├── _active.md ← Current workstream
|
|
@@ -604,7 +604,7 @@ A: Absolutely. They're plain markdown. You can add notes, reorder next steps, or
|
|
|
604
604
|
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.
|
|
605
605
|
|
|
606
606
|
**Q: Can I disable auto-handoff?**
|
|
607
|
-
A: Yes. Run `/auto-handoff` and select "Disable", or manually
|
|
607
|
+
A: Yes. Run `/auto-handoff` and select "Disable", or manually delete `.claude/hooks/.auto-handoff-enabled`. Without this file, auto-handoff is off.
|
|
608
608
|
|
|
609
609
|
**Q: What if auto-handoff triggers too early/late?**
|
|
610
610
|
A: Adjust the threshold. If it triggers too early, increase to 95%. If you're running out of context before it triggers, lower to 80% or 75%. Use `/auto-handoff` to change it interactively.
|
package/cli.js
CHANGED
|
@@ -58,12 +58,44 @@ copyFile('rules/auto-handoff.md', path.join(CLAUDE_DIR, 'rules', 'auto-handoff.m
|
|
|
58
58
|
|
|
59
59
|
// 4. Install hooks
|
|
60
60
|
console.log(` ${YELLOW}[4/10]${NC} Installing hooks...`);
|
|
61
|
-
|
|
61
|
+
|
|
62
|
+
// Detect reinstall: save user's custom settings before overwriting
|
|
63
|
+
const monitorPath = path.join(CLAUDE_DIR, 'hooks', 'context-monitor.sh');
|
|
64
|
+
let isReinstall = false;
|
|
65
|
+
let savedThreshold = '';
|
|
66
|
+
let savedMaxContext = '';
|
|
67
|
+
if (fs.existsSync(monitorPath)) {
|
|
68
|
+
isReinstall = true;
|
|
69
|
+
const oldContent = fs.readFileSync(monitorPath, 'utf-8');
|
|
70
|
+
const thresholdMatch = oldContent.match(/CLAUDE_CONTEXT_THRESHOLD:-(\d+)/);
|
|
71
|
+
const maxContextMatch = oldContent.match(/CLAUDE_MAX_CONTEXT:-(\d+)/);
|
|
72
|
+
if (thresholdMatch) savedThreshold = thresholdMatch[1];
|
|
73
|
+
if (maxContextMatch) savedMaxContext = maxContextMatch[1];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
copyFile('hooks/context-monitor.sh', monitorPath);
|
|
62
77
|
copyFile('hooks/session-cleanup.sh', path.join(CLAUDE_DIR, 'hooks', 'session-cleanup.sh'));
|
|
63
|
-
fs.chmodSync(
|
|
78
|
+
fs.chmodSync(monitorPath, 0o755);
|
|
64
79
|
fs.chmodSync(path.join(CLAUDE_DIR, 'hooks', 'session-cleanup.sh'), 0o755);
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
|
|
81
|
+
if (isReinstall) {
|
|
82
|
+
// Restore user's custom settings
|
|
83
|
+
let content = fs.readFileSync(monitorPath, 'utf-8');
|
|
84
|
+
if (savedThreshold && savedThreshold !== '90') {
|
|
85
|
+
content = content.replace('CLAUDE_CONTEXT_THRESHOLD:-90', `CLAUDE_CONTEXT_THRESHOLD:-${savedThreshold}`);
|
|
86
|
+
console.log(` Preserved threshold: ${CYAN}${savedThreshold}%${NC}`);
|
|
87
|
+
}
|
|
88
|
+
if (savedMaxContext && savedMaxContext !== '200000') {
|
|
89
|
+
content = content.replace('CLAUDE_MAX_CONTEXT:-200000', `CLAUDE_MAX_CONTEXT:-${savedMaxContext}`);
|
|
90
|
+
console.log(` Preserved max context: ${CYAN}${savedMaxContext} tokens${NC}`);
|
|
91
|
+
}
|
|
92
|
+
fs.writeFileSync(monitorPath, content);
|
|
93
|
+
}
|
|
94
|
+
// Auto-handoff is opt-in: disabled by default (no file = disabled)
|
|
95
|
+
// User enables via /auto-handoff which creates .auto-handoff-enabled
|
|
96
|
+
// Clean up legacy disabled flag if present
|
|
97
|
+
const legacyDisabled = path.join(CLAUDE_DIR, 'hooks', '.auto-handoff-disabled');
|
|
98
|
+
if (fs.existsSync(legacyDisabled)) fs.unlinkSync(legacyDisabled);
|
|
67
99
|
|
|
68
100
|
// 5. Configure hooks in settings.json
|
|
69
101
|
console.log(` ${YELLOW}[5/10]${NC} Configuring hooks in settings.json...`);
|
package/commands/auto-handoff.md
CHANGED
|
@@ -6,9 +6,9 @@ Toggle the automatic handoff context monitor on/off, configure threshold, and se
|
|
|
6
6
|
|
|
7
7
|
### Step 1: Check current state
|
|
8
8
|
|
|
9
|
-
Check if `.claude/hooks/.auto-handoff-
|
|
10
|
-
- If exists → currently
|
|
11
|
-
- If not exists → currently
|
|
9
|
+
Check if `.claude/hooks/.auto-handoff-enabled` exists:
|
|
10
|
+
- If exists → currently ENABLED
|
|
11
|
+
- If not exists → currently DISABLED (default)
|
|
12
12
|
|
|
13
13
|
Also read from `.claude/hooks/context-monitor.sh`:
|
|
14
14
|
- `THRESHOLD_PERCENT` value (the default in `THRESHOLD_PERCENT=${CLAUDE_CONTEXT_THRESHOLD:-XX}`)
|
|
@@ -30,7 +30,9 @@ Use AskUserQuestion:
|
|
|
30
30
|
### Step 3: Execute
|
|
31
31
|
|
|
32
32
|
#### Toggle (Ativar/Desativar):
|
|
33
|
-
-
|
|
33
|
+
- Ativar: create `.claude/hooks/.auto-handoff-enabled`
|
|
34
|
+
- Desativar: delete `.claude/hooks/.auto-handoff-enabled`
|
|
35
|
+
- Also delete legacy `.claude/hooks/.auto-handoff-disabled` if it exists
|
|
34
36
|
|
|
35
37
|
#### Ajustar threshold:
|
|
36
38
|
Ask with AskUserQuestion:
|
|
@@ -52,7 +54,7 @@ Ask with AskUserQuestion:
|
|
|
52
54
|
- Update the `MAX_CONTEXT_TOKENS` default value in `context-monitor.sh` by changing `MAX_CONTEXT_TOKENS=${CLAUDE_MAX_CONTEXT:-XXXXXX}` to the chosen value
|
|
53
55
|
|
|
54
56
|
#### Ativar com configuração customizada:
|
|
55
|
-
Run both "Alterar plano" and "Ajustar threshold" flows above, then
|
|
57
|
+
Run both "Alterar plano" and "Ajustar threshold" flows above, then create `.claude/hooks/.auto-handoff-enabled`
|
|
56
58
|
|
|
57
59
|
### Step 4: Confirm
|
|
58
60
|
|
package/hooks/context-monitor.sh
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
# Detecta quando o contexto está próximo do limite e força o salvamento do handoff.
|
|
4
4
|
# Usado como hook "Stop" do Claude Code.
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Auto-handoff is opt-in: only runs if explicitly enabled
|
|
7
7
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
-
if [ -f "$SCRIPT_DIR/.auto-handoff-
|
|
8
|
+
if [ ! -f "$SCRIPT_DIR/.auto-handoff-enabled" ]; then
|
|
9
9
|
exit 0
|
|
10
10
|
fi
|
|
11
11
|
|
package/install.sh
CHANGED
|
@@ -67,12 +67,39 @@ download_file "rules/auto-handoff.md" "$CLAUDE_DIR/rules/auto-handoff.md"
|
|
|
67
67
|
|
|
68
68
|
# 4. Install hooks (auto-handoff context monitor)
|
|
69
69
|
echo -e " ${YELLOW}[4/10]${NC} Installing hooks..."
|
|
70
|
+
|
|
71
|
+
# Detect reinstall: save user's custom settings before overwriting
|
|
72
|
+
IS_REINSTALL=false
|
|
73
|
+
SAVED_THRESHOLD=""
|
|
74
|
+
SAVED_MAX_CONTEXT=""
|
|
75
|
+
if [ -f "$CLAUDE_DIR/hooks/context-monitor.sh" ]; then
|
|
76
|
+
IS_REINSTALL=true
|
|
77
|
+
SAVED_THRESHOLD=$(grep -oP 'CLAUDE_CONTEXT_THRESHOLD:-\K[0-9]+' "$CLAUDE_DIR/hooks/context-monitor.sh" 2>/dev/null || echo "")
|
|
78
|
+
SAVED_MAX_CONTEXT=$(grep -oP 'CLAUDE_MAX_CONTEXT:-\K[0-9]+' "$CLAUDE_DIR/hooks/context-monitor.sh" 2>/dev/null || echo "")
|
|
79
|
+
fi
|
|
80
|
+
|
|
70
81
|
download_file "hooks/context-monitor.sh" "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
71
82
|
download_file "hooks/session-cleanup.sh" "$CLAUDE_DIR/hooks/session-cleanup.sh"
|
|
72
83
|
chmod +x "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
73
84
|
chmod +x "$CLAUDE_DIR/hooks/session-cleanup.sh"
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
|
|
86
|
+
if [ "$IS_REINSTALL" = true ]; then
|
|
87
|
+
# Restore user's custom settings
|
|
88
|
+
if [ -n "$SAVED_THRESHOLD" ] && [ "$SAVED_THRESHOLD" != "90" ]; then
|
|
89
|
+
sed -i.bak "s/CLAUDE_CONTEXT_THRESHOLD:-90/CLAUDE_CONTEXT_THRESHOLD:-${SAVED_THRESHOLD}/" "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
90
|
+
rm -f "$CLAUDE_DIR/hooks/context-monitor.sh.bak"
|
|
91
|
+
echo -e " Preserved threshold: ${CYAN}${SAVED_THRESHOLD}%${NC}"
|
|
92
|
+
fi
|
|
93
|
+
if [ -n "$SAVED_MAX_CONTEXT" ] && [ "$SAVED_MAX_CONTEXT" != "200000" ]; then
|
|
94
|
+
sed -i.bak "s/CLAUDE_MAX_CONTEXT:-200000/CLAUDE_MAX_CONTEXT:-${SAVED_MAX_CONTEXT}/" "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
95
|
+
rm -f "$CLAUDE_DIR/hooks/context-monitor.sh.bak"
|
|
96
|
+
echo -e " Preserved max context: ${CYAN}${SAVED_MAX_CONTEXT} tokens${NC}"
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
99
|
+
# Auto-handoff is opt-in: disabled by default (no file = disabled)
|
|
100
|
+
# User enables via /auto-handoff which creates .auto-handoff-enabled
|
|
101
|
+
# Clean up legacy disabled flag if present
|
|
102
|
+
rm -f "$CLAUDE_DIR/hooks/.auto-handoff-disabled"
|
|
76
103
|
|
|
77
104
|
# 5. Configure hooks in settings.json
|
|
78
105
|
echo -e " ${YELLOW}[5/10]${NC} Configuring hooks in settings.json..."
|
package/package.json
CHANGED
package/uninstall.sh
CHANGED
|
@@ -50,6 +50,7 @@ rm -f "$CLAUDE_DIR/rules/auto-handoff.md"
|
|
|
50
50
|
echo -e " ${YELLOW}[3/6]${NC} Removing hooks..."
|
|
51
51
|
rm -f "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
52
52
|
rm -f "$CLAUDE_DIR/hooks/session-cleanup.sh"
|
|
53
|
+
rm -f "$CLAUDE_DIR/hooks/.auto-handoff-enabled"
|
|
53
54
|
rm -f "$CLAUDE_DIR/hooks/.auto-handoff-disabled"
|
|
54
55
|
rmdir "$CLAUDE_DIR/hooks" 2>/dev/null || true
|
|
55
56
|
|
package/update.sh
CHANGED
|
@@ -58,14 +58,35 @@ echo -e " ${YELLOW}[2/5]${NC} Updating rules..."
|
|
|
58
58
|
download_file "rules/session-continuity.md" "$CLAUDE_DIR/rules/session-continuity.md"
|
|
59
59
|
download_file "rules/auto-handoff.md" "$CLAUDE_DIR/rules/auto-handoff.md"
|
|
60
60
|
|
|
61
|
-
# 3. Update hooks
|
|
61
|
+
# 3. Update hooks (preserving user configuration)
|
|
62
62
|
echo -e " ${YELLOW}[3/5]${NC} Updating hooks..."
|
|
63
63
|
mkdir -p "$CLAUDE_DIR/hooks"
|
|
64
|
+
|
|
65
|
+
# Save user's custom settings before overwriting
|
|
66
|
+
SAVED_THRESHOLD=""
|
|
67
|
+
SAVED_MAX_CONTEXT=""
|
|
68
|
+
if [ -f "$CLAUDE_DIR/hooks/context-monitor.sh" ]; then
|
|
69
|
+
SAVED_THRESHOLD=$(grep -oP 'CLAUDE_CONTEXT_THRESHOLD:-\K[0-9]+' "$CLAUDE_DIR/hooks/context-monitor.sh" 2>/dev/null || echo "")
|
|
70
|
+
SAVED_MAX_CONTEXT=$(grep -oP 'CLAUDE_MAX_CONTEXT:-\K[0-9]+' "$CLAUDE_DIR/hooks/context-monitor.sh" 2>/dev/null || echo "")
|
|
71
|
+
fi
|
|
72
|
+
|
|
64
73
|
download_file "hooks/context-monitor.sh" "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
65
74
|
download_file "hooks/session-cleanup.sh" "$CLAUDE_DIR/hooks/session-cleanup.sh"
|
|
66
75
|
chmod +x "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
67
76
|
chmod +x "$CLAUDE_DIR/hooks/session-cleanup.sh"
|
|
68
77
|
|
|
78
|
+
# Restore user's custom settings
|
|
79
|
+
if [ -n "$SAVED_THRESHOLD" ] && [ "$SAVED_THRESHOLD" != "90" ]; then
|
|
80
|
+
sed -i.bak "s/CLAUDE_CONTEXT_THRESHOLD:-90/CLAUDE_CONTEXT_THRESHOLD:-${SAVED_THRESHOLD}/" "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
81
|
+
rm -f "$CLAUDE_DIR/hooks/context-monitor.sh.bak"
|
|
82
|
+
echo -e " Preserved threshold: ${CYAN}${SAVED_THRESHOLD}%${NC}"
|
|
83
|
+
fi
|
|
84
|
+
if [ -n "$SAVED_MAX_CONTEXT" ] && [ "$SAVED_MAX_CONTEXT" != "200000" ]; then
|
|
85
|
+
sed -i.bak "s/CLAUDE_MAX_CONTEXT:-200000/CLAUDE_MAX_CONTEXT:-${SAVED_MAX_CONTEXT}/" "$CLAUDE_DIR/hooks/context-monitor.sh"
|
|
86
|
+
rm -f "$CLAUDE_DIR/hooks/context-monitor.sh.bak"
|
|
87
|
+
echo -e " Preserved max context: ${CYAN}${SAVED_MAX_CONTEXT} tokens${NC}"
|
|
88
|
+
fi
|
|
89
|
+
|
|
69
90
|
# 4. Ensure hooks are configured in settings.json
|
|
70
91
|
echo -e " ${YELLOW}[4/5]${NC} Checking settings.json hooks..."
|
|
71
92
|
SETTINGS_FILE="$CLAUDE_DIR/settings.json"
|
|
@@ -102,4 +123,5 @@ if [ "$CLEANED" -gt 0 ]; then
|
|
|
102
123
|
fi
|
|
103
124
|
echo ""
|
|
104
125
|
echo -e " Handoff data in .claude/handoffs/ was ${CYAN}not touched${NC}."
|
|
126
|
+
echo -e " Auto-handoff settings (threshold, plan, on/off) were ${CYAN}preserved${NC}."
|
|
105
127
|
echo ""
|