mobile/README.md
Rama main · réplica de lectura del repositorio original.
# Cortex mobile client
The phone client for Cortex: a React + Vite single-page app served by the
desktop's embedded server (`src-tauri/src/mobile_server`) and wrapped by the
Capacitor shell in `native/` for the Android APK and iOS builds. Architecture,
pairing, install and push are documented in [docs/MOBILE.md](../docs/MOBILE.md).
## Layout
```
src/
main.tsx, App.tsx boot → pair | unreachable | ready; tabs; push prompt
lib/api.ts every /api/v2 endpoint with legacy /api/* fallbacks
lib/ws.ts one WebSocket: auth, subscribe, backoff, resync
lib/store.tsx connection state, capabilities, project, theme, badge
lib/nav.ts hash router (#/chats, #/threads/:id, #/inbox, …)
lib/push.ts service worker + VAPID subscription
lib/session.ts server URL + bearer token, pairing-link parsing
lib/demo.ts in-memory server for the demo mode
views/ Pair, Chats, Thread, Inbox, Projects, Runs, More
components/ Shell, Composer, ToolCard, ApprovalCard, Gauge, ui
public/manifest.webmanifest, public/sw.js
```
## Build
```sh
pnpm build:mobile # from the repo root → mobile/dist (bundled as a Tauri resource)
```
`dist/` is git-ignored. `tauri dev` and `tauri build` run this step; CI runs it
before `cargo` so the resource exists.
## Dev against a running Cortex
```sh
cd mobile
VITE_API_BASE=http://localhost:8788 pnpm dev # proxies /api and /ws
```
Open the printed LAN URL on the phone. Requests from a non-loopback address
need a paired token, so pair from **Settings → Mobile** on the desktop first,
or open the demo from the pairing screen for layout work with no server.
## Modes
Boot probes `GET /api/v2/capabilities`:
- 200 → v2 mode; features come from `capabilities.features`.
- 404 → legacy mode against an older Cortex (`/api/sessions`, `/api/chat`);
runs, routines, git and devices show a "needs a newer Cortex" state.
- 401 → pairing screen. Any later 401 returns there.
## Native shell
The web app never imports Capacitor. `native/bridge.ts` installs
`window.CortexNative` (haptics, QR scan, secure storage, deep links, share)
before the bundle runs; every member is optional and feature-detected. Deep
links arrive as a `cortex:deeplink` event carrying the URL.