@opengeni/react 3.7.0-canary.7 → 3.8.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +6 -0
  2. package/dist/chat.js +1 -1
  3. package/dist/chunk-5M6VTFJ5.js +171 -0
  4. package/dist/chunk-5M6VTFJ5.js.map +1 -0
  5. package/dist/{chunk-IOLVN74D.js → chunk-6J56T3MG.js} +15 -1
  6. package/dist/chunk-6J56T3MG.js.map +1 -0
  7. package/dist/{chunk-BQGIXRKV.js → chunk-7BWFU6H4.js} +22 -4
  8. package/dist/chunk-7BWFU6H4.js.map +1 -0
  9. package/dist/{chunk-3HIF5IFC.js → chunk-7W6PVVTK.js} +63 -18
  10. package/dist/chunk-7W6PVVTK.js.map +1 -0
  11. package/dist/{chunk-ZFOFY5ST.js → chunk-NLTS7JHI.js} +16 -31
  12. package/dist/chunk-NLTS7JHI.js.map +1 -0
  13. package/dist/chunk-NOSYBS2D.js +208 -0
  14. package/dist/chunk-NOSYBS2D.js.map +1 -0
  15. package/dist/{chunk-F2CFHN3Y.js → chunk-YAIPFO5D.js} +2 -1
  16. package/dist/chunk-YAIPFO5D.js.map +1 -0
  17. package/dist/chunk-YBM6CQRU.js +292 -0
  18. package/dist/chunk-YBM6CQRU.js.map +1 -0
  19. package/dist/chunk-ZYRGEKWS.js +216 -0
  20. package/dist/chunk-ZYRGEKWS.js.map +1 -0
  21. package/dist/components/composer.d.ts +4 -2
  22. package/dist/components/message-timeline.d.ts +9 -2
  23. package/dist/components/timeline-annotation-chrome.d.ts +25 -0
  24. package/dist/components/timeline-annotation-layout.d.ts +42 -0
  25. package/dist/components/timeline-annotation-markers.d.ts +8 -0
  26. package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
  27. package/dist/components/timeline-annotation-shared.d.ts +31 -0
  28. package/dist/components/timeline-annotations-dialog.d.ts +1 -1
  29. package/dist/components/timeline-annotations.d.ts +8 -2
  30. package/dist/composer.js +2 -2
  31. package/dist/hooks/use-composer.d.ts +2 -0
  32. package/dist/index.js +9 -6
  33. package/dist/index.js.map +1 -1
  34. package/dist/interaction.js +6 -6
  35. package/dist/machines.js +1 -1
  36. package/dist/{queue-surface-implementation-XL2A6PBM.js → queue-surface-implementation-LK3S4BIW.js} +5 -2
  37. package/dist/{queue-surface-implementation-XL2A6PBM.js.map → queue-surface-implementation-LK3S4BIW.js.map} +1 -1
  38. package/dist/session-ui.js +8 -5
  39. package/dist/session.js +1 -1
  40. package/dist/timeline-annotation-markers-DRSTLEM6.js +165 -0
  41. package/dist/timeline-annotation-markers-DRSTLEM6.js.map +1 -0
  42. package/dist/timeline-annotation-selection-IHLUGVND.js +236 -0
  43. package/dist/timeline-annotation-selection-IHLUGVND.js.map +1 -0
  44. package/dist/timeline-annotations-dialog-6Q53N5FG.js +262 -0
  45. package/dist/timeline-annotations-dialog-6Q53N5FG.js.map +1 -0
  46. package/package.json +2 -2
  47. package/src/components/chat-composer.tsx +5 -2
  48. package/src/components/composer.tsx +40 -5
  49. package/src/components/copy-button.tsx +1 -0
  50. package/src/components/machines-dashboard.tsx +1 -16
  51. package/src/components/message-timeline.tsx +357 -297
  52. package/src/components/timeline-annotation-chrome.tsx +183 -0
  53. package/src/components/timeline-annotation-layout.ts +268 -0
  54. package/src/components/timeline-annotation-markers.tsx +185 -0
  55. package/src/components/timeline-annotation-reveal-context.ts +9 -0
  56. package/src/components/timeline-annotation-selection.tsx +99 -54
  57. package/src/components/timeline-annotation-shared.ts +245 -0
  58. package/src/components/timeline-annotations-dialog.tsx +172 -128
  59. package/src/components/timeline-annotations.tsx +178 -45
  60. package/src/hooks/use-composer.ts +17 -0
  61. package/styles/compiled.css +86 -22
  62. package/dist/chunk-3HIF5IFC.js.map +0 -1
  63. package/dist/chunk-BQGIXRKV.js.map +0 -1
  64. package/dist/chunk-F2CFHN3Y.js.map +0 -1
  65. package/dist/chunk-IOLVN74D.js.map +0 -1
  66. package/dist/chunk-W3OUAH6M.js +0 -170
  67. package/dist/chunk-W3OUAH6M.js.map +0 -1
  68. package/dist/chunk-ZFOFY5ST.js.map +0 -1
  69. package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
  70. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
  71. package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
  72. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types/machines.ts","../src/components/machine-status-pill.tsx","../src/components/machine-metrics.tsx","../src/components/machine-card.tsx","../src/components/machines/health.ts","../src/components/machine-health-pill.tsx","../src/components/machines/metric-sparkline.tsx","../src/components/machines/metric-history-chart.tsx","../src/components/machines/machine-detail.tsx","../src/components/machines/series.ts","../src/components/machines/machine-operation-policy.tsx","../src/components/machines-dashboard.tsx","../src/components/machine-dock-bar.tsx","../src/components/enrollment-device-flow.tsx","../src/components/enrollment-consent.tsx","../src/hooks/use-machines.ts","../src/hooks/shared-machines-list.ts"],"sourcesContent":["// ----------------------------------------------------------------------------\n// Bring-your-own-compute — Machines view-model.\n//\n// The data-contract types (MachineView / MetricSample / MachinesResponse /\n// MachineMetricsSeriesResponse / MachineKind / MachineState) are the\n// orchestrator-owned SHARED DATA CONTRACT that M10 ships in `@opengeni/sdk`\n// (hand-written mirrors of `@opengeni/contracts`, pinned by contract-parity).\n// M9 RE-EXPORTS them here so the dashboard UI imports a single, stable name and\n// never drifts from the API — exactly as the contract intends.\n//\n// (During concurrent M9/M10 development this module briefly carried a local\n// view-model with the same field names; once M10 landed the SDK types we\n// reconciled to re-export them — the field names were identical by design.)\n//\n// Endpoints these model (M10 owns the SDK client methods):\n// GET /v1/workspaces/:ws/machines -> MachinesResponse\n// GET /v1/workspaces/:ws/machines/:enrollmentId/metrics/series?window=1h\n// -> { samples: MetricSample[] }\n// ----------------------------------------------------------------------------\nimport type {\n MachineKind,\n MachineMetricsSeriesResponse,\n MachinesResponse,\n MachineState,\n MachineView,\n MachineRuntime,\n MachineRuntimeCapabilities,\n MachineOperationPolicy,\n MachineUpdateState,\n MachineUpdateStatus,\n MetricSample,\n} from \"@opengeni/sdk\";\n\nexport type {\n MachineKind,\n MachineMetricsSeriesResponse,\n MachinesResponse,\n MachineState,\n MachineView,\n MachineRuntime,\n MachineRuntimeCapabilities,\n MachineOperationPolicy,\n MachineUpdateState,\n MachineUpdateStatus,\n MetricSample,\n};\n\n// --- connection-status grouping (a PURE UI projection — not a contract type) --\n\n/**\n * The three connection-status pill values the UI surfaces across the dashboard,\n * the dock, and the timeline. `consent_required` / `display_unavailable` /\n * `enrolling` are NOT connection states — they map onto a connection state for\n * the pill and carry their own badge separately.\n */\nexport type ConnectionStatus = \"online\" | \"reconnecting\" | \"offline\";\n\n/** Project a machine `state` onto its connection-status pill value. */\nexport function connectionStatusForState(state: MachineState): ConnectionStatus {\n switch (state) {\n case \"online\":\n case \"consent_required\":\n case \"display_unavailable\":\n // The control plane is reachable; the limitation is consent / no display.\n return \"online\";\n case \"reconnecting\":\n case \"enrolling\":\n return \"reconnecting\";\n case \"offline\":\n return \"offline\";\n default: {\n // Exhaustiveness guard — a new state must be classified explicitly.\n const _never: never = state;\n return _never;\n }\n }\n}\n","import { cn } from \"../lib/cn\";\nimport {\n type ConnectionStatus,\n connectionStatusForState,\n type MachineState,\n} from \"../types/machines\";\n\nexport type ConnectionStatusMeta = {\n label: string;\n dotClassName: string;\n badgeClassName: string;\n /** Live/transient states breathe; settled states hold still. */\n pulse: boolean;\n};\n\n/** Token-backed meta for the three connection-status pill values. */\nexport const CONNECTION_STATUS_META: Record<ConnectionStatus, ConnectionStatusMeta> = {\n online: {\n label: \"Online\",\n dotClassName: \"bg-og-status-running\",\n badgeClassName: \"text-og-status-running border-og-status-running/30 bg-og-status-running/10\",\n pulse: false,\n },\n reconnecting: {\n label: \"Reconnecting\",\n dotClassName: \"bg-og-status-waiting\",\n badgeClassName: \"text-og-status-waiting border-og-status-waiting/35 bg-og-status-waiting/10\",\n pulse: true,\n },\n offline: {\n label: \"Offline\",\n dotClassName: \"bg-og-status-failed\",\n badgeClassName: \"text-og-fg-subtle border-og-border bg-og-status-failed/10\",\n pulse: false,\n },\n};\n\nexport type MachineStateBadgeMeta = {\n label: string;\n badgeClassName: string;\n};\n\n/**\n * The non-connection state badges that ride ALONGSIDE the connection pill —\n * `consent_required` / `display_unavailable` / `enrolling` describe a capability\n * limitation, not reachability, so they render as their own tinted chip.\n */\nexport const MACHINE_STATE_BADGE_META: Partial<Record<MachineState, MachineStateBadgeMeta>> = {\n consent_required: {\n label: \"Consent required\",\n badgeClassName: \"text-og-status-waiting border-og-status-waiting/35 bg-og-status-waiting/10\",\n },\n display_unavailable: {\n label: \"No display\",\n badgeClassName: \"text-og-fg-muted border-og-border bg-og-surface-2\",\n },\n enrolling: {\n label: \"Enrolling\",\n badgeClassName: \"text-og-accent border-og-accent/30 bg-og-accent-soft\",\n },\n};\n\nexport type ConnectionStatusPillProps = {\n status: ConnectionStatus;\n /** Override the label (\"Online\" -> \"Connected\", ...). */\n label?: string | undefined;\n size?: \"sm\" | \"md\" | undefined;\n className?: string | undefined;\n};\n\n/**\n * The connection-status pill (online / reconnecting / offline) surfaced across\n * the Machines dashboard, the dock header, and the session timeline. Reconnecting\n * breathes (the resiliency-as-headline blip), online/offline hold still.\n */\nexport function ConnectionStatusPill({\n status,\n label,\n size = \"md\",\n className,\n}: ConnectionStatusPillProps) {\n const meta = CONNECTION_STATUS_META[status];\n return (\n <span\n data-connection-status={status}\n className={cn(\n \"og-root inline-flex shrink-0 items-center rounded-full border font-medium\",\n size === \"sm\" ? \"gap-1 px-1.5 py-px text-og-xs\" : \"gap-1.5 px-2 py-0.5 text-og-sm\",\n meta.badgeClassName,\n className,\n )}\n >\n <ConnectionDot status={status} className={size === \"sm\" ? \"size-1\" : \"size-1.5\"} />\n {label ?? meta.label}\n </span>\n );\n}\n\nexport type ConnectionDotProps = {\n status: ConnectionStatus;\n className?: string | undefined;\n};\n\n/** Just the dot — for dense rows, the dock header, and timeline notices. */\nexport function ConnectionDot({ status, className }: ConnectionDotProps) {\n const meta = CONNECTION_STATUS_META[status];\n return (\n <span\n className={cn(\n \"relative inline-flex size-1.5 shrink-0 rounded-full\",\n meta.dotClassName,\n className,\n )}\n >\n {meta.pulse ? (\n <span className={cn(\"absolute inset-0 animate-og-pulse rounded-full\", meta.dotClassName)} />\n ) : null}\n </span>\n );\n}\n\nexport type MachineStatusPillProps = {\n /** The machine's full state — drives the connection pill + any state badge. */\n state: MachineState;\n /** How many live sessions share this lease (renders a \"Shared\" chip when >1). */\n sharedSessionCount?: number | undefined;\n size?: \"sm\" | \"md\" | undefined;\n className?: string | undefined;\n};\n\n/**\n * The composite machine status surface: the connection pill PLUS any\n * consent/display/enrolling badge PLUS a shared-in-use chip. One component the\n * dashboard row, the dock header, and the timeline all reuse so the status\n * language is identical everywhere.\n */\nexport function MachineStatusPill({\n state,\n sharedSessionCount,\n size = \"md\",\n className,\n}: MachineStatusPillProps) {\n const stateBadge = MACHINE_STATE_BADGE_META[state];\n const shared = (sharedSessionCount ?? 0) > 1;\n return (\n <span\n className={cn(\"og-root inline-flex flex-wrap items-center gap-1\", className)}\n data-machine-state={state}\n >\n <ConnectionStatusPill status={connectionStatusForState(state)} size={size} />\n {stateBadge ? (\n <span\n data-state-badge={state}\n className={cn(\n \"inline-flex shrink-0 items-center rounded-full border font-medium\",\n size === \"sm\" ? \"px-1.5 py-px text-og-xs\" : \"px-2 py-0.5 text-og-sm\",\n stateBadge.badgeClassName,\n )}\n >\n {stateBadge.label}\n </span>\n ) : null}\n {shared ? (\n <span\n data-shared-chip\n className={cn(\n \"inline-flex shrink-0 items-center gap-1 rounded-full border font-medium\",\n \"text-og-accent border-og-accent/30 bg-og-accent-soft\",\n size === \"sm\" ? \"px-1.5 py-px text-og-xs\" : \"px-2 py-0.5 text-og-sm\",\n )}\n title={`${sharedSessionCount} sessions are on this machine`}\n >\n Shared · {sharedSessionCount}\n </span>\n ) : null}\n </span>\n );\n}\n","import { cn } from \"../lib/cn\";\nimport { formatBytes } from \"../lib/format\";\nimport type { MetricSample } from \"../types/machines\";\n\nexport type MachineMetricsProps = {\n /** The latest metric sample, or null when the machine hasn't reported yet. */\n metrics: MetricSample | null;\n /** Compact (dashboard row) vs full (the dock detail). */\n density?: \"compact\" | \"full\" | undefined;\n className?: string | undefined;\n};\n\n/** Clamp a 0..100-ish percent into the bar range. */\nfunction pct(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.max(0, Math.min(100, value));\n}\n\n/** A label/value pair with a token-tinted utilisation bar. */\nfunction Meter({\n label,\n value,\n fillPct,\n tone,\n}: {\n label: string;\n value: string;\n fillPct: number;\n tone: \"ok\" | \"warn\" | \"hot\";\n}) {\n // Traffic-light ramp, aligned with the fused health verdict: calm resources\n // read green (idle), pressure ambers (running), near-the-wall reds (failed).\n const fillClass =\n tone === \"hot\"\n ? \"bg-og-status-failed\"\n : tone === \"warn\"\n ? \"bg-og-status-running\"\n : \"bg-og-status-idle\";\n return (\n <div className=\"flex min-w-0 flex-col gap-1\" data-metric={label.toLowerCase()}>\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n {label}\n </span>\n <span className=\"font-og-mono text-[11px] tabular-nums text-og-fg-muted\">{value}</span>\n </div>\n <div className=\"h-1 w-full overflow-hidden rounded-full bg-og-surface-2\">\n <div\n className={cn(\"h-full rounded-full transition-[width] duration-500\", fillClass)}\n style={{ width: `${pct(fillPct)}%` }}\n />\n </div>\n </div>\n );\n}\n\n/** Map a percent to a calm/warn/hot tone (no color invented — token classes). */\nfunction toneFor(p: number): \"ok\" | \"warn\" | \"hot\" {\n if (p >= 90) return \"hot\";\n if (p >= 70) return \"warn\";\n return \"ok\";\n}\n\n/**\n * Load average as three labeled mini-stats (1m / 5m / 15m) — an honest triple of\n * numbers, NOT a fake gauge. Load is not a 0..100 ratio and we don't know the\n * core count, so a raw load of 2 or 8 is not inherently \"bad\" — we render it\n * NEUTRAL rather than falsely alarming. The real saturation signal is the run\n * queue, which rides alongside as a quiet chip when there's pending work.\n */\nfunction StatTriple({\n load1,\n load5,\n load15,\n runQueue,\n}: {\n load1: number;\n load5: number;\n load15: number;\n runQueue: number;\n}) {\n const stats: Array<{ label: string; value: number }> = [\n { label: \"1m\", value: load1 },\n { label: \"5m\", value: load5 },\n { label: \"15m\", value: load15 },\n ];\n return (\n <div className=\"flex items-center justify-between gap-3\" data-metric=\"load\">\n <div className=\"flex min-w-0 flex-col gap-1\">\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n Load\n </span>\n <div className=\"flex items-baseline gap-3\">\n {stats.map((s) => (\n <div key={s.label} className=\"flex items-baseline gap-1\">\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n {s.label}\n </span>\n <span className=\"font-og-mono text-[12px] tabular-nums text-og-fg\">\n {s.value.toFixed(2)}\n </span>\n </div>\n ))}\n </div>\n </div>\n {runQueue > 0 ? (\n <div\n className=\"flex shrink-0 items-baseline gap-1.5 rounded-og-sm bg-og-surface-2 px-2 py-1 text-[11px] text-og-fg-subtle\"\n data-metric=\"runqueue\"\n >\n <span className=\"font-medium uppercase tracking-wide\">Queue</span>\n <span className=\"font-og-mono tabular-nums text-og-fg-muted\">{runQueue}</span>\n </div>\n ) : null}\n </div>\n );\n}\n\n/**\n * Per-machine resource meters: CPU%, load average, memory, disk, and GPU when\n * present. Renders the M2 `machine_metrics_latest` sample. When `metrics` is\n * null the panel shows a quiet \"no samples yet\" placeholder (offline / just\n * enrolled). GPU rows only render when `gpuUtilPct` is non-null.\n */\nexport function MachineMetrics({ metrics, density = \"compact\", className }: MachineMetricsProps) {\n if (!metrics) {\n return (\n <div className={cn(\"text-[11px] text-og-fg-subtle\", className)} data-metrics-empty>\n No metrics yet\n </div>\n );\n }\n\n const memPct =\n metrics.memTotalBytes > 0 ? (metrics.memUsedBytes / metrics.memTotalBytes) * 100 : 0;\n const diskPct =\n metrics.diskTotalBytes > 0 ? (metrics.diskUsedBytes / metrics.diskTotalBytes) * 100 : 0;\n const hasGpu = metrics.gpuUtilPct !== null;\n const gpuMemLabel = metrics.gpuMemBytes !== null ? formatBytes(metrics.gpuMemBytes) : null;\n // Memory & disk are honest used/total ratios → full-width meters; stack them in\n // the dock detail, two-up in the dashboard row.\n const ratioGridClass = density === \"full\" ? \"grid-cols-1\" : \"grid-cols-1 sm:grid-cols-2\";\n\n return (\n <div className={cn(\"flex flex-col gap-3\", className)} data-machine-metrics>\n {/* Resources — used/total ratios with real 0..100% bars. */}\n <div className={cn(\"grid gap-x-4 gap-y-2.5\", ratioGridClass)}>\n <Meter\n label=\"Memory\"\n value={`${formatBytes(metrics.memUsedBytes)} / ${formatBytes(metrics.memTotalBytes)}`}\n fillPct={memPct}\n tone={toneFor(memPct)}\n />\n <Meter\n label=\"Disk\"\n value={`${formatBytes(metrics.diskUsedBytes)} / ${formatBytes(metrics.diskTotalBytes)}`}\n fillPct={diskPct}\n tone={toneFor(diskPct)}\n />\n </div>\n\n {/* Utilization — CPU% (and GPU% when present) as honest percent gauges. */}\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-2.5\">\n <Meter\n label=\"CPU\"\n value={`${metrics.cpuPct.toFixed(0)}%`}\n fillPct={metrics.cpuPct}\n tone={toneFor(metrics.cpuPct)}\n />\n {hasGpu ? (\n <Meter\n label=\"GPU\"\n value={\n gpuMemLabel\n ? `${metrics.gpuUtilPct!.toFixed(0)}% · ${gpuMemLabel}`\n : `${metrics.gpuUtilPct!.toFixed(0)}%`\n }\n fillPct={metrics.gpuUtilPct!}\n tone={toneFor(metrics.gpuUtilPct!)}\n />\n ) : null}\n </div>\n\n {/* Activity — load average as labeled mini-stats (no fake bar) + run queue. */}\n <StatTriple\n load1={metrics.load1}\n load5={metrics.load5}\n load15={metrics.load15}\n runQueue={metrics.runQueue}\n />\n </div>\n );\n}\n","import {\n AlertTriangleIcon,\n ArrowRightIcon,\n CpuIcon,\n CircleCheckIcon,\n DownloadIcon,\n LaptopIcon,\n MonitorIcon,\n MonitorOffIcon,\n LoaderCircleIcon,\n ServerIcon,\n UsersIcon,\n} from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { formatRelativeTime } from \"../lib/format\";\nimport type { MachineView, MetricSample } from \"../types/machines\";\nimport { MachineHealthPill } from \"./machine-health-pill\";\nimport { MachineMetrics } from \"./machine-metrics\";\nimport { MetricSparkline } from \"./machines/metric-sparkline\";\n\nexport type MachineCardProps = {\n machine: MachineView;\n /** Attach/swap the session's active sandbox to this machine. */\n onAttach?: ((machine: MachineView) => void) | undefined;\n /** Whether an attach/swap is currently in flight (disables the affordance). */\n attaching?: boolean | undefined;\n /** Start/retry the exact signed Connected Machine agent update. */\n onUpdateAgent?: ((machine: MachineView) => void) | undefined;\n updatingAgent?: boolean | undefined;\n /** Short recent history (e.g. 15m) — drives the card's CPU trend + preview. */\n series?: MetricSample[] | undefined;\n /** Open the full per-machine telemetry detail. Makes the whole card actionable. */\n onOpenDetail?: ((machine: MachineView) => void) | undefined;\n now?: number | undefined;\n className?: string | undefined;\n};\n\nfunction KindIcon({ machine }: { machine: MachineView }) {\n if (machine.isSessionGroup)\n return <ServerIcon className=\"size-4 text-og-fg-subtle\" aria-hidden />;\n if (machine.kind === \"modal\") return <CpuIcon className=\"size-4 text-og-fg-subtle\" aria-hidden />;\n return <LaptopIcon className=\"size-4 text-og-fg-subtle\" aria-hidden />;\n}\n\n/**\n * One machine in the Machines dashboard: name + kind + OS/arch, the fused HEALTH\n * verdict, latest resource meters, a CPU trend that previews the history, live\n * freshness, and attach/swap. The whole card opens the telemetry detail when\n * `onOpenDetail` is wired. The session's active sandbox carries an accent edge.\n */\nexport function MachineCard({\n machine,\n onAttach,\n attaching,\n onUpdateAgent,\n updatingAgent,\n series,\n onOpenDetail,\n now,\n className,\n}: MachineCardProps) {\n const offline = machine.state === \"offline\";\n const attachable = !machine.active && !offline && Boolean(onAttach);\n const shared = machine.sharedSessionCount > 1;\n const clockNow = now ?? Date.now();\n const sampledAgo = machine.metrics\n ? formatRelativeTime(machine.metrics.sampledAt, new Date(clockNow))\n : null;\n const cpuPts = (series ?? []).map((s) => ({ t: new Date(s.sampledAt).getTime(), v: s.cpuPct }));\n const openable = Boolean(onOpenDetail);\n const runtime = machine.runtime;\n const updateRunning = runtime?.versionState === \"updating\";\n const dispatchConfirmationStalled =\n runtime?.update?.status === \"requested\" &&\n clockNow - new Date(runtime.update.updatedAt).getTime() >= 30_000;\n const canUpdate =\n Boolean(machine.enrollmentId && onUpdateAgent) &&\n !offline &&\n (runtime?.versionState === \"outdated\" ||\n runtime?.versionState === \"update_failed\" ||\n dispatchConfirmationStalled);\n const updateLabel = (() => {\n const update = runtime?.update;\n if (!update) return null;\n switch (update.status) {\n case \"requested\":\n return dispatchConfirmationStalled ? \"Agent confirmation delayed\" : \"Confirming with agent\";\n case \"accepted\":\n return \"Update accepted\";\n case \"waiting_for_idle\":\n return \"Waiting for current work\";\n case \"downloading\":\n case \"verifying\":\n case \"applying\":\n return `${update.status}…`;\n case \"restarting\":\n return \"Restarting agent\";\n case \"succeeded\":\n return `Updated · v${update.targetVersion}`;\n case \"failed\": {\n const detail = update.errorCode?.replaceAll(\"_\", \" \");\n return update.rolledBack\n ? `Update rolled back safely${detail ? ` · ${detail}` : \"\"}`\n : `Update failed${detail ? ` · ${detail}` : \"\"}`;\n }\n }\n })();\n\n return (\n <div\n data-machine-card={machine.sandboxId}\n data-active={machine.active ? \"true\" : \"false\"}\n role={openable ? \"button\" : undefined}\n tabIndex={openable ? 0 : undefined}\n onClick={openable ? () => onOpenDetail?.(machine) : undefined}\n onKeyDown={\n openable\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onOpenDetail?.(machine);\n }\n }\n : undefined\n }\n className={cn(\n \"og-root group relative flex flex-col gap-3 overflow-hidden rounded-og-lg border border-og-border\",\n \"bg-og-surface-1 p-4 shadow-og-sm transition-colors\",\n openable &&\n \"cursor-pointer hover:border-og-border-strong focus-visible:border-og-accent/60 focus-visible:outline-hidden\",\n machine.active && \"border-og-accent/40\",\n className,\n )}\n >\n {machine.active ? (\n <span aria-hidden className=\"absolute inset-y-0 left-0 w-0.5 bg-og-accent\" />\n ) : null}\n\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span className=\"mt-0.5 shrink-0\">\n <KindIcon machine={machine} />\n </span>\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate text-og-base font-medium text-og-fg\">{machine.name}</span>\n {machine.active ? (\n <span\n data-active-marker\n className=\"shrink-0 rounded-full border border-og-accent/30 bg-og-accent-soft px-1.5 py-px text-og-xs font-medium text-og-accent\"\n >\n Active\n </span>\n ) : null}\n </div>\n <div className=\"mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-og-xs text-og-fg-subtle\">\n <span data-machine-scope={machine.scope} className=\"capitalize\">\n {machine.scope === \"user\" ? \"personal\" : machine.scope}\n </span>\n <span aria-hidden>·</span>\n <span className=\"capitalize\">\n {machine.isSessionGroup ? \"session sandbox\" : machine.kind}\n </span>\n <span aria-hidden>·</span>\n <span className=\"font-og-mono\">\n {machine.os}/{machine.arch}\n </span>\n <span aria-hidden>·</span>\n <span className=\"inline-flex items-center gap-1\">\n {machine.hasDisplay ? (\n <MonitorIcon className=\"size-3\" aria-hidden />\n ) : (\n <MonitorOffIcon className=\"size-3\" aria-hidden />\n )}\n {machine.hasDisplay ? \"display\" : \"headless\"}\n </span>\n </div>\n </div>\n </div>\n <MachineHealthPill\n state={machine.state}\n metrics={machine.metrics}\n now={clockNow}\n size=\"sm\"\n className=\"shrink-0\"\n />\n </div>\n\n {shared ? (\n <p\n data-shared-disclosure\n className=\"flex items-center gap-1.5 rounded-og-md border border-og-accent/25 bg-og-accent-soft px-2.5 py-1.5 text-og-xs text-og-fg-muted\"\n >\n <UsersIcon className=\"size-3.5 shrink-0 text-og-accent\" aria-hidden />\n Shared — {machine.sharedSessionCount} sessions are on this machine.\n </p>\n ) : null}\n\n {machine.connectionAuthority.duplicateRunnerDeniedCount > 0 ? (\n <p\n data-runner-conflict\n className=\"flex items-center gap-1.5 rounded-og-md border border-og-status-failed/30 bg-og-status-failed/5 px-2.5 py-1.5 text-og-xs text-og-status-failed\"\n >\n <AlertTriangleIcon className=\"size-3.5 shrink-0\" aria-hidden />\n Competing agent process blocked. Open diagnostics for details.\n </p>\n ) : null}\n\n {runtime ? (\n <div\n data-agent-runtime\n className=\"flex items-center justify-between gap-3 rounded-og-md border border-og-border/70 bg-og-surface-2/35 px-2.5 py-2 text-og-xs\"\n >\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1.5 text-og-fg-muted\">\n {runtime.versionState === \"current\" ? (\n <CircleCheckIcon className=\"size-3.5 text-og-status-idle\" aria-hidden />\n ) : updateRunning ? (\n <LoaderCircleIcon className=\"size-3.5 animate-og-spin text-og-accent\" aria-hidden />\n ) : (\n <DownloadIcon className=\"size-3.5\" aria-hidden />\n )}\n <span className=\"truncate\">\n Agent{\" \"}\n {runtime.installedVersion ? `v${runtime.installedVersion}` : \"version unknown\"}\n </span>\n </div>\n <p className=\"mt-0.5 truncate text-og-fg-subtle\">\n {updateLabel ??\n (runtime.versionState === \"current\"\n ? `Current · ${runtime.updateChannel ?? \"channel unknown\"}`\n : runtime.desiredVersion\n ? `Promoted v${runtime.desiredVersion}`\n : \"No promoted version configured\")}\n </p>\n </div>\n {canUpdate ? (\n <button\n type=\"button\"\n data-update-agent\n disabled={updatingAgent}\n onClick={(event) => {\n event.stopPropagation();\n onUpdateAgent?.(machine);\n }}\n className=\"shrink-0 rounded-og-sm border border-og-border px-2 py-1 font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n {updatingAgent\n ? \"Starting…\"\n : dispatchConfirmationStalled\n ? \"Retry delivery\"\n : runtime.versionState === \"update_failed\"\n ? \"Retry\"\n : \"Update\"}\n </button>\n ) : null}\n </div>\n ) : null}\n\n <MachineMetrics metrics={machine.metrics} />\n\n {/* CPU trend — previews the history and invites opening the detail. */}\n {cpuPts.length > 1 ? (\n <div className=\"flex flex-col gap-1 rounded-og-md bg-og-surface-2/40 p-2.5\">\n <div className=\"flex items-center justify-between text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n <span>CPU · last 15m</span>\n {openable ? (\n <span className=\"flex items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100\">\n Telemetry <ArrowRightIcon className=\"size-2.5\" aria-hidden />\n </span>\n ) : null}\n </div>\n <MetricSparkline points={cpuPts} color=\"var(--og-color-accent)\" yMax={100} height={26} />\n </div>\n ) : null}\n\n <div className=\"mt-1 flex items-center justify-between gap-3 text-og-xs text-og-fg-subtle\">\n <span className=\"inline-flex items-center gap-1.5\">\n {sampledAgo ? (\n <>\n <span\n className={cn(\n \"size-1.5 rounded-full\",\n sampledAgo === \"now\" ? \"bg-og-status-idle\" : \"bg-og-fg-subtle\",\n )}\n aria-hidden\n />\n {sampledAgo === \"now\" ? \"Live\" : `Updated ${sampledAgo} ago`}\n </>\n ) : machine.lastSeenAt ? (\n <>Last seen {formatRelativeTime(machine.lastSeenAt, new Date(clockNow))}</>\n ) : (\n \"Never connected\"\n )}\n </span>\n {machine.active ? (\n <span className=\"text-og-accent\">Routing here</span>\n ) : attachable ? (\n <button\n type=\"button\"\n data-attach\n disabled={attaching}\n onClick={(e) => {\n e.stopPropagation();\n onAttach?.(machine);\n }}\n className={cn(\n \"rounded-og-sm border border-og-border px-2.5 py-1 text-og-xs font-medium text-og-fg-muted transition-colors pointer-coarse:min-h-11\",\n \"hover:border-og-border-strong hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50\",\n )}\n >\n {attaching ? \"Switching…\" : \"Attach\"}\n </button>\n ) : (\n <span className=\"text-og-fg-subtle/70\">{offline ? \"Unavailable\" : \"—\"}</span>\n )}\n </div>\n </div>\n );\n}\n","// ----------------------------------------------------------------------------\n// Machine health — the single derived signal.\n//\n// The dashboard already shows connection state (a pill) and per-resource meters\n// (independently tinted). What it lacks is ONE verdict that fuses the three\n// things that actually make a machine \"in trouble\":\n//\n// 1. reachability — is the control plane still hearing from it?\n// 2. resource load — is a resource (mem/disk/cpu) near the wall?\n// 3. freshness — is the latest sample recent, or has telemetry gone quiet?\n//\n// This module is a PURE function from a machine's state + latest sample + clock\n// to a `HealthVerdict`. No React, no tokens — the UI maps `level` to a color.\n// Keeping it pure means it is trivially testable and reused by cards, the detail\n// hero, and any future fleet-summary count.\n// ----------------------------------------------------------------------------\nimport type { MachineState, MetricSample } from \"../../types/machines\";\n\nexport type HealthLevel = \"healthy\" | \"degraded\" | \"critical\" | \"offline\" | \"unknown\";\n\nexport type HealthVerdict = {\n level: HealthLevel;\n /** Title-case label for the pill (\"Healthy\", \"Under load\", \"Critical\", …). */\n label: string;\n /** One short human clause naming the dominant cause (\"Memory 94%\", \"No display\"…). */\n reason: string;\n /** The latest sample is older than we'd expect from a live agent (~5s cadence). */\n stale: boolean;\n};\n\n// Resource pressure thresholds. `warn` mirrors the existing meter ramp (>=70\n// tints), `crit` is the \"near the wall\" line. Disk is stricter than CPU/mem\n// because a full disk is a hard failure, whereas transient CPU/mem spikes are\n// normal on a working machine.\nconst PRESSURE = {\n cpu: { warn: 90, crit: 98 },\n mem: { warn: 85, crit: 95 },\n disk: { warn: 90, crit: 96 },\n} as const;\n\n// A live agent samples ~every 5s and the series downsamples to ~1/min. We treat\n// a latest sample older than 45s as \"telemetry has gone quiet\" — enough slack to\n// not flap on a single missed beat, tight enough to notice a wedged sampler.\nconst STALE_AFTER_MS = 45_000;\n\nfunction pct(used: number, total: number): number {\n if (!Number.isFinite(used) || !Number.isFinite(total) || total <= 0) return 0;\n return (used / total) * 100;\n}\n\n/** Fold a machine's reachability + latest sample + wall-clock into one verdict. */\nexport function deriveHealth(\n state: MachineState,\n metrics: MetricSample | null,\n now: number = Date.now(),\n): HealthVerdict {\n // Reachability dominates: an offline machine has no meaningful resource story.\n if (state === \"offline\") {\n return { level: \"offline\", label: \"Offline\", reason: \"Not reachable\", stale: true };\n }\n if (state === \"enrolling\") {\n return { level: \"unknown\", label: \"Enrolling\", reason: \"Completing enrollment\", stale: false };\n }\n\n const stale = metrics ? now - new Date(metrics.sampledAt).getTime() > STALE_AFTER_MS : true;\n\n // Reconnecting, or online-but-quiet: reachable yet we can't trust the numbers.\n if (state === \"reconnecting\") {\n return { level: \"degraded\", label: \"Reconnecting\", reason: \"Re-establishing link\", stale };\n }\n if (!metrics) {\n return { level: \"unknown\", label: \"Online\", reason: \"Awaiting first sample\", stale };\n }\n if (stale) {\n return { level: \"degraded\", label: \"Telemetry stale\", reason: \"No recent sample\", stale: true };\n }\n\n // Reachable + fresh: the verdict is now the worst resource pressure. Evaluate\n // each resource, keep the most severe, and name it in the reason.\n const memPct = pct(metrics.memUsedBytes, metrics.memTotalBytes);\n const diskPct = pct(metrics.diskUsedBytes, metrics.diskTotalBytes);\n const cpu = metrics.cpuPct;\n\n const pressures: Array<{ level: HealthLevel; reason: string; sev: number }> = [\n resolve(\"Disk\", diskPct, PRESSURE.disk),\n resolve(\"Memory\", memPct, PRESSURE.mem),\n resolve(\"CPU\", cpu, PRESSURE.cpu),\n ];\n const worst = pressures.reduce((a, b) => (b.sev > a.sev ? b : a));\n\n if (worst.sev === 2) return { level: \"critical\", label: \"Critical\", reason: worst.reason, stale };\n if (worst.sev === 1)\n return { level: \"degraded\", label: \"Under load\", reason: worst.reason, stale };\n return { level: \"healthy\", label: \"Healthy\", reason: \"All systems nominal\", stale };\n}\n\nfunction resolve(\n name: string,\n value: number,\n t: { warn: number; crit: number },\n): { level: HealthLevel; reason: string; sev: number } {\n const rounded = Math.round(value);\n if (value >= t.crit) return { level: \"critical\", reason: `${name} ${rounded}%`, sev: 2 };\n if (value >= t.warn) return { level: \"degraded\", reason: `${name} ${rounded}%`, sev: 1 };\n return { level: \"healthy\", reason: `${name} ${rounded}%`, sev: 0 };\n}\n\n// --- UI mapping helpers (color/token names live here so every surface agrees) --\n\n/**\n * The token color ramp for a health level. Green/amber/red/grey is the\n * universally-legible traffic model; we reserve it for the HEALTH verdict\n * specifically (per-resource meters keep their own ramp in `machine-metrics`).\n */\nexport const HEALTH_TOKEN: Record<HealthLevel, { text: string; dot: string; soft: string }> = {\n healthy: {\n text: \"text-og-status-idle\",\n dot: \"bg-og-status-idle\",\n soft: \"bg-og-status-idle/10 border-og-status-idle/25\",\n },\n degraded: {\n text: \"text-og-status-running\",\n dot: \"bg-og-status-running\",\n soft: \"bg-og-status-running/10 border-og-status-running/25\",\n },\n critical: {\n text: \"text-og-status-failed\",\n dot: \"bg-og-status-failed\",\n soft: \"bg-og-status-failed/10 border-og-status-failed/30\",\n },\n offline: {\n text: \"text-og-fg-subtle\",\n dot: \"bg-og-fg-subtle\",\n soft: \"bg-og-surface-2 border-og-border\",\n },\n unknown: {\n text: \"text-og-fg-muted\",\n dot: \"bg-og-fg-muted\",\n soft: \"bg-og-surface-2 border-og-border\",\n },\n};\n\n/** Live/transient levels breathe; settled levels hold still. */\nexport function healthPulses(level: HealthLevel): boolean {\n return level === \"degraded\" || level === \"critical\";\n}\n","// The card's primary status: the fused HEALTH verdict (dot + label), which\n// subsumes plain connection state (offline/reconnecting fall out of it) and adds\n// resource-pressure + staleness. Capability limitations (consent / no display /\n// enrolling) are orthogonal to reachability, so they ride alongside as their own\n// quiet chip — reusing the existing badge meta so the two surfaces never drift.\nimport { cn } from \"../lib/cn\";\nimport type { MachineState, MetricSample } from \"../types/machines\";\nimport { deriveHealth, HEALTH_TOKEN, healthPulses } from \"./machines/health\";\nimport { MACHINE_STATE_BADGE_META } from \"./machine-status-pill\";\n\nexport type MachineHealthPillProps = {\n state: MachineState;\n metrics: MetricSample | null;\n now?: number | undefined;\n size?: \"sm\" | \"md\" | undefined;\n className?: string | undefined;\n};\n\nexport function MachineHealthPill({\n state,\n metrics,\n now,\n size = \"sm\",\n className,\n}: MachineHealthPillProps) {\n const health = deriveHealth(state, metrics, now ?? Date.now());\n const tone = HEALTH_TOKEN[health.level];\n const badge = MACHINE_STATE_BADGE_META[state];\n const pad = size === \"md\" ? \"px-2.5 py-1 text-og-sm\" : \"px-2 py-0.5 text-og-xs\";\n\n return (\n <div className={cn(\"flex shrink-0 items-center gap-1.5\", className)}>\n {badge ? (\n <span\n className={cn(\n \"rounded-full border px-2 py-0.5 text-og-xs font-medium\",\n badge.badgeClassName,\n )}\n >\n {badge.label}\n </span>\n ) : null}\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border font-medium\",\n pad,\n tone.soft,\n tone.text,\n )}\n data-health={health.level}\n title={health.reason}\n >\n <span className=\"relative flex size-2\">\n {healthPulses(health.level) && (\n <span\n className={cn(\n \"absolute inline-flex size-full animate-og-pulse rounded-full opacity-60\",\n tone.dot,\n )}\n />\n )}\n <span className={cn(\"relative inline-flex size-2 rounded-full\", tone.dot)} />\n </span>\n {health.label}\n </span>\n </div>\n );\n}\n","// ----------------------------------------------------------------------------\n// MetricSparkline — an axis-less micro-trend for stat tiles and (later) cards.\n// Same smoothing as the full chart, no chrome: a hairline + a faint fill and a\n// dot on the latest point. Fixed viewBox so it scales crisply at any width.\n// ----------------------------------------------------------------------------\nimport type { SeriesPoint } from \"./metric-history-chart\";\n\nexport type MetricSparklineProps = {\n points: SeriesPoint[];\n color?: string;\n yMax?: number | \"auto\";\n height?: number;\n className?: string | undefined;\n};\n\nconst VW = 120;\n\nexport function MetricSparkline({\n points,\n color = \"var(--og-color-accent)\",\n yMax = \"auto\",\n height = 28,\n className,\n}: MetricSparklineProps) {\n const valued = points.filter(\n (p): p is { t: number; v: number } => p.v != null && Number.isFinite(p.v),\n );\n if (valued.length < 2) {\n return <div className={className} style={{ height }} aria-hidden />;\n }\n const vh = height;\n const top = yMax === \"auto\" ? Math.max(1, ...valued.map((p) => p.v)) * 1.1 : yMax;\n const tMin = valued[0]!.t;\n const tSpan = Math.max(1, valued[valued.length - 1]!.t - tMin);\n const xy = valued.map((p) => ({\n x: ((p.t - tMin) / tSpan) * VW,\n y: vh - (Math.min(top, Math.max(0, p.v)) / Math.max(1e-6, top)) * (vh - 2) - 1,\n }));\n let d = `M${xy[0]!.x},${xy[0]!.y}`;\n for (let i = 0; i < xy.length - 1; i++) {\n const p0 = xy[i - 1] ?? xy[i]!;\n const p1 = xy[i]!;\n const p2 = xy[i + 1]!;\n const p3 = xy[i + 2] ?? p2;\n d += `C${p1.x + (p2.x - p0.x) / 6},${p1.y + (p2.y - p0.y) / 6} ${p2.x - (p3.x - p1.x) / 6},${p2.y - (p3.y - p1.y) / 6} ${p2.x},${p2.y}`;\n }\n const last = xy[xy.length - 1]!;\n const gid = `spark-${Math.round(top)}-${color.length}`;\n return (\n <svg\n viewBox={`0 0 ${VW} ${vh}`}\n preserveAspectRatio=\"none\"\n className={className}\n style={{ height, width: \"100%\" }}\n aria-hidden\n >\n <defs>\n <linearGradient id={gid} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={color} stopOpacity=\"0.22\" />\n <stop offset=\"100%\" stopColor={color} stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n <path d={`${d} L${last.x},${vh} L${xy[0]!.x},${vh} Z`} fill={`url(#${gid})`} />\n <path\n d={d}\n fill=\"none\"\n stroke={color}\n strokeWidth={1.25}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n />\n <circle cx={last.x} cy={last.y} r={1.6} fill={color} vectorEffect=\"non-scaling-stroke\" />\n </svg>\n );\n}\n","// ----------------------------------------------------------------------------\n// MetricHistoryChart — the per-metric history visual on the machine detail view.\n//\n// A dependency-free SVG line/area chart tuned for the calm dark aesthetic:\n// a soft gradient fill, a smoothed stroke that draws itself in, whisper-quiet\n// gridlines, dashed threshold guides, and a hover crosshair with a mono readout.\n// It degrades honestly — a handful of points render as markers, zero points show\n// a quiet \"no samples\" note rather than an empty axis.\n//\n// Pure presentational: it takes plotted {t, v} points + a little config and owns\n// no data-fetching. `color` is any CSS color (pass a token var for theme-safety).\n// ----------------------------------------------------------------------------\nimport { useLayoutEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\n\nexport type SeriesPoint = { t: number; v: number | null };\n\nexport type MetricHistoryChartProps = {\n points: SeriesPoint[];\n /** Fixed ceiling (100 for %) or \"auto\" to fit the data with headroom. */\n yMax?: number | \"auto\";\n yMin?: number;\n /** Format a value for the axis + readout (default: rounded + unit). */\n format?: (v: number) => string;\n unit?: string;\n /** Stroke/fill hue — any CSS color; pass a token var to stay theme-safe. */\n color?: string;\n thresholds?: { warn?: number | undefined; crit?: number | undefined } | undefined;\n height?: number;\n /** Human range label for the empty state (\"in the last hour\"). */\n rangeLabel?: string | undefined;\n className?: string | undefined;\n};\n\nconst PAD = { top: 10, right: 12, bottom: 18, left: 40 };\n\nfunction niceCeil(v: number): number {\n if (v <= 0) return 1;\n const mag = 10 ** Math.floor(Math.log10(v));\n const n = v / mag;\n const step = n <= 1 ? 1 : n <= 2 ? 2 : n <= 5 ? 5 : 10;\n return step * mag;\n}\n\n/** Catmull-Rom → cubic-bezier path so the line is smooth without overshooting. */\nfunction smoothPath(pts: Array<{ x: number; y: number }>): string {\n if (pts.length === 0) return \"\";\n if (pts.length === 1) return `M${pts[0]!.x},${pts[0]!.y}`;\n let d = `M${pts[0]!.x},${pts[0]!.y}`;\n for (let i = 0; i < pts.length - 1; i++) {\n const p0 = pts[i - 1] ?? pts[i]!;\n const p1 = pts[i]!;\n const p2 = pts[i + 1]!;\n const p3 = pts[i + 2] ?? p2;\n const cp1x = p1.x + (p2.x - p0.x) / 6;\n const cp1y = p1.y + (p2.y - p0.y) / 6;\n const cp2x = p2.x - (p3.x - p1.x) / 6;\n const cp2y = p2.y - (p3.y - p1.y) / 6;\n d += `C${cp1x},${cp1y} ${cp2x},${cp2y} ${p2.x},${p2.y}`;\n }\n return d;\n}\n\nfunction fmtClock(t: number): string {\n const d = new Date(t);\n return `${d.getHours().toString().padStart(2, \"0\")}:${d.getMinutes().toString().padStart(2, \"0\")}`;\n}\n\nexport function MetricHistoryChart({\n points,\n yMax = \"auto\",\n yMin = 0,\n format,\n unit = \"\",\n color = \"var(--og-color-accent)\",\n thresholds,\n height = 132,\n rangeLabel = \"in this range\",\n className,\n}: MetricHistoryChartProps) {\n const ref = useRef<HTMLDivElement>(null);\n const [w, setW] = useState(560);\n const [hover, setHover] = useState<number | null>(null);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n const cw = entries[0]?.contentRect.width;\n if (cw && cw > 0) setW(cw);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n const valued = points.filter(\n (p): p is { t: number; v: number } => p.v != null && Number.isFinite(p.v),\n );\n const fmt = format ?? ((v: number) => `${Math.round(v)}${unit}`);\n\n const H = height;\n const plotW = Math.max(1, w - PAD.left - PAD.right);\n const plotH = Math.max(1, H - PAD.top - PAD.bottom);\n\n const dataMax = valued.length ? Math.max(...valued.map((p) => p.v)) : 1;\n const top = yMax === \"auto\" ? niceCeil(Math.max(dataMax * 1.15, thresholds?.warn ?? 0, 1)) : yMax;\n const span = Math.max(1e-6, top - yMin);\n\n const tMin = valued.length ? valued[0]!.t : 0;\n const tMax = valued.length ? valued[valued.length - 1]!.t : 1;\n const tSpan = Math.max(1, tMax - tMin);\n\n const xOf = (t: number) => PAD.left + ((t - tMin) / tSpan) * plotW;\n const yOf = (v: number) =>\n PAD.top + (1 - (Math.min(top, Math.max(yMin, v)) - yMin) / span) * plotH;\n\n const pxPts = valued.map((p) => ({ x: xOf(p.t), y: yOf(p.v), t: p.t, v: p.v }));\n const sparse = pxPts.length > 0 && pxPts.length <= 4;\n\n const line = smoothPath(pxPts);\n const area =\n pxPts.length > 1\n ? `${line} L${pxPts[pxPts.length - 1]!.x},${PAD.top + plotH} L${pxPts[0]!.x},${PAD.top + plotH} Z`\n : \"\";\n\n // y gridlines at 0 / mid / top\n const yTicks = [yMin, yMin + span / 2, top];\n const gid = `og-mh-${Math.round(top)}-${Math.round(color.length)}`;\n\n const hoverPt = hover != null ? pxPts[hover] : null;\n\n return (\n <div\n ref={ref}\n className={cn(\"relative w-full select-none\", className)}\n style={{ height: H }}\n data-metric-chart\n >\n {valued.length === 0 ? (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <span className=\"text-og-xs text-og-fg-subtle\">No samples {rangeLabel}</span>\n </div>\n ) : (\n <svg\n width={w}\n height={H}\n className=\"overflow-visible\"\n role=\"img\"\n onMouseLeave={() => setHover(null)}\n onMouseMove={(e) => {\n const rect = (e.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mx = e.clientX - rect.left;\n let best = 0;\n let bestD = Infinity;\n for (let i = 0; i < pxPts.length; i++) {\n const d = Math.abs(pxPts[i]!.x - mx);\n if (d < bestD) {\n bestD = d;\n best = i;\n }\n }\n setHover(best);\n }}\n >\n <defs>\n <linearGradient id={gid} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={color} stopOpacity=\"0.26\" />\n <stop offset=\"100%\" stopColor={color} stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n\n {/* gridlines + y labels */}\n {yTicks.map((v, i) => {\n const y = yOf(v);\n return (\n <g key={`yt-${v}`}>\n <line\n x1={PAD.left}\n x2={w - PAD.right}\n y1={y}\n y2={y}\n stroke=\"var(--og-color-border)\"\n strokeOpacity={i === 0 ? 0.9 : 0.4}\n strokeWidth={1}\n />\n <text\n x={PAD.left - 8}\n y={y + 3}\n textAnchor=\"end\"\n className=\"font-og-mono\"\n fontSize={10}\n fill=\"var(--og-color-fg-subtle)\"\n >\n {fmt(v)}\n </text>\n </g>\n );\n })}\n\n {/* threshold guides */}\n {([\"warn\", \"crit\"] as const).map((k) => {\n const tv = thresholds?.[k];\n if (tv == null || tv > top) return null;\n const y = yOf(tv);\n const stroke =\n k === \"crit\" ? \"var(--og-color-status-failed)\" : \"var(--og-color-status-waiting)\";\n return (\n <line\n key={k}\n x1={PAD.left}\n x2={w - PAD.right}\n y1={y}\n y2={y}\n stroke={stroke}\n strokeOpacity={0.5}\n strokeWidth={1}\n strokeDasharray=\"3 4\"\n />\n );\n })}\n\n {/* x time ticks (first + last) */}\n {valued.length > 1 &&\n [tMin, tMax].map((t, i) => (\n <text\n key={i === 0 ? \"x-start\" : \"x-end\"}\n x={i === 0 ? PAD.left : w - PAD.right}\n y={H - 4}\n textAnchor={i === 0 ? \"start\" : \"end\"}\n className=\"font-og-mono\"\n fontSize={10}\n fill=\"var(--og-color-fg-subtle)\"\n >\n {fmtClock(t)}\n </text>\n ))}\n\n {/* area + line */}\n {area && <path d={area} fill={`url(#${gid})`} />}\n <path\n d={line}\n fill=\"none\"\n stroke={color}\n strokeWidth={1.75}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n pathLength={1}\n className=\"og-mh-draw\"\n />\n\n {/* sparse markers */}\n {sparse &&\n pxPts.map((p) => <circle key={`m-${p.t}`} cx={p.x} cy={p.y} r={2.5} fill={color} />)}\n\n {/* hover crosshair */}\n {hoverPt && (\n <g pointerEvents=\"none\">\n <line\n x1={hoverPt.x}\n x2={hoverPt.x}\n y1={PAD.top}\n y2={PAD.top + plotH}\n stroke=\"var(--og-color-border-strong)\"\n strokeWidth={1}\n />\n <circle\n cx={hoverPt.x}\n cy={hoverPt.y}\n r={3.5}\n fill={color}\n stroke=\"var(--og-color-bg)\"\n strokeWidth={1.5}\n />\n </g>\n )}\n </svg>\n )}\n\n {/* floating readout */}\n {hoverPt && (\n <div\n className=\"pointer-events-none absolute z-10 flex flex-col rounded-og-sm border border-og-border-strong bg-og-surface-3/95 px-2 py-1 shadow-og-md backdrop-blur-sm\"\n style={{\n left: Math.min(Math.max(hoverPt.x - 30, 0), w - 78),\n top: Math.max(hoverPt.y - 42, 0),\n }}\n >\n <span className=\"font-og-mono text-og-sm font-medium tabular-nums text-og-fg\">\n {fmt(hoverPt.v)}\n </span>\n <span className=\"font-og-mono text-[10px] tabular-nums text-og-fg-subtle\">\n {fmtClock(hoverPt.t)}\n </span>\n </div>\n )}\n </div>\n );\n}\n","// ----------------------------------------------------------------------------\n// MachineDetail — the marquee per-machine telemetry view.\n//\n// Opens from a machine card. Answers, at a glance and then in depth: is this\n// machine healthy right now (one fused verdict), what are its live numbers, and\n// how have they moved over the chosen window. Built entirely on the existing\n// `og-*` token system — no new visual language, just the missing depth.\n// ----------------------------------------------------------------------------\nimport {\n AlertTriangleIcon,\n ArrowLeftIcon,\n CpuIcon,\n LaptopIcon,\n RadioIcon,\n ServerIcon,\n Trash2Icon,\n} from \"lucide-react\";\nimport { cn } from \"../../lib/cn\";\nimport { formatRelativeTime } from \"../../lib/format\";\nimport type { MachineView, MetricSample } from \"../../types/machines\";\nimport { deriveHealth, HEALTH_TOKEN, healthPulses } from \"./health\";\nimport { MetricHistoryChart } from \"./metric-history-chart\";\nimport { MetricSparkline } from \"./metric-sparkline\";\nimport { METRICS, METRIC_WINDOWS, pointsFor, WINDOW_LABEL, type MetricWindow } from \"./series\";\nimport { MachineOperationPolicyEditor } from \"./machine-operation-policy\";\nimport type { UpdateMachineOperationPolicyRequest } from \"@opengeni/sdk\";\n\nexport type MachineDetailProps = {\n machine: MachineView;\n /** Downsampled history for the active window (from `fetchSeries`). */\n series: MetricSample[];\n window: MetricWindow;\n onWindowChange: (w: MetricWindow) => void;\n loadingSeries?: boolean | undefined;\n onBack?: (() => void) | undefined;\n /** Open the workspace-admin removal confirmation for a self-hosted machine. */\n onRemove?: ((machine: MachineView) => void) | undefined;\n onUpdateOperationPolicy?:\n | ((machine: MachineView, request: UpdateMachineOperationPolicyRequest) => Promise<unknown>)\n | undefined;\n updatingOperationPolicy?: boolean | undefined;\n now?: number | undefined;\n className?: string | undefined;\n};\n\nfunction KindIcon({ kind, session }: { kind: string; session: boolean }) {\n if (session) return <ServerIcon className=\"size-4 text-og-fg-subtle\" aria-hidden />;\n if (kind === \"modal\") return <CpuIcon className=\"size-4 text-og-fg-subtle\" aria-hidden />;\n return <LaptopIcon className=\"size-4 text-og-fg-subtle\" aria-hidden />;\n}\n\nexport function MachineDetail({\n machine,\n series,\n window,\n onWindowChange,\n loadingSeries,\n onBack,\n onRemove,\n onUpdateOperationPolicy,\n updatingOperationPolicy,\n now = Date.now(),\n className,\n}: MachineDetailProps) {\n const health = deriveHealth(machine.state, machine.metrics, now);\n const tone = HEALTH_TOKEN[health.level];\n const latest = machine.metrics;\n const sampledAgo = latest ? formatRelativeTime(latest.sampledAt, new Date(now)) : null;\n const authority = machine.connectionAuthority;\n const duplicateDeniedAgo = authority.duplicateRunnerDeniedAt\n ? formatRelativeTime(authority.duplicateRunnerDeniedAt, new Date(now))\n : null;\n\n // Only render metrics that have a value (GPU is dropped on headless boxes).\n const visible = METRICS.filter((m) => !(m.key === \"gpu\" && latest?.gpuUtilPct == null));\n // The tile grid tracks the metric count exactly so it never leaves a dead cell.\n const tileCols =\n visible.length >= 5\n ? \"grid-cols-2 sm:grid-cols-3 lg:grid-cols-5\"\n : \"grid-cols-2 sm:grid-cols-4\";\n\n return (\n <div className={cn(\"og-root mx-auto flex w-full max-w-5xl flex-col gap-5\", className)}>\n {/* ── top bar ─────────────────────────────────────────────────────── */}\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2.5\">\n {onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n className=\"flex size-7 shrink-0 items-center justify-center rounded-og-sm border border-og-border bg-og-surface-1 text-og-fg-muted transition-colors hover:bg-og-surface-2 hover:text-og-fg\"\n aria-label=\"Back to machines\"\n >\n <ArrowLeftIcon className=\"size-3.5\" aria-hidden />\n </button>\n )}\n <KindIcon kind={machine.kind} session={machine.isSessionGroup} />\n <h1 className=\"truncate text-og-md font-semibold text-og-fg\">{machine.name}</h1>\n <span className=\"hidden shrink-0 rounded-og-sm border border-og-border bg-og-surface-1 px-1.5 py-0.5 font-og-mono text-og-xs text-og-fg-subtle sm:inline\">\n {machine.os} · {machine.arch}\n </span>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-2\">\n {onRemove && machine.enrollmentId && !machine.isSessionGroup ? (\n <button\n type=\"button\"\n data-remove-machine\n aria-label={`Remove machine ${machine.name}`}\n onClick={() => onRemove(machine)}\n className=\"inline-flex min-h-9 items-center gap-1.5 rounded-og-sm border border-og-status-failed/40 px-2.5 py-1 font-medium text-og-xs text-og-status-failed transition-colors hover:bg-og-status-failed/10 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-status-failed/50 pointer-coarse:min-h-11\"\n >\n <Trash2Icon className=\"size-3.5\" aria-hidden />\n <span className=\"hidden sm:inline\">Remove machine</span>\n </button>\n ) : null}\n {/* range selector */}\n <div className=\"flex items-center gap-0.5 rounded-og-md border border-og-border bg-og-surface-1 p-0.5\">\n {METRIC_WINDOWS.map((w) => (\n <button\n key={w}\n type=\"button\"\n onClick={() => onWindowChange(w)}\n data-active={w === window}\n className={cn(\n \"rounded-og-sm px-2 py-1 font-og-mono text-og-xs transition-colors\",\n w === window\n ? \"bg-og-surface-3 text-og-fg shadow-og-sm\"\n : \"text-og-fg-subtle hover:text-og-fg-muted\",\n )}\n >\n {w}\n </button>\n ))}\n </div>\n </div>\n </div>\n\n {/* ── health hero ─────────────────────────────────────────────────── */}\n <div\n className={cn(\n \"relative flex flex-col gap-4 overflow-hidden rounded-og-lg border p-5 shadow-og-sm\",\n tone.soft,\n )}\n >\n <span aria-hidden className={cn(\"absolute inset-y-0 left-0 w-1\", tone.dot)} />\n <div className=\"flex flex-wrap items-center justify-between gap-3 pl-1\">\n <div className=\"flex items-center gap-3\">\n <span className=\"relative flex size-3\">\n {healthPulses(health.level) && (\n <span\n className={cn(\n \"absolute inline-flex size-full animate-og-pulse rounded-full opacity-60\",\n tone.dot,\n )}\n />\n )}\n <span className={cn(\"relative inline-flex size-3 rounded-full\", tone.dot)} />\n </span>\n <div className=\"flex flex-col\">\n <span className={cn(\"text-og-md font-semibold\", tone.text)}>{health.label}</span>\n <span className=\"text-og-sm text-og-fg-muted\">{health.reason}</span>\n </div>\n </div>\n <div className=\"flex items-start gap-5 pr-1\">\n {sampledAgo && (\n <div className=\"flex flex-col items-end gap-0.5\">\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n Sampled\n </span>\n <span className=\"flex items-center gap-1 font-og-mono text-og-sm tabular-nums text-og-fg\">\n <RadioIcon\n className={cn(\"size-3\", health.stale ? \"text-og-fg-subtle\" : tone.text)}\n aria-hidden\n />\n {sampledAgo === \"now\" ? \"live\" : `${sampledAgo} ago`}\n </span>\n </div>\n )}\n {machine.lastSeenAt && (\n <div className=\"hidden flex-col items-end gap-0.5 sm:flex\">\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n Last seen\n </span>\n <span className=\"font-og-mono text-og-sm tabular-nums text-og-fg-muted\">\n {formatRelativeTime(machine.lastSeenAt, new Date(now))}\n </span>\n </div>\n )}\n </div>\n </div>\n\n {/* current-stat tiles */}\n {latest && (\n <div\n className={cn(\n \"grid gap-px overflow-hidden rounded-og-md border border-og-border bg-og-border\",\n tileCols,\n )}\n >\n {visible.map((m) => {\n const pts = pointsFor(m, series);\n return (\n <div key={m.key} className=\"flex flex-col gap-1.5 bg-og-surface-1 p-3\">\n <span className=\"text-[10px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n {m.title}\n </span>\n <span className=\"font-og-mono text-og-md font-medium tabular-nums text-og-fg\">\n {m.current(latest)}\n </span>\n <MetricSparkline points={pts} color={m.color} yMax={m.yMax} height={22} />\n {m.sub && (\n <span className=\"truncate font-og-mono text-[10px] text-og-fg-subtle\">\n {m.sub(latest)}\n </span>\n )}\n </div>\n );\n })}\n </div>\n )}\n\n {authority.state !== \"not_applicable\" ? (\n <div\n data-connection-authority={authority.state}\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-og-md border border-og-border bg-og-surface-1/75 px-3 py-2 text-og-xs\"\n >\n <span className=\"text-og-fg-muted\">\n Runner {authority.state.replace(\"_\", \" \")} · generation {authority.generation}\n {authority.supersededCount > 0\n ? ` · ${authority.supersededCount} earlier ${authority.supersededCount === 1 ? \"runner\" : \"runners\"} fenced`\n : \"\"}\n </span>\n {authority.duplicateRunnerDeniedCount > 0 ? (\n <span className=\"inline-flex items-center gap-1.5 text-og-status-failed\">\n <AlertTriangleIcon className=\"size-3.5\" aria-hidden />\n Blocked {authority.duplicateRunnerDeniedCount} competing runner\n {authority.duplicateRunnerDeniedCount === 1 ? \"\" : \"s\"}\n {duplicateDeniedAgo\n ? ` · ${duplicateDeniedAgo === \"now\" ? \"now\" : `${duplicateDeniedAgo} ago`}`\n : \"\"}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n\n {onUpdateOperationPolicy && machine.enrollmentId && machine.operationPolicy ? (\n <MachineOperationPolicyEditor\n policy={machine.operationPolicy}\n memorySupported={machine.runtime?.capabilities.operationResourcePolicy === true}\n cpuSupported={machine.runtime?.capabilities.operationCpuQuota === true}\n saving={updatingOperationPolicy}\n onSave={(request) => onUpdateOperationPolicy(machine, request)}\n />\n ) : null}\n\n {/* ── history charts ──────────────────────────────────────────────── */}\n <div className=\"grid grid-cols-1 gap-3 lg:grid-cols-2\">\n {visible.map((m) => {\n const pts = pointsFor(m, series);\n return (\n <div\n key={m.key}\n className=\"flex flex-col gap-3 rounded-og-lg border border-og-border bg-og-surface-1 p-4 shadow-og-sm\"\n >\n <div className=\"flex items-baseline justify-between\">\n <span className=\"text-og-sm font-medium text-og-fg\">{m.title}</span>\n {latest && (\n <span className=\"font-og-mono text-og-sm tabular-nums text-og-fg-muted\">\n {m.current(latest)}\n </span>\n )}\n </div>\n <MetricHistoryChart\n points={pts}\n yMax={m.yMax}\n unit={m.unit}\n color={m.color}\n thresholds={m.thresholds}\n rangeLabel={WINDOW_LABEL[window]}\n height={128}\n className={cn(loadingSeries && \"opacity-50 transition-opacity\")}\n />\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n","// Shared series helpers: project a MetricSample[] into per-metric {t, v} points,\n// and the metric catalog the detail view + tiles iterate over.\nimport type { MetricSample } from \"../../types/machines\";\nimport type { SeriesPoint } from \"./metric-history-chart\";\n\nexport type MetricWindow = \"15m\" | \"1h\" | \"6h\" | \"24h\";\nexport const METRIC_WINDOWS: MetricWindow[] = [\"15m\", \"1h\", \"6h\", \"24h\"];\n\nexport const WINDOW_LABEL: Record<MetricWindow, string> = {\n \"15m\": \"in the last 15 min\",\n \"1h\": \"in the last hour\",\n \"6h\": \"in the last 6 hours\",\n \"24h\": \"in the last 24 hours\",\n};\n\nfunction ptsFrom(samples: MetricSample[], pick: (s: MetricSample) => number | null): SeriesPoint[] {\n return samples.map((s) => ({ t: new Date(s.sampledAt).getTime(), v: pick(s) }));\n}\n\nconst memPct = (s: MetricSample) =>\n s.memTotalBytes > 0 ? (s.memUsedBytes / s.memTotalBytes) * 100 : null;\nconst diskPct = (s: MetricSample) =>\n s.diskTotalBytes > 0 ? (s.diskUsedBytes / s.diskTotalBytes) * 100 : null;\n\nexport type MetricKey = \"cpu\" | \"mem\" | \"disk\" | \"load\" | \"gpu\";\n\nexport type MetricDef = {\n key: MetricKey;\n title: string;\n unit: string;\n yMax: number | \"auto\";\n color: string;\n thresholds?: { warn?: number; crit?: number };\n pick: (s: MetricSample) => number | null;\n /** Big current-value string for tiles/badges. */\n current: (s: MetricSample) => string;\n /** Optional sub-line under the current value. */\n sub?: (s: MetricSample) => string | null;\n};\n\nconst fmtBytes = (b: number): string => {\n if (b < 1024) return `${b} B`;\n const u = [\"KB\", \"MB\", \"GB\", \"TB\"];\n let v = b / 1024;\n for (const unit of u) {\n if (v < 1024 || unit === \"TB\") return `${v.toFixed(v < 10 ? 1 : 0)} ${unit}`;\n v /= 1024;\n }\n return `${b} B`;\n};\n\n// The catalog. GPU is included but the detail view only renders it when the\n// latest sample actually reports a GPU (gpuUtilPct != null).\nexport const METRICS: MetricDef[] = [\n {\n key: \"cpu\",\n title: \"CPU\",\n unit: \"%\",\n yMax: 100,\n color: \"var(--og-color-accent)\",\n thresholds: { warn: 90, crit: 98 },\n pick: (s) => s.cpuPct,\n current: (s) => `${Math.round(s.cpuPct)}%`,\n sub: (s) => `${s.runQueue} in run queue`,\n },\n {\n key: \"mem\",\n title: \"Memory\",\n unit: \"%\",\n yMax: 100,\n color: \"var(--og-color-status-idle)\",\n thresholds: { warn: 85, crit: 95 },\n pick: memPct,\n current: (s) => `${Math.round(memPct(s) ?? 0)}%`,\n sub: (s) => `${fmtBytes(s.memUsedBytes)} / ${fmtBytes(s.memTotalBytes)}`,\n },\n {\n key: \"disk\",\n title: \"Disk\",\n unit: \"%\",\n yMax: 100,\n color: \"var(--og-color-status-waiting)\",\n thresholds: { warn: 90, crit: 96 },\n pick: diskPct,\n current: (s) => `${Math.round(diskPct(s) ?? 0)}%`,\n sub: (s) => `${fmtBytes(s.diskUsedBytes)} / ${fmtBytes(s.diskTotalBytes)}`,\n },\n {\n key: \"load\",\n title: \"Load average\",\n unit: \"\",\n yMax: \"auto\",\n color: \"var(--og-color-accent-strong)\",\n pick: (s) => s.load1,\n current: (s) => s.load1.toFixed(2),\n sub: (s) => `5m ${s.load5.toFixed(2)} · 15m ${s.load15.toFixed(2)}`,\n },\n {\n key: \"gpu\",\n title: \"GPU\",\n unit: \"%\",\n yMax: 100,\n color: \"var(--og-color-status-running)\",\n thresholds: { warn: 90, crit: 98 },\n pick: (s) => s.gpuUtilPct,\n current: (s) => (s.gpuUtilPct == null ? \"—\" : `${Math.round(s.gpuUtilPct)}%`),\n sub: (s) => (s.gpuMemBytes == null ? null : `${fmtBytes(s.gpuMemBytes)} used`),\n },\n];\n\nexport function pointsFor(def: MetricDef, samples: MetricSample[]): SeriesPoint[] {\n return ptsFrom(samples, def.pick);\n}\n","import { AlertTriangleIcon, Loader2Icon } from \"lucide-react\";\nimport { useEffect, useState, type FormEvent } from \"react\";\nimport type { MachineOperationPolicy, UpdateMachineOperationPolicyRequest } from \"@opengeni/sdk\";\n\nexport type MachineOperationPolicyEditorProps = {\n policy: MachineOperationPolicy;\n memorySupported: boolean;\n cpuSupported: boolean;\n saving?: boolean | undefined;\n onSave: (request: UpdateMachineOperationPolicyRequest) => Promise<unknown> | unknown;\n};\n\nfunction fieldValue(value: number | null): string {\n return value === null ? \"\" : String(value);\n}\n\nfunction parseByteCount(label: string, value: string): number | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n if (!/^\\d+$/.test(trimmed)) {\n throw new Error(`${label} must be a whole number of bytes or blank`);\n }\n const parsed = Number(trimmed);\n if (!Number.isSafeInteger(parsed) || parsed <= 0) {\n throw new Error(`${label} must be a positive safe-integer byte count or blank`);\n }\n return parsed;\n}\n\nfunction parseCpuMillicores(value: string): number | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n if (!/^\\d+$/.test(trimmed)) {\n throw new Error(\"CPU maximum must be a whole number of millicores or blank\");\n }\n const parsed = Number(trimmed);\n if (!Number.isSafeInteger(parsed) || parsed <= 0 || parsed > 0xffff_ffff) {\n throw new Error(\"CPU maximum must be between 1 and 4294967295 millicores or blank\");\n }\n return parsed;\n}\n\n/** Exact editor for the optional per-enrollment command resource policy. Blank\n * values remain genuinely unrestricted; CPU is a period-independent ratio. */\nexport function MachineOperationPolicyEditor({\n policy,\n memorySupported,\n cpuSupported,\n saving = false,\n onSave,\n}: MachineOperationPolicyEditorProps) {\n const [memoryMaxBytes, setMemoryMaxBytes] = useState(fieldValue(policy.memoryMaxBytes));\n const [memoryHighBytes, setMemoryHighBytes] = useState(fieldValue(policy.memoryHighBytes));\n const [cpuMaxMillicores, setCpuMaxMillicores] = useState(fieldValue(policy.cpuMaxMillicores));\n const [validationError, setValidationError] = useState<string | null>(null);\n\n useEffect(() => {\n setMemoryMaxBytes(fieldValue(policy.memoryMaxBytes));\n setMemoryHighBytes(fieldValue(policy.memoryHighBytes));\n setCpuMaxMillicores(fieldValue(policy.cpuMaxMillicores));\n setValidationError(null);\n }, [policy.memoryMaxBytes, policy.memoryHighBytes, policy.cpuMaxMillicores, policy.revision]);\n\n const submit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n try {\n const max = parseByteCount(\"Hard ceiling\", memoryMaxBytes);\n const high = parseByteCount(\"Reclaim threshold\", memoryHighBytes);\n if (max !== null && high !== null && high > max) {\n throw new Error(\"Reclaim threshold cannot exceed the hard ceiling\");\n }\n const cpuMax = parseCpuMillicores(cpuMaxMillicores);\n setValidationError(null);\n await onSave({\n memoryMaxBytes: max,\n memoryHighBytes: high,\n cpuMaxMillicores: cpuMax,\n expectedRevision: policy.revision,\n });\n } catch (error) {\n setValidationError(error instanceof Error ? error.message : String(error));\n }\n };\n\n const configured =\n policy.memoryMaxBytes !== null ||\n policy.memoryHighBytes !== null ||\n policy.cpuMaxMillicores !== null;\n const memoryConfigured = policy.memoryMaxBytes !== null || policy.memoryHighBytes !== null;\n const unsupportedMemory = memoryConfigured && !memorySupported;\n const unsupportedCpu = policy.cpuMaxMillicores !== null && (!memorySupported || !cpuSupported);\n\n return (\n <section\n data-machine-operation-policy\n className=\"rounded-og-lg border border-og-border bg-og-surface-1 p-4 shadow-og-sm\"\n >\n <div className=\"flex flex-col gap-1\">\n <h2 className=\"text-og-sm font-semibold text-og-fg\">Per-command resource policy</h2>\n <p className=\"text-og-xs leading-relaxed text-og-fg-muted\">\n Optional limits applied separately to each newly admitted exec and Git command. Running\n commands keep their admitted policy. Blank means unrestricted. The runner or host may\n apply a stricter explicit policy; browser, computer-use, and terminal capabilities remain\n unchanged.\n </p>\n </div>\n\n {configured && (unsupportedMemory || unsupportedCpu) ? (\n <div className=\"mt-3 flex gap-2 rounded-og-md border border-og-status-failed/40 bg-og-status-failed/5 p-3 text-og-xs text-og-status-failed\">\n <AlertTriangleIcon className=\"mt-0.5 size-3.5 shrink-0\" aria-hidden />\n <span>\n {unsupportedCpu\n ? \"This runner cannot enforce the configured CPU limit.\"\n : \"This runner cannot enforce the configured memory limit.\"}{\" \"}\n Command execution fails closed until the current runner, OS, and service configuration\n can enforce it, or the unsupported limit is cleared. You can still save limits now for\n later enforcement.\n </span>\n </div>\n ) : null}\n\n <form className=\"mt-4 grid gap-3 sm:grid-cols-2\" onSubmit={submit}>\n <label className=\"flex flex-col gap-1.5 text-og-xs text-og-fg-muted\">\n Hard ceiling (bytes)\n <input\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n value={memoryMaxBytes}\n onChange={(event) => setMemoryMaxBytes(event.target.value)}\n placeholder=\"Unlimited\"\n disabled={saving}\n className=\"min-h-9 rounded-og-sm border border-og-border bg-og-bg px-2.5 font-og-mono text-og-sm text-og-fg outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/50 disabled:opacity-60\"\n />\n </label>\n <label className=\"flex flex-col gap-1.5 text-og-xs text-og-fg-muted\">\n Reclaim threshold (bytes)\n <input\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n value={memoryHighBytes}\n onChange={(event) => setMemoryHighBytes(event.target.value)}\n placeholder=\"Unlimited\"\n disabled={saving}\n className=\"min-h-9 rounded-og-sm border border-og-border bg-og-bg px-2.5 font-og-mono text-og-sm text-og-fg outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/50 disabled:opacity-60\"\n />\n </label>\n <label className=\"flex flex-col gap-1.5 text-og-xs text-og-fg-muted\">\n CPU maximum (millicores)\n <input\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n value={cpuMaxMillicores}\n onChange={(event) => setCpuMaxMillicores(event.target.value)}\n placeholder=\"Unlimited\"\n disabled={saving}\n className=\"min-h-9 rounded-og-sm border border-og-border bg-og-bg px-2.5 font-og-mono text-og-sm text-og-fg outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/50 disabled:opacity-60\"\n />\n <span>1000 millicores = one CPU core. Blank is unlimited.</span>\n </label>\n <div className=\"flex min-h-9 items-center justify-between gap-3 sm:col-span-2\">\n <span\n role={validationError ? \"alert\" : undefined}\n className=\"text-og-xs text-og-status-failed\"\n >\n {validationError}\n </span>\n <button\n type=\"submit\"\n disabled={saving}\n className=\"inline-flex min-h-9 items-center gap-1.5 rounded-og-sm bg-og-accent px-3 py-1.5 text-og-xs font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {saving ? <Loader2Icon className=\"size-3.5 animate-spin\" aria-hidden /> : null}\n Save policy\n </button>\n </div>\n </form>\n </section>\n );\n}\n","import { type ReactNode } from \"react\";\nimport { LaptopIcon, PlusIcon, RefreshCwIcon } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport type { MachineView, MetricSample } from \"../types/machines\";\nimport { MachineCard } from \"./machine-card\";\n\nexport type MachinesDashboardProps = {\n machines: MachineView[];\n /** The session's active sandbox id (drives the per-card \"Active\" marker). */\n activeSandboxId?: string | null | undefined;\n loading?: boolean | undefined;\n error?: Error | null | undefined;\n /** Attach/swap the session's active sandbox to a machine. */\n onAttach?: ((machine: MachineView) => void) | undefined;\n /** The sandbox id currently being attached/swapped to (disables that card). */\n attachingSandboxId?: string | null | undefined;\n onUpdateAgent?: ((machine: MachineView) => void) | undefined;\n updatingEnrollmentId?: string | null | undefined;\n /** Short recent history per machine (keyed by sandboxId) — drives card sparklines. */\n seriesByMachine?: Record<string, MetricSample[]> | undefined;\n /** Open the per-machine telemetry detail (makes each card actionable). */\n onOpenDetail?: ((machine: MachineView) => void) | undefined;\n /** Shared clock so freshness/relative times render consistently across cards. */\n now?: number | undefined;\n /** Open the connection flow (the \"Connect a machine\" CTA). */\n onEnroll?: (() => void) | undefined;\n onRefresh?: (() => void) | undefined;\n className?: string | undefined;\n};\n\nfunction EmptyState({ onEnroll }: { onEnroll?: (() => void) | undefined }) {\n return (\n <div\n data-machines-empty\n className=\"flex flex-col items-center justify-center gap-3 rounded-og-lg border border-dashed border-og-border bg-og-surface-1 px-6 py-12 text-center\"\n >\n <span className=\"flex size-10 items-center justify-center rounded-full bg-og-surface-2 text-og-fg-subtle\">\n <LaptopIcon className=\"size-5\" aria-hidden />\n </span>\n <div className=\"space-y-1\">\n <p className=\"text-og-base font-medium text-og-fg\">No machines yet</p>\n <p className=\"max-w-xs text-og-sm text-og-fg-muted\">\n Connect your own computer to run the agent on it — your files, your terminal, your\n desktop.\n </p>\n </div>\n {onEnroll ? (\n <button\n type=\"button\"\n data-enroll-cta\n onClick={onEnroll}\n className=\"inline-flex items-center gap-1.5 rounded-og-sm bg-og-accent px-3 py-1.5 text-og-sm font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong pointer-coarse:min-h-11\"\n >\n <PlusIcon className=\"size-3.5\" aria-hidden />\n Connect a machine\n </button>\n ) : null}\n </div>\n );\n}\n\nfunction Header({\n count,\n onEnroll,\n onRefresh,\n loading,\n}: {\n count: number;\n onEnroll?: (() => void) | undefined;\n onRefresh?: (() => void) | undefined;\n loading?: boolean | undefined;\n}): ReactNode {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-baseline gap-2\">\n <h2 className=\"text-og-base font-semibold text-og-fg\">Machines</h2>\n <span className=\"font-og-mono text-og-xs text-og-fg-subtle\">{count}</span>\n </div>\n <div className=\"flex items-center gap-1.5\">\n {onRefresh ? (\n <button\n type=\"button\"\n data-refresh\n onClick={onRefresh}\n title=\"Refresh\"\n className=\"rounded-og-sm p-1.5 text-og-fg-subtle transition-colors hover:bg-og-surface-2 hover:text-og-fg\"\n >\n <RefreshCwIcon className={cn(\"size-3.5\", loading && \"animate-og-spin\")} aria-hidden />\n </button>\n ) : null}\n {onEnroll ? (\n <button\n type=\"button\"\n data-enroll-cta\n onClick={onEnroll}\n className=\"inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1 text-og-sm font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg pointer-coarse:min-h-11\"\n >\n <PlusIcon className=\"size-3.5\" aria-hidden />\n Connect a machine\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\n/**\n * The workspace Machines dashboard: the fleet of Connected Machines + the\n * session's managed sandbox, each with its connection-status pill, state badges,\n * latest metrics, and an attach/swap affordance. Renders the empty state (no\n * machines → connect CTA), a load error, and the populated grid. The component\n * is purely presentational — feed it `MachinesResponse` data via `useMachines`.\n */\nexport function MachinesDashboard({\n machines,\n activeSandboxId,\n loading,\n error,\n onAttach,\n attachingSandboxId,\n onUpdateAgent,\n updatingEnrollmentId,\n seriesByMachine,\n onOpenDetail,\n now,\n onEnroll,\n onRefresh,\n className,\n}: MachinesDashboardProps) {\n const isEmpty = !loading && !error && machines.length === 0;\n\n return (\n <section data-machines-dashboard className={cn(\"og-root flex flex-col gap-3\", className)}>\n <Header count={machines.length} onEnroll={onEnroll} onRefresh={onRefresh} loading={loading} />\n\n {error ? (\n <div\n data-machines-error\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-og-md border border-og-status-failed/30 bg-og-status-failed/10 px-3 py-2 text-og-sm text-og-status-failed\"\n >\n <span>Could not load machines: {error.message}</span>\n {onRefresh ? (\n <button\n type=\"button\"\n data-machines-retry\n onClick={onRefresh}\n disabled={loading}\n className=\"inline-flex items-center gap-1.5 rounded-og-sm border border-og-status-failed/30 px-2 py-1 text-og-xs font-medium transition-colors hover:border-og-status-failed/50 disabled:cursor-not-allowed disabled:opacity-60 pointer-coarse:min-h-11\"\n >\n <RefreshCwIcon className={cn(\"size-3.5\", loading && \"animate-og-spin\")} aria-hidden />\n {loading ? \"Retrying…\" : \"Retry\"}\n </button>\n ) : null}\n </div>\n ) : null}\n\n {loading && machines.length === 0 ? (\n <div data-machines-loading className=\"grid gap-3 sm:grid-cols-2\">\n {[0, 1].map((i) => (\n <div\n key={i}\n className=\"h-36 animate-og-pulse rounded-og-lg border border-og-border bg-og-surface-1\"\n />\n ))}\n </div>\n ) : isEmpty ? (\n <EmptyState onEnroll={onEnroll} />\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\" data-machines-grid>\n {machines.map((machine) => (\n <MachineCard\n key={machine.sandboxId}\n machine={{\n ...machine,\n active: machine.active || machine.sandboxId === activeSandboxId,\n }}\n onAttach={onAttach}\n attaching={attachingSandboxId === machine.sandboxId}\n onUpdateAgent={onUpdateAgent}\n updatingAgent={updatingEnrollmentId === machine.enrollmentId}\n series={seriesByMachine?.[machine.sandboxId]}\n onOpenDetail={onOpenDetail}\n now={now}\n />\n ))}\n </div>\n )}\n </section>\n );\n}\n","import { LaptopIcon, CpuIcon, UsersIcon } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport type { MachineKind, MachineState } from \"../types/machines\";\nimport { ConnectionStatusPill, MACHINE_STATE_BADGE_META } from \"./machine-status-pill\";\nimport { connectionStatusForState } from \"../types/machines\";\n\nexport type MachineDockBarProps = {\n /** The active machine's display name. */\n name: string;\n kind: MachineKind;\n state: MachineState;\n /** Live sessions sharing this whole-machine lease (>1 ⇒ shared disclosure). */\n sharedSessionCount?: number | undefined;\n className?: string | undefined;\n};\n\n/**\n * A slim bar that surfaces WHICH machine the dock surfaces (Files/Terminal/\n * Desktop) are bound to + its connection status. Mounted above the dock tabs so\n * the user always knows whether they are looking at the Modal box or their own\n * machine, and whether it is online / reconnecting / offline. The surfaces below\n * render IDENTICALLY regardless of backend — this bar is the only backend-aware\n * chrome (the dock-parity contract: selfhosted == Modal for the surfaces).\n */\nexport function MachineDockBar({ name, kind, state, className }: MachineDockBarProps) {\n const Icon = kind === \"selfhosted\" ? LaptopIcon : CpuIcon;\n const stateBadge = MACHINE_STATE_BADGE_META[state];\n return (\n <div\n data-machine-dock-bar\n className={cn(\n \"flex shrink-0 items-center justify-between gap-2 border-b border-og-border bg-og-surface-1 px-2.5 py-1\",\n className,\n )}\n >\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <Icon className=\"size-3.5 shrink-0 text-og-fg-subtle\" aria-hidden />\n <span className=\"truncate text-[11px] font-medium text-og-fg\">{name}</span>\n {stateBadge ? (\n <span\n data-state-badge={state}\n className={cn(\n \"shrink-0 rounded-full border px-1.5 py-px text-[10px] font-medium\",\n stateBadge.badgeClassName,\n )}\n >\n {stateBadge.label}\n </span>\n ) : null}\n </div>\n <ConnectionStatusPill\n status={connectionStatusForState(state)}\n size=\"sm\"\n className=\"shrink-0\"\n />\n </div>\n );\n}\n\nexport type SharedMachineDisclosureProps = {\n sharedSessionCount: number;\n /** Compact (inline strip) vs full (a notice block). */\n density?: \"compact\" | \"full\" | undefined;\n className?: string | undefined;\n};\n\n/**\n * The \"shared — another session is on this machine\" disclosure. Surfaced in the\n * dock (and reused on the desktop take-control gate) so the user knows others are\n * driving the same whole-machine lease. Render when `sharedSessionCount > 1`.\n */\nexport function SharedMachineDisclosure({\n sharedSessionCount,\n density = \"compact\",\n className,\n}: SharedMachineDisclosureProps) {\n const others = Math.max(0, sharedSessionCount - 1);\n return (\n <div\n data-shared-disclosure\n className={cn(\n \"flex items-center gap-1.5 border-og-accent/25 bg-og-accent-soft text-og-fg-muted\",\n density === \"full\"\n ? \"rounded-og-md border px-3 py-2 text-[12px]\"\n : \"border-b px-2.5 py-1 text-[11px]\",\n className,\n )}\n >\n <UsersIcon className=\"size-3.5 shrink-0 text-og-accent\" aria-hidden />\n <span>\n Shared — {others === 1 ? \"another session is\" : `${others} other sessions are`} on this\n machine. They see the same terminal, files, and desktop.\n </span>\n </div>\n );\n}\n","import { type ReactNode } from \"react\";\nimport { CopyIcon, ExternalLinkIcon, LaptopIcon, TerminalIcon } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport type { MachineState } from \"../types/machines\";\nimport { ConnectionStatusPill } from \"./machine-status-pill\";\n\n/** The poll state of an in-flight device-flow enrollment. */\nexport type DeviceFlowPhase = \"pending\" | \"authorized\" | \"denied\" | \"expired\" | \"disabled\";\n\nexport type EnrollmentDeviceFlowProps = {\n /** The short user code the agent printed (shown big for the human to confirm). */\n userCode: string;\n /** Where the user approves — the same-origin device page. */\n verificationUri: string;\n /** The complete URI (code pre-filled) for a one-click / QR open. */\n verificationUriComplete?: string | undefined;\n /** The install one-liner the user ran (echoed for context). Optional. */\n installCommand?: string | undefined;\n phase?: DeviceFlowPhase | undefined;\n /** Seconds remaining before the code expires (drives a quiet countdown). */\n expiresInSeconds?: number | undefined;\n onCopyCode?: (() => void) | undefined;\n onCopyInstall?: (() => void) | undefined;\n onOpenVerification?: (() => void) | undefined;\n className?: string | undefined;\n};\n\nconst PHASE_TO_STATE: Record<DeviceFlowPhase, MachineState> = {\n pending: \"enrolling\",\n authorized: \"online\",\n denied: \"offline\",\n expired: \"offline\",\n disabled: \"offline\",\n};\n\nfunction PhaseLabel({ phase }: { phase: DeviceFlowPhase }): ReactNode {\n const text: Record<DeviceFlowPhase, string> = {\n pending: \"Waiting for approval\",\n authorized: \"Connected\",\n denied: \"Denied\",\n expired: \"Code expired\",\n disabled: \"Enrollment disabled\",\n };\n return <span>{text[phase]}</span>;\n}\n\n/**\n * The IN-SESSION device-flow panel: the agent (after the install one-liner) prints\n * a short `userCode` + a `verificationUri`; this surfaces them so the user can open\n * the approve page and confirm the code. Polls in the caller; this renders the\n * pending → authorized/denied/expired progression with a connection pill. This is\n * the FIRST step of the IA flow (device-flow → Machines list → attach/swap).\n */\nexport function EnrollmentDeviceFlow({\n userCode,\n verificationUri,\n verificationUriComplete,\n installCommand,\n phase = \"pending\",\n expiresInSeconds,\n onCopyCode,\n onCopyInstall,\n onOpenVerification,\n className,\n}: EnrollmentDeviceFlowProps) {\n const href = verificationUriComplete ?? verificationUri;\n // Before the one-liner runs the caller passes a placeholder (dashes) for the\n // code — surface that as an explicit waiting state rather than dashes that look\n // like a real code to type.\n const codeIsPlaceholder = !/[A-Za-z0-9]/.test(userCode);\n const awaitingCode = phase === \"pending\" && codeIsPlaceholder;\n return (\n <div\n data-enrollment-device-flow\n className={cn(\n \"og-root flex w-full max-w-md flex-col gap-4 rounded-og-lg border border-og-border bg-og-surface-1 p-5 shadow-og-sm\",\n className,\n )}\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"flex size-7 items-center justify-center rounded-full bg-og-surface-2 text-og-fg-muted\">\n <LaptopIcon className=\"size-4\" aria-hidden />\n </span>\n <h2 className=\"text-og-menu font-semibold text-og-fg\">Connect a machine</h2>\n </div>\n <ConnectionStatusPill\n status={\n PHASE_TO_STATE[phase] === \"online\"\n ? \"online\"\n : PHASE_TO_STATE[phase] === \"offline\"\n ? \"offline\"\n : \"reconnecting\"\n }\n label={(<PhaseLabel phase={phase} />) as unknown as string}\n size=\"sm\"\n />\n </div>\n\n {installCommand ? (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-[11px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n 1 · Run on the machine\n </span>\n <div className=\"flex items-center justify-between gap-2 overflow-hidden rounded-og-md border border-og-border bg-og-bg px-2.5 py-1.5\">\n <code className=\"flex min-w-0 items-center gap-2 overflow-x-auto font-og-mono text-[12px] text-og-fg\">\n <TerminalIcon className=\"size-3.5 shrink-0 text-og-fg-subtle\" aria-hidden />\n {installCommand}\n </code>\n <button\n type=\"button\"\n data-copy-install\n onClick={onCopyInstall}\n title=\"Copy command\"\n className=\"shrink-0 rounded-og-sm p-1.5 text-og-fg-subtle transition-colors hover:bg-og-surface-2 hover:text-og-fg\"\n >\n <CopyIcon className=\"size-4\" aria-hidden />\n </button>\n </div>\n </div>\n ) : null}\n\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-[11px] font-medium uppercase tracking-wide text-og-fg-subtle\">\n {installCommand ? \"2 · Approve the machine\" : \"Approve the machine\"}\n </span>\n <div className=\"flex items-center justify-between gap-3 rounded-og-md border border-og-border bg-og-bg px-3 py-2.5\">\n {awaitingCode ? (\n <span data-user-code className=\"font-og-mono text-[13px] text-og-fg-subtle\">\n Run the command above — your code appears here\n </span>\n ) : (\n <span\n data-user-code\n className=\"select-all font-og-mono text-2xl font-semibold tracking-[0.25em] text-og-fg\"\n >\n {userCode}\n </span>\n )}\n <button\n type=\"button\"\n data-copy-code\n onClick={onCopyCode}\n disabled={awaitingCode}\n title=\"Copy code\"\n className=\"shrink-0 rounded-og-sm p-1.5 text-og-fg-subtle transition-colors hover:bg-og-surface-2 hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent disabled:hover:text-og-fg-subtle\"\n >\n <CopyIcon className=\"size-4\" aria-hidden />\n </button>\n </div>\n </div>\n\n <a\n href={href}\n data-open-verification\n target=\"_blank\"\n rel=\"noreferrer\"\n onClick={onOpenVerification}\n className=\"inline-flex items-center justify-center gap-1.5 rounded-og-sm bg-og-accent px-3 py-2 text-og-menu font-medium text-og-accent-fg transition-colors hover:bg-og-accent-strong\"\n >\n Open approval page\n <ExternalLinkIcon className=\"size-3.5\" aria-hidden />\n </a>\n\n <p className=\"text-center text-[11px] text-og-fg-subtle\">\n {awaitingCode ? (\n <>\n The one-liner prints a short code. Open{\" \"}\n <span className=\"font-og-mono text-og-fg-muted\">{verificationUri}</span> and confirm the\n code shown there matches.\n </>\n ) : (\n <>\n Confirm code <span className=\"font-og-mono text-og-fg-muted\">{userCode}</span> — the one\n printed by the one-liner — at{\" \"}\n <span className=\"font-og-mono text-og-fg-muted\">{verificationUri}</span>.\n {typeof expiresInSeconds === \"number\" ? (\n <> Expires in {Math.max(0, Math.round(expiresInSeconds / 60))} min.</>\n ) : null}\n </>\n )}\n </p>\n </div>\n );\n}\n","import { type ReactNode, useState } from \"react\";\nimport type { ResourceAuthorityScope } from \"@opengeni/sdk\";\nimport {\n CircleAlertIcon,\n LaptopIcon,\n MonitorIcon,\n ScreenShareIcon,\n ShieldAlertIcon,\n TerminalIcon,\n UsersIcon,\n} from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\n\n/** The machine identity surfaced to the approver, from the device-flow start. */\nexport type EnrollmentConsentMachine = {\n /** Human-friendly name (hostname by default). */\n machineName: string;\n os: string;\n arch: string;\n /** The agent can offer a display (a real screen / Xvfb is available). */\n canOfferDisplay: boolean;\n /** The agent requests screen control (computer-use). */\n requestsScreenControl: boolean;\n};\n\n/** The phase of the approve page (drives the rendered panel). */\nexport type EnrollmentConsentPhase = \"review\" | \"approving\" | \"approved\" | \"denied\" | \"error\";\n\nexport type EnrollmentConsentProps = {\n /** The short code the user typed / scanned (echoed back for confirmation). */\n userCode: string;\n machine: EnrollmentConsentMachine;\n phase?: EnrollmentConsentPhase | undefined;\n /** Whether this caller may publish the machine to the whole organization. */\n allowOrganizationScope?: boolean | undefined;\n /** Approve with the chosen screen-control consent and explicit access scope. */\n onApprove?: ((allowScreenControl: boolean, scope: ResourceAuthorityScope) => void) | undefined;\n onDeny?: (() => void) | undefined;\n /** Error message when phase === \"error\". */\n errorMessage?: string | undefined;\n className?: string | undefined;\n};\n\nfunction Capability({ icon, title, body }: { icon: ReactNode; title: string; body: string }) {\n return (\n <li className=\"flex items-start gap-2.5\">\n <span className=\"mt-0.5 shrink-0 text-og-status-failed\">{icon}</span>\n <span className=\"min-w-0\">\n <span className=\"block text-og-base font-medium text-og-fg\">{title}</span>\n <span className=\"block text-og-sm text-og-fg-muted\">{body}</span>\n </span>\n </li>\n );\n}\n\n/**\n * The user-facing APPROVE page for the device-flow enrollment: a LOUD,\n * un-minimised whole-machine consent. Approving grants the agent FULL access to\n * this machine — exec, files, terminal — and (when toggled) live screen control.\n * The danger framing is deliberate (§18 hardening: whole-machine = loud consent),\n * never buried. Renders review / approving / approved / denied / error phases.\n */\nexport function EnrollmentConsent({\n userCode,\n machine,\n phase = \"review\",\n allowOrganizationScope = false,\n onApprove,\n onDeny,\n errorMessage,\n className,\n}: EnrollmentConsentProps) {\n const [allowScreenControl, setAllowScreenControl] = useState(machine.requestsScreenControl);\n const [scope, setScope] = useState<ResourceAuthorityScope>(\"user\");\n const busy = phase === \"approving\";\n const scopeCopy = {\n user: {\n label: \"Personal\",\n body: \"Only you can use this machine, from any workspace you can access in this organization.\",\n },\n workspace: {\n label: \"Workspace\",\n body: \"Everyone with access to this workspace can use this machine.\",\n },\n organization: {\n label: \"Organization\",\n body: \"Members of this organization can use this machine from their workspaces.\",\n },\n } satisfies Record<ResourceAuthorityScope, { label: string; body: string }>;\n\n if (phase === \"approved\") {\n return (\n <ConsentResult\n className={className}\n tone=\"ok\"\n title=\"Machine connected\"\n body={`${machine.machineName} is now connected with ${scopeCopy[scope].label.toLowerCase()} access. You can close this page — it will appear in your Machines dashboard.`}\n />\n );\n }\n if (phase === \"denied\") {\n return (\n <ConsentResult\n className={className}\n tone=\"muted\"\n title=\"Enrollment denied\"\n body={`You declined to connect ${machine.machineName}. The agent has no access to this machine. You can re-run the install one-liner to try again.`}\n />\n );\n }\n if (phase === \"error\") {\n return (\n <ConsentResult\n className={className}\n tone=\"danger\"\n title=\"Could not complete enrollment\"\n body={\n errorMessage ??\n \"The code may have expired. Re-run the install one-liner on the machine for a fresh code.\"\n }\n />\n );\n }\n\n return (\n <div\n data-enrollment-consent\n className={cn(\n \"og-root mx-auto flex w-full max-w-md flex-col gap-5 rounded-og-lg border border-og-status-failed/30 bg-og-surface-1 p-6 shadow-og-md\",\n className,\n )}\n >\n <div className=\"flex items-start gap-3\">\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-full bg-og-status-failed/15 text-og-status-failed\">\n <ShieldAlertIcon className=\"size-5\" aria-hidden />\n </span>\n <div className=\"min-w-0\">\n <h1 className=\"text-og-md font-semibold text-og-fg\">\n Give the agent your whole machine?\n </h1>\n <p className=\"mt-1 text-og-base text-og-fg-muted\">\n Approving lets the OpenGeni agent run on{\" \"}\n <span className=\"font-medium text-og-fg\">{machine.machineName}</span> with full access.\n This is your real computer — not a sandbox.\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2 rounded-og-md border border-og-border bg-og-surface-2 px-3 py-2 text-og-sm\">\n <LaptopIcon className=\"size-4 text-og-fg-subtle\" aria-hidden />\n <span className=\"font-medium text-og-fg\">{machine.machineName}</span>\n <span className=\"font-og-mono text-og-fg-subtle\">\n {machine.os}/{machine.arch}\n </span>\n <span aria-hidden className=\"text-og-fg-subtle\">\n ·\n </span>\n <span className=\"text-og-fg-subtle\">\n code <span className=\"font-og-mono font-medium text-og-fg\">{userCode}</span>\n </span>\n </div>\n\n <ul className=\"flex flex-col gap-3\">\n <Capability\n icon={<TerminalIcon className=\"size-4\" aria-hidden />}\n title=\"Read, write & run anything\"\n body=\"The agent can read and modify any file, run any command, and use your git credentials — as if it were you at the keyboard.\"\n />\n {machine.canOfferDisplay ? (\n <Capability\n icon={<MonitorIcon className=\"size-4\" aria-hidden />}\n title=\"See your screen\"\n body=\"The agent can capture this machine's display to watch what it is doing.\"\n />\n ) : null}\n <Capability\n icon={<UsersIcon className=\"size-4\" aria-hidden />}\n title={`${scopeCopy[scope].label} access while connected`}\n body={`${scopeCopy[scope].body} Disconnect the agent to revoke access instantly.`}\n />\n </ul>\n\n <fieldset className=\"flex flex-col gap-2\" disabled={busy}>\n <legend className=\"mb-1 text-og-sm font-medium text-og-fg\">\n Who can use this machine?\n </legend>\n {([\"user\", \"workspace\", \"organization\"] as const).map((candidate) => {\n const disabled = candidate === \"organization\" && !allowOrganizationScope;\n return (\n <label\n key={candidate}\n data-enrollment-scope={candidate}\n data-disabled={disabled ? \"true\" : \"false\"}\n className={cn(\n \"flex items-start gap-2.5 rounded-og-md border border-og-border bg-og-bg px-3 py-2.5\",\n disabled ? \"cursor-not-allowed opacity-50\" : \"cursor-pointer\",\n )}\n >\n <input\n type=\"radio\"\n name=\"enrollment-scope\"\n value={candidate}\n checked={scope === candidate}\n disabled={disabled || busy}\n onChange={() => setScope(candidate)}\n className=\"mt-0.5 size-4 accent-og-accent\"\n />\n <span className=\"min-w-0\">\n <span className=\"block text-og-base font-medium text-og-fg\">\n {scopeCopy[candidate].label}\n {disabled ? \" · organization admin required\" : \"\"}\n </span>\n <span className=\"block text-og-sm text-og-fg-muted\">\n {scopeCopy[candidate].body}\n </span>\n </span>\n </label>\n );\n })}\n </fieldset>\n\n {machine.canOfferDisplay ? (\n <label\n data-screen-control-toggle\n className=\"flex cursor-pointer items-start gap-3 rounded-og-md border border-og-border bg-og-bg px-3 py-2.5\"\n >\n <input\n type=\"checkbox\"\n checked={allowScreenControl}\n disabled={busy}\n onChange={(e) => setAllowScreenControl(e.target.checked)}\n className=\"mt-0.5 size-4 accent-og-accent\"\n />\n <span className=\"min-w-0\">\n <span className=\"flex items-center gap-1.5 text-og-base font-medium text-og-fg\">\n <ScreenShareIcon className=\"size-3.5 text-og-fg-muted\" aria-hidden />\n Also let the agent control my mouse & keyboard\n </span>\n <span className=\"mt-0.5 block text-og-sm text-og-fg-muted\">\n Optional. Enables computer-use — the agent can move the pointer, type, and click on\n this machine's desktop. Leave off to let it only watch.\n </span>\n </span>\n </label>\n ) : (\n <p className=\"flex items-start gap-2 rounded-og-md border border-og-border bg-og-bg px-3 py-2 text-og-sm text-og-fg-muted\">\n <CircleAlertIcon className=\"mt-px size-3.5 shrink-0 text-og-fg-subtle\" aria-hidden />\n This machine has no display, so screen control isn't available — files, terminal, and git\n only.\n </p>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-deny\n disabled={busy}\n onClick={() => onDeny?.()}\n className=\"flex-1 rounded-og-sm border border-og-border px-3 py-2 text-og-sm font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n data-approve\n disabled={busy}\n onClick={() => onApprove?.(allowScreenControl, scope)}\n className=\"flex-1 rounded-og-sm bg-og-status-failed px-3 py-2 text-og-sm font-semibold text-og-accent-fg transition-colors hover:opacity-90 disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n {busy ? \"Connecting…\" : \"Grant full access\"}\n </button>\n </div>\n </div>\n );\n}\n\nfunction ConsentResult({\n tone,\n title,\n body,\n className,\n}: {\n tone: \"ok\" | \"muted\" | \"danger\";\n title: string;\n body: string;\n className?: string | undefined;\n}) {\n const ring =\n tone === \"ok\"\n ? \"border-og-status-running/30\"\n : tone === \"danger\"\n ? \"border-og-status-failed/30\"\n : \"border-og-border\";\n const iconClass =\n tone === \"ok\"\n ? \"text-og-status-running\"\n : tone === \"danger\"\n ? \"text-og-status-failed\"\n : \"text-og-fg-subtle\";\n return (\n <div\n data-enrollment-result={tone}\n className={cn(\n \"og-root mx-auto flex w-full max-w-md flex-col items-center gap-3 rounded-og-lg border bg-og-surface-1 p-6 text-center shadow-og-md\",\n ring,\n className,\n )}\n >\n <span\n className={cn(\n \"flex size-10 items-center justify-center rounded-full bg-og-surface-2\",\n iconClass,\n )}\n >\n <LaptopIcon className=\"size-5\" aria-hidden />\n </span>\n <h1 className=\"text-og-md font-semibold text-og-fg\">{title}</h1>\n <p className=\"max-w-sm text-og-base text-og-fg-muted\">{body}</p>\n </div>\n );\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport type {\n RemoveEnrollmentRequest,\n RemoveEnrollmentResponse,\n MachineOperationPolicy,\n SwapActiveSandboxResponse,\n UpdateMachineOperationPolicyRequest,\n UpdateMachineAgentResponse,\n} from \"@opengeni/sdk\";\nimport { useOpenGeni, type ClientOverride } from \"../provider\";\nimport { useMutationRunner } from \"./internal\";\nimport { EMPTY_MACHINES, useSharedMachinesList } from \"./shared-machines-list\";\nimport type { MachinesResponse, MachineView, MetricSample } from \"../types/machines\";\n\n/** Dashboard list: cheap heartbeat read, keep the pill reasonably fresh. */\nexport const MACHINES_DASHBOARD_POLL_MS = 10_000;\n/** Session surfaces share one poll for the same workspace+session. */\nexport const MACHINES_SESSION_POLL_MS = 15_000;\n/** Composer polls after the first load shows a machine, or to retry a real error. */\nexport const MACHINES_COMPOSER_POLL_MS = 30_000;\n\nconst machinesClientIds = new WeakMap<object, number>();\nlet nextMachinesClientId = 1;\n\nfunction machinesClientId(client: object): number {\n const existing = machinesClientIds.get(client);\n if (existing !== undefined) return existing;\n const id = nextMachinesClientId++;\n machinesClientIds.set(client, id);\n return id;\n}\n\n/**\n * The slice of the SDK client the Machines surface needs. The method NAMES +\n * SIGNATURES match M10's `OpenGeniClient` (`listMachines`, `machineMetricsSeries`)\n * so the real SDK client satisfies this surface DIRECTLY for the read paths — no\n * adapter needed. It is declared structurally (not a hard `OpenGeniClient` Pick)\n * so a test/demo/Geni-frontend client can stand in, keeping the hook dual-consumer\n * safe (works in apps/web AND the separate Geni frontend).\n *\n * The active-sandbox SWAP is now a typed SDK call (`swapActiveSandbox`, the M7\n * user-authenticated REST equivalent of the `sandbox_swap` MCP tool). The real\n * SDK client satisfies it structurally, so the default attach path is wired\n * WHENEVER a sessionId is in scope (the swap is session-scoped). `attachMachine`\n * stays an OPTIONAL escape hatch for a host that wants to supply its own swap\n * adapter; when neither it nor a sessionId is present, attach is a no-op and the\n * card hides the button.\n */\nexport type MachinesClientLike = {\n /** GET /v1/workspaces/:ws/machines — the dashboard list + active pointer. */\n listMachines: (\n workspaceId: string,\n options?: { sessionId?: string; signal?: AbortSignal },\n ) => Promise<MachinesResponse>;\n /** GET .../machines/:enrollmentId/metrics/series — the downsampled history. */\n machineMetricsSeries?: (\n workspaceId: string,\n enrollmentId: string,\n options?: { window?: \"15m\" | \"1h\" | \"6h\" | \"24h\" },\n ) => Promise<MetricSample[]>;\n /** POST .../enrollments/:enrollmentId/revoke — workspace-admin removal. */\n removeEnrollment?: (\n workspaceId: string,\n enrollmentId: string,\n request?: RemoveEnrollmentRequest,\n ) => Promise<RemoveEnrollmentResponse>;\n /** POST .../machines/:enrollmentId/update — signed, generation-fenced update. */\n updateMachineAgent?: (\n workspaceId: string,\n enrollmentId: string,\n ) => Promise<UpdateMachineAgentResponse>;\n /** PATCH .../machines/:enrollmentId/operation-policy — revision-fenced policy. */\n updateMachineOperationPolicy?: (\n workspaceId: string,\n enrollmentId: string,\n request: UpdateMachineOperationPolicyRequest,\n ) => Promise<MachineOperationPolicy>;\n /**\n * POST .../sessions/:sessionId/active-sandbox — swap the session's active\n * sandbox to a machine. The default swap path; the real SDK client provides it.\n */\n swapActiveSandbox?: (\n workspaceId: string,\n sessionId: string,\n request: { target: string },\n ) => Promise<SwapActiveSandboxResponse>;\n /**\n * Host-supplied swap adapter (an escape hatch). When present it wins over the\n * default `swapActiveSandbox` path. Session-scoped, like the swap it backs.\n */\n attachMachine?: (workspaceId: string, sessionId: string, sandboxId: string) => Promise<unknown>;\n};\n\nexport type UseMachinesOptions = ClientOverride & {\n pollIntervalMs?: number | undefined;\n enabled?: boolean | undefined;\n /** Scope the list to a session (adds the synthetic Modal group box + pointer). */\n sessionId?: string | undefined;\n /**\n * Override the client with one implementing `MachinesClientLike`. Defaults to\n * the provider client cast to the surface (the real SDK client satisfies the\n * read paths). An app supplies an adapter to wire `attachMachine` (the swap).\n */\n machinesClient?: MachinesClientLike | undefined;\n};\n\nexport type UseMachinesResult = {\n machines: MachineView[];\n activeSandboxId: string | null;\n activeEpoch: number;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n /** Attach/swap the session's active sandbox to a machine (returns the new pointer). */\n attach: (sandboxId: string) => Promise<boolean>;\n /** Remove a self-hosted enrollment while retaining history. */\n remove: (\n enrollmentId: string,\n request?: RemoveEnrollmentRequest,\n ) => Promise<RemoveEnrollmentResponse | null>;\n canRemove: boolean;\n removingEnrollmentId: string | null;\n /** Start/retry the signed self-update for one Connected Machine. */\n updateAgent: (enrollmentId: string) => Promise<UpdateMachineAgentResponse | null>;\n canUpdateAgent: boolean;\n updatingEnrollmentId: string | null;\n /** Update the optional per-enrollment command memory policy. */\n updateOperationPolicy: (\n enrollmentId: string,\n request: UpdateMachineOperationPolicyRequest,\n ) => Promise<MachineOperationPolicy | null>;\n canUpdateOperationPolicy: boolean;\n updatingOperationPolicyEnrollmentId: string | null;\n /** Whether the host wired an attach/swap path (drives the card affordance). */\n canAttach: boolean;\n /** Fetch a downsampled metric series for one enrolled machine. */\n fetchSeries: (\n enrollmentId: string,\n window?: \"15m\" | \"1h\" | \"6h\" | \"24h\",\n ) => Promise<MetricSample[]>;\n attaching: boolean;\n /** The sandbox id of the in-flight attach (for per-card spinner gating). */\n attachingSandboxId: string | null;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\nfunction swapFailureMessage(result: SwapActiveSandboxResponse): string {\n if (result.reason?.trim()) return result.reason;\n switch (result.code) {\n case \"recovery_in_progress\":\n return \"The managed sandbox is still recovering. Try again shortly.\";\n case \"recovery_degraded\":\n return \"The managed sandbox recovery is degraded and needs attention.\";\n case \"recovery_unrecoverable\":\n return \"The managed sandbox could not be recovered.\";\n case \"offline_enrollment\":\n return \"The selected machine is offline.\";\n case \"concurrent_swap\":\n return \"The session route changed concurrently. Refresh and try again.\";\n default:\n return \"The session stayed on its current sandbox.\";\n }\n}\n\n/**\n * The workspace Machines fleet: the selfhosted enrollments + the session's Modal\n * box, each with latest metrics + state, plus the active-sandbox pointer. Polls\n * the M10 `GET /machines` endpoint and exposes attach/swap + a metric-series\n * fetch. Renders via `<MachinesDashboard>`. Dual-consumer safe: it reads only the\n * structural `MachinesClientLike` surface, so it works in apps/web AND the Geni\n * frontend (each provides its own client/adapter).\n */\nexport function useMachines(options: UseMachinesOptions = {}): UseMachinesResult {\n const { client, workspaceId } = useOpenGeni(options);\n const machinesClient = (options.machinesClient ??\n (client as unknown as MachinesClientLike)) satisfies MachinesClientLike;\n const sessionId = options.sessionId;\n const identityKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${machinesClientId(machinesClient)}`;\n const identityRef = useRef(identityKey);\n identityRef.current = identityKey;\n\n const load = useCallback(\n async (signal?: AbortSignal) => {\n return await machinesClient.listMachines(workspaceId, {\n ...(sessionId ? { sessionId } : {}),\n ...(signal ? { signal } : {}),\n });\n },\n [machinesClient, workspaceId, sessionId],\n );\n\n const {\n data: loadedData,\n loading,\n error,\n refresh,\n } = useSharedMachinesList(identityKey, load, {\n pollIntervalMs: options.pollIntervalMs,\n enabled: options.enabled,\n });\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner(identityKey);\n // The sandbox id of the in-flight attach (drives the per-card spinner).\n const [attachState, setAttachState] = useState<{\n identity: string;\n sandboxId: string | null;\n }>(() => ({ identity: identityKey, sandboxId: null }));\n const attachingSandboxId = attachState.identity === identityKey ? attachState.sandboxId : null;\n const [removeState, setRemoveState] = useState<{\n identity: string;\n enrollmentId: string | null;\n }>(() => ({ identity: identityKey, enrollmentId: null }));\n const removingEnrollmentId =\n removeState.identity === identityKey ? removeState.enrollmentId : null;\n const [updateState, setUpdateState] = useState<{\n identity: string;\n enrollmentId: string | null;\n }>(() => ({ identity: identityKey, enrollmentId: null }));\n const updatingEnrollmentId =\n updateState.identity === identityKey ? updateState.enrollmentId : null;\n const [operationPolicyState, setOperationPolicyState] = useState<{\n identity: string;\n enrollmentId: string | null;\n }>(() => ({ identity: identityKey, enrollmentId: null }));\n const updatingOperationPolicyEnrollmentId =\n operationPolicyState.identity === identityKey ? operationPolicyState.enrollmentId : null;\n\n const data = loadedData ?? EMPTY_MACHINES;\n // The swap is session-scoped: a host adapter (`attachMachine`) wins; otherwise\n // the default `swapActiveSandbox` path is wired whenever a sessionId is in\n // scope. Either way attach needs a sessionId to point at.\n const canAttach =\n sessionId !== undefined &&\n (typeof machinesClient.attachMachine === \"function\" ||\n typeof machinesClient.swapActiveSandbox === \"function\");\n const canRemove = typeof machinesClient.removeEnrollment === \"function\";\n const canUpdateAgent = typeof machinesClient.updateMachineAgent === \"function\";\n const canUpdateOperationPolicy =\n typeof machinesClient.updateMachineOperationPolicy === \"function\";\n\n const attach = useCallback(\n async (sandboxId: string): Promise<boolean> => {\n if (sessionId === undefined) return false;\n const runSwap = machinesClient.attachMachine\n ? () => machinesClient.attachMachine!(workspaceId, sessionId, sandboxId)\n : machinesClient.swapActiveSandbox\n ? () => machinesClient.swapActiveSandbox!(workspaceId, sessionId, { target: sandboxId })\n : null;\n if (!runSwap) return false;\n const ownedIdentity = identityKey;\n setAttachState({ identity: ownedIdentity, sandboxId });\n const result = await run(async () => {\n const response = await runSwap();\n if (\n response &&\n typeof response === \"object\" &&\n \"swapped\" in response &&\n response.swapped === false\n ) {\n throw new Error(swapFailureMessage(response as SwapActiveSandboxResponse));\n }\n return true;\n });\n if (identityRef.current === ownedIdentity) {\n setAttachState({ identity: ownedIdentity, sandboxId: null });\n if (result) await refresh();\n }\n return result === true;\n },\n [machinesClient, workspaceId, sessionId, identityKey, run, refresh],\n );\n\n const fetchSeries = useCallback(\n async (\n enrollmentId: string,\n window: \"15m\" | \"1h\" | \"6h\" | \"24h\" = \"1h\",\n ): Promise<MetricSample[]> => {\n if (!machinesClient.machineMetricsSeries) return [];\n return await machinesClient.machineMetricsSeries(workspaceId, enrollmentId, { window });\n },\n [machinesClient, workspaceId],\n );\n\n const remove = useCallback(\n async (\n enrollmentId: string,\n request: RemoveEnrollmentRequest = {},\n ): Promise<RemoveEnrollmentResponse | null> => {\n if (!machinesClient.removeEnrollment) return null;\n const ownedIdentity = identityKey;\n setRemoveState({ identity: ownedIdentity, enrollmentId });\n const result = await run(() =>\n machinesClient.removeEnrollment!(workspaceId, enrollmentId, request),\n );\n if (identityRef.current === ownedIdentity) {\n setRemoveState({ identity: ownedIdentity, enrollmentId: null });\n if (result?.outcome === \"removed\" || result?.outcome === \"already_removed\") {\n await refresh();\n }\n }\n return result;\n },\n [machinesClient, workspaceId, identityKey, run, refresh],\n );\n\n const updateAgent = useCallback(\n async (enrollmentId: string): Promise<UpdateMachineAgentResponse | null> => {\n if (!machinesClient.updateMachineAgent) return null;\n const ownedIdentity = identityKey;\n setUpdateState({ identity: ownedIdentity, enrollmentId });\n const result = await run(() => machinesClient.updateMachineAgent!(workspaceId, enrollmentId));\n if (identityRef.current === ownedIdentity) {\n setUpdateState({ identity: ownedIdentity, enrollmentId: null });\n await refresh();\n }\n return result;\n },\n [machinesClient, workspaceId, identityKey, run, refresh],\n );\n\n const updateOperationPolicy = useCallback(\n async (\n enrollmentId: string,\n request: UpdateMachineOperationPolicyRequest,\n ): Promise<MachineOperationPolicy | null> => {\n if (!machinesClient.updateMachineOperationPolicy) return null;\n const ownedIdentity = identityKey;\n setOperationPolicyState({ identity: ownedIdentity, enrollmentId });\n const result = await run(() =>\n machinesClient.updateMachineOperationPolicy!(workspaceId, enrollmentId, request),\n );\n if (identityRef.current === ownedIdentity) {\n setOperationPolicyState({ identity: ownedIdentity, enrollmentId: null });\n if (result) await refresh();\n }\n return result;\n },\n [machinesClient, workspaceId, identityKey, run, refresh],\n );\n\n return {\n machines: data.machines,\n activeSandboxId: data.activeSandboxId,\n activeEpoch: data.activeEpoch,\n loading,\n error,\n refresh,\n attach,\n canAttach,\n fetchSeries,\n attaching: mutating && attachingSandboxId !== null,\n attachingSandboxId,\n remove,\n canRemove,\n removingEnrollmentId,\n updateAgent,\n canUpdateAgent,\n updatingEnrollmentId,\n updateOperationPolicy,\n canUpdateOperationPolicy,\n updatingOperationPolicyEnrollmentId,\n mutationError,\n clearMutationError,\n };\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { MachinesResponse } from \"../types/machines\";\nimport { usePageLiveActivity } from \"./internal\";\n\nexport const EMPTY_MACHINES: MachinesResponse = {\n activeSandboxId: null,\n activeEpoch: 0,\n machines: [],\n};\n\nexport type SharedMachinesSnapshot = {\n data: MachinesResponse | null;\n loading: boolean;\n error: Error | null;\n};\n\ntype Subscriber = {\n load: (signal?: AbortSignal) => Promise<MachinesResponse>;\n pollIntervalMs: number | undefined;\n enabled: boolean;\n pageLive: boolean;\n onChange: () => void;\n};\n\ntype Share = {\n snapshot: SharedMachinesSnapshot;\n subscribers: Set<Subscriber>;\n timer: ReturnType<typeof setTimeout> | null;\n disposeTimer: ReturnType<typeof setTimeout> | null;\n abort: AbortController | null;\n inFlight: Promise<void> | null;\n trailing: Promise<void> | null;\n generation: number;\n};\n\nconst shares = new Map<string, Share>();\n\nfunction emit(share: Share): void {\n for (const subscriber of share.subscribers) {\n subscriber.onChange();\n }\n}\n\nfunction effective(share: Share): { enabled: boolean; pollIntervalMs: number | undefined } {\n let enabled = false;\n let pollIntervalMs: number | undefined;\n for (const subscriber of share.subscribers) {\n if (!subscriber.enabled || !subscriber.pageLive) continue;\n enabled = true;\n if (subscriber.pollIntervalMs !== undefined && subscriber.pollIntervalMs > 0) {\n pollIntervalMs =\n pollIntervalMs === undefined\n ? subscriber.pollIntervalMs\n : Math.min(pollIntervalMs, subscriber.pollIntervalMs);\n }\n }\n return { enabled, pollIntervalMs };\n}\n\nfunction latestLoad(share: Share): ((signal?: AbortSignal) => Promise<MachinesResponse>) | null {\n let load: ((signal?: AbortSignal) => Promise<MachinesResponse>) | null = null;\n for (const subscriber of share.subscribers) {\n if (subscriber.enabled && subscriber.pageLive) load = subscriber.load;\n }\n return load;\n}\n\nfunction stopTimer(share: Share): void {\n if (share.timer !== null) {\n clearTimeout(share.timer);\n share.timer = null;\n }\n}\n\nfunction cancelDispose(share: Share): void {\n if (share.disposeTimer !== null) {\n clearTimeout(share.disposeTimer);\n share.disposeTimer = null;\n }\n}\n\nfunction arm(share: Share): void {\n stopTimer(share);\n const { enabled, pollIntervalMs } = effective(share);\n if (!enabled || pollIntervalMs === undefined) return;\n share.timer = setTimeout(() => {\n share.timer = null;\n void run(share).finally(() => arm(share));\n }, pollIntervalMs);\n}\n\nasync function runFresh(share: Share): Promise<void> {\n const load = latestLoad(share);\n if (!load) return;\n const ticket = ++share.generation;\n const abort = new AbortController();\n share.abort = abort;\n try {\n const data = await load(abort.signal);\n if (ticket !== share.generation || abort.signal.aborted) return;\n share.snapshot = { data, loading: false, error: null };\n emit(share);\n } catch (cause) {\n if (ticket !== share.generation || abort.signal.aborted) return;\n share.snapshot = {\n data: share.snapshot.data,\n loading: false,\n error: cause instanceof Error ? cause : new Error(String(cause)),\n };\n emit(share);\n } finally {\n if (share.abort === abort) share.abort = null;\n }\n}\n\nfunction run(share: Share, force = false): Promise<void> {\n if (!force && share.inFlight) return share.inFlight;\n if (force && share.inFlight) {\n if (share.trailing) return share.trailing;\n let trailing!: Promise<void>;\n trailing = share.inFlight\n .then(async () => {\n if (!effective(share).enabled) return;\n await run(share);\n })\n .finally(() => {\n if (share.trailing === trailing) share.trailing = null;\n });\n share.trailing = trailing;\n return trailing;\n }\n let promise!: Promise<void>;\n promise = runFresh(share).finally(() => {\n if (share.inFlight === promise) share.inFlight = null;\n });\n share.inFlight = promise;\n return promise;\n}\n\nfunction reconcile(share: Share): void {\n const { enabled } = effective(share);\n if (!enabled) {\n share.generation += 1;\n share.abort?.abort();\n share.abort = null;\n share.inFlight = null;\n stopTimer(share);\n if (share.snapshot.loading) {\n share.snapshot = { ...share.snapshot, loading: false };\n emit(share);\n }\n return;\n }\n if (share.snapshot.data !== null || share.snapshot.error) {\n arm(share);\n return;\n }\n share.snapshot = { ...share.snapshot, loading: true };\n emit(share);\n void run(share).finally(() => arm(share));\n}\n\nfunction getOrCreate(shareKey: string): Share {\n const existing = shares.get(shareKey);\n if (existing) {\n cancelDispose(existing);\n return existing;\n }\n const created: Share = {\n snapshot: { data: null, loading: true, error: null },\n subscribers: new Set(),\n timer: null,\n disposeTimer: null,\n abort: null,\n inFlight: null,\n trailing: null,\n generation: 0,\n };\n shares.set(shareKey, created);\n return created;\n}\n\nexport async function refreshSharedMachinesList(shareKey: string): Promise<void> {\n const share = shares.get(shareKey);\n if (!share) return;\n await run(share, true);\n}\n\nexport function useSharedMachinesList(\n shareKey: string,\n load: (signal?: AbortSignal) => Promise<MachinesResponse>,\n options: { pollIntervalMs?: number | undefined; enabled?: boolean | undefined } = {},\n): SharedMachinesSnapshot & { refresh: () => Promise<void> } {\n const enabled = options.enabled ?? true;\n const pageLive = usePageLiveActivity();\n const [, setRevision] = useState(0);\n const live = shares.get(shareKey)?.snapshot;\n const view = live ?? { data: null, loading: enabled && pageLive, error: null };\n\n useEffect(() => {\n const share = getOrCreate(shareKey);\n const subscriber: Subscriber = {\n load,\n pollIntervalMs: options.pollIntervalMs,\n enabled,\n pageLive,\n onChange: () => setRevision((revision) => revision + 1),\n };\n share.subscribers.add(subscriber);\n setRevision((revision) => revision + 1);\n reconcile(share);\n return () => {\n share.subscribers.delete(subscriber);\n if (share.subscribers.size > 0) {\n reconcile(share);\n return;\n }\n // Abort immediately so a session switch does not keep the old GET alive.\n // Keep the snapshot one tick so a same-key remount (poll-interval change)\n // does not flash an empty fleet.\n share.generation += 1;\n share.abort?.abort();\n share.abort = null;\n share.inFlight = null;\n share.trailing = null;\n stopTimer(share);\n cancelDispose(share);\n share.disposeTimer = setTimeout(() => {\n share.disposeTimer = null;\n if (share.subscribers.size === 0 && shares.get(shareKey) === share) {\n shares.delete(shareKey);\n }\n }, 0);\n };\n }, [shareKey, load, options.pollIntervalMs, enabled, pageLive]);\n\n const refresh = useCallback(() => refreshSharedMachinesList(shareKey), [shareKey]);\n return { ...view, refresh };\n}\n"],"mappings":"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","names":["jsx","jsxs","memPct","diskPct","pct","memPct","diskPct","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","AlertTriangleIcon","CpuIcon","LaptopIcon","ServerIcon","AlertTriangleIcon","useState","jsx","jsxs","jsx","jsxs","KindIcon","ServerIcon","CpuIcon","LaptopIcon","AlertTriangleIcon","LaptopIcon","jsx","jsxs","LaptopIcon","LaptopIcon","CpuIcon","UsersIcon","jsx","jsxs","LaptopIcon","CpuIcon","UsersIcon","LaptopIcon","Fragment","jsx","jsxs","LaptopIcon","useState","LaptopIcon","MonitorIcon","TerminalIcon","UsersIcon","jsx","jsxs","useState","LaptopIcon","TerminalIcon","MonitorIcon","UsersIcon","useCallback","useRef","useState","useEffect","useState","useState","useEffect","useRef","useCallback","run","useState"]}