Home

mweinbach / agent-coworker

publicmweinbach/agent-coworker
Overview Code History Branches Pull requestsIssuesInsights
main
HomeOverview Code PRsIssues

fix(desktop): restore window bounds, per-thread scroll, and settings layout

3 months ago

dcace81
Authored
mweinbach6/17/2026, 9:00:40 PM
Reopening the app never restored the last window size/position, switching
threads lost scroll position, and switching chat -> settings -> chat dropped
the sidebar + top bar entirely. selectedThreadId / view / settingsPage were
already persisted/restored via the localStorage UI cache; this fills the
three real gaps.

Window bounds (main process):
- electron/services/windowState.ts: dedicated window-state.json (kept
  separate from the IPC-backed state.json so resize/move never churn
  workspace/session state). loadMainWindowBounds clamps saved bounds to a
  visible display so a window saved on a now-disconnected monitor still
  appears on-screen. trackMainWindowBounds debounced-captures on resize/move
  and synchronous-flushes on close.
- electron/main.ts: restore bounds + isMaximized on createMainWindow,
  capture on resize/move/close.

Per-thread scroll:
- store: add scrollPositionsByThreadId (Record<threadId, number>), persisted
  in the UI cache, capped to 24 recent persisted threads.
- ChatView: capture the outgoing thread's scrollTop on switch and restore
  the incoming thread's saved offset instead of always bottom-pinning (keeps
  the original bottom-pin behavior on first mount and when no offset is
  saved, so post-mount scroll callers aren't clobbered).

Settings layout:
- PrimaryContent: route a 'settings' view through ChatShell's content slot
  so the sidebar + top bar stay mounted instead of being replaced by a bare
  settings shell. Removes the separate view==='settings' branch in App.tsx.

Tests:
- test/window-state.test.ts: clamp math, corrupt-state fallback, flush.
- test/bootstrap-cache.test.ts: scrollPositionsByThreadId round-trip.

Parent6b4f950

12 files changed
  • apps/desktop/electron/main.ts+18−3
  • apps/desktop/electron/services/windowState.ts+147−0
  • apps/desktop/src/App.tsx+3−9
  • apps/desktop/src/app/store.actions/bootstrap.ts+6−0
  • apps/desktop/src/app/store.helpers.ts+6−0
  • apps/desktop/src/app/store.helpers/persistence.ts+22−0
  • apps/desktop/src/app/store.ts+1−0
  • apps/desktop/src/app/types.ts
+1
−0
  • apps/desktop/src/ui/ChatView.tsx+41−2
  • apps/desktop/src/ui/layout/PrimaryContent.tsx+12−2
  • apps/desktop/test/bootstrap-cache.test.ts+2−0
  • apps/desktop/test/window-state.test.ts+127−0