# Upgrade a VS Code Extension to the Latest API

Yes. A Rush agent raises engines.vscode and @types/vscode together, compiles, runs the extension tests in VS Code under xvfb and opens a pull request.

[Run this on Rush](https://cloud.getrush.ai/run/upgrade-vscode-engine/vscode-extension/), in a Project that has your repository.

## What the agent does

In a repository like microsoft/vscode-extension-samples, each sample is a separate extension with its own package.json and package-lock.json. tree-view-sample and helloworld-sample both declare engines.vscode ^1.100.0 and @types/vscode ^1.100.0, @types/node ^22, TypeScript 5 and ESLint 9 with typescript-eslint 8. Their scripts are compile (tsc -p ./), watch and lint; neither has a test script or a test file. The agent starts by reading both, because the rule it has to keep is that @types/vscode never names a newer API than engines.vscode promises users have.

It raises engines.vscode and @types/vscode to the same newer version and compiles. In tree-view-sample, which registers several tree views from src/extension.ts using src/fileExplorer.ts, src/ftpExplorer.ts, src/jsonOutline.ts, src/nodeDependencies.ts and src/testViewDragAndDrop.ts, a newer @types/vscode can turn a deprecated call into a type error or a narrower type; the agent fixes those against the API change, not with a cast. It also looks at the runtime dependencies there, which are old (jsonc-parser ^0.4.2, mkdirp ^0.5.1, rimraf ^2.6.2, ftp ^0.3.10), and bumps them only where the code keeps working.

Because neither sample has tests, it adds the setup the repository's own helloworld-test-cli-sample uses: @vscode/test-cli and @vscode/test-electron as dev dependencies, a .vscode-test.mjs with files: 'out/test/**/*.test.js', a pretest of npm run compile and a test script of vscode-test, plus one Mocha test per sample that activates the extension and runs one of its commands. Then it runs xvfb-run -a npm test, which downloads the VS Code version the engine asks for and runs the tests inside it with a virtual display.

The repository's CI only runs npm run validate, which checks that every sample is listed and the README is current, so the agent runs those too after its changes. A bump that breaks compile or the extension tests is left out, with the output.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "In tree-view-sample and helloworld-sample only, raise engines.vscode and @types/vscode together to the latest compatible version and upgrade the other npm dependencies. Fix type errors against the API change, not with casts. Neither sample has tests: add @vscode/test-cli and @vscode/test-electron with a .vscode-test.mjs as helloworld-test-cli-sample does, and one test per sample that activates it and runs one command. Run npm run compile, then xvfb-run -a npm test, and npm run validate at the repository root. Leave out any upgrade that breaks the build or tests and say why. Open a pull request with one line per bump.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

The pull request changes package.json and package-lock.json in both samples, adds a .vscode-test.mjs and one test file under src/test/ in each, and includes whatever source fixes the new API types required, each named in the description. It lists the old and new engines.vscode and @types/vscode, every other bumped package, and the compile and xvfb-run test results.

Before merging, a reviewer checks that engines.vscode and @types/vscode match, since raising the engine stops users on older VS Code versions from installing the extension, and reads the test output in the transcript to see which VS Code build the tests ran in. A runtime dependency left on its old version has its reason beside it.

## Run it on every VS Code monthly release

VS Code ships a release each month, and each one can add API your extension wants or deprecate API it uses. Start a run after each release, or on your own schedule, with this POST /o/{org}/sessions body. A webhook on the key reports run.completed or run.failed.

Once the samples have tests from the first run, later runs prove each bump in the real editor instead of by compile alone.

## Why run it on Rush?

Extension tests run inside a real VS Code instance, which needs a download per version and a display. On a laptop that steals focus or needs a separate profile; in CI it needs xvfb. In Rush the agent runs xvfb-run in its own sandbox, and the test output and VS Code version are kept in the transcript.

Raising an engine is a decision about who can install the extension, not only a version string. A pull request that names the new minimum, shows the API fixes and proves the extension activates in that version gives a maintainer what they need to make that decision.

## Frequently asked questions

### Why change engines.vscode and @types/vscode together?

@types/vscode describes the API, and engines.vscode says which VS Code versions may install the extension. If the types are newer than the engine, the code can call an API that users on the minimum version do not have. Keeping them equal prevents that.

### My extension has no tests. What will it add?

The same setup the repository's helloworld-test-cli-sample uses: @vscode/test-cli, @vscode/test-electron, a .vscode-test.mjs and Mocha tests. It adds one test per extension that activates it and runs a command, enough to prove the upgrade, not a full suite.

### Does it run the tests in a real VS Code?

Yes. vscode-test downloads VS Code and runs the tests inside it, and xvfb-run -a gives it a virtual display in the sandbox.

### Will it publish to the Marketplace?

No. It opens a pull request. Packaging with vsce and publishing stay with your release process.
