Skip to content

Releases

v0.11.0

Choose a tag to compare

@cwt cwt released this 30 Oct 09:22

szn v0.11.0

84 commits since v0.10.0. 1,082 tests passing on both Zig 0.16.0 and Zig 0.17.0.


Headline: Dual Zig 0.16/0.17 Toolchain Support, Lifecycle Memory Reclamation (#542), Lao Script Reflow, Linux Packaging, and 61-Bug Stability Sweep

v0.11.0 is a major stabilization and portability release. It establishes verified dual-compiler support across both Zig 0.16.0 and Zig 0.17.0 from a unified source tree, overhauls session and pane memory lifecycles to eliminate unbounded arena accumulation (#542), expands advanced text reflow and cluster integrity to Lao script, introduces native Linux RPM packaging (Fedora / EL), modernizes the benchmarking suite, and resolves 61 bug tracker entries (#502–#562) spanning terminal emulation fidelity, alt-screen transitions, sixel graphics containment, and SafeAllocator memory safety.


Key Improvements & Features

1. Dual Zig 0.16.0 & 0.17.0 Toolchain Support

  • Single Source Tree Compatibility: The entire codebase compiles and passes its full 1,082-test suite cleanly under both Zig 0.16.0 and Zig 0.17.0.
  • Unified Standard Library Subset: Standardized on APIs present in both toolchains (bufPrintSentinel, fieldNames, mem.zeroes, .empty) and confined release-specific shims strictly to src/compat.zig and build.zig.
  • SafeAllocator Hardening (Bug #562): Resolved subtle test use-after-free hazards that were exposed when Zig 0.17 transitioned std.testing.allocator from DebugAllocator to the unmapping SafeAllocator.

2. Lifecycle Memory Architecture Overhaul (Bug #542)

  • Elimination of Vestigial Session Arena: Removed unbounded non-LIFO arena allocation in Session and cmd/ dispatch.
  • Dynamic Allocation Reclamation: Routed format expansions, option strings, and grid buffers through backing allocators with strict deallocation upon session and pane termination, preventing memory creeping during long-running sessions.
  • Atomic Concurrency & Descriptor Safety (Bugs #504, #510): Synchronized lazy libthai loading with atomic state transitions and made logging descriptor writes atomic.

3. Terminal Emulation Fidelity & VT Completeness (Bugs #523–#526, #546–#552)

  • String Terminator (ST) Compliance (#549): Implemented complete 7-bit (ESC \) and 8-bit (0x9C) ST termination handling across SOS, PM, APC, and OSC sequences.
  • PTY Keypad & Modifier Preservation (#551): Preserved extended keypad modes and modifiers in writeKeyToPty.
  • Modal Escape Handling (#552): Armed escape-time in modal views to ensure rapid, predictable Escape key dispatch.
  • Origin Mode & Navigation Fixes (#523–#526): Wired DECOM origin mode with saturating coordinate clamping, corrected NEL (0x85) column resets, and guarded CBT modulo calculations.
  • Alt-Screen State Preservation (#546, #550): Preserved scroll regions (DECSTBM) and saved main grid contents across alternate screen entries and exits.

4. Advanced Text Reflow, Thai & Lao Typography (Bugs #502–#505, #541, #559)

  • Lao Script Expansion: Extended syllable cluster integrity, zero-width mark attachment, and $O(1)$ backtrack reflow to Lao script (U+0EB0–U+0ECD), including Lao SARA AM (U+0EB3) diff repair and Yamakkan width metrics.
  • Compound Vowel Cluster Protection: Hardened Thai reflow boundaries around compound vowels (เ-าะ patterns) and spacing marks (ๆ, ฯ, ์).
  • Quote Protection Heuristics: Added boundary heuristics preventing dangling opening and closing quotes across pane reflows.

5. Packaging & Benchmarking Infrastructure

  • Native RPM & COPR Packaging: Added szn.spec, Copr build hooks, and multi-distro containerized build scripts (build_all.sh) for Fedora 44/45 and Enterprise Linux 9/10.
  • Hyperfine 2.0 Benchmarking & Report Extraction: Updated benchmark scripts for Hyperfine 2.0 shell syntax and extracted structured reporting into a typed, verified tool at tools/bench_report.py.

Testing & Quality Assurance

Metric v0.9.1 v0.10.0 v0.11.0
Total Passing Tests 970 1,032 1,082
New Regression Tests 11 62 50
Open Bugs in Tracker 0 0 0
Bugs Resolved in Cycle 1 (#440) 61 (#441–#501) 61 (#502–#562)
Binary Size (stripped, x86_64 Linux) ~831 KB ~831 KB 1,053,312 bytes (~1,029 KB)
Binary Size (stripped, aarch64 macOS) ~685 KB ~685 KB 834,864 bytes (~815 KB)
Build Status All passing All passing Clean under Zig 0.16.0 & 0.17.0

v0.10.0

Choose a tag to compare

@cwt cwt released this 26 Sep 18:31

szn v0.10.0

62 commits since v0.9.1. 1,032 tests passing.


Headline: Hot-Path Performance Architecture, VS16 Emoji Promotion, Hardened Sixel Engine, and 61-Bug Stability Sweep

v0.10.0 is a milestone release delivering substantial performance improvements across terminal input processing and rendering pipelines, introducing configurable Unicode Variation Selector 16 (VS16) emoji presentation width control, hardening the Sixel graphics engine with transactional lifecycle guarantees, and resolving 61 bug tracker entries (#441–#501) across memory safety, IPC protocol validation, process lifecycles, and terminal emulation fidelity.


Key Improvements & Features

1. Hot-Path Performance Architecture (#476, #478–#483)

  • Chunked Input Parser Dispatch (advanceBatch): Replaced byte-by-byte virtual method dispatch loops in InputParser with a vectorized batching scanner (advanceBatch). Contiguous runs of printable ASCII characters are scanned in a tight loop and written directly to the screen grid in single operations, dramatically reducing dispatch overhead during heavy terminal output (e.g. cat, compiler logs, find).
  • Fast-Path ASCII Streaming: Optimized Screen.writeStr to stream uninterrupted ASCII byte runs directly into grid cells without per-codepoint decoding or branch evaluation.
  • O(1) Pane Validity & Tree-Walk Elimination: Replaced expensive recursive layout tree traversals on every terminal output chunk with an $O(1)$ pane liveness bit (isPaneValid), eliminating CPU bottlenecks when running multiple active panes.
  • Batched Render Frames & SGR Generation: Replaced per-space writes and cell-by-cell escape formatting with contiguous run-length writes and pre-buffered frame chunks, reducing system calls and IPC payload overhead during screen repainting.
  • Arena-Backed Format Buffering: Replaced heap allocations during status bar and format string expansion with reusable arena allocations.

2. Unicode VS16 Emoji Presentation Width Option

  • variation-selector-always-wide Configuration: Added the variation-selector-always-wide boolean option (default: off), configurable via ~/.szn.conf or set-option -g variation-selector-always-wide on.
  • VS16 Promotion Support: When enabled, single-width base characters followed by Unicode Variation Selector 16 (U+FE0F) are promoted to 2 cells with a dedicated padding cell, matching modern terminals (e.g. Kitty, Alacritty) that expand emoji presentation sequences.
  • Full Engine Synchronization: Synchronized width promotion across Screen.writeChar, status measurement, copy mode selection, and TTY output rendering.

3. Sixel Graphics Subsystem Hardening (#454, #464, #473, #491–#493, #501)

  • Strict Containment Verification: Replaced unchecked pixel dimension math with saturating ceiling division. Images exceeding pane cell boundaries are discarded early to avoid spurious grid scrolling and display corruption (#464).
  • Scroll-Region Bound Anchor Shifting: Constrained shiftSixelAnchors to only adjust images intersecting active scroll regions (DECSTBM), preventing off-region graphics from drifting during partial scrollback (#492).
  • Marker Cell Purging (clearSixelMarkerCells): Erasing screen areas (ED 0, ED 1, ED 2) explicitly purges surviving sixel marker cells so stale IDs do not linger across screen repaints (#493).
  • Transactional Placement Contract & Zero-Leak Rollback: placeSixelImage takes strict ownership of DCS byte buffers; on any allocation failure or scroll error, image memory is immediately freed, refcounts and slot pointers are zeroed, and any partially-written marker cells are rolled back (#501).
  • Refcount Preservation on Emoji Promotion: Preserved sixel image refcounts when base cells are promoted or modified by subsequent VS16 wide characters (#491).

4. Memory Safety, Pointer Stability, & IPC Integrity (#448–#450, #455, #458, #459, #471, #472, #475, #490, #496, #499)

  • Stable Display Client Pointer Lifetimes: Converted server display_clients to ArrayList(*DisplayClient), ensuring pointer stability across dynamic client connections, disconnections, and list resizes (#450).
  • Bounded OSC 52 Clipboard Handling: Capped OSC 52 clipboard sequence buffers at 1 MiB to prevent heap exhaustion and denial-of-service from rogue inner applications (#490).
  • Wire Message Dimension Clamping: Validated and clamped cell_size pixel dimensions to valid ranges ([1, 1024]), rejecting corrupt or malicious packets from crashing the server (#496).
  • Command Output Buffer Bounds: Prevented oversized command response payloads from killing attached display clients (#475).
  • Allocator Ownership Clarification: Removed redundant allocator arguments from InputParser.deinit, ensuring internal DCS/OSC buffers are freed using screen.allocator consistently without risking cross-allocator heap corruption (#499).
  • History Ring Shrink Hardening: Blanked freed history line pointers on ring reduction so subsequent OOM conditions cannot trigger double-free crashes (#455).

5. Terminal Emulation, Key Handling & Process Lifecycle (#486, #487, #489, #495, #498, #500)

  • Race-Free Process Reaping: Pty.deinit reaps child processes before issuing SIGKILL, eliminating PID-reuse race conditions and avoiding zombie processes (#486).
  • Daemon Stdio Redirection: Daemon fork children safely redirect standard descriptors (0, 1, 2) to /dev/null without double-closing descriptor 0 (#487).
  • Kitty Keyboard Protocol Release Filtering: Discarded Kitty extended keyboard release events (:3) to prevent accidental double-inputs in TUIs (#489).
  • Raw Mode Failure Diagnostics: Interactive client startup reports explicit diagnostic errors and exits with non-zero status if setting raw terminal mode fails (#498).
  • Full-Height Rendering Without Status Bar: Fixed renderContent to render up to full terminal height (h = @min(screen.grid.height, self.sy)) when the status bar is disabled (#495).
  • Non-SGR Attribute Masking: Masked out internal non-SGR marker bits in Term.setAttributes to prevent bare escape resets and color cache desynchronization (#500).

Testing & Quality Assurance

Metric v0.9.0 v0.9.1 v0.10.0
Total Passing Tests 959 970 1,032
New Regression Tests — 11 62
Open Bugs in Tracker 0 0 0
Bugs Resolved in Cycle 44 (#395–#439) 1 (#440) 61 (#441–#501)
Build Status All passing All passing Clean under Zig 0.16.0 (Debug, ReleaseSafe, ReleaseFast)

v0.9.1

Choose a tag to compare

@cwt cwt released this 26 Sep 18:30

szn v0.9.1

2 commits since v0.9.0. 967 tests passing.


Headline: Hotfix for Window Status Option Routing & Real-Time Status Invalidation

v0.9.1 is a targeted hotfix release addressing configuration routing, status-line cache freezing, and character alignment issues affecting window-status-format and window-status-current-format (Bug #440).


Key Improvements & Bug Fixes

1. Global Window Option Routing & Fallback (#440)

  • Unscoped set -g Fallback: When configuring options with set -g (or bare set) in config files or via CLI without explicit -s / -w flags, option resolution tries session options first; on error.UnknownOption, it seamlessly falls back to window options. Directives such as set -g window-status-format '#I:#W' and set -g window-status-current-format '#I:#W#F' now configure correctly instead of being dropped.
  • Dedicated set-window-option / setw Command: Added native support for set-window-option / setw in both szn.conf configuration files and the interactive CLI command table (bringing total available commands to 49).

2. Real-Time Status Cache Invalidation & Zero-Lag Triggers (#440, #441, #442)

  • Comprehensive State Change Invalidation: Fixed status cache freezing across all interactive terminal operations. The status line is now immediately invalidated and redrawn on auto-rename process changes (getForegroundProcessName), OSC 0/2 window title sequences (windowTitleCallback), active pane switches (select-pane, arrow keys, mouse focus clicks), pane splits/kills/swaps, window lifecycle operations (new-window, kill-window, rename-window), and IPC command dispatches.
  • Zero-Latency Foreground Process Detection via PGID: Added lightweight tcgetpgrp foreground process group ID change detection (last_foreground_pgid), instantaneously querying the foreground process name on the very first frame of execution or exit (0 ms delay) without burning CPU cycles while the process is running.

3. Single-Quote Comment & Format String Handling (#440)

  • Single Quotes in Config Files: Updated stripInlineComment() and parseValue() in src/cfg.zig to support single-quoted format strings ('#I:#W'). Embedded # characters inside single quotes are no longer misinterpreted as inline comment delimiters.

4. Per-Window Status Format Overrides (#440)

  • Per-Window Format Evaluation: Status line rendering now extracts format options (window-status-format, window-status-current-format) per individual window instead of applying the active window's format globally to all windows.

5. Wide Character Cell Width Truncation (#440)

  • Cell-Width Aware Truncation: Fixed truncateVisible() in src/status.zig to measure character cell width via char_width.charWidth(), matching visibleLen() and preventing half-cell splits or column desync when displaying wide CJK characters and emojis in the status bar.

Testing & Quality Assurance

Metric v0.9.0 v0.9.1
Total Passing Tests 959 970
New Regression Tests — 11
Open Bugs in Tracker 0 0
Build Status Debug & ReleaseSafe Debug, ReleaseSafe & ReleaseFast passing

v0.9.0

Choose a tag to compare

@cwt cwt released this 31 Aug 05:48

szn v0.9.0

56 commits since v0.8.2. 959 tests passing.


Headline: Configurable Scrollback History, Zero-Allocation Ring Buffer, Runtime Log Control, and a 44-Bug Sweep

v0.9.0 is a major feature, performance, and reliability release. It introduces configurable per-pane scrollback history limits (history-limit) powered by a circular ring-buffer deque with zero-allocation steady-state line recycling, dynamic runtime log level control via the SZN_LOG environment variable, robust command-line argument quoting and escape parsing, extended terminal input compatibility (kitty keyboard normalization, DECSET 1003 mouse_any, alternate-screen mouse wheel arrow forwarding), and closes 44 bug entries (#395–#439) across memory safety, rendering, and IPC dispatch.


Key Improvements & Features

1. Configurable Scrollback History & Zero-Allocation Ring Buffer (#360, #361)

  • Configurable history-limit Option: Added history-limit session option (default: 2000, min: 0, max: 1000000) configurable via ~/.szn.conf / ~/.tmux.conf or dynamically at runtime using szn set-option -g history-limit <N>.
  • Circular Ring-Buffer Deque: Rewrote the scrollback history backend from an unbounded linear array into a fixed-capacity circular ring deque (GridLine circular indexing).
  • Line Cell Buffer Recycling: Evicted history lines at the ring boundary have their cell buffers recycled into the new line entering the bottom of the screen. Steady-state scrolling is now 100% zero-allocation, preventing session arena growth.
  • In-Place Grid Recycling: Added Pane.saveGrid and updated restoreSavedGrid to recycle visible line buffers in-place when dimensions match, eliminating multi-megabyte heap churn during clock-mode and choose-buffer mode toggles.
  • Dynamic Capacity Scaling: Implemented Grid.setHistoryLimit to dynamically resize active ring buffers across running panes, supporting instant eviction on limit reduction and linear normalization on expansion.

2. Runtime Log Level Control (SZN_LOG)

  • Environment Variable Control: Added SZN_LOG environment variable support (debug, info, warn, err) to control log verbosity at runtime without recompiling or modifying config files.
  • Diagnostic Demotion: Demoted high-frequency routine diagnostic messages from .info to .debug, keeping standard operational logs clean and informative.

3. Command Line & Configuration Parser Fidelity

  • Argv Quote & Escape Handling (#436): Implemented full argument tokenization in cmd.parse supporting single quotes ('...'), double quotes ("..."), and backslash escapes (\ ). Complex commands such as bind-key X "split-window -h; select-pane -R" now parse and execute seamlessly.
  • Combined Short Options & Scope Flags (#415): Enhanced configuration parser to handle combined short flags (e.g. -d -v), flag routing (-g, -w, -s), set-environment, and if-shell directives.
  • Interrupted Read Resilience (#437): Added EINTR retry handling to the load-buffer file read loop.
  • Session Init Rollback (#438): Automatically rolls back partially-initialized sessions in cmdNewSession if active window or pane setup fails.

4. Terminal Emulation & Extended Input Support

  • Alternate-Screen Mouse Wheel Forwarding (#427): Mouse wheel scrolling inside alternate-screen TUIs (less, vim, man) forwards Up/Down arrow key sequences (\x1bOA / \x1bOB), matching tmux behavior.
  • DECSET 1003 Any-Event Mouse Tracking (#422): Added full support for mouse_any tracking (all cursor motion events reported).
  • Kitty Keyboard Protocol Normalization (#430): Normalized kitty u-mode key codepoints for Tab, Enter, Escape, Backspace, arrow keys, Home, End, PageUp/Down, and F1–F12 into .special, .arrow, and .function variants so standard keybindings match predictably.
  • DCS & Sixel Discrimination (#429): Discard DCS sequences with intermediate bytes (such as DECRQSS ESC P $ q) instead of misrouting them into the Sixel parser.
  • Wide & Combining Character Width in Status Bar (#432): status.visibleLen accurately measures multi-byte UTF-8 CJK and combining characters using char_width.charWidth to prevent status range hit-test misalignments.

5. Memory Safety, IPC Flow Control & Server Hardening

  • MessageReader UAF on Client Detach (#428): Removed deferred reader consume in handleClient packet loop and ensured immediate return upon client detachment.
  • Render Output Flow Control (#431): Routed all frame emissions through appendClientOutFrame with high-watermark backpressure checks and output buffer limits.
  • PTY & Process Lifecycle Hardening (#395, #411, #439): Eliminated double-free and leaks on Pty.spawn fork failures, ensured idempotent Pty.deinit, bound PTY input buffer queuing to 1 MiB, and cleared reaped process IDs on pane destruction.
  • Pane Border Cache Invalidation (#433): Automatically invalidates cached pane border format expansions on resize, split, and layout restructuring.
  • Sixel Image Anchoring & Resize Eviction (#434, #435): Correctly shifts image anchor offsets during DECSTBM region scrolling and evicts out-of-bounds unreferenced images upon terminal resize.
  • Display Out-Queue Atomicity (#402, #418): Guaranteed atomic packet queuing and clean teardown of detached display clients.
  • Zero-Session Server Shutdown (#407, #408): Automatically cleans up and shuts down the server when the last window/session is closed.

44 Bug Fixes (#395–#439)

Category Bugs Resolved
Memory Lifecycle & Safety #395, #396, #398, #407, #408, #411, #428, #438, #439
Grid & Scrollback Deque #360, #361, #405, #421
Sixel Graphics & Screen #399, #406, #419, #420, #434, #435
Server IPC & Flow Control #400, #401, #402, #403, #404, #418, #423, #425, #431
Command & Config Parsers #397, #410, #413, #414, #415, #417, #433, #436, #437
Input & Terminal Emulation #409, #416, #422, #426, #427, #429, #430, #432

Testing & Quality Assurance

Metric v0.8.2 v0.9.0
Total Passing Tests 927 959
New Regression Tests — 32
Open Bugs in Tracker 0 0
Build Status Debug & ReleaseSafe Debug, ReleaseSafe & ReleaseFast passing

v0.8.2

Choose a tag to compare

@cwt cwt released this 24 Aug 03:54

szn v0.8.2

62 commits since v0.8.1. 927 tests passing.


Headline: Stability, Memory Hardening, and Terminal Emulation Fidelity

v0.8.2 is a major stability and reliability release addressing 46 items filed during the deep code audit (#349–#394) and closing out all open actionable bug tracker entries. Key highlights include critical crash and memory safety fixes, elimination of several major memory leaks, accurate DECSTBM scroll region emulation across lines and auto-wraps, standard vi copy-mode defaults with immediate search bar feedback, and seamless keystroke forwarding.


Key Improvements

1. Crash & Memory Safety Fixes

  • Use-After-Free in Batch Polls (#362): Server.isPaneValid now validates candidate pane pointers against live sessions and window trees before dereferencing, preventing crashes on stale batch I/O events following session destruction.
  • Pane Lifecycle & Double-Free (#366): Layout.removePane strictly detaches layout nodes without destroying pane memory, ensuring Server.destroyPane remains the single authoritative pane lifecycle owner.
  • Merged Screen Pointer Guard (#367): Nullified merged_screen slot during resize failure paths to prevent double-free or dangling pointer access.
  • Benign Non-Blocking Reads (#373): Handled EAGAIN/EWOULDBLOCK on client sockets gracefully instead of treating them as client disconnects.
  • IPC Packet Bounds Checking (#375): Enforced strict upper bounds on wire-declared packet lengths to prevent memory allocation exhaustion and DoS attacks.
  • Urgent Command Delivery (#376): Routed server command responses via an urgent queue so throttled or behind clients receive prompt replies without hanging.
  • Listener Socket Probing (#378): Socket path is probed via connect() before unlinking stale sockets, and directory listener permissions are enforced to 0700.

2. Memory Leak & Churn Elimination

  • Zero-Allocation Clock Mode (#359): Implemented Grid.copyVisibleFrom for in-place grid copying during clock mode, eliminating the multi-megabyte/second memory growth from continuous grid and scrollback cloning.
  • Window Title & CWD Arena Leaks (#358, #385): Fixed inline name_buf window title management in auto-rename and eliminated write-only accumulators.
  • Paste Buffer & OSC52 Caps (#357, #363, #382): Enforced MAX_PASTE_SIZE and exact buffer allocations for OSC52 payloads and load-buffer commands.

3. Terminal Emulation & Parser Fidelity

  • Unified DECSTBM Scroll Regions (#368): Unified newline (\n), auto-margin wrapping, and index (ESC D) scrolling through advanceLine() so full-screen TUIs (vim, htop, less) with fixed margins do not corrupt header lines or history.
  • Universal Sequence Abort on CAN/SUB (#388): Implemented VT500/ECMA-48 cancellation for escape, CSI, OSC, and DCS sequences on CAN (0x18) and SUB (0x1A).
  • Text Reflow & History Trimming (#347, #371): Preserved cursor position across empty prompt lines during copy-mode entry reflow, and capped rebuilt reflow history to history_limit.
  • Sixel Overlay Tracking (#387): Maintained sixel image anchor offsets across scroll region operations and raised simultaneous overlay limit to 32.
  • Palette and Modifiers Hardening (#354, #355, #356): Hardened SGR indexed colour bounds, modifyOtherKeys parsing, and sixel raster dimension parsing against overflow panics.

4. Input & User Experience

  • Root Keybinding Dispatch (#353): Directly connected root table keybindings (bind-key -n) to the input dispatcher without requiring prefix key interception.
  • Copy-Mode Defaults & Search Bar (#384): Restored mode-keys default to "vi", allowing standard vi motion keys (h/j/k/l, v, y, w/b, 0/$, g/G) out of the box. Unified / and ? search activation across keymaps with immediate status bar repainting.
  • Fast-Forward Keystrokes: Optimized client startup to immediately forward non-reply keystrokes without delay during cell-size query waiting.
  • Copy-Mode Mouse Polish (#379): Bare mouse clicks no longer yank or exit copy-mode, and existing selections clear cleanly.
  • Escape-Time Timer (#350): Added inactivity timer so standalone ESC keys are flushed promptly as Escape instead of lingering into Alt+key.
  • CR vs LF Separation (#349): Distinctly decoded Enter as CR (\r) and Ctrl-J as LF (\n).

Testing & Quality Assurance

Metric v0.8.1 v0.8.2
Total Passing Tests 870 927
New Regression Tests — 57
Build Status Debug & ReleaseSafe Debug, ReleaseSafe & ReleaseFast passing

v0.8.1

Choose a tag to compare

@cwt cwt released this 09 Aug 16:42

szn v0.8.1

23 commits since v0.8.0. 870 tests passing.


Headline: Reliability Hardening and Zig 0.16 Compliance

v0.8.1 is a patch release that closes out the remaining bug tracker entries
(#300–#346) and brings the codebase into full Zig 0.16 compliance. The
highest-impact fixes are performance (O(n²) → O(1) hot-path caches), memory
safety (UAF, double-free, leaks eliminated), and error handling (91 silent
catch {} suppressions replaced with proper logging).


Performance: O(n) → O(1) Hot-Path Caches

The v0.8.0 performance audit (#300–#310) identified 11 bottlenecks in the
render and event loops. All have been resolved with targeted caching:

  • isPaneValid (#305) — added valid: bool to Pane; now an O(1)
    pointer check instead of an O(N·M·P) tree walk on every PTY event.
  • anyDisplayClientBehind (#303) — added behind_count: u32 to
    Server; O(1) counter instead of traversing display_clients on every
    loop iteration. Backpressure leak fixed: disconnected clients now clear
    the counter on all four removal paths.
  • Foreground process name (#300) — last_foreground_name cached on
    Window; getForegroundProcessName() syscall skipped when the cached
    name matches. 1-second rate limit prevents stale reads.
  • Pane border format (#304/#307) — border_format_cached /
    border_format_gen on Pane; format is expanded once and reused until
    pane-border-format option changes. Allocator mismatch corrected
    (now uses pane's grid allocator).
  • Status line (#309) — per-DisplayClient cache; skipped entirely
    when the server is not dirty and the client width is unchanged.
  • Regressions from the performance sweep (#300–#310) — five defects
    introduced by the initial optimization pass were corrected:
    • Status line cache double-free (the yazi crash) — cache now owns an
      independent copy, freed in DisplayClient.deinit.
    • behind_count leak on client disconnect — all four paths now
      saturating-decrement the counter.
    • Border format generation counter never incremented —
      cmdSetOption now bumps session.border_format_gen.
    • Auto-rename freeze — last_foreground_name aliased win.name,
      making the skip check always true; replaced with timestamp-based
      rate limit.

Memory Safety: UAF, Double-Free, and Leak Fixes

Bug Fix
#312 processInput UAF when an action destroys the active pane or session — added guard
#313 Window title callback called allocator.free on a Session arena pointer
#314 Border format strings allocated with wrong allocator (pane grid vs gpa)
#324 cmdRenameWindow leaked window name into session arena
#338 Status line string duplicated per frame when cache hit — removed redundant allocation
#315/#320/#323 Command/layout desync on pane removal — layout tree and pane list kept in sync
#316/#317 Sixel refcount leaks on vertical screen shrink and history eviction
#318 Layout split failure left parent pane dimensions un-restored
#319 Darwin errno enum check; window name stack pointer fixup; invalid free
#321 Uncapped loop in CSI 'Z' handler — CPU exhaustion DoS
#322 Synchronous blocking write in server response dispatch

Bug Fixes

Parser & Configuration (#325, #326, #327, #328, #329, #330, #334)

  • set -u directive was silently ignored in config parser
  • Substring flag matching in mapCommandToAction could match wrong command
  • Copy-mode single-line backward selection yank failure
  • Format string truncation specifier sliced UTF-8 codepoints
  • Missing OSC discard transition on buffer overflow (input injection)
  • Input parser dropped interrupting Escape (0x1B) control bytes
  • Dropped keystroke on interrupted UTF-8 continuation sequence

Grid & Rendering (#311, #316, #317, #318, #321, #322)

  • Multiline prompt cursor jumping and text scrambling during line editing
  • Sixel leaks on grid rotation and split dimension rollback
  • Rotation desync between Window.panes array and layout tree
  • CSI 'Z' (shift-in) handler caused CPU exhaustion

Server & Dispatch (#312, #315, #319, #320, #323, #325, #335, #336, #337)

  • UAF in processInput when action destroys active pane
  • Command/layout desync on cmdBreakPane / cmdJoinPane
  • Darwin errno enum check; window name stack pointer fixup
  • set -u parser; code duplication in key binding flags and window index resolution
  • Command table switched from function pointer dispatch to inline for

Key Binding & Format (#326, #327, #328, #329, #330, #331, #332, #333, #334)

  • Multiple parser edge cases in key binding, mode copy, and format strings

Zig 0.16 Compliance

Bug Fix
#339 91 instances of catch {} replaced with `catch
#343 detectNested() in main.zig now uses init.environ_map instead of std.c.getenv
#344 main() signature changed from void to !void (Zig 0.16 rule #1)
#345 std.process.Args.Iterator replaced with init.minimal.args.toSlice(arena) — eliminates N heap allocations per invocation
#341 initCapacity() calls updated to = .empty + ensureTotalCapacity for consistency

Three items initially flagged as violations (#340, #342, #346) were verified
against the actual Zig 0.16 std lib source and confirmed as false positives:

  • std.StringHashMap / std.AutoHashMap managed types still exist and are not deprecated
  • std.ArrayList.toOwnedSlice() still exists in both managed and unmanaged variants
  • The codebase is a raw-POSIX syscall codebase (only one std.Io import
    exists in the entire tree) — the io capability pattern does not apply

Bug Tracker Status

Metric v0.8.0 v0.8.1
Total bugs 300 346
Fixed 286 327
False positive 9 17
Intentional 1 1
Open 0 0

All 346 bugs are now resolved.


Testing

Metric v0.8.0 v0.8.1
Passing tests 802 870
New regression tests — 68

v0.8.0

Choose a tag to compare

@cwt cwt released this 03 Aug 03:36

szn v0.8.0

22 commits since v0.7.0. 802 tests passing.


Headline: Client Hardening, Sixel Stability, and a 51-Bug Sweep

v0.8.0 is a reliability release. The interactive client has been hardened for
unstable connections: mosh transport drops, SSH disconnects, and slow links no
longer freeze or crash, and the server correctly backpressures panes to the
link speed. Sixel rendering has been reworked from a per-frame full-redraw to
a delta-based change-tracking pass — images that haven't moved or changed are
no longer re-emitted. 51 bugs (#249–#299) were fixed across every subsystem,
and the documentation bundle was brought into OKF v0.1 compliance.


Client & Backpressure (#298)

The v0.7.0 server-side non-blocking socket fix solved the server freeze, but
the client still blocked on blocking stdout and a blocking server socket.
Under real network latency (mosh, tailscale) the client could stall, the server
could busy-spin, and pipes could fill silently.

  • Non-blocking client I/O — stdout and the server socket are O_NONBLOCK;
    writes use bounded buffers that drop frames on overflow rather than blocking.
    A .redraw request requests a full repaint once the pipe drains.
  • Client drain on dead stdin — the interactive client no longer exits on
    stdin EOF or transport drops (mosh/SSH); it stops polling the dead fd and
    probes it periodically for revival.
  • Signal hardening — SIGPIPE is ignored (broken pipe → EPIPE, not
    kill); SIGTTOU/SIGTTIN are ignored (job control in mosh pty); SIGHUP
    is handled non-fatally.
  • Server-side backpressure — DisplayClient.behind with a 768 KiB
    high-watermark; the server throttles feedPty when all clients are behind
    and removes POLL.IN so the loop sleeps instead of busy-spinning.
  • Client-side backpressure — the client stops reading the server socket
    when its own stdout queue exceeds CLIENT_OUT_HIGH_WATERMARK, tripping
    server-side backpressure. Frames are delivered at link speed rather than
    dropped.
  • Buffer caps raised — MAX_OUT_BUF, MAX_CLIENT_OUT_BUF, and
    MAX_PACKET_SIZE raised from 1 MiB to 16 MiB so large sixel frames are
    delivered instead of dropped-and-looped.
  • Cell-size request flood fixed — sendRequestCellSize rate-limited to
    2/sec (was firing 200k+ times on a DCS false-positive sixel trigger from
    opencode's capability queries).
  • CSI 14 t reply leak fixed — the cell-size query response (ESC [ 4 ; h ; w t) is now parsed and consumed on the client side rather than being
    forwarded to the pane as a keystroke (and echoed by the shell).
  • Client diagnostics — the client writes its own log to
    ~/.szn/szn-client.log (configured via client-log-file) so transport
    freeze attribution has both sides of the wire.

Sixel Rendering Stability

  • Delta-based rendering — renderSixelImages now computes per-pane image
    anchors and IDs and only re-emits a sixel when its anchor OR content changed.
    A pure replacement at the same position draws just that image (no erase-all);
    a full erase-all+redraw happens only when an image is removed or moved.
    Frames stay small instead of growing with each accumulated image.
  • Ghost overlay fixed — exiting the alternate screen (e.g. quitting yazi)
    frees the alt screen's sixel images; images whose marker cells were
    overwritten (refcount 0) are no longer drawn.
  • Oversized sixel dropped gracefully — images larger than 8 MiB are dropped
    at capture time with a log message rather than producing frames that overflow
    the client buffer and freeze the display.
  • First-sixel cell-size race fixed — when a sixel arrives before the
    terminal's cell size is measured, the image is buffered (pending_sixel) and
    replayed once the measurement arrives, avoiding a cursor misplacement after
    the first image.
  • Sixel-wait 100% CPU spin fixed — panes with a pending sixel have
    POLL.IN removed so the event loop sleeps rather than busy-spinning on level-
    triggered PTY data.

51 Bug Fixes (#249–#299)

Since v0.7.0 (bugs up to #248), every remaining entry in the bug tracker has
been resolved. Key areas:

Area Bugs
Grid / history ring-buffer integrity #249, #264, #265
Sixel refcount bookkeeping #253, #278, #279, #291, #292
Layout & pane swap correctness #250, #284
Copy-mode search & cursor bounds #251, #276, #281
Cursor/clamp calculations #277
Memory lifecycle (leaks, UAF, double-free) #230, #266, #267, #269, #280, #282, #283, #285, #286, #287, #288, #295, #296
Configuration parser edge cases #259, #275
DoS / safety caps #228, #260, #261, #270, #297
Performance (O(n²) → O(1) / O(n)) #225, #240, #241, #242, #252, #276
Dead code & code quality #243, #244, #255, #256, #257, #273
Protocol & architecture compliance #258, #293

The bug tracker is now fully resolved: 286 fixed, 9 false positives, 1
intentional, 3 open (false positives with non-standard status formatting in
the original file).


Documentation

  • OKF v0.1 compliance — BUGS.md (4107 lines, 236 KB) split into 299
    individual documents under docs/development/bugs/001.md–299.md, each with
    YAML frontmatter. A new bugs/index.md provides summary tables and a full
    listing.
  • Broken links fixed — 10 historical BUGS.md links in log.md redirected
    to bugs/index.md; 3 absolute file:/// URIs in TEXT_REFLOW.md replaced
    with project-relative paths.
  • build.zig.zon link in log.md fixed (was resolving to docs/build.zig.zon).

Logging

  • Dual log paths — server-log-file and client-log-file options replace
    the single log-file name. Both are disabled by default for privacy.
    "default" resolves to $XDG_STATE_HOME/szn/szn.log (server) and
    ~/.szn/szn-client.log (client).
  • The server sends the configured client-log-file to the client over the wire
    (new .client_log protocol message, 0x85); the client only enables its log
    when it receives a non-empty path.

v0.7.0

Choose a tag to compare

@cwt cwt released this 24 Jul 07:11

szn v0.7.0

35 commits since v0.6.0. 802 tests passing.


Headline: Status Bar, Pane Borders, and a 39-Bug Cleanup Sweep

v0.7.0 delivers the long-awaited tmux-compatible status bar with a rewritten
format engine, pane-border-format indicators, and a systematic 39-bug cleanup
covering everything from scroll history corruption to sixel eviction,
double-frees, and arena allocation discipline.

  • Status Bar — Full tmux-compatible status bar driven by status-left,
    status-right, status-justify, window-status-format, and
    window-status-current-format options. Supports status off to hide the
    bar and status-interval for periodic clock updates. The format engine was
    rewritten with TemplateCache (compile-once), stride-free deduplication,
    #[style] sequences, strftime, and single-character aliases (#S, #I,
    #W, #P, #H, #h, #F, #D, #T) matching tmux conventions.
  • Pane Border Format — pane-border-format (default #P for pane index)
    draws on the top border of each pane in vertical splits, and vertically
    down the left border in horizontal (side-by-side) splits. Both horizontal
    and vertical-border rendering are supported.
  • Systematic Bug Sweep (#210–#248) — 39 bugs found through deep code
    audits, static analysis, and manual review. Every one is fixed. The bug
    tracker now holds 248 entries, all with uniform Status: metadata.

Changes

Description Severity / Type
tmux-compatible status bar (status-left/right, justify, window formats, interval) Feature
Rewritten format engine (TemplateCache, strftime, #style, aliases) Feature
pane-border-format option with horizontal + vertical border rendering Feature
Fix host scrolling desync via DECAWM disable on alt screen (#210) Bug Fix
Fix character width drift for standard symbols misclassified as emoji (#211) Bug Fix
Fix status bar / pane-border-format rendering bugs (#212–#215) Bug Fix
Fix Grid.scrollDown history ordering (#216) Bug Fix
Fix reflowCursorInternal OOM recovery double-free (#217) Bug Fix
Fix sixel registry eviction preferring unreferenced slots (#218) Bug Fix
Fix sixel anchor drift across alt-screen switches (#219) Bug Fix
Fix pane swap not resizing to new layout slot (#220) Bug Fix
Fix daemon startup use-after-free on killed session (#221) Bug Fix
Fix new pane not inheriting cell pixel size from parent (#222) Bug Fix
Fix alt-screen cursor position drift on resize (#223) Bug Fix
Reduce queryCellSize poll timeout from 200ms to 5ms (#224) Bug Fix
Replace O(n²) sixel image ref scanning with O(1) refcounting (#225) Optimization
Fix dangling pointer in renderStatusBar prompt (#226) Bug Fix
Fix CPU infinite loop on 0-byte socket writes (#227) Bug Fix
Add bounds checks to Packet serialize/deserialize (#228) Bug Fix
Fix scroll down and reverse index history corruption (#229) Bug Fix
Fix reflowCursorInternal double-free, leaks, history_start offset (#230) Bug Fix
Fix Grid.clone history_start underflow panic (#231) Bug Fix
Fix layout tree desync on window rotation and 0-pane state (#232) Bug Fix
Enforce minimum pane dimensions for split geometry invariants (#233) Bug Fix
Concatenate soft-wrapped lines in copy mode search (#234) Bug Fix
Clear ghost characters on 2-col wrap, preserve combining marks (#235) Bug Fix
Add SA_RESTART to signal handlers (#236) Bug Fix
Free DispatchResult in prompt command evaluation (#237) Bug Fix
Add errdefers and cleanup to config directive parsers (#238) Bug Fix
Clean up allocated Pane on initialization error (#239) Bug Fix
Skip Sixel matrix scanning when no sixels present (#240) Optimization
Pre-calculate active_bound in drawLayoutBorders (#241) Optimization
Use stack buffer in PTY getCwd (#242) Optimization
Consolidate layout tree traversal into Layout.findPaneBounds (#243) Refactor
Consolidate pane swap logic into swapPaneRelative helper (#244) Refactor
Enforce arena allocation lifecycle per AGENTS.md (#245) Compliance
Use inline for comptime CMD_TABLE lookup (#246) Refactor
Re-analyze DECSM 1000/1002/1003 as intentional (#247) Docs
Change pane-border-format default from #I (window) to #P (pane index) (#248) Bug Fix
Reformat all 248 BUGS.md entries with uniform metadata Docs

v0.6.0

Choose a tag to compare

@cwt cwt released this 20 Jul 03:44

szn v0.6.0

20 commits since v0.5.1.


Headline: Copy-Mode Search, Non-Blocking Display Sockets, and Heavy Rendering Optimizations

This feature release introduces massive improvements to copy-mode capabilities, terminal output responsiveness under load, emoji/character width safety, and extensive rendering performance optimizations:

  • Copy-Mode Search — Fully integrated and highly optimized backward/forward search in copy-mode. Supports prompt prefix indicators (/ and ?), cyclic wrapping, correct cursor placement for 2-width characters, and matching combining marks / Thai (non-ASCII) inputs.
  • Non-Blocking Display Sockets — Switched display-client sockets to non-blocking to prevent event loop freezes when flooding output over slow links. Correctly shifts remaining unwritten buffer bytes to the front on EAGAIN and handles backlogs without skipping frames.
  • Unicode 15/16 Emoji & Width Overrides — Added a modern Unicode East-Asian-Width + emoji-presentation table to eliminate cursor drift for modern checkmarks, stars, and arrows. Added a customizable codepoint-widths session option to allow operators to specify custom width overrides.
  • Heavy Rendering & Memory Optimizations — Integrated arena allocation across server/client boundaries, ring-buffer history, bounds buffer caching, single-buffer yank, delta SGR sequence emission, and flat cells pre-allocation to maximize rendering throughput.
  • Command-line Version Check — Added the -V command-line option to extract the project version from build.zig.zon and print it.

Changes

Description Severity / Type
Copy-mode search (wiring keys, cyclic wrap, prompt prefix, 2-width char cursor) Feature
Support Thai (non-ASCII) input and match combining marks in copy-mode search Feature
Switched display-client sockets to non-blocking output buffering to prevent freeze High
Resolve partial write buffer truncation & event loop spin on display client flush (bug #207) High
Resolve skipped render frames on successful display backlog flush (bug #208) High
Unicode 15/16 emoji/character width correctness and codepoint-widths option (bug #206) High
Support version printing using standard -V option Feature
Re-wrap optimizations, esc_buf field, and osc_buf retain Optimization
Ring-buffer history, sixel pre-check, bounds buffer caching, and single-buffer yank Optimization
Skip clear and non-dirty panes in incremental merged grid rendering Optimization
Delta SGR escape sequence emission (reduced bandwidth overhead) Optimization
Remove event-loop blocking usleep(2000) during sixel cell-size wait Optimization
Pre-allocate flat_cells and logical_spans in reflowCursorInternal Optimization
Fix color loss on attribute-only SGR change Bug Fix

v0.5.1

Choose a tag to compare

@cwt cwt released this 14 Jul 03:50

szn v0.5.1

7 commits since v0.5.0.


Headline: Event Loop PTY FD Leaks & Memory Safety Fixes

This maintenance release focuses on critical stability, memory safety, and resource leak fixes:

  • UAF Segfault on Startup — Fixed a use-after-free segfault on daemon startup where the daemon attempted to spawn and initialize the "default" session's pane shell even if it was killed by a client handshake within the initial 16ms window.
  • PTY FD and Memory Leaks — Resolved multiple resource leaks where closed PTY master descriptors remained in the event loop and pane state was not deinitialized on session, window, or individual pane destruction (e.g., via kill-pane or event loop triggers).
  • Szn Startup Freeze — Fixed a bug where the server failed to launch the default shell, freezing on startup. The daemon was hardcoded to look for a default session ID of 0, but session IDs start at 1.
  • Pane Boundary & Coordinate Calculations — Refactored pane boundary checks and cursor coordinate shifts during terminal resizing and rendering.

Bug Fixes

Description Severity
Event loop PTY fd leak on session/window kill (bug #205) High
Use-after-free segfault in daemon startup when default session is killed High
File descriptor and resource leaks in kill-pane action and command High
Szn startup freeze (checking for session ID 0 instead of actual ID) High
Pane parser memory leak, copy mode space padding, and double allocations Medium
Server pane boundary calculation and cursor coordinate shifts Medium

Documentation

  • Created v0.5.1.md release notes and updated the releases index.
  • Added Bug #205 to BUGS.md tracking event loop leaks.