crap-analyzer/skills/crap-analyzer/SKILL.md
Use to produce a risk-based refactor + test plan for recently-changed code on a diff/branch/PR by computing CRAP (complexity × untested) on changed methods. Multi-language — TypeScript, JavaScript, Python, Java, Kotlin, Go, Ruby, C#, Rust, PHP — auto-discovers how the repo generates coverage. Triggers — "/crap-analyzer", "analyze CRAP", "compute CRAP", "find risky methods", "find complex untested methods".
npx skillsauth add swingerman/atdd crap-analyzerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
CRAP (Change Risk Anti-Patterns) flags functions that are both complex and poorly tested — the worst-risk code to ship.
CRAP(m) = comp(m)² × (1 − cov(m))³ + comp(m)
This skill scopes analysis to a diff, ranks findings worst-first, and turns each finding into a concrete refactor + test-stub proposal.
Determine the diff. First that works:
gh pr diff / gh pr diff <number> if a GitHub PR is referenced.git diff --merge-base <main-branch> — detect the main branch with git remote show origin | grep 'HEAD branch'.git diff --cached for staged changes.git diff HEAD~N..HEAD for a named commit range.Pipe the diff to scripts/compute_crap.py --diff -.
Locate or generate coverage. Let the script auto-discover coverage files first (lcov, Cobertura, JaCoCo, Clover, Go coverage.out, coverage.py JSON). If nothing is found, follow references/coverage-discovery.md to detect the toolchain, then ask before running it. On decline, proceed with coverage=0% and flag it in the report header.
Run the analyzer.
python3 <skill-dir>/scripts/compute_crap.py --diff - --repo-root <repo> --threshold <N> --format both
Default threshold is 20. Read .crap-analyzer.json at repo root if present and pass its threshold through. Full flag list and output JSON shape: references/script-reference.md.
Present the report. Show the markdown table. For each finding, link file:start_line. If more than ~8 findings, surface the top 5 and mention the rest.
Propose fixes per finding, worst-first. For each function above threshold:
When len(findings) >= 3, dispatch one subagent per finding in a single message — per-finding work is independent so parallelizing drops wall-clock from O(n) to O(1). Prompt template + aggregation rules: references/subagent-prompt.md. After subagents return, sort by CRAP descending and sanity-check every "safe to auto-apply" claim against step 7.
Present the wrap-up menu. Dispatch refactor / test-stub work via AskUserQuestion. Menu structure and apply loop: references/wrap-up-menu.md. "Safe refactor" = pure extract-method with no behavior change (same inputs → same outputs, same side effects, same order). One Edit per action; confirm each before applying.
Never auto-apply:
await, .then, subscribe, promise chains, RxJS / coroutine / goroutine ordering).### 1. `file.py:42` — `do_thing` (CRAP 240)
**Why it's flagged:** complexity 15, coverage 0% (no tests touching body).
**Refactor proposal:**
<unified diff or code block>
**Test stubs to add:**
<framework-appropriate test block>
Keep each section tight — one paragraph of "why", diff, stubs. No preamble.
Optional .crap-analyzer.json at repo root:
{ "threshold": 20 }
Read if present, pass --threshold to the script. No other keys for now.
data-ai
Use immediately after a PR is merged to clean up the local feature branch and resync main. Triggers — "/engineer.post-merge", "did we merge", "did we push", "PR merged", "post-merge cleanup", or right after a `gh pr merge` succeeds in the same session.
data-ai
Use to drive a bug fix from first report through close, with a "why didn't we catch it?" loop at the end. Triggers — "/engineer.fix", "a bug came in", "this is broken", "a user reported X", "there's a defect", "we have a regression", "this needs a fix", "another report", "more issues", "still failing", "validation failed again", "another bug", "next defect", "more fixes".
testing
Use mid-task when the working thread is lost — after a context compaction, a long agent run, or coming back to a feature unsure of the role, the current checkpoint, or the next action. Triggers — "/engineer.reorient", "reorient", "re-anchor", "what should I be doing right now", "I lost track", "where was I".
development
Use to check a feature's code against the charter's architecture rules — dependency layering, cycles, forbidden patterns, file naming, file size. Triggers — "/engineer.arch-check", "architecture check", "check architecture fitness", "does this follow the charter", "check layering".