-
Notifications
You must be signed in to change notification settings - Fork 16
Description
I've been using xcsift with Claude Code for a few days now and I noticed a small visual bug while using the tool.
Just a heads up, the summary of the situation and the patch file were generated by Claude Code. I've verified that it does fix the issue, and the fix seems reasonable.
Summary
The pre-xcsift.sh PreToolUse hook uses the deprecated top-level decision field for its JSON output. Claude Code has replaced this with a hookSpecificOutput wrapper structure, so the hook output is no longer recognized — resulting in a PreToolUse:Bash hook error + (No output) on every Bash tool call that isn't an xcodebuild/swift build command.
The tool call still proceeds (Claude Code defaults to allow on hook errors), so nothing is broken functionally — but the error banner appears on every non-build Bash invocation.
Affected Version
xcsift plugin v1.0.2
Details
plugins/claude-code/scripts/pre-xcsift.sh currently outputs the deprecated format:
{"decision": "allow"}
The current expected format is:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow"
}
}
This affects all four output paths in the script — the three passthrough cases (lines 14, 22, 44) and the build-command rewrite (line 41), where updatedCommand should also become updatedInput.
Separately, set -e on line 5 can cause the script to exit silently with no output if jq or grep fails unexpectedly, which also triggers the error banner.
Steps to Reproduce
- Install xcsift plugin in Claude Code
- Run any non-build Bash command (e.g.,
git status,ls,open ...) - Observe
PreToolUse:Bash hook error/(No output)in output
Suggested Fix
--- a/plugins/claude-code/scripts/pre-xcsift.sh
+++ b/plugins/claude-code/scripts/pre-xcsift.sh
@@ -2,8 +2,6 @@
# xcsift pre-tool hook for Claude Code
# Intercepts xcodebuild and swift build/test commands and pipes through xcsift
-set -e
-
# Read tool input from stdin (JSON with tool_input field)
INPUT=$(cat)
@@ -12,14 +10,14 @@
if [ -z "$COMMAND" ]; then
# No command field, allow as-is
- echo '{"decision": "allow"}'
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"}}'
exit 0
fi
# Check if xcsift is available
if ! command -v xcsift &> /dev/null; then
# xcsift not installed, allow command as-is
- echo '{"decision": "allow"}'
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"}}'
exit 0
fi
@@ -38,8 +36,8 @@
MODIFIED_COMMAND="$COMMAND | xcsift -f toon"
# Return modified command
- jq -n --arg cmd "$MODIFIED_COMMAND" '{"decision": "allow", "updatedCommand": $cmd}'
+ jq -n --arg cmd "$MODIFIED_COMMAND" '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","updatedInput":{"command":$cmd}}}'
else
# Not a build command, allow as-is
- echo '{"decision": "allow"}'
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"}}'
fiA patch file is also attached for convenience.
Reference
The current hook output format is documented at https://docs.claude.com/en/docs/hooks — the hookSpecificOutput structure with permissionDecision replaces the deprecated top-level decision field.