Surfaces (Apps & Shortcuts)
A surface is any UI BOR generates: an app (a full Mac window) or a shortcut (a card inside the bubble). Both are sandboxed iframes that talk to the runtime through a single message bridge. This page covers the shared model; see Apps and Shortcuts for each kind.App vs. shortcut
| App | Shortcut | |
|---|---|---|
| Tool | create_app / update_app | create_shortcut / update_shortcut |
| Where it lives | Its own native Mac window | A live iframe card inside the thought bubble |
| Best for | Multi-screen, long-lived products you return to | Small, conversation-adjacent, stateful interactions |
| Examples | Calorie tracker, CRM, dashboard, journal | Pay button, translator, Pomodoro, weather glance |
| Launch later | App Library, ~/Applications, launch_app | launch_shortcut (re-renders in the bubble) |
Surfaces are not for shipping real software. If you ask BOR to “build a React app I can deploy”, that’s a real project written to .bor/workspaces/, not a surface. BOR is trained to ask when the platform is ambiguous.
The sandbox model
Every surface is a sandboxed iframe with no DOM access outside its frame. All I/O goes throughparent.postMessage → the runtime, validated server-side. Surfaces:
- Cannot read or write your disk directly.
- Cannot make arbitrary network calls except through the bridge.
- Cannot escape the iframe (the validator blocks
eval,Function, external scripts,localStorage,parent.*exceptpostMessage).
Anatomy of a surface
Each surface is a folder under the presence’s data dir:app-… or widget-… (shortcuts use the widget- prefix for historical reasons).
The doc (surface.md)
Every surface has a Markdown doc describing its purpose, features, views, data schema, bridge calls, design notes, and a changelog. This is not decoration — it’s how BOR safely updates a surface later without destroying what exists. Before update_app/update_shortcut, BOR must read the doc.
State persistence
state.json survives across HTML rewrites. When BOR updates a surface, it preserves and migrates user data through the bridge’s getState/setState. So you can ask BOR to “redesign my tracker” without losing your data.
The design gate
Before the first surface create/update in a turn, BOR must callget_ux_ui_strict_guidelines and stop. That tool returns the strict design contract for the active theme (the shortcut-card spec, the app icon kit, the theme handbook). Only after seeing it may BOR generate a surface. This keeps every surface on-brand and Apple-grade. See Themes.
Launching & managing
- App Library (bubble header) — the grid of apps; click to open.
~/Applications— apps are mirrored as.appwrappers, so they’re Finder- and Spotlight-launchable. See Multi-presence.list_surfaces— BOR lists existing surfaces (so it updates instead of cloning).launch_app/launch_shortcut— bring an existing surface forward.delete_app/delete_shortcut/rename_widget— manage them.