Files
seastem-electronjs/AGENTS.md
imbytecat e41c4e4515 docs: 更新 AGENTS.md 文档结构和内容
- 新增根目录 AGENTS.md 作为 monorepo 总览
- 移动 desktop AGENTS.md 从 src-tauri/ 到 apps/desktop/
- 修正 server AGENTS.md 目录结构 (src/server/api/ 而非 src/orpc/)
- 明确 desktop 为纯 Tauri 壳子,无前端代码,通过 sidecar 加载 server
2026-02-07 03:29:51 +08:00

6.2 KiB

AGENTS.md - AI Coding Agent Guidelines

Guidelines for AI agents working in this Bun monorepo.

Project Overview

  • Monorepo: Bun workspaces + Turborepo orchestration
  • Runtime: Bun (see mise.toml for version)
  • Apps:
    • apps/server - TanStack Start fullstack web app (see apps/server/AGENTS.md)
    • apps/desktop - Tauri v2 desktop shell, loads server via sidecar (see apps/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 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                   # Copy sidecar + start Tauri dev
bun build                 # Copy sidecar + build installer

# Rust (from apps/desktop/src-tauri/)
cargo check               # Compile check
cargo clippy              # Linter
cargo fmt                 # Formatter

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
cargo test test_name -- --nocapture   # Rust single test with output

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 - array/object access returns T | undefined
  • noImplicitOverride: true
  • verbatimModuleSyntax: true
  • Use @/* path aliases (maps to src/*)

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)
const MyComponent = ({ title }: { title: string }) => {
  return <div>{title}</div>
}

// Routes: TanStack Router file conventions
export const Route = createFileRoute('/')({
  component: Home,
})

// Data fetching: TanStack Query
const { data } = useSuspenseQuery(orpc.todo.list.queryOptions())

Error Handling

  • Use try-catch for async operations
  • Throw descriptive errors
  • ORPC: Use ORPCError with proper codes (NOT_FOUND, INPUT_VALIDATION_FAILED)
  • Never use empty catch blocks

Code Style (Rust - Tauri)

  • Indent: 4 spaces
  • Naming: snake_case (functions), PascalCase (types), SCREAMING_SNAKE (consts)
  • Use expect("中文消息") over unwrap()
  • Async: tokio runtime, tauri::async_runtime::spawn
  • Run cargo fmt and cargo clippy before commit

Database (Drizzle ORM)

import { pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'
import { sql } from '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-core with Zod validation in src/env.ts
  • Server vars: no prefix
  • Client vars: VITE_ prefix required
  • Never commit .env files

Critical Rules

DO:

  • Run bun fix before committing
  • Use @/* path aliases (not relative imports)
  • Let React Compiler handle memoization (no manual useMemo/useCallback)
  • Include createdAt/updatedAt on all tables

DON'T:

  • Edit src/routeTree.gen.ts (auto-generated)
  • Use as any, @ts-ignore, @ts-expect-error
  • Commit .env files
  • Use empty catch blocks catch(e) {}
  • Use unwrap() in Rust without expect()

Git Workflow

  1. Make changes following style guide
  2. bun fix - auto-format and lint
  3. bun typecheck - verify types
  4. bun dev - test locally
  5. 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/          # Tauri v2 shell (no frontend src)
│       ├── src-tauri/    # Rust Tauri code
│       │   ├── src/      # Rust source
│       │   └── binaries/ # Sidecar binaries
│       └── AGENTS.md
├── packages/
│   ├── tsconfig/         # Shared TS configs
│   └── utils/            # Shared utilities
├── biome.json            # Linting/formatting config
├── turbo.json            # Turbo task orchestration
└── package.json          # Workspace root

See Also

  • apps/server/AGENTS.md - Detailed TanStack Start / ORPC patterns
  • apps/desktop/AGENTS.md - Rust / Tauri development guide