Metadata-Version: 2.4
Name: deprisker
Version: 0.1.0
Summary: Find which files will hurt the most when they break — dependency risk analysis for any codebase.
Project-URL: Homepage, https://github.com/pratik-sonigra/deprisker
Project-URL: Repository, https://github.com/pratik-sonigra/deprisker
Project-URL: Bug Tracker, https://github.com/pratik-sonigra/deprisker/issues
Author-email: Pratik Sonigra <pratik.s@dashtechinc.com>
License: MIT
Keywords: code-quality,dependency,devtools,graph,mcp,refactoring,risk,static-analysis
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.9
Requires-Dist: click>=8.0
Requires-Dist: fastmcp>=2.0
Requires-Dist: networkx>=3.0
Description-Content-Type: text/markdown

# deprisker

**Find which files will hurt the most when they break.**

`deprisker` builds a directed dependency graph from your codebase and scores every module by its blast radius — how many other modules would break if it did. It surfaces this as a terminal report, a self-contained interactive HTML visualization, and a structured JSON output for CI pipelines and AI agents.

---

## Why this exists

Every codebase has files that, if incorrectly modified, cascade failures across a disproportionate number of other modules. These high-risk files are not obvious from reading the code. A large file is not necessarily risky. A heavily tested file is not necessarily safe. What actually determines blast radius is **structural position in the dependency graph** — how many other modules depend on it, whether it bridges otherwise disconnected parts of the system, and whether it participates in circular dependency chains.

`deprisker` answers the question _"which file should I be most careful editing?"_ before a refactor, release, or code review — in under 10 seconds, with no configuration required.

---

## Features

- **Zero configuration** — point at a directory, get results
- **Multi-language** — Python, JavaScript/TypeScript, Go, Rust, Ruby, and Java
- **Graph-theoretic scoring** — risk is computed from in-degree, betweenness centrality, lines of code, and cycle participation; not heuristics
- **Interactive HTML report** — force-directed dependency graph, bar chart of top risks, sortable table; all in a single self-contained file with no server required
- **CI-ready** — `--fail-on-high` and `--fail-on <score>` flags for pipeline integration
- **MCP server** — expose analysis as queryable tools for Claude and other AI agents
- **Structured JSON** — `--json` flag for agent pipelines and custom tooling
- **No LLM required** — purely deterministic static analysis

---

## Installation

```bash
pip install deprisker
```

Requires Python 3.9+.

---

## Quick start

```bash
# Analyze the current directory
deprisker analyze .

# Analyze a specific project
deprisker analyze ~/projects/myapp

# Top 5 only, skip the HTML report
deprisker analyze . --top 5 --no-html

# Save the HTML report to a custom path
deprisker analyze . --output reports/risk.html
```

Sample terminal output:

```
  deprisker  |  analyzing /home/user/myapp

  Files scanned : 42
  Import edges  : 87
  Cycles found  : 2
  High risk     : 3
  Medium risk   : 11
  Low risk      : 28

  -- Top 10 riskiest modules ------------------------------------------
   1. [HIGH  ]  ################....   74.3  src/auth/middleware.py
   2. [HIGH  ]  ##############......   68.1  src/db/connection.py
   3. [HIGH  ]  #############.......   62.7  src/core/router.py
   4. [MEDIUM]  ########............   41.2  src/utils/logger.py
   5. [MEDIUM]  #######.............   37.8  src/models/user.py

  HTML report saved -> /home/user/myapp/deprisker_report.html
```

---

## CLI reference

```
deprisker analyze [PATH] [OPTIONS]
```

`PATH` defaults to `.` if not provided.

| Flag | Short | Description |
|---|---|---|
| `--output PATH` | `-o` | Output path for the HTML report (default: `deprisker_report.html`) |
| `--top N` | `-t` | Number of top-risk files to print (default: 10) |
| `--json` | `-j` | Print JSON to stdout, suppress all other output |
| `--no-html` | | Skip writing the HTML report |
| `--threshold FLOAT` | | Report only files with score ≥ threshold |
| `--fail-on-high` | | Exit code 1 if any HIGH risk modules exist |
| `--fail-on FLOAT` | | Exit code 1 if any module score ≥ this value |
| `--include TEXT` | | Comma-separated path prefixes to include only |
| `--exclude TEXT` | | Comma-separated path prefixes to exclude |
| `--version` | `-v` | Print version and exit |

**Exit codes:** `0` = success · `1` = threshold violated · `2` = input error · `3` = output error · `4` = invalid arguments

---

## HTML report

The generated report is a single `.html` file that works offline. It contains:

