Skip to content
| Marketplace
Sign in
Visual Studio Code>Visualization>Review Buddy MarkdownNew to Visual Studio Code? Get it now.
Review Buddy Markdown

Review Buddy Markdown

Review Buddy Markdown

|
20 installs
| (0) | Free
Review Markdown with anchored comments, version history, and agent handoffs.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Review Buddy

Review Buddy icon

Review Markdown where you read it. Keep feedback attached to its passage, discuss it in threads, compare document versions, and hand work to your own agent without copying line numbers.

Review Buddy 0.1.5 targets desktop VS Code 1.102.3 or newer. Manual review needs no AI account. The optional agent workflow needs an agent with local-file/terminal access and Node.js 20.19+. Direct handoff uses the user's existing Copilot CLI account; Copy prompt instead remains available. Review Buddy enables the CLI's extension surface for launched sessions so compatible older CLI versions do not depend on account-specific feature rollout. Direct handoff is verified with Copilot CLI 1.0.85 and newer; older detected versions fail immediately with Copy prompt guidance.

Right-click a saved .md file, choose Open With… → Review Buddy, select text, and press C to comment. The document-first review UI is enabled by default, with explicit Light/Dark themes. Reviews and version snapshots are stored locally in the chosen extension-host or workspace storage. See privacy and storage and support.

Why

While reading a doc you often want to leave feedback ("tighten this", "is this right?") and then have Copilot act on it. Here every comment carries its quoted text and heading path, so you can tell your agent to address the feedback through the review protocol, with its replies appearing back in the thread.

