Paste the failing command. Get a smaller repo that still fails the same way.
繁體中文 · Advisor protocol · Limitations
You already found a real bug. Now the maintainer wants a minimal reproduction, and the repo has 1,000 files. Repo2Repro does the boring part in a disposable copy:
npx github:leavemagic-cyber/repo2repro --output ../issue-repro --match "Expected 2.*Received 3" -- npm test -- --run src/failing.test.tsIt keeps deleting files and npm dependencies only when the chosen failure still reproduces. Then it removes node_modules, performs a clean install, and verifies the reduced failure again.
Repo2Repro produces a reduced, verified reproduction. It does not claim a mathematically minimal result.
For each run, Repo2Repro:
- Copies Git-tracked and non-ignored untracked files to a new directory. The source command is never run in your original repo.
- Excludes Git-ignored files and common credential paths such as
.env,.npmrc, private keys, and credential JSON files. - Captures the same non-zero failure three times. By default, normalized output must be identical;
--matchhandles noisy test runners. - Tests candidate file groups, individual files, and npm dependency groups against that failure oracle.
- Optionally asks any AI CLI for likely removal groups. AI suggestions get no special trust: every group must pass the same oracle.
- Removes
node_modules, performsnpm ci, and reproduces the failure three more times. - Writes
REPRO.mdandrepo2repro-report.jsonbeside the reduced project.
The report records the command, failure signal, exit code, reduction attempts, removed files and dependencies, final verification count, whether a clean install occurred, and safety settings.
C-Reduce and Shrink Ray are serious general-purpose reducers. They are the right tools when you already have a carefully written interestingness test and a reducible test case.
Repo2Repro targets an earlier, messier moment: “this whole npm repo fails when I run this command.” It derives a conservative oracle from the repeated failure, reduces both repository files and package dependencies, and leaves a clean-install evidence report. The scope is narrower; the setup is shorter.
The first release is distributed from GitHub:
npx github:leavemagic-cyber/repo2repro --helpRun it from the Git repository root, or pass --source:
repo2repro --source ./my-app --output ../my-app-repro -- npm test -- --run tests/bug.test.tsThe output directory must not exist. Repo2Repro refuses to overwrite it.
Reduction can take time: the upper bound is roughly --max-attempts × --timeout, plus package installs. The CLI reports every accepted or reverted attempt so a slow reducer does not look hung.
The command after -- is an executable plus arguments, not a shell expression. Put pipes, redirects, environment assignments, or compound commands in a package script first. The command is copied into REPRO.md and the JSON report, so never put a credential in a command argument.
Use the default exact fingerprint when output is deterministic:
repo2repro --output ../repro -- npm test -- --run tests/bug.test.tsThe automatic fingerprint assumes the Git-visible copy contains everything needed to reach the intended bug. If Repo2Repro detects an excluded sensitive-path file, it requires --match so a “missing configuration” error cannot silently replace your real failure. Use --match whenever ignored runtime data may affect the command.
Use a narrow regular expression when timestamps, ports, ordering, or timing make the full output noisy:
repo2repro --output ../repro --match "TypeError: Cannot read properties of undefined" -- npm testA generic signal such as error is dangerous: an unrelated failure may match it. Prefer the failing test name plus its distinctive error text.
Repo2Repro does not require a model. If you already use an AI CLI, --advisor-command lets it inspect the disposable copy and suggest deletion groups:
repo2repro --output ../repro --advisor-command "my-repro-advisor" -- npm testThe advisor receives JSON on stdin and must return strict JSON on stdout. It can be backed by a local model, a hosted model, or deterministic code. Repo2Repro validates every suggestion before accepting it; an advisor cannot declare success. See the provider-neutral protocol.
Repo2Repro protects the source repository, not the machine:
- The failing command runs only in a newly created disposable copy, and command-created files are removed between attempts.
- Existing project files modified by the command make the run fail rather than silently contaminating the oracle.
- npm lifecycle scripts are disabled by default.
--allow-scriptsis an explicit opt-in. - The source manifest is hashed before and after reduction. A concurrent source change aborts the result.
- The output is never overwritten.
This is not a sandbox. The command and optional advisor still have your user permissions and network access. Never use Repo2Repro to run an untrusted command. It also cannot prove that an ordinary tracked source file contains no secret; run your normal secret scanner before sharing the result.
v0.1 intentionally supports the narrow path we can verify well:
- Git repository root
- JavaScript or TypeScript project with
package.json - npm installs and dependency reduction
- deterministic command-line failures
- Node.js 20 or newer
pnpm, Yarn, symbolic links, Git submodules, commands that rewrite existing project files, GUI failures, login-dependent flows, flaky network failures, and hardware-specific failures are not yet supported. See all limits and non-goals.
--source <path> Git repository root (default: current directory)
--output <path> Required new directory for the reproduction
--match <regex> Explicit failure signal for noisy output
--baseline-runs <n> Runs before reduction (default: 3)
--verify-runs <n> Clean verification runs (default: 3)
--timeout <ms> Per-command timeout (default: 120000)
--max-attempts <n> Reduction attempt budget (default: 80)
--advisor-command <cmd> Optional provider-neutral advisor
--skip-dependencies Keep package dependencies unchanged
--skip-install Skip npm install and dependency reduction
--allow-scripts Allow npm lifecycle scripts
git clone https://github.com/leavemagic-cyber/repo2repro.git
cd repo2repro
npm test
npm run checkThe end-to-end test builds a real temporary Git/npm project, reduces unused source and a local dependency, verifies the exact failure after a clean install, and checks that the original repo and ignored .env remain untouched.
Found a repo Repo2Repro cannot shrink without changing the bug? Open an issue with the generated report after removing anything private. Counterexamples are more useful than applause.