codegraphcontext 0.3.9__tar.gz → 0.4.1__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 (140) hide show
  1. {codegraphcontext-0.3.9/src/codegraphcontext.egg-info → codegraphcontext-0.4.1}/PKG-INFO +8 -7
  2. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/README.md +7 -6
  3. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/pyproject.toml +1 -1
  4. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/cli_helpers.py +33 -14
  5. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/config_manager.py +13 -1
  6. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/main.py +49 -40
  7. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/registry_commands.py +4 -84
  8. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/setup_wizard.py +23 -2
  9. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/__init__.py +19 -30
  10. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/bundle_registry.py +12 -2
  11. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/cgc_bundle.py +3 -3
  12. codegraphcontext-0.4.1/src/codegraphcontext/core/cgcignore.py +118 -0
  13. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/watcher.py +6 -6
  14. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/server.py +8 -1
  15. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/code_finder.py +126 -38
  16. codegraphcontext-0.4.1/src/codegraphcontext/tools/graph_builder.py +320 -0
  17. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/handlers/analysis_handlers.py +3 -2
  18. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/handlers/indexing_handlers.py +2 -1
  19. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/handlers/management_handlers.py +8 -3
  20. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -4
  21. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/handlers/watcher_handlers.py +4 -5
  22. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/__init__.py +1 -0
  23. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/constants.py +25 -0
  24. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/discovery.py +64 -0
  25. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/persistence/__init__.py +3 -0
  26. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/persistence/writer.py +758 -0
  27. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/pipeline.py +129 -0
  28. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/pre_scan.py +105 -0
  29. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/resolution/__init__.py +8 -0
  30. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/resolution/calls.py +204 -0
  31. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/resolution/inheritance.py +91 -0
  32. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/sanitize.py +41 -0
  33. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/schema.py +79 -0
  34. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/schema_contract.py +44 -0
  35. codegraphcontext-0.4.1/src/codegraphcontext/tools/indexing/scip_pipeline.py +140 -0
  36. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/dart.py +14 -4
  37. codegraphcontext-0.4.1/src/codegraphcontext/tools/languages/haskell.py +426 -0
  38. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/java.py +0 -24
  39. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/javascript.py +1 -1
  40. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/perl.py +7 -2
  41. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/php.py +27 -0
  42. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/rust.py +18 -21
  43. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/scala.py +1 -1
  44. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/typescript.py +0 -2
  45. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/scip_indexer.py +2 -2
  46. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/system.py +6 -2
  47. codegraphcontext-0.4.1/src/codegraphcontext/tools/tree_sitter_parser.py +103 -0
  48. codegraphcontext-0.4.1/src/codegraphcontext/utils/repo_path.py +27 -0
  49. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/utils/tree_sitter_manager.py +1 -0
  50. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/__vite-browser-external-9wXp6ZBx.js +1 -0
  51. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/function-calls-BtRHrqa2.png +0 -0
  52. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/graph-total-D1fBAugo.png +0 -0
  53. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/hero-graph-2voMJp2a.jpg +0 -0
  54. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/hierarchy-DGADo0YT.png +0 -0
  55. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/index-BJT3EMmQ.js +5571 -0
  56. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/index-DjDPHWki.css +1 -0
  57. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/parser.worker-CZgm11E5.js +208 -0
  58. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/assets/tree-sitter-qKYAACSa.wasm +0 -0
  59. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/favicon.ico +0 -0
  60. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/index.html +31 -0
  61. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/placeholder.svg +1 -0
  62. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/preview-image.png +0 -0
  63. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/robots.txt +14 -0
  64. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-c.wasm +0 -0
  65. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
  66. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-core.js +1 -0
  67. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-cpp.wasm +0 -0
  68. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-dart.wasm +0 -0
  69. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-go.wasm +0 -0
  70. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-java.wasm +0 -0
  71. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-javascript.wasm +0 -0
  72. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-kotlin.wasm +0 -0
  73. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-perl.wasm +1 -0
  74. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-php.wasm +0 -0
  75. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-python.wasm +0 -0
  76. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-ruby.wasm +0 -0
  77. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-rust.wasm +0 -0
  78. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-swift.wasm +0 -0
  79. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-tsx.wasm +0 -0
  80. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter-typescript.wasm +0 -0
  81. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/tree-sitter.wasm +0 -0
  82. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.js +4007 -0
  83. codegraphcontext-0.4.1/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.wasm +0 -0
  84. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/viz/server.py +10 -0
  85. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1/src/codegraphcontext.egg-info}/PKG-INFO +8 -7
  86. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext.egg-info/SOURCES.txt +52 -1
  87. codegraphcontext-0.3.9/src/codegraphcontext/tools/graph_builder.py +0 -1729
  88. codegraphcontext-0.3.9/src/codegraphcontext/tools/languages/haskell.py +0 -542
  89. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/LICENSE +0 -0
  90. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/MANIFEST.in +0 -0
  91. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/setup.cfg +0 -0
  92. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/__init__.py +0 -0
  93. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/__main__.py +0 -0
  94. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/__init__.py +0 -0
  95. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/setup_macos.py +0 -0
  96. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/cli/visualizer.py +0 -0
  97. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/database.py +0 -0
  98. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/database_falkordb.py +0 -0
  99. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
  100. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/database_kuzu.py +0 -0
  101. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/falkor_worker.py +0 -0
  102. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/core/jobs.py +0 -0
  103. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/prompts.py +0 -0
  104. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tool_definitions.py +0 -0
  105. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/__init__.py +0 -0
  106. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
  107. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/c.py +0 -0
  108. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/cpp.py +0 -0
  109. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/csharp.py +0 -0
  110. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/elixir.py +0 -0
  111. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/go.py +0 -0
  112. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
  113. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/python.py +0 -0
  114. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/ruby.py +0 -0
  115. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/swift.py +0 -0
  116. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
  117. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/package_resolver.py +0 -0
  118. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
  119. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
  120. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
  121. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
  122. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
  123. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
  124. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
  125. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
  126. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
  127. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
  128. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
  129. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
  130. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
  131. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
  132. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
  133. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/tools/scip_pb2.py +0 -0
  134. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/utils/debug_log.py +0 -0
  135. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/utils/path_ignore.py +0 -0
  136. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext/utils/visualize_graph.py +0 -0
  137. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  138. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  139. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext.egg-info/requires.txt +0 -0
  140. {codegraphcontext-0.3.9 → codegraphcontext-0.4.1}/src/codegraphcontext.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegraphcontext
3
- Version: 0.3.9
3
+ Version: 0.4.1
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
@@ -74,8 +74,8 @@ Dynamic: license-file
74
74
  - 🇨🇳 [中文](README.zh-CN.md)
75
75
  - 🇰🇷 [한국어](README.kor.md)
76
76
  - 🇺🇦 [Українська](README.uk.md)
77
+ - 🇷🇺 [Русский](README.ru-RU.md)
77
78
  - 🇯🇵 日本語 (Soon)
78
- - 🇷🇺 Русский (Soon)
79
79
  - 🇪🇸 Español (Soon)
80
80
 
81
81
  🌍 **Help translate CodeGraphContext to your language by raising an issue & PR on https://github.com/Shashankss1205/CodeGraphContext/issues!**
@@ -164,7 +164,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
164
164
  ---
165
165
 
166
166
  ## Project Details
167
- - **Version:** 0.3.9
167
+ - **Version:** 0.4.1
168
168
  - **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
169
169
  - **License:** MIT License (See [LICENSE](LICENSE) for details)
170
170
  - **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
@@ -197,7 +197,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
197
197
  - **Interactive Setup:** A user-friendly command-line wizard for easy setup.
198
198
  - **Dual Mode:** Works as a standalone **CLI toolkit** for developers and as an **MCP server** for AI agents.
199
199
  - **Multi-Language Support:** Full support for 14 programming languages.
200
- - **Flexible Database Backend:** KùzuDB (default, zero-config for all platforms), FalkorDB Lite (Unix-only), FalkorDB Remote, or Neo4j (all platforms via Docker/native).
200
+ - **Flexible Database Backend:** KùzuDB (default on Windows), FalkorDB Lite (typical embedded default on Unix when installed), FalkorDB Remote, or Neo4j (all platforms via Docker/native).
201
201
 
202
202
  ---
203
203
 
@@ -221,8 +221,9 @@ Each language parser extracts functions, classes, methods, parameters, inheritan
221
221
 
222
222
  CodeGraphContext supports multiple graph database backends to suit your environment:
223
223
 
224
- | Feature | KùzuDB (Default) | FalkorDB Lite | Neo4j |
224
+ | Feature | KùzuDB | FalkorDB Lite | Neo4j |
225
225
  | :--- | :--- | :--- | :--- |
226
+ | **Typical default** | **Windows** (embedded, when `kuzu` is installed) | **Unix** (Python 3.12+, when `falkordblite` works) | When explicitly configured |
226
227
  | **Setup** | Zero-config / Embedded | Zero-config / In-process | Docker / External |
227
228
  | **Platform** | **All (Windows Native, macOS, Linux)** | Unix-only (Linux/macOS/WSL) | All Platforms |
228
229
  | **Use Case** | Desktop, IDE, Local development | Specialized Unix development | Enterprise, Massive graphs |
@@ -337,8 +338,8 @@ Use CodeGraphContext as an **MCP server** for AI assistants:
337
338
 
338
339
  2. **Database Setup (Automatic)**
339
340
 
340
- - **KùzuDB (Default):** Runs natively on Windows, macOS, and Linux without any setup. Just `pip install kuzu` and you're ready!
341
- - **FalkorDB Lite (Alternative):** Supported on Unix/macOS/WSL for Python 3.12+.
341
+ - **KùzuDB (default on Windows):** Runs natively on Windows, macOS, and Linux. On Windows it is the usual embedded choice; `pip install kuzu` if needed.
342
+ - **FalkorDB Lite (typical default on Unix):** When Python 3.12+ and `falkordblite` are available on Unix/macOS/WSL, the embedded backend prefers FalkorDB Lite; otherwise KùzuDB is used.
342
343
  - **Neo4j (Alternative):** To use Neo4j instead, or if you prefer a server-based approach, run: `cgc neo4j setup`
343
344
 
344
345
  ---
