6.3 KiB
6.3 KiB
AGENTS.md - AI Coding Agent Guidelines
Guidelines for AI agents working in this Bun monorepo.
Project Overview
This project uses Bun exclusively as both the JavaScript runtime and package manager. Do NOT use Node.js / npm / yarn / pnpm. All commands start with
bun— usebun installfor dependencies andbun run/bun <script>for scripts. Never usenpm,npx, ornode.
- Monorepo: Bun workspaces + Turborepo orchestration
- Runtime: Bun (see
mise.tomlfor version) — NOT Node.js - Package Manager: Bun — NOT npm / yarn / pnpm
- Apps:
apps/server- TanStack Start fullstack web app (seeapps/server/AGENTS.md)apps/desktop- Electrobun desktop shell, loads server in native window (seeapps/desktop/AGENTS.md)
- Packages:
packages/utils,packages/tsconfig(shared configs)
Build / Lint / Test Commands
Root Commands (via Turbo)
bun dev # Start all apps in dev mode
bun build # Build all apps
bun fix # Lint + format (Biome auto-fix)
bun typecheck # TypeScript check across monorepo
Server App (apps/server)
bun dev # Vite dev server (localhost:3000)
bun build # Production build -> .output/
bun compile # Compile to standalone binary
bun fix # Biome auto-fix
bun typecheck # TypeScript check
# Database (Drizzle)
bun db:generate # Generate migrations from schema
bun db:migrate # Run migrations
bun db:push # Push schema (dev only)
bun db:studio # Open Drizzle Studio
Desktop App (apps/desktop)
bun dev # Start Electrobun dev mode (requires server dev running)
bun build # Build canary release
bun build:stable # Build stable release
bun fix # Biome auto-fix
bun typecheck # TypeScript check
Testing
No test framework configured yet. When adding tests:
bun test path/to/test.ts # Run single test file
bun test -t "pattern" # Run tests matching pattern
Code Style (TypeScript)
Formatting (Biome)
- Indent: 2 spaces | Line endings: LF
- Quotes: Single
'| Semicolons: Omit (ASI) - Arrow parentheses: Always
(x) => x
Imports
Biome auto-organizes. Order: 1) External packages → 2) Internal @/* aliases → 3) Type imports (import type { ... })
import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'
import { db } from '@/server/db'
import type { ReactNode } from 'react'
TypeScript Strictness
strict: true,noUncheckedIndexedAccess: true,noImplicitOverride: true,verbatimModuleSyntax: true- Use
@/*path aliases (maps tosrc/*)
Naming Conventions
| Type | Convention | Example |
|---|---|---|
| Files (utils) | kebab-case | auth-utils.ts |
| Files (components) | PascalCase | UserProfile.tsx |
| Components | PascalCase arrow | const Button = () => {} |
| Functions | camelCase | getUserById |
| Constants | UPPER_SNAKE | MAX_RETRIES |
| Types/Interfaces | PascalCase | UserProfile |
React Patterns
- Components: arrow functions (enforced by Biome)
- Routes: TanStack Router file conventions (
export const Route = createFileRoute(...)) - Data fetching:
useSuspenseQuery(orpc.feature.list.queryOptions()) - Let React Compiler handle memoization (no manual
useMemo/useCallback)
Error Handling
- Use
try-catchfor async operations; throw descriptive errors - ORPC: Use
ORPCErrorwith proper codes (NOT_FOUND,INPUT_VALIDATION_FAILED) - Never use empty catch blocks
Database (Drizzle ORM)
export const myTable = pgTable('my_table', {
id: uuid().primaryKey().default(sql`uuidv7()`),
name: text().notNull(),
createdAt: timestamp({ withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp({ withTimezone: true }).notNull().defaultNow().$onUpdateFn(() => new Date()),
})
Environment Variables
- Use
@t3-oss/env-corewith Zod validation insrc/env.ts - Server vars: no prefix | Client vars:
VITE_prefix required - Never commit
.envfiles
Dependency Management
- All versions centralized in root
package.jsoncatalogfield - Workspace packages use
"catalog:"— never hardcode versions - Internal packages use
"workspace:*"references
Critical Rules
DO:
- Run
bun fixbefore committing - Use
@/*path aliases (not relative imports) - Include
createdAt/updatedAton all tables - Use
catalog:for dependency versions
DON'T:
- Use
npm,npx,node,yarn,pnpm— always usebun/bunx - Edit
src/routeTree.gen.ts(auto-generated) - Use
as any,@ts-ignore,@ts-expect-error - Commit
.envfiles - Use empty catch blocks
catch(e) {} - Hardcode dependency versions in workspace packages
Git Workflow
- Make changes following style guide
bun fix- auto-format and lintbun typecheck- verify typesbun dev- test locally- Commit with descriptive message
Directory Structure
.
├── apps/
│ ├── server/ # TanStack Start fullstack app
│ │ ├── src/
│ │ │ ├── client/ # ORPC client, Query client
│ │ │ ├── components/
│ │ │ ├── routes/ # File-based routing
│ │ │ └── server/ # API layer + database
│ │ │ ├── api/ # ORPC contracts, routers, middlewares
│ │ │ └── db/ # Drizzle schema
│ │ └── AGENTS.md
│ └── desktop/ # Electrobun desktop shell
│ ├── src/
│ │ └── bun/
│ │ └── index.ts # Main process entry
│ ├── electrobun.config.ts # Electrobun configuration
│ └── AGENTS.md
├── packages/
│ ├── tsconfig/ # Shared TS configs
│ └── utils/ # Shared utilities
├── biome.json # Linting/formatting config
├── turbo.json # Turbo task orchestration
└── package.json # Workspace root + dependency catalog
See Also
apps/server/AGENTS.md- Detailed TanStack Start / ORPC patternsapps/desktop/AGENTS.md- Electrobun desktop development guide