feat(workshop): reworked phase flow — agent makeup, sidebar advance, responsive
Rebuild the participant flow around the agent itself: - Phases: Team registration (+ agent name) -> Meet your agent -> Skills & Policies (edit the agent's makeup) -> UnoQ Dashboard (React Flow configurator) -> Submit. Swapped/renamed the two module pages (Module1/2 -> ModuleDashboard/ModuleMakeup). - Agent name captured at registration, shown on the dashboard and used in the chat greeting (live, not hard-coded), pushed to the board. - One shared conversation across pages (AgentChatContext); Clawd the crab animates the LED matrix and reacts to chat status. - MAKEUP slide-outs: view, edit (wrench), or AI-refine (wand) the agent's personality files and save them back to the board. - Advance button moved into the sidebar for every phase (ProceedContext). - Dropped the ADD-doc build + submission gate; Submit just records the entry. - Responsive pass: sidebar auto-collapses below lg, fluid padding, React Flow pan/zoom/fit + Controls, architecture panel becomes a mobile overlay. - Add @xyflow/react for the configurator. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
0797923933
commit
05207ba986
+22
-79
@@ -1,11 +1,15 @@
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { AddLayerForm } from '@/components/AddLayerForm'
|
||||
import { AddDocument } from '@/components/AddDocument'
|
||||
import { PanelHeading, ProceedButton } from '@/components/cockpit/PanelChrome'
|
||||
import { ADD_LAYERS } from '@/lib/addLayers'
|
||||
import { PanelHeading } from '@/components/cockpit/PanelChrome'
|
||||
import { useSetProceed } from '@/lib/ProceedContext'
|
||||
import { useSession } from '@/store/session'
|
||||
import { makeSubmissionCode } from '@/lib/submission'
|
||||
|
||||
/**
|
||||
* Module 3 · Submit — the finish line. The deliverable is the agent itself (the
|
||||
* makeup/skills you shaped and shipped to the board), so there's no Agent Design
|
||||
* Document to assemble or gate on: submitting just records the team's entry for
|
||||
* judging. The advance control lives in the sidebar.
|
||||
*/
|
||||
export function AddBuilder() {
|
||||
const navigate = useNavigate()
|
||||
const team = useSession((s) => s.team)
|
||||
@@ -14,36 +18,30 @@ export function AddBuilder() {
|
||||
const setSubmission = useSession((s) => s.setSubmission)
|
||||
const completePhase = useSession((s) => s.completePhase)
|
||||
|
||||
const complete = ADD_LAYERS.every(({ key }) => add[key].trim().length > 0)
|
||||
const submitted = !!submission.code
|
||||
|
||||
const onExport = () => window.print()
|
||||
const onSubmit = () => {
|
||||
setSubmission({ code: makeSubmissionCode(team, add), submittedAt: new Date().toISOString() })
|
||||
completePhase('add')
|
||||
}
|
||||
useSetProceed(
|
||||
submitted
|
||||
? { label: 'Back to start', disabled: false, onClick: () => navigate('/workshop') }
|
||||
: { label: 'Submit agent', disabled: false, onClick: onSubmit },
|
||||
)
|
||||
|
||||
// ── Submission finale (design panel6) ──
|
||||
if (submitted) {
|
||||
return (
|
||||
<section className="print:hidden">
|
||||
<section>
|
||||
<div className="mt-5 rounded-[18px] border border-[var(--green-border-2)] bg-[linear-gradient(180deg,var(--green-bg),var(--surface))] px-12 py-14 text-center">
|
||||
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-[var(--green)] text-[32px] text-white">
|
||||
✓
|
||||
</div>
|
||||
<h1 className="mt-6 text-[44px] font-semibold tracking-[-0.02em]">ADD submitted</h1>
|
||||
<h1 className="mt-6 text-[44px] font-semibold tracking-[-0.02em]">Agent submitted</h1>
|
||||
<p className="mx-auto mt-3.5 max-w-[460px] text-[18px] leading-[1.5] text-ink-2">
|
||||
Team <strong className="font-semibold text-ink">{team.name || 'Matrix'}</strong> ·{' '}
|
||||
{(team.name || 'crimson-node').toLowerCase().replace(/\s+/g, '-')} — your Agent Design Document
|
||||
is in for judging. Your node keeps running the design you just shipped.
|
||||
Team <strong className="font-semibold text-ink">{team.name || 'your team'}</strong> — your agent is
|
||||
in for judging, running the makeup you shaped on the board.
|
||||
</p>
|
||||
<div className="mt-7 inline-flex flex-wrap justify-center gap-2.5 font-mono text-[11px] tracking-[0.1em] text-[var(--green)]">
|
||||
{ADD_LAYERS.map(({ n, title }) => (
|
||||
<span key={n} className="rounded-md border border-[var(--green-border)] px-[11px] py-1.5">
|
||||
L{n} {title.split(' ')[0].toUpperCase()}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-8">
|
||||
<button
|
||||
type="button"
|
||||
@@ -60,66 +58,11 @@ export function AddBuilder() {
|
||||
|
||||
return (
|
||||
<section>
|
||||
<div className="print:hidden">
|
||||
<PanelHeading
|
||||
title="Module 3 · Harness, Loops & submit"
|
||||
intro="Finish Layers 4 and 5 — how your node reasons and how it runs over time — review the assembled Agent Design Document, export a PDF, and submit before the deadline."
|
||||
size={44}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 grid gap-4 md:grid-cols-2 print:hidden">
|
||||
<AddLayerForm
|
||||
layer="L4"
|
||||
title="ADD · Layer 4 — Harness"
|
||||
description="Which decisions run on the board, which escalate — and the degradation path, not just the happy path."
|
||||
placeholder={
|
||||
'Routine checks: on-board model, no network needed.\n' +
|
||||
'Ambiguous or high-consequence calls: escalate to the cloud model.\n\n' +
|
||||
'Degradation path:\n' +
|
||||
'• cloud slow → fall back on-board, note reduced confidence\n' +
|
||||
'• no network → keep sensing, logging and safing locally\n' +
|
||||
'• on-board model down → stop actuating, alert, keep recording'
|
||||
}
|
||||
/>
|
||||
<AddLayerForm
|
||||
layer="L5"
|
||||
title="ADD · Layer 5 — Loops"
|
||||
description="How often it checks, what it reports by exception — and how the loop behaves when a cycle fails."
|
||||
placeholder={
|
||||
'Heartbeat every 30 s; sample each minute; report only on exception.\n\n' +
|
||||
'When a cycle fails:\n' +
|
||||
'• missed tick → skip, do not back-fill invented data\n' +
|
||||
'• partial data → report what is missing\n' +
|
||||
'• N failures → escalate to a human and stop acting'
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 rounded-[14px] border border-line bg-surface p-[26px_28px]">
|
||||
<div className="flex items-center justify-between print:hidden">
|
||||
<div className="text-[19px] font-semibold">Assembled document</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onExport}
|
||||
className="rounded-lg border border-line-2 bg-surface px-4 py-2 text-[14px] text-ink transition-colors hover:border-blue hover:text-blue-ink"
|
||||
>
|
||||
Export PDF
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-[18px] print:mt-0">
|
||||
<AddDocument />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 flex items-center justify-between gap-4 print:hidden">
|
||||
<span className={complete ? 'text-[15px] text-[var(--green)]' : 'text-[15px] text-[var(--muted-2)]'}>
|
||||
{complete ? 'All five layers complete — ready to submit.' : 'Complete all five layers to submit.'}
|
||||
</span>
|
||||
<ProceedButton disabled={!complete} onClick={onSubmit}>
|
||||
Submit ADD
|
||||
</ProceedButton>
|
||||
</div>
|
||||
<PanelHeading
|
||||
title="Submit your agent"
|
||||
intro="You've met your agent, shaped its skills and policies, and wired up its dashboard — submit it for judging from the sidebar when you're ready; your node keeps running the design you shipped."
|
||||
size={44}
|
||||
/>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user