agent: scaffold Preact rewrite, Header + StatusChips first slice
Adds a new Preact/TSX build alongside the existing app.js (esbuild
entry `main.tsx` → dist/static/main.{js,css}, same jsx/tsconfig shape
swarm-ui already uses) and the first real page slice: Header +
StatusChips, composing the Badge/Dropdown components from the prior
commit's PR. Not wired into index.html yet — app.js keeps rendering
the live page untouched while this fills in component by component
(state polling, the live SSE stream, login flow, inbox/todos, term
input) in follow-up commits on this branch.
StatusChips folds the model/effort pickers and pause into the badge
row itself (each badge IS its own control), replacing the old
overflow-menu-only pickers — the concrete fix the design guide already
names this page as needing. Presentational only for now (props, not
live data) so it's reviewable against sample data before being wired
to /api/state.
Screenshot-verified against the real agent.css/theme.css/colors.css
(headless chromium, sample data) — renders correctly.
Builds + tsc --noEmit clean.
This commit is contained in:
parent
f5a4e380c9
commit
93b34ebb9b
11 changed files with 334 additions and 3 deletions
37
frontend/packages/agent/src/Root.tsx
Normal file
37
frontend/packages/agent/src/Root.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// <Root> — root of the Preact rewrite. Currently just `Header` +
|
||||
// `StatusChips` wired to local component state as a first slice (real
|
||||
// `/api/state` polling + the live SSE stream land in follow-up commits
|
||||
// on this same PR, per mara's "one pr != one commit" note on the
|
||||
// issue). Sample values below match the shapes in `types.ts`.
|
||||
import { useState } from 'preact/hooks';
|
||||
import { Header } from './components/Header.js';
|
||||
import { StatusChips } from './components/StatusChips.js';
|
||||
|
||||
export function Root() {
|
||||
const [model, setModel] = useState('sonnet');
|
||||
const [effort, setEffort] = useState('high');
|
||||
const [paused, setPaused] = useState(false);
|
||||
|
||||
return (
|
||||
<Header label="IRIS" hiveLabel="constellation / pr1ma">
|
||||
<StatusChips
|
||||
aliveLabel="alive"
|
||||
aliveTone="positive"
|
||||
stateLabel="idle · 6m 1s"
|
||||
stateTone="neutral"
|
||||
stateTooltip="turn loop running, no claude invocation in flight"
|
||||
model={model}
|
||||
availableModels={['haiku', 'sonnet', 'opus']}
|
||||
onSelectModel={setModel}
|
||||
effort={effort}
|
||||
availableEfforts={['low', 'medium', 'high', 'xhigh', 'max']}
|
||||
onSelectEffort={setEffort}
|
||||
ctxLabel="534k"
|
||||
costLabel="$1.6M"
|
||||
paused={paused}
|
||||
onTogglePause={() => setPaused((p) => !p)}
|
||||
lastTurnLabel="last turn 8.4s"
|
||||
/>
|
||||
</Header>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue