Skip to content

Latest commit

 

History

History
152 lines (113 loc) · 6.58 KB

File metadata and controls

152 lines (113 loc) · 6.58 KB

CLAUDE.md

This file provides guidance to Claude Code when working with this repository. Full architecture details are in AGENTS.md and docs/architecture.md. Full project rules are in .claude/PROJECT_RULES.md.

Monorepo Layout

apps/desktop/          # Electron shell: main process, preload, loads web build output
apps/web/              # Standalone React UI (Vite + React Router + Zustand)
packages/agent-core/   # Core business logic, types, storage, MCP tools (@anastomotic_ai/agent-core, ESM)

Commands

# Dev
pnpm dev                                     # Desktop app (web dev server + Electron)
pnpm dev:web                                 # Web UI only (localhost:5173)
pnpm dev:clean                               # Dev with CLEAN_START=1 (clears stored data)

# Build
pnpm build                                   # All workspaces
pnpm build:web                               # Web UI only
pnpm build:desktop                           # Desktop (builds web first)
pnpm clean                                   # Clean build outputs and node_modules

# Typecheck / Lint / Format
pnpm typecheck && pnpm lint:eslint && pnpm format:check
pnpm format                                  # Prettier auto-fix (write mode)

# Tests — always workspace-scoped (no root-level test commands)
pnpm -F @anastomotic/web test:unit            # Web unit tests
pnpm -F @anastomotic/web test:integration     # Web integration tests
pnpm -F @anastomotic/desktop test:unit        # Desktop main-process unit tests
pnpm -F @anastomotic/desktop test:integration # Desktop integration tests
pnpm -F @anastomotic/desktop test:e2e:native  # Playwright E2E tests (serial, Electron)
pnpm -F @anastomotic_ai/agent-core test       # Agent-core tests

# Run a single test file
pnpm -F @anastomotic/desktop vitest run --config vitest.unit.config.ts path/to/file.unit.test.ts

# Environment variables for dev/testing
# CLEAN_START=1        — clear all stored data on start
# E2E_SKIP_AUTH=1      — skip onboarding flow
# E2E_MOCK_TASK_EVENTS=1 — mock task events

Architecture

Data flow

React UI (apps/web)
  ↓ window.anastomotic.* calls
Preload (contextBridge) — apps/desktop/src/preload/index.ts
  ↓ ipcRenderer.invoke / ipcRenderer.on
Main Process — apps/desktop/src/main/ipc/handlers.ts
  ↓ agent-core factories (TaskManager, Storage, etc.)
  ↑ IPC events → taskStore subscriptions in renderer

Adding an IPC handler (required sequence)

  1. Handler in apps/desktop/src/main/ipc/handlers.ts
  2. Expose via contextBridge in apps/desktop/src/preload/index.ts
  3. Typed wrapper in apps/web/src/client/lib/anastomotic.ts
  4. Consume from components or apps/web/src/client/stores/taskStore.ts
  5. pnpm typecheck to verify the full chain

Never skip a step — all 4 must be done together.

agent-core

  • ESM package ("type": "module") — all internal imports must use .js extensions
  • Shared types: packages/agent-core/src/common/types/
  • Factories are the public API: createTaskManager, createStorage, createPermissionHandler, etc.
  • Do not use internal classes directly; use factories

SQLite / Migrations

  • DB: anastomotic.db (prod) / anastomotic-dev.db (dev), in Electron user-data directory
  • Current schema version: 6 (in packages/agent-core/src/storage/migrations/index.ts)
  • To add a migration: create vXXX-description.ts, import + add to the migrations array, bump CURRENT_VERSION
  • Never modify released migration files — always add a new one

Bundled Node.js

The packaged app ships Node.js v20.18.1. When spawning npx/node in the main process, prepend bundledPaths.binDir to PATH — otherwise processes fail with exit code 127 on machines without system Node.js. See docs/architecture.md.

TypeScript Path Aliases

Alias Resolves to
@/* (web only) apps/web/src/client/*
@main/* (desktop only) apps/desktop/src/main/*
@anastomotic_ai/agent-core packages/agent-core/src/index.ts
@anastomotic_ai/agent-core/common packages/agent-core/src/common.ts

Desktop does not have an @/* alias — UI code lives in apps/web.

Critical Rules

Code

  • No require() in agent-core — it is ESM; use import
  • .js extensions required on all imports within agent-core
  • Image assets must use ES module imports (import logo from '/assets/logo.png'), never absolute paths — they break in the packaged app
  • Always use braces for if/else/for/while (enforced by ESLint curly rule)
  • No nested ternaries — use mapper objects or if/else
  • No root-level test scripts — always use -F @anastomotic/web, -F @anastomotic/desktop, or -F @anastomotic_ai/agent-core
  • Reuse UI components — check apps/web/src/client/components/ui/ before creating new ones
  • New files must be < 200 lines — split into logical modules if needed (exceptions: generated files, migrations)
  • No console.log in production code — use the app's existing logger

Never remove features

Do not delete, comment out, or disable existing functionality unless the task explicitly requires removal. If unsure, ask before removing. This applies to: exported functions, components, types, IPC handlers, UI elements, routes, and config entries.

Git

  • Always pull main before branching: git checkout main && git pull origin main
  • Branch naming: feat/ENG-XXX-short-description or fix/ENG-XXX-short-description
  • Conventional commits: feat(scope):, fix(scope):, refactor(scope):, chore(scope):
  • Never force-push a branch that has an open PR

Pre-push checklist (run in order)

# 1. Install deps if any package.json changed
git diff --name-only | grep "package\.json" && pnpm install

# 2. Typecheck → Lint → Format → Build
pnpm typecheck && pnpm lint:eslint && pnpm format:check && pnpm build

# 3. Tests — only workspaces with changed files
pnpm -F @anastomotic/web test:unit          # if apps/web changed
pnpm -F @anastomotic/desktop test:unit      # if apps/desktop changed
pnpm -F @anastomotic_ai/agent-core test     # if packages/agent-core changed

Do not push if any step fails.

Styling

Tailwind CSS + shadcn/ui, CSS variables for theming (no hardcoded colors), DM Sans font, Framer Motion for animations via apps/web/src/client/lib/animations.ts.