Build first-class dreb web dashboard (foundation) - #321
Conversation
…klist, spec Design deliverables for the dreb web dashboard (design issue, PR 320): - tokens.css: design language forked from the approved gallery template (IBM Plex Mono, pure black/white + auto dark mode, hairline borders, status chips as the only accent color) - mockups/: six static screens (fleet-overview, session-view, pairing, files, settings, tree) sharing tokens.css - capture.mjs + screenshots/: Playwright captures at desktop/mobile/dark, all vision-reviewed - PARITY.md: TUI feature parity checklist, ground-truth re-verified against source (21 built-in commands, ~74 keybindings, 19 event types) - SPEC.md: IA, flows, responsive plan, two-mode security UX, foundation scope, SolidJS recommendation, acceptance criteria
Maintainer feedback on PR 320: 1. Files screen reworked from project-scoped to host-wide browsing: places shortcuts (~, /tmp, project roots), breadcrumbs to /, new folder, 'new session here' on any directory. Trusted-operator model documented in SPEC.md: a paired device already equals terminal access, so a project jail would be security theater; paths are still canonicalized and operations logged. 2. Subagent observability designed as three levels: fleet card counts/lines, session subagent strip (clickable chips), and a new read-only subagent-view mockup showing a live drill-in transcript. SPEC.md gains a section on the RPC plumbing gap: background_agent events carry no session path and child JSONL events are consumed privately by the parent, so the implementation PR must add registry exposure over RPC plus an agentId-namespaced event relay — file tailing explicitly rejected. Relay addressing is designed to be reused by future subagent steering (not MVP; requires child stdin control channel).
…sign Dashboard UX/UI design (design-only, merges into future implementation branch)
Implementation PlanAnalysisThe design phase (issue 311, PR 320) produced an accepted, review-hardened spec: Codebase facts confirmed by exploration:
Prior art (beyond what the design phase already researched): the loopback trust path must validate Host/Origin headers — DNS rebinding against localhost dev servers is a live vulnerability class (Vite GHSA-vg6x-rcgg-rjx6, patched January 2025, is the canonical precedent). PR 310's loopback bypass trusted any request arriving on 127.0.0.1; the foundation adds Host allowlisting so a malicious website cannot drive the dashboard API through a rebound DNS name. SSE reconnect uses the standard Branch mechanics (stage 0 — agreed on the issue, non-standard)
Stage 1 — coding-agent RPC extensions (subagent observability, SPEC §5a)The enabler for dashboard levels 1–3 of subagent visibility; file-tailing explicitly rejected by the spec.
Relay volume note: Stage 2 —
|
Vitest coverage
|
…contextUsage in get_state
…, file API) + dreb dashboard subcommand
…t, session, subagent, files, settings, pairing)
Progress: stages 1–5 complete + docs; gaps and observed bugs for the next sessionFoundation implementation is pushed through commit What's done (4 commits on top of the design merge)Stage 1 — coding-agent RPC extensions (
Stages 2–3 — @dreb/dashboard package + server core (
Stages 4–5 — client foundation + six screens (
Docs ( Observed bugs (from maintainer testing — fix first)
Gaps / UX improvements (also next session)
Root README
Remaining planned work (stage 6 + verify)
Verification state
Progress tracked by mach6 |
…models, resources, git branch, daily cost, pending messages - Move TabTitleGenerator to core and wire into RPC mode: sessions auto-name after a threshold of tool calls in dashboard/telegram, not just the TUI; new session_name_changed event notifies all frontends - Fix --session resume clobbering the stored model when scoped models are configured (main.ts skips scoped-first for --session; sdk.ts passes real scopedModels to findInitialModel) - get_state: add scopedModels and usingSubscription - New commands: get_resources, get_git_branch (shared git-branch helper, reused by FooterDataProvider), get_daily_cost, get_pending_messages, clear_pending_messages, abort_compaction
…ranscript, command autocomplete, and session-view parity features Fixes from maintainer testing: - Model selector grouped by provider with scoped/all tabs — same model id under multiple providers is now unmissable; provider/id labels in session bar and fleet cards - Transcript turn ordering fixed (thinking -> text -> tools) with visual turn grouping; background-agent completions render as distinct collapsed agent-result cards instead of 'you' user messages - Markdown rendering (marked + dompurify) for assistant text and agent results; always-expand-thinking browser preference - Files tab starts at home (places race fixed); /tmp sessions bundle into one fleet group; composer auto-grows TUI parity: - Session info bar: cwd + branch + name, token breakdown, cost with (sub) and daily rollup, ctx%, median tok/s; stats popover - Composer: / command autocomplete fed by get_commands, image paste/attach, history recall, queued-message chips with restore-all - Per-message copy, fork-from-message modal, skill badges, bespoke bash/read/write tool bodies, compaction/retry abort buttons - Loaded-context modal (get_resources), live session_name_changed handling, browser notifications on needs-attention, fleet card cost + last-activity preview
…ness - Root README: dashboard interface bullet, packages table row, launch + security + systemd service section with screenshot placeholders - PARITY.md: every row re-verified against shipped source; honest re-dispositions (restore-all dequeue, median tok/s without trend arrow); RPC count updated to 47; closed RPC gaps recorded - rpc.md: all 47 commands documented (added resolve_model, buddy_hatch, buddy_reroll); events table verified complete - dashboard.md + package READMEs refreshed to shipped reality
Progress: all handoff items + session-reported bugs implementedThree commits pushed ( Session-reported fixes (this session's testing)
Handoff items (previous progress comment)
PARITY.md audit (stage 6)Every ✅ row re-verified against shipped source. Shipped this round: per-message copy, fork-from-message modal, image paste/attach in composer, queued-message chips (restore-all — per-item dismiss has no RPC and the TUI itself only restores all; row updated honestly), stats popover, composer history, status-line abort variants for compaction/retry (new Verification
Remaining before ready-for-review
Progress tracked by mach6 |
Maintainer Bug Report — Investigation Findings (round 2)Seven items reported from live testing. Root causes confirmed by code inspection; fixes land in this session. One item is a feature request and was filed as a separate issue. Critical1. Subagent sessions unviewable after dashboard reload 2. Fleet view buries live sessions Important3. Autoscroll only fires after completion, not during streaming 4. Tool inputs truncated with no way to see them in full 5. Markdown-worthy tool output rendered as plain preformatted text Suggestions6. Expand-thinking should be opt-out Tracked separately7. Session-status sidebar in session view — feature request, filed as a standalone issue (linked below) rather than scope-crept into this PR. Investigation by mach6 (maintainer-reported findings) |
…l, live-first fleet, streaming autoscroll, full tool inputs, markdown tool results, expand-thinking default - Subagent views survive browser reloads: new /subagents/:agentId/messages endpoint reads the agent's on-disk session JSONL (registry-located via list_background_agents); hydrateSubagent on drill-in mount; hydrateSession re-seeds backgroundAgents so the session strip reappears too - Fleet is live-first: one flat grid of all live cards on top (attention-first, project path on each card), past sessions below grouped by project with 3 compact rows + all-N expander - Autoscroll works during streaming: per-session revision counter bumps on every envelope (text deltas mutate in place and never changed entries.length); subagent view gains stick-to-bottom scrolling - Expanded tool cards show full inputs (subagent tasks as markdown, generic long args labeled) instead of only the 120-char summary - Markdown-contract tool results render as markdown (subagent/skill/ web_fetch); suggest_next renders its summary + command from details - Expand-thinking preference is opt-out: unset defaults to expanded
Progress: all six maintainer-reported bugs fixed (round 2)One commit pushed ( Fixes
Tracked separately
Verification
Progress tracked by mach6 |
Maintainer Bug Report — round 3 (not yet investigated)Reported from live testing by the maintainer. Investigation and fixes deferred to the next session — root causes below are NOT yet confirmed. Reported bugs
Maintainer-reported findings; investigation to follow in the next session |
Round 3 — Investigation Findings & FixesAll eight reported items root-caused and fixed in this session. Verified by unit tests, a full workspace test run, and a live Playwright E2E against the built server with a real resumed session (26 checks, all passing). Root causes and fixes1. Settings default model was free text 2. Tool cards lost TUI-style color formatting 3. Edit tool output was just the ack 4. Reads/changes illegible while the model works 5. Undismissable warning toast 6. suggest_next summary still not showing 7. Suggested-command chip persisted too long 8. Settings tab missing most TUI settings Verification
Also in this session
Investigation and fixes by mach6 (round 3) |
…it diffs, open-by-default legibility, toast dismissal, suggest_next visibility, chip clearing, model dropdown, settings parity with agent-models editor
Progress: all eight round-3 bugs fixedOne commit pushed ( Shipped
Verification
Commit: Progress tracked by mach6 |
Maintainer Bug Report — round 4 (live testing, latest build)Reported from live testing by the maintainer on the latest build. Treat as ground truth. Wording preserved verbatim; formatting/numbering added for reference. Independent root-cause assessment to follow as a separate comment. Subagent viewing (item 1 — three related observations)1a. page refresh on fleet -> go to session with pre-existing completed subagents -> click a subagent -> error: 1b. ahh okay, so update, I just went into a live session without refresh, and still saw this error: So that top error is all subagent views, and the waiting for output bug is only post-refresh (maybe both completed and running, definitely completed) 1c. UPDATE on the latest build: now I cant even see completed subagents at all, at least on Other bugs2. when steering is submitted, it should show the pending steering messages, even when the agent is currently streaming 3. tab title setter subagent still not running in RPC/dashboard/telegram mode, meaning the sessions are not getting useful automatic titles 4. suggest_next as the agents ending action should set the state on the dashboard to 5. fleet-view session cards should be sorted alphabetically by their project location, then by session start time to break ties. Currently they move around seemingly at random and its bad UX. Consistency is going to be better than dynamic movement. This principle should be documented for future work as well, likely in AGENTS.md. 6. after a page refresh -> go to live running session -> stop button is missing, cannot halt agent anymore (CRITICAL) 7. agent models in settings: No agent definitions found. (wrong) 8. settings page has a red error box up top: 9. bash tool should also open by default 10. tested on my home pc to test tailscale auth. First load of the page on mobile device (with the server already informed about that device per readme) leads to an error page: but no pairing page is accessible 11. new default model selector is empty (even while session is running) 12. agent models in the settings page is also empty, no listed models AND no detected agents
13. draft user input should persist as long as the session exists in browser memory perhaps? 14. stop actually has no impact at all? It should be functioning the same as in TUI, stopping subagents in addition to the parent agent, and any running tools. 15. dashboard needs a restart dashboard service button in the settings (with a warning that itll kill running sessions) Reported by maintainer; posted via mach6 |
Review Assessment — round 4 root-cause analysisAssessing the maintainer bug report posted above (#321 (comment)). Every item was verified against actual source on this branch; three items were additionally investigated by exploration agents with live testing against the built RPC binary. Maintainer follow-ups after posting: the settings 404 (item 8), the "No agent definitions found" (item 7), and the empty agent-models/models lists (item 12) are resolved on the latest code — they were artifacts of a stale running dashboard service (routes added in commit Classifications
Process note — the stale-server trapSix of sixteen reported symptoms trace to one operational issue: the dashboard runs as a long-lived service loading Action PlanOrdered by severity, then dependency (items grouped where one fix serves several findings):
Assessment by mach6 |
… button, TUI-parity abort (subagent + web-tool cancel, queue restore), subagent registry rehydration on resume, provider-aware RPC tab-titles, zero-runtime settings, restart button, unpaired SPA shell, stable fleet sort, suggest_next attention, streaming pending chips, bash open-by-default, draft persistence, clean error bodies
Progress Update — round-4 findings implementedAll 13 action-plan items from the round-4 assessment are implemented, plus the finding-8 error-body polish. Build passes; full suite green (4268 passed / 0 failed via the pre-commit hook; dashboard 168, coding-agent 2603). Critical / high
Medium / UX / polish
Notes
Commit: Progress tracked by mach6 |
Review AssessmentHuman entrypoint into the mach6 loop — the maintainer's manual QA pass on the running dashboard is the "review" here, and this comment is the independent assessment of it: each item verified against the actual source on
Classifications
Action PlanOrdered by priority (auth correctness first, then data safety, then UX):
Counts: 7 genuine · 0 nitpick · 0 false-positive · 0 deferred. Items 2 and 5 are genuine but their plumbing already partly (5: fully) exists — scope them as "expose"/"verify," not "build from scratch." Assessment by mach6 (human-seeded review) |
Review AssessmentReview comment: #321 (comment) Classifications
Action Plan
Assessment by mach6 |
Progress UpdatePushed dashboard review fixes and transcript rendering improvements. Summary:
Validation:
Commit: Progress tracked by mach6 |
Code Review (round 2 — post-fix state, commit
|
Review AssessmentReview comment: #321 (comment) Each finding was independently verified by reading the actual source at commit Classifications
Tally: 8 genuine (3 of them test-coverage), 1 false positive, 4 nitpicks (incl. prior-round dup findings that persist). Action Plan
Skip (nitpicks): Findings 11–13 — optional behavior-preserving cleanup, not merge-blocking. Follow-up (not merge-blocking): Finding 2 is a false positive as a security hole, but SPEC §6 literally lists "Secure" for device cookies while the code intentionally omits it on the plain-HTTP tailnet. Reconcile the SPEC wording (or add optional Assessment by mach6 |
…gle-use PIN, stopAll race, revision-aware hydration, chain subagent hydration, dead code removal, test gaps
Progress UpdateFixed the eight genuine findings from the round-2 review assessment. Skipped finding 2 (false positive — Fixes
Verification
Follow-up (not merge-blocking)Finding 2 is a false positive as a security hole, but SPEC §6 literally lists "Secure" for device cookies while the code intentionally omits it on the plain-HTTP tailnet. The SPEC wording should be reconciled (or optional Commit: Progress tracked by mach6 |
Code Review — targeted pass: in-browser performance & memory leaksMaintainer-requested focus round on browser performance, memory growth, and resource lifecycle for the dashboard client (plus the server ends of the SSE pipeline that feed the browser). Three agents ran: a rendering-performance reviewer, a browser-memory/lifecycle reviewer, and an error-auditor on the SSE pipeline. Overlapping findings are merged; confidence shown is the highest among reporting agents. CriticalNone found. ImportantFinding 1 — Every SSE envelope deep-clones and reconciles the entire session transcript
Finding 2 — Client state is never pruned: every session and subagent transcript is retained forever
Finding 3 — No transcript virtualization; unbounded DOM growth; collapsed tool bodies are eagerly mounted The session view renders Finding 4 — Streaming re-parses markdown / re-highlights the full accumulated text on every delta Streaming assistant blocks render via Finding 5 — Transcript list defeats SolidJS keyed reuse: fresh wrapper objects every render
Finding 6 — SSE fan-out ignores The hub's publish loop and the keepalive both call SuggestionsFinding 7 — Autoscroll work scheduled per SSE revision without coalescing The session screen schedules a double Finding 8 — Base64 image attachments held in reactive state and duplicated Pending attachments are stored as base64 strings (10MB raw cap each, +33% expansion, no total/count cap) in a Solid signal, duplicated into a Finding 9 — Toast arrays grow unbounded and old toasts become undismissable Extension notifications/errors push permanently onto each session's Finding 10 — Composer drafts and prompt history live in module-scope maps with no eviction
Finding 11 — Completed background agents accumulate in
Finding 12 — Route-owned hydration fetches are not abortable; in-flight requests retain disposed screen closures The shared Observation (low, informational) — the files tab renders every directory entry with no pagination; very large directories (dependency caches) create thousands of table rows. Worth windowing eventually, but less central than the transcript findings. Strengths
Agents run: code-reviewer (rendering performance), code-reviewer (memory/lifecycle), error-auditor (SSE pipeline) Reviewed by mach6 |
Review Assessment — performance/memory roundReview comment: #321 (comment) Every finding was independently verified against the actual source at commit Classifications
Counts: 11 genuine, 1 nitpick, 0 false positives, 0 deferred. Root-cause structureFindings 1, 3, 4, 5 are one rendering-pipeline root cause, not four independent bugs. A single new tool result in a long session currently costs: O(transcript) clone (1) + O(transcript) reconcile (1) + full DOM remount via unstable wrappers (5) + re-parse of ALL rows' markdown/highlight (4), against an unbounded DOM (3). Fixing one without the others leaves the super-linear path intact. Action PlanGroup A — rendering pipeline (findings 5 → 1 → 4 → 3), architectural, highest priority:
Group B — server backpressure (finding 6), moderate, independent: Group C — bounded-growth leaks, quick wins, do together: Group D — quick wins, low priority: Follow-up (not merge-blocking):
Given the PR's stated targets (thousands of entries, day-long tabs, dozens of events/sec), Group A and the Group C leaks will bite normal usage — not just extreme scale. Assessment by mach6 |
…c, identity-stable transcript items, throttled streaming markdown/highlight, lazy tool bodies, transcript windowing, large-output truncation
Progress Update — perf-review Group A implementedImplemented the four architectural rendering-pipeline findings (Group A) from the performance/memory review assessment, in the assessor's recommended order (item 5 → 1 → 4 → 3). Pre-commit suite: 4300 passed, 0 failed; full workspace vitest + node:test green; build clean. Shipped
Tests added
Commit: Remaining from the assessment action plan: Group B (SSE write backpressure), Group C (state eviction: session pruning, toast cap, background-agent cap, composer map eviction), Group D (autoscroll coalescing, image attachment cap), and the follow-up item (abortable hydration fetches). Progress tracked by mach6 |
…nect, runtime_removed state eviction, toast cap, background-agent cap with subagent transcript cleanup, composer memory eviction
Progress Update — perf-review Groups B+C implementedImplemented the remaining moderate findings from the performance/memory review assessment: Group B (item 6) and Group C (items 2, 9, 11, 10). Pre-commit suite: 4316 passed, 0 failed; full workspace vitest + node:test green; build clean. Server
Client
Docs
Tests added
Commit: Remaining from the assessment action plan: Group D (item 7 autoscroll coalescing, item 8 image attachment handling) and the follow-up nitpick (item 12 abortable hydration fetches). Progress tracked by mach6 |
… image attachments with aggregate cap and objectURL lifecycle, abortable hydration fetches
Progress Update — perf-review Group D + follow-up implementedImplemented the final items from the performance/memory review assessment: Group D (items 7 and 8) plus the follow-up nitpick (item 12). With this commit, every finding from the perf review's action plan is implemented — Group A (items 5, 1, 4, 3), Group B (item 6), Group C (items 2, 9, 11, 10), and now Group D. Pre-commit suite: 4345 passed, 0 failed; full workspace vitest + node:test green; build clean. Shipped
Tests added
Commit: The review's action plan is fully implemented across four commits (Group A, Groups B+C, Group D). Ready for re-review. Progress tracked by mach6 |
Code Review (round 3 — perf-fix commits
|
Review AssessmentReview comment: #321 (comment) Every finding was independently verified against the actual source at HEAD Classifications
Tally: 10 genuine (1 high, 3 medium correctness, 1 contract, 4 test gaps, 1 cleanup), 2 nitpicks, 1 false positive, 0 deferred. Action PlanPriority 1 — data loss
Priority 2 — runtime-removal correctness (shared root, fix together) Priority 3 — contract mismatch Priority 4 — cleanup Priority 5 — test gaps (new code in this PR ⇒ ship with it, not deferred) Skip: finding 5 (false positive), findings 12–13 (nitpicks, consistent with prior skips). Assessment by mach6 |
…light, shared image byte budget, hydration generation guard, runtime_removed navigation, shared bg-agent cap, test gaps
Progress Update — round-3 review findings implementedImplemented all 10 genuine findings from the round-3 review assessment (#321 (comment)). Skipped items 12–13 (nitpicks, consistent with prior rounds) and item 5 (false positive). Pre-commit suite: 4385 passed, 0 failed; full workspace vitest + node:test green; build + biome clean. Fixed
Tests added
Drive-by
Commit: Progress tracked by mach6 |
…forward - Delete design/ (SPEC.md, PARITY.md, mockups, mockup screenshots, capture script) — the shipped code is now the authority - Delete tokens byte-equality contract test; clean all SPEC/PARITY/mockup references from source comments and docs - Root README: lead with the dashboard as the visual showcase — synchronized desktop/mobile sessions, steering from anywhere, subagent observability, Tailscale-gated remote with pairing; screenshot placeholders for real-build captures
Progress Update — design artifacts removed, README made dashboard-forwardPre-publish cleanup per maintainer direction. Removed
Root READMERewritten to lead with the dashboard as dreb's visual showcase: tagline and "Why choose dreb" now open with synchronized desktop/mobile sessions; the dashboard section covers the desk-to-couch workflow (same sessions as the TUI, one synchronized state over SSE), fleet overview, full-parity session view with steering, live subagent observability, host files, and the Tailscale-only remote model with rotating-code pairing. Screenshot placeholders ( A Docker-isolated demo/screenshot harness was prototyped this session and scrapped by maintainer decision (npm-inside-Docker proved too slow to iterate on); screenshots will be added manually later. VerificationFull workspace suite green (dashboard 272 — one fewer, the deleted contract test), build clean, biome clean. Commit: Progress tracked by mach6 |
Closes #307
First-party dreb web dashboard — foundation PR. Implements the accepted UX/UI design from the design phase (issue 311): dashboard server (loopback default, Tailscale remote opt-in, fail-closed auth, SSE pipeline, host-wide file API), fleet overview, full-parity session view, live subagent observability (including the RPC registry exposure + event relay in coding-agent), files tab, pairing + settings, on the tokens.css visual language.
Design artifacts land on this branch by merging the design PR (320) here as the first act; they iterate on this branch from that point (SPEC.md section 7 is the scope contract, section 9 the review contract).
Implementation plan posted as a comment below.