Files
architecture/docs/writing-commands.md
Hugo Nijhuis d980a0d0bc Add new frontmatter fields from Claude Code 2.1.0
Update documentation and apply new frontmatter capabilities:

Documentation:
- Add user-invocable, context, agent, hooks fields to writing-skills.md
- Add disallowedTools, permissionMode, hooks fields to writing-agents.md
- Add model, context, hooks, allowed-tools fields to writing-commands.md
- Document skill hot-reload, built-in agents, background execution

Skills:
- Add user-invocable: false to gitea (CLI reference)
- Add user-invocable: false to repo-conventions (standards reference)

Commands:
- Add context: fork to heavy exploration commands (improve, plan-issues,
  create-repo, update-claude-md)
- Add missing argument-hint to roadmap, manifesto, improve

Agents:
- Add disallowedTools: [Edit, Write] to code-reviewer for safety

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 14:19:56 +01:00

18 KiB

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)

---
description: Brief description shown in command listings
argument-hint: <required-arg> [optional-arg]
---

Required Fields

Field Purpose
description One-line summary for help/listings

Optional Fields

Field Purpose
argument-hint Shows expected arguments (e.g., <issue-number>, [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)

# 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

---
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"

Advanced Frontmatter Examples

Command with specific model:

---
description: Plan complex feature implementation.
argument-hint: <feature-description>
model: opus
---

Command with isolated context (prevents context pollution):

---
description: Analyze codebase architecture deeply.
context: fork
model: haiku
---

Command with hooks:

---
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:

---
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:

# Work on Issue #$1
1. **View the issue** to understand requirements

Becomes:

# 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:

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:

---
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:

---
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:

# 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

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

# 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:

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:

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:

## 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:

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)

---
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)

---
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)

---
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)

---
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)

---
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-issuework-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:

1. Handle the issue
2. Do the work
3. Finish up

Clear:

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:

List the open issues.

Showing:

Fetch all open issues and format as table:
| # | Title | Author |
|---|-------|--------|

3. Always Ask Before Acting

Never modify resources without user approval:

4. **Present plan** for approval
5. **If approved**, create the issues

4. Handle Edge Cases

Consider what happens when things are empty or unexpected:

## 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:

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:

# Manage Everything
Handle issues, PRs, deployments, and documentation...

Focused:

# 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