CLI Reference
Complete command-line reference for Hotspots.
Installation
# Install from source
cargo install --path hotspots-cli
# Or use pre-built binary
# Download from GitHub releasesGlobal Options
All commands support:
hotspots --help # Show help
hotspots --version # Show versionCommands
hotspots analyze
Analyze source files for complexity metrics.
Supported Languages: TypeScript, JavaScript, Go, Java, Python, Rust
Basic Usage
# Analyze a single file
hotspots analyze src/app.ts
# Analyze a directory (recursive)
hotspots analyze src/
# Analyze with JSON output
hotspots analyze src/ --format jsonOptions
<path>
Required. Path to source file or directory to analyze.
hotspots analyze src/
hotspots analyze lib/utils.ts--format <format>
Optional. Output format: text, json, jsonl, html, or sarif. Default: text
# Human-readable text output (default)
hotspots analyze src/ --format text
# Machine-readable JSON output
hotspots analyze src/ --format json
# Streaming JSONL output (one object per line)
hotspots analyze src/ --format jsonl
# Interactive HTML report (requires --mode)
hotspots analyze src/ --format html --mode snapshot
# SARIF 2.1.0 for GitHub code scanning (requires --mode snapshot)
hotspots analyze . --mode snapshot --format sarif --output .hotspots/results.sarif
# Or capture stdout
hotspots analyze . --mode snapshot --format sarif > results.sarifNotes:
- HTML format requires
--mode snapshotor--mode delta. - SARIF format requires
--mode snapshot. Unlike HTML, SARIF has no default output file — without--output, SARIF is written to stdout.
--mode <mode>
Optional. Output mode: snapshot or delta.
# Snapshot mode: capture current state
hotspots analyze src/ --mode snapshot --format json
# Delta mode: compare against parent commit
hotspots analyze src/ --mode delta --format jsonSnapshot mode:
- Captures current complexity state with git metadata
- Persists to
.hotspots/snapshots/(mainline only) - Updates
.hotspots/index.json - Computes aggregates for output
Delta mode:
- Compares current state vs parent commit
- Supports policy evaluation with
--policy - Shows complexity changes (ΔLRS)
- PR mode: compares vs merge-base
- Mainline mode: compares vs direct parent
--policy
Optional. Evaluate policies (only valid with --mode delta).
# Run policy checks
hotspots analyze src/ --mode delta --policy --format text
# Fail CI build on policy violations
hotspots analyze src/ --mode delta --policy --format json || exit 1Policy Types:
- Blocking failures: Exit code 1 on violations
- No regressions allowed (LRS must not increase)
- No band transitions to higher risk
- Warnings: Exit code 0, informational
- Watch threshold (approaching moderate)
- Attention threshold (approaching high)
- Rapid growth (>50% LRS increase)
- Net repository regression
Requires: --mode delta
--top <N>
Optional. Show only top N functions by LRS. Overrides: Config file top value.
# Show top 20 highest-complexity functions
hotspots analyze src/ --top 20
# No limit (show all)
hotspots analyze src/--min-lrs <threshold>
Optional. Filter functions below minimum LRS threshold. Overrides: Config file min_lrs value.
# Only show functions with LRS ≥ 5.0
hotspots analyze src/ --min-lrs 5.0
# Show everything (no filter)
hotspots analyze src/ --min-lrs 0.0--config <path>
Optional. Path to configuration file. Default: Auto-discover from project root.
# Use specific config file
hotspots analyze src/ --config custom-config.json
# Use CI-specific config
hotspots analyze src/ --config .hotspots.ci.jsonSee Configuration for config file format.
--output <path>
Optional. Output file path (for HTML format). Default: .hotspots/report.html
# Write HTML report to custom location
hotspots analyze src/ --mode snapshot --format html --output reports/complexity.htmlOnly applicable to HTML format.
--explain
Optional. Show human-readable per-function risk breakdown. Only valid with: --mode snapshot --format textMutually exclusive with: --level
# Show ranked functions with full risk factor explanations
hotspots analyze . --mode snapshot --format text --explain
# Limit to top 10 functions
hotspots analyze . --mode snapshot --format text --explain --top 10Displays per-function metric contributions (CC, ND, FO, NS), activity signals (churn, touch count, fan-in, SCC, depth), and a co-change coupling section at the end showing the top 10 high/moderate source-file pairs.
Note: In snapshot mode with --format text, you must specify either --explain or --level <LEVEL>.
--explain-patterns
Optional. Populate and emit per-pattern trigger details (pattern_details). Valid with: all modes and formats. Cannot be used with: --mode delta when a mode is specified.
# Basic mode: Tier 1 pattern details in text output
hotspots analyze src/ --explain-patterns
# Snapshot mode: Tier 1 + Tier 2 details, JSON output
hotspots analyze src/ --mode snapshot --format json --explain-patterns
# Combined with --explain for full per-function breakdown
hotspots analyze src/ --mode snapshot --format text --explain --explain-patternsIn text output, each function row is followed by indented lines showing the metric values that triggered each pattern:
14.10 critical src/imports.rs 622 resolve_cargo_workspace_edges complex_branching, god_function
complex_branching: cc=15 (>=10), nd=5 (>=4)
god_function: loc=120 (>=60), fo=14 (>=10)In JSON output, the pattern_details array is populated on each function object (otherwise omitted).
In snapshot mode, Tier 2 enriched patterns (those requiring call graph and git history) are also included in the details.
--level <LEVEL>
Optional. Switch to a higher-level ranked view instead of per-function output. Only valid with: --mode snapshot --format textMutually exclusive with: --explain
| Value | Output |
|---|---|
file | Ranked file risk table (max CC, avg CC, function count, LOC, churn) |
module | Ranked module instability table (afferent, efferent, instability) |
# File-level risk view (ranked by composite file_risk_score)
hotspots analyze . --mode snapshot --format text --level file
# Module (directory) instability view
hotspots analyze . --mode snapshot --format text --level module
# Limit to top 20 entries
hotspots analyze . --mode snapshot --format text --level file --top 20Note: In snapshot mode with --format text, you must specify either --level or --explain.
--force / -f
Optional. Overwrite an existing snapshot if one already exists for this commit.
hotspots analyze . --mode snapshot --forceSnapshots are normally immutable (identified by commit SHA). Use --force to regenerate a snapshot after a config change or to correct a prior run.
Mutually exclusive with: --no-persist
--no-persist
Optional. Analyze without writing the snapshot to disk. Only valid with: --mode snapshot or --mode deltaMutually exclusive with: --force
# Run snapshot analysis without saving to .hotspots/
hotspots analyze . --mode snapshot --no-persist --format jsonUseful for one-off inspection or CI pipelines where snapshot history is not needed.
--per-function-touches
Optional. Use git log -L to compute per-function touch counts instead of file-level counts. Only valid with: --mode snapshot or --mode delta
hotspots analyze . --mode snapshot --per-function-touchesWarning: Approximately 50× slower on a cold run (no cache). An on-disk touch cache is written after the first run; subsequent warm runs are significantly faster. Default touch metrics are file-level (all functions in a file share the same touch_count_30d). Use this flag when precise per-function activity signals are required.
--no-per-function-touches
Optional. Force file-level touch batching, overriding a per_function_touches: true config file setting.
hotspots analyze . --mode snapshot --no-per-function-touches--skip-touch-metrics
Optional. Skip all touch metric computation (no git log I/O). Touch counts are reported as 0. Recommended for very large repositories (50k+ functions) where git history traversal dominates analysis time.
hotspots analyze . --mode snapshot --skip-touch-metrics--callgraph-skip-above
Optional. Skip call graph betweenness centrality computation when the number of call graph edges exceeds this threshold. Betweenness centrality is O(V·E) and becomes prohibitively slow on large call graphs.
hotspots analyze . --mode snapshot --callgraph-skip-above 50000Fan-in and fan-out are still computed; only betweenness (and derived PageRank) is skipped. Recommended for repositories with 50k+ functions where the full call graph would otherwise take many minutes.
--all-functions
Optional. Output all functions as a flat array instead of the default triage-first structure (quadrant buckets). Only valid with: --mode snapshot --format json
hotspots analyze . --mode snapshot --format json --all-functionsProduces schema v3 output: a flat functions array containing every function, regardless of quadrant. The default triage-first structure groups functions into fire, debt, watch, and ok buckets. Use --all-functions when consuming output in tooling or AI agents that prefer a flat list.
See JSON Schema Reference for the v3 schema.
Examples
Basic analysis (text output):
hotspots analyze src/JSON output for CI:
hotspots analyze src/ --format json --min-lrs 5.0 > analysis.jsonSnapshot with HTML report:
hotspots analyze src/ --mode snapshot --format html
# Opens .hotspots/report.htmlDelta with policy enforcement:
hotspots analyze src/ --mode delta --policy --format text
# Exit code 1 if blocking failures detectedPR mode (automatic in CI):
# In GitHub Actions with PR context
hotspots analyze src/ --mode delta --policy --format json
# Compares vs merge-base automaticallyOverride config settings:
hotspots analyze src/ --config .hotspots.ci.json --min-lrs 6.0 --top 50File-level risk view:
hotspots analyze . --mode snapshot --format text --level file
hotspots analyze . --mode snapshot --format text --level file --top 20Module instability view:
hotspots analyze . --mode snapshot --format text --level moduleHuman-readable per-function explanations with co-change section:
hotspots analyze . --mode snapshot --format text --explainSnapshot without persisting (read-only inspection):
hotspots analyze . --mode snapshot --no-persist --format jsonPattern trigger details:
# Show what triggered each pattern (text)
hotspots analyze src/ --explain-patterns
# Pattern details in JSON for tooling
hotspots analyze src/ --mode snapshot --format json --explain-patternshotspots prune
Prune unreachable snapshots to reduce storage.
Usage
# Prune unreachable snapshots
hotspots prune --unreachable
# Dry-run (preview what would be deleted)
hotspots prune --unreachable --dry-run
# Prune only snapshots older than 30 days
hotspots prune --unreachable --older-than 30Options
--unreachable
Required. Must be explicitly specified to confirm pruning.
Safety: Prevents accidental data loss.
--older-than <days>
Optional. Only prune snapshots older than N days.
# Keep recent history, prune old unreachable snapshots
hotspots prune --unreachable --older-than 90--dry-run
Optional. Preview pruning without deleting.
# See what would be pruned
hotspots prune --unreachable --dry-runOutput
Pruned 15 snapshots
Pruned commit SHAs:
abc123...
def456...
...
Reachable snapshots: 42
Unreachable snapshots kept (due to age filter): 8How Pruning Works
- Find repository root (searches up for
.git) - Identify reachable commits via
refs/heads/*(local branches) - Mark unreachable snapshots for deletion
- Apply age filter (if
--older-thanspecified) - Delete snapshot files from
.hotspots/snapshots/ - Update index (
.hotspots/index.json)
Note: Only prunes unreachable snapshots. Reachable history is preserved.
hotspots compact
Compact snapshot history to reduce storage.
Usage
# Set compaction level
hotspots compact --level 0Options
--level <N>
Required. Compaction level: 0, 1, or 2.
Levels:
- Level 0: Full snapshots (current implementation)
- Level 1: Deltas only (planned)
- Level 2: Band transitions only (planned)
Note: Levels 1 and 2 are not yet implemented. Command only sets metadata.
Output
Compaction level set to 0 (was 0)hotspots trends
Analyze complexity trends from snapshot history.
Usage
# Analyze trends (last 10 snapshots, top 5 functions)
hotspots trends .
# Custom window and top-K
hotspots trends . --window 20 --top 10
# JSON output
hotspots trends . --format json > trends.jsonOptions
<path>
Required. Path to repository root.
--format <format>
Optional. Output format: text, json, jsonl, or html. Default: json
hotspots trends . --format text
hotspots trends . --format html--window <N>
Optional. Number of snapshots to analyze. Default: 10
# Analyze last 20 snapshots
hotspots trends . --window 20--top <K>
Optional. Top K functions for hotspot analysis. Default: 5
# Track top 10 hotspots
hotspots trends . --top 10Output (Text Format)
Trends Analysis
================================================================================
Risk Velocities:
Function Velocity Direction First LRS Last LRS
----------------------------------------------------------------------------------------------------
processOrder 0.50 positive 3.50 5.50
validateInput -0.20 negative 4.20 3.00
Hotspot Stability:
Function Stability Overlap Appearances
----------------------------------------------------------------------------------------
processPayment stable 0.90 9/10
handleError emerging 0.60 6/10
Refactor Effectiveness:
Function Outcome Improvement Sustained
----------------------------------------------------------------------------------------
refactoredFunction successful -2.50 5
Summary:
Risk velocities: 15
Hotspots analyzed: 8
Refactors detected: 3Metrics Explained
Risk Velocity:
- LRS change per snapshot
- Positive: increasing complexity
- Negative: decreasing complexity
- Flat: stable
Hotspot Stability:
- Stable: consistently in top-K (>80% overlap)
- Emerging: recently entered top-K (60-80% overlap)
- Volatile: intermittently in top-K (<60% overlap)
Refactor Effectiveness:
- Successful: sustained LRS reduction (>3 commits)
- Partial: temporary improvement (1-2 commits)
- Cosmetic: no sustained improvement
hotspots config validate
Validate configuration file without running analysis.
Usage
# Validate auto-discovered config
hotspots config validate
# Validate specific config file
hotspots config validate --path custom-config.jsonOptions
--path <path>
Optional. Path to config file. Default: Auto-discover from current directory.
Output
Valid config:
Config valid: .hotspotsrc.jsonNo config found:
No config file found. Using defaults.Invalid config:
Config validation failed: thresholds.moderate (6.0) must be less than thresholds.high (5.0)Exit code 1 on validation failure.
hotspots config show
Show resolved configuration (merged defaults + config file).
Usage
# Show resolved config
hotspots config show
# Show specific config file
hotspots config show --path .hotspots.ci.jsonOptions
--path <path>
Optional. Path to config file. Default: Auto-discover from current directory.
Output
Configuration:
Source: .hotspotsrc.json
Weights:
cc: 1.0
nd: 0.8
fo: 0.6
ns: 0.7
Thresholds:
moderate: 3.0
high: 6.0
critical: 9.0
Filters:
min_lrs: 3.0
top: 50
include: all files
exclude: active (custom patterns)hotspots init
Print hook templates for CI/CD integration.
Usage
# Print pre-commit and shell hook templates
hotspots init --hooksOptions
--hooks
Required to produce output. Prints two hook templates to stdout:
- Option 1 — pre-commit framework (
.pre-commit-config.yamlsnippet) - Option 2 — raw shell hook (standalone
#!/usr/bin/env shscript for.git/hooks/pre-push)
If --hooks is not specified, prints a usage hint and exits successfully.
Setup
Delta mode requires a baseline snapshot to compare against. Seed one before enabling the hook:
# 1. Seed the baseline
hotspots analyze . --mode snapshot
# 2. Print and copy the hook template
hotspots init --hooks
# 3a. pre-commit framework: append the YAML block to .pre-commit-config.yaml
# then install with: pre-commit install --hook-type pre-push
# 3b. Raw shell hook: save the sh block (starting with #!/usr/bin/env sh)
# as .git/hooks/pre-push and run: chmod +x .git/hooks/pre-pushExample Output
# ── SETUP (run once before enabling the hook) ─────────────────────
# Seed the baseline first:
#
# hotspots analyze . --mode snapshot
# ── Option 1: pre-commit framework ───────────────────────────────────
# Add the following to .pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: hotspots
name: hotspots risk check
language: system
entry: hotspots analyze . --mode delta --policy --format text
pass_filenames: false
stages: [pre-push]
# ── Option 2: raw shell hook ─────────────────────────────────────────
# Save the lines below (starting with the shebang) as .git/hooks/pre-push
# and run: chmod +x .git/hooks/pre-push
#!/usr/bin/env sh
set -e
hotspots analyze . --mode delta --policy --format textBoth hooks run --mode delta --policy on push and exit non-zero if blocking policy violations are found.
hotspots diff
Compare analysis snapshots between any two git refs. Both refs must have existing snapshots (created with hotspots analyze --mode snapshot).
Usage
hotspots diff <base> <head> [OPTIONS]Arguments
| Argument | Description |
|---|---|
<base> | Base git ref (branch, tag, SHA, or HEAD~N) |
<head> | Head git ref (branch, tag, SHA, or HEAD~N) |
Options
| Flag | Description |
|---|---|
--format <format> | Output format: text (default), json, jsonl, html |
--output <path> | Write output to file instead of stdout (HTML default: .hotspots/delta-report.html) |
--policy | Evaluate policy rules; exit 1 on blocking failures |
--top <N> | Limit output to top N changed functions by risk magnitude |
--config <path> | Path to config file (default: auto-discover) |
--auto-analyze | Analyze missing refs automatically using git worktrees (not yet implemented) |
Exit Codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Blocking policy failure (--policy only) |
3 | One or both snapshots missing |
Examples
# Compare current branch against main
hotspots diff main HEAD
# Compare two release tags
hotspots diff v1.0.0 v2.0.0
# Top 10 changed functions with policy check
hotspots diff main HEAD --top 10 --policy
# JSON output for scripting
hotspots diff main HEAD --format json
# HTML report written to file
hotspots diff main HEAD --format html --output reports/delta.htmlNotes
--toptruncation happens after policy evaluation, so violations outside the top N are still detected.- Annotated tags are peeled to the underlying commit SHA before snapshot lookup.
- Use
hotspots analyze --mode snapshotto create snapshots for refs that don't have one yet.
Exit Codes
| Code | Meaning |
|---|---|
0 | Success (or warnings only) |
1 | Error or blocking policy failure |
3 | Snapshot missing (hotspots diff only) |
Policy Evaluation:
- Exit code
0if only warnings (watch, attention, rapid growth) - Exit code
1if blocking failures (regressions, band transitions)
Configuration Priority
CLI flags override config file values:
- CLI flags (highest priority)
- Config file (
.hotspotsrc.json, etc.) - Defaults (lowest priority)
# Config file says min_lrs: 3.0, CLI overrides to 5.0
hotspots analyze src/ --min-lrs 5.0See Configuration for details.
Environment Variables
Hotspots respects git environment variables for repository operations:
GIT_DIR- Override.gitdirectory locationGIT_WORK_TREE- Override working directory
CI/CD Detection (PR mode):
GITHUB_EVENT_NAME=pull_request- GitHub Actions PRCI_MERGE_REQUEST_IID- GitLab MRCIRCLE_PULL_REQUEST- CircleCI PRTRAVIS_PULL_REQUEST- Travis CI PR
When PR context is detected, delta mode compares vs merge-base instead of direct parent.
Common Workflows
Local Development
# Quick complexity check
hotspots analyze src/ --top 20
# Detailed analysis with filtering
hotspots analyze src/ --min-lrs 5.0 --format json | jq .CI/CD Integration
GitHub Actions:
- name: Complexity Analysis
run: hotspots analyze src/ --mode delta --policy --format jsonWith config file:
- name: Complexity Analysis
run: hotspots analyze src/ --config .hotspots.ci.json --mode delta --policySee CI Integration for complete examples.
Snapshot Management
# Capture baseline snapshot
hotspots analyze src/ --mode snapshot --format json > baseline.json
# Prune old snapshots (keep 30 days)
hotspots prune --unreachable --older-than 30 --dry-run
hotspots prune --unreachable --older-than 30
# Analyze trends
hotspots trends . --window 20 --format textDebugging
# Validate configuration
hotspots config validate
# Show resolved config (check what's active)
hotspots config show
# Test with dry-run
hotspots analyze src/ --format json --dry-run # (if supported)Troubleshooting
"Path does not exist"
Cause: Invalid path argument.
Fix: Verify path exists:
ls -la src/
hotspots analyze src/"not in a git repository"
Cause: Snapshot/delta mode requires git repository.
Fix: Initialize git or use basic analysis:
git init
# OR
hotspots analyze src/ --format json # (no --mode flag)"--policy flag is only valid with --mode delta"
Cause: Using --policy without --mode delta.
Fix:
hotspots analyze src/ --mode delta --policy"HTML format requires --mode snapshot or --mode delta"
Cause: Using --format html without --mode.
Fix:
hotspots analyze src/ --format html --mode snapshot"SARIF format requires --mode snapshot"
Cause: Using --format sarif without --mode snapshot.
Fix:
hotspots analyze . --mode snapshot --format sarif"Config validation failed"
Cause: Invalid configuration file.
Fix: Validate and fix config:
hotspots config validate
# Read error message, fix config file
cat .hotspotsrc.json | jq . # Check JSON syntax"unreachable flag must be specified"
Cause: Safety check for prune command.
Fix:
hotspots prune --unreachable"text format without --explain is not supported for snapshot mode"
Cause: Using --mode snapshot --format text without --explain or --level.
Fix: Add --explain, --level, or use JSON format:
hotspots analyze . --mode snapshot --format text --explain
hotspots analyze . --mode snapshot --format text --level file
hotspots analyze . --mode snapshot --format json"--level is only valid with --mode snapshot"
Cause: Using --level without --mode snapshot --format text.
Fix:
hotspots analyze . --mode snapshot --format text --level file"--level and --explain are mutually exclusive"
Cause: Both --level and --explain flags specified together.
Fix: Use one or the other:
hotspots analyze . --mode snapshot --format text --level file
# OR
hotspots analyze . --mode snapshot --format text --explain"--no-persist and --force are mutually exclusive"
Cause: Both --no-persist and --force flags specified together.
Fix: Use one or the other:
hotspots analyze . --mode snapshot --no-persist # analyze without saving
hotspots analyze . --mode snapshot --force # overwrite existing snapshotRelated Documentation
- Configuration Guide - Config file format
- CI Integration - GitHub Actions, GitLab CI
- Output Formats - JSON schema, HTML reports
- LRS Specification - How LRS is calculated
- Policy Engine - Policy rules and enforcement