feat(desktop): a File tab spans the side panel

Merged
DA
8d ago
+40-24

Part 1 of 3 of Dean's ask to polish the file viewer: "Let's first make it full width instead of constraining it." Next come a tree route (GET /api/plans/{id}/tree) and then the file tree and breadcrumbs in the File tab.

Summary

  • A File tab now spans the side panel. #2032 kept every side panel tab except the Board to a centred column, and capped the File tab's lines and heading at --code-reading-width (840px). Now a File tab's lines start at the panel's own inset like an editor's, and its heading starts at its usual inset, however wide the panel is.
  • The Code feed keeps its 840px column. Its cards are read one under another like the document, so the centred measure still helps there. The only change is in desktop.css: the three .side-panel-content .file-tab* rules are removed, and the comment above the column rules now says why a File tab is the exception.

Evidence

  • Platform-independent checks: ./scripts/check.sh exit 0 on the head commit.
  • New test in file-tab.test.ts: it loads desktop.css into jsdom, mounts a File tab inside .side-panel-content, and checks that neither its lines nor its heading pad in to the reading column. It fails on main and passes here.
  • macOS Electron verification (./scripts/verify.sh): not run. This was built in a Linux cloud VM. CI could not verify the Mac UI; any Mac break would be caught at the release rehearsal (LUKE-159 is the manual verify.sh pass).

Visual evidence

The real FileTab and the built styles.css, rendered in headless Chrome at a 1100px panel over a fake read. These are not verify.sh captures.

Before (840px column):

before

After (spans the panel):

after

Invariants

  • ./scripts/check.sh green; verify.sh not run (Linux VM, see above).
  • JSON Schema goldens unchanged.
  • Every behavior change has, in this PR, the test that fails without it; no change-detector test added.
  • Gateway envelope goldens unchanged.
  • No new as type assertion outside the allowlisted files.
  • No Effect.runPromise/runSync/runFork outside the runtime edges.
  • No new raw async primitives.
  • No discarded Effect, Stream, or Layer.
  • Test count: +1 (file-tab.test.ts).
  • No hand-rolled file replaced.
  • No CLAUDE.md/AGENTS.md sentence names the changed part.
  • PRIVACY.md unchanged.
  • No dependency changes.
  • Barrel/door rule unaffected.

Notes

  • Blockers or follow-up verification: the Mac pass (LUKE-159).

šŸ¤– Generated with Claude Code