codegraph-engine 2.1.1__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 +37 -0
- codegraph/agent.py +26 -0
- codegraph/architecture.py +328 -0
- codegraph/audit.py +106 -0
- codegraph/cache.py +95 -0
- codegraph/cli.py +854 -0
- codegraph/config.py +43 -0
- codegraph/constraints.py +238 -0
- codegraph/context.py +1228 -0
- codegraph/epistemic.py +90 -0
- codegraph/errors.py +275 -0
- codegraph/evidence/__init__.py +15 -0
- codegraph/evidence/citations.py +397 -0
- codegraph/frameworks.py +434 -0
- codegraph/freshness.py +295 -0
- codegraph/git.py +278 -0
- codegraph/graph/__init__.py +46 -0
- codegraph/graph/models.py +41 -0
- codegraph/graph/traversal.py +1291 -0
- codegraph/indexing/__init__.py +4 -0
- codegraph/indexing/classifier.py +274 -0
- codegraph/indexing/indexer.py +943 -0
- codegraph/indexing/models.py +338 -0
- codegraph/indexing/parser.py +1240 -0
- codegraph/indexing/scanner.py +200 -0
- codegraph/indexing/test_framework.py +116 -0
- codegraph/interrogation.py +1582 -0
- codegraph/llm/__init__.py +3 -0
- codegraph/llm/base.py +15 -0
- codegraph/llm/context.py +20 -0
- codegraph/mcp/__init__.py +3 -0
- codegraph/mcp/server.py +736 -0
- codegraph/memory/__init__.py +3 -0
- codegraph/memory/store.py +46 -0
- codegraph/models.py +289 -0
- codegraph/observability.py +151 -0
- codegraph/optimizer.py +372 -0
- codegraph/planner.py +417 -0
- codegraph/py.typed +1 -0
- codegraph/query_expansion.py +199 -0
- codegraph/ranking.py +363 -0
- codegraph/resolver.py +843 -0
- codegraph/resources/__init__.py +45 -0
- codegraph/resources/cache.py +117 -0
- codegraph/resources/coalescer.py +83 -0
- codegraph/resources/debouncer.py +98 -0
- codegraph/resources/governor.py +232 -0
- codegraph/resources/policy.py +123 -0
- codegraph/retrieval_policy.py +220 -0
- codegraph/search/__init__.py +23 -0
- codegraph/search/hybrid.py +301 -0
- codegraph/search/semantic.py +28 -0
- codegraph/security/__init__.py +3 -0
- codegraph/security/paths.py +35 -0
- codegraph/target_resolver.py +348 -0
- codegraph/task.py +637 -0
- codegraph_engine-2.1.1.dist-info/METADATA +334 -0
- codegraph_engine-2.1.1.dist-info/RECORD +62 -0
- codegraph_engine-2.1.1.dist-info/WHEEL +5 -0
- codegraph_engine-2.1.1.dist-info/entry_points.txt +2 -0
- codegraph_engine-2.1.1.dist-info/licenses/LICENSE +21 -0
- codegraph_engine-2.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"""Generalized file and repository artifact classifier.
|
|
2
|
+
|
|
3
|
+
Classifies files into distinct categories:
|
|
4
|
+
- SOURCE: normal application source code
|
|
5
|
+
- TEST: test suites, mocks, and fixtures
|
|
6
|
+
- GENERATED: minified assets, bundles, generated stubs, source maps
|
|
7
|
+
- BUILD_ARTIFACT: build output directories (dist, build, target)
|
|
8
|
+
- VENDOR: external dependencies (node_modules, vendor, venv)
|
|
9
|
+
- CONFIG: project and build configuration files
|
|
10
|
+
- BINARY: compiled objects, images, archives
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import fnmatch
|
|
15
|
+
from enum import StrEnum
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
_BINARY_EXTENSIONS = {
|
|
19
|
+
".pyc",
|
|
20
|
+
".pyo",
|
|
21
|
+
".pyd",
|
|
22
|
+
".so",
|
|
23
|
+
".dylib",
|
|
24
|
+
".dll",
|
|
25
|
+
".wasm",
|
|
26
|
+
".exe",
|
|
27
|
+
".bin",
|
|
28
|
+
".png",
|
|
29
|
+
".jpg",
|
|
30
|
+
".jpeg",
|
|
31
|
+
".gif",
|
|
32
|
+
".ico",
|
|
33
|
+
".webp",
|
|
34
|
+
".pdf",
|
|
35
|
+
".zip",
|
|
36
|
+
".tar",
|
|
37
|
+
".gz",
|
|
38
|
+
".tgz",
|
|
39
|
+
".7z",
|
|
40
|
+
".woff",
|
|
41
|
+
".woff2",
|
|
42
|
+
".ttf",
|
|
43
|
+
".eot",
|
|
44
|
+
".mp3",
|
|
45
|
+
".mp4",
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_BUILD_ARTIFACT_DIRS = {
|
|
49
|
+
"dist",
|
|
50
|
+
"build",
|
|
51
|
+
"out",
|
|
52
|
+
"target",
|
|
53
|
+
".next",
|
|
54
|
+
".nuxt",
|
|
55
|
+
"coverage",
|
|
56
|
+
".turbo",
|
|
57
|
+
"eggs",
|
|
58
|
+
".pytest_cache",
|
|
59
|
+
".mypy_cache",
|
|
60
|
+
".ruff_cache",
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
_VENDOR_DIRS = {
|
|
64
|
+
"node_modules",
|
|
65
|
+
"vendor",
|
|
66
|
+
"third_party",
|
|
67
|
+
"bower_components",
|
|
68
|
+
".venv",
|
|
69
|
+
"venv",
|
|
70
|
+
"env",
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
_CONFIG_FILENAMES = {
|
|
74
|
+
"package.json",
|
|
75
|
+
"tsconfig.json",
|
|
76
|
+
"pyproject.toml",
|
|
77
|
+
"setup.cfg",
|
|
78
|
+
"setup.py",
|
|
79
|
+
"cargo.toml",
|
|
80
|
+
"go.mod",
|
|
81
|
+
"makefile",
|
|
82
|
+
"dockerfile",
|
|
83
|
+
"docker-compose.yml",
|
|
84
|
+
"docker-compose.yaml",
|
|
85
|
+
"cmakelists.txt",
|
|
86
|
+
".editorconfig",
|
|
87
|
+
".gitignore",
|
|
88
|
+
".codegraphignore",
|
|
89
|
+
"requirements.txt",
|
|
90
|
+
"gemfile",
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_CONFIG_EXTENSIONS = {
|
|
94
|
+
".json",
|
|
95
|
+
".yaml",
|
|
96
|
+
".yml",
|
|
97
|
+
".toml",
|
|
98
|
+
".ini",
|
|
99
|
+
".cfg",
|
|
100
|
+
".xml",
|
|
101
|
+
".env",
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
_TEST_DIRS = {
|
|
105
|
+
"tests",
|
|
106
|
+
"test",
|
|
107
|
+
"__tests__",
|
|
108
|
+
"spec",
|
|
109
|
+
"specs",
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
_GENERATED_PATTERNS = [
|
|
113
|
+
"*.min.js",
|
|
114
|
+
"*.min.css",
|
|
115
|
+
"*.bundle.js",
|
|
116
|
+
"*.bundle.css",
|
|
117
|
+
"*.map",
|
|
118
|
+
"*.generated.*",
|
|
119
|
+
"*_generated.py",
|
|
120
|
+
"*_pb2.py",
|
|
121
|
+
"*.pb.go",
|
|
122
|
+
"*.gen.ts",
|
|
123
|
+
"*.d.ts",
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
_GENERATED_DIR_SUBSTRINGS = {
|
|
127
|
+
"react_assets",
|
|
128
|
+
"generated",
|
|
129
|
+
"gen",
|
|
130
|
+
"bundles",
|
|
131
|
+
"bundle",
|
|
132
|
+
"build_assets",
|
|
133
|
+
"static_bundles",
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class FileCategory(StrEnum):
|
|
138
|
+
SOURCE = "SOURCE"
|
|
139
|
+
TEST = "TEST"
|
|
140
|
+
GENERATED = "GENERATED"
|
|
141
|
+
BUILD_ARTIFACT = "BUILD_ARTIFACT"
|
|
142
|
+
VENDOR = "VENDOR"
|
|
143
|
+
CONFIG = "CONFIG"
|
|
144
|
+
BINARY = "BINARY"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def load_codegraphignore(root: Path) -> list[str]:
|
|
148
|
+
"""Parse .codegraphignore from repository root.
|
|
149
|
+
|
|
150
|
+
Format:
|
|
151
|
+
- one glob pattern per line
|
|
152
|
+
- blank lines ignored
|
|
153
|
+
- lines beginning with # are comments
|
|
154
|
+
- directory patterns end with /
|
|
155
|
+
- negation rules beginning with ! are NOT supported in v2.1.1
|
|
156
|
+
"""
|
|
157
|
+
path = root / ".codegraphignore"
|
|
158
|
+
if not path.is_file():
|
|
159
|
+
return []
|
|
160
|
+
try:
|
|
161
|
+
patterns: list[str] = []
|
|
162
|
+
for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
|
|
163
|
+
stripped = line.strip()
|
|
164
|
+
if not stripped or stripped.startswith("#") or stripped.startswith("!"):
|
|
165
|
+
continue
|
|
166
|
+
patterns.append(stripped)
|
|
167
|
+
return patterns
|
|
168
|
+
except OSError:
|
|
169
|
+
return []
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def is_ignored_by_codegraphignore(relative: Path, patterns: list[str]) -> bool:
|
|
173
|
+
"""Check if relative path matches any .codegraphignore pattern deterministically."""
|
|
174
|
+
if not patterns:
|
|
175
|
+
return False
|
|
176
|
+
posix_path = relative.as_posix()
|
|
177
|
+
name = relative.name
|
|
178
|
+
for pat in patterns:
|
|
179
|
+
clean_pat = pat.rstrip("/")
|
|
180
|
+
# Directory pattern (ends with /)
|
|
181
|
+
if pat.endswith("/"):
|
|
182
|
+
if posix_path.startswith(pat) or f"/{pat}" in f"/{posix_path}/":
|
|
183
|
+
return True
|
|
184
|
+
if any(part == clean_pat or fnmatch.fnmatch(part, clean_pat) for part in relative.parts):
|
|
185
|
+
return True
|
|
186
|
+
# Exact or glob match on full relative path or filename
|
|
187
|
+
if fnmatch.fnmatch(posix_path, clean_pat) or fnmatch.fnmatch(name, clean_pat):
|
|
188
|
+
return True
|
|
189
|
+
# Match within path segments
|
|
190
|
+
if any(fnmatch.fnmatch(part, clean_pat) for part in relative.parts):
|
|
191
|
+
return True
|
|
192
|
+
return False
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def classify_file(
|
|
196
|
+
relative_path: Path | str,
|
|
197
|
+
content: str | bytes | None = None,
|
|
198
|
+
) -> FileCategory:
|
|
199
|
+
"""Classify a repository file into its canonical category."""
|
|
200
|
+
p = Path(relative_path)
|
|
201
|
+
suffix = p.suffix.lower()
|
|
202
|
+
name = p.name.lower()
|
|
203
|
+
parts_lower = [part.lower() for part in p.parts]
|
|
204
|
+
|
|
205
|
+
# 1. Binary check
|
|
206
|
+
if suffix in _BINARY_EXTENSIONS:
|
|
207
|
+
return FileCategory.BINARY
|
|
208
|
+
if isinstance(content, bytes) and b"\x00" in content[:8192]:
|
|
209
|
+
return FileCategory.BINARY
|
|
210
|
+
|
|
211
|
+
# 2. Build artifact check
|
|
212
|
+
for part in parts_lower:
|
|
213
|
+
if part in _BUILD_ARTIFACT_DIRS or part.endswith(".egg-info"):
|
|
214
|
+
return FileCategory.BUILD_ARTIFACT
|
|
215
|
+
|
|
216
|
+
# 3. Vendor check
|
|
217
|
+
for part in parts_lower:
|
|
218
|
+
if part in _VENDOR_DIRS:
|
|
219
|
+
return FileCategory.VENDOR
|
|
220
|
+
|
|
221
|
+
# 4. Test check
|
|
222
|
+
if any(part in _TEST_DIRS for part in parts_lower):
|
|
223
|
+
return FileCategory.TEST
|
|
224
|
+
if (
|
|
225
|
+
name.startswith("test_")
|
|
226
|
+
or name.endswith("_test.py")
|
|
227
|
+
or name.endswith(".test.js")
|
|
228
|
+
or name.endswith(".test.ts")
|
|
229
|
+
or name.endswith(".test.jsx")
|
|
230
|
+
or name.endswith(".test.tsx")
|
|
231
|
+
or name.endswith(".spec.js")
|
|
232
|
+
or name.endswith(".spec.ts")
|
|
233
|
+
or name.endswith(".spec.jsx")
|
|
234
|
+
or name.endswith(".spec.tsx")
|
|
235
|
+
):
|
|
236
|
+
return FileCategory.TEST
|
|
237
|
+
|
|
238
|
+
# 5. Generated artifact check (pattern / path / content heuristics)
|
|
239
|
+
for pat in _GENERATED_PATTERNS:
|
|
240
|
+
if fnmatch.fnmatch(name, pat):
|
|
241
|
+
return FileCategory.GENERATED
|
|
242
|
+
|
|
243
|
+
for part in parts_lower:
|
|
244
|
+
if part in _GENERATED_DIR_SUBSTRINGS:
|
|
245
|
+
return FileCategory.GENERATED
|
|
246
|
+
|
|
247
|
+
if isinstance(content, str) and content:
|
|
248
|
+
# Check source map directive
|
|
249
|
+
if "//# sourceMappingURL=" in content or "/*# sourceMappingURL=" in content:
|
|
250
|
+
return FileCategory.GENERATED
|
|
251
|
+
# Check minified characteristics: single line > 1000 characters or very few lines for large size
|
|
252
|
+
lines = content.splitlines()
|
|
253
|
+
if lines:
|
|
254
|
+
max_line_len = max(len(ln) for ln in lines[:20])
|
|
255
|
+
if max_line_len > 1000:
|
|
256
|
+
return FileCategory.GENERATED
|
|
257
|
+
if len(content) > 5000 and len(lines) < 10 and max_line_len > 500:
|
|
258
|
+
return FileCategory.GENERATED
|
|
259
|
+
# Minified JS runtime boilerplate signatures
|
|
260
|
+
first_line = lines[0].strip()
|
|
261
|
+
if (
|
|
262
|
+
first_line.startswith("!function(")
|
|
263
|
+
or first_line.startswith("(window.webpackJsonp")
|
|
264
|
+
or first_line.startswith("\"use strict\";var ")
|
|
265
|
+
or first_line.startswith("(()=>{var ")
|
|
266
|
+
) and len(content) > 3000:
|
|
267
|
+
return FileCategory.GENERATED
|
|
268
|
+
|
|
269
|
+
# 6. Configuration check
|
|
270
|
+
if name in _CONFIG_FILENAMES or suffix in _CONFIG_EXTENSIONS:
|
|
271
|
+
return FileCategory.CONFIG
|
|
272
|
+
|
|
273
|
+
# 7. Default to SOURCE for all other files
|
|
274
|
+
return FileCategory.SOURCE
|