codegraphcontext 0.2.11__py3-none-any.whl → 0.3.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.
- codegraphcontext/cli/cli_helpers.py +71 -16
- codegraphcontext/core/__init__.py +9 -8
- codegraphcontext/tools/handlers/management_handlers.py +31 -40
- {codegraphcontext-0.2.11.dist-info → codegraphcontext-0.3.0.dist-info}/METADATA +2 -2
- {codegraphcontext-0.2.11.dist-info → codegraphcontext-0.3.0.dist-info}/RECORD +9 -9
- {codegraphcontext-0.2.11.dist-info → codegraphcontext-0.3.0.dist-info}/WHEEL +0 -0
- {codegraphcontext-0.2.11.dist-info → codegraphcontext-0.3.0.dist-info}/entry_points.txt +0 -0
- {codegraphcontext-0.2.11.dist-info → codegraphcontext-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {codegraphcontext-0.2.11.dist-info → codegraphcontext-0.3.0.dist-info}/top_level.txt +0 -0
|
@@ -6,6 +6,15 @@ from pathlib import Path
|
|
|
6
6
|
import time
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
from rich.table import Table
|
|
9
|
+
from rich.progress import (
|
|
10
|
+
Progress,
|
|
11
|
+
SpinnerColumn,
|
|
12
|
+
TextColumn,
|
|
13
|
+
BarColumn,
|
|
14
|
+
TaskProgressColumn,
|
|
15
|
+
TimeRemainingColumn,
|
|
16
|
+
MofNCompleteColumn,
|
|
17
|
+
)
|
|
9
18
|
|
|
10
19
|
from ..core import get_database_manager
|
|
11
20
|
from ..core.jobs import JobManager
|
|
@@ -67,6 +76,64 @@ def _initialize_services():
|
|
|
67
76
|
return db_manager, graph_builder, code_finder
|
|
68
77
|
|
|
69
78
|
|
|
79
|
+
async def _run_index_with_progress(graph_builder: GraphBuilder, path_obj: Path, is_dependency: bool = False):
|
|
80
|
+
"""Internal helper to run indexing with a Live progress bar."""
|
|
81
|
+
job_id = graph_builder.job_manager.create_job(str(path_obj), is_dependency=is_dependency)
|
|
82
|
+
|
|
83
|
+
# Create the progress bar
|
|
84
|
+
with Progress(
|
|
85
|
+
SpinnerColumn(),
|
|
86
|
+
TextColumn("[progress.description]{task.description}"),
|
|
87
|
+
BarColumn(),
|
|
88
|
+
TaskProgressColumn(),
|
|
89
|
+
MofNCompleteColumn(),
|
|
90
|
+
TimeRemainingColumn(),
|
|
91
|
+
TextColumn("[dim]{task.fields[filename]}"),
|
|
92
|
+
console=console,
|
|
93
|
+
transient=True,
|
|
94
|
+
) as progress:
|
|
95
|
+
|
|
96
|
+
task_id = progress.add_task(
|
|
97
|
+
"Indexing...",
|
|
98
|
+
total=None, # Will be updated once file discovery is done
|
|
99
|
+
filename=""
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
indexing_task = asyncio.create_task(
|
|
103
|
+
graph_builder.build_graph_from_path_async(path_obj, is_dependency=is_dependency, job_id=job_id)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
from ..core.jobs import JobStatus
|
|
107
|
+
|
|
108
|
+
# Poll for updates
|
|
109
|
+
while not indexing_task.done():
|
|
110
|
+
job = graph_builder.job_manager.get_job(job_id)
|
|
111
|
+
if job:
|
|
112
|
+
if job.total_files > 0:
|
|
113
|
+
progress.update(task_id, total=job.total_files, completed=job.processed_files)
|
|
114
|
+
|
|
115
|
+
# Update the current filename in the UI
|
|
116
|
+
current_file = job.current_file or ""
|
|
117
|
+
if len(current_file) > 40:
|
|
118
|
+
current_file = "..." + current_file[-37:]
|
|
119
|
+
progress.update(task_id, filename=current_file)
|
|
120
|
+
|
|
121
|
+
if job.status in [JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.CANCELLED]:
|
|
122
|
+
break
|
|
123
|
+
|
|
124
|
+
await asyncio.sleep(0.1)
|
|
125
|
+
|
|
126
|
+
# Wait for actual completion and handle final state
|
|
127
|
+
try:
|
|
128
|
+
await indexing_task
|
|
129
|
+
job = graph_builder.job_manager.get_job(job_id)
|
|
130
|
+
if job and job.status == JobStatus.FAILED:
|
|
131
|
+
error_msg = job.errors[0] if job.errors else "Unknown error"
|
|
132
|
+
raise RuntimeError(error_msg)
|
|
133
|
+
except Exception as e:
|
|
134
|
+
raise e
|
|
135
|
+
|
|
136
|
+
|
|
70
137
|
def index_helper(path: str):
|
|
71
138
|
"""Synchronously indexes a repository."""
|
|
72
139
|
time_start = time.time()
|
|
@@ -107,13 +174,9 @@ def index_helper(path: str):
|
|
|
107
174
|
console.print(f"[yellow]Warning: Could not check file count: {e}. Proceeding with indexing...[/yellow]")
|
|
108
175
|
|
|
109
176
|
console.print(f"Starting indexing for: {path_obj}")
|
|
110
|
-
console.print("[yellow]This may take a few minutes for large repositories...[/yellow]")
|
|
111
|
-
|
|
112
|
-
async def do_index():
|
|
113
|
-
await graph_builder.build_graph_from_path_async(path_obj, is_dependency=False)
|
|
114
177
|
|
|
115
178
|
try:
|
|
116
|
-
asyncio.run(
|
|
179
|
+
asyncio.run(_run_index_with_progress(graph_builder, path_obj, is_dependency=False))
|
|
117
180
|
time_end = time.time()
|
|
118
181
|
elapsed = time_end - time_start
|
|
119
182
|
console.print(f"[green]Successfully finished indexing: {path} in {elapsed:.2f} seconds[/green]")
|
|
@@ -159,13 +222,9 @@ def add_package_helper(package_name: str, language: str):
|
|
|
159
222
|
return
|
|
160
223
|
|
|
161
224
|
console.print(f"Starting indexing for package '{package_name}' at: {package_path}")
|
|
162
|
-
console.print("[yellow]This may take a few minutes...[/yellow]")
|
|
163
|
-
|
|
164
|
-
async def do_index():
|
|
165
|
-
await graph_builder.build_graph_from_path_async(package_path, is_dependency=True)
|
|
166
225
|
|
|
167
226
|
try:
|
|
168
|
-
asyncio.run(
|
|
227
|
+
asyncio.run(_run_index_with_progress(graph_builder, package_path, is_dependency=True))
|
|
169
228
|
console.print(f"[green]Successfully finished indexing package: {package_name}[/green]")
|
|
170
229
|
except Exception as e:
|
|
171
230
|
console.print(f"[bold red]An error occurred during package indexing:[/bold red] {e}")
|
|
@@ -587,13 +646,9 @@ def reindex_helper(path: str):
|
|
|
587
646
|
return
|
|
588
647
|
|
|
589
648
|
console.print(f"[cyan]Re-indexing: {path_obj}[/cyan]")
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
async def do_index():
|
|
593
|
-
await graph_builder.build_graph_from_path_async(path_obj, is_dependency=False)
|
|
594
|
-
|
|
649
|
+
|
|
595
650
|
try:
|
|
596
|
-
asyncio.run(
|
|
651
|
+
asyncio.run(_run_index_with_progress(graph_builder, path_obj, is_dependency=False))
|
|
597
652
|
time_end = time.time()
|
|
598
653
|
elapsed = time_end - time_start
|
|
599
654
|
console.print(f"[green]Successfully re-indexed: {path} in {elapsed:.2f} seconds[/green]")
|
|
@@ -125,7 +125,14 @@ def get_database_manager() -> Union['DatabaseManager', 'FalkorDBManager', 'Falko
|
|
|
125
125
|
else:
|
|
126
126
|
raise ValueError(f"Unknown database type: '{db_type}'. Use 'kuzudb', 'falkordb', 'falkordb-remote', or 'neo4j'.")
|
|
127
127
|
|
|
128
|
-
# 4.
|
|
128
|
+
# 4. Auto-detect: Remote FalkorDB (if FALKORDB_HOST is set)
|
|
129
|
+
# This takes priority over zero-config local backends because it's an explicit signal
|
|
130
|
+
if _is_falkordb_remote_configured():
|
|
131
|
+
from .database_falkordb_remote import FalkorDBRemoteManager
|
|
132
|
+
info_logger("Using remote FalkorDB (auto-detected via FALKORDB_HOST)")
|
|
133
|
+
return FalkorDBRemoteManager()
|
|
134
|
+
|
|
135
|
+
# 5. Implicit Default -> FalkorDB Lite (Unix Zero Config)
|
|
129
136
|
if _is_falkordb_available():
|
|
130
137
|
from .database_falkordb import FalkorDBManager, FalkorDBUnavailableError
|
|
131
138
|
try:
|
|
@@ -139,18 +146,12 @@ def get_database_manager() -> Union['DatabaseManager', 'FalkorDBManager', 'Falko
|
|
|
139
146
|
)
|
|
140
147
|
# fall through to KùzuDB below
|
|
141
148
|
|
|
142
|
-
#
|
|
149
|
+
# 6. Implicit Default -> KùzuDB (Best Zero Config)
|
|
143
150
|
if _is_kuzudb_available():
|
|
144
151
|
from .database_kuzu import KuzuDBManager
|
|
145
152
|
info_logger("Using KùzuDB (default)")
|
|
146
153
|
return KuzuDBManager()
|
|
147
154
|
|
|
148
|
-
# 6. Auto-detect: Remote FalkorDB (if FALKORDB_HOST is set)
|
|
149
|
-
if _is_falkordb_remote_configured():
|
|
150
|
-
from .database_falkordb_remote import FalkorDBRemoteManager
|
|
151
|
-
info_logger("Using remote FalkorDB (auto-detected via FALKORDB_HOST)")
|
|
152
|
-
return FalkorDBRemoteManager()
|
|
153
|
-
|
|
154
155
|
# 7. Fallback if configured
|
|
155
156
|
if _is_neo4j_configured():
|
|
156
157
|
from .database import DatabaseManager
|
|
@@ -276,59 +276,50 @@ def get_repository_stats(code_finder: CodeFinder, **args) -> Dict[str, Any]:
|
|
|
276
276
|
"error": f"Repository not found: {repo_path_obj}"
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
-
#
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
279
|
+
# 1. Files
|
|
280
|
+
file_query = "MATCH (r:Repository {path: $path})-[:CONTAINS*]->(f:File) RETURN count(f) as c"
|
|
281
|
+
file_count = session.run(file_query, path=repo_path_obj).single()["c"]
|
|
282
|
+
|
|
283
|
+
# 2. Functions
|
|
284
|
+
func_query = "MATCH (r:Repository {path: $path})-[:CONTAINS*]->(func:Function) RETURN count(func) as c"
|
|
285
|
+
func_count = session.run(func_query, path=repo_path_obj).single()["c"]
|
|
286
|
+
|
|
287
|
+
# 3. Classes
|
|
288
|
+
class_query = "MATCH (r:Repository {path: $path})-[:CONTAINS*]->(cls:Class) RETURN count(cls) as c"
|
|
289
|
+
class_count = session.run(class_query, path=repo_path_obj).single()["c"]
|
|
290
|
+
|
|
291
|
+
# 4. Modules (imported)
|
|
292
|
+
module_query = "MATCH (r:Repository {path: $path})-[:CONTAINS*]->(f:File)-[:IMPORTS]->(m:Module) RETURN count(DISTINCT m) as c"
|
|
293
|
+
module_count = session.run(module_query, path=repo_path_obj).single()["c"]
|
|
294
294
|
|
|
295
295
|
return {
|
|
296
296
|
"success": True,
|
|
297
297
|
"repository": repo_path_obj,
|
|
298
298
|
"stats": {
|
|
299
|
-
"files":
|
|
300
|
-
"functions":
|
|
301
|
-
"classes":
|
|
302
|
-
"modules":
|
|
299
|
+
"files": file_count,
|
|
300
|
+
"functions": func_count,
|
|
301
|
+
"classes": class_count,
|
|
302
|
+
"modules": module_count
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
else:
|
|
306
306
|
# Overall database stats
|
|
307
|
-
|
|
308
|
-
MATCH (r:Repository)
|
|
309
|
-
OPTIONAL MATCH (f:File)
|
|
310
|
-
OPTIONAL MATCH (func:Function)
|
|
311
|
-
OPTIONAL MATCH (cls:Class)
|
|
312
|
-
OPTIONAL MATCH (m:Module)
|
|
313
|
-
RETURN
|
|
314
|
-
count(DISTINCT r) as repo_count,
|
|
315
|
-
count(DISTINCT f) as file_count,
|
|
316
|
-
count(DISTINCT func) as function_count,
|
|
317
|
-
count(DISTINCT cls) as class_count,
|
|
318
|
-
count(DISTINCT m) as module_count
|
|
319
|
-
"""
|
|
320
|
-
result = session.run(stats_query)
|
|
321
|
-
record = result.single()
|
|
307
|
+
repo_count = session.run("MATCH (r:Repository) RETURN count(r) as c").single()["c"]
|
|
322
308
|
|
|
323
|
-
if
|
|
309
|
+
if repo_count > 0:
|
|
310
|
+
file_count = session.run("MATCH (f:File) RETURN count(f) as c").single()["c"]
|
|
311
|
+
func_count = session.run("MATCH (func:Function) RETURN count(func) as c").single()["c"]
|
|
312
|
+
class_count = session.run("MATCH (cls:Class) RETURN count(cls) as c").single()["c"]
|
|
313
|
+
module_count = session.run("MATCH (m:Module) RETURN count(m) as c").single()["c"]
|
|
314
|
+
|
|
324
315
|
return {
|
|
325
316
|
"success": True,
|
|
326
317
|
"stats": {
|
|
327
|
-
"repositories":
|
|
328
|
-
"files":
|
|
329
|
-
"functions":
|
|
330
|
-
"classes":
|
|
331
|
-
"modules":
|
|
318
|
+
"repositories": repo_count,
|
|
319
|
+
"files": file_count,
|
|
320
|
+
"functions": func_count,
|
|
321
|
+
"classes": class_count,
|
|
322
|
+
"modules": module_count
|
|
332
323
|
}
|
|
333
324
|
}
|
|
334
325
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codegraphcontext
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: An MCP server that indexes local code into a graph database to provide context to AI assistants.
|
|
5
5
|
Author-email: Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -147,7 +147,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
147
147
|
---
|
|
148
148
|
|
|
149
149
|
## Project Details
|
|
150
|
-
- **Version:** 0.
|
|
150
|
+
- **Version:** 0.3.0
|
|
151
151
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
152
152
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
153
153
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -4,14 +4,14 @@ codegraphcontext/prompts.py,sha256=E5P55paM0oHfBcNVfxkxpXRGZnya1kr_mKDg9i49FwM,6
|
|
|
4
4
|
codegraphcontext/server.py,sha256=gcb6V4x0Oh8haBOCm2WBjTCO9FDukrSalAMMApL-oc8,12806
|
|
5
5
|
codegraphcontext/tool_definitions.py,sha256=_0ahezQSURX_ewWydT2sFcvC6OFGdMoPA7KwgWNVcks,11482
|
|
6
6
|
codegraphcontext/cli/__init__.py,sha256=v6CMDVKM5d_sXn3S5nZNf0phXn0IdrnhLazUoen9k9w,38
|
|
7
|
-
codegraphcontext/cli/cli_helpers.py,sha256=
|
|
7
|
+
codegraphcontext/cli/cli_helpers.py,sha256=2T8eP1RmM_p2Z1XfZDv44wx3Hf01jF_b3KGoWVBG0lk,35945
|
|
8
8
|
codegraphcontext/cli/config_manager.py,sha256=MK7GMGZ4hd8-ZOShXBd_KDtNqHQ3ngdbef5KM_naPrQ,15899
|
|
9
9
|
codegraphcontext/cli/main.py,sha256=PSJ5BxQhbdNdCWWyYvW9-6COCiw852iVi-zhP43nYPA,86328
|
|
10
10
|
codegraphcontext/cli/registry_commands.py,sha256=30rJm4SeS0n1jax4JVuhuv4zYLzyMmlHcCSnsDDhgc8,19964
|
|
11
11
|
codegraphcontext/cli/setup_macos.py,sha256=Xjlv_9jk9qv8Gh7stpH1pvlalzC0Fg176y7jc5G1zh0,3575
|
|
12
12
|
codegraphcontext/cli/setup_wizard.py,sha256=yVXKqvAtUM0UC4tUreiS6C5utJbBO5Et2MiPUPWit9s,41393
|
|
13
13
|
codegraphcontext/cli/visualizer.py,sha256=rZOLPx44wlaxVXGLR6uOaiL2GaQvxEnpyDQ4tjRDVC8,45750
|
|
14
|
-
codegraphcontext/core/__init__.py,sha256=
|
|
14
|
+
codegraphcontext/core/__init__.py,sha256=r-dC2b8hn5e4ZBVfWnCcBYMTQVcayxG5-eA5Do6uSM4,7278
|
|
15
15
|
codegraphcontext/core/bundle_registry.py,sha256=kLvTLEl99QwfyAw8a7-4hqconLCtS64G9ECPVdfVBsM,7476
|
|
16
16
|
codegraphcontext/core/cgc_bundle.py,sha256=YHL_uamATXYVweh5qbg9TQjT1lKlt69gXyF-xKKk67c,31353
|
|
17
17
|
codegraphcontext/core/database.py,sha256=2UL8AyE6vX5mVHg1zcD74TYEREmddhKzN7Bjy2THQwM,11435
|
|
@@ -31,7 +31,7 @@ codegraphcontext/tools/scip_pb2.py,sha256=dwOMNKlu6VyLq5h8kTPZRDqxrwfVL8yw7I7zio
|
|
|
31
31
|
codegraphcontext/tools/system.py,sha256=DGeavZoPxzV78wwApV4f7fdBFQRa8oeOSv5wprHSjRE,5733
|
|
32
32
|
codegraphcontext/tools/handlers/analysis_handlers.py,sha256=lYECkMC2NKvnBWI4nQsAeCL5-e_JfJSVvQAwV7IbNJk,4749
|
|
33
33
|
codegraphcontext/tools/handlers/indexing_handlers.py,sha256=B1Op0wZ8MZ2pt170irc558T7rBYyuBTxWJsgRaiQRtw,5217
|
|
34
|
-
codegraphcontext/tools/handlers/management_handlers.py,sha256=
|
|
34
|
+
codegraphcontext/tools/handlers/management_handlers.py,sha256=jCosISjq4QD7oBa8ZaaX9xVzHO6W-6IC4nitlG9pZdk,13537
|
|
35
35
|
codegraphcontext/tools/handlers/query_handlers.py,sha256=KdZ1yH4yFj3RrXT4BTnyO7OZe6OKuNLW7tCAEPmjOy4,7629
|
|
36
36
|
codegraphcontext/tools/handlers/watcher_handlers.py,sha256=9hBkMdI8mwQyXj77WvgyUWCtNeItV3DiCLnmNI7Xjp8,3623
|
|
37
37
|
codegraphcontext/tools/languages/c.py,sha256=mrXQWEvMtzLVElATYNZ7VThNk1ZNZdw2UV8i6r2y2y4,22291
|
|
@@ -71,9 +71,9 @@ codegraphcontext/tools/query_tool_languages/typescript_toolkit.py,sha256=3S4hpmO
|
|
|
71
71
|
codegraphcontext/utils/debug_log.py,sha256=Qg7jwyeg7x2h3Ur_2S34bdMCkHdlk_ngHfPwa97A9vE,2836
|
|
72
72
|
codegraphcontext/utils/tree_sitter_manager.py,sha256=bIuKYN1aj1Zi6BnksGjZSLZzgBwuFRselZzyUpbToAU,9180
|
|
73
73
|
codegraphcontext/utils/visualize_graph.py,sha256=Ntq8l8SvAOvsOp19QKByjEwU7-5rPa_XfcGLOrUehq4,5003
|
|
74
|
-
codegraphcontext-0.
|
|
75
|
-
codegraphcontext-0.
|
|
76
|
-
codegraphcontext-0.
|
|
77
|
-
codegraphcontext-0.
|
|
78
|
-
codegraphcontext-0.
|
|
79
|
-
codegraphcontext-0.
|
|
74
|
+
codegraphcontext-0.3.0.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
|
|
75
|
+
codegraphcontext-0.3.0.dist-info/METADATA,sha256=FH-FTUU-gexxDfZePS6rqliF6540hUmv3ARwXJ_qO-I,21093
|
|
76
|
+
codegraphcontext-0.3.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
77
|
+
codegraphcontext-0.3.0.dist-info/entry_points.txt,sha256=LCxWCWMshdvYGoHBPuQZ8C-e4CiNSHCLXofrNSGHkoE,103
|
|
78
|
+
codegraphcontext-0.3.0.dist-info/top_level.txt,sha256=CBgc6LAPZIO5FS0nSYYkylDifHsZTIqw3Gf5UwDxeGI,17
|
|
79
|
+
codegraphcontext-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|