Files

57 lines
3.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NucleicRemote (iPhone client)
The iOS remote client for Nucleic: a projection of the Mac hosts, with no local git or CLI — the
Mac stays the single authority. It monitors sessions, reads transcripts/diffs, **answers
approvals**, and sends follow-up input at scope `approve`; a device granted scope `control` also
starts chats, interrupts, integrates/discards, retitles and archives, sets a session's
model/effort/Intelligence stop, manages todos and projects, mints pairing codes, brokers agent
sign-in, and syncs account settings — each control verb additionally gated on the host
advertising the matching `WireCapabilities` bit, so an older Mac degrades instead of erroring.
See [`docs/UX_IOS.md`](../../docs/UX_IOS.md) and
[`docs/SYNC_PROTOCOL.md`](../../docs/SYNC_PROTOCOL.md).
## Architecture
All wire/crypto logic is shared with the Mac via the **`NucleicProtocol`** SwiftPM library
(this Xcode project links it as a local package at `../..`):
- **Transports** — three, all carrying the same Noise-encrypted frames end-to-end:
**LAN** (`NWFrameChannel` over NWConnection + `LANDiscovery`, Bonjour `_nucleic._tcp`),
**tailnet** (an embedded `NucleicTailnet` node dialing the Mac's tailnet address), and the
**cloud relay** (`RelayFrameChannel` against the Hydrangea Worker room — which is E2EE-opaque
and forwards bytes it can't read). A relay session may upgrade to a hole-punched `direct` path.
- **Engine** — `NucleicProtocol.SyncClient` runs the Noise handshake (XXpsk0 to pair, IK to
reconnect), exchanges hello/welcome, and turns `HostMsg`s into a `SyncClient.Event` stream.
- **State** — `RemoteStore` (`ObservableObject`) is the single on-device UI state, a pure
projection of the hosts. It is **multi-host**: one `HostConnection` per entry in
`IdentityStore.pairedHosts()`, all connected at once and merged into one session list (no host
switcher). Identity + the paired-host registry live in `IdentityStore` (Keychain +
UserDefaults).
- **UI** — SwiftUI: `SessionsView`/`HomeView` (attention-first list), `SessionDetailView`
(transcript/diff + status-driven action area), `ApprovalCardView` (approve/deny, high-risk
answered in-app), `Composer` + `IntelligenceRail`, `ProjectsView`, `TodosView`, `MeshInfoView`,
`PairingScannerView`, `SettingsView`.
- **Push** — `PushRegistrar`/`Notifications` (APNs approval wakes, actionable for low/medium
risk) and `LiveActivityManager` (one aggregate Live Activity, host-pushed so it stays fresh
while locked).
## Build & run
```sh
# Resolves the local NucleicProtocol package automatically.
xcodebuild -project ios/NucleicRemote/NucleicRemote.xcodeproj \
-scheme NucleicRemote \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' build
```
Or open `NucleicRemote.xcodeproj` in Xcode and run. To pair, start the sync server on the Mac
(Nucleic ▸ Settings ▸ Add iPhone shows the QR), then scan it. Pairing over LAN needs both devices
on the same Wi‑Fi; the QR can also carry a tailnet or relay hint, which work from anywhere.
## Status
Shipped. The pair → list → subscribe → approve → reconnect path, the control-scope verbs, all
three transports, multi-host, push notifications and the Live Activity (UX_IOS §5.1/§5.3) are all
in place; the protocol/server side is covered by tests in `Tests/NucleicProtocolTests` and
`Tests/NucleicCoreTests`, and the relay/APNS Worker by `cloud/nucleic-edge/test/`.