From ba683c067c63d917d2d56cebb86dd73c0da902eb Mon Sep 17 00:00:00 2001 From: Sage Hart Date: Sat, 25 Jul 2026 23:52:36 -0500 Subject: [PATCH 1/3] feat(console): cool slate ops chrome and company-day demo timeline Ship restrained teal slate console, ordered agent activity timeline with stage-reveal, Contracts panel, and multi-frame demo.gif under ADR-05. --- .corp-harness/site.json | 2 +- README.md | 4 +- apps/console/index.html | 6 ++ apps/console/src/main.tsx | 140 +++++++++++++++++++++++++++++-- apps/console/src/styles.css | 92 +++++++++++++++++--- apps/console/src/vite-env.d.ts | 1 + apps/console/tsconfig.json | 4 +- docs/adr/0005-company-day.md | 2 +- docs/assets/README.md | 10 +-- docs/assets/demo.gif | Bin 109727 -> 394943 bytes docs/assets/governor.png | Bin 93880 -> 95298 bytes docs/assets/ops-day.png | Bin 150883 -> 149248 bytes docs/assets/ops.png | Bin 116033 -> 124438 bytes docs/future-of-the-firm.md | 2 +- packages/core/src/company-day.ts | 87 ++++++++++++++++++- scripts/capture-screenshots.mjs | 44 +++++++--- scripts/harness/verify.sh | 37 +++++++- test/company-day.test.ts | 7 ++ 18 files changed, 393 insertions(+), 45 deletions(-) create mode 100644 apps/console/src/vite-env.d.ts diff --git a/.corp-harness/site.json b/.corp-harness/site.json index 955662d..66d2cff 100644 --- a/.corp-harness/site.json +++ b/.corp-harness/site.json @@ -2,7 +2,7 @@ "schema": "corporate-site-site/v1", "site_id": "corpos", "corporate_program": "corpos-autonomous-company", - "corporate_handoff_sha256": "c0bb90e70fdfe705192e435869c30ab401339ec6b47c0576be34d7f48bae1975", + "corporate_handoff_sha256": "0953f106918b8ffe1a61e30f3a69afbd0498bd44df695ff6b3c15c4b6915af68", "verify_argv": ["./scripts/harness/verify.sh"], "adversarial_argv": ["./scripts/harness/adversarial.sh"] } diff --git a/README.md b/README.md index 122fb6a..0e1cf52 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Read the thesis: [`docs/future-of-the-firm.md`](docs/future-of-the-firm.md). ## Demo

- CorpOS ops console — capital and trust, company day result, and Governor audit controls (synthetic demo data) + CorpOS ops console — agents hand off a company day (support → finance → ops), trust unlock, and Governor (synthetic demo data)

### Screenshots @@ -33,7 +33,7 @@ Read the thesis: [`docs/future-of-the-firm.md`](docs/future-of-the-firm.md). - **Local demo:** `npm install && npm run build && npm run dev` → [http://localhost:3000](http://localhost:3000) - **Regenerate GIF/PNGs:** start the console, then `npm run screenshots` — see [`docs/assets/README.md`](docs/assets/README.md) -Click **Run company day** for the multi-handoff demo (support → finance → ops), including an autonomous settle, an exception approval path, compensation, and trust unlock. +Click **Run company day** to watch the agent activity timeline: support → finance → ops handoffs, an autonomous settle, an exception approval path, compensation, and trust unlock. --- diff --git a/apps/console/index.html b/apps/console/index.html index 347e35c..de6a587 100644 --- a/apps/console/index.html +++ b/apps/console/index.html @@ -4,6 +4,12 @@ CorpOS Ops Console + + +
diff --git a/apps/console/src/main.tsx b/apps/console/src/main.tsx index bdb5702..f612fbe 100644 --- a/apps/console/src/main.tsx +++ b/apps/console/src/main.tsx @@ -24,29 +24,93 @@ type Exception = { agentId: string; }; +type Contract = { + id: string; + title: string; + state: string; + assigneesJson?: string; +}; + +type TimelineEvent = { + id: string; + agentId: string; + role: string; + kind: string; + summary: string; +}; + +type CompanyDay = { + contractId: string; + handoffs: number; + autonomousSettles: number; + exceptionSettles: number; + compensated: number; + trustAfter: number; + slaExceptions: number; + auditHead: string; + ok: boolean; + timeline: TimelineEvent[]; +}; + +const REVEAL_MS = 500; + function App() { const [firm, setFirm] = useState(null); const [exceptions, setExceptions] = useState([]); - const [day, setDay] = useState | null>(null); + const [contracts, setContracts] = useState([]); + const [day, setDay] = useState(null); + const [visibleCount, setVisibleCount] = useState(0); + const [running, setRunning] = useState(false); const [tab, setTab] = useState<"ops" | "governor">("ops"); const refresh = async () => { const f = await fetch("/api/firm").then((r) => r.json()); const e = await fetch("/api/exceptions").then((r) => r.json()); + const c = await fetch("/api/contracts").then((r) => r.json()); setFirm(f); setExceptions(e); + setContracts(c); }; useEffect(() => { void refresh(); }, []); + useEffect(() => { + if (!day?.timeline.length) { + setVisibleCount(0); + return; + } + setVisibleCount(0); + let n = 0; + const id = window.setInterval(() => { + n += 1; + setVisibleCount(n); + if (n >= day.timeline.length) { + window.clearInterval(id); + } + }, REVEAL_MS); + return () => window.clearInterval(id); + }, [day]); + const runDay = async () => { - const r = await fetch("/api/company-day", { method: "POST" }).then((res) => res.json()); - setDay(r); - await refresh(); + setRunning(true); + setDay(null); + setVisibleCount(0); + try { + const r = (await fetch("/api/company-day", { method: "POST" }).then((res) => + res.json(), + )) as CompanyDay; + setDay(r); + await refresh(); + } finally { + setRunning(false); + } }; + const timelineDone = Boolean(day && visibleCount >= day.timeline.length); + const dayStatus = !day ? "idle" : timelineDone ? "complete" : "running"; + return (
@@ -58,8 +122,8 @@ function App() {

-