Skip to content

copilot: install chat-lib with the Copilot workspace - #346069

Merged
Ladislau Szomoru (lszomoru) merged 1 commit into
mainfrom
lszomoru/merge-chat-lib-into-copilot
Nov 4, 2026
Merged

Ladislau Szomoru (lszomoru) merged 1 commit into
mainfrom
lszomoru/merge-chat-lib-into-copilot

Conversation

@lszomoru

Copy link
Copy Markdown
Member

extensions/copilot/chat-lib (the @vscode/chat-lib npm package, extracted from the Copilot extension's sources) was a separate pnpm install root, with its own pnpm-workspace.yaml and pnpm-lock.yaml. It becomes a member of the extensions/copilot workspace: one pnpm install in extensions/copilot installs both, and Copilot's pnpm-lock.yaml records them. That takes the repository from 8 pnpm install roots to 7 (after #345794, #345795, #345797 and #345827).

What changed

  • Lockfile and versions:
    • The extraction (extract-chat-lib) already syncs chat-lib's dependencies to Copilot's versions in every pipeline. The committed chat-lib package.json now has those versions too: @anthropic-ai/sdk ^0.82.0, @types/node 24.x, typescript = Copilot's @typescript/typescript6 alias.
    • In Copilot's lockfile, chat-lib's project uses Copilot's entries for all 28 dependencies the two share. The lockfile only gains the project; no packages, no snapshots, and Copilot's own project is unchanged.
  • chat-lib/script/postinstall.ts: every Copilot install now runs it, also before the extraction has created chat-lib's sources. It skipped nothing before and failed ("Could not find the source directory for tokenizer files"); now it skips with a message. In a package installed from npm (dist/ present) it copies the same files as before.
  • chat-lib/package.json compile: tsc → tsc6, the binary of the typescript that chat-lib declares (TypeScript 6). In its own install root, tsc came from @typescript/old (the same TypeScript 6.0.3) only because pnpm hoisted it. In Copilot's workspace, tsc is Copilot's @typescript/native (TypeScript 7), whose declaration emit fails on chat-lib (TS5088/TS7056).
  • extractChatLib.ts / chatLibLockfile.ts:
    • copyLockedDependencies (which copied entries into chat-lib's own lockfile) becomes lockChatLibDependencies. It locks each changed dependency to the version Copilot's project locks in the shared lockfile, drops the entries no project uses anymore, and still resolves nothing.
    • The extraction then runs pnpm install --frozen-lockfile --ignore-scripts. Otherwise its own TypeScript check would use chat-lib's previous versions, which pnpm nests in chat-lib/node_modules.
    • Tests rewritten for the shared lockfile.
  • extensions/copilot/pnpm-workspace.yaml:
    • packages: [chat-lib];
    • hoistWorkspacePackages: false. Without it, pnpm links chat-lib into node_modules/@vscode/chat-lib, and vsce package (pnpm exec vsce package in the Copilot pipeline) fails: its npm list --production reports the link and chat-lib's nested packages as extraneous (ELSPROBLEMS).
  • CI (.github/actions/test-chat-lib; extensions/copilot/build/steps/{build,test}-chat-lib.yml and npm-package-next.yml for the npm package pipelines):
    • the extraction no longer deletes Copilot's node_modules;
    • chat-lib's dependencies are installed in extensions/copilot after the extraction;
    • then pnpm --dir chat-lib run postinstall runs, because pnpm skips lifecycle scripts when the workspace is already up to date. It copies the wasm and tokenizer files next to the extracted sources.
  • build/npm/dirs.ts: chat-lib is a member of extensions/copilot (separateRootMembers). hoistWorkspacePackages is added to the known settings (workspaceConfig.ts).

For reviewers

  • chat-lib's isolation in CI changes. The test-chat-lib action used to delete every node_modules above chat-lib, so chat-lib built and tested against only its own dependencies. Now its dependencies are in Copilot's node_modules, so a chat-lib import of a package that only Copilot declares would no longer fail in CI. Today it doesn't happen: the packed package installs and loads in a clean project (below). A follow-up could add that consumer check to the test-chat-lib action.
  • Copilot's global overrides (zod, string_decoder, yauzl) now also apply to chat-lib's tests. The packages that ship are unaffected: npm consumers resolve chat-lib's dependencies themselves.
  • Every Copilot install (and the root postinstall) now also installs chat-lib. It costs nothing extra: chat-lib uses Copilot's packages.
  • Pre-existing, unchanged: the published @vscode/chat-lib (e.g. 0.73.0) runs tsx script/postinstall.js as postinstall, but tsx is a dev dependency, so npm install @vscode/chat-lib fails unless tsx is available or scripts are ignored.

How to test (macOS arm64; compared with main at b48b93587a9, same steps on both)

  • pnpm install --frozen-lockfile at the root: passes, and chat-lib's postinstall skips. cd extensions/copilot && pnpm install --lockfile-only leaves the lockfile unchanged.
  • Copilot VSIX:
    • pnpm run build, then pnpm exec vsce package -o copilot-chat.vsix --allow-package-secrets sendgrid (as in product-copilot.yml): 82 files, byte-identical to main's VSIX (bundles included).
    • npm list --production (what vsce reads) gives the same 280 paths as on main. Without hoistWorkspacePackages: false, vsce package failed.
  • Built-in Copilot and the product: getProductionDependencies for '', remote, remote/web, extensions and extensions/copilot (233 / 142 / 26 / 1 / 279): name, version and location identical to main.
  • chat-lib npm package, the pipeline steps from a clean tree:
    • install Copilot, extract, install and postinstall, version sync, pnpm run build, pnpm test: 19/19 tests pass;
    • pnpm pack: the same 2143 files as main's package. All compiled .js/.d.ts files are byte-identical; only package.json (compile) and script/postinstall.ts differ.
  • The GitHub test-chat-lib action steps: same result.
  • Drift case, when Copilot bumps a dependency that chat-lib shares (simulated with chat-lib's @anthropic-ai/sdk back on ^0.91.1 in the lockfile): the extraction updates 1 dependency, relocks it to Copilot's version, removes the stale nested copy, and the build and the 19 tests pass.
  • Consumer of the packed package: npm install --ignore-scripts <tgz> into a clean project, require('@vscode/chat-lib') (11 exports), and tsc on a consumer file: same results as main's package. The package's postinstall (run with tsx) copies the same 12 wasm and 2 tokenizer files.
  • cd extensions/copilot && pnpm run typecheck: passes. pnpm exec vitest --run script/test/chatLibLockfile.spec.ts: 5 passed.
  • cd build && pnpm run typecheck: passes. node --test lib/test/pnpmLock.test.ts lib/test/installWithoutSaving.test.ts lib/test/cloudSandbox.test.ts lib/test/dependencies.test.ts lib/test/listNodeModules.test.ts lib/test/detectChanges.test.ts lib/test/detectMissingCaches.test.ts npm/pnpm/test/workspaceConfig.test.ts: 76 passed.
  • Not run: the chat-lib jobs on Linux and Windows (they run on this PR) and the Azure Pipelines npm package pipeline (npm-package.yml, publishing off by default).

`extensions/copilot/chat-lib` was a separate pnpm install root, with its
own `pnpm-workspace.yaml` and `pnpm-lock.yaml`. It becomes a member of
the `extensions/copilot` workspace: one `pnpm install` in
`extensions/copilot` installs both, and Copilot's `pnpm-lock.yaml`
records them.

The extraction already sets chat-lib's dependencies to Copilot's
versions, so the committed chat-lib `package.json` now has those
versions too (`@anthropic-ai/sdk`, `@types/node`, `typescript`). In
Copilot's lockfile chat-lib's project uses Copilot's entries for all its
dependencies: the lockfile gains the project and no packages, and
Copilot's own project doesn't change.

- `chat-lib/script/postinstall.ts`: every Copilot install runs it now,
  also before `extract-chat-lib` created the sources; it skips instead
  of failing. Packages installed from npm (with `dist/`) are unaffected.
- `chat-lib/package.json`: `compile` runs `tsc6`, the compiler of the
  `typescript` that chat-lib declares (TypeScript 6). In its own install
  root, `tsc` came from the same package by accident of hoisting; in
  Copilot's workspace it is Copilot's `@typescript/native`.
- `extractChatLib.ts` / `chatLibLockfile.ts`: after the extraction
  changes chat-lib's dependencies, `lockChatLibDependencies` locks them
  to Copilot's versions in the shared lockfile and drops the entries no
  project uses, still without resolving anything. The extraction then
  also updates `node_modules`, so that its TypeScript check doesn't use
  chat-lib's previous versions.
- `pnpm-workspace.yaml`: `hoistWorkspacePackages: false`. Otherwise pnpm
  links chat-lib into `node_modules/@vscode/chat-lib`, and `vsce package`
  fails: its `npm list --production` reports the link as extraneous.
- CI (`test-chat-lib` action, chat-lib npm package pipelines): chat-lib's
  dependencies are installed in `extensions/copilot` after the
  extraction, then chat-lib's postinstall runs (pnpm skips it when the
  workspace is up to date).
- `build/npm/dirs.ts`: chat-lib is a member of `extensions/copilot`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 4, 2026 17:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues remain for the chat-lib workspace consolidation.

No open issues 🎉

1 file not reviewed
  • extensions/copilot/pnpm-lock.yaml: Generated file
What changed in this PR

This PR moves @vscode/chat-lib into the Copilot pnpm workspace, continuing the install-root consolidation and reducing the repository from eight install roots to seven.

Changes:

  • Consolidates chat-lib’s dependencies into Copilot’s lockfile and aligns its declared versions and compiler command.
  • Updates extraction to synchronize the shared lockfile and installed dependencies, while allowing postinstall to skip before sources exist.
  • Adjusts CI and build tooling for workspace installation and explicit post-extraction asset copying.

No actionable findings remain. Linux/Windows chat-lib jobs and the Azure npm package pipeline remain validation gaps noted in the PR description.

File Description
extensions/​copilot/​script/​test/​chatLibLockfile.spec.ts Rewrites dependency-locking tests for the shared workspace.
extensions/​copilot/​script/​build/​extractChatLib.ts Updates the shared lockfile and refreshes installed dependencies.
extensions/​copilot/​script/​build/​chatLibLockfile.ts Locks chat-lib dependencies to Copilot’s versions and prunes unused entries.
extensions/​copilot/​pnpm-workspace.yaml Adds chat-lib and disables workspace-package hoisting for packaging compatibility.
extensions/​copilot/​pnpm-lock.yaml Adds chat-lib’s project using existing package entries.
extensions/​copilot/​chat-lib/​script/​postinstall.ts Skips asset copying when extracted sources are absent.
extensions/​copilot/​chat-lib/​pnpm-workspace.yaml Removes the standalone workspace configuration.
extensions/​copilot/​chat-lib/​pnpm-lock.yaml Removes the standalone lockfile.
extensions/​copilot/​chat-lib/​package.json Aligns dependency versions and switches compilation to tsc6.
extensions/​copilot/​build/​steps/​test-chat-lib.yml Uses workspace installation and explicitly runs chat-lib postinstall.
extensions/​copilot/​build/​steps/​build-chat-lib.yml Adapts package builds to the shared installation.
extensions/​copilot/​build/​npm-package-next.yml Adapts next-package publishing preparation to the shared installation.
build/​npm/​pnpm/​workspaceConfig.ts Recognizes hoistWorkspacePackages as a supported setting.
build/​npm/​dirs.ts Registers chat-lib as a Copilot workspace member.
build/​lib/​test/​pnpmLock.test.ts Tests chat-lib’s shared lockfile location.
.github/​actions/​test-chat-lib/​action.yml Preserves Copilot dependencies and copies assets after extraction.

Review effort: Balanced

@lszomoru
Ladislau Szomoru (lszomoru) merged commit f692da2 into main Nov 4, 2026
61 checks passed
@lszomoru
Ladislau Szomoru (lszomoru) deleted the lszomoru/merge-chat-lib-into-copilot branch November 4, 2026 19:56
@vs-code-engineering vs-code-engineering Bot added this to the 1.146.0 milestone Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants