# avril for VS Code Native TypeScript language features, live diagnostics, and `avril.conf` syntax highlighting. The client launches `avril lsp` directly; it does not run a Deno or JavaScript language server. ## Build and install There are three pieces: the Avril executable, a separately built **patched native TypeScript executable**, and the VS Code extension. The extension does not bundle either executable. Stock `typescript` from npm and unpatched native TypeScript executables cannot serve as the LSP backend. Prerequisites: - Current stable Rust, a C compiler toolchain, and curl to build Avril. See `README.md` at the repository root for the alternative of building V8 from source. - Git, Bash, and Go for the patched compiler. Its Go module selects the required toolchain; Go may download it on the first build. No Node/npm install is needed in the TypeScript checkout. - Node.js 22.13 or newer (including npm), pnpm 11.27.0, and VS Code 1.90 or newer for the extension. pnpm installs dependencies; `vsce` still uses npm internally to enumerate them. ### 1. Build Avril and the patched compiler Run these commands from the **Avril repository root**, in a Unix shell: ```sh cargo build --locked -p avril-cli --bin avril typescript_src=$(mktemp -d) git clone --filter=blob:none --no-checkout \ https://github.com/microsoft/TypeScript.git "$typescript_src" git -C "$typescript_src" checkout --detach b5c34ba0c61a756c8abaf133236dddf982c27f45 bash lib/lsp/typescript/build.sh "$typescript_src" "/absolute/path/to/avril-tsc" printf 'avril.lsp.executable: %s\n' "$PWD/target/debug/avril" printf 'avril.lsp.backend: %s\n' "/absolute/path/to/avril-tsc" ``` Copy the two printed paths for the settings below. The compiler executable is installed outside the temporary checkout and embeds its library declarations; the checkout is not needed at runtime. The script checks the pinned revision, applies `bridge.patch`, runs the native bridge tests, and builds `7.1.0-dev.20261013.1`. If Go is not on PATH, replace the `build.sh` command above with: ```sh nix shell nixpkgs#go --command bash lib/lsp/typescript/build.sh \ "$typescript_src" "/absolute/path/to/avril-tsc" ``` The script requires a clean checkout and leaves it patched. To rebuild after an Avril patch update, use a fresh checkout rather than rerunning it on the patched one. See `lib/lsp/BACKEND.md` in the source checkout for the backend contract. ### 2. Package and install the extension Still starting from the Avril repository root: ```sh cd editors/vscode pnpm install --frozen-lockfile --prod=false --ignore-scripts pnpm run package code --install-extension avril.vsix --force ``` If your Node installation does not include npm on PATH, Nix can supply both for packaging: run `nix shell nixpkgs#nodejs_24 --command pnpm run package` from `editors/vscode` instead of the plain package command. Use `codium` instead of `code` for VSCodium. Alternatively, choose **Extensions: Install from VSIX...** and select `editors/vscode/avril.vsix`. After installing or updating, run **Developer: Reload Window**. The extension bundles its client dependencies. Projects do not need an npm install; this adds no npm/Node compatibility to avril guests. ## Live language server 1. Open and trust a local workspace. The client currently uses its first folder; other workspace folders retain their own TypeScript language features. 2. Set these **user settings** (executable settings are machine-scoped): ```json { "avril.lsp.backend": "/absolute/path/to/avril-tsc", "avril.lsp.executable": "/absolute/path/to/avril/target/debug/avril" } ``` Substitute the literal absolute paths printed during the build. These settings do not expand `~`, `$HOME`, or `${workspaceFolder}`. Open **Preferences: Open User Settings (JSON)** to edit them; do not put these machine-scoped paths in the project's `.vscode/settings.json`. If you built Avril in release mode or installed it separately, use that executable instead. You do not need to set `typescript.tsdk`. 3. Keep VS Code's built-in **TypeScript and JavaScript Language Features** extension enabled. avril suppresses its competing results for the active folder while the language server runs, and restores them when it stops. 4. With `avril.conf` directly in the first workspace folder, the language server starts automatically once the backend is configured. Nested configurations do not trigger startup. Without a root configuration, run **avril: Start Language Server** manually, then open a TS/TSX/JS/JSX file. The server follows real avril configuration, imports, packages, and declarations. Unsaved imports and disk/config changes refresh automatically. No manifest or generated tsconfig is needed. The editor may populate the permitted cache, but never writes lockfiles or application files. Use `avril.lsp.options` for CLI policy flags, for example `["--offline", "--frozen"]`. Restart the language server after changing launch settings. **avril: Stop Language Server** shuts down the server and native child and prevents automatic restarts until you run **avril: Start Language Server** or reload the window. Set `avril.lsp.autoStart` to `false` to opt out persistently. Use `avril.lsp.preferences` for native TypeScript preferences (for example, `{"referencesCodeLensEnabled": true, "includeInlayParameterNameHints": "all"}`). These update live; omitted preferences preserve native defaults. Creating a root `avril.conf` starts the server; removing it stops an automatically started server. Untrusted workspaces cannot start it. Avril uses the native TypeScript language-service results for completion and resolution, navigation, rename, symbols, formatting, semantic tokens, inlay hints, call hierarchy, code actions, and the other capabilities advertised by the server. Type hierarchy is not advertised because the pinned native backend does not implement it. Workspace sources remain editable; acquired npm files open as immutable `avril-builtin:/dependencies/` documents. HTTPS, HTTP, and builtin declarations open through read-only `avril-https:`, `avril-http:`, and `avril-builtin:` providers. The native backend's server capabilities are exposed directly; resolution and edits remain subject to Avril's project authority. The server currently rebuilds complete generations; broader discovery and checking-context limitations are listed in `lib/lsp/README.md` in the source checkout. ## Verify the setup Open a TypeScript file and check hover, completion, and **Go to Definition**. For a known example, open `lib/lsp/tests/fixture` from this repository as the workspace folder, then open `main.tsx`: hovering `localValue` should show its literal type `42`, and Go to Definition should reach `dep file.ts`. If startup fails, open **View: Toggle Output** and select **avril**. Check that both executable paths exist, the backend was built with this repository's patch, the workspace is trusted, and `avril.conf` is directly in its first folder (or start the server manually). The extension launches `avril lsp`; you do not need to run it separately in a terminal. After rebuilding either executable, run **avril: Stop Language Server**, then **avril: Start Language Server** to replace the running processes. Repackage and reinstall the VSIX only when the extension itself changes. ## Validation Run the client lifecycle, ownership, CodeLens conversion, and read-only document URI roundtrip tests with `pnpm test` from `editors/vscode/`. From the repository root, after installing client dependencies: ```sh export AVRIL_LSP_BACKEND=/absolute/path/to/avril-tsc export AVRIL_LSP_AVRIL="$PWD/target/debug/avril" profile=$(mktemp -d /tmp/avril-editor-test.XXXXXX) xvfb-run -a codium --wait --verbose --disable-gpu --ozone-platform=x11 \ --user-data-dir="$profile/user" --extensions-dir="$profile/extensions" \ --skip-welcome --skip-release-notes --disable-workspace-trust \ --extensionDevelopmentPath="$PWD/editors/vscode" \ --extensionTestsPath="$PWD/editors/vscode/tests/editor.cjs" \ "$PWD/lib/lsp/tests/fixture" > "$profile/test.log" 2>&1 grep AVRIL_EDITOR_TESTS_PASSED "$profile/test.log" ``` The actual extension-host test invokes hover, definition, completion, signature help, rename, and references CodeLens providers; it also runs the resolved CodeLens command through VS Code's built-in references UI. It checks unsaved edits and diagnostics, and opens real builtin declarations. It also checks automatic startup and restoration/suppression of built-in TypeScript diagnostics across server stop/start. It never saves fixture application files. The trust override is for this known fixture only; systems without Chromium sandbox support may also need `--no-sandbox` for the isolated test window. Require the success marker: some editor versions exit zero even when extension tests fail. Tests are excluded from the packaged extension. Run the server's live/protocol/lifecycle and native API regression tests using the commands in `lib/lsp/README.md` in the source checkout.