Skip to content

vscode: markdown preview marker-aware features — inline REVIEW rendering + right-edge marker minimap #863

Description

@amrmelsayed

Problem

Today the markdown preview hides <!-- REVIEW(@<author>): <text> --> markers entirely (HTML comments don't render). Two consequences:

  1. Reading the preview gives no signal that comments exist. Architect opens preview to review a spec; sees clean rendered prose; has no idea five REVIEW markers are sitting in the source. They have to switch to the editor to even know feedback exists, defeating the "preview is the reading surface" pattern that vscode: add review comments from the markdown preview pane (hover-+ per block, no editor mode-switch) #859, vscode: markdown preview navigation chrome — floating TOC + quick-jump overlay + per-heading mini-toolbar for long Codev artifacts #861, etc. are building toward.
  2. No spatial overview of where comments are. Even if the architect knows comments exist, finding their locations means scrolling through the source editor's gutter or opening vscode: review summary webview — bird's-eye list of all REVIEW markers in spec/plan files with click-to-jump #860's review summary panel. No at-a-glance map.

This issue adds two complementary surfaces in the preview, both deriving from the same data (REVIEW markers in the source), both pure rendering (no interaction beyond click-to-jump).

Update (post-#859 / PR #1045): the rendering surface changed

Since this issue was filed, #859 / PR #1045 shipped the Codev Markdown Preview as a host-owned CustomTextEditor built on the @cluesmith/codev-artifact-canvas package (packages/artifact-canvas/). The "markdown preview hides markers entirely" framing in the original Problem section is now out of date: the canvas renderer strips full-line HTML comments pre-parse and renders parsed markers as comment cards above each annotated block.

What this issue still asks for stays correct (in-context visibility plus a spatial overview), but the rendering surface for the inline call-outs is the artifact-canvas package, not a VSCode-side markdown-it plugin. The "Implementation sketch" section below was written for the pre-#945/#859 world; treat its specific file paths and APIs as illustrative of intent only. Concrete file paths now live in packages/artifact-canvas/src/.

New concrete symptom to fix: comment cards overlap targeted content

The v1 marker rendering in the artifact-canvas positions comment cards as absolutely-positioned overlays at the targeted block's data-line y-coordinate. The cards sit on top of the first lines of the block they annotate, hiding part of the content. Reproducible on any rendered spec/plan/review with at least one comment:

  • The + gutter button is correctly placed on the left of the targeted block
  • The comment card stack renders OVER the targeted block instead of above it or beside it
  • For multi-comment blocks the stack grows downward, hiding more content

The intent is sound (cards anchored to the block they annotate), but the layout treatment was minimal v1 and did not reserve space.

Layout fix: pattern review and recommendation

Peer-tool conventions to evaluate against:

Pattern Used by Width budget Pros Cons
Inline-below (insert between blocks) GitHub PR review, GitLab MR Any width Clear block association, no overlap, works in narrow panes Pushes subsequent content down; dense docs stretch
Gutter pin + click to expand Notion, Linear Gutter only No overlap, scales to many comments, no stretching when collapsed Extra click to read
Right sidebar with connecting lines Google Docs, Hypothes.is Wide pane only Doc stays pristine Hostile in narrow VSCode preview pane
Top padding push on the block (no precedent) Any Smallest code change Consumes vertical space even with empty slots; inelegant

Recommendation for v1.1: inline-below as the default, with gutter pin + expand kept as a follow-up option for dense docs. The inline-below pattern fits any width, preserves block association via a thin vertical rule tying back into the gutter where the + button lives, and renders no slot when a block has no comments. It is the GitHub PR review pattern most architects already have muscle memory for.

The change is internal to the artifact-canvas package: CSS plus a small render-tree adjustment in the marker layer. No host adapter changes required; on-disk marker convention unchanged.

Additional acceptance criteria for the layout fix

Proposal — two marker-aware features, one bundle

Bundled because they share the same source of truth (REVIEW markers in the doc), the same parsing infrastructure (regex from plan-review.ts:31), and the same eligibility gating.

1. Inline REVIEW marker rendering

Render <!-- REVIEW(@<author>): <text> --> as styled inline call-out boxes in the preview, not as hidden HTML comments.

Visual:

... existing rendered paragraph ...

  ┌─ 💬 @architect ───────────────────────────────────┐
  │  tighten this paragraph                            │
  └────────────────────────────────────────────────────┘

... next rendered paragraph ...
  • Implementation: a markdownItPlugin that transforms REVIEW markers at AST-conversion time. The plugin recognizes the marker syntax during tokenization and emits a custom <div class="codev-review-marker"> with author + body fields
  • Visual: subtle border, colored accent on the left edge (VS Code theme variable), small icon (💬 or $(comment)), author label, comment body
  • Click: clicking the call-out jumps to the marker's line in the source editor (uses the data-line attribute the plugin emits)
  • Future-compat: when reply / resolve state lands (per the Phase 3 design call), the call-out grows to show thread state (unresolved border color, reply count, etc.)

2. REVIEW marker minimap (right-edge column)

A vertical column at the right edge of the preview showing colored dots at the scroll-positions of each REVIEW marker.

Visual:

              ┃     ← preview content
              ┃
              ┃     • marker at L47
              ┃
              ┃     • marker at L52
              ┃
              ┃     • marker at L58
              ┃
              ┃
              ┃     • marker at L91
              ┃
              ┃

Path eligibility

Same as #859, #860, #861, and the document-state surfaces filing: only .md files in codev/(plans|specs|reviews)/. Other markdown files render REVIEW markers (if any) as standard hidden HTML comments, unchanged.

Implementation sketch

Files

  • New: packages/vscode/src/markdown-preview/marker-render-plugin.ts — markdown-it plugin that recognizes REVIEW markers during tokenization and emits the call-out HTML
  • New: packages/vscode/src/markdown-preview/marker-minimap.jspreviewScripts entry; DOM scanning, dot rendering, click handlers
  • New: packages/vscode/src/markdown-preview/marker-render.csspreviewStyles for both the inline call-outs and the minimap dots

Marker-rendering plugin details

The plugin operates at the inline-token level. When it sees an HTML comment token matching REVIEW_COMMENT_PATTERN, it replaces the token with a custom block-level html_block token whose content is the styled call-out markup. Source-line attribution preserved via data-line (so the minimap can find the position).

Minimap details

Composition with the editor side

The editor-side Comments API surface (plan-review.ts) keeps rendering REVIEW markers as comment threads in the gutter. This issue is preview-only:

  • Editor: gutter + and comment threads (unchanged)
  • Preview: inline call-outs (new) + right-edge minimap (new)

Authors flow consistently through both: a marker added via #859's preview + shows up as an inline call-out in the preview AND as a Comments API thread in the editor on next refresh.

Acceptance criteria

Inline REVIEW marker rendering

  • <!-- REVIEW(@<author>): <text> --> markers in eligible files render as visible inline call-out boxes in the preview
  • Call-out shows author and body; subtle border with colored left edge
  • Click call-out → opens source file at the marker's line in editor
  • Uses VS Code theme variables (--vscode-editor-foreground, --vscode-textBlockQuote-border, etc.)
  • Markers in non-eligible files render as standard hidden HTML comments (no change to default behavior)
  • No regression to existing editor-side Comments API rendering — both surfaces show the same markers

REVIEW marker minimap

General

Out of scope (v1)

  • Reply / thread display in the call-outs — single comment per call-out in v1; design call deferred (depends on the broader Phase 3 reply-storage decision)
  • Resolve state visualization (different border color for resolved markers) — depends on resolve-state storage decision (Phase 3.3 from prior planning); add when that lands
  • Filter UI in preview ("hide resolved markers", "show only mine") — that's vscode: review summary webview — bird's-eye list of all REVIEW markers in spec/plan files with click-to-jump #860's job; preview shows everything
  • Editing markers from the call-out — call-outs are read + click-to-jump only; mutation happens in the editor via the existing Comments API path
  • Per-marker minimap colors (e.g. red for unresolved, gray for resolved) — uniform color in v1; differentiation lands with resolve state
  • Outline panel enrichment (markers as outline children) — different VS Code API entry point; separate filing if/when wanted

Dependencies

Related

Why this is high leverage

Currently the preview is a partial view of the doc — it shows the rendered prose but hides the feedback layer entirely. The architect's "read the preview" workflow gives them no signal that there's anything to address. This issue completes the preview: the feedback layer becomes visible in context (inline call-outs at the exact paragraph being discussed) and spatially (minimap shows where feedback is concentrated). Combined with #859 (add comments from the preview), the preview becomes the complete review surface — read, see existing feedback, add new feedback, see where it is, click to navigate, all without switching to the source editor unless replying/deleting.

Metadata

Metadata

Assignees

Labels

area/vscodeArea: VS Code extension

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions