Skip to content

Comments

feat: Mission Control tab — live visualization of agent activity (Gource-inspired)#85

Open
sujayjayjay wants to merge 1 commit intomainfrom
feat/81
Open

feat: Mission Control tab — live visualization of agent activity (Gource-inspired)#85
sujayjayjay wants to merge 1 commit intomainfrom
feat/81

Conversation

@sujayjayjay
Copy link

Summary

Adds a Mission Control tab to the dashboard that makes parallel agent activity feel alive — the viral moment where someone screen-records 8 agents autonomously building a codebase in real time.

  • Agent Map (left panel): D3 force-directed visualization showing agents as orbiting nodes around a central "main" node, with files they touch as leaf nodes that pulse on modification
  • Branch Timeline (center panel): Horizontal swimlanes per agent showing commits as nodes, visual diff of how far each branch has diverged from main
  • Activity Feed (right panel): Real-time scrolling feed of agent actions via SSE (commits, file changes, PR events)

Technical implementation

  • GitActivityPoller service polls git log on each worktree every 10 seconds
  • New /api/activity SSE endpoint streams events to connected clients
  • D3-force for physics simulation, Canvas for efficient rendering
  • Event buffering to handle rapid-fire git activity

Screenshots

The Mission Control dashboard can be accessed via the "mission control" link in the main dashboard header.

Test plan

  • Navigate to dashboard and click "mission control" link
  • Verify the three-panel layout renders correctly
  • With active agents, verify:
    • Agent nodes appear and orbit the central main node
    • Commits appear as nodes on branch timeline swimlanes
    • Events appear in the activity feed as agents work
  • Verify SSE reconnection on connection drop
  • Run pnpm typecheck - passes
  • Run pnpm lint - no new errors
  • Run pnpm build - passes

Closes #81

🤖 Generated with Claude Code

Implement the Mission Control dashboard for real-time visualization of
parallel agent activity, inspired by Gource. The feature includes three panels:

1. Agent Map (left): D3 force-directed visualization showing agents as
   orbiting nodes around a central "main" node, with files they touch as
   leaf nodes that pulse on modification.

2. Branch Timeline (center): Horizontal swimlanes per agent showing commits
   as nodes, with visual indication of how far each branch has diverged
   from main.

3. Activity Feed (right): Real-time scrolling feed of agent actions via
   SSE, showing commits, file changes, and PR events as they happen.

Technical implementation:
- GitActivityPoller service polls git log on worktrees every 10 seconds
- New /api/activity SSE endpoint streams events to clients
- D3-force for physics simulation, Canvas for rendering
- Event buffering to handle rapid-fire git activity

Closes #81

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 6 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

for (const link of linksRef.current) {
const source = link.source as Node;
const target = link.target as Node;
if (!source.x || !source.y || !target.x || !target.y) continue;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Falsy coordinate check skips nodes at x=0 or y=0

High Severity

The checks !source.x || !source.y and !node.x || !node.y use falsy evaluation, which treats 0 as false. D3's phyllotaxis initialization sets the first node (the "main" node) to y = radius * sin(0) = 0, so the central main node is invisible during early simulation ticks. Any node passing through coordinate 0 during simulation will also flicker out. These checks need to test for undefined/null rather than falsiness.

Additional Locations (1)

Fix in Cursor Fix in Web

es.close();
// Reconnect after 3 seconds
setTimeout(connectToSSE, 3000);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSE reconnection timeout leaks after component unmount

Medium Severity

The setTimeout(connectToSSE, 3000) in onerror is never cancelled on unmount. If the component unmounts while a reconnect timeout is pending, it fires after cleanup runs, creating an orphaned EventSource that is never closed. That orphaned connection can error again, scheduling another timeout — creating an unbounded loop of leaked connections.

Fix in Cursor Fix in Web

Triggered by project rule: BugBot Configuration

hash = hash & hash;
}
return colors[Math.abs(hash) % colors.length];
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated getSessionColor utility across three components

Low Severity

getSessionColor is identically copy-pasted in AgentMap.tsx, ActivityFeed.tsx, and BranchTimeline.tsx. If the color palette or hash logic needs to change, all three copies must be updated in sync. This belongs in a shared utility, which the activity/index.ts barrel file could easily re-export.

Additional Locations (2)

Fix in Cursor Fix in Web

export function clearActivityCache(sessionId: string): void {
activityCache.delete(sessionId);
seenCommits.delete(sessionId);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused exported functions in git-activity.ts

Low Severity

getCachedActivity, getAllCachedActivity, and clearActivityCache are exported but never imported or called anywhere in the codebase. Since clearActivityCache is the only way to prune the module-level seenCommits and activityCache maps, these caches also grow without bound.

Fix in Cursor Fix in Web

},
]),
),
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

State update replaces sessions and gitActivity with incomplete data

High Severity

The state_update event omits branch from session objects and commits from gitActivity entries, but the client replaces sessions wholesale and shallow-merges gitActivity by key. After the first polling cycle (~10 seconds), all sessions lose their branch property and all gitActivity entries lose their commits array. This causes the BranchTimeline to show no branch names and no commit nodes, and affects AgentMap graph construction — effectively breaking the visualization shortly after load.

Additional Locations (1)

Fix in Cursor Fix in Web

No recent commits
</span>
)}
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conflicting flex and relative positioning for commit nodes

Medium Severity

Commit dots are placed inside a flex justify-between container while each item also has position: relative with a left percentage. These two positioning strategies compound: flexbox distributes items evenly, then left shifts each item further from its flex position by a percentage of the container width. For anything beyond the first commit, nodes are pushed progressively further right, with the last commit rendered at roughly double the container width (completely off-screen).

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Mission Control tab — live visualization of agent activity (Gource-inspired)

1 participant