feat: add concurrent agents with dependency system and delightful UI

Major feature implementation for parallel agent execution with dependency-aware
scheduling and an engaging multi-agent UI experience.

Backend Changes:
- Add parallel_orchestrator.py for concurrent feature processing
- Add api/dependency_resolver.py with cycle detection (Kahn's algorithm + DFS)
- Add atomic feature_claim_next() with retry limit and exponential backoff
- Fix circular dependency check arguments in 4 locations
- Add AgentTracker class for parsing agent output and emitting updates
- Add browser isolation with --isolated flag for Playwright MCP
- Extend WebSocket protocol with agent_update messages and log attribution
- Add WSAgentUpdateMessage schema with agent states and mascot names
- Fix WSProgressMessage to include in_progress field

New UI Components:
- AgentMissionControl: Dashboard showing active agents with collapsible activity
- AgentCard: Individual agent status with avatar and thought bubble
- AgentAvatar: SVG mascots (Spark, Fizz, Octo, Hoot, Buzz) with animations
- ActivityFeed: Recent activity stream with stable keys (no flickering)
- CelebrationOverlay: Confetti animation with click/Escape dismiss
- DependencyGraph: Interactive node graph visualization with dagre layout
- DependencyBadge: Visual indicator for feature dependencies
- ViewToggle: Switch between Kanban and Graph views
- KeyboardShortcutsHelp: Help overlay accessible via ? key

UI/UX Improvements:
- Celebration queue system to handle rapid success messages
- Accessibility attributes on AgentAvatar (role, aria-label, aria-live)
- Collapsible Recent Activity section with persisted preference
- Agent count display in header
- Keyboard shortcut G to toggle Kanban/Graph view
- Real-time thought bubbles and state animations

Bug Fixes:
- Fix circular dependency validation (swapped source/target arguments)
- Add MAX_CLAIM_RETRIES=10 to prevent stack overflow under contention
- Fix THOUGHT_PATTERNS to match actual [Tool: name] format
- Fix ActivityFeed key prop to prevent re-renders on new items
- Add featureId/agentIndex to log messages for proper attribution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Auto
2026-01-17 12:59:42 +02:00
parent 91cc00a9d0
commit 85f6940a54
39 changed files with 4532 additions and 157 deletions

View File

@@ -79,6 +79,56 @@ def get_coding_prompt_yolo(project_dir: Path | None = None) -> str:
return load_prompt("coding_prompt_yolo", project_dir)
def get_single_feature_prompt(feature_id: int, project_dir: Path | None = None, yolo_mode: bool = False) -> str:
"""
Load the coding prompt with single-feature focus instructions prepended.
When the parallel orchestrator assigns a specific feature to an agent,
this prompt ensures the agent works ONLY on that feature.
Args:
feature_id: The specific feature ID to work on
project_dir: Optional project directory for project-specific prompts
yolo_mode: If True, use the YOLO prompt variant
Returns:
The prompt with single-feature instructions prepended
"""
# Get the base prompt
if yolo_mode:
base_prompt = get_coding_prompt_yolo(project_dir)
else:
base_prompt = get_coding_prompt(project_dir)
# Prepend single-feature instructions
single_feature_header = f"""## SINGLE FEATURE MODE
**CRITICAL: You are assigned to work on Feature #{feature_id} ONLY.**
This session is part of a parallel execution where multiple agents work on different features simultaneously. You MUST:
1. **Skip the `feature_get_next` step** - Your feature is already assigned: #{feature_id}
2. **Immediately mark feature #{feature_id} as in-progress** using `feature_mark_in_progress`
3. **Focus ONLY on implementing and testing feature #{feature_id}**
4. **Do NOT work on any other features** - other agents are handling them
When you complete feature #{feature_id}:
- Mark it as passing with `feature_mark_passing`
- Commit your changes
- End the session
If you cannot complete feature #{feature_id} due to a blocker:
- Use `feature_skip` to move it to the end of the queue
- Document the blocker in claude-progress.txt
- End the session
---
"""
return single_feature_header + base_prompt
def get_app_spec(project_dir: Path) -> str:
"""
Load the app spec from the project.