Create a new slash command file with proper frontmatter and structure.
Create a new slash command file with proper frontmatter and structure. Use this when building plugin commands that need custom functionality and specific instructions for Claude to follow.
/plugin marketplace add ArcBlock/agent-skills/plugin install plugin-development@arcblock-agent-skillsCreate a new slash command file with proper frontmatter and structure.
$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 toUsage:
# 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
.claude-plugin/plugin.json), OR.claude-plugin/marketplace.json)commands/ directory will be created if neededIMPORTANT: 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:
.claude-plugin/plugin.json in current directoryb. If not in plugin directory, check if we're in marketplace root:
.claude-plugin/marketplace.json in current directoryc. If in marketplace root, determine target plugin:
--plugin=<name> argument was providedd. Discover available plugins (when in marketplace root without --plugin):
.claude-plugin/marketplace.jsonplugins arrayplugins/ directory1. plugin-name-1 (description), 2. plugin-name-2 (description), etc.e. Validate target plugin exists:
plugins/<plugin-name>/.claude-plugin/plugin.json existsf. If neither plugin.json nor marketplace.json found:
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:
plugins/<plugin-name>/ as working directoryIf validation fails, provide clear feedback.
Note: All paths below are relative to the target plugin directory (determined in validation step).
commands/ directory exists in target plugin (create if needed, use require_user_approval: false)<plugin-dir>/commands/$1.md with this template:---
description: $2
argument-hint: [arg1] [arg2]
allowed-tools: Write, Edit
model: claude-3-5-haiku-20241022
disable-model-invocation: false
---
# $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]
IMPORTANT: Only needed if using custom (non-standard) paths.
commands/ directory): No changes to plugin.json needed"commands": ["./commands/$1.md"] (or update existing commands array)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)
- model: Specify different model (optional)
- disable-model-invocation: Prevent SlashCommand tool invocation (optional)
3. Use @path/to/file syntax to reference files in instructions
4. Test with /plugin-development:test-local
Command will be invoked as: /<plugin-name>:$1
Input:
/plugin-development:add-command format-code "Format code according to project standards"
Arguments:
$1 = format-code$2 = Format code according to project standardsResult:
commands/format-code.md with templateFor complete details on commands, see:
---
description: Brief, third-person description (shows in /help)
argument-hint: [arg1] [arg2] # Optional, shows expected arguments
allowed-tools: Write, Edit # Optional, restricts tool access
model: claude-3-5-haiku-20241022 # Optional, specify different model
disable-model-invocation: true # Optional, prevents SlashCommand tool from invoking
---
| Field | Purpose | Default |
|---|---|---|
description | Brief description of the command | First line of prompt |
argument-hint | Expected arguments (shown in auto-complete) | None |
allowed-tools | List of tools the command can use | Inherits from conversation |
model | Specific model to use (full ID like claude-3-5-haiku-20241022) | Inherits from conversation |
disable-model-invocation | Prevent SlashCommand tool from calling this command | false |
Use pipe syntax in argument-hint to define multiple invocation patterns:
---
description: Manage project tags
argument-hint: add [tagId] | remove [tagId] | list
---
This shows users the different ways to invoke the command.
In the command instructions:
$ARGUMENTS: All arguments as a single string$1, $2, etc.: Individual positional argumentsExample:
If the user provided a name via `$1`, use it: "Hello, $1!"
Include file contents using the @ prefix within your command instructions:
# Reference a specific file
Review the implementation in @src/utils/helpers.js
# Reference multiple files
Compare @src/old-version.js with @src/new-version.js
The file contents will be included inline when the command is executed.
Write clear, step-by-step instructions for Claude:
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.
description fieldargument-hintThe SlashCommand tool allows Claude to execute custom slash commands programmatically during a conversation.
For Claude to be able to invoke your command via the SlashCommand tool:
description frontmatter field must be populated/compact)SLASH_COMMAND_TOOL_CHAR_BUDGET environment variable to adjust/context to see warnings displayed as "M of N commands"Reference the command in prompts or CLAUDE.md:
> Run /write-unit-test when you are about to start writing tests.
To prevent a specific command from being invoked by the SlashCommand tool, add to frontmatter:
---
description: My command description
disable-model-invocation: true
---
SlashCommand permissions support exact and prefix matching:
SlashCommand:/commit # Allows only /commit with no arguments
SlashCommand:/review-pr:* # Allows /review-pr with any arguments
❌ 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]
---
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