.base files open as a tab: view switcher (add, duplicate, rename, delete, reorder), toolbar, status line, a raw-YAML fallback card with the parse-error line; virtualised table (only visible rows painted, pages fetched on demand) with sticky header, sort arrows, resizable columns persisted to columnSize, grouping with counts and folding, summary row, typed cells, links that open notes; Properties popover (search, reorder, formulas), Sort and Group menus and a filter builder that round-trips the docs' expression forms (Bases tasks 14-16, Claude Sonnet). Maps tile service: https-only fetcher with the project User-Agent, 5 s timeout, 256 KiB cap, image/png check, burst 8 then 1 request per second and 2 in flight, disk cache with a 7-day floor and size cap, maps.status / maps.clear_cache / maps.tile commands, maps.* settings off by default, nothing runs while disabled (task 12, MiniMax M3.1 Flash, OpenCode Zen free route). Verified with the full cargo xtask ci on a copy of the working tree (4572 tests, clippy -D warnings, layers, tree, i18n). Gaps: no Summarize menu, no cards/list/map views yet, view edits bypass base.view.*.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Index: frontmatter properties (200 per note, 4 KiB per value, 500 list items, 3 levels), size and times; persistent cache format version 2 (old caches are replaced). Engine: base.list, base.read, base.properties, base.query over the index (limit 200 default, over 2000 is an error), base.write (validated; never replaces an unreadable file), base.create, base.view.add|remove|rename|duplicate|reorder, base.row.set (types.json, one undo step in an open buffer, file.name renames with links; other file.* and formula.* are read-only). Bases tasks 9, 10, 11 (Claude Sonnet). Verified with the full cargo xtask ci on a copy of the tree (4526 tests, clippy -D warnings, layers, tree, i18n). Gaps: no result cache keyed by index generation, no 15k-note perf test, base.row.set writes numbers as 5.0.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
run(Base, view, NoteSource, Env) with base and view filters (and/or/not), stable multi-key sort evaluating only the sort keys, groupBy and groupOrder (null group, hidden groups), limit across groups, built-in and custom summaries (Average, Min, Max, Sum, Range, Median, Stddev, Earliest, Latest, Checked, Unchecked, Empty, Filled, Unique, expressions over values), lazily memoised cells, dependency tracking so unused properties are never read; list methods sum, mean, median, min, max. 15000 rows with one filter and one sort run in well under the 500 ms bound. Bases task 7 (Claude Sonnet). Known gap: an empty groupOrder shows all groups (needs Option<Vec> in the model).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
.base model (filters, formulas, properties, views; unknown keys kept in order; limits and invalid-value errors), evaluator with the D5 type rules, lazy if and boolean operators, memoised formulas with cycle errors, depth cap 200, string/number/object/list/date/link/file/regexp functions with lambdas (regex through notescraft-regex), and the map model (Web Mercator, tile ids, viewport tiles, grid clustering, coordinate and colour parsing, OSM attribution constants; Paris z10 is tile 518/352). Bases tasks 2, 5, 6 (Claude Sonnet) and 8 (MiniMax M3.1 Flash, OpenCode Zen free route). Verified: notescraft-bases suites all pass, clippy -D warnings, xtask layers and tree clean. Known gaps: toFixed rounds ties to even, list.unique is quadratic.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
yaml: lossless block and flow YAML subset with | and > scalars, comments, tab-indent error, limits (1 MiB, depth 12, 10000 nodes), emitter that round-trips; 9 fixtures from the Obsidian Bases docs (Bases tasks 1; written by Claude Sonnet after two MiniMax attempts produced no code). expr: tokens, AST and precedence-climbing parser with regex literals, arrays, objects, member/index/call, dependency collection, depth and length limits (task 3; MiniMax M3.1 Flash, OpenCode Zen free route). Verified: notescraft-bases 43+ tests pass, clippy -D warnings clean, xtask layers OK. The previous bases commit message claimed a YAML parser that did not exist yet.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Audio tab and note embeds with waveform, live spectrum (own FFT), seek, speed, loop and volume through ffplay/ffmpeg; code and text files open in an editable source editor with syntax highlighting, a Language chip and a banner to install, pick or ignore a grammar; ico decoding through the largest entry; info card as a clean grid; draw tools: arrows and lines clamped and clipped to the picture with a head, inline text tool, hotkeys; Activity tab with unread count and hotkey; calendar title shows a link icon and a pointing hand; explorer trash button works on press; right panel tab pills shrink so they never cover the collapse button; math: unknown command keeps a parser tooltip; test files grouped into tests/ folders (12-file rule); flaky search-order test waits for the rows. Built by Claude Sonnet and MiniMax M3.1 Flash; the whole tree verified with cargo xtask ci (fmt, clippy -D warnings, 4422 tests, layers, tree, i18n) on a copy of the working tree.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sidecars (*.comments.json) stay out of the index and listings and follow rename and delete of their note; end-to-end comments test over a stub server (Ana comments and mentions Bob, Bob resolves, second sync changes nothing); viewer extension tables gain ico, ogv, 3gp, opus, aac; annotate crate: Edit::Replace for undoable text moves and edits, line items carry an arrow flag; syntax test fixed (TeX is a bundled grammar). Built by MiniMax M3.1 Flash and Claude Sonnet; verified with the full cargo xtask ci on the combined tree (4422 tests, clippy -D warnings, layers, tree, i18n).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
notescraft-bases (L2, no I/O): hand-written lossless YAML subset parser and emitter with limits (1 MiB, depth 12, 10000 nodes), value and date types with durations, month clamp and a total order across types (Bases tasks 1 and 4). Built by MiniMax M3.1 Flash (OpenCode Zen free route). Verified as part of the full cargo xtask ci run on the combined tree.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Inventory of the 29 core plugins (22 done, 2 partial, 5 missing), 80 community plugins with a verdict each, a ranked roadmap with 8 ready briefs, the Bases spec (D1-D13) and 20 tasks, ASCII wireframes of the Bases screens (PaperCraft was not running). crates/bases is registered at layer L2.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Tabs: no cap (a 5000 bound on the saved list only); only the active and 5 recent tabs keep editor state, cold tabs keep caret, view and folds and reload on activation, dirty tabs are never dropped; the strip lays out at most 64 tabs and the overflow list is searchable and virtualised; restore loads only the active tab. Hotkeys: one registry with defaults for tab and panel navigation and opening Outline, Related, Backlinks, Assistant, Lint and Comments, shown in the tooltips; F6 cycles focus; Ctrl+h/l in vim mode; panels are accessibility landmarks. Menus: keycap letters that run the item, vim j/k/h/l/gg/G, focus into the menu and back on Esc, menu and menu-item roles. Explorer: horizontal scroll (Shift+wheel) and full-name tooltips. Comments tab in the right panel (MiniMax M3.1 Flash). Delete confirmation dialog from an earlier session, with its debug code and deadlock removed. Built by Claude Sonnet and MiniMax M3.1 Flash; the whole tree verified with cargo xtask ci (fmt, clippy -D warnings, all tests, layers, tree, i18n) green on a copy of the working tree.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
New inline scanner never drops text and nests emphasis around links and code; [[#H]] and [[N#H]] labels, escapes, double-backtick spans, bare URLs, callout titles and headings through the inline pipeline; callout content parsed as blocks (code, tables, math, nested callouts); markdown images and embeds inside lists, callouts and tables; an HTML subset; hidden block ids; horizontal rules; blockquote bars; custom task statuses; footnote numbers; compact code cards with per-line wrapped inline-code chips.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Video: real pause, interactive seek track with ffmpeg hover thumbnails, skip, speed, loop, mute, open/reveal/copy, decode width follows the tab, probe and spawn off the UI thread. PDF: page jump, zoom, fit width/page, open/reveal/copy. Draw bar redesigned as one card. WebP opens in the tab lightbox. Note embeds open a lightbox with zoom-in/out animation from the thumbnail, a tools bar, a source link, and the same for videos, PDFs and other files.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
arboard (image-data) approved for clipboard paste: image bytes become a PNG attachment, copied files inside the vault are linked without copying, outside files are copied; works in Visual and Source. image crate gains jpeg, gif, webp, bmp decoders. Lazy system-font fallbacks for 28 scripts (Bengali, Indic, Thai, CJK, Khmer...) and the math font as last resort. JetBrains Mono copy with calt emptied (SIL OFL, renamed). Big embedded images are shrunk to the texture limit off the UI thread (fixes a crash).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CommonMark fence scanner (a closing fence is at least as long as the opening one, tilde fences, quote prefixes), used by every fence scan in the note view; math: Bmatrix, Vmatrix, smallmatrix, array, align, hline, lenient parse where an unknown command becomes one red atom; plain/text/txt code blocks are no unknown language; corpus test against pulldown-cmark over the help vault (0 disagreements on 179 notes). Adds the render audit of the help vault (20 findings).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
activity.list|unread|read and mention.candidates over the server's activity endpoints; a comment that mentions a member posts one event (never the body), kept in .notescraft/activity-outbox.json when the server is down and flushed on the next sync cycle; unread cursor in .notescraft/activity.json; unbound vaults answer not_bound (comments spec task 8). Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: notescraft-engine 838 tests pass, clippy -D warnings, xtask layers and tree clean.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
suggestion.list|accept|reject (accept/reject write through the buffer path, viewers refused with forbidden, stale ranges answer stale_range, role from the bound server's member list cached 5 minutes, an unbound vault is the owner). Renaming a note moves its <note>.comments.json; a sync conflict on a sidecar merges the two by thread id instead of leaving two half-files (comments spec tasks 5 and 6). Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: notescraft-engine 816 tests pass, clippy -D warnings, xtask layers and tree clean.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Index: .notescraft/cache/index-v1.bin keeps per-note link info, search doc, knowledge passages and lint votes keyed by (mtime, length), re-checked by stat at import; changed notes re-read; corrupt, truncated, oversized or old caches ignored and replaced. The knowledge vocabulary is trusted only by file hash (the old note-count check made a second open slower than a cold one). mdn-docs (14.7k notes, release): second open 1.4 s instead of 15.7-21 s cold.
Calendar: a per-session cache of what each note's scan gave the agenda (parsed events, all dated tasks) validated by length and mtime; window switches only filter in memory (mdn-docs 695 ms -> 2.7 ms), the cold pass runs in 8 ms slices across frames while the old grid stays visible, the week review reuses loaded items.
Built by Claude Sonnet; verified from a clean checkout of the staged files: 1901 tests in engine, index, knowledge and ui-egui lib plus calendar_view pass, clippy -D warnings on the four crates, xtask layers, tree and i18n clean.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The body scrolls in the screen height left after the title and footer, the card stays at least 24 pt under the top, and the File > Share action passes the active note to the dialog so Publish this note shows. publish_ui 8 and share_ui 10 pass.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Published pages (copy, unpublish), publish this note, read-only links with expiry choices; the secret link is shown once and never in lists, logs or toasts; viewers see lists without buttons; destructive buttons click twice. Re-exports PublicationKind from the engine. Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: 908 lib tests, publish_ui 8 and share_ui 10 pass, clippy -D warnings on ui-egui and engine and xtask tree clean. Open: the shell does not pass the note into the dialog yet and the card needs to scroll on short screens.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
SVG re-rendered as vector at the resting zoom (power-of-two raster scale), bitmaps use nearest magnification. New shared bar card/buttons with Lucide icons, tooltips and compact layout. Wheel zoom clamped per frame (0.85..1.18), trackpad scroll pans, Ctrl/Cmd+wheel and pinch zoom. Video: probe and spawn off the UI thread, decode width follows the tab (max 1280), poster and spinner while the first frame is pending, play/stop icon button, clock and progress track. Scrolled-out icons no longer widen their own clip (design/lottie_icon) and folder view skips hidden rows. Built by Claude Sonnet; verified from a clean checkout of the staged files: 908 lib tests, image_view 7, media_view 2, image_annotate 5, file_viewers_basic 1 pass, clippy -D warnings, xtask i18n and tree clean.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
comment.list|add|reply|edit|delete|resolve|reanchor over <note>.comments.json written through Vault::write; the note file stays byte-identical; author comes from the session identity (binding user_id, else local), edit/delete author-only; limits error and never truncate; anchors re-resolve against the open buffer or the file. Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: notescraft-engine tests 776 pass, clippy -D warnings and xtask layers clean.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Pen, highlighter, line, arrow, rectangle, ellipse, text, eraser, undo/redo, colours, widths, clear (click twice); debounced save, damaged-sidecar notice, image-changed notice, read-only shows marks without tools. The sidecar is read and written through Vault on a worker thread (the view cannot reach the engine commands). Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: 901 lib tests, image_annotate 5 and image_view 5 pass, xtask i18n and tree clean.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Pure model for comments, suggestions and mentions (spec comments-and-mentions tasks 1-3): sidecar codec with hard limits, quote-first anchor resolution (exact, reanchored, fuzzy, orphaned), CriticMarkup scan/accept/reject skipping code fences. Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: notescraft-engine tests 759 pass (30 in review::), clippy -D warnings clean.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
publish.list|enable|disable and share.link.create|list|revoke over the bound server, token only in the minted URL, read-only and unbound sessions refused. Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: notescraft-engine tests 729 pass, clippy -D warnings clean. Integration tests use a stub server speaking the server's JSON.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Image tab: decode off the UI thread, zoom (wheel, buttons), pan, fit, rotate, neighbours, info, transparency checkerboard only when needed. Video tab reuses the ffmpeg embed player, PDF tab renders pages through Session::pdf_preview with previous/next and zoom. Copy tables moved into text/views/files to keep the folder under 12 loose files. Built by MiniMax M3.1 Flash (OpenCode Zen free route); verified from a clean checkout of the staged files: 901 lib tests, image_view, media_view and file_viewers_basic pass, xtask i18n clean. No elapsed time or page total yet; annotations not wired.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Info card (name, kind, size, modified, path, open with the system) for audio, video, PDF and other files; code_view highlighter (rust, js/ts, py, json, toml, yaml, sh, css, html) with line caps, not wired into tabs yet. Moves [ui.file-card] out of [ui.settings-view-calendar] (my earlier commit split it, which broke two calendar settings tests) and updates the Explorer test for show-all-types. Built by GLM 5.3 Flash via Pi; verified from a clean checkout of the staged files: lib tests 856 pass.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Comma-separated extensions, cleaned and capped through FilesConfig::repair_hidden; invalid-only input emits nothing. Built by GLM 5.3 Flash via Pi. Two calendar/feed settings tests already fail at HEAD (clocks_amounts_and_log_lines, adding_and_removing_a_feed_emit_engine_commands).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
TabKind gains Image, Video, Audio, Pdf, Code, Other; sidecars of existing images are hidden; Settings > Files toggles show_all_types and show_annotation_files. hidden_extensions has no Settings row yet. No viewers for the new kinds yet.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Explorer: every non-hidden file is listed with its own icon and tab kind (image, video, audio, pdf, code, text, other); settings show_all_types, hidden_extensions and show_annotation_files; kinds without a viewer open a placeholder card, never the text editor
- crates/annotate: non-destructive image annotations (strokes, lines, rectangles, ellipses, text) with strict sidecar JSON validation, hit testing, zoom/pan transforms and undo
- engine: file.info, file.hash, file.neighbours, image.annotations.load and save (a corrupt sidecar is kept as .bad, the image is never modified), header-only image sizing for PNG, JPEG, GIF, WebP, BMP and SVG
- sync server: publish notes or folders as static HTML (raw HTML escaped, strict CSP, publish: false honoured, no attachments) and expiring revocable share links, with per-route rate limits and audit rows
- ui-egui: "Last edit - name, time ago" in the status bar from server.file_meta
- specs and designs: file viewers spec, 20 PaperCraft exports rated 8.2 of 10 (design/files/RATING.md), annotate and viewer briefs
Verified with cargo xtask ci (fmt, clippy -D warnings, workspace tests, layers, tree, i18n).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- engine: live.join, live.edit, live.poll, live.peers, live.selection, live.info and live.leave over the live session client (at most 8 rooms, no token in any answer, dropping a session with open rooms returns within 2 s); server.file_meta names the last editor of a file
- engine: sync.pending lists the local changes the server does not have yet (new, edited, deleted; at most 500, local comparison only)
- ui-egui: a "Waiting to sync" queue sheet opened from the sync sheet, and the "You are offline" banner on the compact Notes page
- tests: two sessions converge through the real server using live.* commands; stub-server, queue and banner tests
Verified with cargo xtask ci (fmt, clippy -D warnings, workspace tests, layers, tree, i18n).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- engine: ServerClient file_history, file_revision and restore; commands server.history, server.revision, server.restore (bound vault only, 5 MiB cap, no token in any answer)
- ui-egui: the Versions tab lists the server's revisions under the local snapshots with Compare (diff against the note) and a two-click Restore
- specs: collaboration research (browsed, 866 lines, 211 sources) and its ranked next features added to the collaboration task list
Verified with cargo xtask ci (fmt, clippy -D warnings, workspace tests, layers, tree, i18n).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- engine: Remote gains missing_chunks, put_chunk and put_chunked; upload_chunked streams a big file in 4 MiB chunks, sends only the chunks the server lacks, retries with backoff and reports progress (SyncStatus.transfer); the scan hashes by streaming and skips only files over 1 GiB
- engine: server.devices command and a sync.attachments option (non-Markdown files are skipped when it is off)
- ui-egui: the sync pill opens a bottom sheet on a phone-width window (status, devices, conflicts row, options, Sync now); wider windows keep Settings > Sync
- tests: chunk resume against the real server, 6 driven sheet tests, devices stub tests
Verified with cargo xtask ci (fmt, clippy -D warnings, workspace tests, layers, tree, i18n).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sync and the server
- crates/sync: revision ledger (stale writers conflict, edit beats delete), client planner, three-way merge, conflict names, path and hash gates
- apps/notescraft-sync-server: pairing, device tokens, change log with long poll, blobs, accounts with many vaults, roles, invites, audit log, quota, GC, readiness, request ids
- server history (revisions, restore, retention), chunked resumable uploads, live editing endpoints (SSE rooms, presence, flush through the ledger)
- engine: HttpRemote, sync_once, SyncWorker, sync.* commands, share.* and server.* commands, live session client, note.capture, vault catalog and vaults.* commands
Editing together
- crates/collab: operational transformation core (TextOp, transform, client state machine, room, presence)
- ui-egui: Settings > Sync, sync pill, conflicts, Share dialog, live pill and remote carets, launcher Connect and Join flows
App shell
- vault launcher (desktop and phone layouts) wired into the app host (--launcher, File > Vaults...)
- compact (phone) layout with a bottom tab bar
Verified with cargo xtask ci (fmt, clippy -D warnings, workspace tests, layers, tree, i18n). Android and iOS shells are not built: the build machine has no NDK or Xcode.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Visual view's block editor now shares the Source view's task toggle (keys::on_toggle_task).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Ticks or unticks a box, adds a box to a list item, makes a plain or empty line a task.
Round 5 tasks 36-37 added; the Visual block editor's version (37) is open.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Every save of a changed note keeps a snapshot (at most one per 5 minutes, newest 20, under
.notescraft/history), engine history.list/history.read, a Versions tab with Compare and Restore.
Task 31 marked built (git history existed), task 34 deferred by the owner.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>