Skip to content

feat(mobile-remote): add Tauri iOS shell - #1222

Draft
beruro wants to merge 4 commits into
junyu/ios-remote-sharedfrom
junyu/ios-remote-shell
Draft

feat(mobile-remote): add Tauri iOS shell#1222
beruro wants to merge 4 commits into
junyu/ios-remote-sharedfrom
junyu/ios-remote-shell

Conversation

@beruro

@beruro beruro commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Problem

Web Remote already contains the Mobile Remote product flow, but there is no installable iOS host for it. Reusing the Desktop Tauri crate would also pull the local agent runtime, terminal, database, filesystem, and Desktop-only permissions onto the phone. The browser auth path additionally assumes redirect remounts and browser storage, so it cannot safely handle warm iOS callbacks or durable native credentials.

The first simulator launch also exposed two monorepo-specific launch defects: the generated Xcode build phase invoked pnpm tauri from a directory where pnpm selected the Desktop Tauri config, and the native window path was appended to a devUrl that already contained the same path. Requiring a live Cloud OAuth round trip for every local simulator launch also blocked rapid UI and pairing development. The first bypass implementation then used a fixed local-development pairing owner, which made existing account-scoped Keychain pairings invisible and looked like pairing was lost on every launch.

Solution

Add a separate lightweight Tauri iOS shell for ORG2 Remote and keep the agent running on the paired Desktop. The production native entry renders the existing MobileRemoteRoot and supplies only platform adapters for system-browser Supabase PKCE, cold and warm org2remote deep links, foreground WebSocket creation, and app-owned Security.framework Keychain commands.

The shell uses product name ORG2 Remote, bundle id org2ai.org2.remote, iOS 17+, and an independently generated Apple project. Native and Desktop webpack artifacts are isolated. Pairings are stored as a versioned, account-scoped local inventory capped at 20 entries with credential-free summaries and one active Desktop. Shared DevicesTab rows reuse Button, InlineAlert, SectionContainer, SectionRow, StatusDot, and existing typography/color tokens, including pending and failure states.

The generated Xcode build script now changes into the mobile src-tauri directory and invokes the repository Tauri binary directly, preserving the org2ai.org2.remote configuration. The development URL is now origin-only while mobile-native.html remains the window entry, so Tauri resolves the entry exactly once. Contract tests protect both invariants.

Native development builds dynamically load an isolated development root with a synthetic identity. It never creates a Cloud auth client or writes an auth session, but it still consumes native pairing intents and renders the same MobileRemoteApp. Before React bootstraps connection state, the development entry resolves one stable Keychain owner: it keeps a populated development inventory, otherwise reuses the last persisted account user id, and falls back to local-development only when neither exists. This preserves both pairings made during bypass development and pairings created before the bypass. Production builds take the real MobileAuthGate branch, and the development module and synthetic identity are absent from the emitted production bundle. Settings hide the otherwise non-functional sign-out action while the bypass is active.

This is stacked on #1220 and does not change the relay JSON-RPC protocol or move agent execution to iOS.

Potential risks

  • Simulator build and launch are verified, but a signed physical-device build and the complete GitHub/Supabase OAuth callback, Keychain persistence, pairing, and remote-control flow have not been exercised yet. The PR remains Draft.
  • Supabase must allow org2remote://auth/callback outside this repository.
  • Relay endpoints are user-configurable, so CSP connect-src retains wss:. Pairing validation and per-Desktop credentials remain the authorization boundary.
  • The paired Desktop list is local account-scoped history, not a server-authoritative inventory. A remotely revoked device can remain listed until a connection attempt proves it stale.
  • Foreground/background transitions, keyboard behavior, Dynamic Type, VoiceOver, and native resource measurements still need physical-device validation.
  • A simulator with neither a development pairing inventory nor a retained auth session still requires one initial pairing. Subsequent development launches use the stable owner selected at bootstrap.
  • This PR depends on refactor(mobile-remote): add platform adapter boundary #1220. Rollback is to revert the four scoped shell commits; new Keychain namespaces are isolated and do not migrate Desktop or browser storage.

Verification

Passed:

  • pnpm test -- src/modules/MobileRemote — 34 files, 178 tests
  • targeted auth/platform/provider/device tests — 6 files, 60 tests
  • targeted development scope and Tauri persistence tests — 2 files, 15 tests
  • pnpm exec vitest run src/modules/MobileRemote/platform/tauri/iosLaunchConfigContract.test.ts — 1 file, 2 tests
  • pnpm exec eslint src/mobileRemoteNativeEntry.tsx src/modules/MobileRemote/dev/MobileRemoteDevelopmentRoot.tsx src/modules/MobileRemote/dev/MobileRemoteDevelopmentRoot.test.ts src/modules/MobileRemote/platform/tauri/tauriMobileRemotePlatform.test.ts
  • pnpm typecheck
  • pnpm lint
  • pnpm check:test-placement — 470 directories consistent
  • pnpm build
  • pnpm build:mobile-native
  • production-bundle scan — no local-development, local-development profile, or development resolver strings emitted
  • cargo fmt --check
  • cargo check
  • cargo check --target aarch64-apple-ios
  • cargo test --lib — 2 tests
  • cargo tree --depth 1 — no Desktop workspace/runtime crates
  • Xcode 26.6 with the iOS 26.5 simulator runtime — BUILD SUCCEEDED
  • Installed and launched bundle org2ai.org2.remote on iPhone 17 Pro / iOS 26.5
  • Manual simulator check — ORG2 Remote login screen renders inside the status-bar safe area with the GitHub login action visible
  • Manual simulator check — native development build skips login and renders the shared Mobile Remote welcome, pairing, and demo actions
  • Manual simulator terminate/relaunch — development bootstrap completes cleanly; this simulator currently has no matching active pairing, so the expected first-pair welcome is shown
  • git diff --check
  • staged secret, personal-path, and generated-artifact scan

Not run:

  • Signed physical-device build and complete cold/warm OAuth, successful live pairing followed by terminate/relaunch, remote-control, foreground/background, keyboard, Dynamic Type, and VoiceOver flows

Audit

  • Architecture: docs/architecture/ios-remote-shell.md
  • Feature lifecycle: docs/feature-lifecycle-2026-09-02/IosRemoteShell.md
  • Frontend UI: 2 fix findings resolved, 8 keep-with-reason, 0 abstract
  • Performance: lifecycle and bounds are unit-covered; verdict remains blocked pending physical iOS measurements

@beruro
beruro requested a review from Neonforge98 September 2, 2026 06:42
@Harry19081 Harry19081 added enhancement New feature or request security Security-sensitive behavior, credentials, secrets, or advisories cloud-collaboration Cloud sync, organizations, channels, or collaboration frontend-ui Frontend UI, design system, accessibility, layout, or theming labels Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cloud-collaboration Cloud sync, organizations, channels, or collaboration enhancement New feature or request frontend-ui Frontend UI, design system, accessibility, layout, or theming security Security-sensitive behavior, credentials, secrets, or advisories

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants