Decouple bundled UI from runtime API and add remote instance tooling (#1228)
Add a packaged-client runtime boundary so the shared UI can talk to local, desktop, remote, and VS Code runtimes through the right transport instead of assuming one same-origin web server. Centralize OpenChamber-owned API access behind RuntimeAPIs, runtimeFetch, and runtime URL helpers, while keeping official OpenCode traffic on the SDK path. Support runtime switching, remote host selection, desktop client credentials, and headless connection links for pairing packaged clients with remote OpenChamber servers. Harden the new auth model by moving long-lived client tokens out of browser URLs, introducing short-lived scoped URL tokens for browser-owned transports, restricting URL-token access to explicit readable/realtime routes, and making client-token management session-scoped or self-scoped as appropriate. Update browser-owned assets and preview proxy flows to work with the split runtime model, including authenticated project icons, preview token propagation, CSP-safe preview bridge injection, and preview proxy auth that survives short-lived URL-token expiry. Tighten Electron security boundaries for packaged clients by gating privileged preload state to trusted origins and requiring explicit confirmation before connect deep-links import or switch remote runtimes. Also refresh agent guidance and project skills so future runtime/API, auth, preview, UI, CLI, settings, locale, and drag-to-reorder work follows the new architecture.
This commit is contained in:
committed by
GitHub
parent
a4314c189b
commit
2031e3b4a8
@@ -1,15 +1,15 @@
|
||||
# OpenChamber - AI Agent Reference (verified)
|
||||
# OpenChamber - AI Agent Reference
|
||||
|
||||
## Core purpose
|
||||
|
||||
OpenChamber provides UI runtimes (web/desktop/VS Code) for interacting with an OpenCode server (local auto-start or remote URL). UI uses HTTP + SSE via `@opencode-ai/sdk`.
|
||||
OpenChamber provides UI runtimes (web/desktop/VS Code) for interacting with an OpenCode server (local auto-start or remote URL). Official OpenCode traffic goes through `@opencode-ai/sdk`; OpenChamber-owned runtime capabilities go through `RuntimeAPIs`, `runtimeFetch`, and browser/realtime URL helpers.
|
||||
|
||||
## Runtime architecture (IMPORTANT)
|
||||
|
||||
- `Desktop` (Electron) boots the web server **in the same Node process** as the Electron main, then loads the web UI from `http://127.0.0.1:<port>`. No sidecar subprocess.
|
||||
- `Desktop` (Tauri, legacy) still spawns `openchamber-server` as a bun-compiled sidecar binary. Kept only for auto-update compatibility with existing Tauri installs.
|
||||
- All backend logic lives in `packages/web/server/*` (and `packages/vscode/*` for the VS Code runtime). The native shell is not a feature backend.
|
||||
- The shell is used only for stable native integrations: menu, dialog (open folder), notifications, updater, deep-links, quit confirmation.
|
||||
- Backend/domain logic lives in `packages/web/server/*` (and `packages/vscode/*` for VS Code bridge/runtime parity). Electron owns the desktop shell/security boundary: windows, menus, dialogs, notifications, updater, deep-links, runtime host switching, local IPC gates, and SSH/tunnel management.
|
||||
- Do not add OpenCode feature backends to the native shell. Shared UI features should remain server/runtime APIs unless the capability is inherently native.
|
||||
|
||||
### Desktop shell: Electron is the target, Tauri is legacy
|
||||
|
||||
@@ -17,15 +17,15 @@ OpenChamber provides UI runtimes (web/desktop/VS Code) for interacting with an O
|
||||
- `packages/desktop/` (Tauri) is kept running in parallel only to preserve auto-update for existing installs until the cutover. Do **not** add features to it; do **not** port bug fixes back unless they actually affect currently-released Tauri users.
|
||||
- Desktop-side changes (IPC handlers, native integrations, window/quit/notification behavior) land in `packages/electron/main.mjs` + `packages/electron/preload.mjs`. The `__TAURI__` shim exposed by the preload keeps the shared UI working against both shells, so renderer-side code should not branch on shell type.
|
||||
- Electron imports the server via `@openchamber/web/server/index.js` (workspace dep) and calls `startWebUiServer({...})`. The returned handle has `getPort()` / `stop()`. Notifications flow via an `onDesktopNotification` callback injected at startup — no stdout-parsing IPC.
|
||||
- Build/release: both shells ship in the same GitHub release today (`.github/workflows/release.yml`). The one-shot Tauri → Electron auto-update migration is documented in `docs/TAURI_TO_ELECTRON_CUTOVER.md`; run that when the user decides to flip.
|
||||
- Build/release: Electron is the release target. The release workflow also repackages the signed Electron app as a Tauri updater payload for the one-shot migration path documented in `docs/TAURI_TO_ELECTRON_CUTOVER.md`.
|
||||
- After the cutover ships and stabilises, `packages/desktop/` is deleted; this note collapses back to "Desktop is Electron".
|
||||
|
||||
## Tech stack (source of truth: `package.json`, resolved: `bun.lock`)
|
||||
|
||||
- Runtime/tooling: Bun (`package.json` `packageManager`), Node >=20 (`package.json` `engines`)
|
||||
- UI: React, TypeScript, Vite, Tailwind v4
|
||||
- State: Zustand (`packages/ui/src/stores/`)
|
||||
- UI primitives: Base UI (`@base-ui/react`, primary source for dropdown/select/dialog/menu/tooltip/etc. — wrappers live in `packages/ui/src/components/ui/`), Radix UI (`package.json` deps, legacy usages being migrated), HeroUI (`package.json` deps), Remixicon (`package.json` deps)
|
||||
- State: Zustand stores and sync layer (`packages/ui/src/stores/`, `packages/ui/src/sync/`)
|
||||
- UI primitives: Base UI (`@base-ui/react`, primary source for dropdown/select/dialog/menu/tooltip/etc. — wrappers live in `packages/ui/src/components/ui/`), Radix UI (`package.json` deps, legacy usages being migrated), HeroUI (`package.json` deps), Remixicon as SVG sprite source only (use shared `Icon`, never direct `@remixicon/react` imports)
|
||||
- Server: Express (`packages/web/server/index.js`)
|
||||
- Desktop (forward): Electron 41 (`packages/electron/`)
|
||||
- Desktop (legacy, maintenance-only): Tauri v2 (`packages/desktop/src-tauri/`)
|
||||
@@ -53,6 +53,18 @@ Web runtime and server implementation for OpenChamber.
|
||||
|
||||
Server-side integration modules used by API routes and runtime services.
|
||||
|
||||
##### event-stream
|
||||
|
||||
OpenChamber-owned event stream helpers for server-sent runtime events.
|
||||
|
||||
- Module docs: `packages/web/server/lib/event-stream/DOCUMENTATION.md`
|
||||
|
||||
##### fs
|
||||
|
||||
Filesystem routes, raw file access, search helpers, and workspace-scoped file operations.
|
||||
|
||||
- Module docs: `packages/web/server/lib/fs/DOCUMENTATION.md`
|
||||
|
||||
##### quota
|
||||
|
||||
Quota provider registry, dispatch, and provider integrations for usage endpoints.
|
||||
@@ -83,6 +95,18 @@ Notification message preparation utilities for system notifications, including t
|
||||
|
||||
- Module docs: `packages/web/server/lib/notifications/DOCUMENTATION.md`
|
||||
|
||||
##### scheduled-tasks
|
||||
|
||||
Scheduled task persistence, execution, and event fanout for recurring sessions.
|
||||
|
||||
- Module docs: `packages/web/server/lib/scheduled-tasks/DOCUMENTATION.md`
|
||||
|
||||
##### text
|
||||
|
||||
Text processing helpers shared by server-side routes and summarization flows.
|
||||
|
||||
- Module docs: `packages/web/server/lib/text/DOCUMENTATION.md`
|
||||
|
||||
##### terminal
|
||||
|
||||
WebSocket protocol utilities for terminal input handling including message normalization, control frame parsing, and rate limiting.
|
||||
@@ -95,12 +119,52 @@ Server-side text-to-speech services and summarization helpers for `/api/tts/*` e
|
||||
|
||||
- Module docs: `packages/web/server/lib/tts/DOCUMENTATION.md`
|
||||
|
||||
##### tunnels
|
||||
|
||||
Tunnel provider setup and runtime helpers for exposing OpenChamber over remote URLs.
|
||||
|
||||
- Module docs: `packages/web/server/lib/tunnels/DOCUMENTATION.md`
|
||||
|
||||
##### ui-auth
|
||||
|
||||
UI session auth, client tokens, URL-token scoping, passkey/reset flows, and route-level auth gates.
|
||||
|
||||
- Module docs: `packages/web/server/lib/ui-auth/DOCUMENTATION.md`
|
||||
|
||||
##### skills-catalog
|
||||
|
||||
Skills catalog management including discovery, installation, and configuration of agent skill packages.
|
||||
|
||||
- Module docs: `packages/web/server/lib/skills-catalog/DOCUMENTATION.md`
|
||||
|
||||
### ui
|
||||
|
||||
Shared React UI, sync layer, runtime API contracts, and stores.
|
||||
|
||||
#### sync
|
||||
|
||||
Session synchronization, event pipeline, optimistic updates, caches, and live-state stores.
|
||||
|
||||
- Module docs: `packages/ui/src/sync/DOCUMENTATION.md`
|
||||
|
||||
#### stores
|
||||
|
||||
Zustand store ownership, persistence expectations, and store-splitting guidance.
|
||||
|
||||
- Module docs: `packages/ui/src/stores/DOCUMENTATION.md`
|
||||
|
||||
#### session sidebar
|
||||
|
||||
Session sidebar grouping, ordering, virtualization-adjacent behavior, and project/worktree display.
|
||||
|
||||
- Module docs: `packages/ui/src/components/session/sidebar/DOCUMENTATION.md`
|
||||
|
||||
#### message parts
|
||||
|
||||
Chat message part rendering and message-row performance expectations.
|
||||
|
||||
- Module docs: `packages/ui/src/components/chat/message/parts/DOCUMENTATION.md`
|
||||
|
||||
## Build / dev commands (verified)
|
||||
|
||||
All scripts are in `package.json`.
|
||||
@@ -126,9 +190,9 @@ All scripts are in `package.json`.
|
||||
## OpenCode integration
|
||||
|
||||
- UI client wrapper: `packages/ui/src/lib/opencode/client.ts` (imports `@opencode-ai/sdk/v2`)
|
||||
- SSE hookup: `packages/ui/src/hooks/useEventStream.ts`
|
||||
- Sync/event pipeline: app roots mount `SyncProvider` from `packages/ui/src/sync/sync-context.tsx`; OpenCode SSE/WS event handling lives in `packages/ui/src/sync/event-pipeline.ts`
|
||||
- Web server embeds/starts OpenCode server: `packages/web/server/index.js` (`createOpencodeServer`)
|
||||
- Web runtime filesystem endpoints: search `packages/web/server/index.js` for `/api/fs/`
|
||||
- Web runtime filesystem endpoints: `packages/web/server/lib/fs/routes.js`, registered by `packages/web/server/lib/opencode/feature-routes-runtime.js`
|
||||
- External server support: Set `OPENCODE_HOST` (full base URL, e.g. `http://hostname:4096`) or `OPENCODE_PORT`, plus `OPENCODE_SKIP_START=true`, to connect to existing OpenCode instance
|
||||
|
||||
## Key UI patterns (reference files)
|
||||
@@ -142,8 +206,10 @@ All scripts are in `package.json`.
|
||||
|
||||
## External / system integrations (active)
|
||||
|
||||
- Git: `packages/ui/src/lib/gitApi.ts`, `packages/web/server/index.js` (`simple-git`)
|
||||
- Terminal PTY: `packages/web/server/index.js` (`bun-pty`/`node-pty`)
|
||||
- Runtime API contracts: `packages/ui/src/lib/api/types.ts`; React consumption via `packages/ui/src/hooks/useRuntimeAPIs.ts`
|
||||
- Runtime transport/auth: `packages/ui/src/lib/runtime-fetch.ts`, `packages/ui/src/lib/runtime-url.ts`, `packages/ui/src/lib/runtime-auth.ts`
|
||||
- Git: `packages/ui/src/lib/gitApi.ts`, `packages/web/server/lib/git/service.js` (`simple-git`)
|
||||
- Terminal PTY: `packages/web/server/lib/terminal/runtime.js` (`bun-pty`/`node-pty`)
|
||||
- Skills catalog: `packages/web/server/lib/skills-catalog/`, UI: `packages/ui/src/components/sections/skills/`
|
||||
|
||||
## Agent constraints
|
||||
@@ -268,29 +334,20 @@ Do not rely on prompts to enforce policy.
|
||||
Detailed Clack UX patterns (primitives, prompt gating, and implementation checklist)
|
||||
are defined in the `clack-cli-patterns` skill and should not be duplicated here.
|
||||
|
||||
## Clack CLI Skill (MANDATORY for terminal CLI work)
|
||||
## Project Skills (MANDATORY)
|
||||
|
||||
When working on terminal CLI commands, prompts, or output formatting, agents **MUST** study the Clack CLI skill first.
|
||||
Project skills live under `.agents/skills/*/SKILL.md`. Before editing, agents **MUST** load every skill whose trigger matches the work; if multiple rows apply, load all of them.
|
||||
|
||||
**Before starting terminal CLI work:**
|
||||
| Work being done | Required skill call |
|
||||
|---|---|
|
||||
| Terminal CLI commands, prompts, or output formatting, especially `packages/web/bin/*` | `skill({ name: "clack-cli-patterns" })` |
|
||||
| Shared UI data access, `RuntimeAPIs`, `runtimeFetch`, `runtime-url`, OpenCode SDK calls, VS Code bridges/proxies, authenticated browser assets, Electron runtime switching, or web server API endpoints | `skill({ name: "ui-api-decoupling" })` |
|
||||
| UI components, styling, visual elements, colors, buttons, or icons | `skill({ name: "theme-system" })` |
|
||||
| User-facing UI text: labels, buttons, placeholders, aria labels, empty/error/loading states, toasts, dialogs, settings copy, or navigation labels | `skill({ name: "locale-ui-patterns" })` |
|
||||
| Settings pages, settings dialogs, configuration UI, or visual/layout changes inside Settings | `skill({ name: "settings-ui-patterns" })` |
|
||||
| Drag-to-reorder, sortable lists/chips/grids, or `@dnd-kit` behavior including touch/mobile and wrapping variable-width items | `skill({ name: "drag-to-reorder" })` |
|
||||
|
||||
```
|
||||
skill({ name: "clack-cli-patterns" })
|
||||
```
|
||||
|
||||
Scope: terminal CLI only (for example `packages/web/bin/*`). Do not apply this requirement to VS Code or web UI work.
|
||||
|
||||
## Theme System (MANDATORY for UI work)
|
||||
|
||||
When working on any UI components, styling, or visual changes, agents **MUST** study the theme system skill first.
|
||||
|
||||
**Before starting any UI work:**
|
||||
|
||||
```
|
||||
skill({ name: "theme-system" })
|
||||
```
|
||||
|
||||
This skill contains all color tokens, semantic logic, decision tree, and usage patterns. All UI colors must use theme tokens - never hardcoded values or Tailwind color classes.
|
||||
Skill docs are the source of truth for detailed patterns. Do not duplicate their full guidance here; load the skill and follow it before making matching changes.
|
||||
|
||||
## Performance rules (MANDATORY)
|
||||
|
||||
@@ -408,4 +465,4 @@ A single store with N properties means every subscriber re-evaluates on every st
|
||||
## Recent changes
|
||||
|
||||
- Releases + high-level changes: `CHANGELOG.md`
|
||||
- Recent commits: `git log --oneline` (latest tags: `v1.4.6`, `v1.4.5`)
|
||||
- Recent commits: `git log --oneline` (latest tags: `v1.11.7`, `v1.11.6`)
|
||||
|
||||
Reference in New Issue
Block a user