@@ -7,8 +7,8 @@
7
7
  - 🇨🇳 [中文](README.zh-CN.md)
8
8
  - 🇰🇷 [한국어](README.kor.md)
9
9
  - 🇺🇦 [Українська](README.uk.md)
10
+ - 🇷🇺 [Русский](README.ru-RU.md)
10
11
  - 🇯🇵 日本語 (Soon)
11
- - 🇷🇺 Русский (Soon)
12
12
  - 🇪🇸 Español (Soon)
13
13
 
14
14
  🌍 **Help translate CodeGraphContext to your language by raising an issue & PR on https://github.com/Shashankss1205/CodeGraphContext/issues!**
@@ -97,7 +97,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
97
97
  ---
98
98
 
99
99
  ## Project Details
100
- - **Version:** 0.3.9
100
+ - **Version:** 0.4.1
101
101
  - **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
102
102
  - **License:** MIT License (See [LICENSE](LICENSE) for details)
103
103
  - **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
@@ -130,7 +130,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
130
130
  - **Interactive Setup:** A user-friendly command-line wizard for easy setup.
131
131
  - **Dual Mode:** Works as a standalone **CLI toolkit** for developers and as an **MCP server** for AI agents.
132
132
  - **Multi-Language Support:** Full support for 14 programming languages.
133
- - **Flexible Database Backend:** KùzuDB (default, zero-config for all platforms), FalkorDB Lite (Unix-only), FalkorDB Remote, or Neo4j (all platforms via Docker/native).
133
+ - **Flexible Database Backend:** KùzuDB (default on Windows), FalkorDB Lite (typical embedded default on Unix when installed), FalkorDB Remote, or Neo4j (all platforms via Docker/native).
134
134
 
135
135
  ---
136
136
 
@@ -154,8 +154,9 @@ Each language parser extracts functions, classes, methods, parameters, inheritan
154
154
 
155
155
  CodeGraphContext supports multiple graph database backends to suit your environment:
156
156
 
157
- | Feature | KùzuDB (Default) | FalkorDB Lite | Neo4j |
157
+ | Feature | KùzuDB | FalkorDB Lite | Neo4j |
158
158
  | :--- | :--- | :--- | :--- |
159
+ | **Typical default** | **Windows** (embedded, when `kuzu` is installed) | **Unix** (Python 3.12+, when `falkordblite` works) | When explicitly configured |
159
160
  | **Setup** | Zero-config / Embedded | Zero-config / In-process | Docker / External |
160
161
  | **Platform** | **All (Windows Native, macOS, Linux)** | Unix-only (Linux/macOS/WSL) | All Platforms |
161
162
  | **Use Case** | Desktop, IDE, Local development | Specialized Unix development | Enterprise, Massive graphs |
@@ -270,8 +271,8 @@ Use CodeGraphContext as an **MCP server** for AI assistants:
270
271
 
271
272
  2. **Database Setup (Automatic)**
272
273
 
273
- - **KùzuDB (Default):** Runs natively on Windows, macOS, and Linux without any setup. Just `pip install kuzu` and you're ready!
274
- - **FalkorDB Lite (Alternative):** Supported on Unix/macOS/WSL for Python 3.12+.
274
+ - **KùzuDB (default on Windows):** Runs natively on Windows, macOS, and Linux. On Windows it is the usual embedded choice; `pip install kuzu` if needed.
275
+ - **FalkorDB Lite (typical default on Unix):** When Python 3.12+ and `falkordblite` are available on Unix/macOS/WSL, the embedded backend prefers FalkorDB Lite; otherwise KùzuDB is used.
275
276
  - **Neo4j (Alternative):** To use Neo4j instead, or if you prefer a server-based approach, run: `cgc neo4j setup`
276
277
 
277
278
  ---
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codegraphcontext"
3
- version = "0.3.9"
3
+ version = "0.4.1"
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"
@@ -24,6 +24,7 @@ from ..tools.code_finder import CodeFinder
24
24
  from ..tools.graph_builder import GraphBuilder
25
25
  from ..tools.package_resolver import get_local_package_path
26
26
  from ..utils.debug_log import info_logger, warning_logger
27
+ from ..utils.repo_path import any_repo_matches_path
27
28
  from .config_manager import resolve_context, ResolvedContext, register_repo_in_context, ensure_first_run_bootstrap
28
29
 
29
30
  console = Console()
@@ -175,8 +176,8 @@ def index_helper(path: str, context: Optional[str] = None):
175
176
  return
176
177
 
177
178
  indexed_repos = code_finder.list_indexed_repositories()
178
- repo_exists = any(Path(repo["path"]).resolve() == path_obj for repo in indexed_repos)
179
-
179
+ repo_exists = any_repo_matches_path(indexed_repos, path_obj)
180
+
180
181
  if repo_exists:
181
182
  # Check if the repository actually has files (not just an empty node from interrupted indexing)
182
183
  # Use variable-length path to handle both flat (Repository->File) and
@@ -184,7 +185,7 @@ def index_helper(path: str, context: Optional[str] = None):
184
185
  try:
185
186
  with db_manager.get_driver().session() as session:
