{"id":32287891,"url":"https://github.com/saropa/saropa_lints","last_synced_at":"2026-06-01T02:00:50.683Z","repository":{"id":271436401,"uuid":"913444496","full_name":"saropa/saropa_lints","owner":"saropa","description":"2100+ advanced lint rules for Flutter \u0026 Dart. Catches memory leaks, security flaws (OWASP), and runtime crashes that standard linters miss. Optimized for AI coding assistants.","archived":false,"fork":false,"pushed_at":"2026-05-31T17:21:44.000Z","size":31472,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-31T18:17:57.227Z","etag":null,"topics":["accessibility","bloc","code-quality","compliance","dart","dev-tools","flutter","linter","memory-leaks","owasp","riverpod","security","static-analysis"],"latest_commit_sha":null,"homepage":"https://saropa.github.io/saropa_lints/","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saropa.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-07T17:38:29.000Z","updated_at":"2026-05-31T17:21:48.000Z","dependencies_parsed_at":"2026-01-05T15:07:44.599Z","dependency_job_id":"c2c2d8e0-5ad8-47f6-88b4-f89a3cbd9ec3","html_url":"https://github.com/saropa/saropa_lints","commit_stats":null,"previous_names":["saropa/saropa_lints"],"tags_count":275,"template":false,"template_full_name":null,"purl":"pkg:github/saropa/saropa_lints","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saropa%2Fsaropa_lints","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saropa%2Fsaropa_lints/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saropa%2Fsaropa_lints/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saropa%2Fsaropa_lints/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saropa","download_url":"https://codeload.github.com/saropa/saropa_lints/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saropa%2Fsaropa_lints/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33756578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","bloc","code-quality","compliance","dart","dev-tools","flutter","linter","memory-leaks","owasp","riverpod","security","static-analysis"],"created_at":"2025-10-23T02:20:09.965Z","updated_at":"2026-06-01T02:00:50.672Z","avatar_url":"https://github.com/saropa.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Saropa Lints - Advanced Static Analysis](https://raw.githubusercontent.com/saropa/saropa_lints/main/assets/banner_v2.png)\n\n\u003c!-- # Saropa Lints --\u003e\n\n**Catch memory leaks, security vulnerabilities, and runtime crashes that standard linters miss.**\n\u003cbr\u003e\nDeveloped by [Saropa](https://saropa.com) to make the world of Dart \u0026 Flutter better.\n\n\u003c!-- ref: https://shields.io/badges and https://simpleicons.org/?q=flutter --\u003e\n\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n\n\u003c!-- Note that the badges are all grouped together so they flow horizontally. --\u003e\n\n[![pub package](https://img.shields.io/pub/v/saropa_lints.svg?style=flat-square\u0026logo=dart\u0026color=blue)](https://pub.dev/packages/saropa_lints) [![pub points](https://img.shields.io/pub/points/saropa_lints?style=flat-square\u0026logo=dart)](https://pub.dev/packages/saropa_lints/score) [![likes](https://img.shields.io/pub/likes/saropa_lints?style=flat-square\u0026logo=dart\u0026color=red)](https://pub.dev/packages/saropa_lints/score) [![ci](https://img.shields.io/github/actions/workflow/status/saropa/saropa_lints/ci.yml?branch=main\u0026style=flat-square\u0026logo=github\u0026label=build)](https://github.com/saropa/saropa_lints/actions) [![GitHub stars](https://img.shields.io/github/stars/saropa/saropa_lints?style=flat-square\u0026logo=github)](https://github.com/saropa/saropa_lints) [![GitHub forks](https://img.shields.io/github/forks/saropa/saropa_lints?style=flat-square\u0026logo=github)](https://github.com/saropa/saropa_lints) [![GitHub issues](https://img.shields.io/github/issues/saropa/saropa_lints?style=flat-square\u0026logo=github)](https://github.com/saropa/saropa_lints/issues) [![GitHub last commit](https://img.shields.io/github/last-commit/saropa/saropa_lints?style=flat-square\u0026logo=github)](https://github.com/saropa/saropa_lints/commits)\n\n[![Saropa Lints Badge](https://img.shields.io/badge/saropa_lints-2134-blue?style=flat\u0026logo=flutter\u0026logoColor=white\u0026color=435489)](https://pub.dev/packages/saropa_lints) [![Flutter Platform](https://img.shields.io/badge/platform-flutter-02569B.svg?style=flat-square\u0026logo=flutter)](https://flutter.dev/) [![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg?style=flat-square)](https://opensource.org/licenses/MIT)\n\n\u003c/div\u003e\n\u003cbr\u003e\n\n\u003e 💬 **Have feedback on Saropa Lints?** Please share it by [opening an issue](https://github.com/saropa/saropa_lints/issues/new) on GitHub!\n\n---\n\n## VS Code Extension (Recommended)\n\n**Install the [Saropa Lints VS Code extension](https://marketplace.visualstudio.com/items?itemName=saropa.saropa-lints)** for the full experience. Also on [Open VSX](https://open-vsx.org/extension/saropa/saropa-lints) (Cursor, VSCodium).\n\nThe package and the extension are **one product** — published together and versioned in sync. The Dart package provides the rules; the extension is the primary setup, configuration, and triage surface. This README is the single source for both the pub.dev and Marketplace listings.\n\nLint integration defaults **on** for Dart workspaces (`saropaLints.enabled`). Overview and setup stay available even when integration is off; turn it off with **Saropa Lints: Turn Off Lint Integration** if you only want the sidebar without analyzer runs. After installing, run **\"Saropa Lints: Getting Started\"** from the Command Palette for a guided tour of all features.\n\nAt a glance:\n\n- **Health Score** — 0–100 score in the status bar; green/yellow/red bands in the Overview\n- **Violations view** — Violations grouped by severity and file, with Error Lens-style inline annotations; multi-select works with **Copy as JSON**\n- **Security Posture** — OWASP Top 10 coverage matrix, compliance export\n- **Triage** — Disable noisy rules from the UI; see estimated score impact before acting\n- **Rule packs / Lints Config** — Enable stack bundles (Riverpod, Drift, …) from **Saropa Lints: Open Lints Config** (editor tab: per-pack toggles, rule lists, target platforms when embedder folders exist); see [`doc/guides/rule_packs.md`](https://github.com/saropa/saropa_lints/blob/main/doc/guides/rule_packs.md)\n- **Package Vibrancy** — Dependency health, alerts, and optional **version-gap** PR/issue triage (enable with `saropaLints.packageVibrancy.enableVersionGap`; a GitHub token improves results)\n- **Project Vibrancy** — Project code-health scoring for your own Dart source via **Open Code Health Dashboard** (editor-area webview; same scan as the CLI JSON output); use the graph icon on **Violations**, **Overview**, **Config**, or **Package Vibrancy** view titles, or the Command Palette\n- **TODOs \u0026 Hacks** — Sidebar scan for TODO/FIXME/HACK-style markers; full-workspace scan is **opt-in** (`saropaLints.todosAndHacks.workspaceScanEnabled`; leave `false` until you need it) via **TODOs \u0026 Hacks: Enable workspace scan**\n- **File Risk** — Files ranked by violation density; focus on the riskiest first\n- **Trends** — Score progression over time with milestone celebrations\n\nProblems panel empty, analyzer plugin stuck, or no lightbulb fixes? Start with **[`doc/troubleshooting.md`](https://github.com/saropa/saropa_lints/blob/main/doc/troubleshooting.md)** (narrow IDE-focused checks) — then README [Troubleshooting](#troubleshooting) if you still need broader setup help.\n\n![Package Vibrancy Report showing dependency health and version status](https://raw.githubusercontent.com/saropa/saropa_lints/main/assets/20260401_package_vibrancy_report.png)\n\n**Set Up Project** wires `pubspec.yaml`, `analysis_options.yaml`, and analysis. No terminal commands required for that path.\n\n### Requirements\n\n- Dart SDK (or Flutter SDK) on PATH\n- A Dart/Flutter project (workspace with `pubspec.yaml`)\n\n### Usage\n\n1. Open a Dart/Flutter project.\n2. Open the **Saropa Lints** view (checklist icon in the activity bar). **Overview \u0026 options** lists workspace settings, **Activity bar sections** (the default place to show/hide panels), and links (About, Getting Started).\n3. When you are ready to wire the package in, run **Saropa Lints: Set Up Project (pubspec + config)** (or click **Lint integration: Off** if you disabled integration). That will add `saropa_lints` to `dev_dependencies`, run pub get, run `write_config` for your tier, and optionally analyze.\n4. Run **\"Saropa Lints: Getting Started\"** from the Command Palette for a guided tour of all features.\n5. Use **Run Analysis** and **Open Analysis Options** as needed. Violations appear in the **Violations** view when `reports/.saropa_lints/violations.json` exists (written by the analyzer).\n\n### Health Score\n\nA single 0–100 number in the **Overview** and **status bar**, computed from violation count and impact severity. Higher is better:\n\n- **80–100** (green): Good shape — few issues, none critical.\n- **50–79** (yellow): Needs work — some high-impact issues.\n- **Below 50** (red): Serious problems — many critical/high-impact violations.\n\nThe status bar shows the score with a delta from the last run, plus the finding count, in a single item (e.g. \"Saropa: 78 ▲4 · ⚠ 12\"); its background stays neutral rather than turning red, and the score is held back until a full analysis has covered enough of the project. When violations decrease, a celebration message includes the score change.\n\n### Violations view\n\nThe **Violations** view lists lint findings from your analysis report in a **tree**: first by **severity** (Error, Warning, Info), then by **project structure** (folders and files). Each file lists violations (capped per file; excess shown as “and N more…”).\n\n- **Group by (toolbar):** Change how the tree is organized — by Severity (default), File, Impact, Rule, OWASP Category, Rule Type, or Rule Status. Click the tree icon in the toolbar to switch.\n- **Filters (toolbar):** Filter by text (file path, rule, or message), Filter by type (severity and impact), Filter by rule (multi-select), or Filter by rule metadata (`ruleType` / `ruleStatus`). When active, the view shows “Showing X of Y”.\n- **Suppressions:** Right-click a folder, file, violation, or severity node to hide it from the tree (e.g. “Hide folder”, “Hide rule”). Suppressions are persisted; use **Clear suppressions** in the toolbar to restore all.\n- **Code Lens:** In Dart files that have violations, a lens at the top shows e.g. “Saropa: 3 violations — Show in Saropa”. Click to open the Violations view filtered to that file.\n- **Multi-select + JSON:** Ctrl+click (Windows/Linux) or Cmd+click (macOS) multiple tree rows, then **Copy as JSON** (context menu or toolbar) to export those subtrees. For all violations at once, use `reports/.saropa_lints/violations.json` (see [VIOLATION_EXPORT_API.md](https://github.com/saropa/saropa_lints/blob/main/VIOLATION_EXPORT_API.md)).\n- **Context menus:** **Explain rule** (book icon) opens a side tab with full rule details; Apply fix (wrench icon) and Copy message (clipboard icon), then a separator, then hide options: Hide rule from view, Hide rule in this file. On folders/files: Hide folder, Hide file, Copy path; on files: Fix all in file, Show only this file. On severity nodes: Hide this severity.\n- **Explain rule:** Right-click a violation and choose **Explain rule** (or run **Saropa Lints: Explain rule** from the command palette and pick a rule) to open a tab beside your code with the rule’s problem message, how to fix, severity, impact, OWASP mapping (if any), and a link to the ROADMAP.\n- **Violation tooltips:** Show rule name and a “More” link to rule documentation (ROADMAP).\n- **Summary → Violations:** Click **Total violations** in the Summary view to open the Violations view with all findings (clears any active filters). By severity / By impact rows open Violations with the matching filter, and **By rule type / By rule status** rows open Violations filtered to matching metadata groups.\n- **Problems view:** Right-click a problem and choose **Saropa Lints: Show in Saropa Lints** to focus the Violations view filtered to the active file.\n\nThe **File Risk** view ranks files by weighted violation density (same weights as the Health Score). Files with critical violations appear first with a flame icon. Click a file to filter the Violations view to that file.\n\nThe **Security Posture** view shows OWASP Mobile and Web Top 10 coverage based on the active rules and violations. Right-click a category to export an OWASP compliance report.\n\nThe **Triage** view focuses on rule groups by impact/volume and quick enable/disable actions, while full config controls live in **Config Dashboard**.\n\n**TODOs \u0026 Hacks** — Todo-Tree-style markers (TODO, FIXME, …) **after you opt in** to workspace scanning (`saropaLints.todosAndHacks.workspaceScanEnabled`, default **off** to avoid heavy full-repo I/O). Until then, the view shows **Enable workspace scan…** (or use **TODOs \u0026 Hacks: Enable workspace scan**). No `violations.json` required. Default globs: Dart, YAML, TypeScript, JavaScript; add `**/*.md` to `includeGlobs` if you want Markdown. Toolbar: Refresh, Toggle group by tag / folder. Auto-refresh on save respects the same gate. Custom regex: `saropaLints.todosAndHacks.customRegex`.\n\nThe **Logs** view lists analysis reports from `reports/`. Each log shows a parsed hint (e.g. violation counts, init tier). A \"Run Analysis\" action appears when the latest report is over 1 hour old.\n\n### Package Vibrancy activity signal\n\nThe Package Vibrancy report includes an **Activity** grade column (**A-F**) that reflects maintenance activity separately from overall vibrancy.\n\n- Uses both **code activity** (last commit from GitHub `pushed_at`) and **release activity** (latest pub.dev publish date).\n- Activity score uses a 90-day decay for both timelines and takes the weaker side.\n- Report surfaces dormancy hints:\n  - **90+ days** with no commits and no releases: stale\n  - **180+ days** with no commits and no releases: dormant\n\nThis helps distinguish \"not recently released but still actively maintained\" from \"no recent release and no recent code changes.\"\n\n### Code Health (your own source)\n\nThe **Code Health Dashboard** scores the functions in your own Dart code (separate from Package Vibrancy, which scores dependencies).\n\n- Scans your project with `dart run saropa_lints:project_vibrancy` and shows the worst function hotspots in an editor-tab dashboard.\n- KPI cards double as one-click filters for `unused`, `uncovered`, `stub_tested`, `suspicious_coverage`, and `test_drift`.\n- Free-text search filter, sortable table, and active-filter chip strip.\n- Quality gates (min grade, max-unused, max-uncovered, etc.) configured under **Code Health** settings — failures show a banner and are surfaced as a warning toast.\n- Run from the Command Palette via **Saropa Lints: Open Code Health Dashboard**, from the Saropa Lints sidebar entry **Code Health Dashboard**, or from the in-dashboard **Rescan** button.\n\n### Extension settings\n\n| Setting | Default | Description |\n|--------|--------|-------------|\n| `saropaLints.enabled` | `true` | Lint integration for this workspace (upgrade checks, status-bar treatment). Overview stays usable when off; use **Set Up Project** to add the package and config. |\n| `saropaLints.tier` | `recommended` | Tier used when enabling or re-initializing (essential, recommended, professional, comprehensive, pedantic). |\n| `saropaLints.runAnalysisAfterConfigChange` | `true` | Run `dart analyze` after init when enabling. |\n| `saropaLints.runAnalysisOpenEditorsOnly` | `false` | When true, `Run Analysis` runs `dart/flutter analyze` only for Dart files currently open in VS Code (workspace text documents) under the detected project root (pubspec.yaml directory). |\n| `saropaLints.issuesPageSize` | `100` | Max violations shown per file in the Violations tree (1–1000). Remaining appear as “and N more…”. |\n| `saropaLints.violationsGroupBy` | `impact` | Default tree grouping: `impact`, `severity`, `file`, `rule`, `owasp`, `ruleType`, or `ruleStatus`. `impact` lists Critical / High first. Change anytime from the Violations toolbar. |\n\n**Sidebar defaults:** **Commands** (searchable index of every command), **Overview \u0026 options**, **Violations**, **Config Dashboard**, and **Package Vibrancy** show in the activity bar by default. Use **Saropa: Open Package Dashboard** for the full dependency report in an editor tab. Overview includes embedded Health Summary, Next Steps, and Riskiest Files groups when violations exist. **Package Details** appears automatically after a Vibrancy scan. Turn on standalone **Triage**, Summary, Security, File Risk, TODOs, etc. from **Overview \u0026 options -\u003e Activity bar sections** (default path) or Settings (`saropaLints.sidebar.show*` advanced mirror).\n\n| **TODOs \u0026 Hacks** | | |\n|--------|--------|-------------|\n| `saropaLints.todosAndHacks.workspaceScanEnabled` | `false` | When **true**, the view scans the workspace for comment markers (resource-intensive). |\n| `saropaLints.todosAndHacks.tags` | `[\"TODO\", \"FIXME\", \"HACK\", \"XXX\", \"BUG\"]` | Tags to search for in comments (case-sensitive). |\n| `saropaLints.todosAndHacks.includeGlobs` | `[\"**/*.dart\", \"**/*.yaml\", \"**/*.ts\", \"**/*.js\"]` | Glob patterns for files to scan. |\n| `saropaLints.todosAndHacks.excludeGlobs` | `[\"**/node_modules/**\", \"**/.dart_tool/**\", \"**/build/**\", \"**/.git/**\"]` | Extra exclude patterns (merged with search.exclude). |\n| `saropaLints.todosAndHacks.maxFilesToScan` | `2000` | Maximum number of files to scan; view shows a message when capped. |\n| `saropaLints.todosAndHacks.autoRefresh` | `true` | Refresh the TODOs \u0026 Hacks view when a file is saved (debounced). |\n| `saropaLints.todosAndHacks.groupByTag` | `false` | When true, group tree by tag (TODO, FIXME, …) then by file; when false, by folder then file. |\n| `saropaLints.todosAndHacks.customRegex` | `\"\"` | Optional regex override for comment markers. Use capture group 1 for tag, optional group 2 for snippet. Empty = default (//, #, \u003c!-- + tags). Invalid regex falls back to default. |\n\n### Extension commands\n\n- **Saropa Lints: Getting Started** — Open the walkthrough with a guided tour of all features.\n- **Saropa Lints: Set Up Project (pubspec + config)** — Add `saropa_lints` to the project and run init (and optionally analyze).\n- **Saropa Lints: Turn Off Lint Integration** — Disable integration for this workspace (does not remove files).\n- **Saropa Lints: Run Analysis** — Run `dart analyze` / `flutter analyze`.\n- **Saropa Lints: Initialize / Update Analysis Options** — Write analysis_options.yaml with the current tier (uses write_config).\n- **Saropa Lints: Open Analysis Options** — Open `analysis_options_custom.yaml` or `analysis_options.yaml`.\n- **Filter by text…** / **Filter by severity and impact…** / **Filter by rule name…** / **Filter by rule metadata…** — Filter the Violations tree (view toolbar).\n- **Clear filters** / **Clear suppressions** — Reset filters or hidden items (view toolbar when active).\n- **Saropa Lints: Show All Violations** — Open the Violations view and show all findings (clears filters). Used when clicking \"Total violations\" in Summary.\n- **Saropa Lints: Show in Saropa Lints** — Focus the Violations view filtered to the active editor's file (e.g. from Problems view context menu or command palette).\n- **Group by…** — Change how the Violations tree is organized: Severity, File, Impact, Rule, OWASP Category, Rule Type, or Rule Status (view toolbar).\n- **Explain rule** — On a violation in the Violations tree (context menu) or from the command palette (pick a rule): open a side tab with full rule details (message, fix, severity, impact, OWASP, ROADMAP link).\n- **Apply fix** — On a violation in the Violations tree (context menu): run the Dart analyzer's quick fix for that location without opening the file.\n- **Fix all in this file** — On a file in the Violations tree (context menu): run all available quick fixes for that file bottom-up.\n- **TODOs \u0026 Hacks: Refresh** — Refresh the TODOs \u0026 Hacks view (full rescan only when workspace scan is enabled).\n- **TODOs \u0026 Hacks: Enable workspace scan** — Turn on `workspaceScanEnabled` so marker search can run.\n- **Create Saropa Lints Instructions for AI Agents** — Create `.cursor/rules/saropa_lints_instructions.mdc` in the workspace from the bundled template (**Overview \u0026 options → Help \u0026 resources** or Command Palette). Gives AI agents project guidelines for working on saropa_lints.\n- **TODOs \u0026 Hacks: Toggle group by tag / folder** — Switch between grouping by folder→file→line and by tag→file→line (view toolbar).\n- **Export OWASP Compliance Report** — Generate a markdown report with Mobile/Web Top 10 coverage tables and gap analysis.\n\n#### Violation context menu: Hide options\n\nOn a violation, the two “Hide” options mean:\n\n| Option | Effect |\n|--------|--------|\n| **Hide rule from view** | Hides that rule **everywhere** in the Violations tree (all files). |\n| **Hide rule in this file** | Hides that rule **only in this file**; the same rule still appears in other files. |\n\n(“Hide this impact” is not shown on violations: it would hide all violations with that impact level, which is confusing from a single violation. Severity nodes still have “Hide this severity”.)\n\nThese are **view-only** suppressions: they do not change `analysis_options.yaml` or source code. They are stored in workspace state and only affect what the Violations tree shows.\n\n**To undo or manage:** Use **Clear suppressions** in the Violations view toolbar (it appears when any suppressions are active). That clears all hidden folders, files, rules, rule-in-file, severities, and impacts at once. There is no per-item “unhide”; clearing restores everything. To see or edit raw suppressions you would need to inspect workspace state (e.g. extension storage); the UI only offers Clear suppressions.\n\n### API for other extensions\n\nWhen the extension is activated, it exposes a **public API** so other extensions (e.g. [Saropa Log Capture](https://pub.dev/packages/saropa_log_capture)) can read violations and run analysis without parsing `violations.json` from disk.\n\nUsage:\n\n```ts\nconst ext = vscode.extensions.getExtension\u003cimport('./api').SaropaLintsApi\u003e('saropa.saropa-lints');\nif (ext?.exports) {\n  const data = ext.exports.getViolationsData();\n  const path = ext.exports.getViolationsPath();\n  const params = ext.exports.getHealthScoreParams();\n  const version = ext.exports.getVersion();\n  await ext.exports.runAnalysis();\n  await ext.exports.runAnalysisForFiles(['lib/main.dart', 'lib/auth.dart']);\n}\n```\n\n| Method | Description |\n|--------|-------------|\n| `getViolationsData()` | Same shape as `violations.json`; `null` if no project root or read fails. |\n| `getViolationsPath()` | Absolute path to `reports/.saropa_lints/violations.json`; `null` if no project root. |\n| `getHealthScoreParams()` | `{ impactWeights, decayRate }` used by the health score formula. |\n| `runAnalysis()` | Runs full `dart analyze` / `flutter analyze` in the workspace. Returns `true` if exit code 0. |\n| `runAnalysisForFiles(files)` | Runs analyze for the given file paths only (e.g. stack-trace files). Capped at 50 files. Returns `true` if exit code 0. |\n| `getVersion()` | Extension version string (e.g. from package.json). |\n\nThe file contract `reports/.saropa_lints/violations.json` remains the primary integration point; the API is optional and allows Log Capture to avoid disk reads and to refresh analysis for specific files. For the violation export schema, see [VIOLATION_EXPORT_API.md](https://github.com/saropa/saropa_lints/blob/main/VIOLATION_EXPORT_API.md). The same `violations.json` file is used by [Saropa Log Capture](https://pub.dev/packages/saropa_log_capture) for bug report correlation — crash reports include the project's health score and OWASP violations affecting the crash file.\n\n---\n\n## Scope: Static Code vs. Runtime Data (Drift)\n\n`saropa_lints` and **[Saropa Drift Advisor](https://marketplace.visualstudio.com/items?itemName=saropa.saropa-drift-advisor)** are complementary, not overlapping. They analyze different things and should both be installed when you use Drift.\n\n|                 | `saropa_lints`                                                                                       | `saropa_drift_advisor`                                                                 |\n| --------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |\n| **Analyzes**    | Dart source code (AST)                                                                               | Live database file, schema, and data statistics                                        |\n| **Runs as**     | Analyzer plugin (compile-time)                                                                       | VS Code extension + debug server (runtime)                                             |\n| **Drift rules** | 32 static code-pattern rules in [`lib/src/rules/packages/drift_rules.dart`](lib/src/rules/packages/drift_rules.dart) | Runtime/schema diagnostics — anomalies, invariants, data quality, query performance    |\n| **Examples**    | `avoid_drift_enum_index_reorder`, `avoid_drift_update_without_where`, `require_drift_database_close` | Column-value outliers, schema drift, n+1 query detection, unique-index gaps            |\n| **Sees source** | Yes                                                                                                  | No                                                                                     |\n| **Sees data**   | No                                                                                                   | Yes                                                                                    |\n\n**Rule of thumb:**\n\n- A problem with the **code** you wrote (wrong TypeConverter, missing `WHERE`, unclosed DB) → `saropa_lints`.\n- A problem with the **data** in your running DB (unexpected distribution, schema mismatch, missing migration) → `saropa_drift_advisor`.\n\nNeither project will ever subsume the other — they operate on different inputs. File Drift-rule bugs against whichever project owns the rule surface that produced the diagnostic (look at the `source` / `owner` field in the Problems panel).\n\n---\n\n## Quick Start\n\n**Requirements:** Dart SDK `\u003e=3.9.0 \u003c4.0.0` (same constraint as this package’s [`pubspec.yaml`](https://github.com/saropa/saropa_lints/blob/main/pubspec.yaml)).\n\n### Option A — VS Code extension (recommended)\n\n1. Install [Saropa Lints](https://marketplace.visualstudio.com/items?itemName=saropa.saropa-lints) from the VS Code Marketplace\n2. Open the **Saropa Lints** sidebar (checklist icon in the activity bar)\n3. Run **Saropa Lints: Set Up Project** (or use the equivalent control in the Overview) to add the package and analysis config\n\nThe extension adds `saropa_lints` to your project, configures analysis options, and runs analysis. Use the Setup \u0026 triage view to change tier, disable rules, and manage platforms/packages. Run **Saropa Lints: Getting Started** from the command palette for a guided tour.\n\n### Option B — Tier preset (zero-config, no extension)\n\n```bash\ndart pub add --dev saropa_lints\n```\n\nAdd one line to your `analysis_options.yaml`:\n\n```yaml\ninclude: package:saropa_lints/tiers/recommended.yaml\n```\n\nRun `dart analyze` and issues appear in your IDE and terminal.\n\nAvailable presets: `essential.yaml` · `recommended.yaml` · `professional.yaml` · `comprehensive.yaml` · `pedantic.yaml`\n\n### Option C — CLI init (full control, CI/scripting)\n\n```bash\ndart pub add --dev saropa_lints\ndart run saropa_lints:init --tier recommended\n# Optional: rule packs from pubspec + lockfile (see doc/guides/rule_packs.md)\ndart run saropa_lints:init --list-packs\ndart run saropa_lints:init --tier recommended --enable-pack riverpod --enable-pack drift  # IDs must match packs applicable to your pubspec\n```\n\n\u003e **Note:** The CLI init is headless-only as of v9 — no interactive prompts. For interactive setup, use the VS Code extension.\n\n### Rule configuration cheatsheet\n\nUse this mental model:\n\n- **Tier** = broad baseline (`essential` → `pedantic`)\n- **Packs** = domain/version bundles (library and SDK migration groups)\n\nCurrent behavior:\n\n- Pack-owned package/SDK migration rules are **off unless their pack is enabled**.\n- Tier selection still controls non-pack-owned rules.\n- Explicit `diagnostics: rule_name: false` still disables a rule.\n\nMinimal setup pattern:\n\n```yaml\nplugins:\n  saropa_lints:\n    version: \"x.y.z\"\n    rule_packs:\n      enabled:\n        - riverpod\n        - flutter_sdk_3_32\n```\n\nQuick commands:\n\n```bash\ndart run saropa_lints:init --tier recommended\ndart run saropa_lints:init --list-packs\ndart run saropa_lints:init --tier recommended --enable-pack riverpod --enable-pack flutter_sdk_3_32\n```\n\nIf users are unsure, start with a tier only and enable packs later.\n\nThis updates (or creates) two files:\n\n- **`analysis_options.yaml`** — the `plugins: saropa_lints: diagnostics:` section is regenerated with every rule set to `true`/`false` for your tier. All other sections are preserved.\n- **`analysis_options_custom.yaml`** — your project settings (platforms, analysis output). Created on first run; never overwritten.\n\n**Optional runtime tier cap:** to enforce a stricter cumulative band than the rules still listed as enabled in YAML (for example in CI), set the `SAROPA_TIER` environment variable to `essential`, `recommended`, `professional`, `comprehensive`, or `pedantic`, or set `saropa_tier` in `analysis_options_custom.yaml` or `runtime_tier` / `saropa_tier` under `plugins.saropa_lints` in `analysis_options.yaml` — when both env and file are set, the environment variable wins.\n\n### Run analysis\n\n```bash\ndart analyze\n```\n\nIssues appear in your IDE's Problems panel and in the terminal. Saropa Lints runs as a native Dart analyzer plugin.\n\n\u003e **Available tiers:** `essential` · `recommended` · `professional` · `comprehensive` · `pedantic` — see [The 5 Tiers](#the-5-tiers) for details\n\u003e\n\u003e **Stuck?** See [Troubleshooting](#troubleshooting) · **Upgrading?** See [Migration guides](#migrating-from-other-tools)\n\n---\n\n## How It Works\n\n```\nDart package                    VS Code extension\n   │                                  │\n   ▼                                  ▼\nanalysis_options.yaml  ◄───  Set Up Project / Set Tier / Triage\n   │                                  │\n   ▼                                  ▼\ndart analyze           ◄───  Run Analysis (from UI)\n   │                                  │\n   ▼                                  ▼\nviolations.json        ───►  Health Score, Issues, Security,\n                             File Risk, Trends, Inline Annotations\n```\n\nThe **Dart package** provides **2134** lint rules via the native analyzer plugin. The **VS Code extension** reads `violations.json` and provides the UI: Health Score, Issues tree, Security Posture, File Risk, Setup \u0026 triage, and related views. Optional **Drift Advisor** integration shows index suggestions and data-quality anomalies from a running Drift Advisor server in a dedicated sidebar view and in Problems. Both are published together and versioned in sync.\n\n**Rule metadata:** Each rule can expose optional semantics—`RuleType` (bug, vulnerability, code smell, security hotspot), `tags`, MITRE **CWE** IDs, and `RuleStatus` (e.g. beta)—for compliance and future quality gates. Defaults are backward compatible; see [CONTRIBUTING.md](CONTRIBUTING.md) and [bugs/discussion/RULE_METADATA_BULK_STATUS.md](bugs/discussion/RULE_METADATA_BULK_STATUS.md).\n\n---\n\n## Why Saropa Lints?\n\n### Linting vs static analysis\n\n`dart analyze` checks syntax and style. Static analysis checks _behavior_.\n\nYour linter catches unused variables and formatting issues. It doesn't catch undisposed controllers, hardcoded credentials, or `setState` after `dispose` — because these require understanding what the code _does_, not just how it's written.\n\nIn mature ecosystems, tools like [SonarQube](https://www.sonarsource.com/products/sonarqube/), [Coverity](https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html), and [Checkmarx](https://checkmarx.com/) fill this gap. Flutter hasn't had an equivalent — until now.\n\n![Flutter memory leak detection in VS Code showing undisposed TextEditingController](https://raw.githubusercontent.com/saropa/saropa_lints/main/assets/20260401_problems_tab.png)\n\n### What it catches\n\nCode that compiles but fails at runtime:\n\n```dart\n// Memory leak — controller never disposed\nfinal _controller = TextEditingController();\n\n// Crash — setState after widget disposed\nawait api.fetchData();\nsetState(() =\u003e _data = data);  // boom\n\n// State loss — new GlobalKey every build\nWidget build(context) {\n  final key = GlobalKey\u003cFormState\u003e();  // wrong\n  return Form(key: key, ...);\n}\n```\n\nSaropa Lints detects these patterns and hundreds more:\n\n- **Security** — Hardcoded credentials, sensitive data in logs, unsafe deserialization\n- **Accessibility** — Missing semantics, inadequate touch targets, screen reader issues\n- **Performance** — Unnecessary rebuilds, memory leaks, expensive operations in build\n- **Lifecycle** — setState after dispose, missing mounted checks, undisposed resources\n\n**Accuracy focused**: Rules use proper AST type checking instead of string matching, reducing false positives on variable names like \"upstream\" or \"spinning\".\n\n### Stop Debugging Known Issues\n\nSaropa Lints specifically targets the error messages developers search for when their app crashes. It statically analyzes and prevents:\n\n- **Memory Leaks:** `TextEditingController`, `AnimationController`, and `StreamSubscription` created but never disposed.\n- **Concurrency Bugs:** `BuildContext` usage across async gaps and unawaited futures in `initState`.\n- **Security Flaws:** Hardcoded API keys, insecure HTTP (cleartext), and weak cryptography.\n- **UI Crashes:** `setState() called after dispose()`, layout overflow risks, and null assertions on backend data.\n- **State Errors:** `Riverpod` providers reading inside `build` or `Bloc` events added in constructors.\n\n### Essential for popular packages\n\nIf you use **GetX**, **Riverpod**, **Provider**, **Bloc**, **Isar**, **Hive**, or **Firebase**, these audits are critical. These libraries are powerful but have patterns that fail silently at runtime:\n\n| Library      | Common issues caught                                                                             | Guide                                                    |\n| ------------ | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- |\n| **GetX**     | Undisposed controllers, memory leaks from workers, missing super calls                           | [Using with GetX](doc/guides/using_with_getx.md)         |\n| **Riverpod** | Circular provider deps, ref.read() in build, missing ProviderScope                               | [Using with Riverpod](doc/guides/using_with_riverpod.md) |\n| **Provider** | Provider.of in build causing rebuilds, recreated providers losing state                          | [Using with Provider](doc/guides/using_with_provider.md) |\n| **Bloc**     | Events in constructor, mutable state, unclosed Blocs, BlocListener in build                      | [Using with Bloc](doc/guides/using_with_bloc.md)         |\n| **Isar**     | Enum fields causing data corruption on schema changes; caching Isar streams (runtime crash risk) | [Using with Isar](doc/guides/using_with_isar.md)         |\n| **Hive**     | Missing init, unclosed boxes, hardcoded encryption keys, type adapter issues                     | [Using with Hive](doc/guides/using_with_hive.md)         |\n| **Firebase** | Unbounded queries, missing batch writes, invalid Analytics events, FCM token leaks               | [Using with Firebase](doc/guides/using_with_firebase.md) |\n\n![Screenshot of analysis_options_custom.yaml](https://raw.githubusercontent.com/saropa/saropa_lints/main/assets/20260401_analysis_options_custom_yaml.png)\n\nStandard linters don't understand these libraries. They see valid Dart code. Saropa Lints has 50+ rules specifically for library-specific anti-patterns that cause crashes, memory leaks, cost overruns, and data corruption in production. Recent update: `require_camera_permission_check` no longer triggers on non-camera controllers (e.g., IsarStreamController), eliminating a key false positive for Isar users. The new `avoid_cached_isar_stream` rule (with quick fix) prevents a common Isar runtime error.\n\n### Radical Transparency\n\nWe build in public. We don't just show you what works; we explicitly document what _doesn't_ work yet.\n\n- [**ROADMAP.md**](ROADMAP.md): Our active backlog. See exactly what rules are coming next and vote on priorities.\n- **Deferred rules** (in [ROADMAP.md](ROADMAP.md)#part-2-deferred-rules--technical-limitations): The \"Hard Problems.\" Rules we _can't_ implement yet due to technical limitations (cross-file analysis, heuristics). We invite the community to help crack these barriers.\n\n| Marker | Meaning                       | Example                                                                                 |\n| ------ | ----------------------------- | --------------------------------------------------------------------------------------- |\n| 🐙     | Tracked as GitHub issue       | [Open Issues](https://github.com/saropa/saropa_lints/issues)                            |\n| 💭     | Announcements, Q\u0026A, and Ideas | [Discussion: Diagnostic Statistics](https://github.com/saropa/saropa_lints/discussions) |\n\n![AI fixing Flutter security vulnerability automatically in Android Studio](https://raw.githubusercontent.com/saropa/saropa_lints/main/assets/20260401_build_report_terminal_tab.png)\n\n### Compliance: EAA \u0026 OWASP Security\n\nThe [European Accessibility Act](https://accessible-eu-centre.ec.europa.eu/content-corner/news/eaa-comes-effect-june-2025-are-you-ready-2025-01-31_en) takes effect June 2025, requiring accessible apps in retail, banking, and travel. GitHub detected [39 million leaked secrets](https://github.blog/security/application-security/next-evolution-github-advanced-security/) in repositories during 2024.\n\nThese aren't edge cases. They're compliance requirements and security basics that standard linters miss.\n\n### Comparison vs Standard Tools\n\nWhy switch? Saropa Lints covers everything in standard tools plus strict behavioral analysis.\n\n| Feature                              | `flutter_lints` | `very_good_analysis` | **Saropa Lints**       |\n| :----------------------------------- | :-------------: | :------------------: | :--------------------- |\n| **Syntax Checks**                    |       ✅        |          ✅          | ✅                     |\n| **Strict/Opinionated Style**         |       ❌        |          ✅          | ✅                     |\n| **Zero-Config Setup**                |       ✅        |          ✅          | ✅ **(Tier Presets)**  |\n| **Controller Leak Detection**        |       ❌        |          ❌          | ✅ **(Deep Analysis)** |\n| **Runtime Crash Prevention**         |       ❌        |          ❌          | ✅ **(Behavioral)**    |\n| **Security (OWASP Mapped)**          |       ❌        |          ❌          | ✅ **(ISO/OWASP)**     |\n| **Library Specific (Riverpod/Bloc)** |       ❌        |          ❌          | ✅ **(50+ rules)**     |\n| **AI-Ready Diagnostics**             |       ❌        |          ❌          | ✅                     |\n| **Dependency Scanning**              |       ❌        |          ❌          | 🚧 **(Coming Soon)**   |\n\n### OWASP Compliance Mapping\n\nSecurity rules are mapped to **OWASP Mobile Top 10 (2024)** and **OWASP Top 10 (2021)** standards. This enables:\n\n- **Compliance reporting** for security audits\n- **Risk categorization** aligned with industry standards\n- **Coverage analysis** across OWASP categories\n\n| OWASP Mobile          | Coverage | OWASP Web                  | Coverage  |\n| --------------------- | -------- | -------------------------- | --------- |\n| M1 Credential Usage   | 5+ rules | A01 Broken Access Control  | 4+ rules  |\n| M2 Supply Chain       | 2+ rules | A02 Cryptographic Failures | 10+ rules |\n| M3 Authentication     | 5+ rules | A03 Injection              | 6+ rules  |\n| M4 Input Validation   | 6+ rules | A05 Misconfiguration       | 4+ rules  |\n| M5 Communication      | 2+ rules | A07 Authentication         | 8+ rules  |\n| M6 Privacy Controls   | 5+ rules | A09 Logging Failures       | 2+ rules  |\n| M7 Binary Protections | 2+ rules |                            |           |\n| M8 Misconfiguration   | 4+ rules |                            |           |\n| M9 Data Storage       | 7+ rules |                            |           |\n| M10 Cryptography      | 4+ rules |                            |           |\n\n**Gaps**: A06 (Outdated Components) requires dependency scanning tooling.\n\nRules expose their OWASP mapping programmatically:\n\n```dart\n// Query a rule's OWASP categories\nfinal rule = AvoidHardcodedCredentialsRule();\nprint(rule.owasp); // Mobile: M1 | Web: A07\n```\n\n### Open Source \u0026 Community Driven\n\nUnlike \"black box\" paid tools, Saropa Lints is 100% open source (MIT). You can inspect the logic behind every rule, verify the security checks yourself, and fork it if you disagree.\n\n- **No hidden logic:** See exactly how we detect vulnerabilities.\n- **No vendor lock-in:** It's standard Dart code.\n- **Community powered:** Rules are often suggested, debated, and refined by the Flutter community, not just a single vendor.\n\n---\n\n### Built for AI\n\nAI coding assistants like Cursor, Windsurf, and Copilot move fast, but they often hallucinate code that compiles yet fails in production. They might forget to dispose a controller, use a deprecated API, or ignore security best practices.\n\nSaropa Lints acts as the guardrails for your AI. By providing immediate, semantic feedback on **behavior**—not just syntax—it forces the AI to correct its own mistakes in real-time.\n\n**Optimized for AI Repair**\nThe tool is also built to **fix**. Saropa Lints diagnostics are engineered to be \"paste-ready,\" providing deep context and specific failure points. When you copy a problem report directly into your AI tool window, it acts as a perfect prompt—giving the AI exactly the info it needs to refactor the code and resolve the issue immediately, without you needing to explain the context.\n\n![AI fixing Flutter security vulnerability automatically in Android Studio](https://raw.githubusercontent.com/saropa/saropa_lints/main/assets/20260401_AI_solver_tab.png)\n\n---\n\n### Migrating from other tools?\n\n- [Migrating from very_good_analysis](https://github.com/saropa/saropa_lints/blob/main/doc/guides/migration_from_vga.md) (also covers `lints`, `lint`, `pedantic`)\n- [Migrating from DCM (Dart Code Metrics)](https://github.com/saropa/saropa_lints/blob/main/doc/guides/migration_from_dcm.md)\n- [Migrating from solid_lints](https://github.com/saropa/saropa_lints/blob/main/doc/guides/migration_from_solid_lints.md)\n- [Using with flutter_lints](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_flutter_lints.md) (complementary setup)\n\n\u003e **Why three options?** The extension (Option A) is the recommended interactive experience (**Set Up Project** and the sidebar). Tier presets (Option B) are great for quick, zero-config setup. The CLI init tool (Option C) gives you explicit `true`/`false` for every rule, ideal for CI/scripting, plus `--list-packs` / `--enable-pack` for rule packs.\n\n## The 5 Tiers\n\nPick the tier that matches your team's needs. Each tier builds on the previous one.\n\n| Tier              | Purpose                                                                                                                                                                                                                                                 | Target User                                                                   | Example Rules                                                                                                                                                                                                          |\n| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Essential**     | **Prevents crashes, data loss, security breaches, and memory leaks.** These are rules where a single violation can cause real harm - app crashes, user data exposed, resources never released. If your app violates these, something bad _will_ happen. | Every project, every team. Non-negotiable baseline.                           | `require_field_dispose` (memory leak), `avoid_hardcoded_credentials` (security breach), `check_mounted_after_async` (crash), `avoid_null_assertion` (runtime exception), `require_firebase_init_before_use` (crash)    |\n| **Recommended**   | **Catches common bugs, basic performance issues, and accessibility fundamentals.** These are mistakes that cause real problems but may not immediately crash your app - poor UX, sluggish performance, inaccessible interfaces, silent failures.        | Most teams. The sensible default for production apps.                         | `require_semantics_label` (accessibility), `avoid_expensive_build` (performance), `require_json_decode_try_catch` (error handling), `avoid_shrinkwrap_in_scrollview` (performance), `require_image_error_builder` (UX) |\n| **Professional**  | **Enforces architecture, testability, maintainability, and documentation standards.** Code that works but is hard to test, hard to change, or hard to understand. Technical debt that slows teams down over time.                                       | Enterprise teams, long-lived codebases, teams with multiple developers.       | `avoid_god_class` (architecture), `require_public_api_documentation` (docs), `prefer_result_pattern` (error handling), `require_test_cleanup` (testing), `avoid_hardcoded_strings_in_ui` (i18n)                        |\n| **Comprehensive** | **Stricter patterns, optimization hints, and thorough edge case coverage.** Rules that catch subtle issues, enforce consistency, and push toward optimal patterns. Helpful but not critical.                                                            | Quality-obsessed teams, libraries/packages, teams that want maximum coverage. | `prefer_element_rebuild` (subtle perf), `prefer_immutable_bloc_state` (strict pattern), `require_test_documentation` (maintainability), `prefer_fake_platform` (test quality)                                          |\n| **Pedantic**      | **Everything, including pedantic and highly opinionated rules.** Rules that most teams would find excessive but are valuable for greenfield projects or teams that want zero compromise.                                                                | New projects starting fresh, teams that want maximum strictness from day one. | `prefer_custom_single_child_layout` (micro-optimization), `prefer_feature_folder_structure` (opinionated architecture), `avoid_returning_widgets` (pedantic)                                                           |\n\n### Stylistic Rules (Separate Track)\n\n**[175+ stylistic rules](https://github.com/saropa/saropa_lints/blob/main/README_STYLISTIC.md)** for formatting, ordering, and naming conventions.\n\nEnable stylistic rules individually in your config, or use the VS Code extension's Setup \u0026 triage view to enable/disable them with estimated score impact.\n\nFor CI/scripting, use `--no-stylistic` (default) or `--stylistic-all` to bulk-enable:\n\n```bash\ndart run saropa_lints:init --tier recommended --stylistic-all\n```\n\nConflicting pairs (e.g., `prefer_single_quotes` vs `prefer_double_quotes`) must be enabled individually — you choose which style your team prefers.\n\nStylistic rules are orthogonal to correctness. Your code can be perfectly correct while violating every stylistic rule, or perfectly formatted while crashing on every screen. That's why they're separate.\n\n### Configuration template\n\nSee [example/analysis_options_template.yaml](https://github.com/saropa/saropa_lints/blob/main/example/analysis_options_template.yaml) for a complete reference with all **2118** rules organized by category, tier membership, and examples.\n\n### Using a tier\n\n**VS Code extension:** Use **Set Tier** from the command palette or click the tier badge in the status bar.\n\n**Tier preset (zero-config):**\n\n```yaml\n# In analysis_options.yaml — just pick your tier:\ninclude: package:saropa_lints/tiers/recommended.yaml\n```\n\n**CLI init (full control, CI/scripting):**\n\n```bash\ndart run saropa_lints:init --tier recommended\ndart run saropa_lints:init --target /path/to/project\ndart run saropa_lints:init --help\n```\n\nAvailable tiers: `essential` (1), `recommended` (2), `professional` (3), `comprehensive` (4), `pedantic` (5)\n\n### Customizing rules\n\nAfter generating configuration, customize rules by editing `analysis_options.yaml`:\n\n```yaml\nplugins:\n  saropa_lints:\n    diagnostics:\n      # The init tool generates explicit true/false for every rule\n      avoid_hardcoded_strings_in_ui: true # change to false to disable\n      require_public_api_documentation: false # change to true to enable\n\n      # Stylistic rules (enable the ones your team prefers)\n      prefer_single_quotes: true\n      prefer_trailing_comma_always: true\n```\n\nRules use standard YAML map format (no `-` prefix needed).\n\nTo change tiers, either switch the `include:` preset or re-run the init tool:\n\n```bash\ndart run saropa_lints:init --tier professional\n```\n\n### Platform configuration\n\nThe `analysis_options_custom.yaml` file includes a `platforms` section that controls which platform-specific rules are active. Only iOS and Android are enabled by default. Enable the platforms your project targets:\n\n```yaml\n# In analysis_options_custom.yaml\nplatforms:\n  ios: true # enabled by default\n  android: true # enabled by default\n  macos: false # enable if targeting macOS\n  web: false # enable if targeting web\n  windows: false # enable if targeting Windows\n  linux: false # enable if targeting Linux\n```\n\nEach platform has dedicated rules that catch platform-specific issues:\n\n| Platform    | Rules          | Examples                                                                             |\n| ----------- | -------------- | ------------------------------------------------------------------------------------ |\n| **iOS**     | 90+            | Safe area, privacy manifest, App Tracking Transparency, Face ID, HealthKit, keychain |\n| **Android** | 11+            | Runtime permissions, notification channels, PendingIntent flags, cleartext traffic   |\n| **macOS**   | 15+            | Sandboxing, notarization, hardened runtime, window restoration, entitlements         |\n| **Web**     | 10+            | CORS handling, platform channels, deferred loading, URL strategy, web renderer       |\n| **Windows** | Desktop shared | Menu bar, window close confirmation, native file dialogs, focus indicators           |\n| **Linux**   | Desktop shared | Same desktop rules as Windows                                                        |\n\nSome rules are shared across platform groups:\n\n- **Apple rules** (iOS + macOS): Apple Sign In, nonce validation\n- **Desktop rules** (macOS + Windows + Linux): Menu bar, window management, keyboard/mouse interaction patterns\n\nWhen a platform is set to `false`, its rules move to the disabled section. Shared rules (e.g., Apple Sign In for iOS + macOS) are only disabled when **all** their platforms are disabled.\n\n**User overrides always win** — if you force-enable a rule in the overrides section, it stays enabled even if its platform is disabled.\n\nThe `init` tool logs which platforms are disabled and how many rules are affected:\n\n```\nPlatforms disabled: web, windows, linux (23 rules affected)\n```\n\n### Package configuration\n\nThe `analysis_options_custom.yaml` file includes a `packages` section that controls which library-specific rules are active. All packages are enabled by default. Disable packages you don't use to reduce noise:\n\n```yaml\n# In analysis_options_custom.yaml\npackages:\n  # State Management\n  bloc: true\n  provider: true\n  riverpod: true\n  getx: true\n\n  # UI \u0026 Utilities\n  flutter_hooks: true\n\n  # Data Classes\n  equatable: true\n  freezed: true\n\n  # Storage \u0026 Database\n  firebase: true\n  isar: true\n  hive: true\n  shared_preferences: true\n  sqflite: true\n\n  # Networking\n  dio: true\n  graphql: true\n  supabase: true\n\n  # DI \u0026 Services\n  get_it: true\n  workmanager: true\n\n  # Device \u0026 UI\n  url_launcher: true\n  geolocator: true\n  qr_scanner: true\n\n  # Gaming\n  flame: true\n```\n\nSetting a package to `false` moves all its rules to the disabled section. If you don't use Riverpod, for example, set `riverpod: false` to remove 24+ Riverpod-specific rules from your analysis.\n\nRules shared between packages (e.g., database rules shared by Firebase, Isar, Hive, and sqflite) are only disabled when **all** packages that use them are disabled.\n\nAfter changing platform or package settings, re-run init to apply:\n\n```bash\ndart run saropa_lints:init\n```\n\n### Config key names and aliases\n\nRule config keys match the rule name shown in lint messages (the part in `[brackets]`):\n\n```\nlib/my_file.dart:42 - [prefer_arguments_ordering] Named arguments should be in alphabetical order.\n                       ^^^^^^^^^^^^^^^^^^^^^^^^^ This is the config key\n```\n\nTo disable this rule: `prefer_arguments_ordering: false`\n\n**Aliases**: Some rules support shorter aliases for convenience. For example, `prefer_arguments_ordering` also accepts `arguments_ordering`:\n\n```yaml\nplugins:\n  saropa_lints:\n    diagnostics:\n      # Both of these work:\n      prefer_arguments_ordering: false # canonical name\n      arguments_ordering: false # alias\n```\n\nAliases are provided for rules where the prefix (`enforce_`, `require_`) might be commonly omitted.\n\n### Enabling all rules\n\nUse the `pedantic` tier preset or the init tool to enable all rules:\n\n```yaml\n# Option A: Tier preset\ninclude: package:saropa_lints/tiers/pedantic.yaml\n\n# Option B: Init tool\n# dart run saropa_lints:init --tier pedantic --stylistic-all\n```\n\n**This is intentional.** It forces teams to explicitly review and disable rules they disagree with, ensuring:\n\n- No rule is accidentally overlooked\n- Your config becomes a complete record of team style decisions\n- Mutually exclusive rules (e.g., `prefer_single_quotes` vs `prefer_double_quotes`) require explicit choice\n\nIf you enable all rules, you will need to disable one rule from each conflicting pair.\n\n### Severity levels\n\nEach rule has a fixed severity (ERROR, WARNING, or INFO) defined in the rule itself. Severity cannot be overridden per-project. If a rule's severity doesn't match your needs:\n\n- Use `// ignore: rule_name` to suppress individual occurrences\n- Disable the rule entirely with `rule_name: false`\n- [Open an issue](https://github.com/saropa/saropa_lints/issues) if you think the default severity should change\n\n### Baseline for Brownfield Projects\n\n#### The Problem\n\nYou want to adopt saropa_lints on an existing project. You run `dart analyze` and see:\n\n```\nlib/old_widget.dart:42 - avoid_print\nlib/old_widget.dart:87 - no_empty_block\nlib/legacy/api.dart:15 - avoid_dynamic\n... 500 more violations\n```\n\n**That's overwhelming.** You can't fix 500 issues before your next sprint. But you also can't ignore linting entirely - new code should be clean.\n\n#### The Solution: Baseline\n\nThe **baseline feature** records all existing violations and hides them, while still catching violations in new code.\n\n- **Old code**: Violations hidden (baselined)\n- **New code**: Violations reported normally\n\nThis lets you adopt linting **today** without fixing legacy code first.\n\n#### Quick Start (One Command)\n\n```bash\ndart run saropa_lints:baseline\n```\n\nThis command:\n\n1. Runs analysis to find all current violations\n2. Creates `saropa_baseline.json` with those violations\n3. Updates your `analysis_options.yaml` automatically\n\n**Result**: Old violations are hidden, new code is still checked.\n\n#### Combinable baseline types\n\n| Type           | Config          | Description                      | Best For               |\n| -------------- | --------------- | -------------------------------- | ---------------------- |\n| **File-based** | `baseline.file` | JSON listing specific violations | \"Fix nothing yet\"      |\n| **Date-based** | `baseline.date` | Git blame - ignore old code      | \"Fix gradually by age\" |\n\nBoth types are combinable: any match suppresses the violation.\n\n#### Full Configuration\n\n\u003e **Note:** Baseline configuration via YAML is not yet supported. Use the\n\u003e `dart run saropa_lints:baseline` CLI command shown above, which generates\n\u003e the baseline file and updates your config automatically.\n\nThe baseline CLI supports these options:\n\n| Option           | Description                                            |\n| ---------------- | ------------------------------------------------------ |\n| `--file`         | Output file (default: `saropa_baseline.json`)          |\n| `--date`         | Ignore code unchanged since this date (uses git blame) |\n| `--paths`        | Ignore entire directories (glob patterns)              |\n| `--only-impacts` | Only baseline certain severities (e.g., `low,medium`)  |\n\n#### Path Pattern Examples\n\n| Pattern             | Matches                              |\n| ------------------- | ------------------------------------ |\n| `lib/legacy/`       | All files under `lib/legacy/`        |\n| `*.g.dart`          | All files ending in `.g.dart`        |\n| `lib/**/old_*.dart` | Files like `lib/foo/old_widget.dart` |\n\n#### Priority Filtering\n\nUse `only_impacts` to baseline only certain severity levels while still seeing errors:\n\n```yaml\nbaseline:\n  file: \"saropa_baseline.json\"\n  only_impacts: [info] # Still see errors and warnings\n```\n\n\u003e **Severity model:** errors must be fixed; warnings could fail or look bad; info is FYI. The 5-bucket impact taxonomy (`critical / high / medium / low / opinionated`) collapsed into the analyzer's three native severities on 2026-05-03 — see `plans/COLLAPSE_LINT_IMPACT_TO_SEVERITY.md`. Existing `only_impacts: [low, medium, opinionated]` configs keep working (the values map to the new buckets) but new code should use `[info]` / `[warning]` / `[error]`.\n\n#### Cleaning Up Over Time\n\nAs you fix violations, update the baseline to remove fixed items:\n\n```bash\ndart run saropa_lints:baseline --update\n```\n\nOutput shows what was fixed:\n\n```\nBaseline Update Summary:\n  Previous: 150 violations\n  Current:  120 violations\n  Fixed:    30 violations removed!\n```\n\n#### CLI Reference\n\n```bash\ndart run saropa_lints:baseline              # Generate new baseline\ndart run saropa_lints:baseline --update     # Refresh, remove fixed violations\ndart run saropa_lints:baseline --dry-run    # Preview without changes\ndart run saropa_lints:baseline --skip-config # Don't update analysis_options.yaml\ndart run saropa_lints:baseline -o custom.json # Custom output path\ndart run saropa_lints:baseline ./my_project  # Run on specific directory\ndart run saropa_lints:baseline --help        # See all options\n```\n\n### Cross-file analysis CLI\n\nFind unused files, circular imports, and related project-wide checks (CLI only; the extension also exposes cross-file commands).\n\n**Monorepos:** `--path` is a single package root (one `pubspec.yaml`). If the repository has several Dart packages, run cross-file **per package** (from each package directory or with `--path` pointed at that package), or run separate CI jobs per package. One invocation does not span unrelated sibling packages.\n\n```bash\ndart run saropa_lints:cross_file unused-files   # Files not imported by any other file\ndart run saropa_lints:cross_file circular-deps  # Circular import chains\ndart run saropa_lints:cross_file import-stats   # Import graph statistics\ndart run saropa_lints:cross_file feature-deps   # Cross-feature imports (lib/features/…)\ndart run saropa_lints:cross_file unused-symbols # Top-level symbols unused outside defining file\ndart run saropa_lints:cross_file dead-imports     # Likely dead relative imports (heuristic)\ndart run saropa_lints:cross_file watch          # Re-run a command on lib/test changes\ndart run saropa_lints:cross_file report         # HTML report (default: reports/)\ndart run saropa_lints:cross_file graph          # DOT import graph for Graphviz\ndart run saropa_lints:cross_file --help\n# JSON output to file (e.g. for CI or tooling)\ndart run saropa_lints:cross_file unused-files --output json \u003e unused.json\n# Baseline: suppress known issues, fail only on new violations\ndart run saropa_lints:cross_file unused-files --baseline cross_file_baseline.json\ndart run saropa_lints:cross_file unused-files --update-baseline\n# Render DOT graph as SVG\ndot -Tsvg reports/import_graph.dot -o reports/import_graph.svg\n```\n\nOptions: `--path \u003cdir\u003e`, `--output text|json`, `--output-dir \u003cpath\u003e` (for report/graph), `--baseline \u003cfile\u003e`, `--update-baseline`, `--exclude \u003cglob\u003e`, plus command-specific flags (e.g. `unused-symbols`: `--include-private`, `--exclude-public-api`, `--heuristic-unused-symbols`). Exit codes: 0 = no issues, 1 = issues found, 2 = error. [Example GitHub Actions workflow](doc/cross_file_ci_example.md) for CI. See [ROADMAP](ROADMAP.md#cross-file-cli-improvements) cross-file table.\n\n### Project Vibrancy CLI\n\nScore health of your own project functions (age, coverage, usage, complexity, docs) and emit CI-friendly JSON:\n\n```bash\ndart run bin/project_vibrancy.dart --path . --format json\ndart run bin/project_vibrancy.dart --path . --format text\ndart run bin/project_vibrancy.dart --path . --format json --since main\ndart run bin/project_vibrancy.dart --path . --file lib/src/foo.dart\ndart run bin/project_vibrancy.dart --path . --folder lib/src/rules\n```\n\nGate options for CI:\n\n```bash\ndart run bin/project_vibrancy.dart \\\n  --path . \\\n  --format json \\\n  --min-grade C \\\n  --max-unused 20 \\\n  --max-uncovered 30 \\\n  --max-stub-tested 5 \\\n  --max-suspicious-coverage 10 \\\n  --max-test-drift 8\n```\n\nExit code is non-zero when any configured gate is violated. A sample workflow is available at `.github/workflows/project-vibrancy.yml`.\n\nJSON summary includes `stubTestedCount`, `suspiciousCoverageCount`, and `testDriftCount` (see [plans/history/2026.04/2026.04.28/project_vibrancy_report.md](plans/history/2026.04/2026.04.28/project_vibrancy_report.md) for flag semantics; LCOV lacks per-test attribution, so flags use importer + trivial-assertion heuristics).\n\n### Quality gate CLI (new-code focused)\n\nUse the structured `violations.json` summary to enforce pass/fail conditions in CI:\n\n```bash\n# 1) Run analysis so violations.json is produced\ndart analyze\n\n# 2) Copy and adjust the sample gate config\ncp saropa_quality_gate.yaml.example saropa_quality_gate.yaml\n\n# 3) Evaluate gate conditions\ndart run saropa_lints:quality_gate \\\n  --report reports/.saropa_lints/violations.json \\\n  --config saropa_quality_gate.yaml\n```\n\nSupported operators: `eq`, `ne`, `gt`, `ge`, `lt`, `le`.\n\nCommon metrics:\n\n- `new_errors` (alias: `new_critical_issues`)\n- `new_warnings` (alias: `new_high_issues`, `new_medium_issues`)\n- `new_info` (alias: `new_low_issues`)\n- `new_vulnerabilities`\n- `new_security_hotspots`\n- `new_code_smells`\n- `new_bugs`\n- `overall_errors` (alias: `overall_critical_issues`)\n- `overall_warnings` (alias: `overall_high_issues`, `overall_medium_issues`)\n- `overall_info` (alias: `overall_low_issues`)\n- `overall_vulnerabilities`\n\nThe aliases map onto the new severity-keyed names so existing `saropa_quality_gate.yaml` configs keep working without edits. New thresholds should prefer the canonical names.\n\n`violations.json` suppression schema (for CI/report tooling):\n\n```json\n{\n  \"summary\": {\n    \"totalViolations\": 120,\n    \"suppressions\": {\n      \"total\": 14,\n      \"byKind\": { \"ignore\": 8, \"ignoreForFile\": 4, \"baseline\": 2 },\n      \"byRule\": { \"avoid_print\": 5, \"require_https\": 3 },\n      \"byFile\": { \"lib/app.dart\": 7, \"lib/api.dart\": 4 }\n    }\n  }\n}\n```\n\n- `summary.suppressions.total`: total suppressed diagnostics.\n- `summary.suppressions.byKind`: suppression mechanism breakdown.\n- `summary.suppressions.byRule`: suppressed count by rule name.\n- `summary.suppressions.byFile`: suppressed count by relative file path.\n\nExit codes:\n\n- `0`: pass (or warn-only breaches)\n- `1`: fail breach(es)\n- `2`: invalid input/config\n\nGitHub Actions example:\n\n```yaml\n- name: Analyze\n  run: dart analyze\n\n- name: Quality gate\n  run: |\n    cp saropa_quality_gate.yaml.example saropa_quality_gate.yaml\n    dart run saropa_lints:quality_gate \\\n      --report reports/.saropa_lints/violations.json \\\n      --config saropa_quality_gate.yaml\n```\n\n### Standalone Scanner\n\nRun saropa_lints rules against **any Dart project** — even one that doesn't have saropa_lints as a dependency. Useful for evaluating a project before adopting the package, or for scanning the saropa_lints codebase itself.\n\nThe scanner reads the project's `analysis_options.yaml` (generated by `init`) to determine which rules to run, unless you pass `--tier`. Two steps:\n\n```bash\n# 1. Configure rules (once)\ndart run saropa_lints init --target /path/to/project --tier recommended\n\n# 2. Scan\ndart run saropa_lints scan /path/to/project\n```\n\n**CLI options:** `--tier \u003cname\u003e` (essential | recommended | professional | comprehensive | pedantic) overrides the project config for that run. `--files \u003cpath\u003e...` scans only the listed Dart files; `--files-from-stdin` reads one path per line from stdin. `--format json` writes machine-readable JSON to stdout (no report file). Results are otherwise written to `reports/\u003cdate\u003e/\u003ctimestamp\u003e_scan_report.log` with a compact summary printed to terminal.\n\n**Programmatic scan:** Import `package:saropa_lints/scan.dart` to run scans from code (e.g. from another package or script) without invoking the CLI. The public API includes `ScanRunner`, `ScanConfig`, `ScanDiagnostic`, `loadScanConfig`, `scanDiagnosticsToJson`, and `scanDiagnosticsToJsonString`. Example:\n\n```dart\nimport 'package:saropa_lints/scan.dart';\n\nfinal runner = ScanRunner(\n  targetPath: '/path/to/project',\n  tier: 'recommended',           // optional: override config with a tier\n  dartFiles: ['lib/main.dart'],   // optional: scan only these files\n  messageSink: (msg) =\u003e log(msg), // optional: redirect or suppress output\n);\nfinal diagnostics = runner.run();\nif (diagnostics != null) {\n  final json = scanDiagnosticsToJsonString(diagnostics);\n  // ...\n}\n```\n\nJSON output (from `--format json` or `scanDiagnosticsToJson`) includes `version`, `diagnostics` (each with filePath, line, column, ruleName, severity, problemMessage, correctionMessage?), and `summary` (totalCount, byFile, byRule).\n\n## Rule Categories\n\n| Category                 | Description                                                                           |\n| ------------------------ | ------------------------------------------------------------------------------------- |\n| **Flutter Widgets**      | Lifecycle, setState, keys, performance                                                |\n| **Modern Dart 3.0+**     | Class modifiers, patterns, records, when guards                                       |\n| **Modern Flutter**       | TapRegion, OverlayPortal, SearchAnchor, CarouselView                                  |\n| **State Management**     | Provider, Riverpod, Bloc patterns                                                     |\n| **Performance**          | Build optimization, memory, caching                                                   |\n| **Security**             | Credentials, encryption, input validation — [OWASP mapped](#owasp-compliance-mapping) |\n| **Accessibility**        | Screen readers, touch targets, semantics                                              |\n| **Testing**              | Assertions, mocking, flaky test prevention                                            |\n| **Architecture**         | Clean architecture, DI, SOLID principles                                              |\n| **Error Handling**       | Exceptions, logging, recovery                                                         |\n| **Async**                | Futures, Streams, cancellation                                                        |\n| **API \u0026 Network**        | Timeouts, retries, caching                                                            |\n| **Internationalization** | Localization, RTL, plurals                                                            |\n| **Documentation**        | Public API, examples, deprecation                                                     |\n\n## Stylistic Rules\n\n175+ rules for team preferences — not included in any correctness tier. Enable individually in your config, via the VS Code extension's Setup \u0026 triage view, or use `--stylistic-all` to bulk-enable.\n\nExamples: `prefer_relative_imports`, `prefer_single_quotes`, `prefer_arrow_functions`, `prefer_trailing_comma_always`, `prefer_for_in`, `prefer_boolean_prefixes_for_params`\n\n**See [README_STYLISTIC.md](https://github.com/saropa/saropa_lints/blob/main/README_STYLISTIC.md)** for the full list with examples, pros/cons, and quick fixes.\n\n## Performance\n\nSaropa Lints runs as a native Dart analyzer plugin — no separate process needed. The tier system helps manage analysis scope:\n\n- Rules set to `false` are not loaded\n- Start with `essential` or `recommended`\n- Upgrade tiers as you fix warnings\n\n```bash\n# GOOD: Start with recommended tier\ndart run saropa_lints:init --tier recommended\n\n# CAUTION: Enabling everything on a legacy codebase may show thousands of warnings\ndart run saropa_lints:init --tier pedantic\n```\n\n### Performance Tip: Use Lower Tiers During Development\n\nFor faster iteration during development:\n\n1. **Use `essential` tier locally** — catches critical bugs with fewer rules\n2. **Use `professional` or higher in CI** — thorough checking where speed matters less\n3. **Upgrade tiers gradually** — fix warnings before enabling more rules\n\nThe tier you choose has a direct impact on analysis speed (approximate rule counts from `getRulesForTier`; stylistic rules are separate unless you pass `--stylistic-all`):\n\n- `essential`: ~300 rules → **fastest** (memory leaks, security, crashes)\n- `recommended`: ~1000 rules → moderate (+ accessibility, performance)\n- `professional`: ~1800 rules → slower (+ architecture, documentation)\n- `comprehensive`: ~1870 rules → stricter patterns and edge cases\n- `pedantic`: ~1880 rules → **slowest** correctness tier (everything before stylistic)\n\n## Adoption Strategy\n\nStatic analysis doesn't create problems — it reveals ones that already exist. The tiered system lets you start at any level and progress at your own pace. Findings are for your workflow. You control what you address and when.\n\n### New Projects\n\nStart with `professional` or `comprehensive`. Fix issues as you write code.\n\n### Existing Projects\n\n1. Enable `essential`. Fix critical issues first.\n2. Move to `recommended`. Fix warnings as you touch files.\n3. Enable higher tiers when the noise is manageable.\n\n### Suppressing Warnings\n\nWhen a rule doesn't apply to specific code:\n\n```dart\n// ignore: avoid_hardcoded_strings_in_ui\nconst debugText = 'DEBUG MODE';\n\n// For entire files:\n// ignore_for_file: avoid_print_in_production\n```\n\nAlways add a comment explaining **why** you're suppressing.\n\n### Automatic File Skipping\n\nRules automatically skip files that can't be manually fixed:\n\n| File Pattern                                  | Skipped By Default                    |\n| --------------------------------------------- | ------------------------------------- |\n| `*.g.dart`, `*.freezed.dart`, `*.gen.dart`    | Yes (generated code)                  |\n| `*_fixture.dart`, `fixture/**`, `fixtures/**` | Yes (test fixtures)                   |\n| `*_test.dart`, `test/**`                      | Yes (override with `testRelevance`)   |\n| `example/**`                                  | No (override with `skipExampleFiles`) |\n\nTest files are skipped by default because most production-focused rules generate noise in test code. Override `testRelevance` to change behavior per rule:\n\n- `TestRelevance.never` — skip test files (default)\n- `TestRelevance.always` — run on all files including tests\n- `TestRelevance.testOnly` — run only on test files\n\n## Limitations\n\n- **Scope**: Saropa Lints runs as a native analyzer plugin on the package where it's configured. For multi-package workspaces, add `saropa_lints` to each package's `analysis_options.yaml`.\n- **File types**: Only Dart source files (`.dart`) are analyzed. Non-Dart assets (JSON, XML, YAML, scripts, etc.) are out of scope.\n\n## Running the Linter\n\n**Command line:**\n\n```bash\ndart analyze\n```\n\nSaropa Lints runs as a native Dart analyzer plugin. Issues appear automatically in your IDE's Problems panel and in `dart analyze` output.\n\nWhen analysis runs with reporting enabled, the plugin also writes a combined log under `reports/\u003cdate\u003e/` (filename contains `_saropa_lint_report`). That file includes **FILE IMPORTANCE** (fan-in × layer), **FIX PRIORITY** (violations sorted by impact × importance), and **PROJECT STRUCTURE** (import tree), built from import data collected during analysis.\n\n### Impact Report\n\nRun lints with results grouped by business impact:\n\n```bash\ndart run saropa_lints:impact_report\n```\n\nOutput shows critical issues first, with actionable guidance:\n\n```\n--- CRITICAL (2) ---\n  lib/main.dart:45 - avoid_hardcoded_credentials\n  lib/auth.dart:23 - require_dispose\n\n--- HIGH (5) ---\n  lib/widget.dart:89 - avoid_icon_buttons_without_tooltip\n  ...\n\nImpact Summary\n==============\nCRITICAL: 2 (fix immediately!)\nHIGH:     5 (address soon)\nMEDIUM:   12 (tech debt)\nLOW:      34 (style)\n\nTotal: 53 issues\n```\n\n**Impact levels:**\n\n- `critical`: Each occurrence is serious — even 1-2 is unacceptable (memory leaks, security)\n- `high`: 10+ requires action (accessibility, performance anti-patterns)\n- `medium`: 100+ indicates tech debt (error handling, complexity)\n- `low`: Large counts acceptable (style, naming conventions)\n\nExit code equals the number of critical issues (capped at 125), making it CI-friendly.\n\n### IDE Integration\n\nSaropa Lints uses the native Dart analyzer plugin system. Issues appear directly in your IDE's Problems panel — no extra setup required.\n\n**If you don't see warnings:**\n\n1. Run `dart pub get` (or `flutter pub get`)\n2. Restart your IDE (VS Code: `Ctrl+Shift+P` → \"Developer: Reload Window\")\n3. Check **View → Output → Dart Analysis Server** for errors\n\n## Supported Versions\n\nThe current major (`12.x`) is the actively maintained line — new rules, fixes, and quick fixes land here. Earlier majors are no longer updated except for security-impacting issues; if you need a backport of a security fix to a prior major, [open an issue](https://github.com/saropa/saropa_lints/issues/new) tagged `backport-request` with the rule code and the affected version. There is no fixed support window — older lines are evaluated case-by-case based on the severity of the report and the size of the diff. See also [Troubleshooting](#troubleshooting) and [doc/troubleshooting.md](doc/troubleshooting.md) for IDE-specific issues.\n\n## Troubleshooting\n\n### Can't use saropa_lints v7 in my Flutter project\n\n⚠️ **v7 was retracted.** It required **analyzer 10** (and **meta ^1.18.0**); the Flutter SDK pins **meta** to **1.17.0**, so 7.x could not run in Flutter projects. Use **saropa_lints 8.0.0**, which keeps all 7.x rule fixes and stays on **analyzer 9** for Flutter compatibility. See [CHANGELOG](CHANGELOG.md#800) and [Upgrading to v7](doc/guides/upgrading_to_v7.md) (reference only) for context.\n\n### I'm new and completely lost\n\n**Start here:**\n\n1. **Install**: Add to your `pubspec.yaml` dev_dependencies:\n\n   ```yaml\n   dev_dependencies:\n     saropa_lints: ^10.0.0\n   ```\n\n2. **Configure**: Add to your `analysis_options.yaml`:\n\n   ```yaml\n   include: package:saropa_lints/tiers/recommended.yaml\n   ```\n\n3. **Get dependencies**:\n\n   ```bash\n   dart pub get\n   ```\n\n4. **Reload VS Code**:\n   - Press `Ctrl+Shift+P`\n   - Type \"reload\"\n   - Click \"Developer: Reload Window\"\n\n5. **Check**: Look at the PROBLEMS panel (View → Problems), or run `dart analyze`\n\n**Still not working?** See the sections below.\n\n### IDE doesn't show lint warnings\n\n**Quick Fix (works 90% of the time):**\n\n1. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac)\n2. Type \"reload\"\n3. Click \"Developer: Reload Window\"\n4. Wait for analysis to complete\n\n**If that doesn't work:**\n\n1. Clear the cache: Delete the `.dart_tool` folder and run `dart pub get`\n2. Reload VS Code again (steps above)\n3. Check **View → Output → Dart Analysis Server** for errors\n4. Verify configuration is correct (see \"Configuration not working\" below)\n\n**Alternative (command line):**\n\nRun `dart analyze` in your terminal to see all issues immediately.\n\n### Configuration not working (not enough rules loading)\n\n**Problem:** You only get a few rules instead of the full set for your chosen tier.\n\n**Solution:** Use the CLI tool to generate explicit configuration:\n\n```bash\n# Generate config for comprehensive tier\ndart run saropa_lints:init --tier comprehensive\n\n# Or for all rules (pedantic tier)\ndart run saropa_lints:init --tier pedantic\n```\n\nThis generates `analysis_options.yaml` with explicit `rule_name: true` for every enabled rule.\n\n**Verify it worked:** Run `dart analyze` and check the output.\n\n### Too many warnings! What do I do?\n\n**This is normal** when first installing. You'll see hundreds or thousands of warnings.\n\n**Option 1: Start smaller** (recommended for existing projects)\n\n```bash\n# Start with essential tier (~310 critical rules)\ndart run saropa_lints:init --tier essential\n```\n\n**Option 2: Use baseline** (for brownfield projects)\n\nGenerate a baseline to suppress existing issues and only catch new violations:\n\n```bash\ndart run saropa_lints:baseline\n```\n\n**Option 3: Disable noisy rules**\n\nEdit your `analysis_options.yaml` and set specific rules to `false`:\n\n```yaml\nplugins:\n  saropa_lints:\n    diagnostics:\n      prefer_double_quotes: false # disabled\n      prefer_trailing_comma_always: false\n      no_magic_number: false\n```\n\n**Option 4: Use quick fixes**\n\nMany rules have automatic fixes:\n\n- Hover over the warning\n- Click \"Quick Fix\" or press `Ctrl+.`\n- Select \"Fix all in file\" to fix all instances at once\n- Or run `dart fix --apply` from the command line\n\n**Don't stress about fixing everything immediately.** Pick one category (like accessibility or memory leaks) and fix those first.\n\n### Out of Memory errors\n\nIf you see errors like:\n\n```\n../../runtime/vm/zone.cc: 96: error: Out of memory.\n```\n\n**Solution 1: Clear the pub cache** (most effective)\n\n```bash\ndart pub cache clean\ndart pub get\n```\n\n**Solution 2: Increase Dart heap size** (PowerShell)\n\n```powershell\n$env:DART_VM_OPTIONS=\"--old_gen_heap_size=4096\"\ndart analyze\n```\n\n**Solution 3: Delete local build artifacts**\n\n```bash\n# Windows\nrmdir /s /q .dart_tool \u0026\u0026 dart pub get\n\n# macOS/Linux\nrm -rf .dart_tool \u0026\u0026 dart pub get\n```\n\n### Native crashes (Windows)\n\nIf you see native crashes with error codes like `ExceptionCode=-1073741819`:\n\n```bash\n# Windows\nrmdir /s /q .dart_tool \u0026\u0026 flutter pub get\n\n# macOS/Linux\nrm -rf .dart_tool \u0026\u0026 flutter pub get\n```\n\nThen run `dart analyze` again.\n\n## Frequently Asked Questions\n\n**Q: Does this replace `flutter_lints`?**\nA: You can run them side-by-side, but Saropa Lints covers everything in `flutter_lints` plus 2000+ additional behavioral and security checks. Most teams replace `flutter_lints` entirely. With v5, you no longer need `custom_lint` either — just `saropa_lints` in your dev_dependencies.\n\n**Q: Will this slow down my CI/CD pipeline?**\nA: Saropa Lints runs as a native analyzer plugin, integrated directly into `dart analyze`. The **Tier System** allows you to balance speed and strictness. The `essential` tier is designed to be fast for CI environments.\n\n**Q: Can I use this with existing legacy projects?**\nA: Yes! Use the **Baseline** feature (`dart run saropa_lints:baseline`) to suppress existing issues instantly. This lets you enforce quality on _new_ code without having to fix 500+ legacy errors first.\n\n**Q: I'm upgrading from v4 — what changed?**\nA: v5 uses the native Dart analyzer plugin system instead of `custom_lint`. Remove `custom_lint` from your dependencies, replace `custom_lint: rules:` with `plugins: saropa_lints: diagnostics:` in your config (or just use a tier preset), and run `dart analyze` instead of `dart run custom_lint`. The init tool handles the config migration automatically.\n\n**Q: Can I add my own lint rules for my app (e.g. require `CommonText` instead of `Text`)?**\nA: [Rule packs](doc/guides/rule_packs.md) only enable rules already shipped in `saropa_lints`; there is no YAML-only “load arbitrary external rules” switch. The analyzer allows **one plugin per context** ([dart-lang/sdk#50981](https://github.com/dart-lang/sdk/issues/50981)), so use a **composite plugin**: one package that depends on `saropa_lints` and your rules, exposes the single `plugin` entrypoint, calls `loadNativePluginConfig` / `registerSaropaLintRules` from `package:saropa_lints/saropa_lints.dart`, then registers your rules. See [Composite analyzer plugin](doc/guides/composite_analyzer_plugin.md). Alternatives: **private fork** of `saropa_lints`, **non-analyzer** enforcement (codemod, CI), or [professional / upstream](PROFESSIONAL_SERVICES.md).\n\n## Contributing\n\n**We are building the industry standard together.**\n\nWe don't have all the answers. We believe great tools are forged by many hands, and if you've shipped production Flutter apps, we want your opinions.\n\nIf you think a rule is:\n\n- **Wrong** - tell us why, we'll fix it or remove it\n- **Too strict** - maybe it belongs in a higher tier\n- **Too lenient** - maybe it should be stricter or have options\n- **Missing** - propose it, or better yet, implement it\n\n**Want to learn AST analysis?** We mentor contributors. Pick a \"Good First Issue\" and we'll guide you through writing your first linter.\n\n### How to contribute\n\nSee [CONTRIBUTING.md](https://github.com/saropa/saropa_lints/blob/main/CONTRIBUTING.md) for detailed guidelines.\n\n**Adding a new rule:**\n\n1. Create rule in appropriate `lib/src/rules/*.dart` file\n2. Register in `lib/src/rules/all_rules.dart`\n3. Add to the appropriate tier in `lib/src/tiers.dart`\n4. Add tests in `test/`\n5. Update CHANGELOG.md\n\n**Reporting issues:**\n\n- Include a minimal code sample that triggers (or should trigger) the rule\n- Explain what you expected vs what happened\n- If you disagree with a rule's premise, say so directly\n\n### Discussing rules\n\nNot sure if something is a bug or a design decision? Open a discussion issue. We're happy to explain our reasoning and change our minds when presented with good arguments.\n\n## Professional Services\n\nOptional paid services for teams that want hands-on help. See [PROFESSIONAL_SERVICES.md](https://github.com/saropa/saropa_lints/blob/main/PROFESSIONAL_SERVICES.md) for details.\n\n| Service          | Description                                                       |\n| ---------------- | ----------------------------------------------------------------- |\n| **New Projects** | Development scoped to your stage — MVP, Production, or Enterprise |\n| **Upgrade**      | Move existing projects to higher tiers as they grow               |\n| **Audit**        | Assess codebases you inherited; remediation quoted separately     |\n| **Custom Rules** | Rules specific to your architecture and compliance requirements   |\n\nContact: [saropa.com](https://saropa.com) | [services@saropa.com](mailto:services@saropa.com)\n\n## Documentation\n\n| Document                                                                                                                      | Description                                   |\n| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |\n| [README_STYLISTIC.md](https://github.com/saropa/saropa_lints/blob/main/README_STYLISTIC.md)                                   | 175+ optional stylistic rules with examples   |\n| [PERFORMANCE.md](https://github.com/saropa/saropa_lints/blob/main/PERFORMANCE.md)                                             | Performance optimization guide and profiling  |\n| [ROADMAP.md](https://github.com/saropa/saropa_lints/blob/main/ROADMAP.md)                                                     | Planned rules and project direction           |\n| [ROADMAP.md#part-2](https://github.com/saropa/saropa_lints/blob/main/ROADMAP.md#part-2-deferred-rules--technical-limitations) | Deferred rules (cross-file, heuristic)        |\n| [CONTRIBUTING.md](https://github.com/saropa/saropa_lints/blob/main/CONTRIBUTING.md)                                           | How to contribute rules and report issues     |\n| [CHANGELOG.md](https://github.com/saropa/saropa_lints/blob/main/CHANGELOG.md)                                                 | Version history and release notes             |\n| [doc/guides/composite_analyzer_plugin.md](https://github.com/saropa/saropa_lints/blob/main/doc/guides/composite_analyzer_plugin.md) | Saropa + custom rules in one analyzer plugin  |\n| [SECURITY.md](https://github.com/saropa/saropa_lints/blob/main/SECURITY.md)                                                   | Security policy and reporting vulnerabilities |\n| [PROFESSIONAL_SERVICES.md](https://github.com/saropa/saropa_lints/blob/main/PROFESSIONAL_SERVICES.md)                         | Professional services and custom rules        |\n\n### Package Integration Guides\n\nWe provide specialized lint rules for popular Flutter packages. These catch library-specific anti-patterns that standard linters miss.\n\n| Category             | Package   | Guide                                                                                                       |\n| -------------------- | --------- | ----------------------------------------------------------------------------------------------------------- |\n| **State Management** | Riverpod  | [Using with Riverpod](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_riverpod.md)   |\n|                      | Bloc      | [Using with Bloc](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_bloc.md)           |\n|                      | Provider  | [Using with Provider](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_provider.md)   |\n|                      | GetX      | [Using with GetX](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_getx.md)           |\n| **Databases**        | Isar      | [Using with Isar](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_isar.md)           |\n|                      | Hive      | [Using with Hive](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_hive.md)           |\n| **Backend Services** | Firebase  | [Using with Firebase](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_firebase.md)   |\n| **Platform**         | iOS/macOS | [Apple Platform Rules](https://github.com/saropa/saropa_lints/blob/main/doc/guides/apple_platform_rules.md) |\n\n#### For Package Authors\n\n**Want lint rules for your package?** We'd love to collaborate with package maintainers to add rules that catch common gotchas and enforce best practices for your library.\n\nBenefits:\n\n- Help users avoid common mistakes with your package\n- Reduce support burden from preventable issues\n- Improve developer experience with your library\n\nContact us via [CONTRIBUTING.md](https://github.com/saropa/saropa_lints/blob/main/CONTRIBUTING.md) or open an issue to discuss adding rules for your package.\n\n## Badge\n\n**Show off your code quality**\n\nProve that your code is secure, memory-safe, and accessible. Add the Saropa Lints style badge to your README to indicate you follow strict behavioral standards.\n\n[![Saropa Lints Badge](https://img.shields.io/badge/saropa_lints-recommended%2B-blue?style=flat\u0026logo=flutter\u0026logoColor=white\u0026color=435489)](https://pub.dev/packages/saropa_lints)\n\n```md\n[![Saropa Lints Badge](https://img.shields.io/badge/saropa_lints-recommended%2B-blue?style=flat\u0026logo=flutter\u0026logoColor=white\u0026color=435489)](https://pub.dev/packages/saropa_lints)\n```\n\n## License\n\nMIT - see [LICENSE](https://github.com/saropa/saropa_lints/blob/main/LICENSE). Use it however you like.\n\n---\n\nBuilt with care by the Flutter community. Questions? Ideas? We'd love to hear from you.\n\n[pub.dev][pub_link] | [GitHub][github_link] | [Issues][issues_link] | [Saropa][saropa_link]\n\n[pub_link]: https://pub.dev/packages/saropa_lints\n[github_link]: https://github.com/saropa/saropa_lints\n[issues_link]: https://github.com/saropa/saropa_lints/issues\n[saropa_link]: https://saropa.com\n\n---\n\n## About This Project\n\n\u003e \"The bitterness of poor quality remains long after the sweetness of meeting the schedule has been forgotten.\" — Karl Wiegers\n\n\u003e \"Quality is not an act, it is a habit.\" — Aristotle\n\n**saropa_lints** is a comprehensive static analysis package for Flutter and Dart applications. With **2134** lint rules organized into 5 progressive tiers (and more planned), it catches memory leaks, security vulnerabilities, accessibility violations, and runtime crashes that standard linters miss. Whether you're building a startup MVP or enterprise software, saropa_lints helps you ship more stable, secure, and accessible apps.\n\n**Keywords:** Flutter linter, Dart static analysis, Flutter code quality, memory leak detection, security scanning, accessibility testing, WCAG compliance, European Accessibility Act, Flutter best practices, Dart analyzer plugin, code review automation, CI/CD linting, Flutter enterprise tools\n\n**Hashtags:** #Flutter #Dart #StaticAnalysis #CodeQuality #FlutterDev #DartLang #Linting #DevTools #OpenSource #Accessibility #Security #BestPractices\n\n---\n\n## Sources\n\n- **Dart Analyzer** — Dart's static analysis engine\n  https://dart.dev/tools/analysis\n\n- **analysis_server_plugin** — Native Dart analyzer plugin framework\n  https://pub.dev/packages/analysis_server_plugin\n\n- **Flutter Accessibility** — Flutter accessibility documentation\n  https://docs.flutter.dev/ui/accessibility-and-internationalization/accessibility\n\n- **WCAG 2.1 Guidelines** — Web Content Accessibility Guidelines\n  https://www.w3.org/WAI/standards-guidelines/wcag/\n\n- **European Accessibility Act** — EU accessibility legislation effective June 2025\n  https://accessible-eu-centre.ec.europa.eu/content-corner/news/eaa-comes-effect-june-2025-are-you-ready-2025-01-31_en\n\n- **GitHub Secret Scanning** — Leaked credentials detection report\n  https://github.blog/security/application-security/next-evolution-github-advanced-security/\n\n- **OWASP Top 10** — Application security vulnerabilities\n  https://owasp.org/www-project-top-ten/\n\n- **SonarQube** — Static analysis platform\n  https://www.sonarsource.com/products/sonarqube/\n\n- **Effective Dart** — Official Dart style guide\n  https://dart.dev/effective-dart\n\n- **Flutter Performance** — Performance best practices\n  https://docs.flutter.dev/perf\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n[![Share on X](https://img.shields.io/badge/share%20on-X-000000?style=flat-square\u0026logo=x\u0026logoColor=white)](https://twitter.com/intent/tweet?text=Check%20out%20Saropa%20Lints%3A%20Catch%20memory%20leaks%2C%20security%20vulnerabilities%2C%20and%20runtime%20crashes%20in%20Flutter%21\u0026url=https%3A%2F%2Fpub.dev%2Fpackages%2Fsaropa_lints) [![Share on Facebook](https://img.shields.io/badge/share%20on-facebook-1877F2?style=flat-square\u0026logo=facebook\u0026logoColor=white)](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fpub.dev%2Fpackages%2Fsaropa_lints) [![Share on Bluesky](https://img.shields.io/badge/share%20on-bluesky-0285FF?style=flat-square\u0026logo=bluesky\u0026logoColor=white)](https://bsky.app/intent/compose?text=Check%20out%20Saropa%20Lints%3A%20Catch%20memory%20leaks%2C%20security%20vulnerabilities%2C%20and%20runtime%20crashes%20in%20Flutter%21%20https%3A%2F%2Fpub.dev%2Fpackages%2Fsaropa_lints) [![Share on LinkedIn](https://img.shields.io/badge/share%20on-linkedin-0077B5?style=flat-square\u0026logo=linkedin\u0026logoColor=white)](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fpub.dev%2Fpackages%2Fsaropa_lints) [![Share on Reddit](https://img.shields.io/badge/share%20on-reddit-FF4500?style=flat-square\u0026logo=reddit\u0026logoColor=white)](https://www.reddit.com/submit?url=https%3A%2F%2Fpub.dev%2Fpackages%2Fsaropa_lints\u0026title=Saropa%20Lints%20-%20Advanced%20Static%20Analysis)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaropa%2Fsaropa_lints","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaropa%2Fsaropa_lints","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaropa%2Fsaropa_lints/lists"}