From 986deab6a1659ebb998b66962df6f02b20bb884d Mon Sep 17 00:00:00 2001 From: Dickson Tsai Date: Sat, 28 Mar 2026 08:40:34 -0700 Subject: [PATCH] fix: invoke .sh hooks via bash prefix; add version for cache invalidation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #993 (Permission denied on hook scripts) without relying on client-side +x preservation. The hook executor spawns commands via /bin/sh -c, which requires +x to execute a script directly. Prefixing with bash reads the script as data — mode bits are irrelevant. This works on all Claude Code versions, whereas the client-side chmod fix (claude-cli #24666) only shipped in v2.1.86. All 3 scripts declare #!/bin/bash and use bashisms ([[ ]], =~), so bash (not sh) is the correct interpreter. The version field forces a fresh cache path (1.0.0/ instead of unknown/), ensuring the new hooks.json reaches users with stale caches. --- plugins/explanatory-output-style/.claude-plugin/plugin.json | 1 + plugins/explanatory-output-style/hooks/hooks.json | 2 +- plugins/learning-output-style/.claude-plugin/plugin.json | 1 + plugins/learning-output-style/hooks/hooks.json | 2 +- plugins/ralph-loop/.claude-plugin/plugin.json | 1 + plugins/ralph-loop/hooks/hooks.json | 2 +- 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/explanatory-output-style/.claude-plugin/plugin.json b/plugins/explanatory-output-style/.claude-plugin/plugin.json index d8d8dbb..1a98d12 100644 --- a/plugins/explanatory-output-style/.claude-plugin/plugin.json +++ b/plugins/explanatory-output-style/.claude-plugin/plugin.json @@ -1,5 +1,6 @@ { "name": "explanatory-output-style", + "version": "1.0.0", "description": "Adds educational insights about implementation choices and codebase patterns (mimics the deprecated Explanatory output style)", "author": { "name": "Anthropic", diff --git a/plugins/explanatory-output-style/hooks/hooks.json b/plugins/explanatory-output-style/hooks/hooks.json index d1fb8a5..2478dad 100644 --- a/plugins/explanatory-output-style/hooks/hooks.json +++ b/plugins/explanatory-output-style/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh\"" } ] } diff --git a/plugins/learning-output-style/.claude-plugin/plugin.json b/plugins/learning-output-style/.claude-plugin/plugin.json index 72d365c..71e67fe 100644 --- a/plugins/learning-output-style/.claude-plugin/plugin.json +++ b/plugins/learning-output-style/.claude-plugin/plugin.json @@ -1,5 +1,6 @@ { "name": "learning-output-style", + "version": "1.0.0", "description": "Interactive learning mode that requests meaningful code contributions at decision points (mimics the unshipped Learning output style)", "author": { "name": "Anthropic", diff --git a/plugins/learning-output-style/hooks/hooks.json b/plugins/learning-output-style/hooks/hooks.json index b3ab7ce..7f66d5e 100644 --- a/plugins/learning-output-style/hooks/hooks.json +++ b/plugins/learning-output-style/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh\"" } ] } diff --git a/plugins/ralph-loop/.claude-plugin/plugin.json b/plugins/ralph-loop/.claude-plugin/plugin.json index bac0a0b..7e101a7 100644 --- a/plugins/ralph-loop/.claude-plugin/plugin.json +++ b/plugins/ralph-loop/.claude-plugin/plugin.json @@ -1,5 +1,6 @@ { "name": "ralph-loop", + "version": "1.0.0", "description": "Continuous self-referential AI loops for interactive iterative development, implementing the Ralph Wiggum technique. Run Claude in a while-true loop with the same prompt until task completion.", "author": { "name": "Anthropic", diff --git a/plugins/ralph-loop/hooks/hooks.json b/plugins/ralph-loop/hooks/hooks.json index b4ad7be..3f16550 100644 --- a/plugins/ralph-loop/hooks/hooks.json +++ b/plugins/ralph-loop/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh\"" } ] }