Use this reference for extension activation, binary lifecycle, configuration, views, and LSP client behavior.
editors/vscode/src/extension.ts: activation, lifecycle, commands, and view wiring.editors/vscode/src/client.ts: LSP client setup and middleware.editors/vscode/src/commands.ts: CLI subprocess requests.editors/vscode/src/configKeys.ts: restart, reanalysis, and render-only configuration groups.editors/vscode/src/diagnosticFilter.ts: client-side diagnostic filtering and severity projection.editors/vscode/src/download.ts: managed binary download and verification.editors/vscode/package.json: commands, settings, views, menus, and engine compatibility.editors/vscode/src/generated/: generated shared contracts. Never hand-edit these files.
Use package.json and configKeys.ts for the current configuration inventory.
Do not duplicate the full setting list in durable prose.
- Activation events match root files or a language only. Do not add a
workspaceContainsglob with**: VS Code then searches the full workspace tree at startup. A source language of the LSP document selector needs anonLanguageevent, so that a monorepo folder with no rootpackage.jsonstarts the extension when a source file opens.test/package-manifest.test.tsand the activation integration suite check this. - Binary resolution follows the documented priority: explicit user path, workspace dependency, system path, managed binary, then auto-download.
- Validate managed downloads before execution.
- Managed downloads select the release asset for the host C library. On Linux,
src/libc.tsreports musl when/etc/alpine-releaseexists or when the Node diagnostic report has noheader.glibcVersionRuntime. A musl host gets thelinux-<cpu>-muslbinaries. Each download records its asset target in a<binary>.targetfile. A binary without that file comes from a version that downloaded only glibc binaries on Linux. A binary for another target does not count as installed, so an Alpine host replaces an earlier glibc binary. - A managed download is complete only once its file descriptor is closed. Stream completion is not enough: Unix refuses to execute a file that any process still holds open for writing, and the extension chmods, renames, and spawns what it just downloaded.
- A version mismatch is not a trust failure. A managed binary that passed
signature or digest verification but reports another version stays on disk
until a download of the matching version replaces it atomically; only a
failed verification purges. The extension downloads from the GitHub Release
of its own version, and that release is created after the VSIX is public,
so while the release endpoint answers HTTP 404 the extension keeps serving
the installed binary, says so once per session without a modal, and, when
fallow.autoDownloadis on, retries in the background with a bounded backoff and offersfallow.restartwhen the new version has landed. Withfallow.autoDownloadoff no unattended download is scheduled, and a retry already scheduled stops when the setting is turned off. The next activation retries on its own because the version check keeps failing until then. Without an installed binary the download prompt still appears and names the missing release. - Keep LSP analysis, health, audit, security, and runtime coverage as separate lazy workflows unless a measured UX change justifies combining them.
- Configuration changes restart only the surfaces whose initialization state changed. Reanalysis and render-only settings must not cause unnecessary LSP restarts.
- Diagnostic filtering applies only to diagnostics with
source: "fallow". - Generated issue metadata, output contracts, and initialization options stay synchronized with Rust sources.
- Multi-root workspace selection remains explicit and paths stay scoped to the selected project.
- The extension runs as a workspace extension. Local and remote extension hosts therefore select binaries and platform-specific VSIX payloads for the machine that owns the workspace, not the VS Code UI machine.
editors/vscode/scripts/vsix-targets.mjsis the closed source of truth for VSIX targets and their TypeScript backend packages. Target packages contain one matching backend; the untargeted universal fallback contains all supported backends.dist/is generated for packaging and remains untracked.- Release CI derives the extension version from the release tag. Do not manually
bump
editors/vscode/package.jsonfor a release. fallow/analysisCompletenotifications update editor status without requiring another CLI analysis. Keep this notification contract synchronized with LSP.- The status bar shows
package baselinesfor a mixed package scope and lists each workspace root and ref in its tooltip. A globalfallow.changedSincesetting takes precedence, including when its ref is dropped. The Set Baseline at HEAD command explains that its workspace-wide setting overrides package refs before changing that setting, when the last analysis applied package baselines.fallow.packageBaselines: falseturns the map off: the LSP getspackageBaselines: falsein its initialization options, and the sidebar run gets the version-gated--no-package-baselinesflag. The setting restarts the server and re-runs the sidebar analysis. A CLI sidebar refresh reads scope provenance from the combined report root, while LSP notifications carry their own status; neither display path reuses the other's scope. Health and security are separate reports with their own scope controls. - CLI output buffers accommodate large monorepos; preserve the limits in
commands.tswhen changing subprocess handling.
pnpm --dir editors/vscode run lint
pnpm --dir editors/vscode run check:contracts
pnpm --dir editors/vscode run build
pnpm --dir editors/vscode run test:packagingRun focused editor tests for command, configuration, download, or diagnostic
changes. Release packaging uses package:variants to build the universal
fallback and every platform target from one build into an explicit output
directory. Verify extracted artifacts with verify:vsix and the matching
--target value.