wani-code-review
Skill18 starsChanged 5 months agoMITView on GitHub
Pre-review quality assurance for any repo in the WaniWani workspace. Run this skill BEFORE creating a PR, before claiming work is done, or when the user says "review", "QA", "check my changes", "pre-review", "ready for review", or anything suggesting they want to validate their work before sharing it. Also trigger proactively after completing a significant implementation task. This is the last line of defense before code reaches reviewers.
In this repository26 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agent-browserSkill
- copySkill
- deploy-prodSkill
- linear-oneshotSkill
- project-planningSkill
- project-updateSkill
- pull-requestSkill
- create-flow-appSkill
- frontend-designSkill
- knowledge-baseSkill
- release-migrationSkill
- translationsSkill
- visualize-flowSkill
- audit-trackingSkill
- instrument-trackingSkill
- migrate-waniwani-sdk-0.15-to-0.16Skill
- migrate-waniwani-sdk-0.16-to-0.17Skill
- migrate-waniwani-sdk-0.17-to-0.18Skill
- migrate-waniwani-sdk-0.18-to-0.19Skill
- migrate-waniwani-sdk-0.19-to-0.20Skill
- migrate-waniwani-sdk-0.22-to-0.23Skill
- migrate-waniwani-sdk-0.23-to-0.24Skill
- migrate-waniwani-sdk-0.24-to-0.25Skill
- waniwani-sdkSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
33 rules. About 0 are common, 24 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈24
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 14
Before running any checks, determine which repo you're working in:
- Distinctive: line 18
Read the repo's own CLAUDE.md if one exists — it contains repo-specific conventions, commands, and rules that Layer 1 and Layer 2 checks …
- Distinctive: line 19
If the repo happens to sit inside a larger workspace that has its own root CLAUDE.md above it, read that too for cross-repo rules — but …
- Distinctive: line 31
Before creating a PR or pushing a branch
- Distinctive: line 32
Before claiming implementation work is complete
- Distinctive: line 33
When the user asks for a review, QA pass, or pre-review check
- Distinctive: line 38
Run the repo's own tooling and report any failures.
- Very specific: line 42
Run the repo's TypeScript check command.
- Very specific: line 48
Run the repo's lint command (e.g., bun lint, bun check:fix).
- Distinctive: line 50
Must pass with zero errors.
- Very specific: line 54
If the repo has a dead code checker (e.g., bun knip), run it.
- Very specific: line 58
If the repo uses a translation system (check for translations:build in CLAUDE.md or @translations.ts files), verify the translation index …
- Distinctive: line 65
If this produces a diff, the translation index is out of sync.
- Very specific: line 69
Search the diff for as type assertions:
- Distinctive: line 85
Read each changed file in full (not just the diff hunks — you need surrounding context)
- Distinctive: line 86
Read the repo's CLAUDE.md to understand which conventions apply
- Very specific: line 94
Every user-visible string in TSX/JSX must go through the translation system (e.g., useTranslation hook, t.some.key)
- Distinctive: line 97
If a component has user-facing text, verify a co-located translation file exists with all supported languages
- Very specific: line 109
Never use raw fetch() if the repo has API helpers — use the documented pattern (e.g., api.GET() with Zod schema validation)
- Distinctive: line 110
Check that query keys are consistent — if two components fetch the same data, they should use the same query key so the cache is shared
- Distinctive: line 131
Missing indexes: if a query filters on a column that doesn't have an index (check the schema definition), flag it as a warning for any …
- Distinctive: line 137
Verify imports follow the conventions documented in the CLAUDE.md — schemas, types, and query functions should live where the CLAUDE.md …
- Distinctive: line 138
Check for imports from paths that don't match the project's established structure (e.g., importing from an internal subdirectory when the …
- Distinctive: line 139
Check for duplicate definitions — if a Zod schema or type already exists elsewhere, don't redefine it
- Distinctive: line 148
Check that the repo's UI conventions are followed (layout patterns, empty states, confirmation dialogs)
- Distinctive: line 152
No reinventing existing helpers — before writing utility code, search the codebase for existing implementations.
- Distinctive: line 153
No deprecated patterns — if the codebase has moved away from a pattern (check git history and CLAUDE.md for guidance), new code must use …
- Distinctive: line 155
No temporal references in comments ("now", "previously", "was", "switched from") — comments describe current behavior, git handles history
- Distinctive: line 164
Follow the repo's documented UI patterns for page structure, spacing, and component usage
- Very specific: line 168
After completing Layer 1 and Layer 2, invoke the code-review:code-review skill on the same scope.
- Distinctive: line 208
If it's a deterministic check (can be linted/grepped), add it to Layer 1
- Distinctive: line 209
If it requires reading code and understanding context, add it to the appropriate Layer 2 category
- Very specific: line 210
If it's a new category entirely, create a new 2.N section
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
WaniWani Code Review
Quality gate that runs before code reaches human reviewers. Catches the patterns that cause PR feedback loops — type safety violations, missing translations, architectural anti-patterns, and convention drift.
The skill works in three layers: automated tooling checks, a diff analysis against project conventions, and finally a broader code review pass via the code-review:code-review skill.
Step 0: Scope Detection
Before running any checks, determine which repo you're working in:
- Identify the repo from the user's request or from the current working directory / recent file edits
- Find the repo root (look for
.git/,package.json,CLAUDE.md) - Read the repo's own
CLAUDE.mdif one exists — it contains repo-specific conventions, commands, and rules that Layer 1 and Layer 2 checks must respect - If the repo happens to sit inside a larger workspace that has its own root
CLAUDE.mdabove it, read that too for cross-repo rules — but don't assume one exists; many repos are standalone
The repo's CLAUDE.md is the source of truth for:
- Which package manager and commands to use (
bun lintvsnpm run lint) - Which linter/formatter is configured (Biome vs ESLint)
- Repo-specific patterns (data fetching conventions, auth patterns, file structure)
- What tools exist for checking (knip, tsc, translations:build, etc.)
Adapt all Layer 1 commands and Layer 2 checks to the specific repo. The categories below use examples from a Next.js/TypeScript app, but the same principles apply to any repo — adapt to whatever conventions that repo's CLAUDE.md documents.
When to Run
- Before creating a PR or pushing a branch
- Before claiming implementation work is complete
- When the user asks for a review, QA pass, or pre-review check
- Proactively after finishing a multi-file feature implementation
Layer 1: Automated Checks
Run the repo's own tooling and report any failures. Adapt commands based on what the repo's CLAUDE.md documents. These are non-negotiable — fix failures before proceeding to Layer 2.
1.1 Type checking
Run the repo's TypeScript check command. For most repos this is bun tsc --noEmit but check the CLAUDE.md for the exact command (some repos use bun run build which includes type checking).
Report only NEW errors — compare against the base branch if needed.
1.2 Linter / Formatter
Run the repo's lint command (e.g., bun lint, bun check:fix). The specific linter (Biome, ESLint) and its config vary by repo — the CLAUDE.md will specify.
Must pass with zero errors.
1.3 Unused code detection
If the repo has a dead code checker (e.g., bun knip), run it. Any unused export in a file you modified is your responsibility to fix.
1.4 Translation sync (if applicable)
If the repo uses a translation system (check for translations:build in CLAUDE.md or @translations.ts files), verify the translation index is in sync:
bun translations:build
git diff --stat -- src/lib/translations/index.tsIf this produces a diff, the translation index is out of sync.
1.5 Type assertion scan
Search the diff for as type assertions:
git diff HEAD -- '*.ts' '*.tsx' | grep '^\+' | grep -v '^\+\+\+' | grep '\bas\b'Filter out acceptable uses: as const, as keyof typeof, narrowing after type guards. Everything else is a violation per CLAUDE.md — use Zod safeParse for unknown data or typed variables for known unions.
Layer 2: Diff Analysis
Get the full diff of changed files, then read each changed file and evaluate against the categories below. This requires understanding the code and its context — not just pattern matching.
How to run Layer 2
- Get the list of changed files:
git diff --name-only HEAD(or vs the base branch) - Get the full diff:
git diff HEAD - Read each changed file in full (not just the diff hunks — you need surrounding context)
- Read the repo's CLAUDE.md to understand which conventions apply
- Walk through every category below, checking each changed file
- For each issue found, record: file path, line number, category, description, severity (blocker/warning)
2.1 Translations & Localization
Skip this category if the repo doesn't use a translation system.
- Every user-visible string in TSX/JSX must go through the translation system (e.g.,
useTranslationhook,t.some.key) - This includes: button labels, headings, descriptions, empty states, error messages, toast messages, placeholder text, aria labels, loading/fallback text
- This does NOT include: CSS class names, HTML attributes, internal keys, log messages, error codes thrown to API consumers
- If a component has user-facing text, verify a co-located translation file exists with all supported languages
- For French translations: verify proper accents and cedillas. Common misses include words like "Apercu/Apercu", "Parametres/Parametres", "a/a" (preposition). Read the French entries carefully.
- Loading/fallback text is still user-visible — raw strings like
"..."or"Loading"in JSX are violations
2.2 Data Fetching Patterns
Skip categories that don't apply to the repo's stack.
- Server components should prefetch data efficiently — if a page.tsx makes multiple sequential
fetchQuerycalls that could be combined into a single API endpoint, flag it as a waterfall - Client-side request waterfalls: if a client component fetches data A, then uses the result to fetch data B, C, D in sequence (or in a loop), and these could be served by a single endpoint, flag it. The pattern to watch for: one
useQuerywhose result feeds into anotheruseQuery, or a component that maps over query results and fires individual fetches per item. These should be consolidated server-side into one endpoint that returns everything the page needs. - Client components should use the query pattern documented in the repo's CLAUDE.md (e.g.,
useSuspenseQuerywith query option functions, not custom hooks wrappinguseQuery) useQuery(non-suspense) is acceptable only in conditional/optional contexts with anenabledguard — and the component must handle theundefineddata state- Never use raw
fetch()if the repo has API helpers — use the documented pattern (e.g.,api.GET()with Zod schema validation) - Check that query keys are consistent — if two components fetch the same data, they should use the same query key so the cache is shared
2.3 API Route Conventions
Skip if the changed files don't include API routes.
- Authentication: use the auth pattern documented in the CLAUDE.md (e.g.,
authenticate()for org-scoped,authenticateEnvironmentDualAuth()for environment-scoped) - Authorization scope: every query that returns user data must include an
orgIdfilter. If an endpoint authenticates the user but queries a resource only by its own ID (e.g.,WHERE environment_id = XwithoutAND org_id = Y), any user who knows the resource ID can access another org's data. This is a blocker-level security issue. - Request validation: request bodies must be validated with Zod schemas, not trusted blindly
- Response format: use the repo's standard response helpers, not raw
ResponseorNextResponse.json() - Error handling: wrap in try/catch with the standard error handler
- Response shapes must match their Zod schemas — if a schema requires a field (not
.optional()), every code path must include it. Check early returns and error fallbacks especially. - Response scope: an endpoint should return data relevant to its domain. If a use-cases endpoint returns
hasEvents(an SDK integration concern), or an analytics endpoint returns user profile data, flag it as a leaky abstraction — the consuming frontend will couple to unrelated concerns.
2.4 Database & Query Patterns
Skip if the changed files don't include database queries or API routes.
- N+1 queries: if a function fetches a list of items and then calls another query inside a loop (e.g.,
for (const item of items) { await fetchDetails(item.id) }), this is an N+1 pattern. The inner query should be batched — fetch all details in one query usingWHERE id IN (...)or similar, then map results in memory. This is a blocker when the outer list can grow beyond a handful of items. - Raw SQL as a code smell: if Drizzle's query builder is insufficient and you're using
sqltemplate literals,sql.join, orsql.rawto build queries, consider whether the data model fits the access pattern. Occasional raw SQL for JSONB operators or aggregations is fine. But if simple CRUD operations need raw SQL (e.g.,WHERE config_id IN (sql.join(...))instead of a simpleWHERE environment_id = X), the schema likely needs restructuring. Flag these and explain why the query builder doesn't work naturally. - Unnecessary joins: if every query on table A requires joining through table B just to filter by a column that logically belongs on A, the data model has unnecessary indirection. This is a warning — it may be intentional, but it should be called out for the reviewer.
- Missing indexes: if a query filters on a column that doesn't have an index (check the schema definition), flag it as a warning for any table expected to grow.
- Shared data fetched multiple times: if the same data (e.g., events for a date range) is fetched identically in multiple places within the same request lifecycle, it should be fetched once and shared. The classic sign is multiple functions accepting the same
(environmentId, flowId, dateRange)parameters and each making their own DB call. - Data model vs. access pattern mismatch: if the primary query pattern for a feature is "get all X for environment Y" but the schema forces a join through an intermediate table to reach X, the data model doesn't match the access pattern. Ask: could the filtering column live directly on the queried table? If the intermediate table only exists to hold a foreign key, it may be unnecessary indirection. This is a warning — raise it for the reviewer to evaluate.
2.5 Module Structure & Imports
- Verify imports follow the conventions documented in the CLAUDE.md — schemas, types, and query functions should live where the CLAUDE.md says they should
- Check for imports from paths that don't match the project's established structure (e.g., importing from an internal subdirectory when the parent module re-exports everything)
- Check for duplicate definitions — if a Zod schema or type already exists elsewhere, don't redefine it
2.6 Component Architecture
Skip categories that don't apply to the repo's stack.
- One component per file — if a file defines multiple exported components, they should be split
- Event handlers with business logic must be extracted to named functions, not inlined in
onClick - Loading states should use the pattern documented in the CLAUDE.md (e.g., Skeleton components, not spinners)
- Check that the repo's UI conventions are followed (layout patterns, empty states, confirmation dialogs)
2.7 Code Quality
- No reinventing existing helpers — before writing utility code, search the codebase for existing implementations. Date math, response formatting, auth checks, and common operations almost always have existing helpers.
- No deprecated patterns — if the codebase has moved away from a pattern (check git history and CLAUDE.md for guidance), new code must use the modern replacement
- Functions with 2+ parameters should use object input
{ field1, field2 }, not positional arguments (if the CLAUDE.md specifies this convention) - No temporal references in comments ("now", "previously", "was", "switched from") — comments describe current behavior, git handles history
- Code should be self-documenting — don't add comments explaining what code does unless the logic is genuinely non-obvious
- Naming coherence: when a feature introduces a domain concept (e.g., "use case", "flow config"), the naming should be consistent across the schema, API routes, query functions, frontend components, and URL paths. If the schema calls it
funnelsbut the UI says "use cases" and the API path is/analytics/funnel, flag the inconsistency — it creates cognitive overhead for every developer who touches the feature.
2.8 Styling & Design Consistency
Skip if the changed files don't include UI components.
- Colors and styling should use the design token system (CSS variables, Tailwind tokens), not hardcoded hex values. Exception: SVG charts or third-party library configurations where CSS variables can't be applied may use design token hex values.
- Follow the repo's documented UI patterns for page structure, spacing, and component usage
Layer 3: Code Review Pass
After completing Layer 1 and Layer 2, invoke the code-review:code-review skill on the same scope. This adds a broader second pass that catches issues outside the project-specific patterns above — logic bugs, git history context, and cross-cutting concerns.
code-review:code-review is Anthropic's official code-review skill — a separate plugin, not bundled with this skill. If it isn't installed, don't fail: report that Layer 3 was skipped because the code-review skill isn't available (Layers 1 and 2 still ran), and suggest installing the official code-review plugin to enable it.
Determine the right scope argument based on context:
- For uncommitted changes: "review the diff between HEAD and the current uncommitted changes in {repo}/"
- For a feature branch: "review the diff between main and HEAD in {repo}/"
- For a specific PR: "review PR #{number} on {owner}/{repo}"
Reporting
Present findings in this format:
## WaniWani Code Review Report — {repo}
### Layer 1: Automated Checks
- TypeScript: PASS / FAIL (N new errors)
- Lint: PASS / FAIL
- Unused code: PASS / FAIL (N unused exports)
- Translations: PASS / FAIL / N/A
- Type assertions: PASS / FAIL (N violations)
### Layer 2: Diff Analysis
[List issues grouped by severity]
BLOCKERS (must fix before review):
1. [file:line] Category — description
WARNINGS (should fix, reviewer will likely flag):
1. [file:line] Category — description
### Layer 3: Code Review
[Results from code-review:code-review skill]Growing This Skill
This skill is a living document. When a PR reviewer catches something that the skill should have caught, add it:
- If it's a deterministic check (can be linted/grepped), add it to Layer 1
- If it requires reading code and understanding context, add it to the appropriate Layer 2 category
- If it's a new category entirely, create a new
2.Nsection
The goal: every piece of PR feedback should only happen once. After that, this skill catches it automatically.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

