v0.5.0
Highlights
This release makes stacks2099 scriptable. The HTTP API is now self-describing: the binary serves its own /api markdown docs, rendered as minijinja templates with idiomatic Nushell examples and an absolute binary path so the snippets run as-is. /api/state enumerates every clip tagged with its stack, every terminal, and each terminal's working directory (OSC 7). A new /api/events endpoint streams the live log frame feed as newline-delimited JSON.
The clip API grew up. /clip/move takes an absolute ?to= index and a ?stack= target for cross-stack moves; /clip/add accepts an optional ?view= to set display style at creation; /stack/new returns {id} for JSON callers; and /pty/label was renamed to /clip/label. eval now emits results as JSON (strings raw, structured values as JSON) rather than display text. Looking up a clip by an unknown id returns a clean 404 instead of a silent 204.
Terminals are now observable over HTTP: a live raw-output tee, GET /pty/snap for a plain-text buffer snapshot, and clickable wrapped terminal URLs. Resize re-emits the full grid so deltas stay in sync, and grid updates travel as HTML records framed in Nushell.
Navigation went vim-style. h/l alias k/j for clip navigation (niri-friendly), Shift+H/Shift+L alias clip move, x terminates a clip, and the layout toggle moved to w. The full command set works bare in navigate mode (except delete), the New-clip picker takes t/n letter shortcuts, and new clips land directly after the selected clip. Reorders animate with FLIP instead of a hard jump, and newly created or moved clips scroll into view.
Under the hood, the binary now builds on the published http-nu 0.17.1 crate, dropping the vendored engine, and unpacks its bundled app into the store directory rather than a per-user cache.
Raw commits
- docs: add Cate comparison (2026-06-07)
- refactor: build on the http-nu 0.17.1 crate, drop the vendored engine (2026-06-07)
- fix(api): by-id clip routes 404 on an unknown clip instead of silent 204 (2026-06-05)
- feat(ui): Shift+H/Shift+L alias clip move (K/J); move layout toggle to w (2026-06-05)
- fix(ui): seed rename modal from the cursored clip's DOM, not the lagging $label slot (2026-06-05)
- docs: flag the planned h/l rebind (direction-aware) as a breaking change (2026-06-05)
- feat(ui): h/l alias k/j for clip navigation (vim-style, niri-friendly) (2026-06-05)
- feat(ui): terminate clip on x (was d, leader-only); free bare l (layout -> Shift+L) (2026-06-05)
- feat(ui): make the full command set work bare in navigate mode (except delete) (2026-06-05)
- feat(ui): scroll a newly created clip into view once its pane mounts (2026-06-05)
- fix(ui): reveal moved clip via transform-immune offsets, not mid-FLIP rects (2026-06-05)
- feat(ui): scroll the moved clip into view after a reorder, without focusing it (2026-06-05)
- feat(ui): animate pane reorder with FLIP instead of a hard jump (2026-06-04)
- feat(ui): new clips land directly after the selected clip, not top/bottom (2026-06-04)
- feat(api): GET /api/events -- live log frame feed as newline-delimited JSON (2026-06-04)
- feat(api): richer /clip/move -- absolute ?to= index and cross-stack ?stack= (2026-06-04)
- feat(api): optional ?view= on /clip/add to set display style at creation (2026-06-04)
- feat(api): /stack/new returns {id} for Accept: application/json callers (2026-06-04)
- refactor(api): rename /pty/label to /clip/label (query params), drop pty-meta label mirror (2026-06-04)
- feat(api): enumerate every clip in /api/state, tagged with its stack (2026-06-04)
- docs: call out the HTTP/1.1 terminal connection limit and HTTP/2 fix (2026-06-04)
- docs: document the per-store app unpack mechanism (2026-06-04)
- feat: unpack the bundled app into the store dir, not a per-user cache (2026-06-04)
- feat(ui): t/n letter shortcuts in the New-clip picker (2026-06-04)
- docs: research note on OSC 52 clipboard in wezterm-term (2026-06-04)
- feat(eval): emit string results raw, structured results as JSON (2026-06-04)
- fix(ui): crop scru128 ids to the tail, not the head (2026-06-04)
- feat(eval)!: emit result as JSON instead of display text (2026-06-04)
- fix(clip): never orphan a clip from a bogus selectedStack (2026-06-04)
- feat(api): self-contained /api docs -- absolute binary path + eval -c framing (2026-06-04)
- feat(pty): report each terminal's cwd (OSC 7) in pty list and /api/state (2026-06-04)
- docs(api): render /api docs as minijinja templates; idiomatic Nushell examples (2026-06-04)
- feat(api): self-describing /api markdown docs that travel with the binary (2026-06-04)
- fix(pty): clean 404 for an unknown sid on the /pty GET routes (2026-06-04)
- feat(pty): pty snap + GET /pty/snap for a plain-text buffer snapshot (2026-06-04)
- feat(pty): live raw-output tee + list terminals in /api/state (2026-06-03)
- test(e2e): pass options to waitForFunction, not as the bound arg (2026-06-03)
- test(e2e): fix close-clip cursor-drift race and a waitForFunction timeout arg (2026-06-03)
- test(e2e): drive rename with real key events, not synthetic dispatch (2026-06-03)
- fix(pty): re-emit full grid on resize so deltas don't desync (2026-06-03)
- refactor(pty): emit HTML grid-update records, frame datastar in nushell (2026-06-03)
- feat(pty): make wrapped terminal URLs clickable (2026-06-03)
- chore: bump to v0.4.1-dev (2026-06-03)