Packs / Reproduce First

Reproduce First

Skillv1.0.0

Forces a captured reproduction (command output, failing test or screenshot) before any code edit on a bug report.

Install

# once per machine
curl -fsSL https://hookcrate.com/install | bash
# then
hookcrate install reproduce-first

Get access

One license covers all packs.

What it does

A workflow skill for bug reports. When a user says something is broken, Claude must first capture the failure — the exact command and its output, a failing test, or a screenshot path — into a reproduction record before touching code. The record doubles as the fix's verification: the same command re-run after the change is the proof. Ships with the SKILL.md workflow, a checklist template, and capture.ts, a helper that runs a command and writes its exit code and output into the record.

Usage: bun .claude/skills/reproduce-first/scripts/capture.ts --slug login-500 -- bun test src/login.test.ts

When to use this

Use Reproduce First whenever a bug arrives as a sentence rather than a failing test: "export is empty", "login returns 500 sometimes", "the modal overlaps on mobile". A coding agent reading that sentence will find a plausible cause within seconds and start editing — and plausible is not the same as true. The skill inserts one hard step before any edit: capture the failure into a reproduction record, with the command and its verbatim output, the failing test, or a screenshot and the steps that produced it. The capture does double duty — re-running it after the change is the proof the fix worked, with before and after exit codes side by side in the same file. It pays off most on intermittent bugs (where the first attempt at capture often fails, which is itself the finding), on regressions reported by someone else (whose environment differs from yours), and on anything touching data or money, where a confident wrong fix costs more than a slow right one. It is overkill for a typo in a log message. The capture.ts helper keeps the overhead low: one command, and the record is appended with timestamps.

When it triggers

  • Claude reads a bug report: 'X is broken', 'this fails', 'error when', 'not working', 'regression', a pasted stack trace
  • User invokes /reproduce-first

Preview — a sample session

Illustrative transcript showing the pack in use.

User: CSV export is broken again — users get an empty file. Fix it.

Claude: Bug report → reproduce-first. I'm not touching the exporter until I've seen the empty file myself.

● Bash(mkdir -p repro && cp .claude/skills/reproduce-first/templates/REPRO.md repro/csv-export-empty.md)
● Bash(bun .claude/skills/reproduce-first/scripts/capture.ts --slug csv-export-empty -- bun src/cli.ts export --format csv --out /tmp/out.csv)
  ⎿  capture: before recorded in repro/csv-export-empty.md (exit 0)
● Bash(wc -c /tmp/out.csv)
  ⎿  0 /tmp/out.csv
● Bash(bun .claude/skills/reproduce-first/scripts/capture.ts --slug csv-export-empty --note "wc -c /tmp/out.csv → 0 bytes; exit code 0 means the exporter thinks it succeeded")

Claude: Reproduced: exit 0 but 0 bytes written. Expected: a header row plus one line per record. Filling the Before fixing checklist, then diagnosing.

● Read(src/export/csv.ts)
● Grep("rows.length", src/export)

Claude: Root cause: toCsv() was changed to accept an async iterator, but cli.ts still passes an array — the for await over an array of records yields each record, but the writer flushes before the stream ends because await writer.end() was dropped in the refactor. Fix is to await the end and add a test that asserts byte length > 0.

● Edit(src/export/csv.ts)
● Write(src/export/csv.test.ts)
● Bash(bun .claude/skills/reproduce-first/scripts/capture.ts --slug csv-export-empty --phase after -- bun src/cli.ts export --format csv --out /tmp/out.csv)
  ⎿  capture: after recorded in repro/csv-export-empty.md (exit 0)
● Bash(wc -c /tmp/out.csv && bun test src/export/csv.test.ts)
  ⎿  4812 /tmp/out.csv
     3 pass, 0 fail

Claude: Fixed csv-export-empty: before 0 bytes → after 4,812 bytes with the same command; regression guarded by csv.test.ts › writes all rows before closing. Record: repro/csv-export-empty.md.

FAQ

What if the bug cannot be reproduced?

Then the skill says so and stops. Not reproducing is a result: it means the report is missing a step, a data condition, or an environment detail. The agent asks for those instead of guessing at code.

Does it work for UI bugs?

Yes. The capture is a screenshot path plus the steps and the console or DOM excerpt, recorded with capture.ts --note. The point is that something observable exists before the edit, not that it has to be a shell command.

Where do the records go and should I commit them?

Into repro/<slug>.md in the project. Committing them is useful — they are the most honest changelog a bug can have — but many teams gitignore the folder and keep only the regression test.