+
Skip to content

Conversation

siketyan
Copy link
Member

@siketyan siketyan commented Aug 22, 2025

Summary

Part of #2469

This pull request integrates the Boa engine to Biome for JS plugins. It runs the default exported function and pulls diagnostics from the plugin. JS APIs for Biome's AST/CST aren't implemented yet.

Support for JS plugins is gated behind the js_plugin feature and it will be enabled only in preview releases. Thus I think we can merge this to the main branch.

Test Plan

Added a simple test using multiple threads.

Docs

TODO

@siketyan siketyan self-assigned this Aug 22, 2025
Copy link

changeset-bot bot commented Aug 22, 2025

⚠️ No Changeset found

Latest commit: 7b69b76

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Aug 22, 2025

Walkthrough

Adds an optional JavaScript plugin system and runtime. Introduces crate biome_js_runtime (context, module loader, plugin API), a thread-local JS plugin loader in biome_plugin_loader (AnalyzerJsPlugin, ThreadLocalCell), diagnostics plumbing for JS errors, and a js_plugin feature propagated to biome_cli and biome_service. Workspace dependencies (boa_engine, libc, windows, biome_js_runtime) and CI/workflow changes enable building/testing with --features=js_plugin. Adds a minimal @biomejs/plugin-api package (types + erroring JS shim), license files, and an example plugin plugins/plugin.js.

Suggested labels

A-Tooling, A-Diagnostic, A-Resolver

Suggested reviewers

  • ematipico
  • denbezrukov
  • arendjr

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 26c3e9e and 7b69b76.

📒 Files selected for processing (1)
  • crates/biome_js_runtime/src/module_loader.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_js_runtime/src/module_loader.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (26)
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Check JS Files
  • GitHub Check: Bench (biome_css_parser)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added A-Project Area: project L-JavaScript Language: JavaScript and super languages labels Aug 22, 2025
Copy link

codspeed-hq bot commented Aug 22, 2025

CodSpeed Performance Report

Merging #7300 will not alter performance

Comparing siketyan:feat/js-plugin-poc (7b69b76) with main (a3fd2f1)

Summary

✅ 133 untouched benchmarks

@siketyan siketyan force-pushed the feat/js-plugin-poc branch 4 times, most recently from 998ff69 to cf64d70 Compare August 25, 2025 13:46
@siketyan siketyan changed the title feat: JS plugin PoC feat: execute JS plugin in the Boa engine (PoC) Aug 25, 2025
@siketyan siketyan force-pushed the feat/js-plugin-poc branch from cf64d70 to 5c524ff Compare August 25, 2025 16:48
@github-actions github-actions bot added A-CLI Area: CLI A-Linter Area: linter labels Aug 25, 2025
@siketyan siketyan force-pushed the feat/js-plugin-poc branch from 58cf58c to 461411d Compare August 26, 2025 15:49
@siketyan siketyan force-pushed the feat/js-plugin-poc branch from 9bc4a44 to 0466b70 Compare August 26, 2025 17:23
@siketyan siketyan changed the title feat: execute JS plugin in the Boa engine (PoC) feat: execute JS plugin in the Boa engine Aug 26, 2025
@siketyan siketyan marked this pull request as ready for review August 26, 2025 17:37
@siketyan siketyan requested review from a team August 26, 2025 17:37
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/preview.yml (1)

77-82: Use the version job output for BIOME_VERSION

The workflow’s BIOME_VERSION is currently set to ${{ env.cli-version }}, but env.cli-version isn’t defined anywhere in this file. You’ll need to pull in the generated version from the version job’s output instead. In both build steps, replace:

         env:
           # Strip all debug symbols from the resulting binaries
           RUSTFLAGS: "-C strip=symbols -C codegen-units=1"
-          BIOME_VERSION: ${{ env.cli-version }}
+          BIOME_VERSION: ${{ needs.version.outputs.version }}

After that, run your preview binary with --version to ensure it reflects the value from update-preview-version.mjs.

🧹 Nitpick comments (29)
.github/workflows/main.yml (1)

95-95: Also test the default feature set (optional).

Running only --features=js_plugin means we no longer exercise the default build on main. Consider running both to catch regressions early.

Minimal tweak:

-        run: cargo test --workspace --features=js_plugin
+        run: |
+          cargo test --workspace
+          cargo test --workspace --features=js_plugin

If runtime is a concern, a small matrix over features is another tidy option.

.github/workflows/pull_request.yml (1)

88-88: Exercise both default and js_plugin paths on PRs (optional).

Same story here: only testing the feature build may hide default-config breakage. Suggest running both.

Quick win:

-        run: cargo test --workspace --features=js_plugin
+        run: |
+          cargo test --workspace
+          cargo test --workspace --features=js_plugin

Bonus: you may want to include packages/** and plugins/** in paths: so JS-only changes still trigger CI.

crates/biome_js_runtime/Cargo.toml (2)

1-11: Consider inheriting the crate version from the workspace.

To keep versions consistent during releases, consider switching to workspace-inherited package metadata if the root defines workspace.package.

Proposed change:

 [package]
@@
-name                 = "biome_js_runtime"
+name                 = "biome_js_runtime"
@@
-version              = "0.0.1"
+version.workspace    = true

If the workspace doesn’t yet define workspace.package.version, keep 0.0.1 but ensure your release tooling bumps this crate in lockstep with the others.


1-11: Decide whether this crate is publishable now.

If biome_js_runtime isn’t meant to be published during the preview, add publish = false to avoid accidental publication; if it is, ignore this note.

Example:

 [package]
@@
 license.workspace    = true
 name                 = "biome_js_runtime"
 repository.workspace = true
-version              = "0.0.1"
+version              = "0.0.1"
+publish              = false
packages/@biomejs/plugin-api/LICENSE-APACHE (1)

189-201: Year range nit: align copyright year.

Optional: update the copyright year (currently 2023) to either the current year or a range (e.g., 2023–2025) for consistency across packages.

packages/@biomejs/plugin-api/index.d.ts (1)

1-3: Tighten typings and document severity mapping.

Two small improvements:

  • Add JSDoc to clarify how severities map to Biome/LSP severities and how they’re handled at runtime.
  • Consider a const enum or exported union object to help editors with completions; alternatively, keep the union but validate unknown values at runtime on the Rust side.

Example (non-breaking):

-export type Severity = "fatal" | "error" | "warning" | "information" | "hint";
+/**
+ * Diagnostic severity recognised by Biome’s JS plugin runtime.
+ * Unknown values should be rejected at runtime.
+ */
+export type Severity = "fatal" | "error" | "warning" | "information" | "hint";
 
-export function addDiagnostic(severity: Severity, message: string): void;
+/**
+ * Push a diagnostic from a JS plugin.
+ * @param severity Diagnostic severity.
+ * @param message Human-readable message to show to users.
+ */
+export function addDiagnostic(severity: Severity, message: string): void;

Runtime action item: ensure boa-side implementation rejects/normalises unexpected severities and adds tests for each variant.

packages/@biomejs/plugin-api/package.json (3)

1-11: Include index.js in files (now or before publish).

exports.default and main point to ./index.js, but it isn’t listed under "files". It’s fine while "private": true, but will bite later if you flip this to publish. Safer to include it now.

   "files": [
     "README.md",
     "LICENSE-APACHE",
     "LICENSE-MIT",
-    "index.d.ts"
+    "index.d.ts",
+    "index.js"
   ],

12-19: index.js throwing at import is deliberate — add a hint in package metadata.

Because the runtime provides a virtual module, index.js throws when loaded outside Biome. Consider adding a short note in README to explain this to plugin authors.

Happy to draft the README snippet explaining resolution via the Biome runtime vs Node.


30-32: Peer dependency on @biomejs/biome — is it required?

Given this package is types-only and the runtime injects the module, the peer dep on @biomejs/biome may not add value. If kept, please document the rationale; otherwise, consider removing to reduce noise for plugin authors later.

crates/biome_plugin_loader/src/thread_local.rs (4)

28-33: Minor: use a direct cast for pointer type

Not a bug, but we can avoid the const pointer and Some() verbosity. The API accepts a pointer; a simple cast keeps it tidy and avoids questions about mutability.

-            let result = unsafe { win32::FlsSetValue(self.inner, Some(value as *const c_void)) };
+            let result = unsafe { win32::FlsSetValue(self.inner, value as *const c_void) };

76-80: Promote failure checks to hard errors on Unix

pthread_setspecific can fail (EINVAL/ENOMEN). A debug_assert risks dropping failures in release. Prefer assert with a message to surface issues early.

-            let result = unsafe { libc::pthread_setspecific(self.inner, value as *mut c_void) };
-
-            debug_assert_eq!(result, 0);
+            let result = unsafe { libc::pthread_setspecific(self.inner, value as *mut c_void) };
+            assert_eq!(result, 0, "pthread_setspecific failed: {}", result);

124-140: Intentional per-thread leak: document trade-offs and provide an escape hatch

The comment calls out that values aren’t dropped on thread exit, which implies a per-thread leak. That’s likely fine for long-lived worker threads, but can surprise test code and short-lived threads.

  • Please expand the doc comment to state the leak explicitly and why it’s chosen.
  • Consider exposing a cfg(test) only clear() to drop the current thread’s value safely.

Example (outside the shown range):

#[cfg(test)]
impl<T> ThreadLocalCell<T> {
    /// Drops the current thread's value (tests only).
    pub fn clear(&self) {
        unsafe {
            let ptr = self.key.get();
            if !ptr.is_null() {
                drop(Box::from_raw(ptr)); // drop RefCell<T>
                self.key.set(std::ptr::null_mut());
            }
        }
    }
}

101-107: Make ThreadLocalCell Sync so it can be shared across threads

Analyzer plugins are typically shared (Arc) across worker threads. The TLS key is process-wide and operations are thread-safe-by-design; marking Sync enables ergonomic sharing.

Add this (outside the shown range):

// Safe: all access is per-thread via TLS; no cross-thread aliasing of the inner RefCell<T>.
unsafe impl<T> Sync for ThreadLocalCell<T> {}

If you prefer belt-and-braces, gate it with T: 'static to mirror the no-destructor design.

crates/biome_plugin_loader/src/diagnostics.rs (2)

43-51: Parity between Grit and JS compile diagnostics

Grit compile errors preserve the original error as source, whereas JS errors currently don’t (see below). Keeping behaviour consistent improves downstream reporting.

If biome_diagnostics::Error can’t wrap boa_engine::JsError directly, consider storing a stringified version as a source via a lightweight error wrapper type, or attach it as advice.


54-64: Preserve underlying Boa error for richer reporting

Message is helpful, but we lose stack/location by dropping the source. Either wrap the js error as a source or add advice (e.g. LogAdvice) with value.to_string().

For example:

 #[cfg(feature = "js_plugin")]
 impl From<boa_engine::JsError> for PluginDiagnostic {
     fn from(value: boa_engine::JsError) -> Self {
         Self::Compile(CompileDiagnostic {
             message: MessageAndDescription::from(
                 markup! {"Failed to compile the JS plugin: "{value.to_string()}}.to_owned(),
             ),
-            source: None,
+            // If Error::from(value) isn’t available, consider wrapping value.to_string()
+            // into a structured error wrapper or attach it as advice instead.
+            source: None,
         })
     }
 }

Happy to draft a tiny wrapper error if you’d like.

biome.json (1)

27-27: Including plugins/*.js is sensible; watch for noUndeclaredDependencies

With this file now linted, imports like "@biomejs/plugin-api" inside plugins/*.js may trigger correctness/noUndeclaredDependencies since plugins/ isn’t a package. Two options:

  • Add an override to disable that rule for plugins/*.js, or
  • Add a minimal package.json in plugins/ declaring @biomejs/plugin-api as a devDependency.

Example override (outside the shown range):

{
  "overrides": [
    {
      "include": ["plugins/*.js"],
      "linter": {
        "rules": { "correctness": { "noUndeclaredDependencies": "off" } }
      }
    }
  ]
}
plugins/plugin.js (1)

3-8: Tighten sample logic and avoid name shadowing.

Minor polish: use early-return to reduce nesting and rename the parameter to filePath to avoid confusion with Node’s path module.

Apply:

-/** @param {string} path */
-export default function useMyPlugin(path) {
-	if (path.endsWith("plugin.js")) {
-		addDiagnostic("warning", "Hello, world!");
-	}
-}
+/** @param {string} filePath */
+export default function useMyPlugin(filePath) {
+	if (!filePath.endsWith("plugin.js")) return;
+	addDiagnostic("warning", "Hello, world!");
+}
crates/biome_js_runtime/src/lib.rs (1)

1-6: Public re-exports look tidy.

Clear surface area via pub use with private modules. Consider a short crate-level doc to explain the Boa-based runtime and how modules are loaded; future-you will thank you.

crates/biome_service/src/workspace/server.rs (1)

491-496: Arc handoff looks correct; tiny style nit

Passing self.fs.clone() to the new BiomePlugin::load(Arc<dyn FsWithResolverProxy>, …) is spot on. If you want to make the intent extra explicit, consider Arc::clone(&self.fs) (purely stylistic).

crates/biome_js_runtime/src/plugin_api.rs (1)

40-47: Consider including a stable category and optional code for plugin diagnostics

Right now every diagnostic is category!("plugin"). That’s fine for a POC, but you may want category!("plugin/{name}") or a rule code (e.g. with_category/with_code) so users can target-suppress per-plugin in future.

Would you like me to sketch a minimal plugin “name” plumbed from the loader to prefix the category?

crates/biome_js_runtime/src/module_loader.rs (2)

56-60: Enhance diagnostics by naming the module in Module::parse

If Module::parse accepts an optional identifier/source name, pass the specifier (or resolved path) so stack traces and error messages show the module name.


40-47: Base dir fallback

unwrap_or_default() gives an empty path; resolution libraries sometimes treat that oddly. Consider defaulting to the process working directory or / explicitly if working_directory() is None.

crates/biome_plugin_loader/src/lib.rs (2)

62-75: JS plugin detection: consider .mts (and explicitly not .cjs)

You accept .js/.mjs. If you anticipate TS-in-JS plugin transpilation or ESM variants, you might add .mts later. Deliberately skipping .cjs makes sense given ESM-only loader.

Do we want to document the accepted extensions now to avoid plugin author confusion?


97-115: Manifest rule extension check

Using ends_with(b".grit") works but is a tad brittle. rule.extension() == Some("grit") reads clearer and is platform-neutral.

