codeblast 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 codeblast contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ <p align="center">
2
+ <img src="assets/readme/hero.svg" width="100%" alt="codeblast — deterministic code graph: know what breaks before you merge"/>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <b>English</b> | <a href="README.zh-CN.md">简体中文</a>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="#the-three-queries"><img src="https://img.shields.io/badge/TypeScript-function--level-3178c6?style=flat-square" alt="TypeScript function-level"/></a>
11
+ <a href="#the-precision-promise-bounded-and-evidence-backed"><img src="https://img.shields.io/badge/recall-28%2F28_%3D_100%25-3fb950?style=flat-square" alt="mutation-tested recall 100%"/></a>
12
+ <a href="SKILL.md"><img src="https://img.shields.io/badge/Agent-Skill-7c3aed?style=flat-square" alt="agent skill"/></a>
13
+ <img src="https://img.shields.io/badge/license-MIT-8b949e?style=flat-square" alt="MIT"/>
14
+ </p>
15
+
16
+ **codeblast parses your repository into a deterministic code graph and answers the three most expensive questions around any code change:**
17
+ > 🔗 **[Live interactive demo](https://alloevil.github.io/codeblast/)** — real architecture maps of tRPC / Tabby / sgp, with three-level drill-down
18
+
19
+ | | Question | Command |
20
+ |---|---|---|
21
+ | 🎯 | **What breaks if I change this?** | `impact` — direct / transitive / affected-tests, in three tiers |
22
+ | 🔍 | **What did this PR structurally change?** | `change` — symbols and dependency edges added, removed, renamed |
23
+ | 🗺️ | **What does this project look like?** | `archmap` — collapsible module map + circular-dependency detection |
24
+
25
+ Built for humans (CLI / interactive HTML / PR comments) and for AI agents ([SKILL.md](SKILL.md)) — one graph, two front-ends.
26
+ <table>
27
+ <tr>
28
+ <td width="50%">
29
+ <a href="https://alloevil.github.io/codeblast/trpc-impact-demo.html">
30
+ <img src="assets/readme/impact-overlay.png" alt="Impact blast radius painted on the tRPC architecture map: red = direct callers, amber = affected tests, purple = transitive"/>
31
+ </a>
32
+ <p align="center"><sub><b>Impact overlay</b> — blast radius on the map (tRPC · <a href="https://alloevil.github.io/codeblast/trpc-impact-demo.html">live ↗</a>)</sub></p>
33
+ </td>
34
+ <td width="50%">
35
+ <a href="https://alloevil.github.io/codeblast/tabby-arch.html">
36
+ <img src="assets/readme/arch-hover.png" alt="Tabby architecture map with hover highlighting: all edges into tabby-core lit up"/>
37
+ </a>
38
+ <p align="center"><sub><b>Architecture map</b> — hover lights the dependency fan-in (Tabby, 60k★ · <a href="https://alloevil.github.io/codeblast/tabby-arch.html">live ↗</a>)</sub></p>
39
+ </td>
40
+ </tr>
41
+ </table>
42
+
43
+ ```bash
44
+ npx codeblast demo # build a graph of the current repo, run one impact query, emit the map
45
+ npm i -g codeblast # or install globally; needs Node ≥ 22.13 (built-in sqlite) or Bun
46
+
47
+ # Install as an agent skill (Claude Code, Codex, Cursor, and 14 more harnesses)
48
+ npx skills add alloevil/codeblast
49
+ ```
50
+
51
+ ## Why not yet another LLM diagram tool
52
+
53
+ ```
54
+ LLM diagrams: code → model reads it → hand-drawn graph → render graph = the model's opinion, unverifiable
55
+ codeblast: code → deterministic tsc/AST parse → graph → project graph = checkable facts
56
+ ```
57
+
58
+ **Every node, every edge, every claim carries `file:line` evidence** you can open and verify.
59
+ The LLM does exactly one job in the pipeline: giving modules human-readable names — node membership and edges always come from static analysis.
60
+
61
+ ## The three queries
62
+
63
+ ```bash
64
+ # Build the graph: auto-detects TS monorepos / Python, hash-based incremental updates
65
+ # (full build of tRPC, 950 files, in ~20s)
66
+ codeblast index <repo> --db graph.db
67
+
68
+ # ① Impact — check the blast radius before you change anything
69
+ codeblast impact graph.db "createOrder" --json
70
+ # → direct list = callsites you must review; tests list = tests you must run
71
+ # → two channels: call-graph reachable (precision ~0.70, read first)
72
+ # + import reachable (conservative supplement, don't skip)
73
+
74
+ # ② Change Map — structural diff between two refs
75
+ codeblast change <repo> main~5 main --json
76
+ # → unexpected edges_added = a signal the change is out of scope
77
+
78
+ # ③ Architecture Map — interactive HTML: module → file → symbol drill-down,
79
+ # symbols link to source lines
80
+ codeblast archmap graph.db --out arch.html --repo-url <github-url>
81
+
82
+ # Optional: mine git co-change coupling (protocol pairs, config + consumers —
83
+ # edges static analysis can't see)
84
+ codeblast cochange <repo> graph.db
85
+ ```
86
+
87
+ ### PR bot (runs in CI, stays quiet by default)
88
+
89
+ Copy [`.github/workflows-template/codeblast.yml`](.github/workflows-template/codeblast.yml) into your repo (it runs `npx codeblast pr-comment`, no other setup):
90
+ every PR gets an automatic comment with structural changes + blast radius + new symbols with no test coverage; **PRs with no structural change get zero comments**.
91
+ Replayed against 50 real commits: 42 correctly stayed silent, 87.5% of comments were useful.
92
+
93
+ ## The precision promise (bounded, and evidence-backed)
94
+
95
+ - **TypeScript at function level: zero missed impact within statically analyzable scope.** Verified by mutation testing:
96
+ inject mutations into a real repo → run the full test suite to get the ground-truth impact set → compare against predictions.
97
+ Current benchmark (tRPC, 950 files): **28/28 mutations, 100% recall**, average precision 0.36 — favoring
98
+ false positives over false negatives is a deliberate trade: in a controlled experiment, dropping the conservative edges
99
+ raises precision to 0.70 but recall collapses to 14%. Data lives in [`eval/`](eval/).
100
+ - **Blind spots are explicitly flagged.** A blind spot is any call or import that static analysis cannot resolve to an in-repo target — dynamic calls, unresolved calls, failed external-dependency resolution, subprocess boundaries, test-framework globals — not just dynamic calls; each is recorded in `blind_spots` with an "impact may be underestimated" warning, never silently dropped.
101
+ - **Python is file-level.** Dynamic typing makes function-level zero-miss guarantees impossible in principle, and we don't pretend otherwise.
102
+
103
+ ## For AI agents
104
+
105
+ ```
106
+ before editing: impact "symbol" --json → callsite list into context, so nothing gets missed
107
+ after editing: change HEAD~1 HEAD --json → self-check for scope creep and accidental deletions
108
+ ```
109
+
110
+ The full contract and interpretation discipline (including "never pretend the blind-spot list is complete") is in [SKILL.md](SKILL.md).
111
+ Agent conventions: [AGENTS.md](AGENTS.md).
112
+
113
+ ## Status & roadmap
114
+
115
+ M0 graph engine → M1 Impact → M3 architecture map → M4 graph diff + PR bot → M5 precision extensions — **all milestones accepted** (each with a reproducible acceptance script). Single source of truth for design and acceptance criteria: [intent.md](intent.md).
116
+
117
+ MIT © 2026
@@ -0,0 +1,89 @@
1
+ <p align="center">
2
+ <img src="assets/readme/hero.svg" width="100%" alt="codeblast — deterministic code graph: know what breaks before you merge"/>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="README.md">English</a> | <b>简体中文</b>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="#三个查询"><img src="https://img.shields.io/badge/TypeScript-函数级-3178c6?style=flat-square" alt="TypeScript function-level"/></a>
11
+ <a href="#精度承诺有边界有证据"><img src="https://img.shields.io/badge/recall-28%2F28_%3D_100%25-3fb950?style=flat-square" alt="mutation-tested recall 100%"/></a>
12
+ <a href="SKILL.md"><img src="https://img.shields.io/badge/Agent-Skill-7c3aed?style=flat-square" alt="agent skill"/></a>
13
+ <img src="https://img.shields.io/badge/license-MIT-8b949e?style=flat-square" alt="MIT"/>
14
+ </p>
15
+
16
+ **codeblast 把仓库解析成一份确定性代码图谱,回答改代码前后最贵的三个问题:**
17
+ > 🔗 **[在线交互演示](https://alloevil.github.io/codeblast/)** — tRPC / Tabby / sgp 的实时架构图,点开即可三层下钻
18
+
19
+ | | 问题 | 命令 |
20
+ |---|---|---|
21
+ | 🎯 | **改这个会炸哪里?** | `impact` — 直接/传递/受影响测试三级清单 |
22
+ | 🔍 | **这个 PR 在结构上改了什么?** | `change` — 符号与依赖边的增删/重命名 |
23
+ | 🗺️ | **这个项目长什么样?** | `archmap` — 模块折叠图 + 循环依赖检测 |
24
+
25
+ 给人看(CLI / 交互 HTML / PR 评论),也给 AI agent 用([SKILL.md](SKILL.md))——同一份图谱,两个出口。
26
+
27
+ ## 为什么不是又一个 LLM 画图工具
28
+
29
+ ```
30
+ LLM 画图: 代码 → 模型阅读理解 → 手写图 → 渲染 图 = 模型的观点,无法核对
31
+ codeblast: 代码 → tsc/AST 确定性解析 → 图谱 → 投影 图 = 可验证的事实
32
+ ```
33
+
34
+ **每个节点、每条边、每句结论都带 `file:line` 证据**,可直接打开核对。
35
+ LLM 在管线里只做一件事:给模块起人话名字——节点归属和边永远来自静态分析。
36
+
37
+ ## 三个查询
38
+
39
+ ```bash
40
+ # 建图:TS monorepo / Python 自动识别,hash 增量更新(tRPC 950 文件全量 ~20s)
41
+ codeblast index <repo> --db graph.db
42
+
43
+ # ① Impact —— 改动前查影响半径
44
+ codeblast impact graph.db "createOrder" --json
45
+ # → direct 清单 = 必须检查的 callsite;tests 清单 = 必须跑的测试
46
+ # → 双通道:调用链可达(精确率 ~0.70,优先看)+ import 可达(保守补充,勿跳过)
47
+
48
+ # ② Change Map —— 两个 ref 之间的结构 diff
49
+ codeblast change <repo> main~5 main --json
50
+ # → 意料之外的 edges_added = 改动越界信号
51
+
52
+ # ③ Architecture Map —— 交互 HTML:模块→文件→符号三层下钻,符号跳源码行
53
+ codeblast archmap graph.db --out arch.html --repo-url <github-url>
54
+
55
+ # 可选:git 历史耦合挖掘(协议两端、配置与消费者——静态分析看不见的边)
56
+ codeblast cochange <repo> graph.db
57
+ ```
58
+
59
+ ### PR bot(CI 内跑,宁静默不刷屏)
60
+
61
+ 复制 [`.github/workflows-template/codeblast.yml`](.github/workflows-template/codeblast.yml) 到目标仓库:
62
+ 每个 PR 自动评论结构变化 + 影响半径 + 无测试覆盖的新增符号;**无结构变化的 PR 零评论**。
63
+ 50 个真实提交回放:42 个正确静默、评论有效率 87.5%。
64
+
65
+ ## 精度承诺(有边界,有证据)
66
+
67
+ - **TypeScript 函数级,静态可分析范围内零漏报。** 验收方法:变异测试对照
68
+ (真实仓库注入变异 → 全量测试得真实影响集 → 对比预测)。当前基准(tRPC,950 文件):
69
+ **28/28 变异召回率 100%**,平均精确率 0.36——宁误报不漏报是刻意交换:
70
+ 对照实验中砍掉保守边可将精确率提到 0.70,但召回率跌至 14%。数据在 [`eval/`](eval/)。
71
+ - **盲区显式标注。** 盲区 = 静态无法解析到仓内目标的调用/导入(含动态调用、未解析调用、外部依赖解析失败、子进程边界、测试框架全局),并非只有动态调用;
72
+ 一律记入 blind_spots 并提示"影响可能被低估",绝不静默丢弃。
73
+ - **Python 为文件级。** 动态类型使函数级零漏报原理性不成立,不假装做到。
74
+
75
+ ## 给 AI Agent 用
76
+
77
+ ```
78
+ 改前: impact "symbol" --json → callsite 清单进上下文,防漏改
79
+ 改后: change HEAD~1 HEAD --json → 自查结构越界与意外删除
80
+ ```
81
+
82
+ 完整契约与解读纪律(含"禁止假装盲区清单完整")见 [SKILL.md](SKILL.md)。
83
+ Agent 规范另见 [AGENTS.md](AGENTS.md)。
84
+
85
+ ## 状态与路线
86
+
87
+ M0 图谱引擎 → M1 Impact → M3 架构图 → M4 图 diff + PR bot → M5 精度扩展,**全部验收通过**(每项含可复现验收脚本)。方案与验收标准的单一事实源:[intent.md](intent.md)。
88
+
89
+ MIT © 2026
package/SKILL.md ADDED
@@ -0,0 +1,155 @@
1
+ ---
2
+ name: codeblast
3
+ description: Deterministic code-graph analysis for TypeScript and Python repositories. Use when the user asks what breaks if I change this, wants an impact analysis or blast radius before editing a symbol, asks for a repository architecture map grounded in real code, or wants to know what structurally changed between two git refs or in a PR. Unlike LLM-drawn diagrams, every node and edge is extracted by compiler-grade static analysis and carries file:line evidence; impact answers are conservative (no false negatives within the static analysis boundary; dynamic blind spots are explicitly reported, never silently dropped).
4
+ ---
5
+
6
+ # codeblast — impact · change · architecture, with evidence on every edge
7
+
8
+ Three deterministic queries over a graph built by `tsc` (TypeScript, function-level) and the
9
+ Python AST (file-level with typed-call upgrades). Every result carries the `file:line` where the
10
+ dependency actually occurs. The graph comes from the code, not from a model's reading of it.
11
+
12
+ ## When to run it
13
+
14
+ | Situation | Command | What you get back |
15
+ |---|---|---|
16
+ | About to edit an exported symbol | `codeblast impact <db> "<symbol>" --json` | The callsites you must review and the tests you must run |
17
+ | Finished a multi-file change; verifying scope | `codeblast change <repo> HEAD~1 HEAD --json` | Symbols and dependency edges added / removed / renamed |
18
+ | Need to understand an unfamiliar repo | `codeblast archmap <db> --out arch.html` | Module → file → symbol map with cycle detection |
19
+ | Reviewing a PR | `codeblast pr-comment <repo> <base> <head>` | Markdown review comment; empty output when nothing structural changed |
20
+
21
+ Prerequisites: Node ≥ 22.13 or Bun ≥ 1.0 (`npx codeblast` works with no install); `python3` for Python
22
+ repos; the target repo's dependencies installed (missing `node_modules` turns external calls into blind spots).
23
+
24
+ ## Interpretation rules — read before running
25
+
26
+ These are the mistakes an agent makes with this tool. Each one has produced a wrong answer in practice.
27
+
28
+ 1. **Never present the impact list as complete when `blind_spot_count > 0`.** A blind spot is any call or
29
+ import static analysis could not resolve to an in-repo target: dynamic calls, unresolved calls, failed
30
+ external resolution, subprocess boundaries, test-framework globals. Say "impact may be underestimated".
31
+ 2. **Never drop the `file` channel to make the list shorter.** Items with `channel: "call"` are the
32
+ high-confidence core (measured precision ≈ 0.70). Items with `channel: "file"` reach the target only
33
+ through import / re-export edges. Cutting them raised precision but collapsed recall from 100% to 14%
34
+ in a controlled run — tests often call the target from inside anonymous callbacks the call graph
35
+ cannot see. Use `call` items as what to read first; use the full list as what to test.
36
+ 3. **Never claim function-level precision for Python.** Python is file-level with typed-call upgrades;
37
+ there is no zero-miss promise. Say so when reporting on a Python repo.
38
+ 4. **`truncated: true` means the impact is wide** (over `--max`, default 500). Recommend the full test
39
+ suite; do not enumerate a partial list as if it were the whole.
40
+ 5. **`co_change_hints` are not impact.** They are files that historically changed together with the
41
+ target but have no static edge (protocol pairs, config + consumer). Report them as "historically
42
+ co-changed, worth a look", never as "affected".
43
+ 6. **Cite `via_file:via_line`** when you tell the user something depends on the target. That is the
44
+ real location of the dependency and can be opened to check.
45
+ 7. **This is not a diagram generator.** `archmap` outputs facts for navigation. For a presentation
46
+ diagram, feed its JSON to a rendering tool; do not ask codeblast to make it pretty.
47
+
48
+ ## 1. Build the graph (required first; incremental afterwards)
49
+
50
+ ```bash
51
+ codeblast index <repo-root> --db /tmp/graph.db
52
+ ```
53
+
54
+ Auto-discovers every package `tsconfig.json` in a monorepo and ingests Python via AST. Re-running only
55
+ processes files whose content hash changed. Stdout is one JSON object:
56
+
57
+ ```json
58
+ { "db": "...", "seconds": 19.4, "tsconfigs": 12, "files_indexed": 950, "files_skipped": 0,
59
+ "nodes": 14200, "edges": 31800, "blind_spots": 412, "failures": 0 }
60
+ ```
61
+
62
+ Non-zero exit with `failures > 0` means the graph is incomplete — do not query it; report the failure.
63
+
64
+ ## 2. Impact — what breaks if I change this
65
+
66
+ ```bash
67
+ codeblast impact /tmp/graph.db "<symbol-name | full-id | file-path>" --json [--max 500]
68
+ ```
69
+
70
+ Target forms: a bare symbol name (if ambiguous, the command lists candidates and exits 1 — pick the
71
+ full id and re-run), a full id `path/to/file.ts#Symbol` or `path/to/file.ts#Class.method`, or a file
72
+ path relative to the repo root.
73
+
74
+ Output (`--json`):
75
+
76
+ ```ts
77
+ {
78
+ target: string; // resolved full id
79
+ truncated: boolean; // hit --max; impact is wide
80
+ blind_spot_count: number; // unresolved calls/imports in the target's file (rule 1)
81
+ items: Array<{
82
+ id: string; name: string; kind: string; file: string; line: number;
83
+ level: "direct" | "indirect" | "tests"; // 1 hop | 2+ hops | a test that reaches the target
84
+ hops: number;
85
+ confidence: "exact" | "conservative"; // weakest edge on the path; conservative = interface fan-out etc.
86
+ channel: "call" | "file"; // rule 2
87
+ named_miss?: boolean; // file channel only: an import on the path did not name the target
88
+ via_file: string; via_line: number; // where the dependency occurs (rule 6)
89
+ }>;
90
+ co_change_hints: Array<{ file: string; co_commits: number; evidence: string }>; // rule 5
91
+ }
92
+ ```
93
+
94
+ How to use it: `items.filter(level === "direct")` is the callsite checklist. `items.filter(level ===
95
+ "tests")` de-duplicated by `file` is the test set to run. Test-directory fixtures are included
96
+ conservatively; estimate test cost by distinct files, not item count.
97
+
98
+ `co_change_hints` is populated only after `codeblast cochange <repo> /tmp/graph.db` (optional).
99
+
100
+ ## 3. Change — what structurally changed between two refs
101
+
102
+ ```bash
103
+ codeblast change <repo-root> <ref-a> <ref-b> --json
104
+ codeblast change --dbs <a.db> <b.db> --json # two graphs already built
105
+ ```
106
+
107
+ Output when nothing structural changed: `{ "range": "...", "structural_changes": 0 }`. Otherwise:
108
+
109
+ ```ts
110
+ {
111
+ range: string; structural_changes: number;
112
+ nodes_added: Node[]; nodes_removed: Node[]; // Node = { id, kind, name, file, line }
113
+ renamed: Array<{ from, to, file, kind }>; // matched rename, not counted as add + remove
114
+ edges_added: Edge[]; edges_removed: Edge[]; // Edge = { src, dst, kind, file, line }
115
+ modules: Record<string, { added, removed, renamed, edgesIn, edgesOut }>;
116
+ impact: Array<{ symbol, kind, impact_nodes, affected_tests, truncated }>; // per added/renamed symbol
117
+ }
118
+ ```
119
+
120
+ Self-check after an edit: an unexpected entry in `edges_added` is a new dependency the task did not call
121
+ for; a non-empty `nodes_removed` under a "pure refactor" means something was dropped.
122
+
123
+ ## 4. Architecture map
124
+
125
+ ```bash
126
+ codeblast mermaid /tmp/graph.db # Mermaid, for PR descriptions / docs
127
+ codeblast archmap /tmp/graph.db --out arch.html --repo-url <github-blob-url> # interactive HTML
128
+ codeblast archmap head.db --impact "<symbol>" --out impact.html # blast radius painted on the map
129
+ codeblast archmap head.db --diff base.db --out change.html # structural diff painted on the map
130
+ ```
131
+
132
+ Modules collapse by top-level directory; circular dependencies are drawn as red dashed edges; each
133
+ module shows its blind-spot count. The HTML drills module → file → symbol, and symbols link to source
134
+ lines when `--repo-url` is given. `--overlay codeblast.overlay.json` renames / merges / hides modules
135
+ (the file is meant to be committed; the map's ✎ mode generates it).
136
+
137
+ ## 5. PR comment (CI)
138
+
139
+ ```bash
140
+ codeblast pr-comment <repo> <base-sha> <head-sha> [--repo-url <url>]
141
+ ```
142
+
143
+ Exit 0 with empty stdout when there is nothing structural to say — the workflow template in
144
+ `.github/workflows-template/codeblast.yml` posts a sticky comment only when stdout is non-empty.
145
+ Replayed over 50 real commits: 42 stayed silent, 87.5% of the comments posted were judged useful.
146
+
147
+ ## Precision, stated
148
+
149
+ - TypeScript, function level: **zero missed impact within statically analyzable scope**, checked by
150
+ mutation testing (inject a fault, run the real test suite, compare failing tests to the prediction).
151
+ tRPC benchmark, 950 files: 28/28 mutations recalled, precision 0.36 overall / ≈ 0.70 on the call channel.
152
+ The weekly acceptance workflow re-runs this and opens an issue if recall drops below 100%.
153
+ - Conservative edges over-approximate on purpose (an interface method call fans out to every implementer).
154
+ - Python: file-level; typed calls (`b = Builder(); b.method()`, annotated parameters) are function-level;
155
+ untyped attribute chains fall back to file level and are recorded as blind spots.