From merge-checks
Audits git code changes across 13 quality dimensions before or after merge, auto-scoping based on branch/commits/uncommitted state or user input, outputs prioritized tasks by file.
npx claudepluginhub diegomarino/claude-toolshed --plugin merge-checksThis skill is limited to using the following tools:
Audit code changes before or after a merge across 13 quality dimensions.
checks/comments.mdchecks/docs.mdchecks/shared.mdscripts/build-manifest.shscripts/check-debug-artifacts.shscripts/check-env-coverage.shscripts/check-i18n-consistency.shscripts/check-migration-exists.shscripts/check-route-registered.shscripts/check-seed-imported.shscripts/check-shared-types.shscripts/check-story-exists.shscripts/check-test-exists.shscripts/detect-env-vars.shscripts/detect-features.shscripts/detect-mode.shscripts/detect-suppressions.shscripts/ensure-deps.shscripts/gather-context.shscripts/list-hardcoded-strings.shPerforms code reviews for PRs, audits, and changes using Codex MCP. Outputs severity-grouped findings and merge gates. Variants: fast (diff), full (lint/build checks), branch.
Reviews and verifies code before merge via triage-first checks (up to 16 parallel agents). Pipeline mode verifies vs plans; general mode for PRs/branches/staged changes. Flags findings only.
Performs structured code reviews on git branches or PRs using tiered persona agents, confidence-gated findings, and a merge/dedup pipeline. Use before creating PRs or for feedback on changes.
Share bugs, ideas, or general feedback.
Audit code changes before or after a merge across 13 quality dimensions. Output: a prioritized task list grouped by file, ready to act on.
!bash -c 'script="$(find $HOME/.claude/plugins/cache -name gather-context.sh -path "*/merge-checks/*" 2>/dev/null | head -1)"; if [ -z "$script" ]; then echo "ERROR: merge-checks gather-context.sh not found. Try reinstalling the plugin."; exit 1; fi; bash "$script" '"$ARGUMENTS"
Read the CONTEXT block above and determine what code to review. Then run the full analysis via precompute.sh.
Step 1: If an explicit argument was passed, auto-proceed.
If ARGUMENT is non-empty, show a one-line scope confirmation and run precompute:
"Scope: [description based on argument]"
Then run precompute via Bash (find the script the same way gather-context.sh was found, but search for precompute.sh):
bash "$precompute_script" "$ARGUMENT"
Skip to Phase 1.
Step 2: Compute signals from CONTEXT.
has_committed = COMMITS_AHEAD > 0
has_uncommitted = UNCOMMITTED_TOTAL > 0
is_mature = BRANCH_AGE_HOURS > 72 OR COMMITS_AHEAD > 20
has_other_work = RECENT BRANCHES or ACTIVE WORKTREES have activity < 24h old
AND current branch is cold (LAST_COMMIT_HOURS_AGO > 24 AND !has_uncommitted)
Step 3: Obvious cases — auto-proceed with scope message.
| Condition | Scope message | precompute.sh args |
|---|---|---|
| Feature + has_committed + !has_uncommitted + !is_mature | "Scope: all N commits on BRANCH vs BASE (X lines)" | BASE |
| Feature + !has_committed + has_uncommitted | "Scope: uncommitted changes on BRANCH (N files)" | --uncommitted |
| Main + !has_uncommitted + !has_other_work | "Scope: post-merge, last 5 merges on BRANCH" | (no args) |
| Main + has_uncommitted + RECENT_MERGES=0 + !has_other_work | "Scope: uncommitted changes on BRANCH (N files)" | --uncommitted |
Show the scope message, run precompute via Bash, skip to Phase 1.
Step 4: Ambiguous cases — ask the user.
Triggers:
Use AskUserQuestion with header: "Review scope" and a descriptive question that includes branch name, commit count, age, and uncommitted count from the CONTEXT.
Build 2-4 options dynamically from this pool (only include relevant ones):
| Option | When to include | precompute.sh args |
|---|---|---|
| "Everything vs BASE — N commits + uncommitted (X lines since DATE)" | has_committed AND has_uncommitted | --all |
| "Committed changes only — N commits vs BASE" | has_committed AND has_uncommitted | BASE |
| "Uncommitted changes only — N files (staged + unstaged)" | has_uncommitted | --uncommitted |
| "Recent work — last N commits (since DATE)" | is_mature, N = min(5, COMMITS_AHEAD) | --recent=N |
| "Since last merge-check (DATE)" | HAS_PREVIOUS_REPORT=true | --since=PREVIOUS_REPORT_DATE |
| "Today's work — N commits + uncommitted" | LAST_COMMIT_HOURS_AGO < 24 AND is_mature | --today |
| "Switch to BRANCH — N commits, last activity Xh ago" | has_other_work, from RECENT BRANCHES | --branch=BRANCH |
| "Review worktree BRANCH at PATH" | has_other_work, from ACTIVE WORKTREES | run cd PATH && precompute.sh |
Map the user's selection to the corresponding precompute.sh invocation. Run it via Bash.
Step 5: Run precompute.sh
Find and execute the script:
script="$(find $HOME/.claude/plugins/cache -name precompute.sh -path '*/merge-checks/*' 2>/dev/null | head -1)"
bash "$script" [ARGS]
The output contains all mechanical findings. Proceed to Phase 1.
Work through three phases: classify the precompute findings, dispatch reasoning agents, compile report.
Severity levels:
| Level | When to use |
|---|---|
| 🔴 blocker | debugger/FIXME/NOCOMMIT/PLACEHOLDER, schema change without migration, unregistered route, unjustified suppression |
| 🟡 should-fix | Missing env var in example file, missing tests for >80-line logic, silent catches, inline shared types |
| 🔵 nice-to-have | Docs gaps, missing comments, missing stories, stale seeds, i18n strings |
Output format per file:
path/to/file.ext — 2 issues:
[🔴] [check-type] actionable description with line reference
[🔵] [check-type] actionable description with line reference
Read each section of the precompute output (from Phase 0) and produce issues. File reads are only needed for ### suppressions (to verify justification comments).
### debug-artifacts (Check 11)
BLOCKER → 🔴 | WARN → 🟡 | (no debug artifacts found) → clean### suppressions (Check 7)
as unknown as typeof fetch) → 🔵 acceptable### env-coverage (Check 10)
MISSING per variable → 🟡 with exact name and file reference### i18n (Check 6) — skip if I18N=false in FEATURES
t('namespace.key') following the convention in existing locale files### i18n-consistency (Check 13) — skip if I18N=false or no I18N_DIR
MISSING:<locale>:<key> → 🟡 (translation key exists in reference locale but missing from target)EXTRA:<locale>:<key> → 🔵 (key exists in target locale but not in reference — likely stale)(no i18n consistency issues) → clean### stories (Check 3) — skip if STORIES=false
MISSING: → 🔵 with 2-3 suggested story variants (empty state, typical usage, edge case)FOUND: → check if the component's props changed in this diff; if so → 🔵 (stories need updating)SKIP: → ignore### tests (Check 5) — skip if TESTS=false
MISSING: source > 80 lines → 🟡 | source ≤ 80 lines → 🔵INDIRECT: → 🔵 (only indirect coverage exists)FOUND: → no issue### routes (Check 8) — skip if ROUTES_MANUAL=false
NOT_REGISTERED: → 🔴### migrations (Check 9) — skip if MIGRATIONS=false
MISSING: → 🔴 (schema changed without migration; include suggested generator command)### seeds (Check 4) — skip if SEEDS=false
NOT_IMPORTED: → 🔵SKIP: → ignore### shared-types — do not classify here; handled by the reasoning agent in Phase 2.
Using the Task tool, launch all three agents in a single message (parallel execution). Before dispatching, read each instructions file to include its content in the agent prompt.
| Agent | Instructions file | Input to provide |
|---|---|---|
| A — Documentation (Check 1) | checks/docs.md | Full FILE MANIFEST |
| B — Comment quality (Check 2) | checks/comments.md | ADDED files list from FILE MANIFEST |
| C — Shared contracts (Check 12) | checks/shared.md | ### shared-types section + SHARED_PKG value |
Wait for all three agents to return, then merge their findings with Phase 1 results.
Collect Phase 1 + Phase 2 results. Merge issues for the same file.
REPORTED = union of all files mentioned in any output
EXPECTED = every file in FILE MANIFEST
NOT_REVIEWED = EXPECTED − REPORTED
Script-driven checks already guarantee 100% coverage via precompute.sh.
Retry targets only reasoning agents (A, B, C).
IF NOT_REVIEWED is not empty:
docs_gap = NOT_REVIEWED ∩ doc files → re-dispatch Agent A, scope = docs_gap only
comments_gap = NOT_REVIEWED ∩ ADDED files → re-dispatch Agent B, scope = comments_gap only
shared_gap = NOT_REVIEWED ∩ source files → re-dispatch Agent C, scope = shared_gap only
Dispatch retry agents concurrently. Merge results. Re-run coverage check.
Files still NOT_REVIEWED after 1 retry:
## path/to/file.ext [not-reviewed]
⚠️ No agent reported on this file — review manually
## Merge check — [MODE]: [SCOPE]
## [N] issues across [M] files
## 🔴 [n] blockers | 🟡 [n] should-fix | 🔵 [n] nice-to-have
Skipped (not detected): [checks skipped due to FEATURES=false]
Clean (no issues): [checks where all files reported clean]
─────────────────────────────────────────────────────
## path/to/file/with/most/issues.ext (N issues)
- [🔴] [debug] `debugger` at line 42 — remove before merge
- [🟡] [tests] No test file; 130 lines of sync logic — worth covering error paths
- [🔵] [comments] Add JSDoc to syncExternalCalendarById() explaining the algorithm
## path/to/next/file.ext (N issues)
- [🔵] [i18n] "Save changes" at line 89 — use t('common.save')
─────────────────────────────────────────────────────
Sort: 🔴 → 🟡 → 🔵 within each file. Files with most issues first.
| Mistake | Fix |
|---|---|
| gather-context.sh or precompute.sh not found | Plugin is not installed or cache is stale — reinstall with /plugin install merge-checks@claude-toolshed |
| Skipping Phase 0 and running precompute directly | Always go through Phase 0 — it determines the correct scope and runs precompute for you |
| Phase 2 agents do not cover all files after 1 retry | Mark remaining files as [not-reviewed] per 3b — do not dispatch a second retry |
| Reading check files with Bash instead of Read tool | Use the Read tool for checks/docs.md, checks/comments.md, checks/shared.md — it's in allowed-tools |
Classifying shared-types in Phase 1 | Skip it — the shared-types section is handled by Agent C in Phase 2 |
After displaying the output, ask once:
"Would you like to save this report? It will be written to
.claude/merge-checks/merge-checks-[branch]-[yyyy-mm-dd].md"
git branch --show-current # → branch name (replace / with -)
date +%Y-%m-%d
Save to .claude/merge-checks/ if .claude/ exists, otherwise project root.
Write the exact Step 3c output. No additions or removals.
If no issues were found, skip this step.