(chore) init commit and add tasks

This commit is contained in:
Story Crater Bot
2026-08-18 18:33:49 -07:00
commit 6c6218ef36
61 changed files with 9851 additions and 0 deletions
+217
View File
@@ -0,0 +1,217 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { ChevronDown } from 'lucide-react'
import { Panel } from '@/components/cluster/Panel'
import { SlotMeter } from '@/components/cluster/SlotMeter'
const DAILY_BUDGET = 12
type Turn = {
role: 'user' | 'model'
reasoning?: string
content: string
streaming?: boolean
}
const SEED: Turn[] = [
{ role: 'user', content: 'Why is the sms application degraded?' },
{
role: 'model',
reasoning:
'The snapshot lists sms with health "degraded" and sync "synced". Sync being clean means the manifests applied fine, so this is a runtime problem rather than a delivery one. The sms namespace shows 0 of 1 pods running. A single pod that never reaches Running, with Argo reporting the desired state as applied, usually means the pod cannot be placed at all.',
content:
'Delivery is fine — sms is Synced, so Argo applied everything it was asked to. The failure is at runtime: the namespace has one pod and zero running. Argo marks the app degraded because the workload never became ready, not because the manifests are wrong.',
},
]
const REPLY =
'Wave 4 is empty. Waves are sort keys, not a sequence — Argo orders by value and skips gaps, so 3 is followed directly by 5. Nothing is missing.'
const REPLY_REASONING =
'The user is asking about a gap in the wave column display. Argo CD sync waves are integers used purely for ordering; there is no requirement that they be contiguous. The cluster uses 0,1,2,3,5,6,7,8. This is normal and usually happens when a wave is retired or intentionally reserved.'
export default function ChatPage() {
const [turns, setTurns] = useState<Turn[]>(SEED)
const [value, setValue] = useState('')
const [queue, setQueue] = useState<number | null>(null)
const [slots, setSlots] = useState(3)
const [used, setUsed] = useState(2)
const [openReasoning, setOpenReasoning] = useState<number | null>(1)
const scrollRef = useRef<HTMLDivElement>(null)
useEffect(() => {
scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' })
}, [turns, queue])
const send = () => {
if (!value.trim() || queue !== null || used >= DAILY_BUDGET) return
setTurns((t) => [...t, { role: 'user', content: value }])
setValue('')
setQueue(3)
}
// Placeholder for the queue → stream transition. Real version is SSE from atlas.
useEffect(() => {
if (queue === null) return
if (queue > 0) {
const t = setTimeout(() => setQueue((q) => (q === null ? null : q - 1)), 700)
return () => clearTimeout(t)
}
setQueue(null)
setSlots((s) => Math.min(s + 1, 6))
setUsed((u) => u + 1)
setTurns((t) => [...t, { role: 'model', reasoning: REPLY_REASONING, content: '', streaming: true }])
let i = 0
const stream = setInterval(() => {
i += 3
setTurns((t) => {
const next = [...t]
const last = next[next.length - 1]
if (last?.role !== 'model') return t
next[next.length - 1] = { ...last, content: REPLY.slice(0, i), streaming: i < REPLY.length }
return next
})
if (i >= REPLY.length) {
clearInterval(stream)
setSlots((s) => Math.max(s - 1, 1))
}
}, 40)
return () => clearInterval(stream)
}, [queue])
const exhausted = used >= DAILY_BUDGET
return (
<div className="space-y-6">
<header className="border border-wire bg-deck p-6 md:p-8">
<p className="font-data text-[10px] uppercase tracking-[0.2em] text-dim">Surface D — Chat</p>
<h1 className="mt-3 max-w-3xl font-signage text-3xl font-semibold leading-[1.1] tracking-signage md:text-5xl">
A 32B model, running on one card, <span className="text-lamp">two rooms from here.</span>
</h1>
<p className="mt-5 max-w-2xl font-plex text-sm leading-relaxed text-dim">
It reads a redacted snapshot of the cluster and answers questions about it. It cannot query anything, run
anything, or change anything. When all six public slots are busy, you wait in line — the queue is real,
and so is the hardware.
</p>
<div className="mt-6 flex flex-wrap items-center gap-6">
<SlotMeter used={slots} size="lg" showCap />
<span className="font-data text-[10px] uppercase tracking-[0.14em] text-dim">
{DAILY_BUDGET - used} of {DAILY_BUDGET} messages left today
</span>
</div>
</header>
<div className="grid gap-6 lg:grid-cols-[1fr_260px]">
<Panel label="Session" hint="anonymous">
<div ref={scrollRef} className="h-[440px] space-y-5 overflow-y-auto pr-1">
{turns.map((turn, i) =>
turn.role === 'user' ? (
<div key={i} className="flex justify-end">
<p className="max-w-[85%] border border-wire-lit bg-riser px-3 py-2 font-plex text-sm text-chalk">
{turn.content}
</p>
</div>
) : (
<div key={i} className="max-w-[92%] space-y-2">
{turn.reasoning && (
<div className="border-l-2 border-lamp/50">
<button
onClick={() => setOpenReasoning(openReasoning === i ? null : i)}
aria-expanded={openReasoning === i}
className="flex w-full items-center gap-2 py-1 pl-3 font-data text-[10px] uppercase tracking-[0.16em] text-lamp focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp"
>
<ChevronDown
size={12}
className={`transition-transform ${openReasoning === i ? '' : '-rotate-90'}`}
/>
thinking
</button>
{openReasoning === i && (
<p className="py-1 pl-3 pr-2 font-data text-[11px] leading-relaxed text-dim">
{turn.reasoning}
</p>
)}
</div>
)}
<p className="font-plex text-sm leading-relaxed text-chalk">
{turn.content}
{turn.streaming && <span className="ml-0.5 inline-block h-4 w-2 animate-pulse bg-lamp align-text-bottom" />}
</p>
</div>
),
)}
{queue !== null && (
<div className="flex items-center gap-3 border border-lamp/40 px-3 py-2">
<SlotMeter used={6} />
<p className="font-data text-[11px] text-lamp">
all six public slots busy · position {queue} in queue
</p>
</div>
)}
</div>
<form
onSubmit={(e) => {
e.preventDefault()
send()
}}
className="mt-3 flex items-center gap-2 border-t border-wire pt-3"
>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
disabled={exhausted}
aria-label="Message"
placeholder={exhausted ? 'Daily limit reached — resets in 14h' : 'Ask about the cluster'}
className="min-w-0 flex-1 bg-transparent font-plex text-sm text-chalk placeholder:text-dim/60 focus:outline-none disabled:cursor-not-allowed"
/>
<button
type="submit"
disabled={exhausted || queue !== null}
className="border border-lamp px-3 py-1 font-data text-[10px] uppercase tracking-[0.14em] text-lamp transition-colors hover:bg-lamp hover:text-void focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp disabled:opacity-30 disabled:hover:bg-transparent disabled:hover:text-lamp"
>
send
</button>
</form>
</Panel>
<div className="space-y-6">
<Panel label="Limits" hint="tier 3">
<dl className="space-y-2.5 font-data text-[11px]">
{[
['public slots', '6 of 8'],
['queue depth', '20'],
['per session', '12 / day'],
['request timeout', '120s'],
['output cap', '1500 tokens'],
].map(([k, v]) => (
<div key={k} className="flex items-baseline gap-2">
<dt className="text-dim">{k}</dt>
<dd className="ml-auto tabular-nums text-chalk">{v}</dd>
</div>
))}
</dl>
<p className="mt-4 border-t border-wire pt-3 font-plex text-[11px] leading-relaxed text-dim">
Closing this tab frees your slot immediately. Two slots stay reserved so the operator is never locked
out of their own hardware.
</p>
</Panel>
<Panel label="Cannot do" hint="by construction">
<ul className="space-y-1.5 font-data text-[10px] text-dim">
{['call tools', 'query the cluster', 'read logs', 'change anything', 'see Secret contents'].map((x) => (
<li key={x} className="flex items-center gap-2">
<span className="h-px w-3 bg-wire-lit" />
{x}
</li>
))}
</ul>
</Panel>
</div>
</div>
</div>
)
}
+219
View File
@@ -0,0 +1,219 @@
'use client'
import { useCallback, useEffect, useState } from 'react'
import { Panel } from '@/components/cluster/Panel'
import { DEFAULT_KINDS, WAVES, apps, appsInWave, resourceKinds, type App } from '@/lib/clusterMock'
const TOTAL_RESOURCES = apps.reduce((n, a) => n + a.resources, 0)
/** Resource count as discrete cells, capped so a 68-resource app stays readable. */
function CountBar({ n }: { n: number }) {
const cells = Math.min(n, 24)
return (
<div className="mt-2 flex flex-wrap gap-[2px]" aria-label={`${n} resources`}>
{Array.from({ length: cells }, (_, i) => (
<span key={i} className="h-1.5 w-1.5 rounded-[1px] bg-wire-lit" />
))}
{n > 24 && <span className="ml-1 font-data text-[9px] leading-none text-dim">+{n - 24}</span>}
</div>
)
}
function AppCard({
app,
state,
active,
onSelect,
}: {
app: App
state: 'idle' | 'syncing' | 'done'
active: boolean
onSelect: () => void
}) {
const degraded = app.health === 'degraded'
const drifted = app.sync === 'outofsync'
const border = active
? 'border-lamp'
: state === 'syncing'
? 'border-lamp/70'
: degraded
? 'border-rose/50'
: drifted
? 'border-lamp/40'
: 'border-wire'
return (
<button
onClick={onSelect}
aria-pressed={active}
className={[
'w-full border bg-deck p-2.5 text-left transition-all duration-300',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp',
border,
state === 'syncing' ? 'bg-riser' : '',
active ? 'bg-riser' : 'hover:border-wire-lit',
].join(' ')}
>
<div className="flex items-start justify-between gap-2">
<span className="font-data text-[11px] leading-tight text-chalk">{app.name}</span>
<span
className={[
'mt-1 h-1.5 w-1.5 shrink-0 rounded-full transition-colors',
state === 'syncing' ? 'bg-lamp' : degraded ? 'bg-rose' : drifted ? 'bg-lamp' : 'bg-flux',
].join(' ')}
/>
</div>
<CountBar n={app.resources} />
{(degraded || drifted) && (
<p className={`mt-2 font-data text-[9px] uppercase tracking-[0.14em] ${degraded ? 'text-rose' : 'text-lamp'}`}>
{degraded ? 'degraded' : 'out of sync'}
</p>
)}
</button>
)
}
export default function DeliveryPage() {
const [selected, setSelected] = useState<string | null>('prometheus')
const [front, setFront] = useState<number | null>(null)
const replay = useCallback(() => setFront(0), [])
useEffect(() => {
if (front === null) return
if (front > 8) {
const done = setTimeout(() => setFront(null), 700)
return () => clearTimeout(done)
}
const next = setTimeout(() => setFront((w) => (w === null ? null : w + 1)), 520)
return () => clearTimeout(next)
}, [front])
const selectedApp = apps.find((a) => a.name === selected) ?? null
const kinds = selectedApp ? (resourceKinds[selectedApp.name] ?? DEFAULT_KINDS) : []
return (
<div className="space-y-6">
<header className="border border-wire bg-deck p-6 md:p-8">
<p className="font-data text-[10px] uppercase tracking-[0.2em] text-dim">Surface E — Delivery</p>
<h1 className="mt-3 max-w-3xl font-signage text-3xl font-semibold leading-[1.1] tracking-signage md:text-5xl">
Nothing starts until the thing it needs is already running.
</h1>
<p className="mt-5 max-w-2xl font-plex text-sm leading-relaxed text-dim">
{apps.length} applications, {TOTAL_RESOURCES} resources, applied in nine ordered waves. Certificates
before issuers, issuers before ingress, storage before the databases that sit on it. The order is the
design.
</p>
<button
onClick={replay}
disabled={front !== null}
className="mt-6 border border-lamp px-4 py-2 font-data text-[11px] uppercase tracking-[0.16em] text-lamp transition-colors hover:bg-lamp hover:text-void focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp disabled:opacity-40 disabled:hover:bg-transparent disabled:hover:text-lamp"
>
{front !== null ? `syncing wave ${Math.min(front, 8)}` : 'Replay sync'}
</button>
</header>
<div className="grid gap-6 xl:grid-cols-[1fr_340px]">
<Panel label="Sync waves" hint="0 → 8, left to right" className="min-w-0">
<div className="-mx-4 overflow-x-auto px-4 pb-2">
<div className="flex min-w-max gap-3">
{WAVES.map((wave) => {
const inWave = appsInWave(wave)
const state = front === null ? 'idle' : front === wave ? 'syncing' : front > wave ? 'done' : 'idle'
return (
<div key={wave} className="w-[168px] shrink-0">
<div
className={[
'mb-3 flex items-baseline justify-between border-b pb-1.5 transition-colors',
state === 'syncing' ? 'border-lamp' : 'border-wire',
].join(' ')}
>
<span
className={[
'font-signage text-2xl font-semibold leading-none transition-colors',
state === 'syncing' ? 'text-lamp' : inWave.length ? 'text-chalk' : 'text-wire-lit',
].join(' ')}
>
{wave}
</span>
<span className="font-data text-[9px] uppercase tracking-[0.14em] text-dim">
{inWave.length || '—'}
</span>
</div>
{inWave.length === 0 ? (
<p className="border border-dashed border-wire p-2.5 font-data text-[10px] leading-relaxed text-dim">
unused — waves are sparse by design, not sequential
</p>
) : (
<div className="space-y-2">
{inWave.map((app) => (
<AppCard
key={app.name}
app={app}
state={state}
active={selected === app.name}
onSelect={() => setSelected(app.name)}
/>
))}
</div>
)}
</div>
)
})}
</div>
</div>
</Panel>
<Panel
label={selectedApp ? selectedApp.name : 'No selection'}
hint={selectedApp ? `wave ${selectedApp.wave ?? '—'} · ${selectedApp.resources} resources` : 'pick an app'}
>
{selectedApp ? (
<div className="space-y-4">
<dl className="grid grid-cols-2 gap-3 font-data text-[11px]">
<div>
<dt className="text-dim">sync</dt>
<dd className={selectedApp.sync === 'synced' ? 'text-flux' : 'text-lamp'}>{selectedApp.sync}</dd>
</div>
<div>
<dt className="text-dim">health</dt>
<dd className={selectedApp.health === 'healthy' ? 'text-flux' : 'text-rose'}>
{selectedApp.health}
</dd>
</div>
</dl>
<div>
<p className="mb-2 font-data text-[10px] uppercase tracking-[0.16em] text-dim">Resources by kind</p>
<ul className="space-y-1.5">
{kinds.map((k) => (
<li key={k.kind} className="flex items-center gap-3 font-data text-[11px]">
<span className={k.named ? 'text-chalk' : 'text-dim'}>{k.kind}</span>
<span className="h-px flex-1 bg-wire" />
<span className="tabular-nums text-dim">{k.count}</span>
{!k.named && (
<span className="border border-wire-lit px-1 text-[9px] uppercase tracking-[0.1em] text-dim">
count only
</span>
)}
</li>
))}
</ul>
</div>
<p className="border-t border-wire pt-3 font-plex text-[11px] leading-relaxed text-dim">
Secrets appear as counts. Names, source repositories, and condition messages are never sent to the
browser.
</p>
</div>
) : (
<p className="font-plex text-sm text-dim">Select an application to inspect its resources.</p>
)}
</Panel>
</div>
</div>
)
}
+39
View File
@@ -0,0 +1,39 @@
import type { ReactNode } from 'react'
import { IBM_Plex_Mono, IBM_Plex_Sans, IBM_Plex_Sans_Condensed } from 'next/font/google'
import { Rail } from '@/components/cluster/Rail'
import { Ribbon } from '@/components/cluster/Ribbon'
const signage = IBM_Plex_Sans_Condensed({
subsets: ['latin'],
weight: ['600', '700'],
variable: '--font-signage',
})
const plex = IBM_Plex_Sans({
subsets: ['latin'],
weight: ['400', '500', '600'],
variable: '--font-plex',
})
const data = IBM_Plex_Mono({
subsets: ['latin'],
weight: ['400', '500'],
variable: '--font-data',
})
export const metadata = {
title: 'Cluster — Rock Liang',
description: 'Live view of a Talos Kubernetes cluster: topology, GitOps delivery, and GPU inference.',
}
export default function ClusterLayout({ children }: { children: ReactNode }) {
return (
<div className={`${signage.variable} ${plex.variable} ${data.variable} min-h-screen bg-void font-plex text-chalk`}>
<Ribbon />
<div className="flex min-h-[calc(100vh-42px)] flex-col md:flex-row">
<Rail />
<main className="min-w-0 flex-1 p-4 md:p-6">{children}</main>
</div>
</div>
)
}
+147
View File
@@ -0,0 +1,147 @@
'use client'
import { useState } from 'react'
import { Panel } from '@/components/cluster/Panel'
import { SlotMeter } from '@/components/cluster/SlotMeter'
import { models, namespaces, nodes, type Node } from '@/lib/clusterMock'
function Cells({ filled, total, tone = 'flux' }: { filled: number; total: number; tone?: 'flux' | 'rose' }) {
return (
<div className="flex gap-[2px]" aria-label={`${filled} of ${total} running`}>
{Array.from({ length: total }, (_, i) => (
<span
key={i}
className={`h-2.5 w-[5px] rounded-[1px] ${i < filled ? (tone === 'rose' ? 'bg-rose' : 'bg-flux') : 'bg-wire'}`}
/>
))}
</div>
)
}
function NodeCard({ node, active, onSelect }: { node: Node; active: boolean; onSelect: () => void }) {
const isGpu = node.gpu > 0
return (
<button
onClick={onSelect}
aria-pressed={active}
className={[
'group relative border p-4 text-left transition-colors',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp',
active ? 'border-lamp bg-riser' : 'border-wire bg-deck hover:border-wire-lit',
].join(' ')}
>
{isGpu && <span className="absolute right-0 top-0 h-6 w-px bg-lamp" />}
<div className="flex items-baseline justify-between">
<h3 className="font-signage text-xl font-semibold tracking-signage">{node.name}</h3>
<span className={`h-1.5 w-1.5 rounded-full ${node.health === 'healthy' ? 'bg-flux' : 'bg-rose'}`} />
</div>
<p className={`mt-1 font-data text-[10px] uppercase tracking-[0.14em] ${isGpu ? 'text-lamp' : 'text-dim'}`}>
{node.role}
</p>
<dl className="mt-4 space-y-1.5 font-data text-[11px]">
<div className="flex justify-between">
<dt className="text-dim">cpu</dt>
<dd className="tabular-nums">{node.cpu}</dd>
</div>
<div className="flex justify-between">
<dt className="text-dim">mem</dt>
<dd className="tabular-nums">{node.memoryGi} Gi</dd>
</div>
<div className="flex justify-between">
<dt className="text-dim">gpu</dt>
<dd className={`tabular-nums ${isGpu ? 'text-lamp' : 'text-dim'}`}>{node.gpu}</dd>
</div>
<div className="flex justify-between">
<dt className="text-dim">pods</dt>
<dd className="tabular-nums">{node.pods}</dd>
</div>
</dl>
</button>
)
}
export default function TopologyPage() {
const [selected, setSelected] = useState('worker-1')
return (
<div className="space-y-6">
{/* Thesis: the constraint that shaped everything downstream. */}
<header className="border border-wire bg-deck p-6 md:p-8">
<p className="font-data text-[10px] uppercase tracking-[0.2em] text-dim">Surface B — Topology</p>
<h1 className="mt-3 max-w-3xl font-signage text-3xl font-semibold leading-[1.1] tracking-signage md:text-5xl">
Four nodes. One GPU. <span className="text-lamp">Eight sequence slots</span> for everything that thinks.
</h1>
<div className="mt-6 flex flex-wrap items-center gap-4">
<SlotMeter used={3} size="lg" showCap />
</div>
<p className="mt-6 max-w-2xl font-plex text-sm leading-relaxed text-dim">
Every workload below runs on hardware sitting in one room. The scarcest thing in it is inference
capacity, so that is the number this page keeps in front of you.
</p>
</header>
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
{nodes.map((n) => (
<NodeCard key={n.name} node={n} active={selected === n.name} onSelect={() => setSelected(n.name)} />
))}
</div>
<div className="grid gap-6 lg:grid-cols-[1.4fr_1fr]">
<Panel label="Namespaces" hint="pods running / scheduled">
<ul className="space-y-1.5">
{namespaces.map((ns) => {
const short = ns.running < ns.total
return (
<li key={ns.name} className="flex items-center gap-4 py-0.5">
<span className="w-40 shrink-0 truncate font-data text-[11px] text-chalk">{ns.name}</span>
<Cells filled={ns.running} total={ns.total} tone={ns.running === 0 ? 'rose' : 'flux'} />
<span
className={`ml-auto shrink-0 font-data text-[11px] tabular-nums ${short ? 'text-lamp' : 'text-dim'}`}
>
{ns.running}/{ns.total}
</span>
</li>
)
})}
</ul>
</Panel>
<div className="space-y-6">
<Panel label="Inference" hint="KServe · worker-1">
<ul className="space-y-3">
{models.map((m) => (
<li key={m.name} className="border-b border-wire pb-3 last:border-0 last:pb-0">
<div className="flex items-baseline justify-between">
<span className="font-signage text-base font-semibold tracking-signage">{m.name}</span>
<span className={`font-data text-[10px] uppercase tracking-[0.14em] ${m.ready ? 'text-flux' : 'text-rose'}`}>
{m.ready ? 'ready' : 'down'}
</span>
</div>
<p className="mt-1 font-data text-[10px] text-dim">
{m.replicas}× replica · {m.seqPerReplica} seq · {m.contextTokens.toLocaleString()} ctx
</p>
</li>
))}
</ul>
</Panel>
<Panel label="Withheld" hint="redaction allowlist">
<ul className="space-y-1.5 font-data text-[10px] text-dim">
{['node and pod addresses', 'container arguments', 'image tags and digests', 'source repository URLs', 'Secret names', 'condition messages'].map((x) => (
<li key={x} className="flex items-center gap-2">
<span className="h-px w-3 bg-wire-lit" />
{x}
</li>
))}
</ul>
<p className="mt-4 font-plex text-[11px] leading-relaxed text-dim">
Fields are built by explicit construction, so anything not listed as public never enters the
response.
</p>
</Panel>
</div>
</div>
</div>
)
}
+173
View File
@@ -0,0 +1,173 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { Panel } from '@/components/cluster/Panel'
import { namespaces, nodes, apps } from '@/lib/clusterMock'
const COMMANDS = [
'get nodes',
'get pods <ns>',
'get apps',
'top nodes',
'describe pod <ns> <name>',
'help',
]
type Line = { kind: 'input' | 'output' | 'reject'; text: string }
const pad = (s: string, n: number) => s.padEnd(n, ' ')
function run(raw: string): Line[] {
const cmd = raw.trim().toLowerCase()
if (cmd === 'help') {
return [{ kind: 'output', text: COMMANDS.map((c) => ` ${c}`).join('\n') }]
}
if (cmd === 'get nodes') {
const head = `${pad('NAME', 14)}${pad('ROLE', 16)}${pad('CPU', 6)}${pad('MEM', 8)}GPU`
const rows = nodes.map((n) => `${pad(n.name, 14)}${pad(n.role, 16)}${pad(String(n.cpu), 6)}${pad(`${n.memoryGi}Gi`, 8)}${n.gpu}`)
return [{ kind: 'output', text: [head, ...rows].join('\n') }]
}
if (cmd === 'get apps') {
const head = `${pad('NAME', 24)}${pad('WAVE', 7)}${pad('SYNC', 12)}HEALTH`
const rows = apps.map((a) => `${pad(a.name, 24)}${pad(String(a.wave ?? '-'), 7)}${pad(a.sync, 12)}${a.health}`)
return [{ kind: 'output', text: [head, ...rows].join('\n') }]
}
if (cmd === 'top nodes') {
const head = `${pad('NAME', 14)}${pad('CPU%', 8)}MEM%`
const rows = nodes.map((n) => `${pad(n.name, 14)}${pad(n.gpu ? '61%' : '18%', 8)}${n.gpu ? '74%' : '42%'}`)
return [{ kind: 'output', text: [head, ...rows].join('\n') }]
}
if (cmd.startsWith('get pods')) {
const ns = cmd.split(/\s+/)[2]
if (!ns) return [{ kind: 'reject', text: 'get pods requires a namespace. Try: get pods llm-serving' }]
const known = namespaces.find((n) => n.name === ns)
if (!known) {
return [
{
kind: 'reject',
text: `unknown namespace "${ns}" — rejected on snapshot membership, no lookup performed`,
},
]
}
const rows = Array.from({ length: Math.min(known.total, 8) }, (_, i) => {
const running = i < known.running
return `${pad(`${ns}-workload-${i + 1}`, 30)}${pad(running ? '1/1' : '0/1', 6)}${running ? 'Running' : 'Pending'}`
})
return [{ kind: 'output', text: [`${pad('NAME', 30)}${pad('READY', 6)}STATUS`, ...rows].join('\n') }]
}
if (cmd.startsWith('describe pod')) {
return [{ kind: 'output', text: 'phase: Running\nrestarts: 0\nage: 17h\nnode: worker-1\nready: true' }]
}
return [
{
kind: 'reject',
text: `"${raw.trim()}" is not in the command set. Input parses to a closed enum; nothing else reaches the cluster. Type help.`,
},
]
}
const BOOT: Line[] = [
{ kind: 'output', text: 'atlas read-only shell. Six commands, no shell, no exec.\nType help to list them.' },
]
export default function TerminalPage() {
const [lines, setLines] = useState<Line[]>(BOOT)
const [value, setValue] = useState('')
const scrollRef = useRef<HTMLDivElement>(null)
useEffect(() => {
scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight })
}, [lines])
const submit = (raw: string) => {
if (!raw.trim()) return
setLines((prev) => [...prev, { kind: 'input', text: raw }, ...run(raw)])
setValue('')
}
return (
<div className="space-y-6">
<header className="border border-wire bg-deck p-6 md:p-8">
<p className="font-data text-[10px] uppercase tracking-[0.2em] text-dim">Surface C — Terminal</p>
<h1 className="mt-3 max-w-3xl font-signage text-3xl font-semibold leading-[1.1] tracking-signage md:text-5xl">
Six commands. <span className="text-lamp">Everything else is rejected</span> before it reaches anything.
</h1>
<p className="mt-5 max-w-2xl font-plex text-sm leading-relaxed text-dim">
Input parses to a closed enum. Namespace and pod arguments are checked against the current snapshot by
membership, not by pattern matching. There is no shell in the container. Try to break it.
</p>
</header>
<div className="grid gap-6 lg:grid-cols-[1fr_260px]">
<Panel label="Shell" hint="read-only">
<div ref={scrollRef} className="h-[420px] overflow-y-auto font-data text-[12px] leading-relaxed">
{lines.map((line, i) => (
<div key={i} className="whitespace-pre-wrap">
{line.kind === 'input' && (
<p className="mt-3 text-chalk">
<span className="text-lamp">$ </span>
{line.text}
</p>
)}
{line.kind === 'output' && <p className="text-dim">{line.text}</p>}
{line.kind === 'reject' && (
<p className="mt-1 border-l-2 border-rose pl-3 text-rose">{line.text}</p>
)}
</div>
))}
</div>
<form
onSubmit={(e) => {
e.preventDefault()
submit(value)
}}
className="mt-3 flex items-center gap-2 border-t border-wire pt-3"
>
<span className="font-data text-[12px] text-lamp">$</span>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
spellCheck={false}
autoComplete="off"
aria-label="Cluster command"
placeholder="get pods llm-serving"
className="min-w-0 flex-1 bg-transparent font-data text-[12px] text-chalk placeholder:text-dim/60 focus:outline-none"
/>
<button
type="submit"
className="border border-wire-lit px-3 py-1 font-data text-[10px] uppercase tracking-[0.14em] text-dim transition-colors hover:border-lamp hover:text-lamp focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp"
>
run
</button>
</form>
</Panel>
<Panel label="Command set" hint="allowlist">
<ul className="space-y-2">
{COMMANDS.map((c) => (
<li key={c}>
<button
onClick={() => submit(c.replace('<ns>', 'llm-serving').replace('<name>', 'ornith-predictor'))}
className="w-full border border-wire px-2.5 py-2 text-left font-data text-[11px] text-chalk transition-colors hover:border-lamp hover:text-lamp focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lamp"
>
{c}
</button>
</li>
))}
</ul>
<p className="mt-4 border-t border-wire pt-3 font-plex text-[11px] leading-relaxed text-dim">
Every rejected input is logged with its source address. The allowlist is the whole security model.
</p>
</Panel>
</div>
</div>
)
}