Skip to content

v0.14.0

Latest

Choose a tag to compare

@github-actions github-actions released this 25 Jul 06:35

Deterministic Editing — repeatable operations, a plugin host that can't hang the editor, and a crash-recovery format that survives its own filenames.

Macros: transactional record and replay

Macros record the command stream off the message bus, not raw keystrokes, so replay is immune to mode and timing skew.

  • q + a register starts recording, q stops; [N] @ + a register replays with a count.
  • Replay is all-or-nothing. The whole macro applies as one undo group, and a replay that errors mid-way rolls the buffer back to its pre-replay state instead of leaving a half-applied edit.
  • A recording indicator sits in the status bar; a failed replay surfaces the rolled-back step as a toast.

Macros live in per-session az registers. Durable, cross-restart storage arrives with the named-register work in #3.

The plugin host is now a library, and every call is metered

The pure-Zig wasm interpreter has been extracted into its own project, wick — stem's second general-purpose spin-off after vigil. stem now depends on it as a pinned package.

  • Fuel-metered calls. Every plugin call runs under an instruction budget. A runaway plugin fails that one call with OutOfFuel — logged, counted, contained — instead of hanging the editor. Host calls cost one instruction, so a plugin waiting on a slow git subprocess is never penalized.
  • Containment you can see. Per-plugin call, trap, last-error, and fuel-usage stats appear in the plugin-manager dashboard and the control center, and plugin traps feed the check-engine light alongside dead letters and open circuits.

Session files that survive their own filenames

The session and crash-recovery parser scanned for field markers instead of parsing JSON, so a path containing ", \, or } truncated or dropped the buffer it belonged to. On a real session written for a workspace holding quote"file.zig and brace}file.zig, the old parser recovered one usable buffer out of three.

Parsing and serialization now both go through std.json:

  • Paths round-trip exactly — quotes, braces, newlines, control bytes, emoji. Control characters were previously written raw, producing a file that wasn't valid JSON at all.
  • Out-of-range numbers saturate instead of wrapping; a long enough digit run used to panic a safe build.
  • A path that isn't valid UTF-8 costs that one buffer rather than making the whole file unparseable, and a malformed split layout is dropped the same way — losing your layout beats losing your buffers.

Install

Prebuilt archives for macOS (arm64/x86_64), Linux (x86_64/arm64), and Windows (x86_64) are attached below. The Unix tarballs now ship their own installer, which places the binaries and bundled plugins exactly where a from-source install does and tells you what to add to your PATH if it isn't already there:

tar xzf stem-v0.14.0-<target>.tar.gz
cd stem-v0.14.0-<target>
./install.sh                  # or: ./install.sh --prefix ~/.local

The binaries aren't notarized yet, so a browser download is quarantined by Gatekeeper. install.sh clears that for you; if you run the binary straight from the archive instead, fetch it with curl -LO or clear the attribute yourself with xattr -d com.apple.quarantine ./stem.

Verify a download against the attached SHA256SUMS.txt:

shasum -a 256 -c SHA256SUMS.txt

Also in this release

  • Test coverage went from 656 to 723 passing tests — not by writing 67 new ones, but by discovering that nine modules' test suites were never wired into the build and had quietly rotted, split_manager (window splits) among them. Fixing them turned up tests asserting the opposite of real behavior, and a leak-checking helper that could only pass for code that allocated nothing.
  • Dead code removed: an orphaned help_view.zig, a leftover loader helper, an unused import.
  • Docs refreshed across the README, architecture, plugin, and roadmap pages.

Closes #2 and #7.

Full Changelog: v0.13.1...v0.14.0