Skip to content

Release 1.35.0 (build 54) - #84

Merged
adibhanna merged 5 commits into
mainfrom
release/1.35.0
Oct 30, 2026
Merged

adibhanna merged 5 commits into
mainfrom
release/1.35.0

Conversation

@adibhanna

@adibhanna adibhanna commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

ZenNotes for iPhone 1.35.0 (build 54) on core 2.80.0. The branch was rebuilt once before review (force-pushed) to fold in the Android walk's findings ahead of the version commit. Archive from the version commit e2bf684, which main fast-forwards to.

  • Core 2.80.0 (26c926c): core-2.80.0-core.hc5a4589d040cd0da from ZenNotes/zennotes 31520814 (the v2.80.0 tag), provenance checked by core:adopt. The lock moves only the three @zennotes entries (npm 11 also flipped the build tools' dev flags; those lines are kept as they were, and npm ci accepts the result). From core: Kanban swimlanes in the board's View menu, subtasks folded into their card with a progress bar, WIP limits, empty - [ ] placeholders hidden from Tasks, the Calendar sheet and the widgets' data, and the template folder (Settings, Templates; its notes in the template picker).
    • Mirrored in the on-device vault (vault-fs.ts, as desktop vault.ts): templates.folder survives a settings save from the phone through shared-domain's normalizeTemplateFolderSettings, folder only, exactly as desktop main and the Android shell; a folder rename or move carries it along (rewriteTemplateFolderForRename); both task scans take their lists from tasksFolderListsForSettings, so template checkboxes never become tasks; text search drops template notes before ranking.
    • Subtasks: nothing to mirror, the scans already use shared-domain's parsers, which set parentId. template-folder.test.ts runs the core's task-subtasks.json fixture through both scans.
    • Open as Gallery on the drawer's folder sheet, through core's new openBrowseFolderGallery (the desktop 2.80.0 notes promise "a folder's menu opens its Gallery" on phones).
    • Focus guards: core now keeps a phone's keyboard down after a callout pick, Remove callout and the Columns menu opening (hostOpensNotesToRead). The contract test checks core's new gates; read-open.ts keeps its guards as a second line, unchanged and byte-identical with the Android shell's.
    • Bridge: no new methods. The new supportsTemplateFolder capability is left out on purpose (absent means the setting shows, which is right for a vault that keeps unknown keys); for a server vault core reads the server's own flag. No new desktop-only palette commands (the four Lanes commands and Toggle Empty Tasks work on the phone).
  • Cloud refused paths, the shell's half of #1004 (08c5258): the transport keeps a 422's field errors under details.errors, and the direct-upload batch split throws CloudSyncPathRefusedError with batch indices and what was already applied, a port of desktop's DesktopCloudSyncApiClient.mutate (desktop 3c8fb850). Before this, a refusal still stopped every run on the phone.
  • Found by the walks, fixed:
    • 1007421 column and lane headers join the long-press surfaces (Set WIP limit… and the lane menu were unreachable); a card's subtask bar stops 34px short of the move handle; the Tasks Keys button (keyboard help that replaced the hint strips) is hidden on phones as the strips were, its sheet takes one column where it shows narrow, and the scrollbar corner is transparent. These rules are byte-identical with the Android shell's.
    • 689a149 a note opened from a Kanban card (its title, arrow or a subtask line) raised the keyboard; read-open.ts treats a card as an open to read. read-open.ts and kanban-read-open.test.ts are the Android shell's files byte for byte (zennotesandroid b545653).
  • Version (e2bf684): 1.35.0, build 54 in all six configurations.

Validation: npm ci, npm run upstream (boundaries, typecheck), 415 tests, build, cap sync ios, npm audit --omit=dev --audit-level=high. A Release simulator build (iOS 27, iPhone 17 Pro, generic data) was walked: swimlanes by priority with a lane folded and the lane header's long-press menu; a subtask ticked from its card (1/3 to 2/3, written to the note); a WIP limit of 3 against 4 cards from the column header's long-press; empty tasks hidden and shown from the View menu and the "3 hidden" pill, the Calendar sheet without them; the template folder set in Settings (vault.json templates.folder), its checkboxes leaving Tasks (25 to 21), a note made from the folder's Meeting template whose checkboxes are tasks; Open as Gallery from the folder sheet and a card opening to read with the keyboard down; a Kanban card's title and a subtask line opening their note with the keyboard down, and a tap into the text raising it; the widget snapshot without empty or template tasks. Clips: docs/releases/v1.35.0/media/iphone-*.mp4 (local).

… board and Open as Gallery

Core core-2.80.0-core.hc5a4589d040cd0da, built by CI from ZenNotes/zennotes
31520814 (the v2.80.0 tag), replaces h7896a01910a2ea0f (47d26827);
core:adopt checked SHA-256, SHA-512, packed versions and clean-source
provenance. The lock moves only the three @ZenNotes entries: npm 11 also
flipped the build tools' dev flags (esbuild, rolldown, lightningcss), which
would put them under the production audit, so those lines are kept as they
were and npm ci accepts the result.

New for the phone, from core: Kanban swimlanes in the board's View menu;
a task's indented subtasks inside its card, with a 2/3 progress bar and
boxes to tick; WIP limits; empty - [ ] placeholders kept out of Tasks, the
Calendar sheet and the widgets' data, with a quiet "3 hidden"; and a
template folder (Settings, Templates) whose notes show in the template
picker.

The on-device vault mirrors desktop vault.ts for the template folder, as
it does for the Tasks folder lists: a settings save from this device keeps
a desktop user's templates.folder through shared-domain's
normalizeTemplateFolderSettings, exactly as desktop main does (a usable
path cleaned, only the folder kept, an unusable one dropped with no stub
left; the Android shell does the same); renaming or moving the folder, or
one it sits in, carries the
setting along (rewriteTemplateFolderForRename); the task scans take their
folder lists from tasksFolderListsForSettings, so a template's checkboxes
never become tasks, even inside a Task folder; and text search drops
template notes before ranking, so the result limit is spent on real notes.
A self-hosted vault gets the same from server 2.80, which core asks about
itself (supportsTemplateFolder).

Subtasks need nothing here: the scans already parse with shared-domain's
parseTasksFromBody and parseTaskFile, which now set parentId. A test runs
the core's contract fixture (bridge-contract/fixtures/task-subtasks.json)
through both scans.

The drawer's folder sheet gains Open as Gallery, the desktop folder menu's
row, through core 2.80's openBrowseFolderGallery; the drawer closes onto the
folder's cards. A database keeps its own grid, as on desktop.

Core 2.80 now leaves a phone's keyboard down after a callout pick, Remove
callout and the database Columns menu opening (hostOpensNotesToRead), the
three places read-open.ts guards since 1.34.0. The contract test checks
core's new gates; read-open.ts keeps its guards as a second line, unchanged
and still the Android shell's file byte for byte, until both shells drop
them together.
…est of the vault syncs

Core 2.80 (ZenNotes/zennotes#1004) sets aside a path Cloud refuses and
syncs everything else, but it can only see which path was refused when the
host's transport keeps the 422's field errors, and the phone's dropped
them: a refusal still stopped the whole run here, every run after it, the
way it did on desktop before 2.80. Desktop's transport changed in the same
core release (3c8fb850), and its commit names this as the shells' half.

The transport now keeps the answer's errors object under details.errors
beside the error's own details. And mutateWithMobileDirectUploads, which
sends one batch as several requests (inline posts and direct uploads),
turns a path refusal in one of them into CloudSyncPathRefusedError with the
refused mutation's place in the whole batch and what the earlier requests
already applied, so the coordinator commits those and resends only what
went unanswered. A direct upload's own refusal names its field "path"; it
is renamed to the batch position, as desktop does. Any other refusal still
stops the run. A port of DesktopCloudSyncApiClient.mutate; keep the two in
step.

Tests (red first): the transport keeps mutations.1.path and the shared
cloudSyncPathRefusal finds index 1; a refused direct upload after an
applied inline request names index 1 with that request's acknowledgement
and sends nothing after it; an inline refusal after a direct upload names
its batch index, not its request index; a refusal of another field still
throws as before.
…ts keys stay off it

Walking core 2.80's board on the iPhone simulator found three things a
touch screen needs that the desktop board gets from a mouse and keys.

Set WIP limit… lives only in a column header's right-click menu, and a
lane header's menu folds and unfolds lanes; the phone opens right-click
menus only on the long-press surfaces it lists, so neither menu could be
reached. Column and lane headers join LONG_PRESS_SURFACES. A long-press on
a lane header opens its menu without also folding the lane.

A card's subtask bar is a full-width row, and with its subtasks folded its
"1/3 · 33%" ran under the shell's move handle in the card's corner. The
row now ends where the handle starts, 34px from the card's edge.

The Tasks views traded their key-hint strips, which the phone hides, for
a Keys button opening the same keyboard help as a sheet. It is hidden on
phones as the strips were; tablets keep it. Where the sheet does show at a
narrow width, core's two columns in a 92vw popover squeezed the key chips:
it takes one column, and the chips keep their width.

Core styles the scrollbars but not the corner where two meet, which
Chromium paints white; the lanes board scrolls both ways. iOS draws no
such corner, but the rule keeps mobile.css in step with the Android shell,
whose rules these all are, byte for byte.

Tests pin each core marker (a change there fails at the next adoption) and
the shell's rules.
… down

Walking core 2.80.0's board on the release build: opening a note from a
Kanban card raised the soft keyboard over it, on the iPhone as on Android.
Core opens the card's note from a tap on the card, its title, its open
arrow and now a subtask line, and follows the open with an editor focus,
as it does for the Tasks list. The list's rows arm read-open.ts's hold; the
board's cards never did.

read-open.ts treats a tap anywhere on a card ([data-kanban-task-id]) as an
open to read. The card's checkboxes, its subtask bar and the move handle
never focus the editor, so the hold a tap on them arms lapses unused, and
the next touch releases it as before. The click listener and the other
guards are unchanged.

read-open.ts and kanban-read-open.test.ts are the Android shell's files
byte for byte (ZenNotes/zennotesandroid b545653).
@adibhanna
adibhanna merged commit e2bf684 into main Oct 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant