codegraphcontext 0.1.17__tar.gz → 0.1.18__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.
- {codegraphcontext-0.1.17/src/codegraphcontext.egg-info → codegraphcontext-0.1.18}/PKG-INFO +8 -2
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/README.md +5 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/pyproject.toml +4 -3
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/cli_helpers.py +134 -9
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/main.py +46 -4
- codegraphcontext-0.1.18/src/codegraphcontext/core/__init__.py +92 -0
- codegraphcontext-0.1.18/src/codegraphcontext/core/database_falkordb.py +375 -0
- codegraphcontext-0.1.18/src/codegraphcontext/core/falkor_worker.py +68 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/server.py +136 -24
- codegraphcontext-0.1.18/src/codegraphcontext/tools/advanced_language_query_tool.py +99 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/code_finder.py +53 -44
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/graph_builder.py +105 -4
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/cpp.py +90 -3
- codegraphcontext-0.1.18/src/codegraphcontext/tools/languages/csharp.py +531 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/java.py +35 -1
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/ruby.py +71 -3
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +87 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +5 -0
- codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +5 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/utils/debug_log.py +2 -2
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18/src/codegraphcontext.egg-info}/PKG-INFO +8 -2
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/SOURCES.txt +14 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/requires.txt +1 -0
- codegraphcontext-0.1.17/src/codegraphcontext/core/__init__.py +0 -1
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/LICENSE +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/MANIFEST.in +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/setup.cfg +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/setup_macos.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/setup_wizard.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/core/database.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/core/watcher.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/c.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/go.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/javascript.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/python.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/rust.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/typescript.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/package_resolver.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/top_level.txt +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_cpp_parser.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_database_validation.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_end_to_end.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_graph_indexing.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_graph_indexing_js.py +0 -0
- {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_typescript_parser.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codegraphcontext
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.18
|
|
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
|
|
@@ -33,7 +33,7 @@ Classifier: Operating System :: OS Independent
|
|
|
33
33
|
Classifier: Development Status :: 3 - Alpha
|
|
34
34
|
Classifier: Intended Audience :: Developers
|
|
35
35
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
36
|
-
Requires-Python: >=3.
|
|
36
|
+
Requires-Python: >=3.12
|
|
37
37
|
Description-Content-Type: text/markdown
|
|
38
38
|
License-File: LICENSE
|
|
39
39
|
Requires-Dist: neo4j>=5.15.0
|
|
@@ -51,6 +51,7 @@ Requires-Dist: pytest
|
|
|
51
51
|
Requires-Dist: nbformat
|
|
52
52
|
Requires-Dist: nbconvert>=7.16.6
|
|
53
53
|
Requires-Dist: pathspec>=0.12.1
|
|
54
|
+
Requires-Dist: falkordblite>=0.1.0
|
|
54
55
|
Provides-Extra: dev
|
|
55
56
|
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
56
57
|
Requires-Dist: black>=23.11.0; extra == "dev"
|
|
@@ -125,6 +126,11 @@ If you’re using CodeGraphContext in your project, feel free to open a PR and a
|
|
|
125
126
|
- `python-dotenv>=1.0.0`
|
|
126
127
|
- `tree-sitter==0.20.4`
|
|
127
128
|
- `tree-sitter-languages==1.10.2`
|
|
129
|
+
- `pyyaml`
|
|
130
|
+
- `pytest`
|
|
131
|
+
- `nbformat`
|
|
132
|
+
- `nbconvert>=7.16.6`
|
|
133
|
+
- `pathspec>=0.12.1`
|
|
128
134
|
|
|
129
135
|
## Getting Started
|
|
130
136
|
|
|
@@ -66,6 +66,11 @@ If you’re using CodeGraphContext in your project, feel free to open a PR and a
|
|
|
66
66
|
- `python-dotenv>=1.0.0`
|
|
67
67
|
- `tree-sitter==0.20.4`
|
|
68
68
|
- `tree-sitter-languages==1.10.2`
|
|
69
|
+
- `pyyaml`
|
|
70
|
+
- `pytest`
|
|
71
|
+
- `nbformat`
|
|
72
|
+
- `nbconvert>=7.16.6`
|
|
73
|
+
- `pathspec>=0.12.1`
|
|
69
74
|
|
|
70
75
|
## Getting Started
|
|
71
76
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codegraphcontext"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.18"
|
|
4
4
|
description = "An MCP server that indexes local code into a graph database to provide context to AI assistants."
|
|
5
5
|
authors = [{ name = "Shashank Shekhar Singh", email = "shashankshekharsingh1205@gmail.com" }]
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
license = { file = "LICENSE" }
|
|
8
|
-
requires-python = ">=3.
|
|
8
|
+
requires-python = ">=3.12"
|
|
9
9
|
classifiers = [
|
|
10
10
|
"Programming Language :: Python :: 3",
|
|
11
11
|
"License :: OSI Approved :: MIT License",
|
|
@@ -29,7 +29,8 @@ dependencies = [
|
|
|
29
29
|
"pytest",
|
|
30
30
|
"nbformat",
|
|
31
31
|
"nbconvert>=7.16.6",
|
|
32
|
-
"pathspec>=0.12.1"
|
|
32
|
+
"pathspec>=0.12.1",
|
|
33
|
+
"falkordblite>=0.1.0"
|
|
33
34
|
]
|
|
34
35
|
|
|
35
36
|
[project.urls]
|
|
@@ -7,7 +7,7 @@ import time
|
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
from rich.table import Table
|
|
9
9
|
|
|
10
|
-
from ..core
|
|
10
|
+
from ..core import get_database_manager
|
|
11
11
|
from ..core.jobs import JobManager
|
|
12
12
|
from ..tools.code_finder import CodeFinder
|
|
13
13
|
from ..tools.graph_builder import GraphBuilder
|
|
@@ -19,7 +19,12 @@ console = Console()
|
|
|
19
19
|
def _initialize_services():
|
|
20
20
|
"""Initializes and returns core service managers."""
|
|
21
21
|
console.print("[dim]Initializing services and database connection...[/dim]")
|
|
22
|
-
|
|
22
|
+
try:
|
|
23
|
+
db_manager = get_database_manager()
|
|
24
|
+
except ValueError as e:
|
|
25
|
+
console.print(f"[bold red]Database Configuration Error:[/bold red] {e}")
|
|
26
|
+
return None, None, None
|
|
27
|
+
|
|
23
28
|
try:
|
|
24
29
|
db_manager.get_driver()
|
|
25
30
|
except ValueError as e:
|
|
@@ -188,14 +193,134 @@ def cypher_helper(query: str):
|
|
|
188
193
|
db_manager.close_driver()
|
|
189
194
|
|
|
190
195
|
|
|
196
|
+
import webbrowser
|
|
197
|
+
|
|
191
198
|
def visualize_helper(query: str):
|
|
192
|
-
"""Generates a
|
|
199
|
+
"""Generates a visualization."""
|
|
200
|
+
services = _initialize_services()
|
|
201
|
+
if not all(services):
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
db_manager, _, _ = services
|
|
205
|
+
|
|
206
|
+
# Check if FalkorDB
|
|
207
|
+
if "FalkorDB" in db_manager.__class__.__name__:
|
|
208
|
+
_visualize_falkordb(db_manager)
|
|
209
|
+
else:
|
|
210
|
+
try:
|
|
211
|
+
encoded_query = urllib.parse.quote(query)
|
|
212
|
+
visualization_url = f"http://localhost:7474/browser/?cmd=edit&arg={encoded_query}"
|
|
213
|
+
console.print("[green]Graph visualization URL:[/green]")
|
|
214
|
+
console.print(visualization_url)
|
|
215
|
+
console.print("Open the URL in your browser to see the graph.")
|
|
216
|
+
except Exception as e:
|
|
217
|
+
console.print(f"[bold red]An error occurred while generating URL:[/bold red] {e}")
|
|
218
|
+
finally:
|
|
219
|
+
db_manager.close_driver()
|
|
220
|
+
|
|
221
|
+
def _visualize_falkordb(db_manager):
|
|
222
|
+
console.print("[dim]Generating FalkorDB visualization (showing up to 500 relationships)...[/dim]")
|
|
193
223
|
try:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
224
|
+
data_nodes = []
|
|
225
|
+
data_edges = []
|
|
226
|
+
|
|
227
|
+
with db_manager.get_driver().session() as session:
|
|
228
|
+
# Fetch nodes and edges
|
|
229
|
+
q = "MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500"
|
|
230
|
+
result = session.run(q)
|
|
231
|
+
|
|
232
|
+
seen_nodes = set()
|
|
233
|
+
|
|
234
|
+
for record in result:
|
|
235
|
+
# record values are Node/Relationship objects from falkordb client
|
|
236
|
+
n = record['n']
|
|
237
|
+
r = record['r']
|
|
238
|
+
m = record['m']
|
|
239
|
+
|
|
240
|
+
# Process Node helper
|
|
241
|
+
def process_node(node):
|
|
242
|
+
nid = getattr(node, 'id', -1)
|
|
243
|
+
labels = getattr(node, 'labels', [])
|
|
244
|
+
lbl = list(labels)[0] if labels else "Node"
|
|
245
|
+
props = getattr(node, 'properties', {})
|
|
246
|
+
name = props.get('name', str(nid))
|
|
247
|
+
|
|
248
|
+
if nid not in seen_nodes:
|
|
249
|
+
seen_nodes.add(nid)
|
|
250
|
+
color = "#97c2fc" # Default blue
|
|
251
|
+
if "Repository" in labels: color = "#ffb3ba" # Red
|
|
252
|
+
elif "File" in labels: color = "#baffc9" # Green
|
|
253
|
+
elif "Class" in labels: color = "#bae1ff" # Light Blue
|
|
254
|
+
elif "Function" in labels: color = "#ffffba" # Yellow
|
|
255
|
+
elif "Package" in labels: color = "#ffdfba" # Orange
|
|
256
|
+
|
|
257
|
+
data_nodes.append({
|
|
258
|
+
"id": nid,
|
|
259
|
+
"label": name,
|
|
260
|
+
"group": lbl,
|
|
261
|
+
"title": str(props),
|
|
262
|
+
"color": color
|
|
263
|
+
})
|
|
264
|
+
return nid
|
|
265
|
+
|
|
266
|
+
nid = process_node(n)
|
|
267
|
+
mid = process_node(m)
|
|
268
|
+
|
|
269
|
+
# Check Edge
|
|
270
|
+
e_type = getattr(r, 'relation', '') or getattr(r, 'type', 'REL')
|
|
271
|
+
data_edges.append({
|
|
272
|
+
"from": nid,
|
|
273
|
+
"to": mid,
|
|
274
|
+
"label": e_type,
|
|
275
|
+
"arrows": "to"
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
filename = "codegraph_viz.html"
|
|
279
|
+
html_content = f"""
|
|
280
|
+
<!DOCTYPE html>
|
|
281
|
+
<html>
|
|
282
|
+
<head>
|
|
283
|
+
<title>CodeGraphContext Visualization</title>
|
|
284
|
+
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
|
|
285
|
+
<style type="text/css">
|
|
286
|
+
#mynetwork {{
|
|
287
|
+
width: 100%;
|
|
288
|
+
height: 100vh;
|
|
289
|
+
border: 1px solid lightgray;
|
|
290
|
+
}}
|
|
291
|
+
</style>
|
|
292
|
+
</head>
|
|
293
|
+
<body>
|
|
294
|
+
<div id="mynetwork"></div>
|
|
295
|
+
<script type="text/javascript">
|
|
296
|
+
var nodes = new vis.DataSet({json.dumps(data_nodes)});
|
|
297
|
+
var edges = new vis.DataSet({json.dumps(data_edges)});
|
|
298
|
+
var container = document.getElementById('mynetwork');
|
|
299
|
+
var data = {{ nodes: nodes, edges: edges }};
|
|
300
|
+
var options = {{
|
|
301
|
+
nodes: {{ shape: 'dot', size: 16 }},
|
|
302
|
+
physics: {{ stabilization: false }},
|
|
303
|
+
layout: {{ improvedLayout: false }}
|
|
304
|
+
}};
|
|
305
|
+
var network = new vis.Network(container, data, options);
|
|
306
|
+
</script>
|
|
307
|
+
</body>
|
|
308
|
+
</html>
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
out_path = Path(filename).resolve()
|
|
312
|
+
with open(out_path, "w") as f:
|
|
313
|
+
f.write(html_content)
|
|
314
|
+
|
|
315
|
+
console.print(f"[green]Visualization generated at:[/green] {out_path}")
|
|
316
|
+
console.print("Opening in default browser...")
|
|
317
|
+
webbrowser.open(f"file://{out_path}")
|
|
318
|
+
|
|
199
319
|
except Exception as e:
|
|
200
|
-
console.print(f"[bold red]
|
|
320
|
+
console.print(f"[bold red]Visualization failed:[/bold red] {e}")
|
|
321
|
+
import traceback
|
|
322
|
+
traceback.print_exc()
|
|
323
|
+
finally:
|
|
324
|
+
db_manager.close_driver()
|
|
325
|
+
|
|
201
326
|
|
|
@@ -18,7 +18,7 @@ import logging
|
|
|
18
18
|
import json
|
|
19
19
|
import os
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from dotenv import load_dotenv, find_dotenv
|
|
21
|
+
from dotenv import load_dotenv, find_dotenv, set_key
|
|
22
22
|
from importlib.metadata import version as pkg_version, PackageNotFoundError
|
|
23
23
|
|
|
24
24
|
from codegraphcontext.server import MCPServer
|
|
@@ -63,10 +63,17 @@ def get_version() -> str:
|
|
|
63
63
|
@app.command()
|
|
64
64
|
def setup():
|
|
65
65
|
"""
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
Configure Neo4j Database Connection.
|
|
67
|
+
|
|
68
|
+
Note: CodeGraphContext works out of the box with FalkorDB Lite (Default).
|
|
69
|
+
This setup is ONLY required if you want to use an external Neo4j database.
|
|
68
70
|
"""
|
|
69
|
-
|
|
71
|
+
console.print("\n[bold cyan]CodeGraphContext Setup[/bold cyan]")
|
|
72
|
+
console.print("CodeGraphContext works out of the box with FalkorDB. This setup is only required if you want to use Neo4j.\n")
|
|
73
|
+
if typer.confirm("Do you want to configure Neo4j now?", default=True):
|
|
74
|
+
run_setup_wizard()
|
|
75
|
+
else:
|
|
76
|
+
console.print("Setup cancelled. You can continue using FalkorDB Lite.")
|
|
70
77
|
|
|
71
78
|
def _load_credentials():
|
|
72
79
|
"""
|
|
@@ -112,6 +119,33 @@ def _load_credentials():
|
|
|
112
119
|
console.print(f"[bold red]Error loading .env file:[/bold red] {e}")
|
|
113
120
|
|
|
114
121
|
|
|
122
|
+
# Create a subcommand group for "default"
|
|
123
|
+
default_app = typer.Typer(help="Manage default configurations")
|
|
124
|
+
app.add_typer(default_app, name="default")
|
|
125
|
+
|
|
126
|
+
@default_app.command("database")
|
|
127
|
+
def set_default_database(db_type: str = typer.Argument(..., help="Backend type: 'falkordb' or 'neo4j'")):
|
|
128
|
+
"""
|
|
129
|
+
Set the default database backend.
|
|
130
|
+
|
|
131
|
+
This preference is stored in ~/.codegraphcontext/.env
|
|
132
|
+
"""
|
|
133
|
+
db_type = db_type.lower()
|
|
134
|
+
if db_type not in ['falkordb', 'neo4j']:
|
|
135
|
+
console.print(f"[bold red]Invalid database type: {db_type}.[/bold red] Must be 'falkordb' or 'neo4j'")
|
|
136
|
+
raise typer.Exit(code=1)
|
|
137
|
+
|
|
138
|
+
env_path = Path.home() / ".codegraphcontext" / ".env"
|
|
139
|
+
env_path.parent.mkdir(parents=True, exist_ok=True)
|
|
140
|
+
if not env_path.exists():
|
|
141
|
+
env_path.touch()
|
|
142
|
+
|
|
143
|
+
set_key(env_path, "DEFAULT_DATABASE", db_type)
|
|
144
|
+
console.print(f"[green]✔ Default database set to {db_type}[/green]")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
115
149
|
@app.command()
|
|
116
150
|
def start():
|
|
117
151
|
"""
|
|
@@ -168,6 +202,7 @@ def visualize(query: Optional[str] = typer.Argument(None, help="The Cypher query
|
|
|
168
202
|
"""
|
|
169
203
|
if query is None:
|
|
170
204
|
query = "MATCH p=()-->() RETURN p"
|
|
205
|
+
_load_credentials()
|
|
171
206
|
visualize_helper(query)
|
|
172
207
|
|
|
173
208
|
@app.command(name="list-repos")
|
|
@@ -239,6 +274,7 @@ def version_cmd():
|
|
|
239
274
|
@app.callback(invoke_without_command=True)
|
|
240
275
|
def main(
|
|
241
276
|
ctx: typer.Context,
|
|
277
|
+
database: Optional[str] = typer.Option(None, "--database", "-d", help="Override default database backend (falkordb or neo4j)"),
|
|
242
278
|
version_: bool = typer.Option(
|
|
243
279
|
None,
|
|
244
280
|
"--version",
|
|
@@ -251,6 +287,9 @@ def main(
|
|
|
251
287
|
Main entry point for the cgc CLI application.
|
|
252
288
|
If no subcommand is provided, it displays a welcome message with instructions.
|
|
253
289
|
"""
|
|
290
|
+
if database:
|
|
291
|
+
os.environ["CGC_RUNTIME_DB_TYPE"] = database
|
|
292
|
+
|
|
254
293
|
if version_:
|
|
255
294
|
console.print(f"CodeGraphContext [bold cyan]{get_version()}[/bold cyan]")
|
|
256
295
|
raise typer.Exit()
|
|
@@ -262,3 +301,6 @@ def main(
|
|
|
262
301
|
console.print("👉 Run [cyan]cgc help[/cyan] to see all available commands.\n")
|
|
263
302
|
console.print("👉 Run [cyan]cgc --version[/cyan] to check the version.\n")
|
|
264
303
|
console.print("👉 Running [green]codegraphcontext [white]works the same as using [green]cgc")
|
|
304
|
+
|
|
305
|
+
if __name__ == "__main__":
|
|
306
|
+
app()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# src/codegraphcontext/core/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
Core database management module.
|
|
4
|
+
|
|
5
|
+
Supports both Neo4j and FalkorDB Lite backends.
|
|
6
|
+
Use DATABASE_TYPE environment variable to switch:
|
|
7
|
+
- DATABASE_TYPE=falkordb - Uses embedded FalkorDB Lite (recommended for lite-version)
|
|
8
|
+
- DATABASE_TYPE=neo4j - Uses Neo4j server
|
|
9
|
+
- If not set, auto-detects based on what's available
|
|
10
|
+
"""
|
|
11
|
+
import os
|
|
12
|
+
from typing import Union
|
|
13
|
+
|
|
14
|
+
import importlib.util
|
|
15
|
+
|
|
16
|
+
def _is_falkordb_available() -> bool:
|
|
17
|
+
"""Check if FalkorDB Lite is installed (without importing native modules)."""
|
|
18
|
+
try:
|
|
19
|
+
# Check for redislite/falkordb-client spec without loading it
|
|
20
|
+
return importlib.util.find_spec("redislite") is not None
|
|
21
|
+
except ImportError:
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
def _is_neo4j_configured() -> bool:
|
|
25
|
+
"""Check if Neo4j is configured with credentials."""
|
|
26
|
+
return all([
|
|
27
|
+
os.getenv('NEO4J_URI'),
|
|
28
|
+
os.getenv('NEO4J_USERNAME'),
|
|
29
|
+
os.getenv('NEO4J_PASSWORD')
|
|
30
|
+
])
|
|
31
|
+
|
|
32
|
+
def get_database_manager() -> Union['DatabaseManager', 'FalkorDBManager']:
|
|
33
|
+
"""
|
|
34
|
+
Factory function to get the appropriate database manager based on configuration.
|
|
35
|
+
|
|
36
|
+
Selection logic:
|
|
37
|
+
1. Runtime Override: 'CGC_RUNTIME_DB_TYPE' (set via --database flag)
|
|
38
|
+
2. Configured Default: 'DEFAULT_DATABASE' (set via 'cgc default database')
|
|
39
|
+
3. Legacy Env Var: 'DATABASE_TYPE'
|
|
40
|
+
4. Implicit Default: FalkorDB (if available)
|
|
41
|
+
5. Fallback: Neo4j (if configured)
|
|
42
|
+
"""
|
|
43
|
+
from codegraphcontext.utils.debug_log import info_logger
|
|
44
|
+
|
|
45
|
+
# 1. Runtime Override (CLI flag) or Config/Env
|
|
46
|
+
db_type = os.getenv('CGC_RUNTIME_DB_TYPE')
|
|
47
|
+
if not db_type:
|
|
48
|
+
db_type = os.getenv('DEFAULT_DATABASE')
|
|
49
|
+
if not db_type:
|
|
50
|
+
db_type = os.getenv('DATABASE_TYPE')
|
|
51
|
+
|
|
52
|
+
if db_type:
|
|
53
|
+
db_type = db_type.lower()
|
|
54
|
+
if db_type == 'falkordb':
|
|
55
|
+
if not _is_falkordb_available():
|
|
56
|
+
raise ValueError("Database set to 'falkordb' but FalkorDB Lite is not installed.\nRun 'pip install falkordblite'")
|
|
57
|
+
from .database_falkordb import FalkorDBManager
|
|
58
|
+
info_logger("Using FalkorDB Lite (explicit)")
|
|
59
|
+
return FalkorDBManager()
|
|
60
|
+
|
|
61
|
+
elif db_type == 'neo4j':
|
|
62
|
+
if not _is_neo4j_configured():
|
|
63
|
+
raise ValueError("Database set to 'neo4j' but it is not configured.\nRun 'cgc setup' to configure Neo4j.")
|
|
64
|
+
from .database import DatabaseManager
|
|
65
|
+
info_logger("Using Neo4j Server (explicit)")
|
|
66
|
+
return DatabaseManager()
|
|
67
|
+
else:
|
|
68
|
+
raise ValueError(f"Unknown database type: '{db_type}'. Use 'falkordb' or 'neo4j'.")
|
|
69
|
+
|
|
70
|
+
# 4. Implicit Default -> FalkorDB (Zero Config)
|
|
71
|
+
if _is_falkordb_available():
|
|
72
|
+
from .database_falkordb import FalkorDBManager
|
|
73
|
+
info_logger("Using FalkorDB Lite (default)")
|
|
74
|
+
return FalkorDBManager()
|
|
75
|
+
|
|
76
|
+
# 5. Fallback if FalkorDB missing but Neo4j is ready
|
|
77
|
+
if _is_neo4j_configured():
|
|
78
|
+
from .database import DatabaseManager
|
|
79
|
+
info_logger("Using Neo4j Server (auto-detected)")
|
|
80
|
+
return DatabaseManager()
|
|
81
|
+
|
|
82
|
+
raise ValueError(
|
|
83
|
+
"No database backend available.\n"
|
|
84
|
+
"Recommended: Install FalkorDB Lite ('pip install falkordblite')\n"
|
|
85
|
+
"Alternative: Run 'cgc setup' to configure Neo4j."
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# For backward compatibility, export DatabaseManager
|
|
89
|
+
from .database import DatabaseManager
|
|
90
|
+
from .database_falkordb import FalkorDBManager
|
|
91
|
+
|
|
92
|
+
__all__ = ['DatabaseManager', 'FalkorDBManager', 'get_database_manager']
|