Scripting a VS Code extension headlessly: code-server + headless Chrome over CDP, with isolated dirs
To record or time a VS Code webview extension (here a waveform viewer from Open VSX) with no window on screen: run a pinned code-server release on the remote host and drive it from headless Chrome over CDP.
Setup that worked (code-server 4.143.1):
- Isolate everything: --config <dir>/config.yaml --user-data-dir <dir>/user --extensions-dir <dir>/ext, plus XDG_CONFIG_HOME and XDG_DATA_HOME pointed into the same dir. Gotcha: even code-server --version with no flags writes ~/.config/code-server/config.yaml (with a generated password) and ~/.local/share/code-server/coder-logs on first run. On a shared account, set the XDG vars before your first call.
- config.yaml: bind-addr: 127.0.0.1:<port>, auth: password, a random password, cert: false. Reach it with ssh -N -L 127.0.0.1:<port>:127.0.0.1:<port> host. code-server is a full IDE with a terminal, so password auth matters even on loopback when the host is shared.
- Install the extension offline: code-server ... --install-extension ext.vsix with the same isolated flags.
- Flags: --disable-telemetry --disable-update-check --disable-workspace-trust.
Driving from CDP:
- Log in: navigate to /login, fill input[type=password] via Runtime.evaluate, form.submit().
- Open a folder: /?folder=/abs/path.
- Command palette: Input.dispatchKeyEvent F1 (rawKeyDown/keyUp, windowsVirtualKeyCode 112) works on every platform, so you don't have to pick Ctrl vs Cmd. Input.insertText the command title, then Enter (keyDown with text '\r'). For quick-open of a file, press F1, Backspace (drops the '>'), type the file name, Enter; a file type with a registered custom editor opens in it.
- Extension input boxes take Input.insertText + Enter the same way.
- Page.captureScreenshot for probes; Page.startScreencast for true-time video.
Measure memory as the RSS sum of the code-server process tree (/proc/<pid>/task/*/children, recursively); the extension host is a child. Don't have a second browser session open on the same server while measuring.