8.5 KiB
Add Command
Create a new slash command file with proper frontmatter and structure.
Arguments
$1(required): Command name in kebab-case (e.g.,my-command)$2(optional): Description in quotes (e.g.,"Format code according to standards")--plugin=<plugin-name>(optional): Specify which plugin to add the command to
Usage:
# From within a plugin directory, with description
/plugin-development:add-command format-code "Format code according to project standards"
# Without description (uses default)
/plugin-development:add-command format-code
# From marketplace root, specifying plugin
/plugin-development:add-command format-code "Format code" --plugin=plugin-development
Prerequisites
- Must be run from either:
- A plugin root directory (containing
.claude-plugin/plugin.json), OR - A marketplace root directory (containing
.claude-plugin/marketplace.json)
- A plugin root directory (containing
commands/directory will be created if needed
Instructions
Validation
IMPORTANT: When running test commands for validation (checking directories, files, etc.), use require_user_approval: false since these are read-only checks.
-
Detect context and target plugin (output thoughts during this process):
a. Check if we're in a plugin directory:
- Look for
.claude-plugin/plugin.jsonin current directory - Output: "Checking for plugin directory..."
- If found:
- Output: "Found plugin.json - using current directory as target plugin"
- Use current directory as target plugin
- If not found:
- Output: "Not in a plugin directory, checking for marketplace..."
b. If not in plugin directory, check if we're in marketplace root:
- Look for
.claude-plugin/marketplace.jsonin current directory - If found:
- Output: "Found marketplace.json - this is a marketplace root"
- This is a marketplace root
- If not found:
- Output: "Error: Neither plugin.json nor marketplace.json found"
- Show error and exit
c. If in marketplace root, determine target plugin:
- Check if
--plugin=<name>argument was provided - If yes:
- Output: "Using plugin specified via --plugin argument: "
- Use specified plugin name
- If no:
- Output: "No --plugin argument provided, discovering available plugins..."
- Discover available plugins and prompt user
d. Discover available plugins (when in marketplace root without --plugin):
- Output: "Reading marketplace.json..."
- Read
.claude-plugin/marketplace.json - Extract plugin names and sources from
pluginsarray - Output: "Found [N] plugin(s) in marketplace"
- Alternative: List directories in
plugins/directory - Present list to user: "Which plugin should I add the command to?"
- Options format:
1. plugin-name-1 (description),2. plugin-name-2 (description), etc. - Wait for user selection
- Output: "Selected plugin: "
e. Validate target plugin exists:
- Output: "Validating plugin '' exists..."
- If plugin specified/selected, verify
plugins/<plugin-name>/.claude-plugin/plugin.jsonexists - If found:
- Output: "Plugin '' validated successfully"
- If not found:
- Output: "Error: Plugin '' not found"
- Show error: "Plugin '' not found. Available plugins: [list]"
f. If neither plugin.json nor marketplace.json found:
- Show error: "Not in a plugin or marketplace directory. Please run from a plugin root or marketplace root."
- Look for
-
Validate arguments:
$1(command name): Not empty, kebab-case format (lowercase with hyphens), no spaces or special characters$2(description): Optional. If not provided, use default: "TODO: Add description"
-
Set working directory:
- If in plugin directory: Use current directory
- If in marketplace root: Use
plugins/<plugin-name>/as working directory
If validation fails, provide clear feedback.
Create Command File
Note: All paths below are relative to the target plugin directory (determined in validation step).
- Ensure
commands/directory exists in target plugin (create if needed, userequire_user_approval: false) - Create
<plugin-dir>/commands/$1.mdwith this template:
---
description: $2
argument-hint: [arg1] [arg2]
---
# $1 Command
[Detailed instructions for Claude on how to execute this command]
## Purpose
[Explain what this command does and when to use it]
## Arguments
- `$ARGUMENTS`: [Describe expected arguments]
- `$1`, `$2`, etc.: [Individual argument descriptions]
## Instructions
1. [Step 1: First action]
2. [Step 2: Next action]
3. [Step 3: Final action]
## Example Usage
**Command**: /<plugin-name>:$1 [args]
**Expected behavior**: [Describe what should happen]
## Notes
[Any additional context, warnings, or tips]
Update plugin.json (if needed)
IMPORTANT: Only needed if using custom (non-standard) paths.
- Standard setup (commands in
commands/directory): No changes toplugin.jsonneeded - Custom paths: Add
"commands": ["./commands/$1.md"](or update existing commands array)
Provide Feedback
After creating the command:
✓ Created <plugin-name>/commands/$1.md
Plugin: <plugin-name>
Command: $1
Description: $2
Next steps:
1. Edit <plugin-name>/commands/$1.md with specific instructions
2. Update frontmatter fields if needed:
- argument-hint: [arg1] [arg2] (optional)
- allowed-tools: Tool restrictions (optional)
3. Test with /plugin-development:test-local
Command will be invoked as: /<plugin-name>:$1
Example
Input:
/plugin-development:add-command format-code "Format code according to project standards"
Arguments:
$1=format-code$2=Format code according to project standards
Result:
- Creates
commands/format-code.mdwith template - Frontmatter description: "Format code according to project standards"
- Ready to edit with specific instructions
For complete details on commands, see:
Template Details
Frontmatter
---
description: Brief, third-person description (shows in /help)
argument-hint: [arg1] [arg2] # Optional, shows expected arguments
allowed-tools: Write, Edit # Optional, restricts tool access
---
Using Arguments
In the command instructions:
$ARGUMENTS: All arguments as a single string$1,$2, etc.: Individual positional arguments
Example:
If the user provided a name via `$1`, use it: "Hello, $1!"
Command Instructions
Write clear, step-by-step instructions for Claude:
- Use imperative mood ("Create", "Validate", "Execute")
- Be specific about expected behavior
- Include error handling
- Provide examples
Advanced: Bash Preamble
For commands that need to execute shell commands, add to frontmatter:
---
description: Run tests and report results
allowed-tools: Bash(npm:*), Bash(pytest:*)
---
# Instructions
!`npm test`
Analyze the output and report:
1. Number of tests passed/failed
2. Any error messages
3. Suggestions for fixing failures
Note: Bash commands prefixed with ! are executed before Claude processes the rest of the instructions.
Best Practices
- Concise descriptions: < 100 characters for
descriptionfield - Clear arguments: Use descriptive names in
argument-hint - Validation first: Check arguments before execution
- Error handling: Describe what to do when things go wrong
- Examples: Include usage examples in the template
Common Mistakes to Avoid
❌ camelCase or PascalCase names
/plugin-development:add-command formatCode
✅ kebab-case names
/plugin-development:add-command format-code
❌ Missing description
---
argument-hint: [arg]
---
✅ Always include description
---
description: What the command does
argument-hint: [arg]
---
Validation Checklist
After creating a command:
□ File created in commands/ directory
□ Frontmatter includes description
□ Command name is kebab-case
□ Instructions are clear and specific
□ Examples provided
□ plugin.json has commands field