Features

  • Anchored conversations — document and comments scroll independently. A single Comments control opens the pane; when it is hidden, selecting a comment opens its thread in a bounded popup. The legacy layout remains available as an opt-out setting.
  • Select-to-comment — select rendered text and an add-comment glyph appears in the margin (never over the text); or press c. The composer opens in the margin, not over your content.
  • Colored highlights and notes — select saved Working-copy text and press h to apply the last-used highlight colour, or n to choose yellow, blue, green or rose and add an optional note and tags. Notes, colour and tags autosave; tags use one integrated chip field with file, workspace and global suggestions. New tags can remain file-only, become available in the workspace, or be shared globally. Scope appears only on the Create row: clicking its trailing File/Workspace/Global action changes the remembered default without creating the tag. Click a coloured passage directly to open its editor. Navigation from the local pane or workspace dashboard opens the editor only when that highlight has a note; highlight-only items just locate/flash. The textarea remains unfocused until you click inside it. Esc or an outside click closes the editor. The stable Navigate control opens a true Sections/Highlights tabbed pane. Highlight rows separate section, quote and note, show up to two tags plus +N, support current-document multi-tag filtering, and share an ellipsis action menu for editing, navigation and deletion. Sections, Highlights and Comments each expose a quiet search icon that expands into a compact current-document search field only when used. Focus mode hides Review Buddy’s persistent toolbar, panes, splitters and shortcut footer while retaining comments, highlights, notes, editing, Find and keyboard shortcuts through contextual UI. In normal and Focus modes, drag either document edge to adjust the 720–1400px reading width; the edge appears only on hover and a reset icon appears only after modification. Highlights reuse versioned anchoring and are intentionally separate from threaded comments and agent handoff.
  • Workspace annotation dashboard — run Review Buddy: Open Annotation Dashboard to see highlights and notes from the current workspace plus every open loose Markdown file in the current VS Code window. Search tags alongside note and quote text; combine type, colour, document and multi-tag filters. Manage tags separates workspace and global vocabularies, supports workspace-to-global promotion, and keeps removing a suggestion separate from deleting assignments. Switch explicitly from Current project to All projects to search the machine-local index of Review Buddy documents seen in other projects; Review Buddy never crawls the filesystem.
  • Annotation recovery — confidently projected edits show Updated text with original and current excerpts. Removed or ambiguous passages remain stored and appear as Text removed or Location unavailable in the Highlights pane and dashboard. Relink to text uses an explicit select-and-confirm flow that preserves the annotation ID, note, colour, original quote and audited location history. Selecting a dashboard row opens the exact document annotation. A machine-local metadata index keeps the view fast and rebuilds from authoritative review stores. Results are grouped under sticky, collapsible file headers with an Expand/Collapse all toggle.
  • Whole-document comments — press Shift+C or run Review Buddy: Comment on Document when feedback applies to the entire file. These threads are grouped above passage comments, carry their diff source context when relevant, and never pretend to have a text location.
  • Teams/Word-style cards — clearer avatars, author with date/time below, Markdown-rendered bodies with See more, threaded replies (including Copilot's), and inline Reply / Resolve / Edit / Delete (no native dialogs). Resolve/Reopen and full-thread controls sit in the card header. Expanded replies use horizontal separators and the same typography as the original comment.
  • Direct Copilot CLI hand-off — Send review queues the short review instruction directly in a Copilot CLI session without switching terminal apps. Review Buddy remembers the target per document. When no destination is remembered, Send review first asks for an existing session ID/prefix; submitting that prompt empty explicitly starts a new session in your chosen external terminal, while cancelling starts nothing. Active iTerm, Terminal, Windows Terminal, Linux-terminal or custom launcher sessions receive the prompt through an authenticated localhost bridge loaded inside Copilot—not by typing into terminal UI. Once/monitoring and Use a sub-agent remain independent; Use as my default remembers that behavior. Copy prompt instead remains an explicit fallback.
  • Agent reply notifications — every new external agent reply can create a VS Code toast and a persistent toolbar Replies entry beside Comments. The local inbox deduplicates preview/diff watchers, groups toast bursts per document, navigates to exact threads and retains at most 100 metadata-only entries for 30 days. Right-click an item to mark it read or unread. Configure reviewBuddy.notifications.agentReplies as always, whenHidden or off.
  • Versioned anchoring — immutable original selections plus conservative projections into later snapshots. Reliably linked passages have no status badge. The card keeps the original quote; Text changed reveals original/current wording when the passage changes. Unlocated passages have a plain-language explanation and Link to text, rather than implementation labels.
  • Inline block editing — hover or select a block and press e to edit it in place with a Markdown-native WYSIWYG editor. Convert blocks between Paragraph, H1-H6 and fenced Code block; toggle quotes, bulleted/numbered/task lists, indent/outdent, bold, italic, inline code, strikethrough and links; or use visible Undo/Redo. Markdown typing rules recognize heading, quote, list, task and fenced-code prefixes. Tables retain their contextual row/column/move tools. Cmd/Ctrl+Enter or click away to save, Esc to cancel, or use Save / Cancel in the toolbar. Edits go through VS Code undo/redo and Cmd+S; the editor closes only after the host acknowledges the edit. A rejected save leaves the draft editable with an inline explanation. The editor is lazy-loaded on first edit, so reading and commenting stay lightweight.
  • Whole-document rich editing — press Shift+E to edit the complete rendered document with the same Markdown-native toolbar. Saving compares top-level editor blocks and submits only changed, inserted, deleted or reordered source regions in one atomic WorkspaceEdit; untouched Markdown remains byte-for-byte unchanged and the operation is one normal VS Code Undo step. Frontmatter and raw HTML remain byte-exact protected source blocks inside the rich surface, so the formatting tools stay available for the rest of the document. Genuinely unmappable structures fail closed with the draft preserved instead of silently reserializing the file. Double-click only selects text; it never opens an editor.
  • Checklist editing — task items remain real checkboxes in the editor and after saving. Checked state, nested bullet markers, uppercase [X] markers, and inline formatting survive round trips; checkbox changes participate in editor undo/redo. Rendered preview checkboxes update their exact Markdown marker without rebuilding the document, including while the current file has unsaved changes when its source hash still matches. Intentionally escaped literal markers remain ordinary text.
  • Light / Dark themes — switch using the toolbar or reviewBuddy.theme. Changes apply live across preview, comments, editing, find, code, diagrams, and rendered diff without discarding reply drafts or committing an open block edit.
  • Find and safe Replace — Cmd/Ctrl+F opens a VS Code-style find bar with "X of Y", match-case and whole-word controls. Expand Replace, use Cmd+Option+F on macOS or Ctrl+H on Windows/Linux, then replace the current match or all matches atomically. Replacement is available only on a saved Working copy with no active edit or pending agent iteration. Review Buddy preserves surrounding Markdown when the rendered match maps unambiguously to one source span; formatting-spanning, generated or ambiguous matches stay Find-only. Replace all is one VS Code Undo step. Regex and multiline replacement are not supported.
  • Version history per comment — when a change is made for a comment, a version is recorded and shown on that card as Changes (N); clicking a change opens the rendered diff scrolled to it. Versions are stored as hash-verified keyframes and deltas in a lazily-read file next to your comment store. Storage cost depends on the document and the edits, not a fixed per-version size.
  • Rendered diff, side-by-side or inline — compare any two points: git refs (HEAD, Staged, Working Tree) and recorded versions, with an ADO-style Side by side / Inline toggle. The version picker includes Staged → Working copy, Committed (HEAD) → Working copy and Committed (HEAD) → Staged. Git comparisons refresh when the index or references change. Staged, committed and recorded document snapshots remain text-read-only, but their right-hand passages can receive version-aware comments and normal thread actions. Recorded origins use the saved version; HEAD and Staged origins use immutable local comparison snapshots and project into later working versions. Document editing and relinking remain working-copy-only.
  • Mermaid diagrams — ```mermaid blocks render as diagrams (lazy-loaded) with pan, zoom and fit controls. Select Pan before dragging a diagram; otherwise it keeps the normal pointer. Select text within a rendered diagram and use C, H or N to comment, highlight or add a note using the exact matching Mermaid source text. Only the selected words are painted. Press E over a diagram to edit only its Mermaid body; the fence is preserved.
  • Toggle preview ↔ source — Cmd+Alt+E (Ctrl+Alt+E on Windows/Linux).
  • Review navigation history — deliberate jumps from comments, links, Find, notifications and diff changes can be revisited with Option+←/→ on macOS or Alt+←/→ on Windows/Linux. Ordinary scrolling is not recorded.
  • Document navigation — the stable Navigate control opens a left pane with true Sections and Highlights tabs. Sections is a clean nested H1-H4 outline for jumping through the document; headings with descendants have persisted disclosure controls. Read checkboxes share one fixed left column and remain hidden until their row is hovered/focused or they are completed/partially completed. Partial parents use a persistent empty box rather than an indeterminate minus, and a parent checks itself automatically when every child branch is complete, while quiet badges show active comment counts. Parent badges aggregate descendant comments so collapsed branches still reveal outstanding review work; resolved comments are excluded. Progress/filter/bulk controls stay out of the way. Selecting a section places its heading at a comfortable responsive reading inset, highlights it with a text-only accent tint until the next non-scroll user action, and keeps the currently focused section selected and visible in the rail as the document scrolls. Highlights lists the current document's coloured annotations and notes. Comparisons place Navigate at the far left, keep read-state checkboxes editable as review metadata, and add independent Anchors and Highlights visibility controls. Their version labels move with the reduced document viewport when Navigate opens, and historical/Git highlights are projected onto the selected right-hand source. Compact headers retain primary actions and move secondary controls into one chevron menu. Pane visibility, width and active tab persist.

Usage

Make it the default .md editor so opening any Markdown file shows the commentable preview:

"workbench.editorAssociations": {
  "*.md": "reviewBuddy.preview"
}

Or open a single file without changing settings: right-click the file → Open With… → Review Buddy (or run Review Buddy: Open in Commentable Preview). To view it side-by-side with the source, open the source in a second editor group.

Upgrading an earlier local installation

Back up existing reviews, disable earlier local shivang.markdown-preview-comments or shivang.review-buddy installations, then reload after installing review-buddy-markdown.review-buddy-markdown. Existing global reviews remain at their original paths and are reused; workspace sidecars and document-version numbers do not change. Conflicting stores are reported without choosing or overwriting one.

Explicit reviewBuddy.* preferences take precedence; otherwise previously configured markdownComments.* values remain effective. Old commands and saved-version URI schemes remain available as compatibility aliases when the previous extension is absent. Old default-editor associations are updated without changing unrelated associations.

Adding & handing off comments

  1. Save the document, select rendered text → click the margin add-comment glyph (or press c) → write → Comment.
  2. Use each card to Reply / Resolve / Edit / Delete.
  3. Use Send review, or its monitoring variant. The prompt points to the comment store's extension-maintained reviewInstructions: document/tool paths, current-mode rules, command argument arrays and the completion-request shape. The agent discovers current feedback at run time and processes one thread before starting the next. It must not append replies directly.

Monitoring is an explicit choice for that agent session, not a persistent flag in the JSON. For direct Send review handoffs, the session bridge—not an agent-authored shell script—watches the exact review store for actionable feedback and queues a monitor wake in the parent session. A delegated handoff reuses the same idle sub-agent through the parent on every wake. Copied/manual prompts retain the supported watcher or bounded-wait fallback. Both paths ignore the agent's own writes and require explicit reporting when monitoring cannot continue. While active, the handoff control reads Monitoring and its menu provides status plus Stop monitoring; the inactivity countdown remains internal rather than adding a low-value timer to the UI. Monitoring stops manually, when Once is sent, when the destination changes or clears, when the Copilot session closes, or after one hour without actionable user feedback. Expiry clears the status and creates one VS Code notification.

Bridge monitoring is intentionally lightweight: one operating-system file-watch handle, one timer and a small state record per monitored document. Idle CPU usage is effectively zero; the store is read only after a file-change event and bursts are debounced. A tiny localhost status check runs every 30 seconds only while a Review Buddy view is visible.

The handoff dropdown exposes two explicit axes: Review type (Once or Keep monitoring) and Run with (Main agent or Sub-agent), followed by one Send review action. Hover help explains each choice. Persistent default, destination and launch-terminal choices use the same model in a separate Handoff settings dialog.

On first use, Review Buddy asks before installing its user-scoped Copilot CLI bridge under ~/.copilot/extensions/review-buddy (or the configured reviewBuddy.copilot.home). Each CLI session creates an ephemeral localhost endpoint with a private random token stored in a user-readable registry file. The bridge enqueues messages and returns an acknowledgement; it does not emulate terminal input. Review Buddy-launched sessions start with Copilot --allow-all, and the bridge switches a selected live session to allow-all before enqueueing the review so an automated run does not stop at tool, path or URL prompts. Managed enterprise policy may reject that transition; when it does, Review Buddy reports the failure and does not claim delivery. Existing sessions opened before installation or an update must be restarted once. If a chosen terminal cannot be launched, Review Buddy copies the exact launch command and keeps the review prompt pending instead of claiming it was sent.

Reviewing highlights across a workspace

Run Review Buddy: Open Annotation Dashboard. The dashboard includes highlights and notes only, never threaded comments, and does not mix unrelated machine-wide review data. Its local index stores document path/name, annotation ID, colour, tags, section, timestamps and bounded quote/note excerpts. Review stores remain authoritative; opening the dashboard rebuilds its current-window scope. File groups can be collapsed individually or together; the document dropdown remains available for direct filtering. Tag selection is OR within tags and AND with search, type, colour and document. Manage tags reports scope-aware annotation/document usage. Workspace changes affect that workspace; global changes affect indexed documents everywhere. Dashboard results themselves remain limited to the current project by default. All projects searches the persisted machine-local annotation index and labels results with their project; it includes reviewed documents already known to Review Buddy rather than scanning every repository.

Workspace scope follows the stable project boundary: an explicit multi-root workspace first, otherwise the nearest Git repository, otherwise the opened non-home folder. Opening a repository subfolder therefore retains the repository vocabulary, while opening the home directory does not combine unrelated repositories into one tag scope.

Comment locations and visible changes

The first saved baseline is v1. Saving different Markdown creates another version. A completed Copilot iteration handles one thread and creates one version only when the saved document changed; intermediate saves between begin and complete do not create extra versions. Answer-only replies retain the existing version and have no change chip. They use a durable completion receipt, so interrupted delivery and identical retries do not duplicate replies. Numbering is per file, not per workspace or Git branch. Unsaved edits are projected for display but do not become snapshots; save before adding comments or starting an agent iteration. Copying the generic prompt is allowed while editing. Internal anchor status names and snapshot numbers are not shown as routine card badges. Location confidence is separate from whether the conversation is open/resolved or whether Copilot has addressed its feedback.

The visible version UI is the comment-attributed change history: expand Changes (N) on a card, click a change, and compare recorded versions through the rendered From/To view. These same version records carry the rendered projections and anchor metadata used internally, so there is one counter and one timeline rather than a second hidden snapshot history. New Copilot versions are attributed explicitly to their one iteration thread; arbitrary manual edits are no longer assigned to comments from timing or proximity guesses. Change rows show the version and label. Exact time and older inferred/shared attribution remain available in hover and keyboard-accessible descriptions, without the prominent "likely" / "also for" badges. Changes starts collapsed in pane, popup and full-thread views, while retaining deliberate expansion choices. Diff revision labels occupy a separate, clipped row instead of overlapping the controls. The controls wrap in compact windows and version menus stay inside the viewport. Diff changes use red/green fills and word highlights, not vertical change rails or extra rail padding. Native Markdown blockquote styling is retained and explicitly themed in all three document surfaces.

Diff and review actions share one full-width toolbar: comparison/navigation controls on the left, review actions on the right. Comment navigation and the resolved filter live with the comments pane. Version labels are compact; timestamps remain available on hover. Opening a change selects its predecessor/result pair in both the content and picker instead of displaying "All Changes."

Original/current quote excerpts are limited to three lines each and use the full card width, including hidden-pane popups. Open full comparison uses the recorded original and displayed/current version; unavailable original snapshots are not fabricated. The original quote remains available in the full thread.

The bottom hint strip starts with a readable All shortcuts keycap button, followed by only the primary contextual C, H and E actions. The modal includes document comments, notes, thread navigation, Find/Replace, review navigation and F6/Shift+F6 movement between toolbar, Navigate, document, comments and shortcut help. Navigate tabs, section trees, comment/notification lists and dashboard groups support the expected arrow, Home/End, Enter, Space and Escape behavior. Typing fields retain normal text entry and Ctrl/Cmd+F remains Find. Web links use the system opener; local Markdown references open in the commentable preview, and heading references navigate to stable, duplicate-safe heading IDs. Executable link schemes such as javascript: and command: are not supported.

Each anchor retains its original version, selected quote, and half-open UTF-16 range in the rendered-text projection. Its current range, current quote, and status are calculated across versions. Every version reconstructs both raw Markdown and the exact canonical rendered projection; rendered offsets are deliberately not presented as source line/column coordinates. A thread's open/resolved state is independent of its anchor status. Older stores can import uniquely matching quotes into v1; that is an imported baseline, not a reconstruction of their unavailable original document. Unidentifiable legacy locations remain unverified. Outdated/ambiguous locations never fall back to fuzzy matching in the versioned preview. Large diffs are partitioned at unique, order-stable lines and words before bounded character alignment, so an unrelated rewrite does not invalidate every comment. Duplicate landmarks are not tie-broken arbitrarily. A uniquely matched quote with a certified interior also keeps repeated boundary punctuation from absorbing an appended sentence.

Repairing a comment's location

If the extension cannot confidently locate a passage, use Link to text, select its intended passage in the saved current document, then confirm. Change linked text in the comment's actions menu also allows correcting an existing link. Escape/Cancel abandons the selection; document editing is suspended while choosing the new location.

Relinking changes attachment metadata only: it preserves the original quote, conversation, timestamps and first verified origin, records an audit entry, and does not create a document version. A previously unverified comment does not acquire fabricated original context. A changed document/conversation, stale selection or pending agent iteration rejects the operation explicitly. An interrupted delivery can be retried safely.

The repair is new user feedback for pending; the next Copilot response records which location revision it addressed, preventing repeated processing of the same repair. The begin response includes the verified current location, so an agent need not guess from an old quote.

Saved-version comparisons use attachment locations for that revision rather than projecting the latest missing location backwards. Older comparisons remain read-only and offer Open current document when a location needs attention. A comment created later is identified as such. New history records maintain compact location deltas; pruning carries them forward. Older histories are reconstructed conservatively, and missing intermediate evidence never authorizes a fuzzy guess. Intentional deletion does not force relinking: the conversation can still be discussed or resolved.

The extension does not launch an AI agent by itself. The copied prompt asks Copilot to use the bundled dist/iteration.js tool (Node.js required):

node <iteration.js> pending --document <file> --store <comments.json>
node <iteration.js> begin --document <file> --store <comments.json> --expected-hash <fresh-sha256> --threads <one-id> --intent-policy document
node <iteration.js> hash --document <file>
node <iteration.js> complete --document <file> --store <comments.json> --request <request.json>

The completion request contains iterationId, the final saved file's expectedHash, and replies: [{ "commentId": "...", "body": "..." }], containing exactly the one iteration thread. That thread gets one reply with iterationId, baseVersion, version, and a UTC timestamp; parent updatedAt is unchanged. An identical completion retry does not duplicate a version or reply. Review iterations honor the stored document Agent/Ask mode, regardless of old per-thread intent; classic handoffs use --intent-policy per-comment. A mode change during an iteration rejects completion. After completion, discover pending feedback and the current hash again before starting another thread. pending is read-only and excludes resolved or already-answered threads unless new user feedback has arrived.

The tool persists snapshots even with the preview or VS Code closed. Without this protocol, external replies are displayed but do not create duplicate versions or infer comment ownership: missed intermediate file states cannot be recovered. The extension cannot attribute arbitrary disk writes to Copilot; begin/complete define that boundary explicitly.

Stale hashes, changed/resolved/deleted selected threads, overlapping iterations, or conflicting retries fail explicitly and leave data intact. Cancel Pending Copilot Iteration (also available in the preview) abandons a pending iteration and checkpoints any saved partial edits. It does not undo edits. Re-read the document and pending feedback after cancellation; the generic prompt itself is reusable. If a new comment is rejected because its selection is stale or storage is busy, the composer keeps the draft; closing it and selecting text again restores that draft rather than losing it.

Storage

By default comments are stored machine-locally in the extension's storage (keyed by the file's path), keeping your workspace clean — they are personal to your machine and not shared via git. Prefer to share them with a repo? Set the location to workspace and they live in a sidecar file next to the document (<file>.md.comments.json). Comments and history follow explicit VS Code file renames. External filesystem renames cannot be identified reliably; move both stores deliberately instead of relying on same-content guesses. Complete/cancel an iteration before renaming its file because copied prompts contain its original absolute paths.

One unified history file lives beside the comment store as .versions.json (schema v4). It stores periodic keyframes plus compact line deltas for both raw Markdown and canonical rendered projections, with SHA-256 verification for each reconstructed value. The same records contain anchor metadata, attribution, guarded iteration provenance, reply-only completion receipts, historical location deltas and explicit attachment audit/delivery records. Existing v1/v2/v3 histories remain readable; the next mutation writes v4 without renumbering or discarding old snapshots. Back up stores before upgrading; older extension builds must not write the upgraded history. Comment stores remain schema v3, with additive reviewInstructions and locationRevision metadata; replies may record the location revision they addressed.

Anchor-origin, completion-receipt and pending-iteration base versions are pinned and never pruned. Other old versions are retained up to the 500-version / 2 MiB navigation caps; pruning rebases surviving raw and projection chains into keyframes. A single document or projection above 64 MiB fails explicitly.

History writes use unique temporary files and an exclusive .versions.json.lock. Every mutation re-reads the latest file inside the lock so editor and diff sessions cannot overwrite each other. Interrupted reply delivery is journaled and retried on the next checkpoint/completion. Existing .versions.json diff history and <comments.json>.history.json anchor history are merged transactionally on first use; the old anchor file is renamed .migrated only after the unified file is durable.

The comment store is a small JSON document (schema v3):

{
  "version": 3,
  "document": "design-notes.md",
  "comments": [
    {
      "id": "c_ab12cd",
      "quote": "under two minutes",
      "prefix": "aha\" moment in ",
      "suffix": ".",
      "headingPath": ["Overview"],
      "author": "you",
      "status": "open",
      "createdAt": "2026-07-10T00:00:00.000Z",
      "updatedAt": "2026-07-10T00:00:00.000Z",
      "replies": [
        { "author": "you", "body": "Can we make this the headline metric?", "createdAt": "2026-07-10T00:00:00.000Z" },
        { "author": "copilot", "body": "Yes — added.", "createdAt": "2026-07-10T00:06:00.000Z" }
      ]
    }
  ]
}

The example omits generated reviewInstructions for brevity. In v3 the root message is replies[0]; legacy v1/v2 root bodies are still read correctly. Existing copiedAt and attribution metadata are preserved, but no longer used to present a misleading "Sent" state.

Settings

Setting Default Description
reviewBuddy.author automatic Author name stamped on new comments and replies. Review Buddy asks once on the first attributed action and saves the answer as a user setting. When blank, it uses Git user.name, the signed-in GitHub account, or You.
reviewBuddy.storage.location global Where comments are stored: global (machine-local, clean workspace) or workspace (sidecar next to the file, shareable via git).
reviewBuddy.showResolved false Show resolved comments in the preview.
reviewBuddy.theme light Explicit light or dark preview theme, independent of the editor theme. Applies live in classic and review UI.
reviewBuddy.experimental.reviewUi false Enable the document-first review UI. Save/cancel in-place document edits and reload the window after changing this window-scoped setting.

Experimental document-first review UI

The document-first design is enabled by default. Its compatibility setting is:

"reviewBuddy.experimental.reviewUi": true

It provides independently scrolling document/comments regions, self-contained thread cards with per-thread reply boxes, and one document-wide Agent / Ask selector (Agent by default). Clicking a card locates its passage without moving the comments pane. The two rendered-diff document columns remain linked. Light remains the default even in a dark editor theme; choosing Dark is explicit.

Comment navigation and Find reveal the actual quoted/matched text, including passages near the end of long paragraphs and inside horizontally scrolling tables. Diff scroll position survives realignment and working-document refreshes, including large inserted/deleted regions. With Comments hidden, clicking a highlight opens a viewport-bounded thread popup. It shifts upward near the bottom edge; long threads scroll internally so replies and actions stay reachable. Thread popups and new-comment composers adapt to window resizing without clearing drafts. The popup uses the same card renderer as the pane and includes the same Resolve and full-thread controls. Replies start collapsed in both the pane and hidden-pane popup, with an expandable reply count; your explicit per-thread expansion choice is remembered. The popup keeps the original comment fully readable, and Open in full view still displays all replies. Comments is the rightmost toolbar control. Bulk selection has been removed; individual comment/reply deletion remains available. Quoted context and actions share one compact header rather than separate rows. Resolve's icon and label turn green on hover without a filled background; the Agent/Ask menu matches its button's width.

The Agent/Ask dropdown is an accessible in-preview menu with keyboard navigation, a selected-item indicator and a keyboard-only focus ring, rather than a browser/OS select popup.

Preview colour sources

Light and Dark are based on VS Code's built-in Light Modern / Dark Modern colour pairs, independent of the surrounding editor theme. Values were verified against theme-defaults/themes/light_modern.json and dark_modern.json, and the native markdown-language-features/media/markdown.css and highlight.css. Fenced syntax uses the installed Visual Studio highlight styles with the native preview's token overrides.

Surface Light Dark
Document background / foreground #ffffff / #3b3b3b #1f1f1f / #cccccc
Inline code background / foreground #0000001f over white / #3b3b3b #3c3c3c / #d0d0d0
Code block background #f8f8f8 #2b2b2b
Links #005fb8 #4daafc

Both foreground and background are explicit. This prevents VS Code's injected opposite-theme inline code colour from leaking onto the preview's selected theme.

Document mode and drafts

In-place editing validates complete Markdown block boundaries before applying or relocating an edit. It cannot retarget a stale paragraph onto matching text inside a heading, fence, or table fragment. Wide-table editing preserves GFM column alignment, reveals the selected cell, and provides mouse- and keyboard-operable Rows/Columns/Move controls. Diff document editing remains disabled; commenting and replies remain available.

Document mode is saved as optional documentIntent metadata in the comment store. The new UI's copy prompt uses it for every selected thread, without rewriting old per-comment intents or timestamps. Turning the feature off preserves the classic per-comment behavior. Invalid stored mode metadata requires an explicit Agent/Ask choice before copying; it never silently becomes Agent. Changing the selector does not run an agent or copy anything automatically.

Unsent drafts and selected-thread state can follow the document between open review views. They use the VS Code webview-state/host bridge, not the Copilot comment store. Focus, modal state, and viewport layout remain local to each view. Older persisted bulk-selection fields are discarded without clearing drafts or expansion state.

Development

Before changing UI, read the UI instructions. They define the shared design language, component ownership, interaction rules and visual checks for all contributors, including parallel feature branches.

npm install
npm run build          # bundle extension + webview (esbuild); copies codicons + mermaid
npm run test:unit      # Node/jsdom unit tests (pure logic + DOM logic)
npm run test:history   # focused history, anchoring, persistence, and review UI coverage
npm run test:webview   # builds, then runs the real-Chromium e2e harnesses
npm test               # isolated native VS Code UI + real-store/edit/undo integration tests

# package + install into VS Code (build runs automatically via vscode:prepublish):
rm -f *.vsix && npx --yes @vscode/vsce package --allow-missing-repository --skip-license
code --install-extension review-buddy-markdown-0.1.5.vsix --force   # then reload the window

Press F5 in VS Code to launch an Extension Development Host and try it live. Set VSCODE_EXECUTABLE_PATH to the installed VS Code Insiders executable to run integration tests there rather than downloading stable VS Code. VSCODE_TEST_USER_DATA selects an isolated test profile.

On managed machines where package-manager/registry access is prohibited, use existing dependencies and direct binaries (node esbuild.js, ./node_modules/.bin/tsc) rather than the installer commands. The review launchers below never install packages or download an editor.

Architecture

Two layers; only the extension host touches disk, the webview talks via postMessage.

  • Host: src/extension.ts (activate/commands), src/editorProvider.ts (CustomTextEditorProvider — the only surface, opens .md as the preview), src/webviewHost.ts (CommentSession), src/webviewHtml.ts (one production preview/diff HTML builder), src/store/ (CommentStore abstraction: fileStore.ts, factory.ts, keying.ts), src/sidecar.ts (store file I/O + migration), src/render.ts (markdown-it → HTML, source-line mapping, mermaid emit), src/prompt.ts (Copilot prompt + delta), src/documentMode.ts (mode compatibility), src/reviewState.ts (acknowledged shared draft patches), src/anchor.ts (text-quote anchoring + bounded fuzzy), src/blockSource.ts (block↔line mapping + edit plan), src/find/search.ts, src/types.ts.
  • History: src/history/ provides unified raw/rendered keyframe-delta history, anchor mapping, attribution, guarded iteration provenance, and the independent iteration CLI. src/versionView.ts exposes read-only virtual documents and native version comparison. The extension API exposes openVersionPair and showOriginalVersion for consumers using the same history model.
  • Webview: src/webview/ — main.ts (orchestrator), layout.ts (gutter collision + responsive mode), gutter.ts (margin cards), card.ts (card component), commentBody.ts (safe Markdown render), sidebar.ts (panel), dom.ts (text-map + CSS Highlight-API paint + hit-testing), find.ts, blockEdit.ts + pm*.ts (ProseMirror block editor, lazy), tokens.css + styles.css. The default review UI uses reviewLayout.ts, reviewCard.ts, reviewUi.ts and the gated reviewTokens.css / reviewBase.css / review.css sheets in that same bundle.
  • Build: esbuild.js → dist/extension.js, dist/webview.js, dist/webview.css, dist/blockeditor.js (lazy), dist/iteration.js (standalone Node CLI), and copies dist/mermaid.min.js (lazy) + dist/codicon.{css,ttf}.

Testing

  • Unit (test/*.test.ts, Node --test + jsdom): pure logic and DOM logic.
  • Browser e2e (scripts/*-e2e.cjs, playwright-core via installed Edge/Chrome): loads the actual bundled dist/webview.js and drives real gestures under the production CSP. These exist because VS Code webviews are opaque to the OS accessibility tree — UI automation can't drag-select or double-click inside them, so webview interactions are verified here.
  • Integration (@vscode/test-electron): an isolated editor profile exercises production UI code inside a real webview, real temporary comment/history files, live file updates, document mode, draft sharing, in-place edits, WorkspaceEdit/undo/redo, closed-preview iteration completion, and native immutable version documents/diff tabs. A test-only driver is compiled to a temporary location; no test command/eval API is shipped in the extension.

The large fixture is a synthetic README of approximately 330 KB and 11,000 lines. The history suite covers large rewrites, insertion boundaries, deletion, duplicate blocks, heading changes, formatting, code fences, Unicode, multi-block selections, and restoring deleted text. The browser suites use an installed browser (Edge on Windows); MPC_CHROMIUM_EXECUTABLE overrides discovery. Browsers are closed on success and failure rather than left running after a failed assertion.

scripts/copilot-iteration-scenario.cjs provides an opt-in real Copilot trial. Run prepare with a new absolute artifact directory, submit 01-ask.prompt.txt to Copilot, then run after-ask, submit 02-update.prompt.txt, run after-update, submit 03-followup.prompt.txt, and run verify. It checks exact file changes, unchanged parent timestamps, preserved original anchors, and one version per iteration. Ordinary tests never invoke a paid model automatically.

For the live external-iteration integration case, set MPC_LIVE_REVIEW_DIR to a trial awaiting its third prompt before running npm test. The isolated preview writes live-ready.json; run the third Copilot prompt only after that signal. The test checks the pending indicator and the new reply/version appearing without a manual refresh. MPC_CAPTURE_INSIDE=1 enables a local debugging connection for scripts/capture-insiders.cjs; the capture attaches to the existing isolated window, not another browser window. The test runner closes its window afterward.

Design docs and decisions live in design/ (see design/decisions-log.md). Reinstalling a VSIX does not update already-open windows — reload the window to pick up a new build.

UI design workbench

Run node scripts/review-workbench.cjs and open the printed loopback URL. It builds and serves the same production UI assets and HTML as VS Code, with an isolated memory-backed host. There are no alternate card/layout implementations or prototype-only CSS overrides. UI refinements happen once. The workbench does not modify your real documents, comments, or installed extension.

Run node scripts/review-devhost.cjs to open an isolated real VS Code development host with the feature enabled and the same sample document/comments. It uses a cached editor (or VSCODE_EXECUTABLE_PATH), never downloads one, and preserves the sample/profile under .vscode-test/review-devhost/. Your normal VS Code profile and installed extension are unchanged. This isolated profile does not copy your existing global comment stores.

For native integration tests, set VSCODE_EXECUTABLE_PATH to an existing VS Code executable when downloads are not permitted, then run node out/test/runTest.js after compiling/building. This runner creates and removes its own temporary profile. Set MPC_NATIVE_SHOTS to an output directory to also capture the actual isolated VS Code window's light preview/diff and light/dark editor states. This optional test-only capture enables a loopback debugging port for that disposable profile; neither the production extension nor the normal development launcher exposes a debugging endpoint.

See the design brief and preserved-feature inventory and integration contract for scope and verification.

License

MIT — see LICENSE.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft