From ce338389687b294879d031e182ab03163426aa7f Mon Sep 17 00:00:00 2001 From: Thomas Marchand Date: Fri, 2 Jan 2026 17:45:01 +0000 Subject: [PATCH] OpenCode refactor and mission tracking fixes (#14) * Fix missions staying Active after completion with OpenCode backend - Add TerminalReason::Completed variant for successful task completion - Set terminal_reason in OpenCodeAgent on success to trigger auto-complete - Update control.rs to explicitly handle Completed terminal reason - Update CLAUDE.md with OpenCode backend documentation * Improve iOS dashboard UI polish - Remove harsh input field border, use ultraThinMaterial background with subtle focus glow - Clean up model selector pills: remove ugly truncated mission IDs, increase padding - Remove agent working indicator border for cleaner look - Increase input area bottom padding for better thumb reach * Add real-time event streaming for OpenCode backend - Add SSE streaming support to OpenCodeClient via /event endpoint - Parse and forward OpenCode events (thinking, tool_call, tool_result) - Update OpenCodeAgent to consume stream and forward to control channel - Add fallback to blocking mode if SSE connection fails This enables live UI updates in the dashboard when using OpenCode backend. * Fix running mission tracking to use actual executing mission ID Track the mission ID that the main `running` task is actually working on separately from `current_mission`, which can change when the user creates a new mission. This ensures ListRunning and GracefulShutdown correctly identify which mission is being executed. * Add MCP server for desktop tools and Playwright integration - Create desktop-mcp binary that exposes i3/Xvfb desktop automation tools as an MCP server for use with OpenCode backend - Add opencode.json with both desktop and Playwright MCP configurations - Update deployment command to include desktop-mcp binary - Document available MCP tools in CLAUDE.md Desktop tools: start_session, stop_session, screenshot, type, click, mouse_move, scroll, i3_command, get_text * Document SSH key and desktop-mcp binary in production section - Add ~/.ssh/cursor as the SSH key for production access - Add desktop-mcp binary location to production table * Emphasize bun usage and add gitignore entries - Add clear instructions to ALWAYS use bun, never npm for dashboard - Gitignore .playwright-mcp/ directory (local MCP data) - Gitignore dashboard/package-lock.json (we use bun.lockb) * Add mission delete and cleanup features to web and iOS dashboards Backend (Rust): - Add delete_mission() and delete_empty_untitled_missions() to supabase.rs - Add DELETE /api/control/missions/:id endpoint with running mission guard - Add POST /api/control/missions/cleanup endpoint for bulk cleanup Web Dashboard (Next.js): - Add deleteMission() and cleanupEmptyMissions() API functions - Add delete button (trash icon) on hover for each mission row - Add "Cleanup Empty" button with sparkles icon in filters area - Fix analytics to compute stats from missions/runs data instead of broken /api/stats iOS Dashboard (Swift): - Add deleteMission() and cleanupEmptyMissions() to APIService - Add delete() HTTP helper method - Add swipe-to-delete on mission rows (disabled for active missions) - Add "Cleanup" button with sparkles icon and progress indicator - Add success banner with auto-dismiss after cleanup * Fix CancelMission and MCP notification parsing bugs - CancelMission now uses running_mission_id instead of current_mission to correctly identify the executing mission (fixes race condition when user creates new mission while another is running) - MCP server JsonRpcRequest.id field now has #[serde(default)] to handle JSON-RPC 2.0 notifications which don't have an id field * Fix running mission tracking bugs - delete_mission: Query control actor for actual running missions instead of using always-empty running_missions list - cleanup_empty_missions: Exclude running missions from cleanup to prevent deleting missions mid-execution - get_parallel_config: Query control actor for accurate running count - Task completion: Save running_mission_id before clearing and use it for persist and auto-complete (fixes race when user creates new mission while task is running) All endpoints now use ControlCommand::ListRunning to get accurate running state from the control actor loop. * Fix bugbot issues: analytics cost, browser cleanup, title truncation, history append - Add get_total_cost_cents() to supabase.rs for aggregating all run costs - Update /api/stats endpoint to return actual total cost from database - Fix analytics page to use stats endpoint for total cost (not limited to 100 runs) - Fix desktop_mcp.rs to save browser_pid to session file after launch - Fix mission title truncation to use safe_truncate_index and append "..." - Fix mission history to append to existing DB history instead of replacing (prevents data loss when CreateMission is called during task execution) * Fix history context contamination and cumulative thinking content - Only push to local history if completed mission matches current mission, preventing old mission exchanges from contaminating new mission context - Accumulate thinking content across iterations so frontend replacement shows all thinking, matching OpenCode backend behavior * Fix MCP notifications, orphaned processes, and shutdown persistence - MCP server no longer sends responses to JSON-RPC notifications (per spec) - Clean up Xvfb/i3/Chromium processes on partial session startup failure - Graceful shutdown only persists history if running mission matches current * Fix partial field selection deserialization in cleanup endpoint Use PartialMission struct for partial field queries to avoid deserialization failure when DbMission's required fields are missing. * Clarify analytics success rate measures missions not tasks Update labels to "Mission Success Rate" and "X missions completed" to make it clear the metric is mission-level, not task-level. --- .claude/CLAUDE.md | 45 +- .gitignore | 6 + Cargo.toml | 8 + dashboard/src/app/analytics/page.tsx | 29 +- dashboard/src/app/control/control-client.tsx | 3 +- dashboard/src/app/history/page.tsx | 90 +- dashboard/src/lib/api.ts | 24 + .../Services/APIService.swift | 46 +- .../Views/History/HistoryView.swift | 145 ++- opencode.json | 18 + src/agents/leaf/executor.rs | 14 +- src/api/control.rs | 234 +++- src/api/routes.rs | 11 +- src/bin/desktop_mcp.rs | 1027 +++++++++++++++++ src/memory/supabase.rs | 117 +- 15 files changed, 1756 insertions(+), 61 deletions(-) create mode 100644 opencode.json create mode 100644 src/bin/desktop_mcp.rs diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index e2b6fc5..5647e9f 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -23,14 +23,19 @@ cargo test # Run tests cargo fmt # Format code cargo clippy # Lint -# Dashboard (uses Bun, NOT npm) +# Dashboard (uses Bun, NOT npm/yarn/pnpm) cd dashboard -bun install # Install deps +bun install # Install deps (NEVER use npm install) bun dev # Dev server (port 3001) bun run build # Production build +# IMPORTANT: Always use bun for dashboard, never npm +# - bun install (not npm install) +# - bun add (not npm install ) +# - bun run