microsoft / microsoft/component-detection
`NpmComponentDetector` unconditionally skips packages with `engines.vscode`, causing false negatives for products that ship built-in extensions
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 553
- Forks
- 135
- Avg merge
- 20h 58m
- Merged PRs (30d)
- 6
Description
🤖 AI Assisted bug report
Ref https://github.com/microsoft/vscode-engineering/issues/2142
### Context
The VS Code team is migrating our third-party license workflow from a custom tool to Component Governance. VS Code ships ~30 built-in extensions (markdown, css/html/json language features, notebook renderers, etc.) whose transitive npm dependencies are bundled into the product and distributed to users.
During our migration we discovered that CG detects ~74% of our ~1,000 shipping packages out of the box. A significant chunk of the missing 26% traces back to a single check in NpmComponentDetector.
### The problem
[NpmComponentDetector](https://github.com/microsoft/component-detection/blob/main/src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetector.cs#L85-L97) unconditionally skips any package.json that contains `engines.vscode`:
```csharp
if (packageJson.Engines is not null && packageJson.Engines.ContainsKey("vscode"))
{
containsVsCodeEngine = true;
}
if (containsVsCodeEngine)
{
this.Logger.LogInformation(
"{NpmPackageName} found at path {NpmPackageLocation} represents a built-in VS Code extension. This package will not be registered.",
name, filePath);
return false;
}
```
The assumption — "any package with engines.vscode is a dev-time extension and shouldn't be registered" — is correct for repositories that consume VS Code extensions. But it's incorrect for VS Code itself, where built-in extensions are production code that ships inside the installation directory (`resources/app/extensions/*/`).
### Impact
Because the detector skips extension root package.json files, it never walks their dependency trees. This means:
- ~80 extension-bundled npm packages are invisible to component detection. Examples: `chevrotain `and `langium` (transitive deps of `mermaid `via `mermaid-chat-features`), `vscode-css-languageservice` / `vscode-html-languageservice` / vscode-json-languageservice (bundled in language feature extension servers), jsdom (via notebook-renderers), `dompurify`, `@mermaid-js/parser`.
- These packages are compiled/bundled into extension JS via webpack — they don't appear as separate files in the shipped artifact, but their license text is still legally required in our NOTICE file.
- The `notice@0` task can't generate NOTICE entries for components it never detected, so these are silently missing from the output.
### Our current workaround
We built a supplemental scanner that runs after CG's notice@0 task and:
1. Walks extensions/*/node_modules/ to find packages CG skipped
2. Reads LICENSE files directly from disk
3. Merges them into the CG-generated NOTICE
This works but means every VS Code indefinitely needs to maintain our own scanner to catch this edge case.
### What we'd like
Any of these would resolve the issue:
1. Opt-out flag — A detector argument (e.g., --include-vscode-extensions) or an environment variable that disables the engines.vscode skip. Products that ship extensions can opt in; external consumers keep the current behavior.
2. Path-based allow list — A way to tell the detector "treat extensions/*/package.json as regular npm packages even if they declare engines.vscode."
### Reproduction
1. Clone any repo that has a subdirectory with a package.json containing "engines": { "vscode": "^1.80.0" } and npm dependencies
2. Run component detection
3. Observe that the extension's package.json and all its transitive dependencies are absent from the detection results
4. The log will show: " found at path represents a built-in VS Code extension. This package will not be registered."
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetector.cs around the engines.vscode check and review the reproduction steps in the issue. Determine how an opt-in or path-based exception should preserve the current default behavior, then verify that VS Code extension package.json files and their dependencies are detected without changing ordinary extension-consumer results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100