Skip to content

Commit ff1d878

Browse files
sjnimsclaude
andcommitted
docs(command-development): document bash ! prefix for pre-execution syntax
Document the `!`command`` syntax required for bash pre-execution in actual command files: - Add "Syntax: The `!` Prefix" section explaining how pre-execution works - Document that `!`command`` executes before Claude sees the prompt - Explain why skill examples omit `!` (would execute when loaded) - Update reference file examples to use `!` prefix consistently Users copying examples from the reference file into actual command files will now have the correct syntax. Fixes #46 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 3b374b2 commit ff1d878

2 files changed

Lines changed: 69 additions & 28 deletions

File tree

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,54 @@ Ensure:
334334

335335
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.
336336

337+
### Syntax: The `!` Prefix
338+
339+
In actual command files, use the `!` prefix before backticks for pre-execution:
340+
341+
```markdown
342+
Current branch: !`git branch --show-current`
343+
Files changed: !`git diff --name-only`
344+
Environment: !`echo $NODE_ENV`
345+
```
346+
347+
**How it works:**
348+
349+
1. Before Claude sees the command, Claude Code executes `!`command`` blocks
350+
2. The bash output replaces the entire `!`command`` expression
351+
3. Claude receives the expanded prompt with actual values
352+
353+
**Example expansion:**
354+
355+
Command file contains:
356+
357+
```markdown
358+
Review the !`git diff --name-only | wc -l | tr -d ' '` changed files on branch !`git branch --show-current`.
359+
```
360+
361+
Claude receives (after pre-execution):
362+
363+
```markdown
364+
Review the 3 changed files on branch feature/add-auth.
365+
```
366+
367+
### Why Skill Examples Omit `!`
368+
369+
Examples in skill documentation use plain backticks without `!`:
370+
371+
```markdown
372+
Files changed: `git diff --name-only`
373+
```
374+
375+
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.
376+
337377
**When to use:**
338378

339379
- Include dynamic context (git status, environment vars, etc.)
340380
- Gather project/repository state
341381
- Build context-aware workflows
342382

343383
**Implementation details:**
344-
For complete syntax, examples, and best practices, see `references/plugin-features-reference.md` section on bash execution. The reference includes the exact syntax and multiple working examples to avoid execution issues
384+
For advanced patterns, environment-specific configurations, and plugin integration, see `references/plugin-features-reference.md`
345385

346386
## Command Organization
347387

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

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,15 @@ 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: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js`
9898

9999
Read template: @${CLAUDE_PLUGIN_ROOT}/templates/report.md
100100
```
101101

102102
**Expands to:**
103-
```
104-
Run analysis: `node /path/to/plugins/plugin-name/scripts/analyze.js`
103+
104+
```markdown
105+
Run analysis: [actual output from analyze.js]
105106

106107
Read template: @/path/to/plugins/plugin-name/templates/report.md
107108
```
@@ -116,7 +117,7 @@ description: Run custom linter from plugin
116117
allowed-tools: Bash(node:*)
117118
---
118119

119-
Lint results: `node ${CLAUDE_PLUGIN_ROOT}/bin/lint.js $1`
120+
Lint results: !`node ${CLAUDE_PLUGIN_ROOT}/bin/lint.js $1`
120121

121122
Review the linting output and suggest fixes.
122123
```
@@ -154,9 +155,9 @@ description: Complete plugin workflow
154155
allowed-tools: Bash(*), Read
155156
---
156157

157-
Step 1 - Prepare: `bash ${CLAUDE_PLUGIN_ROOT}/scripts/prepare.sh $1`
158+
Step 1 - Prepare: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/prepare.sh $1`
158159
Step 2 - Config: @${CLAUDE_PLUGIN_ROOT}/config/$1.json
159-
Step 3 - Execute: `${CLAUDE_PLUGIN_ROOT}/bin/execute $1`
160+
Step 3 - Execute: !`${CLAUDE_PLUGIN_ROOT}/bin/execute $1`
160161

161162
Review results and report status.
162163
```
@@ -179,7 +180,7 @@ Review results and report status.
179180
allowed-tools: Bash(test:*), Read
180181
---
181182

182-
`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "exists" || echo "missing"`
183+
!`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "exists" || echo "missing"`
183184

184185
If config exists, load it: @${CLAUDE_PLUGIN_ROOT}/config.json
185186
Otherwise, use defaults...
@@ -198,7 +199,7 @@ Review results and report status.
198199

