cognitive_complexity 0.2.6
cognitive_complexity: ^0.2.6 copied to clipboard
Algorithmic Cognitive Complexity calculation and Data-Flow analysis library and CLI tools for Dart and Flutter.
Long, complex functions are hard for humans (and AI agents) to understand. Asking an agent to "refactor the code to make it cleaner" is poorly defined and leaves the agent to make arbitrary decisions.
This Dart package, GitHub Action, and AI agent skill make finding and fixing overly complex logic easy, reliable, and repeatable by implementing the Cognitive Complexity principles articulated by SonarSource.
✨ Features #
- Modern Dart 3 AST Support: Natively parses switch expressions, pattern
guards (
whenclauses), and collection control flow structures. - Deterministic Engine: Calculates complexity algorithmically without LLM calls, external network requests, or token latency.
- Statement Data-Flow Analysis: Evaluates variable inputs, mutations, and downstream live outputs for arbitrary statement slices to power automated method extraction.
- Git Diff Analysis & Ratchet: Compares working copy changes against a target base ref to isolate complexity deltas (Δ) in modified functions.
- Lightweight GitHub Action: Exposes workflow annotations and markdown summary tables for automated CI quality gates.
⚡ Quick Start #
CLI (On-Demand) #
Run the scanner directly in any Dart or Flutter project without prior installation:
dart run cognitive_complexity@
(Requires Dart SDK 3.12.0 or greater).
cognitive_complexity CLI Options #
$ cognitive_complexity --help
Dart & Flutter Cognitive Complexity Calculator
Usage: dart run cognitive_complexity [options] [<file_or_directory>...]
Without targets, scans lib/ (or every workspace member and packages/*/lib, pkgs/*/lib in monorepos).
Options:
-h, --help Print this usage information.
-t, --threshold Minimum complexity score to include in output.
(defaults to "0")
-f, --fail-threshold Exit with non-zero code if any function score exceeds this value.
--max-file-lines=<lines> Opt-in maximum physical line count per source file (0 = disabled). Exits with non-zero code when exceeded.
--max-function-lines=<lines> Opt-in maximum line span per function/method declaration (0 = disabled). Exits with non-zero code when exceeded.
-d, --git-diff=<git-ref> Git reference to compare against. Only evaluates modified files and function complexity deltas.
--fail-on-increase When using --git-diff, exit with non-zero code if any function increased in complexity. When --fail-threshold is also set, only increases that exceed the threshold fail.
--format Output format.
[text (default), json, github]
--comment-output=<path> With --format=github, also write a standalone report to this path, ordered by significance and capped by --max-comment-rows. Intended for posting as a PR comment while the step summary keeps the full table.
--max-comment-rows=<count> Maximum table rows in --comment-output (0 = unlimited). GitHub rejects comment bodies over 65536 characters.
(defaults to "0")
--exclude=<glob> Glob patterns of files/directories to exclude (repeatable or comma-separated).
--[no-]ignore-generated Exclude generated files (*.g.dart, *.freezed.dart, *.mocks.dart, etc.).
(defaults to on)
data_flow CLI Options #
$ data_flow --help
Dart Data-Flow & Method Extraction Analyzer
Analyzes a target slice of code inside a Dart function and deterministically
calculates required parameters (inputs), modified variables (mutations),
and live return values (outputs) for safe method extraction.
Usage: dart run cognitive_complexity:data_flow [options] <file.dart[:start-end]>
Examples:
# Analyze lines 45 through 80 of auth.dart (Agent-first JSON default)
dart run cognitive_complexity:data_flow lib/src/auth.dart:45-80
# Analyze with explicit flags and custom helper name
dart run cognitive_complexity:data_flow --lines=45-80 --name=_validateToken lib/src/auth.dart
# Human-readable terminal output
dart run cognitive_complexity:data_flow --format=text lib/src/auth.dart:45-80
Options:
-h, --help Print this usage information.
-l, --lines Target 1-based line range of the code block to extract (e.g. 45-80).
-n, --name Name for the proposed extracted helper function.
(defaults to "_extracted")
-f, --format Output format.
[json (default), text]
--sdk-path Path to the Dart SDK root used for analysis. Defaults to auto-discovery (running VM, DART_SDK environment variable, PATH, FLUTTER_ROOT).
file_split CLI Options #
$ file_split --help
Dart File Decomposition & Acyclic Dependency Cut Advisor (file_split)
Usage: dart run cognitive_complexity:file_split [options] <file_or_dir>...
Options:
-h, --help Print this usage information.
--target-lines=<lines> Target maximum line count per extracted file cluster.
(defaults to "800")
--min-cluster-lines=<lines> Minimum line count for a standalone extracted cluster (prevents micro-fragmentation).
(defaults to "40")
--[no-]use-parts Allow or prefer `part` / `part of` directives when decomposing oversized classes or tightly coupled SCCs (defaults to auto-detect with user confirmation prompt).
--format Output format (text or json).
[text (default), json]
--sdk-path Path to the Dart SDK root (overrides auto-discovery).
shallow CLI Options #
$ shallow --help
Dart Single-Caller Shallow Helper & Inlining Advisor (shallow)
Detects single-caller pass-through helpers, parameter clumps, and micro-helpers,
and simulates exact caller Cognitive Complexity after re-inlining.
Usage: dart run cognitive_complexity:shallow [options] [file_or_directory...]
Options:
-h, --help Print this usage information.
--max-caller-cc=<score> Maximum allowed caller Cognitive Complexity score after inlining for a candidate to be classified as SAFE_INLINE.
(defaults to "15")
--max-params=<count> Parameter count threshold at or above which a single-caller function is flagged as HIGH_ARITY.
(defaults to "5")
--only-safe Only output SAFE_INLINE candidates where inlining keeps caller complexity <= --max-caller-cc.
-d, --git-diff=<git-ref> Git reference to compare against. Only reports shallow helpers in modified files.
--fail-on-safe-inline Exit with non-zero code if any SAFE_INLINE single-caller shallow helper is found.
--format Output format (text or json).
[text (default), json]
--exclude=<glob> Glob patterns of files/directories to exclude (repeatable or comma-separated).
--[no-]ignore-generated Exclude generated files (*.g.dart, *.freezed.dart, *.mocks.dart, etc.).
(defaults to on)
Library API #
Add cognitive_complexity to your pubspec.yaml:
import 'package:cognitive_complexity/cognitive_complexity.dart';
void main() {
final analyzer = ComplexityAnalyzer();
final results = analyzer.analyzePath('lib');
for (final res in results) {
print('${res.name}: score is ${res.score} (${res.filePath}:L${res.startLine})');
}
}
Suppressing Findings #
Use comment directives (shared across package:analytica tools) to suppress
complexity or line-limit checks for irreducible state machines, generated lookup
tables, or individual functions:
- File-level suppression: Place
// cognitive_complexity:ignore_for_fileanywhere in the file. - Declaration-level suppression: Place
// cognitive_complexity:ignoreon the line immediately preceding a function, method, or constructor.
GitHub Actions #
Add automated complexity audits to .github/workflows/complexity.yml:
name: Cognitive Complexity Audit
on:
pull_request:
branches: [main]
jobs:
audit:
runs-on: ubuntu-latest
permissions:
pull-requests: write # Required for sticky PR comment summaries
contents: read
steps:
- name: Checkout Repository
uses: actions/checkout@v7
with:
fetch-depth: 0 # Full history required for diff-base merge-base comparison
- name: Setup Dart SDK
uses: dart-lang/setup-dart@v1
- name: Run Complexity Scanner
uses: kevmoo/analytica.dart/packages/cognitive_complexity@main
with:
diff-base: origin/${{ github.base_ref }}
fail-threshold: 15
fail-on-increase: true
Action Inputs Reference
| Input | Default | Description |
|---|---|---|
targets |
Auto | Directories or files to scan. Auto-discovers lib/ or workspace package libs. |
threshold |
0 |
Minimum score required to include a declaration in summary tables. |
fail-threshold |
15 |
Maximum complexity ceiling allowed before failing the build. |
max-file-lines |
0 |
Opt-in maximum physical line count per source file (0 = disabled). |
max-function-lines |
0 |
Opt-in maximum line span per function/method declaration (0 = disabled). |
diff-base |
Auto | Git ref to compare against (e.g. origin/main). Auto-detects PR base. |
fail-on-increase |
false |
When true, blocks PR merge on complexity increases exceeding fail-threshold. |
format |
github |
Output format: github (annotations + step summary), text, or json. |
max-comment-rows |
0 |
Maximum table rows in the sticky PR comment (0 = unlimited). |
🧠 AI Agent Integration #
This repository packages an agent skill (dart-cognitive-complexity) to train
AI pair programmers on Cognitive Complexity scoring and refactoring patterns:
Install using either the dart skills CLI:
dart run skills@ add kevmoo/analytica.dart --skill dart-cognitive-complexity
Or npx skills:
npx skills add kevmoo/analytica.dart --skill dart-cognitive-complexity
📚 Documentation & Guides #
Explore in-depth documentation in the doc/ directory:
- 📐 Scoring Model & Specification: Complete scoring table, nesting multipliers, and Dart 3 AST nuances.
- 💻 CLI Reference & CI Ratcheting: Command-line options, git diff delta evaluation, and exit codes.
- 🔄 Statement Data-Flow Analysis: Statement slicing, variable lifecycles, and automated method extraction helper.