v2.1.2
This release fixes terminal mouse-tracking leakage on PTY disconnect, hardens panic-time terminal cleanup, and corrects two release-workflow misfires that surfaced after v2.1.1.
New Features
None
Improvements
- Centralized terminal teardown logic:
TerminalGuard::restore_terminal()ininteractive_signal.rsnow delegates toforce_terminal_cleanup()instead of carrying its own incomplete cleanup, so the panic-hook path and the normal Drop path emit identical sequences.
Bug Fixes
- Restore terminal mouse tracking state on PTY session disconnect (#190, supersedes #189): After a PTY session disconnects (normal exit, Ctrl+C, network drop, or panic), remote interactive programs (vim, tmux, htop) may have enabled mouse tracking on the local terminal. Without cleanup, the terminal remained in tracking mode and printed raw SGR escape sequences on mouse movement. All cleanup paths (
TerminalStateGuard::Drop,force_terminal_cleanup, and the panic hook viaTerminalGuard) now emit the full set of mouse-tracking-off sequences (modes 1000, 1002, 1003, 1006, 1015) plus cursor-show and alternate-screen-exit on teardown. - Make
force_terminal_cleanupsafe to call from the panic hook: switched the globalTERMINAL_MUTEXacquisition totry_lock()so the panic-hook path cannot deadlock if the panicking thread already holds the mutex, and a poisoned mutex from a previous panic no longer triggers a secondary panic viaunwrap(). The lock only serializes concurrent teardown; the underlying stdout writes anddisable_raw_modeare individually safe.
CI/CD Improvements
- Trigger Homebrew formula update only after the official release:
release.ymlnow callsupdate_homebrew_formula.ymlviaworkflow_callfrom thepublish-releasejob (which converts pre-release to official) instead ofworkflow_runfiring on every Release workflow completion (including pre-release builds).workflow_dispatchis kept for manual runs. - Prevent double-trigger of the release workflow: removed the
publishedevent type from the release workflow trigger list. The workflow was previously firing twice — once onprereleasedfromgh release create --prerelease, and again onpublishedwhenpublish-releaseconverted the pre-release to official.publish-releasealready handles that conversion, andworkflow_dispatchcovers manual runs.
Technical Details
- Added unit tests for
force_terminal_cleanup()insrc/pty/terminal.rscovering idempotency, poisoned-mutex resilience, and held-mutex resilience. Tests use localMutexinstances rather than the globalTERMINAL_MUTEXso the global state is not disturbed for other tests in the same process. - Extended the
force_terminal_cleanup()docstring to make explicit that "unsynchronized" means "without the lock" (not "skipped"), addressing the LOW-severity documentation finding from the earlier security review of #189.
Dependencies
None
Breaking Changes
None
Known Issues
None
What's Changed
Full Changelog: v2.1.1...v2.1.2