feat(desktop): move the board and the code into a right side panel with tabs
What
The plan's document is now always the plan page's main content. The whiteboard and the code Luke has on screen move into a collapsible right side panel with tabs, like Cursor, Codex, and VS Code's secondary sidebar.
- Toggle: an icon button at the far right of the plan toolbar ("Show panel" / "Hide panel",
aria-expanded). Shortcut ⌥⌘B, matched on the physical key because Option turns B into∫. It only works while a plan is open in the Plans tab. - Tabs:
Board(today'sPlanBoard) andCode(today'sCodePane; renamed from "Pseudocode" at the orchestrator's request because it shows real lines from the folder). The tabs come from oneas constset (SIDE_PANEL_TAB+SIDE_PANEL_TABSinplanning/use-side-panel.ts), so the Transcript tab means one entry, one label, and onecaseinTabContent(desktop/side-panel.tsx). TypeScript's exhaustive switch makes sure thatcasegets added. - Empty Code tab: shows a quiet line instead of hiding the tab. Nothing opens the panel on its own.
- Resizable: drag the left edge between 280 and 720 px. It's a focusable
separator, and the arrow keys resize it. The document always keeps at least 360 px. - Persisted across launches: open/closed, tab, and width are saved in the renderer's
localStorageand decoded through a Schema; anything unreadable falls back to closed / Board / 400 px. Fixture runs set their own panel state and don't read or write storage. Theplanningprofile opens on Code andplanning-boardopens on Board, soevidence.shstill captures both. - Removed: the Document/Board segmented switch (
PlanViewSwitch),PLAN_VIEW, and the "each plan opens on its document" reset.CodePane's Hide/Show fold is gone along with its floating overlay, since the panel toggle now hides it. - The call/microphone bar stays under the document column.
docs/PLANNING.mdnow describes the side panel. It used to say "one visible view at a time" and described the Document | Board header switch.
Toolbar order follows the agreed layout: [title] … [Choose folder…] [Copy plan] [delete/close, which PR 3 moves into ⋯] [panel toggle].
Tests
desktop/desktop-plans.test.ts (jsdom) mounts the real useSidePanel under DesktopPlans and checks:
- first launch: the document shows alone and the toggle is the toolbar's last control
- the toggle opens the panel on Board and closes it; the document stays rendered
- the tabs switch between Board and Code; the Code tab shows its empty state when there's no code, and the code itself when there is
- the next mount opens the panel the way the last one left it; a fixture-set panel neither reads nor writes storage
- the resize edge moves from the keyboard and stops at the max width
- the chord matches on
KeyBwith Option+Command and doesn't match without Option or with Shift
./scripts/check.sh exits 0 locally.
Mac verification
CI could not verify the Mac UI, and ./scripts/verify.sh was not run: this was built on a Linux VM, and CI builds nothing for the Mac. LUKE-159 is the manual Mac pass. I rendered the real DesktopSidebar and DesktopPlans over the fixture plan in headless Chrome, using a throwaway harness that isn't committed, and checked the panel closed, on Code, and on Board (Excalidraw renders inside the panel). At the default 400 px width, Excalidraw's own toolbar is slightly wider than the panel and gets clipped on the right; widening the panel fixes it.
🤖 Generated with Claude Code