-
-
Notifications
You must be signed in to change notification settings - Fork 714
fix(css): allow navigation property for view-transition (fixes #7340) #7352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…tic message Fixed missing 'is' in the diagnostic message for the noDuplicateObjectKeys rule when applied to JSON files. The message now correctly reads 'This is where a duplicated key was declared again.' instead of 'This where a duplicated key was declared again.' Fixes biomejs#7307
…s#7340) - Adds 'navigation' to known CSS properties - Adds test to ensure 'navigation: auto' is not flagged as unknown - Follows CSS View Transitions spec: https://www.w3.org/TR/css-view-transitions-2/#view-transition-navigation-descriptor
…jectKeys/invalid.json.snap
🦋 Changeset detectedLatest commit: f0cf1c2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughThis PR adds CSS support for the navigation property by updating the known properties list and expands tests to cover it. It introduces a JavaScript plugin runtime (Boa-based) with a module loader, execution context, and plugin API. The plugin loader gains a js_plugin feature and thread-local handling. CI workflows are updated to build/test with the js_plugin feature and bump some action versions. It adjusts JSX-everywhere handling, adds a plugins/*.js include, and introduces an example JS plugin and a new @biomejs/plugin-api package. Minor lints, dependencies, and one rule implementation (exponentiation) are updated. Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
.github/workflows/preview.yml (2)
1-7
: Split workflow update from CSS lint changes
This PR only updates.github/workflows/preview.yml
; no CSS navigation property ornoUnknownProperty
rule modifications were detected. Include the intended lint change or split into separate PRs.
76-82
: Fix undefined BIOME_VERSION env var
- In
.github/workflows/preview.yml
build steps (bothbuild-binaries
andbuild-binaries-gnu
),BIOME_VERSION: ${{ env.cli-version }}
refers to a non-existentcli-version
; replace withneeds.version.outputs.version
(orenv.version
).crates/biome_service/src/file_handlers/javascript.rs (1)
523-528
: Potential mis-detection of file source in parse(): fallback to path removed.
parse()
now uses onlydocument_file_source.to_js_file_source().unwrap_or_default()
. Elsewhere (e.g. resolve_format_options at Lines 190–195 and lint at Lines 704–714) you also fall back toJsFileSource::try_from(path)
. Without that,.tsx/.jsx
or module/script mode inferred from the path can silently default toJsFileSource::js_module()
, changing parser behaviour.Apply for consistency:
- let file_source = file_source.to_js_file_source().unwrap_or_default(); + let file_source = file_source + .to_js_file_source() + .or(JsFileSource::try_from(biome_path.as_path()).ok()) + .unwrap_or_default();crates/biome_js_runtime/Cargo.toml (1)
1-24
: Addcrates/biome_js_runtime
to the root[workspace].members
in Cargo.toml
The crate isn’t listed underworkspace.members
, so itsworkspace = true
deps won’t resolve correctly.crates/biome_plugin_loader/src/lib.rs (1)
98-116
: Avoid unwrap on potentially non‑UTF8 paths from the manifest.Utf8PathBuf::from_path_buf(rule).unwrap() can panic. Convert to a PluginDiagnostic instead.
- .map(|rule| Utf8PathBuf::from_path_buf(rule).unwrap()) + .map(|rule| { + Utf8PathBuf::from_path_buf(rule).ok_or_else(|| { + PluginDiagnostic::unsupported_rule_format(markup!( + "Manifest rule path is not valid UTF-8" + )) + }) + }) + .collect::<Result<Vec<_>, _>>()? + .into_iter() .map(|rule| {
🧹 Nitpick comments (37)
crates/biome_json_analyze/src/lint/suspicious/no_duplicate_object_keys.rs (1)
86-86
: Prefer “duplicate key”; drop the redundant “again”.Reads more naturally and matches the rule name. “Duplicate” implies repetition.
- "This is where a duplicated key was declared again." + "This is where a duplicate key was declared."crates/biome_css_analyze/tests/specs/correctness/noUnknownProperty/valid.css (1)
71-74
: Nit: use the at-rule form for spec accuracyThe descriptor lives under the
@view-transition
at-rule. Using the at-rule keeps the example self-documenting.-/* View Transition navigation property (should not be flagged) */ -view-transition { +/* View Transition navigation descriptor (should not be flagged) */ +@view-transition { navigation: auto; }crates/biome_js_analyze/src/lint/style/use_exponentiation_operator.rs (2)
174-191
: Function now returns onlySome(true)
orNone
; consider simplifying.
does_exponentiation_expression_need_parens
never returnsSome(false)
. You can simplify the API to returnbool
and treat indeterminate cases asfalse
. Not blocking, but it trims a little noise.Suggested refactor within this hunk:
- fn does_exponentiation_expression_need_parens(node: &JsCallExpression) -> Option<bool> { + fn does_exponentiation_expression_need_parens(node: &JsCallExpression) -> bool { - if let Some(parent) = node.parent::<AnyJsExpression>() { - if does_expression_need_parens(node, &parent)? { - return Some(true); - } - } else if let Some(extends_clause) = node.parent::<JsExtendsClause>() { + if let Some(parent) = node.parent::<AnyJsExpression>() { + if does_expression_need_parens(node, &parent).unwrap_or(false) { + return true; + } + } else if let Some(extends_clause) = node.parent::<JsExtendsClause>() { if extends_clause.parent::<JsClassDeclaration>().is_some() { - return Some(true); + return true; } if let Some(class_expr) = extends_clause.parent::<JsClassExpression>() { let class_expr = AnyJsExpression::from(class_expr); - if does_expression_need_parens(node, &class_expr)? { - return Some(true); + if does_expression_need_parens(node, &class_expr).unwrap_or(false) { + return true; } } } - None + false }And the corresponding call site (shown here for context outside this hunk):
- if let Some(true) = does_exponentiation_expression_need_parens(node) { + if does_exponentiation_expression_need_parens(node) {
131-134
: Potential trivia mix‑up (duplicated leading trivia).You append
separator.leading_trivia()
twice; the second one likely wants the trailing trivia. This looks like a tiny copy‑paste slip.- .append_trivia_pieces(chain_trivia_pieces( - separator.leading_trivia().pieces(), - separator.leading_trivia().pieces(), - ))?; + .append_trivia_pieces(chain_trivia_pieces( + separator.leading_trivia().pieces(), + separator.trailing_trivia().pieces(), + ))?;.changeset/use_readonly_class_properties_nested_assignment_fix.md (1)
1-3
: Rename the changeset file to reflect the actual change.Current name references
useReadonlyClassProperties
. Suggest something like:fix-css-no-unknown-property-navigation.md
.crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts (2)
677-687
: Typo in class name.If you keep this test elsewhere, rename
TesAssignmentInNestedCallback
→TestAssignmentInNestedCallback
.-class TesAssignmentInNestedCallback { +class TestAssignmentInNestedCallback {
681-685
: Guard against potential type-check hiccups in tests.If the harness type-checks, declare ambient
ui
/x
to avoid errors, or replace with a self-contained example.- ui.showText("example", { + declare const ui: { showText(msg: string, opts: { callback: () => void }): void }; + declare const x: unknown; + ui.showText("example", {biome.json (1)
27-27
: Include pattern may miss nested plugin filesIf the intent is to lint all plugin JS files, prefer a recursive glob. Also, confirm this inclusion is intended in a PR aimed at CSS property recognition.
- "plugins/*.js", + "plugins/**/*.js",Would you like this broadened, or should we drop the plugin include from this CSS-focused PR?
.github/workflows/pull_request.yml (1)
88-88
: Running tests with js_plugin only—consider a no-feature job tooEnabling features in CI can mask regressions in the default build. Suggest adding a second test step/job without features.
- - name: Run tests - run: cargo test --workspace --features=js_plugin + - name: Run tests (js_plugin) + run: cargo test --workspace --features=js_plugin + - name: Run tests (default features) + run: cargo test --workspace.github/workflows/main.yml (1)
95-95
: Parity check: tests run with js_plugin—consider also testing withoutMirroring PR workflow advice: add a default-features test to catch cfg-gated gaps. Optionally align cargo check/clippy invocations to also include js_plugin.
- - name: Run tests on ${{ matrix.os }} - run: cargo test --workspace --features=js_plugin + - name: Run tests on ${{ matrix.os }} (js_plugin) + run: cargo test --workspace --features=js_plugin + - name: Run tests on ${{ matrix.os }} (default features) + run: cargo test --workspacepackages/@biomejs/plugin-api/index.js (1)
1-3
: Make the runtime guard message crisper and actionableClarify that this package is type-only, and guide users to import types vs runtime.
-throw new Error( - "This package is intended to be used in Biome JS plugins, did you mean `@biomejs/js-api`?", -); +throw new Error( + "This package only provides TypeScript types and has no runtime. If you need the runtime API, use '@biomejs/js-api'. For types only, write: import type { ... } from '@biomejs/plugin-api'.", +);packages/@biomejs/plugin-api/index.d.ts (2)
1-1
: Severity union looks fine; consider exposing constants for ergonomics.Exporting string constants alongside the union reduces typos for plugin authors and improves autocomplete.
Apply:
+/** String constants for valid severities. */ +export const Severities = { + fatal: "fatal", + error: "error", + warning: "warning", + information: "information", + hint: "hint", +} as const; + export type Severity = "fatal" | "error" | "warning" | "information" | "hint";
3-3
: Document and future‑proof the API surface.Add minimal JSDoc now; if you expect codes/locations later, call that out to avoid churn.
-export function registerDiagnostic(severity: Severity, message: string): void; +/** + * Emit a diagnostic from a JS plugin. + * @param severity - Diagnostic severity. + * @param message - Human-readable message. + */ +export function registerDiagnostic(severity: Severity, message: string): void;packages/@biomejs/plugin-api/package.json (2)
6-17
: Include index.js in published files (or drop files field).Even if private today, it avoids surprises if this is ever published.
"files": [ "README.md", "LICENSE-APACHE", "LICENSE-MIT", - "index.d.ts" + "index.d.ts", + "index.js" ],
18-21
: Mark as side‑effect free.This helps bundlers and tree‑shaking; the entry just throws.
"main": "./index.js", "types": "./index.d.ts", + "sideEffects": false, "license": "MIT OR Apache-2.0",
crates/biome_plugin_loader/src/thread_local.rs (6)
93-101
: Document the leak explicitly and provide a way to opt-out.Per the docs, values aren’t dropped on thread exit. That can surprise tests or long-lived services creating many threads. Consider an explicit “clear for this thread” hook.
I can sketch a safe “clear_current_thread” that drops when no outstanding borrows.
112-126
: Avoid unwrap chain after set; handle the impossible explicitly.If set ever fails (see above), unwrap will panic. Replace with expect carrying context or restructure to return an error.
- self.set(value); - Ok(self.get_mut().unwrap()) + self.set(value); + Ok(self.get_mut().expect("TLS set succeeded, value must be present"))
128-136
: Minor safety/readability touch.Cache the deref once and add a debug assert to make intent clear.
- let ptr = self.key.get(); - if ptr.is_null() { + let ptr = self.key.get(); + debug_assert!(!ptr.is_null()); + if ptr.is_null() { None } else { - Some((&*ptr).borrow_mut()) + let cell: &RefCell<T> = &*ptr; + Some(cell.borrow_mut()) }
139-145
: Provide an explicit per-thread teardown to aid tests.Optional helper to free the current thread’s value when needed (e.g. in tests or thread pools).
fn set(&self, value: T) { let cell = Box::into_raw(Box::new(RefCell::new(value))); unsafe { self.key.set(cell); } } + + /// Drops the current thread's value, if any. + /// Call only when no outstanding borrows exist. + #[allow(dead_code)] + fn clear_current_thread(&self) { + unsafe { + let ptr = self.key.get(); + if !ptr.is_null() { + // Clear first to avoid stale pointer if drop panics. + self.key.set(std::ptr::null_mut()); + drop(Box::from_raw(ptr)); + } + } + }
15-24
: Is Key::new really unsafe to call?You already encapsulate the unsafe calls and assert on errors. Consider making Key::new safe and keep the unsafety internal.
Also applies to: 57-66
1-12
: Trait auto-impls: confirm intended Send/Sync story.Using PhantomData<fn() -> T> typically keeps Key Send/Sync regardless of T. That’s desirable for TLS of !Send types. Please confirm this is intentional and add a brief note.
plugins/plugin.js (1)
3-8
: Defensive guard on input type.Tiny safety net so plugins don’t blow up if a non-string sneaks in.
/** @param {string} path */ export default function useMyPlugin(path) { - if (path.endsWith("plugin.js")) { + if (typeof path === "string" && path.endsWith("plugin.js")) { registerDiagnostic("warning", "Hello, world!"); } }crates/biome_service/src/workspace/server.rs (1)
308-323
: JSX-everywhere may affect .cjs unintentionally—gate on .js or confirm intent.Current check flips any non-TS, non-JSX JS source to JSX. If
.cjs
should stay non-JSX, gate by extension.- if !js.is_typescript() && !js.is_jsx() { + if path.extension().is_some_and(|ext| ext == "js") + && !js.is_typescript() + && !js.is_jsx() + { let settings = self .projects .get_settings_based_on_path(project_key, &biome_path) .ok_or_else(WorkspaceError::no_project)?; let jsx_everywhere = settings .languages .javascript .parser .jsx_everywhere .unwrap_or_default() .into(); if jsx_everywhere { js.set_variant(LanguageVariant::Jsx); } }If
.cjs
is meant to honour the flag too, ignore this suggestion and we’re golden.crates/biome_js_runtime/src/plugin_api.rs (3)
29-33
: Tighten the argument validation error to include the expected signature.Small UX win: spell out the exact signature and accepted severities.
- .with_message("registerDiagnostic() expects two string arguments") + .with_message( + "registerDiagnostic(severity, message) expects two string arguments; \ +severity must be one of: fatal, error, warning, information, hint", + )
27-33
: Document the unsafe more explicitly.The closure captures only an Rc<RefCell<_>> (Rust-managed) and no GC-managed Boa values. Add that to the SAFETY note to avoid future refactors breaking the invariant.
49-55
: Plan for spans sooner rather than later.You’re emitting diagnostics with None::. Consider a follow-up API (e.g. registerDiagnosticWithSpan(start, end, message, severity)) so JS plugins can attach precise ranges.
Happy to draft the API and a matching d.ts update if you want.
Cargo.toml (1)
190-244
: Workspace deps add-up: avoid pulling heavy crates unless needed.Adding boa_engine, windows, and libc at the workspace level is OK, but keep them effectively gated by per-crate optional deps so they don’t inflate builds unintentionally.
If any non-plugin crates start depending on these indirectly, consider moving them out of [workspace.dependencies] into only the crates that need them.
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)
58-72
: Clarify sync-only contract (or detect Promises).Boa doesn’t run async tasks; if a plugin returns a Promise nothing happens. Either document “entrypoint must be synchronous” or detect Promise returns and surface a diagnostic.
I can add a Promise check via value.as_object().is_some_and(|o| o.is_promise()) and emit a friendly diagnostic.
crates/biome_plugin_loader/src/lib.rs (1)
62-67
: Nit: “analyser” → “analyzer”.Minor spelling tidy in the TODO comment.
- // TODO: plugin can have multiple analyser rules + // TODO: plugin can have multiple analyzer rulescrates/biome_js_runtime/src/context.rs (3)
32-35
: Avoid magic string for plugin API specifierLift the specifier into a shared constant to prevent typos and ease reuse.
- module_loader.register_module( - js_string!("@biomejs/plugin-api"), + const PLUGIN_API_SPEC: &str = "@biomejs/plugin-api"; + module_loader.register_module( + js_string!(PLUGIN_API_SPEC), api.create_module(&mut ctx), );
82-87
: Guard against endless job-queue spinsIf the promise never settles (plugin bug), this tight loop can hot-spin the CPU. Add a soft cap/yield to be kinder to threads and humans.
- loop { + let mut spins = 0u32; + loop { match promise_result.state() { PromiseState::Pending => { - // Drive the job queue until the promise settles. - ctx.run_jobs(); + // Drive the job queue until the promise settles. + ctx.run_jobs(); + spins += 1; + if spins % 1024 == 0 { + std::thread::yield_now(); + } } PromiseState::Fulfilled(_) => break Ok(module),Please confirm Boa's guidance here; if there's a built-in “drain jobs until settled” helper, use that instead.
100-105
: Fail fast when no default exportToday this returns
undefined
, which is easy to misuse downstream. Prefer a typed error if the module has no default.- pub fn get_default_export(&mut self, module: &Module) -> JsResult<JsValue> { - let ctx = &mut self.ctx; - let namespace = module.namespace(ctx); - - namespace.get(js_string!("default"), ctx) - } + pub fn get_default_export(&mut self, module: &Module) -> JsResult<JsValue> { + let ctx = &mut self.ctx; + let namespace = module.namespace(ctx); + let value = namespace.get(js_string!("default"), ctx)?; + if value.is_undefined() { + return Err(JsNativeError::typ() + .with_message("Module has no default export") + .into()); + } + Ok(value) + }If callers intentionally accept missing defaults, ignore this and keep returning
undefined
.crates/biome_plugin_loader/src/diagnostics.rs (2)
54-64
: Avoid allocating with to_string() inside markup
markup!
supportsDisplay
; pass the error directly to avoid an extra allocation.- message: MessageAndDescription::from( - markup! {"Failed to compile the JS plugin: "{value.to_string()}}.to_owned(), - ), + message: MessageAndDescription::from( + markup! {"Failed to compile the JS plugin: " {value}}.to_owned(), + ),
148-151
: Struct-level diagnostic message: looks right—update snapshotsSwitching to
MessageAndDescription
will change output text. Ensure snapshot tests are refreshed and cover JS plugin compile failures too.Would you like a new test that constructs a
boa_engine::JsError
(behindjs_plugin
) and snapshots the resultingPluginDiagnostic
?crates/biome_js_runtime/src/module_loader.rs (3)
50-52
: Minor: use Default directly- let options = ResolveOptions { - ..Default::default() - }; + let options = ResolveOptions::default();
61-67
: Shadowedsource
hurts readabilityRename the inner binding to avoid reusing
source
for both contents andSource
.- let source = self.fs.read_file_from_path(&path); - match source { - Ok(source) => { - let source = source.as_bytes(); - let source = Source::from_bytes(source).with_path(path.as_std_path()); + let contents = self.fs.read_file_from_path(&path); + match contents { + Ok(contents) => { + let bytes = contents.as_bytes(); + let source = Source::from_bytes(bytes).with_path(path.as_std_path()); let module = Module::parse(source, None, context);
11-15
: Consider cache invalidationThe loader caches by absolute path without eviction. If used in long-lived processes or with hot-reloads, expose a
clear()
or LRU. Optional for now.
📜 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.
⛔ Files ignored due to path filters (5)
Cargo.lock
is excluded by!**/*.lock
and included by**
crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts.snap
is excluded by!**/*.snap
and included by**
crates/biome_json_analyze/tests/specs/suspicious/noDuplicateObjectKeys/invalid.json.snap
is excluded by!**/*.snap
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 (40)
.changeset/keep-jsxeverywhere-variant.md
(1 hunks).changeset/use_readonly_class_properties_nested_assignment_fix.md
(1 hunks).github/workflows/beta.yml
(1 hunks).github/workflows/main.yml
(1 hunks).github/workflows/preview.yml
(3 hunks).github/workflows/pull_request.yml
(1 hunks).github/workflows/release.yml
(1 hunks).github/workflows/release_cli.yml
(2 hunks).github/workflows/release_js_api.yml
(1 hunks)Cargo.toml
(4 hunks)biome.json
(1 hunks)crates/biome_cli/Cargo.toml
(1 hunks)crates/biome_css_analyze/src/keywords.rs
(1 hunks)crates/biome_css_analyze/tests/specs/correctness/noUnknownProperty/valid.css
(1 hunks)crates/biome_js_analyze/Cargo.toml
(1 hunks)crates/biome_js_analyze/src/lint/style/use_exponentiation_operator.rs
(2 hunks)crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts
(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_json_analyze/src/lint/suspicious/no_duplicate_object_keys.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/file_handlers/javascript.rs
(2 hunks)crates/biome_service/src/file_handlers/javascript.tests.rs
(0 hunks)crates/biome_service/src/workspace/server.rs
(3 hunks)crates/biome_service/src/workspace/server.tests.rs
(2 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)
💤 Files with no reviewable changes (1)
- crates/biome_service/src/file_handlers/javascript.tests.rs
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/src/context.rs
crates/biome_json_analyze/src/lint/suspicious/no_duplicate_object_keys.rs
crates/biome_js_runtime/Cargo.toml
crates/biome_service/Cargo.toml
crates/biome_plugin_loader/src/analyzer_js_plugin.rs
crates/biome_cli/Cargo.toml
crates/biome_js_analyze/src/lint/style/use_exponentiation_operator.rs
crates/biome_js_runtime/src/lib.rs
crates/biome_service/src/workspace/server.tests.rs
crates/biome_css_analyze/src/keywords.rs
crates/biome_js_runtime/src/module_loader.rs
crates/biome_service/src/file_handlers/javascript.rs
crates/biome_plugin_loader/src/lib.rs
crates/biome_plugin_loader/src/diagnostics.rs
Cargo.toml
crates/biome_plugin_loader/src/thread_local.rs
crates/biome_plugin_loader/Cargo.toml
crates/biome_service/src/workspace/server.rs
crates/biome_js_runtime/src/plugin_api.rs
crates/**/Cargo.toml
📄 CodeRabbit inference engine (CONTRIBUTING.md)
crates/**/Cargo.toml
: In internal crates, useworkspace = 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_cli/Cargo.toml
crates/biome_plugin_loader/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_cli/Cargo.toml
Cargo.toml
crates/biome_plugin_loader/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_json_analyze/src/lint/suspicious/no_duplicate_object_keys.rs
crates/biome_css_analyze/tests/specs/correctness/noUnknownProperty/valid.css
crates/biome_js_analyze/src/lint/style/use_exponentiation_operator.rs
crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts
crates/biome_css_analyze/src/keywords.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/Cargo.toml
crates/biome_js_runtime/src/context.rs
crates/biome_json_analyze/src/lint/suspicious/no_duplicate_object_keys.rs
crates/biome_js_runtime/Cargo.toml
crates/biome_service/Cargo.toml
crates/biome_plugin_loader/src/analyzer_js_plugin.rs
crates/biome_css_analyze/tests/specs/correctness/noUnknownProperty/valid.css
crates/biome_cli/Cargo.toml
crates/biome_js_analyze/src/lint/style/use_exponentiation_operator.rs
crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts
crates/biome_js_runtime/src/lib.rs
crates/biome_service/src/workspace/server.tests.rs
crates/biome_css_analyze/src/keywords.rs
crates/biome_js_runtime/src/module_loader.rs
crates/biome_service/src/file_handlers/javascript.rs
crates/biome_plugin_loader/src/lib.rs
crates/biome_plugin_loader/src/diagnostics.rs
crates/biome_plugin_loader/src/thread_local.rs
crates/biome_plugin_loader/Cargo.toml
crates/biome_service/src/workspace/server.rs
crates/biome_js_runtime/src/plugin_api.rs
.changeset/*.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
.changeset/*.md
: Create changesets withjust new-changeset
; store them in.changeset/
with correct frontmatter (package keys and change type).
In changeset descriptions, follow content conventions: user-facing changes only; past tense for what you did; present tense for current behavior; link issues for fixes; link rules/assists; include representative code blocks; end every sentence with a period.
When adding headers in a changeset, only use #### or ##### levels.
Files:
.changeset/keep-jsxeverywhere-variant.md
.changeset/use_readonly_class_properties_nested_assignment_fix.md
**/tests/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place test files under a tests/ directory in each crate
Files:
crates/biome_css_analyze/tests/specs/correctness/noUnknownProperty/valid.css
crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts
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 (38)
📚 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_cli/Cargo.toml
crates/biome_js_runtime/src/lib.rs
crates/biome_service/src/workspace/server.tests.rs
crates/biome_plugin_loader/src/diagnostics.rs
Cargo.toml
crates/biome_plugin_loader/Cargo.toml
crates/biome_service/src/workspace/server.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_cli/Cargo.toml
Cargo.toml
crates/biome_plugin_loader/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 : Most diagnostic attributes may be specified only once (either on the type or a single field); #[advice] and #[verbose_advice] may appear multiple times and are recorded in declaration order
Applied to files:
crates/biome_json_analyze/src/lint/suspicious/no_duplicate_object_keys.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:
packages/@biomejs/plugin-api/index.js
packages/@biomejs/plugin-api/package.json
biome.json
📚 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
Cargo.toml
crates/biome_plugin_loader/Cargo.toml
📚 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
Cargo.toml
crates/biome_plugin_loader/Cargo.toml
crates/biome_service/src/workspace/server.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
Cargo.toml
crates/biome_plugin_loader/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
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
crates/biome_service/src/workspace/server.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_js_runtime/Cargo.toml
crates/biome_plugin_loader/src/analyzer_js_plugin.rs
crates/biome_service/src/file_handlers/javascript.rs
crates/biome_service/src/workspace/server.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:
crates/biome_js_runtime/src/lib.rs
crates/biome_service/src/file_handlers/javascript.rs
Cargo.toml
crates/biome_service/src/workspace/server.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/**/tests/specs/**/{invalid*,valid*}.{js,jsx,ts,tsx,css,graphql,jsonc} : Place snapshot test cases under `tests/specs/<group>/<ruleName>/` using files prefixed with `invalid` and `valid`
Applied to files:
crates/biome_service/src/workspace/server.tests.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/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in biome_lsp’s server.tests.rs
Applied to files:
crates/biome_service/src/workspace/server.tests.rs
crates/biome_service/src/file_handlers/javascript.rs
crates/biome_plugin_loader/src/lib.rs
Cargo.toml
crates/biome_plugin_loader/Cargo.toml
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/watcher.tests.rs : Place watcher tests for workspace methods in src/workspace/watcher.tests.rs
Applied to files:
crates/biome_service/src/workspace/server.tests.rs
crates/biome_service/src/file_handlers/javascript.rs
Cargo.toml
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 : Import the FormatNode trait and implement it for your Node
Applied to files:
crates/biome_service/src/workspace/server.tests.rs
crates/biome_plugin_loader/src/diagnostics.rs
crates/biome_service/src/workspace/server.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_service/src/workspace/server.tests.rs
crates/biome_plugin_loader/src/diagnostics.rs
crates/biome_service/src/workspace/server.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:
crates/biome_service/src/workspace/server.tests.rs
crates/biome_plugin_loader/src/diagnostics.rs
Cargo.toml
crates/biome_service/src/workspace/server.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 : Build an intermediate IR via the provided helper APIs when formatting
Applied to files:
crates/biome_service/src/workspace/server.tests.rs
crates/biome_plugin_loader/src/diagnostics.rs
Cargo.toml
crates/biome_service/src/workspace/server.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_service/src/workspace/server.tests.rs
crates/biome_plugin_loader/src/diagnostics.rs
crates/biome_service/src/workspace/server.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_html_formatter/benches/html_formatter.rs : Maintain the HTML formatter benchmark at benches/html_formatter.rs within the biome_html_formatter crate
Applied to files:
crates/biome_service/src/workspace/server.tests.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 : For non-mandatory tokens, use the formatter helper functions (e.g., token, space_token) instead of hardcoding
Applied to files:
crates/biome_service/src/workspace/server.tests.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: 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: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
Cargo.toml
crates/biome_plugin_loader/Cargo.toml
crates/biome_service/src/workspace/server.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 : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement
Applied to files:
crates/biome_service/src/file_handlers/javascript.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_service/src/file_handlers/javascript.rs
crates/biome_plugin_loader/src/lib.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_service/src/file_handlers/javascript.rs
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_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_service/src/file_handlers/javascript.rs
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/** : Place test files under a tests/ directory in each crate
Applied to files:
crates/biome_service/src/file_handlers/javascript.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/language.rs : Create tests/language.rs defining HtmlTestFormatLanguage and implement TestFormatLanguage for it
Applied to files:
crates/biome_service/src/file_handlers/javascript.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-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: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/lib.rs
crates/biome_plugin_loader/src/diagnostics.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-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:
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: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 : Expose a documented public function format_node(options: HtmlFormatOptions, root: &HtmlSyntaxNode) -> FormatResult<Formatted<HtmlFormatContext>> delegating to biome_formatter::format_node
Applied to files:
crates/biome_service/src/workspace/server.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 : Do not attempt to fix code: if a mandatory token/node is missing, return None instead
Applied to files:
crates/biome_service/src/workspace/server.rs
🧬 Code graph analysis (8)
crates/biome_js_runtime/src/context.rs (2)
crates/biome_js_runtime/src/module_loader.rs (1)
new
(18-24)crates/biome_js_runtime/src/plugin_api.rs (2)
new
(17-21)pull_diagnostics
(82-84)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (4)
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)
crates/biome_service/src/workspace/server.tests.rs (3)
crates/biome_service/src/test_utils.rs (1)
setup_workspace_and_open_project
(14-21)crates/biome_service/src/file_handlers/javascript.rs (1)
parse
(501-529)crates/biome_js_parser/src/parse.rs (3)
parse
(173-178)parse
(219-220)parse
(247-250)
crates/biome_js_runtime/src/module_loader.rs (1)
crates/biome_js_runtime/src/context.rs (1)
new
(25-38)
crates/biome_service/src/file_handlers/javascript.rs (2)
crates/biome_service/src/file_handlers/svelte.rs (1)
file_source
(66-79)crates/biome_service/src/file_handlers/vue.rs (1)
file_source
(66-79)
crates/biome_plugin_loader/src/lib.rs (3)
crates/biome_service/src/workspace/server.rs (3)
fs
(1606-1608)fs
(1688-1690)new
(119-141)crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)
load
(59-71)crates/biome_js_runtime/src/context.rs (1)
new
(25-38)
crates/biome_service/src/workspace/server.rs (2)
crates/biome_plugin_loader/src/analyzer_js_plugin.rs (1)
load
(59-71)crates/biome_plugin_loader/src/lib.rs (1)
load
(40-118)
crates/biome_js_runtime/src/plugin_api.rs (3)
packages/@biomejs/plugin-api/index.d.ts (1)
Severity
(1-1)crates/biome_js_runtime/src/context.rs (2)
new
(25-38)pull_diagnostics
(41-43)crates/biome_plugin_loader/src/analyzer_grit_plugin.rs (1)
register_diagnostic
(104-156)
⏰ 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: Lint project (depot-windows-2022)
- GitHub Check: Check JS Files
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Bench (biome_package)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: End-to-end tests
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Check Dependencies
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Test Node.js API
- GitHub Check: autofix
--- | ||
"@biomejs/biome": patch | ||
--- | ||
|
||
Fixed [#7286](https://github.com/biomejs/biome/issues/7286). Files are now formatted with JSX behavior when `javascript.parser.jsxEverywhere` is explicitly set. | ||
|
||
Previously, this flag was only used for parsing, but not for formatting, which resulted in incorrect formatting of conditional expressions when JSX syntax is used in `.js` files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changeset appears unrelated to this PR and misses a trailing full stop.
This PR targets CSS “navigation” property support; this changeset is about JSX-everywhere formatting and links #7286. Either move it to the relevant PR or adjust the content. Also, per repo guidelines, end sentences with a period.
🤖 Prompt for AI Agents
In .changeset/keep-jsxeverywhere-variant.md around lines 1 to 7, the changeset's
content is unrelated to this PR (it documents JSX-everywhere formatting and
links #7286) and the text is missing a trailing period; either remove or move
this changeset into the PR that fixes issue #7286 (or create a new PR that
includes it), or rewrite the changeset to reflect the actual CSS “navigation”
change this PR implements, and ensure all sentences end with a period and follow
repo changeset guidelines.
--- | ||
"@biomejs/biome": patch | ||
--- | ||
|
||
Fixed [#7310](https://github.com/biomejs/biome/issues/7310): [`useReadonlyClassProperties`](https://biomejs.dev/linter/rules/use-readonly-class-properties/) correctly handles nested assignments, avoiding false positives when a class property is assigned within another assignment expression. | ||
|
||
Example of code that previously triggered a false positive but is now correctly ignored: | ||
|
||
```ts | ||
class test { | ||
private thing: number = 0; // incorrectly flagged | ||
|
||
public incrementThing(): void { | ||
const temp = {x: 0}; | ||
temp.x = this.thing++; | ||
} | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Changeset content does not match this PR’s scope (navigation property). Replace with a changeset for noUnknownProperty.
This PR fixes a CSS false positive for navigation
, but the changeset documents an unrelated rule and issue (#7310). Please align the changeset with issue #7340 and the rule lint/correctness/noUnknownProperty
.
Proposed replacement:
---
-"@biomejs/biome": patch
----
-
-Fixed [#7310](https://github.com/biomejs/biome/issues/7310): [`useReadonlyClassProperties`](https://biomejs.dev/linter/rules/use-readonly-class-properties/) correctly handles nested assignments, avoiding false positives when a class property is assigned within another assignment expression.
-
-Example of code that previously triggered a false positive but is now correctly ignored:
-
-```ts
-class test {
- private thing: number = 0; // incorrectly flagged
-
- public incrementThing(): void {
- const temp = {x: 0};
- temp.x = this.thing++;
- }
-}
-```
+ "@biomejs/biome": patch
+---
+
+Fixed [#7340](https://github.com/biomejs/biome/issues/7340): `noUnknownProperty` recognises the CSS `navigation` property from the View Transitions spec, avoiding false positives.
+
+Example (valid, no diagnostics):
+
+```css
+.card {
+ navigation: auto;
+}
+```
I can also open a new changeset file with the correct name and remove this one if you prefer.
globset = { workspace = true } | ||
regex = { workspace = true } | ||
roaring = "0.11.1" | ||
roaring = "0.11.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Roaring bump looks unrelated; verify necessity and lockfile
This PR’s goal is CSS linting. If the bump is intentional, ensure Cargo.lock (and other crates using roaring) are consistent.
🏁 Script executed:
#!/bin/bash
# Check where roaring is used and versions across the workspace
rg -nP '^\s*roaring\s*=\s*".*"' -g '**/Cargo.toml' -n -C0
# Ensure lockfile is updated for roaring
rg -n '"name": "roaring"|roaring ' Cargo.lock -n -C1 || true
Length of output: 195
Commit updated Cargo.lock for roaring bump
The bump of roaring = "0.11.2"
in crates/biome_js_analyze/Cargo.toml
isn’t reflected in Cargo.lock – run cargo update -p roaring
(or cargo update --workspace
) and commit the regenerated lockfile, or revert the bump if it was unintentional.
🤖 Prompt for AI Agents
In crates/biome_js_analyze/Cargo.toml around line 43, the dependency was bumped
to roaring = "0.11.2" but Cargo.lock was not updated; run `cargo update -p
roaring` (or `cargo update --workspace`) from the workspace root to regenerate
Cargo.lock and commit the updated Cargo.lock, or if the version bump was
accidental, revert the change in Cargo.toml and commit that revert instead.
|
||
class TestIncrementInAssignment { | ||
private thing: number = 0; | ||
|
||
public incrementThing(): void { | ||
const temp = { x: 0 }; | ||
temp.x = this.thing++; | ||
} | ||
} | ||
|
||
class TesAssignmentInNestedCallback { | ||
private thing: any; | ||
|
||
public doStuff(): void { | ||
ui.showText("example", { | ||
callback: () => { | ||
this.thing = x; | ||
}, | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
These additions test a different rule and don’t belong in this suite.
You’re adding TS cases for useReadonlyClassProperties
, while the PR is about CSS noUnknownProperty
recognising navigation
. Please drop these lines and instead add a CSS test under the noUnknownProperty
specs.
Apply this diff to remove the unrelated tests:
-+class TestIncrementInAssignment {
-+ private thing: number = 0;
-+
-+ public incrementThing(): void {
-+ const temp = { x: 0 };
-+ temp.x = this.thing++;
-+ }
-+}
-+
-+class TesAssignmentInNestedCallback {
-+ private thing: any;
-+
-+ public doStuff(): void {
-+ ui.showText("example", {
-+ callback: () => {
-+ this.thing = x;
-+ },
-+ });
-+ }
-+}
And add a new file (example path) with a passing case:
crates/biome_css_analyze/tests/specs/lint/correctness/noUnknownProperty/valid.css
/* should not generate diagnostics */
.card {
navigation: auto;
}
I can wire up the CSS test file and adjust snapshots if your harness uses them.
🤖 Prompt for AI Agents
In crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts
around lines 667-687, you added TypeScript tests for useReadonlyClassProperties
that are unrelated to this PR; remove the two classes (TestIncrementInAssignment
and TesAssignmentInNestedCallback) from this file. Instead, add a new CSS test
file at
crates/biome_css_analyze/tests/specs/lint/correctness/noUnknownProperty/valid.css
containing a single passing case with a .card rule using navigation: auto; so
the CSS noUnknownProperty suite tests recognition of the navigation property.
Ensure snapshots/test harness is updated if required.
let base_dir = referrer | ||
.path() | ||
.and_then(|path| path.parent()) | ||
.and_then(Utf8Path::from_path) | ||
.map(Utf8Path::to_path_buf) | ||
.or_else(|| self.fs.working_directory()) | ||
.unwrap_or_default(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Empty base dir fallback is brittle
Utf8PathBuf::new()
yields an empty path; some resolvers treat this oddly. Prefer a clear cwd or emit a diagnostic if none is available.
- let base_dir = referrer
+ let base_dir = referrer
.path()
.and_then(|path| path.parent())
.and_then(Utf8Path::from_path)
.map(Utf8Path::to_path_buf)
- .or_else(|| self.fs.working_directory())
- .unwrap_or_default();
+ .or_else(|| self.fs.working_directory())
+ .unwrap_or_else(|| Utf8PathBuf::from("."));
If working_directory()
can be None
in your embedder, consider returning an error instead of guessing.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
let base_dir = referrer | |
.path() | |
.and_then(|path| path.parent()) | |
.and_then(Utf8Path::from_path) | |
.map(Utf8Path::to_path_buf) | |
.or_else(|| self.fs.working_directory()) | |
.unwrap_or_default(); | |
let base_dir = referrer | |
.path() | |
.and_then(|path| path.parent()) | |
.and_then(Utf8Path::from_path) | |
.map(Utf8Path::to_path_buf) | |
.or_else(|| self.fs.working_directory()) | |
.unwrap_or_else(|| Utf8PathBuf::from(".")); |
let severity = | ||
match severity.to_std_string_lossy().as_str() { | ||
"fatal" => Severity::Fatal, | ||
"error" => Severity::Error, | ||
"warning" => Severity::Warning, | ||
"information" => Severity::Information, | ||
"hint" => Severity::Hint, | ||
_ => return Err(JsNativeError::typ() | ||
.with_message( | ||
"Unexpected severity, expected one of: fatal, error, warning, information, hint", | ||
) | ||
.into()), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Prefer Severity::from_str (plus “info” alias) to keep parsing consistent with other code paths.
The Grit plugin uses Severity::from_str and defaults to Error; duplicating the mapping here risks drift. Also consider accepting “info” as an alias for “information”.
Apply this diff within the match block:
- let severity =
- match severity.to_std_string_lossy().as_str() {
- "fatal" => Severity::Fatal,
- "error" => Severity::Error,
- "warning" => Severity::Warning,
- "information" => Severity::Information,
- "hint" => Severity::Hint,
- _ => return Err(JsNativeError::typ()
- .with_message(
- "Unexpected severity, expected one of: fatal, error, warning, information, hint",
- )
- .into()),
- };
+ let s = severity.to_std_string_lossy();
+ let s = if s == "info" { "information".into() } else { s };
+ let severity = biome_diagnostics::Severity::from_str(&s)
+ .map_err(|_| {
+ JsNativeError::typ().with_message(
+ "Unexpected severity, expected one of: fatal, error, warning, information, hint",
+ )
+ })?;
Add this import near the top:
use std::str::FromStr;
🤖 Prompt for AI Agents
In crates/biome_js_runtime/src/plugin_api.rs around lines 35 to 47, the manual
match mapping of severity strings should be replaced with Severity::from_str to
keep parsing consistent with other code paths and accept the "info" alias;
update the match to call
Severity::from_str(severity.to_std_string_lossy().as_ref()) (or
FromStr::from_str) and map Err to the same JsNativeError.typ() with the existing
message (or default to Severity::Error if you prefer the Grit behavior), and add
use std::str::FromStr; near the top of the file; ensure the error branch
preserves the current error return shape and that "info" is accepted by the
from_str implementation or normalized before parsing.
.map_or_else( | ||
|err| { | ||
vec![RuleDiagnostic::new( | ||
category!("plugin"), | ||
None::<TextRange>, | ||
markup!("Plugin errored: "<Error>{err.to_string()}</Error>), | ||
)] | ||
}, | ||
|_| plugin.ctx.pull_diagnostics(), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t drop diagnostics if the plugin throws.
If the plugin emitted diagnostics before throwing, the error branch discards them. Drain and append the error instead.
- .map_or_else(
- |err| {
- vec![RuleDiagnostic::new(
- category!("plugin"),
- None::<TextRange>,
- markup!("Plugin errored: "<Error>{err.to_string()}</Error>),
- )]
- },
- |_| plugin.ctx.pull_diagnostics(),
- )
+ .map_or_else(
+ |err| {
+ let mut diags = plugin.ctx.pull_diagnostics();
+ diags.push(RuleDiagnostic::new(
+ category!("plugin"),
+ None::<TextRange>,
+ markup!("Plugin errored: "<Error>{err.to_string()}</Error>),
+ ));
+ diags
+ },
+ |_| plugin.ctx.pull_diagnostics(),
+ )
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
.map_or_else( | |
|err| { | |
vec![RuleDiagnostic::new( | |
category!("plugin"), | |
None::<TextRange>, | |
markup!("Plugin errored: "<Error>{err.to_string()}</Error>), | |
)] | |
}, | |
|_| plugin.ctx.pull_diagnostics(), | |
) | |
.map_or_else( | |
|err| { | |
let mut diags = plugin.ctx.pull_diagnostics(); | |
diags.push(RuleDiagnostic::new( | |
category!("plugin"), | |
None::<TextRange>, | |
markup!("Plugin errored: "<Error>{err.to_string()}</Error>), | |
)); | |
diags | |
}, | |
|_| plugin.ctx.pull_diagnostics(), | |
) |
🤖 Prompt for AI Agents
In crates/biome_plugin_loader/src/analyzer_js_plugin.rs around lines 100 to 109,
the closure on the Err branch currently returns a fresh Vec and drops any
diagnostics the plugin may have already emitted; change it to first drain/pull
the plugin context diagnostics into a Vec, then create an additional
RuleDiagnostic representing the error (using err.to_string()) and push/append it
to that Vec, and finally return the combined Vec so existing diagnostics are
preserved and the error is reported.
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()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Make set() failures hard, not debug-only.
If FlsSetValue fails in release, the subsequent unwrap in get_mut_or_try_init can panic. Assert in all builds or propagate an error.
- debug_assert!(result.is_ok());
+ assert!(result.is_ok(), "FlsSetValue failed");
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
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 result = unsafe { win32::FlsSetValue(self.inner, Some(value as *const c_void)) }; | |
assert!(result.is_ok(), "FlsSetValue failed"); | |
} |
🤖 Prompt for AI Agents
In crates/biome_plugin_loader/src/thread_local.rs around lines 29–33, the set()
routine currently uses debug_assert! on the FlsSetValue result which can
silently fail in release and cause a later unwrap in get_mut_or_try_init to
panic; change set() to either (preferred) return a Result<(), Error> (or
std::io::Error/any suitable error type) and propagate that Result up to callers
(update get_mut_or_try_init to propagate or handle the error instead of
unwrapping), or if you prefer to keep the API void, replace debug_assert! with a
release-time check that calls expect/panic with a clear message on failure so
failures are hard in all builds; ensure call sites are adjusted to handle the
new Result if you choose propagation.
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ditto for pthread_setspecific.
Guard failures in all builds to avoid follow-up panics.
- debug_assert_eq!(result, 0);
+ assert_eq!(result, 0, "pthread_setspecific failed");
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
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 result = unsafe { libc::pthread_setspecific(self.inner, value as *mut c_void) }; | |
assert_eq!(result, 0, "pthread_setspecific failed"); | |
} |
🤖 Prompt for AI Agents
In crates/biome_plugin_loader/src/thread_local.rs around lines 77 to 81, the
call to libc::pthread_setspecific is currently only asserted with
debug_assert_eq!, which is stripped in release builds and can lead to silent
failures and subsequent panics; change the guard so failures are checked in all
builds by replacing the debug-only assertion with a runtime check that verifies
result == 0 and panics (or returns a clear error) with a descriptive message
including the errno/result if it is nonzero, ensuring the failure is caught
immediately in release as well as debug.
use biome_configuration::{ | ||
FormatterConfiguration, JsConfiguration, | ||
javascript::{JsFormatterConfiguration, JsParserConfiguration}, | ||
}; | ||
use biome_formatter::{IndentStyle, LineWidth}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests won’t compile: missing import for Bool
.
You use Bool(true|false)
below but don’t import it.
Apply:
use biome_configuration::{
FormatterConfiguration, JsConfiguration,
javascript::{JsFormatterConfiguration, JsParserConfiguration},
};
+use biome_configuration::bool::Bool;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
use biome_configuration::{ | |
FormatterConfiguration, JsConfiguration, | |
javascript::{JsFormatterConfiguration, JsParserConfiguration}, | |
}; | |
use biome_formatter::{IndentStyle, LineWidth}; | |
use biome_configuration::{ | |
FormatterConfiguration, JsConfiguration, | |
javascript::{JsFormatterConfiguration, JsParserConfiguration}, | |
}; | |
use biome_configuration::bool::Bool; | |
use biome_formatter::{IndentStyle, LineWidth}; |
🤖 Prompt for AI Agents
In crates/biome_service/src/workspace/server.tests.rs around lines 1 to 5, the
tests reference the enum variant Bool(true|false) but don’t import it; add a use
statement to bring the variant into scope (for example: use
serde_json::Value::Bool;) so the pattern Bool(true) / Bool(false) compiles.
CodSpeed Performance ReportMerging #7352 will not alter performanceComparing Summary
|
This PR fixes a false positive in the lint/correctness/noUnknownProperty rule for CSS.
->Adds "navigation" to the list of known CSS properties, following the CSS View Transitions spec.
->Adds a test to ensure navigation: auto is not flagged as unknown.
Why:
The navigation property is valid for view transitions, but was previously not recognized by the linter, causing a false positive.
Test:
A test case is added to valid.css to confirm that navigation: auto is accepted.
Fixes #7340