ProSkillsLibraryFreePassScan
Code Review

Code Review · agent skill

TDD Loop

One red, the least green, a refactor, a commit. Repeat.

What it does

Loads when it is needed

Your agent loads it when the user wants a feature or fix driven by tests, one slice at a time. It carries 5 rules and reads a profile.md with your details before it starts, so the output matches your brand and project.

Same prompt, with and without

Add promo codes to checkout totals

Prompt · Add promo code support to the checkout total. Customers enter a code and the total drops. Use tests to drive it.

src/checkout/total.ts:
  export function orderTotal(items: {priceCents:number; qty:number}[], shippingCents: number): number {
    const sub = items.reduce((s,i)=>s+i.priceCents*i.qty,0);
    return sub + shippingCents;
  }
src/checkout/total.test.ts has 3 passing tests (sums items, adds shipping, empty cart = shipping only). Runner: `npm test` (vitest, ~2s).
Rules from product: codes are percent-off or fixed-amount; one code per order; percent applies to items only, not shipping; total never below shipping cost; expired codes are rejected with a clear message. Codes live in a `promo_codes` table (code, kind, value, expires_at); lookup helper `findPromo(code)` exists and returns the row or null.

Profile used: Project: order and payments API; Stack: TypeScript, Express, vitest, Postgres; Strictness: Standard; Conventions: conventional commits, tests beside files

Without the skill
Design: keep `orderTotal` pure with an optional `promo` third argument, so existing callers and tests are unaffected. Put lookup and expiry in `resolvePromo(code, now)`, which wraps `findPromo` and throws a clear error. Run `npx vitest run src/checkout` after each step. 1. Percent applies to items only (red): `expect(orderTotal(items, 500, pct(10))).toBe(1800 + 500)`. Green: add `promo?` and the percent branch. 2. Fixed amount: `expect(orderTotal(items, 500, fixed(300))).toBe(1700 + 500)`. 3. Floor at shipping: fixed 99999 and 100% both return 500; a null promo returns 2500. `const discount = Math.min(Math.max(raw, 0), sub); return sub - discount + shippingCents;` 4. Expiry and unknown codes in `promo.test.ts`, mocking `findPromo`: expired throws /expired/, null throws /not valid/. 5. Wire into the route: an expired code returns a 4xx with the message. I haven't seen the route file, so tell me where it lives. One code per order holds because the API takes a single string. Commit as `feat(checkout): apply percent and fixed promo codes to order total`, or `test:` then `feat:`. Assumptions: `findPromo` is async; `kind` is 'percent' | 'fixed'; percent is whole percent, fixed is cents; `expires_at` is a Date and a code is expired at or after it; percent rounds with `Math.round`; unknown codes are rejected.
With the skill
No code yet: the skill stops at the slice list until you say yes. First action once I can run commands: `npm test` for a green baseline (expect 3 passed, ~2s); red means I stop and report. Slices (Standard strictness: happy, failure and boundary rows; 💰 = money, gets a mutation check): 1. 💰 10000¢ items, 500¢ shipping, 10% code -> 9500¢. Percent hits items only. 2. 💰 Percent code with a half-cent result -> rounds per your rule (Q2). 3. 💰 Fixed 1500¢ -> items + shipping - 1500. 4. 💰 Fixed code larger than items -> total equals shipping. 5. 💰 100% code -> total equals shipping. 6. Empty cart + fixed code -> shipping only. 7. Expired `expires_at` -> rejected: "This promo code expired on <date>". 8. Code expiring exactly at `now` -> pinned by your answer to Q4. 9. `findPromo` returns null -> "This promo code isn't valid". 10. No code -> unchanged (the existing 3 tests already pin it). One code per order is a design choice, not a slice: `orderTotal` takes a single `promo`. Decisions needed: (1) pure `orderTotal(items, shipping, promo?, now)` plus `checkPromo(promo, now)`, or throw a typed error? (2) round percent discounts down or half-up (I'd round down)? (3) is `findPromo` async? (4) valid at exactly `expires_at` (I'd say expired once now >= expires_at)? (5) validate percent outside 0-100, or trust the table? Say yes or answer the five. Then slice 1: one vitest test, its pasted red line, the minimal code, `feat(checkout): apply percent promo to items`.

Both answers from the same model (Claude sonnet), 2026-10-17. The one without the skill was written in a separate session that never saw it. Shortened where marked with …

Install

One command, in your project

It detects your agent; add --agent all for every agent.

npx proskills-cli add tdd-loop --order <order id from your receipt>

Or copy the skill folder (the one holding SKILL.md) into the directory your agent reads, then restart it or start a new session.

AgentThis projectEvery project
Claude Code.claude/skills/~/.claude/skills/
Cursor.agents/skills/ (or .cursor/skills/)~/.cursor/skills/
Codex.agents/skills/~/.agents/skills/
Gemini CLI.agents/skills/ (or .gemini/skills/)~/.gemini/skills/

Changelog

What changed

  • v1.0.0 · 2026-10-17
    • First versioned release: One failing test, the least code, a refactor, a commit. Repeat.
    • Scanned 100/100 before release.

Keep it current with npx proskills-cli update; your profile.md is never touched. Everyone who bought it gets the update free and an email when it lands.

Same collection

More from Code Review

The scan checks spec compliance, token cost, clarity and security patterns. A clean scan is not a guarantee: static scanners can be evaded. Scan any skill yourself.