fix(desktop): show main workspaces in the board's Needs review column

Merged
KI
2mo ago
+18-10

Fixes #7126

Problem

The Workspaces board's Needs review column never showed type: "main" workspaces. deriveBoardColumn rule 7 only routed agentStatus === "review" to the column when workspace.type === "worktree", so a finished agent on a project's main checkout fell through to Idle. The sidebar's green "Ready for review" dot, the dock badge, and the page's own "Ready for review" agent filter all treat that same workspace as review-worthy, so the board (and the list view, which groups with the same helper) disagreed with every other surface.

Fix

Narrow the gate to exclude only session workspaces instead of allowing only worktree ones:

if (workspace.agentStatus === "review" && workspace.type !== "session") {

Why main and session are different. Workspace type is a three-value union: main, worktree, session.

  • main and worktree are both project checkouts a person is driving. There is at most one main checkout per project per host, so it is bounded, and a finished agent there means the same thing it means on a worktree: go look.
  • session workspaces are automation and chat runs with no project checkout (the optional-project work from #6274). They arrive in volume, and routing them to Needs review would bury the real candidates. The original doc comment's "arrives in volume" reasoning applies to them and only them, so they stay excluded.

The doc comment on deriveBoardColumn now names exactly which kind is excluded and why.

Tests

Extended the co-located deriveBoardColumn.test.ts:

  • main + review => review
  • worktree + review => review
  • session + review => idle
  • all existing cases unchanged
bun test src/renderer/routes/_authenticated/_dashboard/v2-workspaces/utils/deriveBoardColumn
10 pass, 0 fail

bun run typecheck in apps/desktop exits 0.

Verified over CDP in the dev app

Drove this worktree's dev desktop app (renderer on its own Vite port, CDP on a dedicated port) through the real user journey: open a project's main checkout (mastra-superset), open a terminal, navigate back to the Workspaces board, then fire the agent lifecycle hooks (SessionStart, Stop) at the host-service for that terminal without reopening the pane.

Rule in deriveBoardColumn.tsBoardSidebar
main branch (type === "worktree")mastra-superset main at the top of Idle (Idle 47 / Needs review 9)green "Ready for review" dot
this PR (type !== "session")same card at the top of Needs review (Idle 46 / Needs review 10)green "Ready for review" dot

The swap was done in place by checking out the main-branch file and letting Vite hot-reload, then restoring HEAD, with the same agent binding in the host-service the whole time. Screenshots are in the session.

Two things learned along the way, in case anyone repeats this: the board's agent-status query only refetches while the window is focused, so a CDP-driven window needs Page.bringToFront plus focus emulation before it picks up new bindings; and the host-service list only includes bindings for live terminals, so a session workspace whose run has already exited can never reach review through this path in the first place. The session exclusion itself is covered by the unit test.

i18n

No user-facing strings touched. Column labels are unchanged, so no catalog updates.

https://claude.ai/code/session_01BjVLqU1kEE6SQqKSYem9ax