Skip to content

Commit 33b06e5

Browse files
committed
fix(hookify): pass warn/block messages to Claude
Warn rules previously returned only `systemMessage`, which is shown to the user console but never injected into Claude's context. Educational messages (the entire point of warn rules) never reached the model. Block rules similarly returned only a generic deny without `permissionDecisionReason`. Now: - Warn rules on PreToolUse/PostToolUse also emit `additionalContext` inside `hookSpecificOutput`, so Claude sees the message and can self-correct. - Block rules on PreToolUse/PostToolUse also emit `permissionDecisionReason`, so Claude sees why the operation was denied. PreToolUse `additionalContext` support landed in Claude Code v2.1.9 (see anthropics/claude-code#15664, anthropics/claude-code#15345). PostToolUse has supported it since earlier. The capability is now available; this patch makes hookify use it. Refs: - anthropics/claude-code#15203 (warn — closed as duplicate) - anthropics/claude-code#12446 (block — closed) - anthropics/claude-code#15664, anthropics/claude-code#15345 (SDK additionalContext support) - Prior PR attempts: anthropics/claude-code#15218, anthropics/claude-code#15219 (closed unmerged, predate v2.1.9)
1 parent 48aa435 commit 33b06e5

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

plugins/hookify/core/rule_engine.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ def evaluate_rules(self, rules: List[Rule], input_data: Dict[str, Any]) -> Dict[
7373
return {
7474
"hookSpecificOutput": {
7575
"hookEventName": hook_event,
76-
"permissionDecision": "deny"
76+
"permissionDecision": "deny",
77+
"permissionDecisionReason": combined_message,
7778
},
7879
"systemMessage": combined_message
7980
}
@@ -86,9 +87,17 @@ def evaluate_rules(self, rules: List[Rule], input_data: Dict[str, Any]) -> Dict[
8687
# If only warnings, show them but allow operation
8788
if warning_rules:
8889
messages = [f"**[{r.name}]**\n{r.message}" for r in warning_rules]
89-
return {
90-
"systemMessage": "\n\n".join(messages)
91-
}
90+
combined = "\n\n".join(messages)
91+
response = {"systemMessage": combined}
92+
# PreToolUse additionalContext supported since Claude Code v2.1.9.
93+
# PostToolUse has supported it since earlier. Inject so Claude (not
94+
# just the user console) sees the educational message.
95+
if hook_event in ('PreToolUse', 'PostToolUse'):
96+
response["hookSpecificOutput"] = {
97+
"hookEventName": hook_event,
98+
"additionalContext": combined,
99+
}
100+
return response
92101

93102
# No matches - allow operation
94103
return {}

0 commit comments

Comments
 (0)