원클릭으로
fxa-review
// Thorough FXA-specific commit review using parallel specialist agents. Covers security, TypeScript, logic/bugs, test quality, and architecture. Agents explore call sites, git history, and monorepo conventions.
// Thorough FXA-specific commit review using parallel specialist agents. Covers security, TypeScript, logic/bugs, test quality, and architecture. Agents explore call sites, git history, and monorepo conventions.
Lists open FXA PRs matching a search term with a rich status table — file/line counts, draft state, review activity, and approval status. Defaults to all open PRs needing review.
Approves the on-hold "Approve Functional Tests (PR)" CircleCI job for the current PR branch, kicking off the gated Playwright functional tests. Requires CIRCLECI_TOKEN in the environment.
Reviews changed React/TSX code for component design, hooks misuse, performance, accessibility, and state management issues. Reports findings with severity and concrete fix recommendations. Operates on files changed vs main.
Fast single-pass FXA-specific commit review covering security, conventions, logic/bugs, tests, and migrations. No subagents — runs directly in the main context.
Drafts Jest tests for changed code. Defaults to staged/unstaged changes or the most recent commit. Output is a starting point for review, not final.
Validates that Jest tests in a given file pass both as a full suite and individually in isolation, catching hidden order dependencies and shared mutable state.
| name | fxa-review |
| description | Thorough FXA-specific commit review using parallel specialist agents. Covers security, TypeScript, logic/bugs, test quality, and architecture. Agents explore call sites, git history, and monorepo conventions. |
| allowed-tools | Bash, Read, Grep, Glob, Agent |
| argument-hint | ["commit-ref"] |
| user-invocable | true |
| context | fork |
Review the most recent commit (or the commit specified in $ARGUMENTS) using specialized parallel agents.
COMMIT_REF="${ARGUMENTS:-HEAD}"
git show "$COMMIT_REF" --format="%H%n%an%n%ae%n%s%n%b"
COMMIT_REF="${ARGUMENTS:-HEAD}"
git show --stat "$COMMIT_REF"
Save the full diff output and commit metadata. You will pass these to each agent in Step 2.
Launch ALL FIVE agents in parallel using the Agent tool in a single message. Each agent receives the full diff and commit metadata in its prompt.
Tell each agent to use Read/Grep/Glob to examine surrounding code in changed files for context. Provide the repo working directory path.
Each agent MUST output findings as a JSON array ONLY (no markdown, no extra text). Each item has: severity (CRITICAL/HIGH/MEDIUM/LOW), category, subcategory, file, line, issue, recommendation. If no issues, return: []
Agent 1 — FXA Security Review
Tell this agent it is a senior security engineer. It should:
* on credentialed endpointsgetRegisteredClientIds() or getClientServiceTags(request)). Free-form strings as tags allow attackers to blow up Prometheus storage.Output JSON array with fields: severity, category ("Security"), subcategory, file, line, issue, recommendation.
Agent 2 — FXA TypeScript Review
Tell this agent it is a senior TypeScript engineer familiar with FXA's mixed JS/TS codebase. It should:
any usage — suggest unknown, interfaces, or generics instead. Note: any is permitted in auth-server during migration but should not be introduced in new code unnecessarily! postfix) — @typescript-eslint/no-non-null-assertion: erroras any is justified — needed for CJS/ESM interop or type system limitations, not hiding real type issuessatisfies against real interfaces where possible@fxa/<domain>/<package> for cross-package, relative within packagerequire() in .ts files — use import instead. Existing CJS patterns in auth-server .js files are fine.async/await over .then() promise chains.js files: review general code patterns, no TypeScript-specific feedbackOutput JSON array with fields: severity, category ("TypeScript"), subcategory, file, line, issue, recommendation, code_before, code_after.
Agent 3 — FXA Logic and Bugs Review
Tell this agent it is a senior software engineer who knows FXA's auth-server patterns deeply. It should:
await, unhandled promise rejections, race conditions — note: some fire-and-forget patterns (metrics, logging) are intentional, check contextAppError usage — HTTP errors must use AppError from @fxa/accounts/errorslog object (mozlog format), not console.logContainer.get()/Container.set() usage — linting rules to disallow these are comingconfig.get('key') keys exist in config/index.tsOutput JSON array with fields: severity, category ("Logic/Bugs"), subcategory, file, line, issue, recommendation.
Agent 4 — FXA Test Quality Review
Tell this agent it is a QA engineer who understands FXA's testing patterns and common flakiness causes. Tell it to read .claude/skills/fxa-testing-shared/GUIDELINES.md before reviewing — that file is the authoritative rule set; the bullets below are the FXA-specific triggers to apply on top of it.
*.spec.ts; fxa-settings uses *.test.tsx conventionproxyquire in new code — should use jest.mock()X, assertion checks for X, no real logic in between).toHaveBeenCalledWith() on mocked dependencies, not just checking return valuesjest.clearAllMocks() in beforeEach only when the package's jest.config.* sets clearMocks: true (currently fxa-auth-server and fxa-profile-server). In other packages it is required to reset mock state between tests — do not recommend removing it without verifying the project config.mockClear/mockReset/jest.clearAllMocks/jest.resetAllMocks calls inside an it() body — these are usually band-aids covering up state leaking from prior tests or shared setup; the fix is proper isolation, not inline clearingawait, setTimeout in testsjest.useFakeTimers() and jest.setSystemTime() over setTimeout or mocking Date.now directlyit('...', async () => {...}, 30_000), jest.setTimeout(30_000) for a single file) — usually masks a real timer or unmocked I/O dependencyact() wrapping in React test state updatesconst mockFoo = { bar: jest.fn() }) where the real interface could be used — typed mocks (jest.Mocked<T>) catch contract drift on the unit under testexpect.anything(), expect.any(Object), broad expect.objectContaining({}) with one trivial key. expect.any(<Type>) is fine for genuinely non-deterministic fields (timestamps, random IDs)forEach / for loops with expect calls inside a single it() body — use it.each so each case is named and independently reportedit.only, describe.only, fit, fdescribe (silently skips the rest of the suite — CRITICAL/HIGH if it lands in CI). For it.skip, xit, xdescribe, it.todo: only flag when there is no adjacent comment explaining the skip — a justified skip with a Jira/issue reference is acceptable per the guidelines*.test.tsx files in fxa-settings and other React packages: also apply the React testing patterns in .claude/skills/fxa-check-react/SKILL.md Section 5 (queries by role, userEvent over fireEvent, no asserting on instances/refs, snapshot scope)..claude/skills/fxa-testing-shared/GUIDELINES.md.Output JSON array with fields: severity, category ("Test Quality"), subcategory, file, line, issue, recommendation.
Agent 5 — FXA Architecture Review
Tell this agent it is a senior architect who knows FXA's monorepo structure and migration directions. It should:
libs/* or fxa-shared instead of app-local — search the monorepo for existing helpers before flagging. Note: fxa-shared is migrating to libs/, check both locations.libs/**, fxa-shared/**, and packages/** for functions/types with the same name or purposefxa-content-server — should be in fxa-settingsfxa-graphql-api was removed, admin-server GraphQL is legacy. Exception: CMS-related GraphQL./fxa-shared/test/db/models/**/*.sql)@fxa/* aliases/check-smells skill (.claude/skills/check-smells/SKILL.md) — read that file and incorporate its design, implementation, test, and dependency smell checks into this reviewMigration direction compliance:
proxyquire → jest.mock()async/awaitfxa-shared → libs/* (in progress)Output JSON array with fields: severity, category ("Architecture"), subcategory, file, line, issue, recommendation.
After all agents return, parse each JSON output. Combine all findings into one list sorted by severity: CRITICAL then HIGH then MEDIUM then LOW. Number sequentially. If an agent returns malformed output, extract what you can and note the issue.
Deduplicate issues flagged by multiple agents (keep the more detailed one, note which reviewers flagged it).
Present the unified report:
Commit Review Summary — commit hash, author, message, files changed count.
Changes Overview — write your own summary of what the commit does from the diff (do not repeat the commit message).
AI Slop Check — flag overly verbose comments, unnecessary abstractions, excessive error handling for impossible cases, redundant validation, or other signs of auto-generated code.
Issues Found — markdown table with columns: #, Severity, Reviewer, Category, File, Line, Issue, Recommendation.
Severity definitions:
Detailed Findings by Reviewer — one subsection per reviewer (Security, TypeScript, Logic/Bugs, Test Quality, Architecture). Include code before/after examples for HIGH+ issues. If a reviewer found nothing, say "No issues found."
Verdict — APPROVE, REQUEST CHANGES, or NEEDS DISCUSSION. Include blocking issue count (CRITICAL + HIGH), total issue count, and which reviewers reported issues. If all agents returned empty arrays: "All specialist reviewers agree — this commit is ready to merge."