ENGINEERING SPECS
OrbitMesh Client Implementation Plan
This plan is written for handoff to implementation agents. Follow phases in order. Do not start mobile VPN work before the desktop process-based client can refresh a profile and run Mihomo locally.
Status (current)
- Phases 0–6 done — bootstrap, domain models, subscription/profile cache with atomic promote/rollback, Mihomo process runner, loopback controller client, desktop UI, macOS system proxy.
- Phase 8 (Android) done — full VPN via a separate-process foreground
VpnServicethat launches Mihomo itself and forwards TUN through hev-socks5-tunnel; survives UI process death; always-on supported. iOS not started. - Phase 9 partially done — in-app update (manifest → APK → FileProvider install with fallbacks), subscription-token secrecy hardening (secure account/tenant/device-scoped bindings). macOS signing/notarization and bundled-binary integrity checks remain.
- Phase 7 (Windows/Linux proxy helpers) not started — they run in process-only mode.
- Beyond the original plan: account login + refresh-token session, invisible per-account subscription provisioning, single-button connect UX with node picker, Clash inbound normalization, and GeoIP prefetch are all implemented.
Phase 0: Flutter Project Bootstrap
Create the Flutter project in apps/client without changing the architecture
folders:
cd apps/client
$HOME/.local/share/flutter/bin/flutter create \
--platforms=android,ios,macos,windows,linux \
--org dev.orbitmesh \
--project-name orbitmesh_client \
.
After generation:
- keep
pubspec.yamlproject name asorbitmesh_client, - keep generated platform folders,
- remove generated counter example code,
- keep architecture directories under
lib/, - run
flutter analyze.
Expected dependencies:
httpfor subscription and controller calls,path_providerfor app support directories,shared_preferencesor secure storage for basic preferences,process_runonly if it improves process portability.
Phase 1: Desktop MVP Domain Model
Implement plain Dart models:
SubscriptionProfileProfileCacheEntryRuntimeStatusConnectionStateSnapshotMihomoProcessConfigSystemProxyMode
Add unit tests for serialization and redaction helpers.
Phase 2: Subscription And Profile Cache
Implement:
- subscription URL validation: only
httpandhttps, - profile fetch with timeout and useful HTTP error messages,
- token-safe logging,
- pending profile write,
- active profile promotion,
- rollback to previous active profile on write failure.
Acceptance criteria:
- profile can be downloaded from an OrbitMesh Clash URL,
- empty responses fail,
- HTTP errors include status but not secret tokens,
- unit tests cover success, empty body, non-2xx, and invalid scheme.
Phase 3: Mihomo Desktop Process Runner
Implement macOS first behind a platform-neutral interface:
abstract interface class MihomoRuntime {
Future<void> start(MihomoProcessConfig config);
Future<void> stop();
Stream<String> get logs;
Stream<RuntimeStatus> get status;
}
Process lookup order:
- bundled app resource,
- user-configured path,
PATHlookup for developer builds.
Acceptance criteria:
- missing binary produces a clear UI error,
- process starts with active profile directory,
- stdout/stderr are visible in diagnostics,
- stop is graceful and then forceful after timeout.
Phase 4: Mihomo Controller Client
Implement loopback controller API client:
- health/version check,
- proxies list,
- traffic counters,
- connections list,
- active node switch where supported.
Acceptance criteria:
- UI can show runtime healthy/unhealthy,
- controller secret is never logged,
- tests cover request construction and error mapping.
Phase 5: Desktop UI
Build Flutter screens:
- Connection dashboard,
- Profile settings,
- Runtime logs,
- Diagnostics.
Controls:
- subscription URL input,
- refresh profile,
- connect,
- disconnect,
- choose Mihomo binary path,
- enable/disable system proxy.
Acceptance criteria:
- app opens directly to the usable dashboard,
- no marketing/landing screen,
- all states are visible: idle, refreshing, ready, connecting, connected, disconnecting, error,
- UI is usable at common desktop window sizes.
Phase 6: macOS System Proxy Adapter
Implement optional macOS proxy mode:
- capture previous proxy settings,
- apply HTTP/SOCKS proxy settings pointing to local Mihomo listeners,
- restore previous settings on disconnect or app shutdown.
Acceptance criteria:
- proxy changes are opt-in,
- restore always runs on disconnect,
- failures are visible and do not leave the app thinking it is connected.
Phase 7: Windows And Linux Desktop Parity
Implement process runner parity first, then proxy helpers:
- Windows: process runner, optional system proxy, future WinTun.
- Linux: process runner, optional desktop proxy, future TUN/capability helper.
Acceptance criteria:
- desktop build succeeds on each platform,
- missing system proxy capability degrades to process-only mode.
Phase 8: Mobile Foundation
Only start after desktop MVP is stable.
Android:
VpnServiceadapter,- Mihomo Android core packaging,
- socket protection callback,
- status/log bridge.
iOS:
- NetworkExtension target,
- app group storage,
- tunnel lifecycle bridge,
- provisioning and entitlement documentation.
Phase 9: Release Hardening
- code signing and notarization for macOS,
- installer and auto-update strategy,
- binary integrity checks for bundled Mihomo,
- crash and diagnostics export,
- privacy/security review for subscription tokens and local logs.
Implementation Ownership
Suggested agent split:
- Agent A: Flutter bootstrap, app shell, UI state model.
- Agent B: subscription fetch, profile cache, redaction tests.
- Agent C: Mihomo process runner and controller client.
- Agent D: macOS proxy helper and packaging.
- Agent E: Windows/Linux parity.
- Agent F: Android/iOS VPN adapters after desktop MVP.