fix(desktop): auto-place session workspaces in the sidebar

Merged
KI
3mo ago
+60-22

Summary

  • Workspaces created for session-mode automations (and CLI project-less sessions) never showed up in the sidebar's Sessions section. The sidebar's placement reconciler now auto-places session-type workspaces the same way it places worktrees.

Why / Context

The sidebar only renders workspaces that have a renderer-local v2WorkspaceLocalState placement row. Creations that happen outside the renderer (automations dispatch workspaces.createSession on the host over the relay; the CLI goes through the host service too) can't write that row, so usePlaceLocalWorktreesInSidebar reconciles them in — but its gate (selectWorktreesToPlace) only admitted type === "worktree" with a project. A session-mode automation run produces type: "session", projectId: null, which failed both clauses: the workspace existed on the host and in the fan-out, but the Sessions section never saw it unless you navigated to the workspace directly (the workspace route places on open). Baked in since project-less sessions shipped (#6274/#6280) — surfaced once automations started running in session mode.

How It Works

  • selectWorktreesToPlace now also returns session workspaces (with projectId: null, landing them in the top-level Sessions section). Return type widens to projectId: string | null; ensureWorkspaceInSidebar already accepts null for sessions.
  • main stays excluded: the host mints one per locally-known project, so placing those would drag every known project into the sidebar. They keep surfacing via the gated isAutoIncludedLocalMainWorkspace path.
  • "Placed once, then respected" is unchanged — hidden/moved/removed rows keep their tombstone and are never re-placed.

Manual QA Checklist

Verified end-to-end over CDP against the dev desktop app (real host-service, same tRPC procedures automations hit):

  • Pre-fix baseline (control alive): workspaces.createSession + a control workspaces.create worktree issued side by side — control placed and rendered in ~7s; session never placed after 42s+ despite appearing in the renderer's host workspace.list
  • Post-fix, existing orphans: previously-created row-less sessions get placed on boot and render in the Sessions section
  • Post-fix, live journey: a new createSession while the app is running gets its v2WorkspaceLocalState row in ~195ms, projectId: null, row visible in the Sessions section with no reload
  • Worktree auto-placement unchanged (control workspace placed under its project)
  • Screenshots captured of Sessions section before (rows absent) and after (rows present)

Testing

  • bun test selectWorktreesToPlace.test.ts — 6 pass (3 new: session placed, already-placed session skipped, worktree-without-project still skipped)
  • bun run typecheck (apps/desktop)
  • bunx biome check on the touched directory

Known Limitations

  • The reconciler (pre-existing behavior) only places workspaces whose hostId matches this machine — an automation dispatched to a different host still won't auto-appear in this device's sidebar. Applies equally to worktrees; out of scope here.

Follow-ups

  • While verifying, found that useHostWorkspaces.isReady waits on every online-flagged host's workspace.list; a stale v2_hosts.is_online = true row for an unreachable relay host held it false indefinitely, which silences the reconciler for all workspace types. Worth a separate ticket.

Summary by cubic

Auto-places session workspaces in the sidebar’s Sessions section. Previously, sessions created via automations or the CLI never appeared unless opened directly; now they place automatically like worktrees.

  • Expands selectWorktreesToPlace to include session workspaces and return { id, projectId: string | null }.
  • Sessions place with projectId: null in the top-level Sessions section; main remains excluded; worktrees without a project remain skipped.
  • Placement policy unchanged: placed once and respected; previously orphaned sessions are placed on boot.
  • Adds unit tests for session placement and skip cases.
  • Annotates the flatMap callback return to unify TypeScript inference; no runtime behavior change.

Summary by CodeRabbit

  • New Features

    • Session workspaces can now appear in the sidebar alongside worktrees, including sessions without an associated project.
    • Sessions and worktrees are placed only once, while main and invalid workspaces remain excluded.
  • Tests

    • Added coverage for project-less sessions, already displayed sessions, and worktrees without projects.