From 93d3c09671a46e892efbd237910e198542d4b808 Mon Sep 17 00:00:00 2001 From: Marty Pradere Date: Mon, 23 Feb 2026 05:27:16 -0800 Subject: [PATCH] frontend skills --- .agents/review-checklists/common.md | 20 + .../review-checklists/jest/business-logic.md | 58 +++ .../review-checklists/jest/code-quality.md | 208 ++++++++ .agents/review-checklists/jest/performance.md | 105 ++++ .../review-checklists/react/business-logic.md | 248 ++++++++++ .../review-checklists/react/code-quality.md | 462 ++++++++++++++++++ .../review-checklists/react/performance.md | 144 ++++++ .claude/skills/code-review-jest/skill.md | 123 +++++ .claude/skills/code-review-react/skill.md | 123 +++++ 9 files changed, 1491 insertions(+) create mode 100644 .agents/review-checklists/common.md create mode 100644 .agents/review-checklists/jest/business-logic.md create mode 100644 .agents/review-checklists/jest/code-quality.md create mode 100644 .agents/review-checklists/jest/performance.md create mode 100644 .agents/review-checklists/react/business-logic.md create mode 100644 .agents/review-checklists/react/code-quality.md create mode 100644 .agents/review-checklists/react/performance.md create mode 100644 .claude/skills/code-review-jest/skill.md create mode 100644 .claude/skills/code-review-react/skill.md diff --git a/.agents/review-checklists/common.md b/.agents/review-checklists/common.md new file mode 100644 index 0000000000..abb6b84237 --- /dev/null +++ b/.agents/review-checklists/common.md @@ -0,0 +1,20 @@ +# Common Review Guidelines + +## Reviewer Priority + +Agents must prioritize findings in this order and report them in this order when multiple issues are present: + +1. **Correctness** (behavioral bugs, warnings, broken contracts, stale state, invalid keys) +2. **Maintainability** (dead code, duplication, unnecessary complexity, high-review-cost risks) +3. **Style** (formatting/convention consistency that does not change behavior) + +Do not prioritize Style-only findings ahead of unresolved Correctness or Maintainability findings. + +## Standard Review Format + +For every rule below, agents should provide: + +1. **Evidence**: exact code snippet or file/line reference from the changed code +2. **Category**: the rule's listed primary category (Correctness, Maintainability, or Style) +3. **Confidence**: apply the rule's confidence threshold before escalating severity in review feedback +4. **Exceptions**: check the rule's false-positive section before flagging \ No newline at end of file diff --git a/.agents/review-checklists/jest/business-logic.md b/.agents/review-checklists/jest/business-logic.md new file mode 100644 index 0000000000..0759dabf17 --- /dev/null +++ b/.agents/review-checklists/jest/business-logic.md @@ -0,0 +1,58 @@ +# Business Logic + +> **Prerequisite:** Review and apply the common guidelines in [`common.md`](../common.md) before using this checklist. + +## Jest tests must assert on meaningful outcomes + +**Urgency:** urgent + +### Category + +Correctness + +### Confidence Threshold + +Flag as a high-severity finding when the test would still pass after removing the feature logic, or when assertions only validate setup/static existence. If the test is intentionally a smoke/no-crash render test, require that intent to be explicit in the test name. + +### Exceptions / False Positives + +- Allow explicit smoke tests when the purpose is only to verify the component/function does not throw on render or initialization. +- Do not flag helper tests that intentionally validate test utilities/builders rather than product behavior, if the subject under test is the utility itself. +- A simple existence assertion can be acceptable when the behavior under review is conditional presence/absence itself (for example, permission-gated rendering). + +### Detection heuristic + +Look for tests where all assertions target mock setup data, static strings, or DOM existence rather than computed/rendered output. + +## Rules + +1. **Assert on component output, not existence.** After `render()`, assert on visible text, element states, or DOM changes that result from the props/state you set up — never just `expect(container).toBeDefined()` or `expect(document.querySelector('.x')).not.toBeNull()`. + +2. **Assert on computed results, not test inputs.** If you pass `mockData` into a component, don't assert that `mockData` has the values you just wrote. Assert on what the component *did* with that data. + +3. **Every test must fail if the feature is removed.** Apply this litmus test: if you deleted the implementation code for the feature under test, would the test still pass? If yes, the test is worthless — rewrite it. + +4. **Interact before asserting (when applicable).** If testing behavior triggered by user action (click, submit, input), simulate that action with `fireEvent` or `userEvent`, then assert on the resulting DOM or state change. + +## Examples + +```js +// ❌ BAD — asserts on render existence +render(); +expect(document.querySelector('.form-container')).not.toBeNull(); + +// ✅ GOOD — asserts on behavioral outcome of props +render(); +expect(screen.getByRole('button', { name: /submit/i })).toBeDisabled(); + +// ❌ BAD — asserts on mock input +const data = [{ name: 'Alpha', value: 10 }]; +render(); +expect(data[0].name).toBe('Alpha'); // This tests your test, not your code + +// ✅ GOOD — asserts on rendered output from that input +const data = [{ name: 'Alpha', value: 10 }]; +render(
); +expect(screen.getByText('Alpha')).toBeInTheDocument(); +expect(screen.getByText('10')).toBeInTheDocument(); +``` diff --git a/.agents/review-checklists/jest/code-quality.md b/.agents/review-checklists/jest/code-quality.md new file mode 100644 index 0000000000..bd6bee4574 --- /dev/null +++ b/.agents/review-checklists/jest/code-quality.md @@ -0,0 +1,208 @@ +# Code Quality + +> **Prerequisite:** Review and apply the common guidelines in [`common.md`](../common.md) before using this checklist. + +## Arrange / Act / Assert (AAA) structure + +**Urgency:** suggestion + +### Category + +Style + +### Confidence Threshold + +Flag only when the test is long enough or complex enough that structure affects readability (for example, multi-step setup/interactions or >10 lines). For short, self-evident tests, prefer a suggestion or no comment. + +### Exceptions / False Positives + +- Do not flag short tests (roughly 3-5 lines) where Arrange/Act/Assert is obvious without comments. +- Do not require AAA comments in parameterized tests when added comments make the test harder to scan than the code itself. +- Prefer suggestions over high-severity findings unless the repository explicitly enforces AAA comment structure in tests. + +### Rules + +1. **Each section must be preceded by a comment** — `// Arrange`, `// Act`, and `// Assert`. +2. **The Assert comment must include a brief explanation** of how the described scenario is being verified. The explanation should summarize what the assertions prove about the behavior stated in the test name. + - Good: `// Assert - textarea shows hash subjects, participantId query param is ignored` + - Good: `// Assert - ID Search button is active` + - Bad: `// Assert` (missing explanation) + - Bad: `// Assert - check results` (too vague; does not connect to the scenario) +3. **Arrange may be omitted** when there is no setup beyond what `beforeEach` already provides, but Act and Assert are always required. +4. **Combined `// Act & Assert` is acceptable** only when the assertion must be wrapped inside a `waitFor` that is inseparable from the action (e.g., awaiting an async side-effect). In that case the comment must still include an explanation: + - Good: `// Act & Assert - empty state message is shown and error was logged to console` + - Bad: `// Act & Assert` +5. **Multiple Act/Assert cycles in one test are allowed** for stateful interaction flows (e.g., click then verify, click again then verify). Each cycle must carry its own `// Act` and `// Assert - ...` comments. + +--- + +## No unused variables, imports, or mocks + +**Urgency:** urgent + +### Category + +Maintainability + +### Confidence Threshold + +Flag when the symbol is clearly unused in the file or when a mock setup is not consumed by behavior under test. If a mock or import may be used implicitly (module mocking side effects, global setup conventions), verify before commenting. + +### Exceptions / False Positives + +- Do not flag side-effect imports (for example, polyfills or test environment setup) just because no identifier is referenced. +- Do not flag module-level `jest.mock(...)` declarations that intentionally replace imports used elsewhere in the file. +- If a placeholder parameter is required for function signature/position, allow underscore-prefixed names (for example, `_arg`). + +### Rules + +1. **Unused imports must be removed.** If a symbol is imported but never referenced in the file, delete the import. This includes named imports, default imports, and type-only imports. +2. **Unused variables and constants must be removed.** If a `const`, `let`, or destructured binding is declared but never read, delete it. This applies to top-level declarations, inside `describe`/`beforeEach`/`test` blocks, and helper functions. +3. **Unused mock declarations must be removed.** If `jest.fn()`, `jest.mock()`, `jest.spyOn()`, or a manual mock variable is set up but never referenced in an assertion or as a dependency, delete it. Mocks that are called implicitly (e.g., module-level `jest.mock('...')` that replaces an import used elsewhere) are considered used. +4. **Unused mock return values must be removed.** If a mock is configured with `.mockReturnValue()`, `.mockResolvedValue()`, or `.mockImplementation()` but the return value is never consumed or asserted on, simplify or remove the configuration. +5. **Unused helper functions and factory functions must be removed.** If a test utility, builder, or factory function defined in the file is never called, delete it. +6. **Unused parameters in callbacks must be prefixed with `_`.** If a callback parameter (e.g., in `.mockImplementation((unusedArg) => ...)`) is required for positional reasons but not used, prefix it with `_` to signal intent (e.g., `_unusedArg`). +7. **Unused `render` results must not be destructured.** If `render()` is called and the return value is not used, do not destructure it. Write `render();` instead of `const { container } = render();` when `container` is never referenced. + +### Examples + +```tsx +// ---- Unused imports ---- + +// ❌ BAD — ApiResponse is imported but never used +import { render, screen } from '@testing-library/react'; +import { ApiResponse, UserProfile } from '../models'; + +const mockProfile: UserProfile = { name: 'Test' }; + +// ✅ GOOD — only referenced imports remain +import { render, screen } from '@testing-library/react'; +import { UserProfile } from '../models'; + +const mockProfile: UserProfile = { name: 'Test' }; + + +// ---- Unused variables ---- + +// ❌ BAD — mockHandler is declared but never used +const mockHandler = jest.fn(); +const mockCallback = jest.fn(); + +test('calls callback on click', () => { + render(; + + return
{item.name}
{items.map(item => )}
; +}; +``` + +### Suggested Fix + +Move the inner component to module scope: + +```tsx +// ✅ Stable component identity — React can reconcile correctly +const InnerRow: FC<{ item: Item }> = ({ item }) => {item.name}; + +const ParentComponent: FC = () => { + return {items.map(item => )}
; +}; +``` \ No newline at end of file diff --git a/.claude/skills/code-review-jest/skill.md b/.claude/skills/code-review-jest/skill.md new file mode 100644 index 0000000000..568eb90ca0 --- /dev/null +++ b/.claude/skills/code-review-jest/skill.md @@ -0,0 +1,123 @@ +--- +name: code-review-jest +description: "Trigger when the user requests a review of Jest test files (e.g., `.test.tsx`, `.spec.tsx`). Supports --full flag for complete file/directory review; defaults to staged changes when a path is provided." +--- + +# Jest Test Code Review + +## Intent +Use this skill whenever the user asks to review Jest test code (especially `.test.tsx`, `.spec.tsx`, `.test.ts`, or `.spec.ts` files). Support three review modes: + +1. **Pending-change review** – bare invocation with no arguments; inspects staged/working-tree + files slated for commit across all repos. +2. **Path review (default)** – a file or directory path is provided (no flag); reviews only the + git staged/working-tree changes for that path. +3. **Full review** – a file or directory path is provided with `--full`; reviews the entire file + contents (or all matching files in a directory) regardless of git status. + +Stick to the checklist below for every applicable file and mode. Apply only the Jest checklist rules to test files — do not apply React component rules to component code that happens to be visible via imports in the test file. + +## Checklist +See [.agents/review-checklists/common.md](../../../.agents/review-checklists/common.md) for reviewer priority and standard review format, and [.agents/review-checklists/jest/code-quality.md](../../../.agents/review-checklists/jest/code-quality.md), [.agents/review-checklists/jest/performance.md](../../../.agents/review-checklists/jest/performance.md), [.agents/review-checklists/jest/business-logic.md](../../../.agents/review-checklists/jest/business-logic.md) for the living checklist split by category—treat it as the canonical set of rules to follow. + +Use the rule's `Urgency` to place findings in the "urgent issues" vs "suggestions" sections. + +## Review Process + +**Argument parsing:** + +Parse the invocation arguments to extract: +- An optional flag: `--full` +- An optional path: a file path or directory path + +**File discovery:** + +- **No path, no flag (bare invocation):** Pending-change review. Discover nested repos by + running `find server/modules -maxdepth 2 -name ".git" -type d` from the workspace root, + then for each discovered repo (and the top-level root) run `git diff --cached --name-only` + and `git diff --name-only`. Aggregate all results, filtering to test file extensions + (`.test.tsx`, `.spec.tsx`, `.test.ts`, `.spec.ts`). + +- **Path provided (no `--full` flag — default):** Determine the git root via + `git -C rev-parse --show-toplevel`. + - *File path:* Run `git diff --cached -- ` and `git diff -- `. If there are + no changes, report "No staged or working-tree changes found for ``." and stop. + If there are changes, proceed to review. + - *Directory path:* Run `git diff --cached --name-only -- ` and + `git diff --name-only -- `. Filter to test file extensions. If no changed files + are found, report "No staged or working-tree changes found under ``." and stop. + +- **Path + `--full`:** Review the entire contents regardless of git status. + - *File path:* Use the file directly — no git discovery needed. + - *Directory path:* Find all files matching test file extensions under the directory + (using glob/find). Review every matching file. + +- **`--full` with no path:** Ask the user to provide a file or directory path. + +**Review scope when reviewing staged changes (default mode):** + +When reviewing staged changes, read the full file for context but **focus the review on changed +lines and their immediate surroundings**. Use the diff output to identify which sections +changed, then apply the checklist rules primarily to those sections. Still flag issues in +unchanged code only if they directly interact with or are affected by the changes. + +**Multi-file grouping:** When reviewing multiple files, group all findings together by urgency section (urgent issues first, then suggestions), not per-file. Include the file path in each finding's `FilePath` field. + +1. Open the relevant test file(s). Gather all lines. +2. For each applicable checklist rule, evaluate the code against the rule text, confidence threshold, and exceptions/false positives before deciding to flag it. +3. For each confirmed violation, capture evidence (exact snippet and/or file/line), record the rule's primary category, and note confidence briefly. +4. Compose the review section per the template below. Group findings by **Urgency** section first (urgent issues, then suggestions). Within each section, order findings by the checklist primary category priority: **Correctness**, then **Maintainability**, then **Style**. + +## Required output +When invoked, the response must exactly follow one of the two templates: + +### Template A (any findings) +``` +# Code review +Found urgent issues that need to be fixed: + +## 1 +FilePath: line +Evidence: +Category: +Confidence: - +Exceptions checked: + + +### Suggested fix + + +--- +... (repeat for each urgent issue) ... + +Found suggestions for improvement: + +## 1 +FilePath: line +Evidence: +Category: +Confidence: - +Exceptions checked: + + +### Suggested fix + + +--- + +... (repeat for each suggestion) ... +``` + +If there are no urgent issues, omit that section. If there are no suggestions, omit that section. + +Always list every urgent issue — never cap or truncate them. If there are more than 10 suggestions, summarize as "10+ suggestions" and output the first 10. + +Don't compress the blank lines between sections; keep them as-is for readability. + +If you use Template A (i.e., there are issues to fix) and at least one issue requires code changes, append a brief follow-up question after the structured output asking whether the user wants you to apply the suggested fix(es). For example: "Would you like me to apply the suggested fixes?" + +### Template B (no issues) +``` +# Code review +No issues found. +``` diff --git a/.claude/skills/code-review-react/skill.md b/.claude/skills/code-review-react/skill.md new file mode 100644 index 0000000000..3cb2a78a6f --- /dev/null +++ b/.claude/skills/code-review-react/skill.md @@ -0,0 +1,123 @@ +--- +name: code-review-react +description: "Trigger when the user requests a review of frontend files (e.g., `.tsx`, `.ts`, `.js`). Excludes test files. Supports --full flag for complete file/directory review; defaults to staged changes when a path is provided." +--- + +# Frontend Code Review + +## Intent +Use this skill whenever the user asks to review frontend code (especially `.tsx`, `.ts`, `.scss`, `.css` or `.js` files). **Exclude test files** with extensions `.test.tsx`, `.test.ts`, `.spec.tsx`, or `.spec.ts` — those should be reviewed using the `code-review-jest` skill instead. Support three review modes: + +1. **Pending-change review** – bare invocation with no arguments; inspects staged/working-tree + files slated for commit across all repos. +2. **Path review (default)** – a file or directory path is provided (no flag); reviews only the + git staged/working-tree changes for that path. +3. **Full review** – a file or directory path is provided with `--full`; reviews the entire file + contents (or all matching files in a directory) regardless of git status. + +Stick to the checklist below for every applicable file and mode. Apply only the React/frontend checklist rules — do not apply Jest test rules to test code that may be co-located or visible in the same file. + +## Checklist +See [.agents/review-checklists/common.md](../../../.agents/review-checklists/common.md) for reviewer priority and standard review format, and [.agents/review-checklists/react/code-quality.md](../../../.agents/review-checklists/react/code-quality.md), [.agents/review-checklists/react/performance.md](../../../.agents/review-checklists/react/performance.md), [.agents/review-checklists/react/business-logic.md](../../../.agents/review-checklists/react/business-logic.md) for the living checklist split by category—treat it as the canonical set of rules to follow. + +Use the rule's `Urgency` to place findings in the "urgent issues" vs "suggestions" sections. + +## Review Process + +**Argument parsing:** + +Parse the invocation arguments to extract: +- An optional flag: `--full` +- An optional path: a file path or directory path + +**File discovery:** + +- **No path, no flag (bare invocation):** Pending-change review. Discover nested repos by + running `find server/modules -maxdepth 2 -name ".git" -type d` from the workspace root, + then for each discovered repo (and the top-level root) run `git diff --cached --name-only` + and `git diff --name-only`. Aggregate all results, filtering to applicable frontend + extensions (`.tsx`, `.ts`, `.js`, `.scss`, `.css`) and excluding test files. + +- **Path provided (no `--full` flag — default):** Determine the git root via + `git -C rev-parse --show-toplevel`. + - *File path:* Run `git diff --cached -- ` and `git diff -- `. If there are + no changes, report "No staged or working-tree changes found for ``." and stop. + If there are changes, proceed to review. + - *Directory path:* Run `git diff --cached --name-only -- ` and + `git diff --name-only -- `. Filter to applicable extensions. If no changed files + are found, report "No staged or working-tree changes found under ``." and stop. + +- **Path + `--full`:** Review the entire contents regardless of git status. + - *File path:* Use the file directly — no git discovery needed. + - *Directory path:* Find all files matching applicable extensions under the directory + (using glob/find). Review every matching file. + +- **`--full` with no path:** Ask the user to provide a file or directory path. + +**Review scope when reviewing staged changes (default mode):** + +When reviewing staged changes, read the full file for context but **focus the review on changed +lines and their immediate surroundings**. Use the diff output to identify which sections +changed, then apply the checklist rules primarily to those sections. Still flag issues in +unchanged code only if they directly interact with or are affected by the changes. + +**Multi-file grouping:** When reviewing multiple files, group all findings together by urgency section (urgent issues first, then suggestions), not per-file. Include the file path in each finding's `FilePath` field. + +1. Open the relevant component/module. Gather all lines. +2. For each applicable checklist rule, evaluate the code against the rule text, confidence threshold, and exceptions/false positives before deciding to flag it. +3. For each confirmed violation, capture evidence (exact snippet and/or file/line), record the rule's primary category, and note confidence briefly. +4. Compose the review section per the template below. Group findings by **Urgency** section first (urgent issues, then suggestions). Within each section, order findings by the checklist primary category priority: **Correctness**, then **Maintainability**, then **Style**. + +## Required output +When invoked, the response must exactly follow one of the two templates: + +### Template A (any findings) +``` +# Code review +Found urgent issues that need to be fixed: + +## 1 +FilePath: line +Evidence: +Category: +Confidence: - +Exceptions checked: + + +### Suggested fix + + +--- +... (repeat for each urgent issue) ... + +Found suggestions for improvement: + +## 1 +FilePath: line +Evidence: +Category: +Confidence: - +Exceptions checked: + + +### Suggested fix + + +--- + +... (repeat for each suggestion) ... +``` + +If there are no urgent issues, omit that section. If there are no suggestions, omit that section. + +Always list every urgent issue — never cap or truncate them. If there are more than 10 suggestions, summarize as "10+ suggestions" and output the first 10. + +Don't compress the blank lines between sections; keep them as-is for readability. + +If you use Template A (i.e., there are issues to fix) and at least one issue requires code changes, append a brief follow-up question after the structured output asking whether the user wants you to apply the suggested fix(es). For example: "Would you like me to apply the suggested fixes?" + +### Template B (no issues) +``` +# Code review +No issues found. +```