import { useEffect, useState, type CSSProperties } from 'react'; import { api } from '../api'; import { fmtId, runtimeFamily as runtimeTargetFamily } from '../util'; import type { Instance, Approval, Cost, RunningTask } from '../types'; interface Status { instances: Instance[]; running: RunningTask[]; approvals: Approval[]; cost: Cost | null; executor: string; connected: boolean; inventoryWarning?: string; } interface OrbitNode { key: string; label: string; meta: string; family: 'host' | 'container' | 'vm' | 'mission' | 'approval' | 'cost' | 'capability' | 'library' | 'action' | 'session' | 'inventory'; tab: string; state: 'running' | 'ready' | 'attention' | 'blocked' | 'idle'; x: number; y: number; } type OrbitStyle = CSSProperties & { '--x': string; '--y': string }; type WallReviewMode = 'topology' | 'handoff'; const ORBIT_POSITIONS = [ [50, 10], [72, 16], [88, 34], [84, 58], [68, 72], [50, 72], [32, 72], [16, 58], [12, 34], [28, 16], [50, 30], ] as const; interface InventoryEnvelope { instances: Instance[]; degraded_admin_inventory?: string; admin_error?: { title?: string; detail?: string; code?: string; status?: number }; } export function Welcome({ onStartSession, onLaunchInstance, goTo }: { onStartSession: () => void; onLaunchInstance: () => void; goTo: (t: string) => void }) { const [st, setSt] = useState(null); const [firstRun] = useState(() => !localStorage.getItem('cockpit.welcomed')); const [selectedStackId, setSelectedStackId] = useState(''); const [selectedRuntime, setSelectedRuntime] = useState('auto'); const [selectedTask, setSelectedTask] = useState('observe'); const [wallMode, setWallMode] = useState(() => initialWallMode()); useEffect(() => { localStorage.setItem('cockpit.welcomed', '1'); }, []); useEffect(() => { (async () => { try { // Inventory + health are load-bearing: they decide whether a stack is // connected. Fetch them first and let a failure fall through to the // disconnected state. const [inv, health] = await Promise.all([ api('/api/inventory'), api<{ executor_url: string }>('/api/health'), ]); // Running / approvals / cost are enrichment. A real executor may expose // no such admin surface (#1638), so each degrades to empty on its own // and must never blank the whole Home view. const [run, apr, cost] = await Promise.all([ api<{ count: number; running: RunningTask[] }>('/api/running').catch(() => ({ running: [] as RunningTask[] })), api<{ approvals: Approval[] }>('/api/approvals?status=pending').catch(() => ({ approvals: [] as Approval[] })), api('/api/cost').catch(() => null), ]); setSt({ instances: inv.instances, running: run.running ?? [], approvals: apr.approvals ?? [], cost, executor: health.executor_url, connected: inv.instances.length > 0, inventoryWarning: inventoryWarning(inv), }); } catch { setSt({ instances: [], running: [], approvals: [], cost: null, executor: '', connected: false }); } })(); }, []); const runningInstances = st?.instances.filter((i) => i.state === 'running') ?? []; const runtimeCoverage = { host: st?.instances.some((i) => runtimeTargetFamily(i.runtime_posture?.kind ?? i.runtime) === 'host') ?? false, container: st?.instances.some((i) => runtimeTargetFamily(i.runtime_posture?.kind ?? i.runtime) === 'container') ?? false, vm: st?.instances.some((i) => runtimeTargetFamily(i.runtime_posture?.kind ?? i.runtime) === 'vm') ?? false, }; const copyStartCommand = async () => { await navigator.clipboard?.writeText('aiwg cockpit'); }; const orbitNodes = buildOrbitNodes(st); const attentionCount = (st?.approvals.length ?? 0) + (runtimeCoverage.host && runtimeCoverage.container && runtimeCoverage.vm ? 0 : 1); const selectedStack = runningInstances.find((i) => i.id === selectedStackId) ?? runningInstances[0] ?? st?.instances[0]; const selectedStackCost = selectedStack ? st?.cost?.per_instance.find((c) => c.instance_id === selectedStack.id) : undefined; const totalCost = st?.cost?.total.usd ?? 0; const quotaUsed = st?.cost ? Math.min(100, Math.max(6, totalCost * 12)) : 0; const startPlan = [ selectedStack ? selectedStack.loadout : 'no stack', selectedRuntime === 'auto' ? 'auto runtime' : selectedRuntime, selectedTask, ].join(' / '); return (

Operator wall

Work alongside your agents

Observe live stacks, take control when a session allows it, and keep approvals, cost, runtime posture, and handoff context visible in one control plane.

{st?.connected && (
)}
{!st ?

Checking your stacks…

: !st.connected ? (

No stack connected

{st.executor ? ( <>

Bridge is connected to a real executor at {st.executor}, but that executor is not reporting any registered instances or agents.

{st.inventoryWarning &&

Inventory note: {st.inventoryWarning}

}
) : ( <>

Cockpit talks to a real agentic-sandbox executor. Start the executor, then point the Bridge at it:

AIWG_COCKPIT_EXECUTOR_URL=http://127.0.0.1:<executor-port> node apps/cockpit/bridge/src/server.mjs
)}
) : ( <>
{orbitNodes.map((node, index) => ( ))} {wallMode === 'handoff' && ( <>
Source {st.running[0] ? fmtId(st.running[0].instance_id) : 'ready'}
Destination {runningInstances[1] ? fmtId(runningInstances[1].id) : 'next stack'}
)}

{wallMode === 'handoff' ? 'Mission route' : 'Live topology'}

{wallMode === 'handoff' ? 'Mission-handoff operator wall' : 'Eleven-stack operator wall'}

Mission {st.running[0] ? fmtId(st.running[0].task_id) : 'ready'} 0 ? 'route-attention' : 'route-ready'}> {attentionCount > 0 ? `${attentionCount} gate(s)` : 'clear'}
Coverage
{[runtimeCoverage.host, runtimeCoverage.container, runtimeCoverage.vm].filter(Boolean).length}/3
Executor
{st.executor || 'unknown'}
Control
{runningInstances.some((i) => i.session_backends.some((b) => b.available && b.drive)) ? 'drive available' : 'observe first'}
Quota
{st.cost ? `$${st.cost.total.usd.toFixed(2)}` : 'n/a'}
Gates
{attentionCount > 0 ? `${attentionCount} attention` : 'clear'}
{runningInstances.slice(0, 6).map((i) => { const task = st.running.find((r) => r.instance_id === i.id); const cost = st.cost?.per_instance.find((c) => c.instance_id === i.id); const drive = i.session_backends.some((b) => b.available && b.drive); return (
{task ? `task ${fmtId(task.task_id)} · ${task.state}` : 'idle · ready for session attach'} {i.transport.label} · {i.transport.mode} {drive ? 'Drive enabled' : 'Observe only'}
{cost ? `$${cost.usd.toFixed(2)}` : 'cost n/a'}
); })}

Guided start

Pick stack, runtime, and task posture.

Plan: {startPlan}

{st.approvals.length > 0 && }
)} {firstRun && (

Three things to know

  1. Sessions are where work happens — attach to observe, take the wheel to drive. Output mirrors to every viewer.
  2. Actions and the + capability picker drop a command into a session; the agent runs it. The Cockpit never runs the CLI.
  3. Explore browses the read-only AIWG catalog. Your own copied/imported assets live in your library — AIWG files are never overwritten.
)}
); } function inventoryWarning(inv: InventoryEnvelope) { const admin = inv.admin_error; return [ inv.degraded_admin_inventory, admin?.code, admin?.title, admin?.detail, ].filter(Boolean).join(' · ') || undefined; } function runtimeFamily(instance: Instance): string { const family = runtimeTargetFamily(instance.runtime_posture?.kind ?? instance.runtime); if (family === 'host') return 'terminal'; if (family === 'vm' || family === 'container') return 'cube'; return 'window'; } function accentFor(value: string): number { let sum = 0; for (const ch of value) sum += ch.charCodeAt(0); return (sum % 4) + 1; } function orbitStyle(node: OrbitNode): OrbitStyle { return { '--x': `${node.x}%`, '--y': `${node.y}%` }; } function initialWallMode(): WallReviewMode { const wall = new URLSearchParams(window.location.search).get('wall'); return wall === 'handoff' ? 'handoff' : 'topology'; } function buildOrbitNodes(st: Status | null): OrbitNode[] { const running = st?.instances.filter((i) => i.state === 'running') ?? []; const host = st?.instances.find((i) => runtimeTargetFamily(i.runtime_posture?.kind ?? i.runtime) === 'host'); const container = st?.instances.find((i) => runtimeTargetFamily(i.runtime_posture?.kind ?? i.runtime) === 'container'); const vm = st?.instances.find((i) => runtimeTargetFamily(i.runtime_posture?.kind ?? i.runtime) === 'vm'); const drive = st?.instances.some((i) => i.session_backends.some((b) => b.available && b.drive)) ?? false; const approvals = st?.approvals.length ?? 0; const cost = st?.cost?.total?.usd; const base: Omit[] = [ { key: 'host', label: host?.loadout || 'Host CLI', meta: host ? `${fmtId(host.id)} · ${host.state}` : 'not connected', family: 'host', tab: 'inventory', state: host ? 'running' : 'blocked', }, { key: 'vm', label: vm?.loadout || 'VM sandbox', meta: vm ? `${fmtId(vm.id)} · ${vm.state}` : 'not connected', family: 'vm', tab: 'inventory', state: vm ? 'running' : 'blocked', }, { key: 'container', label: container?.loadout || 'Docker runtime', meta: container ? `${fmtId(container.id)} · ${container.state}` : 'not connected', family: 'container', tab: 'inventory', state: container ? 'running' : 'blocked', }, { key: 'mission', label: 'Mission handoff', meta: st?.running[0] ? `${fmtId(st.running[0].task_id)} · ${st.running[0].state}` : 'ready', family: 'mission', tab: 'running', state: st?.running.length ? 'running' : 'ready', }, { key: 'approvals', label: 'Approvals', meta: approvals ? `${approvals} pending` : 'clear', family: 'approval', tab: 'approvals', state: approvals ? 'attention' : 'ready', }, { key: 'cost', label: 'Cost & quota', meta: cost === undefined ? 'metrics n/a' : `$${cost.toFixed(2)}`, family: 'cost', tab: 'running', state: cost === undefined ? 'idle' : 'ready', }, { key: 'capabilities', label: 'Capability search', meta: 'catalog ready', family: 'capability', tab: 'explore', state: 'ready', }, { key: 'library', label: 'Library', meta: 'workspace assets', family: 'library', tab: 'library', state: 'ready', }, { key: 'actions', label: 'Actions', meta: drive ? 'drive available' : 'observe first', family: 'action', tab: 'actions', state: drive ? 'ready' : 'idle', }, { key: 'sessions', label: 'Sessions', meta: running.length ? `${running.length} attachable` : 'none active', family: 'session', tab: 'sessions', state: running.length ? 'running' : 'idle', }, { key: 'inventory', label: 'Inventory', meta: `${st?.instances.length ?? 0} registered`, family: 'inventory', tab: 'inventory', state: st?.instances.length ? 'ready' : 'idle', }, ]; return base.map((node, index) => ({ ...node, x: ORBIT_POSITIONS[index][0], y: ORBIT_POSITIONS[index][1] })); }