diff --git a/codev/plans/863-vscode-markdown-preview-marker.md b/codev/plans/863-vscode-markdown-preview-marker.md new file mode 100644 index 000000000..6a1d39e30 --- /dev/null +++ b/codev/plans/863-vscode-markdown-preview-marker.md @@ -0,0 +1,107 @@ +# PIR Plan: Marker-aware artifact canvas — inline-below comment cards + right-edge minimap + +Issue: #863 — *vscode: markdown preview marker-aware features — inline REVIEW rendering + right-edge marker minimap* + +## Understanding + +The issue asks the Codev markdown preview to make the REVIEW-marker feedback layer **visible** in two complementary ways: (1) render each marker as an in-context call-out anchored to the block it annotates, and (2) give a spatial overview of where markers sit via a right-edge minimap. + +The issue body has two eras. The original "Implementation sketch" (a VSCode `markdown-it` plugin + `previewScripts`) is **stale** — its own "Update (post-#859 / PR #1045)" section says so. After #859/#945, the rendering surface is the React package **`packages/artifact-canvas/`**, mounted by VSCode as a read-only `CustomTextEditor` (`packages/vscode/src/markdown-preview/preview-provider.ts` + `webview/main.ts`). I verified this against the tree; the markdown-it/previewScripts files the sketch names do not exist. + +Two consequences of the `CustomTextEditor` reality that reshape the issue's acceptance criteria: + +1. **There is no separate "source editor" to jump into.** The canvas *is* the editor surface. The inline cards already sit beside the content they annotate, so the original "click call-out → open source file at the marker's line" loses its target. I reframe inline cards as **read-only display** (the AC's stated v1 intent is "read + click-to-jump only"); the click-to-jump affordance is preserved on the **minimap dots**, which smooth-scroll the canvas to the marker — an internal scroll, not a host round-trip. +2. **The concrete bug to fix is the overlap.** Today `ArtifactCanvas.tsx` renders the active block's markers in an *absolutely-positioned hover overlay* anchored at the block's `offsetTop` (`ArtifactCanvas.tsx:193-216`, `.codev-canvas-marker-list` in `default-theme.css:79-88`). The list paints over the first lines of the block. The issue's recommended fix (and "Additional acceptance criteria for the layout fix") is **inline-below**: cards rendered in document flow below the annotated block, pushing subsequent content down, tied to the gutter by a thin vertical rule, with no slot when a block has zero comments. + +### Current code map (verified) + +- `packages/artifact-canvas/src/components/ArtifactCanvas.tsx` — owns content + markers state, the post-render decoration effect (`:118-149`), the hover overlay (`:193-216`). +- `packages/artifact-canvas/src/renderer/renderer.ts` — strips full-line HTML comments, stamps `data-line` + `tabindex` on blocks. **No change needed.** +- `packages/artifact-canvas/src/styles/default-theme.css` — 8 `--codev-canvas-*` tokens, overlay + marker-list styles. +- `packages/artifact-canvas/src/overlays/CommentAffordance.tsx` — the `+` button. **No change needed.** +- `packages/vscode/src/markdown-preview/preview-template.ts:39-50` — maps the 8 tokens to `--vscode-*`. Reusing existing tokens means **no host change** for theming. +- `packages/vscode/src/markdown-preview/webview/main.ts` — mounts ``. No new props needed (minimap + cards are internal to the package). +- #861 floating TOC: **does not exist yet** (no grep hits) — "compose with TOC" is forward-looking; the minimap just must not hard-claim space a future TOC would want. + +## Proposed Change + +All work lands in the **`@cluesmith/codev-artifact-canvas` package** so every host (VSCode preview today; dashboard / mobile later) inherits it. No new public props, no new tokens, no host wiring changes. + +### 1. Inline-below comment cards (the layout fix + "inline REVIEW rendering") + +Replace the hover overlay's marker-list with an **always-visible card stack injected inline-below each annotated block**, in document flow. + +- Keep the existing post-render effect pattern (imperative DOM, consistent with `ArtifactCanvas.tsx:118-149`). For each `[data-line]` block that has markers, build a `
` containing one `
` per marker (author label + body), and insert it as the block's next sibling. Clean up previously-injected stacks at the top of the effect (so re-renders from watch/refreshKey don't duplicate). Injecting real DOM siblings means the stack participates in flow and **pushes subsequent content down** (no overlap), satisfying the layout AC. +- A thin vertical rule = a left border / accent on `.codev-canvas-marker-cards`, aligned into the existing left gutter (`padding-left: 1.9rem` on `.codev-artifact-canvas-body`), visually tying the stack to the `+` gutter. +- Zero-comment blocks get **no injected node** → no slot, no consumed vertical space (AC). +- Multiple markers on one line render in `markers` order, which is the codec's `parseReviewMarkers` order (creation order) (AC). +- The hover overlay keeps **only** the `+` `CommentAffordance` (add-comment intent unchanged). Remove the `.codev-canvas-marker-list` branch and `activeMarkers` plumbing from the overlay. +- Keep the existing `.codev-canvas-has-marker` left accent bar on the block as a cheap in-context "this block has feedback" cue (complementary, non-overlapping). +- Cards are display-only (no click handler) — see Understanding for why click-to-jump moved to the minimap. + +### 2. Right-edge marker minimap + +A new `MarkerMinimap` component, rendered by `ArtifactCanvas` as a child of `.codev-artifact-canvas` (which is already `position: relative`). + +- One dot per marker. Dot vertical position is proportional to the annotated block's offset within the rendered body (`block.offsetTop / body.scrollHeight`), mapped onto the minimap column height. Recompute via a layout effect on `[html, markers]` and on a debounced `resize` (window) — the issue's "updates on resize and rebuild". +- `position: fixed` column at the viewport right edge (matches the issue's drawing and the webview's full-window scroll model). Narrow strip so a future #861 TOC can sit beside it without fighting (documented, not enforced). +- **Hover dot** → native `title` = `@author: ` (AC tooltip). +- **Click dot** → `block.scrollIntoView({ behavior: 'smooth', block: 'center' })` (AC smooth-scroll). Dots are real `