github ZenNotes/zennotes v2.37.0
ZenNotes v2.37.0

5 hours ago

ZenNotes 2.37.0: Atlas answers, callouts close once, server boards stay put

Atlas region keys work the moment the map opens, the callout picker respects auto-paired brackets, a task note with no status stays in "No status" on server-backed boards, and the web client's MCP tab no longer blanks the app.

🐛 Fixes

  • Atlas [ and ] work right after Space g. (#670, reported by @uNyanda) The region keys did nothing in a freshly opened Atlas until a click landed inside the map, and that click drew a white focus ring around the pane. #657 taught the global Vim layer to yield brackets to the map, but the yield was keyed off document.activeElement, and opening the map through the leader blurs focus to the page body, so the first bracket was still swallowed as a [b / ]b buffer-sequence prefix. Ownership now comes from the store: the map holds the keyboard whenever its tab is active and no other panel has claimed it, the Vim layer stands down on that, the map takes real focus so every focus-based check agrees, and the focus ring is gone. How to test locally: Vim mode on, open a note, press Space g, then ] or [ immediately. Before: nothing until you click the map. After: the region changes on the first press, with no white border.

  • The callout picker keeps the auto-paired ]. (#671, reported by @uNyanda) With Auto-pair brackets on, typing > [! already leaves a ] after the caret, and picking a type produced > [!quote] ]. The picker now absorbs an existing closer the way the wikilink picker absorbs its ]], reuses a space that already follows it, and lands the caret after the header ready for a title. How to test locally: enable Settings → Editor → Writing → Auto-pair brackets, type > [! in a note, pick Quote. Before: > [!quote] ]. After: > [!quote] .

  • A task note with no status: stays in "No status" on the Custom status board. (#672, reported by @ShowhyT) Every task parser synthesized status: open for a note tagged task whose frontmatter said nothing and put that default into the task's custom fields. The note sat in an "Open" column wearing a phantom @status:open chip, and dragging it into "No status" (which clears the key) painted the move only for the next rescan to undo it; on a server vault the watcher echo arrives a beat later, so the card visibly bounced between the two columns. open is now treated as the note's effective state, not a chosen status: the TypeScript parser and the Go server keep it out of fields unless the frontmatter sets status: explicitly, while checked, cancelled and in-progress still derive from the default. Both server and app need 2.37.0. How to test locally: run the 2.37.0 server and app, create a note with tags: [task] and no status:, open Tasks → Kanban → Group by: Custom status. Before: the card flickers between "Open" and "No status" on every move. After: it sits in "No status" until you move it; a drag into a column writes status: to the note, a drag back removes it, and both stick.

  • Settings → MCP in the web client no longer blanks the app. (#672, reported by @ShowhyT) The web bridge answered the runtime query with an ad-hoc object, the page read runtime.args during render, and React unmounted the whole app into a dark window. The runtime contract gained an unavailableReason, the web bridge returns a well-formed runtime carrying it, and the tab shows a "Desktop only" notice explaining that MCP integrations are set up from the desktop app, whose bundled MCP server reads a vault folder on that machine. How to test locally: open the web client on a self-hosted server, Settings → MCP. Before: a blank window until reload. After: the notice.

🧰 For contributors

  • atlasHoldsKeyboard in lib/atlas.ts is the one answer to "does the map own single keys": VimNav's buffer sequences and the map's own listener both use it, the map focuses its root when it owns the keyboard, and openAtlasView only blurs something that is not the map.
  • calloutTypeSource's apply step replaces through an existing ] after the caret and skips a duplicate space; tests cover auto-pair on and off.
  • File-task parsers (parseTaskFile in shared-domain and parseTaskFile in the Go server) only put an explicit frontmatter status: into fields; status keeps the effective default open, and Go's Fields stays an empty map (never nil) so the JSON reads {}. The MCP copy never reported fields for file tasks and is unchanged; the iPhone vault-core has no file-task fields either.
  • McpServerRuntime.unavailableReason marks a build with no MCP runtime; McpSettings renders the notice and skips the client list and prompt editor when it is set.
  • Demo clips this cycle carry burned captions (PIL over the CDP frame sequence, plus a .vtt sidecar) instead of caption-less clips.

Local-first and keyboard-first, as always.

Don't miss a new zennotes release

NewReleases is sending notifications on new releases.