// panes/about.js — runtime metadata, shortcut grid, public links, credits. import { registerPane } from '../app.js'; import { MCP_BASE, jget, escapeHtml } from '../lib/api.js'; import { fmtJSON, copyToClipboard, ok } from '../lib/ui.js'; const SHORTCUTS = [ ['⌘K / Ctrl-K', 'Open command palette'], ['Esc', 'Close palette / modal'], ['↑ ↓ Enter', 'Navigate palette results'], ['1 … 9', 'Quick-jump to a sidebar tab (when palette open)'], ]; const PLATFORM = [ { tab: 'dashboard', label: 'Dashboard', sub: 'KPIs, service health, activity' }, { tab: 'agent', label: 'Agent', sub: 'MCP status + live events + search' }, { tab: 'inbox', label: 'Inbox', sub: 'Sweep & route artifacts' }, { tab: 'tools', label: 'Tools', sub: 'Browse and invoke MCP tools' }, { tab: 'items', label: 'Items', sub: 'CRUD against /api/items' }, ]; const SERVICES = [ { tab: 'diffusion', label: 'Diffusion', sub: 'Stable Diffusion sidecar' }, { tab: 'demand', label: 'Demand', sub: 'Trend-driven design jobs' }, { tab: 'lang', label: 'Lang', sub: 'Language pipelines' }, { tab: 'slack', label: 'Slack', sub: 'Slack sidecar' }, { tab: 'mac', label: 'macOS', sub: 'Native app distribution' }, { tab: 'files', label: 'Files', sub: 'Platform Studio mirror' }, ]; const DEVELOP = [ { tab: 'api', label: 'API Explorer', sub: 'Hit any backend route' }, { tab: 'websocket', label: 'WebSocket', sub: 'Live frame console' }, { tab: 'system', label: 'System', sub: 'Runtime & host facts' }, ]; const PUBLIC_LINKS = [ { url: 'https://webapp.cxllm.io/', label: 'webapp.cxllm.io', sub: 'production' }, { url: 'https://auth.cxllm.io/if/user/#/library', label: 'App library', sub: 'all CxAI tiles' }, { url: 'https://api.cxllm.io/', label: 'api.cxllm.io', sub: 'public API gateway' }, { url: 'https://mcp.cxllm.io/', label: 'mcp.cxllm.io', sub: 'MCP control plane' }, { url: 'https://files.cxllm.io/', label: 'files.cxllm.io', sub: 'Files Platform Studio' }, { url: 'https://code.cxllm.io/', label: 'code.cxllm.io', sub: 'code-server' }, { url: 'https://monitor.cxllm.io/', label: 'monitor.cxllm.io', sub: 'Grafana' }, { url: 'https://registry.cxllm.io/v2/_catalog', label: 'Container registry', sub: 'cxai/* images' }, ]; function linkCardInternal(t) { return `
${escapeHtml(t.label)}
${escapeHtml(t.sub)}
`; } function linkCardExternal(t) { return `
${escapeHtml(t.label)}
${escapeHtml(t.sub)}
`; } const TPL = `
About
CxWebApp control center — single-page UI over the Crow backend and all sidecars.

Build

Host

Connectivity

MCP base
${escapeHtml(MCP_BASE)}
Origin
${escapeHtml(location.origin)}
Theme
User agent
${escapeHtml(navigator.userAgent)}

Platform panes

${PLATFORM.map(linkCardInternal).join('')}

Services

${SERVICES.map(linkCardInternal).join('')}

Develop

${DEVELOP.map(linkCardInternal).join('')}

Public links

${PUBLIC_LINKS.map(linkCardExternal).join('')}

Keyboard shortcuts

${SHORTCUTS.map(([k, d]) => ``).join('')}
${escapeHtml(k)}${escapeHtml(d)}

Architecture

Crow (HTTP/WebSocket) + cpp-httplib (reverse proxy) compiled into a single C++ binary. Static UI is plain ES modules (no build step). All sidecars are reached through /api/<service>/* reverse-proxy routes registered from src/routes/proxy.cpp.

Configuration env-vars

variablepurpose
CXWEBAPP_VERSIONVersion string returned by /api/version.
CXWEBAPP_GIT_SHABuild SHA.
CXWEBAPP_BUILD_TIMERFC3339 build timestamp.
CXWEBAPP_STATIC_DIROverride static asset directory.
CXAI_DIFFUSION_UPSTREAMDiffusion sidecar URL.
CXAI_DEMAND_UPSTREAMDemand sidecar URL.
CXAI_LANG_UPSTREAMLang sidecar URL.
CXAI_SLACK_UPSTREAMSlack sidecar URL.
CXAI_FILES_UPSTREAMFiles PostgREST URL.
FILES_ANON_KEYPostgREST anon key (injected by proxy).
`; function row(k, v) { return `
${escapeHtml(k)}
${escapeHtml(v ?? '—')}
`; } registerPane('about', { label: 'About', async init(host) { host.innerHTML = TPL; host.querySelector('#ab-theme').textContent = document.documentElement.classList.contains('dark') ? 'dark' : 'light'; try { const [v, s] = await Promise.all([jget('/api/version'), jget('/api/system')]); host.querySelector('#ab-build').innerHTML = row('Name', v.name) + row('Version', v.version) + row('Git SHA', (v.git_sha || '').slice(0, 12)) + row('Build time', v.build_time); host.querySelector('#ab-host').innerHTML = row('Hostname', s.hostname) + row('OS', `${s.sysname || ''} ${s.release || ''}`.trim()) + row('Arch', s.machine) + row('PID', s.pid) + row('CPUs', s.cpu_count); } catch (e) { host.querySelector('#ab-build').innerHTML = `
error
${escapeHtml(e.message)}
`; } host.querySelector('#ab-share').addEventListener('click', async () => { try { const [v, s] = await Promise.all([jget('/api/version'), jget('/api/system')]); copyToClipboard(fmtJSON({ ...v, host: s.hostname, sys: `${s.sysname} ${s.release}` }), 'build info copied'); } catch (e) { copyToClipboard(location.href, 'url copied'); } }); }, });