Operational guide for coding agents working in this repository. Use this as the practical execution handbook for day-to-day tasks.
- Repository type:
pnpmworkspace monorepo (apps/*,packages/*). - Main product:
apps/desktop(Electron + React + Vite + TypeScript). - Shared schema source:
packages/db/schema.ts. - Shared provider definitions:
packages/providers.
Priority order when guidance conflicts:
- Explicit user instruction
CLAUDE.mdAGENTS.md(this file)- Future tool-specific rules (
.cursor/rules,.cursorrules,.github/copilot-instructions.md)
- Install deps (repo root):
pnpm install - Start app (repo root):
pnpm dev - Lint all workspaces (repo root):
pnpm lint - Type-check app:
pnpm -C apps/desktop exec tsc --noEmit
Native dependencies (electron, better-sqlite3) are expected.
apps/desktop runs electron-rebuild for better-sqlite3 in postinstall.
Run from repo root unless noted.
- Dev app:
pnpm dev - Build app (all targets):
pnpm build - Build current platform only:
pnpm build:current - Build per target:
pnpm build:mac,pnpm build:win,pnpm build:linux - Lint all workspaces:
pnpm lint - DB generate (proxied):
pnpm db:generate - DB migrate (proxied):
pnpm db:migrate
Direct apps/desktop equivalents:
pnpm -C apps/desktop devpnpm -C apps/desktop buildpnpm -C apps/desktop lintpnpm -C apps/desktop db:generatepnpm -C apps/desktop db:migrate
There is currently no dedicated test runner configured (test script / Vitest / Jest is not committed).
Use type-check + lint as baseline validation:
pnpm -C apps/desktop exec tsc --noEmitpnpm -C apps/desktop lint- Single file lint:
pnpm -C apps/desktop exec eslint src/path/to/file.tsx - Multiple files lint:
pnpm -C apps/desktop exec eslint electron/foo.ts src/bar.tsx
If a test framework is added later, prefer single-test execution (file or -t filter).
- Implement changes in
apps/desktop/src/**. - Ensure persistence still goes through preload-exposed
window.*API. - Run:
pnpm -C apps/desktop exec tsc --noEmitpnpm -C apps/desktop exec eslint src/path/to/changed-file.tsx
- Optionally run
pnpm -C apps/desktop devfor manual flow verification.
- Implement in
apps/desktop/electron/**. - Keep IPC contracts synchronized with renderer usage.
- Run:
pnpm -C apps/desktop exec tsc --noEmitpnpm -C apps/desktop exec eslint electron/path/to/changed-file.ts
- Verify IPC call path end-to-end from renderer.
- Edit
packages/db/schema.ts. - Run
pnpm -C apps/desktop db:generate. - Commit schema change plus generated files under
apps/desktop/electron/migrations/. - Run
pnpm -C apps/desktop exec tsc --noEmit.
- Update both locale files:
apps/desktop/src/i18n/locales/en.tsapps/desktop/src/i18n/locales/zh.ts
- Keep key hierarchy aligned (
projectLibrary.*, etc.). - Lint/type-check changed files.
- Keep prompt payload types consistent (string or
{ text, images }). - Ensure IPC-safe serialization across preload bridge (binary refs as number arrays).
- Preserve existing queue/status transitions (
queued->running-> terminal). - Validate failure handling and user-facing error messaging.
- Renderer must not access DB or filesystem directly.
- Renderer persistence must go through APIs exposed in
apps/desktop/electron/preload.ts. - New entities must update the full chain in order:
packages/db/schema.tsapps/desktop/electron/handlers/*.tsapps/desktop/electron/preload.tsapps/desktop/electron/electron-env.d.tsapps/desktop/src/db/*_collection.tsand UI usage
- Handler SQL must use raw
better-sqlite3viagetRawDb(), not Drizzle ORM query builder. - Do not manually edit generated router file
apps/desktop/src/routeTree.gen.ts.
- TypeScript is strict: keep strong typing, avoid
anyshortcuts. - Prefer explicit payload/row types for IPC and DB.
- Persisted DB fields use
snake_case(project_id,created_at). - UI/transient values use
camelCase. - Use narrow string unions for enums where possible.
- Normalize external/AI values before DB writes.
- Naming:
- Components:
PascalCase - Functions/variables:
camelCase - DB/IPC fields:
snake_case - Collection files in
src/db:*_collection.ts - Handler registration helpers:
registerXHandlers
- Components:
- Import groups:
- framework/library
- workspace/package
- local relative
- Use
import typefor type-only imports where practical. - Match repo formatting:
- single quotes
- no semicolons
- 2-space indentation
- trailing commas where valid
- Prefer small focused functions and early returns.
- Add comments only when logic is non-obvious.
- Wrap async IPC/AI flows in
try/catch. - Show user-facing errors via i18n keys, not raw exception dumps.
- Preserve behavior on failure (no silent partial state mutation).
- Require explicit confirmation (
window.confirm) for destructive actions.
- Migration files live in
apps/desktop/electron/migrations/. - Prefer idempotent migration SQL when startup compatibility matters.
- Runtime SQLite location is under Electron
userDatapath (never hardcode absolute DB paths). - Settings and AI config use
electron-storeJSON (settings.json), not SQLite. - Vector search uses
sqlite-vec; keep embedding dimension assumptions consistent with existing table setup.
- Forgetting to regenerate migration after editing
packages/db/schema.ts. - Updating handler/preload types but not
electron-env.d.ts. - Editing generated files (especially
routeTree.gen.ts) manually. - Letting renderer bypass IPC for convenience.
- Adding i18n keys in one locale only.
- Keep the change scoped; avoid unrelated refactors.
- Do not revert unrelated dirty worktree files.
- Inspect
git difffor accidental edits. - Run relevant validation commands for touched files.
- Report:
- what changed
- why
- verification commands run
- follow-up actions (if any)