typesweep
v0.1.5
Published
Git-aware codebase complexity auditor with CI gating
Readme
🏔️✨ TypeSweep — Git-aware Codebase Complexity Auditor
TypeScript + Bun CLI that audits your repo for code smells + complexity hotspots, turns results into a hierarchical, clustered report, and can gate CI builds on complexity budgets.
Bun is required to run the CLI.
Why TypeSweep ✨
Complexity creeps in through “small” decisions: one more parameter, another nested branch, a few extra lines. TypeSweep makes entropy visible, so you can keep the codebase malleable instead of brittle.
What You Get 🎯
- 🔥 A ranked list of the functions and files that amplify entropy.
- 🧭 Directory rollups that show hotspots across the tree, not just in individual files.
- 🧪 Gating modes that prevent regressions or enforce budgets.
- 🗺️ Interactive HTML reports for exploration and quick sharing.
Visual Tour ✨🖼️
┌──────────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────────┐
│ 🧭 Scan the repo │ ─▶ │ 🧪 Analyze & cluster │ ─▶ │ 📊 Report & gate │
│ files + git changes │ │ metrics + hotspots │ │ HTML/JSON/console │
└──────────────────────────┘ └──────────────────────────┘ └──────────────────────────┘flowchart LR
A[📁 Repo] --> B[🔎 Discover files]
B --> C[🧮 Metrics per function]
C --> D[🧱 Rollups + percentiles]
D --> E[🔥 Hotspot clustering]
E --> F[📊 Reports]
E --> G[🚦 Gate]┌──────────────────────────────────────────────────────────────┐
│ 🖼️ HTML Report │
├──────────────┬──────────────────────┬─────────────────────────┤
│ Treemap │ Hotspots Table │ Function Drilldown │
│ (heat) │ (ranked) │ (metrics + thresholds) │
├──────────────┴──────────────────────┴─────────────────────────┤
│ Search • Filters • Deep links • Directory rollups │
└──────────────────────────────────────────────────────────────┘Snapshot of the Output 📸
Console (outliers) 🧹
🏔️ TypeSweep — Top 5 Outliers
1. ƒ █████████████████░░ 74.2 run
cyclomatic=18 functionLoc=142 nesting=6 params=7 …/src/core/pipeline.ts
2. ƒ ███████████████░░░░ 68.5 render
cyclomatic=16 functionLoc=121 nesting=5 params=5 …/src/report/html.ts
3. 📄 ████████████░░░░░░ 52.3 src/git/git.ts
fileLoc=980 dataRatio=0.82 …/src/git/git.tsJSON (gate) 🧱
{
"passed": false,
"mode": "regression",
"summary": "❌ 1 regression(s) detected",
"violations": [
{
"rule": "regression",
"metric": "p95cc",
"value": 13,
"limit": 12,
"severity": "fail"
}
],
"warnings": [],
"baseline": {
"cc": { "p50": 2, "p75": 4, "p90": 7, "p95": 12, "p99": 18, "max": 24 },
"fnLoc": { "p50": 10, "p75": 18, "p90": 30, "p95": 55, "p99": 90, "max": 140 },
"fileLoc": { "p50": 80, "p75": 150, "p90": 260, "p95": 420, "p99": 900, "max": 1400 },
"nesting": { "p50": 1, "p75": 2, "p90": 3, "p95": 4, "p99": 6, "max": 9 },
"params": { "p50": 1, "p75": 2, "p90": 3, "p95": 4, "p99": 6, "max": 9 }
},
"current": {
"cc": { "p50": 2, "p75": 4, "p90": 7, "p95": 13, "p99": 18, "max": 24 },
"fnLoc": { "p50": 10, "p75": 18, "p90": 30, "p95": 55, "p99": 90, "max": 140 },
"fileLoc": { "p50": 80, "p75": 150, "p90": 260, "p95": 420, "p99": 900, "max": 1400 },
"nesting": { "p50": 1, "p75": 2, "p90": 3, "p95": 4, "p99": 6, "max": 9 },
"params": { "p50": 1, "p75": 2, "p90": 3, "p95": 4, "p99": 6, "max": 9 }
},
"deltas": { "p95cc": 1, "hotspotScore": 3.2 }
}HTML 🖼️
Treemap and table views with search, deep links, and expandable directory rollups. Use it to find and focus the few files creating the most drag.
Entropy Scoreboard 🧮
| Metric | Why it matters | Typical action | |---|---|---| | 🔺 Cyclomatic | Branch explosion | Split by intent, isolate conditions | | 📏 Function LOC | Hidden complexity | Extract helpers | | 🧱 Nesting depth | Cognitive load | Early returns, flatten logic | | 🧬 Param count | Design smell | Group into domain types |
Install ⚡
# No install needed (Bun required)
bunx typesweep
# Or install globally
bun add -g typesweep
# Or add to project
bun add -d typesweepCommon Workflows
Local Development
# Interactive HTML report
typesweep scan . --format html,json --out ./typesweep-report --open
# PowerShell: quote comma-separated formats
typesweep scan . --format "html,json" --out ./typesweep-report --open
# Top outliers
typesweep outliers . --top 50
# Scan only changed files vs main
typesweep scan . --changed --base origin/main
# Gate in CI (absolute thresholds)
typesweep gate . --threshold preset:strict --fail-on any
# Gate on regressions (PR didn't make things worse)
typesweep gate . --base origin/main --mode regression
# Budget gating (allow small increases)
typesweep gate . --base origin/main --mode budget --budget "hotspotScore:+10,p95cc:+1"
# Diff view (human-readable comparison)
typesweep diff . --base origin/mainWhat it Measures 📏
Per function:
- Cyclomatic complexity
- Lines of code
- Max nesting depth
- Parameter count
- Branch density (branches / LOC)
Per file:
- Total LOC, blank lines, comment lines
- Function count
- Max/avg metrics across functions
- Hotspot score (0–100 composite)
Per directory (hierarchical):
- Rolled-up percentiles (p50/p75/p90/p95/p99/max)
- Cluster hotspot scores
- Top files and functions
Commands 🧰
scan
Analyze and report.
typesweep scan <path> [options]
-f, --format <fmts> console,json,html (comma-separated, default: console)
-o, --out <dir> Output directory (default: ./typesweep-report)
-c, --config <path> Config file path
-t, --threshold <p> preset:strict|balanced|loose
--changed Only scan changed files
--base <ref> Git base ref (default: origin/main)
--unused Enable unused code analysis
--no-unused Disable unused code analysis
--open Open HTML report in browser
--sections <list> Show only: summary,percentiles,unused,callgraph,clusters,outliers,gate
--unused-filter <glob> Filter unused code by file pattern
--limit <n> Limit items shown per section (default: 10)
--quiet Only show issues/failures
-v, --verbose Verbose outputgate
CI gating — exit non-zero on policy failure.
typesweep gate <path> [options]
-m, --mode <mode> absolute|regression|budget (default: absolute)
--base <ref> Git base ref (default: origin/main)
--changed Gate only changed files
-t, --threshold <p> Threshold preset
--budget <spec> e.g. "p95cc:+1,hotspotScore:+10"
--fail-on <rules> any|p95|topOutliers|newOutliers (comma-separated)
--warn-only Non-blocking (always exit 0)
-f, --format <fmts> console,json (default: console)
-o, --out <dir> Output directory (default: ./typesweep-report)
-c, --config <path> Config file path
-v, --verbose Verbose outputdiff
Human-readable comparison vs baseline.
typesweep diff <path> --base origin/main
--base <ref> Git base ref (default: origin/main)
-c, --config <path> Config file path
-v, --verbose Verbose outputoutliers
Show top complexity outliers.
typesweep outliers <path> --top 50
--top <n> Number of outliers to show (default: 50)
-t, --threshold <p> Threshold preset
-c, --config <path> Config file path
-v, --verbose Verbose outputstructure
Export an architectural overview (LLM-friendly).
typesweep structure <path> [options]
-f, --format <fmts> console,json (default: console)
-o, --out <dir> Output directory (default: ./typesweep-report)
--min-complexity <n> Only show classes/methods above threshold
--filter <pattern> Filter files by glob pattern (e.g., 'src/report/**')
--min-cohesion <v> Only show files with cohesion below threshold
--max-cohesion <v> Only show files with cohesion above threshold
--sort-by <field> cohesion|size|constructs (default: constructs)
--compare <file> Compare with previous analysis JSON
-c, --config <path> Config file path
-v, --verbose Verbose outputLLM workflow (compact)
typesweep --format html --openConfiguration
Create typesweep.config.ts (optional):
export default {
// What to scan
include: ["src/**/*.{ts,tsx}"],
exclude: ["**/*.test.*"],
// When to warn/fail
thresholds: {
cyclomatic: { warn: 10, fail: 15 },
functionLoc: { warn: 50, fail: 100 },
nesting: { warn: 4, fail: 6 },
params: { warn: 4, fail: 6 },
},
// CI gating
gate: {
mode: "regression", // Don't let it get worse
baseRef: "origin/main",
changedOnly: true,
},
};Command Reference
typesweep [options]
Main command - shows hotspots.
Options:
--limit <n>— How many items to show (default: 10)--format <f>— Output format: console, json, html (default: console)--sections <s>— Which sections: outliers, unused, summary, percentiles--changed— Only scan changed files (git)--base <ref>— Git base branch (default: origin/main)--unused— Include unused code detection--filter <glob>— File pattern filter--quiet— Only show issues--open— Open HTML report in browser--verbose— Show detailed output
typesweep gate [options]
CI gating - exit non-zero on policy violations.
Options:
--mode <m>— Gate mode: regression, absolute, budget (default: regression)--threshold <p>— Preset: strict, balanced, loose--changed— Only gate changed files--base <ref>— Git base branch (default: origin/main)--warn-only— Don't fail (exit 0 always)
typesweep diff --base <ref>
Show what changed vs baseline.
typesweep structure [options]
Architectural overview (LLM-friendly).
Options:
--format <f>— console or json (default: console)--filter <glob>— File pattern filter--min-complexity <n>— Only show complex items--check— Exit non-zero if issues found
CI Integration
GitHub Actions
name: TypeSweep
on: [pull_request]
jobs:
complexity-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
- run: bun install
- name: TypeSweep gate
run: |
bunx typesweep gate . \
--base origin/main \
--changed \
--mode regression \
--threshold preset:balanced \
--format json \
--out ./artifacts/typesweep
- uses: actions/upload-artifact@v4
if: always()
with:
name: typesweep-report
path: artifacts/typesweepOutput Artifacts 🧾
| File | Contents |
|------|----------|
| metrics.json | Repo summary + directory tree + file/function metrics |
| outliers.json | Ranked outliers with reasons |
| clusters.json | Hotspot clusters + rollups |
| gate.json | Gating decision + violations (deltas for regression/budget) |
| index.html | Interactive report with treemap, tables, search |
Project Structure 🧱
src/
cli/ # scan/gate/diff/outliers commands
config/ # config loading + presets
core/ # main analysis pipeline
discover/ # file discovery + ignore
parse/ # TS parsing via TypeScript compiler API
metrics/ # per-function + per-file metrics
aggregate/ # rollups by dir/repo
outliers/ # percentile/z-score logic
cluster/ # hierarchical clustering
git/ # diff, blame, churn
gate/ # policy evaluation + exit codes
report/ # html/json/console rendering
types/ # shared typesLicense 📜
GPL-3.0-only
How to Reduce Entropy With TypeSweep 🧠
- 🪓 Trim max nesting before anything else; it compounds every other metric.
- 🧱 Split long functions by intent, not by file boundaries; new helpers reduce cc and loc together.
- 🧬 Treat high parameter counts as a design smell; favor option objects or domain types.
- 📈 Focus on percentile deltas (p90/p95), not averages; entropy accumulates at the top.
- 🧨 Use
gate --mode regressionfor PRs andgate --mode absolutefor release branches.
LLM Validation Workflows 🤖
Use TypeSweep as a structured signal generator for LLM reviews. The goal is to keep prompts small and targeted.
1) PR validation loop (fast)
# Get only the issues in changed files
typesweep --changed --format json --quiet --limit 10Send this compact JSON to your LLM to review specific problems.
Pattern 2: Refactoring Target Selection
# 1) Structural overview (LLM-friendly JSON)
typesweep structure . --format json --out ./typesweep-report
# 2) Show only hotspots and unused code
typesweep scan . --sections outliers,unused --limit 15
# 3) Focus on a directory
typesweep scan . --sections outliers,unused --unused-filter 'src/report/**' --limit 10Structure check (fast gate)
# Compare vs main branch
typesweep diff --base origin/mainTrack complexity trends over time.
Why This Works for LLMs
- Structured output — JSON format is easy to parse
- Focused context — Only relevant files/functions
- Actionable metrics — Clear numbers to evaluate
- Small payloads — Use
--limitto keep context small
Design Philosophy
TypeSweep is built around three principles:
- Simple by default —
typesweepjust works - Powerful when needed — Advanced options for complex scenarios
- LLM-first — Structured output for automated reviews
Most users only need:
typesweep— Find hotspotstypesweep gate— Prevent regressionstypesweep --format json— LLM integration
Everything else is optional.
Simplification from v0.1.x
If you're upgrading from earlier versions:
- ✅ Default command now just works (
typesweepinstead oftypesweep scan .) - ✅ Removed rarely-used
outlierscommand (use main command instead) - ✅ Simplified gate modes (regression is now default)
- ✅ Unified output format (
--formatinstead of separate flags) - ⚠️ Config format unchanged (fully backward compatible)
How to Reduce Complexity
Use TypeSweep results to guide refactoring:
- Start with nesting — Flatten deeply nested code first
- Extract functions — Break long functions into smaller pieces
- Simplify conditions — Reduce cyclomatic complexity
- Remove parameters — Use option objects or domain types
- Delete dead code — Remove unused exports
Project Structure
src/
cli/ # Command implementations
core/ # Analysis pipeline
metrics/ # Complexity calculations
parse/ # TypeScript AST parsing
report/ # Output formatters (console, JSON, HTML)
gate/ # CI gating logic
git/ # Git integration
structure/ # Architectural analysisLicense
GPL-3.0-only
FAQ
Q: Do I need Bun?
A: Yes. TypeSweep is built on Bun for speed and simplicity.
Q: Can I use this with JavaScript?
A: Not yet. TypeSweep currently only supports TypeScript.
Q: How is this different from ESLint complexity rules?
A: TypeSweep analyzes the entire codebase holistically (percentiles, git integration, directory rollups). ESLint works file-by-file.
Q: Can I customize thresholds?
A: Yes. Use typesweep.config.ts or --threshold preset:strict|balanced|loose.
Q: How do I integrate with LLMs?
A: Use --format json and --sections to get structured, focused output. See LLM Integration Guide.
Contributing
PRs welcome! Please keep the tool simple and fast.
Development:
# Run from source
bun run src/index.ts
# Type-check
bun run check
# Lint
bun run lint
# Run tests
bun test
# Run tests in watch mode
bun test --watch
# Run tests with coverage
bun test --coverage
# Install git hooks (one-time per clone; also auto-runs on bun install via prepare)
bun run hooks:install
# Verify hooks are configured correctly
bun run hooks:verify
# Run the same unit coverage gate used by pre-push/CI
bun run test:unit:gatePre-push coverage gate:
- The pre-push hook runs
bun run test:unit:gateand blocks push when unit line coverage is below the threshold. - After generating coverage, the pre-push hook automatically stages
typesweep-report/unit-coverage.md(orCOVERAGE_ARTIFACT_PATHif set) so it is included in your changelist. - Default threshold is
85.
Set a custom threshold:
# macOS/Linux (bash/zsh)
COVERAGE_THRESHOLD=90 bun run test:unit:gate# Windows PowerShell
$env:COVERAGE_THRESHOLD = "90"; bun run test:unit:gateTesting:
TypeSweep uses Bun's native test runner for testing. The test suite includes:
- Unit tests for core modules (parser, metrics, outliers, callgraph, utils)
- Integration tests for the analysis pipeline
- Test fixtures for consistent test scenarios
To run specific test files:
bun test tests/unit/utils/stats.test.tsCredits
Built with ❤️ using Bun and TypeScript.
Remember: The best code is no code. The second best is simple code. 🧹
