feat(mobile): host-owned workspace data, single-stack nav, settings, new-chat widget

Merged
SA
4mo ago
+3829-1350

Summary

Moves the mobile app onto the host-owned workspace architecture (PR #5452) and builds out the surrounding product surface: single-stack navigation, native filter subpages, a settings first pass, and the bottom-docked new-chat widget with workspace creation.

Host-owned data layer (desktop parity)

  • Read path: useHostWorkspaces fans out workspace.list to every online host via the relay (user JWT; no host secret on device), merges results, and falls back to the Electric v2_workspaces collection for hosts that don't answer (R3 removes the fallback). 30s poll + focus/pull-to-refresh; no event bus.
  • Host-service client: plain tRPC httpLink + superjson against ${relay}/hosts/${orgId}:${machineId}/trpc, typed by a mobile-declared procedure contract (host-service's Node-flavored type graph can't compile under Expo TS; host now also ships compiled router declarations for future convergence).
  • Writes via the owning host: rename → workspace.update; delete → workspaceCleanup.destroy with dirty-worktree/teardown force-retry alerts and Delete hidden for main workspaces. Fixes the previous cloud-delete path that orphaned worktrees and left the authoritative host row alive.
  • Live diff stats: viewport-bounded git.getStatus (settled-visible rows only, capped) aggregated exactly like desktop's useDiffStats; rendered from the whole react-query cache so scroll-backs don't flicker. Replaces PR cumulative +/− on rows.
  • PR matching parity: repo-scoped ${repositoryId}::${headBranch} with desktop's state derivation (mergedAt → draft → closed → open) and tiebreaks.

Navigation & home

  • Single-stack nav (tab bar dropped), integrated header search, org switcher trimmed to orgs → separator → settings → log out.
  • Workspace filters as a formSheet route with native pushed subpages (Project / Host / Sort) backed by a persisted zustand store; generic filter toolbar icon.
  • Host status icons from merged-item reachability; worktree missing hint.

New-chat widget (workspace creation)

  • Bottom-docked prompt input: target (project+host) picker, branch picker, model selector, photo context carousel (expo-media-library + image-manipulator), creates a workspace via host workspaces.create and launches an agent.
  • Branch picker restyled: full-height sheet, X + centered title, pill search, Default/Recents sections with hairline rows, backed by host workspaceCreation.searchBranches.

Settings first pass

  • Native screens in the authenticated stack: root (account row, organization, hosts, billing, destructive log out w/ confirm), Account, Organization (+members from synced collections), Hosts (status/last-seen/workspace counts), Billing (read-only plan from a new org-scoped subscriptions Electric collection; "manage from desktop").
  • Shared row primitives promoted to screens/(authenticated)/components (ListRow family) and reused by filter + settings.

Native/dev plumbing

  • EXPO_PUBLIC_RELAY_URL env (env.ts, setup script), zustand + date-fns deps, alert-prompt local Swift module.
  • Expo prebuilt-module alignment: expo-image-manipulator@56.0.17 and expo-media-library@56.0.6 pinned to the expo-modules-core 56.0.15 batch (prebuilts released after core's date crash dyld at launch with missing Record.from symbol).

Test plan

  • biome check + mobile tsc --noEmit green
  • Simulator: fan-out serves live host rows through the local relay (workspace.list 200s), cloud fallback renders for silent hosts, diff stats fetch only for settled-visible rows
  • Dirty-worktree delete → CONFLICT alert → force retry; rename via owning host
  • Settings walkthrough incl. members list, host last-seen, Pro plan from synced subscription
  • Dev client rebuilt with aligned native modules; clean boot (no worklet/dyld errors)

Open in Stage

Summary by cubic

Moves mobile to host-owned workspaces with a single-host home view and single-stack navigation. Adds a docked new‑chat composer, settings, a typed host-service client over the relay, and removes the Electric fallback.

  • New Features

    • Host-owned data: single-host workspace.list over the relay with 30s poll and focus/refresh; no Electric fallback.
    • Host-service client: tRPC over the relay using the user JWT; types from compiled router declarations.
    • Writes via the host: rename with workspace.update; delete with workspaceCleanup.destroy and conflict/teardown handling; Delete hidden for main.
    • Live diff stats: viewport-bounded git.getStatus with desktop-style aggregation; PR badges match desktop logic.
    • Navigation and home: single-stack, header search; filters as a formSheet with native subpages and a persisted zustand store; single-host view with an offline placeholder and Switch Host CTA.
    • New‑chat widget: docked composer with project/host target, branch/model pickers as expo-router formSheets, photos/screenshots context, and uploads to the host; calls workspaces.create then launches an agent; native close buttons on all sheets.
    • Settings: Account, Organization (members), Hosts (status/last‑seen), Billing (read-only plan from subscriptions).
    • Workspace host lookup: useWorkspaceHost resolves the owning host by querying online hosts and ignores disabled queries while resolving.
  • Migration

    • Add EXPO_PUBLIC_RELAY_URL to the mobile .env (setup script writes it).
    • Rebuild the dev client after native module alignment: pin expo-modules-core@56.0.15, expo-image-manipulator@56.0.17, and expo-media-library@56.0.6.
    • iOS: include local module @superset/alert-prompt; run a fresh prebuild/Pods install if needed.
    • App config: add the expo-media-library plugin with a photos permission prompt (alongside expo-image-picker).

Summary by CodeRabbit

  • New Features

    • Added a new authenticated home/workspaces experience with filtering (Project/Host/Sort), offline host messaging, and an improved “new chat” flow with project/host/branch/model pickers.
    • Added chat prompt attachments (photos, screenshots, files, camera) and a native text prompt dialog.
    • Added enhanced workspace actions (rename, delete, copy/share) and diff-stat visibility for workspaces.
  • Settings

    • Added settings screens for Account, Organization, Hosts, and Billing, including subscription-aware billing status.
  • UI & Navigation

    • Updated navigation by removing the previous tab-based Search/Tasks/More routes in favor of the new home stack and settings routes.