Skip to content

Autopsy your code. AST-level code quality analyzer for TypeScript & JavaScript — quality scoring (A–F), cyclomatic & cognitive complexity, 13 lint rules, baseline tracking, hotspot detection, plugin system, JSON/HTML/SARIF output.

License

Notifications You must be signed in to change notification settings

O6lvl4/codopsy-ts

Repository files navigation

Codopsy

Autopsy your code. Zero config, instant insight.

AST-level code quality analyzer for TypeScript & JavaScript.
Quality scoring (A–F), cyclomatic & cognitive complexity, 47 lint rules,
baseline tracking, hotspot detection, and plugin support
— all from a single command.

日本語


Why Codopsy?

ESLint + sonarjs Biome oxlint Codopsy
Zero config - partial partial yes
Cyclomatic complexity plugin - - built-in
Cognitive complexity plugin - - built-in
Quality score (A–F) - - - built-in
Baseline / CI gate - - - built-in
Hotspot detection - - - built-in
SARIF output plugin - - built-in
Plugin system yes - - yes
Programmatic API - - - yes
  • Zero config — works out of the box, no .eslintrc jungle
  • Quality score — A–F grade per file and project (0–100 scale)
  • Two complexity metrics — cyclomatic and cognitive (SonarSource method)
  • Baseline tracking — save a snapshot, fail CI if quality degrades
  • Hotspot detection — find files with high complexity and high git churn
  • Plugin system — add custom rules via simple JS/TS modules
  • SARIF output — plug directly into GitHub Code Scanning
  • Git-aware--diff to analyze only changed files
  • Programmatic APIimport { analyze } from 'codopsy-ts' without triggering CLI
  • Self-dogfooding — Codopsy passes its own analysis with grade A (99/100)

Quick Start

npm install -g codopsy-ts

# Generate config (optional)
codopsy-ts init

# Analyze
codopsy-ts analyze ./src
Analyzing ./src ...
Found 28 source file(s).

=== Analysis Summary ===
  Quality Score:  A (99/100)
  Files analyzed: 28
  Total issues:   29
    Error:   0
    Warning: 0
    Info:    29
  Avg complexity: 2.8
  Max complexity: 10 (checkMaxComplexity in src/analyze.ts)

Report written to: codopsy-report.json

Supported Files

.ts .tsx .js .jsx

node_modules/, dist/, *.d.ts, and .gitignore patterns are excluded automatically.


CLI Reference

codopsy-ts analyze

codopsy-ts analyze [options] <dir>
Option Description Default
-f, --format <type> json, html, or sarif json
-o, --output <path> Output file path. - for stdout codopsy-report.{format}
--max-complexity <n> Cyclomatic complexity threshold 10
--max-cognitive-complexity <n> Cognitive complexity threshold 15
--diff <base> Only analyze files changed from <base> ref
--fail-on-warning Exit 1 if warnings found
--fail-on-error Exit 1 if errors found
-v, --verbose Show per-file results
-q, --quiet Summary only
--no-color Disable colors
--save-baseline Save current results as baseline
--baseline-path <path> Path to baseline file .codopsy-baseline.json
--no-degradation Exit 1 if quality degrades vs baseline
--hotspots Show hotspot analysis (complexity x churn)

codopsy-ts init

codopsy-ts init [dir] [--force]

Generate a .codopsyrc.json with all rules configured. Use --force to overwrite.

Examples

# HTML report
codopsy-ts analyze ./src -f html -o report.html

# SARIF for GitHub Code Scanning
codopsy-ts analyze ./src -f sarif -o results.sarif

# Pipe JSON to jq
codopsy-ts analyze ./src -o - | jq '.summary'

# Only check files changed in this PR
codopsy-ts analyze ./src --diff origin/main

# Gate CI on warnings
codopsy-ts analyze ./src --fail-on-warning

# Save baseline and fail on degradation
codopsy-ts analyze ./src --save-baseline
codopsy-ts analyze ./src --no-degradation

# Show hotspots (high complexity + high churn)
codopsy-ts analyze ./src --hotspots

When using -o -, progress messages go to stderr so stdout is pure report data.


Quality Score

Every file and the project as a whole receive a score from 0–100, mapped to an A–F grade.

Grade Score
A 90–100
B 75–89
C 60–74
D 40–59
F 0–39

The score is composed of three sub-scores:

  • Complexity (0–35) — penalties for cyclomatic > 10 (×2, cap 15/fn), cognitive > 15 (×1.5, cap 12/fn)
  • Issues (0–40) — error: -8×count, warning: -4×√count, info: -1×√count (per rule, sqrt diminishing returns)
  • Structure (0–25) — max-lines (-10, cap 12), max-depth (-4, cap 12), max-params (-3, cap 10)

Baseline Tracking

Save a snapshot of your quality metrics, then fail CI if things get worse.

# Save baseline after a clean run
codopsy-ts analyze ./src --save-baseline

# On subsequent runs, compare and fail if degraded
codopsy-ts analyze ./src --no-degradation

The baseline file (.codopsy-baseline.json) stores per-file issue counts, complexity, and score. The comparison output shows:

=== Baseline Comparison ===
  Status: IMPROVED
  Score:  B → A (↑ +5)
  Issues: -3
  Improved: src/index.ts, src/utils.ts

Hotspot Detection

Combine complexity with git churn to find the riskiest files in your codebase.

codopsy-ts analyze ./src --hotspots
=== Hotspot Analysis (last 6 months) ===
  HIGH   src/analyzer/linter.ts (42 commits, 3 authors, complexity: 9)
  MEDIUM src/index.ts (28 commits, 2 authors, complexity: 7)
  LOW    src/utils/file.ts (5 commits, 1 authors, complexity: 4)

Risk levels: HIGH (score > 100), MEDIUM (score > 30), LOW (score <= 30).


Rules

Complexity Metrics

Metric What it measures
Cyclomatic Branching paths per function (if / for / while / case / && / || / ? : / catch)
Cognitive Human-perceived difficulty — penalizes nesting, rewards linear flow (SonarSource method)

Lint Rules

Rule Default Description
max-complexity warning Cyclomatic complexity exceeds threshold
max-cognitive-complexity warning Cognitive complexity exceeds threshold
max-lines warning File exceeds 300 lines
max-depth warning Block nesting exceeds 4 levels
max-params warning Function has more than 4 parameters
no-any warning Usage of any type
no-var warning var declaration
eqeqeq warning == / != instead of === / !==
no-empty-function warning Empty function body (comment-only bodies are considered intentional)
no-nested-ternary warning Nested ternary expression (JSX boundaries are excluded)
no-param-reassign warning Reassignment to function parameter
no-console info console.*() call
prefer-const info let that is never reassigned

Configuration

Generate a config file with codopsy-ts init, or create .codopsyrc.json manually in your project root (searched upward).

{
  "rules": {
    "no-any": "error",
    "no-console": false,
    "max-lines": { "severity": "warning", "max": 500 },
    "max-complexity": { "severity": "error", "max": 15 },
    "max-cognitive-complexity": { "severity": "warning", "max": 20 }
  },
  "plugins": ["./my-plugin.js"]
}
Value Effect
"error" / "warning" / "info" Change severity
false Disable the rule
{ "severity": "...", "max": N } Set severity + threshold

Plugin System

Create custom rules as JS/TS modules. A plugin exports a rules array:

// my-plugin.js
export default {
  rules: [
    {
      id: 'no-todo-comments',
      description: 'Disallow TODO comments',
      defaultSeverity: 'info',
      check(sourceFile, filePath, issues) {
        const text = sourceFile.getFullText();
        const regex = /\/\/\s*TODO/gi;
        let match;
        while ((match = regex.exec(text)) !== null) {
          const { line } = sourceFile.getLineAndCharacterOfPosition(match.index);
          issues.push({
            file: filePath,
            line: line + 1,
            column: 1,
            severity: 'info',
            rule: 'no-todo-comments',
            message: 'TODO comment found',
          });
        }
      },
    },
  ],
};

Register in .codopsyrc.json:

{
  "plugins": ["./my-plugin.js"],
  "rules": {
    "no-todo-comments": "warning"
  }
}

Plugin rules can be configured (change severity or disable) just like built-in rules.


Programmatic API

Use Codopsy as a library without triggering the CLI:

import { analyze } from 'codopsy-ts';

const result = await analyze({ targetDir: './src' });
console.log(result.score);  // { overall: 99, grade: 'A', distribution: { A: 25, B: 3, ... } }
console.log(result.summary.totalIssues);

Available exports

import {
  // High-level
  analyze,

  // Low-level
  analyzeFile,
  analyzeComplexity,
  lintFile,

  // Config
  loadConfig,

  // Report
  formatReport,
  generateReport,

  // Scoring
  calculateFileScore,
  calculateProjectScore,

  // Files
  findSourceFiles,

  // Plugins
  loadPlugins,
} from 'codopsy-ts';

Output Formats

JSON

Machine-readable analysis data. Pipe to jq, feed into dashboards, or post-process in CI.

Example output
{
  "timestamp": "2026-02-17T12:00:00.000Z",
  "targetDir": "./src",
  "score": {
    "overall": 99,
    "grade": "A",
    "distribution": { "A": 25, "B": 3 }
  },
  "files": [
    {
      "file": "src/analyze.ts",
      "complexity": {
        "cyclomatic": 10,
        "cognitive": 8,
        "functions": [
          { "name": "checkMaxComplexity", "line": 74, "complexity": 10, "cognitiveComplexity": 8 }
        ]
      },
      "issues": [],
      "score": { "score": 95, "grade": "A" }
    }
  ],
  "summary": {
    "totalFiles": 28,
    "totalIssues": 29,
    "issuesBySeverity": { "error": 0, "warning": 0, "info": 29 },
    "averageComplexity": 2.8,
    "maxComplexity": { "file": "src/analyze.ts", "function": "checkMaxComplexity", "complexity": 10 }
  }
}

HTML

Visual report with quality score card, grade distribution, per-file complexity breakdown, and issue listings. Open in any browser.

SARIF

SARIF 2.1.0 for integration with GitHub Code Scanning, VS Code SARIF Viewer, and other tools.


GitHub Actions

Using the Action (recommended)

name: Codopsy
on: [push, pull_request]
jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    steps:
      - uses: actions/checkout@v4
      - uses: O6lvl4/codopsy-ts@v1
        with:
          directory: ./src

SARIF results are automatically uploaded to the Security tab.

Action inputs

Input Description Default
directory Directory to analyze ./src
format Output format sarif
max-complexity Cyclomatic threshold 10
max-cognitive-complexity Cognitive threshold 15
fail-on-warning Fail on warnings false
fail-on-error Fail on errors true
upload-sarif Upload SARIF to Code Scanning true

Manual setup

name: Codopsy
on: [push, pull_request]
jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm install -g codopsy-ts
      - run: codopsy-ts analyze ./src --format sarif --output results.sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: results.sarif

Development

git clone https://github.com/O6lvl4/codopsy-ts.git
cd codopsy-ts
npm install
npm start -- analyze ./src        # Run locally
npm test                          # 312 tests
npm run test:watch                # Watch mode
npm run build                     # Compile to dist/

Self-analysis

Codopsy analyzes itself with grade A and 0 warnings:

npm start -- analyze ./src --verbose
# 28 files, Quality Score: A (99/100), 0 warnings

Roadmap

  • LSP / IDE integration — VS Code extension with real-time diagnostics
  • Rule documentation site — Per-rule reference pages with examples, configuration, and rationale

License

ISC

About

Autopsy your code. AST-level code quality analyzer for TypeScript & JavaScript — quality scoring (A–F), cyclomatic & cognitive complexity, 13 lint rules, baseline tracking, hotspot detection, plugin system, JSON/HTML/SARIF output.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •