~bigbes/lethe

ref: 3ae44b2876001b8a2b0e4d8abfd7a35d4a8fa977 lethe/docs/design_handoff_assistant_log/original-spec.md -rw-r--r-- 8.3 KiB
3ae44b28 — Eugene Blikh tooling: adopt go tool directives; rename air→dev; bundle fmt drift a month ago

#Direction 4 · Dense Data UI — assistant-log

#The product

A self-hosted, single-user log aggregator for CLI AI assistants (Claude Code, opencode, crush, pi, kimi). Server runs on a home server (phoebe) behind Tailscale; collectors run as systemd user units on each machine and POST normalized turns to SQLite + FTS5. Server-rendered HTML UI, no SPA. Single user. Full transcripts of every session across every tool across every machine, searchable in one place.

#Aesthetic + personality

GitHub/Linear-style dense data UI for power scanning. Built on the assumption the user lives in terminals all day and wants information density, not chrome.

  • Top bar: dark (#1c1a17), monospace, contains breadcrumb (assistant-log / scarlet), an always-visible search input that responds to ⌘K, and tab nav (Recent / Projects / Stats / Health / Settings).
  • Body: warm off-white (#fdfcf8), Inter for prose, JetBrains Mono for all data (timestamps, paths, tokens, IDs).
  • Accent: terracotta #c96442, used sparingly — selected tab, primary chip, sparkline highlight, FTS hit highlight, "stale" warnings.
  • Type scale: 11–13 px body. Tight (1.4) line-height. Uppercase 10 px column headers with 0.05 em tracking and var(--ink-3) color.
  • Rows: 28–32 px tall (compact mode 22–24), 1 px --rule-2 dividers, hover #f3f0e7.
  • Tags: small mono pills — neutral #ebe7d8, host-green #d9e6dd, accent terracotta. Per-tool a 8 px square color dot (claude-code terracotta, opencode green, crush purple, pi ochre, kimi blue).
  • Sparklines: 60–140 × 12–18 px inline SVG polylines, stroke 1.2, accent-colored when row is "the user's main thing".

#Layout pattern (every page)

  1. Dark mono top bar (search + nav).
  2. Light sub-bar with active filters as removable chips, plus a contextual stat strip on the right (e.g. turns/day sparkline + total).
  3. Tight grid header row (uppercase mono labels).
  4. Scrollable rows with display: grid; grid-template-columns: …, mono in time/path/numeric columns, sans in prose columns.
  5. Optional footer strip for global state (backfill progress, last error).

#Screens

  1. Home (Recent) — Reverse-chronological feed of sessions across all tools/hosts. Columns: when · tool tag · host tag · session question + cwd · turns · tok · turns/h sparkline. Top sub-bar carries tool: any · host: any · since: 30d chips and a global turns/day sparkline.

  2. Search results — Results are a flat table of turns (not sessions), one match per row, with the snippet truncated and FTS hits wrapped in a terracotta <mark>. Filters in chips above. Save-search action lives next to the chip row.

  3. Session view — Two-column. Left aside (240 px) is a turn list with # · role glyph · preview · token count, current turn highlighted with a left accent border. Right pane is the linear transcript: each turn is a row separated by 1 px rules, role label is mono uppercase color-coded (USER neutral, ASSISTANT accent, TOOL muted), tool calls render as monospace cards with a faint background tint. Sticky header carries cwd · title · tool tag · host tag · model · turn count · tokens · open dot.

  4. Project view (cwd) — Header shows ~/code/ breadcrumb + tt-bundle in mono, count chips, and a sparkline of activity. Saved-search chips below. Then the same dense session table filtered to that cwd.

  5. Stats — Top sub-bar has range pills (7d / 30d / 90d / all) and group-by pills (tool / host / project / model). Content is a grid of cards: per-tool stat strip (turns / tokens / cost / sparkline / share %), a stacked turns/day chart (60 days), a 12-week activity heatmap, and a top-cwd bar list.

  6. Ingestion health — Status pills in sub-bar (● 7 ok · ● 1 warn). Table of every (host, tool, source) row with: status dot · host · tool · source path · lag · outbox depth · last-OK · events 24h. Stale rows get accent-colored lag, non-empty outboxes get accent-colored count. Footer strip: backfill progress bar + last parser error inline.

  7. Settings — Sidebar nav (Sources / Display / Auth / Backup / Export / Tags / Saved searches). Sources page is the dense source table with status dot, tool tag, path, poll interval, event count, last-OK, edit. Display has compact tag-pair toggles (density, tool calls, accent).

#Interaction model

  • Always-on global search (⌘K focuses the top input from any page).
  • Filter chips are removable and additive; "+ add filter" opens a small popover.
  • All paths are clickable and open the corresponding Project view.
  • Each row in any list is clickable and opens its session/turn permalink.
  • Keyboard: j/k move row, open, g h/s/p/i jump to home / stats / projects / health.

#Mock data shape

Sample sessions (across claude-code, opencode, crush, pi, kimi on laptop and workpc):

time tool host cwd first prompt turns tok model
14:22 claude-code laptop ~/code/tt-bundle lockfile design for the tt bundle — should we hash inputs or outputs? 84 12.4k claude-opus-4-7
11:08 opencode workpc ~/work/atelier/migrations why does the v3 migration drop the partial index on (org, ts) 12 2.1k gpt-5-mini
10:52 claude-code workpc ~/work/scarlet-svc is there a way to make this retry loop tolerate 429s without a sleep 41 7.7k claude-opus-4-7
09:14 crush laptop ~/code/dotfiles rewrite this zsh prompt to show ssh host only when on a remote 6 0.9k gemini-2-flash
Yest pi laptop ~/notes help me draft a one-pager for the offsite session on incident response 19 4.0k inflection-3
Yest claude-code laptop ~/code/tt-bundle when do we need to re-resolve transitive deps after a lock bump 28 5.3k claude-opus-4-7
Yest kimi workpc ~/work/atelier translate these comments to english but keep the tone 4 0.7k kimi-k2

Ingestion health — 8 collector rows (one per host × tool):

host tool source lag outbox last ok status
laptop claude-code ~/.claude/projects 4s 0 now ok
laptop opencode ~/.local/share/opencode 12s 0 12s ok
laptop crush ~/.cache/crush 28s 0 28s ok
laptop pi ~/.config/pi/history 1m 0 1m ok
workpc claude-code ~/.claude/projects 7s 0 now ok
workpc opencode ~/.local/share/opencode 18s 0 18s ok
workpc kimi ~/.kimi-cli/history.jsonl 2m 127 2m warn
workpc crush ~/.cache/crush 8m 0 8m stale

Per-tool 30-day rollups:

  • claude-code — 1820 turns / 482k tok / $0 (Max sub, cost unknowable)
  • opencode — 211 turns / 18k tok / $4.12
  • crush — 64 turns / 2k tok / $0.71
  • pi — 32 turns / 7k tok / $0
  • kimi — 11 turns / 1k tok / $0

#Tech assumptions for the build

  • React 18.3.1 + Babel standalone for the prototype.
  • Inter + JetBrains Mono via Google Fonts.
  • All data is hard-coded mock data. No real backend.
  • Single HTML file with split JSX modules per screen for maintainability.

#Suggested first prompt for the new chat

Build a hi-fi clickable prototype of a personal CLI AI assistant log aggregator UI in the Dense Data UI style described in the attached spec. One HTML file. Real navigation between screens (top-bar tabs, row clicks, ⌘K search focus, filter chips). Cover Home / Search / Session / Project / Stats / Health / Settings. Use the mock data shape and visual system specified.