From 1b472214a95421566d988306e17083f6ea707d4c Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Sat, 3 Oct 2026 08:01:10 -0400 Subject: [PATCH] docs: update AGENTS.md for oxlint/oxfmt and current conventions Co-Authored-By: Claude Sonnet 5.5 --- AGENTS.md | 107 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index aa3a1006..732428eb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,23 +8,26 @@ Guidelines for AI coding agents working in this repository. pnpm dev # Development server (binds to 0.0.0.0) pnpm build # Production build pnpm lint # Lint and type-check the entire codebase +pnpm lint:fix # Lint with autofixes pnpm lint path/to/file.tsx # Lint a single file +pnpm fmt # Format with oxfmt +pnpm fmt:check # Check formatting (no writes) pnpm db:generate # Generate migration files pnpm db:migrate # Apply migrations ``` -No test suite exists. Validate changes via `pnpm lint` and `pnpm build`. +No test suite exists. Validate changes via `pnpm lint`, `pnpm fmt:check` and `pnpm build`. + +`pnpm build` needs `NEXT_PUBLIC_BASE_URL` set (copy `.env.example` to `.env.local`); database, auth and GitHub secrets are optional for a build. ## Code Style -### Formatting (Biome) +### Formatting & Linting -- **Line width:** 80 characters -- **Indentation:** 2 spaces (no tabs) -- **Quotes:** Double quotes, no JSX single quotes -- **Trailing commas:** ES5 style -- **Semicolons:** Required -- **Tailwind:** Classes auto-sorted via `biome --write --unsafe` +- Formatter is **oxfmt** (`pnpm fmt` to write, `pnpm fmt:check` to verify), configured in `.oxfmtrc.json`. It sorts imports (groups: builtin → external → `@/` internal → relative, blank line between groups) and Tailwind classes (in `className` and `cn`/`clsx`/`cva` calls). Don't hand-sort; run `pnpm fmt`. +- Indentation is 2 spaces (no tabs), with double quotes, semicolons and trailing commas. +- Linter is **oxlint** with type-aware checks; `pnpm lint` runs `next typegen` then `oxlint` and also type-checks. `pnpm lint:fix` applies autofixes. +- Never run `biome`, `eslint` or `prettier`; they are not part of this repo. ### Import Organization @@ -37,7 +40,7 @@ import { eq, desc } from "drizzle-orm"; // 3. Internal modules using @/ alias import { db } from "@/lib/db"; -import Button from "@/components/ui/button"; +import { Button } from "@/components/ui/button"; ``` - Always use `@/` path aliases (never relative `../../`) @@ -47,7 +50,7 @@ import Button from "@/components/ui/button"; - **Strict mode** enabled - no implicit any, strict null checks - **Explicit return types** for API routes and server actions -- **Zod** for runtime validation - share schemas between client and server +- **Zod** (v4) for runtime validation of untrusted input (server-action arguments, content frontmatter in content-collections.ts) - Avoid `any` - use `unknown` with type guards when necessary - Use `as const` for immutable config objects @@ -55,8 +58,8 @@ import Button from "@/components/ui/button"; | Element | Convention | Example | | ------------------- | ------------------------ | ---------------------------- | -| Files | kebab-case | `contact-form.tsx` | -| Components | PascalCase | `ContactForm` | +| Files | kebab-case | `comment-form.tsx` | +| Components | PascalCase | `CommentForm` | | Functions/Variables | camelCase | `getComments`, `isPending` | | Types/Interfaces | PascalCase | `CommentWithUser` | | Constants | camelCase or UPPER_SNAKE | `siteConfig`, `DATABASE_URL` | @@ -71,7 +74,7 @@ import Button from "@/components/ui/button"; **Component structure:** -- Arrow function components with default exports +- Arrow function components, **named exports** gathered at the end of the file (`export { Button, buttonVariants };`). Default exports only where Next.js requires them (`page.tsx`, `layout.tsx`, route files) and for config objects in `lib/config/`. - Props destructured in parameters - Use `cn()` from `@/lib/utils` for className merging - Follow shadcn/ui patterns for UI components @@ -84,31 +87,43 @@ const Button = ({ }: React.ComponentProps<"button"> & VariantProps) => { return