- **Force-directed graph** — nodes sized by risk score, colored by risk level (red/amber/green), with zoom, pan, drag, and hover tooltips showing full risk breakdown
- **Bar chart** — top 10 modules ranked by score
- **Sortable table** — all modules with score, risk level, and dependent count; clicking a row highlights the node in the graph

No web server required. The file can be committed to the repo, shared with the team, or attached to a pull request.

---

## Python API

```python
from deprisker import analyze, render_html

report = analyze("./my-project")

# Summary statistics
print(report.summary)
# {'total_files': 42, 'total_edges': 87, 'cyclic_dependencies': 2,
#  'high_risk_count': 3, 'medium_risk_count': 11, 'low_risk_count': 28, ...}

# Top riskiest files
for path, score in report.top_risks[:5]:
    node = report.nodes[path]
    print(f"{score:.1f}  [{node.risk_level}]  {path}")
    print(f"       dependents={node.risk_factors['dependents']}, "
          f"in_cycle={node.risk_factors['in_cycle']}")

# All circular dependency chains
for cycle in report.cycles:
    print(" -> ".join(cycle) + " -> ...")

# Write the HTML report
out = render_html(report, "risk_report.html")
print(f"Report saved to {out}")
```

---

## CI integration

Fail a build if any HIGH risk module is present in the changed files:

```yaml
# .github/workflows/risk-check.yml
- name: Install deprisker
  run: pip install deprisker

- name: Check dependency risk
  run: deprisker analyze . --no-html --fail-on-high
```

Fail if any module score exceeds a custom threshold:

```bash
deprisker analyze . --no-html --fail-on 70
```

Use JSON output for custom logic:

```python
import json, subprocess, sys

result = subprocess.run(
    ["deprisker", "analyze", ".", "--json"],
    capture_output=True, text=True
)
data = json.loads(result.stdout)

high_risk = [m for m in data["modules"] if m["risk_level"] == "HIGH"]
if high_risk:
    print(f"ERROR: {len(high_risk)} HIGH risk modules")
    sys.exit(1)
```

---

## MCP server

`deprisker` exposes its analysis as an MCP server, allowing Claude and other AI agents to query dependency risk data without running the CLI.

```bash
deprisker mcp                              # stdio transport (for Claude Desktop)
deprisker mcp --transport http --port 8080 # HTTP transport
```

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "deprisker": {
      "command": "deprisker",
      "args": ["mcp"]
    }
  }
}
```

Available tools:

| Tool | Description |
|---|---|
| `analyze_project` | Analyze a directory, cache the result |
| `get_top_risks` | Return the N riskiest modules, with optional level/language filter |
| `get_module_risk` | Full risk breakdown for a specific file |
| `get_dependents` | Direct and transitive dependents of a module |
| `get_cycles` | All circular dependency chains |
| `check_blast_radius` | Given a list of files (e.g. a PR diff), compute total affected modules |
| `generate_report` | Write an HTML report to disk |

---

## Risk scoring

Each module is scored 0–100 using four weighted graph metrics:

| Metric | Weight | What it measures |
|---|---|---|
| In-degree | 35 | How many other modules import this one — the primary blast radius signal |
| Betweenness centrality | 30 | How often this module is the bridge between others — breaking it disconnects the graph |
| Lines of code | 15 | Surface area for bugs; larger files are harder to change safely |
| Cycle participation | 20 | Flat penalty for being in a circular dependency — changes ripple unpredictably |

**Risk levels:**
- `HIGH` — score ≥ 60. A bug here cascades widely.
- `MEDIUM` — score 30–59. Changes warrant extra review.
- `LOW` — score < 30. Relatively safe to modify independently.

All weights and thresholds are configurable via the Python API:

```python
from deprisker import analyze
from deprisker.config import Config

cfg = Config(
    weight_in_degree=40,
    weight_betweenness=25,
    weight_loc=15,
    weight_cycle=20,
    high_threshold=65.0,
)
report = analyze(".", config=cfg)
```

---

## Language support

| Language | Extensions | Import strategy |
|---|---|---|
| Python | `.py` | AST-based (`ast` module) |
| JavaScript / TypeScript | `.js` `.ts` `.jsx` `.tsx` `.mjs` `.cjs` | Regex — ESM imports and `require()` |
| Go | `.go` | Regex — single and block imports; `go.mod`-aware |
| Rust | `.rs` | Regex — `use crate::`, `use super::`, `mod name;` |
| Ruby | `.rb` | Regex — `require_relative` and `require` |
| Java | `.java` | Regex — fully-qualified imports; base package auto-detected |

---

## License

MIT
