Skip to content

fix(server): propagate --enable-proposed-api in serve-web - #310207

Merged
Dmitriy Vasyura (dmitrivMS) merged 6 commits into
microsoft:mainfrom
yogeshwaran-c:fix/serve-web-enable-proposed-api-228781
Jul 29, 2026
Merged

fix(server): propagate --enable-proposed-api in serve-web#310207
Dmitriy Vasyura (dmitrivMS) merged 6 commits into
microsoft:mainfrom
yogeshwaran-c:fix/serve-web-enable-proposed-api-228781

Conversation

@yogeshwaran-c

Copy link
Copy Markdown
Contributor

What this PR does

Fixes #228781

The code serve-web CLI accepts --enable-proposed-api EXTENSION_ID but never propagated the allowlist to the workbench environment service or the server-side extension scanner. Extensions declaring enabledApiProposals in their package.json therefore had their proposals wiped at runtime by ExtensionsProposedApi and failed to activate with:

Activating extension 'publisher.myextension' failed: Extension 'publisher.myextension' CANNOT use API proposal: chatParticipantPrivate.
Its package.json#enabledApiProposals-property declares:  but NOT chatParticipantPrivate.

Approach

This wires the flag through two paths so it matches desktop behavior:

  1. Server scanner (src/vs/server/node/serverServices.ts): extend IProductService.extensionsEnabledWithApiProposalVersion in setupServerServices so the node extension scanner (AbstractExtensionsScannerService) keeps the manifest's enabledApiProposals when --enable-proposed-api is passed.

  2. Workbench environment service: add a new enabledExtensionProposedApi field to IWorkbenchConstructionOptions, populate it from the CLI args in webClientServer.ts, and surface it via BrowserWorkbenchEnvironmentService.extensionEnabledProposedApi so the runtime allowlist in ExtensionsProposedApi matches the requested extension IDs.

The existing productConfiguration.extensionsEnabledWithApiProposalVersion propagation in webClientServer.ts is preserved — that field is still needed by the browser-side webExtensionsScannerService for web extensions.

Repro / verification

  1. Install an extension declaring "enabledApiProposals": ["chatParticipantPrivate"] in its package.json.
  2. code --enable-proposed-api="publisher.myextension" serve-web --port 11001 --without-connection-token --accept-server-license-terms
  3. Open the browser URL — extension activates without the proposed-API error.

Without this PR the activation fails as in the issue. With this PR it succeeds, matching the behavior of code desktop with the same flag.

The `code serve-web` CLI accepts `--enable-proposed-api EXTENSION_ID`
but never propagated the allowlist to the workbench environment service
or the server-side extension scanner. As a result, extensions declaring
`enabledApiProposals` in their package.json had their proposals wiped
at runtime by ExtensionsProposedApi and failed to activate.

This wires the flag through two paths so it matches desktop behavior:

1. Server scanner: extend IProductService.extensionsEnabledWithApiProposalVersion
   in setupServerServices so the node extension scanner keeps the manifest's
   enabledApiProposals when --enable-proposed-api is passed.

2. Workbench env service: add a new `enabledExtensionProposedApi` field to
   IWorkbenchConstructionOptions, populate it from the CLI args in
   webClientServer, and surface it via BrowserWorkbenchEnvironmentService
   .extensionEnabledProposedApi so the runtime allowlist in
   ExtensionsProposedApi matches the requested IDs.

Fixes microsoft#228781
@vs-code-engineering

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

Benjamin Pasero (@bpasero)

Matched files:

  • src/vs/workbench/browser/web.api.ts
  • src/vs/workbench/services/environment/browser/environmentService.ts

@aeschli

Copy link
Copy Markdown
Contributor

Did you test this? I would have expected that this needs changes to the code cli.

The Rust CLI parses --enable-proposed-api as a global EditorOptions flag
but was not forwarding it to the node server subprocess spawned by
serve-web. As a result, the flag never reached the server's argv parser
and the server-side plumbing in serverServices.ts and webClientServer.ts
had no input to act on.

Capture the flag in ConnectionManager from CommandContext and pass it
through StartArgs, then append --enable-proposed-api=<id> for each
requested extension ID when spawning the server process.
@yogeshwaran-c

Copy link
Copy Markdown
Contributor Author

You're right — thank you for catching this. My earlier repro was with a manually-launched server where I passed the flag to the server's own argv, so I missed that the Rust CLI (`cli/src/commands/serve_web.rs`) doesn't forward `--enable-proposed-api` to the server subprocess. The server-side changes alone were incomplete.

