Create docs/writing-commands.md with comprehensive documentation for writing new commands: - File structure (commands/<name>.md with YAML frontmatter) - Argument handling with $1, $2 placeholders and argument-hint patterns - How commands invoke skills and spawn agents - Interactive patterns: approval workflows, choices, input gathering - Annotated examples from all 7 existing commands - Naming conventions and best practices - Submission checklist Closes #5 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
648 lines
17 KiB
Markdown
648 lines
17 KiB
Markdown
# 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: <required-arg> [optional-arg]
|
|
---
|
|
```
|
|
|
|
| Field | Purpose | Required |
|
|
|-------|---------|----------|
|
|
| `description` | One-line summary for help/listings | Yes |
|
|
| `argument-hint` | Shows expected arguments | If arguments needed |
|
|
|
|
### 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 Forgejo issue. Fetches issue details and sets up branch.
|
|
argument-hint: <issue-number>
|
|
---
|
|
|
|
# Work on Issue #$1
|
|
|
|
1. **View the issue**: `fj issue view $1`
|
|
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**: `git push -u origin <branch>`
|
|
7. **Create PR**: `fj pr create "[Issue #$1] <title>" --body "Closes #$1"`
|
|
```
|
|
|
|
## 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**: `fj issue view $1`
|
|
```
|
|
|
|
Becomes:
|
|
```markdown
|
|
# Work on Issue #42
|
|
1. **View the issue**: `fj issue view 42`
|
|
```
|
|
|
|
### 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
|
|
|
|
## If issue number provided ($1):
|
|
1. **Fetch the issue**: `fj issue view $1`
|
|
2. **Evaluate** against checklist
|
|
...
|
|
|
|
## If no argument (groom all):
|
|
1. **List open issues**: `fj issue search -s open`
|
|
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)
|
|
|
|
## Single Issue (default)
|
|
If title provided: `fj issue create "$1" --body "<description>"`
|
|
|
|
## 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
|
|
```
|
|
|
|
## Invoking Skills
|
|
|
|
Commands reference skills by name to gain domain knowledge. When a skill is referenced, Claude reads the skill file before proceeding.
|
|
|
|
### Explicit Reference
|
|
|
|
```markdown
|
|
# Groom Issues
|
|
|
|
Use the **backlog-grooming** and **issue-writing** skills.
|
|
|
|
1. **Fetch the issue**: `fj issue view $1`
|
|
2. **Evaluate** against grooming checklist
|
|
...
|
|
```
|
|
|
|
The phrase "Use the backlog-grooming and issue-writing skills" tells Claude to read and apply knowledge from both skill files.
|
|
|
|
### Implicit Reference
|
|
|
|
Skills can also be used implicitly via tool references:
|
|
|
|
```markdown
|
|
1. **View the issue**: `fj issue view $1`
|
|
```
|
|
|
|
This implicitly uses knowledge from the `forgejo` skill (knowing the `fj` command syntax).
|
|
|
|
### When to Reference Skills
|
|
|
|
| Reference explicitly | Reference implicitly |
|
|
|---------------------|---------------------|
|
|
| Core methodology is needed | Just using a tool |
|
|
| Quality standards matter | Simple operations |
|
|
| Patterns should be followed | Well-known commands |
|
|
|
|
## 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 using `fj issue create`
|
|
```
|
|
|
|
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**: `fj pr merge $1` - Approve and merge the PR
|
|
- **Request changes**: `fj pr comment $1 "<feedback>"` - Leave feedback
|
|
- **Comment only**: `fj pr comment $1 "<comment>"` - Add a comment
|
|
```
|
|
|
|
### 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 Forgejo issue. Fetches issue details and sets up branch.
|
|
argument-hint: <issue-number>
|
|
---
|
|
|
|
# Work on Issue #$1
|
|
|
|
1. **View the issue**: `fj issue view $1`
|
|
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**: `git push -u origin <branch>`
|
|
7. **Create PR**: `fj pr create "[Issue #$1] <title>" --body "Closes #$1"`
|
|
```
|
|
|
|
**Key patterns:**
|
|
- **Linear workflow**: Clear numbered steps in order
|
|
- **Required argument**: `<issue-number>` means must provide
|
|
- **Variable substitution**: `$1` used throughout
|
|
- **Tool integration**: Git and fj commands specified
|
|
- **No explicit skill reference**: Uses forgejo knowledge implicitly
|
|
|
|
### Example 2: dashboard (No Arguments)
|
|
|
|
```markdown
|
|
---
|
|
description: Show dashboard of open issues, PRs awaiting review, and CI status.
|
|
---
|
|
|
|
# Repository Dashboard
|
|
|
|
Run these commands and present a summary:
|
|
|
|
1. **Open Issues**: `fj issue search -s open`
|
|
2. **Open PRs**: `fj pr search -s open`
|
|
|
|
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
|
|
|
|
Use the backlog-grooming and issue-writing skills.
|
|
|
|
## If issue number provided ($1):
|
|
1. **Fetch the issue**: `fj issue view $1`
|
|
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: `fj issue edit $1 --body "..."`
|
|
|
|
## If no argument (groom all):
|
|
1. **List open issues**: `fj issue search -s open`
|
|
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
|
|
- **Explicit skill reference**: "Use the backlog-grooming and issue-writing 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
|
|
|
|
Use the roadmap-planning, issue-writing, and forgejo skills.
|
|
|
|
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 using `fj issue create`
|
|
7. **Update dependencies** with actual issue numbers
|
|
8. **Present summary** with links to created issues
|
|
```
|
|
|
|
**Key patterns:**
|
|
- **Multi-skill composition**: References three skills together
|
|
- **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 Forgejo pull request. Fetches PR details, diff, and comments.
|
|
argument-hint: <pr-number>
|
|
---
|
|
|
|
# Review PR #$1
|
|
|
|
1. **View PR details**: `fj pr view $1`
|
|
2. **Check status**: `fj pr status $1`
|
|
3. **Get the diff**: `fj pr view $1 diff`
|
|
|
|
Review the changes and provide feedback on:
|
|
- Code quality
|
|
- Potential bugs
|
|
- Test coverage
|
|
- Documentation
|
|
|
|
Ask the user what action to take:
|
|
- **Merge**: `fj pr merge $1` - Approve and merge the PR
|
|
- **Request changes**: `fj pr comment $1 "<feedback>"` - Leave feedback
|
|
- **Comment only**: `fj pr comment $1 "<comment>"` - Add a comment
|
|
```
|
|
|
|
**Key patterns:**
|
|
- **Information gathering**: Multiple commands to get context
|
|
- **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**: `fj issue view $1`
|
|
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
|
|
**Open Issues**: `fj issue search -s open`
|
|
|
|
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 issues using `fj issue create`
|
|
```
|
|
|
|
### 4. Handle Edge Cases
|
|
|
|
Consider what happens when things are empty or unexpected:
|
|
|
|
```markdown
|
|
## If no argument (groom all):
|
|
1. **List open issues**: `fj issue search -s open`
|
|
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
|
|
|
|
- [ ] File is at `commands/<name>.md`
|
|
- [ ] Name follows kebab-case verb convention
|
|
- [ ] Frontmatter includes description
|
|
- [ ] Frontmatter includes argument-hint (if arguments needed)
|
|
- [ ] Workflow steps are clear and numbered
|
|
- [ ] Commands and tools are specified explicitly
|
|
- [ ] Skills are referenced where methodology matters
|
|
- [ ] Approval points exist before significant actions
|
|
- [ ] Edge cases are handled (no data, invalid input)
|
|
- [ ] Output formatting is specified
|
|
- [ ] 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
|