Replace internal/ansi with charmbracelet/x/vt emulator#9
Merged
Conversation
The hand-rolled ANSI handling (regex stripping, virtual 2D grid, heuristic frame detection, terminal responder) breaks on complex TUI apps. Replace the entire internal/ansi package with a proper VT terminal emulator. - TUI sessions now use vterm.Screen wrapping a thread-safe VT emulator; PTY output feeds the emulator directly, no raw byte storage needed - Non-TUI ANSI stripping uses vterm.Strip with two paths: fast regex for simple output, temporary VT emulator for cursor-positioned content - Terminal query responses (DA1/DA2/DSR) handled by emulator natively via ReadResponses bridge, replacing hand-rolled TerminalResponder - Atomic version counter replaces byte-count change detection for TUI - wait.ForOutput gains FullOutput flag for TUI-aware pattern matching - Delete internal/ansi/ entirely (5 files, ~2900 lines removed)
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.
Enhancement
The
internal/ansi/package uses hand-rolled regex stripping, a virtual 2D character grid, heuristic-based TUI frame detection, and a manual terminal responder. This works for common cases but breaks on complex TUI apps with cursor-addressed painting, alt screen interactions, and grapheme clusters. Thecharmbracelet/x/vtlibrary is a proper VT terminal emulator in pure Go that handles all of this correctly.Solution
TUI sessions use a
vterm.Screenwrapper aroundcharmbracelet/x/vt's thread-safe emulator. PTY output feeds the emulator directly (no raw byte storage). Reads return the current screen state viaRender()(ANSI-styled) orString()(plain text). An atomic version counter replaces byte-count change detection. Terminal capability queries (DA1, DA2, DSR) are handled natively by the emulator, with aReadResponsesgoroutine bridging responses to the PTY master. Non-TUI ANSI stripping uses a two-path approach: fast regex for simple output, temporary VT emulator for cursor-positioned content.Changes
New package:
internal/vterm/screen.go: VT emulator wrapper with version counter and terminal query response bridgestrip.go: ANSI stripping with fast regex path and emulator fallback for cursor sequencesscreen_test.go,strip_test.go: comprehensive test coverage (60+ strip test cases)TUI session handling (
internal/daemon/server.go):vterm.Screeninstead of FrameDetector + TerminalRespondercaptureOutputfeeds emulator directly for TUI, raw storage for non-TUIhandleRead,handleSnapshot,handleSearch,handleSizeall branch on TUI modeWait/settle adaptation (
internal/wait/wait.go):FullOutputflag treats output as full screen content rather than growing bufferCall site updates (
cmd/,internal/mcp/):ansi.Strip()calls replaced withvterm.StripDefault()InfoResponseincludesTUIModefield for client-side TUI detectionDeleted:
internal/ansi/(5 files, ~2900 lines)clear.go: Virtual 2D grid rendererstrip.go: Regex-based ANSI strippingresponder.go: Manual terminal query responderNotes
Testing
Validated against 18 TUI apps across 6 categories (170/171 tests passed):
Net code reduction
20 files changed, +729, -3263 (net -2534 lines)