entry.ts
1// src/mobile/entry.ts — the mobile WebView's single entrypoint (god document §4.3).2//3// Order is load-bearing: the chrome shim must install `globalThis.chrome`4// before any other module evaluates, and the brain boots before the UI5// mounts so `bridge.sendMessage`'s first call has a handler waiting.6//7// `background/entry.ts` already self-invokes `start()` at its own module8// bottom (verified against source — this diverges from the god document's9// illustrative sketch, which shows calling `start()` again explicitly; doing10// that here would run session-restore, setupAutoLock, and11// setupClipboardClearAlarm a second time). Importing it for the side effect12// is sufficient. `popup/index.tsx` similarly self-mounts `<App/>` and, on13// native platforms, also calls `setupMessageHandler()` again — harmless,14// since that registration is idempotent (see chrome-shim.ts's dispatch15// comment for why running it twice doesn't invoke `handleMessage` twice).16import "./chrome-shim";17import "../background/entry";18import "../popup/index";1920import { ensureSettingsLoaded, isUnlocked, lock } from "../background/vault";21import { isRecoveryConfirmPending } from "../background/recovery-pending";22import { denyAllPendingPasskeyRequests } from "../background/passkey";23import { nativePlugin } from "../shared/native";2425// Lock-on-close, mobile-shaped (§4.4 point 1): entry.ts's real lock-on-close26// listens for the popup's `chrome.runtime.onConnect` port disconnecting —27// there is no such port here, so peach-android's NativeBridge pushes28// foreground/background over the bridge instead. Same intent (mirrors29// entry.ts's onDisconnect body exactly), native trigger.30nativePlugin<{ onLifecycle(cb: (s: "foreground" | "background") => void): void }>("PeachNative")?.onLifecycle(31 (state) => {32 if (state !== "background") return;33 void (async () => {34 await denyAllPendingPasskeyRequests();35 const settings = await ensureSettingsLoaded();36 if (!isUnlocked() || settings.lockOnClose === false) return;37 if (await isRecoveryConfirmPending()) return;38 lock();39 })();40 }41);