codecompass-mcp 2.8.0__tar.gz → 3.0.1__tar.gz

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.
Files changed (47) hide show
  1. codecompass_mcp-3.0.1/PKG-INFO +250 -0
  2. codecompass_mcp-3.0.1/README.md +212 -0
  3. codecompass_mcp-3.0.1/codecompass_mcp.egg-info/PKG-INFO +250 -0
  4. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/graph/code_graph_client.py +79 -47
  5. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/graph/code_query_cli.py +1 -1
  6. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/code_parser.py +137 -6
  7. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/hierarchy_builder.py +1 -1
  8. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/mcp_server.py +5 -2
  9. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/models/code_types.py +6 -0
  10. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/pyproject.toml +1 -1
  11. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_accuracy_fixes.py +24 -0
  12. codecompass_mcp-2.8.0/PKG-INFO +0 -421
  13. codecompass_mcp-2.8.0/README.md +0 -383
  14. codecompass_mcp-2.8.0/codecompass_mcp.egg-info/PKG-INFO +0 -421
  15. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/LICENSE +0 -0
  16. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/SOURCES.txt +0 -0
  17. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/dependency_links.txt +0 -0
  18. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/entry_points.txt +0 -0
  19. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/requires.txt +0 -0
  20. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/top_level.txt +0 -0
  21. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/config.py +0 -0
  22. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/graph/__init__.py +0 -0
  23. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/graph/cli.py +0 -0
  24. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/graph/setup.py +0 -0
  25. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/__init__.py +0 -0
  26. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/chunker.py +0 -0
  27. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/code_normalizer.py +0 -0
  28. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/description_enricher.py +0 -0
  29. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/entity_resolver.py +0 -0
  30. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/file_watcher.py +0 -0
  31. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/graph_writer.py +0 -0
  32. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/reader_agent.py +0 -0
  33. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/ingestion/source_context.py +0 -0
  34. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/main.py +0 -0
  35. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/models/__init__.py +0 -0
  36. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/models/types.py +0 -0
  37. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/setup.cfg +0 -0
  38. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_batch_impact.py +0 -0
  39. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_blast_radius.py +0 -0
  40. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_code_parser.py +0 -0
  41. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_description_enricher.py +0 -0
  42. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_ingestion.py +0 -0
  43. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_lit_css_parser.py +0 -0
  44. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_mcp_server.py +0 -0
  45. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/tests/test_php_parser.py +0 -0
  46. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/utils/__init__.py +0 -0
  47. {codecompass_mcp-2.8.0 → codecompass_mcp-3.0.1}/utils/formatting.py +0 -0
