Claude Code

The gooze plugin for Claude Code is for the moment Claude writes tests that pass but don't catch much. It sets a Go project up for mutation testing, teaches Claude the run, read, kill-survivors loop, and shows Claude the mutation score and every surviving mutant right after it edits a file.

What you get

  • /gooze:init: writes gooze.yaml, adds a short gooze guide to CLAUDE.md and/or AGENTS.md, and allows the gooze commands, asking before each change.
  • /gooze:mutation-testing: runs gooze on the packages you work on, reads the surviving mutants, writes tests that kill them, and reruns to confirm the score went up. Claude also uses it on its own when you ask about mutation testing.
  • /gooze:ci-setup: adds gooze to the Makefile or CI files your repo already has (GitHub Actions, GitLab CI, Taskfile, justfile, …), adapted to their conventions. It never creates new CI files.
  • Results after every edit: when Claude edits a Go file or gooze.yaml, it gets that file's gooze results. Editing a test shows the surviving mutants of the code it tests.
  • A session check that says once when gooze or goozels is missing or too old, or the guide in your project is outdated. Silent otherwise.

It works alongside the official gopls-lsp plugin; keep that on for Go code intelligence.

Install

In a Claude Code session:

/plugin marketplace add gooze-dev/claude-plugin
/plugin install gooze@gooze

Then install the tools it uses, on the PATH of the shell you start claude from: gooze (v1.3.0 or later) and, for the results after every edit, goozels (v0.2.0 or later).

go install gooze.dev/pkg/gooze@latestgo install gooze.dev/pkg/goozels/cmd/goozels@latest

Both need Go 1.27.3 to build. On an older Go, prefix the commands with GOTOOLCHAIN=auto; your project keeps its own Go version.

Set up a project

Run this once in your project:

/gooze:init

It creates gooze.yaml if there is none, adds a gooze section between <!-- gooze:begin --> and <!-- gooze:end --> markers to CLAUDE.md and/or AGENTS.md, and offers permission rules for .claude/settings.json. The section records its own version and the gooze version, so the session check can tell you when to run /gooze:init again; rerunning it updates the section in place.

Use it

Ask in plain words, for example:

  • “Run gooze on ./internal/domain/... and kill the surviving mutants in ignore.go without changing production code.”
  • “Which files in this package have the lowest mutation score?”
  • “Are any of the surviving mutants in parser.go equivalent? Suppress only those.”
  • “Add mutation testing to our CI.”

One function at a time

When Claude kills the survivors of one function, a full run tests every mutant of the package on each try. When gooze has --run, /gooze:mutation-testing uses a shorter loop. It checks that gooze run --help lists the flag first:

  1. Preview with gooze run --estimate --run '^InRange$' ./....
  2. Write a test, run gooze run --run '^InRange$' ./..., and read the survivors with gooze report view -o .gooze-reports/run. Repeat.
  3. When the function is done, gooze report merge adds the results to the main reports.

Ask for it in plain words: “Kill the surviving mutants in InRange only.” Until the merge, the results after an edit come from the main reports, because goozels doesn't read run/. The skill reports a --run score as the function's score, not the package's, and /gooze:ci-setup doesn't put --run or --mutagens in CI.

What Claude sees after an edit

With goozels installed, a hook adds the edited file's results to Claude's context, without blocking the edit. After the first run of the calc package, an edit of calc.go runs the hook below. Claude reads its additionalContext: the goozels check output under a one-line header, and a hint about mutants that can't change behavior:

{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"gooze results from the last run:\ncalc.go:1:1: warning: gooze: score 84.62% — 11 killed, 2 survived\ncalc.go:10:2: warning: gooze: surviving comparison mutant — tests still pass with `if n < lo {` → `if n <= lo {`\ncalc.go:13:2: warning: gooze: surviving comparison mutant — tests still pass with `if n > hi {` → `if n >= hi {`\ngooze: a mutant that cannot change behavior (an equivalent mutant) can be skipped with //gooze:ignore <mutagen> on its line"}}

Both survivors point at the bound checks: no test calls InRange with n equal to lo or hi. Once Claude adds those two boundary tests and reruns gooze, the score line reads:

Mutation score: 100.00% (13 killed, 0 survived; 0 cached, 13 tested)

When the file changed since gooze last ran, the results say so and give the rerun command instead of pointing at lines that moved. Later edits of the same file in a session get a one-line summary until the results change.

CI

/gooze:ci-setup looks for the build and CI files your repo already has and proposes a gooze target or job in their style, with an optional score gate. It applies the change only after you agree. See CI for the full setups.

Code review

Claude Code's built-in /code-review follows CLAUDE.md, so the guide from /gooze:init makes reviews run gooze on the changed packages and report surviving mutants as test gaps.

  • Allow the gooze commands (/gooze:init offers the rules), or the review stops at a prompt for each one. Claude Code applies a project's allow rules only once you have trusted the folder.
  • In a headless run, such as claude -p "/code-review" in CI, pass the rules on the command line:
claude -p "/code-review" --allowedTools "Read,Grep,Glob,Bash(gooze run *),Bash(goozels check *)"

For pull requests, run gooze in CI and give the reviewer its report; the managed Code Review service doesn't run code.

Update

To get new versions automatically, open /plugin, go to Marketplaces, select gooze and choose Enable auto-update. Otherwise:

/plugin marketplace update gooze

Troubleshooting

  • No gooze results after an edit: run goozels check <file> yourself. If it says there are no results yet, run gooze first; if the command isn't found, install goozels on the PATH of the shell you start claude from.
  • A notice at session start: it names what is missing or outdated and the command that fixes it.
  • Plugin problems: open /plugin and check the Errors tab, or start claude --debug. Plugins don't run in cloud sessions or safe mode.

Using Codex or opencode instead? See AI coding agents.