feat(storage): Vault Doctor — health check and conflict repair#832
Merged
Conversation
Rework the duplicate-id decision block from button rows into a shadcn radio-group: split file path into name + folder, add original/copy badges, show the per-row outcome (keeps id / new id), preselect the likely original as canonical, and surface resolved/unresolved group status. Add shadcn radio-group and badge primitives.
Run a non-blocking, read-only vault doctor preview after app load (in idle) and show a sonner with a "Review" action when sync conflicts are found. Doctor lives in Storage settings, which users rarely open, so conflicts (duplicate ids, merge markers, invalid frontmatter) would otherwise go unnoticed. Safe fixes are excluded since the watcher applies them silently.
Pass a `doctor=scan` query from the startup conflict sonner and trigger the scan on mount in Storage, then clear the query. Previously the action landed on an empty Vault Doctor section that required pressing Scan manually.
Move vault doctor state (report, decisions, scan/apply) into a shared module-level composable so the startup health check and the Storage section reuse a single report instead of scanning twice. When opened from the startup notice, reuse the existing report (or scan if absent) and smooth-scroll to the Vault Doctor section.
The default radio border-input (~30% L) nearly matches the card surface (~27% L) in dark theme, making unselected radios invisible. Use border-muted-foreground/50 for a readable outline on any surface.
Replace the per-radio border hack with a surface lift: the Needs decision panel now sits on bg-background (matching its header), so borders and radios inside read against the elevated surface instead of blending into the card. Revert the radio border-color override.
Show the scan spinner only if the scan runs longer than 300ms, mirroring the existing snippet counts loader. Fast scans no longer flash the loader for a split second. The button stays disabled on the real scanning flag so repeat clicks are still blocked instantly.
Apply the same delayed-loader pattern to Apply fixes: show the spinner only if apply runs longer than 300ms. The button stays disabled on the real applying flag so repeat clicks are blocked instantly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Что это
Vault Doctor — maintenance-функция в
Preferences → Storage, которая сканирует markdown vault и помогает привести в порядок проблемы, которые приложение не должно чинить молча. Закрывает два болевых сценария:idпосле слияния, merge-маркеры, conflicted-copy файлы.Раньше такие проблемы оставались невидимыми: doctor живёт в настройках, куда пользователь почти не заходит.
Что делает
code/notes/http/math.blocked, не парсятся и не переписываются..meta.yaml, register, counters) применяются стандартным sync.activeSheetId).Проактивное уведомление
После загрузки приложения — неблокирующий read-only чек (в idle). При наличии конфликтов показывается sonner с кнопкой «Разобрать» → открывает Storage, автоскан, скролл к секции. Состояние вынесено в
useVaultDoctor, поэтому startup-проверка и секция переиспользуют один отчёт (без двойного скана).UI
Оригинал/Копия, исход на строке (сохранит id/новый id), автопредвыбор вероятного оригинала.bg-background) для контраста границ в тёмной теме.Тесты
doctor.test.tsпокрывает детект дублей, reassign по решению, blocked merge-маркеров, исключение trash, env/math repair, идемпотентность.Известное ограничение
В
code/notesнерешаемыйblocked-файл (merge-маркер / битый frontmatter) пока замораживает применение safe fixes во всём спейсе — консервативно-безопасно, но расходится с целью полностью раздельных потоков. Кандидат на доработку отдельным PR.🤖 Generated with Claude Code