Files
stack/docs/TASKS-TUI_Improvements.md
Jason Woltje 82c10a7b33
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
feat(cli): TUI complete overhaul — components, sidebar, search, branding (#157)
Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
2026-03-15 22:17:19 +00:00

6.0 KiB
Raw Permalink Blame History

Tasks: TUI Improvements

Branch: feat/p7-tui-improvements Worktree: /home/jwoltje/src/mosaic-mono-v1-worktrees/tui-improvements PRD: PRD-TUI_Improvements.md


Wave 1 — Status Bar & Polish

ID Task Status Notes
TUI-001 Component architecture — split app.tsx into TopBar, BottomBar, MessageList, InputBar, hooks done 79ff308
TUI-002 Top status bar — branded mosaic icon, version, model, connection indicator done 6c2b01e
TUI-003 Bottom status bar — cwd, git branch, token usage, session ID, gateway status done e8d7ab8
TUI-004 Message formatting — timestamps, role colors ( you / ◆ assistant), word wrap done 79ff308
TUI-005 Quiet disconnect — single indicator, auto-reconnect, no error flood done 79ff308
TUI-006 Tool call display — inline spinner + tool name during execution, ✓/✗ on completion done 79ff308
TUI-007 Thinking/reasoning display — dimmed 💭 block for agent:thinking events done 79ff308
TUI-007b Wire token usage, model info, thinking levels end-to-end (gateway → types → TUI) done a061a64
TUI-007c Ctrl+T to cycle thinking levels via set:thinking socket event done a061a64

Wave 2 — Layout & Navigation

ID Task Status Notes
TUI-010 Scrollable message history — viewport with PgUp/PgDn done 4d4ad38
TUI-008 Conversation sidebar — list, create, switch conversations done 9ef578c
TUI-009 Keybinding system — Ctrl+L, Ctrl+N, Ctrl+K, Escape done 9f38f5a
TUI-011 Message search — find in current conversation done 8627827

Wave 3 — Advanced Features

ID Task Status Notes
TUI-012 Project/mission views not-started
TUI-013 Agent status monitoring not-started
TUI-014 Settings/config screen not-started
TUI-015 Multiple agent sessions not-started

Handoff Notes

File Structure

packages/cli/src/tui/
├── app.tsx                          ← Shell composing all components + global keybindings
├── components/
│   ├── top-bar.tsx                  ← Mosaic icon + version + model + connection
│   ├── bottom-bar.tsx               ← Keybinding hints + 3-line footer: gateway, cwd, tokens
│   ├── message-list.tsx             ← Messages, tool calls, thinking, streaming, search highlights
│   ├── input-bar.tsx                ← Bordered prompt with context-aware placeholder
│   ├── sidebar.tsx                  ← Conversation list with keyboard navigation
│   └── search-bar.tsx               ← Message search input with match count + navigation
└── hooks/
    ├── use-socket.ts                ← Typed Socket.IO + switchConversation/clearMessages
    ├── use-git-info.ts              ← Reads cwd + git branch at startup
    ├── use-viewport.ts              ← Scrollable viewport with auto-follow + PgUp/PgDn
    ├── use-app-mode.ts              ← Panel focus state machine (chat/sidebar/search)
    ├── use-conversations.ts         ← REST client for conversation CRUD
    └── use-search.ts                ← Message search with match cycling

Cross-Package Changes

  • packages/types/src/chat/events.ts — Added SessionUsagePayload, SessionInfoPayload, SetThinkingPayload, session:info event, set:thinking event
  • apps/gateway/src/chat/chat.gateway.ts — Emits session:info on session creation, includes usage in agent:end, handles set:thinking

Key Design Decisions

Wave 1

  • Footer is 3 lines: (1) gateway status right-aligned, (2) cwd+branch left / session right, (3) tokens left / provider+model+thinking right
  • Mosaic icon uses brand colors in windmill cross pattern with GAP const to prevent prettier collapsing spaces
  • flexGrow={1} on header text column prevents re-render artifacts
  • Token/model data comes from gateway via agent:end payload and session:info events
  • Thinking level cycling via Ctrl+T sends set:thinking to gateway, which validates and responds with session:info

Wave 2

  • useViewport calculates scroll offset from terminal rows; auto-follow snaps to bottom on new messages
  • useAppMode state machine manages focus: only the active panel handles keyboard input via useInput({ isActive })
  • Sidebar fetches conversations via REST (GET /api/conversations), not socket events
  • switchConversation in useSocket clears all local state (messages, streaming, tool calls)
  • Search uses useMemo for reactive match computation; viewport auto-scrolls to current match
  • Keybinding hints shown in bottom bar: ^L sidebar · ^N new · ^K search · ^T thinking · PgUp/Dn scroll

How to Run

cd /home/jwoltje/src/mosaic-mono-v1-worktrees/tui-improvements
pnpm --filter @mosaic/cli exec tsx src/cli.ts tui
# or after build:
node packages/cli/dist/cli.js tui --gateway http://localhost:4000

Quality Gates

pnpm --filter @mosaic/cli typecheck && pnpm --filter @mosaic/cli lint
pnpm --filter @mosaic/gateway typecheck && pnpm --filter @mosaic/gateway lint
pnpm --filter @mosaic/types typecheck