ZenNotes 2.65.0 gives Workflows tag lists and a no-tags step, makes Vim mode copy a rendered table as a table (and stops ⌘C from emptying one), keeps Vim keys working in the Tags view, says where a new task went, and stops ZenNotes freezing when it is started from a terminal on Linux.
Released from 21ebc827 through #915 on 2026-10-09. All installers are verified.
Features
- Workflows: tag lists and a
no-tagsstep.tag,taggedandnot-taggedtake a comma-separated list and match any tag in it, sotagged #book, #articlekeeps a note carrying either andnot-tagged #someday, #referencedrops both. The newno-tagsstep keeps only the notes with no tag at all, in the frontmatter or the text, soall | no-tags | move reviewgathers every untagged note into one folder to look through. Completion, the canvas and the step inspector all take the list, and the file always saves it as#a, #b. Tags separated only by spaces (not-tagged #a #b) are an error that shows the comma form: they used to run asnot-tagged #awith a warning, and reading them as a list now would quietly change what an existing workflow touches. Asked for by Tornado300 on Discord. - Copy or duplicate a rendered table from its menu. The table menu (right-click a cell, or
min Vim mode) gains Copy table as Markdown and Duplicate table, which inserts a copy below.
Fixes
- Vim mode copies a rendered table as a table. Shift+V on a rendered table's rows, then
y, now yanks Markdown table rows (the header and its divider row come along when the selection starts there), sopin the note pastes a working table; before, the rows came out as tab-separated cell text pasted into the middle of a line. Worse, ⌘C (Ctrl+C on Windows and Linux) on a Vim selection inside a table reached the table as Vim'sc(change): the selected cells were emptied, and the Escape after it saved the blank table to the note. ⌘C now copies the selection and leaves it alone, and ⌘X cuts it. Reported by Tornado300 on Discord. - Vim keys keep working in the Tags view. One click on a heading or a tag chip inside the Tags view handed the keyboard to the editor, so
jandkstopped moving the cursor until the view was reopened. They keep working now, and pane navigation (Ctrl+W h/l, Alt+h/l) now targets the Tags view in its spot instead of the editor hidden behind it. Reported by Tornado300 on Discord. - A new task says where it went. New Task from the palette or
:newtaskwrote the task file and showed nothing unless the Tasks view happened to be open. Created anywhere else, it now says "Task added" with an Open button that opens the new task. On the Tasks view, where the new row is the answer, it stays quiet. The phone apps get the same when they adopt this release, with a one-tap Task button (zennotesandroid#101). - ZenNotes started from a terminal no longer freezes (Linux). To find
zn, node and the search tools, ZenNotes asks your shell for its PATH, and an interactive shell started from the same terminal could take it over: with zsh, an rc file that prompts left Settings → CLI on "Checking install status..." for good, and with bash,zennotes &stopped the whole app before its window came up. The probe now runs without a terminal, a stuck shell is killed after five seconds, and callers share one probe. Reported by Julie on Discord. - The sidebar scrollbar is the soft tint it was meant to be. Its 30% opacity never applied (scrollbar parts ignore
opacity), so the thumb painted at full text color; it is now a 30% tint, 50% on hover, in every theme. - Help: Vim users can find how to check off the task under the cursor: ⌘L (Ctrl+L on Windows and Linux) works from normal, insert and visual mode, and Help → Vim & Ex now lists it.
For contributors
- Workflows (
packages/shared-domain/src/workflows): atagsparam type binds the remaining tokens as one comma-separated list (coerceTagListinnodes.ts);joinTagListis the single stored form for the parser and the inspector (no#, comma-joined, case-insensitive dedupe), andtagListTextwrites#a, #b. Space-only separation is an error on purpose, and so is an empty entry; an errored statement plans no writes. The step isno-tags, notuntagged, because a step kind wins over a wire of the same name anduntaggedis a natural wire name. Completion continues a list only after a comma and completes the entry under the caret,#a,#bincluded. - Tables (
packages/app-core/src/lib/cm-table.ts):isAppChordhands Cmd and Ctrl chords to the app instead of the cell's Vim, except Ctrl+R, Ctrl+Alt (AltGr) and whatever the pane moves are bound to; a line-visual yank stores linewise Markdown rows through the Vim register. - Tags view: the view re-claims
focusedPanelon its root with capture handlers, as Tasks and Atlas do (the editor pane claims it for any click inside it), andgetVisiblePanelslists the Tags view in the editor's slot. - Toasts:
ToastHostcarriesdata-toast-host, the hook the phone shells use to lift toasts above their floating button. - PATH probe (
apps/desktop/src/main/login-shell-path.ts): the login shell runsdetachedwith stdin ignored, and a timeout kills its whole process group.
Demos
In docs/releases/v2.65.0/media/ (local), 1080p with captions burned in and a .vtt beside each, recorded on the 2.65.0 build with a scratch vault and Vim mode on:
- workflow-no-tags.mp4 (11 s): "Untagged to review" (
all | no-tags | move review) runs on six notes and moves the three without a tag toreview/(one of them has#notatagonly inside inline code); the note tagged only in its frontmatter stays. Then the "Reading list" workflow showstagged #book, #article. - table-copy.mp4 (14 s):
V j j j yon a rendered table,jpast its last row,G,p: a second, working table appears below. Thenmopens the table menu with Copy table as Markdown and Duplicate table. - task-added.mp4 (12 s):
:newtaskfrom a note, a title, Enter: "Task added" with Open, which opens the new task note. - tags-view-keys.mp4 (10 s):
jmoves the cursor in the Tags view; after a click on the view's heading,kandjkeep moving it.
Verification
How to test locally (Vim mode on): build and launch with isolated stores, npm run build --workspace @zennotes/desktop, then ZENNOTES_USER_DATA_PATH=$(mktemp -d) ZENNOTES_CONFIG_DIR=$(mktemp -d) npx electron apps/desktop/out/main/index.js, and open a vault with a few notes.
- Table copy. In a note with a pipe table and a line below it, press
juntil the cell cursor is in the table, thenV j j y,juntil the caret leaves the table below its last row,G,p. Before: tab-separated cell text pasted into that line. After: a Markdown table on its own lines. Then select rows again withV jand press ⌘C: before, the cells emptied and the Escape that followed saved the blank table; after, the cells stay and the clipboard holds the rows. Pressmin a cell for Copy table as Markdown and Duplicate table. - Tags view. Type
:tag <a tag>and Enter, pressj, click the "Tags" heading, then pressjandk. Before: the cursor stops moving after the click. After: it keeps moving. - Workflows. Turn on Workflows (Settings → Workflows), press
Space a, create a workflow with the lineall | no-tags | move reviewand run it: every note without a tag moves toreview/, and a note tagged only in its frontmatter stays.all | tagged #a, #bkeeps either tag;all | not-tagged #a #bis an error that shows the comma form. - New task. In a note, Esc then
:newtask, type a title, Enter. Before: nothing on screen changes. After: "Task added" with Open, which opens the task. From the Tasks view's "+ New task" there is no toast. - Terminal launch (Linux). With bash, start the app in the background from a terminal (
zennotes &): before, no window ever appeared; after, it opens, and Settings → CLI finishes "Checking install status...".
Distribution channels
- GitHub release: installers for macOS (Apple silicon and Intel DMG and zip), Windows (x64 installer and zip) and Linux (x64 and arm64 AppImage, deb, rpm, pacman, tar.gz), with the four update manifests.
- AUR:
zennotes-bin2.65.0-1 (AUR cloneddf02c6, repo8a6dbfda), pinned toZenNotes-2.65.0-linux-x64.tar.gzSHA-256934c681b…a53a(GitHub's own digest for the asset), after the bump script checked the bundled CLI folder is world-readable; bothaur-checkruns passed. - Nix:
packaging/nix/release-data.jsonlifted from the update workflow (run 37960377584, bot PR #916 closed) as6548d082; itsdesktopHashis the same digest as the AUR pin, and nix-build on main passed. - nixpkgs: NixOS/nixpkgs#572180 proposes 2.64.0 -> 2.65.0 (the 2.64.0 PR merged upstream on October 9); the source hash comes from the tag tarball, and the same command reproduces master's 2.64.0 hash.
- Homebrew:
zennotes2.65.0 in the tap (bf6a069), mirrored in614d4cab; both DMGs were downloaded and their SHA-256 matches the cask and GitHub's digest;brew styleclean. - Website: ZenNotes/website#65 merged at
c69e3c0a: the releases page with the four clips, this release's docs (the table menu and Vim table copy, workflow tag lists andno-tags, and ⌘L for the task under the cursor), and the share viewer moved from 2.64.0 to 2.65.0. Its main tests and deploy passed (run 37963502772), Laravel Cloud's deployment succeeded at 17:10 UTC, and zennotes.org serves the 2.65.0 release entry, a clip byte for byte, the new docs, and the 2.65.0 viewer next to the retained 2.64.0, 2.63.0 and 2.51.0 ones, each matching its pinned hash. - zn CLI: unchanged; this release bundles 0.6.3, and no CLI code has changed since.
- Server: ZenNotes/znserver v2.65.0 pins the published
web-2.65.0-web.h42fe629130380f61browser artifact; Dockeradibhanna/zennotes:2.65.0,2.65andlatest(linux/amd64 and arm64, one digeste4e8ac11…); README znserver#19 fast-forwarded. - Phones: iPhone 1.21.0 (37) and Android 1.1.35 (38) on
core-2.65.0-core.hd55341f2a13486b9(published). Both add a create row: tap the circle and Quick, Note and Task sit along the bottom, one tap each, with + for templates, databases and folders; New task is in the Create sheet too, and a new task says "Task added" with Open (zennotesandroid#101, asked for by mptpro). They also carry their dependency updates (zennotesios#52, zennotesandroid#104). iPhone 1.21.0 is waiting for App Review, and Android 1.1.35 goes to Play review next.
Release validation
Cycle checks:
- Each fix was reproduced in the built app over CDP on an isolated profile before it was changed, and checked again after: the Vim table copy (the ⌘C run saved a blank table to disk on 2.64.0), the Tags view keys after a click,
no-tagsand the tag lists end to end in the Workflows view (including the inspector's tag-list field), and the "Task added" toast with Open. The terminal-launch freeze was reproduced and fixed on Linux (Ubuntu 26.04) with the 2.64.0 tarball under a pty. - New tests fail against the old code where they pin a behavior change: 5 of 7 in
cm-table.test.ts(the other 2 drive menu items that did not exist), the Tags view panel order invim-nav.test.ts, 15 of 22 in the workflow tests (the other 7 guard what must not change), and the three probe tests inlogin-shell-path.test.ts.
Release-time gates on 21ebc827:
npm run typecheck8/8 andnpm run test:run6/6 with no turbo cache: shared-domain 1,921, app-core 3,140, quicklook 15 and desktop 1,055 tests passed.npm audit --omit=dev --audit-level=highis clean (15 low or moderate advisories remain, in dompurify, fast-uri, ip-address, katex, smol-toml and sprintf-js).npm run packsigned the app on the first try; deep strict codesign passes, the pack log shows electron-builder's "skipped macOS notarization" next to the hook (CI notarizes), and the app bundlesznv0.6.3 in a world-readableResources/zn-cli. Packaged launch check: a page target in 1.4 s reporting 2.65.0.- Smoke suites on the built app:
test:vim-editor,test:sidebar-vimandtest:editor-improvementspassed on their first run. - PR #915: all nine checks passed on
21ebc827(macOS, Windows, Ubuntu x64 and arm64 builds, the installed-editor browser check, the candidate check, CodeQL and the production audit);mainfast-forwarded to it and the annotated tagv2.65.0started release run 37958415297. - The release run published every platform in one pass: Linux arm64 in 14 minutes, Linux x64 in 15, Windows in 21 and macOS in 41. Each Mac app was notarized once: the log shows electron-builder's "skipped macOS notarization" and then one
[notarize]pass per architecture (arm64 2 minutes 17 seconds, x64 2 minutes 37 seconds). - All four update manifests and the 13 files they name passed size and downloaded SHA-512 verification. The apps in both DMGs passed notarization (
Notarized Developer ID), staple and strict deep signature checks, report 2.65.0 and carryZenNotesQuickLook.appexand a world-readableResources/zn-cli(the arm64znreports v0.6.3). GitHub latest is v2.65.0, andverify:channels -- 2.65.0passed for Homebrew, AUR, Nix and all seven website download routes.