pycode-kg 0.17.2__tar.gz → 0.18.2__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 (63) hide show
  1. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/PKG-INFO +77 -134
  2. pycode_kg-0.18.2/README.md +174 -0
  3. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/pyproject.toml +1 -1
  4. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/__init__.py +1 -1
  5. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/analysis/bridge.py +6 -2
  6. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/analysis/centrality.py +21 -0
  7. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/analysis/framework_detector.py +7 -1
  8. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_bridges.py +1 -0
  9. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_framework_nodes.py +1 -0
  10. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_viz.py +2 -2
  11. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/layout3d.py +30 -14
  12. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/ranking/cli_rank.py +2 -0
  13. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/snapshots.py +12 -0
  14. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/viz3d.py +140 -84
  15. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/viz3d_timeline.py +9 -9
  16. pycode_kg-0.17.2/README.md +0 -231
  17. pycode_kg-0.17.2/src/pycode_kg/mcp/bridge_tools.py +0 -19
  18. pycode_kg-0.17.2/src/pycode_kg/mcp/framework_tools.py +0 -18
  19. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/LICENSE +0 -0
  20. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/.DS_Store +0 -0
  21. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/__main__.py +0 -0
  22. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/analysis/__init__.py +0 -0
  23. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/analysis/hybrid_rank.py +0 -0
  24. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/app.py +0 -0
  25. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/architecture.py +0 -0
  26. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/build_pycodekg_lancedb.py +0 -0
  27. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/build_pycodekg_sqlite.py +0 -0
  28. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/__init__.py +0 -0
  29. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_analyze.py +0 -0
  30. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_architecture.py +0 -0
  31. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_build.py +0 -0
  32. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_build_full.py +0 -0
  33. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_centrality.py +0 -0
  34. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_explain.py +0 -0
  35. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_hooks.py +0 -0
  36. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_init.py +0 -0
  37. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_mcp.py +0 -0
  38. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_model.py +0 -0
  39. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_query.py +0 -0
  40. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_snapshot.py +0 -0
  41. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/main.py +0 -0
  42. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/cli/options.py +0 -0
  43. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/config.py +0 -0
  44. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/graph.py +0 -0
  45. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/index.py +0 -0
  46. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/kg.py +0 -0
  47. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/mcp_server.py +0 -0
  48. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/module/__init__.py +0 -0
  49. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/module/base.py +0 -0
  50. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/module/extractor.py +0 -0
  51. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/module/types.py +0 -0
  52. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg.py +0 -0
  53. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_query.py +0 -0
  54. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_snippet_packer.py +0 -0
  55. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_thorough_analysis.py +0 -0
  56. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_viz.py +0 -0
  57. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_viz3d.py +0 -0
  58. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/ranking/__init__.py +0 -0
  59. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/ranking/coderank.py +0 -0
  60. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/sql/004_add_centrality_table.sql +0 -0
  61. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/store.py +0 -0
  62. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/utils.py +0 -0
  63. {pycode_kg-0.17.2 → pycode_kg-0.18.2}/src/pycode_kg/visitor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycode-kg
3
- Version: 0.17.2
3
+ Version: 0.18.2
4
4
  Summary: A tool to build a searchable knowledge graph from Python repositories
5
5
  License-Expression: Elastic-2.0
6
6
  License-File: LICENSE
@@ -72,22 +72,21 @@ Project-URL: Repository, https://github.com/Flux-Frontiers/pycode_kg
72
72
  Description-Content-Type: text/markdown
73
73
 
74
74
 
