>> .claude/plugins/n8n/skills/mutate-changed
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/workflowchanges — 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.tsfiles (barrels)interfaces.ts,types.ts,constants.ts(same low-value filter asseed-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-teststo 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:
- Plan (before running) — list of files, estimated runtime
- Per-file progress (during) — one line per file as it completes
- 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 skilln8n:strengthen-tests— the natural next step when reds show up
