$npx -y skills add faizkhairi/claude-code-blueprint --skill review-diffScan git diffs for project-specific anti-patterns. Triggers on: 'scan diff', 'check diff', 'anti-pattern check', 'pattern scan', 'review changes'.
| 1 | Scan a git diff for project-specific anti-patterns. This is a fast, targeted scan (seconds), not a full code review. Use `/review` for comprehensive analysis. |
| 2 | |
| 3 | ## Step 0: Detect project |
| 4 | |
| 5 | Ensure you are inside a git repository before running diff commands: |
| 6 | - If cwd is a git repo: use it |
| 7 | - If recent context references a project: `cd` into it first |
| 8 | - Check `CLAUDE.md` or the project manifest (package.json, composer.json, pom.xml, Gemfile, *.csproj, go.mod, Cargo.toml, requirements.txt/pyproject.toml, etc.) in the project root to identify the framework and project-specific patterns |
| 9 | - If unclear: ask which project |
| 10 | |
| 11 | ## Step 1: Get the diff |
| 12 | |
| 13 | Determine the diff source from `$ARGUMENTS`: |
| 14 | - **No arguments**: Run `git diff` (unstaged) + `git diff --cached` (staged). Combine both outputs. |
| 15 | - **Branch name** (e.g., `feat/xyz`): Run `git diff main...$ARGUMENTS` |
| 16 | - **Commit range** (e.g., `HEAD~3..HEAD`): Run `git diff $ARGUMENTS` |
| 17 | - **Single commit hash**: Run `git diff $ARGUMENTS~1..$ARGUMENTS` |
| 18 | |
| 19 | If the diff is empty, report "No changes to scan." and stop. |
| 20 | |
| 21 | ## Step 2: Scan for anti-patterns |
| 22 | |
| 23 | Analyze ONLY `+` lines (additions) in the diff. For each pattern below, search the added lines and the surrounding file context when needed. |
| 24 | |
| 25 | ### Pattern Table |
| 26 | |
| 27 | | # | Pattern | What to look for | Severity | |
| 28 | |---|---------|-----------------|----------| |
| 29 | | 1 | **Filter logic mismatch** | String `===` comparisons where one value could be a prefix of the other (e.g., `'All' === value` when value could be `'All Categories'`). Also: inconsistent use of `startsWith()` vs `===` on the same field across the diff. This requires semantic understanding, not just regex. | HIGH | |
| 30 | | 2 | **Auth gaps** | New `defineEventHandler`, `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()` without a corresponding `@UseGuards()` or `defineMiddleware` in the same file. Read the full file if needed to check. | HIGH | |
| 31 | | 3 | **Soft-delete violations** | `DELETE FROM`, `.delete(`, `.deleteMany(`, `.destroy(` in any ORM/SQL (adapt the delete-method names to your ORM) without corresponding `is_active` or `deleted_at` in the same block. Many projects require soft-delete: `is_active=false` + `deleted_at=new Date()`. Check `CLAUDE.md` for the project's soft-delete convention. | CRITICAL | |
| 32 | | 4 | **(Nuxt/Vue projects, adapt for your framework)** API call pattern | `$fetch(` or `useFetch(` in `.vue` files when the project uses a custom API composable. Check `CLAUDE.md` for the project's API composable (e.g., a wrapper around `$fetch`). Exception: server-side code in `server/` directories may use `$fetch`. | MEDIUM | |
| 33 | | 5 | **(Nuxt/Vue projects, adapt for your framework)** Navigation pattern | `router.push(` or `router.replace(` in `.vue` files when the framework provides a preferred navigation function. Check `CLAUDE.md` for the framework-specific navigation function. | MEDIUM | |
| 34 | | 6 | **Secrets in diff** | Patterns like `password:`, `token:`, `secret:`, `apiKey:`, `DATABASE_URL` followed by a quoted string literal (not `process.env.`, `useRuntimeConfig()`, or env variable references). | CRITICAL | |
| 35 | | 7 | **(Nuxt/Vue projects, adapt for your framework)** External route gap | New files added under `server/routes/` or `server/api/`, check if corresponding frontend navigation uses `external: true` and `<a href>` instead of `<NuxtLink>`. Flag if unclear. | LOW | |
| 36 | | 8 | **N+1 queries** | `findMany`, `findFirst`, `findUnique` called inside `for`, `for...of`, `forEach`, `.map(`, `while` loops. Each iteration hits the DB separately instead of batching. | HIGH | |
| 37 | | 9 | **(Nuxt/Vue projects, adapt for your framework)** CJS default import | `import X from 'cron-parser'` or similar default imports from known CJS packages (`cron-parser`, `lodash`, `moment`). In Nuxt 4 + Vite, use named imports: `import { CronExpressionParser } from 'cron-parser'`. | MEDIUM | |
| 38 | | 10 | **(Nuxt/Vue projects, adapt for your framework)** DevServer binding | `0.0.0.0` appearing in config files (`vite.config`, `nuxt.config`, `devServer` sections). Binds to all network interfaces; security risk. | HIGH | |
| 39 | |
| 40 | ## Step 3: Build findings table |
| 41 | |
| 42 | For each finding, extract: |
| 43 | - **File**: from the diff `+++ b/...` header |
| 44 | - **Line**: calculate from `@@ -X,Y +Z,W @@` hunk headers by counting `+` lines |
| 45 | - **Pattern**: the pattern name from the table above |
| 46 | - **Finding**: the specific line or code that triggered the match |
| 47 | - **Recommendation**: what to change |
| 48 | |
| 49 | Output format: |
| 50 | |
| 51 | ``` |
| 52 | | # | Severity | File | Line | Pattern | Finding | Recommendation | |
| 53 | |---|----------|------|------|---------|---------|----------------| |
| 54 | | 1 | CRITICAL | path/to/file.ts | 42 | Soft-delete | `.delete({ where: ... })` | Use `update({ is_active: false, deleted_at: new Date() })` | |
| 55 | ``` |
| 56 | |
| 57 | If no finding |