feat: folders are fs-authoritative — empty folders are first-class - #63
Conversation
The file tree is now one-to-one with the filesystem in both directions. Folders are user-authored *structure* (the content sibling of notes), never projected into the index — data-model.md "Folders" (2026-07-21). - Vault::list_dirs — the tree's structure half, a live fs walk (dot-dirs skipped, the ingest walk's routing rule): empty folders show, external mkdirs appear on the watcher pulse, no staleness window exists. - Vault::create_dir — the desktop's New-folder is now a real `mkdir -p` on disk, replacing the session-scoped pendingDirs staging (which lost folders on restart/vault-switch and showed folders the fs didn't have). - move_dir/delete_dir already resolved against the disk, so empty folders move/rename/delete everywhere (b2 mv, b2 rm -r, the tree) — now pinned by test; folder deletes in the UI always confirm (an "empty" folder may still hold unindexed files, and remove_dir_all takes everything). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 43 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughFilesystem-backed folder listing and creation are added across the core vault, desktop IPC, and frontend. Empty folders are read live from disk, created through OS operations, rendered in the tree, and covered by core and desktop tests. The previous staged-folder state is removed. ChangesFilesystem-authoritative folder flow
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
CLAUDE.md (1)
126-132: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake the architecture contract internally complete.
This contradicts lines 111-118’s “no durable state outside Markdown” invariant, and the declared façade surface omits
list_resources,move_resource, andmove_dir. Update both statements so this guide remains the authoritative contract.Also applies to: 175-177
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@CLAUDE.md` around lines 126 - 132, Update the architecture contract in CLAUDE.md so the “no durable state outside Markdown” invariant explicitly permits authoritative user-created filesystem folders. Expand the declared façade surface to include list_resources, move_resource, and move_dir, and apply the same corrections to the corresponding repeated contract section.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/b2-core/src/dirs.rs`:
- Around line 33-69: Update collect_dirs to inspect each directory entry’s
symlink metadata and skip symlink entries before the is_dir check, preventing
traversal outside root or recursive links. Update create_dir to resolve and
validate each existing parent component without following symlinks, rejecting
symlinked parents before creation while preserving DirDestination and
DirTargetExists errors.
In `@planning/data-model.md`:
- Around line 67-70: The directory-creation wording must reflect the
non-idempotent create_dir contract: in planning/data-model.md lines 67-70,
replace “mkdir -p” with wording that says creation creates missing parents while
rejecting an existing target; make the same wording change in planning/tasks.md
lines 92-94, replacing “real mkdir -p.”
- Around line 72-74: The filesystem-authority claims must be scoped to managed
non-dot directories because Vault::list_dirs omits dot-folders. In
planning/data-model.md lines 72-74, replace the one-to-one filesystem wording
with “one-to-one with non-dot managed directories”; apply the same scoped
wording to the current-state summary in planning/tasks.md lines 89-97.
In `@ui/src/main.ts`:
- Around line 212-216: Update loadNotes() to fetch notes, resources, and dirs
into temporary results before mutating state, so a listDirs() failure cannot
clear or partially commit existing data. Propagate or return the refresh failure
instead of resolving normally, and update the caller around the success message
at lines 541-552 to report “Created …” only after loadNotes() completes
successfully.
---
Nitpick comments:
In `@CLAUDE.md`:
- Around line 126-132: Update the architecture contract in CLAUDE.md so the “no
durable state outside Markdown” invariant explicitly permits authoritative
user-created filesystem folders. Expand the declared façade surface to include
list_resources, move_resource, and move_dir, and apply the same corrections to
the corresponding repeated contract section.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e6bf698f-c315-4a42-996b-d889d8c8020e
📒 Files selected for processing (21)
CLAUDE.mdcrates/b2-core/src/dirs.rscrates/b2-core/src/error.rscrates/b2-core/src/lib.rscrates/b2-core/src/vault.rscrates/b2-core/tests/dirs.rscrates/b2-core/tests/mv.rscrates/b2-core/tests/rm_delete.rscrates/b2-desktop/src/commands.rscrates/b2-desktop/src/error.rscrates/b2-desktop/src/main.rsplanning/data-model.mdplanning/tasks.mdui/src/api.tsui/src/main.tsui/src/move.test.tsui/src/move.tsui/src/newentry.tsui/src/render.tsui/src/state.tsui/src/types.ts
- loadNotes: fetch all three tree lists before committing state (a mid-refresh failure can't half-update the tree), and resolve a boolean so create flows don't overwrite the failure toast with "Created …". - Docs/comments: create_dir is create-with-parents *refusing* an occupied target (not mkdir -p's idempotence); scope the one-to-one claim to the vault's managed (non-dot) subtree; scope the CLAUDE.md invariant to B2-derived state and complete the façade surface list. - dirs.rs: document that list_dirs deliberately mirrors the ingest walk's symlink-following traversal — diverging would desync tree structure from indexed content; a symlink policy must change both walks together. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The file tree is now one-to-one with the filesystem in both directions. Folders are user-authored structure (the content sibling of notes), never projected into the index — data-model.md "Folders" (2026-07-21).
mkdir -pon disk, replacing the session-scoped pendingDirs staging (which lost folders on restart/vault-switch and showed folders the fs didn't have).Summary by CodeRabbit
New Features
Bug Fixes
Tests