feat: parse and render Obsidian cross-references (task 0005) #4

Closed
alexion wants to merge 1 commits from task-0005-cross-references into main
Owner

Task: .claude/tasks/0005-cross-references.md

Summary

Adds Obsidian cross-references as typed inline nodes and renders them.

  • WikilinkNode and TransclusionNode share a { target, anchor?, display? } shape and are distinct node types.
  • [[…]] wikilinks parse via remark-wiki-link (added to the pipeline); the #anchor is split out in the translation layer and passed through verbatim, and a display alias is captured after |.
  • ![[…]] transclusions — including Step References (#section:N, #N) — are recovered by scanning text runs, since remark-wiki-link@2.0.1 does not recognise embeds.
  • render shows wikilinks underlined (display text, or the target when there is none) and transclusions as their reconstructed raw source text.

Deviations

  • remark-wiki-link@2.0.1 handles only [[…]], not ![[…]] embeds, and does not split the #anchor. Transclusions are therefore recovered by a text-run scan and anchors are split by a shared splitAnchor helper. The plugin's alias divider is set to | so Step Reference anchors like #rolling:2 are not consumed.
  • A wikilink with an anchor but no display renders only the target text; this follows the spec's exact wording ("display text, or the target when there is no display text").

Full detail in the task file's ## Implementation Notes.

Review

Risk

Overall: Medium

  • Blast radius: Medium — adds node types to the shared InlineNode union, though changes are additive and both consuming switches are updated here.
  • Reversibility: Low — pure code plus one dependency addition, trivially revertible; no migrations or published-API breaks.
  • Test coverage: Low — both parse and render paths are covered by new unit tests (anchors, aliases, bare cases, Step References, prose extraction).
  • Sensitive domain: Low — markdown parsing and terminal rendering only.
  • Size & complexity: Medium — modest size, but the regex-based transclusion recovery plus anchor/alias splitting is fiddly control flow.
  • Runtime criticality: Medium — core parse path of a CLI tool, and a new third-party dependency slightly raises supply-chain exposure.

Unaddressed findings

None. The Spec axis reported no blocking findings (all seven acceptance criteria met). The Standards axis's hard findings — semicolons in comments and multiple sentences per comment line — were fixed in this branch; its remaining items (two structurally identical interfaces, and a shared construction shape between translateWikilink/buildTransclusion) were judgement calls the reviewer deemed defensible, given the repo's discriminated-union convention and the genuinely different display-derivation logic.

Task: `.claude/tasks/0005-cross-references.md` ## Summary Adds Obsidian cross-references as typed inline nodes and renders them. - `WikilinkNode` and `TransclusionNode` share a `{ target, anchor?, display? }` shape and are distinct node types. - `[[…]]` wikilinks parse via `remark-wiki-link` (added to the pipeline); the `#anchor` is split out in the translation layer and passed through verbatim, and a display alias is captured after `|`. - `![[…]]` transclusions — including Step References (`#section:N`, `#N`) — are recovered by scanning text runs, since `remark-wiki-link@2.0.1` does not recognise embeds. - `render` shows wikilinks underlined (display text, or the target when there is none) and transclusions as their reconstructed raw source text. ## Deviations - `remark-wiki-link@2.0.1` handles only `[[…]]`, not `![[…]]` embeds, and does not split the `#anchor`. Transclusions are therefore recovered by a text-run scan and anchors are split by a shared `splitAnchor` helper. The plugin's alias divider is set to `|` so Step Reference anchors like `#rolling:2` are not consumed. - A wikilink with an anchor but no display renders only the target text; this follows the spec's exact wording ("display text, or the target when there is no display text"). Full detail in the task file's `## Implementation Notes`. ## Review ### Risk **Overall: Medium** - Blast radius: Medium — adds node types to the shared `InlineNode` union, though changes are additive and both consuming switches are updated here. - Reversibility: Low — pure code plus one dependency addition, trivially revertible; no migrations or published-API breaks. - Test coverage: Low — both parse and render paths are covered by new unit tests (anchors, aliases, bare cases, Step References, prose extraction). - Sensitive domain: Low — markdown parsing and terminal rendering only. - Size & complexity: Medium — modest size, but the regex-based transclusion recovery plus anchor/alias splitting is fiddly control flow. - Runtime criticality: Medium — core parse path of a CLI tool, and a new third-party dependency slightly raises supply-chain exposure. ### Unaddressed findings None. The Spec axis reported no blocking findings (all seven acceptance criteria met). The Standards axis's hard findings — semicolons in comments and multiple sentences per comment line — were fixed in this branch; its remaining items (two structurally identical interfaces, and a shared construction shape between `translateWikilink`/`buildTransclusion`) were judgement calls the reviewer deemed defensible, given the repo's discriminated-union convention and the genuinely different display-derivation logic.
alexion added 1 commit 2026-07-29 20:06:16 -04:00
Model `[[wikilinks]]` and `![[transclusions]]` as distinct inline node
types sharing a `{ target, anchor?, display? }` shape, and render them:
wikilinks underlined (display text or target), transclusions as their
raw source text.

remark-wiki-link is added to the pipeline for `[[…]]`. It does not
recognise `![[…]]` embeds or split the `#anchor` from the target, so
transclusions are recovered by scanning text runs and anchors are split
in the translation layer. Its alias divider is set to `|` so Step
Reference anchors like `#rolling:2` survive.
alexion closed this pull request 2026-07-29 20:26:59 -04:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No Label
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alexion/kitchen-md#4