mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 20:23:36 +00:00
docs: map existing codebase
- STACK.md - Technologies and dependencies - ARCHITECTURE.md - System design and patterns - STRUCTURE.md - Directory layout - CONVENTIONS.md - Code style and patterns - TESTING.md - Test structure - INTEGRATIONS.md - External services - CONCERNS.md - Technical debt and issues
This commit is contained in:
234
.planning/codebase/ARCHITECTURE.md
Normal file
234
.planning/codebase/ARCHITECTURE.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# Architecture
|
||||
|
||||
**Analysis Date:** 2026-01-27
|
||||
|
||||
## Pattern Overview
|
||||
|
||||
**Overall:** Monorepo with layered client-server architecture (Electron-first) and pluggable provider abstraction for AI models.
|
||||
|
||||
**Key Characteristics:**
|
||||
|
||||
- Event-driven communication via WebSocket between frontend and backend
|
||||
- Multi-provider AI model abstraction layer (Claude, Cursor, Codex, Gemini, OpenCode, Copilot)
|
||||
- Feature-centric workflow stored in `.automaker/` directories
|
||||
- Isolated git worktree execution for each feature
|
||||
- State management through Zustand stores with API persistence
|
||||
|
||||
## Layers
|
||||
|
||||
**Presentation Layer (UI):**
|
||||
|
||||
- Purpose: React 19 Electron/web frontend with TanStack Router file-based routing
|
||||
- Location: `apps/ui/src/`
|
||||
- Contains: Route components, view pages, custom React hooks, Zustand stores, API client
|
||||
- Depends on: @automaker/types, @automaker/utils, HTTP API backend
|
||||
- Used by: Electron main process (desktop), web browser (web mode)
|
||||
|
||||
**API Layer (Server):**
|
||||
|
||||
- Purpose: Express 5 backend exposing RESTful and WebSocket endpoints
|
||||
- Location: `apps/server/src/`
|
||||
- Contains: Route handlers, business logic services, middleware, provider adapters
|
||||
- Depends on: @automaker/types, @automaker/utils, @automaker/platform, Claude Agent SDK
|
||||
- Used by: UI frontend via HTTP/WebSocket
|
||||
|
||||
**Service Layer (Server):**
|
||||
|
||||
- Purpose: Business logic and domain operations
|
||||
- Location: `apps/server/src/services/`
|
||||
- Contains: AgentService, FeatureLoader, AutoModeService, SettingsService, DevServerService, etc.
|
||||
- Depends on: Providers, secure filesystem, feature storage
|
||||
- Used by: Route handlers
|
||||
|
||||
**Provider Abstraction (Server):**
|
||||
|
||||
- Purpose: Unified interface for different AI model providers
|
||||
- Location: `apps/server/src/providers/`
|
||||
- Contains: ProviderFactory, specific provider implementations (ClaudeProvider, CursorProvider, CodexProvider, GeminiProvider, OpencodeProvider, CopilotProvider)
|
||||
- Depends on: @automaker/types, provider SDKs
|
||||
- Used by: AgentService
|
||||
|
||||
**Shared Library Layer:**
|
||||
|
||||
- Purpose: Type definitions and utilities shared across apps
|
||||
- Location: `libs/`
|
||||
- Contains: @automaker/types, @automaker/utils, @automaker/platform, @automaker/prompts, @automaker/model-resolver, @automaker/dependency-resolver, @automaker/git-utils, @automaker/spec-parser
|
||||
- Depends on: None (types has no external deps)
|
||||
- Used by: All apps and services
|
||||
|
||||
## Data Flow
|
||||
|
||||
**Feature Execution Flow:**
|
||||
|
||||
1. User creates/updates feature via UI (`apps/ui/src/`)
|
||||
2. UI sends HTTP request to backend (`POST /api/features`)
|
||||
3. Server route handler invokes FeatureLoader to persist to `.automaker/features/{featureId}/`
|
||||
4. When executing, AgentService loads feature, creates isolated git worktree via @automaker/git-utils
|
||||
5. AgentService invokes ProviderFactory to get appropriate AI provider (Claude, Cursor, etc.)
|
||||
6. Provider executes with context from CLAUDE.md files via @automaker/utils loadContextFiles()
|
||||
7. Server emits events via EventEmitter throughout execution
|
||||
8. Events stream to frontend via WebSocket
|
||||
9. UI updates stores and renders real-time progress
|
||||
10. Feature results persist back to `.automaker/features/` with generated agent-output.md
|
||||
|
||||
**State Management:**
|
||||
|
||||
**Frontend State (Zustand):**
|
||||
|
||||
- `app-store.ts`: Global app state (projects, features, settings, boards, themes)
|
||||
- `setup-store.ts`: First-time setup wizard flow
|
||||
- `ideation-store.ts`: Ideation feature state
|
||||
- `test-runners-store.ts`: Test runner configurations
|
||||
- Settings now persist via API (`/api/settings`) rather than localStorage (see use-settings-sync.ts)
|
||||
|
||||
**Backend State (Services):**
|
||||
|
||||
- SettingsService: Global and project-specific settings (in-memory with file persistence)
|
||||
- AgentService: Active agent sessions and conversation history
|
||||
- FeatureLoader: Feature data model operations
|
||||
- DevServerService: Development server logs
|
||||
- EventHistoryService: Persists event logs for replay
|
||||
|
||||
**Real-Time Updates (WebSocket):**
|
||||
|
||||
- Server EventEmitter emits TypedEvent (type + payload)
|
||||
- WebSocket handler subscribes to events and broadcasts to all clients
|
||||
- Frontend listens on multiple WebSocket subscriptions and updates stores
|
||||
|
||||
## Key Abstractions
|
||||
|
||||
**Feature:**
|
||||
|
||||
- Purpose: Represents a development task/story with rich metadata
|
||||
- Location: @automaker/types → `libs/types/src/feature.ts`
|
||||
- Fields: id, title, description, status, images, tasks, priority, etc.
|
||||
- Stored: `.automaker/features/{featureId}/feature.json`
|
||||
|
||||
**Provider:**
|
||||
|
||||
- Purpose: Abstracts different AI model implementations
|
||||
- Location: `apps/server/src/providers/{provider}-provider.ts`
|
||||
- Interface: Common execute() method with consistent message format
|
||||
- Implementations: Claude, Cursor, Codex, Gemini, OpenCode, Copilot
|
||||
- Factory: ProviderFactory picks correct provider based on model ID
|
||||
|
||||
**Event:**
|
||||
|
||||
- Purpose: Real-time updates streamed to frontend
|
||||
- Location: @automaker/types → `libs/types/src/event.ts`
|
||||
- Format: { type: EventType, payload: unknown }
|
||||
- Examples: agent-started, agent-step, agent-complete, feature-updated, etc.
|
||||
|
||||
**AgentSession:**
|
||||
|
||||
- Purpose: Represents a conversation between user and AI agent
|
||||
- Location: @automaker/types → `libs/types/src/session.ts`
|
||||
- Contains: Messages (user + assistant), metadata, creation timestamp
|
||||
- Stored: `{DATA_DIR}/agent-sessions/{sessionId}.json`
|
||||
|
||||
**Settings:**
|
||||
|
||||
- Purpose: Configuration for global and per-project behavior
|
||||
- Location: @automaker/types → `libs/types/src/settings.ts`
|
||||
- Stored: Global in `{DATA_DIR}/settings.json`, per-project in `.automaker/settings.json`
|
||||
- Service: SettingsService in `apps/server/src/services/settings-service.ts`
|
||||
|
||||
## Entry Points
|
||||
|
||||
**Server:**
|
||||
|
||||
- Location: `apps/server/src/index.ts`
|
||||
- Triggers: `npm run dev:server` or Docker startup
|
||||
- Responsibilities:
|
||||
- Initialize Express app with middleware
|
||||
- Create shared EventEmitter for WebSocket streaming
|
||||
- Bootstrap services (SettingsService, AgentService, FeatureLoader, etc.)
|
||||
- Mount API routes at `/api/*`
|
||||
- Create WebSocket servers for agent streaming and terminal sessions
|
||||
- Load and apply user settings (log level, request logging, etc.)
|
||||
|
||||
**UI (Web):**
|
||||
|
||||
- Location: `apps/ui/src/main.ts` (Vite entry), `apps/ui/src/app.tsx` (React component)
|
||||
- Triggers: `npm run dev:web` or `npm run build`
|
||||
- Responsibilities:
|
||||
- Initialize Zustand stores from API settings
|
||||
- Setup React Router with TanStack Router
|
||||
- Render root layout with sidebar and main content area
|
||||
- Handle authentication via verifySession()
|
||||
|
||||
**UI (Electron):**
|
||||
|
||||
- Location: `apps/ui/src/main.ts` (Vite entry), `apps/ui/electron/main-process.ts` (Electron main process)
|
||||
- Triggers: `npm run dev:electron`
|
||||
- Responsibilities:
|
||||
- Launch local server via node-pty
|
||||
- Create native Electron window
|
||||
- Bridge IPC between renderer and main process
|
||||
- Provide file system access via preload.ts APIs
|
||||
|
||||
## Error Handling
|
||||
|
||||
**Strategy:** Layered error classification and user-friendly messaging
|
||||
|
||||
**Patterns:**
|
||||
|
||||
**Backend Error Handling:**
|
||||
|
||||
- Errors classified via `classifyError()` from @automaker/utils
|
||||
- Classification: ParseError, NetworkError, AuthenticationError, RateLimitError, etc.
|
||||
- Response format: `{ success: false, error: { type, message, code }, details? }`
|
||||
- Example: `apps/server/src/lib/error-handler.ts`
|
||||
|
||||
**Frontend Error Handling:**
|
||||
|
||||
- HTTP errors caught by api-fetch.ts with retry logic
|
||||
- WebSocket disconnects trigger reconnection with exponential backoff
|
||||
- Errors shown in toast notifications via `sonner` library
|
||||
- Validation errors caught and displayed inline in forms
|
||||
|
||||
**Agent Execution Errors:**
|
||||
|
||||
- AgentService wraps provider calls in try-catch
|
||||
- Aborts handled specially via `isAbortError()` check
|
||||
- Rate limit errors trigger cooldown before retry
|
||||
- Model-specific errors mapped to user guidance
|
||||
|
||||
## Cross-Cutting Concerns
|
||||
|
||||
**Logging:**
|
||||
|
||||
- Framework: @automaker/utils createLogger()
|
||||
- Pattern: `const logger = createLogger('ModuleName')`
|
||||
- Levels: ERROR, WARN, INFO, DEBUG (configurable via settings)
|
||||
- Output: stdout (dev), files (production)
|
||||
|
||||
**Validation:**
|
||||
|
||||
- File path validation: @automaker/platform initAllowedPaths() enforces restrictions
|
||||
- Model ID validation: @automaker/model-resolver resolveModelString()
|
||||
- JSON schema validation: Manual checks in route handlers (no JSON schema lib)
|
||||
- Authentication: Session token validation via validateWsConnectionToken()
|
||||
|
||||
**Authentication:**
|
||||
|
||||
- Frontend: Session token stored in httpOnly cookie
|
||||
- Backend: authMiddleware checks token on protected routes
|
||||
- WebSocket: validateWsConnectionToken() for upgrade requests
|
||||
- Providers: API keys stored encrypted in `{DATA_DIR}/credentials.json`
|
||||
|
||||
**Internationalization:**
|
||||
|
||||
- Not detected - strings are English-only
|
||||
|
||||
**Performance:**
|
||||
|
||||
- Code splitting: File-based routing via TanStack Router
|
||||
- Lazy loading: React.lazy() in route components
|
||||
- Caching: React Query for HTTP requests (query-keys.ts defines cache strategy)
|
||||
- Image optimization: Automatic base64 encoding for agent context
|
||||
- State hydration: Settings loaded once at startup, synced via API
|
||||
|
||||
---
|
||||
|
||||
_Architecture analysis: 2026-01-27_
|
||||
Reference in New Issue
Block a user