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.
Files changed (61) hide show
  1. {codegraphcontext-0.1.17/src/codegraphcontext.egg-info → codegraphcontext-0.1.18}/PKG-INFO +8 -2
  2. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/README.md +5 -0
  3. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/pyproject.toml +4 -3
  4. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/cli_helpers.py +134 -9
  5. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/main.py +46 -4
  6. codegraphcontext-0.1.18/src/codegraphcontext/core/__init__.py +92 -0
  7. codegraphcontext-0.1.18/src/codegraphcontext/core/database_falkordb.py +375 -0
  8. codegraphcontext-0.1.18/src/codegraphcontext/core/falkor_worker.py +68 -0
  9. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/server.py +136 -24
  10. codegraphcontext-0.1.18/src/codegraphcontext/tools/advanced_language_query_tool.py +99 -0
  11. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/code_finder.py +53 -44
  12. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/graph_builder.py +105 -4
  13. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/cpp.py +90 -3
  14. codegraphcontext-0.1.18/src/codegraphcontext/tools/languages/csharp.py +531 -0
  15. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/java.py +35 -1
  16. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/ruby.py +71 -3
  17. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +5 -0
  18. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +87 -0
  19. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +5 -0
  20. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +5 -0
  21. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +5 -0
  22. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +5 -0
  23. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +5 -0
  24. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +5 -0
  25. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +5 -0
  26. codegraphcontext-0.1.18/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +5 -0
  27. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/utils/debug_log.py +2 -2
  28. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18/src/codegraphcontext.egg-info}/PKG-INFO +8 -2
  29. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/SOURCES.txt +14 -0
  30. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/requires.txt +1 -0
  31. codegraphcontext-0.1.17/src/codegraphcontext/core/__init__.py +0 -1
  32. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/LICENSE +0 -0
  33. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/MANIFEST.in +0 -0
  34. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/setup.cfg +0 -0
  35. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/__init__.py +0 -0
  36. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/__main__.py +0 -0
  37. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/__init__.py +0 -0
  38. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/setup_macos.py +0 -0
  39. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/cli/setup_wizard.py +0 -0
  40. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/core/database.py +0 -0
  41. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/core/jobs.py +0 -0
  42. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/core/watcher.py +0 -0
  43. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/prompts.py +0 -0
  44. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/__init__.py +0 -0
  45. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/c.py +0 -0
  46. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/go.py +0 -0
  47. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/javascript.py +0 -0
  48. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/python.py +0 -0
  49. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/rust.py +0 -0
  50. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/languages/typescript.py +0 -0
  51. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/package_resolver.py +0 -0
  52. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext/tools/system.py +0 -0
  53. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  54. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  55. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/src/codegraphcontext.egg-info/top_level.txt +0 -0
  56. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_cpp_parser.py +0 -0
  57. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_database_validation.py +0 -0
  58. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_end_to_end.py +0 -0
  59. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_graph_indexing.py +0 -0
  60. {codegraphcontext-0.1.17 → codegraphcontext-0.1.18}/tests/test_graph_indexing_js.py +0 -0
  61. {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.17
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.9
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.17"
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.9"
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.database import DatabaseManager
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
- db_manager = DatabaseManager()
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 URL to visualize a Cypher query."""
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
- encoded_query = urllib.parse.quote(query)
195
- visualization_url = f"http://localhost:7474/browser/?cmd=edit&arg={encoded_query}"
196
- console.print("[green]Graph visualization URL:[/green]")
197
- console.print(visualization_url)
198
- console.print("Open the URL in your browser to see the graph.")
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]An error occurred while generating URL:[/bold red] {e}")
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
- Runs the interactive setup wizard to configure the server and database connection.
67
- This helps users set up a local Docker-based Neo4j instance or connect to a remote one.
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
- run_setup_wizard()
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']