mirror of
https://github.com/coder/coder.git
synced 2026-10-31 11:02:50 +08:00
## Summary
Streamlines the agent instruction files, cutting per-session token
overhead by roughly 65%.
The core design change: `AGENTS.md` no longer `@`-imports WORKFLOWS.md,
package.json, the eight detailed guides, or `AGENTS.local.md` into every
session. Guidance moves from guaranteed-in-context to load-on-demand
through a routing table, betting that one-line guardrail summaries plus
links are enough to make agents pull the right doc when a task needs it.
- `AGENTS.md` (251 -> 80 lines): a routing table to the canonical docs
in `.claude/docs/`, the essential command table, and one-line guardrails
for the architectural footguns (SQLC workflow plus audit table, OAuth2
error conformance, chatd architecture-doc rule, Swagger annotations,
`InTx` discipline, test concurrency, workflow `permissions: {}`,
mandatory git hooks, commit/PR title format).
- `site/AGENTS.md` (364 -> 89 lines): keeps the FE1-FE10 contract
summary, TypeScript LSP navigation, pnpm command table, React Compiler
boundaries, accessibility rules, and the pre-PR `frontend-review`
requirement. Drops the generic React tutorial sections that restate
framework documentation.
- The persona and relationship prose ("Our relationship", foundational
rules) is deliberately removed. The behavioral gates worth keeping for
every agent survive as one-liners: get explicit permission before
excepting a rule, discuss architectural decisions before implementing,
and answer questions instead of jumping to implementation.
- Unique operational content is relocated rather than deleted:
Playwright failure-artifact paths and the CI `playwright-artifacts-`
naming convention move to `.claude/docs/AGENT_FAILURES.md`; the
`React.useId()` rule, the `key={String(booleanState)}` remount footgun,
date-as-prop Storybook determinism, and the suppression-comment rule
(updated from `eslint-disable` to `biome-ignore` to match current
tooling) move to `.claude/docs/FRONTEND_PATTERNS.md`.
Content reflects current main: the chatd rule says agents leave TODOs
and the human PR author writes the architecture doc, and MUI/Emotion are
described as removed, not deprecated.
Note for Claude Code users: `CLAUDE.md` symlinks to `AGENTS.md`, so
detailed workflow docs (hook internals, the new-feature checklist,
`AGENTS.local.md`) are no longer auto-loaded into every session; agents
must follow the links.
## Validation
- `pnpm exec markdownlint-cli2` on all four touched files: 0 errors
- `pnpm exec markdown-table-formatter --check` on all four touched
files: pass
- `make lint/emdash`: pass
- `make lint/agents`: pass
- All relative links verified to resolve
> Mux created this PR and description on behalf of Mike.
6.1 KiB
6.1 KiB
Frontend Development Guidelines
Read Frontend Patterns before changing site/src/. It is the canonical contract for FE1 through FE10.
Frontend contract
- FE1: UI behavior changes ship with Storybook stories whose
playfunction exercises the real interaction. Vitest or RTL is for pure logic only. - FE2: No
any,as unknown as, or avoidable casts. Use generated API types fromapi/typesGenerated.ts. - FE3: Search for an existing component or helper before writing one. Keep changes single-purpose.
- FE4: Do not add comments that restate identifiers, assertions, or control flow.
- FE5: Views handle loading, error, empty, and refetch states without clobbering user state.
- FE6: Interactive elements remain keyboard reachable and have correct accessible names.
- FE7: Use React Query for server data. Import query key constants instead of retyping string literals.
- FE8: Use
useEffectonly to synchronize with external systems. Do not derive state or chain fetches in effects. - FE9: Share entity fixtures as
Mock*constants. Compose story query wiring inline per story. - FE10: Tests query semantic roles and names. Do not use
querySelectoror class-name assertions.
Navigation and commands
Use the TypeScript language server when available for definitions, references, type information, diagnostics, and renames.
| Task | Command |
|---|---|
| Develop | pnpm dev |
| Storybook | pnpm storybook --no-open |
| Story tests | pnpm test:storybook |
| One story file | pnpm test:storybook src/path/to/component.stories.tsx |
| Unit tests | pnpm test |
| One unit file | pnpm test path/to/file.test.ts |
| Typecheck | pnpm lint:types |
| Biome check | pnpm check |
| Lint | pnpm lint |
| Fix lint | pnpm lint:fix |
| Format | pnpm format |
| End-to-end tests | pnpm playwright:test |
Some end-to-end tests require a license. The Storybook MCP at http://localhost:6006/mcp requires Storybook to be running.
Components and styling
- Use existing shadcn components and Tailwind CSS. MUI and Emotion have been removed; do not reintroduce them.
- Search
site/src/components/and nearby feature code before creating a component or helper. - Add shadcn components manually. Do not use the shadcn CLI.
- Keep business-specific components in feature modules. Create shared components only when reuse is established.
- Changes to core components are cross-cutting. Coordinate visual or API expansion with design when needed.
- Keep component files near 500 lines or less. Extract coherent sections when a file becomes difficult to navigate.
- Use semantic theme colors and existing Tailwind tokens. Do not use the
dark:prefix.
TypeScript and data flow
- Use ES modules and Biome. Prefer
for...ofoverforEach. - Access browser globals directly. This is a client-only SPA, so do not guard them with
typeof windowor similar checks. - Components must not call API functions directly. Use established React Query definitions and key hierarchies.
- Use
mutate()with callbacks when the result does not need to be awaited. Do not swallow mutation failures in empty catches. - Prefer generated types, annotations, guards, and upstream type fixes over assertions or non-null assertions.
- Match errors by code or HTTP status, not message text.
- Match patterns in the same file before introducing a new convention.
- Avoid single-use wrappers, aliases, constants, and hooks that add navigation without adding meaning.
- Use JSX shorthand for boolean props whose value is
true.
Accessibility and robustness
- Every table has an
aria-labelor caption. - Elements with
tabIndex={0}have an appropriate semantic role. - Visually hidden interactive elements must also leave the tab order and accessibility tree. Prefer conditional rendering.
- Render a visible fallback such as
UnknownorN/Afor missing user-facing text. - Guard number conversions against
NaNand non-finite values. - Pass an explicit locale to
toLocaleString()for deterministic output. - Do not use em dashes, en dashes, or spaced double hyphens as punctuation.
Testing
- Add or update Storybook stories for component and page behavior, visual states, keyboard interaction, focus, and accessibility.
- Assert observable behavior with semantic queries. Do not assert Tailwind classes or implementation details.
- Use
data-testidonly when an element has no suitable role or accessible name. - Do not depend on smooth scrolling in tests. Use instant behavior or control the scroll position directly.
- Keep stories current when components change.
Performance
src/pages/AgentsPage/, includingcomponents/ChatElements/, uses React Compiler. Do not adduseMemo,useCallback, ormemo()there.memo()remains valid for list-item components rendered in a map because compiler memoization does not cross component boundaries.- Isolate frequently changing state in a small child component instead of rerendering a large parent subtree.
- Throttle high-frequency handlers that set state with
requestAnimationFrameor an established throttle utility.
Completion
- Run targeted story or unit tests during iteration.
- Visually inspect affected component stories before handoff.
- Before handoff, run
pnpm check,pnpm lint, andpnpm format, plus affected tests. - For changes under
site/src/, run the repositoryfrontend-reviewskill at.claude/skills/frontend-review/SKILL.mdand fix each applicable FE1 through FE10 failure.