Skip to content

Releases: chris-mclennan/tmnl

0.2.0 — 2026-06-16

17 Jun 00:59

Choose a tag to compare

Release Notes

This release is the deferred-polish + audit sweep — a session built on
four explicit phases: ship the open backlog, drive multi-persona testing
through the headless harness, fix every verified finding, and audit the
public site against ghostty.org. Across 36 commits, shell.rs split
from 4135 → 561 lines (-86%)
via 10 sibling-module extractions; 21
persona-testing findings shipped (4 modifier-guard families, 4
per-window scope inconsistencies, 5 mouse-access via context menu, 4
modal-stacking, 3 headless quirks, plus the help-overlay.gif regression
re-record); 5 ghostty-comparison doc edits landed (landing reorder,
themes quickstart, install per-OS routing, About page, shell-integration
bash/fish). Final state: 544 lib tests pass, Starlight build clean at
28 pages, every audit finding adversarially verified.

Highlights:

  • Shell.rs split — extracted into 8 method submodules (resize,
    scroll, io, queries, render, spawn, accessors, reader) + 9 sibling
    helper crates (shell_cell_attrs, shell_color, shell_config,
    shell_context, shell_keys, shell_mouse, shell_osc1337, shell_prompt,
    shell_pty). Submodule visibility lets each slice touch private
    ShellSession fields without pub(crate) leakage.
  • Persona-testing fixes — keyboard chords no longer get eaten by
    overlay filter buffers (Cmd+Shift+R no longer wipes recents), per-
    window cfg overrides honored by toggle_sidebar / toggle_tab_bar,
    pane management reachable from the right-click menu (Split / Close /
    Zoom / Equalize), pane divider gets a hover cursor, Cmd+W closes
    the topmost overlay from inside palette/find/etc., view.help no
    longer stacks on other overlays, headless --app no longer
    persists user config when toggle buttons are clicked.
  • Render perf — apply_to_grid drops the parser Mutex before the
    rustybuzz ligature pass; sync-depth (DECSET 2026) early return
    reads a cached cursor instead of leaking the live one; per-frame
    ~4KB palette_override.indexed clone replaced with a lock-held
    borrow; per-frame link_grid / underline_grid /
    underline_color_grid clones now gated on sticky-true *_active
    flags so sessions that never see OSC 8 / extended underlines /
    CSI 58 skip the clones entirely.
  • Settings save-failure inline error banner — Save now happens
    before the overlay closes; failure stays the dialog open with a
    red ! save failed: <reason> banner instead of silently losing
    the user's edits.
  • Type-to-filter the help overlay — start typing while ⌘⇧/ is
    open to narrow the binding list.
  • 20 demos shipped across the manual — 3 layout demos
    (many-tabs-horizontal / bottom-tab-bar / tab-layout-toggle), help-
    filter, attention-dot, palette-filter, settings-window-scope,
    discovery-install, help-themes, plus the existing 13.
  • Site audit fixes vs ghostty.org — landing reordered so the
    plain-English value pitch precedes the jargon grid, themes
    quickstart added, install page gains per-OS jump table + version
    banner + Gatekeeper escape hatch, new /about page, shell-
    integration grew bash + fish recipes + verification step.

Menu bar

  • New Edit > Find… menu item (⌘F). Standard macOS slot, mirrors the
    existing chord. Opens the in-pane find bar in the focused pane.
  • New Edit > Find Next and Edit > Find Previous menu items.
    Work whether the find bar is visible or not — as long as a find
    session is active, they advance through matches. Same match-
    advance logic Enter / Shift+Enter use inside the find bar.
    Intentionally no chord — ⌘G / ⌘⇧G stay reserved for the
    fwd.cmd_g forwarder that sends ⌘G as ⌃G to native mnml panes
    (goto-line in the editor).
  • New Shell > New Tab (⌘T) and Shell > Close Tab (⌘W) menu
    items. Standard slots that were previously chord-only.
  • New View > Recents… (⌘R) menu item. Opens the recents picker —
    the same overlay the welcome screen used to surface on startup.
    Mirrors the existing chord; gives the recents flow a discoverable
    menu-bar entry point.
  • New View > Search Tabs… menu item. Toggles the
    tab-search overlay (filter tab chips by name). Intentionally
    no chord — ⌘⇧T is reserved at the chord-registry layer for
    tab.reopen_closed (browser convention).
  • Help > tmnl Help now opens the in-app help overlay (same surface
    ⌘⇧/ opens) instead of logging a placeholder. The overlay lists every
    registered command + its current chord — the discoverable answer to
    "what does tmnl do?" for new users.

Multi-window

  • ⌘W on the last tab of one of N windows now closes only that
    window
    , instead of quitting tmnl and dropping every other open
    window with it. When the focused window's last tab closes and at
    least one background window is open, swap a background window in
    as the new focused window (dropping the previous one's winit
    handle closes the OS window). When no background windows are
    open, the historical "quit the app" behavior still fires.
  • ⌘W no longer cascades through every open window in one
    press. Dropping a WindowState causes AppKit to queue a
    CloseRequested for the just-closed window. The handler used to
    process that stale event against the new focused window and
    cascade-close. Now the dispatcher ignores WindowEvents whose
    WindowId doesn't match any window we still own.
  • Persistence stays in sync with what's actually open
    closing one of N windows (via the red close button or via the
    last-tab ⌘W path) now writes the smaller window-state immediately,
    so the next launch doesn't resurrect the closed window.

Chrome strip

  • Back / forward arrows on Shell panes now jump to the previous /
    next OSC 133 prompt in scrollback (same as ⌘↑ / ⌘↓). They used to
    forward Ctrl+PgUp / Ctrl+PgDn to the focused pane — useful on
    Native (mnml) panes, no-op in bare zsh. The chord stays in place;
    the arrows give it a discoverable click target.

Selection

  • Shift+click now extends the existing body-selection — anchor stays
    put, focus moves to the click position — instead of starting a fresh
    single-cell selection. Falls back to a fresh selection when there's
    no existing one on the same tab + pane. Matches the macOS Terminal /
    iTerm / VS Code convention.
  • The selection highlight now paints during drag, not only on
    release. Each CursorMoved while dragging force-pushes the live
    bounds to gpu.selection_bounds so the next frame paints them even
    if the redraw chain lagged.

Modal overlay accessibility

Every modal overlay — palette, palette overlay (chip-clicked),
welcome, discovery, settings, help, right-click context menu, and
both confirm dialogs (close + paste) — now has full mouse +
keyboard parity:

  • Click a row to activate / focus it (palette dispatches the
    command, welcome opens the entry, discovery toggles in-rail,
    settings focuses the row; second click on the focused settings
    row cycles its value).
  • Wheel scrolls the row selection on welcome / discovery /
    settings / help.
  • Click outside the panel dismisses (palette / palette overlay /
    welcome / discovery / help / context menu); settings is
    intentionally excluded to avoid silently discarding unsaved
    row edits.
  • Confirm-close and confirm-paste dialogs grow visible [Close] / [Cancel] and [Paste] / [Cancel] buttons. Click-outside
    also cancels.
  • Hover pre-selects rows on welcome + discovery — standard menu
    UX, lets users hover-then-Enter without a click.
  • Help overlay click-outside dismiss covers chrome / chip clicks
    that previously slipped past the body-click-dismiss path.

Keyboard chords (closing the persona-report gaps)

  • F2 — rename the focused tab. VS Code parity. Same modal as
    the right-click rename path; first-class menu item lives under
    Window > Rename Tab.
  • ⌘⇧1 … ⌘⇧9 — open launcher rail icons. Closes the "rail is
    mouse-only" gap. Out-of-range indices silently no-op.
  • ⌘Home / ⌘End — jump to top / bottom of scrollback. Pairs
    with the existing ⇧PgUp / ⇧PgDn row-by-row paging.
  • ↑ / ↓ in ⌘F find bar and ⌘⇧T tab-search step matches
    forward / backward. Was Enter / Shift+Enter only.
  • ⌘⇧P palette and ⌘R recents now supersede transient input
    overlays
    — welcome / tab_search / find / palette_overlay /
    discovery / context_menu auto-dismiss as the new one opens.
    The "destructive" modals (settings / help / rename / confirm
    dialogs) still block. Closes the 06-10 hybrid SEV-4 #7 design
    call.
  • ⌘D in a Browser pane forwards as ⌃D instead of unconditionally
    splitting right, so mnml's multi-cursor "select next
    occurrence" chord works when the editor's a Native pane.
  • ⌘Z / X / S / N / P / B / G / / no longer silently eat keys in
    Shell context.
    The fwd.cmd_* chords now gate on Native
    focus; in Shell context they fall through to the pty's char
    path as the user expects.

Browser pane chord coverage

Safari conventions, all gated on Browser-pane focus:

  • ⌘[ / ⌘] — history back / forward.
  • ⌘L — focus the URL bar (seeds the chrome edit buffer with
    the current URL).
  • ⌘R — reload (rides on view.recents's wire; falls through
    to opening recents when no Browser pane is focused).

Maximize Pane (zoom)

The Shell > Splits > Maximize Pane (⌘⇧↩) verb shipped in
0.1.5 but was substantially broken — composite painted via
tab.layout.leaf_rects instead of effective_leaf_rects, so
the zoomed pane's full-area grid only painted at its small
underlying split-tree rect; pane_under_cursor mis-routed
clicks; divider drag still fired through the zoomed pane;
close / split paths left zoomed_pane stale across id shifts.
All fixed; the menu label now flips between Maximize Pane
Restore Pane in sync with the state (across toggle / chord /
menu click / tab switch / window swap / close / split paths).
Active chip in the strip also gains a leading badge while
zoomed.

Multi-window state drift

Several latent state-drift bu...

Read more

v0.0.5

04 Jun 15:06

Choose a tag to compare

Install tmnl-rs 0.0.5

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/chris-mclennan/tmnl/releases/download/v0.0.5/tmnl-rs-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/chris-mclennan/tmnl/releases/download/v0.0.5/tmnl-rs-installer.ps1 | iex"

Download tmnl-rs 0.0.5

File Platform Checksum
tmnl-rs-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
tmnl-rs-aarch64-apple-darwin.pkg Apple Silicon macOS checksum
tmnl-rs-x86_64-apple-darwin.tar.xz Intel macOS checksum
tmnl-rs-x86_64-apple-darwin.pkg Intel macOS checksum
tmnl-rs-x86_64-pc-windows-msvc.zip x64 Windows checksum
tmnl-rs-x86_64-pc-windows-msvc.msi x64 Windows checksum
tmnl-rs-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
tmnl-rs-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

v0.0.4

01 Jun 03:35

Choose a tag to compare

Install tmnl-rs 0.0.4

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/chris-mclennan/tmnl/releases/download/v0.0.4/tmnl-rs-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/chris-mclennan/tmnl/releases/download/v0.0.4/tmnl-rs-installer.ps1 | iex"

Download tmnl-rs 0.0.4

File Platform Checksum
tmnl-rs-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
tmnl-rs-aarch64-apple-darwin.pkg Apple Silicon macOS checksum
tmnl-rs-x86_64-apple-darwin.tar.xz Intel macOS checksum
tmnl-rs-x86_64-apple-darwin.pkg Intel macOS checksum
tmnl-rs-x86_64-pc-windows-msvc.zip x64 Windows checksum
tmnl-rs-x86_64-pc-windows-msvc.msi x64 Windows checksum
tmnl-rs-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
tmnl-rs-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

v0.0.3

31 May 17:23

Choose a tag to compare

Install tmnl-rs 0.0.3

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/chris-mclennan/tmnl/releases/download/v0.0.3/tmnl-rs-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/chris-mclennan/tmnl/releases/download/v0.0.3/tmnl-rs-installer.ps1 | iex"

Download tmnl-rs 0.0.3

File Platform Checksum
tmnl-rs-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
tmnl-rs-aarch64-apple-darwin.pkg Apple Silicon macOS checksum
tmnl-rs-x86_64-apple-darwin.tar.xz Intel macOS checksum
tmnl-rs-x86_64-apple-darwin.pkg Intel macOS checksum
tmnl-rs-x86_64-pc-windows-msvc.zip x64 Windows checksum
tmnl-rs-x86_64-pc-windows-msvc.msi x64 Windows checksum
tmnl-rs-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
tmnl-rs-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

v0.0.2

31 May 17:05

Choose a tag to compare

Install tmnl-rs 0.0.2

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/chris-mclennan/tmnl/releases/download/v0.0.2/tmnl-rs-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/chris-mclennan/tmnl/releases/download/v0.0.2/tmnl-rs-installer.ps1 | iex"

Download tmnl-rs 0.0.2

File Platform Checksum
tmnl-rs-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
tmnl-rs-aarch64-apple-darwin.pkg Apple Silicon macOS checksum
tmnl-rs-x86_64-apple-darwin.tar.xz Intel macOS checksum
tmnl-rs-x86_64-apple-darwin.pkg Intel macOS checksum
tmnl-rs-x86_64-pc-windows-msvc.zip x64 Windows checksum
tmnl-rs-x86_64-pc-windows-msvc.msi x64 Windows checksum
tmnl-rs-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
tmnl-rs-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

0.0.1

31 May 15:24

Choose a tag to compare

Release Notes

Added

  • Shell mode — hosts a real pty, output parsed into cells with vt100;
    mouse input (click, drag, move, scroll).
  • Native mode — the tmnl-protocol wire format over a Unix socket; apps
    send structured Frames of cells, with partial-frame DiffRun updates and
    app-set tab titles.
  • GPU rendering — a wgpu cell pipeline plus a chrome-strip pipeline;
    true-color cells, cursor shape and visibility.
  • Window & chrome — native tabs, a native macOS menu bar, Mac-style editing
    chords, and an in-grid settings modal persisted to
    ~/.config/tmnl/config.toml.
  • OSC 133 shell integration — command-lifecycle tracking and a command-line
    anchor.
  • Local AI command completion⌘I continuation and ⌘K
    natural-language → command, offline via the embedded fim-engine model.
  • Headless mode (--headless) — scriptable cell-grid dumps for tests, plus
    fake_server / fake_client examples that exercise the protocol without a
    GPU window.

Install tmnl-rs 0.0.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/chris-mclennan/tmnl/releases/download/v0.0.1/tmnl-rs-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/chris-mclennan/tmnl/releases/download/v0.0.1/tmnl-rs-installer.ps1 | iex"

Download tmnl-rs 0.0.1

File Platform Checksum
tmnl-rs-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
tmnl-rs-aarch64-apple-darwin.pkg Apple Silicon macOS checksum
tmnl-rs-x86_64-apple-darwin.tar.xz Intel macOS checksum
tmnl-rs-x86_64-apple-darwin.pkg Intel macOS checksum
tmnl-rs-x86_64-pc-windows-msvc.zip x64 Windows checksum
tmnl-rs-x86_64-pc-windows-msvc.msi x64 Windows checksum
tmnl-rs-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
tmnl-rs-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum