feat: reimplement TUI with Solid.js matching opencode design
8 months ago
Authored
ClaudeComplete rebuild of the TUI presentation layer at apps/TUI/ using
@opentui/solid (Solid.js) instead of the monolithic React component.
Copies opencode's design and UX 1:1 with modular architecture:
- 9 context providers (exit, kv, theme, dialog, sync, keybind, local, route, prompt)
- Two-route design: Home (logo + prompt + tips) and Session (header + messages + sidebar + prompt)
- Specialized tool renderers for bash, read, write, edit, glob, grep, web, todo
- Message rendering pipeline with text, reasoning, and tool parts
- Full dialog system: command palette (Ctrl+K), model picker, theme picker, provider connect
- 31 color themes ported from opencode (aura, ayu, catppuccin variants, dracula, nord, etc.)
- Prompt enhancements: persistent history, frecency scoring, stash, autocomplete, shell mode
- Interactive permission/question prompts for approval flows
- Responsive sidebar (42ch) with context metrics, todos, activity
- UI stubs for missing backend features (timeline, fork, subagent, export)
- Legacy fallback via --legacy-tui flag preserves old React TUI
https://claude.ai/code/session_01QE14aSEpndNtZw8ReFrwWw
Parent72b483d
77 files changed
- apps/TUI/app.tsx+48−0
- apps/TUI/component/border.tsx+27−0
- apps/TUI/component/dialog-agent.tsx+30−0
- apps/TUI/component/dialog-command.tsx+271−0
- apps/TUI/component/dialog-mcp.tsx+30−0
- apps/TUI/component/dialog-model.tsx+44−0
- apps/TUI/component/dialog-provider.tsx+40−0
- apps/TUI/component/dialog-session-list.tsx+30
−0
apps/TUI/component/dialog-session-rename.tsx+30−0apps/TUI/component/dialog-stash.tsx+89−0apps/TUI/component/dialog-status.tsx+71−0apps/TUI/component/dialog-theme-list.tsx+38−0apps/TUI/component/logo.tsx+118−0apps/TUI/component/markdown.tsx+205−0apps/TUI/component/message/assistant.tsx+12−0apps/TUI/component/message/reasoning-part.tsx+43−0apps/TUI/component/message/text-part.tsx+7−0apps/TUI/component/message/tool-part.tsx+49−0apps/TUI/component/message/user.tsx+22−0apps/TUI/component/prompt/autocomplete.tsx+285−0apps/TUI/component/prompt/frecency.tsx+91−0apps/TUI/component/prompt/history.tsx+95−0apps/TUI/component/prompt/index.tsx+245−0apps/TUI/component/prompt/stash.tsx+103−0apps/TUI/component/spinner.tsx+27−0apps/TUI/component/textarea-keybindings.ts+50−0apps/TUI/component/tips.tsx+70−0apps/TUI/component/todo-item.tsx+44−0apps/TUI/component/tool/bash.tsx+69−0apps/TUI/component/tool/edit.tsx+58−0apps/TUI/component/tool/generic.tsx+65−0apps/TUI/component/tool/glob.tsx+36−0apps/TUI/component/tool/grep.tsx+34−0apps/TUI/component/tool/read.tsx+23−0apps/TUI/component/tool/todo.tsx+31−0apps/TUI/component/tool/web.tsx+27−0apps/TUI/component/tool/write.tsx+25−0apps/TUI/context/dialog.tsx+67−0apps/TUI/context/exit.tsx+45−0apps/TUI/context/keybind.tsx+96−0apps/TUI/context/kv.tsx+73−0apps/TUI/context/local.tsx+57−0apps/TUI/context/prompt.tsx+96−0apps/TUI/context/route.tsx+37−0apps/TUI/context/sync.tsx+402−0apps/TUI/context/theme.tsx+1460−0apps/TUI/index.tsx+74−0apps/TUI/routes/home.tsx+93−0apps/TUI/routes/session/dialog-fork.tsx+30−0apps/TUI/routes/session/dialog-subagent.tsx+30−0apps/TUI/routes/session/dialog-timeline.tsx+30−0apps/TUI/routes/session/footer.tsx+40−0apps/TUI/routes/session/header.tsx+32−0apps/TUI/routes/session/index.tsx+140−0apps/TUI/routes/session/permission.tsx+89−0apps/TUI/routes/session/question.tsx+109−0apps/TUI/routes/session/sidebar.tsx+101−0apps/TUI/tsconfig.json+7−0apps/TUI/ui/dialog-alert.tsx+31−0apps/TUI/ui/dialog-confirm.tsx+70−0apps/TUI/ui/dialog-export-options.tsx+30−0apps/TUI/ui/dialog-help.tsx+72−0apps/TUI/ui/dialog-prompt.tsx+54−0apps/TUI/ui/dialog-select.tsx+132−0apps/TUI/ui/dialog.tsx+55−0apps/TUI/ui/link.tsx+11−0apps/TUI/ui/toast.tsx+58−0apps/TUI/util/clipboard.ts+22−0apps/TUI/util/editor.ts+27−0apps/TUI/util/format.ts+29−0apps/TUI/util/selection.ts+9−0apps/TUI/util/signal.ts+18−0apps/TUI/util/terminal.ts+10−0apps/TUI/util/transcript.ts+46−0package.json+6−2src/index.ts+10−2tsconfig.json+1−1