codegraphcontext 0.3.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codegraphcontext-0.3.3/MANIFEST.in +4 -0
- {codegraphcontext-0.3.1/src/codegraphcontext.egg-info → codegraphcontext-0.3.3}/PKG-INFO +4 -4
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/README.md +3 -2
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/pyproject.toml +1 -2
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/cli_helpers.py +15 -243
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/main.py +1 -1
- codegraphcontext-0.3.3/src/codegraphcontext/cli/visualizer.py +50 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/cgc_bundle.py +5 -1
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/graph_builder.py +233 -66
- codegraphcontext-0.3.3/src/codegraphcontext/tools/handlers/query_handlers.py +87 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/package_resolver.py +12 -10
- codegraphcontext-0.3.3/src/codegraphcontext/utils/visualize_graph.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/viz/server.py +18 -17
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3/src/codegraphcontext.egg-info}/PKG-INFO +4 -4
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/SOURCES.txt +1 -13
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/requires.txt +0 -1
- codegraphcontext-0.3.1/MANIFEST.in +0 -5
- codegraphcontext-0.3.1/src/codegraphcontext/cli/visualizer.py +0 -1391
- codegraphcontext-0.3.1/src/codegraphcontext/tools/handlers/query_handlers.py +0 -181
- codegraphcontext-0.3.1/src/codegraphcontext/utils/visualize_graph.py +0 -150
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/assets/function-calls-BtRHrqa2.png +0 -0
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/assets/graph-total-D1fBAugo.png +0 -0
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/assets/hero-graph-2voMJp2a.jpg +0 -0
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/assets/hierarchy-DGADo0YT.png +0 -0
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/assets/index-DDAcqlyl.css +0 -1
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/assets/index-Do_-h1Gi.js +0 -23776
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/favicon.ico +0 -0
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/index.html +0 -31
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/placeholder.svg +0 -1
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/preview-image.png +0 -0
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/robots.txt +0 -14
- codegraphcontext-0.3.1/src/codegraphcontext/viz/dist/tree-sitter.wasm +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/LICENSE +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/setup.cfg +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/config_manager.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/registry_commands.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/setup_macos.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/setup_wizard.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/__init__.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/bundle_registry.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database_falkordb.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database_kuzu.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/falkor_worker.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/core/watcher.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/server.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tool_definitions.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/code_finder.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/c.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/cpp.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/csharp.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/dart.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/elixir.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/go.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/haskell.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/java.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/javascript.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/perl.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/php.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/python.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/ruby.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/rust.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/scala.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/swift.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/typescript.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/scip_indexer.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/scip_pb2.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/utils/debug_log.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
- {codegraphcontext-0.3.1 → codegraphcontext-0.3.3}/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.
|
|
3
|
+
Version: 0.3.3
|
|
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
|
|
@@ -46,7 +46,6 @@ Requires-Dist: python-dotenv>=1.0.0
|
|
|
46
46
|
Requires-Dist: tree-sitter>=0.21.0
|
|
47
47
|
Requires-Dist: tree-sitter-language-pack>=0.6.0
|
|
48
48
|
Requires-Dist: pyyaml
|
|
49
|
-
Requires-Dist: pytest
|
|
50
49
|
Requires-Dist: nbformat
|
|
51
50
|
Requires-Dist: nbconvert>=7.16.6
|
|
52
51
|
Requires-Dist: pathspec>=0.12.1
|
|
@@ -70,6 +69,7 @@ Dynamic: license-file
|
|
|
70
69
|
🌐 **Languages:**
|
|
71
70
|
- 🇬🇧 [English](README.md)
|
|
72
71
|
- 🇨🇳 [中文](README.zh-CN.md)
|
|
72
|
+
- 🇰🇷 [한국어](README.kor.md)
|
|
73
73
|
- 🇯🇵 日本語 (Soon)
|
|
74
74
|
- 🇷🇺 Русский (Soon)
|
|
75
75
|
- 🇪🇸 Español (Soon)
|
|
@@ -160,7 +160,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
160
160
|
---
|
|
161
161
|
|
|
162
162
|
## Project Details
|
|
163
|
-
- **Version:** 0.3.
|
|
163
|
+
- **Version:** 0.3.3
|
|
164
164
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
165
165
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
166
166
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -365,7 +365,7 @@ cgc watch .
|
|
|
365
365
|
cgc help
|
|
366
366
|
```
|
|
367
367
|
|
|
368
|
-
**See the full [CLI Commands Guide](
|
|
368
|
+
**See the full [CLI Commands Guide](docs/CLI_COMPLETE_REFERENCE.md) for all available commands and usage scenarios.**
|
|
369
369
|
|
|
370
370
|
### 🎨 Premium Interactive Visualization
|
|
371
371
|
CodeGraphContext can generate stunning, interactive knowledge graphs of your code. Unlike static diagrams, these are premium web-based explorers:
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
🌐 **Languages:**
|
|
6
6
|
- 🇬🇧 [English](README.md)
|
|
7
7
|
- 🇨🇳 [中文](README.zh-CN.md)
|
|
8
|
+
- 🇰🇷 [한국어](README.kor.md)
|
|
8
9
|
- 🇯🇵 日本語 (Soon)
|
|
9
10
|
- 🇷🇺 Русский (Soon)
|
|
10
11
|
- 🇪🇸 Español (Soon)
|
|
@@ -95,7 +96,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
95
96
|
---
|
|
96
97
|
|
|
97
98
|
## Project Details
|
|
98
|
-
- **Version:** 0.3.
|
|
99
|
+
- **Version:** 0.3.3
|
|
99
100
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
100
101
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
101
102
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -300,7 +301,7 @@ cgc watch .
|
|
|
300
301
|
cgc help
|
|
301
302
|
```
|
|
302
303
|
|
|
303
|
-
**See the full [CLI Commands Guide](
|
|
304
|
+
**See the full [CLI Commands Guide](docs/CLI_COMPLETE_REFERENCE.md) for all available commands and usage scenarios.**
|
|
304
305
|
|
|
305
306
|
### 🎨 Premium Interactive Visualization
|
|
306
307
|
CodeGraphContext can generate stunning, interactive knowledge graphs of your code. Unlike static diagrams, these are premium web-based explorers:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codegraphcontext"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.3"
|
|
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"
|
|
@@ -25,7 +25,6 @@ dependencies = [
|
|
|
25
25
|
"tree-sitter>=0.21.0",
|
|
26
26
|
"tree-sitter-language-pack>=0.6.0",
|
|
27
27
|
"pyyaml",
|
|
28
|
-
"pytest",
|
|
29
28
|
"nbformat",
|
|
30
29
|
"nbconvert>=7.16.6",
|
|
31
30
|
"pathspec>=0.12.1",
|
|
@@ -340,7 +340,9 @@ def cypher_helper_visual(query: str):
|
|
|
340
340
|
console.print(f"[bold red]An error occurred while executing query:[/bold red] {e}")
|
|
341
341
|
finally:
|
|
342
342
|
db_manager.close_driver()
|
|
343
|
-
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
import uvicorn
|
|
344
346
|
import urllib.parse
|
|
345
347
|
from ..viz.server import run_server, set_db_manager
|
|
346
348
|
|
|
@@ -356,12 +358,18 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
356
358
|
set_db_manager(db_manager)
|
|
357
359
|
|
|
358
360
|
# Determine the static directory (built React app)
|
|
361
|
+
# This points to src/codegraphcontext/viz/dist where we build the website
|
|
359
362
|
static_dir = Path(__file__).parent.parent / "viz" / "dist"
|
|
363
|
+
|
|
364
|
+
# Fallback for development if not yet built in viz/dist
|
|
360
365
|
if not static_dir.exists():
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
366
|
+
dev_static_dir = Path.cwd() / "website" / "dist"
|
|
367
|
+
if dev_static_dir.exists():
|
|
368
|
+
static_dir = dev_static_dir
|
|
369
|
+
else:
|
|
370
|
+
console.print("[yellow]Warning: Visualization assets not found. Please run 'cd website && npm run build' first.[/yellow]")
|
|
371
|
+
# We continue anyway to let the server start (helpful for dev)
|
|
372
|
+
|
|
365
373
|
# Construct the URL
|
|
366
374
|
backend_url = f"http://localhost:{port}"
|
|
367
375
|
params = {"backend": backend_url}
|
|
@@ -369,7 +377,7 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
369
377
|
params["repo_path"] = str(Path(repo_path).resolve())
|
|
370
378
|
|
|
371
379
|
query_string = urllib.parse.urlencode(params)
|
|
372
|
-
visualization_url = f"{backend_url}/
|
|
380
|
+
visualization_url = f"{backend_url}/explore?{query_string}"
|
|
373
381
|
|
|
374
382
|
console.print(f"[green]Starting visualizer server on {backend_url}...[/green]")
|
|
375
383
|
console.print(f"[cyan]Opening Playground UI:[/cyan] {visualization_url}")
|
|
@@ -377,6 +385,7 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
377
385
|
# Open browser in a separate thread/process if possible, or just before starting server
|
|
378
386
|
def open_browser():
|
|
379
387
|
import time
|
|
388
|
+
import webbrowser
|
|
380
389
|
time.sleep(1.5) # Give the server a moment to start
|
|
381
390
|
webbrowser.open(visualization_url)
|
|
382
391
|
|
|
@@ -390,243 +399,6 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
390
399
|
finally:
|
|
391
400
|
db_manager.close_driver()
|
|
392
401
|
|
|
393
|
-
def _visualize_falkordb(db_manager):
|
|
394
|
-
console.print("[dim]Generating FalkorDB visualization (showing up to 500 relationships)...[/dim]")
|
|
395
|
-
try:
|
|
396
|
-
data_nodes = []
|
|
397
|
-
data_edges = []
|
|
398
|
-
|
|
399
|
-
with db_manager.get_driver().session() as session:
|
|
400
|
-
# Fetch nodes and edges
|
|
401
|
-
q = "MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500"
|
|
402
|
-
result = session.run(q)
|
|
403
|
-
|
|
404
|
-
seen_nodes = set()
|
|
405
|
-
|
|
406
|
-
for record in result:
|
|
407
|
-
# record values are Node/Relationship objects from falkordb client
|
|
408
|
-
n = record['n']
|
|
409
|
-
r = record['r']
|
|
410
|
-
m = record['m']
|
|
411
|
-
|
|
412
|
-
# Process Node helper
|
|
413
|
-
def process_node(node):
|
|
414
|
-
nid = getattr(node, 'id', -1)
|
|
415
|
-
labels = getattr(node, 'labels', [])
|
|
416
|
-
lbl = list(labels)[0] if labels else "Node"
|
|
417
|
-
props = getattr(node, 'properties', {})
|
|
418
|
-
name = props.get('name', str(nid))
|
|
419
|
-
|
|
420
|
-
if nid not in seen_nodes:
|
|
421
|
-
seen_nodes.add(nid)
|
|
422
|
-
color = "#97c2fc" # Default blue
|
|
423
|
-
if "Repository" in labels: color = "#ffb3ba" # Red
|
|
424
|
-
elif "File" in labels: color = "#baffc9" # Green
|
|
425
|
-
elif "Class" in labels: color = "#bae1ff" # Light Blue
|
|
426
|
-
elif "Function" in labels: color = "#ffffba" # Yellow
|
|
427
|
-
elif "Package" in labels: color = "#ffdfba" # Orange
|
|
428
|
-
|
|
429
|
-
data_nodes.append({
|
|
430
|
-
"id": nid,
|
|
431
|
-
"label": name,
|
|
432
|
-
"group": lbl,
|
|
433
|
-
"title": str(props),
|
|
434
|
-
"color": color
|
|
435
|
-
})
|
|
436
|
-
return nid
|
|
437
|
-
|
|
438
|
-
nid = process_node(n)
|
|
439
|
-
mid = process_node(m)
|
|
440
|
-
|
|
441
|
-
# Check Edge
|
|
442
|
-
e_type = getattr(r, 'relation', '') or getattr(r, 'type', 'REL')
|
|
443
|
-
data_edges.append({
|
|
444
|
-
"from": nid,
|
|
445
|
-
"to": mid,
|
|
446
|
-
"label": e_type,
|
|
447
|
-
"arrows": "to"
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
filename = "codegraph_viz.html"
|
|
451
|
-
html_content = f"""
|
|
452
|
-
<!DOCTYPE html>
|
|
453
|
-
<html>
|
|
454
|
-
<head>
|
|
455
|
-
<title>CodeGraphContext Visualization</title>
|
|
456
|
-
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
|
|
457
|
-
<style type="text/css">
|
|
458
|
-
#mynetwork {{
|
|
459
|
-
width: 100%;
|
|
460
|
-
height: 100vh;
|
|
461
|
-
border: 1px solid lightgray;
|
|
462
|
-
}}
|
|
463
|
-
</style>
|
|
464
|
-
</head>
|
|
465
|
-
<body>
|
|
466
|
-
<div id="mynetwork"></div>
|
|
467
|
-
<script type="text/javascript">
|
|
468
|
-
var nodes = new vis.DataSet({json.dumps(data_nodes)});
|
|
469
|
-
var edges = new vis.DataSet({json.dumps(data_edges)});
|
|
470
|
-
var container = document.getElementById('mynetwork');
|
|
471
|
-
var data = {{ nodes: nodes, edges: edges }};
|
|
472
|
-
var options = {{
|
|
473
|
-
nodes: {{ shape: 'dot', size: 16 }},
|
|
474
|
-
physics: {{ stabilization: false }},
|
|
475
|
-
layout: {{ improvedLayout: false }}
|
|
476
|
-
}};
|
|
477
|
-
var network = new vis.Network(container, data, options);
|
|
478
|
-
</script>
|
|
479
|
-
</body>
|
|
480
|
-
</html>
|
|
481
|
-
"""
|
|
482
|
-
|
|
483
|
-
out_path = Path(filename).resolve()
|
|
484
|
-
with open(out_path, "w") as f:
|
|
485
|
-
f.write(html_content)
|
|
486
|
-
|
|
487
|
-
console.print(f"[green]Visualization generated at:[/green] {out_path}")
|
|
488
|
-
console.print("Opening in default browser...")
|
|
489
|
-
webbrowser.open(f"file://{out_path}")
|
|
490
|
-
|
|
491
|
-
except Exception as e:
|
|
492
|
-
console.print(f"[bold red]Visualization failed:[/bold red] {e}")
|
|
493
|
-
import traceback
|
|
494
|
-
traceback.print_exc()
|
|
495
|
-
finally:
|
|
496
|
-
db_manager.close_driver()
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
def _visualize_kuzudb(db_manager):
|
|
500
|
-
console.print("[dim]Generating KùzuDB visualization (showing up to 500 relationships)...[/dim]")
|
|
501
|
-
try:
|
|
502
|
-
data_nodes = []
|
|
503
|
-
data_edges = []
|
|
504
|
-
|
|
505
|
-
with db_manager.get_driver().session() as session:
|
|
506
|
-
# Fetch nodes and edges
|
|
507
|
-
# KùzuDB returns dicts for n, r, m in the result
|
|
508
|
-
q = "MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500"
|
|
509
|
-
result = session.run(q)
|
|
510
|
-
|
|
511
|
-
seen_nodes = set()
|
|
512
|
-
|
|
513
|
-
# Helper to extract Node ID and props
|
|
514
|
-
def process_node(node):
|
|
515
|
-
uid = None
|
|
516
|
-
lbl = 'Node'
|
|
517
|
-
props = {}
|
|
518
|
-
|
|
519
|
-
# Handle Kuzu Node Object (processed by wrapper)
|
|
520
|
-
if hasattr(node, 'properties'):
|
|
521
|
-
props = node.properties or {}
|
|
522
|
-
if hasattr(node, 'labels') and node.labels:
|
|
523
|
-
lbl = node.labels[0]
|
|
524
|
-
if hasattr(node, 'id'):
|
|
525
|
-
uid = str(node.id)
|
|
526
|
-
# Handle Dictionary (raw Kuzu result)
|
|
527
|
-
elif isinstance(node, dict):
|
|
528
|
-
if '_id' in node:
|
|
529
|
-
uid = f"{node['_id']['table']}_{node['_id']['offset']}"
|
|
530
|
-
lbl = node.get('_label', 'Node')
|
|
531
|
-
props = {k: v for k, v in node.items() if not k.startswith('_')}
|
|
532
|
-
|
|
533
|
-
if not uid:
|
|
534
|
-
uid = str(uuid.uuid4())
|
|
535
|
-
|
|
536
|
-
name = props.get('name', str(uid))
|
|
537
|
-
|
|
538
|
-
if uid not in seen_nodes:
|
|
539
|
-
seen_nodes.add(uid)
|
|
540
|
-
color = "#97c2fc" # Default blue
|
|
541
|
-
if "Repository" == lbl: color = "#ffb3ba"
|
|
542
|
-
elif "File" == lbl: color = "#baffc9"
|
|
543
|
-
elif "Class" == lbl: color = "#bae1ff"
|
|
544
|
-
elif "Function" == lbl: color = "#ffffba"
|
|
545
|
-
elif "Module" == lbl: color = "#ffdfba"
|
|
546
|
-
|
|
547
|
-
data_nodes.append({
|
|
548
|
-
"id": uid,
|
|
549
|
-
"label": name,
|
|
550
|
-
"group": lbl,
|
|
551
|
-
"title": str(props),
|
|
552
|
-
"color": color
|
|
553
|
-
})
|
|
554
|
-
return uid
|
|
555
|
-
|
|
556
|
-
# Iterate results
|
|
557
|
-
for record in result:
|
|
558
|
-
# record is dict-like access to row items
|
|
559
|
-
n = record['n']
|
|
560
|
-
r = record['r']
|
|
561
|
-
m = record['m']
|
|
562
|
-
|
|
563
|
-
nid = process_node(n)
|
|
564
|
-
mid = process_node(m)
|
|
565
|
-
|
|
566
|
-
# Process Edge
|
|
567
|
-
e_type = 'REL'
|
|
568
|
-
if hasattr(r, 'type'):
|
|
569
|
-
e_type = r.type
|
|
570
|
-
elif isinstance(r, dict):
|
|
571
|
-
e_type = r.get('_label', 'REL')
|
|
572
|
-
elif hasattr(r, 'label'): # Some versions
|
|
573
|
-
e_type = r.label
|
|
574
|
-
|
|
575
|
-
data_edges.append({
|
|
576
|
-
"from": nid,
|
|
577
|
-
"to": mid,
|
|
578
|
-
"label": e_type,
|
|
579
|
-
"arrows": "to"
|
|
580
|
-
})
|
|
581
|
-
|
|
582
|
-
filename = "codegraph_viz.html"
|
|
583
|
-
html_content = f"""
|
|
584
|
-
<!DOCTYPE html>
|
|
585
|
-
<html>
|
|
586
|
-
<head>
|
|
587
|
-
<title>CodeGraphContext KùzuDB Visualization</title>
|
|
588
|
-
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
|
|
589
|
-
<style type="text/css">
|
|
590
|
-
#mynetwork {{
|
|
591
|
-
width: 100%;
|
|
592
|
-
height: 100vh;
|
|
593
|
-
border: 1px solid lightgray;
|
|
594
|
-
}}
|
|
595
|
-
</style>
|
|
596
|
-
</head>
|
|
597
|
-
<body>
|
|
598
|
-
<div id="mynetwork"></div>
|
|
599
|
-
<script type="text/javascript">
|
|
600
|
-
var nodes = new vis.DataSet({json.dumps(data_nodes)});
|
|
601
|
-
var edges = new vis.DataSet({json.dumps(data_edges)});
|
|
602
|
-
var container = document.getElementById('mynetwork');
|
|
603
|
-
var data = {{ nodes: nodes, edges: edges }};
|
|
604
|
-
var options = {{
|
|
605
|
-
nodes: {{ shape: 'dot', size: 16 }},
|
|
606
|
-
physics: {{ stabilization: false }},
|
|
607
|
-
layout: {{ improvedLayout: false }}
|
|
608
|
-
}};
|
|
609
|
-
var network = new vis.Network(container, data, options);
|
|
610
|
-
</script>
|
|
611
|
-
</body>
|
|
612
|
-
</html>
|
|
613
|
-
"""
|
|
614
|
-
|
|
615
|
-
out_path = Path(filename).resolve()
|
|
616
|
-
with open(out_path, "w") as f:
|
|
617
|
-
f.write(html_content)
|
|
618
|
-
|
|
619
|
-
console.print(f"[green]Visualization generated at:[/green] {out_path}")
|
|
620
|
-
console.print("Opening in default browser...")
|
|
621
|
-
webbrowser.open(f"file://{out_path}")
|
|
622
|
-
|
|
623
|
-
except Exception as e:
|
|
624
|
-
console.print(f"[bold red]Visualization failed:[/bold red] {e}")
|
|
625
|
-
import traceback
|
|
626
|
-
traceback.print_exc()
|
|
627
|
-
finally:
|
|
628
|
-
db_manager.close_driver()
|
|
629
|
-
|
|
630
402
|
|
|
631
403
|
def reindex_helper(path: str):
|
|
632
404
|
"""Force re-index by deleting and rebuilding the repository."""
|
|
@@ -999,7 +999,7 @@ def visualize(
|
|
|
999
999
|
port: int = typer.Option(8000, "--port", "-p", help="Port to run the visualizer server on.")
|
|
1000
1000
|
):
|
|
1001
1001
|
"""
|
|
1002
|
-
Launches the interactive
|
|
1002
|
+
Launches the interactive UI to visualize the code graph.
|
|
1003
1003
|
"""
|
|
1004
1004
|
_load_credentials()
|
|
1005
1005
|
visualize_helper(repo, port)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import urllib.parse
|
|
2
|
+
from typing import Optional, List, Dict, Any, Set
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from .cli_helpers import visualize_helper
|
|
5
|
+
|
|
6
|
+
def check_visual_flag(ctx, visual: bool, cypher_query: str = None):
|
|
7
|
+
"""
|
|
8
|
+
Helper to check the --visual flag and launch the visualizer.
|
|
9
|
+
This is called from within analyze/find commands.
|
|
10
|
+
"""
|
|
11
|
+
if visual and cypher_query:
|
|
12
|
+
# We start the visualizer on port 8000
|
|
13
|
+
# Passing empty repo handles showing just the query results
|
|
14
|
+
port = 8000
|
|
15
|
+
encoded_query = urllib.parse.quote(cypher_query)
|
|
16
|
+
visualization_url = f"http://localhost:{port}/explore?cypher_query={encoded_query}"
|
|
17
|
+
|
|
18
|
+
from rich.console import Console
|
|
19
|
+
console = Console(stderr=True)
|
|
20
|
+
console.print(f"[green]Starting visualizer...[/green]")
|
|
21
|
+
console.print(f"[cyan]Visualizing results at:[/cyan] {visualization_url}")
|
|
22
|
+
|
|
23
|
+
# Start the backend server and open the browser
|
|
24
|
+
visualize_helper(repo_path=None, port=port)
|
|
25
|
+
return True
|
|
26
|
+
return False
|
|
27
|
+
|
|
28
|
+
def visualize_call_graph(cypher_query: str):
|
|
29
|
+
"""Visualize a call graph result."""
|
|
30
|
+
visualize_helper(repo_path=None, port=8000)
|
|
31
|
+
|
|
32
|
+
def visualize_call_chain(cypher_query: str):
|
|
33
|
+
"""Visualize a call chain result."""
|
|
34
|
+
visualize_helper(repo_path=None, port=8000)
|
|
35
|
+
|
|
36
|
+
def visualize_dependencies(cypher_query: str):
|
|
37
|
+
"""Visualize code dependencies."""
|
|
38
|
+
visualize_helper(repo_path=None, port=8000)
|
|
39
|
+
|
|
40
|
+
def visualize_inheritance_tree(cypher_query: str):
|
|
41
|
+
"""Visualize class inheritance tree."""
|
|
42
|
+
visualize_helper(repo_path=None, port=8000)
|
|
43
|
+
|
|
44
|
+
def visualize_overrides(cypher_query: str):
|
|
45
|
+
"""Visualize method overrides."""
|
|
46
|
+
visualize_helper(repo_path=None, port=8000)
|
|
47
|
+
|
|
48
|
+
def visualize_search_results(cypher_query: str):
|
|
49
|
+
"""Visualize search results."""
|
|
50
|
+
visualize_helper(repo_path=None, port=8000)
|
|
@@ -161,9 +161,13 @@ class CGCBundle:
|
|
|
161
161
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
162
162
|
temp_path = Path(temp_dir)
|
|
163
163
|
|
|
164
|
-
# Step 1: Extract ZIP
|
|
164
|
+
# Step 1: Extract ZIP (with Zip Slip protection)
|
|
165
165
|
info_logger("Extracting bundle...")
|
|
166
166
|
with zipfile.ZipFile(bundle_path, 'r') as zip_ref:
|
|
167
|
+
for entry in zip_ref.namelist():
|
|
168
|
+
resolved = (temp_path / entry).resolve()
|
|
169
|
+
if not str(resolved).startswith(str(temp_path.resolve())):
|
|
170
|
+
return False, f"Zip Slip detected: entry '{entry}' escapes target directory"
|
|
167
171
|
zip_ref.extractall(temp_path)
|
|
168
172
|
|
|
169
173
|
# Step 2: Validate bundle
|