github ZenNotes/zennotes v2.51.0
ZenNotes v2.51.0

latest releases: v2.51.1, web-2.51.0-web.hd4bbb4979ae81a3e, viewer-2.51.0-viewer.h98c5c0085c5fe6b4...
3 hours ago

ZenNotes 2.51.0: the ecosystem boundary release, with a pacman updater fix, Cloud vault retirement, and Vim block edits

Released on September 16, 2026 as v2.51.0, at 8ff2cb86. The release branch v2.51.0 was fast-forwarded into main through PR #796, which carries PR #789 (ecosystem boundaries) and PR #795 (server cutover). Two reports came from @uNyanda and one from @vlcinsky; each is closed with a commit-linked comment. Channel and validation details are in the sections at the end.

✨ Features

  • The command-line tool is zn. The desktop's bundled command is now zn, the same name as the standalone Go CLI and terminal app. Opening ZenNotes once upgrades an existing desktop-managed zen shortcut in place; your commands keep working. Settings > CLI shows what is installed and offers a reviewed Repair shortcut when a shortcut points at a moved Mac app or an old AppImage, showing the old target, the replacement and the backup path before it touches anything. Homebrew and manual installations stay managed by their own installer. This version still runs the bundled Node engine; the Go engine arrives in the next release once Go CLI v0.2.0 is published and pinned. ZENNOTES_CLI_ENGINE=legacy keeps the previous engine during the transition.
  • Note creation dates travel with the vault. Creation metadata is now app-owned, kept beside the note under .zennotes/note-metadata/, and moved, renamed and deleted with it by the desktop, the MCP server and the CLI, so creation dates survive syncs, copies and filesystems that drop birth times. Cloud sync carries the metadata as vault content. A sidecar that links outside the vault is refused, and malformed metadata fails a save before the Markdown is touched.
  • Self-hosted offline shell installs again. The self-hosted web app registers its service worker from the bundled code instead of an inline script, which the server's Content Security Policy had been blocking silently. Reaches self-hosters with the server release that embeds this web build.

🐛 Fixes

  • .pacman updater: install shows through to relaunch (#790). On Arch the in-app update ran pacman through pkexec, and pkexec fell back to a textual agent on a terminal the app does not have, so nothing installed and Relaunch did nothing. The updater now has an installing phase, requires a graphical polkit agent, tells "you dismissed the dialog" (exit 126) from "no agent could run" (exit 127), and offers recovery from Details > About. The AUR package now conflicts with the old ZenNotes package name so the two cannot coexist.
  • Deleted Cloud vault no longer shows as up to date (#791). A vault deleted on the server kept reporting successful syncs. Only the authenticated vault-level confirmation now retires the remote association; a missing item, revision or upload stays a sync error rather than being mistaken for a deletion. A retired vault is shown as such, auto-sync stops, and Cloud settings offer unlink.
  • Vim visual-block edits apply to every row (#792). Block insert, append and change only changed the first row because CodeMirror kept a single selection. The Vim extension now enables multiple selections and the block highlighter paints the full rectangle even across short rows.

🧰 For contributors

  • The ecosystem boundary refactor, PR #789: app-core, shared-domain, bridge-contract and shared-ui are consumed as packed packages with a published contract; the share viewer and the self-hosted web bundle ship as immutable, checksummed artifacts (web-*, viewer-* releases); mobile and website consumers pin them.
  • The Go server moved to ZenNotes/znserver, PR #795. apps/server, the Dockerfile and the Docker publisher left this repository; tooling/server-release.json pins the znserver release and tooling/scripts/server-binary.mjs downloads and checksum-verifies it for dev:server, dev:web-stack and the browser harness. docker-compose.yml runs the published adibhanna/zennotes image.
  • #790: d1aa811b. #791: d7bdfa96, with packages/shared-domain/src/cloud-vault-availability.ts as the single classifier. #792: 7f1ec2ae. CLI migration groundwork: b6c3b9da (terminal-release.json, tooling/scripts/terminal-artifact.mjs, docs/specs/desktop-cli-tui-migration.md). Service worker: 019c474b. Handoff docs: 4d4932f7. Version bump: 0964cee9.
  • CI follow-ups on the release branch: 5cd4eb5f (CodeQL: launcher and binary read through one handle), 8ff2cb86 (POSIX-only suites skip on Windows).
  • Closure comments: #790, #791, #792, each linking the fixing commit with local verification steps.

In-app help (help.ts) documents the zn command, the terminal app and existing installations; the website docs mirror it (docs.blade.php CLI section, docs-sections.json zn tui entry).

Demos

No clips shipped with this release. Two of the three fixes need environments the recorder does not have (an Arch install with pkexec for #790, a Cloud account whose vault is deleted server-side for #791); the Vim block-edit clip for #792 can be recorded from the built app later and attached here and on the website entry.

Verification

  • On the v2.51.0 branch: typecheck clean; test:run app-core 2371 tests (210 files) and desktop 849 tests (58 files); terminal artifact and launcher node tests 12; web-dist lock 1; web artifact 5; npm run build 7 of 7 tasks; the built index.html carries no inline script and the bundle registers sw.js.
  • Self-hosted web shell over CDP (headless Chrome, Vite dev of this branch on 5180, the pinned znserver v2.50.4 binary on 7878 with an isolated vault and token): token sign-in and first-run skip, seeded note and task listed from the server, Cmd+P opens the note, typing saves exact UTF-8 bytes through the HTTP bridge, Tasks view shows the new task, zero browser errors.
  • Packaged app from npm run pack on the branch (dist/mac-arm64/ZenNotes.app, 2.51.0, Developer ID signed): a CDP page target exists after launch with both stores isolated and ZEN_PERF=1; first-run tour and Skip setup; seeded vault listed; Cmd+P opens a note; typing saves exact UTF-8 bytes; new note creates Untitled.md and saves its body; Tasks view shows the open task; Settings opens and the CLI, Cloud, About, Vault and Editor tabs render; zero renderer errors, zero main-process error lines.
  • CodeQL on the release PR flagged two check-then-use sequences in the new terminal runtime; fixed by reading the launcher and binary through single handles (Fix(cli): read the launcher and binary through one handle). The Windows build job then caught two suites that only run where POSIX shells exist (CLI shortcut repair, .pacman install); they skip on win32 now, matching the file's existing per-test skips.

Distribution channels

  • Release workflow: 35147840800. Linux x64 and arm64 finished first with all five installer formats each plus both updater manifests, then Windows (installer, portable ZIP, blockmap, manifest), then macOS (Apple silicon and Intel DMGs, ZIPs, blockmaps, manifest) with Developer ID signing and notarization.
  • AUR: 44f1359 in the separate zennotes-bin clone (zennotes-bin 2.51.0-1), mirrored on desktop main as 2d937d74. Downloaded tarball SHA-256 4dac4ef574eb9bb2d510a9118951a978d5334416fc1a1970235eac75e7ed8c95 matched GitHub's asset digest.
  • Nix: nix-update.yml run 35149151215 computed the hashes and opened bot PR #798, lifted exactly onto main as 4e4a7d0e and closed. nix-build.yml 35149433597 passed on main first try.
  • nixpkgs: PR #561418 restacked onto current master as zennotes-desktop: 2.45.0 -> 2.51.0 (fork commit 1b9f0c1f, body in nixpkgs-pr-body.md).
  • Homebrew: bcce447 in the tap (zennotes 2.51.0), mirrored in the repo as 53c7e107 (on the 2.51.1 release branch, which fast-forwards into main). The cask pins both DMG digests from the GitHub API (arm64 94c62da00d885d2cc5605b8ef7943f73616b5acaeb54cb4f6bedab43064946b2, x64 ffda8ae09bdf9e634329535ff98b92e70e0cb78f263139046104772330e6320c).
  • Website: the CLI docs, the terminal walkthrough and the Cloud creation-metadata allowlist went out first as website PR #26 (389833b); the 2.51.0 releases entry followed as be9a294 (full suite 796 tests), deployed, live.
  • Boundary artifacts from the tagged commit: web-2.51.0-web.hd4bbb4979ae81a3e, core-2.51.0-core.h49d73b531d346192 (app-core plus bridge-contract and shared-domain boundaries.h18d39d9887df8897), viewer-2.51.0-viewer.h98c5c0085c5fe6b4; each manifest names source 8ff2cb86, clean, and every archive digest was verified before publication.
  • Server: ZenNotes/znserver v2.51.0 embeds the web artifact above; Docker adibhanna/zennotes:2.51.0, 2.51 and latest published from that tag by the server repository's publisher (multi-arch, labels name znserver 2f3070c4). This repository pins that release in tooling/server-release.json (395e9106).
  • Go CLI: ZenNotes/tui v0.2.0 (six archives, checksums verified); the desktop pins it in 2.51.1.
  • npm run verify:channels -- 2.51.0 passed: Homebrew tap, AUR, Nix, and all seven website download redirects serve 2.51.0.

Release validation

Release PR #796's CI passed on macOS, Ubuntu, Ubuntu arm64 and Windows, plus CodeQL (after two file-system race findings in the new terminal runtime were fixed), the Arch package check and the production dependency audit, before the fast-forward. The release workflow passed every platform job. nix-build.yml 35149433597 rebuilt the desktop Nix package from the lifted hashes on main.

Local gates before the tag: typecheck, test:run (app-core 2371, desktop 849), the terminal, web-dist lock and web artifact node tests, npm run build, the mac app packaged from the branch (npm run pack, 2.51.0, Developer ID signed) exposing a CDP page target with both stores isolated and ZEN_PERF=1 and passing the desktop smoke, and the self-hosted web shell over CDP against the pinned server. The Windows runner caught two POSIX-only suites from the later work; they skip on win32 now.

The release was cut from a scratch worktree of the boundary PR head. Two lessons for the record: actions/checkout treats an abbreviated source_commit as a branch name (pass the full SHA to the artifact workflow), and zennotes-server --help starts the server, so never use it as a probe.

Don't miss a new zennotes release

NewReleases is sending notifications on new releases.