6 new issues for Claude Code hook improvements: - 012: Test output filtering (reduce noise, show failures only) - 013: Stop verification (verify work complete before stopping) - 014: Auto-test on edit (async tests after code changes) - 015: Session context injection (git/issues/CI on startup) - 016: Silent auto-formatting (suppress formatter output) - 017: Expose/hide policy (define what to show vs suppress) Based on Claude Code hooks documentation: - PostToolUse with suppressOutput for noise reduction - Stop hooks with agent verification - Async hooks for background testing - SessionStart for context injection - additionalContext for exposing important info Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2.1 KiB
2.1 KiB
feat(hooks): Auto-run tests after code changes (async)
Summary
Add async PostToolUse hooks that automatically run tests after Write/Edit operations, reporting results without blocking.
Problem
Claude often edits code but forgets to run tests, or runs tests manually each time which is slow and repetitive.
Solution
Async PostToolUse hooks that:
- Detect code file changes (*.go, *.php, *.ts)
- Run relevant tests in background
- Report results on next turn via
systemMessage
Hook Configuration
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "core ai auto-test",
"async": true,
"timeout": 120,
"statusMessage": "Running tests..."
}
]
}
]
}
}
Test Detection Logic
core ai auto-test should:
-
Read file path from stdin:
FILE=$(jq -r '.tool_input.file_path') -
Detect test scope:
*.goinpkg/foo/→core go test ./pkg/foo/...*.phpinsrc/→core php test --filter=related*_test.go→ run that specific test file*.spec.ts→ run that specific spec
-
Run minimal test set:
- Don't run full suite on every change
- Use
--filteror package scope - Cache recent test runs
-
Report results:
{ "systemMessage": "Tests for pkg/foo: 12 passed, 0 failed (2.3s)" }
Smart Test Selection
For Go:
# Find related test file
TEST_FILE="${FILE%.go}_test.go"
if [ -f "$TEST_FILE" ]; then
core go test -run "$(basename $TEST_FILE .go)" ./...
else
# Run package tests
PKG_DIR=$(dirname "$FILE")
core go test "./$PKG_DIR/..."
fi
For PHP:
# Find related test
TEST_FILE=$(echo "$FILE" | sed 's/\.php$/Test.php/' | sed 's|src/|tests/|')
if [ -f "$TEST_FILE" ]; then
core php test "$TEST_FILE"
fi
Debouncing
Avoid running tests multiple times for rapid edits:
- Track last test run per package
- Skip if <5 seconds since last run
- Queue and batch rapid changes