ZenNotes 2.69.0 lets AI assistants reach a ZenNotes Server that needs a token, with one click in Settings instead of a terminal, and makes zn connect work for every MCP install. Setup no longer asks a server vault for a layout, the Claude integrations say which tab of the Claude app they reach, the New note form in search names the keys of the field you are in, and a Cloud vault that another device encrypted reads as encrypted, not deleted. Shortcuts no longer act behind What's New, Settings or a palette, and the phones can now start a note in the folder they are browsing.
Released from d1344076 through #934 on 2026-10-13. All installers are verified.
New
- Assistants reach your ZenNotes Server without a terminal (#830). When the app is connected to a ZenNotes Server that needs a token, Settings → MCP → Server token now offers Let assistants use it. It saves the token the app connects with where
zn connectsaves it, so Claude Code, Codex and any other assistant you installed from Settings → MCP reach the server on their next call, with no terminal and no typing the token a second time. It is your choice, and the section says why: the app keeps its own copy in your system's secure storage, which no assistant can read, and sharing puts a copy in a private file that programs running as you can read. Stop sharing takes it out again. The shared copy follows the app: saving a new token for the server replaces it, and forgetting the server in Settings → Vault removes it. A token you saved yourself withzn connectis never touched. Thanks to Kevin (@diazkev314) for the report and for asking for exactly this. - Start a note in the folder you are browsing, on the phones (ZenNotes/zennotesandroid#108, #923). Browse on Android and iPhone gains a New note row above New folder, in every folder and at the top level. It opens a new note inside the folder you were looking at, with its title selected so you can type the name. Until now a note could only start at the top and then be moved. The part inside ZenNotes ships here; the row arrives with the next Android and iPhone updates. Thanks to @davi-jorge-art for the request.
Fixes
- After
zn connect, every MCP install reaches the server (#830). With the app connected to a token-protected server, an assistant could keep answering "The MCP server has no valid token for this ZenNotes server" even afterzn connect, as the manual says to run. Install registers one of two MCP servers:zn mcpwhenzncame from Settings → CLI, and otherwise the server bundled with the app (aznfrom Homebrew and every Windows install included). Onlyzn mcpread the tokenzn connectsaves. Both do now, for the server the app is connected to, and the call afterzn connectworks without restarting the assistant. The error now names the exactzn connect <url> --no-defaultto run, and the new Server token button first. Thanks to Kevin (@diazkev314). - Setup skips the layout step for a server vault. Connecting to a ZenNotes Server in the setup wizard went on to ask how the vault should be organized, a choice the server's vault has already made for every app connected to it. Clicking through it could change the layout for the phones and the web app too. Setup now goes from the vault straight to Done for a server vault; a folder on this machine still gets the layout step. Thanks to Kevin.
- The Claude integrations say which tab of the Claude app they reach. Settings → MCP read "Claude Code" and "Claude Desktop", which looks like one entry per app. But the Claude desktop app's Code tab runs Claude Code and uses the Claude Code entry, while the Claude Desktop entry reaches only its Chat tab. They now read Claude Code (CLI + Desktop Code tab) and Claude Desktop (Chat). Kevin suggested the names.
- The New note form in search names the keys of the field you are in (#933, by @uNyanda). The form's footer always offered
↑↓ pickand↵ create, which was wrong in most fields: arrows only move through the folder and tag lists, and Enter picks the highlighted row when there is one. Now in Name it reads↵ create note; in Folder↑↓ pick, and↵ choose folderonce a row is highlighted; in Tags↵ add tag; and text that is not a valid tag drops the Enter hint, while the line above says why. Thanks to @uNyanda, who also wrote the component's first tests. - Cancelled tasks no longer count as open for assistants (#929, by @vishalhabib99). The MCP
list_taskstool's open filter andzn task listlisted[-]cancelled tasks next to the ones still to do, although the calendar and Kanban already leave them out. They are left out now;status: alland--allstill show them. The Gozndoes the same from 0.7.1. Thanks to @vishalhabib99. - A Cloud vault that another device encrypted says so. When one device moves a Cloud vault to end-to-end encryption, the other devices linked to the old vault are told it was replaced. The desktop app stopped syncing it but said "Cloud vault deleted", and the phones kept the link and repeated "Update ZenNotes on this device" on every sync, even when up to date. Now every app stops syncing the old vault, the status bar says Cloud vault now encrypted, and Settings says the vault was replaced by an end-to-end encrypted one and how to open it: unlock encryption on this device if needed, then choose the encrypted vault. The phones get this with their next update.
- The manual shows bold names and paragraphs. Thirteen entries of the in-app manual printed
**around the names of buttons and settings, and longer guides ran their paragraphs together. They now read as intended, and a search phrase that runs through a bold name finds its entry. The end-to-end encryption entry also names the right button (Save archive under Backups, in the desktop app; the phone apps send you there) and says what other devices do when a vault is encrypted. - Shortcuts no longer act behind What's New, Settings or a palette. What's New opens by itself on the first launch after an update, so the keys you press out of habit land on it, and none of them knew it was there: Cmd+P opened a note search underneath it that you could not see and took your typing, Cmd+N and Shift+Cmd+N made a note behind it, Shift+Cmd+P opened the command palette and Cmd+, opened Settings under it. Now no shortcut acts behind What's New; its own buttons, Tab and Escape still work, and Cmd+, (or Settings… in the macOS menu) replaces it with Settings. Behind Settings or any palette, Ctrl+Tab (previous note), Alt+Left and Alt+Right (note history) and Shift+Cmd+T (reopen closed tab) switched the note you would come back to, and Shift+Cmd+N made a Quick Note and moved your typing into its hidden title. They wait until the overlay is closed, as tab switching already did. Found while recording this release's demos.
- The Tasks calendar's keys no longer change tasks behind a dialog. With the calendar open under Settings, What's New or a palette, Space on one of the dialog's buttons marked the selected day's task done (x in Vim mode), Tab moved through the calendar's tasks instead of the dialog's buttons, and in Vim mode dd deleted a task. The calendar now leaves the keyboard to the dialog, as the task list and the board already did.
- An encrypted vault shows its name as soon as you unlock. Settings → Cloud showed an encrypted vault as "Encrypted vault" until this device unlocked encryption, and kept showing that after unlocking until Settings was opened again. It reads the list again when you unlock or lock. On the phones, an encrypted vault's backups no longer offer Save archive, which could only fail there; they say to use Save archive in the desktop app.
- Settings on the phones and iPad offers only what the device has. Settings search listed the settings of sections the phones hide, so "review" offered Review agent edits and a tap opened an empty page; and Settings → Keymap on an iPad (and in the web app) listed the keys for reviewing an assistant's edits, which only the desktop app can do, and the grammar keys where grammar checking is not available. With the next phone updates.
For contributors
- MCP token lookup (#830,
ef122a4b):apps/desktop/src/main/remote/zn-credentials.tsreads and writes zn'scredentials.toml([tokens], keyed by the URL trimmed, without trailing slashes, lowercased;0600; atomic replace; a file not in zn's format is never overwritten, and errors never quote it), in the portable config dir (ZENNOTES_CONFIG_DIR, thenXDG_CONFIG_HOME/zennotes, then the platform default). The bundled MCP server (apps/desktop/src/mcp/vault-ops.ts) and the TypeScriptzn(apps/desktop/src/cli/vault-target.ts) resolve a server's token as--token,ZENNOTES_REMOTE_TOKEN, a legacy profile token, then the saved one, the Go server's order, for the URL the app already chose, so a saved token never picks a server. - Server token (
dd0f929b):apps/desktop/src/main/mcp-server-token.ts(statesnonewith a reason,missing,shared,different,unreadable; share, remove only the app's own token, andfollowAppServerTokenon profile save and delete), receipts inuserData/mcp/shared-server-tokens.json. The main process picks the server from the persisted workspace, the way both MCP servers do, and reads the token from the secret store; IPCMCP_SERVER_TOKEN_STATE,_SHAREand_REMOVEtake no arguments from the renderer, which only ever sees the state. The bridge methodsmcpGetServerTokenState,mcpShareServerTokenandmcpRemoveServerTokenare optional and desktop only (faa8f873): the phone bridges implementZenBridgetoo, and a required method broke their typecheck against core 2.69. UI:McpServerTokenSettinginSettingsModal.tsx, Settings search idmcp-server-token. - Onboarding (
ed6fb808):OnboardingWizard.tsxtakes its steps from the workspace mode (visibleSteps,stepAfter); connecting sets the vault and the mode in one store update, so the auto-advance already knows the next step, andgoToStepnow records the step it lands on (the rail could not move forward to it after Back). The web app reports no remote workspace and keeps the layout step, which is how a new server vault gets made. - Create form hints (#933,
bcc52592, follow-upfb9c6fcc):SearchCreateForm.tsxderives↑↓and the Enter label from the focused field and reads the highlighted row exactly the way the Enter handlers do, so a list that shrinks under the highlight (a sync dropping a tag while the form is open) cannot make the hint lie.SearchCreateForm.test.tsis the component's first test file,.tsbecausevitest.config.tsonly includessrc/**/*.test.ts. - Cancelled tasks (#929,
c0d25dd2):list_tasksinapps/desktop/src/mcp/server.tsandzn task listinapps/desktop/src/cli/commands/tasks.ts; the Go mirror is ZenNotes/tui91bb33b(zn 0.7.1). - Superseded vaults (
00c592bb):packages/shared-domain/src/cloud-vault-availability.tsowns the check (isCloudVaultSuperseded: aCloudServiceRequestErrorwith 410 andVAULT_SUPERSEDED) andCLOUD_VAULT_SUPERSEDED_MESSAGE.CloudSyncHostService, the phones' sync host, retires the link on it during a sync and the background remote-changes check, as it does for a 404; the desktop main process uses the same two pieces. app-core's removal notice gains a third reason,encrypted. - Manual rendering (
a72e97c9):packages/app-core/src/lib/help-rich-text.tsx(renderHelpRichText,helpSearchText):**bold**only outside code spans, a blank line starts a paragraph (block spans, since a section description sits in a<p>). Deliberately not the task cards' inline-markdown renderer: the manual mentions[[43 times and shows link syntax as examples to type.help-rich-text.test.tsrenders every manual string and fails on any**left outside code. - Browse (
f9e219b2):requestCreateBrowseNote(host, directory)in the browse boundary besiderequestCreateBrowseFolder, with the same guards, creating throughcreateAndOpenwith the title focused. The phone shells add the row: ZenNotes/zennotesandroid4523a8b(in #111, version 1.1.39) and ZenNotes/zennotesiose5b5928(in #59, version 1.25.0). - MCP integration labels (
504c1551):packages/shared-domain/src/mcp-clients.ts; Settings search keywordcode tab. - Shortcuts behind overlays (
12908407): inApp.tsx, the capture-phase handler (Mod+P, Mod+N, pane focus and modes) addswhatsNewOpento the overlays it bails for; the bubble-phase handler returns at once while What's New is open, exceptglobal.openSettings, which closes it and opens Settings (theonOpenSettingslistener does the same for the macOS menu, which takes Mod+, before the page). The overlay check that guarded tab selection and the template pickers (tabSelectBlocked, nowoverlayOpen) moves to the top of the handler and also guardsglobal.newQuickNote,global.historyBack,global.historyForward,global.toggleRecentNoteandglobal.reopenClosedTab. View toggles and the command palette's own toggle are unchanged. Harnesses:docs/releases/v2.69.0/whats-new-overlay/(local). - Tasks calendar (
6da71c43):TasksCalendar.tsx's capture-phase window handler bails onisOverlayOrDialogOpen(), likeTasksViewandTasksKanban. - Settings per host (
803ae295): each Settings search result carriesdata-settings-result-category(the section id), which the phone shells use to hide the results of the sections they hide;keymapAvailableOnHostinlib/keymaps.tsleaves theeditor.review*/vim.review*keys out withoutsupportsAgentEditReviewand thevim.harper*keys withoutsupportsHarper. - Encrypted vaults in Settings → Cloud (
d1344076):CloudSettingsreads the vault list again when the encryption status'sunlockedchanges (not on the first status); the new optional capabilitysupportsEncryptedBackupArchive(set by the desktop preload) decides whether an encrypted vault's backups offer Save archive. - Phone shells (on their release branches): Settings search hides the results of hidden sections (Android
b6fea3f, iPhone6fa07b5); an assistant's edit record (.zennotes/agent-edits/<note>.json) is a third sidecar invault-fs.ts, moving with renames, moves, Trash and folder renames, going with deletes and Empty Trash, and never inherited by a new note (Androiddc6cb34, iPhone329ee69); the shells' own strings drop the long dash (Androidd72ec37, iPhonec17556a). - Bundled CLI: zn 0.7.1 (
69342fa3), itsterminal-release.jsoncopied byte for byte after it verified againstzn-release-1(source commit91bb33b, protocol 1, all four archives matchingchecksums.txt); the staged darwin-arm64 binary reportszn v0.7.1. It carries #929's task filter and a token message that names the Server token button. - What's New: the 2.69.0 entry in
packages/app-core/src/lib/whats-new.ts(87c7e216). - Docs: the in-app manual's MCP card (which server Install registers when, the Code tab, the Server token paragraph) and CLI card; on the website, the MCP section, the Server token docs, the encryption notice, and the CLI version mentions (
website/docs-2.69).
Demos
In docs/releases/v2.69.0/media/ (local), 1080p with captions burned in and a .vtt beside each, recorded on the 2.69.0 build with scratch vaults; the server clips run a real ZenNotes Server with a token and a real MCP client named claude-code driving the app's own MCP server:
- setup-server-vault.mp4 (12 s): the setup wizard connects to a ZenNotes Server with its token and goes from the vault straight to Done, with no layout step.
- server-token.mp4 (25 s): Settings → MCP shows the renamed Claude entries; Server token's Let assistants use it saves the token where
zn connectwould; then Claude Code creates a note on the server through MCP and it shows up in the app. - new-note-hints.mp4 (28 s): search for a note that does not exist, open the New note form, and watch the footer follow the field: Name, Folder (pick and choose
Inbox › Projects), Tags (add#launch), text that is not a tag, then Create.
Verification
How to test locally. Build once with npm run build --workspace @zennotes/desktop and launch with isolated stores: ZENNOTES_USER_DATA_PATH=$(mktemp -d) ZENNOTES_CONFIG_DIR=$(mktemp -d) npx electron apps/desktop/out/main/index.js. For the server steps, run a ZenNotes Server with a token, for example ZenNotes/znserver's go run ./cmd/zennotes-server with ZENNOTES_VAULT_PATH=<folder> and ZENNOTES_AUTH_TOKEN=<token> (it listens on 127.0.0.1:7878).
- Setup for a server vault. With a fresh profile, the wizard opens. On the Vault step choose Connect to ZenNotes Server, enter
http://127.0.0.1:7878and the token. Before: the next step was "Vault layout". After: "You're ready to write", and the step rail reads Welcome, Vim mode, Theme, Vault, Done. Back returns to Vault; Choose vault folder with a local folder still leads to the layout step. - Server token. Connected to that server, open Settings (Cmd+,) → MCP. The Claude entries read "Claude Code (CLI + Desktop Code tab)" and "Claude Desktop (Chat)". Under Server token, the section says assistants can't reach the server yet. Choose Let assistants use it:
credentials.tomlin your config dir now holds the server's URL and token (mode0600), andzn --server http://127.0.0.1:7878 vault infoanswers withoutzn connect. Stop sharing removes the line and zn is refused again. A local vault shows a one-line note instead of the button. - zn connect reaches the bundled MCP server (#830). Without sharing, run
zn connect http://127.0.0.1:7878 --no-defaultand enter the token, then call any tool from an MCP client runningapps/desktop/out/main/mcp.jswithELECTRON_RUN_AS_NODE=1and the sameZENNOTES_CONFIG_DIR. Before: "no valid token for this ZenNotes server" in the same session and a fresh one. After: the next call reads the server's vault. - New note form hints (#933). Press Cmd+P, type a name no note has, press Shift+Enter. The footer reads
↵ create notein Name; Tab to Folder:↑↓ pick, and after ↓↵ choose folder; in Tags, ↓ gives↵ add tag; type!!!and the Enter hint disappears while the line above explains. Before:↑↓ pickand↵ createeverywhere. - Cancelled tasks (#929). In a vault with
- [ ] openand- [-] dropped:zn task list(and the MCPlist_taskswith its default open filter) lists only "open";--alllists both. - The manual. Open Help (or
:help) and search "Encrypt a Cloud vault": two paragraphs and bold button names, no**. Search a phrase that runs through a bold name, like "choose encrypt this vault in settings": the entry is found. - Shortcuts behind What's New. Launch with a fresh
ZENNOTES_USER_DATA_PATHand an existingconfig.tomlinZENNOTES_CONFIG_DIR(that marks a returning user, so What's New opens). Press Cmd+P and type: before, a hidden search took the text and Escape revealed it; after, nothing happens behind the window. Cmd+N: before,Untitled.mdappeared in the vault; after, nothing. Cmd+,: What's New closes and Settings opens. With What's New closed, open two notes, then Settings, and press Ctrl+Tab: before, the note under Settings changed; after, it stays. - Tasks calendar. Put a task due today in a note, open Tasks → Calendar, open Settings (Cmd+,) and click Appearance, then press Space. Before: the task was marked done on disk. After: unchanged, and Space toggles it again once Settings is closed.
- Phones (once the updates are out): Browse, open a folder, New note: the note opens in that folder, title selected. Settings → search "review": no Review agent edits.
Distribution channels
- GitHub release: installers for macOS (Apple silicon and Intel DMG and zip), Windows (x64 and ARM64 installer and zip) and Linux (x64 and arm64 AppImage, deb, rpm, pacman, tar.gz), with five update manifests.
- AUR:
zennotes-bin2.69.0-1 (AUR clone281358c, repo97a16340), pinned toZenNotes-2.69.0-linux-x64.tar.gzSHA-2564e790b5c…208e(GitHub's own digest for the asset), after the bump script checked the bundled CLI folder is world-readable; aur-check passed. - Nix:
packaging/nix/release-data.jsonlifted from the update workflow (run 38431006332, bot PR #935 closed) ase0fd70cf; itsdesktopHashis the same digest as the AUR pin, and nix-build on main passed. - nixpkgs: NixOS/nixpkgs#572180, still waiting for review, now proposes 2.64.0 -> 2.69.0 (
b5870af); the source hash comes from the tag tarball, by the same prefetch that reproduces the 2.64.0 hash in nixpkgs today. - Homebrew:
zennotes2.69.0 in the tap (e317675), mirrored in634f67a8; both DMGs were downloaded and their SHA-256 matches the cask and GitHub's digest;brew styleclean. - Website: ZenNotes/website#77 merged at
18ceb3ebwith the releases entry and its three clips, the docs for this release (Settings → MCP → Server token, the Claude tabs' names and the zn token the bundled server reads, both MCP servers following a vault switch, the notice for a vault another device encrypted, and CLI 0.7.1 leaving cancelled tasks out), the dashboard's note that an encrypted vault's archive is saved in the desktop app, and the 2.69.0 share viewer (2.68.0 stays installed for pages cached against it). Laravel Cloud deployed it, and the live check passed: the releases page and docs carry 2.69.0, one clip and its captions match the local files byte for byte, a Range request on another answers 206, and the live 2.69.0 and retained 2.68.0 viewer files match their manifests.npm run verify:channels -- 2.69.0: every applicable channel serves v2.69.0. - zn CLI: 0.7.1 (ZenNotes/tui#8, tag
v0.7.1, Homebrew formulabac26a2), bundled here: #929's task filter and a token message that names the Server token button. - Server: ZenNotes/znserver v2.69.0 pins the published
web-2.69.0-web.h90d11c06b6e3cf34browser artifact (#26); its five binaries matchSHA256SUMS, and the released darwin-arm64 binary reports v2.69.0, serves the app and turns away a request without the token. Dockeradibhanna/zennotes:2.69.0,2.69andlatest(linux/amd64 and arm64, one digest6328d4c9…); README #27. - Boundary packages: built by CI from
d1344076and published as pre-releases, never "latest":web-2.69.0-web.h90d11c06b6e3cf34,viewer-2.69.0-viewer.h5e7ef0f99f145d0aandcore-2.69.0-core.h27a2c5df8414d1dd, published once both phone apps had shipped on it; publishing the viewer's draft also started a stray desktop Release run onto the viewer pre-release (the workflow'sv*trigger matchedviewer-...), which was cancelled; v2.69.0's own files were never touched, and 2.69.1 narrows the trigger tov[0-9]*. - Phones: iPhone 1.25.0 (41) and Android 1.1.39 (42), both on
core-2.69.0-core.h27a2c5df8414d1dd: Browse's New note row (#923, zennotesandroid#108), the notice and the name for a Cloud vault another device encrypted, Settings search that offers only what the device has, and an assistant's pending edits that move with a renamed note. iPhone: zennotesios#59 merged atdfa8128; its UI tests passed on iPhone and iPad simulators, the account-backed Cloud UI tests were not run for this build, and it was submitted to App Review on 2026-10-13. Android: zennotesandroid#111 merged at1664759(tagv1.1.39, the same tree as the uploaded bundle) and sent to Google Play review on 2026-10-13 for a full rollout; the GitHub release v1.1.39 carries Play's signed universal APK (31,883,725 bytes, SHA-2563e2d5f90…7f5d, signer9f1af3a4…), byte-identical when downloaded again.
Release validation
Cycle checks:
- #830 end to end with real binaries (
docs/releases/v2.69.0/issue-830/): a token-protected ZenNotes Server, the Goznbuilt at 0.7.0 runningzn connect, andmcp.jsrun exactly as Install registers it. Before:vault_infostill failed afterzn connect, in the same session and a fresh one. After: the same running session read the server's vault on its next call. Server token over CDP in the dev app, with itssafeStorageswapped for an in-memory fake so no Keychain was touched: connected from the wizard, Let assistants use it wrotecredentials.toml(0600, the app's token under zn's key), and the real Goznandmcp.jsboth reached the server; Stop sharing turned both away; sharing again and saving a new token for the server updated the file; forgetting the server emptied it. Unit tests:zn-credentials.test.ts,mcp-server-token.test.tsand the MCP and resolver tests, five of which fail with the fallback removed. - Setup over CDP with throwaway profiles and a loopback server: before, connecting landed on "Vault layout"; after, on Done, with the server's layout untouched; a local folder still lands on the layout step.
- #933 in the built app over CDP: the footer in Name, Folder (with and without a highlight, and filtered to nothing) and Tags (with a highlight and with invalid text) matches the PR; the form, search-create and palette-nav suites (42 tests; the follow-up's new test fails on the merged code). The PR's first CI failure (a test seeded
vaultSettings: null, which vitest does not typecheck) is fixed infb9c6fcc. - Superseded vault: the desktop live test against a local Cloud with
CLOUD_E2EE=beta, the second device getting the real 410; the new host tests fail against the old service; the status bar and both Settings states over CDP. - Browse New note on an Android emulator with a core built from this tree: Browse, New folder "Projects", into it, New note opened "Untitled" with its title selected and wrote
inbox/Projects/Untitled.md; the iPhone shell's row in its browser preview. - Manual:
help-rich-text.test.ts(8), and Open Help over CDP shows two paragraphs with four bold names in the encryption guide. - Found during the release and fixed before it: shortcuts behind What's New and other overlays, reproduced in the built app over CDP with throwaway profiles before the fix (Cmd+P opened a hidden search that took the typed text, Cmd+N wrote
inbox/Untitled.md, Shift+Cmd+N a Quick Note, Shift+Cmd+P and Cmd+, opened their dialogs under What's New; behind Settings, Ctrl+Tab, Alt+Left and Shift+Cmd+T changed the active note and Shift+Cmd+N wrote a Quick Note) and after it (none acts, focus stays, Cmd+, replaces What's New, and with nothing open all four note shortcuts still work). The Tasks calendar behind Settings: Space (Vim off) and x (Vim on) wrote- [x]before and nothing after; with nothing open both still toggle.CloudSettings.test.tsgains three tests (unlocking reads the list again; Save archive per host), each failing with its fix removed;keymaps.test.tsthree. The phone shells: three new vault tests each, failing on the oldvault-fs.ts; Android 278 and iPhone 253 tests pass. With a rehearsal core fromd1344076in the iPhone shell's browser preview: at phone width, Settings search hides every MCP, CLI and Keymap result and nothing else; at iPad width, Keymap lists no review key; Browse's New note row creates the note in the browsed folder with its title focused.
Release-time gates on d1344076: typecheck 8/8 and test:run 6/6 with no turbo cache (shared-domain 1,994, app-core 3,220, quicklook 15, desktop 1,139), npm audit --omit=dev --audit-level=high clean (the same 15 low or moderate as 2.68.0). Pack: Developer ID signed, deep strict codesign OK, bundled zn v0.7.1 in a drwxr-xr-x Resources/zn-cli, the Quick Look extension; packaged launch check: page target and drawn app in 1.5 s, version 2.69.0. Smoke suites: sidebar-vim (12) and editor-improvements (19) pass; vim-editor failed one check on its first run (repeated L read the same scroll position twice, a timing flake) and passed all 12 on the re-run. The commit messages carry no long dash except the merged contributor commit bcc52592, which stays as its author wrote it. Release PR #934: all 11 checks green, including the windows-11-arm package and launch check (CI run 38426359796). Release run 38428914590: all six jobs green in about 45 minutes; verify-installers.py ALL GOOD on the five manifests; both DMGs hash to GitHub's digests and the cask, and the app in each is Notarized Developer ID with a valid stapled ticket. npm run verify:channels -- 2.69.0 passed locally and from a clean runner (run 38437499904). After the cut, CI on main failed twice on Windows: 16 tests timing out at 5 seconds on one slow windows-latest runner, and, on windows-11-arm, one rename test that found a real bug: on Windows, renaming a note onto another note's name could replace that note. It dates from 2.55.0 and is fixed in 2.69.1.