_==/ i i \==_
/XX/ |\___/| \XX\
/XXXX\ |XXXXX| /XXXX\
|XXXXXX\_ _XXXXXXX_ _/XXXXXX|
XXXXXXXXXXXxxxxxxxXXXXXXXXXXXxxxxxxxXXXXXXXXXXX
|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|
XXXXXX/^^^^"\XXXXXXXXXXXXXXXXXXXXX/^^^^^\XXXXXX
|XXX| \XXX/^^\XXXXX/^^\XXX/ |XXX|
\XX\ \X/ \XXX/ \X/ /XX/
"\ " \X/ " /"
TDD workflow commands for Claude Code CLI.
"TDD helps you to pay attention to the right issues at the right time so you can make your designs cleaner, you can refine your designs as you learn." β Kent Beck
Claude Code supports custom slash commandsβtype /foo and Claude receives the contents of foo.md as instructions (from .claude/commands/ in your repo or ~/.claude/commands/ in your home directory). This repo provides ready-made commands for Test-Driven Development workflows.
Custom commands are just a glorified copy-paste mechanismβbut that simplicity is what makes them effective for establishing consistent development practices.
Instead of explaining TDD principles each session, type /red to write a failing test, /green to make it pass, /refactor to clean up. The commands guide Claude through each step methodicallyβyou focus on what to build, Claude handles the how.
Want to go faster? Use /cycle to let Claude run the entire red-green-refactor sequence before checking in with you. For even more autonomy (your mileage may vary), /tdd gives Claude full discretion on when to advance between phases.
Also included are commands for commits, PRs, code reviews, and other tasks that come up during day-to-day development.
npx @wbern/claude-instructions # npmpnpm dlx @wbern/claude-instructions # pnpmThe interactive installer lets you choose:
- Feature flags: Enable optional integrations like Beads MCP
- Scope: User-level (global) or project-level installation
After installation, restart Claude Code if it's currently running.
To automatically regenerate commands when teammates install dependencies, add it as a dev dependency with a postinstall script:
npm install --save-dev @wbern/claude-instructionsThen add a postinstall script to your package.json:
{
"scripts": {
"postinstall": "claude-instructions --scope=project --overwrite"
},
"devDependencies": {
"@wbern/claude-instructions": "^2.8.1"
}
}This ensures commands are regenerated whenever anyone runs npm install, pnpm install, or yarn install.
CLI Options:
| Option | Description |
|---|---|
--scope=project |
Installation scope (project, user) |
--prefix=my- |
Add prefix to command names |
--commands=commit,red,green |
Install only specific commands |
--skip-template-injection |
Skip injecting project CLAUDE.md customizations |
--update-existing |
Only update already-installed commands |
--overwrite |
Overwrite conflicting files without prompting |
--skip-on-conflict |
Skip conflicting files without prompting |
--flags=beads,github |
Enable feature flags (beads, github, gitlab, etc.) |
--allowed-tools=Bash(git diff:*),Bash(git status:*) |
Pre-approve tools for commands (non-interactive mode) |
--help, -h |
Show help message |
--version, -v |
Show version number |
You can inject project-specific instructions into generated commands by adding a <claude-commands-template> block to your CLAUDE.md or AGENTS.md file.
Add this to your project's CLAUDE.md:
# My Project
Other instructions here...
<claude-commands-template>
## Project-Specific Rules
- Always use pnpm instead of npm
- Run tests with `pnpm test`
</claude-commands-template>When you run claude-instructions, the template content is appended to all generated commands.
Use the commands attribute to inject content only into specific commands:
<claude-commands-template commands="commit,ask">
## Git Conventions
- Use conventional commits format
- Reference issue numbers in commits
</claude-commands-template>This injects the content only into commit.md and ask.md.
The generator looks for template blocks in this order:
CLAUDE.md(checked first)AGENTS.md(fallback)
Only the first file found is used.
This is the core TDD workflow. Additional utility commands (worktrees, spikes, etc.) are listed in Available Commands below.
flowchart TB
Start([Start New Work])
Start --> Step1[<b>1. PLAN</b>]
Step1 --> Issue[π /issue<br/>Have GitHub issue<br/><i>Requires: GitHub MCP</i>]
Step1 --> CreateIssues[π /create-issues<br/>No issue yet<br/><i>Optional: Beads MCP</i>]
Issue --> Step2[<b>2. CODE with TDD</b>]
CreateIssues --> Step2
Step2 -->|Manual| Red[π΄ /red<br/>Write failing test]
Red --> Green[π’ /green<br/>Make it pass]
Green --> Refactor[π΅ /refactor<br/>Clean up code]
Refactor --> MoreTests{More tests?}
Step2 -->|Automated| Cycle[π /cycle<br/>Runs red+green+refactor]
Cycle --> MoreTests
MoreTests -->|Yes| Step2
MoreTests -->|No| Step3
Step3[<b>3. SHIP</b>]
Step3 --> Commit[π¦ /commit<br/>Create commit]
Commit --> ShipChoice{How to<br/>merge?}
ShipChoice -->|Simple change| Ship[π’ /ship<br/>Direct to main<br/><i>Requires: GitHub MCP</i>]
ShipChoice -->|Show team| Show[π /show<br/>Auto-merge + notify<br/><i>Requires: GitHub MCP</i>]
ShipChoice -->|Needs review| Ask[π¬ /ask<br/>Create PR<br/><i>Requires: GitHub MCP</i>]
Ship --> Done([β
Done])
Show --> Done
Ask --> Done
/issue- Analyze GitHub issue and create TDD implementation plan/create-issues- Create implementation plan from feature/requirement with PRD-style discovery and TDD acceptance criteria
/spike- Execute TDD Spike Phase - exploratory coding to understand problem space before TDD/tdd- Remind agent about TDD approach and continue conversation/red- Execute TDD Red Phase - write ONE failing test/green- Execute TDD Green Phase - write minimal implementation to pass the failing test/refactor- Execute TDD Refactor Phase - improve code structure while keeping tests green/cycle- Execute complete TDD cycle - Red, Green, and Refactor phases in sequence/simplify- Reduce code complexity while keeping tests green/tdd-review- Review test suite quality against FIRST principles and TDD anti-patterns
/commit- Create a git commit following project standards/busycommit- Create multiple atomic git commits, one logical change at a time/pr- Creates a pull request using GitHub MCP/summarize- Summarize conversation progress and next steps/gap- Analyze conversation context for unaddressed items and gaps/forever- Run autonomously until stopped or stuck/code-review- Code review using dynamic category detection and domain-specific analysis
/ship- Ship code directly to main - for small, obvious changes that don't need review/show- Show code to team with auto-merge - for changes that should be visible but don't need approval/ask- Request team review and approval - for complex changes needing discussion
/worktree-add- Add a new git worktree from branch name or issue URL, copy settings, install deps, and open in current IDE/worktree-cleanup- Clean up merged worktrees by verifying PR/issue status, consolidating settings, and removing stale worktrees
/beepboop- Communicate AI-generated content with transparent attribution/add-command- Guide for creating new slash commands/kata- Generate a TDD practice challenge with boilerplate test setup/research- Research a problem in parallel via web docs, web search, codebase exploration, and deep ultrathink/commitlint-checklist-nodejs- Audit commit hook automation for Node.js projects
Here's a simple example to get you started with the TDD workflow:
1. Write a failing test (/red)
You: /red add a function that validates email addresses
Claude: I'll write a failing test for email validation.
[Creates test file with a test that checks email validation]
[Runs test - shows it failing because function doesn't exist yet]
2. Make it pass (/green)
You: /green
Claude: I'll implement the minimal code to pass the test.
[Creates the email validation function with basic implementation]
[Runs test - shows it passing]
3. Refactor for quality (/refactor)
You: /refactor extract regex pattern to a constant
Claude: I'll refactor while keeping tests green.
[Extracts magic values, improves code structure]
[Runs tests - confirms they still pass]
Starting from a GitHub issue:
/issue 123
Claude analyzes the GitHub issue and creates a TDD implementation plan showing what tests to write.
Running a full TDD cycle:
/cycle implement user authentication with password hashing
Claude executes the complete red-green-refactor cycle: writes a failing test, implements it, then refactors.
Individual phases for more control:
/red test that users can't login with wrong password
/green
/refactor move password verification to separate function
Committing and creating PRs:
/commit
Claude reviews changes, drafts a commit message following project standards, and creates the commit.
/ask
Claude analyzes commits, creates a PR with summary and test plan.
/red- Claude writes ONE failing test based on your description/green- Claude writes minimal implementation to pass the current failing test/refactor- Claude improves code structure without changing behavior/cycle- Claude runs all three phases in sequence for a complete feature
The commands enforce TDD discipline: you can't refactor with failing tests, can't write multiple tests at once, and implementation must match test requirements.
Summary: User works through solving a code challenge: given a list of integers, find the closest to zero. If there is a tie, choose the positive value. (challenge from cyber-dojo.org)
Commands: /red /green /refactor
Legend: π΄ Red (test fails) | π’ Green (test passes) | π΅ Refactor (cleanup)
π€ /red single element [1] returns 1
π΄ writes test
expect(closestToZero([1])).toBe(1);FAIL: closestToZero is not defined
π€ /green
π’ returns hardcoded 1
function closestToZero(nums: number[]): number {
return 1; // minimal - only need to pass current test
}β Test passes
π€ /red two numbers [3, 2] returns 2
π΄ writes test
expect(closestToZero([3, 2])).toBe(2);FAIL: expected 1 to be 2
π€ /green
π’ sorts and returns first
function closestToZero(nums: number[]): number {
return nums.sort((a, b) => a - b)[0]; // minimal
}β 2/2 tests pass
π€ /red with negative [-3, 2] returns 2
π΄ writes test
expect(closestToZero([-3, 2])).toBe(2);FAIL: expected -3 to be 2 (regular sort puts -3 first)
π€ /green
π’ sorts by absolute value
function closestToZero(nums: number[]): number {
return nums.sort((a, b) => Math.abs(a) - Math.abs(b))[0];
}β 3/3 tests pass
π€ /red exact tie [-2, 2] returns positive 2
π΄ writes test
expect(closestToZero([-2, 2])).toBe(2);FAIL: expected -2 to be 2 (returns first when tied)
π€ /green
π’ adds tie-breaking: prefer positive
function closestToZero(nums: number[]): number {
return nums.sort((a, b) => {
const diff = Math.abs(a) - Math.abs(b);
return diff !== 0 ? diff : b - a;
})[0];
}β 4/4 tests pass
π€ /refactor extract helper and use iteration instead of sort
π΅ extracts helper function for comparison logic
function isCloser(candidate: number, current: number): boolean {
const candAbs = Math.abs(candidate);
const currAbs = Math.abs(current);
return candAbs < currAbs || (candAbs === currAbs && candidate > current);
}
function closestToZero(nums: number[]): number {
if (nums.length === 0) return 0;
let closest = nums[0];
for (const num of nums) {
if (isCloser(num, closest)) {
closest = num;
}
}
return closest;
}β 4/4 tests still pass
π€ /refactor
π΅ uses reduce for more functional style
function closestToZero(nums: number[]): number {
if (nums.length === 0) return 0;
return nums.reduce((closest, num) =>
isCloser(num, closest) ? num : closest,
);
}β 4/4 tests still pass
See CONTRIBUTING.md for development workflow, build system, and fragment management.
TDD workflow instructions adapted from TDD Guard by Nizar.
FIRST principles and test quality criteria from TDD Manifesto.
Example kata from Cyber-Dojo.