Summary
Replace FeatureFlags { admin: boolean } with a two-layer RuntimeContext + capability resolution system. This is the foundation that enables assistant-container mode, PWA mode, and the connection-management refactor.
Background
The current features.admin boolean cannot express:
- "Chat + assistant settings but no host management" (assistant-container)
- "Connection management only" (PWA/client-only install)
- "Full host management without Electron IPC" (browser to host-ui)
Every route currently checks if (features.admin) in scattered locations. There is no single source of truth for what the current deploy mode can do.
Design
Full design in docs/technical/ui-runtime-modes-plan.md.
Two-layer model
Server context (computed at request time, public via /api/runtime):
type ServerRuntimeContext = {
version: 2;
hostMode: 'electron-host' | 'host-ui' | 'assistant-container' | 'pwa-static';
serverCapabilities: Capability[];
// ... routes, security, versions
};
Client context (detected in the browser — never server-computed):
type ClientContext = {
displayMode: 'electron' | 'standalone-pwa' | 'browser';
activeConnection?: { kind, id, grantedCapabilities? };
};
Resolved = resolveCapabilities(serverCaps, clientCtx) — one function, one file.
Capability matrix
hostMode |
clientDisplayMode |
Effective capabilities |
electron-host |
electron |
ALL |
host-ui |
browser |
ALL (minus Electron IPC) |
assistant-container |
browser / standalone-pwa |
chat, assistant-settings:read/write |
pwa-static |
standalone-pwa / browser |
connections:manage, connections:switch, chat, pwa:install |
Extension point
activeConnection.grantedCapabilities allows future rules (e.g. "assistant settings when connected to a remote assistant-container") without touching the resolution function structure.
Acceptance criteria
Related
Summary
Replace
FeatureFlags { admin: boolean }with a two-layerRuntimeContext+ capability resolution system. This is the foundation that enablesassistant-containermode, PWA mode, and the connection-management refactor.Background
The current
features.adminboolean cannot express:Every route currently checks
if (features.admin)in scattered locations. There is no single source of truth for what the current deploy mode can do.Design
Full design in
docs/technical/ui-runtime-modes-plan.md.Two-layer model
Server context (computed at request time, public via
/api/runtime):Client context (detected in the browser — never server-computed):
Resolved =
resolveCapabilities(serverCaps, clientCtx)— one function, one file.Capability matrix
hostModeclientDisplayModeelectron-hostelectronhost-uibrowserassistant-containerbrowser/standalone-pwachat,assistant-settings:read/writepwa-staticstandalone-pwa/browserconnections:manage,connections:switch,chat,pwa:installExtension point
activeConnection.grantedCapabilitiesallows future rules (e.g. "assistant settings when connected to a remote assistant-container") without touching the resolution function structure.Acceptance criteria
lib/server/features.ts→computeServerRuntimeContext(event)returningServerRuntimeContextlib/runtime-context.svelte.ts→resolveCapabilities(serverCaps, clientCtx),hasCapability(cap), reactiveruntimeContextstorelib/client-context.ts→detectClientDisplayMode()(client-only, never server-computed)routes/+layout.server.tsreturnsserverRuntimeContextroutes/+layout.svelteinitializesclientContextand deriveseffectiveCapabilitiesroutes/api/runtime/+server.ts— public endpoint, no auth requiredfeatures.adminderived alias preserved so existing code continues to work until migration completesif (features.admin)checks added (all new code useshasCapability())bun run ui:check0 errors 0 warnings; existing tests passRelated
docs/technical/ui-runtime-modes-plan.md— §6.1, §6.2, §6.3, Phase 1