1 line
150 KiB
JSON
1 line
150 KiB
JSON
[{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\avatar.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\badge.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\button.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\dialog.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\dropdown-menu.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\input.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\label.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\scroll-area.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\select.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\separator.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\tabs.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\textarea.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\components\\ui\\tooltip.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\eslint.config.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\lib\\utils.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\next.config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\postcss.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\remotion.config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\scripts\\bb-init.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\scripts\\capture-graph.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\scripts\\capture-kanban.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\scripts\\capture-sessions.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\scripts\\capture-timeline.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\activity\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\agent\\create\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\agents\\[agentId]\\stats\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\agents\\list\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\[id]\\comments\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\_shared.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\close\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\comment\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\create\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\read\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\reopen\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\beads\\update\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\events\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\mission\\[id]\\topology\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\mission\\assign\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\mission\\graph\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\mission\\list\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\projects\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\scan\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\sessions\\[beadId]\\comment\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\sessions\\[beadId]\\conversation\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\sessions\\[beadId]\\messages\\[messageId]\\ack\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\sessions\\[beadId]\\messages\\[messageId]\\read\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\sessions\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\archetypes\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\close\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\create\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\formulas\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\graph\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\join\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\launch\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\leave\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\list\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\prep\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\status\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\api\\swarm\\templates\\route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\graph\\page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\layout.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\mockup\\page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\page-old.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\sessions\\page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\app\\timeline\\page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\activity\\activity-panel.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'e' is defined but never used.","line":281,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":281,"endColumn":17}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client';\n\nimport { useEffect, useState, useMemo } from 'react';\nimport type { BeadIssue } from '../../lib/types';\nimport type { ActivityEvent } from '../../lib/activity';\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar';\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { cn } from '@/lib/utils';\n\ntype AgentStatus = 'active' | 'stale' | 'stuck' | 'dead';\n\ntype AgentTone = {\n cardClass: string;\n labelClass: string;\n ringClass: string;\n glowClass: string;\n};\n\ntype EventTone = {\n label: string;\n labelClass: string;\n dotClass: string;\n cardClass: string;\n idClass: string;\n};\n\ninterface AgentRosterEntry {\n name: string;\n status: AgentStatus;\n lastSeen: string | null;\n beadId: string;\n}\n\ninterface ActivityPanelProps {\n issues: BeadIssue[];\n collapsed?: boolean;\n}\n\nconst AGENT_LABEL = 'gt:agent';\n\n// Determine agent status based on last activity\nfunction deriveAgentStatus(lastSeenAt: string | null): AgentStatus {\n if (!lastSeenAt) return 'dead';\n \n const lastSeen = new Date(lastSeenAt);\n const now = new Date();\n const minutesSince = (now.getTime() - lastSeen.getTime()) / (1000 * 60);\n \n if (minutesSince < 15) return 'active';\n if (minutesSince < 30) return 'stale';\n if (minutesSince < 60) return 'stuck';\n return 'dead';\n}\n\n// Get agent name from bead\nfunction extractAgentName(issue: BeadIssue): string | null {\n const agentMatch = issue.title.match(/Agent:\\s*(\\S+)/i);\n if (agentMatch) return agentMatch[1];\n \n const agentLabel = issue.labels.find(l => l.startsWith('agent:'));\n if (agentLabel) return agentLabel.replace('agent:', '');\n \n return null;\n}\n\n// Build agent roster - filter out dead agents unless none are active\nfunction buildAgentRoster(issues: BeadIssue[]): AgentRosterEntry[] {\n const agentIssues = issues.filter(issue => \n issue.labels.includes(AGENT_LABEL) || \n issue.labels.some(l => l.startsWith('gt:agent')) ||\n issue.labels.includes('agent')\n );\n \n const roster = agentIssues.map(issue => {\n const name = extractAgentName(issue) || issue.title.replace('Agent: ', '') || issue.id;\n const status = deriveAgentStatus(issue.updated_at);\n \n return {\n name,\n status,\n lastSeen: issue.updated_at,\n beadId: issue.id,\n };\n }).sort((a, b) => {\n const statusOrder: Record<AgentStatus, number> = { active: 0, stale: 1, stuck: 2, dead: 3 };\n return statusOrder[a.status] - statusOrder[b.status];\n });\n\n // Show all non-dead agents, or at least the most recent ones\n return roster.filter(a => a.status !== 'dead' || a.lastSeen).slice(0, 10);\n}\n\n// Format relative time\nfunction formatRelativeTime(timestamp: string): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / (1000 * 60));\n const diffHours = Math.floor(diffMs / (1000 * 60 * 60));\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n \n if (diffMins < 1) return 'just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n \n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\nfunction getAgentTone(status: AgentStatus): AgentTone {\n const tones: Record<AgentStatus, AgentTone> = {\n active: {\n cardClass: 'bg-[#173126]',\n labelClass: 'text-[#7CB97A]',\n ringClass: 'ring-[#7CB97A]/45',\n glowClass: 'bg-[#7CB97A]/30',\n },\n stale: {\n cardClass: 'bg-[#322817]',\n labelClass: 'text-[#D4A574]',\n ringClass: 'ring-[#D4A574]/45',\n glowClass: 'bg-[#D4A574]/30',\n },\n stuck: {\n cardClass: 'bg-[#341a1f]',\n labelClass: 'text-[#C97A7A]',\n ringClass: 'ring-[#C97A7A]/45',\n glowClass: 'bg-[#C97A7A]/30',\n },\n dead: {\n cardClass: 'bg-[#2b232b]',\n labelClass: 'text-[#A78A94]',\n ringClass: 'ring-[#A78A94]/40',\n glowClass: 'bg-[#A78A94]/25',\n },\n };\n\n return tones[status];\n}\n\n// reopened=blue, closed=amber, created/opened=green, others semantic\nfunction getEventTone(kind: string): EventTone {\n const normalized = kind.toLowerCase();\n const byKind: Record<string, EventTone> = {\n created: {\n label: 'Created',\n labelClass: 'text-[#7CB97A]',\n dotClass: 'bg-[#7CB97A]',\n cardClass: 'bg-[#182f25]',\n idClass: 'text-[#9ACB98]',\n },\n opened: {\n label: 'Opened',\n labelClass: 'text-[#7CB97A]',\n dotClass: 'bg-[#7CB97A]',\n cardClass: 'bg-[#182f25]',\n idClass: 'text-[#9ACB98]',\n },\n closed: {\n label: 'Closed',\n labelClass: 'text-[#D4A574]',\n dotClass: 'bg-[#D4A574]',\n cardClass: 'bg-[#332716]',\n idClass: 'text-[#DAB891]',\n },\n reopened: {\n label: 'Reopened',\n labelClass: 'text-[#5B95E8]',\n dotClass: 'bg-[#5B95E8]',\n cardClass: 'bg-[#1b2b43]',\n idClass: 'text-[#8DB4EF]',\n },\n status_changed: {\n label: 'Status changed',\n labelClass: 'text-[#D4A574]',\n dotClass: 'bg-[#D4A574]',\n cardClass: 'bg-[#2f2518]',\n idClass: 'text-[#DAB891]',\n },\n priority_changed: {\n label: 'Priority changed',\n labelClass: 'text-[#D4A574]',\n dotClass: 'bg-[#D4A574]',\n cardClass: 'bg-[#2f2518]',\n idClass: 'text-[#DAB891]',\n },\n assignee_changed: {\n label: 'Assigned',\n labelClass: 'text-[#D4A574]',\n dotClass: 'bg-[#D4A574]',\n cardClass: 'bg-[#2f2518]',\n idClass: 'text-[#DAB891]',\n },\n dependency_added: {\n label: 'Dependency added',\n labelClass: 'text-[#D4A574]',\n dotClass: 'bg-[#D4A574]',\n cardClass: 'bg-[#2f2518]',\n idClass: 'text-[#DAB891]',\n },\n dependency_removed: {\n label: 'Dependency removed',\n labelClass: 'text-[#C97A7A]',\n dotClass: 'bg-[#C97A7A]',\n cardClass: 'bg-[#321b21]',\n idClass: 'text-[#D9A9A9]',\n },\n heartbeat: {\n label: 'Heartbeat',\n labelClass: 'text-[#5BA8A0]',\n dotClass: 'bg-[#5BA8A0]',\n cardClass: 'bg-[#173034]',\n idClass: 'text-[#8BC9C1]',\n },\n commented: {\n label: 'Commented',\n labelClass: 'text-[#5BA8A0]',\n dotClass: 'bg-[#5BA8A0]',\n cardClass: 'bg-[#173034]',\n idClass: 'text-[#8BC9C1]',\n },\n comment_added: {\n label: 'Commented',\n labelClass: 'text-[#5BA8A0]',\n dotClass: 'bg-[#5BA8A0]',\n cardClass: 'bg-[#173034]',\n idClass: 'text-[#8BC9C1]',\n },\n };\n\n return (\n byKind[normalized] || {\n label: normalized.replace(/_/g, ' '),\n labelClass: 'text-[#5BA8A0]',\n dotClass: 'bg-[#5BA8A0]',\n cardClass: 'bg-[#173034]',\n idClass: 'text-[#8BC9C1]',\n }\n );\n}\n\nfunction getInitials(name: string): string {\n return name.split(/[-_\\s]/).map(p => p[0]).join('').toUpperCase().slice(0, 2);\n}\n\nexport function ActivityPanel({ issues, collapsed = false }: ActivityPanelProps) {\n const [activities, setActivities] = useState<ActivityEvent[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n \n const agentRoster = useMemo(() => buildAgentRoster(issues), [issues]);\n \n // Fetch activity history\n useEffect(() => {\n async function fetchActivity() {\n try {\n const response = await fetch('/api/activity');\n if (response.ok) {\n const data = await response.json();\n setActivities(data.slice(0, 50)); // Limit to 50 events\n }\n } catch (error) {\n console.error('[ActivityPanel] Failed to fetch activity:', error);\n } finally {\n setIsLoading(false);\n }\n }\n \n fetchActivity();\n }, []);\n \n // Subscribe to real-time activity\n useEffect(() => {\n const source = new EventSource('/api/events');\n \n const onActivity = (event: MessageEvent) => {\n try {\n const data = JSON.parse(event.data);\n if (data?.event) {\n setActivities(prev => [data.event, ...prev].slice(0, 50));\n }\n } catch (e) {\n // Ignore parse errors\n }\n };\n \n source.addEventListener('activity', onActivity as EventListener);\n \n return () => {\n source.removeEventListener('activity', onActivity as EventListener);\n source.close();\n };\n }, []);\n\n const activeAgents = agentRoster.filter(a => a.status === 'active').length;\n if (collapsed) {\n return (\n <div className=\"flex flex-col items-center gap-6 py-6 h-full bg-[linear-gradient(180deg,rgba(0,0,0,0.2),rgba(0,0,0,0.36))] shadow-[inset_10px_0_22px_-20px_rgba(0,0,0,0.9)]\">\n {/* Collapsed Agent Icons with ZFC Rings */}\n <div className=\"flex flex-col gap-4\">\n {agentRoster.slice(0, 6).map(agent => (\n <div key={agent.beadId} className=\"relative group cursor-help\" title={`${agent.name} (${agent.status})`}>\n <div className={cn(\n \"absolute -inset-1 rounded-full blur-[2px] transition-opacity duration-500\",\n agent.status === 'active' ? 'bg-[#7CB97A]/20 opacity-100 animate-pulse' :\n agent.status === 'stale' ? 'bg-[#D4A574]/14 opacity-80' :\n agent.status === 'stuck' ? 'bg-[#C97A7A]/20 opacity-100' : 'bg-[#A78A94]/18 opacity-90'\n )} />\n <Avatar className={cn(\n \"h-9 w-9 ring-2 transition-all duration-300 relative z-10\",\n agent.status === 'active' ? 'ring-[#7CB97A]/45' :\n agent.status === 'stale' ? 'ring-[#D4A574]/45' :\n agent.status === 'stuck' ? 'ring-[#C97A7A]/45' : 'ring-[#A78A94]/40'\n )}>\n <AvatarFallback className=\"text-[10px] font-bold bg-[#1a1a1a] text-text-muted\">\n {getInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n </div>\n ))}\n </div>\n \n <div className=\"w-6 h-[1px] bg-white/20 mx-auto\" />\n \n {/* Activity Pulses */}\n <div className=\"flex flex-col gap-2 opacity-40\">\n {activities.slice(0, 8).map((act) => (\n <div key={act.id} className={cn(\n \"w-1 h-1 rounded-full\",\n getEventTone(act.kind).dotClass\n )} />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full bg-[#070f19] backdrop-blur-xl\">\n {/* AGENT ROSTER SECTION */}\n <div className=\"flex-shrink-0 p-4 bg-[#0b1625] shadow-[0_16px_24px_-24px_rgba(0,0,0,0.9)]\">\n <div className=\"flex items-center justify-between mb-4\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse shadow-[0_0_8px_#10b981]\" />\n <h3 className=\"text-xs font-bold uppercase tracking-[0.2em] text-text-muted\">Live Agents</h3>\n </div>\n <div className=\"text-[10px] font-mono text-[#7CB97A]/80 bg-[#7CB97A]/15 px-2 py-0.5 rounded shadow-[0_10px_16px_-12px_rgba(0,0,0,0.8)]\">\n {activeAgents} ONLINE\n </div>\n </div>\n \n {agentRoster.length === 0 ? (\n <p className=\"text-xs text-text-muted/40 italic text-center py-4\">No agents broadcasting</p>\n ) : (\n <div className=\"grid grid-cols-1 gap-2\">\n {agentRoster.map(agent => (\n <div key={agent.beadId} className={cn(\n 'group flex items-center gap-3 p-2 rounded-xl transition-all duration-300 shadow-[0_14px_24px_-14px_rgba(0,0,0,0.92)]',\n getAgentTone(agent.status).cardClass,\n )}>\n <div className=\"relative\">\n <div className={cn(\n \"absolute -inset-0.5 rounded-full blur-[1px] opacity-0 group-hover:opacity-100 transition-opacity\",\n getAgentTone(agent.status).glowClass\n )} />\n <Avatar className={cn(\"h-8 w-8 relative z-10 ring-1\", getAgentTone(agent.status).ringClass)}>\n <AvatarFallback className=\"text-[10px] font-bold bg-[#252525]\">\n {getInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n </div>\n <div className=\"flex flex-col flex-1 min-w-0\">\n <span className=\"text-xs font-semibold text-text-primary group-hover:text-white transition-colors\">{agent.name}</span>\n <div className=\"flex items-center gap-1.5\">\n <span className={cn(\n \"text-[9px] uppercase tracking-wider font-bold\",\n getAgentTone(agent.status).labelClass\n )}>\n {agent.status}\n </span>\n <span className=\"text-[9px] text-text-muted/40 font-mono\">\n {agent.lastSeen ? formatRelativeTime(agent.lastSeen) : 'N/A'}\n </span>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n \n {/* ACTIVITY FEED SECTION */}\n <div className=\"flex-1 min-h-0 flex flex-col\">\n <div className=\"p-4 flex items-center gap-2 shadow-[0_14px_24px_-24px_rgba(0,0,0,0.9)]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"text-text-muted/60\"><path d=\"M22 12h-4l-3 9L9 3l-3 9H2\"></path></svg>\n <h3 className=\"text-xs font-bold uppercase tracking-[0.2em] text-text-muted\">Telemetry Stream</h3>\n </div>\n \n <ScrollArea className=\"flex-1\">\n {isLoading ? (\n <div className=\"p-10 flex flex-col items-center gap-3\">\n <div className=\"w-4 h-4 border-2 border-teal-500 border-t-transparent rounded-full animate-spin\" />\n <span className=\"text-[10px] font-mono text-text-muted\">SYNCING...</span>\n </div>\n ) : activities.length === 0 ? (\n <div className=\"p-10 text-center opacity-30\">\n <p className=\"text-[10px] font-mono\">VOID_STREAM_NULL</p>\n </div>\n ) : (\n <div className=\"p-3 space-y-3\">\n {activities.map((activity) => {\n const eventTone = getEventTone(activity.kind);\n return (\n <div key={activity.id} className=\"group relative\">\n <div className={cn(\n \"p-3 rounded-xl transition-all duration-300 shadow-[0_14px_24px_-14px_rgba(0,0,0,0.94)]\",\n eventTone.cardClass\n )}>\n <div className=\"flex items-center gap-2 mb-1.5\">\n <div className={cn(\n \"w-1.5 h-1.5 rounded-full shrink-0\",\n eventTone.dotClass\n )} />\n <span className={cn(\"text-[10px] font-bold uppercase tracking-wider\", eventTone.labelClass)}>\n {eventTone.label}\n </span>\n <span className=\"text-[9px] text-text-muted/30 font-mono ml-auto\">\n {formatRelativeTime(activity.timestamp)}\n </span>\n </div>\n \n <p className=\"text-xs font-medium text-text-secondary leading-snug line-clamp-2 mb-2 group-hover:text-text-primary transition-colors\">\n {activity.beadTitle}\n </p>\n \n <div className=\"flex items-center justify-between\">\n <span className={cn(\"text-[10px] font-mono\", eventTone.idClass)}>\n {activity.beadId}\n </span>\n {activity.actor && (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-3 h-3 rounded-full bg-white/10 shadow-[0_0_8px_rgba(0,0,0,0.45)] flex items-center justify-center text-[6px] font-bold\">\n {activity.actor[0].toUpperCase()}\n </div>\n <span className=\"text-[9px] text-text-muted/60\">{activity.actor}</span>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </ScrollArea>\n </div>\n </div>\n );\n}\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\dependency-flow-strip.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\dependency-graph-page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\graph-node-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\graph-section.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\graph-view.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\task-card-grid.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\task-details-drawer.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\graph\\workflow-tabs.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\kanban\\kanban-board.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\kanban\\kanban-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\kanban\\kanban-controls.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\kanban\\kanban-detail.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\kanban\\kanban-page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\mission\\mission-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\mission\\mission-inspector.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\mission\\swarm-graph.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\mission\\team-manager-dialog.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\agent-station-logic.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\agent-station.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\conversation-drawer.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\session-feed-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\session-task-feed.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\sessions-header-logic.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\sessions-header.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\sessions\\sessions-page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\agent-avatar.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\base-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\chip.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\epic-chip-strip.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\left-panel.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\mobile-nav.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\module-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\project-scope-controls.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\right-panel.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\stat-pill.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\status-badge.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\status-utils.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\thread-drawer.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\thread-view.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\top-bar.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\unified-shell.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\workflow-graph.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\shared\\workspace-hero.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\social\\social-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\social\\social-detail.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\social\\social-page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\archetype-inspector.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\convoy-stepper.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\launch-dialog.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\specialized-agent-dag.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\swarm-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\swarm-control-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\swarm-detail.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'SwarmCardData' is defined but never used.","line":4,"column":15,"nodeType":"Identifier","messageId":"unusedVar","endLine":4,"endColumn":28,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"SwarmCardData"},"fix":{"range":[74,88],"text":""},"desc":"Remove unused variable \"SwarmCardData\"."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'cn' is defined but never used.","line":6,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":6,"endColumn":12,"suggestions":[{"messageId":"removeUnusedImportDeclaration","data":{"varName":"cn"},"fix":{"range":[192,230],"text":""},"desc":"Remove unused import declaration."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'e' is defined but never used.","line":53,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":53,"endColumn":17}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { SwarmCardData, SwarmStatusFromApi } from '../../lib/swarm-api';\nimport { Badge } from '../../../components/ui/badge';\nimport { cn } from '../../lib/utils';\nimport { CheckCircle2, PlayCircle, Clock, AlertCircle, Loader2 } from 'lucide-react';\n\ninterface SwarmDetailProps {\n swarmId: string;\n projectRoot: string;\n}\n\nfunction ProgressBar({ progress }: { progress: number }) {\n const filled = Math.round(progress / 10);\n const empty = 10 - filled;\n\n return (\n <div className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"text-slate-400\">Progress</span>\n <span className=\"font-mono text-slate-300\">{progress}%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex-1 font-mono text-xs text-slate-300\">\n {'█'.repeat(filled)}\n {'░'.repeat(empty)}\n </div>\n </div>\n </div>\n );\n}\n\nexport function SwarmDetail({ swarmId, projectRoot }: SwarmDetailProps) {\n const [status, setStatus] = useState<SwarmStatusFromApi | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n async function fetchStatus() {\n setIsLoading(true);\n setError(null);\n try {\n const response = await fetch(\n `/api/swarm/status?projectRoot=${encodeURIComponent(projectRoot)}&epic=${encodeURIComponent(swarmId)}`\n );\n const payload = await response.json();\n if (payload.ok && payload.data) {\n setStatus(payload.data);\n } else {\n setError(payload.error?.message || 'Failed to load swarm status');\n }\n } catch (e) {\n setError('Failed to fetch swarm status');\n } finally {\n setIsLoading(false);\n }\n }\n fetchStatus();\n }, [swarmId, projectRoot]);\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center py-12 text-slate-400\">\n <Loader2 className=\"h-5 w-5 animate-spin mr-2\" />\n Loading swarm...\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"py-8 text-center text-rose-400\">\n {error}\n </div>\n );\n }\n\n if (!status) {\n return (\n <div className=\"py-8 text-center text-slate-400\">\n No swarm data found\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 p-4\">\n {/* Header */}\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-mono text-sm font-semibold text-slate-200\">\n {swarmId}\n </span>\n <Badge variant=\"outline\" className=\"text-[10px] px-1.5 py-0 text-emerald-400 border-emerald-400/30\">\n swarm\n </Badge>\n </div>\n <h3 className=\"text-sm font-medium text-slate-200 line-clamp-2\">\n {status.epic_title}\n </h3>\n </div>\n\n {/* Progress */}\n <ProgressBar progress={status.progress_percent} />\n\n {/* Stats Grid */}\n <div className=\"grid grid-cols-4 gap-2 text-xs\">\n <div className=\"flex items-center gap-1 text-emerald-400\">\n <CheckCircle2 className=\"h-3 w-3\" />\n <span>{status.completed.length} done</span>\n </div>\n <div className=\"flex items-center gap-1 text-amber-400\">\n <PlayCircle className=\"h-3 w-3\" />\n <span>{status.active_count} active</span>\n </div>\n <div className=\"flex items-center gap-1 text-blue-400\">\n <Clock className=\"h-3 w-3\" />\n <span>{status.ready_count} ready</span>\n </div>\n <div className=\"flex items-center gap-1 text-rose-400\">\n <AlertCircle className=\"h-3 w-3\" />\n <span>{status.blocked_count} blocked</span>\n </div>\n </div>\n\n {/* Active Tasks */}\n {status.active.length > 0 && (\n <div className=\"space-y-2\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wider text-slate-400\">\n Active ({status.active.length})\n </h4>\n <div className=\"space-y-1\">\n {status.active.map((task) => (\n <div key={task.id} className=\"p-2 rounded-md bg-amber-500/10 border border-amber-500/20\">\n <span className=\"font-mono text-[10px] text-amber-300\">{task.id}</span>\n <p className=\"text-xs text-slate-300 line-clamp-1\">{task.title}</p>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Ready Tasks */}\n {status.ready.length > 0 && (\n <div className=\"space-y-2\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wider text-slate-400\">\n Ready to Pick Up ({status.ready.length})\n </h4>\n <div className=\"space-y-1\">\n {status.ready.map((task) => (\n <div key={task.id} className=\"p-2 rounded-md bg-blue-500/10 border border-blue-500/20\">\n <span className=\"font-mono text-[10px] text-blue-300\">{task.id}</span>\n <p className=\"text-xs text-slate-300 line-clamp-1\">{task.title}</p>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Blocked Tasks */}\n {status.blocked.length > 0 && (\n <div className=\"space-y-2\">\n <h4 className=\"text-xs font-semibold uppercase tracking-wider text-slate-400\">\n Blocked ({status.blocked.length})\n </h4>\n <div className=\"space-y-1\">\n {status.blocked.map((task) => (\n <div key={task.id} className=\"p-2 rounded-md bg-rose-500/10 border border-rose-500/20\">\n <span className=\"font-mono text-[10px] text-rose-300\">{task.id}</span>\n <p className=\"text-xs text-slate-300 line-clamp-1\">{task.title}</p>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\swarm-inspector.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'SwarmCardData' is defined but never used.","line":4,"column":15,"nodeType":"Identifier","messageId":"unusedVar","endLine":4,"endColumn":28,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"SwarmCardData"},"fix":{"range":[74,88],"text":""},"desc":"Remove unused variable \"SwarmCardData\"."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'Button' is defined but never used.","line":6,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":6,"endColumn":16,"suggestions":[{"messageId":"removeUnusedImportDeclaration","data":{"varName":"Button"},"fix":{"range":[185,234],"text":""},"desc":"Remove unused import declaration."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'agents' is assigned a value but never used.","line":39,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":39,"endColumn":17},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'e' is defined but never used.","line":55,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":55,"endColumn":17},{"ruleId":"react/no-unescaped-entities","severity":2,"message":"`\"` can be escaped with `"`, `“`, `"`, `”`.","line":116,"column":50,"nodeType":"JSXText","messageId":"unescapedEntityAlts","suggestions":[{"messageId":"replaceWithAlt","data":{"alt":"""},"fix":{"range":[4177,4205],"text":"Use "Join\" on the main card."},"desc":"Replace with `"`."},{"messageId":"replaceWithAlt","data":{"alt":"“"},"fix":{"range":[4177,4205],"text":"Use “Join\" on the main card."},"desc":"Replace with `“`."},{"messageId":"replaceWithAlt","data":{"alt":"""},"fix":{"range":[4177,4205],"text":"Use "Join\" on the main card."},"desc":"Replace with `"`."},{"messageId":"replaceWithAlt","data":{"alt":"”"},"fix":{"range":[4177,4205],"text":"Use ”Join\" on the main card."},"desc":"Replace with `”`."}]},{"ruleId":"react/no-unescaped-entities","severity":2,"message":"`\"` can be escaped with `"`, `“`, `"`, `”`.","line":116,"column":55,"nodeType":"JSXText","messageId":"unescapedEntityAlts","suggestions":[{"messageId":"replaceWithAlt","data":{"alt":"""},"fix":{"range":[4177,4205],"text":"Use \"Join" on the main card."},"desc":"Replace with `"`."},{"messageId":"replaceWithAlt","data":{"alt":"“"},"fix":{"range":[4177,4205],"text":"Use \"Join“ on the main card."},"desc":"Replace with `“`."},{"messageId":"replaceWithAlt","data":{"alt":"""},"fix":{"range":[4177,4205],"text":"Use \"Join" on the main card."},"desc":"Replace with `"`."},{"messageId":"replaceWithAlt","data":{"alt":"”"},"fix":{"range":[4177,4205],"text":"Use \"Join” on the main card."},"desc":"Replace with `”`."}]}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { SwarmCardData, SwarmStatusFromApi } from '../../lib/swarm-api';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { CheckCircle2, PlayCircle, Clock, AlertCircle, Loader2, Users } from 'lucide-react';\nimport { AgentAvatar } from '../shared/agent-avatar';\nimport { useAgentPool } from '../../hooks/use-agent-pool';\n\ninterface SwarmInspectorProps {\n swarmId: string;\n projectRoot: string;\n onClose?: () => void;\n}\n\nfunction ProgressBar({ progress }: { progress: number }) {\n const filled = Math.round(progress / 10);\n const empty = 10 - filled;\n\n return (\n <div className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"text-slate-400\">Progress</span>\n <span className=\"font-mono text-slate-300\">{progress}%</span>\n </div>\n <div className=\"flex items-center gap-1 font-mono text-xs text-slate-300 tracking-widest\">\n <span className=\"text-emerald-400\">{'█'.repeat(filled)}</span>\n <span className=\"text-slate-700\">{'░'.repeat(empty)}</span>\n </div>\n </div>\n );\n}\n\nexport function SwarmInspector({ swarmId, projectRoot }: SwarmInspectorProps) {\n const [status, setStatus] = useState<SwarmStatusFromApi | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const { agents, getAgentsBySwarm } = useAgentPool(projectRoot);\n\n useEffect(() => {\n async function fetchStatus() {\n setIsLoading(true);\n setError(null);\n try {\n const response = await fetch(\n `/api/swarm/status?projectRoot=${encodeURIComponent(projectRoot)}&epic=${encodeURIComponent(swarmId)}`\n );\n const payload = await response.json();\n if (payload.ok && payload.data) {\n setStatus(payload.data);\n } else {\n setError(payload.error?.message || 'Failed to load swarm status');\n }\n } catch (e) {\n setError('Failed to fetch swarm status');\n } finally {\n setIsLoading(false);\n }\n }\n fetchStatus();\n }, [swarmId, projectRoot]);\n\n const assignedAgents = getAgentsBySwarm(swarmId);\n\n if (isLoading) {\n return (\n <div className=\"flex h-full items-center justify-center text-slate-400\">\n <Loader2 className=\"h-5 w-5 animate-spin mr-2\" />\n Loading...\n </div>\n );\n }\n\n if (error || !status) {\n return (\n <div className=\"p-4 text-center text-rose-400\">\n {error || 'No data found'}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full bg-[#08111d] text-slate-200\">\n {/* Header */}\n <div className=\"p-4 border-b border-[var(--ui-border-soft)] bg-[#0d1621]\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Badge variant=\"outline\" className=\"font-mono text-[10px] text-emerald-400 border-emerald-400/30 px-1.5\">\n {swarmId}\n </Badge>\n <span className=\"text-[10px] uppercase tracking-wider text-slate-500\">Active Operation</span>\n </div>\n <h3 className=\"text-sm font-semibold leading-snug line-clamp-2 mb-3\">\n {status.epic_title}\n </h3>\n <ProgressBar progress={status.progress_percent} />\n </div>\n\n <div className=\"flex-1 overflow-y-auto p-4 space-y-6\">\n {/* Agent Roster */}\n <section>\n <div className=\"flex items-center justify-between mb-3\">\n <h4 className=\"text-xs font-bold uppercase tracking-widest text-slate-500 flex items-center gap-2\">\n <Users className=\"h-3 w-3\" />\n Assigned Agents\n </h4>\n <span className=\"text-[10px] bg-slate-800 px-1.5 py-0.5 rounded text-slate-400\">\n {assignedAgents.length}\n </span>\n </div>\n \n {assignedAgents.length === 0 ? (\n <div className=\"text-xs text-slate-500 italic p-3 border border-dashed border-slate-800 rounded-lg text-center\">\n No agents currently assigned.\n <br/>\n <span className=\"text-[10px]\">Use \"Join\" on the main card.</span>\n </div>\n ) : (\n <div className=\"space-y-2\">\n {assignedAgents.map(agent => (\n <div key={agent.agent_id} className=\"flex items-center gap-3 p-2 rounded-lg bg-slate-800/50 border border-slate-800\">\n <AgentAvatar \n name={agent.display_name} \n status={agent.status as any} \n size=\"sm\" \n />\n <div>\n <p className=\"text-xs font-medium text-slate-300\">{agent.display_name}</p>\n <p className=\"text-[10px] text-slate-500 font-mono\">{agent.status}</p>\n </div>\n </div>\n ))}\n </div>\n )}\n </section>\n\n {/* Task Stats */}\n <section className=\"grid grid-cols-2 gap-2\">\n <div className=\"p-2 rounded bg-[#0f1824] border border-slate-800\">\n <div className=\"flex items-center gap-2 mb-1 text-emerald-400\">\n <CheckCircle2 className=\"h-3 w-3\" />\n <span className=\"text-[10px] font-bold uppercase\">Done</span>\n </div>\n <span className=\"text-lg font-mono\">{status.completed.length}</span>\n </div>\n <div className=\"p-2 rounded bg-[#0f1824] border border-slate-800\">\n <div className=\"flex items-center gap-2 mb-1 text-amber-400\">\n <PlayCircle className=\"h-3 w-3\" />\n <span className=\"text-[10px] font-bold uppercase\">Active</span>\n </div>\n <span className=\"text-lg font-mono\">{status.active_count}</span>\n </div>\n <div className=\"p-2 rounded bg-[#0f1824] border border-slate-800\">\n <div className=\"flex items-center gap-2 mb-1 text-blue-400\">\n <Clock className=\"h-3 w-3\" />\n <span className=\"text-[10px] font-bold uppercase\">Ready</span>\n </div>\n <span className=\"text-lg font-mono\">{status.ready_count}</span>\n </div>\n <div className=\"p-2 rounded bg-[#0f1824] border border-slate-800\">\n <div className=\"flex items-center gap-2 mb-1 text-rose-400\">\n <AlertCircle className=\"h-3 w-3\" />\n <span className=\"text-[10px] font-bold uppercase\">Blocked</span>\n </div>\n <span className=\"text-lg font-mono\">{status.blocked_count}</span>\n </div>\n </section>\n\n {/* Active Tasks List */}\n {status.active.length > 0 && (\n <section>\n <h4 className=\"text-xs font-bold uppercase tracking-widest text-slate-500 mb-3\">\n Currently Executing\n </h4>\n <div className=\"space-y-2\">\n {status.active.map((task) => (\n <div key={task.id} className=\"p-3 rounded-lg bg-amber-950/20 border border-amber-900/30\">\n <div className=\"flex items-center justify-between mb-1\">\n <span className=\"font-mono text-[10px] text-amber-500\">{task.id}</span>\n <Badge variant=\"outline\" className=\"text-[9px] h-4 border-amber-800 text-amber-500\">IN PROGRESS</Badge>\n </div>\n <p className=\"text-xs text-slate-300 line-clamp-2\">{task.title}</p>\n </div>\n ))}\n </div>\n </section>\n )}\n </div>\n </div>\n );\n}\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\swarm-mission-picker.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\swarm-page.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'LayoutGrid' is defined but never used.","line":18,"column":53,"nodeType":"Identifier","messageId":"unusedVar","endLine":18,"endColumn":63,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"LayoutGrid"},"fix":{"range":[688,700],"text":""},"desc":"Remove unused variable \"LayoutGrid\"."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client';\n\nimport { useMemo, useState, useCallback, useEffect, useRef } from 'react';\nimport { useMissionList, type MissionData } from '../../hooks/use-mission-list';\nimport { MissionCard } from '../mission/mission-card';\nimport { TeamManagerDialog } from '../mission/team-manager-dialog';\nimport { MissionInspector } from '../mission/mission-inspector';\nimport { LaunchSwarmDialog } from './launch-dialog';\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from '@/components/ui/dropdown-menu';\nimport { Button } from '@/components/ui/button';\nimport { ArrowUpDown, ChevronDown, Loader2, Rocket, LayoutGrid, Users, Shield } from 'lucide-react';\nimport { useAgentPool } from '../../hooks/use-agent-pool';\n\ntype SortOption = 'health' | 'activity' | 'progress' | 'name';\n\nconst SORT_LABELS: Record<SortOption, string> = {\n health: 'Health',\n activity: 'Activity',\n progress: 'Progress',\n name: 'Name',\n};\n\nconst INITIAL_LIMIT = 16;\n\nfunction sortMissions(missions: MissionData[], sortBy: SortOption): MissionData[] {\n const sorted = [...missions];\n switch (sortBy) {\n case 'progress':\n return sorted.sort((a, b) => (b.stats.done / (b.stats.total || 1)) - (a.stats.done / (a.stats.total || 1)));\n case 'activity':\n return sorted; // Need last_activity in API to sort real activity\n case 'health':\n return sorted.sort((a, b) => b.stats.blocked - a.stats.blocked); // Most blocked first\n case 'name':\n return sorted.sort((a, b) => a.title.localeCompare(b.title));\n default:\n return sorted;\n }\n}\n\ninterface SwarmPageProps {\n projectRoot: string;\n selectedId?: string;\n onSelect: (id: string) => void;\n setRightPanel?: (content: React.ReactNode | null) => void;\n}\n\nexport function SwarmPage({ projectRoot, selectedId, onSelect, setRightPanel }: SwarmPageProps) {\n const [sortBy, setSortBy] = useState<SortOption>('health');\n const [expanded, setExpanded] = useState(false);\n const [manageTeamId, setManageTeamId] = useState<string | null>(null);\n\n // Refs to break dependency loops\n const onSelectRef = useRef(onSelect);\n useEffect(() => { onSelectRef.current = onSelect; }, [onSelect]);\n\n const { missions, isLoading, error, refresh: refreshMissions } = useMissionList(projectRoot);\n const { agents, refresh: refreshAgents } = useAgentPool(projectRoot);\n \n const sortedMissions = useMemo(() => sortMissions(missions, sortBy), [missions, sortBy]);\n const visibleMissions = expanded ? sortedMissions : sortedMissions.slice(0, INITIAL_LIMIT);\n const hasMore = sortedMissions.length > INITIAL_LIMIT;\n\n const busyAgents = agents.filter(a => a.status === 'working').length;\n\n // Handle Team Manager Actions\n const handleAssign = useCallback(async (agentId: string, action: 'join' | 'leave') => {\n // If called from inspector, we use selectedId. If called from dialog, we use manageTeamId.\n const targetMissionId = manageTeamId || selectedId;\n if (!targetMissionId) return;\n\n const endpoint = action === 'join' ? '/api/mission/assign' : '/api/mission/assign';\n \n await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ \n projectRoot, \n missionId: targetMissionId,\n agentId,\n action\n }),\n });\n \n await Promise.all([refreshMissions(), refreshAgents()]);\n }, [manageTeamId, selectedId, projectRoot, refreshMissions, refreshAgents]);\n\n const activeMissionForInspector = missions.find(m => m.id === selectedId);\n const activeMission = missions.find(m => m.id === manageTeamId);\n\n // Sync right panel on selectedId change\n useEffect(() => {\n if (selectedId && setRightPanel && activeMissionForInspector) {\n setRightPanel(\n <MissionInspector \n missionId={selectedId} \n missionTitle={activeMissionForInspector.title}\n projectRoot={projectRoot} \n assignedAgents={activeMissionForInspector.agents}\n onClose={() => onSelectRef.current('')} \n onAssign={(agentId, action) => handleAssign(agentId, action)}\n />\n );\n } else if (!selectedId && setRightPanel) {\n setRightPanel(null);\n }\n }, [selectedId, projectRoot, setRightPanel, activeMissionForInspector, handleAssign]); // Removed onSelect from deps\n\n return (\n <div className=\"h-full overflow-y-auto bg-[var(--ui-bg-app)] px-4 py-4 md:px-6 custom-scrollbar\">\n {/* Dashboard Stats */}\n <div className=\"mx-auto mb-6 grid w-full max-w-[1200px] grid-cols-1 gap-4 sm:grid-cols-3\">\n <div className=\"flex items-center gap-4 rounded-xl border border-[var(--ui-border-soft)] bg-[var(--ui-bg-shell)] p-4 shadow-sm\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-500/10 text-indigo-500\">\n <Shield className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-[10px] font-bold uppercase tracking-widest text-slate-500\">Active Missions</p>\n <p className=\"text-xl font-mono text-slate-200\">{missions.length}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-4 rounded-xl border border-[var(--ui-border-soft)] bg-[var(--ui-bg-shell)] p-4 shadow-sm\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-emerald-500/10 text-emerald-500\">\n <Users className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-[10px] font-bold uppercase tracking-widest text-slate-500\">Agent Fleet</p>\n <p className=\"text-xl font-mono text-slate-200\">{agents.length}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-4 rounded-xl border border-[var(--ui-border-soft)] bg-[var(--ui-bg-shell)] p-4 shadow-sm border-l-4 border-l-emerald-500\">\n <div>\n <p className=\"text-[10px] font-bold uppercase tracking-widest text-slate-500\">Operational Load</p>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xl font-mono text-slate-200\">{busyAgents}/{agents.length}</span>\n <span className=\"text-[10px] text-slate-500\">engaged</span>\n </div>\n </div>\n </div>\n </div>\n\n {/* Toolbar */}\n <div className=\"mx-auto mb-4 flex w-full max-w-[1200px] items-center justify-between gap-3 rounded-xl border border-[var(--ui-border-soft)] bg-[var(--ui-bg-shell)] px-3 py-2 shadow-sm\">\n <div className=\"flex items-center gap-3\">\n <div className=\"min-w-0\">\n <p className=\"font-mono text-[10px] uppercase tracking-[0.14em] text-[var(--ui-text-muted)]\">Command</p>\n <h2 className=\"text-base font-semibold text-[var(--ui-text-primary)]\">\n Mission Control\n </h2>\n </div>\n <div className=\"h-8 w-px bg-white/5 mx-2\" />\n <LaunchSwarmDialog projectRoot={projectRoot} onSuccess={refreshMissions} />\n </div>\n\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-2 border-white/10 bg-white/5 text-[var(--ui-text-primary)] hover:bg-white/10\"\n >\n <ArrowUpDown className=\"h-4 w-4 text-slate-500\" aria-hidden=\"true\" />\n <span className=\"text-xs uppercase tracking-wider font-bold\">{SORT_LABELS[sortBy]}</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-40 bg-[#0d1621] border-slate-800 text-slate-300\">\n <DropdownMenuLabel className=\"text-[10px] uppercase tracking-widest text-slate-500\">Sort Missions</DropdownMenuLabel>\n <DropdownMenuSeparator className=\"bg-white/5\" />\n {(Object.keys(SORT_LABELS) as SortOption[]).map((option) => (\n <DropdownMenuItem\n key={option}\n onClick={() => setSortBy(option)}\n className={sortBy === option ? 'bg-indigo-500/10 text-indigo-400' : 'focus:bg-white/5 focus:text-white'}\n >\n {SORT_LABELS[option]}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Grid */}\n <div className=\"mx-auto grid w-full max-w-[1200px] grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4\">\n {visibleMissions.map((mission) => (\n <MissionCard\n key={mission.id}\n id={mission.id}\n projectRoot={projectRoot}\n title={mission.title}\n description={mission.description}\n status={mission.status as any}\n stats={mission.stats}\n agents={mission.agents}\n onClick={() => onSelect(mission.id)}\n onDeploy={() => setManageTeamId(mission.id)}\n />\n ))}\n </div>\n\n {hasMore && (\n <div className=\"mt-8 flex justify-center pb-12\">\n <Button\n variant=\"outline\"\n onClick={() => setExpanded(true)}\n className=\"gap-2 border-white/10 bg-white/5 text-[var(--ui-text-primary)] hover:bg-white/10\"\n >\n Show All Missions\n <ChevronDown className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n )}\n\n {isLoading && (\n <div className=\"py-24 flex flex-col items-center justify-center text-[var(--color-text-muted)]\">\n <Loader2 className=\"h-8 w-8 animate-spin mb-4 text-indigo-500\" />\n <p className=\"text-sm font-mono uppercase tracking-widest animate-pulse\">Establishing Uplink...</p>\n </div>\n )}\n\n {!isLoading && !error && missions.length === 0 && (\n <div className=\"py-24 flex flex-col items-center justify-center text-[var(--color-text-muted)]\">\n <Rocket className=\"h-12 w-12 mb-4 opacity-20\" />\n <p className=\"text-sm mb-4\">No active missions. Launch one to begin.</p>\n <LaunchSwarmDialog projectRoot={projectRoot} onSuccess={refreshMissions} />\n </div>\n )}\n\n {/* Dialogs */}\n {activeMission && (\n <TeamManagerDialog\n isOpen={!!manageTeamId}\n onClose={() => setManageTeamId(null)}\n missionId={activeMission.id}\n missionTitle={activeMission.title}\n projectRoot={projectRoot}\n assignedAgents={activeMission.agents}\n onAssign={handleAssign}\n />\n )}\n </div>\n );\n}","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\swarm-workspace.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\telemetry-grid.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\swarm\\template-inspector.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'Edit' is defined but never used.","line":2,"column":19,"nodeType":"Identifier","messageId":"unusedVar","endLine":2,"endColumn":23,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"Edit"},"fix":{"range":[44,50],"text":""},"desc":"Remove unused variable \"Edit\"."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import React from 'react';\r\nimport { X, Save, Edit, Link, Network } from 'lucide-react';\r\nimport type { SwarmTemplate, AgentArchetype } from '../../lib/types-swarm';\r\n\r\ninterface TemplateInspectorProps {\r\n template: SwarmTemplate;\r\n archetypes: AgentArchetype[];\r\n onClose: () => void;\r\n}\r\n\r\nexport function TemplateInspector({ template, archetypes, onClose }: TemplateInspectorProps) {\r\n if (!template) return null;\r\n\r\n const totalAgents = template.team.reduce((acc, curr) => acc + curr.count, 0);\r\n\r\n return (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4 animate-in fade-in duration-200\">\r\n <div className=\"flex flex-col h-[75vh] w-full max-w-2xl overflow-hidden rounded-xl border border-[var(--ui-border-soft)] bg-[#0f1824] shadow-2xl animate-in zoom-in-95 duration-200\">\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between border-b border-[var(--ui-border-soft)] px-5 py-4 bg-[#14202e]\">\r\n <div className=\"flex items-center gap-4\">\r\n <div className=\"h-10 w-10 flex-shrink-0 rounded-full bg-amber-500/10 border border-amber-500/20 flex items-center justify-center text-amber-500 font-bold text-lg\">\r\n {totalAgents}\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <h2 className=\"text-lg font-bold text-[var(--ui-text-primary)] leading-tight\">{template.name}</h2>\r\n {template.isBuiltIn && (\r\n <span className=\"px-1.5 py-0.5 rounded-full bg-white/10 text-[9px] uppercase font-bold text-[var(--ui-text-muted)] border border-white/10\">Built-in</span>\r\n )}\r\n </div>\r\n <p className=\"font-mono uppercase tracking-wider text-[10px] text-[var(--ui-text-muted)] mt-0.5\">{template.id}</p>\r\n </div>\r\n </div>\r\n <button\r\n onClick={onClose}\r\n className=\"rounded-full p-2 text-[var(--ui-text-muted)] hover:bg-white/5 hover:text-white transition-colors\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n\r\n {/* Body Content */}\r\n <div className=\"flex-1 overflow-y-auto p-5 space-y-6 custom-scrollbar\">\r\n\r\n {/* Metadata Section */}\r\n <div>\r\n <label className=\"text-xs font-semibold text-[var(--ui-text-muted)] uppercase tracking-wider mb-1.5 block\">Purpose / Description</label>\r\n <textarea\r\n defaultValue={template.description}\r\n readOnly\r\n rows={2}\r\n className=\"w-full bg-[#0a111a] border border-[var(--ui-border-soft)] rounded-md px-3 py-2 text-sm text-[var(--ui-text-primary)] focus:outline-none focus:border-[var(--ui-accent-info)] focus:ring-1 focus:ring-[var(--ui-accent-info)] resize-none\"\r\n />\r\n </div>\r\n\r\n {/* Team Composition Builder */}\r\n <div className=\"border-t border-[var(--ui-border-soft)] pt-5\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <label className=\"text-xs font-semibold text-[var(--ui-text-muted)] uppercase tracking-wider flex items-center gap-2\">\r\n <Network className=\"w-4 h-4 text-emerald-500\" />\r\n Roster Composition\r\n </label>\r\n <button className=\"text-[11px] font-semibold text-[var(--ui-accent-info)] hover:text-white bg-[var(--ui-accent-info)]/10 px-2 py-1 rounded transition-colors disabled:opacity-50\">\r\n + Add Member\r\n </button>\r\n </div>\r\n\r\n <div className=\"space-y-2\">\r\n {template.team.map((member, idx) => {\r\n const arch = archetypes.find(a => a.id === member.archetypeId);\r\n return (\r\n <div key={idx} className=\"flex items-center gap-3 bg-[#111f2b] border border-[var(--ui-border-soft)] p-3 rounded-lg\">\r\n <div className=\"h-8 w-8 rounded text-sm flex items-center justify-center font-bold\" style={{ backgroundColor: `${arch?.color || '#888'}20`, color: arch?.color || '#888' }}>\r\n {arch?.name.charAt(0) || '?'}\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"font-semibold text-sm text-[var(--ui-text-primary)]\">{arch?.name || member.archetypeId}</div>\r\n <div className=\"text-[11px] text-[var(--ui-text-muted)]\">{arch?.description || 'Unknown Archetype'}</div>\r\n </div>\r\n <div className=\"flex items-center gap-2 bg-[#0a111a] border border-[var(--ui-border-soft)] rounded-md p-1\">\r\n <span className=\"text-xs font-mono text-[var(--ui-text-muted)] px-2\">Count:</span>\r\n <input\r\n type=\"number\"\r\n defaultValue={member.count}\r\n readOnly\r\n className=\"w-12 bg-transparent text-sm font-bold text-center text-[var(--ui-text-primary)] focus:outline-none\"\r\n />\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Advanced: Proto-formula */}\r\n <div className=\"border-t border-[var(--ui-border-soft)] pt-5\">\r\n <label className=\"text-xs font-semibold text-[var(--ui-text-muted)] uppercase tracking-wider mb-2 flex items-center gap-2\">\r\n <Link className=\"w-4 h-4 text-amber-500\" />\r\n MOL Proto-Formula (Optional)\r\n </label>\r\n <div className=\"flex items-center gap-3\">\r\n <input\r\n type=\"text\"\r\n defaultValue={template.protoFormula || ''}\r\n placeholder=\"e.g. 'release' or 'bugfix'\"\r\n readOnly\r\n className=\"flex-1 bg-[#0a111a] border border-[var(--ui-border-soft)] rounded-md px-3 py-2 font-mono text-sm text-amber-500 focus:outline-none focus:border-amber-500/50 focus:ring-1 focus:ring-amber-500/50\"\r\n />\r\n <div className=\"text-[11px] text-[var(--ui-text-muted)] max-w-[200px] leading-tight\">\r\n Specifies a Gastown Formula to execute (`bd mol pour`) when launching this swarm.\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n {/* Footer Controls */}\r\n <div className=\"border-t border-[var(--ui-border-soft)] px-5 py-4 bg-[#14202e] flex justify-end gap-3\">\r\n <button\r\n onClick={onClose}\r\n className=\"px-4 py-2 text-sm font-semibold text-[var(--ui-text-primary)] hover:bg-white/5 rounded-md transition-colors\"\r\n >\r\n Close\r\n </button>\r\n <button\r\n disabled\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-bold bg-[var(--ui-accent-info)] hover:bg-[var(--ui-accent-info)]/90 text-white rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\r\n >\r\n <Save className=\"w-4 h-4\" />\r\n Save Template\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\timeline\\event-card.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\timeline\\timeline-feed.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\components\\timeline\\timeline-store.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-agent-pool.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-archetypes.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-beads-subscription.ts","messages":[],"suppressedMessages":[{"ruleId":"react-hooks/exhaustive-deps","severity":1,"message":"React Hook useEffect has a missing dependency: 'onUpdate'. Either include it or remove the dependency array.","line":110,"column":6,"nodeType":"ArrayExpression","endLine":110,"endColumn":28,"suggestions":[{"desc":"Update the dependencies array to be: [onUpdate, projectRoot, refresh]","fix":{"range":[3876,3898],"text":"[onUpdate, projectRoot, refresh]"}}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-mission-graph.ts","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'e' is defined but never used.","line":32,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":32,"endColumn":17}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { BeadIssue } from '../lib/types';\n\ninterface UseMissionGraphResult {\n nodes: BeadIssue[];\n isLoading: boolean;\n error: string | null;\n}\n\nexport function useMissionGraph(projectRoot: string, missionId: string): UseMissionGraphResult {\n const [nodes, setNodes] = useState<BeadIssue[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n async function fetchGraph() {\n if (!missionId) return;\n setIsLoading(true);\n setError(null);\n try {\n const response = await fetch(\n `/api/mission/graph?projectRoot=${encodeURIComponent(projectRoot)}&id=${encodeURIComponent(missionId)}`\n );\n const payload = await response.json();\n if (payload.ok && payload.data) {\n setNodes(payload.data.nodes);\n } else {\n setError(payload.error || 'Failed to load graph');\n }\n } catch (e) {\n setError('Failed to fetch mission graph');\n } finally {\n setIsLoading(false);\n }\n }\n fetchGraph();\n }, [projectRoot, missionId]);\n\n return { nodes, isLoading, error };\n}\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-mission-list.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-responsive.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-session-feed.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-swarm-list.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-swarm-topology.ts","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'err' is defined but never used.","line":35,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":35,"endColumn":19}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client';\n\nimport { useState, useEffect } from 'react';\n\nexport interface SwarmTopologyData {\n completed: { id: string; title: string; assignee?: string }[];\n active: { id: string; title: string; assignee?: string }[];\n ready: { id: string; title: string }[];\n blocked: { id: string; title: string; blocked_by: string[] }[];\n progress_percent: number;\n}\n\nexport function useSwarmTopology(projectRoot: string, swarmId: string) {\n const [topology, setTopology] = useState<SwarmTopologyData | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let mounted = true;\n\n async function fetchTopology() {\n setIsLoading(true);\n setError(null);\n try {\n const response = await fetch(`/api/mission/${swarmId}/topology?projectRoot=${encodeURIComponent(projectRoot)}`);\n const result = await response.json();\n \n if (mounted) {\n if (result.ok) {\n setTopology(result.data);\n } else {\n setError(result.error);\n }\n }\n } catch (err) {\n if (mounted) setError('Failed to load topology');\n } finally {\n if (mounted) setIsLoading(false);\n }\n }\n\n if (projectRoot && swarmId) {\n fetchTopology();\n }\n\n return () => { mounted = false; };\n }, [projectRoot, swarmId]);\n\n return { topology, isLoading, error };\n}\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-templates.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\hooks\\use-url-state.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\activity-persistence.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\activity.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\agent-mail.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\agent-protocol.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\agent-registry.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\agent-reservations.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\agent-sessions.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\aggregate-read.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\bd-path.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\bridge.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\coalescer.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\graph-view.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\graph.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\issue-editor.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\kanban.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\mutations.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\parser.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\pathing.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\project-context.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\project-scope.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\read-interactions.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\read-issues.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\read-text-retry.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\realtime.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\registry.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\scanner.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\server\\beads-fs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\snapshot-differ.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\social-cards.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\swarm-api.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\swarm-cards.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\swarm-molecules.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\thread-builder.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\types-swarm.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\utils.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\watcher.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\lib\\writeback.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\video\\Main.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\video\\Root.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\video\\components\\Background.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'durationInFrames' is assigned a value but never used.","line":13,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":13,"endColumn":27}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { interpolate, useCurrentFrame, useVideoConfig, AbsoluteFill } from 'remotion';\nimport React, { useMemo } from 'react';\n\nconst COLORS = {\n bgBase: '#2D2D2D',\n accentGreen: '#7CB97A',\n accentAmber: '#D4A574',\n accentTeal: '#5BA8A0',\n};\n\nconst AnimatedGradient: React.FC = () => {\n const frame = useCurrentFrame();\n const { durationInFrames } = useVideoConfig();\n\n // Create smooth looping motion for the blobs\n const offset1 = Math.sin(frame / 60) * 10;\n const offset2 = Math.cos(frame / 50) * 10;\n const scale1 = interpolate(Math.sin(frame / 80), [-1, 1], [0.8, 1.2]);\n const scale2 = interpolate(Math.cos(frame / 70), [-1, 1], [0.8, 1.2]);\n\n return (\n <AbsoluteFill style={{ backgroundColor: COLORS.bgBase, overflow: 'hidden' }}>\n <div\n className=\"absolute top-[-20%] left-[-10%] w-[60%] h-[60%] rounded-full opacity-20 blur-[140px]\"\n style={{\n background: COLORS.accentGreen,\n transform: `translate(${offset1}%, ${offset2}%) scale(${scale1})`,\n }}\n />\n <div\n className=\"absolute bottom-[-20%] right-[-10%] w-[60%] h-[60%] rounded-full opacity-20 blur-[140px]\"\n style={{\n background: COLORS.accentAmber,\n transform: `translate(${-offset2}%, ${-offset1}%) scale(${scale2})`,\n }}\n />\n <div\n className=\"absolute top-[30%] left-[30%] w-[40%] h-[40%] rounded-full opacity-10 blur-[120px]\"\n style={{\n background: COLORS.accentTeal,\n transform: `translate(${offset2 * 0.5}%, ${offset1 * 0.5}%) scale(${scale1})`,\n }}\n />\n </AbsoluteFill>\n );\n};\n\nconst DotGrid: React.FC = () => {\n const frame = useCurrentFrame();\n const { width, height } = useVideoConfig();\n\n // Generate a static grid of dots\n // Only calculate once\n const dots = useMemo(() => {\n const d = [];\n const spacing = 80;\n const cols = Math.ceil(width / spacing);\n const rows = Math.ceil(height / spacing);\n\n for (let i = 0; i < cols; i++) {\n for (let j = 0; j < rows; j++) {\n d.push({ x: i * spacing, y: j * spacing, delay: (i + j) * 2 });\n }\n }\n return d;\n }, [width, height]);\n\n return (\n <AbsoluteFill className=\"items-center justify-center\">\n <svg width=\"100%\" height=\"100%\">\n {dots.map((dot, i) => {\n // Subtle fade in/out ripple effect based on position\n const wave = Math.sin((frame - dot.delay) / 20);\n const opacity = interpolate(wave, [-1, 1], [0.03, 0.15]);\n const scale = interpolate(wave, [-1, 1], [0.5, 1.2]);\n \n return (\n <circle\n key={i}\n cx={dot.x + 40}\n cy={dot.y + 40}\n r={2 * scale}\n fill=\"white\"\n opacity={opacity}\n />\n );\n })}\n </svg>\n </AbsoluteFill>\n );\n};\n\nexport const Background: React.FC = () => {\n return (\n <AbsoluteFill>\n <AnimatedGradient />\n <DotGrid />\n </AbsoluteFill>\n );\n};\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\video\\components\\TerminalScene.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'spring' is defined but never used.","line":1,"column":80,"nodeType":"Identifier","messageId":"unusedVar","endLine":1,"endColumn":86,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"spring"},"fix":{"range":[77,85],"text":""},"desc":"Remove unused variable \"spring\"."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'useMemo' is defined but never used.","line":2,"column":17,"nodeType":"Identifier","messageId":"unusedVar","endLine":2,"endColumn":24,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"useMemo"},"fix":{"range":[117,130],"text":""},"desc":"Remove unused variable \"useMemo\"."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'fps' is assigned a value but never used.","line":45,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":45,"endColumn":14}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { interpolate, useCurrentFrame, useVideoConfig, AbsoluteFill, Sequence, spring } from 'remotion';\nimport React, { useMemo } from 'react';\n\nconst TerminalLine: React.FC<{ text: string; delay: number; color?: string }> = ({ text, delay, color = '#d1d5db' }) => {\n const frame = useCurrentFrame();\n const chars = text.split('');\n \n return (\n <div className=\"font-mono text-xl mb-2 flex\">\n {chars.map((char, i) => {\n const show = frame > delay + i * 1.5;\n return (\n <span key={i} style={{ opacity: show ? 1 : 0, color }}>\n {char}\n </span>\n );\n })}\n </div>\n );\n};\n\nconst JSONLine: React.FC<{ data: object; delay: number }> = ({ data, delay }) => {\n const frame = useCurrentFrame();\n const str = JSON.stringify(data, null, 2);\n const lines = str.split('\\n');\n\n const show = frame > delay;\n const opacity = interpolate(frame, [delay, delay + 10], [0, 1]);\n const y = interpolate(frame, [delay, delay + 10], [10, 0]);\n\n if (!show) return null;\n\n return (\n <div style={{ opacity, transform: `translateY(${y}px)` }} className=\"font-mono text-sm text-green-400/90 bg-black/20 p-4 rounded-md border border-green-500/20 my-2\">\n {lines.map((line, i) => (\n <div key={i}>{line}</div>\n ))}\n </div>\n );\n}\n\n\nexport const TerminalScene: React.FC = () => {\n const frame = useCurrentFrame();\n const { fps } = useVideoConfig();\n\n const opacity = interpolate(frame, [0, 15], [0, 1]);\n const scale = interpolate(frame, [0, 15], [0.95, 1]);\n \n // Header animation\n const headerY = interpolate(frame, [0, 20], [20, 0]);\n const headerOpacity = interpolate(frame, [0, 20], [0, 1]);\n\n return (\n <AbsoluteFill className=\"items-center justify-center bg-transparent p-20 z-10\">\n \n {/* Header */}\n <div style={{ transform: `translateY(${headerY}px)`, opacity: headerOpacity }} className=\"absolute top-20 text-center w-full\">\n <h2 className=\"text-6xl font-bold text-white mb-2 font-['Inter'] drop-shadow-lg\">Protocol v1</h2>\n <p className=\"text-xl text-teal-400 font-mono tracking-widest uppercase\">Safe Coordination Contract</p>\n </div>\n\n <div \n className=\"w-full max-w-5xl bg-[#1e1e1e] rounded-xl overflow-hidden shadow-2xl border border-gray-700/50\"\n style={{ opacity, transform: `scale(${scale})` }}\n >\n {/* Terminal Header */}\n <div className=\"bg-[#2d2d2d] px-4 py-3 flex items-center gap-2 border-b border-gray-700\">\n <div className=\"w-3 h-3 rounded-full bg-red-500\" />\n <div className=\"w-3 h-3 rounded-full bg-yellow-500\" />\n <div className=\"w-3 h-3 rounded-full bg-green-500\" />\n <div className=\"ml-4 text-xs text-gray-400 font-mono\">beadboard-agent — -zsh — 80x24</div>\n </div>\n\n {/* Terminal Body */}\n <div className=\"p-6 h-[600px] font-mono text-gray-300 overflow-hidden relative\">\n <Sequence from={20}>\n <TerminalLine text=\"> bb agent heartbeat --agent amber-otter --json\" delay={0} color=\"#a5f3fc\" />\n </Sequence>\n \n <Sequence from={60}>\n <JSONLine \n delay={0} \n data={{\n status: \"ok\",\n agent_id: \"amber-otter\",\n last_seen: \"2026-02-16T10:42:15Z\",\n liveness: \"active\"\n }}\n />\n </Sequence>\n\n <Sequence from={110}>\n <TerminalLine text=\"> bb protocol emit HANDOFF --to cobalt-harbor\" delay={0} color=\"#a5f3fc\" />\n </Sequence>\n\n <Sequence from={150}>\n <div className=\"mt-4 p-4 border-l-4 border-blue-500 bg-blue-500/10\">\n <TerminalLine text=\"[EVENT] HANDOFF DETECTED\" delay={0} color=\"#60a5fa\" />\n <TerminalLine text=\"Scope: src/components/sessions/*\" delay={10} />\n <TerminalLine text=\"From: amber-otter -> To: cobalt-harbor\" delay={20} />\n <TerminalLine text=\"Reason: Implementation complete, ready for review.\" delay={30} />\n </div>\n </Sequence>\n\n <Sequence from={250}>\n <div className=\"mt-4 p-4 border-l-4 border-yellow-500 bg-yellow-500/10\">\n <TerminalLine text=\"[WARN] INCURSION PREVENTED\" delay={0} color=\"#fbbf24\" />\n <TerminalLine text=\"Target: src/lib/parser.ts (Locked by: obsidian-fox)\" delay={10} />\n <TerminalLine text=\"Action: Write blocked. Queueing request.\" delay={20} />\n </div>\n </Sequence>\n\n {/* Scanlines / CRT Effect Overlay */}\n <div className=\"absolute inset-0 pointer-events-none opacity-5 bg-[linear-gradient(rgba(18,16,16,0)_50%,rgba(0,0,0,0.25)_50%),linear-gradient(90deg,rgba(255,0,0,0.06),rgba(0,255,0,0.02),rgba(0,0,255,0.06))]\" style={{ backgroundSize: \"100% 2px, 3px 100%\" }} />\n </div>\n </div>\n </AbsoluteFill>\n );\n};\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\video\\components\\TimelineScene.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'fps' is assigned a value but never used.","line":60,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":60,"endColumn":16}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { interpolate, useCurrentFrame, useVideoConfig, AbsoluteFill, Sequence, spring } from 'remotion';\nimport React from 'react';\n\nconst COLORS = {\n bgBase: '#2D2D2D',\n cardBg: '#363636',\n accentGreen: '#7CB97A',\n accentAmber: '#D4A574',\n accentTeal: '#5BA8A0',\n textPrimary: '#FFFFFF',\n textSecondary: '#B8B8B8',\n border: 'rgba(255, 255, 255, 0.08)',\n};\n\nconst TimelineCard: React.FC<{ \n title: string; \n subtitle: string; \n time: string; \n type: 'commit' | 'issue' | 'alert'; \n index: number; \n}> = ({ title, subtitle, time, type, index }) => {\n const frame = useCurrentFrame();\n const { fps } = useVideoConfig();\n\n const delay = index * 5;\n const spr = spring({\n frame: frame - delay,\n fps,\n config: { damping: 14, mass: 0.8 },\n });\n\n const y = interpolate(spr, [0, 1], [50, 0]);\n const opacity = interpolate(spr, [0, 1], [0, 1]);\n\n let iconColor = COLORS.textSecondary;\n if (type === 'commit') iconColor = COLORS.accentTeal;\n if (type === 'issue') iconColor = COLORS.accentGreen;\n if (type === 'alert') iconColor = COLORS.accentAmber;\n\n return (\n <div \n style={{ opacity, transform: `translateY(${y}px)` }} \n className=\"flex items-start gap-4 p-4 rounded-lg border bg-[#363636] shadow-lg mb-4 w-full max-w-2xl\"\n // className=\"flex items-start gap-4 p-4 rounded-lg border border-[rgba(255,255,255,0.08)] bg-[#363636] shadow-lg mb-4 w-full max-w-2xl\"\n >\n <div className=\"mt-1 w-3 h-3 rounded-full\" style={{ backgroundColor: iconColor }} />\n <div className=\"flex-1\">\n <div className=\"flex justify-between items-baseline\">\n <h3 className=\"text-lg font-semibold text-white\">{title}</h3>\n <span className=\"text-xs text-gray-500 font-mono\">{time}</span>\n </div>\n <p className=\"text-sm text-gray-400 mt-1\">{subtitle}</p>\n </div>\n </div>\n );\n};\n\nexport const TimelineScene: React.FC = () => {\n const frame = useCurrentFrame();\n const { fps } = useVideoConfig();\n\n const titleOpacity = interpolate(frame, [0, 20], [0, 1]);\n const titleY = interpolate(frame, [0, 20], [20, 0]);\n\n return (\n <AbsoluteFill className=\"items-center justify-center p-10 z-10 flex-col\">\n <div style={{ opacity: titleOpacity, transform: `translateY(${titleY}px)` }} className=\"mb-12 text-center\">\n <h2 className=\"text-6xl font-bold text-white mb-2 font-['Inter'] drop-shadow-lg\">Live Activity Feed</h2>\n <p className=\"text-xl text-teal-400 font-mono tracking-widest uppercase\">Real-time Project Pulse</p>\n </div>\n\n <div className=\"flex flex-col w-full max-w-2xl\">\n <div className=\"text-xs font-mono text-gray-500 mb-4 uppercase tracking-wider ml-2\">Today</div>\n <Sequence from={10}>\n <TimelineCard \n index={0} type=\"commit\" title=\"feat: Implement Session Protocol v1\" \n subtitle=\"amber-otter pushed to main\" time=\"10:42 AM\" \n />\n </Sequence>\n <Sequence from={25}>\n <TimelineCard \n index={1} type=\"issue\" title=\"Docs: Update RFC-001\" \n subtitle=\"cobalt-harbor commented on #23\" time=\"10:45 AM\" \n />\n </Sequence>\n <Sequence from={40}>\n <TimelineCard \n index={2} type=\"alert\" title=\"Incursion Alert\" \n subtitle=\"obsidian-fox attempted write to locked scope\" time=\"11:02 AM\" \n />\n </Sequence>\n \n <Sequence from={60}>\n <div className=\"text-xs font-mono text-gray-500 mt-6 mb-4 uppercase tracking-wider ml-2\">Yesterday</div>\n </Sequence>\n\n <Sequence from={70}>\n <TimelineCard \n index={3} type=\"issue\" title=\"Refactor: Agent Registry\" \n subtitle=\"emerald-wolf closed issue #19\" time=\"4:20 PM\" \n />\n </Sequence>\n <Sequence from={85}>\n <TimelineCard \n index={4} type=\"commit\" title=\"fix: Graph layout rendering\" \n subtitle=\"amber-otter pushed to feature/graph-v2\" time=\"3:15 PM\" \n />\n </Sequence>\n </div>\n </AbsoluteFill>\n );\n};\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\src\\video\\index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tailwind.config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\api\\events-route.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\api\\mutations-routes.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\api\\projects-route.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\api\\sessions-route.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\api\\swarm\\archetypes.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\bootstrap.test.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\sessions\\agent-station-logic.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\sessions\\session-feed-card-state.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\sessions\\sessions-header-logic.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\sessions\\sessions-header.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\sessions\\sessions-store.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\shared\\agent-avatar.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\shared\\base-card.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\shared\\left-panel.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\shared\\mobile-nav.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\shared\\right-panel.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\shared\\status-utils-visual.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\shared\\top-bar.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\social\\social-card.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\swarm\\swarm-card.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\swarm\\swarm-mission-picker.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\swarm\\swarm-workspace.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\unified-shell.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\guards\\graph-responsive-contract.test.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\guards\\kanban-responsive-contract.test.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\guards\\no-direct-jsonl-write.test.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\guards\\no-inline-style-in-kanban.test.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\guards\\ui-foundation-contract.test.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'ViewType' is defined but never used.","line":3,"column":46,"nodeType":"Identifier","messageId":"unusedVar","endLine":3,"endColumn":54,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"ViewType"},"fix":{"range":[116,131],"text":""},"desc":"Remove unused variable \"ViewType\"."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'GraphTabType' is defined but never used.","line":3,"column":61,"nodeType":"Identifier","messageId":"unusedVar","endLine":3,"endColumn":73,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"GraphTabType"},"fix":{"range":[131,150],"text":""},"desc":"Remove unused variable \"GraphTabType\"."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, it } from 'node:test';\r\nimport assert from 'node:assert';\r\nimport { parseUrlState, buildUrlParams, type ViewType, type GraphTabType } from '../../src/hooks/use-url-state';\r\n\r\n/**\r\n * URL State Integration Tests - bb-ui2.22\r\n * \r\n * These tests verify that all URL patterns correctly restore view state\r\n * and that the URL state system handles edge cases properly.\r\n */\r\n\r\nfunction createMockSearchParams(params: Record<string, string | null> = {}) {\r\n const sp = new URLSearchParams();\r\n for (const [key, value] of Object.entries(params)) {\r\n if (value !== null && value !== undefined) {\r\n sp.set(key, value);\r\n }\r\n }\r\n return sp;\r\n}\r\n\r\ndescribe('URL State Integration - bb-ui2.22', () => {\r\n describe('Valid URL Patterns - Social View', () => {\r\n it('/?view=social - defaults to social view', () => {\r\n const sp = createMockSearchParams({ view: 'social' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'social');\r\n assert.strictEqual(state.taskId, null);\r\n assert.strictEqual(state.swarmId, null);\r\n assert.strictEqual(state.panel, 'open');\r\n });\r\n\r\n it('/?view=social&task=bb-buff.1&panel=open - task selected, panel open', () => {\r\n const sp = createMockSearchParams({ view: 'social', task: 'bb-buff.1', panel: 'open' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'social');\r\n assert.strictEqual(state.taskId, 'bb-buff.1');\r\n assert.strictEqual(state.panel, 'open');\r\n });\r\n\r\n it('/?view=social&task=bb-ui2.22 - task with dots in ID', () => {\r\n const sp = createMockSearchParams({ view: 'social', task: 'bb-ui2.22' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.taskId, 'bb-ui2.22');\r\n });\r\n });\r\n\r\n describe('Valid URL Patterns - Graph View', () => {\r\n it('/?view=graph - graph view default', () => {\r\n const sp = createMockSearchParams({ view: 'graph' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'graph');\r\n assert.strictEqual(state.graphTab, 'flow');\r\n });\r\n\r\n it('/?view=graph&task=bb-buff.1 - graph with task selected', () => {\r\n const sp = createMockSearchParams({ view: 'graph', task: 'bb-buff.1' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'graph');\r\n assert.strictEqual(state.taskId, 'bb-buff.1');\r\n });\r\n\r\n it('/?view=graph&graphTab=flow - flow tab selected', () => {\r\n const sp = createMockSearchParams({ view: 'graph', graphTab: 'flow' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.graphTab, 'flow');\r\n });\r\n\r\n it('/?view=graph&graphTab=overview - overview tab selected', () => {\r\n const sp = createMockSearchParams({ view: 'graph', graphTab: 'overview' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.graphTab, 'overview');\r\n });\r\n\r\n it('/?view=graph&swarm=bb-buff - graph filtered by swarm', () => {\r\n const sp = createMockSearchParams({ view: 'graph', swarm: 'bb-buff' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'graph');\r\n assert.strictEqual(state.swarmId, 'bb-buff');\r\n });\r\n });\r\n\r\n describe('Valid URL Patterns - Swarm View', () => {\r\n it('/?view=swarm - swarm view default', () => {\r\n const sp = createMockSearchParams({ view: 'swarm' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'swarm');\r\n });\r\n\r\n it('/?view=swarm&swarm=bb-buff - specific swarm selected', () => {\r\n const sp = createMockSearchParams({ view: 'swarm', swarm: 'bb-buff' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'swarm');\r\n assert.strictEqual(state.swarmId, 'bb-buff');\r\n });\r\n\r\n it('/?view=swarm&swarm=bb-buff&panel=open - swarm with panel open', () => {\r\n const sp = createMockSearchParams({ view: 'swarm', swarm: 'bb-buff', panel: 'open' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.swarmId, 'bb-buff');\r\n assert.strictEqual(state.panel, 'open');\r\n });\r\n });\r\n\r\n describe('Valid URL Patterns - Activity View', () => {\r\n it('/?view=activity - activity view default', () => {\r\n const sp = createMockSearchParams({ view: 'activity' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'activity');\r\n });\r\n\r\n it('/?view=activity&agent=bb-silver-castle - filtered by agent', () => {\r\n const sp = createMockSearchParams({ view: 'activity', agent: 'bb-silver-castle' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'activity');\r\n assert.strictEqual(state.agentId, 'bb-silver-castle');\r\n });\r\n\r\n it('/?view=activity&swarm=bb-buff - filtered by swarm', () => {\r\n const sp = createMockSearchParams({ view: 'activity', swarm: 'bb-buff' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'activity');\r\n assert.strictEqual(state.swarmId, 'bb-buff');\r\n });\r\n });\r\n\r\n describe('Invalid Param Handling', () => {\r\n it('/?view=invalid - invalid view defaults to social', () => {\r\n const sp = createMockSearchParams({ view: 'invalid' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'social');\r\n });\r\n\r\n it('/?view=graph&graphTab=invalid - invalid graphTab defaults to flow', () => {\r\n const sp = createMockSearchParams({ view: 'graph', graphTab: 'invalid' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.graphTab, 'flow');\r\n });\r\n\r\n it('/?panel=invalid - invalid panel defaults to open', () => {\r\n const sp = createMockSearchParams({ panel: 'invalid' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.panel, 'open');\r\n });\r\n\r\n it('/?task=invalid-id - invalid task ID still parsed (no validation)', () => {\r\n const sp = createMockSearchParams({ task: 'invalid-id' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.taskId, 'invalid-id');\r\n });\r\n });\r\n\r\n describe('URL Building - State to URL', () => {\r\n it('builds social view URL', () => {\r\n const sp = createMockSearchParams({});\r\n const url = buildUrlParams(sp, { view: 'social' });\r\n assert.strictEqual(url, '/?view=social');\r\n });\r\n\r\n it('builds graph view with task URL', () => {\r\n const sp = createMockSearchParams({});\r\n const url = buildUrlParams(sp, { view: 'graph', task: 'bb-buff.1' });\r\n assert.strictEqual(url, '/?view=graph&task=bb-buff.1');\r\n });\r\n\r\n it('builds swarm view with swarm param', () => {\r\n const sp = createMockSearchParams({});\r\n const url = buildUrlParams(sp, { view: 'swarm', swarm: 'bb-buff' });\r\n assert.strictEqual(url, '/?view=swarm&swarm=bb-buff');\r\n });\r\n\r\n it('builds activity view with agent filter', () => {\r\n const sp = createMockSearchParams({});\r\n const url = buildUrlParams(sp, { view: 'activity', agent: 'bb-silver-castle' });\r\n assert.strictEqual(url, '/?view=activity&agent=bb-silver-castle');\r\n });\r\n\r\n it('preserves existing params when adding new ones', () => {\r\n const sp = createMockSearchParams({ view: 'social' });\r\n const url = buildUrlParams(sp, { task: 'bb-buff.1' });\r\n assert.strictEqual(url, '/?view=social&task=bb-buff.1');\r\n });\r\n\r\n it('removes params when set to null', () => {\r\n const sp = createMockSearchParams({ view: 'social', task: 'bb-buff.1', panel: 'open' });\r\n const url = buildUrlParams(sp, { task: null, panel: 'closed' });\r\n assert.strictEqual(url, '/?view=social&panel=closed');\r\n });\r\n\r\n it('returns root when all params cleared', () => {\r\n const sp = createMockSearchParams({ view: 'social' });\r\n const url = buildUrlParams(sp, { view: null });\r\n assert.strictEqual(url, '/');\r\n });\r\n });\r\n\r\n describe('Complex URL Scenarios', () => {\r\n it('handles all params together', () => {\r\n const sp = createMockSearchParams({\r\n view: 'graph',\r\n task: 'bb-ui2.22',\r\n swarm: 'bb-ui2',\r\n panel: 'open',\r\n graphTab: 'overview',\r\n agent: 'bb-silver-castle'\r\n });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.view, 'graph');\r\n assert.strictEqual(state.taskId, 'bb-ui2.22');\r\n assert.strictEqual(state.swarmId, 'bb-ui2');\r\n assert.strictEqual(state.panel, 'open');\r\n assert.strictEqual(state.graphTab, 'overview');\r\n assert.strictEqual(state.agentId, 'bb-silver-castle');\r\n });\r\n\r\n it('empty string values treated as null/empty', () => {\r\n const sp = createMockSearchParams({ task: '', swarm: '' });\r\n const state = parseUrlState(sp);\r\n assert.strictEqual(state.taskId, '');\r\n assert.strictEqual(state.swarmId, '');\r\n });\r\n });\r\n\r\n describe('Deep Link Patterns - From Card Icons', () => {\r\n it('SocialCard Graph icon: /?view=graph&task={id}', () => {\r\n const sp = createMockSearchParams({});\r\n const url = buildUrlParams(sp, { view: 'graph', task: 'bb-ui2.33' });\r\n assert.strictEqual(url, '/?view=graph&task=bb-ui2.33');\r\n \r\n const parsed = parseUrlState(createMockSearchParams({ view: 'graph', task: 'bb-ui2.33' }));\r\n assert.strictEqual(parsed.view, 'graph');\r\n assert.strictEqual(parsed.taskId, 'bb-ui2.33');\r\n });\r\n\r\n it('SwarmCard Graph icon: /?view=graph&swarm={id}', () => {\r\n const url = buildUrlParams(createMockSearchParams({}), { view: 'graph', swarm: 'bb-buff' });\r\n assert.strictEqual(url, '/?view=graph&swarm=bb-buff');\r\n });\r\n\r\n it('SwarmCard Timeline icon: /?view=activity&swarm={id}', () => {\r\n const url = buildUrlParams(createMockSearchParams({}), { view: 'activity', swarm: 'bb-buff' });\r\n assert.strictEqual(url, '/?view=activity&swarm=bb-buff');\r\n });\r\n\r\n it('Agent avatar click: /?view=activity&agent={id}', () => {\r\n const url = buildUrlParams(createMockSearchParams({}), { view: 'activity', agent: 'bb-silver-castle' });\r\n assert.strictEqual(url, '/?view=activity&agent=bb-silver-castle');\r\n });\r\n });\r\n});\r\n","usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\use-beads-subscription-shallow.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\use-beads-subscription.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\use-responsive.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\use-url-state.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\activity.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-liveness.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-mail.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-protocol.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-registry-bd.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-registry.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-reservations.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-sessions-liveness.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-sessions-state.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-sessions.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\agent-takeover.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\aggregate-read.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\bd-path.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\bridge.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\coalescer.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\graph-view.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\graph.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\identity-isolation.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\issue-editor.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\kanban.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\mission-pathing.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\mutations.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\parser.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\path-overlap.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\pathing.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\project-context.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\project-scope.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\read-issues.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\read-text-retry.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\realtime-history.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\realtime.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\registry.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\scanner.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\snapshot-differ-stress.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\snapshot-differ.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\social-cards.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\swarm-cards.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\swarm-molecules-simple.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\swarm-molecules.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\watcher.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\lib\\writeback.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\scripts\\bb-init.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\server\\beads-fs.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\skills\\beadboard-driver\\generate-agent-name.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\skills\\beadboard-driver\\readiness-report.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\skills\\beadboard-driver\\resolve-bb.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\skills\\beadboard-driver\\session-preflight.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\skills\\beadboard-driver\\skill-local-runner.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tests\\types\\beads-types-contract.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tools\\bb.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"C:\\Users\\Zenchant\\codex\\beadboard\\tools\\guardrails\\no-direct-jsonl-write.mjs","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]}]
|