Skip to content

feat: add Notes Space with unified architecture#698

Merged
antonreshetov merged 160 commits intomainfrom
feat/notes-editor-cm6-clean
Mar 22, 2026
Merged

feat: add Notes Space with unified architecture#698
antonreshetov merged 160 commits intomainfrom
feat/notes-editor-cm6-clean

Conversation

@antonreshetov
Copy link
Copy Markdown
Member

No description provided.

Address review findings:
- Watcher integration: ignore __spaces__/notes/ in snippet sync
- Own getNotesPaths() function, separate from snippet getPaths()
- Own notesRuntimeRef singleton cache
- Storage contracts and useStorage() integration
- Notes-specific reserved names (not reusing snippet list)
- Separate content update endpoint (PATCH /notes/:id/content)
- Note serialization: frontmatter + raw body (no fragment parsing)
- Composables re-export from index.ts
- notesState as separate electron-store object
- Scope watcher ignore to __spaces__/notes/ only (not __spaces__/ broadly)
- Use separate useNotesStorage() accessor instead of extending StorageProvider
- Own writeNoteFolderMetadata() (FolderRecord has defaultLanguage, NoteFolderRecord doesn't)
- Reuse shared pendingStateWriteByPath for state debounce
- Note to add 'notes' case in refreshAfterStorageSync() switch
Add NotesPaths, NotesState, MarkdownNote, NotesRuntimeCache and other
runtime types. Add notes contracts (NoteRecord, NotesStorage,
NotesFoldersStorage, NoteTagsStorage, NotesStorageProvider) to the
shared contracts file.
Add getNotesPaths(), notesRuntimeRef singleton, notes-specific path
constants. Add folder path utilities (buildNotesFolderPathMap,
findNotesFolderById, etc.). Extend validateEntryName to accept 'note'
kind.
Add loadNotesState, saveNotesState, ensureNotesStateFile that reuse
the shared pendingStateWriteByPath maps from the snippet runtime.
State version starts at 1.
Add serializeNote (YAML frontmatter + raw markdown body), readNoteFromFile,
writeNoteToFile, persistNote, loadNotes, findNoteById, listNoteMarkdownFiles.
Add notes folder metadata read/write without legacy migration or
defaultLanguage.
Add buildNotesSearchIndex, getNoteIdsBySearchQuery, and
invalidateNotesSearchIndex using the same trigram + word token
algorithm as snippet search.
Add syncNotesFoldersWithDisk, syncNotesRuntimeWithDisk,
getNotesRuntimeCache, resetNotesRuntimeCache for the notes storage
runtime. Add barrel export index.ts for the notes runtime module.
…nt-only jump

Down now returns block.from (line start) instead of block.from + 1.
Up now returns the start of the last block line instead of block.to - 1.
Both directions enforce strict adjacency (next/prev line only) instead of
allowing jumps over multiple blank lines via hasOnlyBlankLinesBetween.
…acent lines

Same fixes as mermaid navigation: down/up targets now land at the start
of the target line (block.from / targetLine.from) instead of off-by-one
positions. Replaced hasOnlyBlankLinesBetween with strict adjacent-line
check so the cursor only jumps when exactly one blank line separates it
from the table block.
Previously, clicking anywhere on a mermaid or table widget always placed
the cursor at the first line of the source block. Now the mousedown
handler uses linear interpolation between the click position and the
widget height to estimate the corresponding source line, placing the
cursor closer to where the user actually clicked.
Show raw `[ ]`/`[x]` markup when cursor is on the task marker line
in interactive mode, matching the existing horizontal rule behavior.
…eting

Dispatch setEditorFocusEffect together with selection change so
isSelectionInsideRange sees hasFocus=true in the same transaction.
Table click now detects the exact cell via DOM and maps to the
corresponding source position.
… and markup overlap

- Table/mermaid StateFields now detect setEditorFocusEffect and rebuild
  decorations when editor loses/gains focus
- Remove blank-line requirement from block navigation so ArrowUp/Down
  can enter table/mermaid blocks from any adjacent line
- Preserve cursor column (goal column) when navigating into blocks
- Fix hideMarkup isCursorInRange to use proper interval overlap so
  selections spanning across markup correctly reveal markers
Note (Info), Important (Flame), Warning (TriangleAlert).
Icons are inline-flex with zero height to avoid affecting line height.
Footer select with icon-only trigger (Code, Pencil, BookOpen).
Three modes: raw (no decorations), live preview (cursor-based toggle),
preview (read-only, all pretty). Mode persisted to electron store.
Add cva-based variant system to SelectTrigger (default, ghost).
Use ghost variant for the editor mode selector in notes footer.
- Add NotesEditorSettings (fontSize, fontFamily, codeFontFamily,
  lineHeight, limitWidth, lineNumbers, indentSize) with preferences UI
- Fix Switch wrapper: reka-ui v2.9.0 uses modelValue, not checked
- Extract editor theme to theme.ts
- Line numbers only in raw mode
- Code font configurable via --notes-code-font CSS variable
…Note Editor

Unify icon with space rail (Code2), consistent naming pattern:
Code Editor, Note Editor (future: Math Editor).
@antonreshetov antonreshetov merged commit f3c85ca into main Mar 22, 2026
@antonreshetov antonreshetov deleted the feat/notes-editor-cm6-clean branch March 22, 2026 05:44
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