- useViewport: matchMedia-based hook (no resize polling). Breakpoints
mobile <768 / tablet 768-1023 / desktop >=1024. SSR-safe.
- useSidebarDrawer: Context provider with open/setOpen/toggle + auto-close
on useLocation().pathname change.
- App.tsx: wraps SidebarDrawerProvider around AppShell, renders a
MobileBackdrop (z-30) when the drawer is open on mobile.
- ProjectSidebar: aside is fixed/translate-x-full off-screen on mobile,
slides in (z-40, 200ms transform) when drawerOpen. Inline column on
desktop, unchanged.
- Session.tsx + Project.tsx: hamburger (Menu icon, >=44x44 min) on mobile
opens the drawer. Headers gain paddingTop: max(0.75rem,
env(safe-area-inset-top)) for notch devices. Home.tsx left alone
(sidebar content duplicates the home page).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Swallowed-error logging (audit Feature 3):
- file_index.ts:36-37 (git mtime probes): comment — best-effort, project
may not be a git repo.
- useUserEvents.ts:44 / 53 (ws.close on error / unmount): comments —
best-effort, socket may already be closing.
- RightRail.tsx:38 (localStorage write): comment — best-effort, quota or
private mode.
- App.tsx:21 (api.sessions.get for RightRail projectId): replaced silent
catch with console.warn.
- Session.tsx:38, 41 (session fetch + project list for breadcrumb):
replaced silent catches with console.warn.
H1: ProjectSidebar.tsx:189 — dropped the local sessionEvents.emit
({type:'session_renamed'}) after PATCH. Server publishes via
broker.publishUser since v1.4; useUserEvents forwards.
H2: useSessionStream.ts session_renamed case removed (dead — no
server code path publishes session_renamed on the per-session WS
channel; only user channel via broker.publishUser). Also dropped the
session_renamed variant from WsFrame (in apps/web/src/api/types.ts)
to keep the discriminated-union switch exhaustive.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Session 1:N Chat data model with backfill. Workspace switches to client-side
multi-tab pane management. Right-rail file browser with float-over viewer and
click-drag line selection replaces FileBrowserPane. Adds /compact streaming
summarizer (respects compact markers in context builder), force-send (cancels
in-flight, persists partial as 'cancelled', awaits cancellation completion via
deferred Promise + 5s timeout), message queue, stop generation, chat
auto-rename, session archive/unarchive with Closed Sessions section on repo
landing page. CHECK constraints on sessions.status, messages.role,
messages.status with KEEP IN SYNC comments tying to MESSAGE_ROLES /
MESSAGE_STATUSES const arrays. Deletes dead pane routes/hook and the
api.panes.* client block.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Mirror Pane/PaneState/UserStream types
- api.panes.* CRUD methods
- sessionEvents adds session_updated, session_loaded, open_file_in_browser
- useUserEvents hook: single app-level WS to /api/ws/user with reconnect
- useSidebar handles session_updated (in-place patch + re-sort) and
session_loaded (active-project highlight gap fix); open_file_in_browser
is a deliberate no-op here, consumed by Workspace later
- App.tsx mounts useUserEvents once
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>