- 引入 shadcn/ui(base-nova 风格,Tailwind v4,14 个组件) - 新增 Admin 后台路由架构:/admin(总览)、/admin/bookmarks(管理) - 重写首页为纯展示书签导航(BookmarkCard + CategoryGrid) - 新增 Admin 侧边栏导航(AdminSidebar + SidebarProvider) - 书签管理页:双栏布局 + Dialog 表单 + DnD 排序 + Toast 通知 - 修复 IconPicker overflow 裁切(改用 Dialog portal) - 修复嵌套 button hydration 错误(base-ui render prop) - 删除旧组件(CategorySection/BookmarkItem/IconPicker)和旧路由 - 所有新依赖归入 root catalog - 更新 AGENTS.md 文档(目录结构、shadcn 模式、render prop 规范)
11 KiB
AGENTS.md - AI Coding Agent Guidelines
Guidelines for AI agents working in this Bun monorepo.
Product Vision
Kairos 是一个人生操作系统(Personal Life OS)。所有开发决策必须服务于这个愿景。
Kairos 将个人生活的每一个维度 —— 财务、订阅、健康、资产、决策 —— 整合进一个统一的、自托管的平台。它不是又一个效率工具或仪表盘,而是一个完整的操作系统。
核心模块
| 模块 | 职责 |
|---|---|
| 财务 | 银行账户、交易流水、消费分析、预算追踪 |
| 订阅 | 周期性服务管理 —— 费用、续期、使用频率 |
| 健康 | 身体指标、习惯、睡眠、营养 |
| 资产 | 实体与数字资产、保修、生命周期追踪 |
| 日志 | 决策、复盘、人生事件 |
| 集成 | API 对接、数据导入、自动化 |
每个模块是同一个统一数据层的不同视角,模块之间的数据可以交叉关联和分析。
设计信条
- 数据主权 —— 自托管、本地优先。用户数据不离开用户的机器,除非用户自己决定。所有功能必须在无外部云依赖的情况下完整可用。
- 关联即洞察 —— 孤立数据是噪音,关联数据是洞察。所有模块共享统一数据层,设计时必须考虑跨模块的数据关联能力。
- 可扩展基座 —— Kairos 是有主见的基座,不是封闭成品。架构必须支持模块的独立扩展和自定义。
架构原则
- 契约优先 API —— 每个端点从类型化契约定义开始,实现紧随其后。一份契约,Web 和 CLI 两个消费者共享。
- Web + CLI 双入口 —— Web 应用是主界面;CLI 调用同一套 API,支持脚本编排、自动化、快速数据录入。
- 编译为单文件 —— 服务端编译为独立 Bun 二进制,零运行时依赖,部署极简。
Agent 决策指南
在做任何设计或实现决策时,用以下问题自检:
- 这是否让用户更完整地掌控自己的数据? 如果否,重新考虑。
- 这个模块的数据是否可以被其他模块关联使用? 如果不能,说明数据模型设计有问题。
- 这个功能是否可以在完全离线/自托管环境下工作? 如果不能,必须提供无外部依赖的替代方案。
- 新增的功能是否通过 ORPC 契约暴露? Web 和 CLI 必须能同等访问所有能力。
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 <script>for scripts. Always preferbun run <script>overbun <script>to avoid conflicts with Bun built-in subcommands (e.g.bun buildinvokes Bun's bundler, NOT your package.json script). 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)
- Packages:
packages/tsconfig(shared TS configs)
Build / Lint / Test Commands
Root Commands (via Turbo)
bun run dev # Start all apps in dev mode
bun run build # Build all apps
bun run compile # Compile server to standalone binary (current platform)
bun run compile:darwin # Compile server for macOS (arm64 + x64)
bun run compile:linux # Compile server for Linux (x64 + arm64)
bun run compile:windows # Compile server for Windows x64
bun run fix # Lint + format (Biome auto-fix)
bun run typecheck # TypeScript check across monorepo
Server App (apps/server)
bun run dev # Vite dev server (localhost:3000)
bun run build # Production build -> .output/
bun run compile # Compile to standalone binary (current platform)
bun run compile:darwin # Compile for macOS (arm64 + x64)
bun run compile:darwin:arm64 # Compile for macOS arm64
bun run compile:darwin:x64 # Compile for macOS x64
bun run compile:linux # Compile for Linux (x64 + arm64)
bun run compile:linux:arm64 # Compile for Linux arm64
bun run compile:linux:x64 # Compile for Linux x64
bun run compile:windows # Compile for Windows (default: x64)
bun run compile:windows:x64 # Compile for Windows x64
bun run fix # Biome auto-fix
bun run typecheck # TypeScript check
# Database (Drizzle)
bun run db:generate # Generate migrations from schema
bun run db:migrate # Run migrations
bun run db:push # Push schema (dev only)
bun run db:studio # Open Drizzle Studio
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 v1 beta + postgres-js)
- ORM: Drizzle ORM
1.0.0-beta(RQBv2) - Driver:
drizzle-orm/postgres-js(NOTbun-sql) - Validation:
drizzle-orm/zod(built-in, NOT separatedrizzle-zodpackage) - Relations: Defined via
defineRelations()insrc/server/db/relations.ts(contains schema info, sodrizzle()only needs{ relations }) - Query style: RQBv2 object syntax (
orderBy: { createdAt: 'desc' },where: { id: 1 })
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
Development Principles
These principles apply to ALL code changes. Agents MUST follow them on every task.
- No backward compatibility — This project is in rapid iteration. Always use the latest API and patterns. Never keep deprecated code paths or old API fallbacks "just in case".
- Always sync documentation — When code changes, immediately update all related documentation (
AGENTS.md,README.md, inline code examples). Code and docs must never drift apart. This includes updating code snippets in docs when imports, APIs, or patterns change. - Forward-only migration — When upgrading dependencies, fully adopt the new API. Don't mix old and new patterns in the same codebase.
Critical Rules
DO:
- Run
bun run fixbefore committing - Use
@/*path aliases (not relative imports) - Include
createdAt/updatedAton all tables - Use
catalog:for dependency versions - Update
AGENTS.mdand other docs whenever code patterns change
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
- Leave docs out of sync with code changes
Git Workflow
- Make changes following style guide
bun run fix- auto-format and lintbun run typecheck- verify typesbun run dev- test locally- Commit with descriptive message
Directory Structure
.
├── apps/
│ ├── server/ # TanStack Start fullstack app
│ │ ├── components.json # shadcn/ui configuration
│ │ ├── src/
│ │ │ ├── client/ # ORPC client + TanStack Query utils
│ │ │ ├── components/
│ │ │ │ ├── ui/ # shadcn/ui components (auto-managed)
│ │ │ │ └── AdminSidebar.tsx # Admin panel sidebar
│ │ │ ├── hooks/ # Custom React hooks
│ │ │ ├── lib/ # Utilities (cn, etc.)
│ │ │ ├── modules/ # Feature modules (bookmarks, etc.)
│ │ │ ├── routes/ # File-based routing
│ │ │ │ ├── _protected/ # Auth guard
│ │ │ │ │ ├── index.tsx # Dashboard homepage
│ │ │ │ │ ├── admin.tsx # Admin layout (sidebar)
│ │ │ │ │ └── admin/ # Admin pages
│ │ │ │ │ ├── index.tsx # Admin overview
│ │ │ │ │ └── bookmarks.tsx # Bookmark management
│ │ │ │ └── api/ # API routes
│ │ │ └── server/ # API layer + database + auth
│ │ │ ├── api/ # ORPC contracts, routers, middlewares
│ │ │ ├── auth/ # Better Auth (schema, instance, client)
│ │ │ └── db/ # Drizzle schema + relations
│ │ └── AGENTS.md
├── packages/
│ └── tsconfig/ # Shared TS configs
├── 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 patterns