199200
4. **Combine with arguments:**
200201
```markdown
201-
Run: `${CLAUDE_PLUGIN_ROOT}/bin/process.sh $1 $2`
202+
Run: !`${CLAUDE_PLUGIN_ROOT}/bin/process.sh $1 $2`
202203
```
203204

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

235236
Deploy to $1 environment using:
236237
1. Configuration settings above
237-
2. Current git branch: `git branch --show-current`
238-
3. Application version: `cat package.json | grep version`
238+
2. Current git branch: !`git branch --show-current`
239+
3. Application version: !`cat package.json | grep version`
239240

240241
Execute deployment and monitor progress.
241242
```
@@ -274,9 +275,9 @@ description: Complete build and test workflow
274275
allowed-tools: Bash(*)
275276
---
276277

277-
Build: `bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
278-
Validate: `bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh`
279-
Test: `bash ${CLAUDE_PLUGIN_ROOT}/scripts/test.sh`
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`
280281

281282
Review all outputs and report:
282283
1. Build status
@@ -299,7 +300,7 @@ argument-hint: [dev|staging|prod]
299300

300301
Environment config: @${CLAUDE_PLUGIN_ROOT}/config/$1.json
301302

302-
Environment check: `echo "Deploying to: $1"`
303+
Environment check: !`echo "Deploying to: $1"`
303304

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

322323
Analyze @$1 and save results to cache:
323-
`mkdir -p ${CLAUDE_PLUGIN_ROOT}/cache && date > ${CLAUDE_PLUGIN_ROOT}/cache/last-run.txt`
324+
!`mkdir -p ${CLAUDE_PLUGIN_ROOT}/cache && date > ${CLAUDE_PLUGIN_ROOT}/cache/last-run.txt`
324325

325326
Store analysis for future reference and comparison.
326327
```
@@ -420,7 +421,7 @@ File to review: @$1
420421
Execute comprehensive review:
421422

422423
1. **Static Analysis** (via plugin scripts)
423-
`node ${CLAUDE_PLUGIN_ROOT}/scripts/lint.js $1`
424+
!`node ${CLAUDE_PLUGIN_ROOT}/scripts/lint.js $1`
424425

425426
2. **Deep Review** (via plugin agent)
426427
Launch the code-reviewer agent for detailed analysis.
@@ -448,7 +449,7 @@ description: Deploy to environment with validation
448449
argument-hint: [environment]
449450
---
450451

451-
Validate environment: `echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`
452+
Validate environment: !`echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`
452453

453454
$IF($1 in [dev, staging, prod],
454455
Deploy to $1 environment using validated configuration,
@@ -471,7 +472,7 @@ description: Process configuration file
471472
argument-hint: [config-file]
472473
---
473474

474-
Check file: `test -f $1 && echo "EXISTS" || echo "MISSING"`
475+
Check file: !`test -f $1 && echo "EXISTS" || echo "MISSING"`
475476

476477
Process configuration if file exists: @$1
477478

@@ -491,7 +492,7 @@ description: Create deployment with version
491492
argument-hint: [environment] [version]
492493
---
493494

494-
Validate inputs: `test -n "$1" -a -n "$2" && echo "OK" || echo "MISSING"`
495+
Validate inputs: !`test -n "$1" -a -n "$2" && echo "OK" || echo "MISSING"`
495496

496497
$IF($1 AND $2,
497498
Deploy version $2 to $1 environment,
@@ -510,9 +511,9 @@ allowed-tools: Bash(test:*)
510511
---
511512

512513
Validate plugin setup:
513-
- Config exists: `test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "✓" || echo "✗"`
514-
- Scripts exist: `test -d ${CLAUDE_PLUGIN_ROOT}/scripts && echo "✓" || echo "✗"`
515-
- Tools available: `test -x ${CLAUDE_PLUGIN_ROOT}/bin/analyze && echo "✓" || echo "✗"`
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 "✗"`
516517

517518
If all checks pass, proceed with analysis.
518519
Otherwise, report missing components and installation steps.
@@ -528,12 +529,12 @@ description: Build and validate output
528529
allowed-tools: Bash(*)
529530
---
530531

531-
Build: `bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
532+
Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
532533

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

538539
Report build status and any validation failures.
539540
```
@@ -548,7 +549,7 @@ description: Process file with error handling
548549
argument-hint: [file-path]
549550
---
550551

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

553554
If processing succeeded:
554555
- Report results

0 commit comments

Comments
 (0)