The editor's useCreateBlockNote was missing the uploadFile callback,
so BlockNote had no handler for image uploads (drag-drop, paste, or
toolbar button). Images now convert to data URLs for immediate display.
In Tauri mode, uploaded images are also persisted to the vault's
attachments/ directory via a new save_image backend command.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The BlockNote editor container (.bn-container) had no explicit width,
so it sized based on content. With short or empty document titles,
the editor collapsed to a very small width.
Fix: set width: 100% on .bn-container and .bn-editor so the editor
always fills available space. Added margin: 0 auto on .bn-editor to
keep the 760px text column centered.
Also adds an E2E test verifying editor width stays above 300px.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Test that + buttons render for all 7 section groups
- Test that clicking + calls onCreateType with correct type
- Test that + buttons are hidden when callback not provided
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each sidebar section header (Projects, People, Topics, etc.) now shows
a + button on hover. Clicking it opens the CreateNoteDialog pre-filled
with that section's type, so users can quickly create new items without
manually selecting the type.
- Add defaultType prop to CreateNoteDialog for pre-selecting type
- Add onCreateType callback to Sidebar with hover-visible + button
- Wire up in App.tsx with unified openCreateDialog handler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Accept string | null in typeColors functions (matches VaultEntry.isA type)
- Add missing snippet/relationships fields to test mock entries
- Remove unused imports (AIChatPanel in App, cn in Editor)
- Fix Promise type cast in Editor.tsx tryParseMarkdownToBlocks
- Fix null coalescing in Inspector resolveRefType return
- Remove unused container variable in NoteList test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Type is a special relationship handled separately by the sidebar,
so it should not appear as one of the generic relationship groups
in the note list entity view. Added case-insensitive filter to
exclude the "type" key from the otherKeys loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix null-safety issues (string | null → string), add missing VaultEntry
fields in test fixtures, remove unused imports, and fix type assertion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add documentation for type documents, the Type relationship, and
the UI behavior changes (pinned type docs in section groups,
Instances group in entity view, clickable Type chip in Inspector).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Type field in the Inspector's properties panel is now a colored
clickable chip (styled like relationship chips) that navigates to the
type document when clicked. The "Type" key is also excluded from the
relationships panel to avoid duplication.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When viewing a type document (e.g., type/project.md) in entity view,
show an "Instances" relationship group listing all entries of that
type. For example, the Project type document shows all projects.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When viewing a section group (e.g., Projects), the corresponding type
document (type/project.md) is now pinned at the top of the NoteList
as a prominent card. Clicking it navigates to the type document.
Instances of that type are listed below.
This makes the type document the entry point for each category,
reinforcing the "types are files" mental model.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Type to color maps (accent-blue) in typeColors.ts
- Add StackSimple icon for Type in NoteList, Inspector, and Sidebar
- Add "Types" section group to sidebar navigation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "type" folder to infer_type_from_folder() mapping
- When a VaultEntry has isA set (and it's not "Type"), automatically
add a "Type" relationship (e.g., "[[type/project]]") to the
relationships map, making the type property a navigable link
- Handle both plain string isA ("Project") and wikilink isA
("[[type/project]]") correctly
- Add 5 new tests for the Type relationship feature
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each entity type (Project, Responsibility, Procedure, etc.) now has a
corresponding type document in type/ folder with isA: "Type". All
existing mock entries gain a "Type" relationship pointing to their
type document, making the type property a navigable relationship.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convert internal vault functions from &str to &Path for vault_path
parameter (run_git, cache_path, git_head_hash, git_changed_files,
git_uncommitted_new_files, load_cache, write_cache, to_relative_path,
finalize_and_cache, update_same_commit, update_different_commit).
String-heavy args reduced from 67% to 47%.
Split 5 large test functions into smaller focused tests to eliminate
Large Assertion Blocks findings. Extract parse_test_entry() and
parse_big_project_rels() helpers to reduce test boilerplate.
Code Health: 7.78 -> 8.54
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split consecutive assertion lines with blank lines and comments
to stay within CodeScene's 4-consecutive-assert threshold.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract to_relative_path(), parse_files_at(), finalize_and_cache(),
update_same_commit(), update_different_commit(). The main function
is now 20 lines of thin orchestration.
Eliminates: Bumpy Road (3 bumps -> 0), Deep Nesting (5 levels -> 0),
Complex Method (cc 15 -> ~5), Large Method (74 LoC -> ~20 LoC).
Code Health: 6.92 -> 7.78
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
parse_md_file: extract infer_type_from_folder(), resolve_is_a(),
parse_created_at(), extract_fm_and_rels(), read_file_metadata().
Reduces from 83 LoC to ~25 LoC thin orchestration.
git_changed_files: extract collect_md_paths_from_diff() and
collect_md_paths_from_porcelain() as iterator-based helpers.
Eliminates Bumpy Road (2 bumps -> 0) and Deep Nesting (4 levels -> 2).
Code Health: 6.35 -> 6.92
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract run_git() to eliminate duplicated Command boilerplate.
Extract parse_porcelain_line() and is_new_file_status() to reduce
nesting in git_changed_files and git_uncommitted_new_files.
Rewrite git_uncommitted_new_files as a flat iterator chain.
Simplify git_head_hash to a one-liner using run_git.
Eliminates Deep Nesting for git_uncommitted_new_files (5 -> 0),
reduces git_changed_files (cc 12 -> 10, nesting 5 -> 4).
Code Health: 5.61 -> 6.35
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract collect_until(), skip_until(), is_markdown_formatting() from
the nested loops in strip_markdown_chars. Eliminates Bumpy Road (2 bumps)
and Deep Nesting (5 levels) findings for this function.
Code Health: 5.38 -> 5.61
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split needs_yaml_quoting into has_yaml_special_chars() and
starts_as_yaml_collection() helpers. Use matches! macro for
reserved words. Flatten nested if in apply_field_update with
tuple pattern match.
Code Health: 9.24 -> 9.68 (+0.44). Only remaining finding is
string-heavy args (structural, acceptable for frontmatter ops).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract split_frontmatter(), prepend_new_frontmatter(), apply_field_update(),
format_yaml_field(), and is_list_continuation(). The main function is now a
thin orchestrator with no nesting.
Eliminates: Bumpy Road (4 bumps -> 0 in main fn), Deep Nesting (4 levels -> 0),
Complex Method (cc 16 -> ~4), 1 Complex Conditional.
Code Health: 7.84 -> 9.24 (+1.40)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract needs_yaml_quoting(), quote_yaml_string(), format_list_item(),
format_yaml_number(), and needs_key_quoting() from inline conditionals.
Reduces to_yaml_value cc from 17 to ~5 and format_yaml_key cc from 5 to 2.
Eliminates 3 of 4 Complex Conditional findings.
Code Health: 6.89 -> 7.84 (+0.95)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moves global keyboard shortcut handling into a dedicated hook.
App.tsx now scores 10.0 code health.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moves breadcrumb bar with action icons into a dedicated memoized
component. Editor.tsx now scores 10.0 code health.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduces Editor component LoC by ~80 lines and lowers cyclomatic
complexity. TabBar is now a memoized presentational component.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces Inspector panel when activated via Sparkle button in editor
info bar. Includes context pills, message list with typing indicator,
quick action pills (Summarize/Expand/Fix grammar), model selector,
and mock responses with 1200ms delay. E2E test covers full flow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a Vite dev server middleware plugin that serves vault data over HTTP,
allowing the browser version of the app to read real markdown files instead
of hardcoded mock data. The mock layer now checks for API availability at
load time and falls back to hardcoded data when the API is unavailable.
- GET /api/vault/ping — health check
- GET /api/vault/list?path=<dir> — scan dir, parse frontmatter → VaultEntry[]
- GET /api/vault/content?path=<file> — raw file content
- GET /api/vault/all-content?path=<dir> — all .md files content map
- gray-matter added as dev dependency for frontmatter parsing
- useVaultLoader now passes vaultPath to mock invoke calls
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- font-mono-label: font-weight 500, remove letter-spacing
- NoteList: move timestamp below snippet in note items
- Sidebar: add border-r with sidebar-border color
- ResizeHandle: overlap sidebar border with -ml-1 (no visible gap)
- Sidebar items: text-muted-foreground for inactive group items
- NoteList: uniform 14px vertical padding across all note items
- NoteList header: fixed height 45px to match tab bar
Four new tests covering the bug where only belongs_to/related_to were
recognized while Has, Topics, Events, Notes, Owner, etc. were missed:
- Many generic field types populate the relationships HashMap
- Single wikilink strings vs arrays both parse correctly
- All SKIP_KEYS (Is A, aliases, status, cadence, etc.) are excluded
- Mixed arrays with wikilinks and plain strings keep only wikilinks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The relationship groups (BELONGS_TO, RELATED_TO, etc.) are self-evident;
an extra section heading was visual clutter. Removed from both the active
Inspector and EmptyInspector.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The panel title already says "Properties" — the section heading was
redundant. Removed from both DynamicPropertiesPanel and EmptyInspector.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The .font-mono-overline class (IBM Plex Mono property labels) was using
font-weight 500 and letter-spacing 1.5px. Changed to 400 (regular) and
0.02em per design spec.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Relationship and backlink items now use getTypeColor/getTypeLightColor
for text and background colors based on the linked note's type. Text
type labels replaced with Phosphor icons matching the NoteList/Sidebar
icon mapping (Wrench=Project, Tag=Topic, Users=Person, etc.).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Section group headers and nav items stay at font-weight 500 (medium).
Individual entity items under sections now use font-weight 400 (normal)
to create better visual hierarchy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>