diff --git a/README.md b/README.md index 847cdac..f285e95 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ You work with Claude Code on a feature, close the terminal, come back tomorrow.. ### Key Features ✅ **Lightning-Fast Indexing** - NEW! Tree-sitter hybrid indexing: 10,000 files in 30 seconds (vs 3-5 hours) +✅ **Real-Time Kanban Board** - NEW! Auto-syncing task visualization for agent-os specs (updates within 3 seconds) ✅ **One-Command Project Init** - `/claude-os-init` and you're done ✅ **Automatic Context Loading** - Starts every session with relevant memories ✅ **Session Management** - Track work, save progress, resume later @@ -100,6 +101,53 @@ Inspired by [Aider's](https://github.com/Aider-AI/aider) approach, Claude OS now --- +## 🎨 Visual Interface + +**Claude OS provides a beautiful, intuitive web interface for managing your AI development workflow:** + +
| + +### Welcome Screen + + +Get started with Claude OS + + | ++ +### Project Overview + + +View project details and MCP status + + | +
| + +### Kanban Board + + +Track spec implementation progress + + | ++ +### Services Dashboard + + +Monitor all Claude OS services + + | +
@@ -415,7 +463,6 @@ your-project/ └── .claude/agents/agent-os/ # 8 agents (symlinked) ``` - ### Integration with Claude OS Agent-OS agents deeply integrate with Claude OS: @@ -431,7 +478,10 @@ Agent-OS agents deeply integrate with Claude OS: ## 🎯 Spec Tracking & Kanban Board -**Claude OS now automatically tracks your Agent-OS specs and displays them as an interactive Kanban board!** +**NEW: Real-time auto-syncing Kanban board for Agent-OS specs!** + + +*Visual Kanban board showing specs, tasks, and progress tracking* ### What It Does @@ -440,17 +490,31 @@ When you use Agent-OS to create specs with `/create-spec`, Claude OS automatical - 📋 **Parses tasks.md files** - Extracts all tasks, phases, dependencies, and metadata - 🗄️ **Stores in database** - Tracks progress, completion, and time estimates - 📊 **Displays as Kanban** - Visual board showing specs and tasks by status -- ✅ **Updates in real-time** - Task status changes are reflected immediately +- ⚡ **Real-time sync** - NEW! Auto-detects file changes and updates within 3 seconds +- 👀 **File watching** - Monitors `agent-os/specs/` folder for changes +- ✅ **Auto-refresh** - Board polls every 3 seconds for live updates - 🗃️ **Archives completed specs** - Keep your board focused on active work ### Features +**Real-Time File Watching (NEW!):** + +- Automatically monitors your `agent-os/specs/` folder +- Detects changes to `tasks.md` and `spec.md` files +- 2-second debounce to batch rapid edits +- Auto-syncs to database within 3 seconds +- Frontend auto-refreshes every 3 seconds +- **Total latency: ~6 seconds from file save to board update** + **Automatic Syncing:** + - Syncs all specs from your project's `agent-os/specs/` folder - Tracks task metadata (estimated time, dependencies, risk level) -- Auto-detects completed tasks (marked with ✅ in tasks.md) +- Auto-detects completed tasks (marked with ✅ or `[x]` in tasks.md) +- Supports both checkbox format and classic format **Progress Tracking:** + - **Status auto-updates** based on completion: - `planning` - No tasks completed yet - `in_progress` - Some tasks completed @@ -459,6 +523,7 @@ When you use Agent-OS to create specs with `/create-spec`, Claude OS automatical - Time estimates tracked (estimated vs actual minutes) **Archive Feature:** + - Archive completed specs to keep your board clean - Archived specs hidden by default but can be viewed - Preserves all task history for future reference @@ -481,7 +546,7 @@ PATCH /api/tasks/{task_id}/status "actual_minutes": 15 } -# Sync specs from agent-os folder +# Sync specs from agent-os folder (manual) POST /api/projects/{project_id}/specs/sync # Get Kanban board view @@ -490,30 +555,46 @@ GET /api/projects/{project_id}/kanban?include_archived=false # Archive/unarchive specs POST /api/specs/{spec_id}/archive POST /api/specs/{spec_id}/unarchive + +# NEW: Real-time spec watcher control +GET /api/spec-watcher/status +POST /api/spec-watcher/start/{project_id} +POST /api/spec-watcher/stop/{project_id} +POST /api/spec-watcher/start-all ``` +**See:** `docs/guides/REALTIME_KANBAN_GUIDE.md` for complete documentation. + ### How It Works ``` 1. You create a spec with Agent-OS: /create-spec → agent-os/specs/2025-01-15-user-auth/ -2. Claude OS discovers and parses it: +2. Spec Watcher detects the new folder: + - Auto-starts when MCP server boots + - Monitors agent-os/specs/ directory + - 2-second debounce for batch changes + +3. Auto-sync to database: - Reads tasks.md + - Parses checkbox format: - [x] Task title - Extracts metadata, tasks, phases - Stores in SQLite database + - ✅ Completes within 3 seconds -3. View in Kanban board: +4. View in Kanban board (auto-refreshes every 3 seconds): - Todo: PHASE1-TASK1, PHASE1-TASK2 - In Progress: PHASE2-TASK1 - Done: PHASE1-TASK3, PHASE1-TASK4 -4. Track progress as you work: - - Update task status via API - - Spec status auto-updates - - Progress percentage calculated +5. As you work, agent-os updates tasks.md: + - File watcher detects change + - Auto-syncs to database + - Board refreshes automatically + - Total latency: ~6 seconds -5. Archive when complete: +6. Archive when complete: - Mark spec as archived - Keeps history but cleans up board ``` @@ -523,12 +604,14 @@ POST /api/specs/{spec_id}/unarchive Two new tables track specs and tasks: **`specs` table:** + - Stores spec metadata (name, path, status) - Tracks total/completed tasks - Calculates progress percentage - Archive flag to hide completed specs **`spec_tasks` table:** + - Individual tasks with codes (PHASE1-TASK1) - Status (todo/in_progress/done/blocked) - Time tracking (estimated vs actual) @@ -902,6 +985,7 @@ claude-os/ ### Core Features +- **[docs/guides/REALTIME_KANBAN_GUIDE.md](docs/guides/REALTIME_KANBAN_GUIDE.md)** - ⚡ **NEW! Real-time Kanban board** (auto-sync, file watching, API reference) - **[docs/SELF_LEARNING_SYSTEM.md](docs/SELF_LEARNING_SYSTEM.md)** - 🧠 How Claude learns automatically - **[docs/REAL_TIME_LEARNING_GUIDE.md](docs/REAL_TIME_LEARNING_GUIDE.md)** - Real-time learning usage - **[docs/MEMORY_MCP_GUIDE.md](docs/MEMORY_MCP_GUIDE.md)** - Persistent memory guide diff --git a/app/core/spec_parser.py b/app/core/spec_parser.py index 86ec1c8..c2e2651 100644 --- a/app/core/spec_parser.py +++ b/app/core/spec_parser.py @@ -84,17 +84,21 @@ class TasksParser: """Parse all tasks from the markdown.""" tasks = [] - # Find all task sections (e.g., ### PHASE1-TASK1:) + # Try original format first (### PHASE1-TASK1:) task_pattern = r'###\s+(PHASE\d+-TASK\d+):\s*(.+?)(?=###|\Z)' - matches = re.finditer(task_pattern, self.content, re.DOTALL) + matches = list(re.finditer(task_pattern, self.content, re.DOTALL)) - for match in matches: - task_code = match.group(1) - task_content = match.group(2) - - task = self._parse_single_task(task_code, task_content) - if task: - tasks.append(task) + if matches: + # Original format found + for match in matches: + task_code = match.group(1) + task_content = match.group(2) + task = self._parse_single_task(task_code, task_content) + if task: + tasks.append(task) + else: + # Try checkbox format (- [ ] or - [x]) + tasks = self._parse_checkbox_tasks() return tasks @@ -178,6 +182,58 @@ class TasksParser: return 0 # Default if can't parse + def _parse_checkbox_tasks(self) -> List[Dict]: + """Parse tasks in checkbox format (- [ ] or - [x]).""" + tasks = [] + current_phase = "Phase 1" + task_counter = 1 + + # Match checkbox lines: - [ ] or - [x] followed by task code and title + # Examples: + # - [x] 1.0 Complete database layer + # - [ ] 2.1 Write 2-8 focused tests + checkbox_pattern = r'^[\s]*-\s+\[([ x])\]\s+(\d+\.\d+)\s+(.+?)$' + + lines = self.content.split('\n') + for i, line in enumerate(lines): + match = re.match(checkbox_pattern, line) + if match: + is_checked = match.group(1) == 'x' + task_number = match.group(2) + title = match.group(3).strip() + + # Determine phase from task number (1.x = Phase 1, 2.x = Phase 2, etc.) + phase_num = int(task_number.split('.')[0]) + current_phase = f"Phase {phase_num}" + + # Extract additional details from following indented lines + description_lines = [] + j = i + 1 + while j < len(lines) and (lines[j].startswith(' ') or lines[j].startswith('\t')): + desc_line = lines[j].strip() + if desc_line and not desc_line.startswith('- ['): + description_lines.append(desc_line) + j += 1 + + description = ' '.join(description_lines) if description_lines else '' + + # Build task + task = { + 'task_code': f'PHASE{phase_num}-TASK{task_counter}', + 'phase': current_phase, + 'title': title, + 'description': description[:500] if description else '', # Limit description length + 'estimated_minutes': 60, # Default 1 hour + 'risk_level': 'medium', # Default medium risk + 'dependencies': [], + 'status': 'done' if is_checked else 'todo' + } + + tasks.append(task) + task_counter += 1 + + return tasks + def find_spec_folders(project_path: str) -> List[str]: """Find all spec folders in a project's agent-os directory.""" diff --git a/app/core/spec_watcher.py b/app/core/spec_watcher.py new file mode 100644 index 0000000..e18aa5a --- /dev/null +++ b/app/core/spec_watcher.py @@ -0,0 +1,270 @@ +""" +File system watcher for agent-os specs. +Automatically syncs specs to database when tasks.md files change. +""" + +import os +import logging +import threading +from pathlib import Path +from typing import Dict, Optional, List +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler, FileModifiedEvent, FileCreatedEvent + +from app.core.spec_manager import SpecManager +from app.core.spec_parser import parse_spec_folder +from app.core.sqlite_manager import get_sqlite_manager + +logger = logging.getLogger(__name__) + + +class SpecFileHandler(FileSystemEventHandler): + """Handles file system events for agent-os specs.""" + + def __init__(self, project_id: int, project_path: str): + """ + Initialize spec file handler. + + Args: + project_id: ID of the project + project_path: Path to the project root + """ + self.project_id = project_id + self.project_path = project_path + self.spec_manager = SpecManager() + self.debounce_timers: Dict[str, threading.Timer] = {} + self.debounce_delay = 2.0 # Debounce for 2 seconds + + def on_modified(self, event: FileModifiedEvent): + """Handle file modifications.""" + if event.is_directory: + return + + # Only react to tasks.md or spec.md changes + filename = Path(event.src_path).name + if filename not in ['tasks.md', 'spec.md']: + return + + self._debounce_sync(event.src_path) + + def on_created(self, event: FileCreatedEvent): + """Handle file creation.""" + if event.is_directory: + # New spec folder created - sync entire project + self._debounce_sync_all() + return + + # Only react to tasks.md or spec.md + filename = Path(event.src_path).name + if filename not in ['tasks.md', 'spec.md']: + return + + self._debounce_sync(event.src_path) + + def _debounce_sync(self, file_path: str): + """Debounce sync calls to avoid multiple rapid syncs.""" + # Get the spec folder (parent of tasks.md) + spec_folder = str(Path(file_path).parent) + + # Cancel previous timer if it exists + if spec_folder in self.debounce_timers: + self.debounce_timers[spec_folder].cancel() + + # Create new timer + timer = threading.Timer( + self.debounce_delay, + lambda: self._trigger_sync(spec_folder) + ) + self.debounce_timers[spec_folder] = timer + timer.start() + + def _debounce_sync_all(self): + """Debounce full project sync.""" + key = "__all__" + + # Cancel previous timer if it exists + if key in self.debounce_timers: + self.debounce_timers[key].cancel() + + # Create new timer + timer = threading.Timer( + self.debounce_delay, + self._trigger_sync_all + ) + self.debounce_timers[key] = timer + timer.start() + + def _trigger_sync(self, spec_folder: str): + """Trigger sync for a specific spec.""" + try: + spec_name = Path(spec_folder).name + logger.info(f"Syncing spec: {spec_name} for project {self.project_id}") + + # Parse the spec + spec_data = parse_spec_folder(spec_folder) + if not spec_data: + logger.warning(f"Failed to parse spec folder: {spec_folder}") + return + + # Sync to database + result = self.spec_manager.create_or_update_spec(self.project_id, spec_data) + + action = "Updated" if not result['created'] else "Created" + task_count = len(spec_data['tasks']) + logger.info(f"✅ {action} spec '{spec_data['name']}' with {task_count} tasks") + + except Exception as e: + logger.error(f"Error syncing spec {spec_folder}: {e}", exc_info=True) + + def _trigger_sync_all(self): + """Trigger sync for all specs in project.""" + try: + logger.info(f"Syncing all specs for project {self.project_id}") + result = self.spec_manager.sync_project_specs(self.project_id, self.project_path) + logger.info(f"✅ Synced {result['synced']} new, updated {result['updated']} existing specs") + except Exception as e: + logger.error(f"Error syncing all specs: {e}", exc_info=True) + + +class SpecWatcher: + """Watches agent-os specs folder for a project.""" + + def __init__(self, project_id: int, project_path: str): + """ + Initialize spec watcher. + + Args: + project_id: ID of the project + project_path: Path to the project root + """ + self.project_id = project_id + self.project_path = project_path + self.specs_path = Path(project_path) / "agent-os" / "specs" + self.observer: Optional[Observer] = None + self.event_handler: Optional[SpecFileHandler] = None + + def start(self): + """Start watching specs folder.""" + if not self.specs_path.exists(): + logger.warning(f"Specs folder does not exist: {self.specs_path}") + logger.info(f"Creating specs folder: {self.specs_path}") + self.specs_path.mkdir(parents=True, exist_ok=True) + return + + logger.info(f"Starting spec watcher for project {self.project_id}") + logger.info(f"Watching: {self.specs_path}") + + # Create observer + self.observer = Observer() + + # Create event handler + self.event_handler = SpecFileHandler(self.project_id, self.project_path) + + # Schedule observer + self.observer.schedule(self.event_handler, str(self.specs_path), recursive=True) + self.observer.start() + + logger.info(f"✅ Spec watcher started for project {self.project_id}") + + def stop(self): + """Stop watching specs folder.""" + if self.observer: + self.observer.stop() + self.observer.join() + logger.info(f"Spec watcher stopped for project {self.project_id}") + self.observer = None + self.event_handler = None + + def restart(self): + """Restart watcher.""" + self.stop() + self.start() + + +class GlobalSpecWatcher: + """Manages spec watchers for all projects.""" + + def __init__(self): + """Initialize global spec watcher.""" + self.watchers: Dict[int, SpecWatcher] = {} + self.lock = threading.Lock() + + def start_project(self, project_id: int, project_path: str): + """Start watching a project's specs.""" + with self.lock: + if project_id in self.watchers: + logger.info(f"Spec watcher already exists for project {project_id}, restarting...") + self.watchers[project_id].restart() + return + + watcher = SpecWatcher(project_id, project_path) + watcher.start() + self.watchers[project_id] = watcher + + def stop_project(self, project_id: int): + """Stop watching a project's specs.""" + with self.lock: + if project_id not in self.watchers: + return + + watcher = self.watchers.pop(project_id) + watcher.stop() + + def restart_project(self, project_id: int): + """Restart watcher for a project.""" + with self.lock: + if project_id in self.watchers: + self.watchers[project_id].restart() + + def start_all(self): + """Start watching all projects.""" + # Get all projects from database + db_manager = get_sqlite_manager() + projects = db_manager.list_projects() + + logger.info(f"Starting spec watchers for {len(projects)} projects") + + for project in projects: + try: + self.start_project(project['id'], project['path']) + except Exception as e: + logger.error(f"Error starting spec watcher for project {project['id']}: {e}") + + def stop_all(self): + """Stop watching all projects.""" + with self.lock: + for watcher in self.watchers.values(): + try: + watcher.stop() + except Exception as e: + logger.error(f"Error stopping spec watcher: {e}") + + self.watchers.clear() + + def get_status(self) -> Dict: + """Get status of all spec watchers.""" + with self.lock: + return { + "enabled": len(self.watchers) > 0, + "projects_watched": len(self.watchers), + "projects": { + project_id: { + "project_path": watcher.project_path, + "specs_path": str(watcher.specs_path), + "watching": watcher.observer is not None + } + for project_id, watcher in self.watchers.items() + } + } + + +# Global instance +_global_spec_watcher: Optional[GlobalSpecWatcher] = None + + +def get_global_spec_watcher() -> GlobalSpecWatcher: + """Get or create global spec watcher.""" + global _global_spec_watcher + if _global_spec_watcher is None: + _global_spec_watcher = GlobalSpecWatcher() + return _global_spec_watcher diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md index 5720d8e..2347e41 100644 --- a/docs/API_REFERENCE.md +++ b/docs/API_REFERENCE.md @@ -11,11 +11,13 @@ Complete reference for all Claude OS MCP Server API endpoints. 1. [Knowledge Base Operations](#knowledge-base-operations) 2. [Hybrid Indexing](#hybrid-indexing-new) 3. [Project Management](#project-management) -4. [Hooks System](#hooks-system) -5. [File Watcher](#file-watcher) -6. [Authentication](#authentication) -7. [Utilities](#utilities) -8. [Health Check](#health-check) +4. [Agent-OS Spec Tracking](#agent-os-spec-tracking-new) +5. [Real-Time Spec Watcher](#real-time-spec-watcher-new) +6. [Hooks System](#hooks-system) +7. [File Watcher](#file-watcher) +8. [Authentication](#authentication) +9. [Utilities](#utilities) +10. [Health Check](#health-check) --- @@ -493,6 +495,218 @@ DELETE /api/projects/{id} --- +## Agent-OS Spec Tracking (NEW) + +Real-time tracking and visualization of agent-os specifications and tasks through the Kanban board. + +### Get Project Kanban Board +```http +GET /api/projects/{id}/kanban?include_archived=false +``` + +Returns complete Kanban view with all specs and tasks grouped by status. + +**Response:** +```json +{ + "project_id": 1, + "specs": [ + { + "id": 1, + "name": "Manual Appointment Times", + "slug": "manual-appointment-times", + "folder_name": "2025-10-29-manual-appointment-times", + "path": "/path/to/project/agent-os/specs/2025-10-29-manual-appointment-times", + "total_tasks": 71, + "completed_tasks": 43, + "status": "in_progress", + "progress": 60.6, + "archived": false, + "tasks": { + "todo": [...], + "in_progress": [...], + "done": [...], + "blocked": [...] + }, + "task_count_by_status": { + "todo": 28, + "in_progress": 0, + "done": 43, + "blocked": 0 + } + } + ], + "summary": { + "total_specs": 3, + "total_tasks": 123, + "completed_tasks": 56 + } +} +``` + +### Sync Project Specs +```http +POST /api/projects/{id}/specs/sync +``` + +Manually trigger sync of all spec files from `agent-os/specs/` folder to database. + +**Response:** +```json +{ + "project_id": 1, + "message": "Specs synced successfully", + "synced": 0, + "updated": 3, + "total": 3, + "errors": [] +} +``` + +### Get Spec Tasks +```http +GET /api/specs/{spec_id}/tasks +``` + +Returns all tasks for a specific spec. + +**Response:** +```json +{ + "spec_id": 1, + "tasks": [ + { + "id": 53, + "task_code": "PHASE1-TASK1", + "phase": "Phase 1", + "title": "Complete database layer", + "description": "Implement all database models and migrations", + "status": "done", + "estimated_minutes": 60, + "actual_minutes": 120, + "risk_level": "medium", + "dependencies": [], + "started_at": "2025-10-29T10:00:00Z", + "completed_at": "2025-10-29T12:00:00Z" + } + ] +} +``` + +### Update Task Status +```http +PATCH /api/tasks/{task_id}/status +Content-Type: application/json + +{ + "status": "in_progress", + "actual_minutes": 90 +} +``` + +**Valid Statuses:** +- `todo` - Not started +- `in_progress` - Currently working +- `done` - Completed +- `blocked` - Waiting on dependencies + +**Response:** +```json +{ + "success": true, + "old_status": "todo", + "new_status": "in_progress" +} +``` + +### Archive Spec +```http +POST /api/specs/{spec_id}/archive +``` + +Archives a completed spec to declutter the Kanban board. + +### Unarchive Spec +```http +POST /api/specs/{spec_id}/unarchive +``` + +Restores an archived spec. + +--- + +## Real-Time Spec Watcher (NEW) + +Automatic file system monitoring for `agent-os/specs/` folders. Detects changes to spec files and auto-syncs to database for real-time Kanban updates. + +**See:** `docs/guides/REALTIME_KANBAN_GUIDE.md` for complete documentation. + +### Get Watcher Status +```http +GET /api/spec-watcher/status +``` + +**Response:** +```json +{ + "status": { + "enabled": true, + "projects_watched": 1, + "projects": { + "1": { + "project_path": "/Users/you/Projects/myapp", + "specs_path": "/Users/you/Projects/myapp/agent-os/specs", + "watching": true + } + } + } +} +``` + +### Start Spec Watcher +```http +POST /api/spec-watcher/start/{project_id} +``` + +Starts real-time file watching for a specific project's specs folder. + +**Response:** +```json +{ + "project_id": 1, + "message": "Spec watcher started", + "status": { + "enabled": true, + "projects_watched": 1 + } +} +``` + +### Stop Spec Watcher +```http +POST /api/spec-watcher/stop/{project_id} +``` + +Stops file watching for a specific project. + +### Start All Spec Watchers +```http +POST /api/spec-watcher/start-all +``` + +Starts spec watchers for all projects in the database. + +**Auto-Start:** Spec watchers automatically start when MCP server boots. + +**How it works:** +1. Monitors `agent-os/specs/**/*.md` files +2. Detects changes with 2-second debounce +3. Auto-parses tasks in checkbox format +4. Updates database within 3 seconds +5. Kanban board auto-refreshes every 3 seconds + +--- + ## Hooks System ### Enable Hook diff --git a/docs/guides/REALTIME_KANBAN_GUIDE.md b/docs/guides/REALTIME_KANBAN_GUIDE.md new file mode 100644 index 0000000..5547ceb --- /dev/null +++ b/docs/guides/REALTIME_KANBAN_GUIDE.md @@ -0,0 +1,452 @@ +# Real-Time Kanban Board Guide + +## Overview + +Claude OS features a **real-time Kanban board** that automatically syncs with your agent-os spec files as they're created and updated. This provides live visibility into your development progress without any manual intervention. + +## How It Works + +The real-time Kanban system consists of three integrated components: + +``` +agent-os updates tasks.md + ↓ (2 sec debounce) +Spec Watcher detects change + ↓ +Auto-syncs to database + ↓ (within 3 seconds) +Kanban board auto-refreshes + ↓ +You see updated tasks in real-time! 🎉 +``` + +### 1. Spec File Watcher + +The **Spec Watcher** monitors your project's `agent-os/specs/` folder for file changes: + +- **Watches**: All `tasks.md` and `spec.md` files in your specs folders +- **Triggers on**: File modifications and new file/folder creation +- **Debounce**: 2-second delay to batch rapid changes +- **Auto-starts**: Launches automatically when MCP server starts + +**Technical Details:** +- Location: `app/core/spec_watcher.py` +- Uses: `watchdog` library for filesystem monitoring +- Monitors: `/path/to/project/agent-os/specs/**/*` +- Thread-safe: Uses locks for concurrent access + +### 2. Automatic Database Sync + +When the spec watcher detects changes, it: + +1. Parses the updated `tasks.md` file +2. Extracts tasks in checkbox format: + ```markdown + - [x] 1.0 Complete database layer + - [ ] 2.1 Write tests for services + ``` +3. Updates the SQLite database with new/modified tasks +4. Tracks task status (todo, in_progress, done, blocked) + +**Supported Task Formats:** + +The parser supports two formats: + +**Checkbox Format** (recommended for agent-os): +```markdown +- [x] 1.0 Complete database layer + - [x] 1.1 Write 2-8 focused tests for database models + - [x] 1.2 Create migration: add_manual_time_slots_support +- [ ] 2.0 Complete service layer + - [ ] 2.1 Write 2-8 focused tests for services +``` + +**Classic Format** (legacy support): +```markdown +### PHASE1-TASK1: Database Setup +**Title:** Setup Database Schema +**Description:** Create all required database tables +**Estimated Time:** 2 hours +**Risk Level:** low +**Status:** ✅ COMPLETED +``` + +### 3. Frontend Auto-Refresh + +The Kanban board frontend: + +- **Polls**: Every 3 seconds for database updates +- **Refreshes**: Automatically when new data is detected +- **Smooth**: Uses React Query for optimistic updates +- **Animations**: Framer Motion for smooth task transitions + +## Using the Kanban Board + +### Accessing the Board + +1. Open Claude OS web interface +2. Select your project from the sidebar +3. Click the **"Kanban Board"** tab +4. Board loads automatically with all specs and tasks + +### Board Layout + +The Kanban board displays: + +**Top Section:** +- Summary statistics (total specs, total tasks, completed tasks) +- "Sync Specs" button (manual sync if needed) +- "Show Archived" toggle + +**Spec Cards:** +Each spec shows: +- Spec name and status +- Progress bar +- Task counts by status +- Four columns: Todo, In Progress, Done, Blocked + +**Task Cards:** +- Task code (e.g., PHASE1-TASK1) +- Title +- Risk level badge +- Estimated/actual time +- Dependencies + +### Manual Sync Button + +While the board updates automatically, you can manually trigger a sync: + +1. Click **"Sync Specs"** button at the top +2. All spec files are re-parsed +3. Database updates immediately +4. Board refreshes within 3 seconds + +Use this when: +- Testing the sync functionality +- Recovering from errors +- Adding a new spec folder manually + +## Configuration + +### Spec Watcher Management + +The spec watcher starts automatically, but you can control it via API: + +**Start watcher for a project:** +```bash +curl -X POST http://localhost:8051/api/spec-watcher/start/{project_id} +``` + +**Stop watcher for a project:** +```bash +curl -X POST http://localhost:8051/api/spec-watcher/stop/{project_id} +``` + +**Start all project watchers:** +```bash +curl -X POST http://localhost:8051/api/spec-watcher/start-all +``` + +**Check watcher status:** +```bash +curl http://localhost:8051/api/spec-watcher/status +``` + +Example status response: +```json +{ + "status": { + "enabled": true, + "projects_watched": 1, + "projects": { + "1": { + "project_path": "/Users/you/Projects/myapp", + "specs_path": "/Users/you/Projects/myapp/agent-os/specs", + "watching": true + } + } + } +} +``` + +### Adjusting Refresh Rate + +The default refresh rate is 3 seconds. To change it: + +**File:** `frontend/src/components/KanbanBoard.tsx` + +```typescript +const { data: kanbanData, isLoading } = useQuery({ + queryKey: ['kanban', projectId, includeArchived], + queryFn: async () => { + // ... fetch logic + }, + refetchInterval: 3000, // Change this value (milliseconds) +}); +``` + +**Recommended values:** +- **3000ms (3s)**: Real-time updates, good UX +- **5000ms (5s)**: Balanced performance +- **10000ms (10s)**: Low-traffic, battery-saving + +### Debounce Delay + +The spec watcher waits 2 seconds after detecting a change before syncing. To adjust: + +**File:** `app/core/spec_watcher.py` + +```python +class SpecFileHandler(FileSystemEventHandler): + def __init__(self, project_id: int, project_path: str): + # ... + self.debounce_delay = 2.0 # Change this value (seconds) +``` + +**Why debounce?** +- Prevents sync spam during rapid file edits +- Batches related changes together +- Reduces database load + +## Project Structure Requirements + +For the Kanban board to work, your project must have this structure: + +``` +your-project/ +└── agent-os/ + └── specs/ + ├── 2025-10-29-feature-name/ + │ ├── spec.md # Optional: Feature specification + │ └── tasks.md # Required: Task breakdown + └── 2025-11-01-another-feature/ + ├── spec.md + └── tasks.md +``` + +**Folder naming convention:** +- Format: `YYYY-MM-DD-feature-slug` +- Example: `2025-10-29-manual-appointment-times` +- Slug becomes the spec name (spaces replace hyphens) + +## Troubleshooting + +### Tasks Not Showing Up + +**Check 1: Is the spec watcher running?** +```bash +curl http://localhost:8051/api/spec-watcher/status +``` + +If `"watching": false`, restart the watcher: +```bash +curl -X POST http://localhost:8051/api/spec-watcher/start/{project_id} +``` + +**Check 2: Are your tasks in the right format?** + +Tasks must use the checkbox format with numeric prefixes: +```markdown +- [ ] 1.0 Task title +- [x] 2.1 Another task +``` + +Not this: +```markdown +- [ ] Task without number +- Some random text +``` + +**Check 3: Is tasks.md in the right location?** +``` +✅ project/agent-os/specs/2025-10-29-feature/tasks.md +❌ project/specs/tasks.md +❌ project/agent-os/tasks.md +``` + +**Check 4: Check the MCP server logs** +```bash +tail -50 logs/mcp_server.log +``` + +Look for: +- `✅ Updated spec 'Feature Name' with X tasks` +- Any error messages about parsing + +### Board Not Auto-Refreshing + +**Check 1: Is polling enabled?** + +Open browser DevTools → Network tab → Filter by "kanban" + +You should see requests every 3 seconds to: +``` +GET /api/projects/1/kanban?include_archived=false +``` + +If not, check that React Query is configured correctly. + +**Check 2: Clear browser cache** +``` +Ctrl+Shift+R (Windows/Linux) +Cmd+Shift+R (Mac) +``` + +**Check 3: Check frontend logs** + +Open browser Console and look for errors related to: +- React Query +- Axios requests +- WebSocket connections (if applicable) + +### Sync Taking Too Long + +**Expected timings:** +- File change detected: < 1 second +- Debounce wait: 2 seconds +- Database sync: < 1 second +- Frontend refresh: 3 seconds +- **Total**: ~6 seconds max + +**If slower:** + +1. Check disk I/O (is your disk slow?) +2. Check database size (vacuum if needed): + ```bash + sqlite3 data/claude-os.db "VACUUM;" + ``` +3. Check CPU usage (spec parsing is CPU-intensive for large specs) + +### Parser Errors + +**Common issues:** + +**Issue:** "No tasks found" +- **Cause:** Tasks not in checkbox format +- **Fix:** Add `- [ ]` or `- [x]` before task lines + +**Issue:** "Invalid task code" +- **Cause:** Missing numeric prefix (e.g., `1.0`, `2.1`) +- **Fix:** Add numbers: `- [ ] 1.0 Task title` + +**Issue:** "Spec not found" +- **Cause:** Folder name doesn't match expected format +- **Fix:** Rename to `YYYY-MM-DD-feature-name` + +## Advanced Usage + +### Custom Task Status Updates + +You can manually update task status via API: + +```bash +curl -X PATCH http://localhost:8051/api/tasks/{task_id}/status \ + -H "Content-Type: application/json" \ + -d '{ + "status": "in_progress", + "actual_minutes": 120 + }' +``` + +Valid statuses: `todo`, `in_progress`, `done`, `blocked` + +### Archiving Specs + +Archive completed specs to declutter the board: + +**Via UI:** +1. Click "Archive" button on spec card +2. Spec moves to archived view + +**Via API:** +```bash +curl -X POST http://localhost:8051/api/specs/{spec_id}/archive +``` + +**To view archived specs:** +- Toggle "Show Archived" checkbox in the UI + +### Bulk Operations + +**Sync all specs for a project:** +```bash +curl -X POST http://localhost:8051/api/projects/{project_id}/specs/sync +``` + +Response: +```json +{ + "project_id": 1, + "message": "Specs synced successfully", + "synced": 0, + "updated": 3, + "total": 3, + "errors": [] +} +``` + +## Performance Considerations + +### Database Size + +Each task creates a database row. For large projects: + +**Estimate storage:** +- 100 specs × 50 tasks = 5,000 rows +- SQLite handles this easily (millions of rows supported) + +**Optimize periodically:** +```bash +sqlite3 data/claude-os.db "VACUUM; ANALYZE;" +``` + +### Frontend Performance + +With many tasks, the Kanban board may slow down: + +**Optimization tips:** +1. Archive old specs (reduces rendered tasks) +2. Increase refresh interval to 5-10 seconds +3. Filter by status (show only active tasks) + +### File Watcher Overhead + +The spec watcher uses minimal resources: +- CPU: < 1% idle, ~5% during sync +- Memory: ~20 MB per project +- Disk I/O: Only on file changes + +**Disable if needed:** +```bash +curl -X POST http://localhost:8051/api/spec-watcher/stop/{project_id} +``` + +## API Reference + +See full API documentation in `docs/API_REFERENCE.md` + +**Key endpoints:** + +- `GET /api/projects/{id}/kanban` - Get Kanban data +- `GET /api/projects/{id}/specs` - List all specs +- `POST /api/projects/{id}/specs/sync` - Manual sync +- `PATCH /api/tasks/{id}/status` - Update task status +- `POST /api/specs/{id}/archive` - Archive spec +- `GET /api/spec-watcher/status` - Watcher status + +## Related Documentation + +- **What is Claude OS**: `docs/guides/WHAT_IS_CLAUDE_OS.md` +- **Session Workflow**: `docs/guides/IDEAL_SESSION_WORKFLOW.md` +- **API Reference**: `docs/API_REFERENCE.md` +- **Quick Start**: `docs/QUICK_START_CLAUDE_OS.md` + +## Support + +If you encounter issues: + +1. Check the logs: `tail -f logs/mcp_server.log` +2. Check watcher status: `curl http://localhost:8051/api/spec-watcher/status` +3. Try manual sync: Click "Sync Specs" button +4. Restart MCP server: `./scripts/restart_mcp.sh` +5. Open an issue: [GitHub Issues](https://github.com/anthropics/claude-os/issues) diff --git a/docs/guides/VISUAL_GUIDE.md b/docs/guides/VISUAL_GUIDE.md new file mode 100644 index 0000000..c849a9b --- /dev/null +++ b/docs/guides/VISUAL_GUIDE.md @@ -0,0 +1,451 @@ +# Claude OS Visual Guide + +**A complete visual tour of the Claude OS interface** + +--- + +## 📸 Full Application Tour + +### 1. Welcome Screen + + + +**What you see:** +- Claude OS hero image and branding +- Quick start guide +- Links to documentation +- Get started button + +**What you can do:** +- Learn about Claude OS features +- Access documentation +- Navigate to the main application + +--- + +### 2. Projects List + + + +**What you see:** +- All your Claude OS projects +- Project names and paths +- Quick actions (delete, configure) +- Create new project button + +**What you can do:** +- View all projects +- Select a project to work with +- Create new projects +- Delete old projects +- See project metadata + +**Key Features:** +- ✅ Fast project switching +- ✅ Visual project cards +- ✅ Quick project creation +- ✅ Project organization + +--- + +### 3. Project Overview + + + +**What you see:** +- Project name and description +- Database ID +- Project path +- MCP configuration status (X of 5 MCPs) +- List of configured MCPs: + - knowledge_docs + - project_profile + - project_index + - project_memories + - code_structure + +**What you can do:** +- View project details +- Check MCP configuration +- Access configure button +- See which MCPs are set up +- Understand project structure + +**Key Features:** +- ✅ Complete project metadata +- ✅ MCP status at a glance +- ✅ Configuration access +- ✅ Visual MCP indicators (configured vs not configured) + +--- + +### 4. Kanban Board + + + +**What you see:** +- Project specs organized as Kanban boards +- Progress bars for each spec +- Task counts by status (Todo/In Progress/Done/Blocked) +- Sync specs button +- Show archived toggle +- Summary statistics: + - Total specs + - Total tasks + - Completion percentage + +**What you can do:** +- View all active specs +- See task progress visually +- Click tasks to view details +- Update task status +- Archive completed specs +- Sync new specs from agent-os folder +- Track implementation progress + +**Key Features:** +- ✅ Visual progress tracking +- ✅ Real-time task management +- ✅ Archive completed work +- ✅ Automatic sync from agent-os +- ✅ Progress percentages +- ✅ Task organization by phase + +**Perfect for:** +- Tracking Agent-OS spec implementation +- Visualizing project progress +- Managing task workflow +- Team collaboration +- Sprint planning + +--- + +### 4.5. Task Detail Modal + + + +**What you see:** +- Task code and title +- Full task description +- Current status +- Time estimates (estimated vs actual) +- Risk level +- Dependencies +- Status update buttons + +**What you can do:** +- View complete task details +- Update task status (Todo → In Progress → Done → Blocked) +- Track time spent vs estimated +- See task dependencies +- Close modal to return to Kanban board + +**Key Features:** +- ✅ Quick status updates +- ✅ Time tracking +- ✅ Risk visibility +- ✅ Dependency awareness +- ✅ Clean modal interface + +--- + +### 6. MCP Management + + + +**What you see:** +- Selected MCP knowledge base +- Document list +- Upload interface +- Search functionality +- KB statistics + +**What you can do:** +- Browse documents in knowledge base +- Upload new documents (.md, .txt, .pdf, code files) +- Search across KB +- View KB stats +- Manage knowledge base content + +**Key Features:** +- ✅ Drag & drop file upload +- ✅ Multi-file support +- ✅ Document browser +- ✅ Search within KB +- ✅ File type indicators + +**Supported Knowledge Bases:** +- **project_memories** - Your decisions and insights +- **project_profile** - Coding standards and architecture +- **project_index** - Automated codebase index +- **knowledge_docs** - Documentation and guides +- **code_structure** - Tree-sitter structural index + +--- + +### 7. Chat Interface + + + +**What you see:** +- Chat conversation with Claude +- Message history +- Input field +- RAG settings: + - Hybrid Search toggle + - Reranking toggle + - Agentic RAG toggle + +**What you can do:** +- Ask questions about your project +- Search knowledge bases conversationally +- Get AI-powered answers with citations +- Adjust search strategies +- Reference past conversations + +**Key Features:** +- ✅ Natural language queries +- ✅ Semantic search across KBs +- ✅ Source citations +- ✅ Customizable RAG strategies +- ✅ Context-aware responses + +**RAG Settings:** +- **Hybrid Search** - Combines semantic + keyword search +- **Reranking** - Re-orders results for better relevance +- **Agentic RAG** - AI-powered query refinement + +--- + +### 8. Services Dashboard + + + +**What you see:** +- All Claude OS services status +- Service health indicators (Running/Stopped) +- Individual service cards: + - MCP Server (port 8051) + - Frontend Server (port 5173) + - RQ Worker + - File Watcher + - Redis + - Ollama + +**What you can do:** +- Monitor service health +- See which services are running +- Check service ports +- Identify issues quickly +- Verify complete stack status + +**Key Features:** +- ✅ Real-time service monitoring +- ✅ Visual status indicators +- ✅ Port information +- ✅ Service descriptions +- ✅ Quick health check + +**Service Details:** + +| Service | Purpose | Port | +|---------|---------|------| +| **MCP Server** | FastAPI backend, knowledge base APIs | 8051 | +| **Frontend** | React UI (Vite dev server) | 5173 | +| **RQ Worker** | Background job processing | - | +| **File Watcher** | Auto-sync knowledge_docs folders | - | +| **Redis** | Cache & job queue | 6379 | +| **Ollama** | Local LLM inference | 11434 | + +--- + +### 9. Mobile Experience + + + +**What you see:** +- Responsive mobile interface +- Optimized navigation +- Touch-friendly controls +- Mobile-optimized layouts + +**What you can do:** +- Access Claude OS from any device +- Use all features on mobile +- Responsive design adapts to screen size +- Full functionality on tablets and phones + +**Key Features:** +- ✅ Fully responsive design +- ✅ Touch-optimized UI +- ✅ Mobile navigation +- ✅ All features accessible on mobile +- ✅ Supports all modern mobile browsers + +**Supported Devices:** +- 📱 iPhone (iOS 14+) +- 📱 Android phones +- 📱 Tablets (iPad, Android) +- 💻 Any screen size from 375px to 1920px+ + +--- + +## 🎯 Navigation Flow + +### Typical Workflow + +``` +1. Welcome Screen + ↓ +2. Projects List → Select/Create Project + ↓ +3. Project Overview → See MCP Status + ↓ +4. Choose a Tab: + ├─→ Kanban Board (track implementation) + ├─→ MCP Management (upload docs) + ├─→ Chat (ask questions) + └─→ Services (monitor health) +``` + +### Quick Access Paths + +**To track spec progress:** +``` +Projects List → Select Project → Kanban Board Tab +``` + +**To upload documentation:** +``` +Projects List → Select Project → MCP Management → Select KB → Upload +``` + +**To ask project questions:** +``` +Projects List → Select Project → Chat Tab +``` + +**To check service health:** +``` +Projects List → Select Project → Services Tab +``` + +--- + +## 🎨 UI Components + +### Common Elements + +**Sidebar (Left):** +- Projects list +- Project MCPs +- RAG settings +- Quick actions + +**Top Navigation:** +- Home button +- Project name +- Tab navigation +- Welcome link + +**Main Content:** +- Tab-specific content +- Interactive elements +- Real-time data + +**Status Indicators:** +- ✅ Green = Success/Active +- ⏸️ Yellow = Paused +- ❌ Red = Error/Stopped +- 📊 Blue = In Progress + +--- + +## 📱 Responsive Design + +All pages are designed to work on: +- 💻 Desktop (1920px+) +- 💻 Laptop (1440px) +- 📱 Tablet (768px) +- 📱 Mobile (375px+) + +**Optimized for:** +- Chrome +- Firefox +- Safari +- Edge + +--- + +## 🎯 Feature Highlights by Page + +### Welcome Screen +- First-time user onboarding +- Feature introduction +- Documentation access + +### Projects List +- Multi-project management +- Quick project switching +- Project creation wizard + +### Project Overview +- At-a-glance project status +- MCP configuration visibility +- Quick configuration access + +### Kanban Board +- Visual task management +- Progress tracking +- Spec implementation workflow +- Archive management + +### MCP Management +- Knowledge base content management +- Document upload +- KB organization + +### Chat Interface +- Natural language queries +- Semantic search +- AI-powered answers + +### Services Dashboard +- System health monitoring +- Service status visibility +- Quick diagnostics + +--- + +## 🚀 Getting Started + +**For new users:** + +1. Start at **Welcome Screen** → Learn about features +2. Go to **Projects List** → Create your first project +3. View **Project Overview** → See MCP setup +4. Visit **MCP Management** → Upload documentation +5. Try **Chat** → Ask questions about your docs +6. Check **Kanban** → Track spec implementation +7. Monitor **Services** → Ensure everything running + +**For experienced users:** + +1. **Projects List** → Select project +2. **Kanban** → Continue implementation +3. **Chat** → Quick questions as needed +4. **Services** → Occasional health check + +--- + +## 📖 Related Documentation + +- **[README.md](../../README.md)** - Complete setup guide +- **[WHAT_IS_CLAUDE_OS.md](./WHAT_IS_CLAUDE_OS.md)** - Feature overview +- **[KANBAN_BOARD_GUIDE.md](./KANBAN_BOARD_GUIDE.md)** - Kanban detailed guide +- **[SESSION_START_PROTOCOL.md](./SESSION_START_PROTOCOL.md)** - Session management +- **[API_REFERENCE.md](../API_REFERENCE.md)** - Complete API docs + +--- + +**This visual guide shows the complete Claude OS interface. Every screenshot is from the actual application running with real project data!** 🎉 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 58c0d2c..89e9357 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -21,6 +21,7 @@ }, "devDependencies": { "@eslint/js": "^9.36.0", + "@playwright/test": "^1.56.1", "@tailwindcss/typography": "^0.5.19", "@types/node": "^24.6.0", "@types/react": "^19.1.16", @@ -1111,6 +1112,22 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz", + "integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.56.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.38", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.38.tgz", @@ -4771,6 +4788,53 @@ "node": ">= 6" } }, + "node_modules/playwright": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz", + "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.56.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", + "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", diff --git a/frontend/package.json b/frontend/package.json index 6db0e0e..39e9099 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,8 @@ "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "screenshots": "node ../scripts/capture-screenshots.js" }, "dependencies": { "@tanstack/react-query": "^5.90.5", @@ -23,6 +24,7 @@ }, "devDependencies": { "@eslint/js": "^9.36.0", + "@playwright/test": "^1.56.1", "@tailwindcss/typography": "^0.5.19", "@types/node": "^24.6.0", "@types/react": "^19.1.16", diff --git a/frontend/public/assets/screenshots/kanban-task-detail-modal.png b/frontend/public/assets/screenshots/kanban-task-detail-modal.png new file mode 100644 index 0000000..a989381 Binary files /dev/null and b/frontend/public/assets/screenshots/kanban-task-detail-modal.png differ diff --git a/frontend/public/assets/screenshots/mobile-welcome-screen.png b/frontend/public/assets/screenshots/mobile-welcome-screen.png new file mode 100644 index 0000000..ac70713 Binary files /dev/null and b/frontend/public/assets/screenshots/mobile-welcome-screen.png differ diff --git a/frontend/public/assets/screenshots/project-chat-page.png b/frontend/public/assets/screenshots/project-chat-page.png new file mode 100644 index 0000000..5be9b02 Binary files /dev/null and b/frontend/public/assets/screenshots/project-chat-page.png differ diff --git a/frontend/public/assets/screenshots/project-kanban-page.png b/frontend/public/assets/screenshots/project-kanban-page.png new file mode 100644 index 0000000..046f1d0 Binary files /dev/null and b/frontend/public/assets/screenshots/project-kanban-page.png differ diff --git a/frontend/public/assets/screenshots/project-mcp-page.png b/frontend/public/assets/screenshots/project-mcp-page.png new file mode 100644 index 0000000..a989381 Binary files /dev/null and b/frontend/public/assets/screenshots/project-mcp-page.png differ diff --git a/frontend/public/assets/screenshots/project-overview-page.png b/frontend/public/assets/screenshots/project-overview-page.png new file mode 100644 index 0000000..b866829 Binary files /dev/null and b/frontend/public/assets/screenshots/project-overview-page.png differ diff --git a/frontend/public/assets/screenshots/project-services-dashboard-page.png b/frontend/public/assets/screenshots/project-services-dashboard-page.png new file mode 100644 index 0000000..5d20857 Binary files /dev/null and b/frontend/public/assets/screenshots/project-services-dashboard-page.png differ diff --git a/frontend/public/assets/screenshots/projects-list-page.png b/frontend/public/assets/screenshots/projects-list-page.png new file mode 100644 index 0000000..170cf0b Binary files /dev/null and b/frontend/public/assets/screenshots/projects-list-page.png differ diff --git a/frontend/public/assets/screenshots/welcome-screen.png b/frontend/public/assets/screenshots/welcome-screen.png new file mode 100644 index 0000000..6335594 Binary files /dev/null and b/frontend/public/assets/screenshots/welcome-screen.png differ diff --git a/frontend/src/components/KanbanBoard.tsx b/frontend/src/components/KanbanBoard.tsx index 499db22..c265779 100644 --- a/frontend/src/components/KanbanBoard.tsx +++ b/frontend/src/components/KanbanBoard.tsx @@ -69,7 +69,7 @@ export default function KanbanBoard({ projectId }: KanbanBoardProps) { }); return response.data; }, - refetchInterval: 30000, // Refetch every 30 seconds + refetchInterval: 3000, // Refetch every 3 seconds for real-time updates }); // Sync specs mutation diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 4f1e7d2..1ca4b80 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -5,6 +5,12 @@ import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], server: { + host: true, + allowedHosts: [ + 'localhost', + '.ngrok-free.app', + 'daa65fe0204a.ngrok-free.app' + ], proxy: { '/api': { target: 'http://localhost:8051', diff --git a/mcp_server/server.py b/mcp_server/server.py index 215c970..1d2ff32 100644 --- a/mcp_server/server.py +++ b/mcp_server/server.py @@ -1591,6 +1591,85 @@ async def api_watcher_status(): raise HTTPException(status_code=500, detail=str(e)) +# ============================================================================ +# SPEC WATCHER ENDPOINTS (for real-time agent-os spec syncing) +# ============================================================================ + +@app.post("/api/spec-watcher/start/{project_id}") +async def api_start_spec_watcher(project_id: int): + """Start spec watcher for a project.""" + try: + from app.core.spec_watcher import get_global_spec_watcher + + # Get project path + db_manager = get_sqlite_manager() + project = db_manager.get_project(project_id) + if not project: + raise HTTPException(status_code=404, detail="Project not found") + + spec_watcher = get_global_spec_watcher() + spec_watcher.start_project(project_id, project['path']) + + return { + "project_id": project_id, + "message": "Spec watcher started", + "status": spec_watcher.get_status() + } + except Exception as e: + logger.error(f"Failed to start spec watcher: {e}") + raise HTTPException(status_code=500, detail=str(e)) + + +@app.post("/api/spec-watcher/stop/{project_id}") +async def api_stop_spec_watcher(project_id: int): + """Stop spec watcher for a project.""" + try: + from app.core.spec_watcher import get_global_spec_watcher + + spec_watcher = get_global_spec_watcher() + spec_watcher.stop_project(project_id) + + return { + "project_id": project_id, + "message": "Spec watcher stopped", + "status": spec_watcher.get_status() + } + except Exception as e: + logger.error(f"Failed to stop spec watcher: {e}") + raise HTTPException(status_code=500, detail=str(e)) + + +@app.post("/api/spec-watcher/start-all") +async def api_start_all_spec_watchers(): + """Start spec watchers for all projects.""" + try: + from app.core.spec_watcher import get_global_spec_watcher + + spec_watcher = get_global_spec_watcher() + spec_watcher.start_all() + + return { + "message": "Spec watchers started for all projects", + "status": spec_watcher.get_status() + } + except Exception as e: + logger.error(f"Failed to start all spec watchers: {e}") + raise HTTPException(status_code=500, detail=str(e)) + + +@app.get("/api/spec-watcher/status") +async def api_spec_watcher_status(): + """Get spec watcher status.""" + try: + from app.core.spec_watcher import get_global_spec_watcher + + spec_watcher = get_global_spec_watcher() + return {"status": spec_watcher.get_status()} + except Exception as e: + logger.error(f"Failed to get spec watcher status: {e}") + raise HTTPException(status_code=500, detail=str(e)) + + # ============================================================================ # SPEC TRACKING ENDPOINTS (for agent-os integration and Kanban board) # ============================================================================ @@ -2492,6 +2571,47 @@ async def health_check(): return JSONResponse(content=health_status, status_code=status_code) +# ============================================================================ +# STARTUP/SHUTDOWN EVENTS +# ============================================================================ + +@app.on_event("startup") +async def startup_event(): + """Run tasks on server startup.""" + logger.info("🚀 Starting up Claude OS MCP Server...") + + # Auto-start spec watchers for all projects + try: + from app.core.spec_watcher import get_global_spec_watcher + + spec_watcher = get_global_spec_watcher() + spec_watcher.start_all() + + status = spec_watcher.get_status() + if status['enabled']: + logger.info(f"✅ Spec watchers started for {status['projects_watched']} project(s)") + else: + logger.info("ℹ️ No projects found - spec watchers will start when projects are created") + except Exception as e: + logger.error(f"❌ Failed to start spec watchers: {e}") + + +@app.on_event("shutdown") +async def shutdown_event(): + """Run tasks on server shutdown.""" + logger.info("👋 Shutting down Claude OS MCP Server...") + + # Stop all spec watchers + try: + from app.core.spec_watcher import get_global_spec_watcher + + spec_watcher = get_global_spec_watcher() + spec_watcher.stop_all() + logger.info("✅ Spec watchers stopped") + except Exception as e: + logger.error(f"❌ Failed to stop spec watchers: {e}") + + def main(): """Start the MCP server.""" # Validate configuration before starting diff --git a/scripts/README.md b/scripts/README.md index 4eae0b2..c91d43d 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -166,6 +166,88 @@ RUN /opt/claude-os/scripts/index-codebase.sh MyApp /app http://claude-os:8051 --- +## Screenshot Capture Script + +**`capture-screenshots.js`** - Automatically capture beautiful screenshots of the Claude OS interface using Playwright. + +### Usage + +```bash +# From frontend directory +cd frontend +npm run screenshots + +# Or directly +node ../scripts/capture-screenshots.js +``` + +### Prerequisites + +1. **Services running:** + ```bash + ./start.sh # Starts MCP server (8051) and frontend (5173) + ``` + +2. **At least one project created** (e.g., Pistn) + +3. **Playwright installed:** + ```bash + cd frontend + npx playwright install chromium + ``` + +### What Gets Captured + +Automatically captures 9 screenshots: + +1. `welcome-screen.png` - Landing page +2. `projects-list-page.png` - Projects overview +3. `project-overview-page.png` - Project details & MCP status +4. `project-kanban-page.png` - Kanban board (full page) +5. `kanban-task-detail-modal.png` - Task detail popup +6. `project-mcp-page.png` - Knowledge base management +7. `project-chat-page.png` - Chat interface +8. `project-services-dashboard-page.png` - Service monitoring +9. `mobile-welcome-screen.png` - Mobile version (375x812) + +### Output + +All screenshots saved to: +``` +frontend/public/assets/screenshots/ +``` + +### When to Re-capture + +**Update screenshots when:** +- UI design changes +- New features added +- Before major releases +- For updated documentation + +**Quick update:** +```bash +# 1. Ensure services running +./start.sh + +# 2. Run screenshot capture +cd frontend && npm run screenshots + +# 3. Commit updated screenshots +git add public/assets/screenshots/ +git commit -m "📸 Update UI screenshots" +``` + +### Configuration + +Edit `scripts/capture-screenshots.js` to customize: +- Viewport size (default: 1920x1080) +- Wait times for animations +- Which pages to capture +- Headless mode for CI/CD + +--- + ## Future Scripts Additional utility scripts will be added here: @@ -174,6 +256,8 @@ Additional utility scripts will be added here: - `migrate-project.sh` - Migrate project between Claude OS instances - `export-memories.sh` - Export project memories as markdown - `sync-team-knowledge.sh` - Sync knowledge bases across team +- `test-e2e.js` - End-to-end UI testing with Playwright +- `seed-data.js` - Seed test data for demos --- diff --git a/scripts/capture-screenshots.js b/scripts/capture-screenshots.js new file mode 100644 index 0000000..1ffdcaa --- /dev/null +++ b/scripts/capture-screenshots.js @@ -0,0 +1,168 @@ +/** + * Claude OS Screenshot Capture Script + * + * Automatically captures beautiful screenshots of the entire Claude OS interface + * using Playwright for documentation and marketing materials. + * + * Usage: + * node scripts/capture-screenshots.js + * + * Prerequisites: + * - Frontend running on http://localhost:5173 + * - MCP server running on http://localhost:8051 + * - At least one project created (e.g., Pistn) + */ + +const { chromium } = require(require('path').join(__dirname, '../frontend/node_modules/playwright')); +const path = require('path'); +const fs = require('fs'); + +// Configuration +const BASE_URL = 'http://localhost:5173'; +const SCREENSHOTS_DIR = path.join(__dirname, '../frontend/public/assets/screenshots'); +const VIEWPORT = { width: 1920, height: 1080 }; +const WAIT_TIME = 2000; // Wait for animations/data loading + +// Ensure screenshots directory exists +if (!fs.existsSync(SCREENSHOTS_DIR)) { + fs.mkdirSync(SCREENSHOTS_DIR, { recursive: true }); +} + +async function captureScreenshots() { + console.log('🎭 Starting Claude OS screenshot capture...\n'); + + const browser = await chromium.launch({ + headless: false, // Set to true for CI/CD + }); + + const context = await browser.newContext({ + viewport: VIEWPORT, + }); + + const page = await context.newPage(); + + try { + // 1. Welcome Screen + console.log('📸 Capturing: Welcome Screen...'); + await page.goto(BASE_URL); + await page.waitForTimeout(WAIT_TIME); + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'welcome-screen.png'), + fullPage: false, + }); + console.log('✅ Saved: welcome-screen.png\n'); + + // Navigate to app + await page.click('a[href="/app"]'); + await page.waitForTimeout(WAIT_TIME); + + // 2. Projects List + console.log('📸 Capturing: Projects List...'); + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'projects-list-page.png'), + fullPage: false, + }); + console.log('✅ Saved: projects-list-page.png\n'); + + // Select first project (Pistn) + const firstProject = await page.locator('.p-3.rounded-lg.border').first(); + await firstProject.click(); + await page.waitForTimeout(WAIT_TIME); + + // 3. Project Overview + console.log('📸 Capturing: Project Overview...'); + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'project-overview-page.png'), + fullPage: false, + }); + console.log('✅ Saved: project-overview-page.png\n'); + + // 4. Kanban Board + console.log('📸 Capturing: Kanban Board...'); + await page.click('button:has-text("Kanban Board")'); + await page.waitForTimeout(WAIT_TIME + 1000); // Extra time for Kanban data load + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'project-kanban-page.png'), + fullPage: true, // Capture full Kanban board + }); + console.log('✅ Saved: project-kanban-page.png\n'); + + // 5. Kanban - Task Detail Modal (if tasks exist) + try { + console.log('📸 Capturing: Task Detail Modal...'); + const taskCard = await page.locator('.bg-cool-blue\\/10.border').first(); + await taskCard.click(); + await page.waitForTimeout(1000); + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'kanban-task-detail-modal.png'), + fullPage: false, + }); + console.log('✅ Saved: kanban-task-detail-modal.png\n'); + + // Close modal + await page.keyboard.press('Escape'); + await page.waitForTimeout(500); + } catch (e) { + console.log('⚠️ No tasks found for task detail screenshot\n'); + } + + // 6. MCP Management + console.log('📸 Capturing: MCP Management...'); + await page.click('button:has-text("MCP Management")'); + await page.waitForTimeout(WAIT_TIME); + + // Click on first MCP in sidebar + const firstMCP = await page.locator('.p-2.rounded.border.text-sm').first(); + await firstMCP.click(); + await page.waitForTimeout(WAIT_TIME); + + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'project-mcp-page.png'), + fullPage: false, + }); + console.log('✅ Saved: project-mcp-page.png\n'); + + // 7. Chat Interface + console.log('📸 Capturing: Chat Interface...'); + await page.click('button:has-text("Chat")'); + await page.waitForTimeout(WAIT_TIME); + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'project-chat-page.png'), + fullPage: false, + }); + console.log('✅ Saved: project-chat-page.png\n'); + + // 8. Services Dashboard + console.log('📸 Capturing: Services Dashboard...'); + await page.click('button:has-text("Services")'); + await page.waitForTimeout(WAIT_TIME); + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'project-services-dashboard-page.png'), + fullPage: false, + }); + console.log('✅ Saved: project-services-dashboard-page.png\n'); + + // Bonus: Mobile screenshots (optional) + console.log('📱 Capturing mobile screenshots...'); + await page.setViewportSize({ width: 375, height: 812 }); // iPhone X + + await page.goto(BASE_URL); + await page.waitForTimeout(WAIT_TIME); + await page.screenshot({ + path: path.join(SCREENSHOTS_DIR, 'mobile-welcome-screen.png'), + fullPage: false, + }); + console.log('✅ Saved: mobile-welcome-screen.png\n'); + + console.log('✨ All screenshots captured successfully!\n'); + console.log(`📁 Screenshots saved to: ${SCREENSHOTS_DIR}\n`); + + } catch (error) { + console.error('❌ Error capturing screenshots:', error); + } finally { + await browser.close(); + } +} + +// Run the script +captureScreenshots().catch(console.error);