Skip to content

feat(dash): chat moves to /chat, /dashboard becomes system overview#356

Merged
thinmintdev merged 2 commits into
mainfrom
feat/chat-page-overhaul
May 27, 2026
Merged

feat(dash): chat moves to /chat, /dashboard becomes system overview#356
thinmintdev merged 2 commits into
mainfrom
feat/chat-page-overhaul

Conversation

@thinmintdev
Copy link
Copy Markdown
Contributor

Summary

Overhauls the chat surface UX + restructures the main dashboard.

  • Chat moves to its own #chat route (sidebar entry added). The ChatActive + ChatEmpty split collapses into a single ChatPanel + page-level ChatView; the legacy names stay as thin wrappers for the Tweaks-panel composer-state preview / screenshot harness.
  • #hardware route is retired; its HardwareSection now lives on /dashboard alongside SnapshotStrip, MemoryMap, ThroughputCard, HealthCard. Sidebar + BottomTabs + TopBar labels updated to match.
  • Composer boundary fix: typing surface wrapped in a .composer-input-card with var(--line) border + var(--accent-line) focus-within ring (the prior borderless textarea read as page background).
  • Reasoning toggle in the chat header — pill control, OFF by default, persisted to localStorage["hal0.chat.showReasoning"]. Streaming continues to populate m.reasoning regardless, so flipping on mid-conversation retroactively reveals prior thinking. Gates ReasoningBlock render only.
  • New-chat button now calls useChat.clear() (aborts in-flight + clears messages) instead of window.location.reload().
  • Popout button opens #chat?popout=1 in a 480x760 popup window. parseRoute parses the hash query string; App short-circuits all chrome (TopBar, Sidebar, Footer, BottomTabs, Banners, Tweaks, modals) when popout=1.

Files

ui/src/dash/chat.jsx      | 442 +++++++++++++++++++++++++---------------------
ui/src/dash/chrome.jsx    |   7 +-
ui/src/dash/dashboard.jsx | 172 ++++++++++++++-----
ui/src/dash/extras.jsx    | 111 +--------------
ui/src/dash/main.jsx      |  50 +++++-
ui/src/dashboard.css      | 103 +++++++++-
6 files changed, 509 insertions(+), 376 deletions(-)

Test plan

  • npm run build clean (verified locally: 119 modules, 538 kB JS, 86 kB CSS)
  • ruff check src tests + ruff format --check src tests clean (Python untouched)
  • /#dashboard renders the full hardware spread on the left + SnapshotStrip/MemoryMap/Throughput/Health on the right
  • /#chat renders the chat surface; sidebar Chat entry is active
  • /#hardware falls back to dashboard (route table no longer accepts it)
  • Composer input has a visible border; focus draws an accent ring
  • Reasoning toggle defaults OFF; reload keeps the preference; flipping on after streaming reveals prior reasoning
  • New-chat button clears messages without reloading
  • Popout button opens a small window at #chat?popout=1 with no sidebar/topbar/footer

Known follow-ups (not blocking)

  • MessageList reasoning-only fallback ("see thinking above") is misleading when the toggle is OFF — minor copy fix.
  • composerState Tweaks-panel selector + chatState="active"|"empty" props on DashboardView are dead after this change (only "skip" still routes). Cleanup pass worthwhile.
  • New Storage HwCard in HardwareSection uses placeholder mock copy — not yet wired to /api/hardware.

🤖 Generated with Claude Code

thinmintdev and others added 2 commits May 27, 2026 15:20
Chat surface extracted from /dashboard into its own #chat route with a
dedicated `ChatView` + `ChatPanel` (unified empty/active surface) and a
sidebar entry. The standalone #hardware route is retired; its content
relocates to /dashboard as `HardwareSection` alongside the existing
SnapshotStrip + MemoryMap + ThroughputCard + HealthCard.

Composer gets an explicit `.composer-input-card` boundary with an
accent focus-within ring so the typing surface reads as a card, not a
borderless region of the page.

Reasoning toggle pill in the chat header gates `ReasoningBlock` render
without disabling the stream (so flipping on mid-conversation reveals
prior reasoning). Persisted to localStorage `hal0.chat.showReasoning`,
default OFF.

New-chat button calls `useChat.clear()` (aborts in-flight + clears
messages) instead of `window.location.reload()`.

Popout button opens `#chat?popout=1` in a 480x760 popup. parseRoute
parses the query string; App short-circuits all chrome (TopBar,
Sidebar, Footer, BottomTabs, Banners, Tweaks, modals) when popout=1
and renders just the ChatView.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- chat-reasoning: navigate to /#chat (was /); pre-seed
  `hal0.chat.showReasoning=1` via addInitScript so ReasoningBlock
  renders (toggle now defaults OFF in production).
- dashboard-v3: drop the `.composer` check (chat moved to /chat);
  assert `.hw-section` instead.
- hardware-v3: standalone /hardware route is retired. Retarget at
  /#dashboard and read from `.hw-section .vh h2` (was page-level
  `.view .vh h1`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thinmintdev thinmintdev merged commit fd200b8 into main May 27, 2026
4 checks passed
@thinmintdev thinmintdev deleted the feat/chat-page-overhaul branch May 27, 2026 21:53
thinmintdev added a commit that referenced this pull request May 28, 2026
Five small follow-ups that should have ridden with #356:

- docs(PLAN+README): describe actual dashboard views (incl. Chat,
  retired #hardware), correct stale Vue 3 + Tailwind 4 framing to
  React 18 + Vite, mention popout window + reasoning toggle.

- main.jsx: drop dead `chatState`/`setChatState` state + prop
  passthrough now that chat lives on its own route.

- dashboard.jsx:
  - Drop mocked Storage HwCard (`/var/lib/hal0/models` is wrong
    post-#319 `[models].store`).
  - Replace zero-slots fallback trigger `chatState === "skip"` with
    a real `Array.isArray(slotsQuery.data) && slotsQuery.data.length
    === 0` check. The old signal stopped existing in #356.

- chat.jsx: context-aware copy for the "(no final answer)" line —
  point users at the reasoning toggle when it's currently OFF.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
thinmintdev added a commit that referenced this pull request May 28, 2026
…rough + gut installer auth section (#390)

- docs/operate/lemonade.md (new, .md canonical): operator reference for
  the v0.2 Lemonade runtime — what it is, where state lives, the /v1/*
  proxy + dispatcher fallthrough (PRs #248/#277), slot ↔ Lemonade
  model mapping (PRs #281/#282), max_loaded_models = 8 LRU cap (PR
  #283), per-type LRU eviction per ADR-0008 (supersedes nuclear-evict
  ADR-0007), OFFLINE-on-eviction (PR #276), and the three known v0.3
  caveats (Vulkan KV gauge missing, whisper RUNPATH workaround, GPU
  cleanup unload hang).

- docs/dashboard/v3.md (new, .md canonical, new docs/dashboard/ dir):
  page-by-page tour of the v3 React dashboard shipped in
  v0.3.0-alpha.1 (PR #235). Covers the shell + Mock-badge convention,
  /dashboard (system overview after #356), /chat (real surface per
  #309/#314/#315/#351), /slots (sidebar mirror per #357 + #344 UX
  sweep), /models (#313/#319/#353), /mcp (#304/#300), /agents (Peers
  per #299), /memory (graph #297, throughput #308), Settings (no Auth
  tab post-ADR-0012), and the footer journal (Epic #322 — PRs
  #321/#328/#329/#330/#332). Mock-fallback issues linked via the
  dashboard-v3 label, not enumerated.

- installer/README.md: gut ~95 lines of stale auth prose (Caddy,
  Bearer-token mint/use/revoke, first-run OTP claim wizard,
  HAL0_AUTH_ENABLED/HAL0_AUTH_DISABLED, password recovery, basic_auth
  upgrade path, the TLS recipe). Replace with one paragraph pointing
  at docs/operate/auth.mdx for the reverse-proxy recipe and
  docs/agents/identity.md for the X-hal0-Agent identity model. Auth
  was removed in v0.3.0-alpha.1 per ADR-0012; the README hadn't
  caught up.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant