npx claudepluginhub oprogramadorreal/optimus-claude --plugin optimusThis skill uses the workspace's default tool permissions.
Guide the user through Red-Green-Refactor cycles to implement a feature or fix a bug test-first. Each cycle: write a failing test (Red), write the minimum code to pass it (Green), clean up while tests stay green (Refactor). One behavior per cycle.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Guide the user through Red-Green-Refactor cycles to implement a feature or fix a bug test-first. Each cycle: write a failing test (Red), write the minimum code to pass it (Green), clean up while tests stay green (Refactor). One behavior per cycle.
This skill is for new features and bug fixes — not refactoring. For restructuring existing code without changing behavior, use /optimus:refactor instead (existing tests verify behavior is preserved).
No production code without a failing test first. If implementation code is written before its test, delete it entirely and begin the cycle fresh. Do not preserve it as reference, do not adapt it — write the implementation from scratch once the failing test exists. This is the non-negotiable foundation of every step that follows.
Coming from plan mode? TDD runs in normal mode, in a fresh conversation. If you were iterating on a plan-mode prompt generated by
/optimus:brainstormor/optimus:jira, toggle plan mode off without approving (see$CLAUDE_PLUGIN_ROOT/references/skill-handoff.mdfor client-specific controls), let Claude append the "Refined plan" section to the design or JIRA doc, then start a fresh conversation before invoking this skill — TDD will auto-detect the updated doc.
Read $CLAUDE_PLUGIN_ROOT/skills/init/references/multi-repo-detection.md for workspace detection. If a multi-repo workspace is detected, process each repo independently: run Steps 1–9 inside the repo the user is targeting. If ambiguous, ask which repo.
Check that .claude/CLAUDE.md exists. If it doesn't, stop and recommend running /optimus:init first — coding guidelines and project context are essential for the Refactor step.
Load these documents (they affect quality at every step):
| Document | Role | Effect on skill |
|---|---|---|
.claude/CLAUDE.md | Project overview | Tech stack, test runner command |
coding-guidelines.md | Code quality reference | Applied during Refactor step |
testing.md | Testing conventions | Test file location, naming, framework, mocking patterns |
Monorepo path note: Read the "Monorepo Scoping Rule" section of $CLAUDE_PLUGIN_ROOT/skills/init/references/constraint-doc-loading.md for doc layout and scoping rules. When running TDD inside a subproject, load that subproject's testing.md, not another subproject's.
Locate the test runner command from testing.md, CLAUDE.md, or project manifests (package.json scripts, Makefile, Cargo.toml, etc.). Run it once to confirm it works.
/optimus:init first to set up test infrastructure (framework, runner, coverage tooling, testing.md)Before starting TDD cycles, analyze whether the user's task is a good fit for test-driven development.
Context detection (runs before the task-gathering prompts below — first match wins):
Explicit reference — if the user's input references a file path ending in .md inside docs/design/ or docs/jira/, read that file and use its Goal section as the task description. Proceed to distillation below if the goal is longer than 2-3 sentences.
Design doc auto-discovery — if no explicit reference but docs/design/ exists with .md files, check the most recent one (by filename date prefix). If its date is within the last 7 days, mention it: "Found design doc <path> — use it as the basis for TDD?" via AskUserQuestion — header "Design doc", options "Use it" / "Ignore — describe a different task". If its date is older than 7 days, add a note: "(This design doc is [N] days old — you may want to re-run /optimus:brainstorm for a fresh design.)" Design docs contain full approach details from /optimus:brainstorm — use Goal, Components, and Interfaces sections as the task description.
JIRA context auto-discovery — if no design doc found (or user ignored it) but docs/jira/ exists with .md files, read each file's YAML frontmatter and select the one with the most recent date field. If its date is within the last 7 days, mention it: "Found JIRA context <path> — use it as the basis for TDD?" via AskUserQuestion — header "JIRA context", options "Use it" / "Ignore — describe a different task". If its date is older than 7 days, add a note: "(This context is [N] days old — you may want to re-run /optimus:jira for fresh data.)" JIRA context provides Goal and Acceptance Criteria as the task description.
No context found — proceed with normal task gathering below.
Design docs take priority over JIRA files because they are more detailed (they incorporate JIRA context if brainstorm consumed it). Detected context feeds into the existing task-gathering cascade below — it does NOT bypass Step 3 decomposition. TDD still independently decomposes the goal into behaviors.
If context detection above resolved a task description (user accepted a design doc or JIRA context), use it — skip the inline/prompt gathering below. Otherwise, if the user provided a task description inline (e.g., /optimus:tdd "Add auth endpoint"), use it. Otherwise, use AskUserQuestion — header "TDD scope", question "What feature or bug fix do you want to implement with TDD?":
If the task description is longer than ~2-3 sentences (e.g., a pasted spec, JIRA ticket, or acceptance criteria list), distill it into a single-sentence goal and confirm with AskUserQuestion — header "Distilled goal", question "I've distilled your spec to: '[single-sentence summary]'. Is this accurate?":
Examine the task description against the codebase and classify it:
Suitable for TDD — proceed silently to Step 3:
Not suitable for TDD — stop and redirect:
/optimus:refactorIf not suitable, report to the user:
## Task Analysis
**Task:** [user's description]
**Suitability for TDD:** Not recommended
**Reason:** [specific explanation — e.g., "This is a refactoring task — it changes code structure
without adding new behavior. TDD is for building new behavior test-first."]
**Recommended approach:** [specific skill or approach — e.g., "/optimus:refactor restructures code
while using existing tests as a safety net."]
If ambiguous (the task has both testable and non-testable aspects, or it's unclear whether behavior changes), use AskUserQuestion — header "TDD fit", question "[specific concern about the task]. Proceed with TDD or use a different approach?":
Always create a new branch from the current branch for TDD work. This keeps the user's original branch clean — all changes happen on the new branch.
git rev-parse --abbrev-ref HEAD$CLAUDE_PLUGIN_ROOT/skills/commit/references/branch-naming.md for the naming convention. The <type> is feat for new features or fix for bug fixes (from the task classification in Step 2). The <description> is the slugified task description.git checkout -b <branch-name>## Branch
Created branch `<branch-name>` from `<original-branch>`.
All TDD work will be committed to this branch.
Read $CLAUDE_PLUGIN_ROOT/skills/tdd/references/tdd-worktree-orchestration.md and follow the Setup section, using <branch-name> and <original-branch> from above.
Break the user's description into small, individually testable behaviors. Each behavior should be:
Decomposition strategies by task type:
If the decomposition produces more than 10 behaviors, split into milestones. Present the first milestone (~5-8 behaviors that deliver a coherent slice of functionality) as the current scope, and list remaining behaviors as "Future milestones" with brief descriptions. After completing the last behavior of the current milestone, use AskUserQuestion — header "Milestone complete", question "Milestone [N] is done ([N] behaviors). Continue to the next milestone?":
If the user chooses to continue, present the next milestone's behaviors for approval (return to the "Behaviors" confirmation above), then resume Step 4. This prevents overwhelming behavior lists and gives natural stopping points.
Present the decomposition as a numbered list:
## Behaviors to Implement
1. [Behavior description] — [what the test will verify]
2. [Behavior description] — [what the test will verify]
3. [Behavior description] — [what the test will verify]
...
Use AskUserQuestion — header "Behaviors", question "Does this decomposition look right? Adjust, reorder, or approve to start cycling.":
For bug fixes: the first behavior is always "reproduce the bug" — a test that demonstrates the current broken behavior.
For the current behavior, write a minimal test that:
testing.md (framework, file location, naming, mocking patterns)"returns 401 when token is expired", not "test auth")$CLAUDE_PLUGIN_ROOT/skills/tdd/references/testing-anti-patterns.md before writing mocks; prefer real code over mocks, never assert on mock behavior, mock only external services or non-deterministic dependenciesPlace the test file according to the project's convention (from testing.md). If adding to an existing test file, append; if the convention calls for a new file, create one.
Verification protocol — every test run in this skill (Steps 4, 5, 6) must follow the gate function in $CLAUDE_PLUGIN_ROOT/skills/init/references/verification-protocol.md: identify the command, run it fresh, read complete output, verify the claim matches the evidence, only then report. Never claim "should pass" or "probably works" — state the actual result with evidence (e.g., "14 passed, 1 failed"). This protocol applies to every "Run the test suite" instruction below.
Run the project's test command. The new test must fail. Verify:
If the test passes unexpectedly, the behavior may already be implemented. Use AskUserQuestion — header "Test passed", question "The test passed without new code. The behavior may already exist. How to proceed?":
If the test fails for the wrong reason (import error, missing dependency, syntax error), fix the test — not the source code. The test itself must be valid; only the assertion should fail.
Report to the user:
## Red — [Behavior description]
Test: [test file path]:[test name]
Status: FAILS ✓ (expected)
Reason: [why it fails — e.g., "function returns undefined, expected 'authenticated'"]
Other tests: all passing ✓
Write the minimum code to make the failing test pass. Resist the urge to implement more than what the test demands:
Run the project's test command. All tests must pass — including the new one.
AskUserQuestion — header "Implementation stuck", question "The test has failed after 3 fix attempts. This usually signals a design problem, not a code problem. How to proceed?":
git checkout -- <implementation files>), mark the test as skipped per the project's convention (e.g., skip/xit/@pytest.mark.skip), move to the next behavior"When: the current behavior is a bug reproduction (the first behavior in a bug-fix decomposition). Skip for regular feature behaviors.
This gate proves two things: (1) the test genuinely catches the bug, and (2) the fix genuinely resolves it. Without this, you may have a test that passes regardless of the fix — providing false confidence.
git add <test-file> && git commit -m "test: reproduce <bug-description>"git stash push <implementation-files>git stash popReport:
## Regression Gate — [Bug description]
Test: [test file path]:[test name]
Without fix: FAILS ✓ (test catches the bug)
With fix: PASSES ✓ (fix resolves the bug)
Verdict: REGRESSION GATE PASSED
If the test passes with the fix reverted (step 3), the test is not actually catching the bug. Restore the fix (git stash pop), then rewrite the test to target the actual failure condition.
If a lint or type-check command is configured in CLAUDE.md or the project manifest (e.g., tsc --noEmit, cargo check, go vet, dotnet build), run it. Type errors in implementation code can hide behind passing tests. If it fails, fix the implementation before proceeding to Step 6.
Report to the user:
## Green — [Behavior description]
Test: [test file path]:[test name]
Status: PASSES ✓
Implementation: [file path]:[function/method]
All tests: passing ✓
Type-check: passing ✓ [or omit this line if no type-check command is available]
With all tests passing, review the code just written (both test and implementation) against coding-guidelines.md. Apply each principle as a lens — does the new code satisfy the guidelines? If not, refactor.
Refactoring scope: Review code written in this TDD session and existing code that the new implementation directly interacts with (files it imports, calls, or inherits from). Look for:
Stay bounded: only consider files the new code already references — don't search the broader codebase for extraction opportunities and don't restructure code that the current behavior doesn't interact with. Eliminate duplication created by getting the test to work, but don't refactor further than necessary for this session.
Also review the test:
testing.md conventions?Make improvements only if they genuinely simplify or clarify. Do not add features, handle untested edge cases, or "prepare for" the next behavior.
Run the project's test command after every refactoring change. All tests must remain green. If any test fails, undo the last refactoring change — the refactoring was incorrect.
If a lint or type-check command was run in Step 5, run it here too — refactoring can introduce lint or type errors that tests don't catch. If it fails, fix the issue before proceeding.
Report to the user:
## Refactor — [Behavior description]
Changes: [brief description of what was cleaned up, or "No changes needed — code is clean"]
All tests: passing ✓
After completing one Red-Green-Refactor cycle, automatically commit the work on the feature branch:
git add <specific files> for the test and implementation files touched in this cycle. Use git add -A only if many files were changed (e.g., renames, moves). Never stage files that look like secrets (.env, credentials, keys) — warn the user if any appear in git status$CLAUDE_PLUGIN_ROOT/skills/commit-message/references/conventional-commit-format.md for the format. The message should cover the behavior just completedgit commit -m "<message>"Committed: <short-hash> <commit message>
Then, if behaviors remain, use AskUserQuestion — header "Next step", question "Cycle complete for behavior #[N]. What next?":
If behaviors remain and the user chooses to continue, return to Step 4 (Red) for the next one.
If no behaviors remain, or the user chooses "Stop here", proceed to Step 8 (Quality Gate).
Read these files for the quality gate:
$CLAUDE_PLUGIN_ROOT/skills/tdd/agents/shared-constraints.md — shared constraints for both agents$CLAUDE_PLUGIN_ROOT/skills/tdd/agents/code-simplifier.md — code-simplifier prompt$CLAUDE_PLUGIN_ROOT/skills/tdd/agents/test-guardian.md — test-guardian prompt$CLAUDE_PLUGIN_ROOT/skills/tdd/references/quality-gate.md — execution procedureFollow the Execution section in quality-gate.md. Use <original-branch> from Step 3 to scope the changed files. When complete, proceed to Step 9.
After all behaviors are implemented (or the user stops early):
If there are uncommitted changes (e.g., the user stopped mid-cycle before the auto-commit):
git add <specific files>; use git add -A only if many files changed) and commit: git commit -m "<conventional message covering remaining work>"## TDD Summary
### Behaviors Implemented
| # | Behavior | Test | Status |
|---|----------|------|--------|
| 1 | [description] | [test file]:[test name] | ✓ Complete |
| 2 | [description] | [test file]:[test name] | ✓ Complete |
| 3 | [description] | — | Not started |
### Stats
- Cycles completed: [N] of [total]
- Tests written: [N]
- Tests passing: all ✓
- Files created: [list new files]
- Files modified: [list modified files]
- Quality gate: code-simplifier ([N] findings), test-guardian ([N] findings)
### Coverage
[Detect coverage command from: testing.md coverage section, test runner built-in flag
(e.g., vitest --coverage, pytest --cov=., go test -cover, dotnet test --collect:"XPlat Code Coverage"),
or package.json coverage script. Run it before the first cycle and after the last cycle to measure delta.
If no coverage command is found, omit this section entirely.]
- Before: [X]%
- After: [Y]%
- Delta: +[Z]%
If there are commits on the branch:
Push the feature branch: git push -u origin <branch-name>
Detect the hosting platform — read $CLAUDE_PLUGIN_ROOT/skills/pr/references/platform-detection.md and use the origin URL check and CI file fallback from the Platform Detection Algorithm. Skip multi-remote disambiguation — if ambiguous or unknown, skip PR/MR creation, report the push and suggest running /optimus:pr to create one
Create a PR/MR using the Conventional PR format:
Read $CLAUDE_PLUGIN_ROOT/skills/pr/references/pr-template.md for the Conventional PR format. Generate the PR title and body following this template.
Write the body to a secure temp file: TMPFILE=$(mktemp "${TMPDIR:-/tmp}/pr-body-XXXXXX.md"). Clean up after the creation attempt: rm -f "$TMPFILE".
GitHub (requires gh CLI):
gh is available: gh --version. If not, skip and tell the user to run /optimus:pr to create the PR (it can install the CLI)gh pr create --title "<conventional title>" --body-file "$TMPFILE" --base <original-branch>GitLab (requires glab CLI):
glab is available: glab --version. If not, skip and tell the user to run /optimus:pr to create the MR (it can install the CLI)glab mr create --title "<conventional title>" --description "$(cat "$TMPFILE")" --target-branch <original-branch>Follow the Conventional PR template, incorporating TDD-specific data: include how many behaviors were implemented via TDD in the Summary, use git diff --stat <original-branch>..HEAD for Changes, and list each behavior as a verification item in the Test plan with coverage delta if available (e.g., "Coverage: [X]% → [Y]% (+[Z]%)").
Report to the user:
### Git Activity
- Branch: `<branch-name>` (from `<original-branch>`)
- Commits: [N]
- Pushed: ✓
- PR/MR: [URL] (or "Run `/optimus:pr` to create — CLI not available")
If behaviors remain unfinished, note them and suggest re-running /optimus:tdd to continue.
If a worktree was used (Step 3), read $CLAUDE_PLUGIN_ROOT/skills/tdd/references/tdd-worktree-orchestration.md and follow the Cleanup section.
Recommend running /optimus:code-review to review the PR/MR before merging.
Tell the user: Tip: for best results, start a fresh conversation for the next skill — each skill gathers its own context from scratch.