codegraphcontext 0.3.2__tar.gz → 0.3.4__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.4/MANIFEST.in +4 -0
- {codegraphcontext-0.3.2/src/codegraphcontext.egg-info → codegraphcontext-0.3.4}/PKG-INFO +4 -2
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/README.md +1 -1
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/pyproject.toml +3 -1
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/cli/cli_helpers.py +40 -244
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/cli/main.py +1 -1
- codegraphcontext-0.3.4/src/codegraphcontext/cli/visualizer.py +50 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/graph_builder.py +76 -60
- codegraphcontext-0.3.4/src/codegraphcontext/tools/handlers/query_handlers.py +87 -0
- codegraphcontext-0.3.4/src/codegraphcontext/utils/visualize_graph.py +0 -0
- codegraphcontext-0.3.4/src/codegraphcontext/viz/server.py +230 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4/src/codegraphcontext.egg-info}/PKG-INFO +4 -2
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext.egg-info/requires.txt +2 -0
- codegraphcontext-0.3.2/MANIFEST.in +0 -5
- codegraphcontext-0.3.2/src/codegraphcontext/cli/visualizer.py +0 -1391
- codegraphcontext-0.3.2/src/codegraphcontext/tools/handlers/query_handlers.py +0 -181
- codegraphcontext-0.3.2/src/codegraphcontext/utils/visualize_graph.py +0 -150
- codegraphcontext-0.3.2/src/codegraphcontext/viz/server.py +0 -178
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/LICENSE +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/setup.cfg +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/cli/config_manager.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/cli/registry_commands.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/cli/setup_macos.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/cli/setup_wizard.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/bundle_registry.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/cgc_bundle.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/database.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/database_falkordb.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/database_kuzu.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/falkor_worker.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/core/watcher.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/server.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tool_definitions.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/code_finder.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/c.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/cpp.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/csharp.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/dart.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/elixir.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/go.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/haskell.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/java.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/javascript.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/perl.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/php.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/python.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/ruby.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/rust.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/scala.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/swift.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/typescript.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/package_resolver.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/scip_indexer.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/scip_pb2.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/utils/debug_log.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext.egg-info/SOURCES.txt +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.4}/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.4
|
|
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
|
|
@@ -45,6 +45,7 @@ Requires-Dist: inquirerpy>=0.3.4
|
|
|
45
45
|
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
|
+
Requires-Dist: tree-sitter-c-sharp>=0.21.0
|
|
48
49
|
Requires-Dist: pyyaml
|
|
49
50
|
Requires-Dist: nbformat
|
|
50
51
|
Requires-Dist: nbconvert>=7.16.6
|
|
@@ -56,6 +57,7 @@ Requires-Dist: uvicorn>=0.22.0
|
|
|
56
57
|
Provides-Extra: parsing
|
|
57
58
|
Requires-Dist: tree-sitter>=0.21.0; extra == "parsing"
|
|
58
59
|
Requires-Dist: tree-sitter-language-pack>=0.6.0; extra == "parsing"
|
|
60
|
+
Requires-Dist: tree-sitter-c-sharp>=0.21.0; extra == "parsing"
|
|
59
61
|
Provides-Extra: dev
|
|
60
62
|
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
61
63
|
Requires-Dist: black>=23.11.0; extra == "dev"
|
|
@@ -160,7 +162,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
160
162
|
---
|
|
161
163
|
|
|
162
164
|
## Project Details
|
|
163
|
-
- **Version:** 0.3.
|
|
165
|
+
- **Version:** 0.3.4
|
|
164
166
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
165
167
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
166
168
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -96,7 +96,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
96
96
|
---
|
|
97
97
|
|
|
98
98
|
## Project Details
|
|
99
|
-
- **Version:** 0.3.
|
|
99
|
+
- **Version:** 0.3.4
|
|
100
100
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
101
101
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
102
102
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codegraphcontext"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.4"
|
|
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 @@ dependencies = [
|
|
|
24
24
|
"python-dotenv>=1.0.0",
|
|
25
25
|
"tree-sitter>=0.21.0",
|
|
26
26
|
"tree-sitter-language-pack>=0.6.0",
|
|
27
|
+
"tree-sitter-c-sharp>=0.21.0",
|
|
27
28
|
"pyyaml",
|
|
28
29
|
"nbformat",
|
|
29
30
|
"nbconvert>=7.16.6",
|
|
@@ -38,6 +39,7 @@ dependencies = [
|
|
|
38
39
|
parsing = [
|
|
39
40
|
"tree-sitter>=0.21.0",
|
|
40
41
|
"tree-sitter-language-pack>=0.6.0",
|
|
42
|
+
"tree-sitter-c-sharp>=0.21.0",
|
|
41
43
|
]
|
|
42
44
|
dev = [
|
|
43
45
|
"pytest>=7.4.0",
|
|
@@ -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,42 @@ 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)
|
|
359
|
-
|
|
361
|
+
# This points to src/codegraphcontext/viz/dist where we build the website
|
|
362
|
+
# (relative to src/codegraphcontext/cli/cli_helpers.py)
|
|
363
|
+
# Using .resolve() is more robust for path comparison and existence checks
|
|
364
|
+
this_file = Path(__file__).resolve()
|
|
365
|
+
package_root = this_file.parent.parent
|
|
366
|
+
static_dir = package_root / "viz" / "dist"
|
|
367
|
+
|
|
368
|
+
# Fallback for development if not yet built in viz/dist
|
|
360
369
|
if not static_dir.exists():
|
|
361
|
-
|
|
362
|
-
#
|
|
363
|
-
|
|
364
|
-
|
|
370
|
+
# Look for website/dist in the project root (3 levels up from cli/cli_helpers.py, 4 parents)
|
|
371
|
+
# 1: cli/, 2: codegraphcontext/, 3: src/, 4: project_root/
|
|
372
|
+
project_root = this_file.parent.parent.parent.parent
|
|
373
|
+
dev_static_dir = project_root / "website" / "dist"
|
|
374
|
+
|
|
375
|
+
# Also try one level up from package_root just in case of different layouts
|
|
376
|
+
alt_dev_dir = package_root.parent.parent / "website" / "dist"
|
|
377
|
+
|
|
378
|
+
if dev_static_dir.exists():
|
|
379
|
+
static_dir = dev_static_dir
|
|
380
|
+
elif alt_dev_dir.exists():
|
|
381
|
+
static_dir = alt_dev_dir
|
|
382
|
+
else:
|
|
383
|
+
# Last resort: try current working directory
|
|
384
|
+
cwd_static_dir = Path.cwd() / "website" / "dist"
|
|
385
|
+
if cwd_static_dir.exists():
|
|
386
|
+
static_dir = cwd_static_dir
|
|
387
|
+
else:
|
|
388
|
+
console.print(f"[yellow]Warning: Visualization assets not found.[/yellow]")
|
|
389
|
+
console.print(f"[dim]Checked paths:[/dim]")
|
|
390
|
+
console.print(f" [dim]- {static_dir}[/dim]")
|
|
391
|
+
console.print(f" [dim]- {dev_static_dir}[/dim]")
|
|
392
|
+
console.print(f" [dim]- {alt_dev_dir}[/dim]")
|
|
393
|
+
console.print(f" [dim]- {cwd_static_dir}[/dim]")
|
|
394
|
+
console.print("[dim]Please run 'cd website && npm run build' first.[/dim]")
|
|
395
|
+
# We continue anyway to let the server start (helpful for dev)
|
|
396
|
+
|
|
365
397
|
# Construct the URL
|
|
366
398
|
backend_url = f"http://localhost:{port}"
|
|
367
399
|
params = {"backend": backend_url}
|
|
@@ -369,7 +401,7 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
369
401
|
params["repo_path"] = str(Path(repo_path).resolve())
|
|
370
402
|
|
|
371
403
|
query_string = urllib.parse.urlencode(params)
|
|
372
|
-
visualization_url = f"{backend_url}/
|
|
404
|
+
visualization_url = f"{backend_url}/explore?{query_string}"
|
|
373
405
|
|
|
374
406
|
console.print(f"[green]Starting visualizer server on {backend_url}...[/green]")
|
|
375
407
|
console.print(f"[cyan]Opening Playground UI:[/cyan] {visualization_url}")
|
|
@@ -377,6 +409,7 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
377
409
|
# Open browser in a separate thread/process if possible, or just before starting server
|
|
378
410
|
def open_browser():
|
|
379
411
|
import time
|
|
412
|
+
import webbrowser
|
|
380
413
|
time.sleep(1.5) # Give the server a moment to start
|
|
381
414
|
webbrowser.open(visualization_url)
|
|
382
415
|
|
|
@@ -390,243 +423,6 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
390
423
|
finally:
|
|
391
424
|
db_manager.close_driver()
|
|
392
425
|
|
|
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
426
|
|
|
631
427
|
def reindex_helper(path: str):
|
|
632
428
|
"""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)
|