75
+ <p align="center">
76
+ <img src="assets/logos/pycodeKG.PNG" alt="PyCodeKG" width="200"/>
77
+ </p>
78
+
75
79
  [![Python](https://img.shields.io/badge/python-3.12%20%7C%203.13-blue.svg)](https://www.python.org/)
76
80
  [![License: Elastic-2.0](https://img.shields.io/badge/License-Elastic%202.0-blue.svg)](https://www.elastic.co/licensing/elastic-license)
77
- [![Version](https://img.shields.io/badge/version-0.17.2-blue.svg)](https://github.com/Flux-Frontiers/pycode_kg/releases)
81
+ [![Version](https://img.shields.io/badge/version-0.18.2-blue.svg)](https://github.com/Flux-Frontiers/pycode_kg/releases)
78
82
  [![CI](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml/badge.svg)](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
79
83
  [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/)
80
84
  [![DOI](https://zenodo.org/badge/1202379010.svg)](https://zenodo.org/badge/latestdoi/1202379010)
81
85
 
82
- <p align="center">
83
- <img src="assets/logo-md-256x256.png" alt="PyCodeKG logo" width="256"/>
84
- </p>
85
-
86
86
  **PyCodeKG** — A Deterministic Knowledge Graph for Python Codebases
87
87
  with Semantic Indexing and Source-Grounded Snippet Packing
88
88
 
89
89
  *Author: Eric G. Suchanek, PhD*
90
-
91
90
  *Flux-Frontiers, Liberty TWP, OH*
92
91
 
93
92
  [Technical Paper (PDF)](article/pycode_kg.pdf)
@@ -98,84 +97,57 @@ with Semantic Indexing and Source-Grounded Snippet Packing
98
97
 
99
98
  PyCodeKG constructs a **deterministic, explainable knowledge graph** from a Python codebase using static analysis. The graph captures structural relationships — definitions, calls, imports, and inheritance — directly from the Python AST, stores them in SQLite, and augments retrieval with vector embeddings via LanceDB.
100
99
 
101
- Structure is treated as **ground truth**; semantic search is strictly an acceleration layer. The result is a searchable, auditable representation of a codebase that supports precise navigation, contextual snippet extraction, and downstream reasoning without hallucination.
102
-
103
- ---
104
-
105
- ## What Agents Say
106
-
107
- *From independent assessments run against PyCodeKG's own codebase. See [assessments/](assessments/) for the full reports.*
108
-
109
- > "The workflow compression is real and substantial. Rather than reading files sequentially or running grep searches in the dark, an agent equipped with PyCodeKG can orient itself in seconds."
110
- > — Claude Sonnet 4.6
100
+ **No inference required.** The CLI is fully useful as a standalone analysis tool — every result is derived from structure, not generated. When used with AI agents, PyCodeKG gives them structurally-grounded answers: precise callers, real call chains, exact line numbers. Hallucination-resistant by design.
111
101
 
112
- > "Replaces hours of manual exploration with a single call. The most valuable tool in the suite."
113
- > — Claude Opus 4, on `analyze_repo()`
102
+ Structure is treated as **ground truth**; semantic search is strictly an acceleration layer. The result is a searchable, auditable representation of a codebase that supports precise navigation, contextual snippet extraction, and downstream reasoning without hallucination.
114
103
 
115
- > "It let me move from broad orientation to intent-driven discovery and then to structural validation without dropping down into manual grep or repeated file reads."
116
- > — GPT-5 (via Cline)
104
+ PyCodeKG uses the same architecture as [DocKG](https://github.com/Flux-Frontiers/doc_kg) but targets Python source code rather than document corpora.
117
105
 
118
- > "Traditional file reading and grep-based exploration are slow, linear, and context-poor. PyCodeKG's semantic search, graph navigation, and architectural analysis provide a quantum leap in speed and depth of understanding."
119
- > — GPT-4.1
106
+ ---
120
107
 
121
- > "`pack_snippets()` provided source excerpts around each hit, making the code instantly readable. Context lines and relevance metadata obviated manual file open."
122
- > — Raptor Mini
108
+ ## Features
123
109
 
124
- > "Dramatically more effective than traditional grep/file-reading workflows. Unique value proposition: hybrid search combining natural-language intent with precise structural relationships."
125
- >Claude Haiku 4.5
110
+ - **Static analysis pipeline** Three-pass AST extraction: structure, call graph, data-flow
111
+ - **Deterministic knowledge graph** SQLite-backed canonical store with provenance-tracked edges
112
+ - **Symbol resolution** — `RESOLVES_TO` edges bridge cross-module call sites via import aliases
113
+ - **Hybrid query model** — Semantic seeding (LanceDB embeddings) + structural expansion (graph traversal)
114
+ - **Source-grounded snippet packing** — Definition and call-site snippets with line numbers
115
+ - **Precise fan-in lookup** — Two-phase reverse traversal resolving cross-module caller chains
116
+ - **Temporal snapshots** — Save and diff graph metrics across commits and versions
117
+ - **MCP server** — Nineteen tools for AI agent integration
118
+ - **Streamlit web app** — Interactive graph browser, hybrid query UI, snippet pack explorer
119
+ - **3-D visualizer** — PyVista/PyQt5 interactive graph explorer with FunnelLayout and timeline view
120
+ - **Zero-config MCP setup** — Single-line installer configures Claude Code, Kilo Code, GitHub Copilot, and Cline
126
121
 
127
122
  ---
128
123
 
129
- ## Quick Start
124
+ ## Installation
130
125
 
131
- Run the one-line installer from within the repo you want to index:
126
+ **Requirements:** Python 3.12, < 3.14
132
127
 
133
128
  ```bash
134
- curl -fsSL https://raw.githubusercontent.com/Flux-Frontiers/pycode_kg/main/scripts/install-skill.sh | bash
135
- ```
136
-
137
- This sets up everything end-to-end:
138
-
139
- 1. Installs SKILL.md reference files for Claude Code, Kilo Code, and other agents
140
- 2. Installs Claude Code slash commands (`/pycodekg`, `/setup-mcp`)
141
- 3. Installs the `pycode-kg` package if not already present
142
- 4. Builds the SQLite knowledge graph and LanceDB semantic index
143
- 5. Writes MCP configuration for Claude Code, Kilo Code, GitHub Copilot, and Cline
129
+ # pip
130
+ pip install pycode-kg
144
131
 
145
- After the script completes, restart your AI agent to activate the MCP server.
132
+ # With Streamlit web visualizer
133
+ pip install 'pycode-kg[viz]'
146
134
 
147
- ```bash
148
- # Preview without making changes
149
- curl -fsSL .../install-skill.sh | bash -s -- --dry-run
135
+ # With 3-D visualizer (PyVista/PyQt5)
136
+ pip install 'pycode-kg[viz3d]'
150
137
 
151
- # Claude Code and GitHub Copilot only
152
- curl -fsSL .../install-skill.sh | bash -s -- --providers claude,copilot
138
+ # Poetry
139
+ poetry add pycode-kg
153
140
  ```
154
141
 
155
- **Full installation options, manual setup, and MCP config:** [docs/INSTALLATION.md](docs/INSTALLATION.md)
156
-
157
- ---
158
-
159
- ## Features
160
-
161
- - **Static analysis pipeline** — Three-pass AST extraction: structure, call graph, data-flow
162
- - **Deterministic knowledge graph** — SQLite-backed canonical store with provenance
163
- - **Symbol resolution** — `RESOLVES_TO` edges bridge cross-module call sites via import aliases
164
- - **Hybrid query model** — Semantic seeding (LanceDB) + structural expansion (graph traversal)
165
- - **Source-grounded snippet packing** — Definition and call-site snippets with line numbers
166
- - **Precise fan-in lookup** — Two-phase reverse traversal resolving cross-module caller chains
167
- - **MCP server** — Ten tools for AI agent integration
168
- - **Streamlit web app** — Interactive graph browser, hybrid query UI, snippet pack explorer
169
- - **3D visualizer** — PyVista/PyQt5 interactive graph explorer
170
- - **Zero-config MCP setup** — Single-line installer configures Claude Code, Kilo Code, GitHub Copilot, and Cline
142
+ > For the one-line skill installer (MCP config, Claude slash commands, git hooks) see [docs/INSTALLATION.md](docs/INSTALLATION.md).
171
143
 
172
144
  ---
173
145
 
174
- ## Usage
146
+ ## Quick Start
175
147
 
176
148
  ```bash
177
- # Build the knowledge graph
178
- pycodekg build --repo /path/to/your/repo
149
+ # Index your repo (SQLite + LanceDB in one step)
150
+ pycodekg build --repo /path/to/repo
179
151
 
180
152
  # Natural-language query
181
153
  pycodekg query "authentication flow"
@@ -184,92 +156,63 @@ pycodekg query "authentication flow"
184
156
  pycodekg pack "database connection setup" --format md --out context.md
185
157
 
186
158
  # Full architectural analysis
187
- pycodekg analyze /path/to/your/repo
188
-
189
- # Launch the interactive web app
190
- pycodekg viz
191
-
192
- # Start the MCP server
193
- pycodekg mcp --repo /path/to/your/repo
159
+ pycodekg analyze /path/to/repo
194
160
  ```
195
161
 
196
- ### MCP Tools (once the server is running)
197
-
198
- ```
199
- graph_stats() # node/edge counts by kind
200
- query_codebase("authentication flow") # hybrid semantic + structural search
201
- pack_snippets("database layer") # source-grounded snippets as Markdown
202
- get_node("fn:store:GraphStore.write") # fetch a single node by ID
203
- callers("fn:store:GraphStore.write") # precise fan-in lookup
204
- explain("fn:store:GraphStore.write") # natural-language explanation
205
- analyze_repo() # full architectural analysis as Markdown
206
- snapshot_list() # list saved snapshots with deltas
207
- snapshot_show("latest") # inspect the latest snapshot
208
- snapshot_diff("<key_a>", "<key_b>") # compare two snapshots
209
- ```
162
+ ---
210
163
 
211
- ### Python API
164
+ ## Usage
212
165
 
213
- ```python
214
- from pycode_kg import PyCodeKG
166
+ ### Build and query
215
167
 
216
- kg = PyCodeKG(repo_root="/path/to/repo")
217
- kg.build(wipe=True)
168
+ ```bash
169
+ pycodekg build --repo . # full build (SQLite + LanceDB)
170
+ pycodekg build --repo . --include-dir src # index a specific subtree
171
+ pycodekg query "snapshot freshness comparison" # hybrid semantic + structural search
172
+ pycodekg pack "graph build pipeline" --format md # snippet pack for LLM context
173
+ ```
218
174
 
219
- result = kg.query("database connection setup", k=8, hop=1)
220
- for node in result.nodes:
221
- print(node["id"], node["name"])
175
+ ### Analyze codebase health
222
176
 
223
- pack = kg.pack("authentication flow")
224
- pack.save("context.md")
177
+ ```bash
178
+ pycodekg analyze . # full report + JSON snapshot
225
179
  ```
226
180
 
227
- ---
181
+ ### Snapshots
228
182
 
229
- ## Architecture
183
+ ```bash
184
+ pycodekg snapshot save 0.18.0 # capture current metrics
185
+ pycodekg snapshot list # list all snapshots
186
+ pycodekg snapshot diff <key_a> <key_b> # compare two versions
187
+ ```
230
188
 
231
- <p align="center">
232
- <img src="assets/codeKG_arch_square-web.jpg" alt="PyCodeKG architecture workflow" width="600"/>
233
- </p>
189
+ ### Visualize
234
190
 
235
- ```
236
- Repository
237
-
238
- AST parsing Pass 1: structure, Pass 2: calls, Pass 3: data-flow
239
-
240
- SQLite graph — nodes + edges
241
-
242
- Symbol resolution — RESOLVES_TO edges (sym: stubs → fn:/cls: defs)
243
-
244
- Vector indexing — LanceDB
245
-
246
- Hybrid query — semantic + graph
247
-
248
- Ranking + deduplication
249
-
250
- ├──▶ Streamlit web app
251
- └──▶ MCP server tools
191
+ ```bash
192
+ pycodekg viz # Streamlit web app
193
+ pycodekg viz3d --layout funnel # 3-D PyVista explorer
194
+ pycodekg viz-timeline # metric history timeline
252
195
  ```
253
196
 
254
- The five design principles:
197
+ > Full flag reference: [docs/INSTALLATION.md](docs/INSTALLATION.md) · Query patterns: [docs/CHEATSHEET.md](docs/CHEATSHEET.md)
255
198
 
256
- 1. **Structure is authoritative** — The AST-derived graph is the source of truth.
257
- 2. **Semantics accelerate, never decide** — Embeddings seed and rank retrieval but never invent structure.
258
- 3. **Everything is traceable** — Nodes and edges map to concrete files and line numbers.
259
- 4. **Determinism over heuristics** — Identical input yields identical output.
260
- 5. **Composable artifacts** — SQLite for structure, LanceDB for vectors, Markdown/JSON for consumption.
199
+ ---
200
+
201
+ ## What Agents Say
261
202
 
262
- **Full architecture documentation:** [docs/Architecture.md](docs/Architecture.md)
203
+ *From independent assessments run against PyCodeKG's own codebase. See [assessments/](assessments/) for full reports.*
263
204
 
264
- ---
205
+ > "PyCodeKG compresses a multi-step workflow — semantic search, graph expansion, caller tracing, snippet retrieval, and architectural summarization — into a small set of tools that are fast to invoke and easy to chain. In practice, it let me move from broad orientation to intent-driven discovery and then to structural validation without dropping down into manual grep or repeated file reads."
206
+ > — GPT-5 (via Cline)
265
207
 
266
- ## Contribution Checklist
208
+ > "What sets it apart from 'search the repo with embeddings' tools is the structural layer… Verdict: 4.5/5 — recommend without reservation for any non-trivial Python codebase."
209
+ > — Claude Opus 4.7
267
210
 
268
- When changing MCP tools in `src/pycode_kg/mcp_server.py` (signature, params, defaults, or behavior), update all three in the same commit:
211
+ > "PyCodeKG is dramatically more effective than traditional grep/file-reading workflows. Unique value: hybrid search combining natural-language intent with precise structural relationships."
212
+ > — Claude Haiku 4.5
269
213
 
270
- - Module docstring `Tools` list at the top of `src/pycode_kg/mcp_server.py`
271
- - `mcp = FastMCP(..., instructions=(...))` tool descriptions in `src/pycode_kg/mcp_server.py`
272
- - The runtime tool implementation and `:param:` docstrings
214
+ > "`pack_snippets()` provided source excerpts around each hit, making the code instantly readable. Context lines and relevance metadata obviated manual file open."
215
+ > Raptor Mini
273
216
 
274
217
  ---
275
218
 
@@ -281,7 +224,7 @@ If you use PyCodeKG in your research or project, please cite it:
281
224
 
282
225
  **APA**
283
226
 
284
- > Suchanek, E. G. (2026). *PyCodeKG: Semantic Knowledge Graph for Python Codebases* (Version 0.15.0) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.PLACEHOLDER
227
+ > Suchanek, E. G. (2026). *PyCodeKG: Semantic Knowledge Graph for Python Codebases* (Version 0.18.0) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.19834777
285
228
 
286
229
  **BibTeX**
287
230
 
@@ -289,11 +232,11 @@ If you use PyCodeKG in your research or project, please cite it:
289
232
  @software{suchanek_pycode_kg,
290
233
  author = {Suchanek, Eric G.},
291
234
  title = {{PyCodeKG}: Semantic Knowledge Graph for Python Codebases},
292
- version = {0.15.0},
235
+ version = {0.18.0},
293
236
  year = {2026},
294
237
  publisher = {Flux-Frontiers},
295
238
  url = {https://github.com/Flux-Frontiers/pycode_kg},
296
- doi = {10.5281/zenodo.PLACEHOLDER},
239
+ doi = {10.5281/zenodo.19834777},
297
240
  }
298
241
  ```
299
242
 
@@ -301,5 +244,5 @@ If you use PyCodeKG in your research or project, please cite it:
301
244
 
302
245
  ## License
303
246
 
304
- [Elastic License 2.0](https://www.elastic.co/licensing/elastic-license) — see [LICENSE](LICENSE).
247
+ [Elastic License 2.0](https://www.elastic.co/licensing/elastic-license) — free for non-commercial and internal use; commercial redistribution or hosting requires a license from Flux-Frontiers.
305
248
 
@@ -0,0 +1,174 @@
1
+
2
+ <p align="center">
3
+ <img src="assets/logos/pycodeKG.PNG" alt="PyCodeKG" width="200"/>
4
+ </p>
5
+
6
+ [![Python](https://img.shields.io/badge/python-3.12%20%7C%203.13-blue.svg)](https://www.python.org/)
7
+ [![License: Elastic-2.0](https://img.shields.io/badge/License-Elastic%202.0-blue.svg)](https://www.elastic.co/licensing/elastic-license)
8
+ [![Version](https://img.shields.io/badge/version-0.18.2-blue.svg)](https://github.com/Flux-Frontiers/pycode_kg/releases)
9
+ [![CI](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml/badge.svg)](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
10
+ [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/)
11
+ [![DOI](https://zenodo.org/badge/1202379010.svg)](https://zenodo.org/badge/latestdoi/1202379010)
12
+
13
+ **PyCodeKG** — A Deterministic Knowledge Graph for Python Codebases
14
+ with Semantic Indexing and Source-Grounded Snippet Packing
15
+
16
+ *Author: Eric G. Suchanek, PhD*
17
+ *Flux-Frontiers, Liberty TWP, OH*
18
+
19
+ [Technical Paper (PDF)](article/pycode_kg.pdf)
20
+
21
+ ---
22
+
23
+ ## Overview
24
+
25
+ PyCodeKG constructs a **deterministic, explainable knowledge graph** from a Python codebase using static analysis. The graph captures structural relationships — definitions, calls, imports, and inheritance — directly from the Python AST, stores them in SQLite, and augments retrieval with vector embeddings via LanceDB.
26
+
27
+ **No inference required.** The CLI is fully useful as a standalone analysis tool — every result is derived from structure, not generated. When used with AI agents, PyCodeKG gives them structurally-grounded answers: precise callers, real call chains, exact line numbers. Hallucination-resistant by design.
28
+
29
+ Structure is treated as **ground truth**; semantic search is strictly an acceleration layer. The result is a searchable, auditable representation of a codebase that supports precise navigation, contextual snippet extraction, and downstream reasoning without hallucination.
30
+
31
+ PyCodeKG uses the same architecture as [DocKG](https://github.com/Flux-Frontiers/doc_kg) but targets Python source code rather than document corpora.
32
+
33
+ ---
34
+
35
+ ## Features
36
+
37
+ - **Static analysis pipeline** — Three-pass AST extraction: structure, call graph, data-flow
38
+ - **Deterministic knowledge graph** — SQLite-backed canonical store with provenance-tracked edges
39
+ - **Symbol resolution** — `RESOLVES_TO` edges bridge cross-module call sites via import aliases
40
+ - **Hybrid query model** — Semantic seeding (LanceDB embeddings) + structural expansion (graph traversal)
41
+ - **Source-grounded snippet packing** — Definition and call-site snippets with line numbers
42
+ - **Precise fan-in lookup** — Two-phase reverse traversal resolving cross-module caller chains
43
+ - **Temporal snapshots** — Save and diff graph metrics across commits and versions
44
+ - **MCP server** — Nineteen tools for AI agent integration
45
+ - **Streamlit web app** — Interactive graph browser, hybrid query UI, snippet pack explorer
46
+ - **3-D visualizer** — PyVista/PyQt5 interactive graph explorer with FunnelLayout and timeline view
47
+ - **Zero-config MCP setup** — Single-line installer configures Claude Code, Kilo Code, GitHub Copilot, and Cline
48
+
49
+ ---
50
+
51
+ ## Installation
52
+
53
+ **Requirements:** Python ≥ 3.12, < 3.14
54
+
55
+ ```bash
56
+ # pip
57
+ pip install pycode-kg
58
+
59
+ # With Streamlit web visualizer
60
+ pip install 'pycode-kg[viz]'
61
+
62
+ # With 3-D visualizer (PyVista/PyQt5)
63
+ pip install 'pycode-kg[viz3d]'
64
+
65
+ # Poetry
66
+ poetry add pycode-kg
67
+ ```
68
+
69
+ > For the one-line skill installer (MCP config, Claude slash commands, git hooks) see [docs/INSTALLATION.md](docs/INSTALLATION.md).
70
+
71
+ ---
72
+
73
+ ## Quick Start
74
+
75
+ ```bash
76
+ # Index your repo (SQLite + LanceDB in one step)
77
+ pycodekg build --repo /path/to/repo
78
+
79
+ # Natural-language query
80
+ pycodekg query "authentication flow"
81
+
82
+ # Source-grounded snippet pack — paste straight into an LLM prompt
83
+ pycodekg pack "database connection setup" --format md --out context.md
84
+
85
+ # Full architectural analysis
86
+ pycodekg analyze /path/to/repo
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Usage
92
+
93
+ ### Build and query
94
+
95
+ ```bash
96
+ pycodekg build --repo . # full build (SQLite + LanceDB)
97
+ pycodekg build --repo . --include-dir src # index a specific subtree
98
+ pycodekg query "snapshot freshness comparison" # hybrid semantic + structural search
99
+ pycodekg pack "graph build pipeline" --format md # snippet pack for LLM context
100
+ ```
101
+
102
+ ### Analyze codebase health
103
+
104
+ ```bash
105
+ pycodekg analyze . # full report + JSON snapshot
106
+ ```
107
+
108
+ ### Snapshots
109
+
110
+ ```bash
111
+ pycodekg snapshot save 0.18.0 # capture current metrics
112
+ pycodekg snapshot list # list all snapshots
113
+ pycodekg snapshot diff <key_a> <key_b> # compare two versions
114
+ ```
115
+
116
+ ### Visualize
117
+
118
+ ```bash
119
+ pycodekg viz # Streamlit web app
120
+ pycodekg viz3d --layout funnel # 3-D PyVista explorer
121
+ pycodekg viz-timeline # metric history timeline
122
+ ```
123
+
124
+ > Full flag reference: [docs/INSTALLATION.md](docs/INSTALLATION.md) · Query patterns: [docs/CHEATSHEET.md](docs/CHEATSHEET.md)
125
+
126
+ ---
127
+
128
+ ## What Agents Say
129
+
130
+ *From independent assessments run against PyCodeKG's own codebase. See [assessments/](assessments/) for full reports.*
131
+
132
+ > "PyCodeKG compresses a multi-step workflow — semantic search, graph expansion, caller tracing, snippet retrieval, and architectural summarization — into a small set of tools that are fast to invoke and easy to chain. In practice, it let me move from broad orientation to intent-driven discovery and then to structural validation without dropping down into manual grep or repeated file reads."
133
+ > — GPT-5 (via Cline)
134
+
135
+ > "What sets it apart from 'search the repo with embeddings' tools is the structural layer… Verdict: 4.5/5 — recommend without reservation for any non-trivial Python codebase."
136
+ > — Claude Opus 4.7
137
+
138
+ > "PyCodeKG is dramatically more effective than traditional grep/file-reading workflows. Unique value: hybrid search combining natural-language intent with precise structural relationships."
139
+ > — Claude Haiku 4.5
140
+
141
+ > "`pack_snippets()` provided source excerpts around each hit, making the code instantly readable. Context lines and relevance metadata obviated manual file open."
142
+ > — Raptor Mini
143
+
144
+ ---
145
+
146
+ ## Citation
147
+
148
+ If you use PyCodeKG in your research or project, please cite it:
149
+
150
+ [![DOI](https://zenodo.org/badge/1202379010.svg)](https://zenodo.org/badge/latestdoi/1202379010)
151
+
152
+ **APA**
153
+
154
+ > Suchanek, E. G. (2026). *PyCodeKG: Semantic Knowledge Graph for Python Codebases* (Version 0.18.0) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.19834777
155
+
156
+ **BibTeX**
157
+
158
+ ```bibtex
159
+ @software{suchanek_pycode_kg,
160
+ author = {Suchanek, Eric G.},
161
+ title = {{PyCodeKG}: Semantic Knowledge Graph for Python Codebases},
162
+ version = {0.18.0},
163
+ year = {2026},
164
+ publisher = {Flux-Frontiers},
165
+ url = {https://github.com/Flux-Frontiers/pycode_kg},
166
+ doi = {10.5281/zenodo.19834777},
167
+ }
168
+ ```
169
+
170
+ ---
171
+
172
+ ## License
173
+
174
+ [Elastic License 2.0](https://www.elastic.co/licensing/elastic-license) — free for non-commercial and internal use; commercial redistribution or hosting requires a license from Flux-Frontiers.
@@ -66,7 +66,7 @@ ruff = ">=0.4.0"
66
66
  # ---------------------------------------------------------------------------
67
67
  [project]
68
68
  name = "pycode-kg"
69
- version = "0.17.2"
69
+ version = "0.18.2"
70
70
  description = "A tool to build a searchable knowledge graph from Python repositories"
71
71
  readme = "README.md"
72
72
  license = "Elastic-2.0"
@@ -32,7 +32,7 @@ KGModule SDK (build new domain KGs)::
32
32
  from pycode_kg import KGModule, KGExtractor, PyCodeKGExtractor, NodeSpec, EdgeSpec
33
33
  """
34
34
 
35
- __version__ = "0.17.2"
35
+ __version__ = "0.18.2"
36
36
  __author__ = "Eric G. Suchanek, PhD"
37
37
 
38
38
  # Low-level primitives (locked v0 contract)
@@ -5,6 +5,7 @@ For well-modularized codebases, identifies orchestrator and hub modules.
5
5
 
6
6
  Author: Eric G. Suchanek, PhD
7
7
  Last Revision: 2026-03-12 17:30:35
8
+ License: Elastic 2.0
8
9
  """
9
10
 
10
11
  import sqlite3
@@ -14,8 +15,11 @@ from pycode_kg.analysis.centrality import CentralityRecord, StructuralImportance
14
15
 
15
16
 
16
17
  def compute_bridge_centrality(
17
- kind="module", include_imports=True, top=25, db_path="pycodekg.sqlite"
18
- ):
18
+ kind: str = "module",
19
+ include_imports: bool = True,
20
+ top: int = 25,
21
+ db_path: str = "pycodekg.sqlite",
22
+ ) -> list[tuple[str, float]]:
19
23
  """
20
24
  Compute module connectivity: unique module interactions per module.
21
25
 
@@ -112,6 +112,13 @@ class StructuralImportanceRanker:
112
112
  """
113
113
 
114
114
  def __init__(self, db_path: str | Path, config: CentralityConfig | None = None) -> None:
115
+ """Bind the ranker to a SQLite graph and (optional) tuning config.
116
+
117
+ :param db_path: Path to the PyCodeKG SQLite knowledge graph.
118
+ :param config: Override default relation weights, damping, iteration
119
+ cap, tolerance, cross-module boost, or private-symbol penalty.
120
+ Pass ``None`` for the package defaults (see ``CentralityConfig``).
121
+ """
115
122
  self.db_path = Path(db_path)
116
123
  self.config = config or CentralityConfig()
117
124
 
@@ -204,6 +211,7 @@ class StructuralImportanceRanker:
204
211
  return len(rows)
205
212
 
206
213
  def _load_nodes(self) -> dict[str, _NodeInfo]:
214
+ """Load real graph nodes (modules, classes, functions, methods) from SQLite, keyed by node id. ``sym:`` stubs are excluded."""
207
215
  with sqlite3.connect(self.db_path) as con:
208
216
  rows = con.execute(
209
217
  """
@@ -221,6 +229,11 @@ class StructuralImportanceRanker:
221
229
  self,
222
230
  node_map: dict[str, _NodeInfo],
223
231
  ) -> list[_EffectiveEdge]:
232
+ """Load structural edges (CALLS / INHERITS / IMPORTS / CONTAINS) and rewrite ``sym:`` targets through ``RESOLVES_TO``.
233
+
234
+ Returns deduplicated edges weighted by relation type, with cross-module
235
+ edges receiving an additional boost from ``config.cross_module_boost``.
236
+ """
224
237
  with sqlite3.connect(self.db_path) as con:
225
238
  structural = con.execute(
226
239
  """
@@ -280,6 +293,13 @@ class StructuralImportanceRanker:
280
293
  node_map: dict[str, _NodeInfo],
281
294
  effective_edges: list[_EffectiveEdge],
282
295
  ) -> dict[str, float]:
296
+ """Run weighted PageRank on the resolved edge set until convergence.
297
+
298
+ Iterates up to ``config.max_iter`` with damping ``config.damping``,
299
+ redistributing dangling-node mass uniformly. After convergence, names
300
+ starting with ``_`` are scaled by ``config.private_penalty`` and the
301
+ result is normalized so all scores sum to ``1.0``.
302
+ """
283
303
  nodes = list(node_map)
284
304
  n = len(nodes)
285
305
  if n == 0:
@@ -329,6 +349,7 @@ class StructuralImportanceRanker:
329
349
  effective_edges: list[_EffectiveEdge],
330
350
  scores: dict[str, float],
331
351
  ) -> list[CentralityRecord]:
352
+ """Combine PageRank scores with inbound counts, per-relation breakdowns, and top contributing callers into rank-ordered ``CentralityRecord`` outputs."""
332
353
  inbound_counts: dict[str, int] = defaultdict(int)
333
354
  cross_counts: dict[str, int] = defaultdict(int)
334
355
  rel_breakdown: dict[str, dict[str, int]] = defaultdict(lambda: defaultdict(int))
@@ -1,6 +1,10 @@
1
1
  """
2
2
  Framework Detector for PyCodeKG.
3
3
  Identifies repo-defining abstractions using centrality and cross-module signals.
4
+
5
+ Author: Eric G. Suchanek, PhD
6
+ Last Revision: 2026-03-12 17:30:35
7
+ License: Elastic 2.0
4
8
  """
5
9
 
6
10
  import sqlite3
@@ -33,7 +37,9 @@ _BOILERPLATE_NAMES: frozenset[str] = frozenset(
33
37
  )
34
38
 
35
39
 
36
- def detect_framework_nodes(limit=25, db_path="pycodekg.sqlite"):
40
+ def detect_framework_nodes(
41
+ limit: int = 25, db_path: str = "pycodekg.sqlite"
42
+ ) -> list[tuple[str, float, str]]:
37
43
  """
38
44
  Detect framework-like nodes using SIR and module connectivity.
39
45
 
@@ -8,6 +8,7 @@ from pycode_kg.analysis.bridge import compute_bridge_centrality
8
8
 
9
9
 
10
10
  def main():
11
+ """CLI entry point: parse args and print top bridge modules by connectivity score to stdout."""
11
12
  parser = argparse.ArgumentParser(
12
13
  description="Show top bridge modules by betweenness centrality."
13
14
  )
@@ -8,6 +8,7 @@ from pycode_kg.analysis.framework_detector import detect_framework_nodes
8
8
 
9
9
 
10
10
  def main():
11
+ """CLI entry point: parse args and print top framework-like modules (high SIR + high connectivity) to stdout."""
11
12
  parser = argparse.ArgumentParser(description="Show top framework-like modules.")
12
13
  parser.add_argument("--db", default="pycodekg.sqlite", help="Path to PyCodeKG SQLite DB")
13
14
  parser.add_argument("--top", type=int, default=25, help="Number of top framework nodes to show")
@@ -88,13 +88,13 @@ def viz(db: str, port: str, no_browser: bool) -> None:
88
88
  )
89
89
  @click.option(
90
90
  "--layout",
91
- type=click.Choice(["allium", "cake"]),
91
+ type=click.Choice(["allium", "funnel"]),
92
92
  default="allium",
93
93
  show_default=True,
94
94
  help=(
95
95
  "3-D layout strategy. "
96
96
  "'allium' renders each module as a Giant Allium plant; "
97
- "'cake' stratifies nodes by kind across Z layers."
97
+ "'funnel' stratifies nodes by kind across Z layers."
98
98
  ),
99
99
  )
100
100
  @click.option(