186
187
  result = session.run(
187
- "MATCH (r:Repository {path: $path})-[:CONTAINS*]->(f:File) RETURN count(f) as file_count",
188
+ "MATCH (r:Repository {path: $path})-[:CONTAINS*]->(f:File) RETURN count(DISTINCT f) as file_count",
188
189
  path=str(path_obj)
189
190
  )
190
191
  record = result.single()
@@ -284,7 +285,7 @@ def list_repos_helper(context: Optional[str] = None):
284
285
 
285
286
  for repo in repos:
286
287
  repo_type = "Dependency" if repo.get("is_dependency") else "Project"
287
- table.add_row(repo["name"], repo["path"], repo_type)
288
+ table.add_row(repo.get("name") or "", str(repo.get("path") or ""), repo_type)
288
289
 
289
290
  console.print(table)
290
291
  except Exception as e:
@@ -377,7 +378,7 @@ import urllib.parse
377
378
  from ..viz.server import run_server, set_db_manager
378
379
 
379
380
  def visualize_helper(repo_path: Optional[str] = None, port: int = 8000, context: Optional[str] = None):
380
- """"Generates an interactive visualization using the Playground UI."""
381
+ """Generates an interactive visualization using the Playground UI."""
381
382
  services = _initialize_services(context)
382
383
  if not all(services[:3]):
383
384
  return
@@ -415,15 +416,33 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000, context:
415
416
  if cwd_static_dir.exists():
416
417
  static_dir = cwd_static_dir
417
418
  else:
418
- console.print(f"[yellow]Warning: Visualization assets not found.[/yellow]")
419
- console.print(f"[dim]Checked paths:[/dim]")
420
- console.print(f" [dim]- {static_dir}[/dim]")
419
+ console.print("[bold red]Visualization assets not found.[/bold red]")
420
+ console.print("[dim]Checked paths:[/dim]")
421
+ console.print(f" [dim]- {package_root / 'viz' / 'dist'}[/dim]")
421
422
  console.print(f" [dim]- {dev_static_dir}[/dim]")
422
423
  console.print(f" [dim]- {alt_dev_dir}[/dim]")
423
424
  console.print(f" [dim]- {cwd_static_dir}[/dim]")
424
- console.print("[dim]Please run 'cd website && npm run build' first.[/dim]")
425
- # We continue anyway to let the server start (helpful for dev)
426
-
425
+ console.print(
426
+ "[dim]If you installed from PyPI, upgrade after the next release "
427
+ "(wheels must bundle viz/dist). If you are developing from source, run:[/dim]"
428
+ )
429
+ console.print(" [cyan]./scripts/sync_viz_dist.sh[/cyan]")
430
+ console.print(
431
+ "[dim]or[/dim] [cyan]cd website && npm ci && npm run build[/cyan] "
432
+ "[dim]then sync[/dim] [cyan]website/dist[/cyan] [dim]→[/dim] "
433
+ "[cyan]src/codegraphcontext/viz/dist[/cyan][dim].[/dim]"
434
+ )
435
+ db_manager.close_driver()
436
+ raise SystemExit(1)
437
+
438
+ index_html = static_dir / "index.html"
439
+ if not index_html.is_file():
440
+ console.print(
441
+ f"[bold red]Invalid visualization bundle:[/bold red] missing {index_html}"
442
+ )
443
+ db_manager.close_driver()
444
+ raise SystemExit(1)
445
+
427
446
  # Construct the URL
428
447
  backend_url = f"http://localhost:{port}"
429
448
  params = {"backend": backend_url}
@@ -471,8 +490,8 @@ def reindex_helper(path: str, context: Optional[str] = None):
471
490
 
472
491
  # Check if already indexed
473
492
  indexed_repos = code_finder.list_indexed_repositories()
474
- repo_exists = any(Path(repo["path"]).resolve() == path_obj for repo in indexed_repos)
475
-
493
+ repo_exists = any_repo_matches_path(indexed_repos, path_obj)
494
+
476
495
  if repo_exists:
477
496
  console.print(f"[yellow]Deleting existing index for: {path_obj}[/yellow]")
478
497
  try:
@@ -671,7 +690,7 @@ def watch_helper(path: str, context: Optional[str] = None):
671
690
  # transient empty result from list_indexed_repositories never triggers a
672
691
  # destructive full rescan of an already-populated graph.
673
692
  indexed_repos = code_finder.list_indexed_repositories()
674
- is_indexed = any(Path(repo["path"]).resolve() == path_obj for repo in indexed_repos)
693
+ is_indexed = any_repo_matches_path(indexed_repos, path_obj)
675
694
  if not is_indexed:
676
695
  # Fallback: count File nodes whose path starts with this repo's path.
677
696
  # If > 100 exist, the repo is clearly already indexed — skip the scan.
