cf-tdd
Medium1,500 – 3,000 tokens injected into promptupdatedImplementation workflow — direct code by default, TDD opt-in with --add-tests.
Context footprint: (medium) — what does this mean?
Works without coding-friend-cli. See CLI
requirements for the full matrix.
The cf-tdd skill automatically activates when you're writing new code or refactoring existing code. By default it uses direct implementation — write code directly without new tests, then run any existing tests. To enable TDD (RED → GREEN → REFACTOR), pass --add-tests or set tdd: true in your config. To enable the end-to-end autopilot loop (auto review + fix + commit after implementation), pass --auto.
Mode Detection
The skill detects which mode to use at startup. Mode (Direct vs TDD) and autopilot (off vs on) are orthogonal — any combination is valid:
--add-testsflag present in the invocation → TDD modetdd: truein.coding-friend/config.json→ TDD mode- Neither → Direct mode (default)
--autoflag present → Autopilot post-implementation loop activates on top of the chosen mode
Direct mode shows: > Direct mode — implementing without new tests
TDD mode shows: > TDD mode enabled
Autopilot shows: > 🤖 Autopilot enabled — will auto-review, auto-fix Critical+Important, and auto-commit after implementation
Autopilot Loop (--auto)
Activates iff --auto is in the current /cf-tdd invocation's arguments. This is a single, simple gate — Claude does not introspect whether it was loaded transitively. The autopilot loop is intentionally NOT activated when cf-tdd is loaded as a fallback under /cf-plan (because /cf-plan owns the loop there and never propagates --auto to subagents).
When active, after implementation completes its own verification (tests + typecheck):
- Auto-invoke
/cf-reviewon uncommitted changes - If 🚨 Critical or ⚠️ Important findings → dispatch one fix task to
cf-implementer→ re-run review (max 2 review rounds; 1 fix attempt) - If the fix task itself fails (
[CF-RESULT: failure]) → STOP autopilot, do NOT consume the second review round - On clean review (or only 💡 Suggestions) →
git add -A+ single conventional commit (<type>(<scope>): <task summary>). Suggestions are logged in the commit body - Report what was implemented, reviewed, fixed, and committed
Stop conditions (autopilot only halts on these):
- Implementation fails its own verification
- Fix task returns failure
- Review round 2 still has Critical or Important findings
- Review output cannot be parsed
git commitfails repeatedly after hook fixes- User explicitly interrupts
Skip Conditions
Both modes skip entirely when:
- All changed files are non-code — styles (
.css,.scss,.sass,.less,.styl), docs (.md,.mdx,.txt,.rst), or config (.json,.yaml,.yml,.toml,.env,.ini,.lock,.config). Whitelist matches only when all changed files belong to these types. - User passes
--no-tdd— deprecated flag, kept for backward compatibility.
Agent Handoff
When cf-tdd dispatches the cf-implementer agent for substantial implementations, it uses a structured JSON context file to pass findings without losing nuance through text serialization. See Agent Context Handoff for the full mechanism, schema, and retry protocol.
When It Activates
Automatically triggered when:
- Creating new functions or methods
- Adding new modules or classes
- Writing feature code from scratch
- Refactoring existing code ("refactor this", "clean up", "extract this", "simplify")
- Test file exists but implementation doesn't
Direct Mode (Default)
Implements the feature without writing new tests:
- Read task context and understand requirements
- Implement the feature directly
- Run existing tests if any (
npm test,pytest, etc.) — do not write new ones - Run type checking and linting if configured
- Report what was done
TDD Mode (--add-tests)
The classic RED → GREEN → REFACTOR cycle:
RED: Write Failing Test
Start by writing a test that describes desired behavior — it fails because the code doesn't exist yet.
// test/user.test.ts
test("should hash password with bcrypt", () => {
const password = "secret123";
const hashed = hashPassword(password);
expect(hashed).not.toBe(password);
expect(hashed.length).toBeGreaterThan(10);
});
GREEN: Implement Minimal Code
Write the simplest code that makes the test pass. No over-engineering.
// src/user.ts
export function hashPassword(password: string): string {
return "hashed_" + password;
}
REFACTOR: Improve Code
Now improve the code while keeping tests green.
// src/user.ts
import bcrypt from "bcrypt";
export function hashPassword(password: string): string {
return bcrypt.hashSync(password, 10);
}
When TDD Helps Most
- Complex business logic
- Data transformations
- Critical paths (auth, payments)
- Edge case handling
- Error scenarios
Config Option
Set tdd: true in .coding-friend/config.json to make TDD the default for all implementations in a project:
{
"tdd": true
}
Or configure it interactively with cf config or cf init.