From 4ac18cedb6010a355dd15f3218b95446645dde33 Mon Sep 17 00:00:00 2001 From: Dorian Date: Wed, 4 Mar 2026 22:56:54 +0000 Subject: [PATCH] docs: add research docs for iOS app, Mac desktop, plugin security - iOS: Capacitor vs WKWebView vs React Native WebView analysis - Mac: Tauri v2 vs Electron comparison with menu bar app patterns - Plugins: Signature validation, sandboxed iframes, permission system Co-Authored-By: Claude Opus 4.6 --- docs/research/ios-app.md | 113 +++++++++++++++++ docs/research/mac-desktop.md | 119 ++++++++++++++++++ docs/research/plugin-security.md | 209 +++++++++++++++++++++++++++++++ 3 files changed, 441 insertions(+) create mode 100644 docs/research/ios-app.md create mode 100644 docs/research/mac-desktop.md create mode 100644 docs/research/plugin-security.md diff --git a/docs/research/ios-app.md b/docs/research/ios-app.md new file mode 100644 index 00000000..dcc3032c --- /dev/null +++ b/docs/research/ios-app.md @@ -0,0 +1,113 @@ +# iOS App Research — AIUI + +## Overview + +Three approaches for shipping AIUI (Vue 3 + Vite SPA) as an iOS app. + +## Approach 1: Capacitor (Recommended) + +Capacitor wraps the Vite build output (`dist/`) in a native iOS Xcode project. The web app runs inside WKWebView with a JavaScript bridge to native device APIs. + +```bash +pnpm add @capacitor/core @capacitor/cli @capacitor/ios +npx cap init && npx cap add ios +pnpm build && npx cap sync +npx cap open ios # opens Xcode +``` + +**Pros:** +- Near-zero code changes to existing Vue 3 app — one codebase for web + iOS + Android +- Large, mature plugin ecosystem (camera, biometrics, push, geolocation, haptics) +- Hot reload during dev via `npx cap run ios --livereload` +- OTA live updates possible via Capgo, bypassing App Store review for JS changes +- `@capacitor/push-notifications` wraps APNs natively + +**Cons:** +- Service workers do NOT work in WKWebView on iOS (capacitor:// protocol breaks SW registration) +- Performance ceiling is WebKit JS engine (not V8) +- Each iOS SDK bump requires Capacitor + plugin updates + +**Push Notifications:** Full support via `@capacitor/push-notifications` (APNs). Production-grade. + +**Offline:** Entire app bundle ships inside .ipa — available offline. Dynamic data must use `@capacitor/preferences` or local SQLite. Workbox/SW caching does not work. + +**Performance:** Modern WKWebView uses Nitro JS engine (same as Safari). For a chat UI like AIUI, indistinguishable from Safari. GPU-accelerated CSS transforms work well. + +## Approach 2: Custom WKWebView Swift Wrapper + +Write a native Swift/SwiftUI app embedding WKWebView. Use `WKScriptMessageHandler` for JS↔Swift communication. + +**Pros:** +- Maximum native control — own the shell, native navigation, gestures +- Can implement App Clips, Share Extensions, Widgets alongside web content +- Full access to all iOS APIs at the native layer + +**Cons:** +- Requires Swift knowledge — adds second language + build system +- JS↔Swift bridge must be hand-written for every integration +- No structured plugin community; each integration is bespoke +- More setup friction vs Capacitor + +**Push/Offline/Performance:** Same as Capacitor (all use WKWebView). More manual setup. + +## Approach 3: React Native WebView + +Create a React Native app with `react-native-webview` rendering the Vite build output. + +**Pros:** +- RN has deep native API access and large ecosystem +- Surrounding shell can be fully native + +**Cons:** +- Two separate tech stacks (Vue + RN) — highest maintenance burden +- No code sharing between Vue app and RN shell +- Performance often worse (full RN runtime + WebView engine) +- RN's own breaking changes cadence adds risk + +**Verdict:** Only justified if an existing RN app is already in production. + +## App Store Risk: Guideline 4.2 + +Apple's Guideline 4.2 (Minimum Functionality) is the primary risk for all webview-based apps. Apps that pass share these traits: +- Native tab bar or navigation (not web-based menus) +- At least one native API integration (push, biometrics, camera, Apple Pay) +- Offline functionality beyond what a browser bookmark offers +- UI formatted for iOS, not a desktop website in a phone frame + +For AIUI: the chat interface, push notifications, and offline message history constitute sufficient native functionality. + +## Service Workers in WKWebView + +**SWs do not run inside WKWebView** — this is a fundamental WebKit limitation, not framework-specific. The correct offline strategy for all three approaches: ship assets in app bundle + implement dynamic caching via native storage APIs. + +## Deep Linking + +All three support iOS Universal Links via AASA file + Associated Domains capability: +- **Capacitor:** `@capacitor/app` `appUrlOpen` event → Vue Router +- **Custom WKWebView:** `AppDelegate.application(_:continue:...)` → JS evaluation +- **RN:** React Navigation linking config → WebView `postMessage` + +## Comparison + +| Dimension | Capacitor | Custom WKWebView | RN WebView | +|---|---|---|---| +| Vue code reuse | 100% | 100% | 100% | +| Native shell effort | Low | High | Very high | +| Push notifications | First-class | Manual APNs | Via RN layer | +| App Store risk | Moderate* | Moderate* | Moderate* | +| Performance | Good | Good | Adequate | +| Maintenance burden | Low-moderate | High | Very high | +| Team fit (web-first) | Best | Poor | Poor | + +*All face identical Guideline 4.2 scrutiny — framework choice is irrelevant to reviewers. + +## Concrete Next Steps + +1. Add `@capacitor/core`, `@capacitor/cli`, `@capacitor/ios` to `packages/app` +2. Set Vite `base: './'` for the Capacitor build config +3. Disable PWA service worker for native builds (partially done already) +4. Add `@capacitor/push-notifications` for APNs +5. Implement native splash screen and app icon +6. Test on iOS Simulator via `npx cap run ios` +7. Set up Apple Developer account + code signing +8. Submit TestFlight build for internal testing diff --git a/docs/research/mac-desktop.md b/docs/research/mac-desktop.md new file mode 100644 index 00000000..19e70b09 --- /dev/null +++ b/docs/research/mac-desktop.md @@ -0,0 +1,119 @@ +# Mac Desktop App Research — AIUI + +## Overview + +Two approaches for shipping AIUI as a Mac desktop app: Tauri v2 (Rust-based, system WebView) vs Electron (Chromium-based). + +## Tauri v2 (Recommended) + +Released stable October 2024. Uses OS-native WebView (WKWebView on macOS). The Vue 3 + Vite frontend runs inside the WebView unchanged. JS calls into Rust via typed IPC bridge. + +**Binary Size:** 2–8 MB installer (no bundled runtime) +**Memory Usage:** ~30–40 MB idle +**Startup Time:** < 500ms + +### Menu Bar App Pattern (Raycast-style) + +Fully supported via `tauri-plugin-positioner` + tray + window APIs. Frameless popover window anchored to tray icon with `decorations: false`, `skip_taskbar: true`. Community examples exist (`ahkohd/tauri-macos-menubar-app-example` v2-popover branch). + +### Global Hotkey + +Built-in via `@tauri-apps/plugin-global-shortcut`. Register accelerators (e.g., `CmdOrCtrl+Space`) that fire even when background/minimized. First-class plugin. + +### System Tray + +First-class support. `AppHandle::tray()` with native menus and click event handling from Rust or frontend. + +### Auto-Update + +`@tauri-apps/plugin-updater` — signed updates required (Ed25519 keypair). Host a static JSON endpoint with version metadata and signed artifact URLs. + +### macOS Code Signing / Notarization + +Automated via Tauri CLI environment variables (`APPLE_CERTIFICATE`, `APPLE_SIGNING_IDENTITY`, `APPLE_ID`, `APPLE_TEAM_ID`). Notarization adds ~2–5 min per build. + +### Build Pipeline + +- Prerequisites: Rust toolchain + Xcode CLI tools +- First build: 5–15 min (Cargo compiles Rust deps) +- Incremental builds: Fast with caching +- Config: `tauri.conf.json` + `Cargo.toml` +- Complexity: Medium-High (Rust requirement is the barrier) + +### Mobile Support + +Tauri v2 has **first-class iOS/Android support** in the same codebase (WKWebView on iOS, Android System WebView on Android). HMR extends to physical devices. This is a genuine differentiator — Electron is desktop-only. + +## Electron + +Mature since 2013. Bundles full Chromium + Node.js runtime. Used by VS Code, Slack, Discord, Obsidian. + +**Binary Size:** 80–150 MB installer +**Memory Usage:** 200–350 MB idle +**Startup Time:** 1–2s + +### Menu Bar App + +Well-established via `menubar` npm package. Creates BrowserWindow positioned below tray icon, manages show/hide on tray click. Very mature. + +### Global Hotkey + +`globalShortcut` module in Electron core. System-wide even when hidden. + +### System Tray + +`Tray` class in Electron core with context menus and click events. + +### Auto-Update + +`electron-updater` (S3/GitHub Releases) or `update.electronjs.org` (free for open-source). + +### macOS Code Signing / Notarization + +Via `@electron/osx-sign` + `@electron/notarize`, integrated into `electron-builder` / Electron Forge. + +### Build Pipeline + +- Prerequisites: Node.js only — no additional runtimes +- Build tools: `electron-vite` for Vue 3 + Vite integration +- Build times: 2–5 min (no Rust compilation) + 2–5 min notarization +- Complexity: Medium (main/renderer process split requires understanding) + +## Comparison + +| Dimension | Tauri v2 | Electron | +|---|---|---| +| Installer size | 2–8 MB | 80–150 MB | +| Idle RAM | 30–40 MB | 200–350 MB | +| Startup time | < 500ms | 1–2s | +| Menu bar app | Supported | Supported | +| Global hotkey | Built-in plugin | Built-in API | +| System tray | Built-in | Built-in | +| Auto-update | Built-in (signed) | electron-updater | +| New language | Rust | None (JS/TS) | +| iOS/Android | Yes (same codebase) | No | +| WebView | WKWebView (varies by OS) | Chromium (pinned, consistent) | +| Ecosystem maturity | Growing fast | Very mature | +| Security model | Capability-based, opt-in | Opt-out, manual discipline | +| Debug tools | Safari Web Inspector | Chrome DevTools | + +## Recommendation + +**Tauri v2 is the stronger choice for AIUI:** + +1. **Memory advantage is decisive.** Users running local LLMs or managing API streaming need resources for the AI workload, not the shell. 30 MB vs 300 MB matters. +2. **Menu bar pattern fits naturally** for a chat/AI assistant (Raycast-style quick invoke). +3. **iOS/Android support** from the same codebase aligns with AIUI's multi-surface vision. +4. **Capability-based security** is appropriate for handling API keys and sensitive chat data. +5. **Binary size matters** — 5 MB download vs 120 MB affects distribution trust. + +## Concrete Next Steps + +1. Scaffold Tauri v2 project: `npm create tauri-app@latest` with Vite template +2. Point dev server to existing `packages/app` Vite config +3. Implement tray icon + menu bar popover window +4. Register global hotkey (e.g., `Cmd+Shift+Space`) to invoke chat +5. Write Rust commands for: file I/O, tray management, updater config +6. Set up macOS code signing + notarization pipeline +7. Distribute via Homebrew cask or direct download +8. Evaluate Tauri mobile targets for iOS/Android convergence diff --git a/docs/research/plugin-security.md b/docs/research/plugin-security.md new file mode 100644 index 00000000..6a1545b1 --- /dev/null +++ b/docs/research/plugin-security.md @@ -0,0 +1,209 @@ +# Plugin System Hardening Research — AIUI + +## Current State + +The plugin system has these existing components: +- `packages/core/src/types/plugin.ts` — `AIUIPlugin` interface, `PluginContext`, `PluginType` +- `packages/core/src/plugins/registry.ts` — in-memory Vue ref-based registry +- `packages/app/src/stores/pluginMarketplace.ts` — `InstalledPlugin`, `PluginPermission`, `installPlugin`, `hasPermission` +- `packages/app/src/components/settings/PluginMarketplace.vue` — permissions dialog +- `packages/app/src/components/renderers/CodeRunner.vue` — existing `