Skip to content

Commit 098629c

Browse files
committed
feat(hooks): add build-check Stop/SubagentStop hook
When Claude or a subagent finishes, run `make compile` to catch syntax/compilation errors early; on failure, block and feed a parsed error summary back to Claude (falling back to the tail of the output when no error lines match). Written in Bash; matches on hook_event_name Stop/SubagentStop and parses the payload with jq. Stacked on hooks-1-editorconfig. Signed-off-by: Edmund Miller <edmund.miller@seqera.io>
1 parent 97108a2 commit 098629c

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

.claude/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ understood on its own. This file documents the hooks that are currently wired up
2323
skips silently if it is not present)
2424
- **Failure mode**: non-blocking — prints a warning, never stops Claude
2525

26+
### 2. Build check (Stop + SubagentStop)
27+
- **Script**: `hooks/check-build.sh`
28+
- **Trigger**: when Claude (or a subagent) finishes responding
29+
- **Action**: runs `make compile` to catch syntax/compilation errors early
30+
- **Failure mode**: blocking — feeds a parsed error summary back to Claude so it
31+
can fix the breakage before yielding
32+
2633
## Enabling / disabling
2734

2835
Hooks are configured in `.claude/settings.json`. Disable one by removing its entry;

.claude/hooks/check-build.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Build check hook for Nextflow development.
4+
#
5+
# On Stop / SubagentStop, run `make compile` to catch syntax and compilation
6+
# errors. On failure, block and feed a parsed error summary back to Claude.
7+
#
8+
# Reads the Claude Code hook payload as JSON on stdin (requires `jq`).
9+
10+
set -uo pipefail
11+
12+
command -v jq >/dev/null 2>&1 || exit 0
13+
14+
input=$(cat)
15+
event=$(jq -r '.hook_event_name // ""' <<<"$input")
16+
17+
case "$event" in
18+
Stop|SubagentStop) ;;
19+
*) exit 0 ;;
20+
esac
21+
22+
start=$SECONDS
23+
if out=$(make compile 2>&1); then
24+
jq -n --arg s "$(( SECONDS - start ))" \
25+
'{suppressOutput: true, systemMessage: ("✓ Build check passed (" + $s + "s)")}'
26+
else
27+
summary=$(printf '%s\n' "$out" | grep -iE 'error|failed|exception' | tail -n 10)
28+
[[ -n "$summary" ]] || summary=$(printf '%s\n' "$out" | tail -n 20)
29+
jq -n --arg r "Build check failed:
30+
$summary" \
31+
'{decision: "block", reason: $r, stopReason: "Build compilation failed"}'
32+
fi

.claude/settings.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,28 @@
1111
}
1212
]
1313
}
14+
],
15+
"Stop": [
16+
{
17+
"hooks": [
18+
{
19+
"type": "command",
20+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-build.sh",
21+
"timeout": 120
22+
}
23+
]
24+
}
25+
],
26+
"SubagentStop": [
27+
{
28+
"hooks": [
29+
{
30+
"type": "command",
31+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-build.sh",
32+
"timeout": 120
33+
}
34+
]
35+
}
1436
]
1537
}
1638
}

0 commit comments

Comments
 (0)