Repository navigation
Conversation
The ESLint engine runs with ESLint's default parser, which cannot read TypeScript syntax. Parse errors carry no rule ID and were dropped, so .ts/.tsx files never produced findings. oxlint parses JS, TS, JSX and TSX natively and ships as a single SHA-256-verified binary, so no npm install is needed per run. The engine runs no-eval, no-implied-eval, no-new-func, no-script-url and react/no-danger with nested project configs disabled, and reports unparseable files in the engine note instead of dropping them. `engines: "all"` now runs oxlint instead of eslint. ESLint remains available as an opt-in engine. engines:check now finds a tool's latest release in monorepos such as oxc-project/oxc, where the repository-wide latest release can belong to another product (oxfmt, crates). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Unchecked PATH versions and unsafe source discovery can undermine reproducibility, omit scanned files, or discard valid findings.
2 open issues
What changed in this PR
Adds oxlint as PolyScan’s default JavaScript/TypeScript scanner, replacing ESLint in engines: "all" while retaining ESLint as an opt-in.
Changes:
- Adds oxlint provisioning, security rules, and diagnostic parsing.
- Updates release discovery for repositories publishing multiple tools.
- Adds tests, documentation, and the generated runtime bundle.
| File | Description |
|---|---|
tools.lock.json |
Pins oxlint version and checksum. |
test/tool-versions.test.ts |
Checks oxlint download metadata. |
test/oxlint-parser.test.ts |
Tests parsing and source detection. |
test/engines.test.ts |
Verifies updated default engines. |
test/engine-tools-cli.test.ts |
Tests product-specific release discovery. |
src/summary.ts |
Updates URL documentation comments. |
src/schema.ts |
Documents oxlint-provided URLs. |
src/main.ts |
Dispatches oxlint scans. |
src/engines/oxlint.ts |
Implements the oxlint adapter. |
src/engines.ts |
Registers oxlint and changes defaults. |
scripts/engine-tools.mjs |
Matches releases against tool tag templates. |
README.md |
Documents oxlint and changed defaults. |
dist/index.js |
Bundles the updated implementation. |
CHANGELOG.md |
Records additions and migration effects. |
action.yml |
Updates engine input documentation. |
.github/workflows/selftest.yml |
Checks TypeScript detection through SARIF. |
.github/skills/engine-tool-update/SKILL.md |
Adds oxlint to skill scope. |
.github/copilot-instructions.md |
Adds oxlint to the engine overview. |
Review effort: Balanced
| const findings: Finding[] = []; | ||
| const parseErrorFiles = new Set<string>(); | ||
| for (const batch of oxlintBatches(files, flags)) { | ||
| const res = await run(bin, [...flags, ...batch], { cwd: abs }); |
| fs.writeFileSync(configPath, JSON.stringify(CONFIG)); | ||
|
|
||
| // Nested project configs are disabled so a repository cannot switch the security rules off. | ||
| const flags = ["--config", configPath, "--disable-nested-config", "--no-ignore", "--format", "json", "--"]; |
| const unparsed = [...parseErrorFiles].sort(); | ||
| return { | ||
| engine: "oxlint", | ||
| findings, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
The ESLint engine runs with ESLint's default parser, which cannot read TypeScript syntax. Parse errors have no rule ID and were silently dropped (
src/engines/eslint.ts), so.ts/.tsxfiles never produced findings. Verified locally with ESLint 10.12.0 ontest-fixtures/src/vuln.ts:Parsing error: The keyword 'interface' is reserved.This PR adds an oxlint engine and makes it the default JS/TS scanner.
src/engines/oxlint.ts: pinned, SHA-256-verified standalone binary (oxlint_v1.89.0, digest matches the GitHub release API). It parses JS/TS/JSX/TSX natively and is skipped without a download when the target has no JS/TS files.no-eval,no-implied-eval,no-new-func,no-script-url,react/no-danger. All default categories are off. Nested project configs are disabled so a scanned repo cannot switch the rules off.react/jsx-no-script-urlis left out becauseno-script-urlreports the same location.engines: "all"now runsoxlintinstead ofeslint. ESLint stays available as an opt-in engine.engines:checkpreviously failed for oxc-project/oxc because the repo also publishesoxfmt_v…andcrates_v…releases. It now picks the newest stable release whose tag matches the tool's template.oxlint/no-evalfinding intest-fixtures/src/vuln.ts.action.yml, Copilot instructions.Findings move from
eslint/<rule>tooxlint/<rule>rule IDs, so existing code scanning alerts close and reopen under the new IDs. Together with the changedalldefault, this probably warrants a major release (v17).Test plan
npm run typecheck,npm test(214/214),npm run buildwith Node 24. Thedist/diff contains only the expected changes.test-fixtures:no-evalinvuln.js:7andsrc/vuln.ts:10. It is skipped on a directory without JS/TS files.oxlint-x86_64-unknown-linux-gnu, which matches the rename in the installer.Note: in a local test, oxlint's
no-implied-evaldid not flagsetTimeout("alert(1)", 1). It stays in the config at no cost.🤖 Generated with Claude Code