Skip to content

feat(tui): comprehensive UX uplift with smart scroll-lock, clipboard copy, and visual redesign - #74

Merged
justinwilkin merged 7 commits into
mainfrom
feat/tui-uplift
Mar 2, 2026
Merged

feat(tui): comprehensive UX uplift with smart scroll-lock, clipboard copy, and visual redesign#74
justinwilkin merged 7 commits into
mainfrom
feat/tui-uplift

Conversation

@justinwilkin

Copy link
Copy Markdown
Member

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

  • Smart Scroll-Lock (ADR-0048): Scroll up to review history without auto-scroll interference; banner notifies when new content arrives; press G to jump back and resume auto-follow
  • Clipboard Copy (ADR-0050): Ctrl+Y copies full conversation history as plain text for external use
  • Bracketed Paste (ADR-0049): Safe multi-line paste in settings overlay prevents accidental command execution
  • Visual Redesign (ADR-0051): Compact header bar with workspace/model info, context-aware hints, improved spacing, and refined color scheme

UI/UX Improvements

  • Command palette now accessible via Ctrl+K / Ctrl+P or typing /
  • Agent thinking blocks display inline with elapsed time; toggleable visibility in settings
  • Enhanced overlay styles for help, settings, diff viewer, and tool results
  • Improved viewport height calculation and spacer handling (ADR-0052)
  • Tool result history browser with Ctrl+L; quick latest result with Ctrl+V

Documentation

  • Comprehensive TUI user guide with all features and keyboard shortcuts
  • ADRs for smart scroll-lock, bracketed paste, clipboard copy, and visual redesign
  • Product documentation for TUI visual polish and UX enhancements

Code Quality

  • Refactored update logic into focused modules: update_input.go, update_keys.go, update_messages.go
  • Added extensive test coverage for scroll-lock, viewport height, settings overlay, and message handling
  • Updated README with new TUI features and capabilities

Testing

Manual Testing

  1. Smart Scroll-Lock: Run forge and start a conversation. Scroll up with arrow keys or PgUp. Verify banner appears when new content arrives. Press G to return to bottom.
  2. Clipboard Copy: Press Ctrl+Y during a session. Paste into external editor and verify full conversation is captured as plain text.
  3. Bracketed Paste: Open settings overlay (Ctrl+,), paste multi-line text into a field. Verify it pastes safely without triggering commands.
  4. Visual Polish: Observe compact header with workspace path and model. Check context hints update appropriately (e.g., "Press Ctrl+C to cancel" when waiting for input).
  5. Command Palette: Press Ctrl+K or type / and verify slash command launcher appears.

Automated Testing

  • Run go test ./pkg/executor/tui/... to verify scroll-lock, viewport height, settings overlay, and message handling tests pass
  • Verify no regressions in approval workflow tests

entr-agent and others added 6 commits February 26, 2026 18:44
… 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>
Copilot AI review requested due to automatic review settings March 2, 2026 09:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 []DisplayMessage history 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.

Comment thread pkg/executor/tui/update_keys.go Outdated
Comment thread pkg/executor/tui/helpers.go Outdated
Comment thread pkg/executor/tui/view.go
Comment thread pkg/executor/tui/events.go
Comment thread pkg/executor/tui/overlay/help.go
Comment thread pkg/executor/tui/overlay/context.go
Comment thread pkg/executor/tui/messages.go
Comment thread pkg/executor/tui/view.go
… width calculation

Co-authored-by: Justin Wilkin <justin@entr.net.au>
@justinwilkin
justinwilkin merged commit 818697f into main Mar 2, 2026
5 checks passed
@justinwilkin
justinwilkin deleted the feat/tui-uplift branch March 2, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants