Releases: Aaronontheweb/termina
Termina 0.13.0
Release Notes — Termina 0.13.0
Release date: 2026-06-17
Features
Gradient primitives, GraphNode, and ProgressBarNode (#298) — Jan (@st0o0)
A major visual components update with gradient coloring support across the board.
Color.Lerp— Linear RGB interpolation between two colorsGradient— Immutable multi-stop gradient with color stop interpolationGraphNode— Reactive, self-invalidating layout node for live scrolling graphs in four styles:Blocks— Filled block columns (▁▂▃▄▅▆▇█)Outline— Top edge only, sparkline feelBraille— Double vertical resolution using braille charactersAscii— ASCII fallback for terminals without Unicode- All styles support gradient coloring by row height
- Configurable timer interval or data-driven updates
ProgressBarNode— Single-row progress bar with:- Gradient fill across the bar width
- Configurable fill/empty characters and colors
- Optional formatted label (e.g.,
"{0:P0}"for percentage)
- Full API docs and interactive gallery demo
Color and icon support for toast notifications (#296) — Jan (@st0o0)
Toast notifications can now be customized with colors, icons, and positions.
ToastOptions.Color— Optional color override for toast borderToastOptions.Icon— Optional icon string displayed in the toast- Built-in presets:
- Success — Green border, ✓ icon, Top Right
- Error — Red border, ✗ icon, Top Right
- Warning — Yellow border, ⚠ icon, Top Center
- Info — Cyan border, ℹ icon, Bottom Right
- Custom — Magenta border, 🚀 icon, Bottom Center
- Default — No overrides (unchanged behavior)
Bug Fixes
Parse CSI Z (backtab) as Shift+Tab (#297) — Jan (@st0o0)
In legacy terminal mode, the CSI Z escape sequence (ESC [ Z) was silently dropped. It now correctly maps to Shift+Tab, restoring expected backward-tab behavior.
ScrollableContainerNode ignoring bounds.Y (#301)
ScrollableContainerNode was ignoring bounds.Y during layout, causing it to overwrite content above the scrollable area. The layout calculation now correctly respects vertical bounds.
Docs
- Embedded animated GIF demos for Toast and Graph/Progress components (#302)
Contributors
Thanks to Jan (@st0o0) for these contributions!
Termina 0.12.1
0.12.1 June 11th 2026
New Features:
- WithFooter and WithFooterColor API on ModalNode (#292)
- New
WithFooter(string)andWithFooterColor(Color)builder methods onModalNodefor adding a footer line to modal dialogs - Footer renders on the bottom border line with automatic text truncation to fit modal width
- Optional color customization via
WithFooterColor— falls back to reset terminal colors when not specified - Demonstrated with a TodoListPage demo showcasing modals with actionable footers
- New
Documentation:
- Updated ModalNode component docs with WithFooter API reference and usage example (#293)
Termina 0.12.0
0.12.0 June 9th 2026
New Features:
- FilePickerNode for interactive file/folder selection (#284)
- New layout node providing an interactive terminal-based file picker with breadcrumb navigation, fuzzy filtering, and configurable selection modes (Files, Directories, or All)
- Supports both single-select and multi-select modes with Space/Enter keyboard shortcuts
- Hidden file toggle and glob-based file filters via
FileSystemName.MatchesSimpleExpression IFileSystemProviderabstraction enables deterministic unit testing of file picker behavior- Includes a Gallery demo page demonstrating file picker and folder picker side by side
Dependency Updates:
- Updated R3 reactive framework from 1.3.0 to 1.3.1 (#282)
Termina 0.11.1
0.11.1 June 8th 2026
Bug Fix — DECCKM arrow disambiguation:
- CSI A/B no longer misrouted as wheel events in terminals that ignore DECCKM (#280)
CsiFunctionalDecoderunconditionally treated bare CSI A/B as alternate-scroll wheel events when Kitty was inactive, assuming the terminal honored DECCKM (?1h) and sent real arrows as SS3. Terminals that ignore DECCKM (VHS, some PTY wrappers) keep sending arrows as CSI form, so arrow navigation broke silently.- Added a
DeckmConfirmedflag toTerminalModeContext. The parser sets it when it first sees an SS3 arrow key — proof the terminal honored DECCKM.CsiFunctionalDecoderonly routes CSI A/B as wheel after this confirmation; until then they are keyboard arrows. - Narrowed the DECCKM confirmation to SS3 arrow keys only (A/B/C/D). SS3 F1-F4 (P/Q/R/S) use the SS3 encoding as a VT220 legacy independent of DECCKM and no longer false-positive the detection.
Termina 0.11.0
0.11.0 June 7th 2026
Terminal Input Reliability and Native Copy/Paste Support
- Added an internal semantic input pipeline that decodes terminal protocol input before adapting back to Termina's existing public input events.
- Extracted protocol-specific decoders for SGR mouse input, SS3 keyboard input, CSI functional keys, legacy CSI keyboard sequences, Kitty keyboard formats, bracketed paste, and unknown-sequence fallback handling.
- Preserved the existing public input surface:
KeyPressed,MouseScrollEvent,PasteEvent, andResizeEvent. - Expanded Linux terminal conformance coverage for baseline PTY, tmux, kitty, and kitty plus tmux scenarios.
- Added real terminal selection, explicit clipboard copy, and paste-into-focused-input coverage to validate native terminal clipboard workflows.
- Hardened file trace disposal so buffered trace events drain deterministically.
Upgrade Notes
- Existing applications continue using
LegacyMouseTrackingby default. - Applications that need native terminal text selection should opt into raw input plus alternate-scroll.
- Built-in text inputs handle bracketed paste automatically.
- Custom focusable input components should implement
IPasteReceiverto receive focused paste content. - For tmux, enable passthrough with
set -g allow-passthrough on. - When tmux mouse mode captures selection, use Shift-drag plus the terminal copy shortcut, usually
Ctrl+Shift+C. - See the 0.11.0 upgrade advisory for the recommended runtime configuration and tmux workflow.
Termina 0.10.2
0.10.2 May 30th 2026
Bug Fixes — Input parsing, rendering, and tracing:
-
Unrecognized CSI tilde sequences now flush correctly (#232)
- Fix for [5~ (PgUp), [6~ (PgDn) and other bracketed CSI sequences being silently swallowed by the escape sequence parser. These were causing the parser to stay stuck in InBracketSequence mode, blocking all subsequent input. Sequences now flush as raw KeyPressed events for application handling.
-
Legacy CSI tilde key decoding — Maps legacy CSI tilde key sequences to semantic ConsoleKey events while preserving unknown tilde raw flush behavior.
-
TextInputNode placeholder background color fixed (#233)
- Placeholders now render with the correct background fill against the configured Background color instead of inheriting the terminal's default.
-
FileTraceListener UTF-8 encoding fixed (#234)
- Switched from Encoding.Default to UTF-8 (without BOM), preventing ArgumentException on Unicode characters (e.g., ➭ U+27AD) and the resulting consumer task faults, channel fill, and OOM issues in trace output.
- DisposeAsync drain order fixed — _disposed flag is now set after waiting for the consumer to drain, preventing buffered events from being skipped and leaving trace files empty.
Test Fixes
- SelectionItemContent invalidation test made deterministic (#236)
Termina 0.10.1
0.10.1 May 24th 2026
Bug Fixes — StreamingTextNode thread-safety and disposal hardening:
-
RebuildBuffercorrectly inserts a newline before block segments afterClear()(#224)- Pre-fix, after
Clear()resetHasContentOnCurrentLine, the first re-added block segment skipped its leading newline during rebuild, causing block content to collide with prior content on the same line. - Moves the block-newline check inline, evaluated after prior elements are re-appended so the buffer state reflects the in-progress reconstruction.
- Pre-fix, after
-
Animation callbacks now hold
_contentLock(#225)- Animation
Invalidatedcallbacks fromIAnimatedTextSegment(e.g.SpinnerSegmenton the R3 timer thread) previously calledRebuildBufferwithout locking, racing with public mutators (Append/AppendTracked/Remove/Replace/Clear/Dispose) that all hold the lock. Symptoms ranged fromInvalidOperationException("Collection was modified") on theforeachinsideRebuildBufferto torn buffer state andObjectDisposedExceptionifDispose()ran while a callback was queued behind the lock. - Funnels both callback sites through a single
OnAnimationInvalidated()helper that takes_contentLock, checks a new volatile_disposedflag, then runsRebuildBuffer+ notification safely. Dispose()is now idempotent and sets_disposed = truefirst so in-flight callbacks bail before touching_invalidated.
- Animation
-
NotifyChangedhardened against post-Dispose race (#227)- Every public mutator released
_contentLockbefore callingNotifyChanged(), so a racingDispose()could complete_invalidated.OnCompleted()/Dispose()in the gap and the mutator'sOnNextwould throwObjectDisposedException. Same shape applied to deliberate use-after-dispose calls. NotifyChangednow reads_disposedand try/catchesObjectDisposedException.OnAnimationInvalidatedroutes throughNotifyChangedso the animation path inherits the same hardening.
- Every public mutator released
Test improvements (#226):
- Restructured the
Replacethread-safety stress test so the ticker always fires on a live, permanently-tracked spinner (was mostly hitting an already-disposed segment after eachReplace). - Added a reflection-based test that directly exercises the
_disposedbelt-and-suspenders guard insideOnAnimationInvalidated(the originalAfterDisposetest was passing for the wrong reason because subscription teardown was hiding the in-flight-callback path).
Termina 0.10.0
0.10.0 May 24th 2026
New Features:
-
ReactivePage.InvalidateLayout()for runtime layout rebuilds (#220)- New
protected void InvalidateLayout()method onReactivePage<TViewModel>that discards the cached layout tree and rebuilds viaBuildLayout() - Solves the problem of layout values "baked in" at first navigation time (e.g.
SizeConstraint.Autorecords) being permanently frozen — consumers can now trigger a full rebuild when external state changes (terminal resize, etc.) - Preserves user subscriptions, key bindings, and focus when the target node survives the rebuild
- Exception-safe: builds the new tree first, then atomically swaps — if
BuildLayoutthrows, the existing layout is left intact - Includes 17 comprehensive lifecycle tests covering disposed-guard, re-entrancy, idempotent dispose, and subscription cleanup
- New
-
Alternate-scroll wheel mode with Kitty keyboard protocol disambiguation (#215)
- Replaces SGR mouse tracking with
?1007halternate-scroll mode for wheel events, combined with Kitty keyboard protocol (report_all_keys) for true key disambiguation - On Ghostty, kitty, WezTerm, foot, and iTerm2 ≥ 3.5: scroll-wheel scrolls
IScrollablecomponents, arrow keys act as arrows even in always-focused text inputs, and native text selection (click-drag) still works - New opt-in
TERMINA_UNIX_RAW_INPUT=1environment variable enables raw Unix stdin for the protocol to work - Dual Ctrl+C quit pattern replaces per-demo Ctrl+Q convention
- Replaces SGR mouse tracking with
-
Harden alternate-scroll rollout and document runtime input modes (#217)
- Restored legacy mouse tracking as the framework default — alternate-scroll is now opt-in via explicit app configuration
- Moved Kitty keyboard negotiation into
TerminaApplicationwith safer raw-input fallback on non-interactive consoles - Added comprehensive website docs covering runtime input modes, raw input, alternate-scroll, Kitty flags, and tmux passthrough
Bug Fixes:
ResizeEventnow forwards toViewModel.Inputobservable (#219)- Fixed
TerminaApplication.ProcessEventswallowingResizeEventvia earlyreturn;— the event now correctly falls through to_inputSubject.OnNext(inputEvent) - Pages and ViewModels subscribing via
ViewModel.Input.OfType<ResizeEvent>()now receive resize notifications as intended - Enables consumers to recompute width- or height-sensitive layout on terminal resize
- Fixed
Termina 0.9.0
0.9.0 May 18th 2026
New Features:
-
SelectionListNode pre-selection via
WithHighlightedIndex()(#213)- New fluent method
WithHighlightedIndex(int index)allows callers to pre-select a highlighted item inSelectionListNodeby index at construction time - Useful for dialogs that should open with a sensible default already highlighted
- New fluent method
-
SelectionListNode full-height mode via
WithFillHeight()(#210)- New fluent method
WithFillHeight()makesSelectionListNodeexpand to fill all available vertical space - Enables list-first layouts where the selection list is the primary content of the page
- New fluent method
Bug Fixes:
-
Fixed navigation data race that crashed pages on ARM64 (#212)
- Resolved a race condition in the navigation system that caused page crashes on ARM64 hardware
- Affects any multi-core ARM64 deployment (Apple Silicon, AWS Graviton, Raspberry Pi, etc.)
-
Fixed garbled output when the terminal does not start in UTF-8 (#204)
AnsiTerminalno longer cachesConsole.Out. SettingConsole.OutputEncodingreplacesConsole.Outwith a newTextWriter, so a cached reference could be left bound to a stale, non-UTF-8 encoding — rendering Unicode box-drawing characters asU+FFFD. The output writer is now resolved on every flush.- Consolidated UTF-8 output-encoding setup into a single owner (
ConsoleEnvironment.EnsureUtf8Output, invoked by the platform console) instead of three separate call sites. - Original problem diagnosed by @logical-intent in #204 / #205.
Security:
- Fixed CVE-2026-40894: pinned OpenTelemetry.Api to 1.15.3 (#209)
- Pinned
OpenTelemetry.Apito 1.15.3 to address a security vulnerability in earlier versions
- Pinned
Termina 0.8.0
0.8.0 March 17th 2026
New Features:
-
CopyableTextNode with terminal clipboard support (#179)
- New
CopyableTextNodecomponent for selectable, copyable text with keyboard-driven selection - Configurable copy key bindings via
CopyKeyBinding - Terminal clipboard integration using OSC 52 escape sequences with automatic tmux transport fallback
IClipboardService/IClipboardTransportinterfaces for extensible clipboard backendsTerminalClipboardServiceregistered automatically viaAddTermina()in DI
- New
-
Toast notification system (#179)
- New
ToastOverlayNodefor non-blocking in-app notifications IToastService/ToastServicefor programmatic toast dispatch- Configurable
ToastPosition(TopRight, TopLeft, BottomRight, BottomLeft) andToastOptions CopyFeedbackModecontrols copy success feedback: toast overlay or inline indicator
- New