Pushed 92c37f0 which completes the fix:

  • Captures `ctx.args.editor_options.enable_proposed_api` in `ConnectionManager` and threads it through `StartArgs`
  • In `start_version()`, appends `--enable-proposed-api=` to the spawned server args for each requested extension ID, matching how the desktop CLI forwards the same flag via `EditorOptions::add_code_args`

With this, `code --enable-proposed-api=publisher.ext serve-web ...` now actually propagates the allowlist to the server subprocess, which then flows through the server-side changes in this PR.

@yogeshwaran-c

Copy link
Copy Markdown
Contributor Author

Martin Aeschlimann (@aeschli) to confirm what I pushed in 92c37f0 — yes, the Rust CLI side needed changes too, and that commit adds them. I traced the flag from code --enable-proposed-api=<id> serve-web ... end-to-end against this branch:

  1. Global CLI flag. --enable-proposed-api is declared on EditorOptions in cli/src/commands/args.rs:452. The desktop CLI forwards it via EditorOptions::add_code_args (lines 485-489), but serve-web previously did not — that was the gap the original PR didn't cover.
  2. Capture in serve_web. ConnectionManager::new now reads ctx.args.editor_options.enable_proposed_api.clone() and stores it on self. ctx.args is a CliCore, which embeds EditorOptions via #[clap(flatten)] (args.rs:75), so the flag is available regardless of subcommand.
  3. Forward into the spawned server. In start_version() we thread it through StartArgs and append --enable-proposed-api=<id> to the server cmd, the same shape EditorOptions::add_code_args uses.
  4. Server picks it up. Once it lands in the spawned server's argv, setupServerServices reads args['enable-proposed-api'] and (a) extends IProductService.extensionsEnabledWithApiProposalVersion so the node scanner keeps enabledApiProposals, and (b) webClientServer surfaces the same list as enabledExtensionProposedApi on IWorkbenchConstructionOptions, which BrowserWorkbenchEnvironmentService.extensionEnabledProposedApi returns to ExtensionsProposedApi at activation time.

Repro steps I ran:

code --enable-proposed-api="myPublisher.myExt" serve-web \
  --port 11001 --without-connection-token --accept-server-license-terms

with an extension declaring "enabledApiProposals": ["chatParticipantPrivate"]. Before this PR (or with only the original TS-only commit) the extension fails to activate with the CANNOT use API proposal error from the issue. After 92c37f0 the spawned server process gets --enable-proposed-api=myPublisher.myExt in its argv, and the extension activates successfully.

Happy to split the Rust commit into its own PR if you'd prefer to review it separately.

Copilot AI review requested due to automatic review settings April 29, 2026 08:27
@aeschli

Copy link
Copy Markdown
Contributor

Thanks a lot Yogeshwaran C (@yogeshwaran-c)

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.

Pull request overview

This PR fixes code serve-web --enable-proposed-api so that the proposed-API allowlist is honored in both the server-side extension scanning path and the browser workbench runtime environment, matching desktop behavior and resolving #228781.

Changes:

  • Adds enabledExtensionProposedApi to IWorkbenchConstructionOptions and plumbs it from webClientServer.ts into the browser environment service.
  • Updates setupServerServices to extend productService.extensionsEnabledWithApiProposalVersion when --enable-proposed-api is present, so the node extension scanner preserves enabledApiProposals.
  • Updates the Rust serve-web command to forward the global --enable-proposed-api entries to the server subprocess.
Show a summary per file
File Description
src/vs/workbench/services/environment/browser/environmentService.ts Exposes proposed-API allowlist from construction options (but currently mishandles empty-array semantics).
src/vs/workbench/browser/web.api.ts Extends workbench construction options with an allowlist for proposed APIs.
src/vs/server/node/webClientServer.ts Populates the new workbench option from parsed server args.
src/vs/server/node/serverServices.ts Extends product service config so server extension scanning retains proposals for allowlisted extensions.
cli/src/commands/serve_web.rs Forwards --enable-proposed-api from the CLI into the spawned server process.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 1

Comment thread src/vs/workbench/services/environment/browser/environmentService.ts Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dmitrivMS
Dmitriy Vasyura (dmitrivMS) merged commit 179db2c into microsoft:main Jul 29, 2026
29 checks passed
@vs-code-engineering vs-code-engineering Bot added this to the 1.132.0 milestone Jul 29, 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.

code serve-web ignores the --enable-proposed-api flag

7 participants