cognitive_complexity 0.2.1
cognitive_complexity: ^0.2.1 copied to clipboard
Algorithmic Cognitive Complexity calculation library and CLI tool for Dart and Flutter.
A deterministic, zero-token Cognitive Complexity calculation library, CLI tool, and GitHub Action for Dart and Flutter repositories.
Unlike Cyclomatic Complexity (which measures control flow branch density), Cognitive Complexity measures how difficult a method is for a human engineer to read and understand, following the whitepaper specification by G. Ann Campbell.
Features #
- Modern Dart 3 AST Support: Natively parses switch expressions, pattern
guards (
whenclauses), and collection control flow structures. - Deterministic Engine: Calculates complexity algorithmically without invoking LLM calls or external network requests.
- Git Diff Analysis: Compares current workspace declarations against a target base ref to isolate complexity deltas (Δ) in modified functions.
- Lightweight GitHub Action: Exposes workflow annotations and step summaries for CI check integration.
Scoring Model #
Scores follow the SonarSource Cognitive Complexity whitepaper (G. Ann Campbell, v1.7):
| Construct / Syntax | Base Cost | Nesting Multiplier | Deepens Nesting? | Notes |
|---|---|---|---|---|
if, for, while, do-while, catch / on |
+1 |
+D (Current Depth) |
Yes | Standard flow-breaking structures |
switch Statements & Expressions |
+1 |
+D (Current Depth) |
Yes | Entire block costs +1 regardless of arm count |
else / else if |
+1 |
+0 (Flat penalty) |
No | Branch contents sit one level below head if |
Logical Operators (&&, ||) |
+1 |
+0 (Flat penalty) |
No | +1 per sequence; +1 for each alternation |
Pattern when Guards |
+1 |
+0 (Flat penalty) |
No | Dart 3 specific interpretation |
| Lambdas & Local Functions | +0 |
+0 |
Yes | Deepens nesting depth for enclosed bodies |
Null-Aware (??, ?., ??=), assert, try / finally |
+0 |
+0 |
No | Benign syntax; completely free |
| Switch Case Labels & Pattern Combinators | +0 |
+0 |
No | Stacked arms / or-patterns (1 || 2) are free |
Dart-specific interpretations of the spec:
- Pattern
whenguards add +1 (a guard is an extra condition to evaluate). - Pattern-level combinators (
case 1 || 2:,case > 0 && < 10) are free — an or-pattern is the modern spelling of stacked case labels, which the spec scores at zero. - The whitepaper's "+1 for each method in a recursion cycle" is not implemented, matching SonarSource's own reference implementation (sonar-java), which omits it as well.
💻 CLI Usage #
You can run the scanner on-demand without installation, locally inside a project, or globally. (Requires Dart SDK 3.12.0 or greater).
On-Demand (Recommended) #
Run the scanner directly in any Dart or Flutter project root using the Dart SDK:
dart run cognitive_complexity@ [options] [targets]
(Note: The trailing @ instructs the Dart VM to resolve and execute the latest published version of the package on-demand).
Project Dependency #
Add the package to your dev_dependencies in pubspec.yaml:
dev_dependencies:
cognitive_complexity: ^0.2.0
And run:
dart run cognitive_complexity [options] [targets]
Global Installation #
To install the scanner globally on your system:
dart install cognitive_complexity
cognitive_complexity [options] [targets]
Options #
-t, --threshold <value>: Minimum score to display in the terminal (default:0).-f, --fail-threshold <value>: Ceilings score. Exits with code1if any declaration exceeds this value.-d, --git-diff <git-ref>: Compares current code against a git commit/ref, evaluating complexity deltas (Δ) on modified functions.--fail-on-increase: When using--git-diff, exits with code1if any modified function experienced a complexity score increase.--format <text|json|github>: Report output formatting (default:text).
📦 Library API Usage #
Exposes programmatic analyzers for Dart and Flutter applications.
Add to pubspec.yaml:
dependencies:
cognitive_complexity: ^0.2.0
Programmatic Scan Example #
import 'package:cognitive_complexity/cognitive_complexity.dart';
void main() {
final analyzer = ComplexityAnalyzer();
// Scan a directory or file path
final results = analyzer.analyzePath('lib/src');
for (final res in results) {
print('${res.name}: score is ${res.score} (${res.filePath}:L${res.startLine})');
}
}
🤖 GitHub Actions Integration #
You can run complexity checks automatically on pull requests using the integrated composite GitHub Action.
PR Delta Audit Workflow Example #
This workflow scans only the files and functions modified in the pull request. It injects inline code review warnings directly on modified PR lines and prints a beautiful markdown transition table to the workflow summary.
Create .github/workflows/complexity.yml:
name: Cognitive Complexity Audit
on:
pull_request:
branches: [ main ]
jobs:
audit:
runs-on: ubuntu-latest
permissions:
pull-requests: write # Required to post/update sticky PR comments
contents: read # Required for actions/checkout
steps:
- name: Checkout Repository
uses: actions/checkout@v7
with:
# Fetch full history so merge-base comparison can locate common ancestor
fetch-depth: 0
- name: Setup Dart SDK
uses: dart-lang/setup-dart@v1
- name: Run Complexity Scanner
uses: kevmoo/cognitive_complexity.dart@main
with:
# Auto-configures pull request merge base comparison
diff-base: origin/${{ github.base_ref }}
fail-threshold: 15
fail-on-increase: true
Action Configuration Parameters (with:) #
targets: Space-separated directories or files to scan (default:lib).threshold: Minimum score to include in report tables (default:0).fail-threshold: Max complexity ceiling (default:15).diff-base: Git ref to compare against (e.g.origin/main). Leave empty to compare full repository files.fail-on-increase: Settrueto block PR merge if complexity increases.format: Summary format:github(GHA annotations + summary),text, orjson.
Permissions & Security #
By default, GitHub Actions runs with read-only permissions. To enable posting and updating the sticky PR comment summary directly on the PR thread, you must explicitly grant write permissions to pull-requests:
permissions:
pull-requests: write
contents: read
If write permissions are not granted, the scanner will execute normally, and output annotations and step summaries, but will skip posting the PR comment without failing the build.
Fork PR Security Note
Workflows triggered by pull requests from external forks are executed with restricted read-only permissions by GitHub. For security reasons, the action will gracefully skip posting PR comments on forks to prevent Remote Code Execution (RCE) risks, while still validating code complexity in GHA annotations and build status.
🧠 AI Agent Integration (Skill) #
This repository packages an authoritative Agent Skill (dart-cognitive-complexity)
designed to train LLMs and autonomous agents on Cognitive Complexity math,
threshold boundaries, and structural Dart refactoring patterns (such as Dart 3
switch expressions and guard clauses). (Note: Executing automated skill scans via CLI requires Dart SDK version 3.12.0 or greater in the agent runtime).
Installing the Skill #
You can install this skill into your AI agent environment:
npx skills add kevmoo/cognitive_complexity.dart --skill dart-cognitive-complexity