codegraphcontext 0.2.7__tar.gz → 0.2.9__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 (87) hide show
  1. codegraphcontext-0.2.9/MANIFEST.in +4 -0
  2. {codegraphcontext-0.2.7/src/codegraphcontext.egg-info → codegraphcontext-0.2.9}/PKG-INFO +17 -13
  3. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/README.md +15 -12
  4. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/pyproject.toml +2 -1
  5. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/cli_helpers.py +174 -8
  6. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/config_manager.py +2 -2
  7. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/main.py +48 -9
  8. codegraphcontext-0.2.9/src/codegraphcontext/core/__init__.py +176 -0
  9. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/core/database_falkordb.py +44 -12
  10. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/core/database_falkordb_remote.py +4 -2
  11. codegraphcontext-0.2.9/src/codegraphcontext/core/database_kuzu.py +456 -0
  12. codegraphcontext-0.2.9/src/codegraphcontext/core/falkor_worker.py +132 -0
  13. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/code_finder.py +60 -45
  14. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/graph_builder.py +140 -51
  15. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/handlers/query_handlers.py +3 -2
  16. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9/src/codegraphcontext.egg-info}/PKG-INFO +17 -13
  17. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext.egg-info/SOURCES.txt +1 -0
  18. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext.egg-info/requires.txt +1 -0
  19. codegraphcontext-0.2.7/MANIFEST.in +0 -2
  20. codegraphcontext-0.2.7/src/codegraphcontext/core/__init__.py +0 -130
  21. codegraphcontext-0.2.7/src/codegraphcontext/core/falkor_worker.py +0 -76
  22. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/LICENSE +0 -0
  23. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/setup.cfg +0 -0
  24. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/__init__.py +0 -0
  25. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/__main__.py +0 -0
  26. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/__init__.py +0 -0
  27. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/registry_commands.py +0 -0
  28. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/setup_macos.py +0 -0
  29. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/setup_wizard.py +0 -0
  30. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/cli/visualizer.py +0 -0
  31. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/core/bundle_registry.py +0 -0
  32. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/core/cgc_bundle.py +0 -0
  33. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/core/database.py +0 -0
  34. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/core/jobs.py +0 -0
  35. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/core/watcher.py +0 -0
  36. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/prompts.py +0 -0
  37. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/server.py +0 -0
  38. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tool_definitions.py +0 -0
  39. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/__init__.py +0 -0
  40. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
  41. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
  42. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
  43. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
  44. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
  45. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/c.py +0 -0
  46. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/cpp.py +0 -0
  47. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/csharp.py +0 -0
  48. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/dart.py +0 -0
  49. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/go.py +0 -0
  50. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/haskell.py +0 -0
  51. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/java.py +0 -0
  52. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/javascript.py +0 -0
  53. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
  54. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/perl.py +0 -0
  55. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/php.py +0 -0
  56. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/python.py +0 -0
  57. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/ruby.py +0 -0
  58. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/rust.py +0 -0
  59. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/scala.py +0 -0
  60. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/swift.py +0 -0
  61. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/typescript.py +0 -0
  62. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
  63. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/package_resolver.py +0 -0
  64. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
  65. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
  66. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
  67. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
  68. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
  69. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
  70. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
  71. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
  72. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
  73. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
  74. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
  75. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
  76. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
  77. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
  78. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
  79. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/scip_indexer.py +0 -0
  80. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/scip_pb2.py +0 -0
  81. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/tools/system.py +0 -0
  82. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/utils/debug_log.py +0 -0
  83. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
  84. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext/utils/visualize_graph.py +0 -0
  85. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  86. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  87. {codegraphcontext-0.2.7 → codegraphcontext-0.2.9}/src/codegraphcontext.egg-info/top_level.txt +0 -0
@@ -0,0 +1,4 @@
1
+ prune website
2
+ prune images
3
+ prune vscode-extension
4
+ prune playground
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegraphcontext
3
- Version: 0.2.7
3
+ Version: 0.2.9
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
@@ -50,6 +50,7 @@ Requires-Dist: pytest
50
50
  Requires-Dist: nbformat
51
51
  Requires-Dist: nbconvert>=7.16.6
52
52
  Requires-Dist: pathspec>=0.12.1
53
+ Requires-Dist: falkordb>=0.1.0
53
54
  Requires-Dist: falkordblite>=0.1.0; sys_platform != "win32" and python_version >= "3.12"
54
55
  Provides-Extra: parsing
55
56
  Requires-Dist: tree-sitter>=0.21.0; extra == "parsing"
