# session-handoff hooks Opt-in PostToolUse hook that detects substantive `git commit` invocations and signals the agent ("consider running session-handoff write-mode") via a system reminder. Replaces the agent-side commit-detection heuristic in the SKILL.md `When to use` section with a deterministic harness-side trigger. ## Why opt-in (not auto-installed) `install.sh` deliberately does **not** mutate `~/.claude/settings.json`. Auto-rewriting the user's hook config on every skill install is the wrong shape — user expects `install.sh` to copy files, nothing more. The hook is shipped as scripts; user enables it once per machine. ## Enable on Windows (PowerShell) Add to `~/.claude/settings.json`: ```jsonc { "hooks": { "PostToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "pwsh -NoProfile -ExecutionPolicy Bypass -File \"$env:USERPROFILE\\.claude\\skills\\session-handoff\\hooks\\commit-detector.ps1\"" } ] } ] } } ``` If `hooks.PostToolUse` already exists — append the matcher block to the array. Don't overwrite existing entries. ## Enable on Linux / macOS (bash) ```jsonc { "hooks": { "PostToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "bash ~/.claude/skills/session-handoff/hooks/commit-detector.sh" } ] } ] } } ``` The bash variant needs `python3` on PATH (used to parse the PostToolUse JSON stdin). ## What gets signalled On a successful `git commit` whose subject prefix is not in {`meta`, `docs`, `style`, `chore`} or `fix typo`, **and** whose body exceeds 200 characters or which touches more than 3 files — the hook emits a `hookSpecificOutput.additionalContext` system reminder of shape: > Substantive commit detected on ``: `` (N files changed, body M chars). Consider invoking session-handoff write-mode to update `.tasks/NEXT_SESSION.md`. On any of these → silent skip (exit 0, no JSON): - malformed PostToolUse stdin - Bash command isn't `git commit` - command is `git commit --amend` - commit returned non-zero exit - cwd isn't a git work-tree - subject prefix is in trivial set - body ≤ 200 chars AND files ≤ 3 ## Smoke test (without enabling the hook) Pipe a synthetic PostToolUse JSON to the script. On Windows: ```powershell $payload = @{ tool_input = @{ command = 'git commit -m "subject"' } tool_response = @{ exit_code = 0 } cwd = (Get-Location).Path } | ConvertTo-Json -Compress $payload | pwsh -NoProfile -File .\skills\session-handoff\hooks\commit-detector.ps1 ``` If your `HEAD` is a non-trivial commit (e.g. recent `feat:` with > 200-char body or > 3 files), output is JSON containing `additionalContext`. Otherwise — empty stdout (silent skip). ## Caveats - **Rebase / cherry-pick noise.** Every commit in a rebase or cherry-pick batch will re-fire the hook. Deferred to a follow-up if it actually annoys in practice; the hook is opt-in so the cost is bounded. - **First-non-trivial commit of session.** The agent-side heuristic in SKILL.md treats the *first* non-trivial commit of a session as "always substantive" regardless of thresholds. The hook can't see session boundaries — uses only body/file thresholds. Slight under-detection on small first commits; acceptable trade-off for harness-side determinism. - **No automatic write-mode invocation.** Hook only signals. The agent still decides whether to run session-handoff write-mode in response — keeps the user-agency invariant from SKILL.md `What NOT to do`.