@@ -78,7 +78,7 @@ CONFIG_DESCRIPTIONS = {
78
78
 
79
79
  # Valid values for each config key
80
80
  CONFIG_VALIDATORS = {
81
- "DEFAULT_DATABASE": ["neo4j", "falkordb", "kuzudb"],
81
+ "DEFAULT_DATABASE": ["neo4j", "falkordb", "falkordb-remote", "kuzudb"],
82
82
  "INDEX_VARIABLES": ["true", "false"],
83
83
  "ALLOW_DB_DELETION": ["true", "false"],
84
84
  "DEBUG_LOGS": ["true", "false"],
@@ -219,6 +219,18 @@ def find_local_env() -> Optional[Path]:
219
219
  return None
220
220
 
221
221
 
222
+ def codegraphcontext_dotenv_at_cwd(cwd: Optional[Path] = None) -> Optional[Path]:
223
+ """
224
+ Return ``<cwd>/.codegraphcontext/.env`` if that file exists, else None.
225
+
226
+ *cwd* defaults to ``Path.cwd()``. Parent directories are **not** searched—same rule as
227
+ local context resolution (``find_local_cgc_dir``).
228
+ """
229
+ root = (cwd or Path.cwd()).resolve()
230
+ candidate = root / ".codegraphcontext" / ".env"
231
+ return candidate if candidate.exists() else None
232
+
233
+
222
234
  def save_config(config: Dict[str, str], preserve_db_credentials: bool = True):
223
235
  """
224
236
  Save configuration to file.
@@ -19,7 +19,6 @@ import logging
19
19
  import json
20
20
  import os
21
21
  from pathlib import Path
22
- from dotenv import load_dotenv, find_dotenv, set_key
23
22
  from importlib.metadata import version as pkg_version, PackageNotFoundError
24
23
 
25
24
  from codegraphcontext.server import MCPServer
@@ -111,6 +110,7 @@ def mcp_setup():
111
110
  - VS Code, Cursor, Windsurf
112
111
  - Claude Desktop, Gemini CLI
113
112
  - Cline, RooCode, Amazon Q Developer
113
+ - OpenCode (prints stdio config + link to vendor docs)
114
114
 
115
115
  Works with FalkorDB by default (no database setup needed).
116
116
  """
@@ -290,19 +290,18 @@ def _load_credentials():
290
290
  Uses per-variable precedence - each variable is loaded from the highest priority source.
291
291
  Priority order (highest to lowest):
292
292
  1. Local `mcp.json` env vars (highest - explicit MCP server config)
293
- 2. Local `.env` in project directory (high - project-specific overrides)
293
+ 2. ``<cwd>/.codegraphcontext/.env`` only (no parent-directory walk)
294
294
  3. Global `~/.codegraphcontext/.env` (lowest - user defaults)
295
+
296
+ Step 2 skips duplicate loading when that file is the same path as the global file.
297
+ Arbitrary repo-root `.env` files are not loaded—only CodeGraphContext config paths.
295
298
  """
296
299
  from dotenv import dotenv_values
297
- from codegraphcontext.cli.config_manager import ensure_config_dir
300
+ from codegraphcontext.cli.config_manager import (
301
+ ensure_config_dir,
302
+ codegraphcontext_dotenv_at_cwd,
303
+ )
298
304
 
299
- # Capture DATABASE_TYPE from actual shell env BEFORE we load .env files.
300
- # If the user ran `DATABASE_TYPE=falkordb cgc …` we must not let
301
- # DEFAULT_DATABASE=neo4j in .env steal priority later.
302
- shell_db_type = os.environ.get('DATABASE_TYPE')
303
- if shell_db_type and not os.environ.get('CGC_RUNTIME_DB_TYPE'):
304
- os.environ['CGC_RUNTIME_DB_TYPE'] = shell_db_type
305
-
306
305
  # Ensure config directory exists (lazy initialization)
307
306
  ensure_config_dir()
308
307
 
@@ -319,14 +318,16 @@ def _load_credentials():
319
318
  except Exception as e:
320
319
  console.print(f"[yellow]Warning: Could not load global .env: {e}[/yellow]")
321
320
 
322
- # 2. Local project .env (higher priority - project-specific overrides)
321
+ # 2. <cwd>/.codegraphcontext/.env only (overrides global when distinct)
323
322
  try:
324
- dotenv_path = find_dotenv(usecwd=True, raise_error_if_not_found=False)
325
- if dotenv_path:
326
- config_sources.append(dotenv_values(dotenv_path))
327
- config_source_names.append(str(dotenv_path))
323
+ local_cgc_env = codegraphcontext_dotenv_at_cwd(Path.cwd())
324
+ if local_cgc_env and local_cgc_env.resolve() != global_env_path.resolve():
325
+ config_sources.append(dotenv_values(str(local_cgc_env)))
326
+ config_source_names.append(str(local_cgc_env))
328
327
  except Exception as e:
329
- console.print(f"[yellow]Warning: Could not load .env from current directory: {e}[/yellow]")
328
+ console.print(
329
+ f"[yellow]Warning: Could not load .codegraphcontext/.env at cwd: {e}[/yellow]"
330
+ )
330
331
 
331
332
  # 1. Local mcp.json (highest priority - explicit MCP server config)
332
333
  mcp_file_path = Path.cwd() / "mcp.json"
@@ -348,9 +349,9 @@ def _load_credentials():
348
349
 
349
350
  # Apply merged config to environment.
350
351
  # IMPORTANT: DB-selection keys set in the shell must win over .env defaults.
351
- # E.g. `DATABASE_TYPE=falkordb cgc index …` must not be overridden by
352
+ # E.g. `DEFAULT_DATABASE=falkordb cgc index …` must not be overridden by
352
353
  # DEFAULT_DATABASE=neo4j sitting in ~/.codegraphcontext/.env
353
- DB_OVERRIDE_KEYS = {"DATABASE_TYPE", "CGC_RUNTIME_DB_TYPE", "DEFAULT_DATABASE"}
354
+ DB_OVERRIDE_KEYS = {"CGC_RUNTIME_DB_TYPE", "DEFAULT_DATABASE"}
354
355
  for key, value in merged_config.items():
355
356
  if value is not None: # Only set non-None values
356
357
  # Never let .env clobber a DB-type key that the user already set in the shell
@@ -369,16 +370,10 @@ def _load_credentials():
369
370
 
370
371
 
371
372
  # Show which database is actually being used.
372
- # When DATABASE_TYPE is explicitly set, trust it. When it's left to auto-
373
- # detect, call get_database_manager() so the banner can never lie: e.g. if
374
- # falkordblite is installed but its native .so is missing (frozen bundle),
375
- # the factory falls back to KùzuDB and we display that correctly.
373
+ # When CGC_RUNTIME_DB_TYPE or DEFAULT_DATABASE is set, trust it. Otherwise
374
+ # call get_database_manager() so the banner matches factory fallbacks.
376
375
  runtime_db = os.environ.get("CGC_RUNTIME_DB_TYPE")
377
- explicit_db = (
378
- runtime_db
379
- or os.environ.get("DEFAULT_DATABASE")
380
- or os.environ.get("DATABASE_TYPE")
381
- )
376
+ explicit_db = runtime_db or os.environ.get("DEFAULT_DATABASE")
382
377
 
383
378
  if explicit_db:
384
379
  default_db = explicit_db.lower()
@@ -416,12 +411,9 @@ def _load_credentials():
416
411
  if host:
417
412
  console.print(f"[cyan]Using database: FalkorDB Remote ({host})[/cyan]")
418
413
  else:
419
- console.print("[yellow]⚠ DATABASE_TYPE=falkordb-remote but FALKORDB_HOST not set.[/yellow]")
420
- elif default_db == "falkordb":
421
- if os.environ.get("FALKORDB_HOST"):
422
- console.print(f"[cyan]Using database: FalkorDB Remote ({os.environ.get('FALKORDB_HOST')})[/cyan]")
423
- else:
424
- console.print("[cyan]Using database: FalkorDB[/cyan]")
414
+ console.print(
415
+ "[yellow]⚠ DEFAULT_DATABASE=falkordb-remote but FALKORDB_HOST not set.[/yellow]"
416
+ )
425
417
  else:
426
418
  console.print(f"[cyan]Using database: {default_db}[/cyan]")
427
419
 
@@ -474,7 +466,7 @@ def config_reset():
474
466
  console.print("[yellow]Reset cancelled[/yellow]")
475
467
 
476
468
  @config_app.command("db")
477
- def config_db(backend: str = typer.Argument(..., help="Database backend: 'neo4j' or 'falkordb'")):
469
+ def config_db(backend: str = typer.Argument(..., help="Database backend: 'neo4j', 'falkordb', 'falkordb-remote', or 'kuzudb'")):
478
470
  """
479
471
  Quickly switch the default database backend.
480
472
 
@@ -483,14 +475,19 @@ def config_db(backend: str = typer.Argument(..., help="Database backend: 'neo4j'
483
475
  Examples:
484
476
  cgc config db neo4j
485
477
  cgc config db falkordb
478
+ cgc config db kuzudb
486
479
  """
487
480
  backend = backend.lower()
488
- if backend not in ['falkordb', 'falkordb-remote', 'neo4j']:
481
+ if backend not in ['falkordb', 'falkordb-remote', 'neo4j', 'kuzudb']:
489
482
  console.print(f"[bold red]Invalid backend: {backend}[/bold red]")
490
- console.print("Must be 'falkordb', 'falkordb-remote', or 'neo4j'")
483
+ console.print("Must be 'falkordb', 'falkordb-remote', 'neo4j', or 'kuzudb'")
491
484
  raise typer.Exit(code=1)
492
485
 
493
- config_manager.set_config_value("DEFAULT_DATABASE", backend)
486
+ updated = config_manager.set_config_value("DEFAULT_DATABASE", backend)
487
+ if not updated:
488
+ console.print(f"[bold red]Failed to switch default database to {backend}[/bold red]")
489
+ raise typer.Exit(code=1)
490
+
494
491
  console.print(f"[green]✔ Default database switched to {backend}[/green]")
495
492
 
496
493
  # ============================================================================
@@ -672,10 +669,12 @@ def bundle_load(
672
669
  @app.command("export", rich_help_panel="Bundle Shortcuts")
673
670
  def export_shortcut(
674
671
  output: str = typer.Argument(..., help="Output path for the .cgc bundle file"),
675
- repo: Optional[str] = typer.Option(None, "--repo", "-r", help="Specific repository path to export")
672
+ repo: Optional[str] = typer.Option(None, "--repo", "-r", help="Specific repository path to export"),
673
+ no_stats: bool = typer.Option(False, "--no-stats", help="Skip generating statistics in the bundle"),
674
+ context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"),
676
675
  ):
677
676
  """Shortcut for 'cgc bundle export'"""
678
- bundle_export(output, repo, False)
677
+ bundle_export(output, repo, no_stats, context)
679
678
 
680
679
  @app.command("load", rich_help_panel="Bundle Shortcuts")
681
680
  def load_shortcut(
@@ -796,6 +795,7 @@ def doctor():
796
795
 
797
796
  # 1. Check configuration
798
797
  console.print("[bold]1. Checking Configuration...[/bold]")
798
+ config = {}
799
799
  try:
800
800
  config = config_manager.load_config()
801
801
 
@@ -851,6 +851,15 @@ def doctor():
851
851
  all_checks_passed = False
852
852
  else:
853
853
  console.print(f" [yellow]⚠[/yellow] Neo4j credentials not set. Run 'cgc neo4j setup'")
854
+ elif default_db == "kuzudb":
855
+ from importlib.util import find_spec
856
+
857
+ if find_spec("kuzu") is not None:
858
+ console.print(f" [green]✓[/green] KuzuDB is installed")
859
+ else:
860
+ console.print(f" [red]✗[/red] KuzuDB is not installed")
861
+ console.print(f" Run: pip install kuzu")
862
+ all_checks_passed = False
854
863
  else:
855
864
  # FalkorDB
856
865
  try:
@@ -2313,7 +2322,7 @@ def main(
2313
2322
  None,
2314
2323
  "--database",
2315
2324
  "-db",
2316
- help="[Global] Temporarily override database backend (falkordb or neo4j) for any command"
2325
+ help="[Global] Temporarily override database backend (falkordb, falkordb-remote, neo4j, or kuzudb) for any command"
2317
2326
  ),
2318
2327
  visual: bool = typer.Option(
2319
2328
  False,
@@ -17,93 +17,12 @@ console = Console()
17
17
 
18
18
  GITHUB_ORG = "CodeGraphContext"
19
19
  GITHUB_REPO = "CodeGraphContext"
20
- REGISTRY_API_URL = f"https://api.github.com/repos/{GITHUB_ORG}/{GITHUB_REPO}/releases"
21
- MANIFEST_URL = f"https://github.com/{GITHUB_ORG}/{GITHUB_REPO}/releases/download/on-demand-bundles/manifest.json"
22
20
 
23
21
 
24
22
  def fetch_available_bundles() -> List[Dict[str, Any]]:
25
- """
26
- Fetch all available bundles from GitHub Releases.
27
- Returns a list of bundle dictionaries with metadata.
28
- Preserves all versions - no deduplication.
29
- """
30
- all_bundles = []
31
-
32
- try:
33
- # 1. Fetch on-demand bundles from manifest
34
- try:
35
- response = requests.get(MANIFEST_URL, timeout=10)
36
- if response.status_code == 200:
37
- manifest = response.json()
38
- if manifest.get('bundles'):
39
- for bundle in manifest['bundles']:
40
- bundle['source'] = 'on-demand'
41
- # Ensure bundle has a full_name field (with version info)
42
- if 'bundle_name' in bundle:
43
- # Extract full name without .cgc extension
44
- bundle['full_name'] = bundle['bundle_name'].replace('.cgc', '')
45
- all_bundles.append(bundle)
46
- except Exception as e:
47
- console.print(f"[dim]Note: Could not fetch on-demand bundles: {e}[/dim]")
48
-
49
- # 2. Fetch weekly pre-indexed bundles
50
- try:
51
- response = requests.get(REGISTRY_API_URL, timeout=10)
52
- if response.status_code == 200:
53
- releases = response.json()
54
-
55
- # Find weekly releases (bundles-YYYYMMDD pattern)
56
- weekly_releases = [r for r in releases if r['tag_name'].startswith('bundles-') and r['tag_name'] != 'bundles-latest']
57
-
58
- if weekly_releases:
59
- # Get the most recent weekly release
60
- latest_weekly = weekly_releases[0]
61
-
62
- for asset in latest_weekly.get('assets', []):
63
- if asset['name'].endswith('.cgc'):
64
- # Full bundle name without extension
65
- full_name = asset['name'].replace('.cgc', '')
66
-
67
- # Parse bundle name
68
- name_parts = full_name.split('-')
69
- bundle = {
70
- 'name': name_parts[0], # Base package name
71
- 'full_name': full_name, # Complete name with version
72
- 'repo': f"{name_parts[0]}/{name_parts[0]}", # Simplified
73
- 'bundle_name': asset['name'],
74
- 'version': name_parts[1] if len(name_parts) > 1 else 'latest',
75
- 'commit': name_parts[2] if len(name_parts) > 2 else 'unknown',
76
- 'size': f"{asset['size'] / 1024 / 1024:.1f}MB",
77
- 'download_url': asset['browser_download_url'],
78
- 'generated_at': asset['updated_at'],
79
- 'source': 'weekly'
80
- }
81
- all_bundles.append(bundle)
82
- except Exception as e:
83
- console.print(f"[dim]Note: Could not fetch weekly bundles: {e}[/dim]")
84
-
85
- # Normalize all bundles to have required fields
86
- for bundle in all_bundles:
87
- # Ensure 'name' field exists (base package name)
88
- if 'name' not in bundle:
89
- repo = bundle.get('repo', '')
90
- if '/' in repo:
91
- bundle['name'] = repo.split('/')[-1]
92
- else:
93
- # Extract from full_name or bundle_name
94
- full_name = bundle.get('full_name', bundle.get('bundle_name', 'unknown'))
95
- bundle['name'] = full_name.split('-')[0]
96
-
97
- # Ensure 'full_name' exists
98
- if 'full_name' not in bundle:
99
- bundle['full_name'] = bundle.get('bundle_name', bundle.get('name', 'unknown')).replace('.cgc', '')
100
-
101
- # NO DEDUPLICATION - Keep all versions
102
- return all_bundles
103
-
104
- except Exception as e:
105
- console.print(f"[bold red]Error fetching bundles: {e}[/bold red]")
106
- return []
23
+ """Fetch all available bundles from GitHub Releases (delegates to core BundleRegistry)."""
24
+ from ..core.bundle_registry import BundleRegistry
25
+ return BundleRegistry.fetch_available_bundles()
107
26
 
108
27
 
109
28
  def _get_base_package_name(bundle_name: str) -> str:
@@ -213,6 +132,7 @@ def search_bundles(query: str):
213
132
  matching_bundles = [
214
133
  b for b in bundles
215
134
  if query_lower in b.get('name', '').lower() or
135
+ query_lower in b.get('full_name', '').lower() or
216
136
  query_lower in b.get('repo', '').lower() or
217
137
  query_lower in b.get('description', '').lower()
218
138
  ]
@@ -135,12 +135,26 @@ def convert_mcp_json_to_yaml():
135
135
  yaml.dump(mcp_config, yaml_file, default_flow_style=False)
136
136
  console.print(f"[green]Generated devfile.yaml for Amazon Q Developer at {yaml_path}[/green]")
137
137
 
138
+ def _print_opencode_mcp_instructions(mcp_config: dict) -> None:
139
+ """OpenCode manages MCP in its own UI; we only print the stdio snippet + doc link."""
140
+ console.print("\n[bold cyan]OpenCode[/bold cyan]")
141
+ console.print(
142
+ "Register a stdio MCP server in OpenCode using the same command, args, and env as below "
143
+ "(mirror your generated mcp.json so OpenCode and the CLI share one database)."
144
+ )
145
+ console.print(
146
+ "\n[dim]Vendor guide:[/dim] https://opencode.ai/docs/ko/mcp-servers/#_top"
147
+ )
148
+ console.print("\n[bold]Suggested MCP server JSON:[/bold]")
149
+ console.print(json.dumps(mcp_config, indent=2))
150
+
151
+
138
152
  def _configure_ide(mcp_config):
139
153
  """Asks user for their IDE and configures it automatically."""
140
154
  questions = [
141
155
  {
142
156
  "type": "confirm",
143
- "message": "Automatically configure your IDE/CLI (VS Code, Cursor, Windsurf, Claude, Gemini, Cline, RooCode, ChatGPT Codex, Amazon Q Developer, Aider, Kiro, Antigravity)?",
157
+ "message": "Automatically configure your IDE/CLI (VS Code, Cursor, Windsurf, Claude, Gemini, Cline, RooCode, ChatGPT Codex, Amazon Q Developer, Aider, Kiro, Antigravity, OpenCode)?",
144
158
  "name": "configure_ide",
145
159
  "default": True,
146
160
  }
@@ -154,7 +168,7 @@ def _configure_ide(mcp_config):
154
168
  {
155
169
  "type": "list",
156
170
  "message": "Choose your IDE/CLI to configure:",
157
- "choices": ["VS Code", "Cursor", "Windsurf", "Claude code", "Gemini CLI", "ChatGPT Codex", "Cline", "RooCode", "Amazon Q Developer", "JetBrainsAI", "Aider", "Kiro", "Antigravity", "None of the above"],
171
+ "choices": ["VS Code", "Cursor", "Windsurf", "Claude code", "Gemini CLI", "ChatGPT Codex", "Cline", "RooCode", "Amazon Q Developer", "JetBrainsAI", "Aider", "Kiro", "Antigravity", "OpenCode", "None of the above"],
158
172
  "name": "ide_choice",
159
173
  }
160
174
  ]
@@ -165,6 +179,13 @@ def _configure_ide(mcp_config):
165
179
  console.print("\n[cyan]You can add the MCP server manually to your IDE/CLI.[/cyan]")
166
180
  return
167
181
 
182
+ if ide_choice == "OpenCode":
183
+ _print_opencode_mcp_instructions(mcp_config)
184
+ console.print(
185
+ "\n[green]When you have pasted this into OpenCode, reload MCP and run "
186
+ "`cgc mcp start` from a terminal to verify the server starts cleanly.[/green]"
187
+ )
188
+ return
168
189
 
169
190
  if ide_choice in ["VS Code", "Cursor", "Claude code", "Gemini CLI", "ChatGPT Codex", "Cline", "Windsurf", "RooCode", "Amazon Q Developer", "JetBrainsAI", "Aider", "Kiro", "Antigravity"]:
170
191
  console.print(f"\n[bold cyan]Configuring for {ide_choice}...[/bold cyan]")