Goal
Remove the replace github.com/charmbracelet/ultraviolet => github.com/dgageot/ultraviolet ... directive and use the official upstream revision already required by go.mod:
github.com/charmbracelet/ultraviolet v0.0.0-20260811164956-006e29f97886.
Why this is now safe
The current replacement is pinned to github.com/dgageot/ultraviolet v0.0.0-20260313154905-9451997d56b6, reintroduced for the macOS/iTerm2 emoji-rendering regression tracked by #2089 (after the earlier #1233 issue).
A source comparison of the fork commit 9451997d56b6 against the exact upstream target 006e29f97886 found that upstream now contains a functionally equivalent or improved solution for every fork change:
- correct handling of wide-cell/emoji placeholders, with upstream regression coverage;
- iTerm2/wcwidth cursor-drift handling, improved via wide-line reanchoring and grapheme-width negotiation;
- safe colored-blank erase handling through explicit pen updates;
- an additional upstream fix for Kitty extended-key release/repeat events that remains absent in the frozen fork.
Docker-agent direct usages (DEC 2031 color-scheme events, EventDecoder, and NewCancelReader) have no identified behavioral incompatibility. Both modules have compatible dependency sets, MIT licensing, and upstream's Go version requirement is compatible with docker-agent's go 1.26.5.
Sandboxes precedent
/Users/arnaud/Workspace/Dev/docker/sandboxes commit cec304d2f (Stop using the ultraviolet fork, 2026-06-25) removed its dgageot replacement without a later revert or reported Ultraviolet regression. This is supporting evidence only: sandboxes has no direct Ultraviolet imports and does not independently validate docker-agent's iTerm2 path.
Implementation plan
- Add targeted regression coverage for wide emoji/background rendering, and establish a green baseline against the current fork.
- Run a manual blocking check of the TUI on macOS + iTerm2 with real emoji content; the original regression only had manual visual confirmation.
- Remove the
replace directive, retain the existing official upstream requirement, run go mod tidy, and update go.sum.
- Remove the obsolete ultraviolet entry from
.golangci.yml's gomoddirectives.replace-allow-list.
- Validate with
task lint, task test, task build, native Windows CI, and the license check.
Rollback
If a gate fails, revert only the replacement-removal change: restore the replace directive, matching go.sum updates, and the linter allow-list. The regression coverage can remain.
Open decision
Assign a maintainer/tester to perform the required macOS+iTerm2 manual check before the replacement-removal PR merges.
Goal
Remove the
replace github.com/charmbracelet/ultraviolet => github.com/dgageot/ultraviolet ...directive and use the official upstream revision already required bygo.mod:github.com/charmbracelet/ultraviolet v0.0.0-20260811164956-006e29f97886.Why this is now safe
The current replacement is pinned to
github.com/dgageot/ultraviolet v0.0.0-20260313154905-9451997d56b6, reintroduced for the macOS/iTerm2 emoji-rendering regression tracked by #2089 (after the earlier #1233 issue).A source comparison of the fork commit
9451997d56b6against the exact upstream target006e29f97886found that upstream now contains a functionally equivalent or improved solution for every fork change:Docker-agent direct usages (DEC 2031 color-scheme events,
EventDecoder, andNewCancelReader) have no identified behavioral incompatibility. Both modules have compatible dependency sets, MIT licensing, and upstream's Go version requirement is compatible with docker-agent'sgo 1.26.5.Sandboxes precedent
/Users/arnaud/Workspace/Dev/docker/sandboxescommitcec304d2f(Stop using the ultraviolet fork, 2026-06-25) removed its dgageot replacement without a later revert or reported Ultraviolet regression. This is supporting evidence only: sandboxes has no direct Ultraviolet imports and does not independently validate docker-agent's iTerm2 path.Implementation plan
replacedirective, retain the existing official upstream requirement, rungo mod tidy, and updatego.sum..golangci.yml'sgomoddirectives.replace-allow-list.task lint,task test,task build, native Windows CI, and the license check.Rollback
If a gate fails, revert only the replacement-removal change: restore the
replacedirective, matchinggo.sumupdates, and the linter allow-list. The regression coverage can remain.Open decision
Assign a maintainer/tester to perform the required macOS+iTerm2 manual check before the replacement-removal PR merges.