add qwen plan
ober
95c346f249e8c4042f8ecddd2e5a942b96c6b0a0
new file mode 100644 --- /dev/null +++ b/qwen-plan.md @@ -0,0 +1,796 @@ +# jcode → opencode Look & Feel — Upgrade Plan + +**Date:** 2026-05-05 +**Goal:** Make jcode's TUI feel as polished as opencode's TUI +**Reference:** `~/mine/opencode/packages/opencode/src/cli/cmd/tui/` + +--- + +## Current State + +jcode is a fully-featured AI coding agent with a working TUI built on termbox2 via FFI. +It has 3 built-in themes (dark, light, gruvbox), a face-based theming system with ~45 named +faces, basic markdown rendering, a sidebar, dialog system, and multi-line input. + +opencode's TUI is built by terminal.shop creators using a custom SolidJS + @opentui renderer. +It has 33+ themes, streaming tree-sitter syntax highlighting, a home screen with ASCII art +logo, toast notifications, a command palette, leader-key vim-like bindings, agent-colored +accents, a stacked dialog system, mouse text selection, and extensive sidebar panels. + +The gap is significant in visual polish and interaction richness. This plan proposes closing +that gap in phases, starting with quick wins that deliver maximum visual impact. + +--- + +## Key Differences (jcode vs opencode) + +| Feature | jcode | opencode | +|---------|-------|----------| +| Themes | 3 built-in | 33+ built-in + custom theme JSON loading | +| Dark/Light auto-detect | No | Yes (ANSI escape query `\x1b]11;?`) | +| Home screen | None (jumps into session) | Logo + prompt + rotating tips | +| ASCII art logo | None | Half-block (`▀`) rendering with 3D shadows | +| Message styling | "You:" labels + text color | Colored left borders + hover-highlighted backgrounds | +| Syntax highlighting | Static face-based colors | Real-time tree-sitter per language | +| Thinking/reasoning display | No special treatment | Dimmed/translucent rendering | +| Toast notifications | None | Top-right, colored left border, auto-dismiss | +| Command palette | Slash-command completion only | Ctrl+K fuzzy search with categories + keybind hints | +| Leader key | None | Space → 2s chord window → second key | +| Keybinds | ~15 direct bindings | 30+ configurable keybinds with leader support | +| Dialog system | Single modal | Stacked modals with dimmed backdrop | +| Mouse support | Wheel scroll only | Selection + right-click copy + scroll acceleration | +| Sidebar panels | Sessions, files, tools, connections | Files tree, MCP, LSP diagnostics, todos, context files | +| Session timeline | None | Timeline view with fork capability | +| Agent color accent | None | Each agent has unique color flowing through UI | +| Layout responsiveness | Auto-hide sidebar <100 cols | Auto-show sidebar >120 cols, overlay on narrow | +| Theme semantic slots | ~45 face names | 55+ semantic slots with dark/light variants | +| Custom themes | None | `~/.opencode/themes/*.json` loading | +| Terminal transparency | No | Background alpha support | +| Config file | `jcode.json` | `opencode.json` with TUI schema (scroll, keybinds, etc.) | + +--- + +## Phase 1 — Quick Wins (Low Effort, High Impact) + +**Estimated effort:** 1-2 weeks + +### 1.1 Add Popular Built-in Themes + +**Files:** `src/jcode/ui/tui-theme.ss` + +Add 10 popular themes matching opencode's palette definitions: +- dracula (purple/cyan on dark) +- catppuccin-mocha (pink/blue/green on dark) +- catppuccin-latte (light variant) +- tokyonight (blue/purple on dark) +- tokyonight-day (light variant) +- nord (arctic blue palette) +- one-dark (Atom theme) +- monokai (classic) +- gruvbox-light +- solarized-dark + +Each theme requires defining all face entries. Copy the opencode color definitions from: +- `~/mine/opencode/src/cli/cmd/tui/context/theme/{dracula,catppuccin,tokyonight,nord,one-dark,monokai,solarized}.json` + +Extract the color values from the `defs` section, then map the `theme` section's semantic +slots to jcode face names. Example mapping: + +``` +primary → input-prompt, user-label +secondary → status-mode-plan +accent → spinner, tool-name, heading +error → error +warning → status-mode-plan +success → status-mode-build +info → tool-name +text → default, assistant-text, user-text +textMuted → dim, tool-result, status-dim +background → default bg +backgroundPanel → sidebar-bg, completion-item +backgroundElement → dialog-border bg, completion-selected bg +border → tool-border, divider, sidebar-divider, blockquote-border +borderSubtle → horizontal-rule +``` + +### 1.2 Add ASCII Art Logo + +**Files:** New `src/jcode/ui/tui-logo.ss`, modified `src/jcode/ui/tui.ss` + +Create a logo similar to opencode's half-block rendering. opencode uses: + +``` +left: [" ", "█▀▀█ █▀▀█ █▀▀█ █▀▀▄", "█__█ █__█ █^^^ █__█", "▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀~~▀"] +right: [" ▄ ", "█▀▀▀ █▀▀█ █▀▀█ █▀▀█", "█___ █__█ █__█ █^^^", "▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀"] +``` + +Shadow markers: `_` (full shadow), `^` (letter top/shadow bottom via ▀), `~` (shadow top via ▀). + +For jcode, design a "JC" or "jcode" ASCII block logo using the same technique: + +1. Create two halves (left=shadow, right=bold text) +2. Render each row by printing half-block `▀` characters where fg=letter color, bg=tinted + shadow of the theme's background +3. Display centered on the screen when the message list is empty (first launch) + +Implementation in termbox2: use `tb-change-cell!` with the upper-half block character `▀` +(U+2580), set fg to the letter color, bg to a shadow tint (mix of bg + fg at 25%). + +```scheme +(def (render-logo! x y fg shadow-fg) + ;; For each cell in the logo lines: + ;; - If marker is a normal char: tb-print! the char with fg + ;; - If marker is _: tb-print! space with bg=shadow + ;; - If marker is ^: tb-print! ▀ with fg=letter-color bg=shadow + ;; - If marker is ~: tb-print! ▀ with fg=shadow bg=theme-bg + ) +``` + +Display the logo centered in the message area when no messages exist yet. + +### 1.3 Add Colored Left Borders to Messages + +**Files:** `src/jcode/ui/tui-message.ss` + +Currently messages are rendered as plain text lines. Add a 1-column colored left border +to each message block: + +- User messages: `user-label` face color (blue in dark theme) +- Assistant messages: `assistant-text` face color or a subtle primary accent +- Tool messages: `tool-name` face color (teal) +- Error messages: `error` face color (red) + +Modify `render-msg-block!` to: + +1. Before rendering each message block's lines, draw a 1-cell-wide vertical border from + `y` to `y + height - 1` at column `x` (or `x - 1` if we shift content right) +2. Use `tb-change-cell!` to set the border cell's bg to the role's border color +3. Add 1 column of padding between the border and the text content + +Result: +``` +│ You: Fix the bug in... +│ + ⟡ read ← tool border (teal) +│ +│ Here's the fix... ← assistant border (primary/accent) +``` + +This is a visual change that makes message blocks feel like "cards" with colored side +accents, similar to opencode's approach. + +### 1.4 Add Toast Notification System + +**Files:** New `src/jcode/ui/tui-toast.ss`, modified `src/jcode/ui/tui.ss` and `src/jcode/ui/tui-theme.ss` + +Add a toast component that displays top-right positioned notifications with: + +- Variant-specific colored left border (error=red, warning=yellow, success=green, info=cyan) +- Optional title (bold) and message text +- Auto-dismiss after configurable duration (default 5s) +- Manual dismiss on click or key press + +New faces needed: +```scheme +(toast-error-border . ,(make-face (rgb #xf4 #x47 #x47) ...)) +(toast-warning-border . ,(make-face (rgb #xff #xcc #x00) ...)) +(toast-success-border . ,(make-face (rgb #x4e #xc9 #xb0) ...)) +(toast-info-border . ,(make-face (rgb #x56 #x9c #xd6) ...)) +(toast-bg . ,(make-face ... (rgb #x2d #x2d #x2d) ...)) +(toast-title . ,(make-face ... ... #t #f #f)) +(toast-message . ,(make-face ... ... #f #f #f)) +``` + +Toast struct: +```scheme +(defstruct toast (variant title message dismiss-at)) +``` + +Integration points: +- Agent errors → show error toast +- Tool completion (long-running) → show success toast +- Session saved → show info toast +- Config loaded → show info toast + +In the main event loop, maintain a list of active toasts, render them at top-right +(positioned at `x = width - toast-width - 2, y = 2`), and remove expired ones. + +### 1.5 Add Custom Theme Loading + +**Files:** `src/jcode/ui/tui-theme.ss`, `src/jcode/core/config.ss` + +Add support for loading custom themes from JSON files: + +1. Scan `~/.jcode/themes/*.json` and `./.jcode/themes/*.json` on startup +2. Parse JSON theme files using opencode's theme schema (the `defs` + `theme` structure) +3. Map the parsed semantic slots to jcode face names +4. Register loaded themes alongside built-in themes + +JSON schema (opencode-compatible): +```json +{ + "$schema": "https://opencode.ai/theme.json", + "defs": { "bg": "#1e1e2e", "fg": "#cdd6f4", "accent": "#cba6f7", ... }, + "theme": { + "primary": { "dark": "accent", "light": "accent" }, + "text": { "dark": "fg", "light": "fg" }, + "background": { "dark": "bg", "light": "bg" }, + ... + } +} +``` + +Add a theme loading function: +```scheme +(def (load-theme-from-json path) + ;; Parse JSON, resolve defs, map theme slots to faces + ;; Return a theme hash table compatible with make-theme-table + ) +``` + +This gives users parity with opencode's custom theme ecosystem and allows sharing themes +between the two tools. + +### 1.6 Expand Face System with Additional Semantic Slots + +**Files:** `src/jcode/ui/tui-theme.ss` + +Add the following faces to match opencode's 55+ semantic slots: + +```scheme +;; Markdown (additional) +markdown-emph ;; italic/underscore text +markdown-strong ;; bold text +markdown-code-fence ;; ``` markers + +;; Toast (see 1.4) +toast-error-border +toast-warning-border +toast-success-border +toast-info-border +toast-bg +toast-title +toast-message + +;; Thinking/Reasoning (for Phase 2) +thinking-text ;; dimmed reasoning content +thinking-border ;; border around thinking blocks + +;; Agent accent (for Phase 3) +agent-accent ;; current agent's accent color (dynamic) + +;; Home screen (for Phase 2) +home-logo-fg ;; logo primary color +home-logo-shadow ;; logo shadow color +home-tip-text ;; rotating tip text +home-tip-icon ;; tip icon color + +;; Status (additional) +status-session-name ;; session name in status +status-warning ;; warning indicators + +;; Interactive states +message-hover-bg ;; message background on hover +``` + +--- + +## Phase 2 — Medium Effort + +**Estimated effort:** 2-4 weeks + +### 2.1 Home Screen with Logo and Tips + +**Files:** New `src/jcode/ui/tui-home.ss`, modified `src/jcode/ui/tui.ss` + +Add a dedicated home screen that appears when: +- No session is active, OR +- The user is on a fresh launch with no messages + +Layout (centered vertically): +``` + ┌─────────────────────┐ + │ ASCII LOGO │ + │ (with shadows) │ + └─────────────────────┘ + + ┌─────────────────────────┐ + │ > Fix a TODO... │ ← input prompt + └─────────────────────────┘ + + 💡 Tip: Press Ctrl+B to toggle sidebar +``` + +Implementation: +1. Add a `home?` state to the TUI app-state +2. When `home?` is true, render the home screen instead of the message area +3. Center the logo using the terminal dimensions +4. Render the input prompt below the logo +5. Rotate through tip messages every 8 seconds below the prompt + +Tips to include: +- "Press Ctrl+B to toggle the sidebar" +- "Use /help to see all slash commands" +- "Press Ctrl+T to cycle themes" +- "Multi-line input: Enter for newline, Alt+Enter to submit" +- "Toggle PLAN/BUILD mode with Shift+Tab" +- "Scroll with PageUp/PageDown or mouse wheel" + +When the user submits their first message, transition from home screen to session view. + +### 2.2 Dimmed Thinking/Reasoning Display + +**Files:** `src/jcode/ui/tui-message.ss`, `src/jcode/ui/tui-markdown.ss`, `src/jcode/ui/tui-theme.ss` + +When the LLM sends reasoning/thinking content (e.g., Anthropic's extended thinking), +render it visually distinct from the main response: + +1. Detect thinking content (marked by `<thinking>` tags or provider-specific metadata) +2. Render thinking blocks with: + - Dimmed text color (use `thinking-text` face, ~60% opacity of normal text) + - Left border in a muted accent color + - Header line: "⚙ Thinking..." (collapsible) + - When collapsed: show only the header with elapsed time + +New faces: +```scheme +(thinking-text . ,(make-face (rgb #x60 #x60 #x60) ... #f #t #f)) ;; dim + italic +(thinking-border . ,(make-face (rgb #x3a #x3a #x3a) ...)) +(thinking-header . ,(make-face (rgb #x80 #x80 #x80) ... #t #f #f)) +``` + +This matches opencode's `subtleSyntax` approach where thinking is visually separated +with reduced opacity and italic styling. + +### 2.3 Stacked Dialog System + +**Files:** `src/jcode/ui/tui-dialog.ss`, `src/jcode/ui/tui.ss`, `src/jcode/ui/tui-theme.ss` + +Currently, jcode has a single-modal dialog system. Upgrade to stacked dialogs: + +1. Maintain a dialog stack instead of a single active dialog +2. When a new dialog opens, push it onto the stack +3. Escape pops the top dialog (one layer at a time) +4. Render a dimmed backdrop behind the dialog stack +5. Position stacked dialogs with slight offset so the stack is visible + +```scheme +(defstruct dialog-stack + (dialogs ;; list of dialog structs, top = car + backdrop? ;; whether to render dimmed overlay + )) +``` + +Backdrop rendering: +- Draw the entire screen with a semi-transparent overlay (use a darkened version of the + current background, or render `░` characters with dimmed fg) +- Render only the top dialog at full brightness + +This enables nested operations like: permission prompt → confirmation → result alert, +without losing the parent context. + +### 2.4 Command Palette (Ctrl+K) + +**Files:** New `src/jcode/ui/tui-command-palette.ss`, modified `src/jcode/ui/tui-keys.ss`, `src/jcode/ui/tui.ss` + +Add a VS Code-style command palette accessible via Ctrl+K (or `/` from home screen): + +Features: +- Fuzzy search across all commands +- Categorized sections: Sessions, Models, Agents, Display, System +- Keybind hints displayed inline for each command +- Slash commands shown as aliases +- Recent commands at top (frecency ranking) + +Commands to include: +``` +/session new Ctrl+N New session +/session list Ctrl+O List sessions +/session rename Rename current session +/model list List available models +/model cycle Cycle to next model +/agent list List available agents +/agent cycle Cycle agent +/theme Cycle theme +/theme list Theme picker +/sidebar toggle Ctrl+B Toggle sidebar +/display thinking Toggle thinking visibility +/display tool-details Toggle tool detail expansion +/command palette Ctrl+K Open command palette (self) +/help Show help +/quit Ctrl+D Quit +``` + +Implementation: +1. Overlay the command palette as a dialog-like panel centered on screen +2. Input field at top with fuzzy matching +3. Results list below, grouped by category +4. Navigate with arrows, select with Enter +5. Display keybinds on right side of each entry + +### 2.5 Leader Key System + +**Files:** `src/jcode/ui/tui-keys.ss`, `src/jcode/ui/tui-theme.ss`, `src/jcode/ui/tui.ss` + +Add a vim-like leader key system (default: Space): + +1. When leader key is pressed, enter a 2-second chord window +2. During the chord window, the prompt dims and shows "LEADER" indicator +3. Second key completes the chord and triggers the bound action +4. Timeout after 2 seconds cancels leader mode + +Default leader keybinds: +``` +<leader>s n → new session +<leader>s l → list sessions +<leader>s r → rename session +<leader>m l → list models +<leader>m c → cycle model +<leader>a l → list agents +<leader>a c → cycle agent +<leader>t → cycle theme +<leader>b → toggle sidebar +<leader>k → command palette +<leader>? → show leader key help overlay +``` + +Implementation: +```scheme +(defstruct leader-state + (active? + timer ;; thread-based timer for 2s timeout + prefix ;; accumulated keys so far + bindings)) ;; tree of key → action or sub-tree +``` + +Add faces: +```scheme +(leader-indicator . ,(make-face (rgb #xff #xcc #x00) ... #t #f #f)) +(leader-dim . ,(make-face (rgb #x40 #x40 #x40) ...)) +``` + +### 2.6 Richer Sidebar Panels + +**Files:** `src/jcode/ui/tui-sidebar.ss`, modified `src/jcode/ui/tui-theme.ss` + +Expand the sidebar to include richer panels: + +**Files panel** (tree view): +- Recursive file tree of the project directory +- Show modified/added/deleted status with colored indicators +- Expandable/collapsible directories + +**MCP panel**: +- List connected MCP servers with status indicators +- Show available tools per server +- Connection/disconnection controls + +**LSP panel**: +- List diagnostics from LSP (errors, warnings, info) +- File:line:column format +- Severity-colored indicators + +Current sidebar sections: Sessions, Files Changed, Tools, Connections +New sections to add: File Tree, MCP Servers, LSP Diagnostics, Todos (future) + +--- + +## Phase 3 — Larger Effort + +**Estimated effort:** 1-3 months + +### 3.1 Streaming Syntax Highlighting + +**Files:** `src/jcode/ui/tui-markdown.ss`, new `src/jcode/ui/tui-syntax.ss` + +Currently, code blocks in markdown use a single `code-block` face. opencode uses tree-sitter +for real-time syntax highlighting as the LLM streams content. + +Approach 1 — Full tree-sitter FFI: +1. Build tree-sitter as a static library or shared library +2. Write FFI bindings to `ts_parser_new`, `ts_parser_parse`, `ts_tree_root_node`, + `ts_node_child`, `ts_node_type`, `ts_node_start_byte`, `ts_node_end_byte` +3. Language-specific parsers: bash, python, javascript, typescript, scheme, rust, go, etc. +4. Map tree-sitter highlight queries to theme syntax faces + +```scheme +;; New syntax faces: +syntax-comment syntax-keyword syntax-function +syntax-variable syntax-string syntax-number +syntax-type syntax-operator syntax-punctuation +``` + +Approach 2 — Lightweight keyword-based (simpler, faster to implement): +1. Build per-language keyword lists +2. Scan each line of code for keywords, strings (quoted), comments +3. Apply syntax faces per token +4. Less accurate than tree-sitter but provides 80% of the visual benefit + +Both approaches require extending the markdown renderer to pass code block language info +to the syntax highlighter and render mixed-face lines within code blocks. + +### 3.2 Agent-Colored Accent System + +**Files:** `src/jcode/ui/tui-theme.ss`, `src/jcode/ui/tui.ss`, `src/jcode/ui/tui-input.ss` + +Each agent (coder, architect, reviewer, etc.) gets a unique accent color that flows +through the UI: + +1. Define accent colors per agent name (or generate from name hash) +2. When the active agent changes, update a dynamic `agent-accent` color parameter +3. Use `agent-accent` for: + - Input prompt border color + - Spinner color + - Status bar accent highlight + - Assistant message left border color + +```scheme +(def *agent-accent* (make-parameter (rgb #x4e #xc9 #xb0))) ;; default teal + +(def (agent-accent-color agent-name) + (case agent-name + (("coder") (rgb #x4e #xc9 #xb0)) ;; teal + (("architect") (rgb #x56 #x9c #xd6)) ;; blue + (("reviewer") (rgb #xdc #xdc #xaa)) ;; yellow + (else (rgb #x4e #xc9 #xb0)))) ;; default +``` + +When switching agents, update `*agent-accent*` and trigger a re-render. The user will +see the UI's accent color change to match the active agent. + +### 3.3 Auto-Detect Terminal Dark/Light Mode + +**Files:** `src/jcode/ui/tui.ss`, `src/jcode/ui/tui-theme.ss` + +Query the terminal's background color to auto-select dark or light theme: + +1. Send ANSI escape sequence: `\x1b]11;?\x07` +2. Parse the response: `\x1b]11;rgb:RRRR/GGGG/BBBB\x07` or similar +3. Calculate luminance of the background RGB value +4. If luminance < 0.5, terminal is dark → use dark variant +5. If luminance >= 0.5, terminal is light → use light variant + +Implementation: +```scheme +(def (query-terminal-bg) + ;; Write query to terminal, read response with timeout + ;; Return 'dark or 'light + ) + +(def (luminance r g b) + ;; Standard luminance calculation + (+ (* 0.299 r) (* 0.587 g) (* 0.114 b))) +``` + +This provides seamless light/dark theme switching that matches the user's terminal +configuration. Add a `theme-auto` option that activates this behavior. + +### 3.4 Mouse Text Selection + +**Files:** `src/jcode/ui/tui.ss`, `src/jcode/ui/tui-message.ss`, `src/jcode/ui/tui-ffi.ss` + +Add mouse text selection support: + +1. Capture mouse button press/release and drag events (termbox2 already supports this + via `TB_INPUT_MOUSE`) +2. Track selection start (press) and end (drag/release) as (x, y) screen positions +3. Map screen positions to text content in the message thread +4. Highlight selected text with a selection background color +5. Copy to clipboard on Ctrl+C (or right-click) when selection is active + +New faces: +```scheme +(selection-bg . ,(make-face ... (rgb #x3a #x3a #x5a) ...)) +``` + +Selection state: +```scheme +(defstruct selection + (start-x start-y end-x end-y active?)) +``` + +This allows users to select and copy text from the message area, which is currently +not possible (only mouse wheel scrolling works). + +### 3.5 Scroll Acceleration + +**Files:** `src/jcode/ui/tui.ss` + +Add configurable scroll acceleration for faster navigation: + +1. Track time between consecutive scroll events +2. If scroll events come rapidly (< 30ms apart), increase scroll multiplier +3. Gradually decrease multiplier when scrolling stops +4. Add `scroll_speed` and `scroll_acceleration` config options + +```scheme +(defstruct scroll-state + (last-scroll-time + velocity + multiplier)) +``` + +Default: base_scroll = 3 lines, max_acceleration = 4x → max 12 lines per scroll event. + +### 3.6 Session Timeline and Fork UI + +**Files:** New `src/jcode/ui/tui-timeline.ss`, modified `src/jcode/ui/tui-dialog.ss`, `src/jcode/ui/tui-message.ss` + +Add a visual timeline of the conversation that allows users to: + +1. View a condensed list of all messages (user + assistant) in the session +2. Jump to any point in the conversation +3. Fork the conversation from any point (create a branch) +4. Compare branches + +Timeline panel (as a dialog or sidebar sub-panel): +``` +── Timeline ───────────────────────── + 1. You: Fix the bug in parser + 2. Assistant: [edited parser.ss] + 3. You: Add tests + 4. Assistant: [created parser-test.ss] + 5. You: The tests fail ← fork point +───────────────────────────────────── +``` + +Fork from point 5 creates a new session that starts from message 4's context but allows +a different conversation path. + +--- + +## Phase 4 — Architectural (Optional / Long-term) + +**Estimated effort:** 2-6 months + +### 4.1 Client/Server Architecture + +**Current:** jcode runs the agent and TUI in the same process. Agent runs on worker +threads, TUI on the main thread, communication via `thread-send`. + +**Target:** Separate the agent into its own process (server) that the TUI connects to +via RPC (stdio, TCP, or WebSocket). This enables: +- Remote control (mobile app, another terminal) +- Multiple TUI clients connecting to the same session +- Server-side session management independent of any client +- Headless operation (agent runs as a daemon, TUI attaches on demand) + +This is a significant architectural change that affects: +- `src/jcode/core/agent.ss` → becomes the server +- `src/jcode/ui/tui.ss` → becomes a thin client +- `src/jcode/ui/serve.ss` → already has JSONL server, could be extended to RPC + +### 4.2 Plugin UI Slots + +**Files:** `src/jcode/ui/tui.ss`, `src/jcode/core/plugin.ss` + +Add a plugin slot system similar to opencode's `TuiPluginRuntime.Slot`: + +1. Define named slots: `home_logo`, `home_prompt`, `home_bottom`, `home_footer`, + `app`, `session_header`, `session_footer`, `sidebar`, `message_actions` +2. Plugins can register components to fill or replace slots +3. Slot modes: `append` (add after default), `prepend` (add before), `replace` (override), + `single_winner` (multiple plugins compete) + +This enables third-party UI extensions without modifying core TUI code. + +--- + +## Theme Schema Mapping Reference + +For implementing opencode-compatible JSON themes (Phase 1.5), here is the complete +mapping from opencode's semantic slots to jcode face names: + +``` +opencode slot → jcode face name(s) +──────────────────────────────────────────────── +primary → user-label, input-prompt +secondary → status-mode-plan +accent → spinner, tool-name, heading, status-mode-build +error → error +warning → status-mode-plan +success → status-mode-build +info → tool-name +text → default, assistant-text, user-text +textMuted → dim, tool-result, status-dim, status-tokens, status-cost +background → default (bg) +backgroundPanel → sidebar-bg, completion-item (bg), dialog-* (bg) +backgroundElement → completion-selected (bg), code-inline (bg) +border → tool-border, divider, sidebar-divider +borderActive → dialog-border, sidebar-selected (border) +borderSubtle → horizontal-rule, blockquote-border +diffAdded → diff-added +diffRemoved → diff-removed +diffContext → diff-context +diffHunkHeader → diff-hunk +diffHighlightAdded +diffHighlightRemoved +diffAddedBg → diff-added (bg) +diffRemovedBg → diff-removed (bg) +diffContextBg → diff-context (bg) +diffLineNumber +diffAddedLineNumberBg +diffRemovedLineNumberBg +markdownText → assistant-text, user-text +markdownHeading → heading +markdownLink → link +markdownLinkText +markdownCode → code-block, code-inline +markdownBlockQuote → blockquote +markdownEmph → italic +markdownStrong → bold +markdownHorizontalRule → horizontal-rule +markdownListItem → list-bullet +markdownListEnumeration → list-bullet +markdownImage +markdownImageText +markdownCodeBlock → code-block +syntaxComment → (future: syntax faces) +syntaxKeyword → (future) +syntaxFunction → (future) +syntaxVariable → (future) +syntaxString → (future) +syntaxNumber → (future) +syntaxType → (future) +syntaxOperator → (future) +syntaxPunctuation → (future) +``` + +For opencode themes with `{ dark: "...", light: "..." }` variants, jcode should: +1. Always use the `dark` variant when rendering (since jcode themes are defined per-theme, + not per-mode) +2. OR: define a paired dark/light theme where dark uses dark variants and light uses light + variants from the JSON + +--- + +## File Changes Summary + +### New Files to Create +1. `src/jcode/ui/tui-logo.ss` — ASCII art logo rendering +2. `src/jcode/ui/tui-toast.ss` — Toast notification system +3. `src/jcode/ui/tui-home.ss` — Home screen with logo and tips +4. `src/jcode/ui/tui-command-palette.ss` — Command palette +5. `src/jcode/ui/tui-timeline.ss` — Session timeline (Phase 3) +6. `src/jcode/ui/tui-syntax.ss` — Syntax highlighting (Phase 3) + +### Files to Modify (Phase 1) +1. `src/jcode/ui/tui-theme.ss` — Add 10+ themes, expand face system, add theme JSON loading +2. `src/jcode/ui/tui-message.ss` — Add colored left borders to message blocks +3. `src/jcode/ui/tui.ss` — Integrate toast rendering, home screen state, logo display +4. `src/jcode/core/config.ss` — Add theme directory scanning, TUI config schema + +### Files to Modify (Phase 2) +1. `src/jcode/ui/tui-dialog.ss` — Stacked dialog system +2. `src/jcode/ui/tui-keys.ss` — Leader key support, command palette keybind +3. `src/jcode/ui/tui-sidebar.ss` — Richer panels (file tree, MCP, LSP) +4. `src/jcode/ui/tui-markdown.ss` — Thinking/reasoning rendering, syntax highlighting hooks + +### Files to Modify (Phase 3) +1. `src/jcode/ui/tui-ffi.ss` — Mouse selection events, termbox2 mouse mode extensions + +--- + +## Priority Recommendations + +### Highest Impact, Lowest Effort (Do First) +1. **Add popular themes** (1.1) — immediate visual variety, ~500 lines of face definitions +2. **Colored left borders** (1.3) — changes how messages feel, ~50 lines in tui-message.ss +3. **Toast notifications** (1.4) — modern UX pattern, ~200 lines new file + +### Medium Impact (Do Second) +4. **ASCII art logo** (1.2) — branding, ~100 lines +5. **Home screen** (2.1) — first impression, ~200 lines +6. **Custom theme loading** (1.5) — ecosystem expansion, ~150 lines + +### Higher Effort (Do Third) +7. **Command palette** (2.4) — power user feature, ~300 lines +8. **Leader key** (2.5) — vim-like UX, ~150 lines +9. **Stacked dialogs** (2.3) — ~100 lines modified +10. **Thinking display** (2.2) — depends on provider support + +### Long-term (Plan For) +11. **Syntax highlighting** (3.1) — requires FFI work +12. **Agent accents** (3.2) — requires agent metadata +13. **Session timeline** (3.6) — significant UI addition +14. **Client/server** (4.1) — architectural rewrite