ui/ToastManager

Summary: ============================================================================ ToastManager - Unified Toast Notification System ============================================================================ ToastManager provides a user-friendly toast notification system for Plauna. It separates UI notifications from debug logging and provides a clean API. TOAST POSITIONS: - top-right: Top-right corner (default) - top-left: Top-left corner - top-center: Top-center - bottom-right: Bottom-right corner - bottom-left: Bottom-left corner - bottom-center: Bottom-center TOAST TYPES: - success: Green checkmark, 3s duration - error: Red X, 5s duration - warning: Yellow warning, 4s duration - info: Blue info, 3s duration - loading: Gray spinner, indefinite (must be manually dismissed) TOAST LIFECYCLE: 1. show(options): Creates toast element and appends to container 2. Animate in: Slide-in animation based on position 3. Display: Shows for duration (or indefinite) 4. Animate out: Slide-out animation 5. Remove: Element removed from DOM TOAST STRUCTURE: - Container: Fixed-position div at specified position - Toast Element: Individual toast with type styling - Icon: Type-specific icon (✓, ✕, ⚠, ℹ, ⟳) - Content: Title and optional description - Close Button: X button to dismiss manually - Progress Bar: Optional countdown indicator AUTO-DISMISS: - maxToasts: Maximum concurrent toasts (default: 5) - defaultDuration: Default display time (default: 4000ms) - Oldest toasts are dismissed when limit is reached - Loading toasts have indefinite duration (duration: 0) ANIMATIONS: - Slide-in/out based on position - Fade effect for smooth transitions - CSS transitions defined in Toast.css CONVENIENCE METHODS: - success(message, options): Show success toast - error(message, options): Show error toast - warning(message, options): Show warning toast - info(message, options): Show info toast - loading(message, options): Show loading toast GLOBAL SINGLETON: - Toast.initialize() creates global singleton - Toast.show() uses global singleton - Used by NotificationSystem and widget gallery USAGE: const manager = new ToastManager({ position: 'top-right' }); manager.success('Operation completed'); manager.error('Failed to save', { duration: 6000 }); // Or use global singleton Toast.initialize(); Toast.show('Hello world', 'info');


ToastManager

Summary: ToastManager - Unified toast notification system. Toast pattern: - Fixed-position container at specified position - Type-specific styling (success, error, warning, info, loading) - Auto-dismiss with configurable duration - Slide-in/out animations based on position - Max concurrent toast limit with FIFO dismissal Lifecycle: 1. show(): Creates toast and appends to container 2. Animate in: Slide-in based on position 3. Display: Shows for duration (or indefinite for loading) 4. Animate out: Slide-out animation 5. Remove: Element removed from DOM


ui/WidgetGallery

Summary: ============================================================================ WidgetGallery - Storybook-Style Widget Showcase ============================================================================ WidgetGallery is a Storybook-like gallery that renders real interactive widget instances from widget.stories() definitions. It's used for development and documentation of Plauna widgets. RENDERING STRATEGY: - Uses widgetRenderer.render() directly to bypass the broken require() in create() - Instantiates widgets with new WidgetClass(id, storyOptions) - Renders each widget to DOM in preview cells - Adds interactive state badges (on/off/animating/sending toast) - Wires click/change/input events to emit toast notifications GALLERY STRUCTURE: - Header: Title and theme selector dropdown - Tabs: Category navigation (Primitive, Input, Form, Layout, Navigation, etc.) - Content Area: Grid of widget story previews - Story Cell: Widget preview + label + state badges STORY PATTERN: Each widget defines static stories() returning named configurations: static stories() { return { 'Story Name': { variant: 'primary', size: 'md' }, 'Another Story': { disabled: true } }; } SPECIAL HANDLING: - Tooltips: Appended to document.body for correct overlay positioning - Toasts: Call show() immediately for visible demos - State Badges: Display on/off/animating/sending-toast indicators - Interactive Events: Click/change/input emit toast notifications DATA ATTRIBUTES: - data-widget: Widget ID (e.g., 'button', 'badge') - data-variant: Story variant name - data-size: Story size name - data-story: Story name TOAST INTEGRATION: - Uses global Toast from ToastManager - Emits toasts on widget interactions for immediate feedback - Toast position defaults to top-right THEME SELECTOR: - Async dropdown in header - Calls shell.setTheme() on change - Refreshes gallery on theme change


WidgetGallery

Summary: WidgetGallery - Interactive widget showcase. Gallery architecture: - Storybook-like interface for widget documentation - Renders real interactive widget instances - Category-based navigation with tabs - Interactive state badges (on/off/animating/sending toast) - Toast integration for immediate feedback


ui/WidgetShowcase

Summary: WidgetShowcase - Display system for widget examples and variants. Architecture: - Renders individual widget examples with state variations - Creates structured showcase sections with title, description, and variants - Supports variant grids, state grids, size grids, and color grids - Uses PlaunaTextService for internationalization - Returns UINode trees for integration with Plauna rendering Showcase structure: - Container: Card-like container with title and description - Variants grid: Auto-fit grid for widget variants - States grid: Grid for different widget states (hover, active, disabled) - Size grid: Grid for different widget sizes - Color grid: Grid for different color variants


WidgetShowcase

Summary: WidgetShowcase - Widget example renderer. Showcase pattern: - Creates structured sections for widget documentation - Renders variants, states, sizes, and colors in grids - Returns UINode trees for Plauna rendering - Supports optional interactive mode


widgets/DataViews/Card

Summary: Card - Flexible content container widget for Plauna Provides header, body, and footer slots with variant system


widgets/DataViews/List

Summary: List - Basic list widget for Plauna Provides list functionality with multiple variants and states


widgets/DataViews/ListView

Summary: ListView - Data display widget for Plauna Provides virtualized list rendering with selection and sorting


widgets/DataViews/Table

Summary: Table - Data table widget for Plauna Provides table functionality with sorting, filtering, and pagination


widgets/DataViews/Tree

Summary: Tree - Hierarchical data display widget for Plauna Provides tree functionality with expand/collapse and navigation


widgets/DataViews/index

Summary: Data Views Widgets Category Data display and visualization widgets


widgets/Feedback/Alert

Summary: Alert - Alert message widget for Plauna Provides alert functionality with multiple variants and dismissible options


widgets/Feedback/EmptyState

Summary: EmptyState - Empty state widget for Plauna Provides empty state functionality with multiple variants and content options


widgets/Feedback/Spinner

Summary: Spinner - Loading spinner widget for Plauna Provides spinner functionality with multiple variants and sizes


widgets/Feedback/Status

Summary: Status - Status indicator widget for Plauna Provides status functionality with multiple variants and sizes


widgets/Feedback/Toast

Summary: Toast - Notification toast widget for Plauna Provides toast functionality with multiple variants and auto-dismiss


widgets/Feedback/index

Summary: Feedback Widgets Category User feedback and notification widgets


widgets/Form/Checkbox

Summary: Checkbox - Multi-select form control widget for Plauna Provides checkbox functionality with multiple states and variants


widgets/Form/Input

Summary: Input - Form input widget for Plauna Provides text input with validation and styling options


widgets/Form/Radio

Summary: Radio - Single-select form control widget for Plauna Provides radio button functionality with multiple states and variants


widgets/Form/Rating

Summary: Rating - Star rating widget for Plauna Provides rating functionality with multiple states and variants


widgets/Form/Select

Summary: Select - Multi-option selection widget for Plauna Provides dropdown functionality with search and keyboard navigation


widgets/Form/Slider

Summary: Slider - Range selection widget for Plauna Provides slider functionality with multiple states and variants


widgets/Form/Switch

Summary: Switch - Binary on/off form control widget for Plauna Provides toggle functionality with multiple states and variants


widgets/Form/Textarea

Summary: Textarea - Multi-line text input widget for Plauna Provides textarea functionality with multiple states and variants


widgets/Form/index

Summary: Form Widgets Category Form elements and validation widgets


widgets/Input/Button

Summary: Button - Interactive button widget for Plauna Provides various button types, states, and accessibility


widgets/Input/Color

Summary: Color - Color picker widget for Plauna Provides color selection with various input formats


widgets/Input/Date

Summary: Date - Date picker widget for Plauna Provides date selection with various formats and validation


widgets/Input/File

Summary: File - File input widget for Plauna Provides file upload functionality with drag-and-drop support


widgets/Input/Input

Summary: Input - Text input widget for Plauna Provides various input types with validation, states, and accessibility


widgets/Input/Number

Summary: Number - Number input widget for Plauna Provides numeric input with validation, controls, and formatting


widgets/Input/Range

Summary: Range - Range slider widget for Plauna Provides range selection with various configurations


widgets/Input/Search

Summary: Search - Search input widget for Plauna Provides search functionality with suggestions and filters


Summary: Search - Search input widget for Plauna Provides search functionality with suggestions and filters Refactored to follow the new WidgetItem pattern while maintaining UINode compatibility


widgets/Input/Tag

Summary: Tag - Tag input widget for Plauna Provides tag management with autocomplete and suggestions


widgets/Input/Time

Summary: Time - Time picker widget for Plauna Provides time selection with various formats and validation


widgets/Input/Upload

Summary: Upload - File upload widget for Plauna Provides advanced file upload with drag-and-drop, progress, and preview


widgets/Input/index

Summary: Input Widgets Category User input and data entry widgets


widgets/Layout/Collapse

Summary: Collapse - Collapsible content widget for Plauna Provides collapsible/expandable content areas with smooth animations


widgets/Layout/Container

Summary: Container - Layout container widget for Plauna Provides flexible container with multiple variants and layouts


widgets/Layout/Divider

Summary: Divider - Visual separation widget for Plauna Provides orientation variants with text label support


widgets/Layout/Grid

Summary: Grid - CSS Grid wrapper widget for Plauna Provides responsive breakpoints and template areas support


widgets/Layout/HeaderFooter

Summary: HeaderFooter - Header and Footer widget for Plauna Provides semantic header and footer containers with comprehensive styling options


widgets/Layout/Panel

Summary: Panel - Content panel widget for Plauna Provides panel containers with various styles and configurations


widgets/Layout/Section

Summary: Section - Content section widget for Plauna Provides semantic section containers with layout and styling options


widgets/Layout/Spacer

Summary: Spacer - Flexible spacing utility widget for Plauna Provides flexible sizing with token integration


widgets/Layout/index

Summary: Layout Widgets Category Layout and container widgets


widgets/Navigation/Breadcrumb

Summary: Breadcrumb - Navigation hierarchy widget for Plauna Provides breadcrumb navigation with customizable separators


widgets/Navigation/Dropdown

Summary: Dropdown - Context menu widget for Plauna Provides dropdown menus with keyboard navigation and accessibility


widgets/Navigation/Menu

Summary: Menu - Navigation menu widget for Plauna Provides menu functionality with multiple variants and states


widgets/Navigation/Navbar

Summary: Navbar - Navigation bar widget for Plauna Provides navbar functionality with multiple variants and layouts


widgets/Navigation/Pagination

Summary: Pagination - Data navigation widget for Plauna Provides page controls with ellipsis and keyboard navigation


widgets/Navigation/Sidebar

Summary: Sidebar - Sidebar navigation widget for Plauna Provides sidebar functionality with multiple variants and states


widgets/Navigation/Stepper

Summary: Stepper - Step indicator widget for Plauna Provides stepper functionality with multiple variants and states


widgets/Navigation/Tabs