@@ -146,7 +147,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
146
147
  ---
147
148
 
148
149
  ## Project Details
149
- - **Version:** 0.2.7
150
+ - **Version:** 0.2.9
150
151
  - **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
151
152
  - **License:** MIT License (See [LICENSE](LICENSE) for details)
152
153
  - **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
@@ -179,7 +180,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
179
180
  - **Interactive Setup:** A user-friendly command-line wizard for easy setup.
180
181
  - **Dual Mode:** Works as a standalone **CLI toolkit** for developers and as an **MCP server** for AI agents.
181
182
  - **Multi-Language Support:** Full support for 14 programming languages.
182
- - **Flexible Database Backend:** FalkorDB Lite (default, inbuilt for Unix and through WSL for Windows) or Neo4j (all platforms via Docker/native).
183
+ - **Flexible Database Backend:** KùzuDB (default, zero-config for all platforms), FalkorDB Lite (Unix-only), FalkorDB Remote, or Neo4j (all platforms via Docker/native).
183
184
 
184
185
  ---
185
186
 
@@ -201,14 +202,16 @@ Each language parser extracts functions, classes, methods, parameters, inheritan
201
202
 
202
203
  ## Database Options
203
204
 
204
- CodeGraphContext supports two graph database backends:
205
+ CodeGraphContext supports multiple graph database backends to suit your environment:
205
206
 
206
- | Feature | FalkorDB Lite (Default) | Neo4j |
207
- | :--- | :--- | :--- |
208
- | **Setup** | Zero-config / In-process | Docker / External |
209
- | **Platform** | Unix / WSL / macOS | All (incl. Windows Native) |
210
- | **Use Case** | Local dev & Quick tests | Production & Massive graphs |
211
- | **Requirement**| Python 3.12+ | Any supported Python |
207
+ | Feature | KùzuDB (Default) | FalkorDB Lite | Neo4j |
208
+ | :--- | :--- | :--- | :--- |
209
+ | **Setup** | Zero-config / Embedded | Zero-config / In-process | Docker / External |
210
+ | **Platform** | **All (Windows Native, macOS, Linux)** | Unix-only (Linux/macOS/WSL) | All Platforms |
211
+ | **Use Case** | Desktop, IDE, Local development | Specialized Unix development | Enterprise, Massive graphs |
212
+ | **Requirement**| `pip install kuzu` | `pip install falkordblite` | Neo4j Server / Docker |
213
+ | **Speed** | ⚡ Extremely Fast | ⚡ Fast | 🚀 Scalable |
214
+ | **Persistence**| Yes (to disk) | Yes (to disk) | Yes (to disk) |
212
215
 
213
216
  ---
214
217
 
