pycode-kg 0.19.1__tar.gz → 0.19.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 (66) hide show
  1. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/PKG-INFO +4 -5
  2. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/pyproject.toml +4 -10
  3. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/__init__.py +1 -1
  4. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_build.py +11 -5
  5. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_build_full.py +12 -6
  6. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_init.py +1 -1
  7. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_model.py +1 -1
  8. pycode_kg-0.19.2/src/pycode_kg/index.py +11 -0
  9. pycode_kg-0.19.2/src/pycode_kg/module/base.py +33 -0
  10. pycode_kg-0.19.2/src/pycode_kg/module/extractor.py +127 -0
  11. pycode_kg-0.19.2/src/pycode_kg/module/types.py +31 -0
  12. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/pycodekg.py +2 -1
  13. pycode_kg-0.19.2/src/pycode_kg/store.py +7 -0
  14. pycode_kg-0.19.1/src/pycode_kg/index.py +0 -575
  15. pycode_kg-0.19.1/src/pycode_kg/module/base.py +0 -720
  16. pycode_kg-0.19.1/src/pycode_kg/module/extractor.py +0 -276
  17. pycode_kg-0.19.1/src/pycode_kg/module/types.py +0 -532
  18. pycode_kg-0.19.1/src/pycode_kg/store.py +0 -766
  19. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/LICENSE +0 -0
  20. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/README.md +0 -0
  21. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/.DS_Store +0 -0
  22. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/__main__.py +0 -0
  23. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/analysis/__init__.py +0 -0
  24. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/analysis/bridge.py +0 -0
  25. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/analysis/centrality.py +0 -0
  26. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/analysis/framework_detector.py +0 -0
  27. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/analysis/hybrid_rank.py +0 -0
  28. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/app.py +0 -0
  29. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/architecture.py +0 -0
  30. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/build_pycodekg_lancedb.py +0 -0
  31. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/build_pycodekg_sqlite.py +0 -0
  32. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/__init__.py +0 -0
  33. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_analyze.py +0 -0
  34. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_architecture.py +0 -0
  35. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_bridges.py +0 -0
  36. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_centrality.py +0 -0
  37. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_explain.py +0 -0
  38. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_framework_nodes.py +0 -0
  39. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_hooks.py +0 -0
  40. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_mcp.py +0 -0
  41. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_query.py +0 -0
  42. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_snapshot.py +0 -0
  43. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/cmd_viz.py +0 -0
  44. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/main.py +0 -0
  45. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/cli/options.py +0 -0
  46. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/config.py +0 -0
  47. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/explain.py +0 -0
  48. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/graph.py +0 -0
  49. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/kg.py +0 -0
  50. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/layout3d.py +0 -0
  51. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/mcp_server.py +0 -0
  52. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/module/__init__.py +0 -0
  53. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/pycodekg_query.py +0 -0
  54. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/pycodekg_snippet_packer.py +0 -0
  55. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/pycodekg_thorough_analysis.py +0 -0
  56. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/pycodekg_viz.py +0 -0
  57. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/pycodekg_viz3d.py +0 -0
  58. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/ranking/__init__.py +0 -0
  59. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/ranking/cli_rank.py +0 -0
  60. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/ranking/coderank.py +0 -0
  61. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/snapshots.py +0 -0
  62. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/sql/004_add_centrality_table.sql +0 -0
  63. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/utils.py +0 -0
  64. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/visitor.py +0 -0
  65. {pycode_kg-0.19.1 → pycode_kg-0.19.2}/src/pycode_kg/viz3d.py +0 -0
  66. {pycode_kg-0.19.1 → pycode_kg-0.19.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.19.1
3
+ Version: 0.19.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
@@ -25,10 +25,9 @@ Requires-Dist: PyQt5 (>=5.15.0) ; extra == "viz3d"
25
25
  Requires-Dist: click (>=8.1.0,<9)
26
26
  Requires-Dist: detect-secrets (>=1.5.0) ; extra == "all"
27
27
  Requires-Dist: detect-secrets (>=1.5.0) ; extra == "dev"
28
- Requires-Dist: doc-kg (>=0.11.0) ; extra == "dev"
29
- Requires-Dist: doc-kg (>=0.11.0) ; extra == "kgdeps"
30
- Requires-Dist: kgmodule-utils (>=0.2.1)
31
- Requires-Dist: lancedb (>=0.29.0)
28
+ Requires-Dist: doc-kg (>=0.15.2) ; extra == "dev"
29
+ Requires-Dist: doc-kg (>=0.15.2) ; extra == "kgdeps"
30
+ Requires-Dist: kgmodule-utils[semantic] (>=0.3.1)
32
31
  Requires-Dist: markdown (>=3.6) ; extra == "all"
33
32
  Requires-Dist: markdown (>=3.6) ; extra == "viz3d"
34
33
  Requires-Dist: mcp (>=1.0.0)
@@ -43,11 +43,6 @@
43
43
  requires = ["poetry-core>=2.0.0"]
44
44
  build-backend = "poetry.core.masonry.api"
45
45
 
46
- [[tool.poetry.source]]
47
- name = "testpypi"
48
- url = "https://test.pypi.org/simple/"
49
- priority = "supplemental"
50
-
51
46
  [tool.poetry]
52
47
  packages = [{ include = "pycode_kg", from = "src" }]
53
48
 
@@ -66,7 +61,7 @@ ruff = ">=0.4.0"
66
61
  # ---------------------------------------------------------------------------
67
62
  [project]
68
63
  name = "pycode-kg"
69
- version = "0.19.1"
64
+ version = "0.19.2"
70
65
  description = "A tool to build a searchable knowledge graph from Python repositories"
71
66
  readme = "README.md"
72
67
  license = "Elastic-2.0"
@@ -86,7 +81,6 @@ classifiers = [
86
81
  requires-python = ">=3.12,<3.14"
87
82
  dependencies = [
88
83
  "click>=8.1.0,<9",
89
- "lancedb>=0.29.0",
90
84
  "mcp>=1.0.0",
91
85
  "numpy>=1.24.0",
92
86
  "pandas>=2.0.0",
@@ -95,7 +89,7 @@ dependencies = [
95
89
  "sentence-transformers>=5.4.1",
96
90
  "torch>=2.5.1",
97
91
  "transformers>=4.40.0,<4.57",
98
- "kgmodule-utils>=0.2.1",
92
+ "kgmodule-utils[semantic]>=0.3.1",
99
93
  ]
100
94
 
101
95
  [project.optional-dependencies]
@@ -108,7 +102,7 @@ dev = [
108
102
  "pytest>=8.0.0",
109
103
  "pytest-cov>=5.0.0",
110
104
  "ruff>=0.4.0",
111
- "doc-kg>=0.11.0",
105
+ "doc-kg>=0.15.2",
112
106
  # agent-kg not yet on PyPI — install manually: pip install git+https://github.com/Flux-Frontiers/agent_kg.git
113
107
  ]
114
108
  viz = [
@@ -127,7 +121,7 @@ viz3d = [
127
121
 
128
122
  # note that dockg is on pypi; agent-kg is not yet — install manually from git
129
123
  kgdeps = [
130
- "doc-kg>=0.11.0",
124
+ "doc-kg>=0.15.2",
131
125
  ]
132
126
  all = [
133
127
  "detect-secrets>=1.5.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.19.1"
35
+ __version__ = "0.19.2"
36
36
  __author__ = "Eric G. Suchanek, PhD"
37
37
 
38
38
  # Low-level primitives (locked v0 contract)
@@ -16,12 +16,12 @@ import click
16
16
  from pycode_kg.cli.main import cli
17
17
  from pycode_kg.cli.options import exclude_option, include_option, repo_option
18
18
  from pycode_kg.config import load_exclude_dirs, load_include_dirs
19
- from pycode_kg.graph import CodeGraph
20
19
  from pycode_kg.index import (
21
20
  SemanticIndex,
22
21
  SentenceTransformerEmbedder,
23
22
  suppress_ingestion_logging,
24
23
  )
24
+ from pycode_kg.module.extractor import EdgeSpec, NodeSpec, PyCodeKGExtractor
25
25
  from pycode_kg.pycodekg import DEFAULT_MODEL
26
26
  from pycode_kg.store import GraphStore
27
27
 
@@ -53,19 +53,25 @@ def build_sqlite(
53
53
  include = load_include_dirs(repo_root) | set(include_dir)
54
54
  exclude = load_exclude_dirs(repo_root) | set(exclude_dir)
55
55
 
56
- graph = CodeGraph(
56
+ extractor = PyCodeKGExtractor(
57
57
  repo_root,
58
58
  include=include if include else None,
59
59
  exclude=exclude if exclude else None,
60
60
  )
61
- nodes, edges = graph.extract().result()
61
+ node_specs: list[NodeSpec] = []
62
+ edge_specs: list[EdgeSpec] = []
63
+ for item in extractor.extract():
64
+ if isinstance(item, NodeSpec):
65
+ node_specs.append(item)
66
+ else:
67
+ edge_specs.append(item)
62
68
 
63
69
  store = GraphStore(db_path)
64
- store.write(nodes, edges, wipe=wipe)
70
+ store.write(node_specs, edge_specs, wipe=wipe)
65
71
  resolved = store.resolve_symbols()
66
72
  store.close()
67
73
 
68
- print(f"OK: nodes={len(nodes)} edges={len(edges)} resolved={resolved} db={db_path}")
74
+ print(f"OK: nodes={len(node_specs)} edges={len(edge_specs)} resolved={resolved} db={db_path}")
69
75
 
70
76
 
71
77
  @cli.command("build-lancedb")
@@ -22,12 +22,12 @@ from pycode_kg.cli.options import (
22
22
  repo_option,
23
23
  )
24
24
  from pycode_kg.config import load_exclude_dirs, load_include_dirs
25
- from pycode_kg.graph import CodeGraph
26
25
  from pycode_kg.index import (
27
26
  SemanticIndex,
28
27
  SentenceTransformerEmbedder,
29
28
  suppress_ingestion_logging,
30
29
  )
30
+ from pycode_kg.module.extractor import EdgeSpec, NodeSpec, PyCodeKGExtractor
31
31
  from pycode_kg.store import GraphStore
32
32
 
33
33
 
@@ -126,15 +126,21 @@ def _run_pipeline(
126
126
 
127
127
  # Step 1: Build graph store
128
128
  t1 = time.monotonic()
129
- graph = CodeGraph(
129
+ extractor = PyCodeKGExtractor(
130
130
  repo_root,
131
131
  include=include if include else None,
132
132
  exclude=exclude if exclude else None,
133
133
  )
134
- nodes, edges = graph.extract().result()
134
+ node_specs: list[NodeSpec] = []
135
+ edge_specs: list[EdgeSpec] = []
136
+ for item in extractor.extract():
137
+ if isinstance(item, NodeSpec):
138
+ node_specs.append(item)
139
+ else:
140
+ edge_specs.append(item)
135
141
 
136
142
  store = GraphStore(db_path)
137
- store.write(nodes, edges, wipe=wipe)
143
+ store.write(node_specs, edge_specs, wipe=wipe)
138
144
  resolved = store.resolve_symbols()
139
145
  store.close()
140
146
 
@@ -142,8 +148,8 @@ def _run_pipeline(
142
148
  1,
143
149
  "graph store",
144
150
  [
145
- ("nodes", str(len(nodes))),
146
- ("edges", str(len(edges))),
151
+ ("nodes", str(len(node_specs))),
152
+ ("edges", str(len(edge_specs))),
147
153
  ("resolved", str(resolved)),
148
154
  ],
149
155
  elapsed=time.monotonic() - t1,
@@ -18,6 +18,7 @@ import tomllib
18
18
  from pathlib import Path
19
19
 
20
20
  import click
21
+ from kg_utils.semantic import _local_model_path
21
22
 
22
23
  from pycode_kg.cli.cmd_build_full import _run_pipeline
23
24
  from pycode_kg.cli.cmd_hooks import _PRE_COMMIT_HOOK
@@ -28,7 +29,6 @@ from pycode_kg.cli.options import (
28
29
  model_option,
29
30
  repo_option,
30
31
  )
31
- from pycode_kg.index import _local_model_path
32
32
  from pycode_kg.kg import PyCodeKG
33
33
  from pycode_kg.pycodekg_thorough_analysis import PyCodeKGAnalyzer
34
34
  from pycode_kg.snapshots import SnapshotManager
@@ -9,9 +9,9 @@ CLI command for managing the PyCodeKG embedding model cache.
9
9
  from __future__ import annotations
10
10
 
11
11
  import click
12
+ from kg_utils.semantic import _local_model_path
12
13
 
13
14
  from pycode_kg.cli.main import cli
14
- from pycode_kg.index import _local_model_path
15
15
  from pycode_kg.pycodekg import DEFAULT_MODEL
16
16
 
17
17
 
@@ -0,0 +1,11 @@
1
+ """pycode_kg/index.py — Re-exports semantic index from kg_utils.semantic."""
2
+
3
+ from kg_utils.semantic import ( # noqa: F401
4
+ DEFAULT_MODEL,
5
+ Embedder,
6
+ SeedHit,
7
+ SemanticIndex,
8
+ SentenceTransformerEmbedder,
9
+ resolve_model_path,
10
+ suppress_ingestion_logging,
11
+ )
@@ -0,0 +1,33 @@
1
+ """pycode_kg/module/base.py — KGModule for pycode_kg: thin subclass of kg_utils.pipeline."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import abstractmethod
6
+
7
+ from kg_utils.extractor import KGExtractor
8
+ from kg_utils.pipeline import KGModule as _KGModuleBase
9
+ from kg_utils.store import GraphStore
10
+
11
+
12
+ class KGModule(_KGModuleBase):
13
+ """Abstract base for Python code knowledge graphs.
14
+
15
+ Domain authors implement :meth:`make_extractor`, :meth:`kind`, and
16
+ :meth:`analyze`. Build/query/pack infrastructure comes from
17
+ :class:`kg_utils.pipeline.KGModule`.
18
+ """
19
+
20
+ _default_dir: str = ".pycodekg"
21
+
22
+ def _post_build_hook(self, store: GraphStore) -> None:
23
+ """Run symbol resolution after the graph is written."""
24
+ store.resolve_symbols()
25
+
26
+ @abstractmethod
27
+ def make_extractor(self) -> KGExtractor: ...
28
+
29
+ @abstractmethod
30
+ def kind(self) -> str: ...
31
+
32
+ @abstractmethod
33
+ def analyze(self) -> str: ...
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ module/extractor.py
4
+
5
+ KGExtractor — abstract extraction protocol for any knowledge graph domain.
6
+
7
+ NodeSpec and EdgeSpec are imported from kg_utils.specs and re-exported here.
8
+ PyCodeKGExtractor is the Python-AST-backed implementation.
9
+
10
+ Author: Eric G. Suchanek, PhD
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from collections.abc import Iterator
16
+ from pathlib import Path
17
+ from typing import Any
18
+
19
+ from kg_utils.extractor import KGExtractor # noqa: F401
20
+ from kg_utils.specs import EdgeSpec, NodeSpec # noqa: F401
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # PyCodeKGExtractor — Python-AST-backed extractor
24
+ # ---------------------------------------------------------------------------
25
+
26
+
27
+ class PyCodeKGExtractor(KGExtractor):
28
+ """KGExtractor backed by CodeGraph (Python AST analysis).
29
+
30
+ Wraps :class:`~pycode_kg.graph.CodeGraph` and converts its :class:`Node`
31
+ and :class:`Edge` v0 primitives to :class:`NodeSpec` / :class:`EdgeSpec`
32
+ for the generic :class:`~pycode_kg.module.base.KGModule` build pipeline.
33
+
34
+ This is the extractor used by :class:`~pycode_kg.kg.PyCodeKG` and is the
35
+ reference implementation for source-code KG extractors.
36
+
37
+ :param repo_path: Path to the Python repository root.
38
+ :param include: Set of top-level directory names to include (all if empty).
39
+ :param exclude: Set of directory names to exclude at every depth.
40
+ :param config: Optional config dict (forwarded to super).
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ repo_path: Path,
46
+ *,
47
+ include: set[str] | None = None,
48
+ exclude: set[str] | None = None,
49
+ config: dict[str, Any] | None = None,
50
+ ) -> None:
51
+ """Initialise the extractor for a Python repository.
52
+
53
+ :param repo_path: Path to the Python repository root.
54
+ :param include: Top-level directory names to include (empty = all).
55
+ :param exclude: Directory names to exclude at every walk depth.
56
+ :param config: Optional domain-specific configuration dict.
57
+ """
58
+ super().__init__(repo_path, config)
59
+ self._include: set[str] = include or set()
60
+ self._exclude: set[str] = exclude or set()
61
+
62
+ def node_kinds(self) -> list[str]:
63
+ """Return the Python AST node kinds.
64
+
65
+ :return: ``['module', 'class', 'function', 'method', 'symbol']``
66
+ """
67
+ return ["module", "class", "function", "method", "symbol"]
68
+
69
+ def edge_kinds(self) -> list[str]:
70
+ """Return the Python AST edge relation types.
71
+
72
+ :return: List of all relation strings emitted by the Python extractor.
73
+ """
74
+ return [
75
+ "CONTAINS",
76
+ "CALLS",
77
+ "IMPORTS",
78
+ "INHERITS",
79
+ "READS",
80
+ "WRITES",
81
+ "ATTR_ACCESS",
82
+ "DEPENDS_ON",
83
+ "RESOLVES_TO",
84
+ ]
85
+
86
+ def meaningful_node_kinds(self) -> list[str]:
87
+ """Return the node kinds indexed by LanceDB and counted in coverage.
88
+
89
+ Excludes ``'symbol'`` (unresolved import stubs).
90
+
91
+ :return: ``['module', 'class', 'function', 'method']``
92
+ """
93
+ return ["module", "class", "function", "method"]
94
+
95
+ def extract(self) -> Iterator[NodeSpec | EdgeSpec]:
96
+ """Run Python AST extraction and yield NodeSpec / EdgeSpec objects.
97
+
98
+ Delegates to :class:`~pycode_kg.graph.CodeGraph` for the AST walk, then
99
+ converts the v0-locked :class:`~pycode_kg.pycodekg.Node` and
100
+ :class:`~pycode_kg.pycodekg.Edge` primitives to the generic spec types.
101
+
102
+ :return: Iterator of :class:`NodeSpec` and :class:`EdgeSpec` objects.
103
+ """
104
+ from pycode_kg.graph import CodeGraph # pylint: disable=import-outside-toplevel
105
+
106
+ graph = CodeGraph(self.repo_path, include=self._include, exclude=self._exclude)
107
+ nodes, edges = graph.result()
108
+
109
+ for n in nodes:
110
+ yield NodeSpec(
111
+ node_id=n.id,
112
+ kind=n.kind,
113
+ name=n.name,
114
+ qualname=n.qualname or "",
115
+ source_path=n.module_path or "",
116
+ lineno=n.lineno,
117
+ end_lineno=n.end_lineno,
118
+ docstring=n.docstring or "",
119
+ )
120
+
121
+ for e in edges:
122
+ yield EdgeSpec(
123
+ source_id=e.src,
124
+ target_id=e.dst,
125
+ relation=e.rel,
126
+ metadata={"evidence": e.evidence} if e.evidence else {},
127
+ )
@@ -0,0 +1,31 @@
1
+ """pycode_kg/module/types.py — Re-exports from kg_utils for backward compat."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ from kg_utils.pipeline import ( # noqa: F401
6
+ compute_span,
7
+ docstring_signal,
8
+ lexical_overlap_score,
9
+ make_module_summary,
10
+ make_snippet,
11
+ normalize_query_text,
12
+ query_tokens,
13
+ read_lines,
14
+ safe_join,
15
+ semantic_score_from_distance,
16
+ spans_overlap,
17
+ )
18
+ from kg_utils.specs import BuildStats, QueryResult, SnippetPack # noqa: F401
19
+
20
+
21
+ @dataclass
22
+ class Snippet:
23
+ """Backward-compat shim. Snippets are now dicts on node["snippet"]."""
24
+
25
+ path: str
26
+ start: int
27
+ end: int
28
+ text: str
29
+
30
+ def to_dict(self) -> dict:
31
+ return {"path": self.path, "start": self.start, "end": self.end, "text": self.text}
@@ -37,7 +37,8 @@ from pathlib import Path
37
37
  # ============================================================================
38
38
  # Configuration
39
39
  # ============================================================================
40
- from pycode_kg.index import DEFAULT_MODEL as DEFAULT_MODEL # noqa: F401 — re-exported
40
+ from kg_utils.semantic import DEFAULT_MODEL as DEFAULT_MODEL # noqa: F401 — re-exported
41
+
41
42
  from pycode_kg.utils import node_id, rel_module_path
42
43
  from pycode_kg.visitor import PyCodeKGVisitor
43
44
 
@@ -0,0 +1,7 @@
1
+ """pycode_kg/store.py — Re-exports GraphStore from kg_utils.store."""
2
+
3
+ from kg_utils.store import ( # noqa: F401
4
+ DEFAULT_RELS,
5
+ GraphStore,
6
+ ProvMeta,
7
+ )