What this does
The phone's shell after the agreed mockups (docs/ui-prototypes/mobile/01-home-and-session.html, 04 for inbox and search):
- Floating pill nav as the tab bar. Sessions · Inbox · Settings are an expo-router
Tabsgroup (src/app/(tabs)/) whose tab bar is the glass pill, with search detached beside it. Each tab is one instance that keeps its own state and scroll. A tap goes through the navigator (tabPress, thennavigate), so switching never stacks screens, re-tapping does nothing, and Android back goes to Sessions and then out. The Inbox badge counts the sessions waiting on you, and screen readers hear it too ("Inbox, 2 need you"). - Sessions home. Big title with the environment line (live dot, label, route kind) and tabs All · Active · Drafts. Active is grouped as Needs you · Working · Failed · Recent, and empty groups are left out. All is grouped by day (Today, Yesterday, weekday, "Earlier this month", then the month). A tree is ranked by its most urgent member and dated by its newest one, so live work in a child is never buried under a quiet parent. A child session nests under its parent with a connector. Each row shows one status glyph per state, then the title, project chip, what the session is doing, and its age. A draft row shows the first line, the project, the tool as its mark (never its name), the image count, and "Not synced" or "Sending".
- Inbox. Needs you (Permissions / Questions / Plans) · Done · Failed, with an all-clear state. "Mark all seen" waits until it can acknowledge on the server.
- Search. A modal in the root stack, with the field and projects shown before you type. Matching is word-wise across title and project ("tool pay" finds "Tool Call Payloads"), and results show as the standard rows, then projects.
- Placeholders with working back controls. There is a session page frame, a "New session" page behind the compose button, and a draft page behind each draft row. Back and close return to the previous screen, or to the home when a cold deep link left nothing to go back to.
Design system (apps/mobile/src/ui)
Glass: expo-blur under the scheme's translucent floating surface plus the float shadow, fed by the theme tokens.StatusMark: one glyph per state. The glyph ink comes from the theme:inkOn/statusInkpick the canvas or the ink by WCAG contrast.ProviderMark: the web provider marks.ProjectChip: a project's square, in a colour picked from the theme's documented project palette by the project's name.- Rows and chrome:
SessionRow,DraftRow,SegmentedTabs,BigTitle,SectionLabel,FadeOut,IconButton.
Fills, not borders. The home and inbox lists are SectionLists.
Data
The home reads through src/home/source.ts. Until the phone speaks the environment protocol, that returns a fixture (src/home/fixture.ts) in the shared sidebar's own shapes (SidebarSessionEntry, SidebarDraft, WorkspaceEntry). The sessions-list work swaps the hook for the shared sidebar providers without touching the screens.
Status marks use the web sidebar's own mapping. sessionBusyTone moved into a pure, import-free app-core module (packages/app-core/src/components/sidebar/session-busy-tone.ts). It is exported from the logic graph and as a package subpath, and SessionBusyLoader re-exports it, so web is unchanged. done, busy, ready and idle read the same on both, and a status with no glyph shows the ring at rest. Nothing here invents, merges or changes server state.
src/home/rows.ts and src/home/search.ts are pure and unit-tested.
Also
- Every screen paints the theme canvas, so the navigator's default white never shows.
- The Convex-era session page stays behind its provider when
EXPO_PUBLIC_CONVEX_URLis set. Otherwise the page frame shows, so the app runs with no Convex at all. - New native modules:
expo-blur,expo-haptics,expo-linear-gradient(SDK-pinned). - README: a Shell section.
- Android glass (a
BlurViewinside theBlurTargetViewit blurs) still needs a check on a device.
Verification
| Check | Result |
|---|---|
mobile typecheck, root pnpm -r typecheck | clean |
| mobile vitest | 38 pass |
| app-core lint / tests | 0 errors / 523 pass |
npx expo export --platform android | ok |
| web export + headless Chrome | 22 screens across dark and light, 0 page or console errors. Tab switching keeps one instance per tab and history stops growing. The home's Drafts tab survives a trip to Inbox and back. Cold deep links return home. |
🤖 Generated with Claude Code
Activity
13[Medium impact] The changes since the last review appear safe to merge.
Summary
Builds the phone’s navigation shell with Sessions, Inbox, Settings, search, and placeholder detail pages.
- Sessions, Inbox, and Settings stay in a floating tab shell.
- Sessions groups work by urgency, date, and draft status.
- Inbox groups sessions that need attention, finished, or failed.
- Search finds sessions and projects by the words you type.
- Session and draft rows open pages with a working way back.
- Mobile and web read session states from one shared mapping.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
Root[Root stack] --> Tabs[Tab navigator]
Tabs --> Sessions[Sessions]
Tabs --> Inbox[Inbox]
Tabs --> Settings[Settings]
Root --> Search[Search modal]
Root --> Session[Session page]
Root --> Draft[Draft page]
Source[Fixture source] --> Sessions
Source --> Inbox
Source --> SearchReviews (5) · Last reviewed commit: "Anchor cold deep links on the tabs with ..." · Reviewed by Greptile
🚀 Deploying Preview to Cloudflare 🚀
Preview Deployments by commit
View logs ↗
View logs ↗
View logs ↗
View logs ↗