feat(tui): comprehensive UX uplift with smart scroll-lock, clipboard copy, and visual redesign - #74
Merged
Merged
Conversation
… visual redesign ADRs Co-authored-by: Justin Wilkin <justin@entr.net.au>
* feat(tui): implement smart scroll-lock with follow mode and new content indicator (ADR-0048) Co-authored-by: Justin Wilkin <justin@entr.net.au> * fix(tui): intercept 'g' scroll-lock key before textarea update Copilot PR review identified that pressing 'g' while scroll-locked would insert an unwanted 'g' character into the textarea because handleScrollKey was called from handleKeyPress, which runs after textarea.Update(msg). Fix: pre-empt the textarea update with an early-return guard at the same call site as the command palette pre-emption (lines 100-137). When the model is scroll-locked (!followScroll) and the user presses 'g', we jump to the viewport bottom, resume auto-follow, and return before the textarea ever sees the keystroke. The 'g' branch in handleScrollKey is now only reached when followScroll is already true, so its !followScroll guard makes it a no-op — no duplicate logic, just belt-and-suspenders safety. * style(tui): align struct field assignments in scroll_lock_test.go Co-authored-by: Justin Wilkin <justin@entr.net.au> --------- Co-authored-by: anvxl <anvxl@entr.net.au>
…rlay (#72) * fix(tui/overlay): handle bracketed paste input in settings dialog Co-authored-by: Justin Wilkin <justin@entr.net.au> * docs(adr): update ADR-0049 to reflect implemented bracketed paste solution Co-authored-by: Justin Wilkin <justin@entr.net.au> * fix(tui/overlay): address PR review comments on bracketed paste implementation - Replace isPrintableInput() guard in handleDialogCharInput with keyMsg.Type == tea.KeyRunes check; avoids inserting Bubble Tea control-key strings (ctrl+v, ctrl+c, alt+x) as literal text - Use keyMsg.Runes directly for character insertion (avoids keyMsg.String() which formats multi-key events as 'ctrl+x' etc.) - Replace handleDialogPaste whitelist (\n\r\t) with unicode.IsPrint filter so escape sequences and other control chars are also stripped - Fix maxLength enforcement in both handleDialogCharInput and handleDialogPaste to use rune counts (len([]rune(...))) not byte counts - Remove isPrintableInput() helper (no longer needed) - Replace TestIsPrintableInput with TestInputDialog_CharInput (5 subtests) - Add TestInputDialog_BracketedPaste: escape-sequence stripping and rune-based maxLength subtests (11 subtests total, all pass) --------- Co-authored-by: anvxl <anvxl@entr.net.au>
Co-authored-by: Justin Wilkin <justin@entr.net.au>
Co-authored-by: Justin Wilkin <justin@entr.net.au>
* refactor(tui): replace emoji icons with ASCII alternatives Co-authored-by: Justin Wilkin <justin@entr.net.au> * fix(tui): correct viewport height reservation for scroll-lock indicator Co-authored-by: Justin Wilkin <justin@entr.net.au> * refactor(tui): redesign overlays with responsive sizing and flat visual style Co-authored-by: Justin Wilkin <justin@entr.net.au> * docs(tui): add slash menu discoverability redesign scratch doc and palette refactor Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): add command palette scrolling and adjust toast overlay position Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): execute selected command immediately on enter Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): dynamically adjust textarea height based on terminal size * feat(tools): add unique ID to tool calls and related events Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): simplify context summarization by removing progress tracking * feat(tui): improve output formatting, sanitization, and error display Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): add collapsible thinking blocks with elapsed time indicator Co-authored-by: Justin Wilkin <justin@entr.net.au> * fix(tui): remove extra newlines in summarization status rendering Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): add show thinking toggle setting to UI config and settings overlay Co-authored-by: Justin Wilkin <justin@entr.net.au> * style(tui): normalize whitespace and simplify overlay code Co-authored-by: Justin Wilkin <justin@entr.net.au> * docs(readme): update TUI feature list and add guides for redesigned interface Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): redesign header bar and centralize version constant Co-authored-by: Justin Wilkin <justin@entr.net.au> * fix(tui): account for visual spacer line in viewport height calculation Co-authored-by: Justin Wilkin <justin@entr.net.au> * refactor(tui): simplify message rendering and improve scroll logic Co-authored-by: Justin Wilkin <justin@entr.net.au> * feat(tui): update user icon style color from salmon pink to coral pink --------- Co-authored-by: anvxl <anvxl@entr.net.au>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR delivers a broad TUI v2 UX uplift: scroll-lock while streaming, clipboard export, reflow-capable message history, and a flat visual redesign with responsive overlays—plus plumbing updates to track tool calls via stable IDs.
Changes:
- Adds scroll-lock state + indicator, keyboard handlers (PgUp/PgDn + g/G), and viewport/layout recalculation improvements.
- Introduces TUI-owned
[]DisplayMessagehistory with resize reflow, output sanitization, and clipboard copy (Ctrl+Y). - Refactors/update modularization (messages/keys/input), responsive overlay sizing helpers, and stable ToolCallID propagation end-to-end.
Reviewed changes
Copilot reviewed 68 out of 68 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| review.md | Implementation review notes and remaining gaps. |
| pkg/version/version.go | New shared application version constant. |
| pkg/types/event_test.go | Updates tests for ToolCallID-aware tool event constructors. |
| pkg/types/event.go | Adds ToolCallID field + updates tool event constructors to accept an ID. |
| pkg/tools/coding/search_files.go | Updates formatting glyphs for search output. |
| pkg/tools/coding/list_files.go | Updates formatting glyphs for list output. |
| pkg/executor/tui/viewport_height_test.go | Adds viewport height regression tests (spacer/indicators/multiline input). |
| pkg/executor/tui/view.go | Implements compact header/tips, scroll-lock banner, input redesign, toast/summarization redesign hooks. |
| pkg/executor/tui/update_overlay_fix_test.go | Test adjustments for overlay closing behavior. |
| pkg/executor/tui/update_messages.go | New message-handling module for non-key update messages. |
| pkg/executor/tui/update_keys.go | New key-handling module incl. scroll-lock keys + clipboard copy. |
| pkg/executor/tui/update_input.go | New input-dispatch module for enter handling (slash/bash/user messages). |
| pkg/executor/tui/types/styles.go | Flattens overlay/container styles + adds responsive sizing helpers. |
| pkg/executor/tui/styles.go | Updates TUI color tokens and styles for redesigned UI elements. |
| pkg/executor/tui/slash_commands.go | Adds /thinking, redesigns help overlay content + updates toast icons. |
| pkg/executor/tui/scroll_lock_test.go | Adds unit tests for scroll-lock behavior and key handling. |
| pkg/executor/tui/result_display.go | Sanitizes preview lines and enhances execute_command summaries + parsing for new glyphs. |
| pkg/executor/tui/overlay/tool_result.go | Uses shared key constants for overlay close handling. |
| pkg/executor/tui/overlay/settings_test.go | Updates overlay dimension expectations + adds paste/char input tests. |
| pkg/executor/tui/overlay/palette.go | Makes command palette responsive with scrolling list and new render signature. |
| pkg/executor/tui/overlay/notes.go | Makes notes overlay responsive and aligns styling with redesign. |
| pkg/executor/tui/overlay/help.go | Makes help overlay responsive + adds resize handling and centered header/footer. |
| pkg/executor/tui/overlay/diff.go | Makes diff viewer responsive and aligns styling with redesign. |
| pkg/executor/tui/overlay/context.go | Makes context overlay responsive + adds resize handling and centered header/footer. |
| pkg/executor/tui/overlay/approval.go | Makes generic approval overlay responsive + adds resize handling and separator usage. |
| pkg/executor/tui/overlay.go | Adjusts toast overlay vertical placement and alignment. |
| pkg/executor/tui/model.go | Introduces messages []DisplayMessage, thinking toggle/timer, scroll-lock state fields. |
| pkg/executor/tui/messages_test.go | Adds tests for message trimming, concatenation, and resize reflow behavior. |
| pkg/executor/tui/messages.go | Adds DisplayMessage abstraction + render/append helpers with retention cap. |
| pkg/executor/tui/init.go | Defers viewport sizing to WindowSizeMsg; loads showThinking from config; clears textarea prompt. |
| pkg/executor/tui/helpers.go | Adds ANSI stripping/sanitization + improves rune-width wrapping; updates textarea height logic. |
| pkg/executor/tui/executor.go | Removes debug logging and updates toast icons for startup warnings. |
| pkg/executor/tui/events.go | Switches to DisplayMessage history + sanitization; implements scrollToBottomOrMark/resumeFollowScroll; ToolCallID caching. |
| pkg/executor/tui/bash_commands.go | Updates icons and clears internal textarea prompt for external prompt rendering. |
| pkg/executor/tui/approval/pr_test.go | Updates expected toast icon for cancel path. |
| pkg/executor/tui/approval/pr.go | Updates PR approval/reject toast icons. |
| pkg/executor/tui/approval/commit_test.go | Updates expected toast icon for cancel path. |
| pkg/executor/tui/approval/commit.go | Updates commit approval/reject toast icons. |
| pkg/config/ui.go | Adds persisted show_thinking UI config setting with getters/setters. |
| pkg/agent/tools/tool.go | Adds generated ToolCall ID field to ToolCall. |
| pkg/agent/tools/parser.go | Generates UUID for each parsed tool call. |
| pkg/agent/tool_execution.go | Emits tool events with ToolCallID for correlation. |
| go.mod | Promotes atotto/clipboard to a direct dependency. |
| gaps.md | Tracks spec/ADR implementation gaps and resolution status. |
| docs/product/scratch/tui-ux-enhancements.md | Product scratch doc capturing UX enhancement plan and rationale. |
| docs/product/scratch/tui-output-formatting.md | Product scratch doc for sanitization/command output UI strategy. |
| docs/product/scratch/tui-input-alternatives.md | Product scratch doc exploring input UI variants. |
| docs/product/scratch/slash-menu-discoverability.md | Product scratch doc for command palette discoverability improvements. |
| docs/product/scratch/overlay-toast-redesign.md | Product scratch doc defining responsive overlay/toast redesign rules. |
| docs/adr/README.md | Marks additional ADRs as implemented and adds missing entries. |
| docs/adr/0052-tui-viewport-spacer-height-fix.md | Adds ADR documenting spacer height regression and fix. |
| docs/adr/0050-tui-clipboard-copy.md | Adds ADR documenting clipboard copy behavior and implementation. |
| docs/adr/0049-tui-bracketed-paste-support.md | Adds ADR documenting settings overlay paste behavior. |
| docs/adr/0048-tui-smart-scroll-lock.md | Adds ADR documenting scroll-lock behavior and implementation. |
| docs/adr/0033-notes-viewer-tui-command.md | Marks ADR 0033 as implemented. |
| docs/adr/0025-tui-package-reorganization.md | Marks ADR 0025 as implemented. |
| docs/adr/0012-enhanced-tui-executor.md | Marks ADR 0012 as implemented. |
| docs/adr/0011-coding-tools-architecture.md | Fixes ADR cross-reference link text. |
| docs/adr/0010-tool-approval-mechanism.md | Fixes ADR cross-reference link text. |
| cmd/forge/main.go | Uses shared pkg/version Version constant. |
| README.md | Updates TUI feature list and adds link to new TUI how-to guide + ADR links. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… width calculation Co-authored-by: Justin Wilkin <justin@entr.net.au>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major TUI enhancement bringing modern, polished UX to the terminal interface. This PR implements smart scroll-lock for reviewing history while the agent works, clipboard copy for conversation export, bracketed paste support for safe multi-line input, and a complete visual redesign with compact header, context-aware hints, and improved readability.
Changes
Core Features
Gto jump back and resume auto-followCtrl+Ycopies full conversation history as plain text for external useUI/UX Improvements
Ctrl+K/Ctrl+Por typing/Ctrl+L; quick latest result withCtrl+VDocumentation
Code Quality
update_input.go,update_keys.go,update_messages.goTesting
Manual Testing
forgeand start a conversation. Scroll up with arrow keys orPgUp. Verify banner appears when new content arrives. PressGto return to bottom.Ctrl+Yduring a session. Paste into external editor and verify full conversation is captured as plain text.Ctrl+,), paste multi-line text into a field. Verify it pastes safely without triggering commands.Ctrl+Kor type/and verify slash command launcher appears.Automated Testing
go test ./pkg/executor/tui/...to verify scroll-lock, viewport height, settings overlay, and message handling tests pass