pi-mutation-test

Pi extension: real mutation testing score for your test suite (Stryker, mutmut, cargo-mutants) — /mutation-test

Packages

Package details

extension

Install pi-mutation-test from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-mutation-test
Package
pi-mutation-test
Version
1.3.5
Published
Aug 26, 2026
Downloads
1,345/mo · 21/wk
Author
theophile-baudouin
License
MIT
Types
extension
Size
64.3 KB
Dependencies
0 dependencies · 0 peers
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

mutation-test — Pi extension

Runs mutation testing on the current project via /mutation-test and writes a deterministic MUTATION_REPORT.md.

Supported stacks (auto-detected):

Stack Tool Marker file
JavaScript / TypeScript Stryker package.json
Python mutmut 3.x pyproject.toml, setup.py or setup.cfg
Rust cargo-mutants Cargo.toml

The extension is a measurement tool: it reports facts (mutants, statuses, score, locations, diffs). It performs no AI analysis, suggests no fixes, and infers no business behavior.

Install

ln -sfn "$PWD" ~/.pi/agent/extensions/mutation-test

(or copy the directory; then /reload in Pi, or restart Pi)

Usage

In Pi, inside the project to test: /mutation-test

Flow: detect stack → confirm install of the mutation tool if missing (uses the project's package manager) → confirm run → run in background → write MUTATION_REPORT.md in the project root. Full tool output is saved to a log file in the system temp directory (path is shown on errors; the log is removed on a clean run).

The command requires an interactive Pi session: it must confirm both the tool install and the long run. In headless/scripted sessions it refuses to run — install the mutation tool manually and re-run in the TUI.

Mutants whose status the extension doesn't recognize are excluded from the score and reported in a dedicated Unknown statuses line, so nothing is silently dropped.

When the stack needs it, the install step also covers the tool's own prerequisites — e.g. Stryker requires the typescript package when a tsconfig.json exists, so the extension installs typescript@^5 alongside @stryker-mutator/core (or as a follow-up install when Stryker is already present). Nothing is installed without your confirmation.

Requirements

  • Node ≥ 23.6 to run the tests (node --test "src/**/*.test.ts" uses TypeScript type stripping).
  • Stryker path: npm-compatible toolchain (npx); jest/vitest/mocha detected automatically, otherwise Stryker's command runner (npm test). Projects with a tsconfig.json also need a resolvable typescript 5.x — the extension installs it automatically (typescript ≥ 7 / tsgo lacks the compiler API Stryker needs).
  • mutmut path: pytest installed; uv / poetry / pipenv / .venv detected automatically.
  • cargo-mutants path: Rust toolchain; cargo install cargo-mutants (slow, one-time).

Development

npm install        # dev-only deps (@types/node)
npm test           # full unit suite
npm run typecheck  # tsc --noEmit

The extension has zero runtime dependencies; @types/node is a dev-only dependency for type-checking.

Score formulas

  • Stryker: (killed + timeout) / (killed + timeout + survived + noCoverage)
  • mutmut: (killed + timeout) / (total − skipped)
  • cargo-mutants: caught / (caught + missed + timeout)

Scope

/mutation-test mutates only production code — never docs, markdown, dependencies, generated files, or test files.

  • Stryker (JS/TS): passes --mutate covering src//lib/ (and other conventional dirs) plus root-level code files (index.ts, main.js, …), excluding *.spec.* / *.test.* / __tests__/. Non-code files (docs, markdown, node_modules, build output, …) are excluded from the sandbox copy with --ignorePatterns, so mutation runs stay fast and focused. If no conventional source dir exists, the tool's own default scope is used.
  • mutmut (Python): mutmut 3.x has no CLI scope flags (config-file only), so the project's own [tool.mutmut] / [mutmut] settings are respected. Default behavior is already production-code-only and coverage-guided: only .py files in source_paths (guessed as src//lib//package name) that are actually called by tests. To narrow it, add only_mutate / do_not_mutate to your pyproject.toml.
  • cargo-mutants (Rust): mutates only the current crate — dependencies are separate crates and are never mutated. To exclude files, add -f/-e globs or .cargo/mutants.toml (examine_globs/exclude_globs).