@@ -0,0 +1,250 @@
1
+ Metadata-Version: 2.4
2
+ Name: codecompass-mcp
3
+ Version: 3.0.1
4
+ Summary: Structural code context for AI coding agents — a local code knowledge graph for blast radius, impact, deps, dead code, and flow tracing
5
+ Author: CodeCompass contributors
6
+ License: MIT
7
+ Keywords: ai,code-graph,llm,coding-agent,tree-sitter
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Software Development :: Code Generators
16
+ Classifier: Topic :: Software Development :: Compilers
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: anthropic>=0.40.0
21
+ Requires-Dist: fastmcp>=2.0.0
22
+ Requires-Dist: networkx>=3.0
23
+ Requires-Dist: pypdf2>=3.0.0
24
+ Requires-Dist: python-dotenv>=1.0.0
25
+ Requires-Dist: rich>=13.0.0
26
+ Requires-Dist: tqdm>=4.66.0
27
+ Requires-Dist: tree-sitter>=0.21.0
28
+ Requires-Dist: tree-sitter-python>=0.21.0
29
+ Requires-Dist: tree-sitter-javascript>=0.21.0
30
+ Requires-Dist: tree-sitter-typescript>=0.21.0
31
+ Requires-Dist: tree-sitter-html>=0.21.0
32
+ Requires-Dist: tree-sitter-css>=0.21.0
33
+ Requires-Dist: watchdog>=4.0.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
36
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # CodeCompass
40
+
41
+ A local code knowledge graph that gives AI agents a map of your codebase — so they navigate by structure instead of grepping blind, and know what's connected before they edit.
42
+
43
+ No database. No cloud. One JSON file per repo. Python, JavaScript/TypeScript, PHP, HTML/CSS.
44
+
45
+ ---
46
+
47
+ ## Why it's faster
48
+
49
+ AI agents read files one at a time and grep to find their way. On a real task that means opening candidate after candidate to answer "who calls this?" or "what breaks if I change this?" CodeCompass answers those from a precomputed graph, so the agent reads *only the code it actually needs*.
50
+
51
+ We benchmarked it against traditional grep/read on six standard tasks (impact, blast radius, dead code, flow trace, find-and-edit, feature scoping) across four real repos, measuring **tokens to a verified answer** — the query output *plus* the code still read to trust it.
52
+
53
+ ![Tokens to a verified answer: CodeCompass vs grep/read across Python, PHP, and JavaScript](docs/benchmark-chart.svg)
54
+
55
+ CodeCompass wins every relational and discovery task; grep only holds even on a
56
+ plain textual find of a known string. The advantage grows with codebase size and
57
+ name collisions. Full breakdown, per-task numbers, and honest limitations in
58
+ **[docs/benchmark-results.md](docs/benchmark-results.md)**.
59
+
60
+ ---
61
+
62
+ ## The workflow
63
+
64
+ The graph turns navigation into a cheap, deterministic loop:
65
+
66
+ **discover → trace → read → edit**
67
+
68
+ 1. **Discover** — find the symbols you care about without opening files:
69
+
70
+ | You have… | Use |
71
+ |---|---|
72
+ | a feature request that names a concept ("session timeout") | `grep` the concept |
73
+ | a regex / name pattern | `grep` |
74
+ | keywords | `search` |
75
+ | a vague, nameless need | `map` (compact index to reason over) |
76
+
77
+ 2. **Trace** — a relationship around a known symbol/file:
78
+
79
+ | Question | Use |
80
+ |---|---|
81
+ | who calls / would break if I change this? | `impact` |
82
+ | what files are affected if I edit this file? | `blast_radius` |
83
+ | what does this file depend on? | `deps` |
84
+ | what does this entry point call, step by step? | `flow` |
85
+ | explain a flow to a human (diagram + narration) | `flow_summary` |
86
+ | anything unused? | `dead_code` |
87
+
88
+ 3. **Read** the specific slice the graph points to (`impact` gives `file:line`).
89
+ 4. **Edit** — check `impact`/`blast_radius` first so you don't miss a caller.
90
+
91
+ ---
92
+
93
+ ## What makes it accurate
94
+
95
+ - **Precise call graph.** Nodes are file- *and* class-qualified, so
96
+ `Command.invoke` and `Context.invoke` (same file) stay distinct, and
97
+ `impact` returns the callers of a *specific* method — no same-named
98
+ look-alikes, no test noise.
99
+ - **Receiver-type resolution.** `self.send()` resolves to the enclosing class;
100
+ `x = new Adapter()` / `x: Adapter` / `x = make()` (with a return type) resolve
101
+ by type. Calls that can't be typed statically (dynamic dispatch) are
102
+ **surfaced flagged `resolved: false`** — never dropped, never claimed precise.
103
+ - **Line-anchored.** Every `impact` caller carries its real call-site
104
+ `file:line`, so verification reads a few lines, not a whole function.
105
+
106
+ ---
107
+
108
+ ## Install
109
+
110
+ ```bash
111
+ pip install codecompass-mcp
112
+ ```
113
+
114
+ Gives you the `codecompass` CLI and the `codecompass-mcp` MCP server.
115
+
116
+ ### Index a project
117
+
118
+ ```bash
119
+ cd /path/to/your/project
120
+ codecompass init # creates .codecompass/, writes AGENTS.md
121
+ codecompass ingest-code # parses source and builds the graph
122
+ ```
123
+
124
+ `ingest-code` runs `init` automatically if needed. Re-ingest after refactors (or run `codecompass watch` to keep the graph live).
125
+
126
+ ### Connect an MCP client
127
+
128
+ The server speaks stdio MCP and defaults to the working directory.
129
+
130
+ **Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
131
+
132
+ ```json
133
+ { "mcpServers": { "codecompass": { "command": "codecompass-mcp" } } }
134
+ ```
135
+
136
+ **Cline / Cursor / other** — add a server with command `codecompass-mcp`. To query a different repo, the agent calls `set_repo`, or set `CODECOMPASS_REPO=/path/to/project` in the server env.
137
+
138
+ ---
139
+
140
+ ## Queries (CLI)
141
+
142
+ ```bash
143
+ # discover
144
+ codecompass query --grep "^get_" # regex over graph entities
145
+ codecompass query --search "session cookie" # keyword search
146
+ codecompass query --map # compact {file: [symbols]} index
147
+
148
+ # trace
149
+ codecompass query --impact "Session.send" # callers (disambiguated), with file:line
150
+ codecompass query --blast-radius src/app.py # what depends on this file
151
+ codecompass query --deps src/api/routes.py # what this file imports
152
+ codecompass query --flow "Session.request" # lean call-flow structure
153
+ codecompass query --flow-summary "main" # flow + mermaid + narration
154
+ codecompass query --dead-code # unreferenced candidates
155
+ codecompass query --tree # full hierarchy
156
+ ```
157
+
158
+ Add `--hops N` for traversal depth (start at 1 and follow the one path you need). Add `--rich` for tables.
159
+
160
+ ### Flow: `flow` vs `flow-summary`
161
+
162
+ - **`flow`** — lean structure only (node name/kind/file/depth, edge from/to/order/line). What an agent needs to navigate; no embedded source.
163
+ - **`flow-summary`** — the trace rendered for a human: a mermaid flowchart with prose narration (`--format mermaid`, default), or source-embedded JSON (`--format json`), or a draw.io diagram (`--format drawio`). Written to `.codecompass/flow_<entry>.*`.
164
+
165
+ ---
166
+
167
+ ## MCP tools
168
+
169
+ | Tool | Returns |
170
+ |---|---|
171
+ | `grep(pattern, field, ignore_case)` | Regex search over graph entities |
172
+ | `search(query, kind)` | Keyword search, ranked |
173
+ | `map(include_tests)` | Compact `{file: [symbols]}` index |
174
+ | `impact(symbol, hops)` | Callers/importers, disambiguated, with `resolved` + `line` |
175
+ | `blast_radius(target, hops)` | Files reachable from a file or symbol |
176
+ | `batch_impact(targets, hops)` | Union of blast radii for a multi-file change |
177
+ | `deps(file_path, hops)` | What a file imports |
178
+ | `flow(entry_symbol, hops)` | Lean call/import flow structure |
179
+ | `flow_summary(entry_symbol, hops, format)` | Flow + narration (mermaid/json/drawio) |
180
+ | `trace(symbol, hops)` | Forward call chain |
181
+ | `dead_code(include_entrypoints)` | Entities with no inbound caller |
182
+ | `styles(element)` | CSS selectors that style an element |
183
+ | `tree()` | Full project hierarchy |
184
+ | `set_repo` / `get_repo` / `init` / `ingest` | Project selection & indexing |
185
+
186
+ ---
187
+
188
+ ## Supported languages
189
+
190
+ | Language | Extracted |
191
+ |---|---|
192
+ | Python | functions, classes, imports, calls, inheritance, receiver/return-type inference, `__all__`/public exports |
193
+ | JavaScript / JSX | functions, classes, `require`/`import`, calls, receiver/return-type inference, `module.exports`/`export` |
194
+ | TypeScript / TSX | as JS, plus type annotations for receiver resolution |
195
+ | PHP | functions, classes, methods, calls, receiver/return-type inference, `public`/`private`/`protected` visibility |
196
+ | HTML | elements, references, includes |
197
+ | CSS / SCSS | selectors, variables, `@import`/`@use` |
198
+ | `.styles.ts` (Lit) | CSS-in-JS `var(--token)` usages and `:host` declarations |
199
+
200
+ Receiver capture, type inference, and export/visibility awareness apply to all
201
+ call-based languages (JS/TS, Python, PHP). Node de-merge and the discovery tools
202
+ are language-agnostic.
203
+
204
+ ---
205
+
206
+ ## Navigation guardrail (optional, installed by `init`)
207
+
208
+ `AGENTS.md` guides any agent through the discover→trace→read→edit loop. For
209
+ Claude Code and [pi](https://pi.dev), `init` also installs a `PreToolUse` hook
210
+ that **blocks code *search*** (`grep`/`rg`, the `Grep`/`Glob` tools) and
211
+ **whole-file `cat`**, routing discovery through the graph — while leaving
212
+ **targeted reads free** (the `Read` tool, `sed -n`, `head`/`tail`). The point is
213
+ to change the default reflex to graph-first, not to remove reads. Both pick the
214
+ files up after a one-time trust prompt (they execute shell commands). The hook
215
+ is a plain file under `.claude/hooks/` — edit or delete it to adjust.
216
+
217
+ ---
218
+
219
+ ## How it works
220
+
221
+ ```
222
+ Source files
223
+ ▼ hierarchy_builder walks repo → Project / Folder / File skeleton
224
+ ▼ code_parser tree-sitter extraction (no API calls) → typed CodeTriples
225
+ ▼ graph.json NetworkX MultiDiGraph as JSON; file+class-qualified nodes,
226
+ typed edges (CALLS/IMPORTS/INHERITS/STYLES/…), resolved calls
227
+ ▼ code_query_cli traversal: grep / search / map / impact / blast-radius /
228
+ deps / flow / dead-code / tree
229
+ ```
230
+
231
+ Everything runs locally, in-process. No network, no database, no API keys.
232
+
233
+ Inside each indexed project:
234
+
235
+ ```
236
+ your-project/
237
+ ├── .codecompass/graph.json the code knowledge graph (auto-generated)
238
+ └── AGENTS.md discovery guide for agents (auto-updated)
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Limitations
244
+
245
+ - **Structure, not semantics** — the graph knows what calls what, not what it means.
246
+ - **Static analysis** — dynamic dispatch, reflection, and string-based invocation
247
+ can't be fully resolved. `impact` surfaces those flagged `resolved: false`, and
248
+ `dead_code` results are always candidates to verify.
249
+ - **No cross-repo edges** — entities outside the indexed repo don't appear.
250
+ - **Re-ingest after refactors** — the graph doesn't auto-update unless `watch` is running.
@@ -0,0 +1,212 @@
1
+ # CodeCompass
2
+
3
+ A local code knowledge graph that gives AI agents a map of your codebase — so they navigate by structure instead of grepping blind, and know what's connected before they edit.
4
+
5
+ No database. No cloud. One JSON file per repo. Python, JavaScript/TypeScript, PHP, HTML/CSS.
6
+
7
+ ---
8
+
9
+ ## Why it's faster
10
+
11
+ AI agents read files one at a time and grep to find their way. On a real task that means opening candidate after candidate to answer "who calls this?" or "what breaks if I change this?" CodeCompass answers those from a precomputed graph, so the agent reads *only the code it actually needs*.
12
+
13
+ We benchmarked it against traditional grep/read on six standard tasks (impact, blast radius, dead code, flow trace, find-and-edit, feature scoping) across four real repos, measuring **tokens to a verified answer** — the query output *plus* the code still read to trust it.
14
+
15
+ ![Tokens to a verified answer: CodeCompass vs grep/read across Python, PHP, and JavaScript](docs/benchmark-chart.svg)
16
+
17
+ CodeCompass wins every relational and discovery task; grep only holds even on a
18
+ plain textual find of a known string. The advantage grows with codebase size and
19
+ name collisions. Full breakdown, per-task numbers, and honest limitations in
20
+ **[docs/benchmark-results.md](docs/benchmark-results.md)**.
21
+
22
+ ---
23
+
24
+ ## The workflow
25
+
26
+ The graph turns navigation into a cheap, deterministic loop:
27
+
28
+ **discover → trace → read → edit**
29
+
30
+ 1. **Discover** — find the symbols you care about without opening files:
31
+
32
+ | You have… | Use |
33
+ |---|---|
34
+ | a feature request that names a concept ("session timeout") | `grep` the concept |
35
+ | a regex / name pattern | `grep` |
36
+ | keywords | `search` |
37
+ | a vague, nameless need | `map` (compact index to reason over) |
38
+
39
+ 2. **Trace** — a relationship around a known symbol/file:
40
+
41
+ | Question | Use |
42
+ |---|---|
43
+ | who calls / would break if I change this? | `impact` |
44
+ | what files are affected if I edit this file? | `blast_radius` |
45
+ | what does this file depend on? | `deps` |
46
+ | what does this entry point call, step by step? | `flow` |
47
+ | explain a flow to a human (diagram + narration) | `flow_summary` |
48
+ | anything unused? | `dead_code` |
49
+
50
+ 3. **Read** the specific slice the graph points to (`impact` gives `file:line`).
51
+ 4. **Edit** — check `impact`/`blast_radius` first so you don't miss a caller.
52
+
53
+ ---
54
+
55
+ ## What makes it accurate
56
+
57
+ - **Precise call graph.** Nodes are file- *and* class-qualified, so
58
+ `Command.invoke` and `Context.invoke` (same file) stay distinct, and
59
+ `impact` returns the callers of a *specific* method — no same-named
60
+ look-alikes, no test noise.
61
+ - **Receiver-type resolution.** `self.send()` resolves to the enclosing class;
62
+ `x = new Adapter()` / `x: Adapter` / `x = make()` (with a return type) resolve
63
+ by type. Calls that can't be typed statically (dynamic dispatch) are
64
+ **surfaced flagged `resolved: false`** — never dropped, never claimed precise.
65
+ - **Line-anchored.** Every `impact` caller carries its real call-site
66
+ `file:line`, so verification reads a few lines, not a whole function.
67
+
68
+ ---
69
+
70
+ ## Install
71
+
72
+ ```bash
73
+ pip install codecompass-mcp
74
+ ```
75
+
76
+ Gives you the `codecompass` CLI and the `codecompass-mcp` MCP server.
77
+
78
+ ### Index a project
79
+
80
+ ```bash
81
+ cd /path/to/your/project
82
+ codecompass init # creates .codecompass/, writes AGENTS.md
83
+ codecompass ingest-code # parses source and builds the graph
84
+ ```
85
+
86
+ `ingest-code` runs `init` automatically if needed. Re-ingest after refactors (or run `codecompass watch` to keep the graph live).
87
+
88
+ ### Connect an MCP client
89
+
90
+ The server speaks stdio MCP and defaults to the working directory.
91
+
92
+ **Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
93
+
94
+ ```json
95
+ { "mcpServers": { "codecompass": { "command": "codecompass-mcp" } } }
96
+ ```
97
+
98
+ **Cline / Cursor / other** — add a server with command `codecompass-mcp`. To query a different repo, the agent calls `set_repo`, or set `CODECOMPASS_REPO=/path/to/project` in the server env.
99
+
100
+ ---
101
+
102
+ ## Queries (CLI)
103
+
104
+ ```bash
105
+ # discover
106
+ codecompass query --grep "^get_" # regex over graph entities
107
+ codecompass query --search "session cookie" # keyword search
108
+ codecompass query --map # compact {file: [symbols]} index
109
+
110
+ # trace
111
+ codecompass query --impact "Session.send" # callers (disambiguated), with file:line
112
+ codecompass query --blast-radius src/app.py # what depends on this file
113
+ codecompass query --deps src/api/routes.py # what this file imports
114
+ codecompass query --flow "Session.request" # lean call-flow structure
115
+ codecompass query --flow-summary "main" # flow + mermaid + narration
116
+ codecompass query --dead-code # unreferenced candidates
117
+ codecompass query --tree # full hierarchy
118
+ ```
119
+
120
+ Add `--hops N` for traversal depth (start at 1 and follow the one path you need). Add `--rich` for tables.
121
+
122
+ ### Flow: `flow` vs `flow-summary`
123
+
124
+ - **`flow`** — lean structure only (node name/kind/file/depth, edge from/to/order/line). What an agent needs to navigate; no embedded source.
125
+ - **`flow-summary`** — the trace rendered for a human: a mermaid flowchart with prose narration (`--format mermaid`, default), or source-embedded JSON (`--format json`), or a draw.io diagram (`--format drawio`). Written to `.codecompass/flow_<entry>.*`.
126
+
127
+ ---
128
+
129
+ ## MCP tools
130
+
131
+ | Tool | Returns |
132
+ |---|---|
133
+ | `grep(pattern, field, ignore_case)` | Regex search over graph entities |
134
+ | `search(query, kind)` | Keyword search, ranked |
135
+ | `map(include_tests)` | Compact `{file: [symbols]}` index |
136
+ | `impact(symbol, hops)` | Callers/importers, disambiguated, with `resolved` + `line` |
137
+ | `blast_radius(target, hops)` | Files reachable from a file or symbol |
138
+ | `batch_impact(targets, hops)` | Union of blast radii for a multi-file change |
139
+ | `deps(file_path, hops)` | What a file imports |
140
+ | `flow(entry_symbol, hops)` | Lean call/import flow structure |
141
+ | `flow_summary(entry_symbol, hops, format)` | Flow + narration (mermaid/json/drawio) |
142
+ | `trace(symbol, hops)` | Forward call chain |
143
+ | `dead_code(include_entrypoints)` | Entities with no inbound caller |
144
+ | `styles(element)` | CSS selectors that style an element |
145
+ | `tree()` | Full project hierarchy |
146
+ | `set_repo` / `get_repo` / `init` / `ingest` | Project selection & indexing |
147
+
148
+ ---
149
+
150
+ ## Supported languages
151
+
152
+ | Language | Extracted |
153
+ |---|---|
154
+ | Python | functions, classes, imports, calls, inheritance, receiver/return-type inference, `__all__`/public exports |
155
+ | JavaScript / JSX | functions, classes, `require`/`import`, calls, receiver/return-type inference, `module.exports`/`export` |
156
+ | TypeScript / TSX | as JS, plus type annotations for receiver resolution |
157
+ | PHP | functions, classes, methods, calls, receiver/return-type inference, `public`/`private`/`protected` visibility |
158
+ | HTML | elements, references, includes |
159
+ | CSS / SCSS | selectors, variables, `@import`/`@use` |
160
+ | `.styles.ts` (Lit) | CSS-in-JS `var(--token)` usages and `:host` declarations |
161
+
162
+ Receiver capture, type inference, and export/visibility awareness apply to all
163
+ call-based languages (JS/TS, Python, PHP). Node de-merge and the discovery tools
164
+ are language-agnostic.
165
+
166
+ ---
167
+
168
+ ## Navigation guardrail (optional, installed by `init`)
169
+
170
+ `AGENTS.md` guides any agent through the discover→trace→read→edit loop. For
171
+ Claude Code and [pi](https://pi.dev), `init` also installs a `PreToolUse` hook
172
+ that **blocks code *search*** (`grep`/`rg`, the `Grep`/`Glob` tools) and
173
+ **whole-file `cat`**, routing discovery through the graph — while leaving
174
+ **targeted reads free** (the `Read` tool, `sed -n`, `head`/`tail`). The point is
175
+ to change the default reflex to graph-first, not to remove reads. Both pick the
176
+ files up after a one-time trust prompt (they execute shell commands). The hook
177
+ is a plain file under `.claude/hooks/` — edit or delete it to adjust.
178
+
179
+ ---
180
+
181
+ ## How it works
182
+
183
+ ```
184
+ Source files
185
+ ▼ hierarchy_builder walks repo → Project / Folder / File skeleton
186
+ ▼ code_parser tree-sitter extraction (no API calls) → typed CodeTriples
187
+ ▼ graph.json NetworkX MultiDiGraph as JSON; file+class-qualified nodes,
188
+ typed edges (CALLS/IMPORTS/INHERITS/STYLES/…), resolved calls
189
+ ▼ code_query_cli traversal: grep / search / map / impact / blast-radius /
190
+ deps / flow / dead-code / tree
191
+ ```
192
+
193
+ Everything runs locally, in-process. No network, no database, no API keys.
194
+
195
+ Inside each indexed project:
196
+
197
+ ```
198
+ your-project/
199
+ ├── .codecompass/graph.json the code knowledge graph (auto-generated)
200
+ └── AGENTS.md discovery guide for agents (auto-updated)
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Limitations
206
+
207
+ - **Structure, not semantics** — the graph knows what calls what, not what it means.
208
+ - **Static analysis** — dynamic dispatch, reflection, and string-based invocation
209
+ can't be fully resolved. `impact` surfaces those flagged `resolved: false`, and
210
+ `dead_code` results are always candidates to verify.
211
+ - **No cross-repo edges** — entities outside the indexed repo don't appear.
212
+ - **Re-ingest after refactors** — the graph doesn't auto-update unless `watch` is running.