Skip to content

Commit 7aeacea

Browse files
Joseph Edmondsclaude
andcommitted
fix(hooks): auto-continue hook should only run for Stop events
- Modified auto-continue.py to silently no-op (return {}) for non-Stop events - Updated deploy-skills.bash to register auto-continue ONLY in Stop section - Deploy script now removes auto-continue from PreToolUse if incorrectly added - Prevents confusing "stopped continuation" messages on every tool call 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 34d1941 commit 7aeacea

2 files changed

Lines changed: 59 additions & 19 deletions

File tree

.claude/hooks/php-qa-ci__auto-continue.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ def main() -> None:
202202
"""
203203
Default entry point - determines event from script name or env var.
204204
205+
IMPORTANT: This hook is ONLY designed for Stop events (auto-continue).
206+
For PreToolUse/PostToolUse, it silently no-ops to avoid confusing messages.
207+
205208
Event detection order:
206209
1. CLAUDE_HOOK_EVENT environment variable (explicit)
207210
2. Script name suffix (e.g., script--stop.py -> Stop)
@@ -210,17 +213,22 @@ def main() -> None:
210213
# Check environment variable first
211214
event_from_env = os.environ.get("CLAUDE_HOOK_EVENT")
212215
if event_from_env:
216+
# This hook only makes sense for Stop events
217+
# For other events, silently allow without any message
218+
if event_from_env != "Stop":
219+
print("{}")
220+
sys.exit(0)
213221
process_hook_logic(event_from_env)
214222
return
215223

216224
# Check script name for event suffix
217225
script_name = os.path.basename(sys.argv[0]) if sys.argv else ""
218226
if "--stop" in script_name.lower():
219227
main_stop()
220-
elif "--pretooluse" in script_name.lower():
221-
main_pre_tool_use()
222-
elif "--posttooluse" in script_name.lower():
223-
main_post_tool_use()
228+
elif "--pretooluse" in script_name.lower() or "--posttooluse" in script_name.lower():
229+
# Silently no-op for PreToolUse/PostToolUse - this hook is Stop-only
230+
print("{}")
231+
sys.exit(0)
224232
else:
225233
# This hook's primary purpose is Stop event - use that as default
226234
main_stop()

scripts/deploy-skills.bash

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ import sys
169169
settings_file = sys.argv[1]
170170
hooks_to_add = sys.argv[2:]
171171
172+
# Hooks that should ONLY be registered in Stop event (not PreToolUse)
173+
STOP_ONLY_HOOKS = {
174+
".claude/hooks/php-qa-ci__auto-continue.py",
175+
}
176+
172177
# Load existing settings
173178
try:
174179
with open(settings_file, 'r') as f:
@@ -181,31 +186,58 @@ if 'hooks' not in settings:
181186
settings['hooks'] = {}
182187
if 'PreToolUse' not in settings['hooks']:
183188
settings['hooks']['PreToolUse'] = [{'hooks': []}]
189+
if 'Stop' not in settings['hooks']:
190+
settings['hooks']['Stop'] = [{'hooks': []}]
184191
185-
# Get existing hooks list
192+
# Get existing PreToolUse hooks list
186193
pre_tool_use = settings['hooks']['PreToolUse']
187194
if not pre_tool_use:
188195
pre_tool_use = [{'hooks': []}]
189196
settings['hooks']['PreToolUse'] = pre_tool_use
197+
pre_hooks_list = pre_tool_use[0].get('hooks', [])
190198
191-
hooks_list = pre_tool_use[0].get('hooks', [])
199+
# Get existing Stop hooks list
200+
stop_hooks = settings['hooks']['Stop']
201+
if not stop_hooks:
202+
stop_hooks = [{'hooks': []}]
203+
settings['hooks']['Stop'] = stop_hooks
204+
stop_hooks_list = stop_hooks[0].get('hooks', [])
192205
193-
# Get existing hook commands
194-
existing_commands = {h.get('command') for h in hooks_list if isinstance(h, dict)}
206+
# Get existing hook commands (check both raw command and with env prefix)
207+
pre_existing_commands = {h.get('command') for h in pre_hooks_list if isinstance(h, dict)}
208+
stop_existing_commands = {h.get('command') for h in stop_hooks_list if isinstance(h, dict)}
195209
196-
# Add new hooks if not already present
210+
# Remove any Stop-only hooks that were incorrectly added to PreToolUse
211+
pre_hooks_list = [h for h in pre_hooks_list if h.get('command') not in STOP_ONLY_HOOKS]
212+
213+
# Add new hooks to appropriate sections
197214
for hook_path in hooks_to_add:
198-
if hook_path not in existing_commands:
199-
hooks_list.append({
200-
'type': 'command',
201-
'command': hook_path,
202-
'timeout': 5
203-
})
204-
print(f" Registered: {hook_path}")
215+
if hook_path in STOP_ONLY_HOOKS:
216+
# Stop-only hooks get CLAUDE_HOOK_EVENT=Stop prefix
217+
stop_command = f"CLAUDE_HOOK_EVENT=Stop {hook_path}"
218+
if stop_command not in stop_existing_commands and hook_path not in stop_existing_commands:
219+
stop_hooks_list.append({
220+
'type': 'command',
221+
'command': stop_command,
222+
'timeout': 5
223+
})
224+
print(f" Registered (Stop): {stop_command}")
225+
else:
226+
print(f" Already registered (Stop): {hook_path}")
205227
else:
206-
print(f" Already registered: {hook_path}")
207-
208-
pre_tool_use[0]['hooks'] = hooks_list
228+
# Regular hooks go to PreToolUse
229+
if hook_path not in pre_existing_commands:
230+
pre_hooks_list.append({
231+
'type': 'command',
232+
'command': hook_path,
233+
'timeout': 5
234+
})
235+
print(f" Registered (PreToolUse): {hook_path}")
236+
else:
237+
print(f" Already registered (PreToolUse): {hook_path}")
238+
239+
pre_tool_use[0]['hooks'] = pre_hooks_list
240+
stop_hooks[0]['hooks'] = stop_hooks_list
209241
210242
# Write back
211243
with open(settings_file, 'w') as f:

0 commit comments

Comments
 (0)