v0.12.1
a maintenance release: a broad internal code-quality pass plus security and test-infrastructure hardening. no user-facing feature or keybinding changes.
security
SessionOptionnow reads session options viashow-options -qv(option name passed as data) instead of interpolating an untrusted, save-file-derived session name into a tmux#{...}format string.- save files are now validated on read: session/window names containing control characters or format-significant
#/}are rejected. - pane-capture files are written
0600(were0644) and the capture dir0700— pane scrollback can contain secrets.
fixes
- shutdown no longer races the shared control-mode client: the backend watcher is fully drained before the client closes.
- the throttle in the backend poller is now cancellable, so quitting is prompt.
Save/Restorerespect context cancellation on every progress send (a stalled consumer can no longer leak the producer goroutine).pane:joinno longer emits a trace event for a join that never happens.- multi-select id parsing unified — the previous space-splitting could corrupt names containing spaces.
internal / quality
- modernized to go 1.25 idioms (min/max, slices/maps helpers, strings.Cut, cmp.Or, sync.OnceValues, sync.WaitGroup.Go, errors.Is/Join).
- large de-duplication across the menu, ui-render, tmux-snapshot, and state-store layers; the resurrect package decomposed.
- gradient progress bars now use the vendored lipgloss blending API instead of a hand-rolled per-cell implementation.
tests
- fixed
AssertNoServerCrash, which was a silent no-op (tmux verbose logs were written outside the directory it inspected) — integration crash detection now actually works. - added the missing
TestMainteardown to the menu package and fixed a test-ordering hazard under-shuffle=on.