# AGENTS.md Guidelines for AI coding agents working in this repository. ## Build & Development Commands ```bash 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`, `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 & Linting - 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 - Always use `@/` path aliases (never relative `../../`) - Use `type` keyword for type-only imports: `import type { Foo } from "bar"` ### TypeScript - **Strict mode** enabled - no implicit any, strict null checks - **Explicit return types** for API routes and server actions - **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 ### Naming Conventions | Element | Convention | Example | | ------------------- | ------------------------ | ---------------------------- | | 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` | ### Component Patterns **Prefer Server Components** - Only add `"use client"` when necessary for: - Event handlers (onClick, onChange, onSubmit) - React hooks (useState, useEffect, useTransition) - Browser-only APIs **Component structure:** - 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 ```typescript const Button = ({ className, variant, ...rest }: React.ComponentProps<"button"> & VariantProps) => { return