mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 08:13:37 +00:00
- 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
8.8 KiB
8.8 KiB
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:
- User creates/updates feature via UI (
apps/ui/src/) - UI sends HTTP request to backend (
POST /api/features) - Server route handler invokes FeatureLoader to persist to
.automaker/features/{featureId}/ - When executing, AgentService loads feature, creates isolated git worktree via @automaker/git-utils
- AgentService invokes ProviderFactory to get appropriate AI provider (Claude, Cursor, etc.)
- Provider executes with context from CLAUDE.md files via @automaker/utils loadContextFiles()
- Server emits events via EventEmitter throughout execution
- Events stream to frontend via WebSocket
- UI updates stores and renders real-time progress
- 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 flowideation-store.ts: Ideation feature statetest-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:serveror 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:webornpm 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
sonnerlibrary - 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