@@ -315,10 +318,11 @@ Use CodeGraphContext as an **MCP server** for AI assistants:
315
318
  ```
316
319
  </details>
317
320
 
318
- 2. **Database Setup (Automatic for Unix/WSL)**
321
+ 2. **Database Setup (Automatic)**
319
322
 
320
- - **FalkorDB Lite (Default):** If you're on Unix/Linux/macOS/WSL with Python 3.12+, you're done! FalkorDB Lite is already configured.
321
- - **Neo4j (Optional/Windows):** To use Neo4j instead, or if you're on Windows without WSL, run: `cgc neo4j setup`
323
+ - **KùzuDB (Default):** Runs natively on Windows, macOS, and Linux without any setup. Just `pip install kuzu` and you're ready!
324
+ - **FalkorDB Lite (Alternative):** Supported on Unix/macOS/WSL for Python 3.12+.
325
+ - **Neo4j (Alternative):** To use Neo4j instead, or if you prefer a server-based approach, run: `cgc neo4j setup`
322
326
 
323
327
  ---
324
328
 
@@ -84,7 +84,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
84
84
  ---
85
85
 
86
86
  ## Project Details
87
- - **Version:** 0.2.7
87
+ - **Version:** 0.2.9
88
88
  - **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
89
89
  - **License:** MIT License (See [LICENSE](LICENSE) for details)
90
90
  - **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
@@ -117,7 +117,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
117
117
  - **Interactive Setup:** A user-friendly command-line wizard for easy setup.
118
118
  - **Dual Mode:** Works as a standalone **CLI toolkit** for developers and as an **MCP server** for AI agents.
119
119
  - **Multi-Language Support:** Full support for 14 programming languages.
120
- - **Flexible Database Backend:** FalkorDB Lite (default, inbuilt for Unix and through WSL for Windows) or Neo4j (all platforms via Docker/native).
120
+ - **Flexible Database Backend:** KùzuDB (default, zero-config for all platforms), FalkorDB Lite (Unix-only), FalkorDB Remote, or Neo4j (all platforms via Docker/native).
121
121
 
122
122
  ---
123
123
 
@@ -139,14 +139,16 @@ Each language parser extracts functions, classes, methods, parameters, inheritan
139
139
 
140
140
  ## Database Options
141
141
 
142
- CodeGraphContext supports two graph database backends:
142
+ CodeGraphContext supports multiple graph database backends to suit your environment:
143
143
 
144
- | Feature | FalkorDB Lite (Default) | Neo4j |
145
- | :--- | :--- | :--- |
146
- | **Setup** | Zero-config / In-process | Docker / External |
147
- | **Platform** | Unix / WSL / macOS | All (incl. Windows Native) |
148
- | **Use Case** | Local dev & Quick tests | Production & Massive graphs |
149
- | **Requirement**| Python 3.12+ | Any supported Python |
144
+ | Feature | KùzuDB (Default) | FalkorDB Lite | Neo4j |
145
+ | :--- | :--- | :--- | :--- |
146
+ | **Setup** | Zero-config / Embedded | Zero-config / In-process | Docker / External |
147
+ | **Platform** | **All (Windows Native, macOS, Linux)** | Unix-only (Linux/macOS/WSL) | All Platforms |
148
+ | **Use Case** | Desktop, IDE, Local development | Specialized Unix development | Enterprise, Massive graphs |
149
+ | **Requirement**| `pip install kuzu` | `pip install falkordblite` | Neo4j Server / Docker |
150
+ | **Speed** | ⚡ Extremely Fast | ⚡ Fast | 🚀 Scalable |
151
+ | **Persistence**| Yes (to disk) | Yes (to disk) | Yes (to disk) |
150
152
 
151
153
  ---
152
154
 
@@ -253,10 +255,11 @@ Use CodeGraphContext as an **MCP server** for AI assistants:
253
255
  ```
254
256
  </details>
255
257
 
256
- 2. **Database Setup (Automatic for Unix/WSL)**
258
+ 2. **Database Setup (Automatic)**
257
259
 
258
- - **FalkorDB Lite (Default):** If you're on Unix/Linux/macOS/WSL with Python 3.12+, you're done! FalkorDB Lite is already configured.
259
- - **Neo4j (Optional/Windows):** To use Neo4j instead, or if you're on Windows without WSL, run: `cgc neo4j setup`
260
+ - **KùzuDB (Default):** Runs natively on Windows, macOS, and Linux without any setup. Just `pip install kuzu` and you're ready!
261
+ - **FalkorDB Lite (Alternative):** Supported on Unix/macOS/WSL for Python 3.12+.
262
+ - **Neo4j (Alternative):** To use Neo4j instead, or if you prefer a server-based approach, run: `cgc neo4j setup`
260
263
 
261
264
  ---
262
265
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codegraphcontext"
3
- version = "0.2.7"
3
+ version = "0.2.9"
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"
@@ -29,6 +29,7 @@ dependencies = [
29
29
  "nbformat",
30
30
  "nbconvert>=7.16.6",
31
31
  "pathspec>=0.12.1",
32
+ "falkordb>=0.1.0",
32
33
  "falkordblite>=0.1.0; sys_platform != 'win32' and python_version >= '3.12'"
33
34
  ]
34
35
 
@@ -1,6 +1,6 @@
1
- # src/codegraphcontext/cli/cli_helpers.py
2
1
  import asyncio
3
2
  import json
3
+ import uuid
4
4
  import urllib.parse
5
5
  from pathlib import Path
6
6
  import time
@@ -27,10 +27,32 @@ def _initialize_services():
27
27
 
28
28
  try:
29
29
  db_manager.get_driver()
