Train z: attachments backend, [[ suggestions, Vim mode (#539, #448, #538) #567

Closed
kayg wants to merge 0 commits from train/2026-10-18z into dev
Owner

Train z ran the full suite on the parallel runner (all 11 projects), plus install, fmt, clippy, workspace tests and the build, all green.

  • Two test locators fixed: glass and vim matched #564's new "Create …" row as well. They're now anchored to the note's own row, in a test-only commit.
  • Reruns (×2–3):
    • glass and vim: 43/44 on chromium (one glass:268 blip, a different test), 38/38 on webkit;
    • toast-bar, trash and tree on webkit-1440: 53/54 (one toast-bar:40 blip, a known load flake).
  • Also included: a load-proof tag-speed test (best of 9).

Contents:

  • #563 the attachments backend;
  • #564 [[ suggests titles and not-yet-created links first;
  • #566 Vim mode (off by default).

Merging.

🤖 Generated with Claude Code

Train z ran the full suite on the parallel runner (all 11 projects), plus install, fmt, clippy, workspace tests and the build, all green. - **Two test locators fixed:** glass and vim matched #564's new "Create …" row as well. They're now anchored to the note's own row, in a test-only commit. - **Reruns (×2–3):** - glass and vim: 43/44 on chromium (one `glass:268` blip, a different test), 38/38 on webkit; - toast-bar, trash and tree on webkit-1440: 53/54 (one `toast-bar:40` blip, a known load flake). - **Also included:** a load-proof tag-speed test (best of 9). Contents: - #563 the attachments backend; - #564 [[ suggests titles and not-yet-created links first; - #566 Vim mode (off by default). Merging. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kayg added 10 commits 2026-10-18 02:42:17 +00:00
Attachments: upload, sniffing, limits, dated paths (#539)
Some checks failed
CI / server (pull_request) Successful in 26s
CI / rust (pull_request) Failing after 35s
CI / web (pull_request) Failing after 6s
a2a20c4153
A new `attachments` plugin. Uploads stream to a hidden temporary file in
`Photos/YYYY/YYYY-MM-DD/` or `Documents/YYYY/YYYY-MM-DD/` (G12), with the
type taken from the content signature (`infer` plus HEIF/CR3 brands; the
extension only picks between text types; HTML kept as text/plain), the
size limit enforced while streaming, and a blake3 hash for "Already
uploaded" (ADR 0027/0028). The upload then runs `attachments.add` through
the one action pipeline, so it is journaled and idempotent.

Files are opened through a new `calternal_fsio::beneath` module
(`openat2` with RESOLVE_BENEATH), so no path can leave the Home. Unsafe
types are served as downloads with nosniff and a sandboxing CSP. Crash
markers let the next start remove temporary files a kill -9 left.

Tests: sniffing, names, days, limits while streaming, retries, traversal,
isolation (Bob vs Alice) in isolation.rs, kill -9 mid-upload through the
real binary, and a 1 GiB upload in bounded memory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCcFhwwgMK66k9LMVqogNJ
[[ suggests titles and not-yet-created links first (#448)
Some checks failed
CI / server (pull_request) Successful in 25s
CI / rust (pull_request) Successful in 2m29s
CI / web (pull_request) Failing after 28s
523d10a419
Typing `[[Keshav Nayyar` listed unrelated journal days that only mention
the name in their text, and not "Keshav Nayyar" itself when other notes
already link to it but no note exists yet.

The picker now offers, in order: notes whose title matches (exact, starts
with, word starts with, holds, letters in order; ties by what you link
most, then newest; days also match by date), link targets other notes
point at that nobody made (muted, note-and-+ icon, "linked from N notes";
same path, so the same future note), a Create row for exactly what was
typed, and, only while fewer than five titles match, a "Mentioned in"
section with the matched words marked.

Server: notes.missing-targets reads the links index once into a short list
kept at most five seconds, so a keystroke only filters it in memory.
Client: the ranking is one pass over ready-made folded titles in
@calternal/editor (link-rank.ts), with unit tests and a speed check at
10,000 notes. Choosing a note now tells search (search.visit).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCcFhwwgMK66k9LMVqogNJ
Vim's keys in the editor, as a plugin: off by default, turned on in
Settings → Editor, and loaded only once it's on. It stays off on a touch
screen until a hardware key shows a keyboard is there.

- @replit/codemirror-vim 6.4.0 (MIT) for motions, operators, counts,
  registers, `.`, text objects, visual modes and `:` commands, fitted to
  the editor in packages/editor/src/vim/:
  - u and Ctrl-r undo this person's own changes;
  - V selects whole blocks the app's way;
  - `:` and `/` are typed in the bottom bar;
  - each Vim change is one undo step;
  - the hidden properties are out of reach;
  - another device's edits never join `.`;
  - `it` works on inline HTML.
- The caret shows the mode: a block in normal mode, the bar in insert
  mode, an outline in visual mode. It doesn't blink with reduced motion.
- A note opens in insert mode. Esc gives normal mode and does nothing
  more there.
- The command line morphs the bar into a field with its prefix. Search
  highlights matches as you type. :w, :q, :n, :s and :%s work.
- Fix: a block selection (Esc, the handle, V) now looks like a block,
  a rounded accent tint, never like selected words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCcFhwwgMK66k9LMVqogNJ
Peak memory above idle is the fixed buffers, not the file: 64 MiB, 1 GiB
and 2 GiB uploads all peaked 6 to 11 MiB above idle on this host, debug
or release. The 8 MiB bound sat inside that noise; 16 MiB still fails long
before a buffered upload would.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCcFhwwgMK66k9LMVqogNJ
Workspace runs and trains upload 128 MiB (the suite takes about 1.7 s
instead of 6 to 9 s). The 16 MiB bound stays meaningful: a buffered
128 MiB upload would peak eight times over it. The nightly job runs the
test at 1 GiB with CALTERNAL_TEST_UPLOAD_MB=1024.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCcFhwwgMK66k9LMVqogNJ
Vim mode: accent caret over Vim's own, opt-in plugin chunks counted apart
Some checks failed
CI / server (pull_request) Successful in 34s
CI / rust (pull_request) Successful in 2m23s
CI / web (pull_request) Failing after 36s
3a71b7a8ac
- The caret and search matches are drawn in the accent. Vim's own pink,
  yellow and cyan styles no longer win.
- bundle-size.mjs counts chunks that only load once their plugin is
  turned on (the Vim chunk, 37.7 KB brotli) as web.bundle.plugins_*,
  with their own budget (≤ 45 KB), and leaves them out of "all".
- A reload never leaves the bar on an empty command line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCcFhwwgMK66k9LMVqogNJ
# Conflicts:
#	packages/editor/src/index.ts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCcFhwwgMK66k9LMVqogNJ
Merge remote-tracking branch 'origin/issue/538-vim' into train/2026-10-18z
Some checks failed
CI / web (pull_request) Failing after 8s
CI / server (pull_request) Successful in 20s
CI / rust (pull_request) Successful in 2m4s
0f4377dc03
Author
Owner

This PR's commits are on dev (landed). Forgejo kept it open and its merge endpoint answers 405, so it is closed by hand.

This PR's commits are on dev (landed). Forgejo kept it open and its merge endpoint answers 405, so it is closed by hand.
kayg closed this pull request 2026-10-21 11:32:50 +00:00
Some checks failed
CI / web (pull_request) Failing after 8s
CI / server (pull_request) Successful in 20s
CI / rust (pull_request) Successful in 2m4s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal!567
No description provided.