Skip to content

Release 1.34.0 (build 53) - #83

Merged
adibhanna merged 22 commits into
mainfrom
release/1.34.0-b53
Oct 29, 2026
Merged

adibhanna merged 22 commits into
mainfrom
release/1.34.0-b53

Conversation

@adibhanna

@adibhanna adibhanna commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

ZenNotes for iPhone 1.34.0 (build 53), replacing build 52 (withdrawn from review) on core 2.79.0. Not to be archived or merged before the desktop v2.79.0 tag. Archive from the branch tip fdd429d: the walk fixes and the core refreshes up to the final 2.79.0 core landed after the version commit, and the build number stays 53 because nothing was uploaded.

  • Status bar switch hidden on the phone layout (0597473): core 2.79's Settings, Appearance, Chrome, Status bar would change nothing on a phone, which draws its strip only while Cloud needs attention; the row hides like Title bar. A desktop-layout iPad keeps it.

  • Core 2.79.0 (969bda3): core-2.79.0-core.h04cf920466765284 from ZenNotes/zennotes 584487ff, provenance checked by core:adopt. The shell sets openNotesToRead: isPhoneViewport, so a note opened from a Search pick or a palette command shows its first line rendered with the keyboard down, and a cancelled palette or a palette toggle leaves the keyboard down. Also from core: the cover fold in Edit mode, a bare timestamp title for a blank Quick Note prefix, and the Tasks filter matching a tag in a task note's body.

    • Palette hide list (phone layout): Toggle Timeline (a keyboard-driven side panel that would draw as a sheet over the note a pick opens; the Tasks view lists tasks by date) and Toggle Status Bar (changes nothing on a phone).
    • No rule needed: the Unsplash commands, tab and Settings row follow the bridge's optional Unsplash methods, which this shell leaves out; Default shares location is macOS desktop only; the key recorder's palette hint sits in the palette footer the phone already hides, and Settings, Keymap is hidden on phone hardware.
    • Bridge: only optional Unsplash methods and the sharesLocation vault setting (passed through by normalizeVaultSettings). The connection error's doc comment loses a long dash.
  • Version (5fc0f23): 1.34.0, build 53 in all six configurations.

  • Core refresh (3453dc2): core-2.79.0-core.h434377c05a50e117 from 44954fab, which replaces the first draft; its one change is the Settings, Typography, Covers description naming the Unsplash key only where a key row exists.

  • Found by the walk, fixed (all also in build 52):

    • 12fc216 a note picked in Browse (the drawer's note, database and file rows) opened with the keyboard up and the caret before the raw # Title; the rows now open through drawer-open.ts, which arms the read-open hold at the tap, before the drawer closes.
    • 733e9f4 the header's Back chevron ran nav.back outside the palette and raised the keyboard; it now goes through openToRead.
    • 45c84b8 Return in the command palette could run a row the shell hides (typing "timeline" then Return opened the Timeline): palette-hidden-rows.ts keeps the highlight on a visible row, makes the arrows skip hidden rows, and lets Return run only a visible one.
    • e4ebd92 MCP, CLI and Keymap came back in the Settings section list after typing in Settings search and clearing it (core rebuilds the list; the shell hid them once at mount). The hide now runs in cleanSettingsContent through settings-sections.ts, on every change.
    • 51ff99b coming back to a note being read raised the keyboard through core's focus heal (App.tsx #350); focus-heal.ts holds the read-open hold through it unless the editor was being typed in. focus-heal.ts, its test and read-open.ts are byte-identical with the Android shell's.
    • a5e4c76 Settings, Layout from Desktop back to Automatic reloaded with the keyboard up and the caret on line 1: the restore landing closes the sidebar that held the focus (core hands it to the editor, #353) and the restored pane focuses itself; the landing now runs inside openToRead, as on Android (restore-landing.test.ts is the same file). A cold launch did not reproduce.
    • 5c9acfb Settings search listed settings on hidden sub-tabs and rows ("key", "vim", "quick capture", "status bar", "trash"); HIDDEN_SETTING_RESULTS in settings-sections.ts (the Android helper with the iPhone's own rows) hides them, with a check against the installed core and mobile.css.
  • Startup and later fixes:

    • 0f52375 boot no longer waits forever on a native answer (the app version, Cloud sign-in links, shared captures): each wait ends after 2 s (boot-wait.ts, the Android helper) and boot goes on, logging once; a late answer never overwrites what boot decided.
    • 8a3e430 a Settings search whose every match is hidden shows core's own "No settings match your search." box; sub-tab results follow the same device sets that hide the tabs, so an iPad in a narrow window keeps its Vim and Folders results. 0479123 the box sits exactly where core's own does.
    • 622d678 the restore landing holds the keyboard until the restored note's editor is on screen (landing-hold.ts, holdLanding), capped at 15 s; the Android files, byte for byte.
  • Core refreshes: 17e02ae h747103b57a975077 (source cefd86d9, the #1012 editor fix: typing in a just-indented empty task lands after its marker); fb9b833 the final core-2.79.0-core.h7896a01910a2ea0f (source 47d26827): the folder Gallery, database table view columns and picked rows, Set Callout Type and Remove Callout, the code block language picker, the theme pick keyboard fix and typing in a just-named note under its title (found on the iPhone, fixed in core).

  • Found walking the final core, fixed in the shell (the same as the Android shell's, read-open.ts byte for byte):

    • 7506e51 a Gallery card opened its note with the keyboard up (cards join the read-open rows), and the Gallery's wrapped header controls drew under the first cards (a wrapping pane header keeps its own height).
    • 5a7a94e the database Columns menu's find field took the focus as the menu opened, and a callout type pick refocused the editor; both raised the keyboard. A programmatic focus on that field is refused unless it was tapped, and the callout menu rows arm the read-open hold.
    • 0e7a938, af1199c the theme list's "Theme preview" caption ran under the palette's Cancel; the row now ends before Cancel and its Back stays on one line.
    • fdd429d a database table's selection bar ran Clear off the right edge; on a phone the count takes its own line and the actions wrap under it (the picks editor's bar too).

Validation: npm run upstream (boundaries, typecheck), 393 tests, build, cap sync ios; CI green on every push, last on fdd429d (run 40941286580). The Release-configuration simulator build of the final core (iOS 27, 1.34.0 (53)) was walked on 2026-10-29 on an iPhone 17 Pro and an iPad Pro 11-inch: cold launches, resume and 15 rapid Layout reloads (none blank, keyboard down, settings kept); the all-hidden Settings search box; Vim and Folders results in a narrow iPad window; read-open from Home, Browse and search; the Layout switch both ways; typing or reading, then Home and back; a 2,500-note vault (no keyboard when the scan lands, polled for 29 s); #1012 with a hardware Tab (Return then Tab on iPhone, Vim o then Tab on iPad); the theme pick and new-note typing fixes; the Gallery, database Columns and picked rows, Set Callout Type and Remove Callout, and the code language picker by touch. af1199c was rebuilt and its theme list rechecked, and fdd429d rebuilt and its database selection bar walked (select, Clear, picks, Edit picks). Clips in the desktop repo's docs/releases/v2.79.0/media/phones/iphone-*.mp4. The phone does not show core's What's New view.

…des Title bar

Core 2.79 adds a Status bar switch under Settings, Appearance, Chrome. On a phone the strip along the bottom only shows while ZenNotes Cloud needs attention, whatever the switch says, so the row would change nothing there; it is hidden in the phone layout like the Title bar row. iPad in the desktop layout keeps it.
…old and a bare Quick Note title

Core core-2.79.0-core.h04cf920466765284, built by CI from ZenNotes/zennotes
584487ff (the v2.79.0 release commit); core:adopt checked SHA-256,
SHA-512, packed versions and clean-source provenance.

Core 2.79.0 lets a host open notes to read: a note opened from a Search
pick or a palette command shows its first line rendered with the keyboard
down, and backing out of the palette or running a toggle from it leaves
the keyboard down too. This shell turns it on for the phone layout
(openNotesToRead: isPhoneViewport); a desktop-layout iPad keeps core's
focus. The shell's own read-open guard still covers Home, the lists and
widget links. Also from core: a cover's frontmatter folds to one line in
Edit mode, a blank Quick Note prefix gives a bare timestamp title (#1008),
and the Tasks filter matches a tag written in a task note's body (#1008).

The phone layout hides two new palette commands: Toggle Timeline (a
keyboard-driven side panel that would draw as a sheet over the note a pick
opens; the Tasks view already lists tasks by date) and Toggle Status Bar
(the phone draws its strip only while Cloud needs attention, so it would
change nothing; its Settings row hid in 0597473). Nothing else needs a
rule: the Unsplash commands and Settings row follow the bridge's optional
Unsplash methods, which this shell leaves out, so the phone has no Unsplash
tab; Default shares location shows only in the macOS desktop app; and the
key recorder's palette hint sits in the palette footer the phone already
hides, with Settings, Keymap hidden on phone hardware.

The bridge contract adds only optional methods (Unsplash) and the
sharesLocation vault setting, which DEFAULT_VAULT_SETTINGS now carries and
this shell's normalizeVaultSettings passes through untouched, as it does
every key a desktop writes. The connection error's doc comment loses its
long dash.
The drawer's Notes list opened its rows through a bare openNote, outside
the read-open guard, so a note picked there came up with the soft keyboard
over half of it and the caret parked before the raw "# Title". The same
note opened from Home, a core list, a link, a search pick or a palette
command is left to read with its first line rendered. Build 52 did the
same; walking build 53 on the Release simulator build turned it up.

The note, database and file rows (pinned notes are among the note rows)
now open through openDrawerRowToRead (drawer-open.ts), which arms the
read-open hold when the row is tapped and keeps it through the drawer's
close and the open a beat later. Arming it at the open alone would be too
late: the editor can take the focus as the drawer closes. A tap into the
text releases the hold and raises the keyboard as always. New note here
keeps the drawer's plain go, so a note created there still focuses.

The other shell opens were checked and already read: Home's Recent and
Favorites, the Tasks, Quick Notes and Tags lists (READ_ROWS), wikilink
taps, the note swipe and widget links.
Walking the drawer fix turned up the same keyboard from the chevron at the
start of a note's header: with history behind it, Back ran nav.back through
core's command registry outside the palette, so the note it went back to
came up with the soft keyboard over it and the caret before the raw
"# Title". Build 52 did the same. The palette's Go Back already reads
(core 2.79 marks it opensToRead), and so does every other way of landing
on a note that is already there.

Back now runs nav.back through openToRead, so the read-open hold refuses
core's follow-up focus; a tap into the text raises the keyboard as before.
With no history, Back still goes to Home, and the reference sheet's chevron
still closes the sheet.
The shell hides desktop-only palette commands by setting their rows to
display: none, but core's highlight is an index into every result, hidden
rows included, and its arrows and Return go by that index. Typing
"timeline" left the highlight on the hidden Toggle Timeline, and the soft
keyboard's Return opened the Timeline as a sheet; the same held for every
hidden command (Split Right, Check for Updates and the rest), so it
predates this release. The walk of build 53 turned it up.

palette-hidden-rows.ts keeps core's highlight on a visible row: when the
results change and the highlighted row is hidden, the first visible row
takes it, through the same mousemove core uses for a pointer. A
capture-phase keydown guard makes the arrows (and Ctrl+N/P, Ctrl+J/K)
skip hidden rows, and lets Return run only a visible row; with no visible
row, Return does nothing and the palette stays open. It lives in the shell
because core does not know the shell's hide list, and it does nothing
while no row is hidden. Taps only ever reach visible rows.
…sh key on a phone

Core core-2.79.0-core.h434377c05a50e117, built by CI from ZenNotes/zennotes
44954fab, replaces h04cf920466765284 (584487ff); core:adopt checked
SHA-256, SHA-512, packed versions and clean-source provenance.

The one change: Settings, Typography, Covers described itself as "How a
note's cover shows, and the Unsplash key the cover picker searches with."
on every host, while this shell has no Unsplash bridge and so no key row
under it. Core now names the key only where the row is there, so the phone
reads "How a note's cover shows." The bridge contract and shared domain
are repacked from the new source commit with no other change, and the lock
moves only the three @ZenNotes entries. The build number stays 53: nothing
was uploaded.
On a phone the Settings section list hides MCP, CLI and Keymap (the first
two on any device, Keymap on phone hardware), but the hide ran once, when
the panel mounted. Core rebuilds the section list whenever the Settings
search empties, so typing anything and clearing it brought all three back,
and a tap opened those desktop pages. The core markup is the same as in
2.78, so the gap is older than this release; walking build 53 turned it up.

The rows are now hidden by cleanSettingsContent, which already re-runs on
every change to the panel for the search results and the sub-tabs, through
hideSettingsSectionRows (settings-sections.ts). The hide holds across
searches, clears and section switches. A desktop-layout iPad is unchanged.
…rd down

Core heals the editor's focus whenever the window regains focus or the page
becomes visible again (App.tsx, #350): if its store says the editor was the
last surface and the editor lacks DOM focus, it focuses it. A note opened to
be read is still that surface, so the heal raised the keyboard over it on a
return to the app (the Android shell saw it three times of three).

focus-heal.ts notes, as the app is left (the window's blur, the page going
hidden, pagehide), whether the editor held the focus. Coming back to a note
that was being read arms the read-open hold just before the heal runs, so
its focus is refused; a touch releases it. Someone who was typing gets the
keyboard back from the heal. The listeners in read-open.ts run in the
capture phase, before core's. A desktop-layout iPad is left to core.
focus-heal.ts, its test and read-open.ts are byte-identical with the
Android shell's.
…yboard down

Switching Settings, Layout from Desktop back to Automatic reloads the app,
and the restored note came back with the keyboard up and the caret on
line 1 (reproduced on the Release build). Logged on the page, the reload
brings no window focus or visibility event: the restore landing
(usePhoneLayoutBoot) closes the sidebar for the phone layout, and core
hands the focus to the editor when a sidebar that held it closes (App.tsx,
#353), while the restored note's pane focuses itself as it mounts. In the
desktop layout the sidebar was open and focused, since that is where its
Settings button is, and after a reload the web view still holds the focus,
so the keyboard came up. A cold launch runs the same focus calls, but the
web view does not hold the focus yet, so no keyboard showed there.

The landing now runs inside openToRead, so the hold is armed while the
sidebar closes and the restored note or view appears, and both focus calls
are refused like an open's; a touch releases it as always. The shape
follows the Android shell's fix, and restore-landing.test.ts is the same
file.
Settings search listed every setting that matched, the ones on pages the
phone hides too: "key" offered the Vim sub-tab's Exit insert mode with and
the Quick capture hotkey, "vim" the whole Vim sub-tab, and "status bar" or
"title bar" the rows mobile.css hides; a tap opened a hidden page or a
section with nothing to show. Only the Keymap, MCP and CLI sections were
filtered, by the section id core puts on each result.

A result row carries only its section, so HIDDEN_SETTING_RESULTS
(settings-sections.ts) names each hidden setting by section and title:
the settings on the Search, Quick capture and Workflows sub-tabs and the
rows mobile.css hides on any device, plus, on a phone, the Vim and Folders
sub-tabs and the phone-only rows, Status bar and Title bar among them.
cleanSettingsContent calls hideSettingsSearchResults at every width; the
hidden sections and the phone-only entries apply at phone width. The
helper matches the Android shell's, with the iPhone's own rows.
settings-sections.test.ts checks every title is still in the installed
core; settings-sections-core.test.ts checks the list against core's
sub-tab search ids and mobile.css, so a new setting on a hidden sub-tab or
a newly hidden row fails at the next adoption.
…page

Boot awaits a few native bridge calls before anything renders: the app
version, the Cloud sign-in link listeners and launch URL, and the Share
Extension's waiting captures. On the Android shell, about eleven rapid
Layout reloads left one of those calls unanswered, and the page stayed
blank with nothing to do but quit. The iPhone awaits the same kind of
calls, so it had the same exposure.

Each wait now ends after two seconds (boot-wait.ts) and boot goes on
without the answer, logging once. The work itself keeps running, so
listeners still register and shared captures still land when the answer
comes, but a late answer is never applied over what boot already decided:
the app version stays the placeholder Cloud sign-in was configured with.
The vault open is deliberately not bounded, since without it there is
nothing to show. The helper is the Android shell's; the iPhone has no
native preferences restore, so the bounded steps differ. Tests cover an
answer that never comes, a fast one, a late one that must not clobber,
and a failure in time.
… keeps its tabs' results

Two leftovers of hiding Settings search results the shell hides.

A search whose every match was hidden left an empty list: core shows "No
settings match your search." only when nothing matched at all. The shell
now adds that same element, copied from core's markup (a test checks the
class and text against the installed core), when every result is hidden,
and removes it as soon as a visible result is back.

Results for a sub-tab's settings were hidden by window width, so an iPad
in a Split View narrow enough for the phone layout lost its Vim and
Folders results although it still shows those tabs. Sub-tab results now
follow the same device sets that hide the tabs themselves, which moved to
settings-sections.ts so the two cannot drift; rows mobile.css hides still
follow the phone layout class, as the CSS does.
… on screen

The landing after a reload or a cold launch ran under openToRead, whose
hold lets go a set time after it is armed: 700 ms after the landing's
synchronous work, which is all the landing waited for. But the landing
returns as soon as it has closed the sidebar and chosen Home or the note,
while the restored note's editor may not be on screen yet; when it mounts,
core focuses it, because closing the sidebar had already handed the focus
to the editor. On a slow vault that could come after the hold had let go.

holdLanding (read-open.ts) arms the hold before the landing runs and keeps
it armed, re-arming every 2.5 s, until landingOnScreen says the landing
has nothing left to load: Home or a view at once, a note once its editor
is on screen. landing-hold.ts caps it at 15 s, so a note that never
appears cannot hold the keyboard forever, and a touch ends it at once as
it ends every hold.

Ported from the Android shell's fix: landing-hold.ts, its test, read-open.ts
and restore-landing.test.ts are the same files in both shells. Tests: a
slow restore stays held past five seconds and settles when the note
appears; the cap lets go and stops re-arming; a touch stops it without
re-arming; a fast landing settles at once; source checks that the landing
runs under holdLanding and the hold is armed before it.
…ands after its marker

Core core-2.79.0-core.h747103b57a975077, built by CI from ZenNotes/zennotes
cefd86d9, replaces h434377c05a50e117 (44954fab); core:adopt checked
SHA-256, SHA-512, packed versions and clean-source provenance.

The one change to the phones is the editor fix for #1012: an empty task
(`- [ ] `) indented with Tab (after Vim's `o`, or after Enter) put the
caret before the marker, so the next keys typed landed in front of
`- [ ] `. Core now keeps the caret after the marker. The other change in
that source range is desktop main only. The bridge contract and shared
domain are repacked from the new source commit with no other change, and
the lock moves only the three @ZenNotes entries. The build number stays
53: nothing was uploaded.
…s own does

The walk of a search whose every match is hidden ("ripgrep", "hotkey")
showed the shell's "No settings match your search." box 4px lower than the
same box core shows for a search with no results at all ("zzqx"). Core's
results list spaces its children with space-y-1, and the hidden results
before the shell's box still count as siblings there, so the box took a
top margin core's own never gets. mobile.css now takes that margin off the
shell's box only; a test checks core still spaces that list the same way.
…view columns and code languages

Core core-2.79.0-core.h7896a01910a2ea0f, built by CI from ZenNotes/zennotes
47d26827, replaces h747103b57a975077 (cefd86d9); core:adopt checked
SHA-256, SHA-512, packed versions and clean-source provenance. This is
the core 2.79.0 ships with.

New for the phone: a folder opens as a Gallery of its notes by cover
(Open Folder Gallery in the palette); a database table view keeps its own
columns (a Columns picker) and its own picked rows, and the + makes table
views and copies; the palette's Set Callout Type... and Remove Callout turn
a block into a callout and back (#1016); a code block's label picks its
language by tap and names the language it guesses for an unlabeled block
(#1014); long menus get a find field, where j and k are letters with Vim
mode off; and What's New gains cards for these.

Two fixes found walking the phones: picking a theme from the palette no
longer raises the keyboard, and typing in a just-named note goes on the
line under its title instead of in front of the `# Title` (the name
field's Return left the caret where the new editor started, at the very
beginning). The bridge contract and shared domain are repacked from the
new source commit with no other change, and the lock moves only the three
@ZenNotes entries. The build number stays 53: nothing was uploaded.
…o longer covers the cards

Walking core 2.79.0's folder Gallery at phone width turned up two shell
gaps, the same two the Android shell found. A tap on a card opened its
note with the editor focused, the keyboard up and the caret at the top,
where it revealed the note's cover controls and frontmatter: the read-open
guard listed core's other note lists (Home, Tasks, Quick Notes, Tags,
Archive, Trash) but not the new cards. And the Gallery's header, which
wraps its Sort and Include subfolders controls under the title and grows
from core's min-h-12, was held to the phone's fixed pane-header height, so
its second line drew under the first row of cards.

read-open.ts adds [data-gallery-card] to the rows that open to read, and
mobile.css lets a wrapping pane header (flex-wrap; only the Gallery's
wraps) take its own height; the note, database and other single-line
headers keep 2.75rem. read-open.ts and gallery-phone.test.ts are the
Android shell's files, byte for byte.

Tests: the Gallery card marker is in the read-open rows and is still
core's own; core's Gallery header still wraps and the phone rule lets it
grow.
A palette list opened from a command (Themes..., a workflow, a vault)
draws a row above its input with "Back" and a caption, and the phone's
Cancel sits over the top-right corner of the palette, which on these lists
is that row: picking a theme showed "Theme preview · ↵ to keep, esc to
revert" running under Cancel. The row now ends before Cancel and its
caption wraps, as the New note form's header already does. Matched on the
row's Back button ("Back to commands"), which a test checks is still
core's.
…own on a phone

Two core 2.79.0 behaviors that a desktop wants raised the soft keyboard
on the phone layout, the same two the Android shell found. The database
Columns menu focuses its find field as it opens (DatabaseColumnsMenu.tsx,
so typing filters at once), which on a phone put the keyboard over the
menu each time Columns opened it; the iPhone walk saw it on a new
database's table. And picking a type in the Callout type menu (from the
palette's Set Callout Type... as from the editor menu) ends with
view.focus() (EditorPane.tsx, the caret back where it was), which raised
the keyboard over the new callout; Remove callout in the editor menu does
the same.

read-open.ts refuses a programmatic focus on that find field at phone
width unless the last touch went down on the field itself, so a tap into
it still raises the keyboard; and a tap on a Callout type row or on
Remove callout arms the read-open hold, as a note row does, so the editor
focus that follows is refused. Core is unchanged: on a desktop both
focuses are what people want. read-open.ts and phone-focus-guards.test.ts
are the Android shell's files, byte for byte.

Tests: core still focuses the field and the editor in those places (a
change there fails at the next adoption), and the shell's guards are in
place.
With the caption now ending before Cancel, the walk showed the row's
"‹ Back" button squeezed onto two lines by the wrapping caption. The
button keeps its width and stays on one line; the caption wraps beside it.
Selecting rows in a database table shows a bar with the count, "Show
only these in this view", Delete and Clear, laid out as one desktop line.
That line is wider than a phone: on an iPhone 17 Pro Clear ran off the
right edge, and a two-digit count or a narrower phone loses more.

On a phone the bar wraps, and its first span (the count) takes a line of
its own, so the actions sit together on the line under it and wrap again
only on a phone narrower still. The picks editor's bar (Editing picks,
Update picks, Cancel) carries the same data-db-selection-bar attribute
and gets the same two lines. Core is unchanged; a test checks both of its
bars still open with the count's span and that Clear is there. The rule
and its test are the Android shell's, byte for byte.
@adibhanna
adibhanna merged commit fdd429d into main Oct 29, 2026
1 check passed
renovate Bot added a commit to scottames/copr that referenced this pull request Oct 30, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ZenNotes/zennotes](https://redirect.github.com/ZenNotes/zennotes) |
minor | `2.78.0` → `2.79.0` |

---

### Release Notes

<details>
<summary>ZenNotes/zennotes</summary>

###
[`v2.79.0`](https://redirect.github.com/ZenNotes/zennotes/releases/tag/v2.79.0):
ZenNotes v2.79.0

[Compare
Source](https://redirect.github.com/ZenNotes/zennotes/compare/v2.78.0...v2.79.0)

ZenNotes 2.79.0 puts your tasks on a timeline and every command on a
key. The new Timeline panel lays every open task with a date down one
line, with overdue work and milestones marked. Every command in the
palette can now take a key of its own, from Move Note to Trash to a
leader sequence in Vim mode. On macOS, Share to ZenNotes saves a page or
a selection from Safari and any other app. Unsplash covers arrive with a
key of your own, and the keyboard works fully with Vim mode off, in the
sidebar and in every side panel.

Released from
[`47d2682`](https://redirect.github.com/ZenNotes/zennotes/commit/47d26827)
through
[#&#8203;1010](https://redirect.github.com/ZenNotes/zennotes/issues/1010),
[#&#8203;1011](https://redirect.github.com/ZenNotes/zennotes/issues/1011),
[#&#8203;1013](https://redirect.github.com/ZenNotes/zennotes/issues/1013)
and
[#&#8203;1017](https://redirect.github.com/ZenNotes/zennotes/issues/1017)
on 2026-10-29.

#### Features

- **The Timeline panel**
([#&#8203;1007](https://redirect.github.com/ZenNotes/zennotes/issues/1007),
asked for by williamcheuk03). A fifth right-hand panel, beside Outline,
Connections, Comments and Calendar, that lays every open task in the
vault with a date down one line. Overdue tasks sit on top in red with
how many days late each one is, Today follows, then one node for each
later day that has work; a run of empty days folds into one "N quiet
days" line. A task's date is its `due:` date, or for a task in a daily
note, that note's date. Tag a task `#milestone` and its day draws as a
diamond, saying how many open tasks are due before it. A switch reaches
2 weeks ahead (the default), a month or everything (`timeline_range`
under `[view]` in config.toml), and the filter takes the Tasks filter
syntax. Open it with `Mod+7`, `Space n` in Vim mode, `:timeline`, Toggle
Timeline in the command palette, or its button in the note header;
`j`/`k` move, `x` ticks, `m` opens the task menu, Enter opens the note
at the task's line.
- **Every command can take a key**
([#&#8203;971](https://redirect.github.com/ZenNotes/zennotes/issues/971),
thanks to Asterythm). All 197 commands in the command palette can now be
given a key, all unbound to start. Highlight one in the palette and
press `Alt+Enter` (`Option+Enter` on macOS) to record a key without
leaving the palette, or use the new Commands group in Settings, Keymap.
A key is a chord, a function key, or with Vim mode on a leader sequence
such as `Space x a`, which shows in the leader hints. Your key wins over
every default, the editor's own keys included; the recorder warns when
it takes over a default and refuses one another of your bindings holds.
When a command cannot run where you are, its key says why ("Restore from
Trash only works on a note in the Trash"). In config.toml the keys live
under `[keymaps.commands]`, and from the ex line `:bind <C-BS>
note.trash` binds and `:unbind command note.trash` takes the key away.
- **Share to ZenNotes on macOS** (asked for by charles b.). Choose
Share, ZenNotes in Safari or any app with a Share menu to save the page
you are on, the text you selected, or both, as a note, with an optional
line of your own. A page becomes a note named after it, with your
selection quoted and a link back; text alone is named from its first
line. Each vault chooses where shares land under Settings, Vault, Notes,
Default shares location: Quick Notes (the default), your primary notes
location, or a folder such as `Clippings`, and the sheet's heading says
where a share will go. With ZenNotes closed, a share waits and is filed
the next time you open it; a share for a server vault is filed once you
are connected to it.
- **Unsplash covers with your own key** (asked for by charles b.). The
cover picker has an Unsplash tab: paste your Unsplash Access Key once
under Settings, Typography, Covers, and search millions of photos for a
note's cover. Searches go straight from your computer (or your browser,
in the web app) to Unsplash with your key; zennotes.org takes no part.
The key is kept in your system's secure storage, the photo is credited
to its photographer on the cover, and without a key the tab shows how to
get one.
- **A cover's frontmatter folds to one line.** In Edit and Split, a
cover's `banner`, `banner_y` and credit lines fold into one muted line,
such as `cover · Unsplash photo by Kalen Emsley` or `cover ·
lisbon.jpg`, since the cover above already shows the picture. Move the
cursor onto it (arrows, or `j`/`k`) or click it to edit the raw lines;
it folds again when you leave.
- **A switch for the status bar** (asked for by Piotr). Settings,
Appearance, Chrome, Status bar hides the bar along the bottom of the
window; it comes back on its own only while ZenNotes Cloud needs you.
Also Toggle Status Bar in the command palette and `:set nostatusbar`
(`show_status_bar` under `[appearance]` in config.toml).
- **Trash from the sidebar by key**
([#&#8203;972](https://redirect.github.com/ZenNotes/zennotes/issues/972),
thanks to Asterythm). `x` in Vim mode, or `Mod+Backspace` in either
mode, moves the note under the sidebar cursor to the Trash after a
confirm, or the whole selection with one confirm; the cursor stays on
the row that took its place. With the sidebar focused, Move Note to
Trash and Move Note to Archive act on that row too.
- **A folder as a Gallery** (asked for by charles b.). Open as Gallery
on a folder in the sidebar shows its notes as cards by their covers: a
vault image, an Unsplash photo or a gradient, and the title's first
letter for a note without one. Sort by updated, created or title, switch
on Include subfolders, and filter by title. Open it with Open Folder
Gallery in the command palette, `:gallery` (with an optional folder,
`:gallery Projects`), or `Space G` in Vim mode; in the grid h, j, k and
l move, Enter or `o` opens, and `/` filters (with Vim mode off, the
arrows, Enter and Escape). Covers are read only for the cards on screen,
so a folder of a thousand notes opens at once. The sort and the
subfolder switch travel in config.toml (`gallery_sort`,
`gallery_include_subfolders` under `[view]`).
- **Database views that keep their own columns** (asked for by charles
b.). A table view's Columns button, beside Filter, opens a checklist of
its columns with a find field, Show all and Hide all, and reads "Columns
5 of 44" once some are hidden; each saved view keeps its own, so one
wide CSV can carry several narrow views. The + beside the view tabs
makes a New table view, a New board view, or a copy of the current one
(Duplicate this view). To keep certain rows in a view, select them and
choose Show only these in this view: the view says "Showing N picked
rows", with Edit picks and Show all rows, a row you add there joins its
picks, and a board shows its picks too. Press `c` in the grid in Vim
mode for Columns; five palette commands (Choose Database Columns, New
Table View, Duplicate View, Show Only Selected Rows, Show All Rows) can
each take a key.
- **Right-click to make or change a callout**
([#&#8203;1016](https://redirect.github.com/ZenNotes/zennotes/issues/1016),
asked for by williamcheuk03). Right-click selected lines, or a
paragraph, and choose Turn into callout…: a Callout type menu lists
every type with its icon (Note, Info, Tip, Success, Warning, Danger
(Error), Quote and the rest), and your lines become a `> [!type]`
callout in one undoable change. Right-click a callout, written out or
drawn as a card in Live Preview, for Change callout type… (its title and
fold marker stay) and Remove callout, which turns it back into plain
lines. From the keyboard: Set Callout Type… and Remove Callout in the
command palette, each bindable, and `Space l a` in Vim mode.
- **Code blocks pick their language, and guess one they lack**
([#&#8203;1014](https://redirect.github.com/ZenNotes/zennotes/issues/1014),
asked for by williamcheuk03). The language label at a code block's top
right now opens a Code block language picker: type to find any of the
languages the editor highlights (your own TextMate grammars too) and
pick one, and only the fence's language word changes, as one undoable
edit; Text (plain) removes it. Copy moved to its own icon beside the
label. A block with no language gets a guess, highlighted the same way
and labeled `python · detected`, but nothing is written to the file
until you choose Python (detected) at the top of the picker; tiny or
ambiguous blocks stay plain text. From the keyboard: Set Code Block
Language… in the command palette, or `Space l l` in Vim mode. Settings,
Editor, Writing, Detect code block languages turns guessing off in the
editor and the reading view alike (`detect_code_languages` under
`[editor]` in config.toml).

#### Fixes

- **Update checks while a release is uploading**
([#&#8203;1003](https://redirect.github.com/ZenNotes/zennotes/issues/1003),
thanks to THEMaeker). A check for updates in the first minutes of a
release could find the new version before its update file was uploaded
and showed a dialog full of HTTP headers that called a 404 a "temporary
server error". It now says "ZenNotes 2.79.0 is still being published.
Try again in a few minutes.", every other update error gets one plain
sentence, and the raw text sits under Details in Settings, About. From
this release on, a new version only becomes the latest release once all
five update files are on it, so that window is gone.
- **Select all leaves the note's title alone**
([#&#8203;1006](https://redirect.github.com/ZenNotes/zennotes/issues/1006),
thanks to williamcheuk03). With the cursor in a note's text, the first
Ctrl+A (Cmd+A on macOS) selects from the first line under the `# Title`
heading to the end, so typing over it no longer replaces the title; a
second press selects the whole note. Vim's Ctrl+A increment keeps
working.
- **A blank Quick Note prefix gives a bare timestamp**
([#&#8203;1008](https://redirect.github.com/ZenNotes/zennotes/issues/1008),
thanks to davi-jorge-art). Clearing the prefix in Settings still named
new quick notes "Quick Note ...": the empty field was saved, but the
title builder put the default back. It now gives a title that is just
the timestamp or date, the empty field reads "No prefix", and the field
keeps the spaces you type.
- **The Tasks filter finds a task note by a tag in its body**
([#&#8203;1008](https://redirect.github.com/ZenNotes/zennotes/issues/1008)).
A task made with New task (a note of its own) now matches a tag written
anywhere in its note, in the list, the calendar and the board, as the
Tags view already did.
- **Menus with Vim mode off take j and k as letters.** In a right-click
menu, `j` and `k` moved the highlight even with Vim mode off; with it
off they now go into the menu's filter like any letter, and the arrows
move.
- **Typing in a new note goes under its title.** Make a note, name it
and press Enter (or run New Note from the palette), then type: the text
went in front of the `# Title` heading, as `Body# My note`, on desktop
and on the phones. It now goes on the empty line under the heading.
- **Typing in a new sub-task lands after its checkbox**
([#&#8203;1012](https://redirect.github.com/ZenNotes/zennotes/issues/1012),
thanks to JulianBnder). Vim `o` on a task line and then Tab (or Enter,
then Tab, with Vim mode off) showed the cursor after the new sub-task's
`- [ ] `, but what you typed went in before it. Since 2.71.0, an empty
task that you indented did this; text now goes where the cursor shows.
- **Self-hosted servers behind your own certificate authority connect on
macOS**
([#&#8203;1009](https://redirect.github.com/ZenNotes/zennotes/issues/1009),
thanks to lewxdev). With a certificate from a private authority that
your Mac trusts (step-ca, a company root), connecting failed with "fetch
failed" unless ZenNotes was launched with `NODE_USE_SYSTEM_CA=1`. The
app and its MCP server now also trust the certificates in the system's
store, as the window always did.
- **Cloud sync after an assistant edits a note**
([#&#8203;1004](https://redirect.github.com/ZenNotes/zennotes/issues/1004),
thanks to tdtmusic2). Once an assistant (through the MCP server) had
edited a note, Cloud sync failed on every run with "This path is not
eligible for vault sync." The fix is on the Cloud server and is already
live, so every version syncs again with no update.
- **The keyboard with Vim mode off.** The sidebar walks like a tree: →
opens or expands, ← collapses, Page Up and Page Down move a screenful,
and Shift+F10 opens a row's menu. The note list, Connections, Outline
and Comments panels gained the same keys (→ opens, ← goes back, Page
Up/Down, the menu key in the note list), and Focus Sidebar from the
command palette keeps the keyboard instead of handing it back to the
editor. Letter keys stay off with Vim mode off.
- **The palette names no Vim key with Vim mode off.** Seventeen palette
rows showed keys that only work in Vim mode (leader chords like `Space
d`, ex commands like `:w`, `z c`, `Ctrl+O`, `Ctrl+W h`). They now show
only with Vim mode on, and Go Back and Go Forward show `Alt+←` and
`Alt+→` instead.
- **Ctrl, Alt and Cmd keys work for list-view actions.** A modifier key
bound to a list view action (such as `"nav.delete" = "Mod+Backspace"`)
was silently stored without its `Mod` and never fired. It now keeps its
modifier and fires in the sidebar and every list view, and Settings
marks a binding that a global shortcut holds as "Never fires".
- **Deleting a comment from the keyboard asks first.** `d`, Backspace
and Delete in the Comments panel deleted a comment for good with no
confirm; they now ask, and the cursor moves to the next comment instead
of jumping back to the first. The card's own Delete button is unchanged.
- **An image in the note list opens as an image.** Enter or `l` on an
image file in the note list loaded the picture into the editor as text;
it now opens in its own tab, as a click does.
- **The cursor shows on a selected sidebar row.** A row that was part of
a multi-selection never drew the Vim cursor; it now shows as a ring over
the selection.
- **Phones open notes to read** (in the phone releases built on this
core: iPhone 1.34.0 and Android 1.1.50). A note opened from Home, the
drawer, a list, a link, a search pick, the Back button or a palette
command opens with its first line rendered and the keyboard down; tap
the text to type. Backing out of the palette, running a toggle from it,
or picking a theme leaves the keyboard down too, Return in the palette
no longer runs a command the phone hides, and Settings no longer
mentions an Unsplash key the phones do not have. On Android, a
self-hosted server whose certificate comes from your own certificate
authority now connects once that authority is installed (thanks to
lewxdev,
[ZenNotes/zennotesandroid#141](https://redirect.github.com/ZenNotes/zennotesandroid/issues/141)).

#### For contributors

- Timeline (`ecb35368`): `lib/timeline-rail.ts` builds the rail from the
Tasks view's own Today and Upcoming groups and `filterTasks` (no new
date or overdue rule, no parser copy touched); `TimelinePanel.tsx` joins
the right-panel family (`RightPanelId`, `side-panel-fit`, the tuck rail)
and handles its keys in its own `onKeyDown` after VimNav. New portable
pref `timelineRange`.
- Command keys (`28f7ed99`, `de773eda`): `commandKeymaps` sits beside
`keymapOverrides`, with a generated `shared-domain/commands-catalog.ts`
that a test rebuilds from `buildCommands()`.
`lib/command-keymap-dispatch.ts` is a capture-phase listener that stands
down for every overlay; leader sequences run in VimNav after the
built-in leader keys, which always win. `[keymaps.commands]` in
config.toml, with a courtesy read of bare command ids under `[keymaps]`
(`nav.back` is both an action and a command, so it stays the action).
`KeymapRecorder.tsx` is shared by Settings and the palette.
- Keymap chords in list views (`865c14d0`): `normalizeSequenceToken`
keeps `Mod` and resolves it at match time; `lib/list-view-keys.ts`
replaces the per-view `metaKey || ctrlKey || altKey` bail. Sidebar trash
(`4cb73ecf`): `lib/sidebar-note-actions.ts`, new action
`nav.sidebarTrash` (`Mod+Backspace`), and `note.trash` / `note.archive`
follow the sidebar cursor when it has focus.
- Vim off (`9b070afe`, `701988d2`): VimNav installs one more listener
that routes the focused sidebar and panels to their existing Vim
handlers with Vim off, typed keys gated; App's
`handlePanelKeyWithoutVim` is gone. `CommandPalette.runCommand` records
the panel a command moved the keyboard to before the palette closes,
which is what made Focus Sidebar stick. Palette hints (`4b7deaff`):
`vimOnly` in `commands.ts`.
- Share to ZenNotes (`fab6f182`, `27c30cdc`, `605b023b`, `9e35242d`):
`apps/share-extension` is a Swift share extension built and signed into
the app in `after-pack.js` like Quick Look; it writes JSON into
`~/Library/Application Support/ZenNotes/Share Inbox/Captures`, which
`share-inbox.ts` drains through `createNote`. `vault.json` gains
`sharesLocation`; server vaults need znserver 2.79
(`supportsSharesLocation`).
- Unsplash (`15cee9f2`, `1063a4f4`): the key lives in `safeStorage`
(refused without OS encryption) and the main process calls
api.unsplash.com directly; the web client keeps it in browser storage.
Covers stay hotlinked with `banner_credit` / `banner_credit_url` and the
download ping, per Unsplash's terms. The cover fold (`0df65fce`) is
`lib/cm-cover-fold.ts`, reading cover lines through `readNoteCoverLines`
in `shared-domain/note-cover.ts`; `cm-vim-display-line.ts` and
`cm-math-nav.ts` step into it like a math block.
- Updates (`63594b19`, `7edddae8`): `describeUpdateError` reads an HTTP
status only from structured fields (a bare `5\d\d` had matched an HSTS
header), and `ErrorDetails.tsx` is shared with the Cloud errors.
`release.yml` creates the release with `--latest=false`; a
`promote-latest` job marks it latest once all five feeds are up and
never over a newer release.
- Phones (`d10fdd76`, `c329a9a5`, `ea958af8`, `00cf1621`): the editor
host's `openNotesToRead()` decides read or edit;
`lib/command-landing.ts` sorts palette commands into read, edit and
stay, defaulting to stay. Status bar (`cfd3b103`): portable pref
`showStatusBar`, `:set statusbar`.
- Smaller fixes: `5d0d78e6` (`resolveQuickNoteTitle` takes `string |
null`), `2db21e79` (`filterTasks` takes a note-tags map), `57f9e8b3`
(`selectNoteText`, with `leadingTitleHeading` in shared-domain),
`39ac61b0` (`sidebarSelectedRowClass`), `aeaa41d4` (comment cursor).

#### Demos

Clips and screenshots of this release on the release build, attached to
this release:

**The Timeline**: `Mod+7` opens it beside a project note, with two
overdue tasks, today, the quiet days folded and a `#milestone` diamond;
`Space n`, `j`/`k` and `x` tick a task off the rail, and Month reaches
further ahead. [Watch the
clip](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/timeline.mp4)
(33 seconds, captioned).

![The Timeline panel beside a project
note](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/post-1-timeline.png)

**A key for any command**: `Alt+Enter` on Toggle Word Wrap in the
palette records F8, and F8 then wraps the note; in Settings, Keymap,
Commands, Move Note to Archive takes `Space x a`. [Watch the
clip](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/command-keys.mp4)
(39 seconds, captioned).

**Unsplash covers and the cover fold**: the frontmatter folds to `cover
· Unsplash photo by ...`, `k` opens it, and the Unsplash tab sets a new
photo (recorded against a local stand-in for Unsplash, with real photos
and their photographers). [Watch the
clip](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/cover-fold.mp4)
(26 seconds, captioned).

![The Unsplash tab in the cover
picker](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/post-3-unsplash-picker.png)

**Share to ZenNotes** from Safari, and the note it files:

![The ZenNotes share sheet over a Safari
page](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/post-4-share-sheet.png)

**The sidebar with Vim mode off**: `Alt+H`, the arrows walk the tree,
and `Mod+Backspace` trashes one note, then three at once with one
confirm. [Watch the
clip](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/sidebar-trash.mp4)
(28 seconds, captioned). **The status bar** hides from the palette and
comes back with `:set statusbar`: [watch the
clip](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/status-bar.mp4)
(13 seconds).

**A folder as a Gallery**: a Recipes folder with image, Unsplash and
gradient covers, the letter cards for notes without one, and the cursor
ring.

![A folder's notes as a Gallery of
covers](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/gallery.png)

**Database views**: a Pipeline view showing five of a database's 44
columns and three picked rows.

![A table view with five columns and three picked
rows](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/database-views.png)

**The callout menu**: Turn into callout… opens the Callout type list for
two selected lines.

![The Callout type
menu](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/callout-menu.png)

**Code block languages**: a block without a language, detected as
Python, with Python (detected) at the top of the picker.

![The code block language picker with a detected
language](https://redirect.github.com/ZenNotes/zennotes/releases/download/v2.79.0/code-language.png)

#### 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`. Turn Vim mode on in
Settings for steps 1 to 4.

1. **Timeline.** Write a few tasks with `due:` dates (one in the past,
one today, one next week) and one tagged `#milestone`. Press `Mod+7`:
overdue tasks sit on top in red, today has an accent ring, the milestone
is a diamond. Press `Space n`, then `j` and `x`: the task leaves the
rail and the note reads `- [x]`.
2. **Command keys.** Open the command palette, type "word wrap", press
`Alt+Enter`, then F8, then Enter. Press F8 in a note: word wrap toggles.
Run `:bind <C-BS> note.trash` and press Ctrl+Backspace on a note: it
asks to move it to the Trash.
3. **Sidebar trash.** Focus the sidebar (`Ctrl+W h`), move to a note
with `j`, press `x`: confirm, and the note is in the Trash with the
cursor on the next row.
4. **Select all.** In a note made with New note, click into its text and
press Cmd+A (Ctrl+A on Windows and Linux): the title is not selected.
Press it again: everything is.
5. **Quick Note prefix.** Settings, Notes, clear Quick Note prefix, then
make a quick note: its title is just the timestamp.
6. **Vim off.** Turn Vim mode off, press Alt+H: the arrows walk the
sidebar, → expands a folder, ← collapses it, Shift+F10 opens the menu,
and `j` does nothing. Open the command palette: no row shows `Space`,
`:` or `z` keys.
7. **Unsplash.** Under Settings, Typography, Covers, paste an Unsplash
Access Key (make one at unsplash.com/developers) and press Save. Run Add
Cover, press Tab, type "fog" and pick a photo: the cover shows with
"Photo by ... on Unsplash", and the frontmatter folds to one `cover ·
Unsplash photo by ...` line.
8. **Share to ZenNotes (macOS).** With ZenNotes running, in Safari
choose Share, ZenNotes, then Save: the page is a new note in Quick
Notes.
9. **Status bar.** Run Toggle Status Bar: the bar along the bottom goes
away.
10. **New sub-task.** With Vim mode on, in a note with `- [ ] parent`,
press `o`, then Tab, then type `abc`: the line reads ` - [ ] abc` (it
was ` abc- [ ]`). With Vim mode off, Enter then Tab does the same.
11. **Private certificate authority (macOS).** With a server whose
certificate comes from an authority in your keychain, launch ZenNotes
from the Dock and connect: it connects without `NODE_USE_SYSTEM_CA`.
12. **Gallery.** Put a few notes with covers in a folder, right-click
the folder in the sidebar and choose Open as Gallery: the notes show as
cards by cover. Press `l` and `j` (or the arrows with Vim mode off) to
move, Enter to open.
13. **Database views.** Open a database with many columns, press
Columns, Hide all, then tick four. Press +, New table view, and switch
back: each view keeps its own columns. Select three rows and choose Show
only these in this view: the view reads "Showing 3 picked rows".
14. **New note.** Make a new note, type its name, press Enter (in Vim
mode, then `i`) and type `Body`: it lands on the line under `# <name>`.
15. **Callouts.** Select two lines, right-click, choose Turn into
callout…, then Warning: the lines become a `> [!warning]` callout.
Right-click inside it, Change callout type…, Tip: it reads `[!tip]`.
Right-click again, Remove callout: the plain lines are back.
16. **Code languages.** Write a fenced block of Python without a
language: its label reads `python · detected` and it is highlighted,
while the file still has a bare ` ``` `. Click the label and choose
Python (detected): the fence reads ` ```python `. Click the label of
another block, type `type`, pick TypeScript, then Undo: the fence is
back as it was.

#### Distribution channels

- **GitHub release:** installers for macOS (Apple silicon and Intel DMG
and zip), Windows (x64 and ARM64 installer) and Linux (x64 and arm64
AppImage, deb, rpm, pacman, tar.gz), with five update manifests; the
clips and screenshots in Demos are attached too. This is the first
release made "latest" by the release workflow itself, only once all five
update manifests were uploaded:
- **AUR:** `zennotes-bin` 2.79.0-1 (AUR clone `6f48c67`, repo
`f47e888d`), pinned to `ZenNotes-2.79.0-linux-x64.tar.gz` SHA-256
`d8120c35…b172`, after the tarball check confirmed the bundled CLI
folder is world-readable.
- **Nix:** `packaging/nix/release-data.json` lifted from the update
workflow ([run
40946961282](https://redirect.github.com/ZenNotes/zennotes/actions/runs/40946961282),
bot PR
[#&#8203;1018](https://redirect.github.com/ZenNotes/zennotes/issues/1018)
closed) as `257da0e9`, and [nix-build on
main](https://redirect.github.com/ZenNotes/zennotes/actions/runs/40947531769)
passed.
- **nixpkgs:**
[NixOS/nixpkgs#579420](https://redirect.github.com/NixOS/nixpkgs/pull/579420)
now proposes 2.74.0 -> 2.79.0, changing only the version and two hashes;
the source hash comes from the tag tarball, and the same command
reproduces master's 2.74.0 hash.
- **Homebrew:** `zennotes` 2.79.0 in the tap (`a778600`), mirrored in
`2eab66f2`; both DMGs' SHA-256 match the cask and GitHub's digests;
`brew style` clean.
- **zn CLI:** the bundled zn is 0.12.2, the latest ZenNotes/tui release.
- **Website:**
[ZenNotes/website#97](https://redirect.github.com/ZenNotes/website/pull/97)
merged with the 2.79.0 entry and five captioned clips, the docs for
everything in this release, the server 2.79.0 and Android 1.1.50 entries
on their tabs, and the 2.79.0 share viewer (the 2.78.0 viewer kept for
pages already open).
[ZenNotes/website#98](https://redirect.github.com/ZenNotes/website/pull/98),
the
[#&#8203;1004](https://redirect.github.com/ZenNotes/zennotes/issues/1004)
Cloud fix, shipped earlier the same day. GitHub Actions cannot start
jobs on the website repository while its billing is blocked, so both ran
their full test suite on a Linux machine instead and were deployed to
Laravel Cloud by hand (`3c0b57c9`, then `f3b4a1c8`); the live check
passed: /releases leads with 2.79.0, the timeline clip matches the
merged file byte for byte, seeking works, /docs has the new sections,
and both viewers are served.
- **Server and Docker:** [ZenNotes/znserver
v2.79.0](https://redirect.github.com/ZenNotes/znserver/releases/tag/v2.79.0)
pins the browser app `web-2.79.0-web.h3e205408b9525e19` (`0c094f6`,
[ZenNotes/znserver#51](https://redirect.github.com/ZenNotes/znserver/issues/51));
all five binaries match `SHA256SUMS`, and the `manifest.json` asset
matches the pin byte for byte. `adibhanna/zennotes:2.79.0`, `2.79` and
`latest` are published from the tag. The README's install commands name
2.79.0
([ZenNotes/znserver#52](https://redirect.github.com/ZenNotes/znserver/issues/52)).
- **Boundary packages:** `core-2.79.0-core.h7896a01910a2ea0f`,
`web-2.79.0-web.h3e205408b9525e19` and
`viewer-2.79.0-viewer.h0711b886c5c63e6c`, built by CI from `47d26827`
and published as pre-releases (core once both phones were submitted on
it). "Latest" names v2.79.0.
- **Phones:** iPhone 1.34.0 (build 53,
[ZenNotes/zennotesios#83](https://redirect.github.com/ZenNotes/zennotesios/pull/83),
on the final core) is Waiting for Review in App Store Connect, set to
release automatically; it replaces build 52, which was withdrawn before
review. Android 1.1.50 (versionCode 53,
[ZenNotes/zennotesandroid#142](https://redirect.github.com/ZenNotes/zennotesandroid/pull/142),
which includes lewxdev's
[ZenNotes/zennotesandroid#141](https://redirect.github.com/ZenNotes/zennotesandroid/issues/141))
is in Google Play review at 100% rollout with no devices lost, and [on
GitHub](https://redirect.github.com/ZenNotes/zennotesandroid/releases/tag/v1.1.50)
with Play's signed universal APK.

#### Release validation

Every CI failure since 2.78.0 was read before this release, and the
gates ran in a worktree with its own node_modules on each of the
release's tips; on the final commit `47d26827`: typecheck 8/8 with no
turbo cache, test:run (shared-domain 2,208, app-core 4,401, desktop
1,255, quicklook 18), a fresh build, a Developer ID signed pack, and the
packaged launch check (page target and drawn app in 1.5 seconds, version
2.79.0). The vim-editor, sidebar-vim and editor-improvements smoke
suites passed on the first run. Release PR
[#&#8203;1017](https://redirect.github.com/ZenNotes/zennotes/issues/1017):
all ten checks passed; CI on `main` for `47d26827` ([run
40931288961](https://redirect.github.com/ZenNotes/zennotes/actions/runs/40931288961)):
all six jobs green before the tag. Release [run
40944582753](https://redirect.github.com/ZenNotes/zennotes/actions/runs/40944582753):
all jobs green; `verify-installers.py` ALL GOOD on the five manifests;
the app in both DMGs is `Notarized Developer ID` with a valid stapled
ticket. `npm run verify:channels -- 2.79.0`: every channel serves
v2.79.0 (Homebrew, AUR, Nix and the website's eight download buttons).

The new rule that a release becomes "latest" only when all five update
manifests are on it held on its first run: publishing the notes left
v2.78.0 as latest, and the release workflow's "Mark the release latest"
step ran at 20:48:03 UTC, nine seconds after the last manifest
(`latest-arm64.yml`) was uploaded. Nobody checking for updates during
the upload was offered 2.79.0 before its files existed, the case behind
[#&#8203;1003](https://redirect.github.com/ZenNotes/zennotes/issues/1003).

Late changes were gated again each time: the three fixes found on
release morning
([#&#8203;1004](https://redirect.github.com/ZenNotes/zennotes/issues/1004)
on the server,
[#&#8203;1009](https://redirect.github.com/ZenNotes/zennotes/issues/1009)
and
[#&#8203;1012](https://redirect.github.com/ZenNotes/zennotes/issues/1012)
in the app), then charles b.'s database views and Gallery,
[#&#8203;1016](https://redirect.github.com/ZenNotes/zennotes/issues/1016)
and
[#&#8203;1014](https://redirect.github.com/ZenNotes/zennotes/issues/1014),
and two fixes found by the phone walks (a theme pick raising a phone's
keyboard, and typing in a new note going in front of its title, a bug
older than this release, also on desktop). Each feature was checked in
the built app over CDP with isolated stores before it merged (the
Gallery also against a self-hosted server and in the web app), and both
phones were walked end to end on their release builds of the final core,
with clips.

Things that went wrong, told plainly: the vim-editor smoke check "3j
follows logical relative line numbers" failed once on a busy machine and
then passed five times, beside load and without; its detail was lost,
its cause is not named yet, and it is being chased for 2.80.0. One
app-core test waited a fixed 80 ms for rows that took longer when every
package's tests ran at once; it now waits for the rows (`b996b58b`, no
product change). The production dependency audit failed once on `main`
because npm's registry refused the request; the same audit passes
locally with no high advisories, and its re-run passed. Code signing on
the release Mac could not reach Apple's timestamp server over IPv6, so
the local pack was signed through its IPv4 address (CI is unaffected).
The core, web and viewer packages were rebuilt four times as fixes and
features joined the release; only the final ones were published.

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/Los_Angeles)

- Branch creation
  - Every minute (`* * * * *`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/scottames/copr).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xODguMiIsInVwZGF0ZWRJblZlciI6IjQ0LjE4OC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
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