github ZenNotes/zennotes v2.54.1
ZenNotes v2.54.1

latest releases: web-2.55.0-web.h37369c6e25817727, v2.55.0, core-2.54.1-core.h75d82a521571dc20...
one day ago

ZenNotes 2.54.1: in the New note form that note search opens, the first click on Create now lands while a tag is still being typed in the Tags field; 2.54.0 lost that click (the tag turned into a chip, the footer moved, and the click missed), so the note was not created until a second click or Enter

Released on September 22, 2026 as v2.54.1, at 0285443b. The release branch v2.54.1 was cut from main at 0ccfa0b5 (the 2.54.0 release, after its channel commits) and fast-forwarded into main through PR #835. One fix, found the same day 2.54.0 shipped, while the phone shells were being moved onto its core. The commits: 591107e1 Fix(search), then the version bump 0285443b. Nothing else changed since 2.54.0.

🐛 Fixes

  • The first click on Create lands while a tag is still typed (New note form, follow-up to #826). In 2.54.0's New note form (note search, Shift+Enter or the Create row), typing a tag in the Tags field and reaching for the Create button with the mouse lost the click. The button took focus the moment the mouse went down; that blurred the Tags field, which committed the typed word as a chip, and the suggestion row under the fields ("Add #urgent", or the vault's matching tags) disappeared, so the footer with Back and Create moved up before the mouse came back up. No click fired. In the built app the button moved 44 px, the release landed on the backdrop outside the card, and the palette closed with the typed name and tag gone; with a taller suggestion list the release lands inside the card and a second click works, which is how it was noticed. Enter was never affected. Now the footer buttons (and the "Open it" button next to the duplicate warning) do not take focus on mouse-down, the same rule the folder and tag rows under the fields already followed, so nothing moves until the click completes, and create() counts the text still typed in Tags the way Enter does. One click creates the note with the tag under its heading. This is core, so the web client gets it with this version and the phones with the shell releases that adopt this core.

🧰 For contributors

  • The fix is 591107e1, two attributes in packages/app-core/src/components/SearchCreateForm.tsx: onMouseDown={(e) => e.preventDefault()} on the footer's button wrapper and on the collision "Open it" Button, each with a comment stating why (a blur commits the typed tag and unmounts the list under the fields). Tests in packages/app-core/src/components/SearchPalette.test.ts, describe "the create row opens a New note form": a press(button, focusedField) helper dispatches a cancelable mousedown and blurs the field only when the event was not cancelled, since jsdom does not move focus on its own; "pressing the mouse on Create keeps the Tags field focused, so the click lands and the typed tag counts" and "pressing the mouse on Back keeps the folder list until the click" (the six folder rows are still there after the press). Both were red on the shipped code (focus went to body, the list unmounted) and are green with the fix.
  • The live harness is tools/check-create-click-typed-tag.mjs (local, in this folder): it drives the built desktop app over CDP with both stores isolated and sends the mouse press and release through Input.dispatchMouseEvent, the only way to see the focus change and the layout shift a synthetic element.click() skips. It reads the Create button's rectangle between press and release, so the run reports how far the button moved.

Verification

  • Unit: npx turbo run typecheck --force clean, 7 of 7 tasks; npx turbo run test:run --force green, shared-domain 59 files and 1685 tests, app-core 231 files and 2646 tests (1 skipped), desktop 59 files and 891 tests (4 skipped). Red before, green after: the two new SearchPalette.test.ts cases named above.
  • Live, in the built desktop app over CDP with both stores isolated (tools/check-create-click-typed-tag.mjs), run against both builds. Sources at 0ccfa0b5 (2.54.0): after Mod+P, "Click check", Shift+Enter, two Tabs into Tags and "urgent" typed with no Enter, one real click on Create moved focus to the button, turned urgent into a chip, removed the suggestion row, moved Create up by 44 px (y 358 to 314), closed the palette and wrote nothing (tools/click-before.json, 3 of 10 checks failed). With the fix: the press left the Tags field focused with urgent still text, Create did not move (movedBy 0), one click closed the palette and wrote inbox/Click check.md as # Click check\n\n#urgent\n\n (tools/click-after.json, 10 of 10). Screenshots tools/click-before-typed-tag.png (the form with the typed tag and the "Add #urgent" row above the footer) and tools/click-after-note-open.png (the new note open with its #urgent line) inspected.
  • How to test locally: cd apps/desktop && npx electron-vite build, then node docs/releases/v2.54.1/tools/check-create-click-typed-tag.mjs after. By hand: open the app, Mod+P, type a name no note has, Shift+Enter, Tab twice into Tags, type a word without pressing Enter, click Create once. Before: the word becomes a chip and the form stays open (or the palette closes with nothing created). After: the note opens with the tag under its heading.
  • Not exercised live: the web client (same core, same SearchCreateForm) and the phone shells (they adopt this core; their Cancel-button fix for the same form is a shell CSS change and ships with the shell releases).

Distribution channels

  • Release workflow: the tag's run 35777395102 built every platform and finished green on the first attempt, 45 minutes from tag to the last upload (20:00 to 20:45 UTC on September 22). 25 installer assets, the same set as 2.54.0; no demo clips this time. macOS is Developer ID signed and notarized. Both macOS apps carry ZenNotes CLI 0.4.0 as the bundled zn (read from Contents/Resources/terminal/manifest.json inside the arm64 DMG).
  • AUR: 47e2e79 in the separate zennotes-bin clone (zennotes-bin 2.54.1-1), mirrored on desktop main as e94608fe; aur-check.yml passed (runs 35779082781 on main and 35779079003 on v2.54.1). The tarball downloaded from the release has SHA-256 b2e5cebb753a6d5f735741e9823b9c0519e36ae2a0da5ef00b9ab2417753ef7a, equal to GitHub's asset digest and to the pinned value.
  • Nix: nix-update.yml run 35779112970 opened bot PR #836, lifted byte-for-byte onto main as 240f5405 and closed with a one-line comment pointing at that commit; nix-build.yml run 35779429813 passed on main first try. desktopHash (sha256-suXOu3U6bV9zV0HpgjucBRnjauKg2l7wC5qyQXdT73o=) is the same tarball digest as the AUR pin, in SRI form.
  • nixpkgs: PR #561418 amended in place to zennotes-desktop: 2.45.0 -> 2.54.1 (fork commit b214ff95, force-pushed to zennotes-desktop-2.46.0, body in nixpkgs-pr-body.md). Only version, npmDepsHash (sha256-9FDrQVckCFMke9dAUooU68MSEinxIEXCCW3yKI24ueU=) and the source hash (sha256-/7YK3BvjxdNwar2dLH+3PI8E1IHR4TYV1GkAEQoy1ZQ=, both lifted from packaging/nix/release-data.json) change. The runbook's refetch of upstream master was skipped on purpose: git fetch upstream master against the partial clone hung with no progress (0.5 s of CPU in 15 minutes) and was killed, so the commit sits on the base the 2.54.0 restack already had.
  • Homebrew: f5d0426 in the tap (zennotes 2.54.1), mirrored on desktop main as 67be33c9. The cask pins both DMG digests from the GitHub API (arm64 46f3ed18da38f9a519aacf4a7e17cf4c6ec6c4e577ac16823c204c433eb35dbe, x64 ec7a534f69226cc18cc7bec3072bc5ee4b3ee1119ebb32b682f07b803df88792), and both equal a local shasum of the downloaded DMGs.
  • Website: no docs change for a point release; the 2.54.1 releases entry (one fix, no features, no clips) merged as website PR #34 (54db30df, a merge commit like PR #33). Laravel Cloud deployed it on its own from main; the release page answered with 2.54.1 within four minutes of the merge (20:57 to 21:01 UTC).
  • Docker and the server: unchanged by this release.
  • npm run verify:channels -- 2.54.1: passed at 21:00 UTC: Homebrew tap, AUR, Nix, and all seven website download redirects serve 2.54.1. releases/latest on GitHub answers v2.54.1. The live release page leads with 2.54.1 (47 documented releases).

Release validation

  • Release PR #835's CI run 35776341766 passed first try; the fix is core-only (SearchCreateForm.tsx and its tests), so no packaging change was needed and the branch was fast-forwarded onto main without a merge commit.
  • Before the cut, on the bumped branch: npx turbo run typecheck --force 7 of 7 and npx turbo run test:run --force green (shared-domain 1685, app-core 2646 with 1 skipped, desktop 891 with 4 skipped), and the fix itself checked live over CDP with real mouse events against both the shipped and the fixed build (tools/check-create-click-typed-tag.mjs: shipped code moved Create by 44 px and wrote nothing, fixed code moved it by 0 and wrote the note with its tag, 10 of 10 checks). A local npm run pack also produced dist/mac-arm64/ZenNotes.app at 2.54.1, but the launch check was run on the released artifact (below), not on that local pack.
  • The release workflow's tag-push path behaved as it did for 2.54.0: each platform's installers went up one at a time and its update manifest last (Linux: assets 20:13:40 to 20:14:22, latest-linux-arm64.yml 20:14:20, latest-linux.yml 20:14:23 UTC; Windows: exe 20:37:42, blockmap 20:37:43, zip 20:37:51, latest.yml 20:37:52; macOS: DMGs and zips 20:44:25 to 20:45:08, latest-mac.yml 20:45:09). macOS was the slowest job at 45 minutes (20:00:27 to 20:45:17). No asset was uploaded twice and nothing had to be rebuilt.
  • Verified by hand after the uploads: the three installers named by the manifests that verify-installers.py covers (ZenNotes-2.54.1-mac-arm64.dmg, ZenNotes-2.54.1-mac-x64.dmg, ZenNotes-2.54.1-win-x64.exe) were downloaded in full and match the size and SHA-512 in their manifest (verify-installers.py 2.54.1 --download, "ALL GOOD"); the arm64 macOS app is accepted by Gatekeeper as Notarized Developer ID (Lumary Labs LLC) with a valid stapled ticket (spctl -a -vv accepted, stapler validate worked), reads version 2.54.1 and bundles zn 0.4.0; the released arm64 app, copied out of its DMG, launches with both stores isolated (packaged-launch-check.mjs: CDP page target in 2.5 s, version 2.54.1, Welcome screen rendered), so the artifact users download was launch-checked, not only the local pack. The x64 app was checksum-verified but not mounted or launched.
  • Expected red marks, none of them about the release: runs 35779270900 (CI), 35779270988 (Nix build) and 35779271129 (CodeQL) started on the bot branch nix/update-v2.54.1 and lost their branch when PR #836 was closed (each shows no jobs at all), and CI run 35779083328 on main (the AUR packaging commit e94608fe) was cancelled by the next push, the Nix packaging commit 240f5405, which CI then ran on and passed. The same pattern appeared on 2.54.0 and 2.53.0. The runs that count, on main, passed.

Local-first and keyboard-first, as always.

Don't miss a new zennotes release

NewReleases is sending notifications on new releases.