From 7354f4c37f6a0fa2a7a868057dbe46b6b5d176ae Mon Sep 17 00:00:00 2001 From: Asaf Korem Date: Mon, 2 Mar 2026 10:33:19 +0200 Subject: [PATCH 1/4] fix: quote plugin paths in shell hook commands for Windows compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- plugins/explanatory-output-style/hooks/hooks.json | 2 +- plugins/learning-output-style/hooks/hooks.json | 2 +- plugins/ralph-wiggum/hooks/hooks.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/explanatory-output-style/hooks/hooks.json b/plugins/explanatory-output-style/hooks/hooks.json index d1fb8a5734..2478dadf7e 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/hooks/hooks.json b/plugins/learning-output-style/hooks/hooks.json index b3ab7ce9b7..7f66d5ec31 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-wiggum/hooks/hooks.json b/plugins/ralph-wiggum/hooks/hooks.json index 2e5f697934..bfdcddd7ce 100644 --- a/plugins/ralph-wiggum/hooks/hooks.json +++ b/plugins/ralph-wiggum/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\"" } ] } From acf16d75a3e711bbf23174702b77a61e07946b5e Mon Sep 17 00:00:00 2001 From: Asaf Korem Date: Mon, 2 Mar 2026 10:49:39 +0200 Subject: [PATCH 2/4] fix: quote ${CLAUDE_PLUGIN_ROOT} paths in plugin-dev documentation examples 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) --- .../skills/command-development/SKILL.md | 10 +++--- .../examples/plugin-commands.md | 36 +++++++++---------- .../references/plugin-features-reference.md | 14 ++++---- .../skills/hook-development/SKILL.md | 12 +++---- .../hook-development/references/advanced.md | 2 +- .../hook-development/references/migration.md | 2 +- .../hook-development/references/patterns.md | 8 ++--- .../skills/plugin-structure/SKILL.md | 6 ++-- .../examples/advanced-plugin.md | 12 +++---- .../examples/standard-plugin.md | 4 +-- .../references/manifest-reference.md | 2 +- 11 files changed, 54 insertions(+), 54 deletions(-) diff --git a/plugins/plugin-dev/skills/command-development/SKILL.md b/plugins/plugin-dev/skills/command-development/SKILL.md index e39435e14d..1fa9cc2a51 100644 --- a/plugins/plugin-dev/skills/command-development/SKILL.md +++ b/plugins/plugin-dev/skills/command-development/SKILL.md @@ -553,7 +553,7 @@ Review results and report findings. ```markdown # Execute plugin script -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/script.sh` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/script.sh"` # Load plugin configuration @${CLAUDE_PLUGIN_ROOT}/config/settings.json @@ -635,9 +635,9 @@ description: Complete build workflow allowed-tools: Bash(*) --- -Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh` -Test: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test.sh` -Package: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/package.sh` +Build: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/build.sh"` +Test: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/test.sh"` +Package: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/package.sh"` Review outputs and report workflow status. ``` @@ -811,7 +811,7 @@ description: Build with error handling allowed-tools: Bash(*) --- -Execute build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh 2>&1 || echo "BUILD_FAILED"` +Execute build: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/build.sh" 2>&1 || echo "BUILD_FAILED"` If build succeeded: Report success and output location diff --git a/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md b/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md index e14ef4ddbb..a9e1a59380 100644 --- a/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md +++ b/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md @@ -65,13 +65,13 @@ model: sonnet Running complete audit on $1: **Security scan:** -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh $1` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh" $1` **Performance analysis:** -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/perf-analyze.sh $1` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/perf-analyze.sh" $1` **Best practices check:** -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/best-practices.sh $1` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/best-practices.sh" $1` Analyze all results and create comprehensive report including: - Critical issues requiring immediate attention @@ -141,16 +141,16 @@ allowed-tools: Bash(*), Read Executing release workflow for version $1: **Step 1 - Pre-release validation:** -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/pre-release-check.sh $1` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/pre-release-check.sh" $1` **Step 2 - Build artifacts:** -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build-release.sh $1` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/build-release.sh" $1` **Step 3 - Run test suite:** -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/run-tests.sh` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-tests.sh"` **Step 4 - Package release:** -!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/package.sh $1` +!`bash "${CLAUDE_PLUGIN_ROOT}/scripts/package.sh" $1` Review all step outputs and report: 1. Any failures or warnings @@ -358,17 +358,17 @@ allowed-tools: Bash(*) Validate environment argument: !`echo "$1" | grep -E "^(dev|staging|prod)$" && echo "VALID" || echo "INVALID"` -Check build script exists: !`test -x ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh && echo "EXISTS" || echo "MISSING"` +Check build script exists: !`test -x "${CLAUDE_PLUGIN_ROOT}/scripts/build.sh" && echo "EXISTS" || echo "MISSING"` -Verify configuration available: !`test -f ${CLAUDE_PLUGIN_ROOT}/config/$1.json && echo "FOUND" || echo "NOT_FOUND"` +Verify configuration available: !`test -f "${CLAUDE_PLUGIN_ROOT}/config/$1.json" && echo "FOUND" || echo "NOT_FOUND"` If all validations pass: **Configuration:** @${CLAUDE_PLUGIN_ROOT}/config/$1.json -**Execute build:** !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh $1 2>&1` +**Execute build:** !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/build.sh" $1 2>&1` -**Validation results:** !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate-build.sh $1 2>&1` +**Validation results:** !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/validate-build.sh" $1 2>&1` Report build status and any issues. @@ -408,14 +408,14 @@ Load environment configuration: @${CLAUDE_PLUGIN_ROOT}/config/$1-checks.json Determine check level: !`echo "$1" | grep -E "^prod$" && echo "FULL" || echo "BASIC"` **For production environment:** -- Full test suite: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test-full.sh` -- Security scan: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh` -- Performance audit: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/perf-check.sh` -- Compliance check: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/compliance.sh` +- Full test suite: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/test-full.sh"` +- Security scan: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh"` +- Performance audit: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/perf-check.sh"` +- Compliance check: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/compliance.sh"` **For non-production environments:** -- Basic tests: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test-basic.sh` -- Quick lint: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/lint.sh` +- Basic tests: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/test-basic.sh"` +- Quick lint: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/lint.sh"` Analyze results based on environment requirements: @@ -529,7 +529,7 @@ Use for: Verifying required plugin files exist --- allowed-tools: Bash(*) --- - !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/script.sh` + !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/script.sh"` ``` 3. **Not validating inputs:** diff --git a/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md b/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md index c89e9060b4..8b2fdeec9d 100644 --- a/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md +++ b/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md @@ -154,7 +154,7 @@ description: Complete plugin workflow allowed-tools: Bash(*), Read --- -Step 1 - Prepare: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/prepare.sh $1` +Step 1 - Prepare: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/prepare.sh" $1` Step 2 - Config: @${CLAUDE_PLUGIN_ROOT}/config/$1.json Step 3 - Execute: !`${CLAUDE_PLUGIN_ROOT}/bin/execute $1` @@ -179,7 +179,7 @@ Review results and report status. allowed-tools: Bash(test:*), Read --- - !`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "exists" || echo "missing"` + !`test -f "${CLAUDE_PLUGIN_ROOT}/config.json" && echo "exists" || echo "missing"` If config exists, load it: @${CLAUDE_PLUGIN_ROOT}/config.json Otherwise, use defaults... @@ -198,7 +198,7 @@ Review results and report status. 4. **Combine with arguments:** ```markdown - Run: !`${CLAUDE_PLUGIN_ROOT}/bin/process.sh $1 $2` + Run: !`bash "${CLAUDE_PLUGIN_ROOT}/bin/process.sh" $1 $2` ``` ### Troubleshooting @@ -274,9 +274,9 @@ description: Complete build and test workflow allowed-tools: Bash(*) --- -Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh` -Validate: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh` -Test: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test.sh` +Build: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/build.sh"` +Validate: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh"` +Test: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/test.sh"` Review all outputs and report: 1. Build status @@ -528,7 +528,7 @@ description: Build and validate output allowed-tools: Bash(*) --- -Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh` +Build: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/build.sh"` Validate output: - Exit code: !`echo $?` diff --git a/plugins/plugin-dev/skills/hook-development/SKILL.md b/plugins/plugin-dev/skills/hook-development/SKILL.md index d1c0c199c7..3e4e0b2619 100644 --- a/plugins/plugin-dev/skills/hook-development/SKILL.md +++ b/plugins/plugin-dev/skills/hook-development/SKILL.md @@ -46,7 +46,7 @@ Execute bash commands for deterministic checks: ```json { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh\"", "timeout": 60 } ``` @@ -90,7 +90,7 @@ Execute bash commands for deterministic checks: "hooks": [ { "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/validate.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/validate.sh\"" } ] } @@ -248,7 +248,7 @@ Execute when Claude Code session begins. Use to load context and set environment "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh\"" } ] } @@ -333,7 +333,7 @@ Available in all command hooks: ```json { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh\"" } ``` @@ -371,7 +371,7 @@ In plugins, define hooks in `hooks/hooks.json`: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh\"", "timeout": 10 } ] @@ -613,7 +613,7 @@ Test command hooks directly: ```bash echo '{"tool_name": "Write", "tool_input": {"file_path": "/test"}}' | \ - bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh + bash "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh" echo "Exit code: $?" ``` diff --git a/plugins/plugin-dev/skills/hook-development/references/advanced.md b/plugins/plugin-dev/skills/hook-development/references/advanced.md index a84a38fbbf..ad5e2a3044 100644 --- a/plugins/plugin-dev/skills/hook-development/references/advanced.md +++ b/plugins/plugin-dev/skills/hook-development/references/advanced.md @@ -14,7 +14,7 @@ Combine command and prompt hooks for layered validation: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/quick-check.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/quick-check.sh\"", "timeout": 5 }, { diff --git a/plugins/plugin-dev/skills/hook-development/references/migration.md b/plugins/plugin-dev/skills/hook-development/references/migration.md index 587cae37e6..6c9f9bb570 100644 --- a/plugins/plugin-dev/skills/hook-development/references/migration.md +++ b/plugins/plugin-dev/skills/hook-development/references/migration.md @@ -214,7 +214,7 @@ Combine both for multi-stage validation: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/quick-check.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/quick-check.sh\"", "timeout": 5 }, { diff --git a/plugins/plugin-dev/skills/hook-development/references/patterns.md b/plugins/plugin-dev/skills/hook-development/references/patterns.md index 447538654d..52fb45c27f 100644 --- a/plugins/plugin-dev/skills/hook-development/references/patterns.md +++ b/plugins/plugin-dev/skills/hook-development/references/patterns.md @@ -58,7 +58,7 @@ Load project-specific context at session start: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh\"" } ] } @@ -95,7 +95,7 @@ Log all notifications for audit or analysis: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/log-notification.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/log-notification.sh\"" } ] } @@ -183,7 +183,7 @@ Run linters or formatters on file edits: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/check-quality.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/check-quality.sh\"" } ] } @@ -248,7 +248,7 @@ Combine multiple patterns for comprehensive protection: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/load-context.sh\"" } ] } diff --git a/plugins/plugin-dev/skills/plugin-structure/SKILL.md b/plugins/plugin-dev/skills/plugin-structure/SKILL.md index 6fb8a3baa1..0bec565425 100644 --- a/plugins/plugin-dev/skills/plugin-structure/SKILL.md +++ b/plugins/plugin-dev/skills/plugin-structure/SKILL.md @@ -219,7 +219,7 @@ hooks/ "matcher": "Write|Edit", "hooks": [{ "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate.sh\"", "timeout": 30 }] }] @@ -261,7 +261,7 @@ Use `${CLAUDE_PLUGIN_ROOT}` environment variable for all intra-plugin path refer ```json { - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/run.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/run.sh\"" } ``` @@ -285,7 +285,7 @@ Use `${CLAUDE_PLUGIN_ROOT}` environment variable for all intra-plugin path refer **In manifest JSON fields** (hooks, MCP servers): ```json -"command": "${CLAUDE_PLUGIN_ROOT}/scripts/tool.sh" +"command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/tool.sh\"" ``` **In component files** (commands, agents, skills): diff --git a/plugins/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md b/plugins/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md index a7c069691e..4f2a74477b 100644 --- a/plugins/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md +++ b/plugins/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md @@ -622,7 +622,7 @@ For copy-paste examples: For manifest validation: \`\`\`bash -bash ${CLAUDE_PLUGIN_ROOT}/skills/kubernetes-ops/scripts/validate-manifest.sh deployment.yaml +bash "${CLAUDE_PLUGIN_ROOT}/skills/kubernetes-ops/scripts/validate-manifest.sh" deployment.yaml \`\`\` ``` @@ -636,7 +636,7 @@ bash ${CLAUDE_PLUGIN_ROOT}/skills/kubernetes-ops/scripts/validate-manifest.sh de "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/security/scan-secrets.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/security/scan-secrets.sh\"", "timeout": 30 } ] @@ -658,7 +658,7 @@ bash ${CLAUDE_PLUGIN_ROOT}/skills/kubernetes-ops/scripts/validate-manifest.sh de "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/workflow/update-status.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/workflow/update-status.sh\"", "timeout": 15 } ] @@ -670,12 +670,12 @@ bash ${CLAUDE_PLUGIN_ROOT}/skills/kubernetes-ops/scripts/validate-manifest.sh de "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/quality/check-config.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/quality/check-config.sh\"", "timeout": 45 }, { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/workflow/notify-team.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/workflow/notify-team.sh\"", "timeout": 30 } ] @@ -687,7 +687,7 @@ bash ${CLAUDE_PLUGIN_ROOT}/skills/kubernetes-ops/scripts/validate-manifest.sh de "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/security/validate-permissions.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/security/validate-permissions.sh\"", "timeout": 20 } ] diff --git a/plugins/plugin-dev/skills/plugin-structure/examples/standard-plugin.md b/plugins/plugin-dev/skills/plugin-structure/examples/standard-plugin.md index d903166556..43be7567f1 100644 --- a/plugins/plugin-dev/skills/plugin-structure/examples/standard-plugin.md +++ b/plugins/plugin-dev/skills/plugin-structure/examples/standard-plugin.md @@ -78,7 +78,7 @@ Run comprehensive linting checks on the project codebase. Execute the linting script: \`\`\`bash -bash ${CLAUDE_PLUGIN_ROOT}/scripts/run-linter.sh +bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-linter.sh" \`\`\` Parse the output and present issues organized by: @@ -445,7 +445,7 @@ See language-specific guides for: "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-commit.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-commit.sh\"", "timeout": 45 } ] diff --git a/plugins/plugin-dev/skills/plugin-structure/references/manifest-reference.md b/plugins/plugin-dev/skills/plugin-structure/references/manifest-reference.md index 40c9c2f363..54b384a6f8 100644 --- a/plugins/plugin-dev/skills/plugin-structure/references/manifest-reference.md +++ b/plugins/plugin-dev/skills/plugin-structure/references/manifest-reference.md @@ -280,7 +280,7 @@ Hook configuration location or inline definition. "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh\"", "timeout": 30 } ] From 82bebd55ab98bc1f48d23473b3868e2914930cb8 Mon Sep 17 00:00:00 2001 From: Asaf Korem Date: Mon, 2 Mar 2026 10:56:15 +0200 Subject: [PATCH 3/4] fix: add bash prefix to ralph-loop command and quote remaining test paths - 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) --- plugins/plugin-dev/skills/command-development/SKILL.md | 4 ++-- .../skills/command-development/examples/plugin-commands.md | 2 +- .../references/plugin-features-reference.md | 6 +++--- plugins/ralph-wiggum/commands/ralph-loop.md | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/plugin-dev/skills/command-development/SKILL.md b/plugins/plugin-dev/skills/command-development/SKILL.md index 1fa9cc2a51..53b8fc646e 100644 --- a/plugins/plugin-dev/skills/command-development/SKILL.md +++ b/plugins/plugin-dev/skills/command-development/SKILL.md @@ -796,8 +796,8 @@ allowed-tools: Bash(test:*) --- Validate plugin setup: -- Script: !`test -x ${CLAUDE_PLUGIN_ROOT}/bin/analyze && echo "✓" || echo "✗"` -- Config: !`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "✓" || echo "✗"` +- Script: !`test -x "${CLAUDE_PLUGIN_ROOT}/bin/analyze" && echo "✓" || echo "✗"` +- Config: !`test -f "${CLAUDE_PLUGIN_ROOT}/config.json" && echo "✓" || echo "✗"` If all checks pass, run analysis. Otherwise, report missing components. diff --git a/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md b/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md index a9e1a59380..7fc0335bfb 100644 --- a/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md +++ b/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md @@ -474,7 +474,7 @@ Use for: Validating command arguments ### Pattern: Resource Validation ```markdown -Check exists: !`test -f ${CLAUDE_PLUGIN_ROOT}/path/file && echo "YES" || echo "NO"` +Check exists: !`test -f "${CLAUDE_PLUGIN_ROOT}/path/file" && echo "YES" || echo "NO"` ``` Use for: Verifying required plugin files exist diff --git a/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md b/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md index 8b2fdeec9d..00d8b96929 100644 --- a/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md +++ b/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md @@ -510,9 +510,9 @@ allowed-tools: Bash(test:*) --- Validate plugin setup: -- Config exists: !`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "✓" || echo "✗"` -- Scripts exist: !`test -d ${CLAUDE_PLUGIN_ROOT}/scripts && echo "✓" || echo "✗"` -- Tools available: !`test -x ${CLAUDE_PLUGIN_ROOT}/bin/analyze && echo "✓" || echo "✗"` +- Config exists: !`test -f "${CLAUDE_PLUGIN_ROOT}/config.json" && echo "✓" || echo "✗"` +- Scripts exist: !`test -d "${CLAUDE_PLUGIN_ROOT}/scripts" && echo "✓" || echo "✗"` +- Tools available: !`test -x "${CLAUDE_PLUGIN_ROOT}/bin/analyze" && echo "✓" || echo "✗"` If all checks pass, proceed with analysis. Otherwise, report missing components and installation steps. diff --git a/plugins/ralph-wiggum/commands/ralph-loop.md b/plugins/ralph-wiggum/commands/ralph-loop.md index 3b4dbcb62a..d7277ff681 100644 --- a/plugins/ralph-wiggum/commands/ralph-loop.md +++ b/plugins/ralph-wiggum/commands/ralph-loop.md @@ -10,7 +10,7 @@ hide-from-slash-command-tool: "true" Execute the setup script to initialize the Ralph loop: ```! -"${CLAUDE_PLUGIN_ROOT}/scripts/setup-ralph-loop.sh" $ARGUMENTS +bash "${CLAUDE_PLUGIN_ROOT}/scripts/setup-ralph-loop.sh" $ARGUMENTS ``` Please work on the task. When you try to exit, the Ralph loop will feed the SAME PROMPT back to you for the next iteration. You'll see your previous work in files and git history, allowing you to iterate and improve. From 71de019a7f06240dcaf4ac30d8585dd908b7831a Mon Sep 17 00:00:00 2001 From: Asaf Korem Date: Mon, 2 Mar 2026 12:08:22 +0200 Subject: [PATCH 4/4] fix: use bash -c with path normalization for Windows compatibility 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) --- plugins/explanatory-output-style/hooks/hooks.json | 2 +- plugins/learning-output-style/hooks/hooks.json | 2 +- plugins/ralph-wiggum/commands/ralph-loop.md | 2 +- plugins/ralph-wiggum/hooks/hooks.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/explanatory-output-style/hooks/hooks.json b/plugins/explanatory-output-style/hooks/hooks.json index 2478dadf7e..0f24fcd7c9 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": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh\"" + "command": "bash -c 'bash \"${CLAUDE_PLUGIN_ROOT//\\\\//}/hooks-handlers/session-start.sh\"'" } ] } diff --git a/plugins/learning-output-style/hooks/hooks.json b/plugins/learning-output-style/hooks/hooks.json index 7f66d5ec31..39a585c770 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": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh\"" + "command": "bash -c 'bash \"${CLAUDE_PLUGIN_ROOT//\\\\//}/hooks-handlers/session-start.sh\"'" } ] } diff --git a/plugins/ralph-wiggum/commands/ralph-loop.md b/plugins/ralph-wiggum/commands/ralph-loop.md index d7277ff681..83151c4799 100644 --- a/plugins/ralph-wiggum/commands/ralph-loop.md +++ b/plugins/ralph-wiggum/commands/ralph-loop.md @@ -10,7 +10,7 @@ hide-from-slash-command-tool: "true" Execute the setup script to initialize the Ralph loop: ```! -bash "${CLAUDE_PLUGIN_ROOT}/scripts/setup-ralph-loop.sh" $ARGUMENTS +bash -c 'bash "${CLAUDE_PLUGIN_ROOT//\\//}/scripts/setup-ralph-loop.sh" $ARGUMENTS' ``` Please work on the task. When you try to exit, the Ralph loop will feed the SAME PROMPT back to you for the next iteration. You'll see your previous work in files and git history, allowing you to iterate and improve. diff --git a/plugins/ralph-wiggum/hooks/hooks.json b/plugins/ralph-wiggum/hooks/hooks.json index bfdcddd7ce..66fe3b4a0c 100644 --- a/plugins/ralph-wiggum/hooks/hooks.json +++ b/plugins/ralph-wiggum/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh\"" + "command": "bash -c 'bash \"${CLAUDE_PLUGIN_ROOT//\\\\//}/hooks/stop-hook.sh\"'" } ] }