Umpire
Runs your tests after Claude edits code and makes the call. Off by default.

36 passingnone14Run tests after file edits
Umpire runs your tests after Claude Code edits files with its own tools and shows the result. Automatic runs are off by default.
How it works
Slash commands
/umpireRuns your tests after Claude edits code: on, off, run, show, command, tell
Settings
enabledDefault:true- Switch umpire off without uninstalling it. The modmyclaude hub flips this too.
startOnDefault:false- Run the tests after every turn that changes files, in every session, without typing /umpire on.
commandDefault:- The command to run, as you would type it (run through sh). Empty: found from the project (package.json's test script, pytest, go test, cargo test).
maxSecondsDefault:120- A run longer than this is stopped and called timed out. 5 to 600.
Hook events
The prompt
Build me a Claude Code mod called "umpire": it runs my tests after Claude edits code and shows the call. It is off until I say /umpire on. Find the test command once per session: my setting first, else one I set for this project with /umpire command (kept per project in the mod's store), else package.json's test script (through pnpm, yarn, bun or npm by lockfile, never npm's "no test specified" placeholder), pytest, go test ./... or cargo test. Run it at the end of any main turn in which Claude's Edit, Write or NotebookEdit changed a file: one run at a time in the project root with CI=1 and colour off, a time limit I can set, started off the turn's clock (never inside a hook's wait); a turn that ends during a run queues exactly one more. Read the result from Jest, Vitest, pytest, go test and cargo test summaries (passed, failed, the failing names), else from the exit code. Show one line above the prompt with the counts, the first three failing names (+N more) and the run time, in the error colour when failing; a toast only when the result flips; a status-line entry with the counts. /umpire show opens a pane with the call, a history mark per run, the failing names and the output's end. "tell Claude" fills my prompt box with the failing names and the last 30 lines, secrets redacted, after anything I typed; never send anything yourself. on, run, command and tell run only when I type them.Details
Runs your tests after Claude edits code and makes the call: passed and failed counts above the prompt, a toast when it flips. Off by default.
umpire: 142 passed · 2 failed · auth.test.ts, user.test.ts · 8.3 s
Use it
Type /umpire on. From then on, at the end of every turn in which Claude changed files with its own tools (Edit, Write, NotebookEdit), umpire runs your project's tests once, and:
- A line above the prompt makes the call: passed and failed counts, the first three failing tests or files (
+2 morepast that) and how long it took, in the error colour when something fails. While the tests run it says so. - A toast only when the call flips: the tests started failing, or they pass again. Never on every run.
- The status line keeps the count:
tests 142/144. /umpire showopens the last run: the call, a mark per run for the last ten, the failing names, and the end of the output. tell Claude puts the failing names and the output's last 30 lines in your prompt box, after anything you typed, with anything that looks like a secret redacted. You decide whether to send it.- A hold when a file that says what the tests run changes:
package.json,pyproject.toml,pytest.ini,go.modorCargo.toml. Claude editing one anywhere in the project, or anything changing one at the project root (a shell command, you), stops the runs that start on their own, and the line says which file. They wait until you start a run with/umpire runor run again, so a test command Claude just changed waits for you to start it.
It finds the test command once per session: your setting, else the one you set for this project with /umpire command, else package.json's test script (through pnpm, yarn, bun or npm, by lockfile), pytest, go test ./... or cargo test. It understands the summaries of Jest, Vitest, pytest, go test and cargo test; for anything else, the exit code makes the call.
| Command | What it does |
|---|---|
/umpire on | Run the tests after each turn that changes files (only when you type it) |
/umpire off | Stop |
/umpire run | Run them now (only when you type it) |
/umpire show | The last run, in a pane |
/umpire command <cmd> | Set this project's test command, as you would type it (only when you type it) |
/umpire tell | Put the failures in your prompt box (only when you type it) |
"Only when you type it" means typed by you in the terminal, the desktop app or Remote Control. A program you run that drives Claude Code through its SDK counts as you too, since the desktop app sends that way; another mod, a peer session or Claude running the command is refused.
Settings
Every setting has a default, so the notice at install about options not yet set is expected; change them in /config.
- On: on by default. Off, Umpire runs nothing and draws nothing, and every
/umpirecommand says it is off; switched on again,/umpire on(or the setting below) decides, as before./configor the modmyclaude hub flips it, live. It runs commands, so another mod cannot switch it on; anyone can switch it off. - On from the start: run in every session without
/umpire on. Off by default. - Test command: the command to run, as you would type it. Empty: found from the project.
- Time limit (seconds): 120 by default; a longer run is stopped and called timed out.
What it can touch
- Runs: the one test command, in the project root, with
CI=1and colour off so test runners do not wait in watch mode, stopped at the time limit. A command you typed (the setting or/umpire command) runs throughshas you wrote it. Nothing else. - Reads: the project's
package.json,pyproject.toml,pytest.ini,go.modandCargo.toml, and whether a lockfile ortests/exists, to find the command and to see when one of those files changes. The paths of the files Claude's tools edit, to hold the runs when one of them is such a file. - Keeps: the last ten runs' output, a million characters at most, in the mod's memory only. The command you set per project in its own store, keyed by a hash of the project's path.
- Writes: its session state (on or off, the runs' calls, the hold), the line, the status line, toasts, and your prompt box when you press tell Claude, never sent.
- Network, model calls: none of its own. Your tests may do anything your tests do.
Limits
- Changes a shell command made (a formatter, a codegen script) do not trigger a run; only Claude's own file tools do.
/umpire runcovers the rest. - One run at a time: a turn that ends during a run queues exactly one more, run when the first is done.
- Counts come from the test runner's summary line; go test without
-vnames failing tests but counts no passes. - The run's output is shown as the runner printed it, without colour. Long output keeps its end. Past 4 MB the engine stops keeping it: the call then says
output cut at 4 MBand may have no counts. - The hold covers the files that say what the command runs. The tests themselves are code, and Claude may have written them: umpire runs them as your test runner would, so turn it on only where you would run the tests yourself. A command you set that reads another file (a Makefile) is not held when that file changes.
- The line, the pane and the presses are checked through the engine's test kit on the terminal and desktop surfaces, with the test runner stood in for.
Built from a prompt
This mod was built from the Umpire prompt.
Pairs well with
Follow modmyclaude for new mods: TikTok · Instagram · YouTube · X · Threads · Facebook