diff --git a/src/client/pages/Overview.tsx b/src/client/pages/Overview.tsx index 8a6aaa7..504e1b5 100644 --- a/src/client/pages/Overview.tsx +++ b/src/client/pages/Overview.tsx @@ -51,7 +51,7 @@ function AgentCard({ agent, summary }: { agent: LiveAgent; summary?: string }) { function RecentColumns({ state, events }: { state: LiveState; events: ActivityEvent[] }) { const recent = useQuery({ queryKey: ["recent"], queryFn: fetchRecent, refetchInterval: 8000 }); const byPane = new Map(state.agents.map((a) => [a.paneId, a])); - // Live status changes first, then each agent's last session activity so the column is useful straight after loading. + const seen = new Set(events.map((e) => e.paneId)); const feed = [ ...events.slice(0, 8).map((e) => ({ key: `e${e.id}`, paneId: e.paneId, name: e.agent, status: e.to, text: e.from ? `${STATUS_LABEL[e.from]} → ${STATUS_LABEL[e.to]}` : `Appeared as ${STATUS_LABEL[e.to]}`, at: e.at })), diff --git a/src/client/styles/app.css b/src/client/styles/app.css index 088bc1f..13b2a98 100644 --- a/src/client/styles/app.css +++ b/src/client/styles/app.css @@ -7,7 +7,7 @@ a { color: inherit; text-decoration: none; } :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } .mono { font-family: var(--mono); } -/* shell */ + .shell { display: grid; grid-template-columns: var(--sidebar) 1fr; height: 100%; } .sidebar { background: var(--surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; min-height: 0; } .brand { display: flex; align-items: center; gap: 10px; padding: 14px 16px; font-weight: 600; } @@ -39,7 +39,7 @@ a { color: inherit; text-decoration: none; } .content { overflow: auto; padding: 24px; min-height: 0; flex: 1; } .page { max-width: 1280px; margin: 0 auto; display: grid; gap: 28px; } -/* status */ + .sdot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--s-idle); } .sdot.blocked { background: var(--s-blocked); box-shadow: 0 0 0 3px var(--s-blocked-bg); } .sdot.done { background: var(--s-done); } @@ -53,7 +53,7 @@ a { color: inherit; text-decoration: none; } .badge.working { background: var(--s-working-bg); color: var(--s-working); } .chip { font: 400 var(--text-xs)/1 var(--mono); padding: 3px 7px; border-radius: 5px; background: var(--raised); border: 1px solid var(--border); color: var(--text-2); white-space: nowrap; } -/* overview */ + .h2 { font: 600 var(--text-xs)/1 var(--font); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-3); margin: 0 0 12px; display: flex; align-items: center; gap: 8px; } .kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); } .kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: 16px 18px; text-align: left; transition: border-color var(--dur) var(--ease); } @@ -91,7 +91,7 @@ a.row:hover { background: var(--raised); } .ws-head .grow { flex: 1; } .group { margin-bottom: var(--gap); } -/* agent page */ + .agent-page { display: grid; grid-template-columns: minmax(0, 1fr) 300px; height: 100%; min-height: 0; } .convo { display: flex; flex-direction: column; min-height: 0; min-width: 0; border-right: 1px solid var(--border); } .convo-head { padding: 14px 24px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--border); flex: none; } @@ -153,7 +153,7 @@ a.row:hover { background: var(--raised); } .attention-bar .msg { flex-basis: 100%; } } -/* avatar + rows */ + .avatar { border-radius: 50%; display: inline-grid; place-items: center; font-weight: 600; flex: none; letter-spacing: 0.02em; } .avatar-wrap { position: relative; display: inline-flex; } .avatar-status { position: absolute; right: -2px; bottom: -2px; background: var(--surface); border-radius: 50%; padding: 2px; display: grid; } @@ -169,7 +169,7 @@ a.arow:hover { background: var(--raised); } @media (hover: none) { .arow .more { opacity: 1; } } details > summary { list-style: none; } details > summary::-webkit-details-marker { display: none; } -/* context menu + dialogs */ + .ctx { position: fixed; z-index: 30; min-width: 210px; background: var(--raised); border: 1px solid var(--border-strong); border-radius: var(--r-md); padding: 6px; box-shadow: 0 12px 32px rgba(0,0,0,0.45); display: grid; } .ctx-title { padding: 6px 10px 8px; font: 600 var(--text-xs) var(--font); color: var(--text-3); letter-spacing: 0.06em; text-transform: uppercase; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .ctx button { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border: 0; background: none; border-radius: var(--r-sm); font-size: var(--text-sm); text-align: left; } @@ -185,7 +185,7 @@ details > summary { list-style: none; } details > summary::-webkit-details-marke .field:focus { border-color: var(--accent); } .danger-btn { background: var(--danger); border-color: var(--danger); color: #1a0606; } -/* chat */ + .seg { display: inline-flex; background: var(--raised); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 2px; } .seg button { background: none; border: 0; padding: 4px 12px; border-radius: 4px; font-size: var(--text-xs); font-weight: 500; color: var(--text-2); } .seg button[aria-selected="true"] { background: var(--hover); color: var(--text); } @@ -215,7 +215,7 @@ details > summary { list-style: none; } details > summary::-webkit-details-marke .chat { padding-left: 16px; padding-right: 16px; } } -/* recent columns */ + .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; } .frow { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 10px 16px; border-top: 1px solid var(--border); font-size: var(--text-sm); } .frow:first-child { border-top: 0; } @@ -244,7 +244,7 @@ a.frow:hover { background: var(--raised); } .notice span { flex: 1 1 260px; } .notice strong { color: var(--text); } -/* board */ + .tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; } .tile { display: flex; align-items: center; gap: 12px; padding: 11px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease); } .tile:hover { background: var(--raised); border-color: var(--border-strong); } diff --git a/src/server/demo.ts b/src/server/demo.ts index 9dd5cf7..d4fbbf7 100644 --- a/src/server/demo.ts +++ b/src/server/demo.ts @@ -80,7 +80,7 @@ export class DemoLive implements LiveSource { if (a.status === "done") a.log.push("", "● Done. Let me know if you want any changes."); } } - // The first working agent finishes a pass and starts another every 40s so the demo keeps moving. + const cycle = Math.floor((now - this.started) / 40000) % 2; const ada = this.agents[0]; if (!ada.until && cycle === 1 && ada.status === "working") {