fix(graph): surface unresolved wikilinks instead of dropping them (#12) - #49
Conversation
A body `[[link]]` that resolves to nothing — a `[[Hermes]]` naming a *folder* (a note is one `.md` file, so a folder is never a valid target), or a plain typo — was projected as a dangling edge (`dst_id` and `dst_resource_path` both NULL) and then filtered out of `neighbors`. The link neither showed nor flagged: from the user's side it silently vanished. Keep the model as-is (a folder is not a note) but stop hiding the failure. Add `graph::unresolved_outbound` (the complement of `neighbors`' outbound half, backed by the existing `edges_dangling_idx`) and surface it through the façade: - `ExplainView` gains an `unresolved: Vec<UnresolvedLink>` field, and a new `Vault::unresolved_links` op backs `b2 neighbors`. - `b2 explain` / `b2 neighbors` print an "unresolved" line per broken link (⚠ + the authored target); `explain --json` carries the structured field. `neighbors --json` keeps its resolved-neighbors array contract — the full picture, including unresolved links, is `explain`. - Desktop Connections pane renders each unresolved link as a distinct broken-link card (⚠ emblem, red-tinted, non-clickable), theme-aware. Resolving the target (create the note, fix the path) turns the same edge into an ordinary connection on the next reindex — no separate authoring step. Folder-note resolution (Obsidian-style `Hermes/Hermes.md`) is left as a possible later refinement. Tests: core graph + façade explain cover the folder/typo split (resolved → neighbor, dangling → unresolved) and no false positives; CLI covers the human + JSON surfaces. Docs: data-model §3 documents the surfaced-dangling edge. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014jemskScrnc4LTw1oqy9Ax
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
📝 WalkthroughWalkthroughThe change preserves dangling outbound links as unresolved data and exposes them through vault, CLI, and UI paths. Human-readable CLI and UI outputs now show unresolved targets, while JSON explain output includes structured unresolved entries. ChangesUnresolved outbound link handling
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CLI
participant Vault
participant Graph
CLI->>Vault: query unresolved links
Vault->>Graph: query dangling outbound edges
Graph-->>Vault: return unresolved metadata
Vault-->>CLI: return unresolved links
CLI-->>CLI: render unresolved warnings
Possibly related issues
Suggested reviewers: Poem
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
A body
[[link]]that resolves to nothing — a[[Hermes]]naming afolder (a note is one
.mdfile, so a folder is never a valid target),or a plain typo — was projected as a dangling edge (
dst_idanddst_resource_pathboth NULL) and then filtered out ofneighbors. Thelink neither showed nor flagged: from the user's side it silently vanished.
Keep the model as-is (a folder is not a note) but stop hiding the failure.
Add
graph::unresolved_outbound(the complement ofneighbors' outboundhalf, backed by the existing
edges_dangling_idx) and surface it throughthe façade:
ExplainViewgains anunresolved: Vec<UnresolvedLink>field, and a newVault::unresolved_linksop backsb2 neighbors.b2 explain/b2 neighborsprint an "unresolved" line per broken link(⚠ + the authored target);
explain --jsoncarries the structured field.neighbors --jsonkeeps its resolved-neighbors array contract — the fullpicture, including unresolved links, is
explain.broken-link card (⚠ emblem, red-tinted, non-clickable), theme-aware.
Resolving the target (create the note, fix the path) turns the same edge
into an ordinary connection on the next reindex — no separate authoring
step. Folder-note resolution (Obsidian-style
Hermes/Hermes.md) is left asa possible later refinement.
Tests: core graph + façade explain cover the folder/typo split (resolved →
neighbor, dangling → unresolved) and no false positives; CLI covers the
human + JSON surfaces. Docs: data-model §3 documents the surfaced-dangling
edge.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_014jemskScrnc4LTw1oqy9Ax
Summary by CodeRabbit
New Features
neighborsandexplain.Documentation