diff --git a/CLAUDE.md b/CLAUDE.md index c9ef839..ef1d7d0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -54,6 +54,12 @@ python autonomous_agent_demo.py --project-dir my-app --yolo # Parallel mode: run multiple agents concurrently (1-5 agents) python autonomous_agent_demo.py --project-dir my-app --parallel --max-concurrency 3 + +# Batch mode: implement multiple features per agent session (1-3) +python autonomous_agent_demo.py --project-dir my-app --batch-size 3 + +# Batch specific features by ID +python autonomous_agent_demo.py --project-dir my-app --batch-features 1,2,3 ``` ### YOLO Mode (Rapid Prototyping) @@ -68,7 +74,7 @@ python autonomous_agent_demo.py --project-dir my-app --yolo ``` **What's different in YOLO mode:** -- No regression testing (skips `feature_get_for_regression`) +- No regression testing - No Playwright MCP server (browser automation disabled) - Features marked passing after lint/type-check succeeds - Faster iteration for prototyping @@ -97,10 +103,13 @@ npm run lint # Run ESLint ### Python ```bash -ruff check . # Lint -mypy . # Type check -python test_security.py # Security unit tests (163 tests) -python test_security_integration.py # Integration tests (9 tests) +ruff check . # Lint +mypy . # Type check +python test_security.py # Security unit tests (12 tests) +python test_security_integration.py # Integration tests (9 tests) +python -m pytest test_client.py # Client tests (20 tests) +python -m pytest test_dependency_resolver.py # Dependency resolver tests (12 tests) +python -m pytest test_rate_limit_utils.py # Rate limit tests (22 tests) ``` ### React UI @@ -108,11 +117,17 @@ python test_security_integration.py # Integration tests (9 tests) ```bash cd ui npm run lint # ESLint -npm run build # Type check + build +npm run build # Type check + build (Vite 7) npm run test:e2e # Playwright end-to-end tests npm run test:e2e:ui # Playwright tests with UI ``` +### CI/CD + +GitHub Actions (`.github/workflows/ci.yml`) runs on push/PR to master: +- **Python job**: ruff lint + security tests +- **UI job**: ESLint + TypeScript build + ### Code Quality Configuration in `pyproject.toml`: @@ -124,16 +139,21 @@ Configuration in `pyproject.toml`: ### Core Python Modules - `start.py` - CLI launcher with project creation/selection menu -- `autonomous_agent_demo.py` - Entry point for running the agent +- `autonomous_agent_demo.py` - Entry point for running the agent (supports `--yolo`, `--parallel`, `--batch-size`, `--batch-features`) - `autocoder_paths.py` - Central path resolution with dual-path backward compatibility and migration - `agent.py` - Agent session loop using Claude Agent SDK -- `client.py` - ClaudeSDKClient configuration with security hooks and MCP servers +- `client.py` - ClaudeSDKClient configuration with security hooks, MCP servers, and Vertex AI support - `security.py` - Bash command allowlist validation (ALLOWED_COMMANDS whitelist) -- `prompts.py` - Prompt template loading with project-specific fallback +- `prompts.py` - Prompt template loading with project-specific fallback and batch feature prompts - `progress.py` - Progress tracking, database queries, webhook notifications -- `registry.py` - Project registry for mapping names to paths (cross-platform) +- `registry.py` - Project registry for mapping names to paths (cross-platform), global settings model - `parallel_orchestrator.py` - Concurrent agent execution with dependency-aware scheduling +- `auth.py` - Authentication error detection for Claude CLI +- `env_constants.py` - Shared environment variable constants (API_ENV_VARS) used by client.py and chat sessions +- `rate_limit_utils.py` - Rate limit detection, retry parsing, exponential backoff with jitter +- `api/database.py` - SQLAlchemy models (Feature, Schedule, ScheduleOverride) - `api/dependency_resolver.py` - Cycle detection (Kahn's algorithm + DFS) and dependency validation +- `api/migration.py` - JSON-to-SQLite migration utility ### Project Registry @@ -147,13 +167,36 @@ The registry uses: ### Server API (server/) -The FastAPI server provides REST endpoints for the UI: +The FastAPI server provides REST and WebSocket endpoints for the UI: -- `server/routers/projects.py` - Project CRUD with registry integration -- `server/routers/features.py` - Feature management -- `server/routers/agent.py` - Agent control (start/stop/pause/resume) -- `server/routers/filesystem.py` - Filesystem browser API with security controls -- `server/routers/spec_creation.py` - WebSocket for interactive spec creation +**Routers** (`server/routers/`): +- `projects.py` - Project CRUD with registry integration +- `features.py` - Feature management +- `agent.py` - Agent control (start/stop/pause/resume) +- `filesystem.py` - Filesystem browser API with security controls +- `spec_creation.py` - WebSocket for interactive spec creation +- `expand_project.py` - Interactive project expansion via natural language +- `assistant_chat.py` - Read-only project assistant chat (WebSocket/REST) +- `terminal.py` - Interactive terminal I/O with PTY support (WebSocket bidirectional) +- `devserver.py` - Dev server control (start/stop) and config +- `schedules.py` - CRUD for time-based agent scheduling +- `settings.py` - Global settings management (model selection, YOLO, batch size, headless browser) + +**Services** (`server/services/`): +- `process_manager.py` - Agent process lifecycle management +- `project_config.py` - Project type detection and dev command management +- `terminal_manager.py` - Terminal session management with PTY (`pywinpty` on Windows) +- `scheduler_service.py` - APScheduler-based automated agent scheduling +- `dev_server_manager.py` - Dev server lifecycle management +- `assistant_chat_session.py` / `assistant_database.py` - Assistant chat sessions with SQLite persistence +- `spec_chat_session.py` - Spec creation chat sessions +- `expand_chat_session.py` - Expand project chat sessions +- `chat_constants.py` - Shared constants for chat services + +**Utilities** (`server/utils/`): +- `process_utils.py` - Process management utilities +- `project_helpers.py` - Project path resolution helpers +- `validation.py` - Project name validation ### Feature Management @@ -164,18 +207,26 @@ Features are stored in SQLite (`features.db`) via SQLAlchemy. The agent interact MCP tools available to the agent: - `feature_get_stats` - Progress statistics -- `feature_get_next` - Get highest-priority pending feature (respects dependencies) -- `feature_claim_next` - Atomically claim next available feature (for parallel mode) -- `feature_get_for_regression` - Random passing features for regression testing +- `feature_get_by_id` - Get a single feature by ID +- `feature_get_summary` - Get summary of all features +- `feature_get_ready` - Get features ready to work on (dependencies met) +- `feature_get_blocked` - Get features blocked by unmet dependencies +- `feature_get_graph` - Get full dependency graph +- `feature_claim_and_get` - Atomically claim next available feature (for parallel mode) +- `feature_mark_in_progress` - Mark feature as in progress - `feature_mark_passing` - Mark feature complete +- `feature_mark_failing` - Mark feature as failing - `feature_skip` - Move feature to end of queue +- `feature_clear_in_progress` - Clear in-progress status - `feature_create_bulk` - Initialize all features (used by initializer) +- `feature_create` - Create a single feature - `feature_add_dependency` - Add dependency between features (with cycle detection) - `feature_remove_dependency` - Remove a dependency +- `feature_set_dependencies` - Set all dependencies for a feature at once ### React UI (ui/) -- Tech stack: React 19, TypeScript, TanStack Query, Tailwind CSS v4, Radix UI, dagre (graph layout) +- Tech stack: React 19, TypeScript, Vite 7, TanStack Query, Tailwind CSS v4, Radix UI, dagre (graph layout), xterm.js (terminal) - `src/App.tsx` - Main app with project selection, kanban board, agent controls - `src/hooks/useWebSocket.ts` - Real-time updates via WebSocket (progress, agent status, logs, agent updates) - `src/hooks/useProjects.ts` - React Query hooks for API calls @@ -187,6 +238,12 @@ Key components: - `DependencyGraph.tsx` - Interactive node graph visualization with dagre layout - `CelebrationOverlay.tsx` - Confetti animation on feature completion - `FolderBrowser.tsx` - Server-side filesystem browser for project folder selection +- `Terminal.tsx` / `TerminalTabs.tsx` - xterm.js-based multi-tab terminal +- `AssistantPanel.tsx` / `AssistantChat.tsx` - AI assistant for project Q&A +- `ExpandProjectModal.tsx` / `ExpandProjectChat.tsx` - Add features via natural language +- `DevServerControl.tsx` - Dev server start/stop control +- `ScheduleModal.tsx` - Schedule management UI +- `SettingsModal.tsx` - Global settings panel Keyboard shortcuts (press `?` for help): - `D` - Toggle debug panel @@ -248,15 +305,6 @@ The following directories (relative to home) are always blocked: - `.docker`, `.config/gcloud` - Container/cloud configs - `.npmrc`, `.pypirc`, `.netrc` - Package manager credentials -**Example Output:** - -``` -Created security settings at /path/to/project/.claude_settings.json - - Sandbox enabled (OS-level bash isolation) - - Filesystem restricted to: /path/to/project - - Extra read paths (validated): /Users/me/docs, /opt/shared-libs -``` - #### Per-Project Allowed Commands The agent's bash command access is controlled through a hierarchical configuration system: @@ -318,13 +366,29 @@ blocked_commands: **Files:** - `security.py` - Command validation logic and hardcoded blocklist -- `test_security.py` - Unit tests for security system (136 tests) -- `test_security_integration.py` - Integration tests with real hooks (9 tests) -- `TEST_SECURITY.md` - Quick testing reference guide +- `test_security.py` - Unit tests for security system +- `test_security_integration.py` - Integration tests with real hooks - `examples/project_allowed_commands.yaml` - Project config example (all commented by default) - `examples/org_config.yaml` - Org config example (all commented by default) - `examples/README.md` - Comprehensive guide with use cases, testing, and troubleshooting +### Vertex AI Configuration (Optional) + +Run coding agents via Google Cloud Vertex AI: + +1. Install and authenticate gcloud CLI: `gcloud auth application-default login` +2. Configure `.env`: + ``` + CLAUDE_CODE_USE_VERTEX=1 + CLOUD_ML_REGION=us-east5 + ANTHROPIC_VERTEX_PROJECT_ID=your-gcp-project-id + ANTHROPIC_DEFAULT_OPUS_MODEL=claude-opus-4-5@20251101 + ANTHROPIC_DEFAULT_SONNET_MODEL=claude-sonnet-4-5@20250929 + ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-3-5-haiku@20241022 + ``` + +**Note:** Use `@` instead of `-` in model names for Vertex AI. + ### Ollama Local Models (Optional) Run coding agents using local models via Ollama v0.14.0+: @@ -360,8 +424,24 @@ Run coding agents using local models via Ollama v0.14.0+: ## Claude Code Integration -- `.claude/commands/create-spec.md` - `/create-spec` slash command for interactive spec creation -- `.claude/skills/frontend-design/SKILL.md` - Skill for distinctive UI design +**Slash commands** (`.claude/commands/`): +- `/create-spec` - Interactive spec creation for new projects +- `/expand-project` - Expand existing project with new features +- `/gsd-to-autocoder-spec` - Convert GSD codebase mapping to app_spec.txt +- `/check-code` - Run lint and type-check for code quality +- `/checkpoint` - Create comprehensive checkpoint commit +- `/review-pr` - Review pull requests + +**Custom agents** (`.claude/agents/`): +- `coder.md` - Elite software architect agent for code implementation (Opus) +- `code-review.md` - Code review agent for quality/security/performance analysis (Opus) +- `deep-dive.md` - Technical investigator for deep analysis and debugging (Opus) + +**Skills** (`.claude/skills/`): +- `frontend-design` - Distinctive, production-grade UI design +- `gsd-to-autocoder-spec` - Convert GSD codebase mapping to Autocoder app_spec format + +**Other:** - `.claude/templates/` - Prompt templates copied to new projects - `examples/` - Configuration examples and documentation for security settings @@ -392,7 +472,7 @@ The UI receives updates via WebSocket (`/ws/projects/{project_name}`): When running with `--parallel`, the orchestrator: 1. Spawns multiple Claude agents as subprocesses (up to `--max-concurrency`) -2. Each agent claims features atomically via `feature_claim_next` +2. Each agent claims features atomically via `feature_claim_and_get` 3. Features blocked by unmet dependencies are skipped 4. Browser contexts are isolated per agent using `--isolated` flag 5. AgentTracker parses output and emits `agent_update` messages for UI @@ -405,6 +485,16 @@ The orchestrator enforces strict bounds on concurrent processes: - Testing agents are capped at `max_concurrency` (same as coding agents) - Total process count never exceeds 11 Python processes (1 orchestrator + 5 coding + 5 testing) +### Multi-Feature Batching + +Agents can implement multiple features per session using `--batch-size` (1-3, default: 3): +- `--batch-size N` - Max features per coding agent batch +- `--testing-batch-size N` - Features per testing batch (1-5, default: 3) +- `--batch-features 1,2,3` - Specific feature IDs for batch implementation +- `--testing-batch-features 1,2,3` - Specific feature IDs for batch regression testing +- `prompts.py` provides `get_batch_feature_prompt()` for multi-feature prompt generation +- Configurable in UI via settings panel + ### Design System The UI uses a **neobrutalism** design with Tailwind CSS v4: diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 9842f9d..dcfe729 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -28,7 +28,7 @@ import { ThemeSelector } from './components/ThemeSelector' import { ResetProjectModal } from './components/ResetProjectModal' import { ProjectSetupRequired } from './components/ProjectSetupRequired' import { getDependencyGraph, startAgent } from './lib/api' -import { Loader2, Settings, Moon, Sun, RotateCcw } from 'lucide-react' +import { Loader2, Settings, Moon, Sun, RotateCcw, BookOpen } from 'lucide-react' import type { Feature } from './lib/types' import { Button } from '@/components/ui/button' import { Card, CardContent } from '@/components/ui/card' @@ -335,6 +335,17 @@ function App() { )} + {/* Docs link */} + + {/* Theme selector */} void +} + +/** + * Maps each section id from docsData to its corresponding React component. + * Order matches DOC_SECTIONS so we can iterate safely. + */ +const SECTION_COMPONENTS: Record = { + 'getting-started': GettingStarted, + 'app-spec-setup': AppSpecSetup, + 'project-structure': ProjectStructure, + 'features-kanban': FeaturesKanban, + 'agent-system': AgentSystem, + 'settings-config': SettingsConfig, + 'developer-tools': DeveloperTools, + 'ai-assistant': AIAssistant, + scheduling: Scheduling, + 'appearance-themes': AppearanceThemes, + security: Security, + 'advanced-config': AdvancedConfig, + faq: FAQ, +} + +export function DocsContent({ onSectionVisible }: DocsContentProps) { + const containerRef = useRef(null) + // Store refs to each section heading element so the observer can watch them + const headingRefs = useRef>(new Map()) + + // Stable callback ref setter -- avoids recreating refs on every render + const setHeadingRef = useCallback((id: string, element: HTMLElement | null) => { + if (element) { + headingRefs.current.set(id, element) + } else { + headingRefs.current.delete(id) + } + }, []) + + // IntersectionObserver: track which section heading is at or near the top of the viewport + useEffect(() => { + const headings = headingRefs.current + if (headings.size === 0) return + + // rootMargin: trigger when a heading enters the top 20% of the viewport. + // This ensures the sidebar updates *before* the user scrolls past the heading. + const observer = new IntersectionObserver( + (entries) => { + // Find the topmost visible heading -- the one closest to the top of the viewport + const visible = entries + .filter((entry) => entry.isIntersecting) + .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top) + + if (visible.length > 0) { + const topEntry = visible[0] + const sectionId = topEntry.target.getAttribute('data-section-id') + if (sectionId) { + onSectionVisible(sectionId) + } + } + }, + { + // Observe from the very top of the viewport down to -60% from the bottom, + // so headings are detected while in the upper portion of the screen. + rootMargin: '0px 0px -60% 0px', + threshold: 0, + }, + ) + + headings.forEach((element) => observer.observe(element)) + + return () => observer.disconnect() + }, [onSectionVisible]) + + return ( +
+ {DOC_SECTIONS.map((section) => { + const SectionComponent = SECTION_COMPONENTS[section.id] + if (!SectionComponent) return null + + const Icon = section.icon + + return ( +
+ {/* Section heading with anchor */} +

setHeadingRef(section.id, el)} + data-section-id={section.id} + className="font-display text-2xl font-bold tracking-tight mb-6 flex items-center gap-3 + text-foreground border-b-2 border-border pb-3" + > + + {section.title} +

+ + {/* Section body */} + +
+ ) + })} +
+ ) +} diff --git a/ui/src/components/docs/DocsPage.tsx b/ui/src/components/docs/DocsPage.tsx new file mode 100644 index 0000000..25288cc --- /dev/null +++ b/ui/src/components/docs/DocsPage.tsx @@ -0,0 +1,215 @@ +/** + * DocsPage Component + * + * Main layout for the documentation route (#/docs). + * Full-page layout with a sticky header, collapsible sidebar on the left, + * and scrollable content area on the right. + * + * Mobile-responsive: sidebar collapses behind a hamburger menu that + * opens as an overlay. + */ + +import { useState, useEffect, useCallback } from 'react' +import { ArrowLeft, Menu, X, Moon, Sun } from 'lucide-react' +import { useHashRoute } from '../../hooks/useHashRoute' +import { useTheme } from '../../hooks/useTheme' +import { ThemeSelector } from '../ThemeSelector' +import { Button } from '@/components/ui/button' +import { Badge } from '@/components/ui/badge' +import { DocsSidebar } from './DocsSidebar' +import { DocsSearch } from './DocsSearch' +import { DocsContent } from './DocsContent' + +export function DocsPage() { + const [activeSectionId, setActiveSectionId] = useState(null) + const [searchQuery, setSearchQuery] = useState('') + const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false) + + const { section: initialSection } = useHashRoute() + const { theme, setTheme, darkMode, toggleDarkMode, themes } = useTheme() + + // On mount, if the hash includes a section id (e.g. #/docs/getting-started), + // scroll to it and set it as active + useEffect(() => { + if (initialSection) { + setActiveSectionId(initialSection) + // Delay scroll slightly so the DOM is rendered + requestAnimationFrame(() => { + const element = document.getElementById(initialSection) + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }) + } + }) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) // Run only on mount + + // When a sidebar item is clicked, scroll the corresponding element into view + const handleSectionClick = useCallback((id: string) => { + setActiveSectionId(id) + + // Update hash for linkability (without triggering a route change) + history.replaceState(null, '', `#/docs/${id}`) + + const element = document.getElementById(id) + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }) + } + }, []) + + // Called by DocsContent's IntersectionObserver when a heading scrolls into view + const handleSectionVisible = useCallback((id: string) => { + setActiveSectionId(id) + }, []) + + // Close mobile sidebar when pressing Escape + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape' && mobileSidebarOpen) { + setMobileSidebarOpen(false) + } + } + + window.addEventListener('keydown', handleKeyDown) + return () => window.removeEventListener('keydown', handleKeyDown) + }, [mobileSidebarOpen]) + + // Prevent body scroll when mobile sidebar overlay is open + useEffect(() => { + if (mobileSidebarOpen) { + document.body.style.overflow = 'hidden' + } else { + document.body.style.overflow = '' + } + return () => { + document.body.style.overflow = '' + } + }, [mobileSidebarOpen]) + + return ( +
+ {/* Sticky header */} +
+
+
+ {/* Left side: hamburger (mobile) + title + badge */} +
+ {/* Mobile hamburger button -- only visible below lg breakpoint */} + + + + AutoCoder + + + + Documentation + +
+ + {/* Right side: theme controls + back button */} +
+ + + + + +
+
+
+
+ + {/* Body: sidebar + content */} +
+ {/* ---------------------------------------------------------------- + Desktop sidebar -- visible at lg and above + Fixed width, sticky below the header, independently scrollable + ---------------------------------------------------------------- */} + + + {/* ---------------------------------------------------------------- + Mobile sidebar overlay -- visible below lg breakpoint + ---------------------------------------------------------------- */} + {mobileSidebarOpen && ( + <> + {/* Backdrop */} +
setMobileSidebarOpen(false)} + aria-hidden="true" + /> + + {/* Sidebar panel */} + + + )} + + {/* ---------------------------------------------------------------- + Content area -- fills remaining space, scrollable + ---------------------------------------------------------------- */} +
+
+ +
+
+
+
+ ) +} diff --git a/ui/src/components/docs/DocsSearch.tsx b/ui/src/components/docs/DocsSearch.tsx new file mode 100644 index 0000000..896f3cd --- /dev/null +++ b/ui/src/components/docs/DocsSearch.tsx @@ -0,0 +1,78 @@ +/** + * DocsSearch Component + * + * Search input for the documentation sidebar. + * Supports Ctrl/Cmd+K keyboard shortcut to focus, + * and shows a keyboard hint when the input is empty. + */ + +import { useRef, useEffect } from 'react' +import { Search, X } from 'lucide-react' + +interface DocsSearchProps { + value: string + onChange: (value: string) => void +} + +export function DocsSearch({ value, onChange }: DocsSearchProps) { + const inputRef = useRef(null) + + // Global keyboard shortcut: Ctrl/Cmd+K focuses the search input + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if ((e.ctrlKey || e.metaKey) && e.key === 'k') { + e.preventDefault() + inputRef.current?.focus() + } + } + + window.addEventListener('keydown', handleKeyDown) + return () => window.removeEventListener('keydown', handleKeyDown) + }, []) + + return ( +
+ {/* Search icon */} + + + onChange(e.target.value)} + placeholder="Search docs..." + className="w-full pl-9 pr-16 py-2 text-sm bg-muted border border-border rounded-lg + text-foreground placeholder:text-muted-foreground + focus:outline-none focus:ring-2 focus:ring-ring/50 focus:border-ring + transition-colors" + /> + + {/* Right side: clear button when has value, otherwise Ctrl+K hint */} + {value ? ( + + ) : ( + + Ctrl+K + + )} +
+ ) +} diff --git a/ui/src/components/docs/DocsSidebar.tsx b/ui/src/components/docs/DocsSidebar.tsx new file mode 100644 index 0000000..4be7576 --- /dev/null +++ b/ui/src/components/docs/DocsSidebar.tsx @@ -0,0 +1,189 @@ +/** + * DocsSidebar Component + * + * Left sidebar navigation for the documentation page. + * Lists all sections from docsData with expandable subsections. + * Supports search filtering with auto-expansion of matching sections. + */ + +import { useState, useMemo } from 'react' +import { ChevronRight } from 'lucide-react' +import { DOC_SECTIONS, type DocSection } from './docsData' + +interface DocsSidebarProps { + activeSectionId: string | null + onSectionClick: (id: string) => void + searchQuery: string + onMobileClose?: () => void +} + +export function DocsSidebar({ + activeSectionId, + onSectionClick, + searchQuery, + onMobileClose, +}: DocsSidebarProps) { + // Track which top-level sections are manually expanded by the user + const [expandedSections, setExpandedSections] = useState>(() => { + // Start with the first section expanded so the sidebar is not fully collapsed + const initial = new Set() + if (DOC_SECTIONS.length > 0) { + initial.add(DOC_SECTIONS[0].id) + } + return initial + }) + + const normalizedQuery = searchQuery.trim().toLowerCase() + + // Filter sections based on search query, matching against section title, + // subsection titles, and keywords + const filteredSections = useMemo(() => { + if (!normalizedQuery) { + return DOC_SECTIONS + } + + return DOC_SECTIONS.filter((section) => { + // Check section title + if (section.title.toLowerCase().includes(normalizedQuery)) return true + + // Check keywords + if (section.keywords.some((kw) => kw.toLowerCase().includes(normalizedQuery))) return true + + // Check subsection titles + if (section.subsections.some((sub) => sub.title.toLowerCase().includes(normalizedQuery))) { + return true + } + + return false + }) + }, [normalizedQuery]) + + // Determine which sections should appear expanded: + // - When searching: auto-expand all matching sections + // - Otherwise: use manual expanded state, plus expand whichever section contains the active item + const isSectionExpanded = (sectionId: string): boolean => { + if (normalizedQuery) return true + + if (expandedSections.has(sectionId)) return true + + // Also expand the section that contains the currently active subsection + if (activeSectionId) { + const section = DOC_SECTIONS.find((s) => s.id === sectionId) + if (section) { + if (section.id === activeSectionId) return true + if (section.subsections.some((sub) => sub.id === activeSectionId)) return true + } + } + + return false + } + + const toggleSection = (sectionId: string) => { + setExpandedSections((prev) => { + const next = new Set(prev) + if (next.has(sectionId)) { + next.delete(sectionId) + } else { + next.add(sectionId) + } + return next + }) + } + + /** + * Checks whether a given id (section or subsection) is the currently active item. + * Active items get a highlighted visual treatment. + */ + const isActive = (id: string): boolean => activeSectionId === id + + /** + * Checks whether a section contains the active subsection. + * Used to highlight parent sections in a muted way. + */ + const sectionContainsActive = (section: DocSection): boolean => { + if (!activeSectionId) return false + return section.subsections.some((sub) => sub.id === activeSectionId) + } + + const handleItemClick = (id: string) => { + onSectionClick(id) + // On mobile, close the sidebar after navigation + onMobileClose?.() + } + + return ( + + ) +} diff --git a/ui/src/components/docs/docsData.ts b/ui/src/components/docs/docsData.ts new file mode 100644 index 0000000..d7b2875 --- /dev/null +++ b/ui/src/components/docs/docsData.ts @@ -0,0 +1,222 @@ +import { + Rocket, + FileText, + FolderTree, + LayoutGrid, + Bot, + Settings, + Terminal, + MessageSquare, + Clock, + Palette, + Shield, + Wrench, + HelpCircle, + type LucideIcon, +} from 'lucide-react' + +export interface DocSubsection { + id: string + title: string +} + +export interface DocSection { + id: string + title: string + icon: LucideIcon + subsections: DocSubsection[] + keywords: string[] +} + +export const DOC_SECTIONS: DocSection[] = [ + { + id: 'getting-started', + title: 'Getting Started', + icon: Rocket, + subsections: [ + { id: 'what-is-autocoder', title: 'What is AutoCoder?' }, + { id: 'quick-start', title: 'Quick Start' }, + { id: 'creating-a-project', title: 'Creating a New Project' }, + { id: 'existing-project', title: 'Adding to an Existing Project' }, + { id: 'system-requirements', title: 'System Requirements' }, + ], + keywords: ['install', 'setup', 'start', 'begin', 'new', 'requirements', 'prerequisites'], + }, + { + id: 'app-spec-setup', + title: 'App Spec & Project Setup', + icon: FileText, + subsections: [ + { id: 'what-is-app-spec', title: 'What is an App Spec?' }, + { id: 'creating-spec-with-claude', title: 'Creating a Spec with Claude' }, + { id: 'writing-spec-manually', title: 'Writing a Spec Manually' }, + { id: 'initializer-agent', title: 'The Initializer Agent' }, + { id: 'starting-after-spec', title: 'Starting After Spec Creation' }, + ], + keywords: ['spec', 'specification', 'xml', 'app_spec', 'initializer', 'prompt', 'template'], + }, + { + id: 'project-structure', + title: 'Target Project Structure', + icon: FolderTree, + subsections: [ + { id: 'autocoder-directory', title: '.autocoder/ Directory Layout' }, + { id: 'features-db', title: 'Features Database' }, + { id: 'prompts-directory', title: 'Prompts Directory' }, + { id: 'allowed-commands-yaml', title: 'Allowed Commands Config' }, + { id: 'claude-md', title: 'CLAUDE.md Convention' }, + { id: 'legacy-migration', title: 'Legacy Layout Migration' }, + { id: 'claude-inheritance', title: 'Claude Inheritance' }, + ], + keywords: ['folder', 'directory', 'structure', 'layout', 'files', 'database', 'sqlite', 'migration'], + }, + { + id: 'features-kanban', + title: 'Features & Kanban Board', + icon: LayoutGrid, + subsections: [ + { id: 'kanban-overview', title: 'Kanban Board Overview' }, + { id: 'feature-cards', title: 'Feature Cards' }, + { id: 'dependency-graph', title: 'Dependency Graph View' }, + { id: 'adding-features', title: 'Adding Features' }, + { id: 'editing-features', title: 'Editing & Deleting Features' }, + { id: 'feature-dependencies', title: 'Feature Dependencies' }, + { id: 'expanding-with-ai', title: 'Expanding Project with AI' }, + { id: 'feature-priority', title: 'Priority & Ordering' }, + ], + keywords: ['kanban', 'board', 'feature', 'card', 'dependency', 'graph', 'priority', 'pending', 'progress', 'done'], + }, + { + id: 'agent-system', + title: 'Agent System', + icon: Bot, + subsections: [ + { id: 'maestro-orchestrator', title: 'Maestro: The Orchestrator' }, + { id: 'coding-agents', title: 'Coding Agents' }, + { id: 'testing-agents', title: 'Testing Agents' }, + { id: 'agent-lifecycle', title: 'Agent Lifecycle' }, + { id: 'concurrency', title: 'Concurrency Control' }, + { id: 'mission-control', title: 'Agent Mission Control' }, + { id: 'agent-mascots', title: 'Agent Mascots & States' }, + { id: 'agent-logs', title: 'Viewing Agent Logs' }, + { id: 'process-limits', title: 'Process Limits' }, + ], + keywords: ['agent', 'maestro', 'orchestrator', 'coding', 'testing', 'parallel', 'concurrency', 'mascot', 'spark', 'fizz', 'octo', 'batch'], + }, + { + id: 'settings-config', + title: 'Settings & Configuration', + icon: Settings, + subsections: [ + { id: 'opening-settings', title: 'Opening Settings' }, + { id: 'yolo-mode', title: 'YOLO Mode' }, + { id: 'headless-browser', title: 'Headless Browser' }, + { id: 'model-selection', title: 'Model Selection' }, + { id: 'regression-agents', title: 'Regression Agents' }, + { id: 'features-per-agent', title: 'Features per Agent (Batch Size)' }, + { id: 'concurrency-setting', title: 'Concurrency' }, + { id: 'settings-persistence', title: 'How Settings are Persisted' }, + ], + keywords: ['settings', 'config', 'yolo', 'headless', 'model', 'opus', 'sonnet', 'haiku', 'batch', 'regression'], + }, + { + id: 'developer-tools', + title: 'Developer Tools', + icon: Terminal, + subsections: [ + { id: 'debug-panel', title: 'Debug Panel' }, + { id: 'agent-logs-tab', title: 'Agent Logs Tab' }, + { id: 'dev-server-logs', title: 'Dev Server Logs Tab' }, + { id: 'terminal', title: 'Terminal' }, + { id: 'dev-server-control', title: 'Dev Server Control' }, + { id: 'per-agent-logs', title: 'Per-Agent Logs' }, + ], + keywords: ['debug', 'terminal', 'logs', 'dev server', 'console', 'xterm', 'shell'], + }, + { + id: 'ai-assistant', + title: 'AI Assistant', + icon: MessageSquare, + subsections: [ + { id: 'what-is-assistant', title: 'What is the Assistant?' }, + { id: 'opening-assistant', title: 'Opening the Assistant' }, + { id: 'assistant-capabilities', title: 'What It Can Do' }, + { id: 'assistant-limitations', title: 'What It Cannot Do' }, + { id: 'conversation-history', title: 'Conversation History' }, + ], + keywords: ['assistant', 'ai', 'chat', 'help', 'question', 'conversation'], + }, + { + id: 'scheduling', + title: 'Scheduling', + icon: Clock, + subsections: [ + { id: 'what-scheduling-does', title: 'What Scheduling Does' }, + { id: 'creating-schedule', title: 'Creating a Schedule' }, + { id: 'schedule-settings', title: 'Schedule Settings' }, + { id: 'schedule-overrides', title: 'Schedule Overrides' }, + { id: 'crash-recovery', title: 'Crash Recovery' }, + ], + keywords: ['schedule', 'timer', 'automated', 'cron', 'run', 'recurring', 'utc'], + }, + { + id: 'appearance-themes', + title: 'Appearance & Themes', + icon: Palette, + subsections: [ + { id: 'themes-overview', title: 'Themes Overview' }, + { id: 'dark-light-mode', title: 'Dark & Light Mode' }, + { id: 'theme-selector', title: 'Theme Selector' }, + { id: 'keyboard-shortcuts', title: 'Keyboard Shortcuts' }, + ], + keywords: ['theme', 'dark', 'light', 'color', 'appearance', 'twitter', 'claude', 'neo', 'brutalism', 'retro', 'aurora', 'business', 'keyboard', 'shortcut'], + }, + { + id: 'security', + title: 'Security', + icon: Shield, + subsections: [ + { id: 'command-validation', title: 'Command Validation Overview' }, + { id: 'command-hierarchy', title: 'Command Hierarchy' }, + { id: 'hardcoded-blocklist', title: 'Hardcoded Blocklist' }, + { id: 'global-allowlist', title: 'Global Allowlist' }, + { id: 'project-allowlist', title: 'Per-Project Allowed Commands' }, + { id: 'org-config', title: 'Organization Configuration' }, + { id: 'extra-read-paths', title: 'Extra Read Paths' }, + { id: 'filesystem-sandboxing', title: 'Filesystem Sandboxing' }, + ], + keywords: ['security', 'sandbox', 'allowlist', 'blocklist', 'command', 'bash', 'permission', 'filesystem'], + }, + { + id: 'advanced-config', + title: 'Advanced Configuration', + icon: Wrench, + subsections: [ + { id: 'vertex-ai', title: 'Vertex AI Setup' }, + { id: 'ollama', title: 'Ollama Local Models' }, + { id: 'env-variables', title: 'Environment Variables' }, + { id: 'cli-arguments', title: 'CLI Arguments' }, + { id: 'webhooks', title: 'Webhook Support' }, + { id: 'project-registry', title: 'Project Registry' }, + ], + keywords: ['vertex', 'gcloud', 'ollama', 'local', 'env', 'environment', 'cli', 'webhook', 'n8n', 'registry', 'api'], + }, + { + id: 'faq', + title: 'FAQ & Troubleshooting', + icon: HelpCircle, + subsections: [ + { id: 'faq-new-project', title: 'Starting a New Project' }, + { id: 'faq-existing-project', title: 'Adding to Existing Project' }, + { id: 'faq-agent-crash', title: 'Agent Crashes' }, + { id: 'faq-custom-commands', title: 'Custom Bash Commands' }, + { id: 'faq-blocked-features', title: 'Blocked Features' }, + { id: 'faq-parallel', title: 'Running in Parallel' }, + { id: 'faq-local-model', title: 'Using Local Models' }, + { id: 'faq-reset', title: 'Resetting a Project' }, + { id: 'faq-agent-types', title: 'Coding vs Testing Agents' }, + { id: 'faq-real-time', title: 'Monitoring in Real Time' }, + ], + keywords: ['faq', 'troubleshoot', 'help', 'problem', 'issue', 'fix', 'error', 'stuck', 'reset', 'crash'], + }, +] diff --git a/ui/src/components/docs/sections/AIAssistant.tsx b/ui/src/components/docs/sections/AIAssistant.tsx new file mode 100644 index 0000000..cceb297 --- /dev/null +++ b/ui/src/components/docs/sections/AIAssistant.tsx @@ -0,0 +1,75 @@ +/** + * AIAssistant Documentation Section + * + * Covers the project assistant: what it is, how to open it, + * its capabilities and limitations, and conversation history. + */ + +import { Badge } from '@/components/ui/badge' + +export function AIAssistant() { + return ( +
+ {/* What is the Assistant? */} +

+ What is the Assistant? +

+

+ The AI Assistant is a read-only project helper that can answer questions about your project, search + code, view progress, and help you understand what’s happening — without making any changes. +

+ + {/* Opening the Assistant */} +

+ Opening the Assistant +

+
    +
  • + Press A to toggle the assistant panel +
  • +
  • Or click the floating action button (chat bubble) in the bottom-right corner
  • +
  • The panel slides in from the right side
  • +
+ + {/* What It Can Do */} +

+ What It Can Do +

+
    +
  • Read and search your project’s source code
  • +
  • Answer questions about code architecture and implementation
  • +
  • View feature progress and status
  • +
  • Create new features based on your description
  • +
  • Explain what agents have done or are currently doing
  • +
  • Help debug issues by analyzing code and logs
  • +
+ + {/* What It Cannot Do */} +

+ What It Cannot Do +

+
    +
  • Modify files (read-only access)
  • +
  • Run bash commands
  • +
  • Mark features as passing/failing
  • +
  • Start or stop agents
  • +
  • Access external APIs or the internet
  • +
+
+ This is a deliberate security design — the assistant is a safe way to interact with your project + without risk of unintended changes. +
+ + {/* Conversation History */} +

+ Conversation History +

+
    +
  • Conversations are stored per-project in SQLite database
  • +
  • Multiple conversations supported — start new ones as needed
  • +
  • Switch between conversations using the conversation selector
  • +
  • History persists across browser sessions
  • +
+
+ ) +} diff --git a/ui/src/components/docs/sections/AdvancedConfig.tsx b/ui/src/components/docs/sections/AdvancedConfig.tsx new file mode 100644 index 0000000..2ed1584 --- /dev/null +++ b/ui/src/components/docs/sections/AdvancedConfig.tsx @@ -0,0 +1,220 @@ +/** + * AdvancedConfig Documentation Section + * + * Covers Vertex AI setup, Ollama local models, environment variables, + * CLI arguments, webhook support, and the project registry. + */ + +import { Badge } from '@/components/ui/badge' + +/** Environment variable descriptor for the reference table. */ +interface EnvVar { + name: string + description: string +} + +const ENV_VARS: EnvVar[] = [ + { name: 'CLAUDE_CODE_USE_VERTEX', description: 'Enable Vertex AI (1)' }, + { name: 'CLOUD_ML_REGION', description: 'GCP region' }, + { name: 'ANTHROPIC_VERTEX_PROJECT_ID', description: 'GCP project ID' }, + { name: 'ANTHROPIC_BASE_URL', description: 'Custom API base URL (for Ollama)' }, + { name: 'ANTHROPIC_AUTH_TOKEN', description: 'API auth token' }, + { name: 'API_TIMEOUT_MS', description: 'API timeout in milliseconds' }, + { name: 'EXTRA_READ_PATHS', description: 'Comma-separated extra read directories' }, + { name: 'ANTHROPIC_DEFAULT_OPUS_MODEL', description: 'Override Opus model name' }, + { name: 'ANTHROPIC_DEFAULT_SONNET_MODEL', description: 'Override Sonnet model name' }, + { name: 'ANTHROPIC_DEFAULT_HAIKU_MODEL', description: 'Override Haiku model name' }, +] + +/** CLI argument descriptor for the reference table. */ +interface CliArg { + name: string + description: string +} + +const CLI_ARGS: CliArg[] = [ + { name: '--project-dir', description: 'Project directory path or registered name' }, + { name: '--yolo', description: 'Enable YOLO mode' }, + { name: '--parallel', description: 'Enable parallel mode' }, + { name: '--max-concurrency N', description: 'Max concurrent agents (1-5)' }, + { name: '--batch-size N', description: 'Features per coding agent (1-3)' }, + { name: '--batch-features 1,2,3', description: 'Specific feature IDs to implement' }, + { name: '--testing-batch-size N', description: 'Features per testing batch (1-5)' }, + { name: '--testing-batch-features 1,2,3', description: 'Specific testing feature IDs' }, +] + +export function AdvancedConfig() { + return ( +
+ {/* Vertex AI Setup */} +

+ Vertex AI Setup +

+

+ Run coding agents via Google Cloud Vertex AI: +

+
    +
  1. + Install and authenticate the gcloud CLI:{' '} + + gcloud auth application-default login + +
  2. +
  3. + Configure your{' '} + .env file: +
  4. +
+
+
{`CLAUDE_CODE_USE_VERTEX=1
+CLOUD_ML_REGION=us-east5
+ANTHROPIC_VERTEX_PROJECT_ID=your-gcp-project-id
+ANTHROPIC_DEFAULT_OPUS_MODEL=claude-opus-4-5@20251101
+ANTHROPIC_DEFAULT_SONNET_MODEL=claude-sonnet-4-5@20250929
+ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-3-5-haiku@20241022`}
+
+
+ Use @{' '} + instead of -{' '} + in model names for Vertex AI. +
+ + {/* Ollama Local Models */} +

+ Ollama Local Models +

+

+ Run coding agents using local models via Ollama v0.14.0+: +

+
    +
  1. + Install Ollama from{' '} + + ollama.com + +
  2. +
  3. + Start Ollama:{' '} + ollama serve +
  4. +
  5. + Pull a coding model:{' '} + ollama pull qwen3-coder +
  6. +
  7. + Configure your{' '} + .env: +
  8. +
+
+
{`ANTHROPIC_BASE_URL=http://localhost:11434
+ANTHROPIC_AUTH_TOKEN=ollama
+API_TIMEOUT_MS=3000000
+ANTHROPIC_DEFAULT_SONNET_MODEL=qwen3-coder`}
+
+

+ Recommended models:{' '} + qwen3-coder{' '} + deepseek-coder-v2{' '} + codellama +

+

+ Limitations: Smaller context windows than Claude + (model-dependent), extended context beta disabled (not supported by Ollama), and performance + depends on local hardware (GPU recommended). +

+ + {/* Environment Variables */} +

+ Environment Variables +

+

+ Key environment variables for configuring AutoCoder: +

+ + + + + + + + + {ENV_VARS.map((v) => ( + + + + + ))} + +
+ Variable + + Description +
+ {v.name} + {v.description}
+ + {/* CLI Arguments */} +

+ CLI Arguments +

+

+ Command-line arguments for{' '} + + autonomous_agent_demo.py + + : +

+ + + + + + + + + {CLI_ARGS.map((arg) => ( + + + + + ))} + +
+ Argument + + Description +
+ {arg.name} + {arg.description}
+ + {/* Webhook Support */} +

+ Webhook Support +

+
    +
  • AutoCoder can send webhook notifications on feature completion
  • +
  • Compatible with N8N and similar automation tools
  • +
  • Configure the webhook URL in project settings
  • +
  • + Payload includes: feature name, status, and project info +
  • +
+ + {/* Project Registry */} +

+ Project Registry +

+
    +
  • + All projects are registered in{' '} + ~/.autocoder/registry.db{' '} + (SQLite) +
  • +
  • Maps project names to filesystem paths
  • +
  • Uses POSIX path format (forward slashes) for cross-platform compatibility
  • +
  • SQLAlchemy ORM with SQLite's built-in transaction handling
  • +
+
+ ) +} diff --git a/ui/src/components/docs/sections/AgentSystem.tsx b/ui/src/components/docs/sections/AgentSystem.tsx new file mode 100644 index 0000000..0edc2d3 --- /dev/null +++ b/ui/src/components/docs/sections/AgentSystem.tsx @@ -0,0 +1,280 @@ +/** + * AgentSystem Documentation Section + * + * Covers the orchestrator (Maestro), coding agents, testing agents, + * agent lifecycle, concurrency control, mission control dashboard, + * agent mascots and states, viewing logs, and process limits. + */ + +import { Badge } from '@/components/ui/badge' + +export function AgentSystem() { + return ( +
+ {/* Maestro: The Orchestrator */} +

+ Maestro: The Orchestrator +

+

+ Maestro is the central orchestrator that coordinates all agents. It acts as the conductor, + ensuring features are implemented efficiently and in the correct order. +

+
    +
  • Manages the full lifecycle of coding and testing agents
  • +
  • Schedules which features to work on based on dependencies and priority
  • +
  • Monitors agent health and restarts crashed agents automatically
  • +
  • Reports status to the UI in real time via WebSocket
  • +
+ + {/* Coding Agents */} +

+ Coding Agents +

+
    +
  • Implement features one at a time, or in batches of 1–3
  • +
  • + Claim features atomically via the{' '} + + feature_claim_and_get + {' '} + MCP tool — no two agents work on the same feature +
  • +
  • Run in isolated environments with their own browser context
  • +
  • + Use the Claude Code SDK with project-specific tools and{' '} + CLAUDE.md +
  • +
+ + {/* Testing Agents */} +

+ Testing Agents +

+
    +
  • Run regression tests after features are implemented
  • +
  • Verify that new code does not break existing features
  • +
  • Configurable ratio: 0–3 testing agents per coding agent
  • +
  • Can batch-test multiple features per session (1–5)
  • +
+ + {/* Agent Lifecycle */} +

+ Agent Lifecycle +

+

+ Agents are controlled through the UI or CLI. The lifecycle states are: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Action + + Behavior +
Start + Click the Play button or run the CLI command +
Stop + Gracefully terminates all running agents +
Pause + Temporarily halts work (agents finish their current task first) +
Resume + Continues from where the agents were paused +
+

+ Agents auto-continue between sessions with a 3-second delay, so they keep working until + all features are complete or they are explicitly stopped. +

+ + {/* Concurrency Control */} +

+ Concurrency Control +

+
    +
  • + A slider in the agent control bar sets the number of concurrent coding agents + (1–5) +
  • +
  • + More agents means faster progress, but also higher API usage +
  • +
  • Each agent runs as an independent subprocess
  • +
  • + Feature claiming is atomic — no two agents will ever work on the same feature + simultaneously +
  • +
+ + {/* Agent Mission Control */} +

+ Agent Mission Control +

+

+ The Mission Control dashboard provides a real-time overview of all active agents: +

+
    +
  • Active agent cards with mascot icons and current status
  • +
  • The feature each agent is currently working on
  • +
  • Agent state indicators (thinking, working, testing, etc.)
  • +
  • Orchestrator status and a recent activity feed
  • +
+ + {/* Agent Mascots & States */} +

+ Agent Mascots & States +

+

+ Each agent is assigned a unique mascot for easy identification:{' '} + Spark,{' '} + Fizz,{' '} + Octo,{' '} + Hoot,{' '} + Buzz, and more. Agent states include: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ State + + Animation + + Description +
+ Thinking + BouncingAgent is planning its approach
+ Working + ShakeActively writing code
+ Testing + RotatingRunning tests
+ Success + CelebrationFeature completed
+ Error + Red shakeEncountered an issue
+ Struggling + Concerned expressionMultiple consecutive failures
+ + {/* Viewing Agent Logs */} +

+ Viewing Agent Logs +

+
    +
  • Click any agent card in Mission Control to see its log output
  • +
  • Logs are color-coded by level (info, warning, error)
  • +
  • Output streams in real time via WebSocket
  • +
  • Each agent's logs are isolated and filterable
  • +
+ + {/* Process Limits */} +

+ Process Limits +

+

+ The orchestrator enforces strict bounds on concurrent processes to prevent resource + exhaustion: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Limit + + Value +
+ + MAX_PARALLEL_AGENTS + + 5 (maximum concurrent coding agents)
+ + MAX_TOTAL_AGENTS + + + 10 (hard limit on coding + testing combined) +
Testing agents + Capped at the same count as coding agents +
Total Python processes + Never exceeds 11 (1 orchestrator + 5 coding + 5 testing) +
+
+ ) +} diff --git a/ui/src/components/docs/sections/AppSpecSetup.tsx b/ui/src/components/docs/sections/AppSpecSetup.tsx new file mode 100644 index 0000000..a4084a9 --- /dev/null +++ b/ui/src/components/docs/sections/AppSpecSetup.tsx @@ -0,0 +1,130 @@ +/** + * AppSpecSetup Documentation Section + * + * Explains what an app spec is, how to create one interactively + * or manually, the initializer agent, and starting after spec creation. + */ + +export function AppSpecSetup() { + return ( +
+ {/* What is an App Spec? */} +

+ What is an App Spec? +

+

+ The app spec is an XML document that describes the application to be built. It lives at{' '} + + .autocoder/prompts/app_spec.txt + {' '} + and tells the initializer agent what features to create. The spec defines your app's name, + description, tech stack, and the features that should be implemented. +

+
+
{`
+  My App
+  A task management app
+  
+    User authentication with login/signup
+    Task CRUD with categories
+  
+`}
+
+ + {/* Creating a Spec with Claude */} +

+ Creating a Spec with Claude +

+
    +
  • + In the UI, select your project and click{' '} + Create Spec +
  • +
  • + An interactive chat with Claude helps you define your app — it asks about + your app's purpose, features, and tech stack +
  • +
  • The spec is generated and saved automatically
  • +
  • After creation, the initializer agent can be started immediately
  • +
+ + {/* Writing a Spec Manually */} +

+ Writing a Spec Manually +

+
    +
  • + Create{' '} + + .autocoder/prompts/app_spec.txt + {' '} + in your project directory +
  • +
  • + Use XML format with app name, description, tech stack, and a feature list +
  • +
  • + Be specific about each feature — the initializer creates test cases from these + descriptions +
  • +
  • + Include technical constraints where needed (e.g.,{' '} + + "use PostgreSQL" + + ,{' '} + + "React with TypeScript" + + ) +
  • +
+ + {/* The Initializer Agent */} +

+ The Initializer Agent +

+

+ The initializer agent is the first agent to run on a new project. It bridges the gap between + your spec and the coding agents that implement features. +

+
    +
  • Runs automatically on first agent start when no features exist in the database
  • +
  • Reads the app spec and creates features with descriptions, steps, and priorities
  • +
  • + Sets up feature dependencies (e.g., "auth must be done before user profile") +
  • +
  • + Creates the feature database at{' '} + + .autocoder/features.db + +
  • +
+ + {/* Starting After Spec Creation */} +

+ Starting After Spec Creation +

+

+ Once your spec is ready, you can kick off the agents: +

+
    +
  • + From the UI, click the Play button to start + the agent +
  • +
  • + Or run from the CLI: +
  • +
+
+
python autonomous_agent_demo.py --project-dir your-project
+
+

+ The initializer runs first to create features, then coding agents take over to implement + them. Progress is shown in real time on the Kanban board. +

+
+ ) +} diff --git a/ui/src/components/docs/sections/AppearanceThemes.tsx b/ui/src/components/docs/sections/AppearanceThemes.tsx new file mode 100644 index 0000000..d713983 --- /dev/null +++ b/ui/src/components/docs/sections/AppearanceThemes.tsx @@ -0,0 +1,185 @@ +/** + * AppearanceThemes Documentation Section + * + * Covers built-in themes with color previews, dark/light mode toggling, + * the theme selector dropdown, and global keyboard shortcuts. + */ + +import { Badge } from '@/components/ui/badge' + +/** Theme descriptor used to render the preview rows. */ +interface ThemePreview { + name: string + description: string + colors: { label: string; hex: string }[] +} + +const THEMES: ThemePreview[] = [ + { + name: 'Twitter', + description: 'Clean, modern blue design. Primary: blue, Background: white/dark gray.', + colors: [ + { label: 'Background', hex: '#ffffff' }, + { label: 'Primary', hex: '#4a9eff' }, + { label: 'Accent', hex: '#e8f4ff' }, + ], + }, + { + name: 'Claude', + description: "Warm beige/cream tones with orange accents. Inspired by Anthropic's Claude brand.", + colors: [ + { label: 'Background', hex: '#faf6f0' }, + { label: 'Primary', hex: '#c75b2a' }, + { label: 'Accent', hex: '#f5ede4' }, + ], + }, + { + name: 'Neo Brutalism', + description: 'Bold colors, hard shadows, no border radius. High contrast, expressive design.', + colors: [ + { label: 'Background', hex: '#ffffff' }, + { label: 'Primary', hex: '#ff4d00' }, + { label: 'Accent', hex: '#ffeb00' }, + ], + }, + { + name: 'Retro Arcade', + description: 'Vibrant pink and teal with pixel-art inspired styling.', + colors: [ + { label: 'Background', hex: '#f0e6d3' }, + { label: 'Primary', hex: '#e8457c' }, + { label: 'Accent', hex: '#4eb8a5' }, + ], + }, + { + name: 'Aurora', + description: 'Deep violet and luminous teal, inspired by the northern lights.', + colors: [ + { label: 'Background', hex: '#faf8ff' }, + { label: 'Primary', hex: '#8b5cf6' }, + { label: 'Accent', hex: '#2dd4bf' }, + ], + }, + { + name: 'Business', + description: 'Professional deep navy and gray monochrome palette for corporate use.', + colors: [ + { label: 'Background', hex: '#eaecef' }, + { label: 'Primary', hex: '#000e4e' }, + { label: 'Accent', hex: '#6b7280' }, + ], + }, +] + +/** Keyboard shortcut descriptor for the shortcuts table. */ +interface Shortcut { + key: string + action: string +} + +const SHORTCUTS: Shortcut[] = [ + { key: '?', action: 'Show keyboard shortcuts help' }, + { key: 'D', action: 'Toggle debug panel' }, + { key: 'T', action: 'Toggle terminal' }, + { key: 'G', action: 'Toggle Kanban/Graph view' }, + { key: 'N', action: 'Add new feature' }, + { key: 'E', action: 'Expand project with AI' }, + { key: 'A', action: 'Toggle AI assistant' }, + { key: ',', action: 'Open settings' }, + { key: 'R', action: 'Reset project' }, + { key: 'Escape', action: 'Close current modal' }, +] + +export function AppearanceThemes() { + return ( +
+ {/* Themes Overview */} +

+ Themes Overview +

+

+ AutoCoder comes with 6 built-in themes. Each theme provides a complete visual identity including + colors, accents, and dark mode variants. +

+
+ {THEMES.map((theme) => ( +
+ {/* Color swatches */} +
+ {theme.colors.map((color) => ( +
+ ))} +
+ {/* Description */} +
+ {theme.name} + {theme.name === 'Twitter' && ( + <> + {' '} + Default + + )} + — {theme.description} +
+
+ ))} +
+ + {/* Dark & Light Mode */} +

+ Dark & Light Mode +

+
    +
  • Toggle with the sun/moon icon in the header
  • +
  • All 6 themes have dedicated dark mode variants
  • +
  • + Preference is saved in browser{' '} + localStorage +
  • +
  • Dark mode affects all UI elements including the docs page
  • +
+ + {/* Theme Selector */} +

+ Theme Selector +

+
    +
  • Hover over the palette icon in the header to open the theme dropdown
  • +
  • Preview themes by hovering over each option (live preview)
  • +
  • Click to select — the change is applied instantly
  • +
  • Theme preference persists across sessions
  • +
+ + {/* Keyboard Shortcuts */} +

+ Keyboard Shortcuts +

+

+ Press ? anywhere in the UI to see the shortcuts help overlay. +

+ + + + + + + + + {SHORTCUTS.map((shortcut) => ( + + + + + ))} + +
KeyAction
+ {shortcut.key} + {shortcut.action}
+
+ ) +} diff --git a/ui/src/components/docs/sections/DeveloperTools.tsx b/ui/src/components/docs/sections/DeveloperTools.tsx new file mode 100644 index 0000000..06a5999 --- /dev/null +++ b/ui/src/components/docs/sections/DeveloperTools.tsx @@ -0,0 +1,104 @@ +/** + * DeveloperTools Documentation Section + * + * Covers the debug panel, agent logs tab, dev server logs, + * terminal, dev server control, and per-agent logs. + */ + +import { Badge } from '@/components/ui/badge' + +export function DeveloperTools() { + return ( +
+ {/* Debug Panel */} +

+ Debug Panel +

+
    +
  • + Press D to toggle the debug panel at the bottom of the screen +
  • +
  • Resizable by dragging the top edge
  • +
  • + Three tabs: Agent Logs,{' '} + Dev Server Logs, and{' '} + Terminal +
  • +
  • Shows real-time output from agents and dev server
  • +
+ + {/* Agent Logs Tab */} +

+ Agent Logs Tab +

+
    +
  • + Color-coded log levels:{' '} + Error,{' '} + Warning,{' '} + Info,{' '} + Debug,{' '} + Success +
  • +
  • Timestamps on each log entry
  • +
  • Auto-scrolls to latest entry
  • +
  • Clear button to reset log view
  • +
+ + {/* Dev Server Logs Tab */} +

+ Dev Server Logs Tab +

+
    +
  • + Shows stdout/stderr from the project’s dev server (e.g.,{' '} + npm run dev) +
  • +
  • Useful for seeing compilation errors, hot reload status
  • +
  • Clear button available
  • +
+ + {/* Terminal */} +

+ Terminal +

+
    +
  • + Press T to open terminal (opens debug panel on the terminal tab) +
  • +
  • Full xterm.js terminal emulator with WebSocket backend
  • +
  • Multi-tab support: create multiple terminal sessions
  • +
  • Rename tabs by double-clicking the tab title
  • +
  • Each tab runs an independent PTY (pseudo-terminal) session
  • +
  • Supports standard terminal features: colors, cursor movement, history
  • +
+ + {/* Dev Server Control */} +

+ Dev Server Control +

+
    +
  • Start/stop button in the header bar
  • +
  • + Auto-detects project type (Next.js, Vite, CRA, etc.) and runs the appropriate dev command +
  • +
  • Shows the dev server URL when running
  • +
  • Automatic crash detection and restart option
  • +
  • Dev server output piped to the Dev Server Logs tab
  • +
+ + {/* Per-Agent Logs */} +

+ Per-Agent Logs +

+
    +
  • In Agent Mission Control, click any agent card to see its individual logs
  • +
  • + Logs include: what feature the agent is working on, code changes, test results +
  • +
  • Separate logs for coding agents and testing agents
  • +
  • Real-time streaming — see agent output as it happens
  • +
+
+ ) +} diff --git a/ui/src/components/docs/sections/FAQ.tsx b/ui/src/components/docs/sections/FAQ.tsx new file mode 100644 index 0000000..82b4f66 --- /dev/null +++ b/ui/src/components/docs/sections/FAQ.tsx @@ -0,0 +1,157 @@ +/** + * FAQ Documentation Section + * + * Covers frequently asked questions about project setup, agent behavior, + * customization, troubleshooting, and real-time monitoring. + */ + +export function FAQ() { + return ( +
+ {/* Starting a New Project */} +

+ Starting a New Project +

+

+ How do I use AutoCoder on a new project? +

+

+ From the UI, select "Create New Project" in the project dropdown. Choose a folder and + name. Then create an app spec using the interactive chat or write one manually. Click Start to run + the initializer agent, which creates features from your spec. Coding agents then implement features + automatically. +

+ + {/* Adding to Existing Project */} +

+ Adding to Existing Project +

+

+ How do I add AutoCoder to an existing project? +

+

+ Register the project folder through the UI project selector using "Add Existing". + AutoCoder creates a{' '} + .autocoder/ directory + alongside your existing code. Write an app spec describing what to build (new features), and the + agent works within your existing codebase. +

+ + {/* Agent Crashes */} +

+ Agent Crashes +

+

+ What happens if an agent crashes? +

+

+ The orchestrator (Maestro) automatically detects crashed agents and can restart them. Features + claimed by a crashed agent are released back to the pending queue. Scheduled runs use exponential + backoff with up to 3 retries. Check the agent logs in the debug panel for crash details. +

+ + {/* Custom Bash Commands */} +

+ Custom Bash Commands +

+

+ How do I customize which bash commands the agent can use? +

+

+ Create{' '} + + .autocoder/allowed_commands.yaml + {' '} + in your project with a list of allowed commands. Supports exact names, wildcards (e.g.,{' '} + swift*), and local + scripts. See the Security section for full details on the command hierarchy. +

+ + {/* Blocked Features */} +

+ Blocked Features +

+

+ Why are my features stuck in "blocked" status? +

+

+ Features with unmet dependencies show as blocked. Check the Dependency Graph view (press{' '} + G) to see which + features are waiting on others. A feature can only start when all its dependencies are marked as + "passing". Remove or reorder dependencies if needed. +

+ + {/* Running in Parallel */} +

+ Running in Parallel +

+

+ How do I run multiple agents in parallel? +

+

+ Use the concurrency slider in the agent control bar (1–5 agents) or pass{' '} + + --parallel --max-concurrency N + {' '} + on the CLI. Each agent claims features atomically, so there is no conflict. More agents means + faster progress but higher API cost. +

+ + {/* Using Local Models */} +

+ Using Local Models +

+

+ Can I use a local model instead of the Claude API? +

+

+ Yes, via Ollama v0.14.0+. Install Ollama, pull a coding model (e.g.,{' '} + qwen3-coder), and + configure your{' '} + .env to point to + localhost. See the Advanced Configuration section for full setup instructions. +

+ + {/* Resetting a Project */} +

+ Resetting a Project +

+

+ How do I reset a project and start over? +

+

+ Press R (when agents + are stopped) to open the Reset modal. Choose between: "Reset Features" (clears the + feature database, keeps the spec) or "Full Reset" (removes the spec too, starts fresh). + After a full reset, you will be prompted to create a new spec. +

+ + {/* Coding vs Testing Agents */} +

+ Coding vs Testing Agents +

+

+ What's the difference between coding and testing agents? +

+

+ Coding agents implement features — they write code, create files, and run feature-specific + tests. Testing agents run regression tests across completed features to ensure new code does not + break existing functionality. Configure the testing agent ratio (0–3) in settings. +

+ + {/* Monitoring in Real Time */} +

+ Monitoring in Real Time +

+

+ How do I view what an agent is doing in real time? +

+

+ Multiple ways: (1) Watch the Kanban board for feature status changes. (2) Open the debug panel + (D key) for live + agent logs. (3) Click agent cards in Mission Control for per-agent logs. (4) The progress bar + updates in real time via WebSocket. +

+
+ ) +} diff --git a/ui/src/components/docs/sections/FeaturesKanban.tsx b/ui/src/components/docs/sections/FeaturesKanban.tsx new file mode 100644 index 0000000..4076af8 --- /dev/null +++ b/ui/src/components/docs/sections/FeaturesKanban.tsx @@ -0,0 +1,182 @@ +/** + * FeaturesKanban Documentation Section + * + * Covers the Kanban board, feature cards, dependency graph view, + * adding/editing features, dependencies, expanding with AI, + * and priority ordering. + */ + +import { Badge } from '@/components/ui/badge' + +export function FeaturesKanban() { + return ( +
+ {/* Kanban Board Overview */} +

+ Kanban Board Overview +

+

+ The main view organizes features into three columns representing their current status: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column + + Color + + Meaning +
Pending + Yellow + Waiting to be picked up
In Progress + Cyan + An agent is actively working on it
Done + Green + Implemented and passing
+

+ Each feature appears as a card showing its name, priority, and category. The board updates + in real time as agents work. +

+ + {/* Feature Cards */} +

+ Feature Cards +

+
    +
  • + Each card displays a priority badge (P1 through{' '} + P5), a category tag, and the feature name +
  • +
  • Status icons indicate the current state of the feature
  • +
  • Click a card to open the detail modal with the full description and test steps
  • +
  • + Cards in the "In Progress" column show which agent is currently working on them +
  • +
+ + {/* Dependency Graph View */} +

+ Dependency Graph View +

+

+ An alternative to the Kanban board that visualizes feature relationships as a directed graph. +

+
    +
  • + Press G to toggle between Kanban and Graph view +
  • +
  • Uses the dagre layout engine for automatic node positioning
  • +
  • + Nodes are colored by status — pending, in-progress, and done each have + distinct colors +
  • +
  • Arrows show dependency relationships between features
  • +
  • Click any node to open the feature detail modal
  • +
  • Supports both horizontal and vertical layout orientations
  • +
+ + {/* Adding Features */} +

+ Adding Features +

+
    +
  • + Press N to open the Add Feature form +
  • +
  • Fill in: name, description, category, and priority
  • +
  • Optionally define steps (test criteria the agent must pass to complete the feature)
  • +
  • New features are added to the Pending column immediately
  • +
+ + {/* Editing & Deleting Features */} +

+ Editing & Deleting Features +

+
    +
  • Click a feature card to open the detail modal
  • +
  • + Click Edit to modify the name, description, + category, priority, or steps +
  • +
  • + Delete removes the feature permanently +
  • +
  • + Skip moves a feature to the end of the queue + without deleting it +
  • +
+ + {/* Feature Dependencies */} +

+ Feature Dependencies +

+

+ Features can declare dependencies on other features, ensuring they are implemented in the + correct order. +

+
    +
  • Set dependencies in the feature edit modal
  • +
  • + Cycle detection prevents circular dependencies (uses Kahn's algorithm combined + with DFS) +
  • +
  • + Blocked features display a lock icon and cannot be claimed by agents until their + dependencies are met +
  • +
  • The Dependency Graph view makes these relationships easy to visualize
  • +
+ + {/* Expanding Project with AI */} +

+ Expanding Project with AI +

+
    +
  • + Press E to open the Expand Project modal +
  • +
  • Chat with Claude to describe the new features you want to add
  • +
  • Supports image attachments for UI mockups or design references
  • +
  • Claude creates properly structured features with appropriate dependencies
  • +
  • New features appear on the board immediately after creation
  • +
+ + {/* Priority & Ordering */} +

+ Priority & Ordering +

+
    +
  • + Features are ordered by priority: P1 is the highest + and P5 is the lowest +
  • +
  • Within the same priority level, features are ordered by creation time
  • +
  • Agents always pick up the highest-priority ready feature first
  • +
+
+ ) +} diff --git a/ui/src/components/docs/sections/GettingStarted.tsx b/ui/src/components/docs/sections/GettingStarted.tsx new file mode 100644 index 0000000..1ee560b --- /dev/null +++ b/ui/src/components/docs/sections/GettingStarted.tsx @@ -0,0 +1,134 @@ +/** + * GettingStarted Documentation Section + * + * Covers what AutoCoder is, quick start commands, + * creating and adding projects, and system requirements. + */ + +import { Badge } from '@/components/ui/badge' + +export function GettingStarted() { + return ( +
+ {/* What is AutoCoder? */} +

+ What is AutoCoder? +

+

+ AutoCoder is an autonomous coding agent system that builds complete applications over multiple + sessions using a two-agent pattern: +

+
    +
  1. + Initializer Agent — reads your app spec + and creates features in a SQLite database +
  2. +
  3. + Coding Agent — implements features one by + one, marking each as passing when complete +
  4. +
+

+ It comes with a React-based UI for monitoring progress, managing features, and controlling agents + in real time. +

+ + {/* Quick Start */} +

+ Quick Start +

+

+ Launch AutoCoder with a single command. The CLI menu lets you create or select a project, + while the Web UI provides a full dashboard experience. +

+
+
{`# Windows
+start.bat          # CLI menu
+start_ui.bat       # Web UI
+
+# macOS/Linux
+./start.sh         # CLI menu
+./start_ui.sh      # Web UI`}
+
+ + {/* Creating a New Project */} +

+ Creating a New Project +

+
    +
  • + From the UI, click the project dropdown and select{' '} + Create New Project +
  • +
  • Enter a name and select or browse to a folder for the project
  • +
  • + Create an app spec interactively with Claude, or write one manually in XML format +
  • +
  • + The initializer agent reads your spec and creates features automatically +
  • +
+ + {/* Adding to an Existing Project */} +

+ Adding to an Existing Project +

+
    +
  • Register the project folder via the UI project selector
  • +
  • + AutoCoder creates a{' '} + .autocoder/{' '} + directory inside your project +
  • +
  • + Existing code is preserved — AutoCoder adds its configuration alongside it +
  • +
  • Write or generate an app spec describing what to build
  • +
+ + {/* System Requirements */} +

+ System Requirements +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Requirement + + Details +
Python + 3.11+ +
Node.js + 20+{' '} + (for UI development) +
Claude Code CLI + Required for running agents +
Operating System + Windows, macOS, or Linux +
+
+ ) +} diff --git a/ui/src/components/docs/sections/ProjectStructure.tsx b/ui/src/components/docs/sections/ProjectStructure.tsx new file mode 100644 index 0000000..0b6aa6b --- /dev/null +++ b/ui/src/components/docs/sections/ProjectStructure.tsx @@ -0,0 +1,162 @@ +/** + * ProjectStructure Documentation Section + * + * Covers the .autocoder/ directory layout, features database, + * prompts directory, allowed commands, CLAUDE.md convention, + * legacy migration, and Claude inheritance. + */ + +export function ProjectStructure() { + return ( +
+ {/* .autocoder/ Directory Layout */} +

+ .autocoder/ Directory Layout +

+

+ Every AutoCoder project stores its configuration and runtime files in a{' '} + .autocoder/{' '} + directory at the project root. +

+
+
{`your-project/
+\u251C\u2500\u2500 .autocoder/
+\u2502   \u251C\u2500\u2500 features.db              # SQLite feature database
+\u2502   \u251C\u2500\u2500 .agent.lock              # Lock file (prevents multiple instances)
+\u2502   \u251C\u2500\u2500 .gitignore               # Ignores runtime files
+\u2502   \u251C\u2500\u2500 allowed_commands.yaml    # Per-project bash command allowlist
+\u2502   \u2514\u2500\u2500 prompts/
+\u2502       \u251C\u2500\u2500 app_spec.txt         # Application specification (XML)
+\u2502       \u251C\u2500\u2500 initializer_prompt.md # First session prompt
+\u2502       \u2514\u2500\u2500 coding_prompt.md     # Continuation session prompt
+\u251C\u2500\u2500 CLAUDE.md                    # Claude Code convention file
+\u2514\u2500\u2500 app_spec.txt                 # Root copy for template compatibility`}
+
+ + {/* Features Database */} +

+ Features Database +

+
    +
  • + SQLite database managed by SQLAlchemy, stored at{' '} + + .autocoder/features.db + +
  • +
  • + Each feature record includes: id, priority, category, name, description, steps, status + (pending,{' '} + in_progress,{' '} + passing,{' '} + failing), + and dependencies +
  • +
  • Agents interact with features through MCP server tools, not direct database access
  • +
  • Viewable in the UI via the Kanban board or the Dependency Graph view
  • +
+ + {/* Prompts Directory */} +

+ Prompts Directory +

+

+ Prompts control how agents behave during each session: +

+
    +
  • + app_spec.txt{' '} + — your application specification in XML format +
  • +
  • + + initializer_prompt.md + {' '} + — prompt for the initializer agent (creates features from the spec) +
  • +
  • + + coding_prompt.md + {' '} + — prompt for coding agents (implements features) +
  • +
+

+ These can be customized per project. If not present, defaults from{' '} + + .claude/templates/ + {' '} + are used as a fallback. +

+ + {/* Allowed Commands Config */} +

+ Allowed Commands Config +

+

+ The optional{' '} + + .autocoder/allowed_commands.yaml + {' '} + file lets you grant project-specific bash commands to the agent. This is useful when your + project requires tools beyond the default allowlist (e.g., language-specific compilers or + custom build scripts). +

+

+ See the Security section for full details on + the command hierarchy and how project-level commands interact with global and organization + policies. +

+ + {/* CLAUDE.md Convention */} +

+ CLAUDE.md Convention +

+
    +
  • + CLAUDE.md{' '} + lives at the project root, as required by the Claude Code SDK +
  • +
  • + Contains project-specific instructions that the agent follows during every coding session +
  • +
  • + Automatically inherited by all agents working on the project — no additional + configuration needed +
  • +
+ + {/* Legacy Layout Migration */} +

+ Legacy Layout Migration +

+

+ Older projects stored configuration files directly at the project root (e.g.,{' '} + features.db,{' '} + prompts/). +

+
    +
  • + On the next agent start, these files are automatically migrated into{' '} + .autocoder/ +
  • +
  • Dual-path resolution ensures both old and new layouts work transparently
  • +
  • No manual migration is needed — it happens seamlessly
  • +
+ + {/* Claude Inheritance */} +

+ Claude Inheritance +

+

+ Agents inherit all MCP servers, tools, skills, custom commands, and{' '} + CLAUDE.md{' '} + from the target project folder. +

+
+ If your project has its own MCP servers or Claude commands, the coding agent can use them. + The agent essentially runs as if Claude Code was opened in your project directory. +
+
+ ) +} diff --git a/ui/src/components/docs/sections/Scheduling.tsx b/ui/src/components/docs/sections/Scheduling.tsx new file mode 100644 index 0000000..913bb78 --- /dev/null +++ b/ui/src/components/docs/sections/Scheduling.tsx @@ -0,0 +1,102 @@ +/** + * Scheduling Documentation Section + * + * Covers schedule creation, per-schedule settings, + * overrides, and crash recovery with exponential backoff. + */ + +import { Badge } from '@/components/ui/badge' + +export function Scheduling() { + return ( +
+ {/* What Scheduling Does */} +

+ What Scheduling Does +

+

+ Scheduling automates agent runs at specific times. Set up a schedule and AutoCoder will automatically + start agents on your project — useful for overnight builds, periodic maintenance, or continuous + development. +

+ + {/* Creating a Schedule */} +

+ Creating a Schedule +

+
    +
  • Click the clock icon in the header to open the Schedule modal
  • +
  • Set: start time, duration (how long agents run), days of the week
  • +
  • Optionally configure: YOLO mode, concurrency, model selection
  • +
  • Schedule is saved and starts at the next matching time
  • +
+ + {/* Schedule Settings */} +

+ Schedule Settings +

+

+ Each schedule can override global settings: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
SettingDetails
YOLO modeOn/off per schedule
Concurrency + 1–5 agents +
Model tierOpus / Sonnet / Haiku
DurationHow long the session runs before auto-stopping
+
+ All schedule times are in UTC timezone. +
+ + {/* Schedule Overrides */} +

+ Schedule Overrides +

+
    +
  • Manually skip a scheduled run (one-time override)
  • +
  • Pause a schedule temporarily (resumes on next period)
  • +
  • + View upcoming runs with{' '} + Running until /{' '} + Next run indicators +
  • +
  • Override without deleting the schedule
  • +
+ + {/* Crash Recovery */} +

+ Crash Recovery +

+
    +
  • If a scheduled agent crashes, it uses exponential backoff for retries
  • +
  • + Maximum 3 retry attempts per scheduled run +
  • +
  • Backoff prevents rapid restart loops
  • +
  • Failed runs are logged for troubleshooting
  • +
+
+ ) +} diff --git a/ui/src/components/docs/sections/Security.tsx b/ui/src/components/docs/sections/Security.tsx new file mode 100644 index 0000000..2e4e09a --- /dev/null +++ b/ui/src/components/docs/sections/Security.tsx @@ -0,0 +1,218 @@ +/** + * Security Documentation Section + * + * Covers the defense-in-depth security model: command validation layers, + * the hierarchical allowlist/blocklist system, per-project and org-level + * configuration, extra read paths, and filesystem sandboxing. + */ + +import { Badge } from '@/components/ui/badge' + +export function Security() { + return ( +
+ {/* Command Validation Overview */} +

+ Command Validation Overview +

+

+ AutoCoder uses a defense-in-depth approach for security. All three layers must pass before any + command is executed: +

+
    +
  1. + OS-level sandbox — bash commands run inside + a restricted sandbox environment +
  2. +
  3. + Filesystem restriction — agents can only + access the project directory (plus configured extra read paths) +
  4. +
  5. + Hierarchical allowlist — every bash command + is validated against a multi-level allowlist system +
  6. +
+ + {/* Command Hierarchy */} +

+ Command Hierarchy +

+

+ Commands are evaluated against a 5-level hierarchy, from highest to lowest priority: +

+
    +
  1. + Hardcoded Blocklist{' '} + security.py{' '} + — NEVER allowed, cannot be overridden +
  2. +
  3. + Org Blocklist{' '} + ~/.autocoder/config.yaml{' '} + — org-wide blocks, cannot be project-overridden +
  4. +
  5. + Org Allowlist{' '} + ~/.autocoder/config.yaml{' '} + — available to all projects +
  6. +
  7. + Global Allowlist{' '} + security.py{' '} + — default commands (npm, git, curl, etc.) +
  8. +
  9. + Project Allowlist{' '} + + .autocoder/allowed_commands.yaml + {' '} + — project-specific additions +
  10. +
+
+ Higher priority levels always win. A command blocked at level 1 or 2 can never be allowed by + lower levels. +
+ + {/* Hardcoded Blocklist */} +

+ Hardcoded Blocklist +

+

+ The following commands can never be allowed, regardless + of any configuration. They are hardcoded in{' '} + security.py and + cannot be overridden: +

+
+ {['dd', 'sudo', 'su', 'shutdown', 'reboot', 'poweroff', 'mkfs', 'fdisk', 'mount', 'umount', 'systemctl'].map( + (cmd) => ( + + {cmd} + + ), + )} +
+ + {/* Global Allowlist */} +

+ Global Allowlist +

+

+ Default commands available to all projects out of the box. These are the standard development + commands needed for most projects: +

+
+ {['npm', 'npx', 'node', 'git', 'curl', 'python', 'pip', 'cat', 'ls', 'mkdir', 'cp', 'mv', 'rm', 'grep', 'find'].map( + (cmd) => ( + + {cmd} + + ), + )} +
+ + {/* Per-Project Allowed Commands */} +

+ Per-Project Allowed Commands +

+

+ Each project can define additional allowed commands in{' '} + + .autocoder/allowed_commands.yaml + + : +

+
+
{`# .autocoder/allowed_commands.yaml
+version: 1
+commands:
+  # Exact command name
+  - name: swift
+    description: Swift compiler
+
+  # Wildcard - matches swiftc, swiftlint, swiftformat
+  - name: swift*
+    description: All Swift tools (wildcard)
+
+  # Local project scripts
+  - name: ./scripts/build.sh
+    description: Project build script`}
+
+

+ Pattern matching: exact match ( + swift), wildcard ( + swift* matches swiftc, + swiftlint, etc.), and scripts ( + ./scripts/build.sh). + Limit: 100 commands per project. +

+ + {/* Organization Configuration */} +

+ Organization Configuration +

+

+ System administrators can set org-wide policies in{' '} + ~/.autocoder/config.yaml: +

+
+
{`# ~/.autocoder/config.yaml
+version: 1
+
+# Commands available to ALL projects
+allowed_commands:
+  - name: jq
+    description: JSON processor
+
+# Commands blocked across ALL projects (cannot be overridden)
+blocked_commands:
+  - aws        # Prevent accidental cloud operations
+  - kubectl    # Block production deployments`}
+
+

+ Org-level blocked commands cannot be overridden by any project configuration. +

+ + {/* Extra Read Paths */} +

+ Extra Read Paths +

+

+ Allow agents to read files from directories outside the project folder via the{' '} + EXTRA_READ_PATHS{' '} + environment variable: +

+
+
EXTRA_READ_PATHS=/path/to/docs,/path/to/shared-libs
+
+
    +
  • Must be absolute paths and must exist as directories
  • +
  • Only read operations allowed (Read, Glob, Grep — no Write/Edit)
  • +
  • + Sensitive directories are always blocked:{' '} + .ssh,{' '} + .aws,{' '} + .gnupg,{' '} + .docker,{' '} + .kube, etc. +
  • +
+ + {/* Filesystem Sandboxing */} +

+ Filesystem Sandboxing +

+
    +
  • Agents can only write to the project directory
  • +
  • Read access is limited to the project directory plus configured extra read paths
  • +
  • + Path traversal attacks are prevented via canonicalization ( + Path.resolve()) +
  • +
  • File operations are validated before execution
  • +
+
+ ) +} diff --git a/ui/src/components/docs/sections/SettingsConfig.tsx b/ui/src/components/docs/sections/SettingsConfig.tsx new file mode 100644 index 0000000..6045c5a --- /dev/null +++ b/ui/src/components/docs/sections/SettingsConfig.tsx @@ -0,0 +1,188 @@ +/** + * SettingsConfig Documentation Section + * + * Covers global settings: opening the modal, YOLO mode, headless browser, + * model selection, regression agents, batch size, concurrency, and persistence. + */ + +import { Badge } from '@/components/ui/badge' + +export function SettingsConfig() { + return ( +
+ {/* Opening Settings */} +

+ Opening Settings +

+

+ Press the , (comma) key or click the gear icon in the header bar to + open the Settings modal. Settings are global and apply to all projects. +

+ + {/* YOLO Mode */} +

+ YOLO Mode +

+

+ YOLO mode is for rapid prototyping — it skips testing for faster iteration: +

+
    +
  • + What’s skipped: Regression testing, Playwright MCP + server (browser automation disabled) +
  • +
  • + What still runs: Lint and type-check (to verify code + compiles), Feature MCP server for tracking +
  • +
  • + Toggle via the lightning bolt button in the UI or the{' '} + --yolo CLI flag +
  • +
  • + When to use: Early prototyping when you want to scaffold + features quickly without verification overhead +
  • +
  • Switch back to standard mode for production-quality development
  • +
+ + {/* Headless Browser */} +

+ Headless Browser +

+
    +
  • When enabled, Playwright runs without a visible browser window
  • +
  • Saves CPU/GPU resources on machines running multiple agents
  • +
  • Tests still run fully — just no visible browser UI
  • +
  • Toggle in settings or via the UI button
  • +
+ + {/* Model Selection */} +

+ Model Selection +

+

+ Choose which Claude model tier to use for your agents: +

+ + + + + + + + + + + + + + + + + + + + + +
Tier + Characteristics +
+ Opus + Most capable, highest quality
+ Sonnet + Balanced speed and quality
+ Haiku + Fastest, most economical
+
    +
  • Model can be set globally in settings
  • +
  • Per-schedule model override is also available
  • +
  • + When using Vertex AI, model names use{' '} + @ instead of{' '} + - (e.g.,{' '} + + claude-opus-4-5@20251101 + + ) +
  • +
+ + {/* Regression Agents */} +

+ Regression Agents +

+

+ Controls how many testing agents run alongside coding agents (0–3): +

+
    +
  • + 0: No regression testing (like YOLO but coding agents + still test their own feature) +
  • +
  • + 1: One testing agent runs in background verifying + completed features +
  • +
  • + 2–3: Multiple testing agents for thorough + verification +
  • +
  • Testing agents batch-test 1–5 features per session
  • +
+ + {/* Features per Agent / Batch Size */} +

+ Features per Agent (Batch Size) +

+

+ Controls how many features each coding agent implements per session (1–3): +

+
    +
  • + 1: One feature per session (most focused, lower risk of + conflicts) +
  • +
  • + 2–3: Multiple features per session (more efficient, + fewer session startups) +
  • +
  • + Set via settings UI or the{' '} + --batch-size CLI flag +
  • +
  • + Can also target specific features:{' '} + --batch-features 1,2,3 +
  • +
+ + {/* Concurrency */} +

+ Concurrency +

+
    +
  • Per-project default concurrency saved in project settings
  • +
  • Override at runtime with the concurrency slider in agent controls
  • +
  • + Range: 1–5 concurrent coding agents +
  • +
  • Higher concurrency = faster progress but more API cost
  • +
+ + {/* How Settings are Persisted */} +

+ How Settings are Persisted +

+
    +
  • + Global settings stored in SQLite registry at{' '} + ~/.autocoder/registry.db +
  • +
  • Per-project settings (like default concurrency) stored in the project registry entry
  • +
  • UI settings (theme, dark mode) stored in browser localStorage
  • +
  • Settings survive app restarts and are shared across UI sessions
  • +
+
+ ) +} diff --git a/ui/src/hooks/useHashRoute.ts b/ui/src/hooks/useHashRoute.ts new file mode 100644 index 0000000..1482199 --- /dev/null +++ b/ui/src/hooks/useHashRoute.ts @@ -0,0 +1,36 @@ +import { useState, useEffect, useCallback } from 'react' + +export type Route = 'app' | 'docs' + +interface HashRouteState { + route: Route + section: string | null + navigate: (hash: string) => void +} + +function parseHash(hash: string): { route: Route; section: string | null } { + const cleaned = hash.replace(/^#\/?/, '') + if (cleaned === 'docs' || cleaned.startsWith('docs/')) { + const section = cleaned.slice(5) || null // Remove 'docs/' prefix + return { route: 'docs', section } + } + return { route: 'app', section: null } +} + +export function useHashRoute(): HashRouteState { + const [state, setState] = useState(() => parseHash(window.location.hash)) + + useEffect(() => { + const handleHashChange = () => { + setState(parseHash(window.location.hash)) + } + window.addEventListener('hashchange', handleHashChange) + return () => window.removeEventListener('hashchange', handleHashChange) + }, []) + + const navigate = useCallback((hash: string) => { + window.location.hash = hash + }, []) + + return { ...state, navigate } +} diff --git a/ui/src/main.tsx b/ui/src/main.tsx index fa4dad9..b4d89a2 100644 --- a/ui/src/main.tsx +++ b/ui/src/main.tsx @@ -1,7 +1,9 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { useHashRoute } from './hooks/useHashRoute' import App from './App' +import { DocsPage } from './components/docs/DocsPage' import './styles/globals.css' // Note: Custom theme removed - using shadcn/ui theming instead @@ -14,10 +16,16 @@ const queryClient = new QueryClient({ }, }) +function Router() { + const { route } = useHashRoute() + if (route === 'docs') return + return +} + createRoot(document.getElementById('root')!).render( - + , ) diff --git a/ui/src/styles/globals.css b/ui/src/styles/globals.css index e927b54..035bffe 100644 --- a/ui/src/styles/globals.css +++ b/ui/src/styles/globals.css @@ -1134,6 +1134,143 @@ } } +/* ============================================================================ + Documentation Prose Typography + ============================================================================ */ + +.docs-prose { + line-height: 1.7; + color: var(--muted-foreground); +} + +.docs-prose h2 { + font-size: 1.5rem; + font-weight: 700; + color: var(--foreground); + margin-top: 3rem; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 2px solid var(--border); + scroll-margin-top: 5rem; +} + +.docs-prose h2:first-child { + margin-top: 0; +} + +.docs-prose h3 { + font-size: 1.15rem; + font-weight: 600; + color: var(--foreground); + margin-top: 2rem; + margin-bottom: 0.75rem; + scroll-margin-top: 5rem; +} + +.docs-prose p { + margin-bottom: 1rem; + max-width: 65ch; +} + +.docs-prose ul, +.docs-prose ol { + margin-bottom: 1rem; + padding-left: 1.5rem; +} + +.docs-prose ul { + list-style-type: disc; +} + +.docs-prose ol { + list-style-type: decimal; +} + +.docs-prose li { + margin-bottom: 0.375rem; +} + +.docs-prose li > ul, +.docs-prose li > ol { + margin-top: 0.375rem; + margin-bottom: 0; +} + +.docs-prose pre { + background: var(--muted); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1rem; + overflow-x: auto; + margin-bottom: 1rem; + font-family: var(--font-mono); + font-size: 0.8125rem; + line-height: 1.6; +} + +.docs-prose code:not(pre code) { + background: var(--muted); + padding: 0.125rem 0.375rem; + border-radius: 0.25rem; + font-family: var(--font-mono); + font-size: 0.8125rem; +} + +.docs-prose table { + width: 100%; + border-collapse: collapse; + margin-bottom: 1rem; + font-size: 0.875rem; +} + +.docs-prose th { + background: var(--muted); + font-weight: 600; + color: var(--foreground); + text-align: left; + padding: 0.5rem 0.75rem; + border: 1px solid var(--border); +} + +.docs-prose td { + padding: 0.5rem 0.75rem; + border: 1px solid var(--border); +} + +.docs-prose tr:nth-child(even) td { + background: var(--muted); + opacity: 0.5; +} + +.docs-prose blockquote { + border-left: 4px solid var(--primary); + padding-left: 1rem; + margin-bottom: 1rem; + font-style: italic; + color: var(--muted-foreground); +} + +.docs-prose a { + color: var(--primary); + text-decoration: underline; + text-underline-offset: 2px; +} + +.docs-prose a:hover { + opacity: 0.8; +} + +.docs-prose strong { + color: var(--foreground); + font-weight: 600; +} + +.docs-prose hr { + border: none; + border-top: 1px solid var(--border); + margin: 2rem 0; +} + /* ============================================================================ Scrollbar Styling ============================================================================ */