Conversation
The which-key card is bottom-anchored with no height cap, so on a short window (tiled WMs like Niri, high zoom factors) it grew past the top edge of the viewport, and the header naming the menu was exactly what clipped first. Below the sm breakpoint the grid also collapses to one column, doubling the card's height, which is why narrow tiles hit this hardest. Cap the card at the viewport height, pin the header, and let the item grid scroll under it. The card takes pointer events now so the wheel can reach the list (the wrapper stays click-through), and overscroll containment keeps the page behind from scrolling along. Claude-Session: https://claude.ai/code/session_011wnqvUakYs9Me5kyRgsUw2
The installer already asked a login shell for node and npm, but zsh, the macOS default, reads ~/.zshrc only when interactive, and that is exactly where nvm initializes. A plain `-lc` shell never saw an nvm-managed node, so the settings page claimed node was missing on machines where the terminal finds it instantly. The shared resolver now asks the interactive login shell for its PATH first and scans those directories itself instead of parsing `command -v`, which in an interactive shell is free to answer with an alias definition or a lazy-loader function instead of a path. The answer travels on a marked line so rc-file banners cannot corrupt it, and a sanity gate rejects fish's space-joined PATH expansion. When the shells come up empty for the node toolchain, ~/.nvm/versions/node is probed directly (default alias first, newest install otherwise), which also covers setups that lazy-load nvm and have no node on any shell's PATH at all. The Raycast module's private login-shell duplicate is deleted in favor of the shared helper, so ripgrep/fzf detection and the CLI installer's PATH check inherit the same fidelity. Claude-Session: https://claude.ai/code/session_011wnqvUakYs9Me5kyRgsUw2
The jumplist admitted only notes and database surfaces, and the panel views were shut out twice over: the gate refused to record them, and openTasksView/openTagView open their tab through the raw pane primitive, which keeps no history. So the panel was not just skipped; putting it in your path could kill the whole trail, because the note-to-panel hop recorded nothing and the panel-to-note hop was gate-blocked. Ctrl+O sometimes simply did nothing. The Tasks and Tags views are destinations the user navigates to on purpose, so they now ride the jumplist like everything else: the gate admits them, opening a panel records the origin note (and clears the forward stack, as any jump does), and jumping back reopens the tab through focusTabInPane, which already carries each panel's reopen semantics. Panel entries are captured with zeroed scroll numbers, a lingering editorViewRef belongs to some other note. Deliberately unchanged: tab-strip clicks stay non-jumps for every tab kind, and help/trash/plain-asset tabs stay out of the history. Claude-Session: https://claude.ai/code/session_011wnqvUakYs9Me5kyRgsUw2
The picker's row gave the path column shrink-0 and the title flex-1 with a zero basis, so a long path claimed its full width and the title absorbed the entire squeeze: "Calen…" beside a fully spelled-out sixty-character path, when the title is the thing you are switching by. Three changes, one row. The subtitle is now the note's folder rather than the full path (the filename part just repeated the title; the full path stays in the search keywords). The flex priorities are inverted: the title takes its natural width and truncates only when it alone overflows, while the folder column takes the leftover and collapses first. And when the folder does truncate, it truncates from the left, keeping the distinguishing tail visible, via a dir="rtl" span with an LRE/PDF bidi embedding so the path itself still reads left-to-right. Verified in the built app against the report's exact vault shape: titles measure untruncated where all three truncated before, and a deep folder at a narrow window collapses to "…Q3/Meeting Notes And Decisions" with the title untouched. Claude-Session: https://claude.ai/code/session_011wnqvUakYs9Me5kyRgsUw2
Sync used to inline every file into the mutation JSON, so a big PDF or video buffered whole in memory and pushed the request toward server limits. Files over 5 MB now travel through an upload session instead: the client asks the cloud for a signed destination, PUTs the bytes directly to object storage (streaming from the file on disk, never holding it in memory), and completes the session, which folds the result back into the ordinary mutation response, conflicts included. The seams are where the care went. Mutation batches keep their order by flushing inline runs around each direct upload. A failed or rejected upload aborts its session server-side; completion retries transient errors a few times before giving up. Conflict responses (revision, path, deleted, quota) map back into normal sync conflicts rather than surfacing as transport errors. Local scans hash oversized files in a stream and remember each file's source path so the upload can read from disk, and the signed URL is required to be https. Claude-Session: https://claude.ai/code/session_011wnqvUakYs9Me5kyRgsUw2
| async function encodeFileContent(relPath: string, absolutePath: string): Promise<CloudSyncContent> { | ||
| const stats = await fs.stat(absolutePath) | ||
| if (stats.size <= CLOUD_SYNC_INLINE_UPLOAD_LIMIT_BYTES) { | ||
| const bytes = await fs.readFile(absolutePath) |
| } | ||
|
|
||
| if (byteLength <= CLOUD_SYNC_INLINE_UPLOAD_LIMIT_BYTES) { | ||
| const bytes = await fs.readFile(absolutePath) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The 2.31.0 release branch. The headline is direct uploads for ZenNotes Cloud: large files stream from disk to storage instead of traveling inline through the sync request. Around it, a four-issue community sweep, three of them reported by @uNyanda.
Large files sync for real
Sync used to inline every file into the mutation JSON, so a big PDF or video buffered whole in memory and pushed against server limits. Files over 5 MB now travel through an upload session: the client asks the cloud for a signed destination, streams the bytes straight from disk, and completes the session, which folds the result back into the ordinary mutation response, conflicts included. Batch order is preserved around direct uploads, failed uploads abort their session server-side, completion retries transient errors, and revision/path/quota conflicts surface as normal sync conflicts rather than transport failures. Local scans hash oversized files in a stream, and the signed URL must be https.
The issue sweep
~/.zshrconly when interactive, which is exactly where nvm initializes, so the non-interactive login-shell lookup never saw it. The shared resolver now reads the interactive shell's PATH and scans it directly, with a~/.nvm/versions/nodeprobe for lazy-loaded setups; ripgrep/fzf detection and the CLI installer's PATH check inherit the same fidelity.Every fix was verified in the built app over CDP against the reporter's repro, alongside the unit suites (new store tests cover the #633 round-trips; the direct-upload work lands with its own client, filesystem, and API tests) and repo typecheck.
Full release notes land on the GitHub release when CI finishes the installers.
https://claude.ai/code/session_011wnqvUakYs9Me5kyRgsUw2