Skip to content

Latest commit

 

History

History
147 lines (128 loc) · 31.4 KB

File metadata and controls

147 lines (128 loc) · 31.4 KB

Tasks

In Progress

  • Reveal-in-sidebar + residual external-watcher misses: SPECs/reveal-in-sidebar-and-external-watcher-spec.md — keep the explicit tab-context-menu "Reveal in sidebar" action working, leave ordinary file opens from expanding the Everything tree, and characterize the remaining external-file-watcher miss cases through a logging + manual-repro pass before patching further.

Done

  • Keyboard scrolling stalls in long notes (#125) — the ProseMarkEditor mount was h-full, so its content overflowed it and CodeMirror's scrollRectIntoView treated it as a scroller, clipping the caret rect to its (viewport-high) bounds before reaching EditorScrollContainer; scrollTop stuck at 113px after ~27 Down presses. Now min-h-full. e2e/specs/keyboard-scroll.spec.js holds Down and Up through a 114-line note and checks a short note's mount still fills the viewport. Follow-up not done: Up to the first line stops at scrollTop 120 (CodeMirror scrolls to the line, not the frontmatter/top padding above it), so the title sits under the top fade — same before this change.
  • Website download button follows the latest published release — apps/website/src/latest-release.ts fetches GitHub's releases/latest (the release-asset redirect the updater uses has no CORS headers, so the REST API is the only source a browser can read) and useLatestRelease swaps the prerendered build-time version/DMG pair for the live one; on a non-2xx (spent rate limit) or an unexpected payload the page keeps the build-time pair and warns in the console. Docs in docs/website-deploy.md ("Download link").
  • Scroll jumps when the caret's line leaves the viewport: SPECs/offscreen-selection-line-height-spec.md — CodeMirror keeps the selection's anchor and head lines rendered wherever the viewport is and measures them into the height map, but every plugin decorating view.visibleRanges (and @codemirror/language's tree highlighter) left them bare, so an H1 holding the caret measured 28.8px instead of 92.1px once it scrolled out and the note above the viewport shifted 63px. renderedRanges(view) / renderedRangesChanged(update) in prosemark-core/utils.ts are now the one definition of what to decorate, used by the heading, wiki-link, code fence, tab width and blockquote plugins; offscreenSelectionHighlightExtension highlights those lines since the tree highlighter can't be told about them. Verified in the playground on the same note: no line above the viewport changes height across a full blurred scroll pass with the caret on the H1, in a code block, or on a long list item.
  • Scroll jumps on long notes — @codemirror/view bumped 6.40.0 → 6.43.12 (@codemirror/state to 6.7.5 alongside, so pnpm keeps one copy). Before 6.42.1 the height oracle treated a >0.1px change in sampled character width as a font change and re-estimated every line outside the viewport, discarding measured heights; Writer's short fenced-code lines sample in the monospace font (9.4px per character vs 6.65px for the prose dummy line), so every pass through a code block reshuffled the heightmap and moved the scroll position by up to ~1000px. Reproduced and verified in the playground on a note mixing a wide table, code blocks and nested lists; the mechanism and what still shifts are in docs/editor.md ("Line-height estimates").
  • List exit paths and the parse frontier — Backspace at the text start of a top-level item leaves a blank line between the list and the new paragraph (same listExitSeparator as Enter on an empty item; nested items keep their one-level-out behaviour). listLineAt trusts the prefix grammar when syntaxTreeAvailable is false at the line, closing the follow-up where Enter/Backspace/Tab past the committed parse fell through to the generic markdown handlers. Verified in the built app by e2e/specs/list-enter-exit.spec.js: Enter+Enter, Enter+Backspace, and a 3000-item note typed without pauses.
  • Editor playground — apps/playground, a plain Vite + React page that mounts prosemark-core with the app theme beside a live markdown source view (whitespace made visible, caret marked), for QA in a normal browser with agent-browser recording. Used to confirm in a real browser that ending a list with Enter leaves a blank line, on a short note and a 4000-item one.
  • Nested list second pass: SPECs/nested-list-editing-audit-spec.md ("Second pass") — a loose item's later paragraphs are padded like wrapped lines (only the marker line was skipped before, so a second paragraph's first line sat at the margin while its wrapped lines were padded); Tab and Shift-Tab move an item's own wrapped lines with its marker line; Backspace at the marker or body start steps back to the parent's whitespace via reindentTarget("outdent") instead of a fixed two characters, so tabs and ordered parents count as one level. itemParagraphLines is the one source for "the item's lines other than the marker line". Enter on an empty top-level item now leaves a blank line between the list and the caret (unless one is already there), because - a⏎What is a lazy continuation of a per CommonMark and the continuation padding made that visible.
  • Code blocks scroll instead of wrapping: SPECs/code-block-horizontal-scroll-spec.md — fenced code and frontmatter lines get white-space: pre + overflow-x: clip; a per-block pixel offset in codeBlockScrollField renders as a text-indent line decoration on every line of the block, driven by horizontal wheel gestures, by caret reveal, and by a draggable scrollbar thumb drawn in a CodeMirror layer. Lines are not scroll containers because drawSelection's caret/selection layers would not follow them.
  • Heading line-height — .cm-heading-line inherited the body's 1.8 line-height (~46px line box at the 1.6em H1), so wrapped titles looked loosely stacked; set line-height: 1.3 on the heading line in prosemark-theme.css.
  • Gap below headings — the 1.3 line-height also removed the half-leading under a heading, so the first line of a paragraph or list sat tight against it; .cm-heading-line now has padding-bottom: 0.35em (body-relative, since the heading font-size lives on the inner span) in prosemark-theme.css.
  • View zoom shortcuts: SPECs/view-zoom-shortcuts-spec.md — Cmd+= / Cmd++ / numpad + zoom the note text in, Cmd+- out, Cmd+0 back to actual size. Persisted as the global editor.zoom percent setting (50–300, browser-style stops) bound to --writer-editor-zoom; App.css multiplies it into --writer-editor-font-size on top of editor.font-size (now bound to --writer-editor-base-font-size), so the chrome stays put and the existing cssVar side effect is the only write path. Palette commands Zoom In / Zoom Out / Reset Zoom; JS-only handling (no View menu needed); the Mermaid canvas now ignores Cmd chords. Whole-window webview zoom was tried first and dropped by decision.
  • List item spacing — items that follow another item at the same level carry cm-list-item-gap on their marker line, and the theme gives it padding-top: var(--writer-list-item-gap, 0.4em). Only the first item of a top-level list and continuation lines are excluded (a nested list's first child is gapped from its parent, via hasListItemGap, so spacing inside a list is uniform); fixed value for now, no setting.
  • Nested list editing audit: SPECs/nested-list-editing-audit-spec.md — Tab/Shift-Tab take their target from the syntax tree (ordered parents, loose lists, tab indentation, odd indents), a selected parent moves its subtree with it, Enter on an empty nested item outdents instead of wiping, the bullet/task toggles keep indent on nested lines, and hard-wrapped items pad their continuation lines to the body column. The spec holds the full pass/fail matrix; four follow-ups added under Up Next.
  • Sidebar "Folders first" toggle: SPECs/sidebar-sort-options-spec.md — the sort submenu is renamed "Sort by" and ends with a "Folders first" check item, persisted as appearance.sidebar-folders-first (default on, the previous behavior). Off sorts folders and files together by the selected mode like ls. sortTreeEntries and flattenTree take a foldersFirst flag; no backend change since folders already carry both timestamps.
  • Sidebar sort options: SPECs/sidebar-sort-options-spec.md — right-click the sidebar for a "Sort files by" submenu with name, modified-time, and created-time modes in both directions, persisted as appearance.sidebar-sort. Folders stay first and alphabetical; "name" is the visible label (title or filename stem). One registry in sidebar-sort.ts drives the comparator and the menu; DirEntry gains created_at, and own saves patch the tree's cached modified_at since the watcher suppresses them.
  • Last Cmd+W hides the window: SPECs/last-cmd-w-hides-window-spec.md — Cmd+W with no file open requests a window close; the main window's close-requested handler hides it instead of destroying it (so the app keeps running and a Dock click brings it back via RunEvent::Reopen), while secondary and standalone windows still close. Every focus-existing-window path and in-place runtime open now reveals a hidden main window.
  • Sidebar sort by visible label — the Everything tree re-sorts each folder in flatten-tree.ts by the same fileTreeLabel function the rows render with (title or filename stem per appearance.sidebar-file-label), folders first, via a natural-order Intl.Collator. The Rust listing keeps its filename sort as the baseline for other consumers.
  • Website mobile hero overlap — drop the desktop-only sticky positioning from .hero in the stacked (<900px) layout and use min-height: 100svh instead of a fixed 100vh, so the demo-video strip no longer scrolls over the feature list.
  • Website PostHog analytics: SPECs/website-posthog-analytics-spec.md — replace the marketing site's self-hosted Umami script and data-umami-* attributes with posthog-js behind the official PostHogProvider, capturing $pageview plus updates_opened, github_opened, and download_started (carrying app_version). Configuration is build-time only and shares the desktop app's project: VITE_POSTHOG_KEY first, then WRITER_POSTHOG_KEY from the repo-root .env (bridged by name in vite.config.ts, never by widening envDir, so the signing secrets beside it cannot reach the bundle); host likewise. With no key nothing is initialized and nothing is sent, mirroring telemetry.rs. Full disclosure in docs/website-analytics.md.
  • Opt-in telemetry: SPECs/opt-in-telemetry-spec.md — off-by-default PostHog reporting behind a one-time first-run consent dialog, with a self-declared email the prompt asks for by name, a Privacy settings section, and four fixed events (app_opened, workspace_opened, file_created, folder_created) carrying no paths or content. The client is Rust-side so commands/fs.rs stays the single write path and posthog-js autocapture can never reach the editor DOM; the project key is build-time only, so clone-and-build binaries are inert. Review follow-ups not yet done: promote track(&str) to an Event enum with a unit test that parses the event table out of docs/telemetry.md; factor the enable/once-per-session state machine off the OnceLock static so apply_settings and the consent-time app_opened path get unit coverage; give the e2e harness a keyed build so telemetry-consent.spec.js actually runs in CI.
  • Editor audit fixes: SPECs/editor-audit-spec.md — five commits: stale-decoration and titled-link bugs plus helper dedupe; keystroke-path performance (deferred stats/headings, indexed fold specs, line-scoped heading guard, cached HTML sanitising, facet-based image src); tree-gated single list-prefix grammar; trimmed basic setup, Escape-closes-find, paste notice, one command registry; hook split into focused modules.
  • Editor content width slider: SPECs/editor-content-width-spec.md — replace the two-state appearance.editor-width enum with a 480–1600px editor.content-width range under Preferences → Editor, bound directly to --writer-editor-max-width so the frontmatter panel and text column share one width; old narrow/full values migrate to 720/1600.
  • Table column sizing (Phase A, CSS-only): SPECs/table-column-sizing-spec.md — folded table cells inherited overflow-wrap: anywhere from EditorView.lineWrapping, which feeds min-content sizing and let the auto table layout starve columns until words broke mid-word. Reset to overflow-wrap: break-word + word-break: normal, replaced the blanket min-width: 6em with a max-width: 48ch per-cell demand cap, top-aligned cells, and left-aligned headers while keeping explicit :---: / ---: alignment. Phase B (wide tables breaking out of the editor measure) and Phase C (JS column-width computation) remain open.
  • PR #111 review fixes: SPECs/Agent/worksheet-pr111-review-fixes.md — guard creation and external launches against workspace switches, closes, and replaced roots; preserve cross-window global settings writes; and route the sidebar background menu through the full surface and rootless shell.
  • Folder-row Open in Terminal: SPECs/sidebar-empty-area-context-menu-spec.md — add an Open in Terminal action to folder row context menus, launching the selected in-workspace directory with the configured terminal.
  • Configurable default terminal: SPECs/configurable-default-terminal-spec.md — add a global Workspace preference for the terminal app/executable used by the sidebar's Open in Terminal action, preserving the platform default when unset.
  • Sidebar empty-area workspace actions: SPECs/sidebar-empty-area-context-menu-spec.md — right-click sidebar gaps and section headers to create a root file/folder, open the workspace in Terminal or Finder, and retain the existing Search/Recents visibility toggles.
  • Status bar + sidebar visibility toggles: SPECs/statusbar-sidebar-visibility-spec.md — hide/show each footer metric (words, characters, paragraphs) and the sidebar Search button and Recents section, via five new boolean settings and native right-click check-item menus on the footer and sidebar surface.
  • Select-only Typography font controls: SPECs/font-select-spec.md — replace the AppKit Font panel and editable stack field with a standard installed-family <select> matching the other settings controls; default UI/editor to SF Pro and the renamed Code font setting to SF Mono.
  • Native macOS font picker + Typography settings: SPECs/native-font-picker-spec.md — replace the custom installed-font combobox with AppKit's system Font panel, route selections back to the originating settings row/window, preserve editable CSS fallback stacks, and rename the settings section from Fonts to Typography.
  • Global font settings: SPECs/global-font-settings-spec.md — the six per-mode theme.{mode}.{ui,editor,mono}-font settings become three global fonts.{ui,editor,mono} settings in a Typography section above the theme cards (fonts are typographic, not chromatic); startup migration adopts existing per-mode values (light wins, dark fallback) and drops the old keys. The font control is a single select-style pill (stack input + chevron in one surface).
  • Obsidian image embeds: SPECs/obsidian-image-embed-spec.md — ![[image.png]] renders inline via the wiki-link decorator; path targets resolve workspace- then note-relative, bare basenames fall back to an on-demand case-insensitive basename walk (find_file_by_name, shortest path wins), unresolved embeds show the raw source as a muted placeholder.
  • Editor bug sweep — image widget scroll-height stability (per-URL measured-height cache + re-measure on decode), viewport force-parse on scroll so tree-derived decorations (list hanging indent, hide, fold) stop rendering stale in unparsed regions, and compact recents picker fixes (loading state before empty state, non-destructive prune, atomic saves, recording/display extension mismatch).
  • LaTeX math rendering: SPECs/latex-math-spec.md — KaTeX-render $...$ inline and $$...$$ display math through the fold-widget pattern (rendered when the selection is outside, raw source when touched), with Pandoc-style inline-$ guards so currency amounts stay prose. Verified at runtime via a browser-driven editor harness (widgets render, currency stays literal, click-to-edit unfolds, refolds on caret move); e2e/specs/latex-math.spec.js covers the same flow for macOS harness runs.
  • Font picker for theme font settings — new font setting type on the six theme.{mode}.{ui,editor,mono}-font entries: stack input plus a searchable popover of installed system fonts (Rust list_system_fonts via fontdb, cached, hidden dot-prefixed families filtered), previewed in each face; picking swaps the stack's primary family over the schema-default tail. Verified end-to-end via a new e2e/specs/font-picker.spec.js (see apps/desktop/.claude/skills/verify/SKILL.md).
  • Configurable monospace code font — add a per-mode theme.{mode}.mono-font setting bound to a new --mono-font CSS variable; --pm-code-font and the remaining hardcoded code-font stacks (HTML block widgets, Mermaid source editor and error display) now resolve through it. Ported from upstream commit 6bb56f5.
  • Sidebar drag-and-drop move: SPECs/sidebar-drag-and-drop-move-spec.md — drag files/folders in the Everything tree to re-parent them (drop on folder → inside, on file → its folder, on empty space → workspace root), with multi-select batches, open-tab/pin/expanded-state rewrites, and collision reporting. Pointer-event based so it coexists with the existing Finder-drop-to-open; inline rename and drag-move now share one write path (use-move-entry).
  • Compact picker recents polish — add a plain non-hovering Recents label using sidebar section styling, remove the search field, per-row opened time, Open other file row, and active file entry, then keep the row remove affordance small so the picker is a direct global recents list.
  • Global-scoped compact mode: SPECs/global-compact-mode-spec.md — compact windows are fully workspace-free (no root, no indexing, parent-dir single-file watcher), the picker shows a persisted global recent-files list, and the workspace-scoped compact setting is replaced by an "Open File in Compact Window" command.
  • Compact picker trigger hit area — scope the closed trigger surface hover/focus state to the pill instead of the full picker-width wrapper.
  • Compact picker trigger close hold — keep the closed trigger surface visible for 300ms after the picker close morph, then fade it with the picker opacity curve.
  • Compact picker shadow fade — move the light-mode popover shadow to an opacity-animated layer so it fades out on close.
  • Compact picker light trigger fill — make the light-mode compact trigger use a subtle gray tint instead of a near-white fill.
  • Compact picker light shadow — add a subtle floating-card-style shadow to the compact picker popover in light mode.
  • Compact picker timing — slow the picker morph and related content fades to 260ms while keeping the previous easing curve.
  • Compact picker height cap — raise the compact navigator popover max height to 420px while keeping content-sized wrapping below the cap.
  • Compact picker center anchoring — counter-scale the picker content from the horizontal center so the navigator stays centered while the popover expands.
  • Compact footer polish — hide the document stats footer in compact chrome while leaving the normal workspace footer unchanged.
  • Compact mode setting: SPECs/compact-mode-setting-spec.md — make compact chrome a persisted appearance setting with a command-palette toggle, while removing the debug-only compact launch environment variable.
  • Compact single-file window: SPECs/compact-window-spec.md — use compact chrome for explicit single-file opens with no sidebar, no sidebar toggle, no tab strip, and a top dropdown that reuses Pinned, Recents, and Everything navigation.
  • Website TanStack Start refactor: SPECs/website-tanstack-start-refactor-spec.md — move the marketing website from a plain Vite SPA to TanStack Start routing/document/build structure while preserving the static Cloudflare deployment path.
  • Floating card shadow polish — add a large subtle shadow to the shared command-palette/popover card surface.
  • Sidebar sections redesign: SPECs/sidebar-sections-spec.md — split the sidebar into collapsible Pinned, Recents, and Everything sections; keep the existing file tree under Everything; add per-workspace pinned files and compact metadata-backed recent files with Show More pagination.
  • Table virtualization scroll stability: SPECs/table-virtualization-scroll-stability-spec.md — give folded markdown table widgets stable CodeMirror height estimates so scrolling through virtualized documents with tables does not suddenly resize the document or scrollbar.
  • Sidebar file label setting — add an appearance.sidebar-file-label enum (title | filename, default title) and have the sidebar file tree render the filename stem or the title-fallback chain accordingly. Also expose a "Rename..." action in the file context menu (files reuse the inline-rename flow folders already had).
  • Desktop dev script — make the root dev script delegate to the desktop package's Tauri dev workflow and keep desktop build/preview scripts on Vite+ commands.
  • Dependency lock refresh: SPECs/Agent/worksheet-dependency-lock-refresh.md — refresh compatible Rust and JavaScript dependency lockfiles, including the vite-plus toolchain update, root TypeScript config alignment, and package-audit fixes.
  • Default paragraph line height — make new and reset editor line-height settings use 1.8 instead of 1.6.
  • List prefix interaction zones: SPECs/list-prefix-interaction-zones-spec.md — constrain pre-body caret positions to line start, marker start, and body start, then make Backspace and multi-line Tab/Shift-Tab operate from those source zones.
  • List selection geometry revamp: SPECs/list-selection-geometry-revamp-spec.md — replace bullet/task point widgets plus zero-width hidden prefixes with measurable source-backed prefix marks so horizontal drag selection has stable hit-test geometry.
  • Table cell link regressions: SPECs/table-cell-link-regressions-spec.md — keep rendered table-cell links clickable without unfolding the table, and render Obsidian wiki links with table-escaped aliases correctly.
  • Table cell markdown preview: SPECs/table-cell-markdown-preview-spec.md — render inline markdown inside folded table preview cells instead of showing the raw markdown delimiters.
  • Table unfold codeblock display: SPECs/table-unfold-codeblock-spec.md — render touched table markdown as codeblock-styled source lines in the main editor instead of plain prose.
  • Markdown heading top padding: SPECs/heading-top-padding-spec.md — inject a shared editor heading class and use it to add 1rem top padding to Markdown headings.
  • Sidebar hover and active foreground polish — make sidebar icons and labels use full foreground color on hover, selection, and active states.
  • Code block editor font size — make fenced Markdown code blocks and inline code follow the editor font-size setting.
  • Link and image paths with spaces: SPECs/link-paths-with-spaces-spec.md — make Markdown links/images and existing wiki-style link resolution work when labels, aliases, folders, filenames, or generated asset paths contain spaces.
  • Empty list caret visibility: SPECs/empty-list-caret-spec.md — keep the caret visible at the body column on empty bullet and task-list items whose source marker is hidden by the list-prefix renderer.
  • List selection and TODO checkbox regression: SPECs/list-selection-todo-checkbox-regression-spec.md — replace list-prefix replace widgets with point widgets to stop selection/caret snaps, and render TODO checkboxes as a single non-native span so drag-selection and nested alignment work.
  • Mermaid canvas widget: SPECs/mermaid-canvas-widget-spec.md — render mermaid blocks in a fixed-height canvas-style frame with pan, zoom, reset-to-fit, and an edit-code toggle.
  • Mermaid fullscreen diagram: SPECs/mermaid-fullscreen-diagram-spec.md — expand button on the canvas opens the diagram in a viewport-sized <dialog> with reused pan/zoom controls.
  • Heading anchor links: SPECs/heading-anchor-links-spec.md — GFM slugger, same-doc smooth scroll, cross-doc navigate+scroll, inline warning on unresolved anchors.
  • Section indicators: SPECs/section-indicators-spec.md — left-edge rail of heading ticks with active-heading tracking, hover outline popover, click-to-scroll, and right-click Copy heading link.
  • Mermaid drag-selection edit-mode flip: SPECs/mermaid-drag-selection-edit-mode-flip-spec.md — freeze editMode for the duration of a pointer drag-selection so the widget doesn't flip into source view mid-drag.

Up Next

  • Backspace on an empty nested item at depth 2 or deeper leaves a whitespace-only line (····- → ··), per the literal "marker plus one indent level" rule in SPECs/list-prefix-interaction-zones-spec.md. Consider outdenting to the parent's indent instead, matching Enter on an empty nested item.
  • Nested ordered items (now reachable with Tab) render with the fixed 3ch ordered hanging indent, so their leading source spaces stay visible; give ordered lines the same depth-aware indent as bullets.
  • Cmd+Shift+8 on a task line strips - and leaves [ ] text; it should probably strip the whole task prefix or leave the line alone.

Backlog

Previously-triaged work organized by phase. Pull into Up Next as capacity opens.

Content features

Visual and media polish

Architectural bets

  • Archive files: SPECs/archive-files-spec.md — medium risk. Adds a parallel storage area and a purge job.
  • Multi window (v1 shipped — single-process multi-window): SPECs/multi-window-spec.md. Future work: macOS Window menu listing open workspaces, session restore of all open windows at quit, tab tear-off across windows.
  • Custom MCP: SPECs/custom-mcp-spec.md — high risk. New protocol client, trust model, and tool invocation surface.
  • Writer CLI: SPECs/writer-cli-spec.md — standalone second binary; can slot in whenever convenient.

Performance and resilience

  • Slow storage resilience: SPECs/slow-storage-resilience-spec.md — async title extraction + bounded timeout so iCloud / Dropbox / network-mount workspaces stay responsive. Storage-agnostic, no provider-specific path lists.
  • Workspace snapshot: SPECs/workspace-snapshot-spec.md — architectural cleanup of AppState into a single versioned Arc<Snapshot> with inode-keyed entries and watcher-maintained titles. Follow-up to the workspace-switch-hang fix; pull in only if the current epoch/cancel primitives prove insufficient or if tags / new-tab-recents want the richer metadata.

Done

See CHANGELOG.md and git log for shipped work. Notable items:

  • External file watcher: external file changes (Finder, git, vim, scripts) reach the sidebar and reload-from-disk reliably; dotdir workspace roots, /var aliases, and self-write echoes all fixed (SPECs/external-file-watcher-spec.md)
  • Cmd+F polish: safe scroll-into-view, Cmd+G / Cmd+Shift+G next/previous, scrollbar match overview (SPECs/cmd-f-spec.md)
  • Caret position after history navigation
  • Obsidian-style wikilink parsing — aliases, escaped table pipes, note fragments, same-file fragment links
  • Sidebar toggle tab chrome shift
  • Rename bundled Codex theme preset to Writer
  • Recent workspaces Dock menu
  • Editor search lifecycle refactor
  • Theming system — CSS-var-driven primaries (accent, bg, fg, fonts, translucency, contrast) per light/dark mode
  • Multi-window v1 (single-process, per-window state): SPECs/multi-window-spec.md — WorkspaceState keyed by window label isolates watcher, file index, settings, pending-open queue
  • Tabbed pages (settings in a tab + page-kind registry)
  • Frontmatter edit flow
  • Editor shortcut clashes + markdown formatting keymap
  • Editor context menu (incl. Format/Paragraph/Insert submenus)
  • Extensionless markdown links
  • Mermaid diagrams
  • Editor tab switch performance — tab-keyed panes, watcher/save coordination
  • Local-only macOS E2E smoke test via Choochmeque/tauri-webdriver — apps/desktop/e2e/
  • Workspace visual redesign
  • Auto update, titlebar double-click zoom, scrollbar layout shift fix, scroll active tab into view, hide sidebar handle, remove saving indicator + tab dirty dot
  • Sidebar file/folder context menus, sidebar bulk actions, craft-style sidebar
  • Gitignore-aware workspace
  • Reduce document open latency
  • Cold-start startup performance — bundled restore_workspace IPC, pre-resolved restore_target, skeleton-shell rendering, dev-only startup telemetry
  • Keyboard and accessibility pass
  • Workspace switch hang fix
  • Writer open CLI — writer-cli binary + shared open_target module, macOS PATH-install menu item, bundle-resource staging