You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Codev specs and plans routinely cross 200–400 lines. The built-in markdown preview ships with no persistent navigation chrome — the only ways to move between sections are scrolling, opening the VS Code Outline panel (separate sidebar, no scroll-sync with the preview), or hand-rolling anchor links via URL. For a long spec being reviewed, this is a real friction tax on the read-pass.
The preview is the natural reading surface for long Codev artifacts (see #859 for the add-comment companion). This issue gives it a navigation layer designed for the long-doc case.
Proposal — three preview-pane navigation affordances, one bundle
These three features ship together because they share infrastructure: DOM heading scanning, previewScripts keyboard/click wiring, previewStyles overlay positioning, and localStorage UI-state persistence. Splitting them into three issues would duplicate the same plumbing three times.
1. Floating TOC sidebar
A persistent panel on the right edge of the preview listing every <h1>–<h3> heading in the current doc.
Renders:previewScripts scans rendered DOM for <h1>–<h3>, builds a tree (or flat list with indentation by depth), renders into a position: fixed panel
Click entry → smooth-scrolls preview to that heading's anchor
Scroll-spy: highlights the entry corresponding to the section currently in view (uses IntersectionObserver on the headings)
Collapsible per H1: click an H1 row to expand/collapse its children; state persists per-file in localStorage
Floating toggle icon (e.g. ≡) in the top-right corner of the preview to hide/show the whole TOC; the rendered content widens to fill when TOC is hidden
A centered fuzzy-search overlay that lets the user jump to any heading without leaving the keyboard.
Trigger: configurable keybind, default / (mirrors GitHub's "search this page" + vim's search) when the preview has focus. Alternative Cmd+K G if / conflicts
Always-visible context; scroll-spy shows where you are
Takes screen real-estate
Quick-jump overlay
Keyboard-only, fast for power users
Hidden until invoked
Per-heading toolbar
Discoverable, in-context (right next to where you're reading)
Per-section only, no whole-doc map
Different users converge on different patterns (mouse-driven prefer the TOC; keyboard-driven prefer the overlay; everyone uses the per-heading actions when they happen to hover). Shipping all three covers the surface area.
Path eligibility
Same gating as #859 and #860: only applies to .md files in codev/(plans|specs|reviews)/. The TOC, overlay, and toolbar are all no-ops on other markdown files (which already have the standard VS Code preview behavior).
Both contributed via contributes.markdown.previewScripts and contributes.markdown.previewStyles in package.json
Path gating in webview script
The preview script needs to know the source document URI to gate. VS Code's markdown preview passes this via meta tags in the rendered HTML (<meta name="vscode-markdown-preview-source" content="<uri>">). Script reads this on load; bails (no-op) if the URI doesn't match the eligibility regex.
State persistence
localStorage keys, scoped per-file:
codev.toc.visible.<uri> — boolean, default true
codev.toc.collapsed.<uri> — array of collapsed H1 anchor IDs
codev.section.collapsed.<uri> — array of collapsed heading anchor IDs (from the toolbar collapse action)
No markdownItPlugins for this issue
All three features operate on the rendered DOM (post-markdown-it). No AST transformation needed. This keeps the contribution surface to just previewScripts + previewStyles.
Acceptance criteria
Floating TOC
Persistent panel on the right edge of the preview; shows every <h1>–<h3> heading
Click any entry → smooth-scrolls preview to that heading
Scroll-spy highlights the entry corresponding to the section currently visible
Collapsible per H1; collapse state persists per-file across reloads via localStorage
Floating toggle icon (e.g. ≡) hides/shows the whole TOC; rendered content reflows to fill
Visible only on .md files in codev/(plans|specs|reviews)/
Quick-jump overlay
Keybind (default /) opens a centered overlay listing all headings; configurable via package.json keybinding contribution
Type to fuzzy-filter; Arrow keys to move selection; Enter to jump; Esc to dismiss
Breadcrumb path shown for the selected row
Visible only on the eligible-path set
Per-heading mini-toolbar
On hover over any heading, a floating toolbar appears to the right of it
Buttons: prev section / next section / copy link / collapse
copy link writes <basename>.md#<anchor> to the clipboard
collapse toggles visibility of everything until the next same-level heading; state persists per-file
Reading progress bar / AC progress badge / frontmatter status badges — Document-state surfaces; separate themed filing
Outline panel enrichment (showing REVIEW markers as outline children) — different VS Code API entry point (DocumentSymbolProvider, not preview-side); separate filing if/when desired
Mobile / touch support — hover-triggered affordances assume a pointing device
Customizable TOC styling — fixed visual; no user settings in v1
For long Codev artifacts — which is the typical case — navigation friction is the read-pass friction. Today's preview is "scroll a big document"; with this layer it becomes "navigate a structured document." The three surfaces cover keyboard-driven, mouse-driven, and discovery-driven workflows simultaneously. Shipping all three as one PR is genuinely cheaper than splitting them because of the shared script/style infrastructure.
Problem
Codev specs and plans routinely cross 200–400 lines. The built-in markdown preview ships with no persistent navigation chrome — the only ways to move between sections are scrolling, opening the VS Code Outline panel (separate sidebar, no scroll-sync with the preview), or hand-rolling anchor links via URL. For a long spec being reviewed, this is a real friction tax on the read-pass.
The preview is the natural reading surface for long Codev artifacts (see #859 for the add-comment companion). This issue gives it a navigation layer designed for the long-doc case.
Proposal — three preview-pane navigation affordances, one bundle
These three features ship together because they share infrastructure: DOM heading scanning,
previewScriptskeyboard/click wiring,previewStylesoverlay positioning, andlocalStorageUI-state persistence. Splitting them into three issues would duplicate the same plumbing three times.1. Floating TOC sidebar
A persistent panel on the right edge of the preview listing every
<h1>–<h3>heading in the current doc.previewScriptsscans rendered DOM for<h1>–<h3>, builds a tree (or flat list with indentation by depth), renders into aposition: fixedpanelIntersectionObserveron the headings)H1: click anH1row to expand/collapse its children; state persists per-file inlocalStorage≡) in the top-right corner of the preview to hide/show the whole TOC; the rendered content widens to fill when TOC is hiddenpreviewStylesuses VS Code theme variables (--vscode-sideBar-background,--vscode-foreground, etc.); ~200px wide; subtle border-left2. Quick-jump overlay (keyboard-driven)
A centered fuzzy-search overlay that lets the user jump to any heading without leaving the keyboard.
/(mirrors GitHub's "search this page" + vim's search) when the preview has focus. AlternativeCmd+K Gif/conflictspreviewScriptsinjects DOM,previewStylespositions and themes)↑/↓to move selection; Enter to jump; Esc to dismissAcceptance criteria > 4. Out of scope)3. Per-heading floating mini-toolbar
A small overlay that appears on hover over any heading element, providing inline navigation actions.
<h1>–<h6>; toolbar fades in to the right of the heading↑ prev section— scrolls to the previous same-level heading↓ next section— scrolls to the next same-level heading🔗 copy link— copies<file.md>#<heading-anchor>to clipboard▾ collapse— toggles collapse of everything until the next same-level heading (uses CSS to hide siblings; state inlocalStorage)+add-comment affordance (different hover target — heading vs paragraph)Why all three together
Different users converge on different patterns (mouse-driven prefer the TOC; keyboard-driven prefer the overlay; everyone uses the per-heading actions when they happen to hover). Shipping all three covers the surface area.
Path eligibility
Same gating as #859 and #860: only applies to
.mdfiles incodev/(plans|specs|reviews)/. The TOC, overlay, and toolbar are all no-ops on other markdown files (which already have the standard VS Code preview behavior).Implementation sketch
Files
packages/vscode/src/markdown-preview/navigation.js—previewScriptsentry point; orchestrates DOM scanning, TOC rendering, overlay, per-heading toolbarpackages/vscode/src/markdown-preview/navigation.css—previewStyles; positioning + theme variablescontributes.markdown.previewScriptsandcontributes.markdown.previewStylesinpackage.jsonPath gating in webview script
The preview script needs to know the source document URI to gate. VS Code's markdown preview passes this via
metatags in the rendered HTML (<meta name="vscode-markdown-preview-source" content="<uri>">). Script reads this on load; bails (no-op) if the URI doesn't match the eligibility regex.State persistence
localStoragekeys, scoped per-file:codev.toc.visible.<uri>— boolean, defaulttruecodev.toc.collapsed.<uri>— array of collapsedH1anchor IDscodev.section.collapsed.<uri>— array of collapsed heading anchor IDs (from the toolbar collapse action)No
markdownItPluginsfor this issueAll three features operate on the rendered DOM (post-markdown-it). No AST transformation needed. This keeps the contribution surface to just
previewScripts+previewStyles.Acceptance criteria
Floating TOC
<h1>–<h3>headingH1; collapse state persists per-file across reloads vialocalStorage≡) hides/shows the whole TOC; rendered content reflows to fill.mdfiles incodev/(plans|specs|reviews)/Quick-jump overlay
/) opens a centered overlay listing all headings; configurable viapackage.jsonkeybinding contributionPer-heading mini-toolbar
copy linkwrites<basename>.md#<anchor>to the clipboardcollapsetoggles visibility of everything until the next same-level heading; state persists per-file+add-comment affordance (different hover target — heading element vs paragraph element)General
.mdfilesOut of scope (v1)
DocumentSymbolProvider, not preview-side); separate filing if/when desiredRelated
previewScripts/previewStylesinfrastructure. Same eligibility regex, same DOM-scanning pattern. Land vscode: add review comments from the markdown preview pane (hover-+ per block, no editor mode-switch) #859 first or together — both depend on the samepackage.jsoncontribution-point bootstrappingWhy this is high leverage
For long Codev artifacts — which is the typical case — navigation friction is the read-pass friction. Today's preview is "scroll a big document"; with this layer it becomes "navigate a structured document." The three surfaces cover keyboard-driven, mouse-driven, and discovery-driven workflows simultaneously. Shipping all three as one PR is genuinely cheaper than splitting them because of the shared script/style infrastructure.