stryker-reporter-llm
v0.1.0
Published
Stryker reporter that produces LLM-friendly survivors output
Maintainers
Readme
stryker-reporter-llm
Stryker reporter that produces LLM-friendly survivor output (survivors.md).
Installation
pnpm add -D stryker-reporter-llmConfiguration
Add to your stryker.config.*:
export default {
reporters: ["html", "json", "stryker-reporter-llm"],
plugins: ["@stryker-mutator/vitest-runner", "stryker-reporter-llm"],
// ...
};Output path
You can configure where survivors.md is written via llmReporter.outputPath. Default: .stryker-output/survivors.md.
export default {
reporters: ["html", "json", "stryker-reporter-llm"],
plugins: ["@stryker-mutator/vitest-runner", "stryker-reporter-llm"],
llmReporter: {
outputPath: "custom/path/survivors.md",
},
// ...
};When using a custom outputPath, ensure any agent or tool that reads the survivors file uses the same path.
Output
The reporter writes .stryker-output/survivors.md (or your configured outputPath) with surviving mutants formatted for LLM consumption. If no survivors exist, the file contains ALL_KILLED.
Enriched output format
Each survivor entry includes context to help an LLM classify likely causes and propose fixes:
| Field | Description |
|-------|-------------|
| ID | Stable mutant identifier for correlation across runs |
| Location | Line and optional column range for precise navigation |
| Tests completed | Number of tests run for this mutant |
| Covered by | Resolved test names that exercised this code (when Stryker provides testFiles) |
| Nearby killed mutants | Killed mutants on the same line, with their failure reasons (helps distinguish "add test" vs "strengthen assertion") |
| Original (snippet) | Code snippet at the mutation site |
This helps LLMs distinguish between:
- Missing test — no or weak coverage; add a new test case
- Weak assertion — covered but not asserted; strengthen an existing test
- Equivalent mutant — nearby mutants killed with different reasons; may be ignorable
Example
## File: `src/discount.ts`
### Survivor 1 — Line 27
- **ID:** `2`
- **Mutator:** `ConditionalExpression`
- **Replacement:** `false`
- **Location:** Line 27 (col 7–20)
- **Tests completed:** 3
- **Covered by:** calculateDiscount returns subtotal for bronze tier; calculateDiscount applies silver discount for quantity >= 5; calculateDiscount handles gold tier
- **Nearby killed mutants:** `ConditionalExpression`: expected -1 to be 20 // Object.is equality; `EqualityOperator`: expected -1 to be 20 // Object.is equality
- **Original (snippet):** `if (unitPrice < 0) {`Optional: STRYKER_SCOPE
When running scoped mutations (e.g. stryker run --mutate "src/auth.ts"), you can set STRYKER_SCOPE so the reporter filters survivors to only include files in scope:
- Format: Comma-separated file paths or globs (e.g.
src/auth.ts,src/**/*.ts) - Behavior: When set,
survivors.mdincludes only mutants from files matching the scope - Default: When not set, all survivors are included (backward compatible)
Example:
STRYKER_SCOPE=src/auth.ts npx stryker run --mutate "src/auth.ts"