30
- except ValueError as e:
31
- console.print(f"[bold red]Database Connection Error:[/bold red] {e}")
32
- console.print("Please ensure your Neo4j credentials are correct and the database is running.")
33
- return None, None, None
30
+ except Exception as e:
31
+ # Check if this is a FalkorDB failure that should trigger a KùzuDB fallback
32
+ from ..core.database_falkordb import FalkorDBUnavailableError
33
+ if isinstance(e, FalkorDBUnavailableError):
34
+ console.print(f"[yellow]⚠ FalkorDB Lite is not functional in this environment: {e}[/yellow]")
35
+ console.print("[cyan]Falling back to KùzuDB for a reliable experience...[/cyan]")
36
+
37
+ # Close the broken driver/socket
38
+ try:
39
+ db_manager.close_driver()
40
+ except Exception:
41
+ pass
42
+
43
+ # Re-initialize explicitly with KùzuDB
44
+ from ..core.database_kuzu import KuzuDBManager
45
+ db_manager = KuzuDBManager()
46
+ try:
47
+ db_manager.get_driver()
48
+ console.print("[green]✓[/green] Successfully switched to KùzuDB fallback")
49
+ except Exception as kuzu_e:
50
+ console.print(f"[bold red]Critical Error:[/bold red] Both FalkorDB and KùzuDB failed: {kuzu_e}")
51
+ return None, None, None
52
+ else:
53
+ console.print(f"[bold red]Database Connection Error:[/bold red] {e}")
54
+ console.print("Please ensure your database is configured correctly or run 'cgc doctor'.")
55
+ return None, None, None
34
56
 
35
57
  # The GraphBuilder requires an event loop, even for synchronous-style execution
36
58
  try:
@@ -263,16 +285,28 @@ def cypher_helper_visual(query: str):
263
285
  import webbrowser
264
286
 
265
287
  def visualize_helper(query: str):
266
- """Generates a visualization."""
288
+ """"Generates a visualization."""
267
289
  services = _initialize_services()
268
290
  if not all(services):
269
291
  return
270
292
 
271
293
  db_manager, _, _ = services
272
294
 
273
- # Check if FalkorDB
274
- if "FalkorDB" in db_manager.__class__.__name__:
295
+ # Check Backend Type
296
+ backend = getattr(db_manager, "name", "").lower()
297
+ if not backend:
298
+ # Fallback check
299
+ if "FalkorDB" in db_manager.__class__.__name__:
300
+ backend = "falkordb"
301
+ elif "Kuzu" in db_manager.__class__.__name__:
302
+ backend = "kuzudb"
303
+ else:
304
+ backend = "neo4j"
305
+
306
+ if backend == "falkordb":
275
307
  _visualize_falkordb(db_manager)
308
+ elif backend == "kuzudb":
309
+ _visualize_kuzudb(db_manager)
276
310
  else:
277
311
  try:
278
312
  encoded_query = urllib.parse.quote(query)
@@ -391,6 +425,138 @@ def _visualize_falkordb(db_manager):
391
425
  db_manager.close_driver()
392
426
 
393
427
 
