diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 844e56a..7186977 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -7,7 +7,7 @@ {"id":"bd-1c6","title":"TEST-002: Add store integration tests","description":"Test Coverage: Add integration tests for EventStore - event indexing, LRU eviction, worker tracking, query performance.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-03-03T07:53:40.409846186Z","created_by":"coder","updated_at":"2026-03-03T07:53:40.409846186Z","closed_at":"2026-03-03T07:53:40.409846186Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["store","testing"]} {"id":"bd-1cc","title":"Port FileHeatmap component to web dashboard","description":"Port the TUI FileHeatmap component (src/tui/components/FileHeatmap.ts) to React for the web dashboard. Add corresponding API endpoint if needed.","status":"closed","priority":3,"issue_type":"task","assignee":"coder","created_at":"2026-03-03T14:27:43.759301428Z","created_by":"coder","updated_at":"2026-03-03T15:08:13.822190937Z","closed_at":"2026-03-03T15:08:13.792085291Z","close_reason":"done","source_repo":".","compaction_level":0,"original_size":0,"labels":["frontend","phase-4","web"]} {"id":"bd-1e1","title":"P3-001: Setup Express HTTP server with static file serving","description":"Phase 3 Web Dashboard: Create Express server in src/web/server.ts that serves static files and handles WebSocket upgrade. Foundation for web dashboard.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-03-03T07:52:09.228852666Z","created_by":"coder","updated_at":"2026-03-03T10:05:21.171663977Z","closed_at":"2026-03-03T10:05:21.171457522Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["phase-3","server","web"]} -{"id":"bd-1fe","title":"Add RecoveryPanel component to web frontend","description":"Port TUI RecoveryPanel.ts to React web frontend. Create src/web/frontend/src/components/RecoveryPanel.tsx showing recovery suggestions for stuck workers.","status":"open","priority":2,"issue_type":"task","created_at":"2026-03-03T14:26:22.464306236Z","created_by":"coder","updated_at":"2026-03-03T14:26:22.464306236Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["frontend","phase-3","web"]} +{"id":"bd-1fe","title":"Add RecoveryPanel component to web frontend","description":"Port TUI RecoveryPanel.ts to React web frontend. Create src/web/frontend/src/components/RecoveryPanel.tsx showing recovery suggestions for stuck workers.","status":"in_progress","priority":2,"issue_type":"task","assignee":"coder","created_at":"2026-03-03T14:26:22.464306236Z","created_by":"coder","updated_at":"2026-03-03T15:24:21.626219525Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["frontend","phase-3","web"]} {"id":"bd-1fk","title":"P1: Add Express HTTP server for web dashboard","description":"Set up Express.js HTTP server with basic routing for web dashboard. Should serve static files and provide API endpoints for worker data. Part of Phase 3 Web Dashboard.","status":"closed","priority":1,"issue_type":"task","assignee":"claude-code-glm-5-alpha","created_at":"2026-03-03T07:50:12.280655428Z","created_by":"coder","updated_at":"2026-03-03T09:37:50.271173474Z","closed_at":"2026-03-03T08:51:00.693337164Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["http","phase-3","server","web"],"comments":[{"id":10,"issue_id":"bd-1fk","author":"Jed Arden","text":"Express server implemented in src/web/server.ts","created_at":"2026-03-03T08:52:43Z"}]} {"id":"bd-1fm","title":"ALERT: Worker claude-code-glm-5-alpha has no work available","description":"# Worker Starvation Alert\n\nWorker **claude-code-glm-5-alpha** has exhausted all priorities and found zero work.\n\nThis is considered an error state - there should always be more work.\n\n## Worker State\n\n- **Executor:** claude-code-glm-5\n- **Model:** glm-5\n- **Workspace:** /home/coder/FABRIC\n- **Root Boundary:** /home/coder/FABRIC\n- **Last completion:** \n- **Beads completed:** 0\n- **Claim success rate:** %\n- **Uptime:** 31401s (h)\n- **Consecutive empty iterations:** 5\n\n## Priorities Exhausted\n\n1. ✗ Local workspace (bottoms-up): No beads in /home/coder/FABRIC or subfolders\n2. ✗ Parent exploration: No suitable workspaces found\n3. ✓ Maintenance: Completed (cleaned orphaned claims/locks)\n4. ✗ Gap analysis: false - No gaps found or created\n5. ✗ HUMAN alternatives: true - No HUMAN beads found to unblock\n\n## Discovered Workspaces\n\nTotal: 1\n\n- /home/coder/FABRIC\n\n## Required Actions\n\n1. Review discovery roots: Are all project folders being scanned?\n2. Check if projects need new features/tasks\n3. Review ROADMAP.md files across projects\n4. Enable gap analysis if disabled: `--enable-gap-analysis`\n5. Enable HUMAN alternatives if disabled\n6. Create manual beads to bootstrap work\n\n---\n*This alert was created automatically by Priority 6*","status":"closed","priority":0,"issue_type":"human","assignee":"coder","created_at":"2026-03-03T13:06:51.751924505Z","created_by":"coder","updated_at":"2026-03-03T13:08:06.993513587Z","closed_at":"2026-03-03T13:08:06.982302024Z","close_reason":"False positive worker starvation alert. Ready queue has 22 beads available. Worker discovery should check .beads/ready-queue.json before creating starvation alerts.","source_repo":".","compaction_level":0,"original_size":0} {"id":"bd-1fz","title":"Add React Testing Library tests for WorkerGrid component","description":"Add unit tests for src/web/frontend/src/components/WorkerGrid.tsx using React Testing Library and Vitest","status":"closed","priority":2,"issue_type":"task","assignee":"coder","created_at":"2026-03-03T14:27:27.809285552Z","created_by":"coder","updated_at":"2026-03-03T15:00:31.604214765Z","closed_at":"2026-03-03T15:00:31.576519565Z","close_reason":"completed","source_repo":".","compaction_level":0,"original_size":0,"labels":["frontend","phase-3","testing","web"]} diff --git a/src/web/frontend/src/App.tsx b/src/web/frontend/src/App.tsx index 8f8def7..5af87a5 100644 --- a/src/web/frontend/src/App.tsx +++ b/src/web/frontend/src/App.tsx @@ -5,6 +5,7 @@ import ActivityStream from './components/ActivityStream'; import WorkerDetail from './components/WorkerDetail'; import CollisionAlert from './components/CollisionAlert'; import FileHeatmap from './components/FileHeatmap'; +import DependencyDag from './components/DependencyDag'; const App: React.FC = () => { const [workers, setWorkers] = useState([]); @@ -14,6 +15,7 @@ const App: React.FC = () => { const [collisionAlerts, setCollisionAlerts] = useState([]); const [showCollisionPanel, setShowCollisionPanel] = useState(false); const [showFileHeatmap, setShowFileHeatmap] = useState(false); + const [showDependencyDag, setShowDependencyDag] = useState(false); const handleWebSocketMessage = useCallback((message: WebSocketMessage) => { if (message.type === 'init') { @@ -118,6 +120,14 @@ const App: React.FC = () => {

FABRIC

+
); diff --git a/src/web/frontend/src/index.css b/src/web/frontend/src/index.css index 68900bb..5903b60 100644 --- a/src/web/frontend/src/index.css +++ b/src/web/frontend/src/index.css @@ -53,6 +53,32 @@ body { gap: 1rem; } +.dag-toggle { + display: flex; + align-items: center; + gap: 0.375rem; + background: rgba(33, 150, 243, 0.2); + border: 1px solid var(--info); + color: var(--info); + padding: 0.375rem 0.625rem; + border-radius: 4px; + cursor: pointer; + transition: all 0.2s; +} + +.dag-toggle:hover { + background: rgba(33, 150, 243, 0.3); +} + +.dag-toggle-icon { + font-size: 0.875rem; +} + +.dag-toggle-label { + font-size: 0.75rem; + font-weight: 600; +} + .collision-alert-toggle { display: flex; align-items: center; diff --git a/src/web/frontend/src/types.ts b/src/web/frontend/src/types.ts index 7aa913e..0691466 100644 --- a/src/web/frontend/src/types.ts +++ b/src/web/frontend/src/types.ts @@ -237,3 +237,72 @@ export interface DagOptions { } export type DagViewMode = 'tree' | 'blockers' | 'ready' | 'stats'; + +// ============================================ +// Recovery Playbook Types +// ============================================ + +export type ErrorCategory = + | 'network' + | 'permission' + | 'validation' + | 'resource' + | 'not_found' + | 'timeout' + | 'syntax' + | 'tool' + | 'unknown'; + +export type RecoveryPriority = 'immediate' | 'high' | 'normal' | 'low'; + +export type RecoveryActionType = + | 'retry' + | 'backoff' + | 'alternative' + | 'escalate' + | 'skip' + | 'fix_config' + | 'install_dep' + | 'fix_permissions' + | 'cleanup' + | 'restart' + | 'investigate'; + +export interface RecoveryAction { + id: string; + type: RecoveryActionType; + title: string; + description: string; + priority: RecoveryPriority; + automated: boolean; + command?: string; + expectedOutcome?: string; + prerequisites?: string[]; + riskLevel?: 'safe' | 'moderate' | 'risky'; + estimatedTime?: number; +} + +export interface RecoverySuggestion { + id: string; + errorGroupId: string; + playbookId?: string; + category: ErrorCategory; + title: string; + errorSummary: string; + actions: RecoveryAction[]; + generatedAt: number; + confidence: number; + affectedWorkers: string[]; + relatedErrors?: string[]; + isActive: boolean; +} + +export interface RecoveryStats { + totalSuggestions: number; + activeSuggestions: number; + byCategory: Record; + automatedActions: number; + manualActions: number; + avgConfidence: number; + topActionTypes: Array<{ type: RecoveryActionType; count: number }>; +}