codegraph-network 0.1.0__py3-none-any.whl
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.
- codegraph/__init__.py +1 -0
- codegraph/bench.py +93 -0
- codegraph/cli.py +128 -0
- codegraph/community.py +77 -0
- codegraph/docs.py +141 -0
- codegraph/embed.py +221 -0
- codegraph/indexer.py +190 -0
- codegraph/install.py +219 -0
- codegraph/keys.py +94 -0
- codegraph/links.py +220 -0
- codegraph/parser.py +459 -0
- codegraph/py.typed +0 -0
- codegraph/queries.py +657 -0
- codegraph/rank.py +121 -0
- codegraph/report.py +199 -0
- codegraph/review.py +145 -0
- codegraph/server.py +81 -0
- codegraph/store.py +638 -0
- codegraph/tools.py +99 -0
- codegraph_network-0.1.0.dist-info/METADATA +220 -0
- codegraph_network-0.1.0.dist-info/RECORD +25 -0
- codegraph_network-0.1.0.dist-info/WHEEL +5 -0
- codegraph_network-0.1.0.dist-info/entry_points.txt +2 -0
- codegraph_network-0.1.0.dist-info/licenses/LICENSE +21 -0
- codegraph_network-0.1.0.dist-info/top_level.txt +1 -0
codegraph/tools.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""One definition of the codegraph tool surface, shared by the MCP server and the CLI.
|
|
2
|
+
|
|
3
|
+
Keeping the signature, the argument spec and the handler in one place is the only way the two
|
|
4
|
+
front ends cannot drift apart.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class Param:
|
|
13
|
+
name: str
|
|
14
|
+
type: str # "str" | "int" | "bool"
|
|
15
|
+
default: object = None
|
|
16
|
+
help: str = ""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(frozen=True)
|
|
20
|
+
class Tool:
|
|
21
|
+
name: str
|
|
22
|
+
summary: str # what the agent should use it for
|
|
23
|
+
params: tuple[Param, ...] = field(default_factory=tuple)
|
|
24
|
+
|
|
25
|
+
def defaults(self) -> dict:
|
|
26
|
+
return {p.name: p.default for p in self.params}
|
|
27
|
+
|
|
28
|
+
def usage(self) -> str:
|
|
29
|
+
parts = [p.name if p.default is None else f"[{p.name}]" for p in self.params]
|
|
30
|
+
return f"codegraph {self.name} " + " ".join(parts)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _p(name, type_, default=None, help_=""):
|
|
34
|
+
return Param(name, type_, default, help_)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
TOOLS: tuple[Tool, ...] = (
|
|
38
|
+
Tool("repo_map", "Ranked overview of the repo. Start here instead of reading whole files.",
|
|
39
|
+
(_p("prefix", "str", "", "directory prefix to zoom into"),
|
|
40
|
+
_p("max_tokens", "int", 1500),
|
|
41
|
+
_p("focus", "str", "", "symbols, words or paths, comma separated"))),
|
|
42
|
+
Tool("search", "Find symbols by name, split words or docstring; by meaning too when the embed extra is installed.",
|
|
43
|
+
(_p("query", "str", None), _p("limit", "int", 10))),
|
|
44
|
+
Tool("outline", "Symbol tree of a file, without any code.",
|
|
45
|
+
(_p("file", "str", None),)),
|
|
46
|
+
Tool("context", "Best first call for a symbol: source, what it uses, who uses it.",
|
|
47
|
+
(_p("symbol", "str", None), _p("max_tokens", "int", 1500))),
|
|
48
|
+
Tool("related", "Closest symbols to one symbol, direct and multi-hop, ranked.",
|
|
49
|
+
(_p("symbol", "str", None), _p("max_tokens", "int", 800))),
|
|
50
|
+
Tool("similar", "Symbols that mean the same thing as this one, even with no call between them "
|
|
51
|
+
"(needs the embed extra).",
|
|
52
|
+
(_p("symbol", "str", None), _p("limit", "int", 10))),
|
|
53
|
+
Tool("source", "Exact source of one symbol.",
|
|
54
|
+
(_p("symbol", "str", None),)),
|
|
55
|
+
Tool("callers", "Who calls / uses / inherits from this symbol.",
|
|
56
|
+
(_p("symbol", "str", None), _p("depth", "int", 1), _p("limit", "int", 30))),
|
|
57
|
+
Tool("callees", "What this symbol calls.",
|
|
58
|
+
(_p("symbol", "str", None), _p("depth", "int", 1), _p("limit", "int", 30))),
|
|
59
|
+
Tool("impact", "Blast radius of a change, grouped by file. Use before editing.",
|
|
60
|
+
(_p("symbol", "str", None), _p("depth", "int", 3))),
|
|
61
|
+
Tool("deps", "What a file imports and which files import it.",
|
|
62
|
+
(_p("file", "str", None),)),
|
|
63
|
+
Tool("stats", "Index size: files, symbols, edges by confidence, imports, communities."),
|
|
64
|
+
Tool("report", "Whole-repo overview: key symbols, communities, surprising connections. "
|
|
65
|
+
"Also writes .codegraph/GRAPH_REPORT.md and a browsable graph.html.",
|
|
66
|
+
(_p("max_tokens", "int", 1500),)),
|
|
67
|
+
Tool("review", "Review a change: symbols the git diff touches, their blast radius, missing tests, "
|
|
68
|
+
"files that usually change with it.",
|
|
69
|
+
(_p("base", "str", "", "branch/commit to diff against (default: where this branch left main)"),
|
|
70
|
+
_p("max_tokens", "int", 1500))),
|
|
71
|
+
Tool("reindex", "Re-scan the repo incrementally. Use after large external edits.",
|
|
72
|
+
(_p("force", "bool", False),)),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
TOOLS_BY_NAME = {t.name: t for t in TOOLS}
|
|
76
|
+
|
|
77
|
+
# extra CLI spellings, e.g. `codegraph map` for `repo_map`
|
|
78
|
+
CLI_ALIASES = {"repo_map": ("map",), "review": ("prs", "pr")}
|
|
79
|
+
QUERY_TOOLS = tuple(t for t in TOOLS if t.name not in ("reindex",))
|
|
80
|
+
|
|
81
|
+
# CLI flag aliases: param name -> (long flag, short flag or None).
|
|
82
|
+
# Anything not listed here is exposed under its own parameter name.
|
|
83
|
+
CLI_FLAGS = {
|
|
84
|
+
"max_tokens": ("tokens", "-t"),
|
|
85
|
+
"focus": ("focus", "-f"),
|
|
86
|
+
"depth": ("depth", "-d"),
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def make_callable(tool: Tool, graph, reindex_fn=None):
|
|
91
|
+
"""Bind a Tool spec to a Graph, producing the callable used by both front ends."""
|
|
92
|
+
def call(**kwargs):
|
|
93
|
+
return getattr(graph, tool.name)(**kwargs)
|
|
94
|
+
call.__name__ = tool.name
|
|
95
|
+
call.__doc__ = tool.summary
|
|
96
|
+
if tool.name == "reindex":
|
|
97
|
+
assert reindex_fn is not None
|
|
98
|
+
call = reindex_fn
|
|
99
|
+
return call
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codegraph-network
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Graph-based code understanding for LLM agents: fewer tokens, better answers
|
|
5
|
+
Author: Oviing
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Oviing/codegraph
|
|
8
|
+
Project-URL: Issues, https://github.com/Oviing/codegraph/issues
|
|
9
|
+
Keywords: code-graph,tree-sitter,mcp,llm,static-analysis
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: tree-sitter>=0.23
|
|
23
|
+
Requires-Dist: tree-sitter-language-pack
|
|
24
|
+
Requires-Dist: mcp>=1.2
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
28
|
+
Provides-Extra: embed
|
|
29
|
+
Requires-Dist: fastembed>=0.4; extra == "embed"
|
|
30
|
+
Requires-Dist: numpy>=1.24; extra == "embed"
|
|
31
|
+
Provides-Extra: bench
|
|
32
|
+
Requires-Dist: pyyaml>=6; extra == "bench"
|
|
33
|
+
Provides-Extra: pdf
|
|
34
|
+
Requires-Dist: pypdf>=4; extra == "pdf"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# codegraph
|
|
38
|
+
|
|
39
|
+
Graph-based code understanding for LLM agents. Parses a repo once with tree-sitter (no LLM, no cost),
|
|
40
|
+
stores symbols and relations in SQLite, and serves compact, token-budgeted answers over MCP.
|
|
41
|
+
|
|
42
|
+
Instead of reading whole files, the agent asks the graph.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
pip install codegraph-network # provides the `codegraph` command
|
|
47
|
+
pip install "codegraph-network[embed]" # optional: semantic search, see "Hybrid search"
|
|
48
|
+
|
|
49
|
+
From a checkout:
|
|
50
|
+
|
|
51
|
+
pip install -e ".[dev]" # drop [dev] if you don't need pytest/ruff
|
|
52
|
+
pip install -e ".[embed]" # optional: semantic search (fastembed + numpy), see "Hybrid search"
|
|
53
|
+
|
|
54
|
+
## Use with Claude Code
|
|
55
|
+
|
|
56
|
+
claude mcp add codegraph -- codegraph -r /path/to/repo serve
|
|
57
|
+
|
|
58
|
+
Or in any MCP client config:
|
|
59
|
+
|
|
60
|
+
{"mcpServers": {"codegraph": {"command": "codegraph", "args": ["-r", "/path/to/repo", "serve"]}}}
|
|
61
|
+
|
|
62
|
+
The index lives in `<repo>/.codegraph/graph.db` and updates incrementally on every server start;
|
|
63
|
+
`reindex` re-scans after edits made outside the session. `.gitignore` it.
|
|
64
|
+
|
|
65
|
+
## Tools
|
|
66
|
+
|
|
67
|
+
| Tool | Use it to |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `repo_map` | PageRank-ranked overview within a token budget; `focus=` personalizes it to what you're working on |
|
|
70
|
+
| `search` | Find symbols by name, words (camel/snake split) or docstring; with the embed extra also by meaning, each hit tagged `[lexical]` / `[semantic]` / `[both]` |
|
|
71
|
+
| `context` | Best first call: source + signatures it uses + who uses it, in one reply |
|
|
72
|
+
| `source` | Exact source of one symbol |
|
|
73
|
+
| `outline` | Symbol tree of a file, without code |
|
|
74
|
+
| `callers` / `callees` | Walk the call/inherit graph (depth N) |
|
|
75
|
+
| `impact` | Blast radius of a change, grouped by file |
|
|
76
|
+
| `related` | Closest symbols to one symbol (direct + multi-hop), ranked by personalized PageRank; each line says how it is related (`uses`, `used by`, `tested by`, `tests`, `key`, `similar`) |
|
|
77
|
+
| `similar` | Symbols that mean the same thing as this one even with no call between them (needs the embed extra) |
|
|
78
|
+
| `file_deps` | What a file imports and what imports it |
|
|
79
|
+
| `stats` | Index size, edges by confidence, communities |
|
|
80
|
+
| `report` | Key symbols, communities, surprising connections; writes `.codegraph/GRAPH_REPORT.md` and a browsable `graph.html` |
|
|
81
|
+
| `review` (`prs`) | What the git diff touches: blast radius per changed symbol, missing tests, files that usually change with it |
|
|
82
|
+
| `reindex` | Re-scan after big external edits |
|
|
83
|
+
|
|
84
|
+
The MCP server and the CLI are both generated from one tool registry (`src/codegraph/tools.py`), so
|
|
85
|
+
they cannot drift apart. The CLI mirrors the tools: `codegraph map`, `codegraph context Store.resolve`,
|
|
86
|
+
`codegraph impact parse`, ...
|
|
87
|
+
|
|
88
|
+
## Languages
|
|
89
|
+
|
|
90
|
+
Python, TypeScript/TSX, JavaScript, Go, Rust, C/C++.
|
|
91
|
+
|
|
92
|
+
Beyond code, also parsed statically (no LLM): Markdown (headings become `section` symbols; `` `code spans` `` link
|
|
93
|
+
to the symbols they name, relative links count as imports), SQL (`CREATE TABLE/VIEW/FUNCTION/PROCEDURE`, with
|
|
94
|
+
`FROM`/`JOIN`/`REFERENCES` links), and PDF pages (`pip install -e ".[pdf]"`). Prose and SQL mentions link only
|
|
95
|
+
when the name is unambiguous.
|
|
96
|
+
|
|
97
|
+
## Edge confidence
|
|
98
|
+
|
|
99
|
+
Every edge records how it was resolved: `extracted` (one target named by the source itself: same file, an import,
|
|
100
|
+
`self.x()`), `inferred` (a name match by proximity) or `ambiguous` (several equally plausible targets). `callers`,
|
|
101
|
+
`callees` and `context` tag anything that is not `extracted`; `impact` marks it with `?`. Treat tagged edges as
|
|
102
|
+
upper bounds.
|
|
103
|
+
|
|
104
|
+
## Scripting and ignoring
|
|
105
|
+
|
|
106
|
+
`codegraph <tool>` exits 0 on an answer, 3 when a name matches several symbols, 4 when it matches none.
|
|
107
|
+
`.codegraphignore` (gitignore-style: `#` comments, `dir/`, `/anchored`, `*.glob`, `!negation`) excludes paths
|
|
108
|
+
from the index, on top of the built-in skips (`node_modules`, `venv`, `dist`, hidden directories, ...).
|
|
109
|
+
|
|
110
|
+
## Installing into assistants and git
|
|
111
|
+
|
|
112
|
+
codegraph install [claude|cursor|gemini|agents|all] # skill, MCP config, guidance block; --uninstall to undo
|
|
113
|
+
codegraph hook install # re-index after commit, checkout, merge, rebase
|
|
114
|
+
|
|
115
|
+
`install` is idempotent and merges into existing files (guidance lives between `<!-- codegraph:start/end -->`
|
|
116
|
+
markers; JSON configs keep their other entries). For Claude Code it also adds a `Glob|Grep` hint hook
|
|
117
|
+
(`--no-hooks` to skip). Git hooks are appended to existing ones and run the indexer in the background.
|
|
118
|
+
|
|
119
|
+
## How it works
|
|
120
|
+
|
|
121
|
+
Indexing is incremental in two layers. Files are re-parsed only when their hash changes, and edge
|
|
122
|
+
resolution is scoped: a change re-resolves only the raw references whose name, or whose source file,
|
|
123
|
+
is affected. Parsing runs across processes and writes are batched; PageRank and community detection
|
|
124
|
+
warm-start from the previous run. On a 3,091-file / 59k-symbol / 79k-edge corpus (8 cores) a full index takes
|
|
125
|
+
~7.6s (was ~22s single-process), changing one file ~2s, and a no-op reindex ~0.3s. PageRank is the one step
|
|
126
|
+
that always walks the whole graph; whether it converged is reported by `codegraph index` rather than assumed.
|
|
127
|
+
|
|
128
|
+
Edge resolution is name-based, using the strongest evidence available:
|
|
129
|
+
|
|
130
|
+
- `self.x()` / `this.x()` link only to methods of the enclosing class, its bases and its subclasses
|
|
131
|
+
(no match => inherited from an external base => no edge).
|
|
132
|
+
- `obj.x()` links only if a candidate is in the same file, an imported file or the same directory.
|
|
133
|
+
- bare `x()` prefers same file, then imported files, then same directory, then anywhere.
|
|
134
|
+
- a bare call to a Python builtin, or to a name imported from a module outside the repo
|
|
135
|
+
(`from typing import cast`), links to nothing — otherwise `isinstance(...)` would attach thousands
|
|
136
|
+
of phantom edges to whatever repo method happens to share the name.
|
|
137
|
+
- Targets defined in more than 4 places are dropped as too ambiguous.
|
|
138
|
+
|
|
139
|
+
## Hybrid search and hidden links
|
|
140
|
+
|
|
141
|
+
Everything above is exact and structural. A second layer adds *recall* for relationships that are not
|
|
142
|
+
spelled out in code. It never touches `callers` / `callees` / `impact` or global PageRank: those stay
|
|
143
|
+
structural. Soft links live in their own tables (`links`, `file_links`) and enter the personalized
|
|
144
|
+
PageRank behind `context` / `related` / `repo_map(focus=)` at a lower weight than a call edge
|
|
145
|
+
(`LINK_WEIGHT` in `queries.py`).
|
|
146
|
+
|
|
147
|
+
| Link | Source | Needs |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `tests` | `test_foo.py` / `foo.test.ts` / `foo_test.go` -> the file named after it, and `test_bar` -> `bar` inside that pair; test callers are labelled `tested by` | nothing |
|
|
150
|
+
| `key` | the same string literal used in matching roles in different files: route path (`@app.get("/x")` vs `requests.get("/x")`, express vs `fetch`), event name (`emit` vs `on`), config key (`getenv`, `config.get`). Table-driven: add a row to `PATTERNS` in `keys.py`. Keys shared by more than 8 symbols and generic events (`error`, `data`, ...) are ignored | nothing |
|
|
151
|
+
| co-change | `git log --name-only` (last 1000 commits, commits over 30 files ignored, pairs need 3+ co-changes); shown by `deps` and used by `repo_map`'s ranking. No git or no history: no edges | git |
|
|
152
|
+
| `similar` | top-5 nearest neighbours by embedding cosine >= 0.85, skipping pairs already linked by a call/inheritance, overloads, and test-to-test pairs | embed extra |
|
|
153
|
+
|
|
154
|
+
**Semantic search** is optional: `pip install codegraph[embed]` (fastembed + numpy). Each function / method /
|
|
155
|
+
class / type is embedded from its name as words, qualified name, signature and doc line with a small local
|
|
156
|
+
ONNX model (`BAAI/bge-small-en-v1.5`); there is no network access at query time, the model files are
|
|
157
|
+
downloaded once at the first index. Vectors are cached in SQLite by content hash, so only changed symbols are
|
|
158
|
+
ever re-embedded and a no-change reindex stays near-instant. `search` fuses FTS5 and vector rankings with
|
|
159
|
+
reciprocal rank fusion (semantic hits in test files count half). Without the extra, or with
|
|
160
|
+
`CODEGRAPH_EMBED=off`, nothing changes: the output is the plain lexical search, byte for byte.
|
|
161
|
+
|
|
162
|
+
Providers are pluggable: `CODEGRAPH_EMBED=package.module:factory` loads any object with a `name`,
|
|
163
|
+
`embed_passages(list[str])` and `embed_query(str)` returning L2-normalised float32 vectors (see
|
|
164
|
+
`tests/fake_embed.py`); `CODEGRAPH_EMBED_MODEL` picks another fastembed model.
|
|
165
|
+
|
|
166
|
+
### Measured (fastembed bge-small, Apple silicon, CPU)
|
|
167
|
+
|
|
168
|
+
| | Flask (Python) | ky (TypeScript) |
|
|
169
|
+
|---|---|---|
|
|
170
|
+
| files / symbols | 88 / 1,723 | 100 / 11,427 |
|
|
171
|
+
| cold index, no embeddings | 0.4 s | 0.9 s |
|
|
172
|
+
| first-time embedding (one-off, then cached) | 27 s / 1,624 symbols | 58 s / 7,389 symbols |
|
|
173
|
+
| no-change reindex | 0.06 s | 0.04 s |
|
|
174
|
+
| edges (structural) | 1,011 calls, 74 inherits | 2,915 calls, 8 inherits |
|
|
175
|
+
| soft links | 70 tests, 52 key, 353 similar, 39 co-change | 3 key, 1,261 similar, 40 co-change |
|
|
176
|
+
|
|
177
|
+
`codegraph bench tasks.yaml` replays your own `(task, expected symbols)` list and reports, per task and in
|
|
178
|
+
total, recall@k of lexical-only vs hybrid search and the tokens an agent reads through the graph vs reading
|
|
179
|
+
the files that contain the expected symbols (`pip install codegraph[bench]` for YAML; JSON works without).
|
|
180
|
+
On 7 Flask and 5 ky natural-language tasks written for this README: hybrid recall 8/9 and 3/5, lexical-only
|
|
181
|
+
1/9 and 1/5. The lexical baseline is the existing search, which needs every query word to match, so it
|
|
182
|
+
scores ~0 on questions phrased unlike the code by construction. Treat the gap as "what the semantic layer adds
|
|
183
|
+
for descriptive queries", not as a general accuracy figure.
|
|
184
|
+
|
|
185
|
+
The similarity threshold (0.85) was set on codegraph's own code: bge-small cosines are high in general
|
|
186
|
+
(median nearest-neighbour 0.80 here); real near-duplicates (`make_repo` in two test files, `pagerank` vs
|
|
187
|
+
`personalized_pagerank`) start around 0.85, and below it the pairs are mostly generically similar test names.
|
|
188
|
+
|
|
189
|
+
## Tests
|
|
190
|
+
|
|
191
|
+
pytest # 232 tests
|
|
192
|
+
pytest tests/test_edges.py -rA # per-language edge precision/recall report
|
|
193
|
+
|
|
194
|
+
`tests/fixtures/<lang>/expected.json` holds hand-verified edges per language. Each fixture lists
|
|
195
|
+
`true` edges (must all be found) and `known_ambiguous` ones (accepted false positives from not
|
|
196
|
+
tracking receiver types, each with a stated reason). Anything the tool emits that is in neither list
|
|
197
|
+
fails the test, so a new kind of false positive cannot slip in unnoticed.
|
|
198
|
+
|
|
199
|
+
## Known limits
|
|
200
|
+
|
|
201
|
+
- Remaining false positives: `obj.x()` where `obj`'s type is unknown and an imported file defines a
|
|
202
|
+
method called `x` (e.g. `Path(p).resolve()` vs your own `resolve`). Type-aware indexers (SCIP) fix this.
|
|
203
|
+
- Dynamic dispatch, reflection and macros are mostly invisible.
|
|
204
|
+
- Semantic search is as good as a small local model: it can miss (`jsonify` for "turn python objects into a
|
|
205
|
+
json response" in Flask) and it ranks by meaning of the name/signature/doc line, not of the body. Variables
|
|
206
|
+
and TypeScript interface fields are not embedded.
|
|
207
|
+
- String keys match on identical literals only (no `/users/{id}` vs `/users/1`), and only for Python and
|
|
208
|
+
JS/TS call shapes listed in `keys.py`. `os.environ["X"]` and `process.env.X` are not recognised yet.
|
|
209
|
+
- Co-change uses the last 1000 commits and treats renames as new files.
|
|
210
|
+
- Object-literal properties in JS/TS (`{ json: body }`) are indexed as methods by the parser, which inflates
|
|
211
|
+
TypeScript indexes (ky: 11k symbols for 100 files) and puts noise in semantic results.
|
|
212
|
+
- Go/Rust/C++ import resolution is heuristic. Notably a stdlib import can collide with a local
|
|
213
|
+
directory of the same name: `net/http` matches an `internal/http` directory, because there is no
|
|
214
|
+
`go.mod` to tell the module prefix apart. Python imports are exact (see `py_lookup` in `store.py`).
|
|
215
|
+
|
|
216
|
+
## Next steps
|
|
217
|
+
|
|
218
|
+
- Type-aware resolution via SCIP/LSIF indexers for exact call edges
|
|
219
|
+
- Optional one-line LLM summaries per symbol, generated once at index time
|
|
220
|
+
- Git-aware ranking by recency (co-change is in; "recently changed" is not)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
codegraph/__init__.py,sha256=kUR5RAFc7HCeiqdlX36dZOHkUI5wI6V_43RpEcD8b-0,22
|
|
2
|
+
codegraph/bench.py,sha256=-2_kV76N8gjM58mW5Qb3tvMGGxfB-XEj_MsJTg7-t8s,3880
|
|
3
|
+
codegraph/cli.py,sha256=08n_GNkr4jEKKy6f_6Bfnft8M3lIENy5VzgjYqtXnj8,4877
|
|
4
|
+
codegraph/community.py,sha256=HtsQK58zDfUkySLE1mvuEoup1GR9RIIwh7UoY4iRDnw,3737
|
|
5
|
+
codegraph/docs.py,sha256=YHzg24v9tviiz5PqSG_nqHsnQhPntVgk8ABx2pmarcI,6126
|
|
6
|
+
codegraph/embed.py,sha256=LVryGlwSkktpWgPJzVtRFYJny4yWWu3AtuF-RQXruyo,9891
|
|
7
|
+
codegraph/indexer.py,sha256=ySizCFui6JFMgE00SoPChpTh4l0bm20XokyMWZc5hnU,7825
|
|
8
|
+
codegraph/install.py,sha256=ldx78xs6M2eiJZFnxxMoAY9mBdih7RfUWoDfjg2Qads,9821
|
|
9
|
+
codegraph/keys.py,sha256=OcDYsTxst8Jg_hcSNucuk-jxoTbLAuSgVbPm3bNbV7E,4149
|
|
10
|
+
codegraph/links.py,sha256=sn7bZIxf0fLFv7BjoK7V2opMVW1BuwQNaXsMSQprI04,9846
|
|
11
|
+
codegraph/parser.py,sha256=Q4mtOCaqyZm-b0fnPNH9fa6sA39tejmZmLag__RZa-w,19619
|
|
12
|
+
codegraph/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
codegraph/queries.py,sha256=CTt6TpRfWOcXgA4wwXIJJYs6-Vu8r14UUt-WdqepXpc,30829
|
|
14
|
+
codegraph/rank.py,sha256=FUJ-W9ogQPnXngNxCBHD-58ke6sXBTlZlb1xETuC6-g,4963
|
|
15
|
+
codegraph/report.py,sha256=xjoQ7KYKo-6hjDsmA6wykbeX2Yi0uFbVZknUeRYYS_E,9853
|
|
16
|
+
codegraph/review.py,sha256=yh5hNWtnsppc40hidL8Kb4kzSb9gugO5MJrIxY-37kM,6380
|
|
17
|
+
codegraph/server.py,sha256=lTmdhnHE-r2aLmNwWKu_svHBZ5XJ1j7higQDoT9W-TY,3094
|
|
18
|
+
codegraph/store.py,sha256=rOxweItAg1jMvb8D6W_rt4TTZSVkUOrj2tjurW_OVqY,30847
|
|
19
|
+
codegraph/tools.py,sha256=UNsiuta7TFaC1AgGMTDCOHb5jV0Czvz-5kh7nXoUB70,4338
|
|
20
|
+
codegraph_network-0.1.0.dist-info/licenses/LICENSE,sha256=2g3-GEuR7lJgSNW_8hDmQ67ottLWLC7TB7pWmiVYcdQ,1063
|
|
21
|
+
codegraph_network-0.1.0.dist-info/METADATA,sha256=b7tTVDFxSGgadSmqUUyFteXKf0MR-TTrI4iQWu9APr8,13153
|
|
22
|
+
codegraph_network-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
23
|
+
codegraph_network-0.1.0.dist-info/entry_points.txt,sha256=3f2dJK7oR3dBzP21qRk_KuQa6Li8MVbVXeKcx3UjQ6c,49
|
|
24
|
+
codegraph_network-0.1.0.dist-info/top_level.txt,sha256=RqBj9sPbifZTb9aeHtnbxTgKJvfHIQdmYE1Brv8Wdkg,10
|
|
25
|
+
codegraph_network-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Oviing
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codegraph
|