Apply this small refactor?

-                .map(|rule| {
-                    if rule.as_os_str().as_encoded_bytes().ends_with(b".grit") {
+                .map(|rule| {
+                    if rule.extension().is_some_and(|ext| ext == "grit") {
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (2)

27-39: load_plugin ergonomics

LGTM for the core flow (context → import → default export check). Optional: attach the plugin path/specifier to the TypeError message for better UX.


72-108: Good per-thread isolation; consider passing the AST soon

Thread-local context + function entrypoint is a sensible MVP. There’s already a TODO to pass the AST; doing so early will help stabilise the JS API shape.

crates/biome_js_runtime/src/context.rs (3)

1-8: Drop unused import and minor nitpick on Rc cloning

  • The ModuleLoader import (Line 5) isn’t used in this file; this will trip clippy -D warnings in CI.
  • Style: Rc::clone(&module_loader) (Line 27) can be module_loader.clone().

Apply:

- use boa_engine::module::ModuleLoader;

Optional style tweak:

-            .module_loader(Rc::clone(&module_loader))
+            .module_loader(module_loader.clone())

91-96: Default export type is unchecked; consider a function-specific accessor

Downstream code likely expects the default export to be callable. Returning a raw JsValue pushes type errors later and makes crashes more mysterious.

Option A (add a helper, keep current API):

// Add alongside get_default_export
pub fn get_default_export_function(&mut self, module: &Module) -> JsResult<JsFunction> {
    let value = self.get_default_export(module)?;
    let ctx = &mut self.inner;
    let obj = value.as_object().ok_or_else(|| {
        JsNativeError::typ()
            .with_message("Default export is not an object/function")
            .into()
    })?;
    if let Some(func) = obj.as_function() {
        Ok(func.clone())
    } else {
        Err(JsNativeError::typ().with_message("Default export is not a function").into())
    }
}

If Boa’s API differs, adjust to the available “is callable/as function” helpers.


98-105: Call surface is fine; optional ergonomics

Passing an explicit this is flexible, but most plugin functions won’t need it. A convenience call_function_undefined_this (or defaulting this internally) can reduce boilerplate for callers.

Example:

pub fn call_function_undefined_this(
    &mut self,
    function: &JsFunction,
    args: &[JsValue],
) -> JsResult<JsValue> {
    function.call(&JsValue::undefined(), args, &mut self.inner)
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a3fd2f1 and 7b7cf4c.

⛔ Files ignored due to path filters (3)
  • Cargo.lock is excluded by !**/*.lock and included by **
  • crates/biome_plugin_loader/src/snapshots/evaluate_in_worker_threads.snap is excluded by !**/*.snap and included by **
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml and included by **
📒 Files selected for processing (26)
  • .github/workflows/main.yml (1 hunks)
  • .github/workflows/preview.yml (2 hunks)
  • .github/workflows/pull_request.yml (1 hunks)
  • Cargo.toml (4 hunks)
  • biome.json (1 hunks)
  • crates/biome_cli/Cargo.toml (1 hunks)
  • crates/biome_js_analyze/Cargo.toml (1 hunks)
  • crates/biome_js_runtime/Cargo.toml (1 hunks)
  • crates/biome_js_runtime/src/context.rs (1 hunks)
  • crates/biome_js_runtime/src/lib.rs (1 hunks)
  • crates/biome_js_runtime/src/module_loader.rs (1 hunks)
  • crates/biome_js_runtime/src/plugin_api.rs (1 hunks)
  • crates/biome_plugin_loader/Cargo.toml (1 hunks)
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1 hunks)
  • crates/biome_plugin_loader/src/diagnostics.rs (3 hunks)
  • crates/biome_plugin_loader/src/lib.rs (11 hunks)
  • crates/biome_plugin_loader/src/thread_local.rs (1 hunks)
  • crates/biome_service/Cargo.toml (1 hunks)
  • crates/biome_service/src/workspace/server.rs (1 hunks)
  • package.json (1 hunks)
  • packages/@biomejs/plugin-api/LICENSE-APACHE (1 hunks)
  • packages/@biomejs/plugin-api/LICENSE-MIT (1 hunks)
  • packages/@biomejs/plugin-api/index.d.ts (1 hunks)
  • packages/@biomejs/plugin-api/index.js (1 hunks)
  • packages/@biomejs/plugin-api/package.json (1 hunks)
  • plugins/plugin.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_js_analyze/Cargo.toml
  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_service/Cargo.toml
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
  • crates/biome_js_runtime/src/plugin_api.rs
  • crates/biome_plugin_loader/Cargo.toml
  • crates/biome_cli/Cargo.toml
  • Cargo.toml
  • crates/biome_js_runtime/src/module_loader.rs
  • crates/biome_js_runtime/src/lib.rs
  • crates/biome_plugin_loader/src/thread_local.rs
  • crates/biome_service/src/workspace/server.rs
  • crates/biome_js_runtime/src/context.rs
  • crates/biome_plugin_loader/src/lib.rs
  • crates/biome_plugin_loader/src/diagnostics.rs
crates/**/Cargo.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

crates/**/Cargo.toml: In internal crates, use workspace = true for internal dependencies.
Use path dependencies for dev-dependencies in internal crates.

Files:

  • crates/biome_js_analyze/Cargo.toml
  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_service/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • crates/biome_cli/Cargo.toml
{Cargo.toml,crates/**/Cargo.toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep the version field consistent across all crates during release.

Files:

  • crates/biome_js_analyze/Cargo.toml
  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_service/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • crates/biome_cli/Cargo.toml
  • Cargo.toml
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/Cargo.toml
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/Cargo.toml
  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_service/Cargo.toml
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
  • crates/biome_js_runtime/src/plugin_api.rs
  • crates/biome_plugin_loader/Cargo.toml
  • crates/biome_cli/Cargo.toml
  • crates/biome_js_runtime/src/module_loader.rs
  • crates/biome_js_runtime/src/lib.rs
  • crates/biome_plugin_loader/src/thread_local.rs
  • crates/biome_service/src/workspace/server.rs
  • crates/biome_js_runtime/src/context.rs
  • crates/biome_plugin_loader/src/lib.rs
  • crates/biome_plugin_loader/src/diagnostics.rs
Cargo.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Centralize shared dependencies in the root Cargo.toml using workspace dependencies.

Files:

  • Cargo.toml
crates/biome_service/src/workspace/server.rs

📄 CodeRabbit inference engine (crates/biome_service/CONTRIBUTING.md)

Use WorkspaceServer (src/workspace/server.rs) to maintain workspace state in daemon and CLI daemonless modes

Files:

  • crates/biome_service/src/workspace/server.rs
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Add biome_js_formatter as a path dependency in Cargo.toml: biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Add biome_js_formatter as a path dependency in Cargo.toml: biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }

Applied to files:

  • crates/biome_js_analyze/Cargo.toml
  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_service/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • crates/biome_cli/Cargo.toml
  • Cargo.toml
  • crates/biome_plugin_loader/src/lib.rs
  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/Cargo.toml : Add the specified dev-dependencies (biome_formatter_test, biome_html_factory, biome_html_parser, biome_parser, biome_service, countme with feature enable, iai 0.1.1, quickcheck, quickcheck_macros, tests_macros) to Cargo.toml under [dev-dependencies]

Applied to files:

  • crates/biome_js_analyze/Cargo.toml
  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_service/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • crates/biome_cli/Cargo.toml
  • Cargo.toml
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Specify category and severity using #[diagnostic(...)] on the type or derive them from fields

Applied to files:

  • packages/@biomejs/plugin-api/index.d.ts
  • crates/biome_plugin_loader/src/lib.rs
  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-17T08:55:30.118Z
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-17T08:55:30.118Z
Learning: Applies to crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/** : Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • Cargo.toml
📚 Learning: 2025-08-11T11:40:38.097Z
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:40:38.097Z
Learning: Applies to crates/**/Cargo.toml : In internal crates, use `workspace = true` for internal dependencies.

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • Cargo.toml
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace.rs : Implement the Workspace trait in src/workspace.rs

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • Cargo.toml
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-17T08:57:34.751Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:57:34.751Z
Learning: Applies to crates/biome_parser/crates/biome_*_syntax/** : Create a new crate named biome_<language>_syntax under crates/

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • Cargo.toml
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
  • crates/biome_js_runtime/src/plugin_api.rs
  • crates/biome_cli/Cargo.toml
  • crates/biome_plugin_loader/src/lib.rs
📚 Learning: 2025-08-11T11:40:38.097Z
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:40:38.097Z
Learning: Applies to Cargo.toml : Centralize shared dependencies in the root Cargo.toml using workspace dependencies.

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • crates/biome_plugin_loader/Cargo.toml
  • Cargo.toml
📚 Learning: 2025-08-17T08:57:34.751Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:57:34.751Z
Learning: Applies to crates/biome_parser/crates/biome_*_factory/** : Create a new crate named biome_<language>_factory under crates/

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • Cargo.toml
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in biome_lsp’s server.tests.rs

Applied to files:

  • crates/biome_js_runtime/Cargo.toml
  • Cargo.toml
  • crates/biome_plugin_loader/src/lib.rs
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
PR: biomejs/biome#7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.

Applied to files:

  • biome.json
  • packages/@biomejs/plugin-api/package.json
  • packages/@biomejs/plugin-api/index.js
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: For debugging: run commands against the daemon (e.g., `cargo run --bin=biome -- lint --use-server <path>`)

Applied to files:

  • .github/workflows/preview.yml
📚 Learning: 2025-08-11T11:40:38.097Z
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:40:38.097Z
Learning: Applies to crates/**/Cargo.toml : Use path dependencies for dev-dependencies in internal crates.

Applied to files:

  • crates/biome_plugin_loader/Cargo.toml
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options in the `biome_rule_options` crate under `lib/`, with serde- and schemars-compatible derives and `#[serde(rename_all = "camelCase", deny_unknown_fields, default)]`

Applied to files:

  • crates/biome_plugin_loader/Cargo.toml
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Build an intermediate IR via the provided helper APIs when formatting

Applied to files:

  • Cargo.toml
  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • Cargo.toml
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs : Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Applied to files:

  • Cargo.toml
  • crates/biome_js_runtime/src/module_loader.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/lib.rs : Place the plumbing traits and impls (AsFormat, IntoFormat, FormattedIterExt, and their Iterator adapters) in the biome_html_formatter crate’s lib.rs

Applied to files:

  • Cargo.toml
  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace/server.rs : Use WorkspaceServer (src/workspace/server.rs) to maintain workspace state in daemon and CLI daemonless modes

Applied to files:

  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace/client.rs : Use WorkspaceClient (src/workspace/client.rs) to connect to the daemon and communicate with WorkspaceServer

Applied to files:

  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Types implementing Diagnostic must also implement Debug (e.g., use #[derive(Debug, Diagnostic)])

Applied to files:

  • crates/biome_plugin_loader/src/lib.rs
  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_plugin_loader/src/lib.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_test.rs : Create tests/spec_test.rs implementing the run(spec_input_file, _expected_file, test_directory, _file_type) function as shown and include!("language.rs")

Applied to files:

  • crates/biome_plugin_loader/src/lib.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_plugin_loader/src/lib.rs
  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_tests.rs : Create tests/spec_tests.rs in the biome_html_formatter crate that generates tests via tests_macros::gen_tests! for all HTML files at tests/specs/html/**/*.html

Applied to files:

  • crates/biome_plugin_loader/src/lib.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : #[derive(Diagnostic)] can be used on enums only if every variant contains a diagnostic type

Applied to files:

  • crates/biome_plugin_loader/src/lib.rs
📚 Learning: 2025-08-17T08:55:30.118Z
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-17T08:55:30.118Z
Learning: Applies to **/tests/specs/**/*.snap : Use snapshot spec tests stored as .snap files under tests/specs/ (via cargo insta)

Applied to files:

  • crates/biome_plugin_loader/src/lib.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use dbg_write! to debug and inspect the written IR elements during formatter development

Applied to files:

  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use the generic Format trait and FormatNode for AST nodes when implementing the formatter

Applied to files:

  • crates/biome_plugin_loader/src/diagnostics.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the FormatNode trait and implement it for your Node

Applied to files:

  • crates/biome_plugin_loader/src/diagnostics.rs
🧬 Code graph analysis (7)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (5)
crates/biome_plugin_loader/src/lib.rs (2)
  • load_plugin (141-157)
  • load (40-118)
crates/biome_plugin_loader/src/thread_local.rs (3)
  • new (15-22)
  • new (56-70)
  • new (102-106)
crates/biome_js_runtime/src/plugin_api.rs (2)
  • new (17-21)
  • None (42-42)
crates/biome_js_runtime/src/context.rs (1)
  • new (23-36)
crates/biome_js_runtime/src/module_loader.rs (1)
  • new (17-22)
crates/biome_js_runtime/src/plugin_api.rs (2)
packages/@biomejs/plugin-api/index.d.ts (1)
  • Severity (1-1)
crates/biome_js_runtime/src/context.rs (2)
  • new (23-36)
  • pull_diagnostics (39-41)
crates/biome_js_runtime/src/module_loader.rs (1)
crates/biome_js_runtime/src/context.rs (1)
  • new (23-36)
crates/biome_service/src/workspace/server.rs (2)
crates/biome_plugin_loader/src/lib.rs (1)
  • load (40-118)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)
  • load (57-69)
crates/biome_js_runtime/src/context.rs (2)
crates/biome_js_runtime/src/plugin_api.rs (3)
  • new (17-21)
  • pull_diagnostics (73-75)
  • None (42-42)
crates/biome_js_runtime/src/module_loader.rs (1)
  • new (17-22)
crates/biome_plugin_loader/src/lib.rs (6)
crates/biome_fs/src/utils.rs (1)
  • normalize_path (43-72)
crates/biome_service/src/workspace/server.rs (3)
  • fs (1590-1592)
  • fs (1672-1674)
  • new (119-141)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)
  • load (57-69)
crates/biome_js_runtime/src/context.rs (1)
  • new (23-36)
crates/biome_js_runtime/src/module_loader.rs (1)
  • new (17-22)
crates/biome_fs/src/fs/memory.rs (1)
  • default (37-49)
crates/biome_plugin_loader/src/diagnostics.rs (1)
crates/biome_service/src/diagnostics.rs (8)
  • fmt (172-174)
  • fmt (178-180)
  • fmt (538-540)
  • message (357-364)
  • message (403-419)
  • message (499-501)
  • message (563-572)
  • message (642-650)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (26)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Documentation
  • GitHub Check: Test Node.js API
  • GitHub Check: Check JS Files
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_css_parser)
🔇 Additional comments (25)
crates/biome_js_analyze/Cargo.toml (2)

43-43: Patch bump to roaring looks good.

0.11.2 is a safe patch upgrade; no objections from me.


43-43: All roaring dependencies aligned at 0.11.2
Scanned every Cargo.toml and the lockfile only lists roaring v0.11.2—no mismatches or duplicates. Lockfile refresh isn’t needed.

packages/@biomejs/plugin-api/LICENSE-MIT (2)

1-22: MIT licence file added — spot on.

Standard text, correct attribution. Thanks for keeping the legal ducks in a row.


1-22: Ensure npm metadata matches the chosen licence(s).

If this package is dual-licensed (MIT/Apache-2.0 like the rest of the repo), please confirm packages/@biomejs/plugin-api/package.json has license: "MIT OR Apache-2.0" (or just "MIT" if that’s the intent).

packages/@biomejs/plugin-api/index.js (2)

1-3: Guardrail import that throws — sensible defensive move.

Clear signal if someone tries to use this outside the Biome runtime. No objections.


1-3: ✅ Verification complete: loader intercepts and bridged module provided

  • In crates/biome_js_runtime/src/context.rs the loader registers "@biomejs/plugin-api" via module_loader.register_module (lines 29–33).
  • In crates/biome_plugin_loader/src/analyzer_js_plugin.rs the plugin imports from "@biomejs/plugin-api", confirming the runtime wiring (lines 147–151).
  • The suggested package @biomejs/js-api exists under packages/@biomejs/js-api with a valid package.json.

No changes required—this throw will never fire. Carry on!

.github/workflows/preview.yml (1)

76-76: Enabling js_plugin in preview builds looks good.

Nice and surgical: only the CLI is built with --features=js_plugin and only in preview. That keeps the feature well-gated while you iterate.

Also applies to: 132-132

crates/biome_js_runtime/Cargo.toml (1)

13-21: Workspace deps are correctly referenced.

All internal crates use workspace = true. Third-party crates are also pulled from the workspace, aligning with the repo’s centralised dependency policy. Ship it.

packages/@biomejs/plugin-api/LICENSE-APACHE (1)

1-3: License file included — all good.

Standard Apache-2.0 text present. Cheers for dual-licensing hygiene.

crates/biome_plugin_loader/src/diagnostics.rs (1)

142-155: Nice: switch to MessageAndDescription

Good move. This unifies message and description handling and plays nicely with the console formatter and snapshots.

crates/biome_service/Cargo.toml (1)

83-84: Feature wiring looks good

Transitive enablement of biome_plugin_loader/js_plugin from biome_service is clean and keeps the path opt-in. No further changes needed here.

crates/biome_cli/Cargo.toml (1)

92-94: CLI feature exposure is tidy

Exposing js_plugin at the CLI level via biome_service/js_plugin is exactly what we need. It remains non-default, which fits the “preview” gating.

package.json (1)

21-21: All green for @biomejs/plugin-api
Both index.js and index.d.ts were found under packages/@biomejs/plugin-api. Ready to ship!

crates/biome_plugin_loader/Cargo.toml (3)

33-35: Optional, workspace-managed deps for the JS runtime are spot on.

Using workspace = true with optional = true keeps compile costs down unless js_plugin is enabled. Nice.


43-44: Dev-deps wired to the workspace.

biome_js_parser and insta via workspace are consistent with our guidelines.


36-41: Seems our sandbox can’t cross-compile (no /proc), so the checks didn’t run. Could you please verify locally that:

cargo check -p biome_plugin_loader --no-default-features --features js_plugin --target x86_64-unknown-linux-gnu
cargo check -p biome_plugin_loader --no-default-features --features js_plugin --target aarch64-apple-darwin
cargo check -p biome_plugin_loader --no-default-features --features js_plugin --target x86_64-pc-windows-msvc

all pass cleanly?

Cargo.toml (1)

139-139: Dependency feature graph & cross-target checks need your local run

The sandbox couldn’t execute cargo tree or cargo check (no /proc/self/exe), so please run these on your machine and share the outputs to confirm the JS runtime graph and versions:

• Generate the feature graph for js_plugin:

cargo tree -p biome_plugin_loader --features js_plugin -e features \
  | rg -n 'boa_engine|windows|libc|biome_js_runtime'

• Cross-target build verification:

for target in x86_64-unknown-linux-gnu aarch64-apple-darwin x86_64-pc-windows-msvc; do
  echo "==> Checking target: $target"
  cargo check --workspace --no-default-features \
    --features biome_plugin_loader/js_plugin --target "$target"
done

Let me know the results so we can sign off on the pinned versions and workspace setup.

crates/biome_js_runtime/src/plugin_api.rs (1)

73-75: LGTM: cheap drain with mem::take

Returning and clearing the collected diagnostics atomically is perfect here.

crates/biome_plugin_loader/src/lib.rs (3)

8-15: Feature-gated JS plugin plumbing looks tidy

Clean separation under #[cfg(feature = "js_plugin")] and re-export is good.


41-46: API change to Arc<dyn FsWithResolverProxy> is applied correctly

Switching from &dyn to Arc<dyn …> here aligns with downstream runtime needs. Nice.


153-156: Tests updated for Arc<dyn FsWithResolverProxy> look correct

The memory FS wrapping and new loads pass muster. The JS single-rule test is a nice sanity check.

Also applies to: 165-166, 181-183, 198-200, 209-213, 215-229

crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)

119-195: Concurrency smoke test is solid

Nice coverage across two threads; snapshots make regressions obvious.

crates/biome_js_runtime/src/context.rs (3)

16-20: Nice encapsulation of runtime state

JsExecContext cleanly bundles the Boa Context, FS proxy and plugin API; good separation of concerns.


22-36: Constructor looks solid; module pre-registration is neat

Initialising the loader, building the context and pre-registering @biomejs/plugin-api up-front is a good call. Keeps plugin code simple.


38-41: Diagnostic drain is tidy

Forwarding to JsPluginApi::pull_diagnostics is exactly what we want here.

siketyan and others added 3 commits August 27, 2025 02:54
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

♻️ Duplicate comments (1)
crates/biome_plugin_loader/src/thread_local.rs (1)

15-24: Make Key::new() fallible (don’t panic on FlsAlloc failure).

FlsAlloc may return FLS_OUT_OF_INDEXES (u32::MAX). Panicking in release is unfriendly; return an io::Result and propagate instead. Mirrors the same concern on Unix (see below).

-    impl<T> Key<T> {
-        pub(super) unsafe fn new() -> Self {
-            let inner = unsafe { win32::FlsAlloc(None) };
-            // FlsAlloc returns FLS_OUT_OF_INDEXES (u32::MAX) on failure.
-            assert!(inner != u32::MAX, "FlsAlloc failed: out of FLS indexes");
-
-            Self {
-                inner,
-                _phantom: PhantomData,
-            }
-        }
+    impl<T> Key<T> {
+        pub(super) unsafe fn new() -> std::io::Result<Self> {
+            let inner = win32::FlsAlloc(None);
+            // FlsAlloc returns FLS_OUT_OF_INDEXES (u32::MAX) on failure.
+            if inner == u32::MAX {
+                return Err(std::io::Error::new(
+                    std::io::ErrorKind::Other,
+                    "FlsAlloc failed: out of FLS indexes",
+                ));
+            }
+            Ok(Self { inner, _phantom: PhantomData })
+        }
🧹 Nitpick comments (2)
crates/biome_plugin_loader/src/thread_local.rs (2)

93-101: Consider installing TLS destructors to prevent per-thread leaks.

You’re intentionally leaking the per-thread Box to dodge drop-order hazards. If that becomes an issue under high churn threads, add a destructor (FlsAlloc callback / pthread_key_create dtor) that only frees the Box, or provide a clear_current_thread() for deterministic cleanup.

Would you like me to open a follow-up to prototype a safe destructor that avoids the double-free scenario you’ve seen?


125-134: Minor: document safety invariants around raw pointer use.

A brief SAFETY: comment stating why casting from TLS pointer and borrowing is sound (one Box per thread, never freed, RefCell borrow discipline) will help future maintainers.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e94c573 and e36b0f4.

📒 Files selected for processing (1)
  • crates/biome_plugin_loader/src/thread_local.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_plugin_loader/src/thread_local.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_plugin_loader/src/thread_local.rs
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Add biome_js_formatter as a path dependency in Cargo.toml: biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: Test Node.js API
  • GitHub Check: autofix
  • GitHub Check: Check JS Files
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_json_formatter)

Copy link
Contributor

@arendjr arendjr left a comment

Choose a reason for hiding this comment

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

Love it!

Left a few comments, and CodeRabbit also pointed out some unwraps that I think would be good to address before merging, but I like where this is going!

siketyan and others added 2 commits August 27, 2025 16:50
@siketyan siketyan force-pushed the feat/js-plugin-poc branch from df63ea0 to 317f1a9 Compare August 27, 2025 15:45
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (3)

27-39: Consider adding timeout protection for plugin loading.

Since JS plugins can potentially hang during module loading (infinite loops, blocking operations), you might want to add a timeout mechanism to prevent the loader from hanging indefinitely.

Would you like me to suggest an implementation using a timeout wrapper around the load operation?


73-108: Consider adding resource limits for plugin execution.

JS plugins could potentially consume excessive memory or CPU. Consider implementing resource limits (memory usage, execution time) to protect against misbehaving plugins.

You might want to explore Boa's built-in limits API or wrap the execution in a timeout to prevent runaway plugins from affecting the host application's performance.


90-90: Track the AST passing TODO.

The TODO indicates AST needs to be passed to the plugin. This is a core feature for plugins to analyse code structure.

Would you like me to create an issue to track implementing the AST serialisation and passing mechanism to JS plugins?

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 907af24 and 317f1a9.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock and included by **
📒 Files selected for processing (8)
  • crates/biome_js_runtime/src/context.rs (1 hunks)
  • crates/biome_js_runtime/src/module_loader.rs (1 hunks)
  • crates/biome_js_runtime/src/plugin_api.rs (1 hunks)
  • crates/biome_plugin_loader/Cargo.toml (1 hunks)
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1 hunks)
  • crates/biome_plugin_loader/src/thread_local.rs (1 hunks)
  • packages/@biomejs/plugin-api/index.d.ts (1 hunks)
  • plugins/plugin.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/@biomejs/plugin-api/index.d.ts
  • crates/biome_plugin_loader/Cargo.toml
  • crates/biome_js_runtime/src/plugin_api.rs
  • plugins/plugin.js
  • crates/biome_js_runtime/src/module_loader.rs
  • crates/biome_plugin_loader/src/thread_local.rs
  • crates/biome_js_runtime/src/context.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Add biome_js_formatter as a path dependency in Cargo.toml: biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use the local `rule_category!()` macro in diagnostics for the rule’s category, not string-parsed categories

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options in the `biome_rule_options` crate under `lib/`, with serde- and schemars-compatible derives and `#[serde(rename_all = "camelCase", deny_unknown_fields, default)]`

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Types implementing Diagnostic must also implement Debug (e.g., use #[derive(Debug, Diagnostic)])

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Specify category and severity using #[diagnostic(...)] on the type or derive them from fields

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Mark code blocks in docs with a language and required properties: use `expect_diagnostic` for invalid examples (exactly one diagnostic), `options`/`full_options` for config blocks, and `use_options` for subsequent examples

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
🧬 Code graph analysis (1)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (5)
crates/biome_plugin_loader/src/diagnostics.rs (6)
  • from (44-51)
  • from (56-63)
  • from (67-69)
  • from (73-75)
  • from (79-81)
  • from (137-139)
crates/biome_plugin_loader/src/lib.rs (2)
  • load_plugin (141-157)
  • load (40-118)
crates/biome_js_runtime/src/context.rs (1)
  • new (25-38)
crates/biome_js_runtime/src/plugin_api.rs (2)
  • new (17-21)
  • None (51-51)
crates/biome_plugin_loader/src/thread_local.rs (3)
  • new (15-24)
  • new (57-71)
  • new (106-110)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Check JS Files
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: autofix
🔇 Additional comments (2)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (2)

56-69: Good fix for the load error handling!

The plugin is now properly loaded upfront to catch errors early, addressing the previous concern about swallowed errors.


142-194: Well-structured multithreading test!

The test effectively validates thread-local plugin isolation by running two workers with separate files and ensuring diagnostics are produced correctly.

@siketyan siketyan force-pushed the feat/js-plugin-poc branch from 317f1a9 to 7ba2798 Compare August 27, 2025 15:54
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (6)
crates/biome_plugin_loader/src/thread_local.rs (6)

15-24: Prefer a fallible constructor for TLS key allocation

Panic on FlsAlloc == u32::MAX isn’t great UX in release. Return io::Result<Self> and propagate.

Example:

-        pub(super) unsafe fn new() -> Self {
+        pub(super) unsafe fn new() -> std::io::Result<Self> {
             let inner = unsafe { win32::FlsAlloc(None) };
-            // FlsAlloc returns FLS_OUT_OF_INDEXES (u32::MAX) on failure.
-            assert!(inner != u32::MAX, "FlsAlloc failed: out of FLS indexes");
+            if inner == u32::MAX {
+                return Err(std::io::Error::new(std::io::ErrorKind::Other, "FlsAlloc: FLS_OUT_OF_INDEXES"));
+            }
-            Self {
+            Ok(Self {
                 inner,
                 _phantom: PhantomData,
-            }
+            })
         }

Follow-up: bubble this through ThreadLocalCell::new().


56-71: POSIX: make pthread_key_create path fallible

Mirror Windows: don’t assert, return io::Result.

Apply:

-        pub(super) unsafe fn new() -> Self {
-            let inner = unsafe {
-                let mut inner = MaybeUninit::uninit();
-                let result = libc::pthread_key_create(inner.as_mut_ptr(), None);
-
-                assert_eq!(result, 0);
-
-                inner.assume_init()
-            };
-
-            Self {
-                inner,
-                _phantom: PhantomData,
-            }
-        }
+        pub(super) unsafe fn new() -> std::io::Result<Self> {
+            let mut inner = MaybeUninit::uninit();
+            let rc = libc::pthread_key_create(inner.as_mut_ptr(), None);
+            if rc != 0 {
+                return Err(std::io::Error::from_raw_os_error(rc));
+            }
+            Ok(Self { inner: inner.assume_init(), _phantom: PhantomData })
+        }

77-81: POSIX: don’t ignore pthread_setspecific failures

A failed set leads to a later unwrap() panic. Assert or, better, return Result.

Minimal change:

-        pub(super) unsafe fn set(&self, value: *mut T) {
-            let result = unsafe { libc::pthread_setspecific(self.inner, value as *mut c_void) };
-
-            debug_assert_eq!(result, 0);
-        }
+        pub(super) unsafe fn set(&self, value: *mut T) {
+            let rc = libc::pthread_setspecific(self.inner, value as *mut c_void);
+            debug_assert_eq!(rc, 0, "pthread_setspecific failed");
+        }

102-110: Remove the panic edge after set(); propagate TLS errors from get_mut_or_try_init

self.set(value); Ok(self.get_mut().unwrap()) will panic if the platform set() fails. Make set() return io::Result<()> and map errors in get_mut_or_try_init.

Sketch:

-    pub(crate) fn new() -> Self {
-        Self { key: unsafe { platform::Key::new() }, }
-    }
+    pub(crate) fn new() -> std::io::Result<Self> {
+        Ok(Self { key: unsafe { platform::Key::new()? } })
+    }

-    pub(crate) fn get_mut_or_try_init<F, E>(&self, default: F) -> Result<RefMut<'_, T>, E>
+    pub(crate) fn get_mut_or_try_init<F, E>(&self, default: F) -> Result<RefMut<'_, T>, E>
     where
         F: FnOnce() -> Result<T, E>,
     {
         match self.get_mut() {
             Some(r) => Ok(r),
             _ => match default() {
-                Ok(value) => {
-                    self.set(value);
-                    Ok(self.get_mut().unwrap())
-                }
+                Ok(value) => {
+                    self.set(value); // now returns io::Result<()>
+                    // map TLS error into E if you prefer a unified error type
+                    Ok(self.get_mut().expect("TLS set succeeded but value missing"))
+                }
                 Err(err) => Err(err),
             },
         }
     }

-    fn set(&self, value: T) {
+    fn set(&self, value: T) {
         let cell = Box::into_raw(Box::new(RefCell::new(value)));
-        unsafe { self.key.set(cell); }
+        unsafe { self.key.set(cell); /* -> io::Result<()> in platform layer */ }
     }

Happy to wire a small TlsInitError<E> enum if you want the full error story.

Also applies to: 112-126, 139-145


29-33: Windows: FlsSetValue check is wrong; use .as_bool() and handle failure

windows BOOL doesn’t have .is_ok(). This is a build breaker on Windows targets.

Apply:

-        pub(super) unsafe fn set(&self, value: *mut T) {
-            let result = unsafe { win32::FlsSetValue(self.inner, Some(value as *const c_void)) };
-
-            debug_assert!(result.is_ok());
-        }
+        pub(super) unsafe fn set(&self, value: *mut T) {
+            let ok = win32::FlsSetValue(self.inner, Some(value as *const c_void)).as_bool();
+            debug_assert!(ok, "FlsSetValue failed");
+        }

36-41: Windows: FlsFree check is wrong; use .as_bool()

Same issue as above; .is_ok() will not compile.

Apply:

-        fn drop(&mut self) {
-            let result = unsafe { win32::FlsFree(self.inner) };
-
-            debug_assert!(result.is_ok());
-        }
+        fn drop(&mut self) {
+            let ok = unsafe { win32::FlsFree(self.inner) }.as_bool();
+            debug_assert!(ok, "FlsFree failed");
+        }
🧹 Nitpick comments (6)
crates/biome_js_runtime/src/module_loader.rs (2)

57-58: Set source path for better stack traces

Attach the resolved path to Source so errors show correct filenames.

Apply:

-                        let source = Source::from_bytes(source.as_bytes());
+                        let source = Source::from_bytes(source.as_bytes()).with_path(path.as_std_path());

33-36: Cache key may collide across different referrers; confirm Boa’s specifier semantics

You key the cache by the raw specifier string. If two modules in different directories import the same relative specifier (e.g. "./config.js"), you may return the wrong cached module. If Boa passes the original (unresolved) specifier into get_module, this is a real hazard.

Options:

  • Key by the resolved absolute path (preferred), and in load_imported_module consult this map first.
  • Or maintain a secondary map keyed by (referrer_path, specifier).

Would you confirm Boa’s contract for get_module/register_module specifiers? If it’s unresolved, we should switch to a resolved-path cache.

Also applies to: 40-47, 52-59, 86-88

crates/biome_plugin_loader/src/analyzer_js_plugin.rs (3)

50-53: Include plugin path in Debug output

Handy when multiple plugins are loaded.

Apply:

 impl Debug for AnalyzerJsPlugin {
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("AnalyzerJsPlugin").finish_non_exhaustive()
+        f.debug_struct("AnalyzerJsPlugin")
+            .field("path", &self.path)
+            .finish_non_exhaustive()
     }
 }

80-85: Add plugin path to the “could not load” diagnostic

Gives users immediate context.

Apply:

-                return vec![RuleDiagnostic::new(
+                return vec![RuleDiagnostic::new(
                     category!("plugin"),
                     None::<TextRange>,
-                    markup!("Could not load the plugin: "<Error>{err.to_string()}</Error>),
+                    markup!("Could not load the plugin "<Emphasis>{self.path.as_str()}</Emphasis>": "<Error>{err.to_string()}</Error>),
                 )];

99-105: Include plugin path in runtime error diagnostic

Same rationale as above.

Apply:

-                    vec![RuleDiagnostic::new(
+                    vec![RuleDiagnostic::new(
                         category!("plugin"),
                         None::<TextRange>,
-                        markup!("Plugin errored: "<Error>{err.to_string()}</Error>),
+                        markup!("Plugin "<Emphasis>{self.path.as_str()}</Emphasis>" errored: "<Error>{err.to_string()}</Error>),
                     )]
crates/biome_js_runtime/src/context.rs (1)

48-53: Enrich I/O error with path

The extra context helps debugging.

Apply:

-        let source = self
-            .fs
-            .read_file_from_path(path)
-            .map_err(|err| JsNativeError::error().with_message(err.to_string()))?;
+        let source = self
+            .fs
+            .read_file_from_path(path)
+            .map_err(|err| JsNativeError::error().with_message(format!("Failed to read {}: {}", path, err)))?;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 317f1a9 and 7ba2798.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock and included by **
📒 Files selected for processing (8)
  • crates/biome_js_runtime/src/context.rs (1 hunks)
  • crates/biome_js_runtime/src/module_loader.rs (1 hunks)
  • crates/biome_js_runtime/src/plugin_api.rs (1 hunks)
  • crates/biome_plugin_loader/Cargo.toml (1 hunks)
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1 hunks)
  • crates/biome_plugin_loader/src/thread_local.rs (1 hunks)
  • packages/@biomejs/plugin-api/index.d.ts (1 hunks)
  • plugins/plugin.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • plugins/plugin.js
  • packages/@biomejs/plugin-api/index.d.ts
  • crates/biome_js_runtime/src/plugin_api.rs
  • crates/biome_plugin_loader/Cargo.toml
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_js_runtime/src/module_loader.rs
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
  • crates/biome_plugin_loader/src/thread_local.rs
  • crates/biome_js_runtime/src/context.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_runtime/src/module_loader.rs
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
  • crates/biome_plugin_loader/src/thread_local.rs
  • crates/biome_js_runtime/src/context.rs
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Add biome_js_formatter as a path dependency in Cargo.toml: biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs : Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Applied to files:

  • crates/biome_js_runtime/src/module_loader.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use the local `rule_category!()` macro in diagnostics for the rule’s category, not string-parsed categories

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Specify category and severity using #[diagnostic(...)] on the type or derive them from fields

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Types implementing Diagnostic must also implement Debug (e.g., use #[derive(Debug, Diagnostic)])

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options in the `biome_rule_options` crate under `lib/`, with serde- and schemars-compatible derives and `#[serde(rename_all = "camelCase", deny_unknown_fields, default)]`

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Mark code blocks in docs with a language and required properties: use `expect_diagnostic` for invalid examples (exactly one diagnostic), `options`/`full_options` for config blocks, and `use_options` for subsequent examples

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
🧬 Code graph analysis (3)
crates/biome_js_runtime/src/module_loader.rs (2)
crates/biome_js_runtime/src/context.rs (1)
  • new (25-38)
crates/biome_js_runtime/src/plugin_api.rs (1)
  • new (17-21)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (5)
crates/biome_plugin_loader/src/lib.rs (1)
  • load (40-118)
crates/biome_js_runtime/src/context.rs (1)
  • new (25-38)
crates/biome_js_runtime/src/module_loader.rs (1)
  • new (17-22)
crates/biome_js_runtime/src/plugin_api.rs (2)
  • new (17-21)
  • None (51-51)
crates/biome_plugin_loader/src/thread_local.rs (3)
  • new (15-24)
  • new (57-71)
  • new (106-110)
crates/biome_js_runtime/src/context.rs (2)
crates/biome_js_runtime/src/module_loader.rs (1)
  • new (17-22)
crates/biome_js_runtime/src/plugin_api.rs (2)
  • new (17-21)
  • pull_diagnostics (82-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Documentation
  • GitHub Check: End-to-end tests
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test Node.js API
  • GitHub Check: Check JS Files
  • GitHub Check: autofix
🔇 Additional comments (2)
crates/biome_js_runtime/src/module_loader.rs (1)

60-67: Nice: cache after parse to avoid re-parsing

Good addition; this prevents duplicate work and aligns with Boa’s expectations.

crates/biome_js_runtime/src/context.rs (1)

90-95: Double-check JsError::try_native return type for your Boa version

Some versions return Option<JsNativeError>, others a Result. Your match uses Ok(native), which may be incompatible.

If it returns Option, prefer:

if let Some(native) = opaque.try_native(ctx) {
    break Err(native.into());
}
break Err(opaque);

Else keep the current Result-based handling.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
crates/biome_js_runtime/src/module_loader.rs (1)

68-71: Nice: parsed modules are cached

This addresses redundant parsing; good alignment with Boa’s loader contract and prior feedback.

🧹 Nitpick comments (2)
crates/biome_js_runtime/src/module_loader.rs (1)

50-52: Tiny clean-up: simplify default init

Minor readability win.

-        let options = ResolveOptions {
-            ..Default::default()
-        };
+        let options = ResolveOptions::default();
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)

100-109: Optional: include JS stack in error diagnostics

If available, prefer a representation that preserves the JS stack/frames for quicker debugging.

Example (if Boa exposes it):

-            .map_or_else(
-                |err| {
+            .map_or_else(
+                |err| {
                     vec![RuleDiagnostic::new(
                         category!("plugin"),
                         None::<TextRange>,
-                        markup!("Plugin errored: "<Error>{err.to_string()}</Error>),
+                        markup!("Plugin errored: "<Error>{err.display().to_string()}</Error>),
                     )]
                 },

Happy to wire a helper that formats Boa errors consistently across plugin diagnostics.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7ba2798 and 26c3e9e.

📒 Files selected for processing (3)
  • crates/biome_js_runtime/src/context.rs (1 hunks)
  • crates/biome_js_runtime/src/module_loader.rs (1 hunks)
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_js_runtime/src/context.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_js_runtime/src/module_loader.rs
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_runtime/src/module_loader.rs
  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Add biome_js_formatter as a path dependency in Cargo.toml: biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs : Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Applied to files:

  • crates/biome_js_runtime/src/module_loader.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference resolves TypeReference::Import across modules into TypeReference::Resolved using the module graph; do not cache full-inference results

Applied to files:

  • crates/biome_js_runtime/src/module_loader.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use the local `rule_category!()` macro in diagnostics for the rule’s category, not string-parsed categories

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Specify category and severity using #[diagnostic(...)] on the type or derive them from fields

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options in the `biome_rule_options` crate under `lib/`, with serde- and schemars-compatible derives and `#[serde(rename_all = "camelCase", deny_unknown_fields, default)]`

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Types implementing Diagnostic must also implement Debug (e.g., use #[derive(Debug, Diagnostic)])

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Mark code blocks in docs with a language and required properties: use `expect_diagnostic` for invalid examples (exactly one diagnostic), `options`/`full_options` for config blocks, and `use_options` for subsequent examples

Applied to files:

  • crates/biome_plugin_loader/src/analyzer_js_plugin.rs
🧬 Code graph analysis (2)
crates/biome_js_runtime/src/module_loader.rs (1)
crates/biome_js_runtime/src/context.rs (1)
  • new (25-38)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (4)
crates/biome_plugin_loader/src/lib.rs (1)
  • load (40-118)
crates/biome_js_runtime/src/context.rs (1)
  • new (25-38)
crates/biome_js_runtime/src/plugin_api.rs (2)
  • new (17-21)
  • None (51-51)
crates/biome_plugin_loader/src/thread_local.rs (3)
  • new (15-24)
  • new (57-71)
  • new (106-110)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Documentation
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: autofix
  • GitHub Check: Check JS Files
  • GitHub Check: Test Node.js API
🔇 Additional comments (1)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)

63-65: No mapping needed—JsError already converts to PluginDiagnostic

There’s an existing impl From<boa_engine::JsError> for PluginDiagnostic in crates/biome_plugin_loader/src/diagnostics.rs:55, so the ? on a JsResult will automatically convert a JsError into a PluginDiagnostic. The code compiles as-is.

Likely an incorrect or invalid review comment.

@siketyan siketyan merged commit 1d2d4b1 into biomejs:main Aug 28, 2025
30 checks passed
Copy link
Member

Choose a reason for hiding this comment

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

Was this file used for testing purposes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, and I would keep it for an example of the plugin. Plus we can include it in the E2E test after lifted the js_plugin feature

Copy link
Member

Choose a reason for hiding this comment

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

If that's the case, should we add the package inside the peer dependencies?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! I'll do it in a follow-up PR

Copy link
Member

Choose a reason for hiding this comment

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

We should pull the type from workspace.ts

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, but I would avoid depending on the @biomejs/backend-jsonrpc package as most part of it is unnecessary. I'll add a codegen for AST types later and will include the type of Severity there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Linter Area: linter A-Project Area: project L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载