Repository navigation
Releases: ZenNotes/zennotesandroid
Release list
ZenNotes for Android 1.1.34: long Mermaid labels wrap instead of being cut off
ZenNotes for Android 1.1.34: long Mermaid labels wrap instead of being cut off
Version 1.1.34, versionCode 37, October 8, 2026, following 1.1.33 (36). PR #103 carries fe0832d; the signed bundle zennotes-1.1.34-vc37.aab (31,574,805 bytes, SHA-256 c4d9d9ae…5f49) was built from main e47521e, whose tree equals fe0832d.
What changes on the phone
- Long Mermaid labels wrap instead of being cut off. A diagram label longer than about 200 pixels stayed on one line and was cut off mid-word on a display with a fractional scale, which many Android phones have. It now wraps onto two or three lines, in the editor and in Preview (ZenNotes/zennotes#911).
- Clearer first-run text. The onboarding no longer says notes are "never on our servers", which is not true for people who turn on ZenNotes Cloud; it says notes are plain Markdown files on your device. The Welcome note a new vault starts with keeps its wording with plainer punctuation.
Under the hood
Core core-2.64.0-core.hbc630bc258a16fbb was built by CI from ZenNotes/zennotes 82943baf, the v2.64.0 release commit (run 37844622178), and published as a pre-release; iPhone 1.20.0 vendors the identical archives. core:adopt checked SHA-256, SHA-512, packed versions and clean-source provenance.
Source: branch release/1.1.34 from main 3ef798c, which includes #99's Capacitor plugin patch releases (app 8.1.2, filesystem 8.1.4, keyboard 8.0.6, share 8.0.3, status-bar 8.0.4). On the branch: 0eba505 takes #100's development bumps (@types/node 22.20.5, vite 8.3.2), which conflicted once #99 merged; b77d80c the onboarding and Welcome note text; dc14a30 the version commit (Gradle, the bridge fallback version, package.json and the lockfile root); fe0832d the core adoption. The APK requests the same three permissions as 1.1.33, and no SDK was added.
Validation
- On core 2.64.0: typecheck, 229 JavaScript tests, the Vite build, Capacitor sync and a Gradle
assembleDebugpassed; JDK 21bundleReleasepassed. - PR #103 CI on
fe0832dpassed: the build job, and the emulator launch job on its second attempt (the first attempt's emulator took 466 seconds to boot and its input service failed before the app was installed). - The label fix was verified in the shared core: driven in the desktop app over CDP at twelve display scales and zoom levels, and by its unit tests. It was not exercised on an Android device here.
Play Console submission
1.1.33 (36) was live. Production, Create new release: release notes inside <en-US> tags, the AAB dropped in by Adib, processed as 37 (1.1.34): API 24+, target SDK 36; no devices lost or added (12,345 phones, 6,780 tablets); 5.44 MB update; only the usual "no deobfuscation file" warning. Saved, "Submit 1 change for review", "Send changes for review" on October 8 at about 22:00 UTC: "Changes in review", full rollout. Managed publishing is off, so approval publishes it.
PR #103 merged as e47521e (merge tree equals fe0832d, the AAB's source); lightweight tag v1.1.34. This release carries Play's signed universal APK from App bundle explorer as zennotes-1.1.34-universal.apk: 31,826,753 bytes, SHA-256 f0482137…6069, md.zennotes 37 / 1.1.34, min 24 / target 36, signer 9f1af3a4… as since 1.1.22, no CHECK_LICENSE or pairip.
How to test locally
npm ci && npm run build && npx cap sync android, then openandroid/in Android Studio and run on a device or emulator.- In a note, add a Mermaid diagram with a long label, for example
flowchart TBwitha["aurora: forwarding disabled PLUS SOME MORE EXTRA TEXT"] --- b["USB NIC enp0s20f0u9 at 10.255.255.2/30"], and switch to Preview. Before: on a phone with a fractional display scale, each long label is cut off mid-word. After: each wraps onto two or three lines and reads in full. - On a fresh install, the first-run screen says "Notes are plain Markdown files on your device."
ZenNotes for Android 1.1.33: a lone dash under a line stays a paragraph
ZenNotes for Android 1.1.33: a lone dash under a line stays a paragraph
Version 1.1.33, versionCode 36, October 6, 2026, following 1.1.32 (35). PR #98 carries 14018e2; the signed bundle zennotes-1.1.33-vc36.aab (31,574,014 bytes, SHA-256 339f47e0…8902) was built from main ec62b08, whose tree equals 14018e2.
What changes on the phone
- A line over a lone
-stays a paragraph. Typing-under a paragraph to start a list turned that paragraph into a heading in the editor, the outline and Preview, because Markdown reads a single dash under a line as a heading underline. It now stays a paragraph;--,---and===under a line still make a heading (ZenNotes/zennotes#898). - The in-app help is current, including its clipboard and command-line entries.
Under the hood
Core core-2.63.0-core.hf5ca19182888aa46 was built by CI from ZenNotes/zennotes dc8fe105, the v2.63.0 release commit (run 37535271990), and published as a pre-release; iPhone 1.19.0 vendors the identical archives. core:adopt checked SHA-256, SHA-512, packed versions and clean-source provenance, and the adoption's lockfile diff is only the three @zennotes pins.
Source: branch release/1.1.33 from main ce3a448: adoption bbcaec0, version commit f54632c (Gradle, the bridge fallback version, package.json and the lockfile root), and 14018e2, a lockfile-only patch for two advisories published this week that failed the PR's production audit: GHSA-rvm3-566m-v7fv (Capacitor's internal proxy path) in the @capacitor/ios 8.5.0 that @aparajita/capacitor-secure-storage pulls in (now 8.5.2; the iOS runtime is never built into this app, and its own @capacitor/android 8.5.2 was already outside the advisory), and GHSA-68fv-2mgg-jv7q in source-map-js (now 1.2.2). No native code, permission or SDK changes.
Validation
- On core 2.63.0: typecheck and 229 JavaScript tests passed, plus the Vite build and Capacitor sync;
npm audit --omit=devat high is clean. JDK 21bundleReleasepassed. - PR #98 CI on
14018e2passed: the build job and the emulator launch job. - The lone-dash rule was verified in the shared core: driven in the desktop app over CDP (editor, outline and Preview) and by its unit tests. It was not exercised on an Android device here.
Play Console submission
1.1.32 (35) was live. Production, Create new release: release notes (235 characters, inside <en-US> tags), the AAB dropped in by Adib, processed as 36 (1.1.33): API 24+, target SDK 36; no devices lost (12,320 phones, 6,749 tablets); 3.12 MB update; only the usual "no deobfuscation file" warning. Saved, "Submit 1 change for review", "Send changes for review" at about 22:40 UTC: "Changes in review". Managed publishing is off, so approval publishes it.
PR #98 merged as ec62b08 (merge tree equals 14018e2, the AAB's source); lightweight tag v1.1.33. This release carries Play's signed universal APK from App bundle explorer as zennotes-1.1.33-universal.apk: 31,826,753 bytes, SHA-256 960c2f2e…f801, md.zennotes 36 / 1.1.33, min 24 / target 36, signer 9f1af3a4… as since 1.1.22, no CHECK_LICENSE or pairip.
How to test locally
npm ci && npm run build && npx cap sync android, then openandroid/in Android Studio and run on a device or emulator.- In a note, type
Things to buy:, press Enter, then type-. Before: "Things to buy:" turns into a heading in the editor and in Preview. After: it stays a paragraph;---under a line still makes a heading.
ZenNotes for Android 1.1.32: folder files, steady Edit scrolling and Kanban by due date
ZenNotes for Android 1.1.32: folder files, steady Edit scrolling and Kanban by due date
Version 1.1.32, versionCode 35, October 5, 2026, following 1.1.31 (34). PR #97 carries beb0408; the signed bundle zennotes-1.1.32-vc35.aab (31,572,679 bytes, SHA-256 16625015…47f99c) was built from that commit.
What changes on the phone
- Browse lists a folder's files as well as its notes: pictures, PDFs and other attachments appear after the notes (#95, with core 2.62.0).
- Scrolling a note in Edit mode stays where you scroll instead of jumping back to the cursor while the keyboard is up (ZenNotes/zennotes#891, #96).
- A note keeps its creation date when it is renamed or moved (#95).
- A file that has not reached this device says so in the note instead of drawing an empty player, and turns into the picture or player when it arrives.
- Kanban columns can be ordered by due date: Order, next to Group by (ZenNotes/zennotes#889).
- Cloud: Settings → Cloud opens on what needs you and says why an automatic backup was skipped and which plan limit a backup hit; a restored note leaves no copy behind; a restore that only changes a note's capitalization renames it in place, and a run stopped between its two renames recovers.
- Fixed: a dated link such as
[[2024.01.15]]opens its note instead of a browser address.
Under the hood
Core core-2.62.0-core.hcf81934394c63533 was built by CI from ZenNotes/zennotes fb3d13f8, the v2.62.0 release commit (run 37378093758), and published as a pre-release; iPhone 1.18.0 vendors the identical archives. core:adopt checked SHA-256, SHA-512, packed versions and clean-source provenance, and the lockfile diff is only the three @zennotes pins.
Source: branch release/1.1.32 from main 8559c57 (the merges of #95 and #96): adoption 98f0ffc, version commit beb0408 (Gradle, the bridge fallback version, package.json and the lockfile root). No native code, permission or SDK changes.
Validation
- On core 2.62.0: boundaries, typecheck and 229 JavaScript tests passed, plus the Vite build and Capacitor sync. JDK 21
bundleReleasepassed. - PR #97 CI on
beb0408passed: the build job and the emulator launch job (18m39s). - The folder file rows, the missing-file notice, the dated link and Kanban Order were checked on the iPhone build of the same core on a simulator; not on an Android device here.
Play Console submission
1.1.31 (34) was live. Production, Create new release: release notes (476 characters, inside <en-US> tags), the AAB dropped in by Adib, processed as 35 (1.1.32): API 24+, target SDK 36; no devices lost (12,320 phones, 6,749 tablets); 3 MB update; only the usual "no deobfuscation file" warning. Saved, "Submit 1 change for review", "Send changes for review"; Google published it the same evening. Managed publishing is off.
PR #97 merged as ce3a4484 (merge tree equals beb0408, the AAB's source); lightweight tag v1.1.32. This release carries Play's signed universal APK from App bundle explorer as zennotes-1.1.32-universal.apk: 31,826,753 bytes, SHA-256 e3f20ca1…a490, md.zennotes 35 / 1.1.32, min 24 / target 36, signer 9f1af3a4… as since 1.1.22, no CHECK_LICENSE or pairip.
How to test locally
npm ci && npm run build && npx cap sync android, then openandroid/in Android Studio and run on a device or emulator.- Put a picture in a note folder, open Browse on that folder: the picture is listed after the notes. Open Tasks → Kanban and set Order to Due date: each column sorts by date.
ZenNotes for Android 1.1.31: Cloud says what it is waiting on
ZenNotes for Android 1.1.31: Cloud says what it is waiting on
Version 1.1.31, versionCode 34, October 2, 2026, following 1.1.30 (33). PR #94 carries fdd848b; the signed bundle zennotes-1.1.31-vc34.aab (31,565,446 bytes, SHA-256 55b1c461…5c8d25) was built from that commit.
What changes on the phone
These come from testing ZenNotes Cloud on real devices against the production service on October 2.
- A note paused by a sync conflict says so on the note. A one-row banner across its top, with Review opening the conflict queue on that note, and one notification per new conflict. Before, only Settings → Cloud knew.
- Limits name themselves. "1 file too large for Cloud" on the status row, the file named in the message, and "Not synced to Cloud: larger than the 10 MB file-size limit, so it stays on this device." right under the file in the note. A 10 GB plan reads 10 GB, not 9.3 GB.
- Attached videos, audio and PDFs embed in the note and play in Edit and Read mode, instead of landing as a link.
- Deleting a Cloud vault asks for its name, and other devices say "Cloud vault deleted" instead of quietly stopping. Review on the Cloud row opens Settings on the Cloud page.
- The backup browser lists and searches the whole backup, with Load more, instead of stopping at the first 50 files.
- Fixed: pulling a note at the top level of a vault left an empty folder named after it minus its last letter (
Welcome.m), since 1.1.12; and Cloud no longer syncs its own bookkeeping files.
Under the hood
Core core-2.60.4-core.hae0e49f9e5397fc2 was built by CI from ZenNotes/zennotes c507caa3 on v2.61.0 (run 37072275356) and published as a pre-release; iPhone 1.17.1 vendors the identical archives. core:adopt checked SHA-256, SHA-512, packed versions and clean-source provenance. The shell wires the new optional listCloudBackupItemsPage bridge method. The lockfile is main's with only the root pins and the three @zennotes entries swapped; npm ci accepts it.
Source: branch release/1.1.31 from main 7c6d778: root-level pull fix 1cf261e, Settings target f8d87c2, media embeds b802c91, adoption 276d4a2 (2.60.4), version commit fdd848b (Gradle, the bridge fallback version, package.json and the lockfile root). No native code, permission or SDK changes.
Validation
- On core 2.60.4: boundaries, typecheck and 206 JavaScript tests passed, plus the Vite build and Capacitor sync. JDK 21
bundleReleasepassed. - PR #94 CI on
fdd848bpassed: the build job and the emulator launch job. - The Cloud changes were exercised on a physical iPhone with development builds of the same core against production Cloud, and on desktop; not on an Android device here.
Play Console submission
1.1.30 (33) went live on October 2. Production, Create new release: release notes (402 characters, inside <en-US> tags), the AAB dropped in by Adib, processed as 34 (1.1.31): API 24+, target SDK 36; no devices lost (12,320 phones, 6,749 tablets); 2.29 MB update; only the usual "no deobfuscation file" warning. Saved, "Submit 1 change for review", "Send changes for review": Changes in review. Managed publishing is off, so approval publishes it.
PR #94 merged as 81493e4d (merge tree equals fdd848b, the AAB's source); lightweight tag v1.1.31. This release carries Play's signed universal APK from App bundle explorer as zennotes-1.1.31-universal.apk: 31,818,291 bytes, SHA-256 97e40b44…0a0b45, md.zennotes 34 / 1.1.31, target 36, signer 9f1af3a4… as since 1.1.22, no CHECK_LICENSE or pairip.
How to test locally
npm ci && npm run build && npx cap sync android, then openandroid/in Android Studio and run on a device or emulator.- Sign in to ZenNotes Cloud and link a vault that also syncs on a desktop.
- On the desktop, create
Welcome.mdat the vault root and sync. Before (1.1.30): the phone grows an emptyWelcome.mfolder. After: onlyWelcome.md. - Edit the same line of a note on both devices while one is offline, then reconnect. Before: nothing on the phone said sync had paused. After: the note shows "Sync is paused for this note…" with Review.
- Attach a short video to a note. Before: a link with the file name. After: a player.
ZenNotes for Android 1.1.30: folder pickers, heading links and native Cloud transfers
ZenNotes for Android 1.1.30: folder pickers, heading links and native Cloud transfers
Version 1.1.30, versionCode 33, October 2, 2026, following 1.1.29 (32). PR #92 was rebuilt on main after #93 (native Cloud streaming) merged and carries a83bb57; the signed bundle zennotes-1.1.30-vc33.aab (31,557,330 bytes, SHA-256 f8ee7e64…395a) was built from that commit. Earlier bundles on core 2.60.1 and 2.60.2 were superseded and never uploaded.
What changes on the phone
- Folder pickers open without the keyboard. Since core 2.53.0 (the first core the phones took after desktop 2.52.0 added the shared dialog focus), Move to… (for a note or a folder) opened with the soft keyboard up, covering the list of folders it asks you to tap. PromptModal leaves touch prompts with suggestions tap-first, but the shared dialog shell focused their input on open anyway. With core 2.60.1 the picker opens with the whole list visible; tap a folder to move there, or tap the field to type a path. Prompts with nothing to tap (Rename, New folder) still open with the keyboard.
- Heading links land in Read mode. A Markdown
[text](#heading)had nothing to scroll to (rendered headings carry no id), and in the editor only the exact heading text matched. Both now follow#heading,#Heading%20Textand#heading-slugto the heading. A tap on a wikilink also stops opening the hover card first: on iPhone that card swallowed the tap entirely (emailed report on iOS 1.15.0); on Android it only flashed.
Under the hood
Draft core-2.60.3-core.h44232ae9fc126112 was built from ZenNotes/zennotes e5e34f84d4a7b3eaaa4ac319f9bfb2a5a0cb6656 on v2.61.0 by workflow 37018099829: main's Cloud core from #884 merged with the picker fix 0c3071a6 and the heading-link fix a6d0997a (merge 5c3d3bd9); iPhone 1.17.0 vendors the identical archives. core:adopt checked SHA-256, SHA-512, packed versions and clean-source provenance. App-core is 2.60.3-core.h44232ae9fc126112. No bridge changes, so the shell needs no port.
Source: branch release/1.1.30 rebuilt from main f3bfe28 (merge of #93: core 2.60.1 adoption and native Cloud streaming through CloudFileStream/DirectUploadPlugin): adoption aeb3f4c (2.60.3), version commit a83bb57 (Gradle, the bridge fallback version, package.json and the lockfile root). The lockfile is main's with only the root pins and the three @zennotes entries swapped; npm ci accepts it. Native code changed in #93 (Cloud file streaming plugin); no permission or SDK changes in this release's own commits.
Validation
- On core 2.60.3 with #93: boundaries, typecheck, 203 JavaScript tests (including the native-bridge test that no response groups large attachments, which fails on this core without #93), production audit (0 vulnerabilities), Vite build and Capacitor sync passed.
- JDK 21:
testDebugUnitTest,lintDebug,assembleDebugandbundleReleasepassed. The bundle's merged manifest reads versionCode 33 / 1.1.30, and itspublic/assets equaldist/file for file. - The picker fix was verified on the iPhone shell with the same core (Move to… opens with no keyboard and the whole list visible; one tap on the field raises it) and by composed jsdom tests upstream. The heading-link fix was verified on desktop over CDP (all three link forms land the heading) and on the iPhone simulator. Neither was exercised on an Android device or emulator here; PR #92's emulator job is the launch check.
Play Console submission
1.1.29 (32) was already live (Active, 178 countries) on October 2, so 1.1.30 is a regular update. Production, Create new release: release notes (the What's New text, 434 characters, inside <en-US> tags) filled in the built-in browser; the AAB dropped in by Adib (signed in to Google first); processed as 33 (1.1.30): API 24+, target SDK 36, same screen layouts, ABIs and required features as 1.1.29; no devices lost (12,320 phones, 6,749 tablets); 6.1 MB update; only the usual "no deobfuscation file" warning; rollout 100.0. Saved, Publishing overview, "Submit 1 change for review", "Send changes for review" at about 15:17 UTC: "Changes in review", sent once Play's quick checks finish. Managed publishing is off, so approval publishes it.
PR #92 CI on a83bb57 passed (build, and the emulator job with #93's instrumentation tests in about 21 minutes). Merged as 7c6d778f (merge tree equals a83bb57, the AAB's source); lightweight tag v1.1.30. GitHub release v1.1.30 (latest) carries Play's signed universal APK from App bundle explorer as zennotes-1.1.30-universal.apk: 31,810,001 bytes, SHA-256 b9bdb7e1…37ee, md.zennotes 33 / 1.1.30, target 36, signer 9f1af3a4… as since 1.1.22, no CHECK_LICENSE or pairip.
How to test locally
npm ci && npm run build && npx cap sync android, then openandroid/in Android Studio and run on a device or emulator.- Open Browse, long-press a note, tap Move to….
- Before (1.1.29): the keyboard comes up over the folder list. After: the list is fully visible with no keyboard; tapping the field brings the keyboard up.
- In a note with
## Section Threefar down and[jump](#section-three)at the top, switch to Read and tap the link. Before: nothing happens. After: the note scrolls to the heading.
ZenNotes for Android 1.1.29: faster links in large vaults
ZenNotes for Android 1.1.29: faster links in large vaults
Version 1.1.29, versionCode 32, October 1, 2026, following 1.1.28 (31). PR #91 carries 79c37fb; the signed bundle zennotes-1.1.29-vc32.aab (31,542,341 bytes, SHA-256 26a13f62…6c17) was built from that commit.
What changes on the phone
- Faster links in large vaults (#880). Resolving a wikilink used to search every note, and counting a note's backlinks did that for every link in the vault. The shared core now builds its link index once per notes list, so opening notes and resolving their links in a vault with thousands of notes and links no longer stalls. Which note a link opens, and which notes count as backlinks, is exactly as before. On desktop the same change took a note switch in a 6,500-note vault from about 1 second to under 0.1 seconds; the phone was not measured.
Under the hood
The three archives come from core-2.60.0-core.hb0d0b54f320a8e3f (a draft until both apps ship), built from desktop release commit 158293947e451f2a88011ddf647517c847cc0a76 (ZenNotes 2.60.0) by workflow 36887215873; iPhone vendors the identical archives in zennotesios#37. core:adopt verified SHA-256, SHA-512, packed versions and clean-source provenance. App-core is 2.60.0-core.hb0d0b54f320a8e3f; bridge-contract and shared-domain are 2.60.0-boundaries.hbdc4a2a12368fec1. The bridge gained only optional, desktop-only methods (the desktop CLI updater), so the shell needs no port. Core 2.59.0, adopted first on this branch, changed nothing on the phone.
Source: branch chore/core-2.59.0 (PR #91): adoption 8600b9f (2.59.0), adoption d463bfc (2.60.0), version commit 79c37fb. Versions cover Gradle, the bridge fallback, package.json and the lockfile. No native implementation, permission or SDK changes.
Validation
- Boundaries, typecheck, 162 JavaScript tests, Vite build and Capacitor sync passed; production audit passes the high-severity gate (one existing low DOMPurify advisory).
- JDK 21:
testDebugUnitTest,lintDebugandassembleDebugpassed;bundleReleaseproduced the signed bundle. - PR CI on
79c37fb: build and emulator launch passed; merged as5e6f09ed(same tree), tagv1.1.29. - Play processed the bundle as 32 (1.1.29): API 24+, target SDK 36, same screen layouts, ABIs and required features as 1.1.28; no devices lost (12,320 phones, 6,749 tablets); 2.98 MB update; only the usual "no deobfuscation file" warning.
Play Console submission
Production, Create new release: release notes (the What's New text inside <en-US> tags) filled in the built-in browser; the AAB dropped in by Adib; release name 32 (1.1.29), rollout 100%, all targeted countries. Saved, then Publishing overview, "Submit 1 change for review", sent October 1, 2026 (state "Changes in review", quick checks first). Managed publishing is off, so approval publishes it. GitHub release v1.1.29 (latest) carries Play's signed universal APK from App bundle explorer as zennotes-1.1.29-universal.apk: 31,797,713 bytes, SHA-256 44725bfd…89763, md.zennotes 32 / 1.1.29, min SDK 24, target 36, signer 9f1af3a4… as since 1.1.22, no CHECK_LICENSE or pairip.
How to test locally
npm ci && npm run build && npx cap sync android, then openandroid/in Android Studio and run on a device or emulator (or install the universal APK from the GitHub release).- Open a vault with many notes and wikilinks, open several notes, and tap links.
- Before (1.1.28): with thousands of links, opening a note could pause. After: notes open promptly, with the same links and backlinks.
ZenNotes for Android 1.1.28: lists, tasks and callouts fold, and the Cloud settings question fits the screen
ZenNotes for Android 1.1.28 (versionCode 31): the shared ZenNotes core moves from 2.56.1 to 2.58.1. List items, tasks and callouts fold, and the Cloud settings question fits the phone screen.
What changes on the phone
- Fold list items and tasks (ZenNotes/zennotes#848). Bullets, numbered items and tasks with indented details collapse to their first line. Edit and Read have disclosure arrows, and folded items keep theirs visible. Folding leaves the Markdown and the task status alone.
- Foldable callouts (ZenNotes/zennotes#853).
> [!note]- Detailsstarts closed and> [!tip]+ Detailsstarts open. Tap the title in Read or its chevron in Edit. A callout without either marker stays expanded. - The Cloud settings question fits the screen (#88). When Cloud finds vault settings that differ between devices, the dialog put its buttons below the bottom of the screen, so the question could not be answered. It is now capped to the visible screen: only its list scrolls and its footer wraps, at any text size.
- More room in Atlas (ZenNotes/zennotes#861). Notes added after the first visit get space beside the notes they link to, and reopening a saved map separates linked notes that the old placement piled together.
- More reliable note opening and refreshes (ZenNotes/zennotes#863). Shared note-open actions hand focus to the editor, and refreshes keep open notes that have unsaved text.
Under the hood
Core packages: @zennotes/app-core 2.58.1-core.h87d94b8810f1f1d1, @zennotes/bridge-contract and @zennotes/shared-domain 2.58.1-boundaries.heab3fee5cb1fe45a, built with a clean tree from ZenNotes/zennotes 178fab2b (the desktop's 2.58.0 release plus the #88 dialog fix; core release core-2.58.1-core.h87d94b8810f1f1d1). Adopted with npm run core:adopt, which checks every archive's SHA-256 and SHA-512 against its provenance and that all three record that source commit; the boundary check passed without an override. The iPhone app 1.15.0 ships the identical archives. Outside the core pins, only version numbers changed (android/app/build.gradle, the bridge's version fallback, package.json): no shell code, dependency, permission or native changes.
Installing the APK
zennotes-1.1.28-universal.apk is the Google Play-signed universal APK for 1.1.28 (31), Android 7.0 and later, downloaded from Play Console's App bundle explorer and attached exactly as downloaded: 31,793,617 bytes, SHA-256 b18b1a7962662fbb342a75d5219432605b2613e8ef73486d65e335b9f0a55ed0. aapt2 dump badging reads md.zennotes versionCode 31, versionName 1.1.28, minSdkVersion 24, targetSdkVersion 36; apksigner verify --print-certs signer SHA-256 9f1af3a4b6b11156a6b1f49e1a54bcaecef480f18eab1692a3bd8f416af6ae50, the same certificate as every release since 1.1.22; no CHECK_LICENSE or pairip entries. Sideloaded installs do not self-update; use Obtainium. The same version is live on Google Play.
Validation
Release branch release/1.1.28 (0d5e877 adopt core 2.57.0, d1af62c bump, cf6a30f adopt core 2.58.1), merged as PR #87 (b23cf864, the same tree as cf6a30f). On the release tree: package boundary check without an override, typecheck, 162 unit tests, production audit, production build, Capacitor sync, JDK 21 unit tests, lint and a debug APK, then the signed release bundle (zennotes-1.1.28-vc31.aab, 31,540,393 bytes, SHA-256 2c501ef119c83f697e180c2bff25d75c0d42cc8fcd35dd08bc2fae0468f87e9c, upload key unchanged). CI run 36609487995 passed: the build and boundary job, and the emulator job's instrumentation tests on an API 35 emulator after one re-run (the first attempt's unaccelerated emulator took 509 seconds to boot and failed before the app was installed). #88 was reproduced first in the shared web client at 393 × 851 and 360 × 640 with text at 100%, 115% and 130%, then verified fixed at each size. Submitted to Google Play production on September 29, 2026 at 19:10 UTC, 100% rollout, all targeted countries; approved and live the same day. No local Android emulator pass this cycle; coverage is not physical-device certification.
ZenNotes for Android 1.1.27
ZenNotes for Android 1.1.27 (versionCode 30): the shared ZenNotes core moves from 2.55.0 to 2.56.1, and a vault can go by a name of its own.
What changes on the phone
- A vault can go by a name of its own (ZenNotes/zennotes#692). Rename Vault… in the command palette (the menu button, More, All commands…) or the Vault name field under Settings → Vault names the vault in the sidebar drawer's header and in the vault switcher; the folder keeps its name on disk, and an empty name goes back to it. The name lives in the vault's own
.zennotes/vault.json, so a vault named on the desktop shows that name here, a folder vault named here shows it on the desktop, and a sync carries it along. On the phone this took a core fix and shell work: this shell's vault root is a label ("On this device › ZenNotes › docs"), so core 2.56.1 lets a host name the folder itself (ZenNotes/zennotes@f8b24c09) and the bridge hands overfolderName, and the bridge resolves the display name from vault.json whenever it returns the open vault, so a named vault shows its name from the first launch instead of after the first settings save. - The vault switcher marks the open vault by its folder. The Vaults sheet compared folder names with the shown name, so a renamed vault lost its check mark and the manage view offered Delete and Rename for the vault that was open. It now compares folders; each row shows the name the vault goes by, and the manage view names the folder beside a display name that differs, so a rename or delete is understood to act on the folder.
- A Markdown table converts into a database, linked from the note (ZenNotes/zennotes#832). With the cursor in a pipe table, Convert Table to Database… in the command palette writes a
<Name>.basedatabase with typed columns and leaves a[[Name]]link where the table stood, one undo away. - Settings search reaches every setting, and finds where new tasks go. Searching for tasks folder, tasks location or new task lands on Vault → Notes → Default tasks location, and the drawings and databases locations beside it and fourteen more settings are found too; every hit opens the tab its setting is on with the row highlighted.
- Tasks added or moved from the calendar panel join the note's Tasks section (ZenNotes/zennotes#851) instead of the bottom of the note.
- A code block inside a task stays under the task's text in Preview (ZenNotes/zennotes#849), and a done task strikes its words, not its code.
- Undo after the open note changed on disk no longer saves a text nobody wrote (ZenNotes/zennotes#852). When a sync changes the open note, the editor starts a clean history from the text on disk.
- Help reads as one page: a title, a search field and section links that stay pinned while you scroll.
- In the core without a surface here: the template pickers' new shortcuts (ZenNotes/zennotes#847) are keyboard chords, and the palette's template entries are the phone's routes, unchanged.
Under the hood
Core packages: @zennotes/app-core 2.56.1-core.hc872c08b6872aec4, @zennotes/bridge-contract and @zennotes/shared-domain 2.56.1-boundaries.h3434125ac49b85c7, built with a clean tree from ZenNotes/zennotes f8b24c09 (the desktop's 2.56.0 release commit 2c3dd065 plus two test-only commits, one tooling commit and the core fix; core release core-2.56.1-core.hc872c08b6872aec4). Adopted with npm run core:adopt, which checks every archive's SHA-256 and SHA-512 against its provenance and that all three record that source commit; the boundary check passed without an override. The shell's own changes are folderName and describeCurrentVault in the bridge, display-name reads from vault.json in native-fs.ts, the Vaults sheet's current row by folder with display names on its rows, and one new test of the vault.json round trip. No dependency changes, no new permissions, no native code changes; android/app/build.gradle only moves the version.
Installing the APK
zennotes-1.1.27-universal.apk is the Google Play-signed universal APK for 1.1.27 (30), Android 7.0 and later, downloaded from Play Console's App bundle explorer and attached exactly as downloaded: 31,785,233 bytes, SHA-256 05573d34c3148ebc6c1c3e1b43421f1c98b325e24fb4c52d1c4bcaa47b4d7e62. aapt dump badging reads md.zennotes versionCode 30, versionName 1.1.27, sdkVersion 24, targetSdkVersion 36; apksigner verify --print-certs signer SHA-256 9f1af3a4b6b11156a6b1f49e1a54bcaecef480f18eab1692a3bd8f416af6ae50, the same certificate as every release since 1.1.22; no CHECK_LICENSE or pairip entries. Sideloaded installs do not self-update; use Obtainium. The same version rolls out on Google Play once approved.
Validation
Release branch release/1.1.27 (cfc1bc7 adopt core 2.56.1, 2f2d8f6 bump, 542e27f the Vaults sheet fix), merged as PR #85 by fast-forwarding main to 542e27f after CI passed (build and boundary job, and the emulator job's instrumentation tests on an API 35 emulator, which passed on one re-run after the runner's emulator failed before the app was installed; run 36140337102). On the release tree: package boundary check without an override, typecheck, 162 unit tests, production build, Capacitor sync and the signed release bundle (~/Desktop/zennotes-1.1.27-vc30.aab, 31,533,054 bytes, SHA-256 a5c53a77a9212983ce67a93e85021f85d5cf6361f7dfde228a98be23ec3af832, upload key unchanged). Submitted to Google Play production on September 25, 2026 at 09:15 CDT (14:15 UTC), 100% rollout, all targeted countries. The vault-name flow was driven on the iPhone shell's simulator with the same TypeScript; no local Android emulator pass this cycle; coverage is not physical-device certification.
ZenNotes for Android 1.1.26: the shared 2.55.0 core, and nothing keyboard-only left on the phone
ZenNotes for Android 1.1.26 (versionCode 29): the shared ZenNotes core moves from 2.54.1 to 2.55.0, and nothing keyboard-only is left on the phone.
What changes on the phone
- The New note form shows no keyboard hints on the phone (ZenNotes/zennotes#842). The form that note search opens ended with the desktop's key hints in its footer (
↑↓ pick,↵ create,esc back) on a phone with no hardware keyboard. The core now marks that hint group and this shell hides it (PR #83), so the footer holds Back and Create and nothing else. - No Vim key names anywhere (the core's Vim-off sweep, ZenNotes/zennotes@cdccd554). Vim mode is never on in this app, but the core still drew a ring around the sidebar drawer after a tap, an
mchip on the row under the cursor,j/kandpstrips in the connections panel andn a e r dbadges in the comments panel. With Vim mode off none of that is drawn any more. - A new note takes the name you give it, and a refused rename says why (ZenNotes/zennotes#839). Renaming a note to a name that an older, since-moved note once had used to fail without a word, because that note's creation date had been left behind under the old name; renames and moves now discard the leftover, and a rename that still cannot happen says so on screen.
- Move… offers your own folders (ZenNotes/zennotes#844). On a vault whose notes live at the root the prompt lists the vault's own folders with Vault root on top, instead of an
inbox/that is not there. - In the core without a surface here: workflow runs carry a note's comments and creation date with the notes they move (undo puts them back), the "Notes in folder" step can name the vault root (ZenNotes/zennotes#840), and workflow event triggers (ZenNotes/zennotes#843) run on the desktop and the web client; this shell does not offer the Workflows view and triggers do not fire on phones by design.
Under the hood
Core packages: @zennotes/app-core 2.55.0-core.h0743bd3af2a4204a, @zennotes/bridge-contract and @zennotes/shared-domain 2.55.0-boundaries.hd2f617179eb16ef2, built with a clean tree from ZenNotes/zennotes 00db7036 (the desktop's v2.55.0 release commit; core release core-2.55.0-core.h0743bd3af2a4204a). Adopted with npm run core:adopt, which checks every archive's SHA-256 and SHA-512 against its provenance and that all three record that source commit; the boundary check passed without an override. The shell's own changes are the [data-keyboard-hints] CSS rule (#83) and production dependency patch updates (#81: @capacitor/share 8.0.2, CodeMirror 6.11.1 / 6.7.5 / 6.43.12). No native code changes; android/app/build.gradle only moves the version.
Installing the APK
zennotes-1.1.26-universal.apk is the Google Play-signed universal APK for 1.1.26 (29), Android 7.0 and later, downloaded from Play Console's App bundle explorer and attached exactly as downloaded: 31,780,750 bytes, SHA-256 b40dd7d07ce063494e9dd023274d6410aa98673b5203e45126db62f5585bfceb. aapt dump badging reads md.zennotes versionCode 29, versionName 1.1.26, sdkVersion 24, targetSdkVersion 36; apksigner verify --print-certs signer SHA-256 9f1af3a4b6b11156a6b1f49e1a54bcaecef480f18eab1692a3bd8f416af6ae50, the same certificate as every release since 1.1.22; no CHECK_LICENSE or pairip entries. Sideloaded installs do not self-update; use Obtainium. The same version rolls out on Google Play once approved.
Validation
Release branch release/1.1.26 (7da44a7 adopt core 2.55.0, 8afaf0e bump, a2502e2 merge of main with #82's dev-dependency bumps, whose web build is byte-identical to the bundle's assets), merged as PR #84 (00506699) after CI passed (build and boundary job, and the emulator job's instrumentation tests on an API 35 emulator, run 35922196879). On the release tree: package boundary check without an override, typecheck, 161 unit tests, production build, Capacitor sync and the signed release bundle (~/Desktop/zennotes-1.1.26-vc29.aab, 31,524,455 bytes, SHA-256 8a2745301a0e10012fdb5658e2328abffec43492a152c6cf5937ec71dd3893fb, upload key unchanged). Submitted to Google Play production on September 23, 2026 at 16:37 CDT (21:37 UTC), 100% rollout, all targeted countries. No local emulator pass this cycle; coverage is not physical-device certification.
ZenNotes for Android 1.1.25: search creates the note you typed, and the shared 2.54.1 core
ZenNotes for Android 1.1.25: search creates the note you typed, and the shared 2.54.1 core
One update in two parts: the shared ZenNotes core moves from 2.53.0 to the published 2.54.1 (the desktop's 2.54.0 and 2.54.1 releases, both from September 22), and the Android shell adds the one CSS rule the new core's form needed. No native code changes; android/app/build.gradle only moves the version to 1.1.25 (28). The headline is the New note form (#826), requested by @vinivinoo: note search used to end in "No matches." for a name no note had, and the trip went through the menu, New, and typing the name again. Now the search itself creates the note. One item in this core came from this app: #820, the footer that kept showing a tapped wikilink's target, was reported from the Android app on core 2.53.0 and listed as a known follow-up in the 1.1.24 notes.
What changes on the phone
- Note search creates the note you typed (#826). Tap the menu button, then Search, and type a name. Whatever the results, the list now ends with a Create "Meeting notes"… row with its destination on the right (Inbox, or Inbox › projects for a typed path). Tap it and a New note form opens in the same full-screen search, with the query kept behind it so Cancel returns you to the results. Name is prefilled from what you typed. Folder is empty for the Inbox root, or a path such as
projects/ideasto nest under it,archive/xorquick/xfor those areas; once the field has focus, every folder of the vault is listed under the fields (roots first, never the Trash, never a database folder), typing narrows the list, and a typed path that does not exist yet is created with the note. Tags takes chips: any#tagin the query arrives as one, the vault's tags are listed most used first with a new tag row last for a word that is not one yet, and a tag that cannot be one blocks Create and says why. Before writing, the form checks the name against the live notes: a same-titled note in the chosen folder blocks Create in red ("Weekly review" already exists in Inbox. Change the name, or open it.) and Open it opens that note instead; a same-titled note in another folder only warns, since the folder was chosen on purpose. The check is by title, ignoring case, never counting a trashed note or a partial match. The status line under the fields names the outcome in words (Creates "Q4 plan" in Inbox › projects with #planning #q4). Create writes the note with a heading and one#a #bline under it (the shapezn create --tagwrites, not frontmatter) and opens it. The default destination is the Inbox root, matching what a dead wikilink does; the "New notes go to" setting is not consulted, on purpose, the same choice the desktop made. - The first tap on Create counts while a tag is still typed (core 2.54.1). In 2.54.0's form, typing a tag and then tapping Create lost the tap: the button took focus on touch-down, that blurred the Tags field, which committed the typed word as a chip and removed the Add #urgent row under the fields, so the footer with Back and Create moved up before the finger came back up. On the phone the footer moved a full row and the tap landed on nothing; a second tap worked. Now the footer buttons (and Open it) do not take focus on touch-down, the same rule the folder and tag rows already followed, so nothing moves until the tap completes, and Create counts the text still typed in Tags the way Enter does. One tap creates the note with the tag under its heading. Found on the iPhone simulator while that shell was tested on 2.54.0, and fixed in the core before either phone shipped, so this app never had the bug.
- The form's header keeps its label clear of Cancel (this shell). On the phone the search is a full-screen takeover, and the shell places a Cancel button at its top right, the spot the form's header uses for its destination label ("in Inbox"). In the first cut the two overlapped: Cancel was drawn across the faded label. The header now ends before Cancel begins, and the three fields give back the right-hand padding that had been reserved for a Cancel over the search input, so their text no longer stops short of the field's edge.
- Following a wikilink clears its target from the footer (#820). Reported from this app on core 2.53.0: in Reading mode, tap
[[Alpha plan#Milestones]]and the target opened at the heading, but the footer's left slot on the new note kept readingAlpha plan#Milestonesuntil the next tap on something that was not a link. A tap reaches the page as a mouse sequence with nomouseleave, and the only clears were the article'smouseleaveand the preview's unmount, neither of which a tap fires. Following a link now clears the slot, and so does a change of the open note. With a mouse (a tablet with a trackpad, or a desktop), a pointer resting on a link still shows its target. - Leaving Reading mode opens the editor where you were reading (#822). Read on through a long note, scroll to a later section, switch to Edit from the menu, and the editor came back at the line the cursor had when you left (the top of the note, for one just opened). Every route out of Reading mode now reads what the reading view has on screen and opens the editor with that block at the top and the cursor on its first line; if the cursor's line is already on screen nothing moves, so a peek at the render and back leaves the cursor alone. The desktop's double-click on a paragraph to edit it is in the same core change; whether the Android WebView turns a double tap into that event was not checked in this cycle, so it is not claimed here.
- The YAML header no longer renders in heading type with Live Preview off (#827). A note that opens with
---, threekey: valuelines and---showed the property lines big and bold in Edit mode with Live Preview off, because CommonMark reads a paragraph followed by a---line as a setext heading. The editor now carves the frontmatter block out before markdown sees it, so no heading, list or rule token can come out of it in any mode. With Live Preview on the properties card looks as before. - A note whose text returns to what is on disk is not written again (#828). Type a character and delete it, or undo back to the saved text, and the note used to be saved anyway: identical bytes, a new modified time,
{{modified_time}}tokens moving, and a sync change to carry. The store now remembers what is on disk for a note with unsaved changes and treats an edit that brings the text back to those bytes as no change: the note reads clean, the pending save is cancelled, nothing is written. Real typing still saves once. On the desktop this showed as a custom Vim escape (jk) rewriting the note; the phone shares the store, so it gets the same rule, and on a folder vault it is one fewer write through the Storage Access Framework. - The built-in Help note is updated for 2.54.
Desktop only, on purpose: Harper's dictionary fix (#829, the phones never run Harper), the Vim half-page motions in visual mode (#825, a hardware-keyboard Vim change with no phone surface) and zn mcp's flags (#831, the desktop CLI). On the phone the Create row is the way into the form; the desktop's Shift+Enter shortcut needs a hardware keyboard and was not tried on a tablet in this cycle. Known follow-up: the form's footer shows the desktop's key hints (↑↓ pick, ↵ create, esc back) on a phone with no hardware keyboard, tracked as ZenNotes/zennotes#842.
Under the hood
The shell change is thirteen lines of src/ui-mobile/mobile.css: two rules scoped to .zn-mobile.zn-phone .z-palette [data-search-create-form], the marker the core's form carries. The first gives the header row padding-right: 4.25rem so the destination label ends before the shell's injected Cancel begins; the second sets the three fields' padding-right back to 0.625rem, undoing the padding the phone stylesheet reserves for a Cancel drawn over the search input, which the form does not have. The two rules are the same text as the iPhone shell's, where an XCUITest measures the header label's frame against Cancel's on the simulator. Nothing else in the shell had to move: the menu button, the search's full-screen takeover, the Cancel injection, MobileShell.tsx, MobileDrawer.tsx and the folder-vault plugin are as they were in 1.1.24. src/bridge/mobile-bridge.ts changes only its APP_VERSION string; core 2.54.1 adds no bridge-contract methods, so nothing in the bridge had to be implemented.
The adoption was done with the script that landed on main after 1.1.24 (npm run core:adopt -- core-2.54.1-core.h75d82a521571dc20 --source 0285443b51889a6034dc24b5b603c0dbab099d4f, tooling/adopt-core.mjs): it downloaded the core release from ZenNotes/zennotes, verified every archive's SHA-256 and SHA-512 against its .tgz.json provenance, the packed package versions, and that all three archives record the same clean source commit, then swapped them into vendor/zennotes/, rewrote manifest.json, the three file: dependencies in package.json and the README's version sentence, ran npm install and the boundary check. The same script was brought over to the iPhone shell in this cycle, so both phones now adopt a core the same way.
Core packages: [core-2.54.1-core.h75d82a521571dc20](https://github.com/ZenNotes/zennotes/releases/tag/core-...