pycode-kg 0.18.1__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.
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/PKG-INFO +21 -35
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/README.md +20 -34
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/pyproject.toml +1 -1
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/__init__.py +1 -1
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/analysis/centrality.py +21 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_bridges.py +1 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_framework_nodes.py +1 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/ranking/cli_rank.py +2 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/snapshots.py +12 -0
- pycode_kg-0.18.1/src/pycode_kg/mcp/bridge_tools.py +0 -19
- pycode_kg-0.18.1/src/pycode_kg/mcp/framework_tools.py +0 -18
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/LICENSE +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/.DS_Store +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/__main__.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/analysis/__init__.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/analysis/bridge.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/analysis/framework_detector.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/analysis/hybrid_rank.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/app.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/architecture.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/build_pycodekg_lancedb.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/build_pycodekg_sqlite.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/__init__.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_analyze.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_architecture.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_build.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_build_full.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_centrality.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_explain.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_hooks.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_init.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_mcp.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_model.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_query.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_snapshot.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/cmd_viz.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/main.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/cli/options.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/config.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/graph.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/index.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/kg.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/layout3d.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/mcp_server.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/module/__init__.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/module/base.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/module/extractor.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/module/types.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_query.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_snippet_packer.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_thorough_analysis.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_viz.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/pycodekg_viz3d.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/ranking/__init__.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/ranking/coderank.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/sql/004_add_centrality_table.sql +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/store.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/utils.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/visitor.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/viz3d.py +0 -0
- {pycode_kg-0.18.1 → pycode_kg-0.18.2}/src/pycode_kg/viz3d_timeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycode-kg
|
|
3
|
-
Version: 0.18.
|
|
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
|
|
@@ -78,7 +78,7 @@ Description-Content-Type: text/markdown
|
|
|
78
78
|
|
|
79
79
|
[](https://www.python.org/)
|
|
80
80
|
[](https://www.elastic.co/licensing/elastic-license)
|
|
81
|
-
[](https://github.com/Flux-Frontiers/pycode_kg/releases)
|
|
82
82
|
[](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
|
|
83
83
|
[](https://python-poetry.org/)
|
|
84
84
|
[](https://zenodo.org/badge/latestdoi/1202379010)
|
|
@@ -114,31 +114,13 @@ PyCodeKG uses the same architecture as [DocKG](https://github.com/Flux-Frontiers
|
|
|
114
114
|
- **Source-grounded snippet packing** — Definition and call-site snippets with line numbers
|
|
115
115
|
- **Precise fan-in lookup** — Two-phase reverse traversal resolving cross-module caller chains
|
|
116
116
|
- **Temporal snapshots** — Save and diff graph metrics across commits and versions
|
|
117
|
-
- **MCP server** —
|
|
117
|
+
- **MCP server** — Nineteen tools for AI agent integration
|
|
118
118
|
- **Streamlit web app** — Interactive graph browser, hybrid query UI, snippet pack explorer
|
|
119
119
|
- **3-D visualizer** — PyVista/PyQt5 interactive graph explorer with FunnelLayout and timeline view
|
|
120
120
|
- **Zero-config MCP setup** — Single-line installer configures Claude Code, Kilo Code, GitHub Copilot, and Cline
|
|
121
121
|
|
|
122
122
|
---
|
|
123
123
|
|
|
124
|
-
## Quick Start
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
# Index your repo (SQLite + LanceDB in one step)
|
|
128
|
-
pycodekg build --repo /path/to/repo
|
|
129
|
-
|
|
130
|
-
# Natural-language query
|
|
131
|
-
pycodekg query "authentication flow"
|
|
132
|
-
|
|
133
|
-
# Source-grounded snippet pack — paste straight into an LLM prompt
|
|
134
|
-
pycodekg pack "database connection setup" --format md --out context.md
|
|
135
|
-
|
|
136
|
-
# Full architectural analysis
|
|
137
|
-
pycodekg analyze /path/to/repo
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
124
|
## Installation
|
|
143
125
|
|
|
144
126
|
**Requirements:** Python ≥ 3.12, < 3.14
|
|
@@ -161,6 +143,24 @@ poetry add pycode-kg
|
|
|
161
143
|
|
|
162
144
|
---
|
|
163
145
|
|
|
146
|
+
## Quick Start
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Index your repo (SQLite + LanceDB in one step)
|
|
150
|
+
pycodekg build --repo /path/to/repo
|
|
151
|
+
|
|
152
|
+
# Natural-language query
|
|
153
|
+
pycodekg query "authentication flow"
|
|
154
|
+
|
|
155
|
+
# Source-grounded snippet pack — paste straight into an LLM prompt
|
|
156
|
+
pycodekg pack "database connection setup" --format md --out context.md
|
|
157
|
+
|
|
158
|
+
# Full architectural analysis
|
|
159
|
+
pycodekg analyze /path/to/repo
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
164
|
## Usage
|
|
165
165
|
|
|
166
166
|
### Build and query
|
|
@@ -198,20 +198,6 @@ pycodekg viz-timeline # metric history timeline
|
|
|
198
198
|
|
|
199
199
|
---
|
|
200
200
|
|
|
201
|
-
## MCP Integration
|
|
202
|
-
|
|
203
|
-
Start the MCP server, then wire it into your AI agent:
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
pycodekg mcp --repo /path/to/repo
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
PyCodeKG exposes seventeen tools covering hybrid search, snippet packing, caller tracing, architectural analysis, and temporal snapshots. Any MCP-compatible agent — Claude Code, Claude Desktop, Cursor, Continue, GitHub Copilot — can consume them directly.
|
|
210
|
-
|
|
211
|
-
> Full provider setup, tool reference, and SSE transport: [docs/MCP.md](docs/MCP.md)
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
201
|
## What Agents Say
|
|
216
202
|
|
|
217
203
|
*From independent assessments run against PyCodeKG's own codebase. See [assessments/](assessments/) for full reports.*
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
[](https://www.python.org/)
|
|
7
7
|
[](https://www.elastic.co/licensing/elastic-license)
|
|
8
|
-
[](https://github.com/Flux-Frontiers/pycode_kg/releases)
|
|
9
9
|
[](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
|
|
10
10
|
[](https://python-poetry.org/)
|
|
11
11
|
[](https://zenodo.org/badge/latestdoi/1202379010)
|
|
@@ -41,31 +41,13 @@ PyCodeKG uses the same architecture as [DocKG](https://github.com/Flux-Frontiers
|
|
|
41
41
|
- **Source-grounded snippet packing** — Definition and call-site snippets with line numbers
|
|
42
42
|
- **Precise fan-in lookup** — Two-phase reverse traversal resolving cross-module caller chains
|
|
43
43
|
- **Temporal snapshots** — Save and diff graph metrics across commits and versions
|
|
44
|
-
- **MCP server** —
|
|
44
|
+
- **MCP server** — Nineteen tools for AI agent integration
|
|
45
45
|
- **Streamlit web app** — Interactive graph browser, hybrid query UI, snippet pack explorer
|
|
46
46
|
- **3-D visualizer** — PyVista/PyQt5 interactive graph explorer with FunnelLayout and timeline view
|
|
47
47
|
- **Zero-config MCP setup** — Single-line installer configures Claude Code, Kilo Code, GitHub Copilot, and Cline
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
51
|
-
## Quick Start
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
# Index your repo (SQLite + LanceDB in one step)
|
|
55
|
-
pycodekg build --repo /path/to/repo
|
|
56
|
-
|
|
57
|
-
# Natural-language query
|
|
58
|
-
pycodekg query "authentication flow"
|
|
59
|
-
|
|
60
|
-
# Source-grounded snippet pack — paste straight into an LLM prompt
|
|
61
|
-
pycodekg pack "database connection setup" --format md --out context.md
|
|
62
|
-
|
|
63
|
-
# Full architectural analysis
|
|
64
|
-
pycodekg analyze /path/to/repo
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
51
|
## Installation
|
|
70
52
|
|
|
71
53
|
**Requirements:** Python ≥ 3.12, < 3.14
|
|
@@ -88,6 +70,24 @@ poetry add pycode-kg
|
|
|
88
70
|
|
|
89
71
|
---
|
|
90
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
91
|
## Usage
|
|
92
92
|
|
|
93
93
|
### Build and query
|
|
@@ -125,20 +125,6 @@ pycodekg viz-timeline # metric history timeline
|
|
|
125
125
|
|
|
126
126
|
---
|
|
127
127
|
|
|
128
|
-
## MCP Integration
|
|
129
|
-
|
|
130
|
-
Start the MCP server, then wire it into your AI agent:
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
pycodekg mcp --repo /path/to/repo
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
PyCodeKG exposes seventeen tools covering hybrid search, snippet packing, caller tracing, architectural analysis, and temporal snapshots. Any MCP-compatible agent — Claude Code, Claude Desktop, Cursor, Continue, GitHub Copilot — can consume them directly.
|
|
137
|
-
|
|
138
|
-
> Full provider setup, tool reference, and SSE transport: [docs/MCP.md](docs/MCP.md)
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
128
|
## What Agents Say
|
|
143
129
|
|
|
144
130
|
*From independent assessments run against PyCodeKG's own codebase. See [assessments/](assessments/) for full reports.*
|
|
@@ -66,7 +66,7 @@ ruff = ">=0.4.0"
|
|
|
66
66
|
# ---------------------------------------------------------------------------
|
|
67
67
|
[project]
|
|
68
68
|
name = "pycode-kg"
|
|
69
|
-
version = "0.18.
|
|
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.18.
|
|
35
|
+
__version__ = "0.18.2"
|
|
36
36
|
__author__ = "Eric G. Suchanek, PhD"
|
|
37
37
|
|
|
38
38
|
# Low-level primitives (locked v0 contract)
|
|
@@ -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))
|
|
@@ -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")
|
|
@@ -16,6 +16,7 @@ from .coderank import (
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
19
|
+
"""Parse CodeRank CLI arguments. Pass ``argv`` to override ``sys.argv`` (used in tests)."""
|
|
19
20
|
parser = argparse.ArgumentParser(description="Compute CodeRank metrics for PyCodeKG graphs.")
|
|
20
21
|
parser.add_argument("--sqlite", required=True, help="Path to PyCodeKG SQLite graph.")
|
|
21
22
|
parser.add_argument("--top", type=int, default=25, help="Number of top results to print.")
|
|
@@ -43,6 +44,7 @@ def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
def main(argv: Sequence[str] | None = None) -> int:
|
|
47
|
+
"""CLI entry point: compute CodeRank scores, optionally persist them to ``node_metrics``, and print the top results as plain text or JSON. Returns the process exit code."""
|
|
46
48
|
args = parse_args(argv)
|
|
47
49
|
sqlite_path = Path(args.sqlite)
|
|
48
50
|
if not sqlite_path.exists():
|
|
@@ -269,6 +269,15 @@ class SnapshotManager(_BaseSnapshotManager):
|
|
|
269
269
|
db_path: Path | str | None = None,
|
|
270
270
|
package_name: str = "pycode-kg",
|
|
271
271
|
) -> None:
|
|
272
|
+
"""Initialize the manager rooted at ``snapshots_dir``.
|
|
273
|
+
|
|
274
|
+
:param snapshots_dir: Directory where snapshot JSON files live; created
|
|
275
|
+
on first save if it does not exist.
|
|
276
|
+
:param db_path: PyCodeKG SQLite graph path; required for collecting
|
|
277
|
+
per-module node counts during ``capture()``. Optional otherwise.
|
|
278
|
+
:param package_name: Package name used for version detection in saved
|
|
279
|
+
snapshots. Defaults to ``"pycode-kg"``.
|
|
280
|
+
"""
|
|
272
281
|
super().__init__(snapshots_dir, package_name=package_name, db_path=db_path)
|
|
273
282
|
|
|
274
283
|
# ------------------------------------------------------------------
|
|
@@ -457,14 +466,17 @@ class SnapshotManager(_BaseSnapshotManager):
|
|
|
457
466
|
# ------------------------------------------------------------------
|
|
458
467
|
|
|
459
468
|
def load_snapshot(self, key: str) -> Snapshot | None: # type: ignore[override]
|
|
469
|
+
"""Load a snapshot by key and re-wrap it as a pycode-kg ``Snapshot`` with typed-accessor properties. Returns ``None`` if no snapshot matches."""
|
|
460
470
|
snap = super().load_snapshot(key)
|
|
461
471
|
return _rewrap(snap) if snap is not None else None
|
|
462
472
|
|
|
463
473
|
def get_previous(self, key: str) -> Snapshot | None: # type: ignore[override]
|
|
474
|
+
"""Return the snapshot immediately preceding ``key`` in manifest chronology, re-wrapped as a pycode-kg ``Snapshot``. ``None`` when ``key`` is the earliest."""
|
|
464
475
|
snap = super().get_previous(key)
|
|
465
476
|
return _rewrap(snap) if snap is not None else None
|
|
466
477
|
|
|
467
478
|
def get_baseline(self) -> Snapshot | None: # type: ignore[override]
|
|
479
|
+
"""Return the earliest (baseline) snapshot in the manifest, re-wrapped as a pycode-kg ``Snapshot``. ``None`` if no snapshots exist."""
|
|
468
480
|
snap = super().get_baseline()
|
|
469
481
|
return _rewrap(snap) if snap is not None else None
|
|
470
482
|
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
MCP tool hooks for bridge centrality in PyCodeKG.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
# Placeholder for MCP integration
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def top_bridges(kind="module", limit=20):
|
|
9
|
-
from pycode_kg.analysis.bridge import ( # pylint: disable=import-outside-toplevel
|
|
10
|
-
compute_bridge_centrality,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
bridges = compute_bridge_centrality(kind=kind, top=limit)
|
|
14
|
-
return bridges
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def why_bridge(node_id):
|
|
18
|
-
# TODO: Explain why a node is a bridge
|
|
19
|
-
pass
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
MCP tool hooks for framework node detection in PyCodeKG.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
# Placeholder for MCP integration
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def detect_framework_nodes(limit=20):
|
|
9
|
-
from pycode_kg.analysis.framework_detector import ( # pylint: disable=import-outside-toplevel
|
|
10
|
-
detect_framework_nodes as detect_fw,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
return detect_fw(limit=limit)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def why_framework_node(node_id):
|
|
17
|
-
# TODO: Explain why a node is a framework node
|
|
18
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|