428
+ def _visualize_kuzudb(db_manager):
429
+ console.print("[dim]Generating KùzuDB visualization (showing up to 500 relationships)...[/dim]")
430
+ try:
431
+ data_nodes = []
432
+ data_edges = []
433
+
434
+ with db_manager.get_driver().session() as session:
435
+ # Fetch nodes and edges
436
+ # KùzuDB returns dicts for n, r, m in the result
437
+ q = "MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500"
438
+ result = session.run(q)
439
+
440
+ seen_nodes = set()
441
+
442
+ # Helper to extract Node ID and props
443
+ def process_node(node):
444
+ uid = None
445
+ lbl = 'Node'
446
+ props = {}
447
+
448
+ # Handle Kuzu Node Object (processed by wrapper)
449
+ if hasattr(node, 'properties'):
450
+ props = node.properties or {}
451
+ if hasattr(node, 'labels') and node.labels:
452
+ lbl = node.labels[0]
453
+ if hasattr(node, 'id'):
454
+ uid = str(node.id)
455
+ # Handle Dictionary (raw Kuzu result)
456
+ elif isinstance(node, dict):
457
+ if '_id' in node:
458
+ uid = f"{node['_id']['table']}_{node['_id']['offset']}"
459
+ lbl = node.get('_label', 'Node')
460
+ props = {k: v for k, v in node.items() if not k.startswith('_')}
461
+
462
+ if not uid:
463
+ uid = str(uuid.uuid4())
464
+
465
+ name = props.get('name', str(uid))
466
+
467
+ if uid not in seen_nodes:
468
+ seen_nodes.add(uid)
469
+ color = "#97c2fc" # Default blue
470
+ if "Repository" == lbl: color = "#ffb3ba"
471
+ elif "File" == lbl: color = "#baffc9"
472
+ elif "Class" == lbl: color = "#bae1ff"
473
+ elif "Function" == lbl: color = "#ffffba"
474
+ elif "Module" == lbl: color = "#ffdfba"
475
+
476
+ data_nodes.append({
477
+ "id": uid,
478
+ "label": name,
479
+ "group": lbl,
480
+ "title": str(props),
481
+ "color": color
482
+ })
483
+ return uid
484
+
485
+ # Iterate results
486
+ for record in result:
487
+ # record is dict-like access to row items
488
+ n = record['n']
489
+ r = record['r']
490
+ m = record['m']
491
+
492
+ nid = process_node(n)
493
+ mid = process_node(m)
494
+
495
+ # Process Edge
496
+ e_type = 'REL'
497
+ if hasattr(r, 'type'):
498
+ e_type = r.type
499
+ elif isinstance(r, dict):
500
+ e_type = r.get('_label', 'REL')
501
+ elif hasattr(r, 'label'): # Some versions
502
+ e_type = r.label
503
+
504
+ data_edges.append({
505
+ "from": nid,
506
+ "to": mid,
507
+ "label": e_type,
508
+ "arrows": "to"
509
+ })
510
+
511
+ filename = "codegraph_viz.html"
512
+ html_content = f"""
513
+ <!DOCTYPE html>
514
+ <html>
515
+ <head>
516
+ <title>CodeGraphContext KùzuDB Visualization</title>
517
+ <script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
518
+ <style type="text/css">
519
+ #mynetwork {{
520
+ width: 100%;
521
+ height: 100vh;
522
+ border: 1px solid lightgray;
523
+ }}
524
+ </style>
525
+ </head>
526
+ <body>
527
+ <div id="mynetwork"></div>
528
+ <script type="text/javascript">
529
+ var nodes = new vis.DataSet({json.dumps(data_nodes)});
530
+ var edges = new vis.DataSet({json.dumps(data_edges)});
531
+ var container = document.getElementById('mynetwork');
532
+ var data = {{ nodes: nodes, edges: edges }};
533
+ var options = {{
534
+ nodes: {{ shape: 'dot', size: 16 }},
535
+ physics: {{ stabilization: false }},
536
+ layout: {{ improvedLayout: false }}
537
+ }};
538
+ var network = new vis.Network(container, data, options);
539
+ </script>
540
+ </body>
541
+ </html>
542
+ """
543
+
544
+ out_path = Path(filename).resolve()
545
+ with open(out_path, "w") as f:
546
+ f.write(html_content)
547
+
548
+ console.print(f"[green]Visualization generated at:[/green] {out_path}")
549
+ console.print("Opening in default browser...")
550
+ webbrowser.open(f"file://{out_path}")
551
+
552
+ except Exception as e:
553
+ console.print(f"[bold red]Visualization failed:[/bold red] {e}")
554
+ import traceback
555
+ traceback.print_exc()
556
+ finally:
557
+ db_manager.close_driver()
558
+
559
+
394
560
  def reindex_helper(path: str):
395
561
  """Force re-index by deleting and rebuilding the repository."""
396
562
  time_start = time.time()
