Skip to content

Commit 8db8955

Browse files
sjnimsclaude
andauthored
fix: replace ! with [BANG] placeholder in skill documentation (#142)
## Summary - Replace `!` followed by backticks with `[BANG]` placeholder in command-development skill files - Prevents bash execution errors when skills are loaded into Claude's context ## Problem Skill documentation containing the `!` prefix (used for pre-execution in slash commands) triggers unintended bash execution when the skill content is loaded. This causes errors like: ``` Bash command permission check failed for pattern "!`...": Command contains newlines... ``` ## Solution Use `[BANG]` as a placeholder in skill documentation. When Claude explains the concept to users, it correctly renders the actual `!` syntax they should use in their command files. ## Related Issue Workaround for anthropics/claude-code#12781 ## Test plan - [x] Load plugin locally with `cc --plugin-dir plugins/plugin-dev` - [x] Trigger skill loading by asking about command development - [x] Trigger reference file loading by asking about CLAUDE_PLUGIN_ROOT - [x] Verify no bash execution errors occur 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2e0779e commit 8db8955

2 files changed

Lines changed: 38 additions & 38 deletions

File tree

plugins/plugin-dev/skills/command-development/SKILL.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,28 +337,28 @@ Ensure:
337337

338338
Commands can execute bash commands inline to dynamically gather context before Claude processes the command. This is useful for including repository state, environment information, or project-specific context.
339339

340-
### Syntax: The `!` Prefix
340+
### Syntax: The `[BANG]` Prefix
341341

342-
In actual command files, use the `!` prefix before backticks for pre-execution:
342+
In actual command files, use `[BANG]` (exclamation mark) before backticks for pre-execution:
343343

344344
```markdown
345-
Current branch: !`git branch --show-current`
346-
Files changed: !`git diff --name-only`
347-
Environment: !`echo $NODE_ENV`
345+
Current branch: [BANG]`git branch --show-current`
346+
Files changed: [BANG]`git diff --name-only`
347+
Environment: [BANG]`echo $NODE_ENV`
348348
```
349349

350350
**How it works:**
351351

352-
1. Before Claude sees the command, Claude Code executes `!`command`` blocks
353-
2. The bash output replaces the entire `!`command`` expression
352+
1. Before Claude sees the command, Claude Code executes `[BANG]`command`` blocks
353+
2. The bash output replaces the entire `[BANG]`command`` expression
354354
3. Claude receives the expanded prompt with actual values
355355

356356
**Example expansion:**
357357

358358
Command file contains:
359359

360360
```markdown
361-
Review the !`git diff --name-only | wc -l | tr -d ' '` changed files on branch !`git branch --show-current`.
361+
Review the [BANG]`git diff --name-only | wc -l | tr -d ' '` changed files on branch [BANG]`git branch --show-current`.
362362
```
363363

364364
Claude receives (after pre-execution):
@@ -367,15 +367,15 @@ Claude receives (after pre-execution):
367367
Review the 3 changed files on branch feature/add-auth.
368368
```
369369

370-
### Why Skill Examples Omit `!`
370+
### Why Skill Examples Omit `[BANG]`
371371

372-
Examples in skill documentation use plain backticks without `!`:
372+
Examples in skill documentation use plain backticks without `[BANG]`:
373373

374374
```markdown
375375
Files changed: `git diff --name-only`
376376
```
377377

378-
This is intentional. When skill content loads into Claude's context, `!`command`` would actually execute. Skill examples show the conceptual pattern; add the `!` prefix when writing actual command files.
378+
This is intentional. When skill content loads into Claude's context, `[BANG]` followed by `[command name]` would actually execute. Skill examples show the conceptual pattern; add the `[BANG]` prefix when writing actual command files.
379379

380380
**When to use:**
381381

plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ description: Analyze using plugin script
9494
allowed-tools: Bash(node:*), Read
9595
---
9696

97-
Run analysis: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js`
97+
Run analysis: [BANG]`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js`
9898

9999
Read template: @${CLAUDE_PLUGIN_ROOT}/templates/report.md
100100
```
@@ -117,7 +117,7 @@ description: Run custom linter from plugin
117117
allowed-tools: Bash(node:*)
118118
---
119119

120-
Lint results: !`node ${CLAUDE_PLUGIN_ROOT}/bin/lint.js $1`
120+
Lint results: [BANG]`node ${CLAUDE_PLUGIN_ROOT}/bin/lint.js $1`
121121

122122
Review the linting output and suggest fixes.
123123
```
@@ -155,9 +155,9 @@ description: Complete plugin workflow
155155
allowed-tools: Bash(*), Read
156156
---
157157

158-
Step 1 - Prepare: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/prepare.sh $1`
158+
Step 1 - Prepare: [BANG]`bash ${CLAUDE_PLUGIN_ROOT}/scripts/prepare.sh $1`
159159
Step 2 - Config: @${CLAUDE_PLUGIN_ROOT}/config/$1.json
160-
Step 3 - Execute: !`${CLAUDE_PLUGIN_ROOT}/bin/execute $1`
160+
Step 3 - Execute: [BANG]`${CLAUDE_PLUGIN_ROOT}/bin/execute $1`
161161

162162
Review results and report status.
163163
```
@@ -180,7 +180,7 @@ Review results and report status.
180180
allowed-tools: Bash(test:*), Read
181181
---
182182

183-
!`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "exists" || echo "missing"`
183+
[BANG]`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "exists" || echo "missing"`
184184

185185
If config exists, load it: @${CLAUDE_PLUGIN_ROOT}/config.json
186186
Otherwise, use defaults...
@@ -199,7 +199,7 @@ Review results and report status.
199199

200200
4. **Combine with arguments:**
201201
```markdown
202-
Run: !`${CLAUDE_PLUGIN_ROOT}/bin/process.sh $1 $2`
202+
Run: [BANG]`${CLAUDE_PLUGIN_ROOT}/bin/process.sh $1 $2`
203203
```
204204

205205
### Troubleshooting
@@ -235,8 +235,8 @@ Load configuration: @${CLAUDE_PLUGIN_ROOT}/deploy-config.json
235235

236236
Deploy to $1 environment using:
237237
1. Configuration settings above
238-
2. Current git branch: !`git branch --show-current`
239-
3. Application version: !`cat package.json | grep version`
238+
2. Current git branch: [BANG]`git branch --show-current`
239+
3. Application version: [BANG]`cat package.json | grep version`
240240

241241
Execute deployment and monitor progress.
242242
```
@@ -275,9 +275,9 @@ description: Complete build and test workflow
275275
allowed-tools: Bash(*)
276276
---
277277

278-
Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
279-
Validate: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh`
280-
Test: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test.sh`
278+
Build: [BANG]`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
279+
Validate: [BANG]`bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh`
280+
Test: [BANG]`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test.sh`
281281

282282
Review all outputs and report:
283283
1. Build status
@@ -300,7 +300,7 @@ argument-hint: [dev|staging|prod]
300300

301301
Environment config: @${CLAUDE_PLUGIN_ROOT}/config/$1.json
302302

303-
Environment check: !`echo "Deploying to: $1"`
303+
Environment check: [BANG]`echo "Deploying to: $1"`
304304

305305
Deploy application using $1 environment configuration.
306306
Verify deployment and run smoke tests.
@@ -321,7 +321,7 @@ allowed-tools: Bash(*), Read, Write
321321
Cache directory: ${CLAUDE_PLUGIN_ROOT}/cache/
322322

323323
Analyze @$1 and save results to cache:
324-
!`mkdir -p ${CLAUDE_PLUGIN_ROOT}/cache && date > ${CLAUDE_PLUGIN_ROOT}/cache/last-run.txt`
324+
[BANG]`mkdir -p ${CLAUDE_PLUGIN_ROOT}/cache && date > ${CLAUDE_PLUGIN_ROOT}/cache/last-run.txt`
325325

326326
Store analysis for future reference and comparison.
327327
```
@@ -393,9 +393,9 @@ description: Commit with pre-commit validation
393393
allowed-tools: Bash(git:*)
394394
---
395395

396-
Stage changes: !`git add $1`
396+
Stage changes: [BANG]`git add $1`
397397

398-
Commit changes: !`git commit -m "$2"`
398+
Commit changes: [BANG]`git commit -m "$2"`
399399

400400
Note: This commit will trigger the plugin's pre-commit hook for validation.
401401
Review hook output for any issues.
@@ -421,7 +421,7 @@ File to review: @$1
421421
Execute comprehensive review:
422422

423423
1. **Static Analysis** (via plugin scripts)
424-
!`node ${CLAUDE_PLUGIN_ROOT}/scripts/lint.js $1`
424+
[BANG]`node ${CLAUDE_PLUGIN_ROOT}/scripts/lint.js $1`
425425

426426
2. **Deep Review** (via plugin agent)
427427
Launch the code-reviewer agent for detailed analysis.
@@ -449,7 +449,7 @@ description: Deploy to environment with validation
449449
argument-hint: [environment]
450450
---
451451

452-
Validate environment: !`echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`
452+
Validate environment: [BANG]`echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`
453453

454454
$IF($1 in [dev, staging, prod],
455455
Deploy to $1 environment using validated configuration,
@@ -472,7 +472,7 @@ description: Process configuration file
472472
argument-hint: [config-file]
473473
---
474474

475-
Check file: !`test -f $1 && echo "EXISTS" || echo "MISSING"`
475+
Check file: [BANG]`test -f $1 && echo "EXISTS" || echo "MISSING"`
476476

477477
Process configuration if file exists: @$1
478478

@@ -492,7 +492,7 @@ description: Create deployment with version
492492
argument-hint: [environment] [version]
493493
---
494494

495-
Validate inputs: !`test -n "$1" -a -n "$2" && echo "OK" || echo "MISSING"`
495+
Validate inputs: [BANG]`test -n "$1" -a -n "$2" && echo "OK" || echo "MISSING"`
496496

497497
$IF($1 AND $2,
498498
Deploy version $2 to $1 environment,
@@ -511,9 +511,9 @@ allowed-tools: Bash(test:*)
511511
---
512512

513513
Validate plugin setup:
514-
- Config exists: !`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "✓" || echo "✗"`
515-
- Scripts exist: !`test -d ${CLAUDE_PLUGIN_ROOT}/scripts && echo "✓" || echo "✗"`
516-
- Tools available: !`test -x ${CLAUDE_PLUGIN_ROOT}/bin/analyze && echo "✓" || echo "✗"`
514+
- Config exists: [BANG]`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "✓" || echo "✗"`
515+
- Scripts exist: [BANG]`test -d ${CLAUDE_PLUGIN_ROOT}/scripts && echo "✓" || echo "✗"`
516+
- Tools available: [BANG]`test -x ${CLAUDE_PLUGIN_ROOT}/bin/analyze && echo "✓" || echo "✗"`
517517

518518
If all checks pass, proceed with analysis.
519519
Otherwise, report missing components and installation steps.
@@ -529,12 +529,12 @@ description: Build and validate output
529529
allowed-tools: Bash(*)
530530
---
531531

532-
Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
532+
Build: [BANG]`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
533533

534534
Validate output:
535-
- Exit code: !`echo $?`
536-
- Output exists: !`test -d dist && echo "✓" || echo "✗"`
537-
- File count: !`find dist -type f | wc -l`
535+
- Exit code: [BANG]`echo $?`
536+
- Output exists: [BANG]`test -d dist && echo "✓" || echo "✗"`
537+
- File count: [BANG]`find dist -type f | wc -l`
538538

539539
Report build status and any validation failures.
540540
```
@@ -549,7 +549,7 @@ description: Process file with error handling
549549
argument-hint: [file-path]
550550
---
551551

552-
Try processing: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/process.js $1 2>&1 || echo "ERROR: $?"`
552+
Try processing: [BANG]`node ${CLAUDE_PLUGIN_ROOT}/scripts/process.js $1 2>&1 || echo "ERROR: $?"`
553553

554554
If processing succeeded:
555555
- Report results

0 commit comments

Comments
 (0)