Skip to content

Prepare core, cloud, and test surfaces for the bb mobile app - #1987

Merged
SawyerHood merged 4 commits into
bb-mobile-1-client-corefrom
bb-mobile-2-core-prep
Aug 20, 2026
Merged

Prepare core, cloud, and test surfaces for the bb mobile app#1987
SawyerHood merged 4 commits into
bb-mobile-1-client-corefrom
bb-mobile-2-core-prep

Conversation

@SawyerHood

@SawyerHood SawyerHood commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Stack layer 2 of 4 for the bb mobile app (stack #1990). Prerequisite: #1986 (@bb/client-core). Next layer: #1988 (the app).

What was wrong

A native client needs a few small, additive pieces the server, cloud, SDK, and test harness do not have today: a way to tell the server it is a mobile client, SDK types that survive React Native's global Response/FormData declarations, a shared contract for the two plugin-rendered pending interactions so the phone can render them natively, a deterministic approval path in the fake provider for e2e, a harness that can run on a fixed port behind a stub gate, a way to mint a connect pairing code for a phone, and app-link association files so universal links can work.

What changed

  • packages/config + apps/server: request-side RequestAppSurface (desktop | web | mobile) for x-bb-app-surface + telemetry; the server config union stays desktop | web. Test added.
  • packages/sdk: SdkResponseLike structural constraint in response.ts/transport.ts (Hono client responses stay assignable under RN globals); projects.sidebarBootstrap(); public-types test updates.
  • New packages/plugin-interaction-contracts: the ask-user-question and secret-request payload/resolution schemas moved from the two plugins' private contracts.ts; both plugins re-export them (their tests unchanged).
  • packages/agent-runtime fake provider: approve:<kind> control token (command | file_change | permission_grant | plan) emits an approval interactive request; adapter decodes/encodes approval payloads; 5 tests.
  • tests/integration: harness serverPort/bindHost options; mobile-e2e/backend.ts (seeded long-lived harness) and connect-stub.ts (TLS stub gate in front of the harness) + scripts + turbo tasks.
  • plugins/connect: "Add mobile device" QR/code in Settings → Remote access and bb connect machine-code [--json] (uses the existing createMachineCode RPC; 409 machine-limit surfaced). Guide template, bb-cli SKILL, docs/multiple-devices.md, docs/configuration.md pairing section updated per docs/cli-guide-and-skill.md.
  • Hidden behind the new mobileApp experiment (off by default; Settings → Experiments → "Mobile app", or bb settings experiment mobileApp true) until the app is generally available. @bb/domain gains the key; the connect plugin reads it through its loopback SDK (bb.sdk.system.config()) on every call — a new mobilePairing rpc tells the panel whether to render the section, and createMachineCode / bb connect machine-code refuse with a pointer to the toggle. No new plugin-SDK API. With the experiment off, a paired install sees no visual change from this PR.
  • packages/connect-client: pairing helpers used by the phone.
  • apps/connect (gate) + apps/web (apex) + packages/connect-db: serve /.well-known/apple-app-site-association and /.well-known/assetlinks.json before the session gate (static JSON only; Android fingerprints from ASSETLINKS_SHA256_FINGERPRINTS, empty if unset). No auth change.

No daemon contract change → HOST_DAEMON_PROTOCOL_VERSION untouched.

How you verified

  • pnpm exec turbo run typecheck lint for config, server, sdk, plugin-interaction-contracts, ask-user-question, secrets, connect plugin, agent-runtime, integration-tests, connect-client, templates, @bb/connect, @bb/web, connect-db, cli — pass (the only failure is the pre-existing conversation-outline-parity.test.ts typecheck on main from Keep mid-turn user exchanges visible after a turn completes #1657).
  • Tests: sdk 96, agent-runtime 413, connect plugin 88, templates 43, connect/connect-db/connect-client, server telemetry + public route tests (342), @bb/integration-tests test:smoke 28 — all pass.

Part of the bb mobile app plan (plans/bb-mobile-expo.md, lands in #1988).

AGENT GENERATED: by Claude Opus 5

@bb-slop-cop

bb-slop-cop Bot commented Aug 20, 2026

Copy link
Copy Markdown

🚨 SLOP COP 🚨 · review

I am SlopCop. I am reviewing this pull request now.

I will check security, code quality, performance, architecture, and the main product path.

SawyerHood and others added 4 commits August 19, 2026 19:28
Small server/SDK/cloud/test changes the native client needs, with no mobile
code:

- Request-side `mobile` app surface (`x-bb-app-surface`): `@bb/config`
  `parseRequestAppSurface`, server request context + telemetry.
- `@bb/sdk`: `SdkResponseLike` transport/response contract,
  `projects.sidebarBootstrap()`.
- New `@bb/plugin-interaction-contracts` package with the ask-user-question
  and secrets pending-interaction schemas; both plugins re-export it.
- Fake provider `approve:<kind>` script step for approval fixtures.
- Integration harness `serverPort` / `bindHost` options, the long-lived
  mobile e2e backend and the TLS bb connect stub (`e2e:mobile-backend`,
  `e2e:mobile-connect-stub`).
- bb connect mobile pairing: `@bb/connect-client` machine-code pairing
  helpers, Settings → Remote access "Add mobile device" QR, the
  `bb connect machine-code` CLI command, guide/skill/docs updates.
- `/.well-known/apple-app-site-association` and `assetlinks.json` served by
  the connect gate worker and the apex web routes (`@bb/connect-db`
  `app-links`).

Co-Authored-By: Claude <noreply@anthropic.com>
The bb mobile app is not generally available yet, but the connect panel
rendered "Add mobile device" for every paired install and `bb connect
machine-code` was live. Add a `mobileApp` experiment (off by default) in
@bb/domain with a toggle in Settings → Experiments, and have the connect
plugin read it through its loopback SDK binding (`bb.sdk.system.config()`)
on every call — no new plugin API:

- new `mobilePairing` rpc tells the panel whether to render the section
- `createMachineCode` rpc and `bb connect machine-code` refuse with a
  pointer to the toggle (`bb settings experiment mobileApp true`)
- docs, the bb-cli skill, and the guide template mention the experiment

Co-Authored-By: Claude <noreply@anthropic.com>
The desktop app's own connect enrollment and the web "Add machine" dialog
mint machine codes through the same `createMachineCode` rpc, so the
mobileApp experiment gate added in 00fc462 broke both by default. The gate
now covers only the mobile-specific surfaces: the panel card (through the
`mobilePairing` rpc) and `bb connect machine-code`.

Co-Authored-By: Claude <noreply@anthropic.com>
- connect worker: answer the Apple/Android app-link association files only
  for bare labels; share hosts (`<label>--<port>`) front arbitrary local
  apps and must not claim /threads, /projects, /settings for the mobile app
- AASA: emit only the modern `appIDs` + `components` form (Apple TN3155
  warns against mixing it with the legacy `appID` + `paths` keys)
- mobile-e2e backend: print a security warning (and the LAN URL hint) when
  BB_MOBILE_E2E_BIND_HOST=0.0.0.0 exposes the unauthenticated harness
- ask-user-question / secrets plugins: import the shared renderer-ID
  constants instead of repeating the literals
- docs: drop a forward-referencing anchor

Co-Authored-By: Claude <noreply@anthropic.com>
@SawyerHood
SawyerHood force-pushed the bb-mobile-2-core-prep branch from d27f60c to c0794d7 Compare August 20, 2026 02:47
@SawyerHood
SawyerHood marked this pull request as ready for review August 20, 2026 02:49
@SawyerHood
SawyerHood merged commit 9e2f8ed into main Aug 20, 2026
12 checks passed
@SawyerHood
SawyerHood deleted the bb-mobile-2-core-prep branch August 20, 2026 03:12
SawyerHood added a commit that referenced this pull request Aug 20, 2026
Stack layer 1 of 4 for the bb mobile app (stack #1990). No prerequisite;
the next layer is #1987.

## What was wrong

The native mobile app (`apps/mobile`, layer 3) needs the web app's
platform-neutral client logic — sidebar grouping and sorting, thread
read state, prompt draft and submission policy, mention triggers,
timeline merge/paging helpers, renderable-patch rules, the terminal
WebSocket transport, panel tab schemas, file preview, localhost link
rewriting, route builders. Today these live inside `apps/app/src` next
to DOM and react-router code, so a React Native app cannot import them.

## What changed

- New `packages/client-core` (`@bb/client-core`): the pure modules moved
out of `apps/app` unchanged, plus a `test/no-dom.test.ts` guard that
walks `src/**` and fails on
`window`/`document`/`localStorage`/`navigator`/react-router/`@/`
references.
- `apps/app`: every old path is a one-line re-export shim, so web
imports and tests keep working; the few files that mixed DOM and pure
code (`route-paths.ts`, `fixed-panel-tabs-state.ts`,
`useThreadTimelineController.ts`,
`localhost-link-rewrite-preference.ts`, `terminal-websocket-url.ts`,
`TimelineFileDiffBlock.tsx`, `secondaryPanelTabState.ts`) keep the
web-only parts and import the rest from client-core. 19 tests moved with
their modules.
- `TerminalWebSocketTransport` treats an undefined
`socket.bufferedAmount` as 0 (React Native's WebSocket never sets it),
with a regression test.
- `@bb/client-core` depends on `@bb/domain`, `@bb/server-contract`,
`@bb/core-ui`, `@bb/thread-view`, `@bb/fuzzy-match`,
`@bb/desktop-contract` (pure), `zod`. No React.

No behavior change in the web app is intended.

## How you verified

- `pnpm exec turbo run typecheck lint test --filter=@bb/client-core
--filter=@bb/app` — client-core 236 tests, app 2955 tests / 392 files,
lint 0 errors (the 144 warnings pre-exist on main).
- `packages/client-core/test/no-dom.test.ts` guards the DOM-free rule;
the transport test fails without the `bufferedAmount` fix.

Part of the bb mobile app plan (`plans/bb-mobile-expo.md`, lands in
#1988).

> AGENT GENERATED: by Claude Opus 5

---------

Co-authored-by: Claude <noreply@anthropic.com>
SawyerHood added a commit that referenced this pull request Aug 20, 2026
Stack layer 3 of 4 for the bb mobile app (stack #1990). Prerequisites:
#1986 (`@bb/client-core`) and #1987 (core prep). Next layer: #1989 (push
notifications).

## What was wrong

bb has no native phone client. The PWA works on a phone but is bounded
by mobile-web limits (keyboard/viewport hacks, no push, no background
reconnect, no secure credential storage, no camera/photo attachments,
WebKit style-recalc stalls). Plan, decisions, and research:
`plans/bb-mobile-expo.md`, `plans/bb-mobile-research/`; execution log
with per-phase verification: `plans/bb-mobile-progress.md`.

## What changed

New `apps/mobile` (`@bb/mobile`, Expo SDK 57 / React Native 0.86 / Expo
Router / NativeWind v5, iOS first; ~81k lines of app code, ~20k of unit
tests, 26 Maestro flows). Everything else in this PR is toolchain/docs;
no server or web behavior changes.

- Connectivity: server profiles in SecureStore; Direct mode (LAN /
Tailscale / simulator) and bb connect (machine enrollment by QR/code →
desktop-session cookie in the native jar, renewal, re-pair); per-profile
SDK + realtime manager (ping/pong, watermark reconnect, AppState
suspend/resume) + QueryClient with realtime invalidation; global
mutation error toasts.
- Screens: drawer sidebar + home thread list (organize/sort, pinned,
unread glyphs, long-press actions), search, archived, compose with
pickers (project, provider, model+reasoning, permission mode, service
tier, environment incl. reuse/worktree/branch/path, machine), new
project + project settings + machine setup, thread detail (FlashList
timeline with every row kind via a renderer registry, native markdown,
native diffs, ANSI, lightbox, unread divider, ToC, prompt-stack cards),
prompt area (composer with mentions/typeahead/attachments/voice/drafts,
send/queue/steer/stop, queued messages, pending-interaction banner incl.
approvals, questions, ask-user-question and secret-request forms,
context banner with git/PR/parent/children, message/thread/git action
sheets, fork/handoff), workspace panel (Info, Diff, Files + previews,
terminal = bundled xterm WebView with RN-owned socket + accessory bar,
synced thread tabs), settings (general, appearance palettes from
`theme.css`, experiments, providers, usage, machines list/detail/add,
updates, plugins management + marketplaces, skills library/registry,
haptics), deep links (`bb://`, universal link mapping, thread-open
signal), outbound share.
- Design system: generated native theme tokens
(`scripts/generate-native-theme.ts` from `theme.css`, drift-tested),
primitives (sheets, action sheets, toasts, etc.), Inter + Fira Code,
hugeicons.
- Toolchain: Metro resolves `@bb/*` from TS source (`source` condition
scoped to workspace packages), `pnpm patch` for
`expo-modules-jsi@57.0.4` on Xcode 26.2, scoped `lightningcss` override
for NativeWind v5, turbo/eslint/prettier wiring,
`.github/workflows/mobile-e2e.yml` (label `mobile-e2e` / nightly;
Release build + Maestro) and `mobile-runner-probe.yml`, `eas.json`
profiles, docs (`docs/platform-support.md`,
`docs/repository-overview.md`).
- Early access: the bb-side pairing surfaces (Settings → Remote access →
Add mobile device, `bb connect machine-code`) are behind the `mobileApp`
experiment from #1987; the app's own Settings → Experiments screen lists
that toggle too (it is shared server state).
- Not in this layer: push notifications (#1989). Not yet: Android,
plugin frontends (SPA-in-WebView planned), inbound share (needs a native
rebuild), TestFlight (needs an EAS account).

## How you verified

- `pnpm exec turbo run typecheck lint test --filter=@bb/mobile` — 794
tests / 117 files, 0 lint findings.
- Every phase was built by parallel agents and independently
re-verified; the full Maestro regression (26 flows) passed on the iPhone
17 Pro simulator (iOS 26.3) against the seeded harness backend
(`tests/integration/mobile-e2e/backend.ts`) and the connect stub gate;
results table and screenshots list in `plans/bb-mobile-progress.md`.
Connect enrollment was also exercised against the real `bee.getbb.app`.
- On this layer specifically (no push): `phase1-shell`, `phase4b-send`,
`phase5-links` flows re-run and pass.
- Known gap carried in the log: on bb connect profiles the left-edge
drawer swipe can also press the home row under the touch (Direct
profiles are fine).

> AGENT GENERATED: by Claude Opus 5

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant