feat(linter): add pluginRules configuration for plugin rule severity#8726
feat(linter): add pluginRules configuration for plugin rule severity#8726amorriscode wants to merge 2 commits intobiomejs:mainfrom
Conversation
Add support for configuring individual plugin rules via configuration,
including in overrides. Plugin rules can be set to off/on/info/warn/error.
Example:
```json
{
"linter": {
"pluginRules": {
"my-plugin": "off"
}
},
"overrides": [{
"includes": ["scripts/**"],
"linter": {
"pluginRules": { "my-plugin": "off" }
}
}]
}
```
Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 5
Claude-Permission-Prompts: 1
Claude-Escapes: 0
Claude-Plan:
<claude-plan>
# Plan: Plugin Rule Configuration in Overrides
## Goal
Add support for configuring individual plugin rules (enable/disable/severity) via configuration, including in overrides.
**Target syntax:**
```json
{
"linter": {
"pluginRules": {
"no-process-cwd": "off",
"my-rule": "warn"
}
},
"overrides": [{
"includes": ["scripts/**"],
"linter": {
"pluginRules": { "no-process-cwd": "off" }
}
}]
}
```
## Background
- Plugin rules are identified by `SignalRuleKey::Plugin(name)` where name comes from the Grit pattern's `name` field
- Suppression already works via comments (`// biome-ignore lint/plugin/ruleName`)
- `TopLevelSuppression.plugins` tracks suppressed plugin names
- No configuration-based mechanism exists yet
## Implementation Approach
Use the existing suppression mechanism path (not `RuleFilter`) because:
- Plugin names are dynamic strings, not `'static` references like built-in rules
- Plugins already have their own suppression path (`suppressed_plugin()`)
- Minimal changes to core types
## Files to Modify
### 1. Configuration Schema
**`crates/biome_configuration/src/analyzer/linter/mod.rs`**
- Add `PluginRules` type: `FxHashMap<String, RulePlainConfiguration>`
- Add `plugin_rules: Option<PluginRules>` field to `LinterConfiguration`
**`crates/biome_configuration/src/overrides.rs`**
- Add `plugin_rules: Option<PluginRules>` to `OverrideLinterConfiguration`
### 2. Settings Layer
**`crates/biome_service/src/settings.rs`**
- Add `plugin_rules: Option<PluginRules>` to `LinterSettings`
- Add to `OverrideLinterSettings`
- Update `to_linter_settings()` to pass through plugin_rules
- Add `as_plugin_rules(&self, path: &Utf8Path) -> PluginRules` method to merge base + overrides
### 3. Analyzer Integration
**`crates/biome_analyze/src/options.rs`**
- Add `plugin_rules: FxHashMap<String, RulePlainConfiguration>` to `AnalyzerConfiguration`
- Add builder method `with_plugin_rules()`
**`crates/biome_analyze/src/lib.rs`**
- Modify `flush_matches()` around line 423 to check plugin rule configuration
- Handle Off/Warn/Error severities appropriately
### 4. Wire Configuration to Analyzer
**`crates/biome_service/src/file_handlers/javascript.rs`** (and other handlers)
- When building `AnalyzerConfiguration`, populate `plugin_rules` from settings
## Implementation Steps
1. **Add configuration types** - Create `PluginRules` type (`FxHashMap<String, RulePlainConfiguration>`) and add to `LinterConfiguration`
2. **Add to overrides** - Add field to `OverrideLinterConfiguration`
3. **Settings layer** - Add field to `LinterSettings`, implement merging via `as_plugin_rules(path)`
4. **Analyzer options** - Add `plugin_rules` field to `AnalyzerConfiguration`
5. **Wire handlers** - Populate `plugin_rules` in file handlers (JS, CSS, etc.)
6. **Filtering logic** - Implement severity handling in `flush_matches()`:
- Off → skip emission
- Warn/Error → modify diagnostic severity via `with_severity()`
7. **Tests** - Add integration tests for both disabling and severity changes
## Full Severity Support
For warn/error severity changes (not just "off"):
1. Store plugin rule config as `FxHashMap<String, RulePlainConfiguration>` (not just disabled set)
2. In `flush_matches()`, for plugin signals:
- If `Off` → skip emission (don't call emit_signal)
- If `Warn` or `Error` → get diagnostic via `signal.diagnostic()`, apply `with_severity()`, emit modified diagnostic
3. The `AnalyzerDiagnostic` type supports `with_severity()` via `DiagnosticExt` trait
### Implementation Detail
In `crates/biome_analyze/src/lib.rs` around line 495:
```rust
// For plugin signals, check configured severity
if let SignalRuleKey::Plugin(plugin_name) = &entry.rule {
if let Some(config) = self.options.configuration.plugin_rules.get(plugin_name.as_ref()) {
match config {
RulePlainConfiguration::Off => {
self.signal_queue.pop();
continue;
}
RulePlainConfiguration::Warn | RulePlainConfiguration::Error => {
// Modify severity before emission
if let Some(diag) = entry.signal.diagnostic() {
let severity = Severity::from(*config);
let modified_diag = diag.with_severity(severity);
// Emit modified diagnostic
}
self.signal_queue.pop();
continue;
}
_ => {} // On/Info - use default behavior
}
}
}
```
## Edge Cases
- **Precedence**: Config disabling takes precedence (can't re-enable via comment)
- **Override merging**: Plugin rules merge (later overrides win for same rule name)
- **Unknown names**: Consider warning for plugin names that don't exist (follow-up)
## Detailed Implementation Notes
### Configuration Types Location
- `LinterConfiguration` is at `crates/biome_configuration/src/analyzer/linter/mod.rs:19`
- `OverrideLinterConfiguration` is at `crates/biome_configuration/src/overrides.rs:182`
### AnalyzerConfiguration Location
- `AnalyzerConfiguration` is at `crates/biome_analyze/src/options.rs:57`
- Built in file handlers like `crates/biome_service/src/file_handlers/javascript.rs:380`
- Add `.with_plugin_rules(plugin_rules)` builder method
### Filtering Location
- `flush_matches()` in `crates/biome_analyze/src/lib.rs` around line 412
- Check `SignalRuleKey::Plugin(plugin)` case (line 423)
## Verification
1. Create a test Grit plugin with a named rule
2. Configure `pluginRules: { "rule-name": "off" }` in biome.json
3. Run `cargo biome-cli-dev lint` and verify the rule is suppressed
4. Add an override for a specific path and verify path-specific suppression works
5. Run existing plugin tests: `cargo test -p biome_service plugin`
6. Run `just gen-analyzer` if needed for any generated code
</claude-plan>
🦋 Changeset detectedLatest commit: 037754a The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 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 introduces plugin rule configuration support across Biome's architecture. It adds configuration structures to allow enabling/disabling individual plugin rules via biome.json at both top-level and overrides levels. The changes propagate through configuration, settings, and service layers, ultimately wiring plugin rule severity checks into the analyzer's signal processing logic to suppress disabled rules. Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
.changeset/plugin-rules-config.md (1)
1-24: Document the full set of supported severities (not just “off”).This changeset reads as “enable/disable”, but the PR summary says severities
off | on | info | warn | errorare supported—worth reflecting that here so users don’t discover it the hard way.Proposed tweak
-Add `pluginRules` configuration option to enable/disable individual plugin rules via `biome.json`. Plugin rules can be configured at the top level or within overrides. +Add `pluginRules` configuration option to configure individual plugin rules via `biome.json` (supported severities: `off`, `on`, `info`, `warn`, `error`). Plugin rules can be configured at the top level or within overrides.crates/biome_configuration/src/overrides.rs (1)
193-203: Good addition; consider documenting the rule-name mapping here too.
plugin_rulesbeing override-able is great; I’d consider adding a one-liner about how plugin rule names are derived (so users don’t guess wrong keys).crates/biome_service/src/workspace.tests.rs (1)
816-898: Test could be a touch more “fails for the right reason”.
Right now it only asserts absence of plugin diagnostics; a quick pre-check (same setup but withoutlinter.plugin_rules) would prove the plugin emits 1 diagnostic and then gets suppressed by config.Proposed tweak (keep it minimal)
fn plugin_rules_can_be_disabled_via_config() { @@ let OpenProjectResult { project_key } = workspace @@ .unwrap(); + // Sanity check: plugin emits a diagnostic by default + workspace + .update_settings(UpdateSettingsParams { + project_key, + configuration: Configuration { + plugins: Some(Plugins(vec![PluginConfiguration::Path( + "./plugin.grit".to_string(), + )])), + ..Default::default() + }, + workspace_directory: Some(BiomePath::new("/project")), + extended_configurations: Default::default(), + }) + .unwrap(); + + workspace + .open_file(OpenFileParams { + project_key, + path: BiomePath::new("/project/a.ts"), + content: FileContent::FromServer, + document_file_source: None, + persist_node_cache: false, + }) + .unwrap(); + + let baseline = workspace + .pull_diagnostics(PullDiagnosticsParams { + project_key, + path: BiomePath::new("/project/a.ts"), + categories: RuleCategories::default(), + only: Vec::new(), + skip: Vec::new(), + enabled_rules: Vec::new(), + pull_code_actions: true, + }) + .unwrap(); + + let baseline_plugin_diags: Vec<_> = baseline + .diagnostics + .iter() + .filter(|diag| diag.category().is_some_and(|cat| cat.name() == "plugin")) + .collect(); + assert_eq!(baseline_plugin_diags.len(), 1); + // Configure with the plugin and disable it via pluginRules @@ - workspace - .update_settings(UpdateSettingsParams { + workspace.update_settings(UpdateSettingsParams { project_key, configuration: Configuration { - plugins: Some(Plugins(vec![PluginConfiguration::Path( - "./plugin.grit".to_string(), - )])), linter: Some(LinterConfiguration { plugin_rules: Some(PluginRules(plugin_rules_map)), ..Default::default() }), ..Default::default() }, workspace_directory: Some(BiomePath::new("/project")), extended_configurations: Default::default(), - }) - .unwrap(); - - workspace - .open_file(OpenFileParams { - project_key, - path: BiomePath::new("/project/a.ts"), - content: FileContent::FromServer, - document_file_source: None, - persist_node_cache: false, - }) - .unwrap(); + }).unwrap();crates/biome_configuration/src/analyzer/linter/mod.rs (1)
3-8: Severity coverage confirmed;#[serde(transparent)]remains optional.
RulePlainConfigurationexposes the full set of severity levels (Off, On, Info, Warn, Error) for plugin rules, so no action needed there. The#[serde(transparent)]suggestion is still worth considering if you want to make the newtype wrapping explicit for future maintainers—serde's behaviour is already correct, but the attribute would eliminate any "is this actually transparent?" drive-by questions.crates/biome_analyze/src/options.rs (1)
56-97: Naming's slightly ambiguous; the emission logic looks sound.The
plugin_rule_severity(&self, plugin_name: &str)parameter could be clearer—consider renaming torule_nameor updating the docs, since it refers to the full rule identifier, not just the plugin.The emission pipeline correctly gates on
is_off()before processing, so the severity check is properly implemented.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
.changeset/plugin-rules-config.mdcrates/biome_analyze/src/lib.rscrates/biome_analyze/src/options.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_configuration/src/lib.rscrates/biome_configuration/src/overrides.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/css.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_service/src/file_handlers/grit.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/settings.rscrates/biome_service/src/workspace.tests.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use thedbg!()macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
crates/biome_service/src/workspace*.rs
📄 CodeRabbit inference engine (crates/biome_service/CONTRIBUTING.md)
Implement the Workspace trait in the Biome Service to manage internal state of projects, including open documents, project layout instances, and module graph instances
Files:
crates/biome_service/src/workspace.tests.rs
🧠 Learnings (36)
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Use `Option<_>` wrapper for rule option fields to enable proper merging of configurations
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Rule options must be defined in the `biome_rule_options` crate with a file named after the rule
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rs.changeset/plugin-rules-config.mdcrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : When porting rules from other linters, use `sources` metadata with `RuleSource::Eslint().same()` for identical behavior or `.inspired()` for different behavior
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `action` function and add `fix_kind` metadata to the rule macro if the rule provides code actions
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Deprecated rules must include a `deprecated` field in the `declare_lint_rule!` macro with an explanation of what rule to use instead
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Implement `biome_deserialize::Merge` for rule option types to define how shared and user configurations are merged
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `declare_lint_rule!` macro with a `version` field set to `next` for new rules
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Apply `#[serde(rename_all = "camelCase")]` to rule option structs to match JSON configuration naming convention
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `use` prefix when the rule's sole intention is to mandate a single concept
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `rule_category!()` macro to refer to the diagnostic category instead of dynamically parsing its string name
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/file_handlers/javascript.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use the `Semantic<T>` query type to access semantic information about bindings, references, and scope within a rule
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use helper functions like `map`, `filter`, and `and_then` to avoid excessive nested `if let` statements
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_service/src/file_handlers/graphql.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement custom `Queryable` and `Visitor` types for rules that require deep inspection of child nodes to avoid inefficient traversals
Applied to files:
crates/biome_service/src/file_handlers/css.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `.ok()?` to transform `Result` types into `Option` or `let else` pattern to handle errors when the function returns `Vec`
Applied to files:
crates/biome_service/src/file_handlers/css.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : New rules must be placed inside the `nursery` group before promotion to other groups
Applied to files:
crates/biome_configuration/src/lib.rscrates/biome_service/src/configuration.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Apply `#[serde(deny_unknown_fields)]` to rule option structs to enforce strict configuration validation
Applied to files:
crates/biome_configuration/src/lib.rscrates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_service/src/file_handlers/graphql.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Use `Box<[Box<str>]>` instead of `Vec<String>` for collections of strings in rule options to save memory
Applied to files:
crates/biome_configuration/src/lib.rscrates/biome_analyze/src/options.rscrates/biome_service/src/workspace.tests.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `ctx.get_service()` to retrieve services by type when a rule requires multiple services beyond those pulled in the Query
Applied to files:
crates/biome_configuration/src/lib.rscrates/biome_service/src/configuration.rscrates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-22T09:27:13.161Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:27:13.161Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.
Applied to files:
crates/biome_service/src/file_handlers/html.rscrates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_configuration/src/overrides.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/javascript.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : The first paragraph of rule documentation must be written in a single line to ensure proper rendering in the rules overview table
Applied to files:
crates/biome_service/src/file_handlers/html.rscrates/biome_service/src/settings.rscrates/biome_configuration/src/overrides.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Rule option types must derive `Deserializable`, `Serialize`, `Deserialize`, and optionally `JsonSchema` traits
Applied to files:
crates/biome_service/src/file_handlers/json.rscrates/biome_service/src/configuration.rscrates/biome_analyze/src/options.rscrates/biome_analyze/src/lib.rscrates/biome_configuration/src/analyzer/linter/mod.rscrates/biome_service/src/file_handlers/grit.rs
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 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:
.changeset/plugin-rules-config.md
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Implement the Diagnostic trait on types, or use the #[derive(Diagnostic)] procedural macro to implement the trait. Configure category, severity, description, message, location, and tags using the #[diagnostic] attribute
Applied to files:
crates/biome_analyze/src/options.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper types from the biome_diagnostics::v2 module (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) or implement the Advices trait yourself for custom advice handling
Applied to files:
crates/biome_analyze/src/options.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use #[derive(Diagnostic)] on enums when every variant contains a type that is itself a diagnostic
Applied to files:
crates/biome_analyze/src/options.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic
Applied to files:
crates/biome_analyze/src/lib.rscrates/biome_service/src/workspace.tests.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `run` function to return `Option<Self::State>` or `Vec<Self::State>` (as `Box<[Self::State]>`) depending on whether the rule reports one or multiple signals
Applied to files:
crates/biome_analyze/src/lib.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `diagnostic` function to provide error messages explaining what the error is, why it is triggered, and what the user should do
Applied to files:
crates/biome_analyze/src/lib.rscrates/biome_service/src/file_handlers/javascript.rs
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Implement watcher tests for workspace methods in watcher.tests.rs and end-to-end tests in LSP tests
Applied to files:
crates/biome_service/src/workspace.tests.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/Cargo.toml : Include development dependencies in `Cargo.toml` for formatter tests: `biome_formatter_test`, `biome_<language>_factory`, `biome_<language>_parser`, `biome_parser`, `biome_service`, `countme`, `iai`, `quickcheck`, `quickcheck_macros`, and `tests_macros`
Applied to files:
crates/biome_service/src/workspace.tests.rs
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace*.rs : Implement the Workspace trait in the Biome Service to manage internal state of projects, including open documents, project layout instances, and module graph instances
Applied to files:
crates/biome_service/src/workspace.tests.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/* : Create test files with `invalid` and `valid` prefixes to represent code that should and should not trigger the rule
Applied to files:
crates/biome_service/src/workspace.tests.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `no` prefix when the rule's sole intention is to forbid a single concept
Applied to files:
crates/biome_service/src/workspace.tests.rs
📚 Learning: 2025-12-21T21:15:03.796Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: Applies to **/*.rs : Use inline rustdoc documentation for rules, assists, and their options
Applied to files:
crates/biome_service/src/workspace.tests.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Code blocks in rule documentation must specify a language identifier and be tagged with `expect_diagnostic` for invalid examples or remain untagged for valid examples
Applied to files:
crates/biome_service/src/workspace.tests.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `Markup!` macro for diagnostic messages and code action descriptions to ensure proper formatting
Applied to files:
crates/biome_service/src/file_handlers/javascript.rs
🧬 Code graph analysis (8)
crates/biome_service/src/file_handlers/css.rs (1)
crates/biome_service/src/configuration.rs (2)
to_analyzer_rules(459-477)to_plugin_rules_configuration(480-490)
crates/biome_service/src/file_handlers/html.rs (1)
crates/biome_service/src/configuration.rs (2)
to_analyzer_rules(459-477)to_plugin_rules_configuration(480-490)
crates/biome_service/src/file_handlers/json.rs (1)
crates/biome_service/src/configuration.rs (2)
to_analyzer_rules(459-477)to_plugin_rules_configuration(480-490)
crates/biome_service/src/file_handlers/graphql.rs (1)
crates/biome_service/src/configuration.rs (2)
to_analyzer_rules(459-477)to_plugin_rules_configuration(480-490)
crates/biome_service/src/workspace.tests.rs (1)
crates/biome_configuration/src/analyzer/mod.rs (7)
default(86-88)default(132-134)default(363-365)default(1120-1122)from_str(613-618)from_str(746-824)from_str(891-897)
crates/biome_configuration/src/overrides.rs (1)
crates/biome_service/src/settings.rs (1)
linter(210-212)
crates/biome_service/src/file_handlers/javascript.rs (1)
crates/biome_service/src/configuration.rs (2)
to_analyzer_rules(459-477)to_plugin_rules_configuration(480-490)
crates/biome_service/src/file_handlers/grit.rs (2)
crates/biome_analyze/src/options.rs (2)
configuration(219-221)plugin_rules(256-258)crates/biome_service/src/configuration.rs (1)
to_plugin_rules_configuration(480-490)
🔇 Additional comments (12)
crates/biome_service/src/file_handlers/css.rs (1)
6-7: Plugin rule configuration wiring looks consistent.Good: computing
plugin_rulesfromSettings+file_pathand threading it intoAnalyzerConfigurationkeeps override semantics centralised into_plugin_rules_configuration.Also applies to: 237-251
crates/biome_service/src/file_handlers/json.rs (1)
5-5: Nice addition; please sanity-check thePreferredQuote::Doublebehaviour change.
with_plugin_rules(plugin_rules)is spot-on. The only thing to double-check is whether hard-codingPreferredQuote::Doublehere is intentional vs relying on the previous default.Also applies to: 224-242
crates/biome_service/src/file_handlers/javascript.rs (1)
7-8: Consistent plugin-rules plumbing.The new
plugin_rulesderivation and.with_plugin_rules(plugin_rules)integration matches the existing configuration-building style and keeps the per-path logic in one place.Also applies to: 380-389
crates/biome_configuration/src/lib.rs (1)
39-42: Sensible public re-export.Re-exporting
PluginRuleshere makes the new config surface easier to consume downstream without spelunking modules.crates/biome_service/src/file_handlers/graphql.rs (1)
7-8: Nice, consistent wiring of plugin rules into GraphQL analysis.
Pullingto_plugin_rules_configuration(...)intoresolve_analyzer_optionsand feeding it via.with_plugin_rules(...)is clean and keeps the existing rules path unchanged.Also applies to: 174-183
crates/biome_service/src/file_handlers/html.rs (1)
7-8: LGTM: plugin rules now flow into HTML analysis as intended.
This matches the new configuration plumbing and keeps the existing.with_rules(...)behaviour intact.Also applies to: 203-213
crates/biome_analyze/src/lib.rs (2)
41-45: Re-export looks sensible.
SurfacingPluginRuleSeverity/PluginRulesConfigurationhere makes the feature easier to consume downstream.
426-445: Your UX concern about disabled rules + suppression comments is valid—there's a test gap here.When a plugin rule is disabled via config and a
biome-ignore lint/plugin/...comment exists, the short-circuit at line 432 preventsdid_suppress_signalfrom being set. This meansfinalize_suppressions()will incorrectly report the suppression as unused. The existing testplugin_rules_can_be_disabled_via_config()doesn't cover this scenario—it has no suppression comment on the disabled rule. You'll want to either:
- Track that a suppression matched a config-disabled rule (set
already_suppressedor similar), or- Add a test case with
biome-ignoreon a disabled plugin rule to catch this UX issue.crates/biome_service/src/configuration.rs (1)
479-507: Override precedence confirmed. TheSettings::as_plugin_rulesimplementation correctly merges base plugin rules with pattern overrides viamerge_with(). Rustdoc claim is accurate; conversion helpers are sound.crates/biome_service/src/file_handlers/grit.rs (1)
6-7: Nice: plugin rules are now wired into Grit analysis without disturbing existing defaults.
AnalyzerConfiguration::default().with_plugin_rules(...)keeps the change nicely scoped, andto_plugin_rules_configuration(global, path.as_path())should correctly respect per-path overrides.Also applies to: 13-13, 143-159
crates/biome_service/src/workspace.tests.rs (1)
900-1024: Overrides test reads well and actually proves the override path is doing the work.
Asserting 1 diagnostic for/project/a.tsand 0 for/project/scripts/b.tsis a nice, crisp signal.crates/biome_service/src/settings.rs (1)
18-20: Override-aware merge forplugin_rulesis consistent with the rest of Settings.
Settings::as_plugin_rules()mirrors the rules/domains merging approach, and the wiring throughto_override_settings/to_linter_settings/TryFromlooks complete.Also applies to: 262-281, 454-456, 484-486, 1794-1802, 2026-2051
Summary
Add support for configuring individual plugin rules via configuration, including in overrides. Plugin rules can be set to off/on/info/warn/error.
Example Configuration
{ "linter": { "pluginRules": { "my-plugin": "off" } }, "overrides": [{ "includes": ["scripts/**"], "linter": { "pluginRules": { "my-plugin": "off" } } }] }Changes
PluginRulestype andplugin_rulesfield toLinterConfigurationplugin_rulestoOverrideLinterConfigurationfor override supportPluginRuleSeverityenum supporting Off/On/Info/Warn/Errorflush_matches()to skip emission of disabled plugin rulesTest Plan
plugin_rules_can_be_disabled_via_configtestplugin_rules_can_be_disabled_in_overridestestNotes
my-plugin.grit→"my-plugin")