# Writing Commands A guide to creating user-facing entry points that trigger workflows. ## What is a Command? Commands are **user-facing entry points** that trigger workflows. Unlike skills (which encode knowledge) or agents (which execute tasks autonomously), commands define *what* to do—they orchestrate the workflow that users invoke directly. Think of commands as the interface between users and the system. Users type `/work-issue 42` and the command defines the entire workflow: fetch issue, create branch, implement, commit, push, create PR. ## File Structure Commands live directly in the `commands/` directory as markdown files: ``` commands/ ├── work-issue.md ├── dashboard.md ├── review-pr.md ├── create-issue.md ├── groom.md ├── roadmap.md └── plan-issues.md ``` ### Why Flat Files? Unlike skills and agents (which use folders), commands are single files because: - Commands are self-contained workflow definitions - No supporting files needed - Simple naming: `/work-issue` maps to `work-issue.md` ## Command Document Structure A well-structured command file has two parts: ### 1. Frontmatter (YAML Header) ```yaml --- description: Brief description shown in command listings argument-hint: [optional-arg] --- ``` #### Required Fields | Field | Purpose | |-------|---------| | `description` | One-line summary for help/listings | #### Optional Fields | Field | Purpose | |-------|---------| | `argument-hint` | Shows expected arguments (e.g., ``, `[title]`) | | `model` | Model to use: `haiku`, `sonnet`, `opus`. Overrides session default. | | `context` | Execution context. Use `fork` to run in isolated sub-agent context. | | `hooks` | Define PreToolUse, PostToolUse, or Stop hooks scoped to this command. | | `allowed-tools` | Restrict which tools the command can use. | ### 2. Body (Markdown Instructions) ```markdown # Command Title Brief intro if needed. 1. **Step one**: What to do 2. **Step two**: What to do next ... ``` The body contains the workflow steps that Claude follows when the command is invoked. ## Complete Command Example ```markdown --- description: Work on a Gitea issue. Fetches issue details and sets up branch. argument-hint: --- # Work on Issue #$1 @~/.claude/skills/gitea/SKILL.md 1. **View the issue** to understand requirements 2. **Create a branch**: `git checkout -b issue-$1-` 3. **Plan**: Use TodoWrite to break down the work 4. **Implement** the changes 5. **Commit** with message referencing the issue 6. **Push** the branch to origin 7. **Create PR** with title "[Issue #$1] " and body "Closes #$1" ``` ## Advanced Frontmatter Examples **Command with specific model:** ```yaml --- description: Plan complex feature implementation. argument-hint: <feature-description> model: opus --- ``` **Command with isolated context (prevents context pollution):** ```yaml --- description: Analyze codebase architecture deeply. context: fork model: haiku --- ``` **Command with hooks:** ```yaml --- description: Deploy to production environment. hooks: - type: PreToolUse matcher: Bash command: echo "Validating deployment command..." - type: Stop command: ./scripts/notify-deployment.sh --- ``` **Read-only command with tool restrictions:** ```yaml --- description: Generate codebase report without modifications. allowed-tools: - Read - Glob - Grep --- ``` ## Argument Handling Commands can accept arguments from the user. Arguments are passed via positional variables: `$1`, `$2`, etc. ### The ARGUMENTS Pattern When users invoke a command with arguments: ``` /work-issue 42 ``` The system provides the arguments via the `$1`, `$2`, etc. placeholders in the command body: ```markdown # Work on Issue #$1 1. **View the issue** to understand requirements ``` Becomes: ```markdown # Work on Issue #42 1. **View the issue** to understand requirements ``` ### Argument Hints Use `argument-hint` in frontmatter to document expected arguments: | Pattern | Meaning | |---------|---------| | `<arg>` | Required argument | | `[arg]` | Optional argument | | `<arg1> <arg2>` | Multiple required | | `[arg1] [arg2]` | Multiple optional | | `<required> [optional]` | Mix of both | Examples: ```yaml argument-hint: <issue-number> # One required argument-hint: [issue-number] # One optional argument-hint: <title> [description] # Required + optional argument-hint: [title] or "batch" # Choice of modes ``` ### Handling Optional Arguments Commands often have different behavior based on whether arguments are provided: ```markdown --- description: Groom issues. Without argument, reviews all. With argument, grooms specific issue. argument-hint: [issue-number] --- # Groom Issues @~/.claude/skills/gitea/SKILL.md ## If issue number provided ($1): 1. **Fetch the issue** details 2. **Evaluate** against checklist ... ## If no argument (groom all): 1. **List open issues** 2. **Review each** against checklist ... ``` ### Multiple Modes Some commands support distinct modes based on the first argument: ```markdown --- description: Create issues. Single or batch mode. argument-hint: [title] or "batch" --- # Create Issue(s) @~/.claude/skills/gitea/SKILL.md ## Single Issue (default) If title provided, create an issue with that title. ## Batch Mode If $1 is "batch": 1. Ask user for the plan 2. Generate list of issues 3. Show for approval 4. Create each issue ``` ## Including Skills Commands include skills using the `@` file reference syntax. This automatically injects the skill content into the command context when the command is invoked. ### File Reference Syntax Use the `@` prefix followed by the path to the skill file: ```markdown # Groom Issues @~/.claude/skills/gitea/SKILL.md @~/.claude/skills/backlog-grooming/SKILL.md @~/.claude/skills/issue-writing/SKILL.md 1. **Fetch the issue** details 2. **Evaluate** against grooming checklist ... ``` When the command runs, the content of each referenced skill file is automatically loaded into context. ### Why File References? **DO NOT** use phrases like "Use the gitea skill" - skills have only ~20% auto-activation rate. File references guarantee the skill content is available. | Pattern | Behavior | |---------|----------| | `@~/.claude/skills/gitea/SKILL.md` | Content automatically injected | | "Use the gitea skill" | Relies on auto-activation (~20% success) | ### When to Include Skills | Include explicitly | Skip skill reference | |-------------------|---------------------| | CLI syntax is needed | Well-known commands | | Core methodology required | Simple operations | | Quality standards matter | One-off actions | | Patterns should be followed | No domain knowledge needed | ## Invoking Agents Commands can spawn agents for complex subtasks that benefit from skill composition or context isolation. ### Spawning Agents ```markdown For comprehensive backlog review, spawn the **product-manager** agent to: - Review all open issues - Categorize by readiness - Propose improvements ``` ### When to Spawn Agents Spawn an agent when the command needs: - **Parallel processing**: Multiple independent tasks - **Context isolation**: Deep exploration that would pollute main context - **Skill composition**: Multiple skills working together - **Autonomous operation**: Let the agent figure out details ### Example: Conditional Agent Spawning ```markdown # Groom Issues ## If no argument (groom all): For large backlogs (>10 issues), consider spawning the product-manager agent to handle the review autonomously. ``` ## Interactive Patterns Commands often require user interaction for confirmation, choices, or input. ### Approval Workflows Always ask for approval before significant actions: ```markdown 5. **Ask for approval** before creating issues 6. **Create issues** in order ``` Common approval points: - Before creating/modifying resources (issues, PRs, files) - Before executing destructive operations - When presenting a plan that will be executed ### Presenting Choices When the command leads to multiple possible actions: ```markdown Ask the user what action to take: - **Merge**: Approve and merge the PR - **Request changes**: Leave feedback without merging - **Comment only**: Add a comment for discussion ``` ### Gathering Input Some commands need to gather information from the user: ```markdown ## Batch Mode If $1 is "batch": 1. **Ask user** for the plan/direction 2. Generate list of issues with titles and descriptions 3. Show for approval ``` ### Presenting Results Commands should clearly show what was done: ```markdown 7. **Update dependencies** with actual issue numbers after creation 8. **Present summary** with links to created issues ``` Good result presentations include: - Tables for lists of items - Links for created resources - Summaries of changes made - Next step suggestions ## Annotated Examples Let's examine existing commands to understand effective patterns. ### Example 1: work-issue (Linear Workflow) ```markdown --- description: Work on a Gitea issue. Fetches issue details and sets up branch. argument-hint: <issue-number> --- # Work on Issue #$1 @~/.claude/skills/gitea/SKILL.md 1. **View the issue** to understand requirements 2. **Create a branch**: `git checkout -b issue-$1-<short-kebab-title>` 3. **Plan**: Use TodoWrite to break down the work 4. **Implement** the changes 5. **Commit** with message referencing the issue 6. **Push** the branch to origin 7. **Create PR** with title "[Issue #$1] <title>" and body "Closes #$1" ``` **Key patterns:** - **Linear workflow**: Clear numbered steps in order - **Required argument**: `<issue-number>` means must provide - **Variable substitution**: `$1` used throughout - **Skill reference**: Uses gitea skill for CLI knowledge - **Git integration**: Branch and push steps specified ### Example 2: dashboard (No Arguments) ```markdown --- description: Show dashboard of open issues, PRs awaiting review, and CI status. --- # Repository Dashboard @~/.claude/skills/gitea/SKILL.md Fetch and display: 1. All open issues 2. All open PRs Format as tables showing issue/PR number, title, and author. ``` **Key patterns:** - **No argument-hint**: Command takes no arguments - **Output formatting**: Specifies how to present results - **Aggregation**: Combines multiple data sources - **Simple workflow**: Just fetch and display ### Example 3: groom (Optional Argument with Modes) ```markdown --- description: Groom and improve issues. Without argument, reviews all. With argument, grooms specific issue. argument-hint: [issue-number] --- # Groom Issues @~/.claude/skills/gitea/SKILL.md @~/.claude/skills/backlog-grooming/SKILL.md @~/.claude/skills/issue-writing/SKILL.md ## If issue number provided ($1): 1. **Fetch the issue** details 2. **Evaluate** against grooming checklist 3. **Suggest improvements** for: - Title clarity - Description completeness - Acceptance criteria quality 4. **Ask user** if they want to apply changes 5. **Update issue** if approved ## If no argument (groom all): 1. **List open issues** 2. **Review each** against grooming checklist 3. **Categorize**: Ready / Needs work / Stale 4. **Present summary** table 5. **Offer to improve** issues that need work ``` **Key patterns:** - **Optional argument**: `[issue-number]` with brackets - **Mode switching**: Different behavior based on argument presence - **Skill file references**: Uses `@~/.claude/skills/` to include multiple skills - **Approval workflow**: "Ask user if they want to apply changes" - **Categorization**: Groups items for presentation ### Example 4: plan-issues (Complex Workflow) ```markdown --- description: Plan and create issues for a feature. Breaks down work into well-structured issues. argument-hint: <feature-description> --- # Plan Feature: $1 @~/.claude/skills/gitea/SKILL.md @~/.claude/skills/roadmap-planning/SKILL.md @~/.claude/skills/issue-writing/SKILL.md 1. **Understand the feature**: Analyze what "$1" involves 2. **Explore the codebase** if needed to understand context 3. **Break down** into discrete, actionable issues 4. **Present the plan**: ``` ## Proposed Issues for: $1 1. [Title] - Brief description Dependencies: none ... ``` 5. **Ask for approval** before creating issues 6. **Create issues** in order 7. **Update dependencies** with actual issue numbers 8. **Present summary** with links to created issues ``` **Key patterns:** - **Multi-skill composition**: Includes three skills via `@~/.claude/skills/` - **Codebase exploration**: May need to understand context - **Structured output**: Template for presenting the plan - **Two-phase execution**: Plan first, then execute after approval - **Dependency management**: Creates issues in order, updates references ### Example 5: review-pr (Action Choices) ```markdown --- description: Review a Gitea pull request. Fetches PR details, diff, and comments. argument-hint: <pr-number> --- # Review PR #$1 @~/.claude/skills/gitea/SKILL.md 1. **View PR details** including description and metadata 2. **Get the diff** to review the changes Review the changes and provide feedback on: - Code quality - Potential bugs - Test coverage - Documentation Ask the user what action to take: - **Merge**: Approve and merge the PR - **Request changes**: Leave feedback without merging - **Comment only**: Add a comment for discussion ``` **Key patterns:** - **Information gathering**: Fetches context before analysis - **Review criteria**: Checklist of what to examine - **Action menu**: Clear choices with explanations - **User decides outcome**: Command presents options, user chooses ## Naming Conventions ### Command File Names - Use **kebab-case**: `work-issue.md`, `plan-issues.md` - Use **verbs or verb phrases**: Commands are actions - Be **concise**: 1-3 words is ideal - Match the **invocation**: `/work-issue` → `work-issue.md` Good names: - `work-issue` - Action + target - `dashboard` - What it shows - `review-pr` - Action + target - `plan-issues` - Action + target - `groom` - Action (target implied) Avoid: - `issue-work` - Noun-first is awkward - `do-stuff` - Too vague - `manage-issues-and-prs` - Too long ### Command Titles The H1 title can be more descriptive than the filename: | Filename | Title | |----------|-------| | `work-issue.md` | Work on Issue #$1 | | `dashboard.md` | Repository Dashboard | | `plan-issues.md` | Plan Feature: $1 | ## Best Practices ### 1. Design Clear Workflows Each step should be unambiguous: **Vague:** ```markdown 1. Handle the issue 2. Do the work 3. Finish up ``` **Clear:** ```markdown 1. **View the issue** to understand requirements 2. **Create a branch**: `git checkout -b issue-$1-<title>` 3. **Plan**: Use TodoWrite to break down the work ``` ### 2. Show Don't Tell Include actual commands and expected outputs: **Telling:** ```markdown List the open issues. ``` **Showing:** ```markdown Fetch all open issues and format as table: | # | Title | Author | |---|-------|--------| ``` ### 3. Always Ask Before Acting Never modify resources without user approval: ```markdown 4. **Present plan** for approval 5. **If approved**, create the issues ``` ### 4. Handle Edge Cases Consider what happens when things are empty or unexpected: ```markdown ## If no argument (groom all): 1. **List open issues** 2. If no issues found, report "No open issues to groom" 3. Otherwise, **review each** against checklist ``` ### 5. Provide Helpful Output End with useful information: ```markdown 8. **Present summary** with: - Links to created issues - Dependency graph - Suggested next steps ``` ### 6. Keep Commands Focused One command = one workflow. If doing multiple unrelated things, split into separate commands. **Too broad:** ```markdown # Manage Everything Handle issues, PRs, deployments, and documentation... ``` **Focused:** ```markdown # Review PR #$1 Review and take action on a pull request... ``` ## When to Create a Command Create a command when you have: 1. **Repeatable workflow**: Same steps used multiple times 2. **User-initiated action**: User explicitly triggers it 3. **Clear start and end**: Workflow has defined boundaries 4. **Consistent behavior needed**: Should work the same every time ### Signs You Need a New Command - You're explaining the same workflow repeatedly - Users would benefit from a single invocation - Multiple tools need orchestration - Approval checkpoints are needed ### Signs You Don't Need a Command - It's a one-time action - No workflow orchestration needed - A skill reference is sufficient - An agent could handle it autonomously ## Command Lifecycle ### 1. Design Define the workflow: - What triggers it? - What arguments does it need? - What steps are involved? - Where are approval points? - What does success look like? ### 2. Implement Create the command file: - Clear frontmatter - Step-by-step workflow - Skill references where needed - Approval checkpoints - Output formatting ### 3. Test Verify the workflow: - Run with typical arguments - Test edge cases (no args, invalid args) - Confirm approval points work - Check output formatting ### 4. Document Update references: - Add to ARCHITECTURE.md table - Update README if user-facing - Note any skill/agent dependencies ## Checklist: Before Submitting a New Command ### Structure - [ ] File is at `commands/<name>.md` - [ ] Name follows kebab-case verb convention ### Frontmatter (Required) - [ ] `description` is set with clear one-line summary - [ ] `argument-hint` is set (if command takes arguments) ### Frontmatter (Consider) - [ ] `model` if command benefits from specific model (e.g., `opus` for complex planning) - [ ] `context: fork` if command does heavy exploration that would pollute context - [ ] `allowed-tools` if command should be restricted to certain tools - [ ] `hooks` if command needs validation or post-execution actions ### Content - [ ] Workflow steps are clear and numbered - [ ] Commands and tools are specified explicitly - [ ] Skills are included via `@~/.claude/skills/<name>/SKILL.md` file references - [ ] Approval points exist before significant actions - [ ] Edge cases are handled (no data, invalid input) - [ ] Output formatting is specified ### Integration - [ ] ARCHITECTURE.md is updated with new command ## See Also - [ARCHITECTURE.md](../ARCHITECTURE.md): How commands fit into the overall system - [writing-skills.md](writing-skills.md): Creating skills that commands reference - [writing-agents.md](writing-agents.md): Creating agents that commands spawn - [VISION.md](../VISION.md): The philosophy behind composable components