Prox OS Internal Docs
PlatformArchitectureApps

App Contract View

The app contract defines how apps are described, launched, permissioned, and hosted inside the OS Shell.

Purpose

The app contract defines how apps are described, launched, permissioned, and hosted inside the OS Shell.

This is the foundation for future local apps, route apps, isolated apps, and community apps.

Initial App Types

Local App

A React component bundled into apps/os-shell.

Use for first-party early apps.

OS Package App

A reusable official app exported from packages/apps/system-apps and imported by apps/os-shell.

Use when an app no longer needs deep access to shell internals but should still run as part of the browser OS bundle.

Iframe App

A local developer tool or external surface hosted in an iframe.

Use for development-only tools such as docs, UI workshop, API explorer, or project graph surfaces before deeper integration exists.

Route App

An app represented by a route or external deployment under the same product domain.

Use for larger apps that deserve independent routing or deployment.

Isolated App Future

An app loaded with stronger isolation boundaries.

Use for community or third-party apps.

Initial Manifest Shape

export type OsAppManifest = {
  id: string
  title: string
  shortTitle: string
  icon: string
  description: string
  category:
    | 'workspace'
    | 'data'
    | 'ops'
    | 'shell'
    | 'system'
    | 'developer'
    | 'ai'
    | 'finance'
    | 'games'
    | 'user'
    | 'productivity'
    | 'media'
    | 'security'
  routeGroup:
    | 'app'
    | 'app-data' // deprecated compatibility alias
    | 'app-track'
    | 'app-connectors'
    | 'app-user'
    | 'app-user-connectors' // deprecated compatibility alias
    | 'app-game'
    | 'app-sports'
    | 'app-shell'
    | 'app-dev'
    | 'app-admin'
    | 'app-iframe'
    | 'app-hub'
    | 'app-os'
  routing: {
    mode:
      | 'local-module'
      | 'iframe'
      | 'external-module'
      | 'web-component'
      | 'remote-route'
      | 'system'
    owner: 'shell' | 'app'
    routeBase: `/${string}`
    defaultPath?: `/${string}`
    supportsDeepLink?: boolean
    preferredUrlMode?: 'path' | 'hash' | 'query' | 'memory'
    externalEntry?: string
    healthPath?: string
    allowedOrigins?: string[]
  }
  runtime:
    | { kind: 'local-module'; module: string }
    | { kind: 'os-package'; packageName: '@prox-os/os-apps'; exportName: string }
    | { kind: 'iframe'; iframeUrl: string; fallbackCommand: string; healthCheckUrl?: string }
    | { kind: 'route-app' }
    | { kind: 'isolated-app'; sourceUrl?: string }
  surfaceCapabilities?: SurfaceCapability[]
  window: DefaultWindow
  permissions: AppPermission[]
}

Responsibilities

packages/contracts/app-contract owns:

  • Manifest types
  • Window contract types
  • Permission names
  • Data scope names
  • Runtime context shape for OS app exports, including narrow window actions and readonly window snapshots
  • App-facing shell settings and keyboard shortcut contracts
  • Optional surfaceCapabilities links to @prox-os/os-surface so manifests can describe where an app can appear without importing shell renderers

apps/os-shell owns:

  • Rendering windows
  • Opening apps
  • Managing active window state
  • Shell-coupled apps that remain under /app-shell
  • Adapting shell-local window store state into the app runtime context
  • Adapting public settings and keyboard contracts to the shell's local state implementation

packages/os-surface owns:

  • Workspace layout mode names
  • Surface kind names
  • Atlas, Grid, Ops, and local-only development engine capability metadata
  • Placement model shapes and v0 capability overrides
  • Helpers for reading surface capability support

packages/apps/*-apps category packages own:

  • Reusable package apps that can be imported by the shell
  • App folders shaped around index.ts, manifest.ts, App.tsx, README.md, optional routes.tsx, components, hooks, api, store.ts, and types.ts

Current package app exports:

  • Package apps export both component and manifest from the owning category package root such as @prox-os/user-apps, @prox-os/game-apps, or @prox-os/os-apps.
  • Each migrated manifest uses runtime.kind: "os-package" and a category-specific sourcePackage.
  • The shell adapts package apps through apps/os-shell/src/apps/registry.ts and apps/os-shell/src/apps/localAppComponents.tsx.
  • Shell-coupled control apps such as Display options and Keyboard shortcuts remain local modules until their contracts are stable enough to extract.

apps/api-worker may later validate:

  • Permissions
  • App installation state
  • Data access scopes
  • AppRuntimeContext.links: optional openLinkChoiceAt(href, x, y) — opens the shell managed-link menu (Open in OS / new tab / copy). Use real <a href> in OS apps when possible; the desktop scene captures left-click on OS-resolvable targets.
  • AppRuntimeContext.session: optional requestSignIn() — opens the existing sign-in overlay (placeholder auth). Used by the Hola welcome app.
  • Platform hosts (packages/runtime/app-registry/src/platformHosts.ts): docs.prox-os.com → docs iframe app, ui.prox-os.com → UI workshop, api.prox-os.com → Scalar API explorer. Dev shells use /app-dev/* routes instead. These hostnames are deployment origins, not app primary keys. For deployment and Access boundaries, see cloudflare-deploy-and-access.md and app-namespace-and-domain-strategy.md.
  • Iframe guests: today use ProxOsIframeGuestLinkMessage (postMessage) to request the same menu; future work is to align guest links with resolveManagedLink rules centrally.

Future identity vs launch targets (roadmap)

Current: shell id / appId in the composed registry is the stable in-OS key. routing.routeBase, iframeUrl, and platform hostnames are launch targets.

Candidate (not final): server-backed registry with owner + slug, public paths such as /@owner/apps/:appSlug, and optional runtime isolation subdomains separate from canonical URLs. Stable appId must survive slug renames (aliases + redirects). Do not use a new second-level subdomain per app by default.

Seed manifest shape and Moments / API / system-app notes: app-namespace-and-domain-strategy.md.

Long-term platform object model

Exploration: app contracts should evolve toward the Prox OS Space platform model without forcing a one-shot redesign.

Conceptual primary objects:

User
Profile
Space
App
Source
Collection
Context
Workflow

Conceptual platform objects:

Manifest
Connector
Capability
Permission
MCP Endpoint
Template

Future app manifests may declare sources, permissions, capabilities, and MCP readiness. A declaration should not mean every app owns its own MCP server. Long-term MCP execution should route through a Prox MCP Gateway that enforces auth, scopes, rate limits, audit logs, and user approval.

This model is documented in prox-os-platform-vision.md. It is not a current database migration, API contract, or required code change.

Routing Boundary

  • Shell navigation: browser URL, route groups, website-mode variants, the historical /spaces/:spaceId fullscreen runtime route, window open/focus/close. Implemented with TanStack Router in apps/os-shell; this is OS-level only and is not the canonical URL model for new Studio resources.
  • App navigation: owned by the app under manifest.routing.routeBase. The Shell Wrapper passes AppRuntimeContext.route (routeBase, appPath, fullPath, optional windowId, search, and hash) plus generic AppRuntimeContext.navigation hints. The contract never exposes a Router type from any library. First-party os-apps may mount their own TanStack Router (often memory-based) when needed. Third-party stacks keep their router behind an adapter; iframe apps are always isolated.

See app-routing.md for the current Local Module App + Shell Wrapper routing contract and future iframe / external module phases.

Design Rule

The OS Shell should not hardcode every app forever.

It should gradually move toward manifest-driven app registration.

App ids should use kebab-case without dots or other punctuation. For example, the Architecture app uses developer-architecture.

On this page