@@ -48,7 +48,7 @@ DEFAULT_CONFIG = {
48
48
 
49
49
  # Configuration key descriptions
50
50
  CONFIG_DESCRIPTIONS = {
51
- "DEFAULT_DATABASE": "Default database backend (neo4j|falkordb)",
51
+ "DEFAULT_DATABASE": "Default database backend (neo4j|falkordb|kuzudb)",
52
52
  "FALKORDB_PATH": "Path to FalkorDB database file",
53
53
  "FALKORDB_SOCKET_PATH": "Path to FalkorDB Unix socket",
54
54
  "INDEX_VARIABLES": "Index variable nodes in the graph (lighter graph if false)",
@@ -75,7 +75,7 @@ CONFIG_DESCRIPTIONS = {
75
75
 
76
76
  # Valid values for each config key
77
77
  CONFIG_VALIDATORS = {
78
- "DEFAULT_DATABASE": ["neo4j", "falkordb"],
78
+ "DEFAULT_DATABASE": ["neo4j", "falkordb", "kuzudb"],
79
79
  "INDEX_VARIABLES": ["true", "false"],
80
80
  "ALLOW_DB_DELETION": ["true", "false"],
81
81
  "DEBUG_LOGS": ["true", "false"],
@@ -229,6 +229,13 @@ def _load_credentials():
229
229
  from dotenv import dotenv_values
230
230
  from codegraphcontext.cli.config_manager import ensure_config_dir
231
231
 
232
+ # Capture DATABASE_TYPE from actual shell env BEFORE we load .env files.
233
+ # If the user ran `DATABASE_TYPE=falkordb cgc …` we must not let
234
+ # DEFAULT_DATABASE=neo4j in .env steal priority later.
235
+ shell_db_type = os.environ.get('DATABASE_TYPE')
236
+ if shell_db_type and not os.environ.get('CGC_RUNTIME_DB_TYPE'):
237
+ os.environ['CGC_RUNTIME_DB_TYPE'] = shell_db_type
238
+
232
239
  # Ensure config directory exists (lazy initialization)
233
240
  ensure_config_dir()
234
241
 
@@ -272,9 +279,16 @@ def _load_credentials():
272
279
  for config in config_sources:
273
280
  merged_config.update(config)
274
281
 
275
- # Apply merged config to environment
282
+ # Apply merged config to environment.
283
+ # IMPORTANT: DB-selection keys set in the shell must win over .env defaults.
284
+ # E.g. `DATABASE_TYPE=falkordb cgc index …` must not be overridden by
285
+ # DEFAULT_DATABASE=neo4j sitting in ~/.codegraphcontext/.env
286
+ DB_OVERRIDE_KEYS = {"DATABASE_TYPE", "CGC_RUNTIME_DB_TYPE", "DEFAULT_DATABASE"}
276
287
  for key, value in merged_config.items():
277
288
  if value is not None: # Only set non-None values
289
+ # Never let .env clobber a DB-type key that the user already set in the shell
290
+ if key in DB_OVERRIDE_KEYS and key in os.environ:
291
+ continue
278
292
  os.environ[key] = str(value)
279
293
 
280
294
  # Report what was loaded
@@ -287,14 +301,31 @@ def _load_credentials():
287
301
  console.print("[yellow]No configuration file found. Using defaults.[/yellow]")
288
302
 
289
303
 
290
- # Show which database is actually being used
291
- # Check for runtime override first (from -db/--database flag)
304
+ # Show which database is actually being used.
305
+ # When DATABASE_TYPE is explicitly set, trust it. When it's left to auto-
306
+ # detect, call get_database_manager() so the banner can never lie: e.g. if
307
+ # falkordblite is installed but its native .so is missing (frozen bundle),
308
+ # the factory falls back to KùzuDB and we display that correctly.
292
309
  runtime_db = os.environ.get("CGC_RUNTIME_DB_TYPE")
293
- if runtime_db:
294
- default_db = runtime_db.lower()
310
+ explicit_db = (
311
+ runtime_db
312
+ or os.environ.get("DEFAULT_DATABASE")
313
+ or os.environ.get("DATABASE_TYPE")
314
+ )
315
+
316
+ if explicit_db:
317
+ default_db = explicit_db.lower()
295
318
  else:
296
- default_db = os.environ.get("DEFAULT_DATABASE", "falkordb").lower()
297
-
319
+ # No explicit choice — ask the factory which backend it will use
320
+ try:
321
+ from codegraphcontext.core import get_database_manager
322
+ _mgr = get_database_manager()
323
+ default_db = _mgr.get_backend_type() # e.g. 'falkordb' / 'kuzudb'
324
+ except Exception:
325
+ # Factory failed entirely — still show a best-guess
326
+ from codegraphcontext.core import _is_falkordb_available
327
+ default_db = "falkordb" if _is_falkordb_available() else "kuzudb"
328
+
298
329
  if default_db == "neo4j":
299
330
  has_neo4j_creds = all([
300
331
  os.environ.get("NEO4J_URI"),
@@ -308,18 +339,26 @@ def _load_credentials():
308
339
  else:
309
340
  console.print("[cyan]Using database: Neo4j[/cyan]")
310
341
  else:
311
- console.print("[yellow]⚠ DEFAULT_DATABASE=neo4j but credentials not found. Falling back to FalkorDB.[/yellow]")
342
+ console.print("[yellow]⚠ DEFAULT_DATABASE=neo4j but credentials not found. Falling back to default.[/yellow]")
343
+ elif default_db == "falkordb":
344
+ console.print("[cyan]Using database: FalkorDB Lite[/cyan]")
345
+ elif default_db == "kuzudb":
346
+ console.print("[cyan]Using database: KùzuDB[/cyan]")
312
347
  elif default_db == "falkordb-remote":
313
348
  host = os.environ.get("FALKORDB_HOST")
314
349
  if host:
315
350
  console.print(f"[cyan]Using database: FalkorDB Remote ({host})[/cyan]")
316
351
  else:
317
352
  console.print("[yellow]⚠ DATABASE_TYPE=falkordb-remote but FALKORDB_HOST not set.[/yellow]")
318
- else:
353
+ elif default_db == "falkordb":
319
354
  if os.environ.get("FALKORDB_HOST"):
320
355
  console.print(f"[cyan]Using database: FalkorDB Remote ({os.environ.get('FALKORDB_HOST')})[/cyan]")
321
356
  else:
322
357
  console.print("[cyan]Using database: FalkorDB[/cyan]")
358
+ else:
359
+ console.print(f"[cyan]Using database: {default_db}[/cyan]")
360
+
361
+
323
362
 
324
363
  # ============================================================================
325
364
  # CONFIG COMMAND GROUP
@@ -0,0 +1,176 @@
1
+ # src/codegraphcontext/core/__init__.py
2
+ """
3
+ Core database management module.
4
+
5
+ Supports Neo4j, FalkorDB Lite, remote FalkorDB, and KùzuDB backends.
6
+ Use DATABASE_TYPE environment variable to switch:
7
+ - DATABASE_TYPE=kuzudb - Uses embedded KùzuDB (Recommended for cross-platform zero-config)
8
+ - DATABASE_TYPE=falkordb - Uses embedded FalkorDB Lite (Unix-only)
9
+ - DATABASE_TYPE=falkordb-remote - Uses a remote/hosted FalkorDB server over TCP
10
+ - DATABASE_TYPE=neo4j - Uses Neo4j server
11
+ - If not set, auto-detects based on what's available
12
+
13
+ Priority (no DATABASE_TYPE set):
14
+ 1. FalkorDB Lite (Unix + Python 3.12+ + falkordblite installed)
15
+ 2. KùzuDB (cross-platform fallback)
16
+ 3. Remote FalkorDB (if FALKORDB_HOST is set)
17
+ 4. Neo4j (if credentials are configured)
18
+ """
19
+ import os
20
+ import platform
21
+ from typing import Union
22
+
23
+ import importlib.util
24
+
25
+ def _is_kuzudb_available() -> bool:
26
+ """Check if KùzuDB is installed."""
27
+ try:
28
+ return importlib.util.find_spec("kuzu") is not None
29
+ except ImportError:
30
+ return False
31
+
32
+ def _is_falkordb_available() -> bool:
33
+ """Check if FalkorDB Lite is installed (Unix only)."""
34
+ if platform.system() == "Windows":
35
+ return False
36
+
37
+ import sys
38
+ if sys.version_info < (3, 12):
39
+ return False
40
+ try:
41
+ import redislite
42
+ return hasattr(redislite, 'falkordb_client')
43
+ except ImportError:
44
+ return False
45
+
46
+ def _is_falkordb_remote_configured() -> bool:
47
+ """Check if a remote FalkorDB host is configured."""
48
+ return bool(os.getenv('FALKORDB_HOST'))
49
+
50
+ def _is_neo4j_configured() -> bool:
51
+ """Check if Neo4j is configured with credentials."""
52
+ return all([
53
+ os.getenv('NEO4J_URI'),
54
+ os.getenv('NEO4J_USERNAME'),
55
+ os.getenv('NEO4J_PASSWORD')
56
+ ])
57
+
58
+ def get_database_manager() -> Union['DatabaseManager', 'FalkorDBManager', 'FalkorDBRemoteManager', 'KuzuDBManager']:
59
+ """
60
+ Factory function to get the appropriate database manager based on configuration.
61
+
62
+ Selection logic:
63
+ 1. Runtime Override: 'CGC_RUNTIME_DB_TYPE' (set via --database flag)
64
+ 2. Configured Default: 'DEFAULT_DATABASE' (set via 'cgc default database')
65
+ 3. Legacy Env Var: 'DATABASE_TYPE'
66
+ 4. Implicit Default: KùzuDB (Best cross-platform zero-config)
67
+ 5. Auto-detect: Remote FalkorDB (if FALKORDB_HOST is set)
68
+ 6. Fallback Default: FalkorDB Lite (if Unix and available)
69
+ 7. Fallback: Neo4j (if configured)
70
+ """
71
+ from codegraphcontext.utils.debug_log import info_logger
72
+
73
+ # 1. Runtime Override (CLI flag) or Config/Env
74
+ db_type = os.getenv('CGC_RUNTIME_DB_TYPE')
75
+ if not db_type:
76
+ db_type = os.getenv('DEFAULT_DATABASE')
77
+ if not db_type:
78
+ db_type = os.getenv('DATABASE_TYPE')
79
+
80
+ if db_type:
81
+ db_type = db_type.lower()
82
+ if db_type == 'kuzudb':
83
+ if not _is_kuzudb_available():
84
+ raise ValueError("Database set to 'kuzudb' but Kùzu is not installed.\nRun 'pip install kuzu'")
85
+ from .database_kuzu import KuzuDBManager
86
+ info_logger("Using KùzuDB (explicit)")
87
+ return KuzuDBManager()
88
+
89
+ elif db_type == 'falkordb':
90
+ if not _is_falkordb_available():
91
+ info_logger("FalkorDB Lite is not supported or not installed. Falling back to KùzuDB.")
92
+ if _is_kuzudb_available():
93
+ from .database_kuzu import KuzuDBManager
94
+ return KuzuDBManager()
95
+ raise ValueError("Database set to 'falkordb' but FalkorDB Lite is not installed or not supported on this OS.\nRun 'pip install falkordblite'")
96
+
97
+ from .database_falkordb import FalkorDBManager, FalkorDBUnavailableError
98
+ try:
99
+ mgr = FalkorDBManager()
100
+ info_logger("Using FalkorDB Lite (explicit)")
101
+ return mgr
102
+ except FalkorDBUnavailableError as falkor_err:
103
+ info_logger(f"FalkorDB Lite not functional ({falkor_err}). Falling back to KùzuDB.")
104
+ if _is_kuzudb_available():
105
+ from .database_kuzu import KuzuDBManager
106
+ return KuzuDBManager()
107
+ raise
108
+
109
+ elif db_type == 'falkordb-remote':
110
+ if not _is_falkordb_remote_configured():
111
+ raise ValueError(
112
+ "Database set to 'falkordb-remote' but FALKORDB_HOST is not set.\n"
113
+ "Set the FALKORDB_HOST environment variable to your remote FalkorDB host."
114
+ )
115
+ from .database_falkordb_remote import FalkorDBRemoteManager
116
+ info_logger("Using remote FalkorDB (explicit)")
117
+ return FalkorDBRemoteManager()
118
+
119
+ elif db_type == 'neo4j':
120
+ if not _is_neo4j_configured():
121
+ raise ValueError("Database set to 'neo4j' but it is not configured.\nRun 'cgc neo4j setup' to configure Neo4j.")
122
+ from .database import DatabaseManager
123
+ info_logger("Using Neo4j Server (explicit)")
124
+ return DatabaseManager()
125
+ else:
126
+ raise ValueError(f"Unknown database type: '{db_type}'. Use 'kuzudb', 'falkordb', 'falkordb-remote', or 'neo4j'.")
127
+
128
+ # 4. Implicit Default -> FalkorDB Lite (Unix Zero Config)
129
+ if _is_falkordb_available():
130
+ from .database_falkordb import FalkorDBManager, FalkorDBUnavailableError
131
+ try:
132
+ mgr = FalkorDBManager()
133
+ info_logger("Using FalkorDB Lite (default)")
134
+ return mgr
135
+ except FalkorDBUnavailableError as falkor_err:
136
+ info_logger(
137
+ f"FalkorDB Lite not functional in this environment ({falkor_err}). "
138
+ "Falling back to KùzuDB."
139
+ )
140
+ # fall through to KùzuDB below
141
+
142
+ # 5. Implicit Default -> KùzuDB (Best Zero Config)
143
+ if _is_kuzudb_available():
144
+ from .database_kuzu import KuzuDBManager
145
+ info_logger("Using KùzuDB (default)")
146
+ return KuzuDBManager()
147
+
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
+ # 7. Fallback if configured
155
+ if _is_neo4j_configured():
156
+ from .database import DatabaseManager
157
+ info_logger("Using Neo4j Server (auto-detected)")
158
+ return DatabaseManager()
159
+
160
+ error_msg = "No database backend available.\n"
161
+ error_msg += "Recommended: Install KùzuDB for zero-config ('pip install kuzu')\n"
162
+
163
+ if platform.system() != "Windows":
164
+ error_msg += "Alternative: Install FalkorDB Lite ('pip install falkordblite')\n"
165
+
166
+ error_msg += "Alternative: Run 'cgc neo4j setup' to configure Neo4j."
167
+
168
+ raise ValueError(error_msg)
169
+
170
+ # For backward compatibility, export managers
171
+ from .database import DatabaseManager
172
+ from .database_falkordb import FalkorDBManager
173
+ from .database_falkordb_remote import FalkorDBRemoteManager
174
+ from .database_kuzu import KuzuDBManager
175
+
176
+ __all__ = ['DatabaseManager', 'FalkorDBManager', 'FalkorDBRemoteManager', 'KuzuDBManager', 'get_database_manager']