`(& git log -1 --format='%b')` in PowerShell collapses multi-line subprocess
output into string[]. The threshold check used `$body.Length` which on a
string[] returns the line count, not char count — so the body>200 condition
was effectively comparing "more than 200 lines", which is much harder to
meet. Files-count saves it in practice for big commits, but small-file
big-message commits were under-detected.
Fix: join the array back into a single string with `-join "`n"` before
measuring length. Verified via stdin-pipe smoke against current HEAD:
body chars now report 1255 (vs 29 before — the line count).
POSIX `.sh` variant unaffected — `$()` collapses output and `${#var}` is
char count.
Bump 0.3.0 → 0.3.1 PATCH (bugfix, no behavior contract change).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.0 KiB
4.0 KiB
session-handoff-posttooluse-hook
Goal
Автоматизировать substantive-commit detection в session-handoff через PostToolUse hook на Bash matcher'е (settings.json уровне), вместо поведенческой памяти агента. Hook parses git log -1, применяет ту же substantive-эвристику что и в SKILL.md, и на hit emits hookSpecificOutput.additionalContext чтобы Claude Code surface'ил system reminder в следующей итерации агента.
Key files
skills/session-handoff/hooks/commit-detector.ps1— Windows/PowerShell hook scriptskills/session-handoff/hooks/commit-detector.sh— Linux/macOS POSIX hook script (требует python3 для JSON parsing)skills/session-handoff/hooks/README.md— opt-in инструкции, cross-platform settings.json snippets, smoke procedureskills/session-handoff/SKILL.md— body When-to-use updated: substantive-commit пункт получил «Optional: harness-side hook см. hooks/README.md»skills/session-handoff/SKILL.mdfrontmatter — bump 0.2.1 → 0.3.0 (MINOR: new opt-in capability)
Decisions log
- 2026-05-24: install.sh НЕ мутирует ~/.claude/settings.json. Auto-rewriting user hook config — неправильная shape для install скрипта. Hooks ship as files; user enables once per machine. SKILL.md и hooks/README.md документируют opt-in step (раз сделал — работает на все sessions).
- 2026-05-24: JSON output protocol: hook возвращает
hookSpecificOutput.additionalContext(per Claude Code PostToolUse hook protocol). На hit — JSON; на miss — silent exit 0 без output. Confirmed via claude-code-guide subagent (https://code.claude.com/docs/en/hooks.md § JSON Output Format). - 2026-05-24: --amend skip (recommended в task design questions). Amend обычно правит prev session коммит, не новый work artifact.
- 2026-05-24: rebase/cherry-pick noise — deferred. Hook fires per commit, batch operations spam. Trade-off acceptable for opt-in v0.3.0; defer "только original commit-event (HEAD@{1} != HEAD)" к follow-up если actually annoys.
- 2026-05-24: first-non-trivial-commit-of-session special case — NOT in hook. Session boundaries are agent-state, не accessible from hook side. Hook uses only body/file thresholds. Под-detection on small first commits acceptable; agent-side эвристика остаётся как backup.
- 2026-05-24: POSIX requires python3 for safe JSON parsing of PostToolUse stdin. Alternatives (sed/awk JSON parsing) fragile. Documented as dep in README.
Open questions
- Live-hook smoke test — отдельной сессией (enable hook → substantive commit → see additionalContext surface). Не делалось в этой сессии чтобы не interfere с current commits.
Completed steps
- Research PostToolUse hook output protocol (claude-code-guide subagent)
- Inspect existing ~/.claude/settings.json (no hooks currently configured)
- Write commit-detector.ps1 (Windows)
- Write commit-detector.sh (POSIX)
- Write hooks/README.md (opt-in instructions cross-platform + smoke procedure)
- Update SKILL.md body — When-to-use mentions hook as opt-in alternative
- Bump SKILL.md 0.2.1 → 0.3.0 (MINOR — new capability)
- Reinstall via scripts/install.ps1
- stdin-pipe smoke (6 scenarios): substantive HEAD ✓ emits JSON; --amend / ls / empty / malformed / failed-commit ✓ silent skip
- discover + fix PS bug:
git log %b→ string[],.Lengthwas line count;-join "n"` fix; PATCH bump 0.3.0 → 0.3.1 - STATUS.md → 🟢 (partial: stdin smoke ✓, live-hook deferred to separate session)
- commit (next)
Notes
Live-hook enable + e2e validation = separate task / separate session. Adding hook to settings.json in this active session would fire on every git commit done here, including the closure commit itself — meta-feedback loop best avoided.