fix: quote plugin paths in shell hook commands for Windows compatibility#30024
Draft
asafkorem wants to merge 4 commits intoanthropics:mainfrom
Draft
fix: quote plugin paths in shell hook commands for Windows compatibility#30024asafkorem wants to merge 4 commits intoanthropics:mainfrom
asafkorem wants to merge 4 commits intoanthropics:mainfrom
Conversation
On Windows, `${CLAUDE_PLUGIN_ROOT}` resolves to a path with backslashes
(e.g., `C:\Users\...`). When the CLI executes hook commands via
`cmd.exe → bash`, unquoted backslashes are interpreted by bash as escape
characters, mangling the path (e.g., `C:\Users` becomes `C:Users`).
Wrapping the substituted path in double quotes preserves backslashes in
bash (only `\$`, `\"`, `\`, `` \` ``, and `\newline` are special in
double-quoted strings). Adding an explicit `bash` prefix ensures
consistent execution across platforms and prevents the CLI's Windows
`.sh` detection from double-prepending.
Affected plugins: ralph-wiggum, learning-output-style,
explanatory-output-style.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…amples
Update all shell script path examples in the plugin-dev skill
documentation to use proper double-quoting around ${CLAUDE_PLUGIN_ROOT}.
This ensures plugins generated using these examples as guidance will
work correctly on Windows, where the substituted path contains
backslashes that bash interprets as escape characters when unquoted.
Affected documentation:
- hook-development: SKILL.md, patterns.md, advanced.md, migration.md
- plugin-structure: SKILL.md, manifest-reference.md, component-patterns,
standard-plugin.md, advanced-plugin.md
- command-development: SKILL.md, plugin-commands.md,
plugin-features-reference.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…aths
- Add explicit `bash` prefix to ralph-loop.md setup script execution
(the Bash tool path doesn't have the CLI's automatic .sh detection)
- Quote remaining unquoted ${CLAUDE_PLUGIN_ROOT} paths in test commands
across plugin-dev documentation examples
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous approach (double-quoting ${CLAUDE_PLUGIN_ROOT}) preserved
backslashes but bash still couldn't resolve Windows paths as script
filenames. The actual fix needs to convert backslashes to forward
slashes at runtime.
New approach uses bash -c with parameter expansion:
bash -c 'bash "${CLAUDE_PLUGIN_ROOT//\//}/hooks/stop-hook.sh"'
How it works:
- ${CLAUDE_PLUGIN_ROOT//\//} is NOT matched by the CLI's pB1 regex
(which only matches ${CLAUDE_PLUGIN_ROOT} exactly)
- CLAUDE_PLUGIN_ROOT env var IS set by the CLI for hook execution
- Bash expands the env var and //\// replaces all \ with /
- Result: C:/Users/.../hooks/stop-hook.sh (forward slashes)
- Works with both shell:true (cmd.exe) and shell:'bash'
Verified end-to-end via Node.js spawnSync simulating exact CLI behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Mar 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
${CLAUDE_PLUGIN_ROOT}substitutionralph-wiggum,learning-output-style,explanatory-output-styleplugins${CLAUDE_PLUGIN_ROOT}in double quotes and adds explicitbashprefix to prevent backslash interpretationProblem
On Windows,
${CLAUDE_PLUGIN_ROOT}resolves to a path with backslashes (e.g.,C:\Users\asafk\.claude\plugins\cache\...). When the CLI executes hook commands viacmd.exe → bash(withshell: true), unquoted backslashes are interpreted by bash as escape characters:Root cause
In the CLI's hook execution function (
rZ6incli.js),${CLAUDE_PLUGIN_ROOT}is replaced with the raw OS path, then the resulting command string is passed to bash without quoting:Fix
Wrap the
${CLAUDE_PLUGIN_ROOT}path in double quotes within hook commands. In bash double quotes, backslashes are only special before$,`,",\, and newline — so\U,\a,\.,\p,\c,\r,\1are all preserved literally.The explicit
bashprefix:bashon Windows (it skips when command already starts withbash)#!/bin/bashshebang on Unix)Verification
Tested on Windows 11 with Git Bash:
Also verified Unix-style forward-slash paths are unaffected.
Test plan
/ralph-loop🤖 Generated with Claude Code