0012. Help renders the guide through VS Code’s markdown.api.render

Status: Accepted (2026-09-30), from the first Phase 0 check of the refactor plan (§2.7, §8.4).

Context

Help shows the pages of docs/guide/ inside its panel. Today guide.ts renders them with markdown-it, rewrites their links and images for the panel, and passes the result through sanitize-html. Those two packages and the 21 they pull in are inlined into dist/extension.js and run in the extension host. The guide is Deckard’s own content, shipped in the VSIX, so the sanitizer guards nothing there.

VS Code’s built-in Markdown extension exposes a command, markdown.api.render, that turns a Markdown string into HTML with the engine every preview uses. The plan chose it for Help, pending a check that it is reachable from the extension host and renders the guide acceptably. The alternative was rendering the guide at build time.

The check

A throwaway extension ran inside VS Code 1.139.1 on macOS (Electron 43.6.0, Node 24.20.0), launched by @vscode/test-electron once with --disable-extensions, as the test runner launches it, and once without. For each of the 17 pages in docs/guide/ it called markdown.api.render and Deckard’s own renderGuidePage, then compared the two.

Question Answer
Does the command exist in the extension host? Yes, with or without --disable-extensions, which leaves built-in extensions running.
Is it listed by vscode.commands.getCommands()? No. It is an internal command the Markdown extension registers without contributing it.
Does it activate the Markdown extension? Yes. The first call took about 500 ms while the extension activated; each page after that took 1 to 10 ms.
Is the visible text the same? Yes, on all 17 pages, once tags are removed and whitespace is collapsed.
Are the heading ids the same? Yes, on all 17 pages. Both follow GitHub’s slugs, so links written for GitHub still land.
Is the raw HTML in the pages kept? Yes. The themes page’s screenshot table renders with the same nine images.

The output differs from Deckard’s in ways the panel would have to handle:

Decision

Help renders the guide through markdown.api.render in Phase 6, as planned. The check passed: the command is reachable, and the guide reads the same.

Consequences

Alternatives considered

How to repeat the check

The probe is a package.json with only an engines field as the extension, and a tests module whose run() calls vscode.commands.executeCommand('markdown.api.render', source) for each guide page, requires out/ui/webview/guide.js for renderGuidePage, and writes both outputs to disk. It runs with runTests({ version, extensionDevelopmentPath, extensionTestsPath, launchArgs: ['--disable-extensions'] }). It was not run on VS Code 1.134, Deckard’s minimum, because the machine had no disk space for a second download. The command dates from well before 1.134, but Phase 6’s host test should run on the minimum version too.