Skip to content

Latest commit

 

History

History
315 lines (255 loc) · 19.2 KB

File metadata and controls

315 lines (255 loc) · 19.2 KB

AGENTS.md — Front-End Checklist

Repository rules and conventions for contributors and automation tools.

Project Overview

Front-End Checklist is an open-source monorepo providing 385 quality-gated frontend best practice rules with an MCP server for structured review workflows.

  • MCP Server: https://mcp.frontendchecklist.io (11 tools)
  • Rules: packages/content/rules/en/<category>/<slug>.mdx
  • Web App: apps/web/ (Next.js App Router)
  • MCP Package: packages/mcp/ (TypeScript)
  • Package Manager: pnpm (workspaces + Turborepo)

MCP Usage

When working on frontend implementation, review, debugging, or audit tasks, use the Front-End Checklist MCP server when available so recommendations stay grounded in the project rule corpus.

  • Use review_code first for pasted or inspected HTML, CSS, JavaScript, TypeScript, React, or Next.js code.
  • Use search_rules before making accessibility, performance, SEO, security, image, privacy, i18n, or testing recommendations.
  • Use get_rule, check_rule, fix_rule, or explain_rule for rule-specific guidance and remediation.
  • Use get_workflow or get_checklist_rules for broad launch, accessibility, SEO, security, performance, and testing audits.
  • Use audit_url for public https:// pages.

Some clients lazy-load installed MCP tools. If the tools are not initially visible, search for or explicitly request the Front-End Checklist MCP before proceeding with frontend work.

Monorepo Structure

apps/
  web/                    # Next.js app (App Router)
packages/
  mcp/                    # MCP server implementation
  content/                # Rules MDX content + content-collections config
  auth/                   # Better-Auth + Prisma + Supabase
  design-system/          # Shared UI components
  types/                  # Shared TypeScript types
  data-layer/             # Data access layer
  schemas/                # Zod v4 schemas

Rule MDX Frontmatter Spec

Rules live at packages/content/rules/en/<category>/<slug>.mdx.

Required Fields

---
title: "Human-readable rule title (string, use quotes)"
description: "One-sentence description of what to do"
categories: ['html']           # Array; first item = primaryCategory
priority: 'high'               # 'critical' | 'high' | 'medium' | 'low'
difficulty: 'beginner'         # 'beginner' | 'intermediate' | 'advanced' | 'expert'
estimatedTime: 15              # Minutes as integer
prompts:
  check: "Prompt for checking whether the implementation follows this rule"
  fix: "Prompt for fixing the issue"
  explain: "Prompt for explaining why this rule matters"
---

Recommended Fields

These fields are not required by the parser, but they materially improve rule quality, MCP usefulness, and generated skills.

subcategory: 'keyboard'        # Sub-grouping within category
tldr:                          # Array of bullet points (used in llms.txt)
  - "Key point one"
  - "Key point two"
whyItMatters: "Paragraph explaining the business/user impact"
sources:
  - title: "MDN or spec page title"
    url: "https://..."
    type: "mdn|spec|guide|wcag|google"
    id: "stable-source-id"
    role: "standard|reference|implementation|compatibility|regulation|search|research"
    authority: "primary|secondary"
resources:
  - name: "Supplementary tool or article"
    url: "https://..."
    type: "tool|article|reference"
relatedRules:
  - slug: other-rule-slug
    reason: "Why these rules relate"
tools:
  - name: "Tool Name"
    url: "https://..."         # or null
tags: ['wcag', 'performance']
prompts:
  codeReview: "Recommended prompt for systematic code review context"
aiContext: "Additional context for automated review about when this rule applies"

Authoring placement rules:

  • Put authoritative citations in sources, not in body prose like Reference: ...
  • sources are proof metadata, not generic further reading. Every rule needs at least 2 sources, 2 source roles, and 1 authority: primary.
  • resources are for further reading or tools only. Do not map evidence claims to resources.
  • The system may infer or normalize id, role, and authority for sources at build time; authors should focus on strong, relevant sources rather than maintaining claim-by-claim proof objects.
  • Put cross-rule navigation in relatedRules, not in body prose like See also ...
  • Keep intro paragraphs focused on the rule itself; metadata should render from frontmatter-driven UI

Inline link contract:

  • Natural inline links inside body prose are allowed when they support a specific claim, comparison, or implementation recommendation.
  • Prefer light-touch density: usually 2-5 inline links per rule, with 0-1 in the intro and 1-3 across the main guidance sections.
  • Prefer external links over internal ones; internal rule links should usually stay at 0-1, with 2 only for unusually interconnected rules.
  • Keep standalone metadata lines out of the body. Do not add paragraphs that start with See also ... or Reference: ....
  • Keep evergreen proof in sources, and use newer inline external articles only when they add practical or recent context that the primary sources do not cover alone.
  • When a named tool is mentioned in prose for the first meaningful time (for example Screaming Frog or Google Search Console), link that first mention if the tool materially helps the reader and already exists in resources or tools.
  • Approved secondary inline links should stay curated. Prefer strong platforms such as CSS-Tricks, Smashing Magazine, Nielsen Norman Group, WebAIM, Screaming Frog, Sitebulb, Moz, or Yoast when they add practical implementation context.
  • Use descriptive anchor text tied to the sentence claim, not generic labels like “read more”.

impact, standards, and automation are intentionally not part of the active rule-writing contract right now. The current corpus and tooling do not consume them consistently enough to justify treating them as standard authoring fields.

Canonical Rule Shape

New and refreshed rules should follow this structure unless there is a strong reason not to:

  1. Short intro paragraph explaining the rule in plain language
  2. ## Code Example or ## Code Examples
  3. ## Why It Matters
  4. Optional implementation or guidance sections
  5. ## Verification

Canonical ordering rules:

  • ## Code Example or ## Code Examples must appear before ## Why It Matters
  • ## Why It Matters must appear before ## Verification
  • ## Verification must be the final H2 in the rule body
  • Optional H2 sections belong between ## Why It Matters and ## Verification

Preferred optional H2 taxonomy:

  • ## Best Practices
  • ## Common Mistakes
  • ## Framework Examples
  • ## Tools & Validation
  • ## Thresholds
  • ## Exceptions
  • ## Browser Support
  • ## Support Notes
  • ## Standards
  • ## Implementation Notes

The validator reports headings outside this preferred taxonomy so section sprawl stays visible over time.

Rule Contract V2 adds three conditional concepts:

  • ## Exceptions for nuanced rules, false positives, or valid caveats
  • ### Automated Checks and ### Manual Checks inside ## Verification when both matter
  • a short visible standards/support note for compatibility-sensitive or compliance-sensitive rules

Apply these conditionally, not universally.

Browser support guidance should be derived from the repo browser policy in .browserslistrc plus package-backed compatibility data, not from memory.

Use explicit thresholds whenever the rule is measurable:

  • Web Vitals and performance metrics (LCP <= 2.5s, CLS <= 0.1, bundle or image size budgets)
  • Accessibility measurements (contrast ratios, target sizes, zoom or reflow thresholds)
  • SEO and crawling states (indexability, status codes, canonical-url behavior)
  • Security headers and transport requirements

Prefer “how to verify” guidance over generic advice. A strong rule should tell an engineer exactly how to confirm the rule passes.

Common Mistakes to Avoid

  • Unquoted colons in YAML: Always quote strings containing : — e.g. title: "Use rel: new-tab" not title: Use rel: noopener
  • Stub prompts: Prompts must be actionable. Bad: "Check this rule". Good: "Find all <img> elements missing an alt attribute in this HTML"
  • Missing sources: Add at least one authoritative reference (MDN, W3C/WCAG, specs, web.dev, or product docs) before considering a rule complete
  • No verification path: Include a final ## Verification section so the fix is testable
  • Verification not last: Do not place additional H2 sections after ## Verification
  • Missing caveats: Add ## Exceptions when the rule has important false positives or valid exceptions
  • Missing support note: Add ## Browser Support, ## Support Notes, or a visible standards note when compatibility or compliance changes implementation decisions
  • Wrong priority: critical = site-breaking / security / legal. high = significantly degrades UX. medium = best practice. low = nice-to-have
  • Missing required fields: All 7 required fields must be present; builds fail otherwise
  • Emoji in titles: Titles should be plain text (no emoji)

Category Taxonomy

Valid values for the categories array:

Slug Description
html Document structure, semantics, forms
css Layout, typography, animation, responsive
javascript Client-side scripting, async, security
performance Loading speed, rendering, Core Web Vitals
accessibility WCAG, ARIA, keyboard, screen readers
seo Meta tags, structured data, crawlability
security HTTPS, CSP, XSS prevention, headers
images Optimization, formats, responsive images
testing Unit, integration, e2e, a11y testing
privacy Consent, data minimisation, data rights
i18n Localization, pluralization, bidi, locale formatting
general Cross-cutting best practices

Quality Scoring Rubric

Rules are scored automatically via pnpm score:rules (100-point base score plus up to 12 conditional points, minimum 50 to pass the current quality gate).

Dimension Points What to Check
Prompts (check/fix/explain) 24 All 3 prompts are specific and non-generic
TLDR bullets 4 3+ actionable bullets
Why it matters 4 Explains user, business, or operational impact
AI context 6 Captures where and when the rule applies in automated reviews
Related rules 6 Links adjacent rules with clear reasons
Sources 10 Includes authoritative references
Resources / tools 6 Includes useful supporting docs or tools
Code review prompt 6 Provides a systematic review strategy
Code examples 10 Includes realistic examples, not just prose
Body depth 10 Provides substantive implementation detail
Verification section 8 Includes Verification, Testing, Audit Checklist, or equivalent
Thresholds / pass-fail criteria 6 Uses explicit numbers or conditions where the rule is measurable
Exceptions (conditional) 4 Adds an Exceptions section when the rule is nuanced or false-positive-prone
Verification split (conditional) 4 Splits verification into automated and manual checks when both apply
Standards/support visibility (conditional) 4 Adds a visible threshold, standards note, or support note when required by the rule type

Rules scoring < 50 are excluded from MCP tool responses and the web UI.

Adding or Updating a Rule

  1. Create packages/content/rules/en/<category>/<slug>.mdx
  2. Fill all required frontmatter fields
  3. Add recommended metadata: sources, resources, aiContext, relatedRules, and prompts.codeReview where applicable
  4. Write the rule using the canonical-url structure (intro, examples, why it matters, verification, category-specific guidance)
  5. Run pnpm score:rules — must score ≥ 50 for now; target 60+ for new work
  6. Run pnpm validate:rule-structure — validates rule section order and final Verification heading
  7. Run pnpm report:rule-links — reviews inline-link density and suggests safe internal/external candidates
  8. Run pnpm validate:sources — validates external URLs
  9. Run pnpm generate:skills — regenerates skills index

Scripts Reference

pnpm score:rules          # Score all rules; flags < 50 quality gate failures
pnpm validate:rule-structure  # Validate rule heading structure and report drift
pnpm report:v2-gaps       # Report conditional V2 gaps by category and migration batch
pnpm report:rule-links    # Review inline-link density and candidate internal/external links
pnpm generate:exceptions-hints  # Dry-run suggestions for missing Exceptions sections
pnpm generate:support-notes  # Dry-run support-note suggestions from browser data
pnpm generate:verification-split  # Dry-run Verification split suggestions
pnpm validate:sources     # Validate external URLs in rule frontmatter
pnpm validate:packages    # Check package dependency consistency
pnpm generate:skills      # Regenerate skills/ directory from rules
pnpm build                # Full monorepo build (via Turborepo)
pnpm typecheck            # TypeScript check across all packages
pnpm lint                 # Biome lint
pnpm lint:fix             # Biome lint with auto-fix

MCP Tool Development

New MCP tools go in packages/mcp/src/tools/<tool-name>.ts and must be:

  1. Exported from packages/mcp/src/tools/index.ts
  2. Added to BASE_TOOL_DEFINITIONS in packages/mcp/src/server.ts
  3. Added as a case in the handleToolsCall switch in server.ts

Tool definition shape:

export const myToolDefinition = {
  name: 'my_tool',
  description: '...',  // Critical for tool discoverability — be specific
  inputSchema: {
    type: 'object' as const,
    properties: { ... },
    required: ['fieldName'],
  },
}

Workspace Architecture Notes

  • Auth: Better-Auth + Prisma + Supabase Postgres in packages/auth/
  • Validation: Zod v4 — use .issues not .errors on ZodError
  • Forms: @tanstack/react-form with manual Zod validation on submit
  • Email: Resend SDK v6, sending domain mail.frontendchecklist.io
  • Rate limiting: @upstash/ratelimit + @upstash/redis in apps/web/lib/rate-limit.ts
  • Query: TanStack Query v5 with getQueryClient() factory (not singleton)
  • Dev server: portless run next dev

Learned User Preferences

  • Put shared concerns (e.g. fonts, typography) in the design system and import from there; apps wire implementation (e.g. next/font) using config from the design system.
  • Do not use suppressHydrationWarning; fix server/client mismatch (e.g. defer client-only state until after mount).
  • Reuse existing components instead of creating page-specific variants (e.g. shared FAQAccordion for any FAQ section, .code-block/.code-inline for all code display, ChecklistActionBar instead of new progress bars). When adding a feature to one page type, add it to all relevant page types (e.g. ShareButton on category, rule detail, and all-rules pages).
  • Rule row: click on rule title toggles completion; expand/collapse only via the plus/minus icon. Expanded content shows description first, then tags and action buttons on one row aligned with the description.
  • Prefer Tailwind utility classes in components over custom CSS classes in globals.css.
  • Use a scalable overrides map for special-case labels (e.g. subcategory aria → ARIA) instead of hardcoded conditionals.
  • Do not use git commit --no-verify; fix ALL pre-commit violations (JSDoc, as-casts, barrel files, complexity, relative imports) rather than deferring or working around them. Write JSDoc at the same time as the code, not as a batch fix later.
  • Card-style links: Use the stretched-link pattern: the <a>/<Link> wraps only the title text inside a heading and uses after:absolute after:inset-0 after:content-[""] so its ::after pseudo-element expands to fill the card container (position: relative). Secondary interactive elements need relative z-10. See docs/card-links.md.
  • Centralize all icons in @repo/design-system: brand icons in brand-icons.tsx, Lucide re-exported from icons.ts. Use official brand icons (@icons-pack/react-simple-icons) for branded services, not Lucide approximations. Consumers never import directly from lucide-react.
  • Never use Tailwind opacity modifiers (/50, /60, /70) on semantic theme text colors like text-foreground-muted — it crushes contrast in light mode. Use the appropriate token (text-foreground-muted, text-foreground-subtle) at full opacity instead.
  • Always refer to the social platform as "X", never "Twitter". Schema fields use xUrl (not twitterUrl), UI labels say "X", and URLs point to x.com.
  • About page link belongs in the footer only, not in the main navbar.

Learned Workspace Facts

  • Fluid typography tokens use clamp() in @theme inline for text-base and above; text-xs and text-sm stay fixed for compact UI controls (buttons, badges, inputs, tooltips).
  • next/font: apply each font’s .className to the document element (not .variable); Next.js requires literal option objects, so the app must inline font options while the design system can document them.
  • Do not apply client-side bot protection (e.g. Vercel BotID) to programmatic API endpoints like MCP; use it only for browser-originated form and mutation endpoints.
  • Next.js reads next.config.js at startup; restart the dev server after changing it (e.g. images.remotePatterns). withContentCollections returns a Promise (async config) so it must be the outermost wrapper — export default withContentCollections(withBotId(nextConfig)). withBotId does not handle async configs and will silently drop all properties including images.
  • Tailwind preflight resets list-style on ul/ol; .prose styles must explicitly set list-style-type: disc (ul), decimal (ol), and nested variants (circle, lower-alpha).
  • CSS custom properties use OKLCH color format. Light mode tokens need visible contrast on all screens: --border at least oklch(0.885), --foreground-subtle at oklch(0.64), shadows at 0.06+ opacity. Use color-mix(in oklch, var(--token) N%, transparent) for theme-aware transparent colors instead of hardcoded rgba().
  • Pre-commit hooks (lefthook) enforce: biome check, JSDoc, no-as-casts, no-barrel-files, file-complexity (300 lines React / 500 lines other), no-deep-relative-imports, no-console-logs, test coverage.
  • Button default variant uses bg-accent text-accent-foreground hover:bg-accent-hover (project's accent tokens), not shadcn's bg-primary; keep project-specific semantic tokens in component variants even when shadcn aliases exist.
  • Scripts are organized in subfolders: scripts/{validation,generate,rule-structure,validate,audit}/; scripts/README.md documents each script and subfolder.
  • Biome's useSortedClasses only sorts class order; it cannot rename deprecated classes. Use @tailwindcss/upgrade (installed in apps/web) to canonicalize class names project-wide.
  • Monorepo uses pnpm catalogs (catalog: in pnpm-workspace.yaml) for centralized dependency versions; shared deps appearing in 2+ packages use catalog: instead of hardcoded version strings.
  • Brand icons (ChatGPT, Claude, X, LinkedIn, Reddit, Cursor, VSCode) live in packages/design-system/src/brand-icons.tsx and are re-exported from the design-system barrel.