Good AI Tools

>> .claude/plugins/n8n/skills/mutate-changed

stars: 190251
forks: 58132
watches: 1095
last updated: 2026-05-29 19:48:29

description: Run Stryker mutation testing on the source files changed in the current branch (vs origin/master). One command for "did my work hold up under mutation?" before pushing. Triages on the side which files dropped below threshold and offers to invoke n8n:strengthen-tests on them. Use when the user says /mutate-changed, "mutate what I changed", "check my changes", or has just finished writing a feature and wants pre-merge feedback. Scope: only packages/workflow/src/** changes are mutated today.

Mutate what I changed

Closes the local dev loop. Single command to run Stryker against every source file the current branch touched (vs origin/master), then point at any reds that need strengthening.

When to use

  • User says /mutate-changed, "mutate the files I changed", "check my changes", "did my tests stick"
  • Mid-feature: dev wants pre-merge feedback before pushing
  • Pre-PR: cheaper than waiting for the nightly cron

Don't use:

  • For a single specific file (/n8n:mutation-test <path> is faster)
  • For non-packages/workflow changes — Stryker is only wired up there today
  • After the user already ran /n8n:strengthen-tests (which calls mutation-test internally for verification — running both again is wasted compute)

Inputs

  • Default base: origin/master. Override with --base <ref> if comparing against another branch (e.g. --base HEAD~5).
  • Default scope: packages/workflow/src/**/*.ts. The only package with Stryker wired up today.

Steps

1. Identify changed source files

git diff --name-only origin/master...HEAD -- 'packages/workflow/src/**/*.ts'

(... is correct — three-dot means "since the branch diverged from base," which is what we want.)

If git fetch hasn't been run recently, suggest the user git fetch origin master first; otherwise the base ref is stale.

Filter out:

  • **/*.d.ts (declarations, no behaviour)
  • **/*.stories.ts (Storybook scaffolding, not present in workflow but defensive)
  • index.ts files (barrels)
  • interfaces.ts, types.ts, constants.ts (same low-value filter as seed-ledger.mjs)

2. Surface the plan to the user

Print the filtered list before running anything. Each Stryker run is 1–5 minutes; the user should confirm if there are many.

Found N changed source files to mutate:
  - packages/workflow/src/foo.ts
  - packages/workflow/src/bar.ts
  ...

Estimated runtime: ~M-K minutes (M minutes minimum if every Stryker run is fast).
Proceed? (skill default: yes if N ≤ 3, ask if N > 3)

If the filtered list is empty: report "No source files under packages/workflow/src/** changed vs $base — nothing to mutate." and stop. Exit cleanly.

If N > 8: refuse and ask the user to narrow scope (a different base ref, or invoke per-file). Running 8+ mutations sequentially is a 30+ minute session that should be a deliberate choice.

3. Run mutation testing per file

For each file in the plan, invoke pnpm --filter=n8n-workflow mutate <package-relative-path>. The summary.json and other artefacts get overwritten on each run, so capture the score per file as you go.

After each run completes, print one line:

✓ src/foo.ts   95.12% (39/41 killed)   GREEN
✗ src/bar.ts   54.83% (17/31 killed)   RED  — 13 survivors, top: ConditionalExpression, EqualityOperator

If a Stryker run hard-fails (exit 3, no summary.json), print ! src/foo.ts Stryker failed — see stderr and continue to the next file. Don't abort the whole batch.

4. Summary table

After all files have been mutated, print one compact table:

=== Mutation results: N files, M green, K red, J failed ===
| File                        | Score   | Verdict | Survivors |
|-----------------------------|---------|---------|-----------|
| src/foo.ts                  |  95.12% | GREEN   |         2 |
| src/bar.ts                  |  54.83% | RED     |        13 |
| src/baz.ts                  |    n/a  | FAILED  |         - |

5. Offer the strengthen step on the worst red file

If any file came back red:

The lowest-score red file is src/bar.ts (54.83%, 13 survivors). Run /n8n:strengthen-tests to triage them and write assertion changes? (suggesting; don't auto-invoke)

Only suggest one file at a time — n8n:strengthen-tests caps at 5 survivors per invocation, and re-running this skill after edits is cheap.

If everything is green: report it and stop. No follow-up needed.

Output shape

Three deliverable sections per invocation:

  1. Plan (before running) — list of files, estimated runtime
  2. Per-file progress (during) — one line per file as it completes
  3. Summary table + recommendation (after) — compact view

Don't dump full summary.json payloads — the per-file mutate runs already write them to disk under packages/workflow/reports/mutation/ (overwriting each time, since the orchestrator uses fixed filenames). The user can read the latest one if they want detail.

Constraints

  • Hardcoded to packages/workflow. Generalise when Stryker is wired up to other packages.
  • Max 8 files per invocation. Above that, ask user to narrow.
  • Don't auto-invoke /n8n:strengthen-tests. Suggest, don't act. Same reasoning as the other skills: each pass should be a deliberate human-approved step.
  • No commits. Edits land in working tree; user reviews.
  • No fabricated scores. If a Stryker run fails, mark FAILED in the table — never guess a value.

Common follow-ups

  • "strengthen them all" → loop the user through /n8n:strengthen-tests, one file at a time
  • "what changed?" → git diff origin/master...HEAD -- <file> for the file in question
  • "ignore " → re-run with the user's exclude added to the filter

Related

  • n8n:mutation-test — single-file version of this skill
  • n8n:strengthen-tests — the natural next step when reds show up