Skip to main content

Apps

An app is a BOR-internal surface that opens as its own native Mac window. It’s the right surface for something multi-screen and long-lived — a tool you’ll return to. Apps are built with create_app and revised with update_app.

When BOR builds an app

BOR builds an app when the result deserves its own window and the user lives inside BOR (not deploying their own project). Triggers:
  • “Make me a calorie tracker / journal / focus app / dashboard / CRM.”
  • “Build me a [something] app” with no framework or deployment target named — though BOR will ask if the platform is genuinely ambiguous (BOR app? web app? desktop? mobile?).
It does not build an app when you ask for real, deployable software (“build a Next.js dashboard I can ship”) — that’s a real project. BOR is trained to keep these apart.

What a good app contains

BOR doesn’t ship a dumb form. For a real domain it researches first (web_search + web_fetch for category expectations), then builds the complete workflow. For example, “build a calorie tracker app” produces:
  • Home with camera/photo meal capture
  • An LLM nutrition estimate from the photo (via the bridge’s askAI)
  • An editable macro breakdown
  • Meal history, goals/commitments, insights
  • Preferences, reminders, and a graceful manual-entry fallback
  • Mobile-style navigation
The AI workflow is the product; manual entry is only the fallback.

How it’s built

  1. Design gate. Before the first surface in a turn, BOR calls get_ux_ui_strict_guidelines and stops. That returns the active theme’s handbook, the icon kit, and the strict spec. See Themes.
  2. Generate. create_app carries the full <html> (the app), a <doc> (its documentation), and a <thumbnail> (the launcher icon). The HTML streams into an editor card in the bubble.
  3. Open. The app opens as a native Mac window you can move, resize, and dock-tab to.
  4. Persist. It’s written to os-data/presences/<id>/surfaces/app-…/ and mirrored as an .app in ~/Applications (Finder/Spotlight launchable).

Living software

Apps are not one-shot. When you ask to improve, expand, redesign, fix, or extend an app:
  1. BOR reads the app’s doc: path first (the executor rejects an update_app that skips this).
  2. It uses update_app with the existing app-… id — not a new create_app.
  3. state.json persists across HTML rewrites, so your data survives a redesign. BOR migrates it through the bridge’s getState/setState.
BOR also scans the existing-surfaces list before creating, so you don’t end up with five overlapping trackers — it updates the close match instead.

The bridge

Apps are sandboxed. Everything real — saving state, calling the AI, searching the web, generating images, launching other apps, scheduling cron, sending notifications — goes through the bridge. BOR copies the bridge helper into every app that needs it. The app never touches your disk or network directly.

Settings & secrets

If an app needs any user-supplied value to work — an API key, an account id, a base URL, a channel id, a timezone — BOR must build a settings screen inside the app where you enter it, plus an in-app guide on how to obtain it. An app that needs setup but ships without that screen is considered broken and won’t be emitted. Keys are stored in the surface’s own state, not hard-coded or pasted into chat.

Tools

ToolPurpose
create_appBuild a new app (<html>, <doc>, <thumbnail>).
update_appRevise an existing app by id (read its doc first).
launch_appOpen/bring forward an existing app.
delete_appRemove an app.
See the Tool reference for exact params, and Shortcuts for the in-bubble alternative.