Summary: Tabs - Tab navigation widget for Plauna Provides tabbed interface with keyboard navigation and styling


widgets/Navigation/index

Summary: Navigation Widgets Category Navigation and menu widgets


widgets/Primitive/Avatar

Summary: Avatar - User representation widget for Plauna Provides image, icon, and text fallback with status indicators


widgets/Primitive/Badge

Summary: Badge - Status indicator widget for Plauna Provides status indicators, counts, and labels with variants


widgets/Primitive/Button

Summary: Button - Interactive button widget for Plauna Provides clickable button with styling, states, and event handling


widgets/Primitive/Chip

Summary: Chip/Tag - Removable tag widget for Plauna Provides chip functionality with multiple variants and states


widgets/Primitive/Modal

Summary: Modal - Overlay dialog widget for Plauna Provides modal dialogs with focus trapping, accessibility, and backdrop


widgets/Primitive/Panel

Summary: Panel - Basic container widget for Plauna Provides a container for other UI elements with styling and layout options


widgets/Primitive/Progress

Summary: Progress - Task completion indicator widget for Plauna Provides linear and circular progress indicators with multiple states


widgets/Primitive/Skeleton

Summary: Skeleton - Content loading placeholder widget for Plauna Provides loading placeholders with realistic shapes and shimmer animation


widgets/Primitive/Text

Summary: Text - Basic text widget for Plauna Provides text rendering with styling and layout options


widgets/Primitive/Tooltip

Summary: Tooltip - Contextual help widget for Plauna Provides positioning engine with arrow support and accessibility


widgets/WidgetConfig

Summary: Widget Configuration System Manages widget configurations, presets, and user preferences Following the same pattern as the editor's theme system


UnsupportedWidgetConfigVersionError

class UnsupportedWidgetConfigVersionError extends Error


widgetConfigManager

Summary: Singleton export for WidgetConfigManager. Ensures a single instance is used throughout the application: - Consistent configuration state across all components - Single storage persistence point - Centralized event notification system


widgets/WidgetItem

Summary: WidgetItem - Base class for all Plauna widgets. Follows the same pattern as SpawnableItem from the editor: - Static properties for metadata - Static methods for configuration - Registry-based discovery - Category-based organization ```js export class MyWidget extends WidgetItem { static id = 'my-widget'; static name = 'My Widget'; static icon = '🔧'; static category = 'custom'; static description = 'A custom widget for specific use case'; static create(container, options = {}) { return new MyWidget(container, options); } } ```


widgets/WidgetRenderer

Summary: ============================================================================ WidgetRenderer - UINode to DOM Converter ============================================================================ WidgetRenderer is the bridge between Plauna's retained UINode tree and the actual browser DOM. It converts UINode instances into DOM elements recursively. RENDERING PIPELINE: 1. render(node) - Entry point, converts UINode tree to DOM tree 2. createDOMElement(node) - Creates appropriate DOM element for UINode type 3. Applies styles, classes, IDs, text content, and attributes 4. Recursively renders children and appends to parent 5. Returns root DOM element ready for insertion into document MAPPING TABLES: - nodeToDOM: Map<UINode, HTMLElement> - UINode → DOM element - domToNode: Map<HTMLElement, UINode> - DOM element → UINode (reverse lookup) ELEMENT TYPE MAPPING: - SVG elements: svg, circle, path, etc. → created with createElementNS - Text nodes: type='text' → rendered as <span> - Form elements: button, input, textarea, select, label, form, img → native elements - HTML elements: h1-h6, p, div, header, footer, nav, etc. → native elements - Unknown types: fallback to <div> SPECIAL HANDLING: - Raw HTMLElements: If node is already an HTMLElement, return it directly - Pre-existing DOM: If node.element exists (created by widget), use it - Back-reference: Sets element._plaunaNode for reverse lookup (used by SmartContextMenu) STYLE APPLICATION: 1. node.style: Direct inline styles (highest priority) 2. node.computedStyle: Computed styles from layout engine 3. node.className: CSS class names 4. node.id: Element ID TEXT CONTENT: - node.textContent: Plain text content - node.innerHTML: HTML string content - If node has children, text content is ignored


widgets/WidgetStyleManager

Summary: WidgetStyleManager - Widget-specific styling system Provides theme-based styling utilities for widgets and UI components


WidgetStyleManager

Summary: WidgetStyleManager - Theme-aware widget styling system. Architecture pattern: - Singleton pattern for consistent styling across the application - Style caching for performance (memoization by widgetType:variant:theme) - Theme integration with ThemeManager for dynamic theme switching - Observer pattern for reactive style updates on theme changes - Base token fallback for graceful degradation Features: - Generates CSS styles based on theme tokens - Supports multiple widget types (modal, tooltip, dropdown, etc.) - Automatic cache invalidation on theme changes - Token-based styling for consistency


widgetStyleManager

Summary: Singleton export for WidgetStyleManager. Ensures a single instance is used throughout the application: - Consistent style caching across all components - Single theme subscription point - Centralized style generation


widgets/index

Summary: ============================================================================ PLAUNA WIDGET REGISTRY ============================================================================ This file serves as the central registry for all Plauna widgets. It imports widgets from their category folders and provides: 1. widgets array - Flat array of all widget classes 2. widgetRegistry - Map of widget.id → widget class for O(1) lookup 3. categories - Map of category name → array of widgets in that category 4. Helper functions for querying and filtering widgets WIDGET CATEGORIES: - Primitive: Basic building blocks (Button, Badge, Avatar, Chip, etc.) - Input: Form input controls (Search, Color, Date, File, etc.) - Form: Form elements (Checkbox, Radio, Switch, Select, etc.) - Layout: Layout containers (Card, Grid, Panel, Divider, etc.) - Navigation: Navigation components (Menu, Tabs, Sidebar, etc.) - DataViews: Data presentation (List, Table, Tree, etc.) - Feedback: User feedback (Alert, Toast, Spinner, etc.) WIDGET PATTERN: Each widget class MUST have: - static id: Unique string identifier (e.g., 'button') - static name: Display name (e.g., 'Button') - static category: Category name (e.g., 'primitive') - static icon: Emoji or icon for UI display - static description: Short description of widget purpose - static tags: Array of searchable tags - static dependencies: Array of required widget IDs - static getDefaultOptions(): Returns default configuration object - static stories(): Returns named story configurations for showcase - constructor(id, options): Initializes widget instance IMPORTANT: - Do NOT use widget.create() - it has require() that breaks in ESM - Instead, instantiate directly: new WidgetClass(id, options) - Use widgetRegistry.get(id) to find widget class by ID


createWidget

createWidget(widgetId, container, options = {})


createWidgetWithTheme

createWidgetWithTheme(widgetId, container, theme, options = {})


workspace/Panel

Summary: Panel.js — Base panel and two concrete flavours: DOMPanel  — a positioned <div> container for Plauna widgets / HTML content GPUPanel  — owns a GPUTexture render target; blitted to canvas by WorkspaceCompositor Lifecycle:  create → mount(container) → [resize / focus / show / hide] → destroy()


Panel

Summary: Panel - Base class for workspace panels. Architecture pattern: - Abstract base class for DOMPanel and GPUPanel - Lifecycle: create → mount → [resize/focus/show/hide] → destroy - Observer pattern for event emission (move, resize, visibility, focus, blur) - Position/size constraints with min-size enforcement - Z-index management for panel stacking Panel types: - DOMPanel: Renders Plauna widgets in DOM elements - GPUPanel: Renders to WebGPU textures, composited by WorkspaceCompositor


workspace/PanelLayout

Summary: PanelLayout.js — Layout engine for arranging panels in a workspace. Modes: fullscreen — one panel fills the entire workspace float      — panels are free-position windows (drag/resize) split      — tmux/VS Code-style binary split tree (horizontal | vertical) tile       — auto-arranged fixed grid


LayoutEngine

Summary: LayoutEngine - Panel layout orchestration. Layout modes: - fullscreen: First visible panel fills entire workspace - float: Panels are free-position windows with drag/resize - split: Binary tree layout (like tmux/VS Code) with recursive splits - tile: Auto-arranged grid layout Architecture: - Mode-based layout dispatch (apply() switches between modes) - Split tree cached for efficiency (reused if panels unchanged) - Z-index management for float mode (focused panel on top) - Observer pattern for mode change notifications


workspace/Workspace

Summary: Workspace.js — Virtual desktop for panels. Architecture: - Virtual desktop that holds an ordered list of panels - DOM layer that sits over WebGPU canvas - LayoutEngine for panel arrangement (fullscreen/float/split/tile) - WorkspaceManager handles switching between workspaces via CSS transitions Lifecycle: - mount(container): Creates DOM layer and mounts panels - activate(): Shows workspace (opacity 1, pointer-events auto) - deactivate(): Hides workspace (opacity 0, pointer-events none) - CSS transitions for smooth workspace switching Panel management: - addPanel(): Adds panel to workspace and mounts it - removePanel(): Removes panel from workspace - Layout applied automatically on mount and resize


Workspace

Summary: Workspace - Virtual desktop container. Virtual desktop pattern: - Each workspace is a separate DOM layer - Workspaces are stacked with CSS z-index - Only one workspace active/visible at a time - CSS opacity transitions for smooth switching - Panels are mounted into workspace DOM layer


workspace/WorkspaceCompositor

Summary: WorkspaceCompositor.js — WebGPU blit pipeline for GPU panels. Architecture: - Each GPUPanel owns a GPUTexture render target - Compositor blits all visible GPU panels onto canvas swap chain each frame - DOM panels are rendered directly by browser (compositor only handles WebGPU) - Simple blit shader: just copies texture to canvas Pipeline components: - Sampler: Linear filtering for panel textures - Bind group layout: Single texture binding (binding 0) - Shader: Simple vertex + fragment shader for texture copy - Blend state: Alpha blending for layered panels Render loop: - Called by WorkspaceManager each frame - Iterates visible GPU panels in z-order - Creates bind group per panel - Issues draw call (6 vertices for quad)


WorkspaceCompositor

Summary: WorkspaceCompositor - WebGPU texture compositor. Compositor pattern: - Blits GPU panel textures to canvas swap chain - Handles only WebGPU panels (DOM panels rendered by browser) - Simple texture copy pipeline (no post-processing) - Alpha blending for layered panel support


workspace/WorkspaceManager

