parent.postMessage to the runtime, which validates and answers it. BOR copies the bridge helper into every surface that needs state, AI, web, or images.
The bridge lives in shell/surface-bridge.js (classic) and is forwarded by host/surface-preload.cjs when a surface is opened as a native window. Server-side it’s backed by the widget-host / surface endpoints.
The API
A surface calls these on the injected bridge object:State
state.json is the surface’s private store. It survives update_app/update_shortcut, so a redesign keeps user data.
AI
askAI runs server-side through /api/surface-llm using the same provider onboarding set up. This is how a “translator card” streams translations or a calorie app estimates nutrition from a photo. No separate API key is needed — BOR already has the user’s provider configured. Surfaces should never tell the user “you’d need an API key for that” for the built-in bridge call.
Web
Images
Launching
Cron & notifications
Surfaces can schedule work and notify the user through the bridge:- Schedule a cron job (
type: 'cron'). - Push a notification (
type: 'notification-push').
How it’s secured
Every bridge call is apostMessage the runtime receives, validates server-side, and answers. The surface never holds your keys, never touches your disk, and can’t make arbitrary network calls. The validator additionally blocks eval, Function, external <script src>, localStorage, and all parent.* access except parent.postMessage. The iframe sandbox attribute is the first wall; the validator and server-side checks are the rest.
Using it in a surface
BOR pastes the bridge bootstrap into the surface’s HTML, then calls the API like any local function. A minimal pattern:When to wire AI in
BOR is told to wireaskAI (or generateImage) into any surface that’s AI-shaped — a translator, summarizer, classifier, explainer, planner, image lab, extractor, comparison dashboard. If you ask a one-off AI question, BOR answers directly with <say>; if a durable AI workflow helps, it builds a surface around askAI.
Surfaces should also use state like a real app team uses a local store: remember drafts, last-opened routes, preferred cities, recent results, cached data, and active-tab state when it improves the experience.