brokenbartender/blast-radius
GitHub: brokenbartender/blast-radius
一款基于 Python AST 的增量调用图分析工具,用于快速查询代码修改的潜在影响范围与依赖关系。
Stars: 1 | Forks: 0
# blast-radius
**如果我更改了这个文件,会影响哪些部分?**
`blast-radius` 会为你的 Python 项目构建一个增量的 AST 调用图,并
瞬间回答这个问题。它将导入和符号定义索引到
SQLite 中(使用 SHA-256 缓存——仅重新索引更改过的文件),并在几毫秒内
解析传递依赖。
```
pip install impact-radius
```
[](https://pypi.org/project/impact-radius/)
[](https://pypi.org/project/impact-radius/)
[](https://www.python.org/)
[](LICENSE)
[](https://github.com/brokenbartender/blast-radius/actions)
## 快速入门
```
# 构建依赖图 (增量构建 — 仅重新索引已更改的文件)
impact-radius --build
# 如果我更改 src/utils.py,会影响哪些地方?
impact-radius --query src/utils.py
# 输出 Mermaid 图表 (可在 GitHub READMEs / PRs 中渲染)
impact-radius --query src/utils.py --mermaid
# Watch 模式 — 每次保存时自动重新构建
impact-radius --watch
# 原始 JSON 输出 (通过管道传递给 jq、脚本、CI)
impact-radius --query src/utils.py --json
```
## 终端输出 (使用 Rich)
```
src/utils.py ⚡ GOD NODE
├── 📄 src/api/routes.py
├── 📄 src/models/user.py
├── 🧪 tests/test_utils.py
└── 🧪 tests/test_api.py
14 file(s) affected · in-degree 47 · 2 test file(s)
```
安装 Rich 以获得彩色输出:
```
pip install impact-radius[rich]
```
## Mermaid 图表 (在 GitHub 中渲染)
```
from blast_radius import build_graph, get_blast_radius, to_mermaid
build_graph()
result = get_blast_radius("src/utils.py")
print(to_mermaid(result))
```
将输出粘贴到任何 GitHub issue、PR 或 README 中:
```
graph TD
utils_py["src/utils.py"]
utils_py --> routes_py["src/api/routes.py"]
utils_py --> user_py["src/models/user.py"]
utils_py --> test_utils_py["tests/test_utils.py"]
style test_utils_py fill:#22c55e,color:#fff
%% total affected: 3 | in-degree: 0
```
## Python API
```
from blast_radius import build_graph, get_blast_radius, to_mermaid, watch
# 构建 import graph (增量构建 — 仅重新索引已更改的文件)
n = build_graph()
print(f"{n} files indexed")
# 查询 blast radius
result = get_blast_radius("src/mymodule.py")
print(result["total_affected"]) # int
print(result["direct_dependents"]) # list of file paths
print(result["test_files"]) # files that start with tests/
# Mermaid 输出
diagram = to_mermaid(result)
# Watch 模式 (阻塞式 — 运行直到 Ctrl+C)
watch(interval=2.0)
```
## 配置
所有路径均可配置——没有硬编码的假设:
```
# 仅扫描特定目录
impact-radius --build --scan src tests
# 使用自定义 DB 路径 (在 CI 中很有用)
impact-radius --build --db /tmp/my-graph.db
# 调整 watch 轮询间隔
impact-radius --watch --interval 1.0
```
或者通过 Python API:
```
from pathlib import Path
build_graph(scan_dirs=["src", "tests"], db_path=Path("/tmp/my-graph.db"))
get_blast_radius("src/utils.py", db_path=Path("/tmp/my-graph.db"))
```
## pytest 插件 — 针对性测试选择
只运行那些实际受到你暂存更改影响的测试:
```
pip install "impact-radius[pytest]"
```
```
# 仅运行位于暂存文件 blast radius 内的测试 (pre-commit 模式)
pytest --blast-radius
# 显式文件
pytest --blast-radius --br-file src/utils.py
# 绕过过滤器 — 运行完整套件 (当 --blast-radius 位于 addopts 中时很有用)
pytest --blast-radius --br-all
```
添加到 `pytest.ini` 或 `pyproject.toml` 中,将针对性测试设为默认设置:
```
[pytest]
addopts = --blast-radius
```
该插件会取消选择任何不在你更改文件影响范围内的测试。
如果未找到暂存文件或图谱不可用,则会安全地回退到完整的测试套件。
## --staged 标志 — 所有更改文件的影响报告
查看你即将提交的所有更改的综合影响范围:
```
impact-radius --build
impact-radius --staged
```
```
Staged (2 file(s)):
src/utils.py
src/models/user.py
Blast radius — 6 file(s) affected:
-> src/api/routes.py
-> src/api/auth.py
-> tests/test_utils.py [TEST]
-> tests/test_api.py [TEST]
-> tests/test_auth.py [TEST]
-> src/cli.py
```
添加 `--json` 以获取机器可读的输出:
```
impact-radius --staged --json | jq '.test_files'
```
## pre-commit 集成
添加到你的 `.pre-commit-config.yaml` 中:
```
repos:
- repo: https://github.com/brokenbartender/blast-radius
rev: v1.1.0
hooks:
# Rebuild the graph whenever Python files change
- id: blast-radius-build
# Show impact report for staged files (informational, never blocks)
- id: blast-radius-staged
```
## GitHub Action — 在 PR 上评论影响范围
```
# .github/workflows/blast-radius.yml
name: Blast Radius
on: [pull_request]
jobs:
blast-radius:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with: {python-version: "3.11"}
- run: pip install impact-radius
- name: Compute blast radius for changed files
id: br
run: |
impact-radius --build
# Get the first changed .py file to query
CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- '*.py' | head -1)
if [ -n "$CHANGED" ]; then
echo "mermaid<> $GITHUB_OUTPUT
impact-radius --query "$CHANGED" --mermaid >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
else
echo "mermaid=No Python files changed." >> $GITHUB_OUTPUT
fi
- uses: marocchino/sticky-pull-request-comment@v2
with:
message: |
## Blast Radius
${{ steps.br.outputs.mermaid }}
```
## Graphify 上帝节点检测 (可选)
如果你安装了 [`graphify`](https://github.com/graphify-io/graphify) 并且
在你的仓库中运行了 `graphify update .`,`blast-radius` 将使用
传递中心性数据丰富结果,并标记 **上帝节点** (被 30 个以上模块导入的文件):
```
result = get_blast_radius("src/core.py")
if result.get("graphify", {}).get("god_node"):
print("WARNING: this is a god node — change it carefully")
```
## 安装说明
```
# Core (无依赖)
pip install impact-radius
# 带 Rich 彩色输出
pip install impact-radius[rich]
# 带 watchdog 文件监控 (比轮询更快)
pip install impact-radius[watch]
# Everything
pip install impact-radius[all]
```
## 已知限制
| 限制 | 影响 | 缓解措施 |
|------------|--------|------------|
| 仅支持静态分析 | 动态导入 (`__import__`, `importlib`) 会被标记,但不会在图谱中进行遍历 | 检查结果中的 `result["dynamic_import_warning"]`;手动验证动态目标 |
| 仅支持 Python | 无跨语言分析 | 在多语言仓库中配合使用特定语言的工具 |
| 未解析导入别名 | `import numpy as np; np.something` 无法解析符号级别的依赖 | 仍会捕获结构性的文件级依赖 |
| 未解析 `__all__` 以进行重新导出 | 通过 `__all__` 重新导出的符号看起来像死胡同 | 按照约定,将重新导出文件视为高影响范围 |
| 无运行时导入分析 | 条件导入 (`if TYPE_CHECKING`) 被计为实时依赖 | 使用 `--type-checking-only` 标志 (计划中) 进行过滤 |
## 对比:impact-radius 与替代方案
| 功能 | impact-radius | `pydeps` | `importlab` | `modulegraph` |
|---------|--------------|---------|------------|--------------|
| 传递影响范围查询 | 是 | 否 | 部分 | 否 |
| 增量 SQLite 缓存 | 是 (SHA-256) | 否 | 否 | 否 |
| 上帝节点检测 | 是 | 否 | 否 | 否 |
| Mermaid 图表输出 | 是 | 否 | 否 | 否 |
| 文件监视模式 | 是 | 否 | 否 | 否 |
| 动态导入检测 | 是 (已标记) | 否 | 部分 | 否 |
| CLI + Python API | 两者皆有 | 仅 CLI | 仅 Python | 仅 Python |
| 安装大小 | 最小 | 中等 | 最小 | 中等 |
## 性能
| 项目大小 | 索引构建 | 影响范围查询 |
|---|---|---|
| 50 个文件 | ~0.3s | <1ms |
| 500 个文件 | ~2s | <5ms |
| 5,000 个文件 | ~18s | <20ms |
在初次构建之后,增量重新索引仅处理更改过的文件。
查询时间与项目大小无关——SQLite 索引查找的时间复杂度为 O(log n)。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
由 [Broken Arrow Entertainment LLC](https://lexipro.online) 构建 · Sovereign Intelligence Systems Group
## OS 集成 — 上帝节点门控
`blast-radius` 接入编辑前的安全门控,在任何
智能体接触高中心性文件之前强制执行硬停止。这是在
[LexiPro Sovereign OS](https://lexipro.online) 中使用的 v9.6 集成模式:
```
# tool_hook_pipeline.py — _hook_guardian_path_guard (v9.6)
from blast_radius import get_blast_radius, rebuild_if_stale
async def pre_edit_gate(file_path: str) -> dict:
rebuild_if_stale(max_age_seconds=300)
br = get_blast_radius(file_path)
# Hard block — god-node writes require explicit mutex acquisition
if br.get("graphify", {}).get("god_node"):
in_deg = br["graphify"]["in_degree_sum"]
return {
"allowed": False,
"error": (
f"GOD_NODE_PROTECTED: {file_path} has in_degree_sum={in_deg}. "
f"Acquire hard mutex before editing god-node files."
),
}
# High blast radius — warn + emit contention pheromone
if br["total_affected"] >= 10:
emit_contention_pheromone(file_path, strength=br["total_affected"] / 50.0)
return {"allowed": True, "warning": f"{br['total_affected']} dependents affected"}
```
**上帝节点阈值:** 具有 `in_degree_sum >= 30` 的文件(通过 Graphify)在执行任何写入之前需要获取显式互斥锁。在没有 Graphify 的情况下,当 `total_affected >= 10` 时,门控仍会发出警告。
**信息素广播:** 高影响范围的编辑会向 NeuralBus 发出 `WRITE_CONTENTION` 信号,以便其他智能体能够观察到争议资源,并可以推迟非关键的写入操作。
在你的仓库根目录中运行 `graphify update .` 以生成 `graphify-out/graph.json` 并启用上帝节点检测。
标签:Mermaid, odt, Python, SOC Prime, SQLite, WebSocket, 云安全监控, 代码分析, 代码审查, 代码维护, 依赖关系图, 依赖分析, 凭证管理, 增量索引, 安全规则引擎, 开发工具, 影响范围分析, 抽象语法树, 无后门, 自动化payload嵌入, 调用图, 逆向工具, 重构, 静态分析