Summary: ============================================================================ WorkspaceManager - Virtual Desktop Management ============================================================================ WorkspaceManager provides a virtual desktop system for Plauna, allowing multiple workspaces with different layouts and panel configurations. WORKSPACE CONCEPT: - A Workspace is a virtual desktop that holds panels - Each workspace can have its own layout mode (fullscreen, float, split, tile) - Workspaces are DOM layers stacked over the canvas - Only one workspace is active/visible at a time PANEL TYPES: - DOMPanel: Wrapper for Plauna widgets (div-based) - GPUPanel: WebGPU texture panel (for GPU-accelerated content) LAYOUT MODES: - fullscreen: One panel fills the entire workspace - float: Draggable, resizable windows with z-order - split: Recursive binary tree layout (like tmux/VS Code) - tile: Auto-arranged grid layout COMPOSITOR: - WorkspaceCompositor blits GPU panel textures to canvas swap chain - Iterates visible GPU panels in z-order - Required for GPU panel support SWITCHER: - WorkspaceSwitcher provides HUD overlay (Ctrl+`) - Shows thumbnails of all workspaces - Keyboard navigation with arrow keys - Enter to switch workspace SINGLE CONSTRAINT: - Only one WebGPU canvas context allowed per page - Only one GPUDevice instance shared across all workspaces - GPU panels share the same device and canvas PUBLIC API: - createWorkspace({ name, layout }): Create new workspace - switchTo(id): Switch active workspace - createPanel(type, options): Create panel in active workspace - list(): List all workspaces - activeWorkspace: Get currently active workspace INITIALIZATION: - Requires: container (DOM element), device (WebGPU), canvas - Optional: format (texture format), logger - Must call initialize() before using KEYBOARD SHORTCUTS: - Ctrl+`: Open workspace switcher - Arrow keys: Navigate switcher - Enter: Switch to selected workspace - Escape: Close switcher USAGE: const manager = new WorkspaceManager({ container: document.body, device: gpuDevice, canvas: canvasElement, format: 'bgra8unorm' }); await manager.initialize(); const ws = manager.createWorkspace({ name: 'Main', layout: 'float' }); manager.switchTo(ws.id); manager.createPanel('dom', { title: 'Panel 1' });


workspace/WorkspaceSwitcher

Summary: WorkspaceSwitcher.js — HUD overlay for workspace switching. Architecture: - Triggered by Ctrl+` (managed by WorkspaceManager) - Shows thumbnails of all workspaces in grid layout - Keyboard navigation with arrow keys - Enter to switch to selected workspace - Escape to close switcher UI pattern: - Full-screen overlay with backdrop blur - Centered card with workspace thumbnails - Highlighted selection indicator - CSS transitions for smooth show/hide Keyboard handling: - Arrow keys: Navigate between workspaces - Enter: Switch to selected workspace - Escape: Close switcher without switching


WorkspaceSwitcher

Summary: WorkspaceSwitcher - HUD overlay for workspace navigation. HUD pattern: - Full-screen overlay with backdrop blur - Grid layout of workspace thumbnails - Keyboard navigation support - Smooth CSS transitions for show/hide


workspace/index

Summary: plauna/workspace — Virtual desktop / multi-panel system for Plauna. Exported classes: - Panel, DOMPanel, GPUPanel - Workspace - WorkspaceManager - WorkspaceCompositor - WorkspaceSwitcher - LayoutEngine, LayoutMode


browser-bridge/BrowserBridgeClient

Summary: Singleton — shared by all syscall consumers.


validateBridgeArgs

validateBridgeArgs(args, service = '', method = '')


browser-bridge/BrowserBridgeDriver

Summary: BrowserBridgeDriver.js — kernel-level wrapper around BrowserBridgeClient. Held at kernel.browserBridge. Manages availability probing on boot, event relay to the kernel event bus, and exposes the full typed client for syscalls.


browser-extension/adblock-content

Summary: adblock-content.js — in-frame cosmetic ad filtering (Layer 2). Runs in the DEFAULT (ISOLATED) world, in ALL frames, at document_start. ISOLATED world is required so chrome.runtime / chrome.storage are available (the MAIN-world content.js cannot reach them). Cosmetic hiding and DOM node removal only need access to the SHARED DOM, which the isolated world has. Responsibilities: - Inject cosmetic CSS hiding known ad containers. - Watch the DOM and remove ad/tracker <iframe>/<script>/<img> nodes whose src targets a blocked domain (defence-in-depth alongside the DNR rule). - Report removals to the background counter. Strictly scoped: only activates inside frames that belong to the WebGPU OS browser (top page is an OS host, or the outermost ancestor is an OS host), and only while ad-blocking is enabled. Stays completely inert during the user's normal browsing.


browser-extension/adblock-list

Summary: adblock-list.js — shared ad/tracker blocklist for the WebGPU OS browser. SINGLE SOURCE OF TRUTH, consumed by three enforcement layers: 1. background.js        → declarativeNetRequest BLOCK rules (network layer, scoped to OS tabs only — never the user's normal browsing) 2. adblock-content.js   → cosmetic hiding + DOM ad-node removal inside OS-embedded frames 3. _extProxyFetch       → ad-tag stripping for proxied (srcdoc) pages Ported and expanded from the Playwright stealth blocker (C:\Coding\fail\server\tools\stealth.py — ADBLOCK_DOMAINS / ADBLOCK_URL_KEYWORDS). This is an ES module: background.js imports it directly; the content script loads it via dynamic import(chrome.runtime.getURL('adblock-list.js')), which is why it is also listed under web_accessible_resources in the manifest. The hand-curated CORE list below is augmented at runtime by an optional, build-generated list (adblock-domains.generated.js) produced from EasyList / EasyPrivacy via build_adblock_rules.py. The generated file ships empty until you run that script, so the extension always loads.


hostnameOf

Summary: Lowercased hostname from a URL, or '' if unparseable.


isAdDomain

Summary: True if the URL targets a known ad/tracker domain (or a subdomain of one).


looksLikeAd

Summary: Broader match incl. keyword patterns — for the cosmetic/proxy layers only.


cosmeticCss

Summary: A single <style> string that hides all cosmetic selectors.


browser-extension/ai-settings


browser-extension/background

Summary: background.js — WebGPU OS Frame Unblocker + Browser Bridge service worker. Static rules (rules.json) are the primary mechanism. Dynamic rules (updateDynamicRules) are registered as a fallback on every startup in case Chrome silently rejected the static ruleset. Browser Bridge: handles __os_bridge_request__ messages routed from relay.js, delegating to the four service modules (Tabs, Injection, Navigation, Rules).


browser-extension/content

Summary: content.js — runs in the page's MAIN world at document_start. 1. Sets window.__frameUnblockerActive so the OS browser app can detect the extension. 2. In sub-frames (iframes): overrides window.top / window.parent / window.frameElement so frame-busting scripts (e.g. DuckDuckGo: "if (top !== self) top.location = ...") think they are the top-level page and do not navigate away. Must run in world: "MAIN" and all_frames: true to take effect before site JS.


browser-extension/offscreen


browser-extension/options


browser-extension/popup


browser-extension/popup-ai


mountSecureProviderList

mountSecureProviderList({ root, summary, manageButton, refreshButton, send = runtimeMessageSender, onChange = ()


browser-extension/popup-size


browser-extension/relay

Summary: relay.js — runs in the ISOLATED content script world (default). chrome.runtime IS available here (unlike world: "MAIN"). Acts as a bridge between the OS page (MAIN world) and the extension background. Two-way channels: 1. Proxy fetch (legacy): page →__os_proxy_request__→ relay → background → __os_proxy_response__→ page 2. Browser Bridge requests: page →__os_bridge_request__→ relay → background → __os_bridge_response__→ page 3. Push events from background (nav/tab changes): background →sendMessage→ relay →__os_bridge_event__→ page


browser-extension/services/AIProviderCatalog

Summary: Shared provider metadata and OpenAI-compatible endpoint normalization. Keep this module free of chrome.* calls so the service worker and tests can use the exact same routing and capability rules.


resolveProviderDataPolicy

resolveProviderDataPolicy(providerId, route = {}, { authority = 'catalog' } = {})


resolveModelAccess

resolveModelAccess(providerId, model = {}, { authority = 'catalog' } = {})


detectProvider

detectProvider({ key = '', endpoint = '' } = {})


planCredentialStorage

Summary: Decide whether an entered credential can be stored for the explicitly selected provider. Prefix detection is advisory only; it must never move a secret to another provider slot behind the user's back.


normalizeEndpoint

normalizeEndpoint(value, { defaultBase = '' } = {})


endpointFor

endpointFor(providerId, customBase = '')


inferModelTaskAffinities

inferModelTaskAffinities(providerId, model = {})

Summary: Infer preference-only task affinities from bounded catalog evidence. These hints may improve ranking, but must never authorize tools, strict output, private disclosure, or any other compatibility or security decision.


inferModelCapabilities

inferModelCapabilities(providerId, model = {})


normalizeReasoningControl

normalizeReasoningControl(model = {}, modelId = '')

Summary: Preserve the endpoint's own reasoning control surface. A single `reasoning` boolean cannot answer the questions a caller has to ask before touching reasoning: whether the endpoint rejects a disable (`mandatory`), whether it reasons unless told otherwise (`defaultEnabled`), and which gateway knobs are real for it. OpenRouter reports effort levels and token budgets per model, and both are honoured for only a few families, so a caller that guesses either sends a parameter that silently does nothing or one that fails the request. `softSwitch` is inferred from the model family because it is a training-time prompt convention that no catalog reports.


normalizeSupportedParameters

Summary: Preserve exact provider compatibility evidence in one deterministic shape. Some provider APIs use supported_parameters while saved OS routes use supportedParameters, so merge both aliases instead of allowing one to hide the other. Values are bounded before they can enter extension storage.


browser-extension/services/AIProviderService

Summary: AIProviderService.js — remote LLM provider bridge for the OS AI Hub. Runs in the extension background service worker context (privileged fetch, no CORS; host_permissions already grant <all_urls> for this extension, so no additional host_permissions are needed for the built-in providers). The OS page NEVER sees provider URLs, headers, or API keys — it only sends {provider, model, messages, params} and gets back {message, usage}. Keys are read via KeyVaultService.getRawKeyInternal(), which is not reachable through the bridge router (see KeyVaultService.js for why). Allowlists: - providerAllowlist/pathAllowlist: AIProviderCatalog is the only set of provider ids + exact endpoint URLs ever fetched for non-custom requests. - originAllowlist (custom provider): CUSTOM_ENDPOINTS is a user-approved https-only allowlist, persisted in chrome.storage.local, populated only via allowCustomEndpoint().


browser-extension/services/AudioService

Summary: AudioService.js — privileged tab-audio bridge for WebGPU OS. Browser page audio inside the OS tab (YouTube, video sites, embedded frames) does not pass through the OS AudioDriver. Chrome extensions can control that audio by capturing the tab stream, replaying it through an offscreen AudioContext, and applying a GainNode. The OS mixer sends the effective gain here; the service worker owns tabCapture permission and the offscreen document owns Web Audio playback.


browser-extension/services/BridgeSessionPolicy

Summary: Memory-only session boundary between the isolated relay and background worker. Secrets never cross window.postMessage. A service-worker restart invalidates every session and forces the still-isolated relay to open a fresh one.


browser-extension/services/CorsService

Summary: CorsService.js — per-site opt-in CORS/API unblocking for the OS bridge. Runs in the extension background service worker context. The blanket rule 9005 only injects `Access-Control-Allow-Origin: *` on NON-credentialed static assets (scripts/fonts/etc.), deliberately leaving a framed site's own credentialed `fetch`/XHR/API calls untouched — a wildcard ACAO is illegal for credentialed requests and would break logins. This service lets the user OPT IN, per trusted site, to also unblock those credentialed API calls. For each enabled origin O (host H) we add session rules (tab-scoped to OS tabs) that, for requests INITIATED BY that site's frames (initiatorDomains: [H]), set on the response: Access-Control-Allow-Origin:      O        (echoes the page origin, not *) Access-Control-Allow-Credentials: true Access-Control-Allow-Methods:     GET,POST,PUT,PATCH,DELETE,OPTIONS Access-Control-Allow-Headers:     * Scoping by initiatorDomains keeps this correct with multiple sites open and never affects the user's normal browsing (session rules are tab-scoped).


browser-extension/services/ExtensionSenderPolicy

Summary: Authenticate privileged runtime messages from this extension's own pages. Extension pages opened in a popup window can have sender.tab; content scripts also have sender.tab, so ownership must be decided from the sender URL/origin rather than from tab presence alone.


browser-extension/services/InjectionService


browser-extension/services/KeyVaultService

Summary: KeyVaultService.js — provider API key storage for the AI Bridge. Runs in the extension background service worker context. Keys are NEVER exposed to the OS page/bridge caller — only status booleans cross the bridge. getRawKeyInternal() remains a module-only worker export. V2 binds provider and generation into AES-GCM additional authenticated data. V1 encrypted envelopes and bounded legacy plaintext remain read-only inputs and migrate on first use. A durable generation tombstone prevents an older persistent credential from reappearing after a session-only switch or an interrupted clear.


KeyVaultContractError

class KeyVaultContractError extends Error


normalizeKeyVaultEnvelope

normalizeKeyVaultEnvelope(provider, raw, { persisted = false, label = 'AI key record' } = {})


normalizeKeyVaultState

normalizeKeyVaultState(provider, raw, label = 'AI key state')


getRawKeyInternal

Summary: Internal-only accessor; deliberately absent from KeyVaultService dispatch.


KeyVaultService

Summary: Page/bridge-facing surface — status only, never the raw key.


browser-extension/services/LivePatchRuntime

Summary: Clean-room declarative browser surface editor. This module deliberately accepts data, never JavaScript source. The exported page function is self-contained so chrome.scripting can serialize it into the extension's ISOLATED world without eval, Function, or page-owned callbacks.


normalizeBrowserLivePatch

Summary: Validate and reduce a kernel patch before it crosses the 64 KiB bridge.


runBrowserLivePatch

runBrowserLivePatch(command, payload = {})

Summary: Self-contained function executed by chrome.scripting in the ISOLATED world. Do not introduce references to module-scope bindings here.


browser-extension/services/NaviFacultyStatusService

Summary: Memory-only projection of kernel-owned Browser Semantic Faculty readiness. The Companion does not sign, verify, install, enable, or approve Faculties. It accepts a content-free status only through an authenticated OS bridge session so extension-owned UI can show which exact kernel package revision the OS reports as verified. A service-worker restart or bridge revocation clears the projection.


browser-extension/services/NavigationService

Summary: NavigationService.js — webNavigation history + OS push events. Runs in the extension background service worker context. The background registers webNavigation listeners that call NavigationService.addEvent(). The OS can poll history() or receive live push events via the __os_bridge_event__ channel.


browser-extension/services/OpenRouterAuthService

Summary: OpenRouterAuthService.js — extension-owned OAuth PKCE sign-in. The authorization code and generated API key never cross the page bridge. Only the extension credential window can start this flow, and the resulting key is immediately encrypted through KeyVaultService.


browser-extension/services/ProviderProtocol

Summary: Pure OpenAI-compatible request/response helpers shared by the privileged extension transport and the browser-direct mobile fallback. This module performs no storage, network, DOM, or chrome.* work.


providerErrorNumber

Summary: Stable public diagnosis family; never contains provider-controlled text.


applyProviderErrorContext

applyProviderErrorContext(error, context = {})

Summary: Attach only bounded, structured-clone-safe diagnostic correlation fields.


providerResponseModel

providerResponseModel(value, fallback = '')

Summary: Normalize a provider model identifier without trusting arbitrary text.


providerModelAttribution

providerModelAttribution({ provider = '', requestedModel = '', responseModel = '' } = {})

Summary: Keep the requested route separate from provider-reported attribution. `model` remains backward-compatible, but modelEvidence makes an omitted or dynamic alias explicitly non-concrete so callers cannot mistake a request fallback for observed provider output.


normalizeProviderTools

Summary: Normalize the provider-facing projection of locally authoritative OS tools. These definitions help a model form typed calls; they never grant execution authority, which remains with the descriptor hash, graph validator, and ToolRouter after the provider response returns.


canonicalProviderToolCalls

canonicalProviderToolCalls(payload, providerTools = [], transport = 'provider-native')

Summary: Convert completed native provider calls into one provider-neutral batch.


createProviderToolStreamAccumulator

createProviderToolStreamAccumulator(providerTools = [], transport = 'provider-native-stream')

Summary: Accumulate provider tool-call stream fragments without executing partial arguments. ID/name conflicts and malformed mixed batches fail atomically.


buildOpenAICompatibleBody

buildOpenAICompatibleBody(spec, providerDefinition = null)


providerHttpError

providerHttpError(json, status, provider = '', responseMetadata = null)

Summary: Construct the only provider-originated Error shape allowed to cross the AI bridge. Endpoint URLs, headers, response bodies, request content, and keys are deliberately excluded. Retryability is asserted only for unambiguous transient HTTP classes; every other status remains unclassified so the Navi broker can apply its own fail-closed policy.


providerOutputError

providerOutputError(code, provider, message, retryable = true, responseMetadata = null)


providerChoiceError

providerChoiceError(json, status, provider = '', responseMetadata = null)


assertUsableProviderOutput

assertUsableProviderOutput({ message = '', reasoning = '', toolCalls = [], provider = '', strictOutput = false } = {})


providerFailureProjection

Summary: Return a bounded structured-clone-safe view of an AI provider failure.


browser-extension/services/ResidentService

Summary: ResidentService.js — manages the resident SecureMesh node (offscreen document). Exposed via the bridge router (service name `resident`) so the trusted OS page can query/toggle it, and via dedicated messages for the popup. Keeps an offscreen document alive (MV3's persistent WebRTC-capable context) using a chrome.alarms keep-alive that respawns the service worker to re-ensure the doc exists. Privacy: this only ever stores the PUBLIC cert bundle the OS page pushes (pub key, name, room) — never the identity private key. It is OFF by default and fully user-controlled. Real background mesh reachability is NOT attempted here (keep an OS tab open for that); this is a lightweight cert vault + keepalive responder.


browser-extension/services/RuleService

Summary: RuleService.js — declarativeNetRequest dynamic rule manager for the OS bridge. Runs in the extension background service worker context. User-added rules use IDs >= 50000 to avoid colliding with the built-in frame-unblock rules (IDs 100-102).


browser-extension/services/SemanticAutomationRuntime

Summary: Validate and compact one AI Echo browser-semantic request before it crosses the extension boundary. Unknown fields fail closed so the protocol cannot silently grow into a generic page-execution channel.


runBrowserSemanticAction

Summary: Packaged Chrome scripting entry point. This function is intentionally self-contained because chrome.scripting serializes the function body into the target tab; it cannot close over extension service-worker state.


browser-extension/services/TabService

Summary: TabService.js — chrome.tabs wrapper for the OS bridge. Runs in the extension background service worker context.


browser-extension/services/TrustedOsOriginPolicy

Summary: Exact OS origins trusted with privileged browser bridge authority.


browser-extension/services/WebMCPBridgeRuntime

Summary: WebMCPBridgeRuntime.js - clean-room, versioned adapter between AI Echo and the browser's evolving WebMCP surface. Page-owned metadata and results are always untrusted. The extension never exposes callbacks, Window objects, or credentials across the OS bridge.


normalizeBrowserWebMCPRequest

Summary: Validate one bridge request before any page script is dispatched.


runBrowserWebMCPAction

Summary: Packaged Chrome scripting entry point. It deliberately feature-detects the origin-trial API, because WebMCP is still a Community Group draft and the browser execution helper is not yet part of the portable specification.


drivers/AudioDriver

Summary: AudioDriver.js — the OS audio server (kernel service). Provides system-wide audio output routing, a per-app volume mixer, output-device switching, OS-level media transport (navigator.mediaSession), and opt-in spatial (window-position) panning. Mirrors the kernel-service pattern of AmbientEngine / ThemeEngine: created in KernelBootstrap, exposed via createAudioSyscalls() in Syscalls.js, guarded per-app in guardSyscalls(). ── Two routing models ────────────────────────────────────────────────────────── 1. Shared-context routing (true central mix): apps hand the driver an <audio>/<video> element (attachElement) or an AudioNode built in the OS context (context() + attachNode). The driver builds: source → sessionGain → analyser → stereoPanner → masterGain → destination(setSinkId) 2. Cooperative sessions: apps that keep their own AudioContext register with an onVolume(effective, muted) / onPan(pan) callback. The driver cannot touch their nodes, so it calls the callback whenever the user changes master/app volume, mute, or pan, and the app applies it to its own graph. Everything no-ops safely before the first user gesture (autoplay policy) and on browsers without setSinkId / mediaSession. ── Events ────────────────────────────────────────────────────────────────────── kernel.events.emit('os:audio-change', { type })   // 'sessions' | 'master' | 'devices' | 'spatial'


drivers/CryptoDriver

Summary: CryptoDriver.js — OS-level cryptographic identity driver. Wraps CollabIdentity (ECDSA P-256) and exposes a simple API: - Persistent key pair stored in IndexedDB (survives page reload) - Same fingerprint = same user across sessions - sign(data)                  → ECDSA signature bytes - verify(pubKeyRaw, data, sig) → boolean - publicKeyRaw / fingerprint   → identity Used by: - kernel/Syscalls.js  → syscalls.crypto.* - chat room           → signed messages (tamper-evident + authenticated) - future game systems → anti-cheat signed receipts, session proofs


drivers/EmbeddedParticleNode

Summary: One embedded Particle node per browser profile. Resident availability and temporary supernode/witness roles are facets of this same node identity.


drivers/NetDriver

Summary: NetDriver.js — Phase 5 network driver for WebGPU OS. Tiered transport (fastest-wins): Tier 1 — BroadcastChannel (same-origin tabs, <1ms, always available) Tier 2 — WebRTC full-mesh via CollabCore + pinned Particle V2 signaling (cross-machine). BitTorrent remains an explicit, off-by-default hard fallback. Public API (mirrored by kernel/Syscalls.js net namespace): connect(roomId, opts)          — join a named room disconnect()                   — leave current room send(channel, data)            — broadcast to all peers sendTo(peerId, channel, data)  — unicast to specific peer on(channel, cb)                — subscribe to incoming channel messages off(channel, cb)               — unsubscribe peers()                        — list connected peers { id, transport } isConnected()                  — true if at least one peer stats()                        — transport statistics selfId                         — this peer's UUID


drivers/NetworkDriver

Summary: drivers/NetworkDriver.js — kernel driver backing `syscalls.network.*` / `syscalls.sync.*` / `syscalls.workstation.*` (network plan Phase 6 webgpu-os wiring, previously deferred — see C:\Users\btspa\.windsurf\plans\particle-network-layer-2bf6f0.md). Thin glue only: delegates to engine/network's already-complete client-side modules (identity, routes/MasterServerList, the shared pinned ParticleNetworkDaemon, syncManager, workstation) and reads/writes the SAME localStorage-backed config `factory/apps/network-manager/NetworkManagerApp.js` already uses (`os.network.masterServers` / `os.network.syncRules`), so any app calling these syscalls sees the exact same state the Control Panel shows — one source of truth, not a second copy. Security model (see kernel/RuleGraph.js): `network.read`/`sync.read` are low-risk status/config visibility; `network.connect` actually opens a Masterserver session and can attach/signal on routes (declaration-gated, high risk); `sync.manage` changes what syncs where (medium risk). Every live-session method requires `connect()` to have been called first for that url — apps cannot attach/signal/discover on a session they never opened, even though the underlying WebSocket may be SHARED with other OS features via the V2 daemon registry (or the V1 registry only for explicit compatibility endpoints).


drivers/NetworkPersistence

Summary: drivers/NetworkPersistence.js — OS-integration persistence for engine/network's intentionally storage-agnostic modules (network plan §15/§38 persistence gap: "EventLog is in-memory only" / "PeerTicketStore is in-memory only... callers are responsible for persisting"). engine/network never imports webgpu-os/storage/AppSandbox.js (same layering rule as drivers/ResidentBootstrapSource.js) — this file is the glue that reads/writes an AppSandbox instance using the snapshot/hydrate/ replay functions those modules already expose: - engine/network/groupLedger/GroupLedger.js: replayGroupLedger() - engine/network/peerTickets/PeerTicketStore.js: snapshotPeerTicketStore()/hydratePeerTicketStore() AppSandbox encrypts everything at rest (AES-256-GCM, device+app-bound key) and is isolated per appId (webgpu-os/storage/AppSandbox.js) — callers should pass the sandbox of THE APP THAT OWNS THIS DATA (e.g. a future groups/chat app), not some shared "network" pseudo-app, so the sandbox's per-app isolation guarantee stays meaningful.


saveGroupLedger

Summary: Persist a group ledger's full replayable state: its static config (groupId/founders/mode/threshold) plus `eventLog.entries()`. Cheap to call after every `proposeGroupEvent`/`genesisGroup` — it's a full snapshot, not an incremental diff, so there's nothing to get out of sync.


loadGroupLedger

Summary: Load and replay a previously-saved group ledger.


listSavedGroupIds

Summary: groupIds this sandbox currently has a saved ledger for.


deleteGroupLedger

Summary: Forget a saved group ledger. Does not affect any already-live in-memory ledger object.


savePeerTickets

Summary: Persist a peer ticket store (full snapshot — see PeerTicketStore.js's snapshotPeerTicketStore).


loadPeerTickets

Summary: Load a previously-saved peer ticket store, or a fresh empty one if none is saved.


saveStateChannelCheckpoint

async saveStateChannelCheckpoint(sandbox, channelId, checkpoint)

Summary: Persist one complete, fenced State Channel authority checkpoint.


saveStateChannelOutbox

async saveStateChannelOutbox(sandbox, channelId, intents, maxEntries = 512)

Summary: Bounded pending intents survive tab reload until a receipt is observed.


createStateChannelCheckpointStore

Summary: Adapter consumed by StateChannelAuthorityCoordinator.


drivers/ProfileDriver

Summary: ProfileDriver.js — OS-level multi-user profile + per-profile identity. SecureMesh Phase 1. Lawful, user-owned identity: profile = OS-created account + per-profile ECDSA P-256 keypair + random (hashed) install id + user-held recovery code. Privacy rules baked in: - NO hardware/browser fingerprinting feeds identity. `localDeviceIdHash` is a SHA-256 of a RANDOM, user-resettable install id (never the raw id, never any device characteristics). - The private key is NEVER stored raw. The working signing key is held as a NON-EXTRACTABLE WebCrypto key (cannot be exfiltrated). A separate copy is stored encrypted (AES-GCM, PBKDF2-from-recovery-code) purely for user-triggered export / portability. Storage: IndexedDB `profiles` store (CryptoKey objects are structured-cloneable); active profile id + random install id live in the generic `kv` store. This driver is additive — the legacy global CryptoDriver identity is left untouched. Apps opt into per-user identity via `syscalls.profile.*`.


ProfileSchemaVersionError

class ProfileSchemaVersionError extends Error


assertSupportedProfileSchemaVersion

assertSupportedProfileSchemaVersion(value, { allowMissing = true, label = 'profile record' } = {})

Summary: Reject records from a newer writer before normalization can discard fields. Missing versions are accepted as the legacy v1 shape and migrated explicitly.


drivers/RealmNetworkFeatureFlags

Summary: Persisted rollout gates for the additive Realm Network upgrade. Realm Network Alpha ships with every completed slice active. Version 2 stores only explicit user overrides, so later default changes cannot erase a deliberate opt-out. Callers may inject a storage-compatible object in tests; the driver uses localStorage in the OS.


drivers/ResidentBootstrapSource

Summary: drivers/ResidentBootstrapSource.js — OS-integration adapter wiring the browser extension's resident cert vault (browser-extension/services/ ResidentService.js) into engine/network/dht/BootstrapSource.js's `{ id, scan, advertise }` interface (network plan §37/§47/§48). `engine/network` intentionally has no `webgpu-os` dependency (same layering rule as the deferred `kernel/Syscalls.js` wiring — see BootstrapSource.js's header comment) — this file is the OS-side glue the plan called out as the natural adapter, kept honest about what the resident node actually does today: - The resident node is a lightweight, OFF-BY-DEFAULT cert vault + a chrome.alarms keepalive heartbeat living in an MV3 offscreen document. It does NOT run a real WebRTC/Masterserver client and does NOT answer DISCOVER while no OS tab is open (see ResidentService.js's own header comment). Do not oversell this as "background reachability" anywhere in the UI (network plan §42's "never overstate privacy/reachability"). - What it DOES give a bootstrap attempt: a small piece of persisted memory that survives an OS tab closing — "the last identity this browser saved for room X" — which is a legitimate (if modest) bootstrap hint once a new tab reopens, and a place to advertise our current identity so it's still there next time.


createResidentBootstrapSource

createResidentBootstrapSource({ browserBridge } = {})


drivers/WebSurfaceDriver

Summary: WebSurfaceDriver.js — Render any cross-origin website as a live WebGPU texture. ── How it works ───────────────────────────────────────────────────────────── 1. Creates an <iframe> that loads the target URL (browser renders it normally) 2. User clicks "Share Tab" once via getDisplayMedia({ preferCurrentTab: true }) 3. Element Capture API restricts the stream to just the iframe's pixels 4. HTMLVideoElement.srcObject = stream  →  live video feed of the website 5. device.importExternalTexture({ source: videoEl }) → WebGPU texture every frame Result: any cross-origin URL renders as a live GPU texture surface inside the OS. ── Browser support ─────────────────────────────────────────────────────────── getDisplayMedia:   all major browsers Element Capture:   Chrome 116+  (RestrictionTarget.fromElement) importExternalTexture: Chrome/Edge (WebGPU) ── Security model ──────────────────────────────────────────────────────────── - User must approve screen share once (one-time gesture, can be re-used) - iframe is sandboxed; cross-origin website cannot access our JS - We only get pixels, not DOM of the foreign page - Mouse/keyboard relay is optional (events forwarded to iframe element)


kernel/AmbientEngine

Summary: AmbientEngine.js — Desktop background rendering service. Owns a fixed full-screen DOM layer (z-index: -10) that sits permanently behind every panel and shell element.  Supports CSS gradients, solid colors, static images, video, and extensible driver plug-ins registered by mods.  Exposes the same before/after hook middleware pattern as ThemeEngine so mods can intercept and customize background changes. ThemeEngine drives this automatically via setFromTheme() when the accent or wallpaper preset changes.  Mods (or the user) can bypass ThemeEngine entirely with apply() for fully custom backgrounds. ── Modder API ──────────────────────────────────────────────────────────── const amb = syscalls.ambient; // Register a totally custom renderer (canvas, WebGPU, Three.js …) amb.registerDriver('webgpu-scene', { apply(layer, config) { layer.innerHTML = ''; const canvas = document.createElement('canvas'); canvas.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;'; layer.appendChild(canvas); // … render into canvas … }, destroy(layer) { layer.innerHTML = ''; } }); // Before hook — middleware: modify config before the layer receives it amb.before('my-mod', (cfg, next) => next({ ...cfg, opacity: 0.7 }), 'Dim'); // After hook — react after background is applied amb.after('my-mod', (cfg) => console.log('Ambient applied:', cfg)); // Apply custom backgrounds amb.apply({ type: 'css',   value: 'linear-gradient(135deg,#ff0080,#7928ca)' }); amb.apply({ type: 'color', value: '#1a0533' }); amb.apply({ type: 'image', src: '/bg.jpg', size: 'cover', position: 'center' }); amb.apply({ type: 'video', src: '/bg.mp4', bg: '#000' }); amb.apply({ type: 'webgpu-scene', ... }); // custom driver // Set opacity of the ambient layer (0–1) amb.setOpacity(0.85); // Export / import config JSON const json = amb.export(); amb.import(json); // Subscribe to changes kernel.events.on('os:ambient-change', ({ config }) => { … });


kernel/AppRegistrationScope

Summary: Authenticated app wrappers for registration-bearing syscall namespaces. Identity binding is independent of permission-enforcement mode: developer mode may relax capability checks, but it never relaxes ownership.


scopeToolSyscalls

scopeToolSyscalls(kernel, appId, raw = kernel?.syscalls?.tools)


scopeProtocolSyscalls

scopeProtocolSyscalls(kernel, appId, raw = kernel?.syscalls?.protocol)


scopeCommandSyscalls

scopeCommandSyscalls(kernel, appId, raw = kernel?.syscalls?.cmd)


cleanupAppRegistrations

cleanupAppRegistrations(kernel, appId, { logger = console } = {})


kernel/AppRegistry

Summary: AppRegistry.js — fully dynamic, fetch-based app discovery. NO apps are hardcoded here. Discovery works as follows: 1. Fetch  apps/index.json  → array of folder names, e.g. ["calculator","notepad",…] 2. For each folder, fetch  apps/<folder>/manifest.json 3. Resolve manifest.entry against the manifest URL (absolute URL) 4. Register and emit 'change' so the shell re-renders live To add a new app: create  apps/<name>/manifest.json  +  apps/<name>/YourApp.js, then add "<name>" to  apps/index.json.  No JS edits required. Manifest shape (see docs/APP_MANIFEST_SPEC.md): appId, name, entry, icon, category, surface, defaultWidth, defaultHeight, permissions, description, version, settings[]


AppManifestValidationError

class AppManifestValidationError extends Error


validateAppManifest

validateAppManifest(manifest, { mode = APP_MANIFEST_VALIDATION.STRICT, registry = schemaRegistry, logger = console, } = {})

Summary: Validate an authority-bearing manifest after removing registry-only fields.


kernel/CommandBus

Summary: CommandBus.js — OS-wide addressable command registry. Every syscall namespace, app, and service can register handlers for dot-namespaced command strings: pkg.install    patch.apply    gpu.profile.start    browser.tabs.list Dispatch flow: caller → cmd.dispatch('pkg.install', { url }) → handler → result All dispatches are logged to /os/logs/commands.log (async, non-blocking). Usage: kernel.cmd.register('pkg.install', async ({ url }, ctx) => { ... }); const result = await kernel.cmd.dispatch('pkg.install', { url: '...' });


kernel/FxBus

Summary: FxBus.js — the OS "FX Bridge". A normalized pipeline that lets apps (and the OS itself) publish a lightweight "vibe" — a dominant accent color, optional palette, an energy level, and an optional beat/mood — which the desktop reacts to (ambient tint/pulse, accent glow) and which external sinks (WLED / Home Assistant / Hue via a relay) can later subscribe to. Producers: - Explicit: an app calls `syscalls.fx.publish(frame)` (capability `fx.emit`). Sandboxed iframe guests call `window.os.fx.publish(frame)`, routed over the existing postMessage RPC bridge. - Automatic: `startAutoSample()` samples a provided surface (canvas/img/video) and extracts the dominant color, so an app can drive effects with no code. Consumers subscribe to the kernel event `os:fx-frame`. The built-in consumer is AmbientEngine.fxTint(); more sinks can be added without touching producers. Frames are normalized and rate-limited (coalesced to ~one emit per minInterval) so a chatty producer cannot flood the desktop or thrash the compositor.


kernel/GpuDeviceBroker

Summary: GpuDeviceBroker.js — per-app GPU device facades, quotas, and adapter redaction. WHY a facade and not a Proxy of the real GPUDevice? Host objects with internal slots (GPUDevice/GPUQueue) fail brand checks when a Proxy is handed back to other WebGPU APIs (notably `GPUCanvasContext .configure({ device })`). So we hand apps a *forwarding facade*: a plain object that forwards to the real device and ALWAYS returns real host objects (real GPUBuffer/GPUTexture/encoder/queue). The only host API that consumes the device object itself is `context.configure` — untrusted apps should get their canvas via `gpu.acquireSurface` (configured by the OS with the REAL device), so they never need to pass the facade anywhere. If an untrusted app does configure a canvas itself with the facade it fails closed (safe). POLICY: trusted / built-in apps receive the RAW device (zero compatibility risk). Untrusted (unverified) apps receive a facade that: - tracks + quota-checks every createBuffer / createTexture (via VRAMTracker), - counts pipelines / shader modules / queue submits per app, - enforces a command-submit budget (anti-runaway), - partitions the shader-module cache per app (no cross-app cache sharing), - fails closed after device loss until the broker re-issues a fresh facade.


bucketLimits

Summary: Bucket GPUSupportedLimits into a coarse, plain object. Reduces fingerprint entropy (exact limits vary per GPU/driver) while keeping values usable. Returns a plain object with the same keys apps read.


bucketAdapterInfo

Summary: Redact a rich adapter-info report down to a coarse, low-entropy summary for untrusted apps. Keeps the vendor *bucket* and capability booleans; drops the precise renderer string, driver version, device id, and exact limits.


kernel/GpuInfo

Summary: GpuInfo.js — rich, consolidated GPU adapter reporting for the OS. Browsers expose the GPU through several uneven channels; the most accurate picture comes from combining them (this mirrors what the engine's VGPUMemoryTracker / GPU Profiler do, minus the heavy VRAM probe): 1. WebGPU `adapter.info`            → vendor / architecture / device / description 2. `adapter.requestAdapterInfo()`   → same, legacy async fallback 3. `device.adapterInfo`             → some implementations expose it here 4. WebGL `WEBGL_debug_renderer_info`→ the UNMASKED renderer string is usually the only place the real model name (e.g. "AMD Radeon RX 6700 XT") appears, since Chrome hides it from adapter.info. 5. `adapter.features` / `.limits`   → capability flags + key device limits `gatherGpuInfo()` returns ONE structured report plus best-effort adapter preference probes. Everything is best-effort and never throws — missing channels just leave their fields empty.


vendorBucket

Summary: Coarse vendor label from any descriptive string.


friendlyAdapterName

Summary: Best human-readable adapter name from the combined channels.


gatherGpuInfo

async gatherGpuInfo(adapter, device = null, options = {})

Summary: Gather a full GPU report from a WebGPU adapter (+ optional device).


kernel/KernelBootstrap

Summary: KernelBootstrap — the OS kernel layer. Owns: - The single shared WebGPU device (if available). - The central task scheduler (kernel-owned RAF). - The event bus. - GPU device-lost fan-out to all registered apps. - The syscall surface exposed to apps. Tier-2 note: In Tier 2 this becomes a Rust native-host service; the kernel.syscalls shape must remain stable across tiers.


KernelEventBus

Summary: Minimal synchronous event bus for kernel-internal use. Apps should use kernel.syscalls.ipc for cross-app messaging.


kernel/LaunchCoordinator

Summary: Route validated launch intents through the existing desktop and subsurface services.


kernel/LaunchIntent

Summary: Canonical, untrusted-input boundary for browser and operating-system launches.


parseLaunchUrl

parseLaunchUrl(input, { baseUrl = globalThis.location?.href ?? 'https://localhost/webgpu-os/', scopePath = DEFAULT_LAUNCH_SCOPE, } = {})

Summary: Parse a canonical launch URL. Non-launch URLs inside the shell return null; malformed URLs under /open/ throw so callers can log a security rejection.


kernel/ModRegistry

Summary: ModRegistry.js — dynamic mod discovery, mirroring AppRegistry. Scans  mods/index.json  → per-mod  mods/<folder>/manifest.json Imports the mod entry and registers its hooks into PatchBus. Mod manifest shape: modId        — unique reverse-domain id, e.g. "com.example.dark-plus" name         — display name version      — semver string author       — author name description  — one-line description targets      — array of appIds to patch, or ["*"] for all apps entry        — relative path to mod JS module (default export = mod object) entryOverride — boolean, if true this mod completely replaces the app entry enabled      — boolean (default true), false to disable without removing Adding a new mod: 1. Create  mods/<name>/manifest.json 2. Create  mods/<name>/YourMod.js  (default export: mod object) 3. Add "<name>" to  mods/index.json No kernel or app code changes required.


kernel/OsLogger

Summary: OsLogger.js — in-memory ring-buffer logger for the OS kernel and apps. Levels: debug < info < warn < error Keeps the last MAX_ENTRIES entries in memory. Listeners (e.g. Log Viewer) are notified on each write. Optionally flushes to /os/logs/os.log via StorageManager (non-blocking).


projectLogMetadata

Summary: Produce an accessor-free, bounded, closed projection for a log entry. Unknown fields and nested objects are omitted instead of serialized.


kernel/PatchBus

Summary: PatchBus.js — Android-style mod / patch bus for WebGPU OS. Provides: beforeMount / afterMount / beforeUnmount / afterUnmount hooks UI injection    — mods append DOM into any app panel CSS injection   — scoped to the app's panel element automatically Manifest patch  — mods can widen panels, add permissions, change defaults Entry override  — a mod can fully replace an app's module Syscall intercept — middleware chain on any syscall namespace.method Hook execution order: mods registered first run first (FIFO per phase). Syscall interceptors are chained: each calls next() to delegate down. ── Mod object API (default export from mod entry file) ───────────────────── beforeMount(container, syscalls, manifest)           → void | Promise afterMount(container, syscalls, appInstance, manifest) → void | Promise beforeUnmount(appInstance, manifest)                 → void | Promise afterUnmount(manifest)                               → void | Promise injectUI(container, manifest)                        → HTMLElement | null injectCSS(manifest)                                  → string | null patchManifest(manifest)                              → Partial<Manifest> interceptSyscall(syscallPath, args, next)            → any None of these are required — implement only what you need.


kernel/PermissionPortal

Summary: PermissionPortal.js — user-facing permission prompt. Appears as a stacked card above the taskbar whenever an app requests a capability that is not yet decided. Multiple requests queue and show one at a time (FIFO). Each card: ┌──────────────────────────────────────┐ │ 🔒  os.my-app wants permission       │ │     Access camera                    │ │     Risk: ● High                     │ │  [Deny]  [Allow Once]  [Allow Always] │ └──────────────────────────────────────┘ Usage (kernel internal — apps call syscalls.permissions.request()): const portal = new PermissionPortal(); portal.mount(document.body); const granted = await portal.ask(appId, capability, manifest);


kernel/PermissionStore

Summary: PermissionStore.js — IDB-backed persistence of user permission decisions. Decisions are keyed as `{appId}::{capability}` in the 'permissions' IDB store. Each record: { appId, capability, decision: 'allow'|'deny', scope: 'once'|'always', ts } 'once' decisions are in-memory only (not persisted). 'always' decisions are stored and reloaded on next boot.


kernel/Permissions

Summary: Permissions.js — capability gating backed by RuleGraph. Phase 4: enforces manifest-declared permissions via a declarative RuleGraph. Phase 1 mode: audit-only (log violations, never block) — set enforcing=false. Tier 2: delegates to WASI capability broker (same check() interface). Usage: kernel.permissions.registerApp(appId, manifest) kernel.permissions.check(appId, 'gpu.compute')  → { granted, reason } kernel.permissions.require(appId, 'gpu.compute') → throws if denied + enforcing


PermissionDeniedError

class PermissionDeniedError extends Error


kernel/ProcessTable

Summary: ProcessTable.js — tracks all running app panel instances. Each entry maps an appId to its runtime handle: { appId, panelId, manifestPath, panel, resources, startedAt, parentAppId, cpuMs, memoryBytes, networkBytes, diskBytes, lastSampleAt } Phase 4 extends this with per-app VRAM quotas, capability sets, and "destroy on policy breach" enforcement. Phase 5 adds full system monitoring (CPU%, memory, network I/O, disk I/O).


kernel/ProvenanceChecker

Summary: ProvenanceChecker.js — SLSA-inspired build provenance validation. Signatures prove WHO built a package; provenance proves HOW. The 2026 TanStack attack shipped packages with valid signatures from a hijacked builder, so we validate a provenance block and (critically) that the declared source materials actually match the packaged files. Provenance block shape (in the envelope): { sourceRef:  'git@…#<commit>' | 'webgpu-os/devtools', builderId:  'webgpu-os/devtools' | 'ci/github', builtAt:    ISO timestamp, buildParams:{ … }, materials:  [ { path: 'files/app.js', sha256: '…' }, … ] } Returns a verdict { ok, level, builderId, warnings[] }: level 0 — no provenance (allowed, but lowers trust → risk badge) level 1 — provenance present + materials match packaged files level 2 — level 1 AND builder is a recognized trusted builder


kernel/RuleGraph

Summary: RuleGraph.js — declarative capability-based permissions engine. Rules are evaluated in registration order; the LAST matching rule wins (CSS-like specificity — more specific rules override general ones). Capabilities follow a dot-namespace convention: fs.read, fs.write, gpu.compute, gpu.acquireSurface, net.send, net.on, ai.infer, ui.notify, ipc.emit, … Wildcard matching: 'fs.*'  matches any capability starting with 'fs.' '*'     matches everything Condition functions receive (appId, capability, manifest) and return bool. A rule with a condition is only applied when the condition is true. Usage: const graph = new RuleGraph() .allow('fs.*') .deny('net.*') .allowIf('gpu.compute', (id, cap, mf) => mf.permissions?.includes('gpu.compute')); const { granted, reason } = graph.check('os.calculator', 'fs.read', manifest);


buildDefaultRuleGraph

Summary: Build the default OS-wide RuleGraph. Apps with explicit manifest.permissions entries unlock restricted capabilities.


Summary: Human-readable label for each capability (used by PermissionPortal).


kernel/RuntimeModeManager

Summary: RuntimeModeManager.js — Runtime ↔ Developer mode switch. Modes: 'runtime'   — enforcing permissions, no debug surface, production-like 'developer' — enforcing permissions, bounded diagnostics, hot-reload enabled Effects applied on mode change: runtime    → permissions.setEnforcing(true), window.__DEV__ = false developer  → permissions.setEnforcing(true), window.__DEV__ = true Developer mode is never an authority bypass. Entering it requires a trusted system principal and a live browser user activation; the kernel object and private services are never projected onto `window`. Persisted in IDB kv store under key 'os.runtimeMode'. Emits kernel event 'os:mode-change' with { mode, prev }.


kernel/SearchManager

Summary: SearchManager.js — unified OS search backend for the command palette. Aggregates "app elements" from three kinds of sources, on top of the apps / subsurfaces / deep-links the palette already indexes: 1. Quick Actions (static)  — declared in a manifest's `actions` array. Each is a runnable item. If it carries a `command`, the palette dispatches it on the CommandBus; otherwise it is delivered to the app as an app-action (the app is opened/focused first, then receives ui:app-action / reads pendingActions). 2. Live content providers  — a running app registers a query callback via ui.registerSearchProvider(id, { label, query }). `query(q)` returns result items { id, label, sublabel?, icon?, run } where run() performs the action. Providers are same-realm closures, so run() can call straight back into the app. 3. Commands (opt-in)        — CommandBus commands registered with meta.search:true become searchable; selecting dispatches them (no-arg). Opt-in keeps destructive commands out of search by default. Events: ui:app-action { appId, actionId, args } — a manifest app-action was invoked.


kernel/SecurityDoctor

Summary: SecurityDoctor.js — in-browser security posture report (no Node required). Aggregates the OS's runtime security signals into a single graded report: - syscall guard coverage (reuses auditSyscallGuards) - complete capability-policy coverage (reuses auditCapabilityMap) - permission enforcement state - package trust posture (quarantined / untrusted installed packages) - update supply-chain policy (signed + trusted-for-auto) - GPU containment (per-app broker + VRAM quotas) - shell CSP delivery (Report-Only vs enforcing, inline-script regressions) - browser-extension presence Each finding has a severity ('critical'|'high'|'medium'|'low'|'info') and a pass flag. `runSecurityDoctor(kernel)` returns a structured report suitable for logging or rendering in a Security Doctor panel.


kernel/SessionStore

Summary: SessionStore.js — OS-wide, encrypted per-origin session + credential store. One machine-bound, AES-256-GCM encrypted IndexedDB store (via AppSandbox, db `os.sandbox.os.sessions`) shared by every app and the compat layer. It replaces the Browser app's localStorage-local vault/cookie stores so logins and per-site policy are managed OS-wide and consistently encrypted. Record kinds (one IDB key each): policy:<origin>  → 'persist' | 'isolated'      per-site session policy sess:<origin>    → { cookies:{k:v}, local:{k:v}, t }   agent-captured data vault            → the Browser vault blob (itself master-password encrypted; stored here so all apps share one OS-wide vault) IMPORTANT — what this can and cannot do: We CANNOT read a cross-origin live frame's real cookies (browser isolation), and Set-Cookie is a forbidden header. So "persistence" is policy-driven: • 'isolated' (default) → frame loads `credentialless` (ephemeral, sessionless) • 'persist'            → frame drops `credentialless` so the browser keeps its cookies natively across reloads + restarts Captured `sess:<origin>` data only comes from surfaces we CONTROL (proxied / srcdoc / compat-sandbox documents) via an injected agent — never scraped from a live cross-origin frame.


kernel/SigningLineage

Summary: SigningLineage.js — publisher signing-key rotation lineage (proof-of-rotation). Models the Android APK Signature Scheme v3 "proof-of-rotation" idea in our ECDSA P-256 world: a singly-linked list of publisher keys, ordered oldest → newest, where EACH ancestor key signs the NEXT key's payload. This proves that a new key is endorsed by the previous one, so an app update signed by a fresh key is provably the same publisher identity as the version a user already pinned — "reuse the same identity with new keys, still isolated per update." Two independent guarantees (kept separate, exactly like APK v3): 1. File integrity / self-verification — the CURRENT key signs the version's Merkle root (PackageBuilder.buildV2). That is unchanged and lives outside this module: a package always verifies against its own files. 2. Identity continuity — THIS module. The lineage is carried inside the signed package envelope (so it is covered by the current key's signature and cannot be stripped/swapped in transit), and proves the head key descends from the previously-pinned key. Lineage shape (`prlineage-v1`): { format: 'prlineage-v1', appId:  'community.my-app', nodes:  [ { pubKey:<b64>, fingerprint:<hex>, flags:<uint>, rotatedAt:<iso> }, ... ],  // oldest → newest links:  [ <b64 sig>, ... ]   // links[i] = nodes[i] signing canonical(nodes[i+1]); length = nodes.length - 1 } Node flags (self-trusted-old-certs, bitfield): FLAG_INSTALL  (1) — this (old) key may still authorize fresh installs FLAG_UPDATE   (2) — this (old) key may still sign updates Default for new rotations is 0 (strict): only the head key installs/updates; ancestors are accepted ONLY to prove continuity to a pinned fingerprint. SECURITY: this verifier is FAIL-CLOSED. Any malformed structure, fingerprint mismatch, or broken link signature ⇒ { valid:false }. Callers fall back to the existing publisher-change quarantine path on invalid/absent lineage. fingerprintOf:(pubRaw:Uint8Array)=>Promise<string>, sign?:(data:string)=>Promise<Uint8Array|null> }} CryptoLike


lineageNodePayload

Summary: Canonical signed payload for a lineage node — the bytes an ancestor key signs to endorse this successor node. Binds the successor's key, fingerprint, flags, the appId, and the PREVIOUS node's fingerprint, so a link cannot be replayed onto a different app or spliced into a different chain.


verifyLineage

Summary: Verify a lineage end-to-end. FAIL-CLOSED.


authorizeRotation

async authorizeRotation(lineage, signerFingerprint, pinnedFingerprint, crypto)

Summary: Decide whether an update may proceed via key rotation. FAIL-CLOSED. Accepts iff the lineage is valid, its head equals the package's current signer fingerprint, and the previously-pinned fingerprint appears in the chain (i.e. the head provably descends from the key the user already trusts).


createGenesisLineage

async createGenesisLineage(appId, pubKeyRaw, crypto, flags = 0)

Summary: Build the genesis (single-node) lineage for a brand-new publisher key.


appendRotation

async appendRotation(lineage, newPubKeyRaw, signWithCurrent, crypto, opts = {})

Summary: Append a rotation: the CURRENT head key signs the NEW key's node, proving the new key inherits the identity. The caller supplies a `signWithCurrent(data)` bound to the OLD/head private key (the dev's safely-kept key), so private keys never enter this module.


kernel/SubsurfaceManager

Summary: SubsurfaceManager.js — kernel navigation service for app SUBSURFACES. A "surface" is an app's top-level display mode (window / overlay / tray — see manifest.surface). A "subsurface" is a navigable sub-location *inside* an app (a tab, section, or view), declared in the manifest as: "subsurfaces": [ { "id": "mixer", "label": "Volume Mixer", "icon": "🎚", "keywords": ["volume"] }, ... ] This service is the OS-level registry/tracker for deep-linking into those: - Active tracking: which subsurface each running app currently shows. - Pending nav:     a deep-link target stashed for an app that is still launching (the app reads it on mount via ui.pendingNavigate). - Recents + Pins:  persisted deep-link shortcuts (the "small UI shortcuts"), surfaced in the command palette / Start Menu. NOTE: This is distinct from SurfaceManager.js, which allocates WebGPU canvases. Events emitted on kernel.events: ui:navigate-subsurface  { appId, subsurfaceId, args }  — a deep-link was requested ui:subsurface-change    { appId, subsurfaceId }         — an app reported its active sub os:deeplinks-change     {}                              — pins/recents changed


kernel/SurfaceManager

Summary: SurfaceManager.js — allocates and manages one WebGPU canvas surface per panel. Checks permissions (gpu.acquireSurface) and VRAM quotas before allocating.


SurfaceManager

Summary: Each `gpu-panel` app gets an exclusive <canvas> + GPUCanvasContext bound to the kernel's GPU device. The SurfaceManager handles: - Canvas creation and insertion into the panel body - GPUCanvasContext.configure() with the preferred format - ResizeObserver wiring so the canvas tracks panel resize - Clean release (unconfigure + canvas removal) on panel close Quota admission happens before GPUCanvasContext creation/configuration.


kernel/Syscalls

Summary: Syscalls.js — the stable Tier 1 ↔ Tier 2 contract boundary. Every app sees ONLY this surface. In Tier 1 (browser) each method delegates to the corresponding engine module. In Tier 2 (Rust + Wasmtime) each method becomes a WASI capability-table entry. ⚠  Never expose engine internals directly to apps. If an app needs a new capability, add a method here first; never let apps import from ../../engine/. Syscall namespaces: kernel.fs   — virtual filesystem (IndexedDB + ProjectManager) kernel.gpu  — GPU stats, resource budgets, device info kernel.ipc  — cross-app event bus kernel.ai   — inference handle (AGI driver, Phase 6) kernel.net    — networking (collab driver, Phase 5) kernel.crypto — ECDSA P-256 identity, sign/verify (CryptoDriver) kernel.ui     — notifications, modals, panels


guardSyscalls

Summary: Wrap a syscalls object with per-app permission enforcement. Only restricted capabilities are guarded — universally-open ones (fs.*, ipc.*, ui.*) are skipped since they are always granted and the overhead is unnecessary.


auditSyscallGuards

Summary: Inventory every syscall method and classify it as guarded / open / unguarded. Build-only: no syscall is invoked. Use at boot (dev mode) or in tests to catch privileged methods added without a capability guard.


kernel/ThemeEngine

Summary: ThemeEngine.js — Kernel-level theme orchestration service. Single source of truth for all OS appearance state. Exposes a middleware-chain hook system so mods can intercept theme changes before or after they are applied to the DOM. ── Modder API ──────────────────────────────────────────────────────────── const tm = syscalls.theme; // Before hook — middleware: receive appear + next(modified) tm.before('my-mod', (appear, next) => next({ ...appear, chromeStyle: 'metal' }), 'Force metal chrome'); // After hook — react to a completed theme change tm.after('my-mod', (appear) => console.log('Theme applied:', appear)); // Remove hooks tm.removeHook('my-mod'); // Reorder tm.moveHook('my-mod', 'before', 1);           // move to index 1 in before list // Preview (no save, no events) tm.preview({ ...tm.current(), chromeStyle: 'metal' }); // Apply (save + emit os:theme-change) tm.apply({ ...tm.current(), themeId: 'crimson' }); // Export / import theme JSON const json = tm.export(); tm.import(json); // List registered hooks tm.hookList(); // → [{ id, phase, description, enabled, order }]


normalizeAppearance

Summary: Normalize untrusted or legacy appearance data into the supported schema.


writeAppearanceRecord

Summary: Publish one canonical appearance record after guarding the existing version.


removeAppearanceRecord

Summary: Remove the current record only when this runtime can understand it.


kernel/ToolDriver

Summary: ToolDriver — small OS-native tool registry for LLM/tool callers. This mirrors the useful parts of Augment's tool registry in browser-native form: schema listing, guarded execution, history, read-only batching, and a narrow terminal bridge that never exposes the interactive terminal's eval path.


projectContentFreeToolFailure

async projectContentFreeToolFailure(error, { toolName = 'unknown', errorCode = null, } = {})

Summary: Project an arbitrary handler failure without retaining its message. Handler messages are untrusted and may quote complete tool inputs, credentials, or provider content. The digest preserves deterministic incident correlation.


kernel/TrayManager

Summary: TrayManager.js — system notification area (status icons). Background/utility apps register a small status icon next to the clock, the same model used by Windows' notification area, macOS' menu-bar extras, and the FreeDesktop StatusNotifier spec. Apps register via syscalls.ui.registerTrayIcon(spec) and the StatusTray renders them, with an overflow popup for icons beyond the visible limit. Icon spec: { id, appId?, icon, tooltip?, onClick?, menu?, priority? } - icon:    emoji/glyph string (or short text) - onClick: fn() invoked on left click (shared-realm apps only) - menu:    [{ label, onClick }] optional right-click menu - priority: higher sorts first (default 0)


kernel/TrustStore

Summary: TrustStore.js — ring-0 trust anchors + publisher pinning for the package system. Two tiers of trust: 1. ROOTS  — public keys baked into the OS bundle (kernel/trust/roots.json). A publisher certificate that chains to a root is fully trusted. 2. PINS   — publishers the user accepted on first install (trust-on-first-use). Persisted in IndexedDB (kv store, key `trust.pin.<fingerprint>`). Anti-takeover: a pinned publisher is bound to a specific key fingerprint. If a later package for the same publisher presents a *different* fingerprint, the caller (PackageManager.verifyAndAuthorize) treats it as an identity change and blocks pending explicit re-consent — defending event-stream/durabletask-style account takeovers. SECURITY NOTE: signatures prove *who* built a package, not that the build was clean. Trust here is combined with provenance + static scan + egress controls.


kernel/UiSounds

Summary: UiSounds.js — OS-wide UI sound engine (kernel service). Procedurally synthesizes short UI sounds (click, open, close, notify, error, …) through the OS AudioDriver's shared context, so every cue is mixed and volume- controlled centrally (it appears in the Sound mixer as a "System sounds" session). Sounds are auto-triggered from OS-wide kernel events (panel open/close/minimize/ restore, notifications, theme toggle) and from a global click listener, so the whole desktop gets feedback without each app wiring anything. Apps can also play a cue explicitly via syscalls.ui.sound('click'). ── Future customization ────────────────────────────────────────────────────────── Every cue is a named entry in a registry. A mod / sound pack can override or add cues at runtime: kernel.uiSounds.register('click', (ctx, out, t0) => { ... custom synth ... }); kernel.uiSounds.register('coin', (ctx, out, t0) => { ... new cue ... }); Per-cue enable flags, global enable, and volume persist in localStorage, ready for a settings UI (the Sound app exposes the global toggle + volume today).


kernel/VRAMTracker

Summary: VRAMTracker.js — per-app GPU memory budget tracking. WebGPU does not expose actual VRAM usage. We track *requested* allocations: Surfaces  — estimated from canvas dimensions × bytes-per-pixel Buffers   — exact size passed to createBuffer (when routed via syscalls) Textures  — estimated from width × height × format bytes-per-pixel Admission is checked before allocations. Canvas surfaces receive a small, bounded reserve so buffer/texture workloads cannot consume the final UI capacity and make an app impossible to close or recover. Phase 5+ upgrade path: hook device.createBuffer/createTexture via a GPUDevice proxy to track all allocations, not just syscall-routed ones.


kernel/VirtualFS

Summary: VirtualFS.js — path-tree virtual filesystem. Features: POSIX-like paths   — /user/notepad/file.txt Directories        — implicit from file paths; explicit mkdir supported Persistence        — OPFS-backed via StorageManager (falls back to localStorage) Events             — on('write'|'delete'|'*', cb) for live watchers (e.g. Notepad tabs) JSON helpers       — readJSON / writeJSON All public methods are synchronous (reads from in-memory cache). Writes flush to OPFS asynchronously in the background. Call `await virtualFS.hydrate()` once at OS boot to preload OPFS → memory.


kernel/agent/JavaScriptProjectFacts

Summary: Bounded lexical facts shared by project indexing and source verification. This module deliberately does not claim to parse JavaScript, TypeScript, or JSX. It identifies inspectable declarations and import specifiers while keeping lexical evidence distinct from parser evidence.


inspectJavaScriptProjectFacts

inspectJavaScriptProjectFacts({ path = '', content = '', maxTokens = MAX_TOKENS, maxSymbols = MAX_SYMBOLS, maxImports = MAX_IMPORTS, } = {})


resolveJavaScriptImport

resolveJavaScriptImport({ sourcePath = '', specifier = '', knownFiles = null } = {})


kernel/agent/MountedProjectIntelligenceIndex

Summary: Deterministic, authority-free project intelligence for a mounted workspace. The builder can see a workspace only through AI Echo's existing bounded storage.list and storage.read tool contracts. It returns source-backed facts separately from advisory suggestions and never exposes complete source text.


buildMountedProjectIntelligence

async buildMountedProjectIntelligence({ invokeTool, rootPath, workspaceRevision = '', maxEntries = DEFAULT_MAX_ENTRIES, maxDepth = DEFAULT_MAX_DEPTH, maxReadFiles = DEFAULT_MAX_READ_FILES, maxReadChars = DEFAULT_MAX_READ_CHARS, maxTotalReadChars = DEFAULT_MAX_TOTAL_READ_CHARS, } = {})


kernel/ai-hub/AIDispatchScheduler

Summary: AIDispatchScheduler.js — bounded, in-memory admission for live model calls. Prompts stay inside the caller's run closure and are never serialized or persisted by this scheduler. Owners are serviced round-robin while each owner's jobs retain FIFO start order. Provider and exact-route limits keep a burst of Navi work from crushing one remote endpoint.


kernel/ai-hub/AIService

Summary: AIService.js — the OS.ai() entrypoint (Phase 1 skeleton). Remote-provider based through an adaptive credential boundary. It prefers the isolated AI Bridge extension and falls back on phones to browser-direct OpenRouter or an approved user-controlled HTTPS proxy. Fully separate from `syscalls.ai.*` (the local on-device GGUF runtime). Exposed at kernel.aiHub and wrapped by syscalls.aiHub (capability-gated).


kernel/ai-hub/AdaptiveProviderBridge

Summary: Chooses one credential/transport boundary per operation. The extension is always preferred because its origin isolates secrets from the OS page. Browser-direct is selected only when the extension remains unavailable after a bridge reprobe. Provider requests are never replayed across the two backends, preventing duplicate billing and duplicate tool/model effects.


kernel/ai-hub/DirectProviderBridge

Summary: Browser-direct AI transport for phones and other browsers without extension support. The allowlist is deliberately narrow: - OpenRouter, whose official OAuth/PKCE flow supports browser clients. - A user-approved HTTPS OpenAI-compatible proxy controlled by the user. OpenAI, Anthropic, and other long-lived provider keys stay extension/server only. Their presence in the shared provider catalog does not grant this transport permission to call them.


writeCustomEndpointAllowlist

writeCustomEndpointAllowlist(endpoints, storage = globalThis.localStorage)


writeDirectModelCache

writeDirectModelCache(records, storage = globalThis.localStorage)


kernel/ai-hub/ExtensionBridge

Summary: ExtensionBridge.js — the AI Hub's preferred isolated path to a remote provider. Talks to WebGPU OS Companion via kernel.browserBridge (relay.js's message contract). Never called with a page-supplied header; built-in routes accept only provider/model/messages/ params while custom endpoints remain explicitly approved by the user.


kernel/ai-hub/LocalCredentialVault

Summary: Same-origin credential vault for browsers that cannot install extensions. Session credentials remain ephemeral. Opt-in persistent credentials use a non-extractable IndexedDB CryptoKey and a versioned, encrypted readback. V2 commits the Files-visible readback first and the matching IndexedDB slot second. Readers compare monotonically increasing generations and repair an interrupted second step. V1 envelopes/readbacks remain read-only inputs.


LocalCredentialContractError

class LocalCredentialContractError extends Error


kernel/ai-hub/LocalRuntimeProvider

Summary: AI Hub adapter for the kernel-owned, on-device GGUF runtime. Installed models and generation defaults stay authoritative in LLMDriver; this class only translates that state into the provider-neutral AI Hub contract.


automaticRoutingReadiness

automaticRoutingReadiness(model, runtimeStatus = {})

Summary: Automatic Navi routing is stricter than catalog presence. A saved handle can identify a model without proving that this tab can read it, and an initialized driver can exist without a usable WebGPU device. Manual LLM Runtime flows may still ask the operator to reconnect a handle; unattended routing may not.


kernel/ai-hub/ModelCapabilityRegistry

Summary: ModelCapabilityRegistry.js — maps an abstract `modelTier` to a concrete { provider, model } pair for the OS AI Hub. Apps ask for a tier ('fast', 'balanced', 'reasoning'), not a specific vendor model, so the default can change without touching every app's request payload.


writeModelCapabilityRouting

writeModelCapabilityRouting(tiers, storage = globalThis.localStorage)


kernel/ai-hub/ProviderRouter

Summary: ProviderRouter.js — picks the concrete { provider, model } for a normalized OS.ai() request: an explicit provider/model on the request always wins, otherwise it resolves the request's modelTier via ModelCapabilityRegistry.


kernel/ai-hub/RequestNormalizer

Summary: RequestNormalizer.js — validates and normalizes an OS.ai(request) payload into the canonical shape the rest of the AI Hub pipeline consumes.


kernel/ai-hub/ResultBroker

Summary: ResultBroker.js — wraps a raw provider chat result into the OS.ai() response envelope and stamps it with CSE provenance (engine/state). Model output is always MODEL_PREDICTED/untrusted-for-authority — it becomes canonical only if/when Phase 9's finalizer + CommitCoordinator commit it.


kernel/ai-hub/SmartModelPolicy

Summary: SmartModelPolicy.js - deterministic policy and catalog ranking for AI Hub. This module performs no provider calls, stores no credentials, and grants no authority. It projects provider catalog records into an inspectable ranking that Navi cognition can compile into its existing signed route contract.


classifySmartModelRouterAlias

Summary: Classify provider-side router aliases separately from concrete model IDs. Dynamic aliases may resolve to a different model on every request, so their catalog capabilities cannot safely authorize strict or effectful tasks.


defaultSmartModelPolicy

Summary: Return a detached, immutable basic policy suitable for persisted settings.


normalizeSmartModelPolicy

Summary: Normalize persisted policy. Missing fields migrate to v1 defaults, while an unknown field or version is rejected so misspelled safety controls never silently disappear.


inferSmartModelWorkloadProfile

Summary: Infer preference-only workload affinities from one provider catalog row. The result improves ranking and model-picker explanations. It is never an authorization claim: privacy, modality, tool transport, context, endpoint health, and budget remain separate hard eligibility checks.


classifySmartModelTask

Summary: Classify a task without consulting a model. Explicit purpose wins; otherwise bounded, ordered rules use declared modality/privacy/background state before keyword signals. Raw user text is never copied into the returned evidence.


normalizeSmartModelCandidate

Summary: Project one provider-catalog record into the policy's provider-neutral form.


estimateSmartModelCostMicrounits

Summary: Conservative projected cost for a normalized candidate and token estimate.


rankSmartModelPool

rankSmartModelPool({ policy: rawPolicy = null, models = [], task = {}, usage = null } = {})

Summary: Rank a catalog and return a deterministic, inspectable decision. The caller still owns provider authentication, canonical resource reservations, and final execution authority.


selectSmartModelPool

Summary: Semantic alias for callers that consume the selected route and fallbacks.


kernel/attestation/CapabilityAttestation

Summary: CapabilityAttestation.js — gates capability minting on descriptor attestation. Wraps engine/state's CapabilityRegistry/Capability.js (via the Phase 4 CapabilityNegotiator, kernel.protocol.capabilities — no parallel capability logic) and layers DescriptorHashStore on top so a capability is only minted for a tool whose descriptor hash matches the approved hash. The always-on Navi runtime requires explicit package or operator approval for every first-seen descriptor.