codegraphcontext 0.1.12__tar.gz → 0.1.14__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.1.12/src/codegraphcontext.egg-info → codegraphcontext-0.1.14}/PKG-INFO +30 -10
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/README.md +25 -9
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/pyproject.toml +5 -1
- codegraphcontext-0.1.14/src/codegraphcontext/cli/main.py +288 -0
- codegraphcontext-0.1.14/src/codegraphcontext/cli/setup_macos.py +95 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/cli/setup_wizard.py +48 -5
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/core/watcher.py +55 -22
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/server.py +122 -25
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/tools/code_finder.py +42 -27
- codegraphcontext-0.1.14/src/codegraphcontext/tools/graph_builder.py +570 -0
- codegraphcontext-0.1.14/src/codegraphcontext/tools/languages/cpp.py +127 -0
- codegraphcontext-0.1.14/src/codegraphcontext/tools/languages/javascript.py +550 -0
- codegraphcontext-0.1.14/src/codegraphcontext/tools/languages/python.py +406 -0
- codegraphcontext-0.1.14/src/codegraphcontext/tools/languages/rust.py +120 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14/src/codegraphcontext.egg-info}/PKG-INFO +30 -10
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext.egg-info/SOURCES.txt +8 -4
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext.egg-info/requires.txt +4 -0
- codegraphcontext-0.1.14/tests/test_end_to_end.py +175 -0
- codegraphcontext-0.1.14/tests/test_graph_indexing.py +487 -0
- codegraphcontext-0.1.14/tests/test_graph_indexing_js.py +115 -0
- codegraphcontext-0.1.12/src/codegraphcontext/cli/main.py +0 -183
- codegraphcontext-0.1.12/src/codegraphcontext/tools/graph_builder.py +0 -1171
- codegraphcontext-0.1.12/tests/test_cgc_integration.py +0 -30
- codegraphcontext-0.1.12/tests/test_imports.py +0 -185
- codegraphcontext-0.1.12/tests/test_jsonrpc.py +0 -113
- codegraphcontext-0.1.12/tests/test_tools.py +0 -407
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/LICENSE +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/MANIFEST.in +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/setup.cfg +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/core/__init__.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/core/database.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/tools/import_extractor.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext/utils/debug_log.py +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
- {codegraphcontext-0.1.12 → codegraphcontext-0.1.14}/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.1.
|
|
3
|
+
Version: 0.1.14
|
|
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
|
|
@@ -44,6 +44,10 @@ Requires-Dist: typer[all]>=0.9.0
|
|
|
44
44
|
Requires-Dist: rich>=13.7.0
|
|
45
45
|
Requires-Dist: inquirerpy>=0.3.4
|
|
46
46
|
Requires-Dist: python-dotenv>=1.0.0
|
|
47
|
+
Requires-Dist: tree-sitter==0.20.4
|
|
48
|
+
Requires-Dist: tree-sitter-languages==1.10.2
|
|
49
|
+
Requires-Dist: pyyaml
|
|
50
|
+
Requires-Dist: pytest
|
|
47
51
|
Provides-Extra: dev
|
|
48
52
|
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
49
53
|
Requires-Dist: black>=23.11.0; extra == "dev"
|
|
@@ -51,14 +55,26 @@ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
|
51
55
|
Dynamic: license-file
|
|
52
56
|
|
|
53
57
|
# CodeGraphContext
|
|
58
|
+
|
|
59
|
+
<!-- ====== Project stats ====== -->
|
|
60
|
+
<!-- ====== Project stats ====== -->
|
|
61
|
+
|
|
62
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/stargazers)
|
|
63
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/network/members)
|
|
64
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/issues)
|
|
65
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/pulls)
|
|
66
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/pulls?q=is%3Apr+is%3Aclosed)
|
|
67
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/graphs/contributors)
|
|
68
|
+
[](https://github.com/Shashankss1205/CodeGraphContext)
|
|
54
69
|
[](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml)
|
|
55
|
-
[](https://pypi.org/project/codegraphcontext/)
|
|
56
|
-
[](https://pypi.org/project/codegraphcontext/)
|
|
57
|
-
[](https://pypi.org/project/codegraphcontext/)
|
|
71
|
+
[](https://pypi.org/project/codegraphcontext/)
|
|
72
|
+
[](LICENSE)
|
|
73
|
+
[](http://codegraphcontext.vercel.app/)
|
|
74
|
+
[](https://youtu.be/KYYSdxhg1xU)
|
|
75
|
+
[](https://discord.gg/dR4QY32uYQ)
|
|
76
|
+
|
|
77
|
+
|
|
62
78
|
|
|
63
79
|
An MCP server that indexes local code into a graph database to provide context to AI assistants.
|
|
64
80
|
|
|
@@ -69,7 +85,7 @@ An MCP server that indexes local code into a graph database to provide context t
|
|
|
69
85
|

|
|
70
86
|
|
|
71
87
|
## Project Details
|
|
72
|
-
- **Version:** 0.1.
|
|
88
|
+
- **Version:** 0.1.14
|
|
73
89
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
74
90
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
75
91
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -104,6 +120,8 @@ If you’re using CodeGraphContext in your project, feel free to open a PR and a
|
|
|
104
120
|
- `rich>=13.7.0`
|
|
105
121
|
- `inquirerpy>=0.3.4`
|
|
106
122
|
- `python-dotenv>=1.0.0`
|
|
123
|
+
- `tree-sitter==0.20.4`
|
|
124
|
+
- `tree-sitter-languages==1.10.2`
|
|
107
125
|
|
|
108
126
|
## Getting Started
|
|
109
127
|
|
|
@@ -120,8 +138,10 @@ If you’re using CodeGraphContext in your project, feel free to open a PR and a
|
|
|
120
138
|
After setting up your database, the wizard will ask to configure your development environment. It can automatically detect and configure the following:
|
|
121
139
|
* VS Code
|
|
122
140
|
* Cursor
|
|
141
|
+
* Windsurf
|
|
123
142
|
* Claude
|
|
124
143
|
* Gemini CLI
|
|
144
|
+
* ChatGPT Codex
|
|
125
145
|
|
|
126
146
|
Upon successful configuration, `cgc setup` will generate and place the necessary configuration files:
|
|
127
147
|
* It creates an `mcp.json` file in your current directory for reference.
|
|
@@ -240,6 +260,6 @@ Once the server is running, you can interact with it through your AI assistant u
|
|
|
240
260
|
|
|
241
261
|
Contributions are welcome! 🎉
|
|
242
262
|
Please see our [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
|
|
243
|
-
If you have ideas for new features, integrations, or improvements, open an [issue](https://github.com/Shashankss1205/CodeGraphContext/issues) or submit a
|
|
263
|
+
If you have ideas for new features, integrations, or improvements, open an [issue](https://github.com/Shashankss1205/CodeGraphContext/issues) or submit a Pull Request.
|
|
244
264
|
|
|
245
265
|
Join discussions and help shape the future of CodeGraphContext.
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
# CodeGraphContext
|
|
2
|
+
|
|
3
|
+
<!-- ====== Project stats ====== -->
|
|
4
|
+
<!-- ====== Project stats ====== -->
|
|
5
|
+
|
|
6
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/stargazers)
|
|
7
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/network/members)
|
|
8
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/issues)
|
|
9
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/pulls)
|
|
10
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/pulls?q=is%3Apr+is%3Aclosed)
|
|
11
|
+
[](https://github.com/Shashankss1205/CodeGraphContext/graphs/contributors)
|
|
12
|
+
[](https://github.com/Shashankss1205/CodeGraphContext)
|
|
2
13
|
[](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml)
|
|
3
|
-
[](https://pypi.org/project/codegraphcontext/)
|
|
4
|
-
[](https://pypi.org/project/codegraphcontext/)
|
|
5
|
-
[](https://pypi.org/project/codegraphcontext/)
|
|
15
|
+
[](https://pypi.org/project/codegraphcontext/)
|
|
16
|
+
[](LICENSE)
|
|
17
|
+
[](http://codegraphcontext.vercel.app/)
|
|
18
|
+
[](https://youtu.be/KYYSdxhg1xU)
|
|
19
|
+
[](https://discord.gg/dR4QY32uYQ)
|
|
20
|
+
|
|
21
|
+
|
|
10
22
|
|
|
11
23
|
An MCP server that indexes local code into a graph database to provide context to AI assistants.
|
|
12
24
|
|
|
@@ -17,7 +29,7 @@ An MCP server that indexes local code into a graph database to provide context t
|
|
|
17
29
|

|
|
18
30
|
|
|
19
31
|
## Project Details
|
|
20
|
-
- **Version:** 0.1.
|
|
32
|
+
- **Version:** 0.1.14
|
|
21
33
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
22
34
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
23
35
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -52,6 +64,8 @@ If you’re using CodeGraphContext in your project, feel free to open a PR and a
|
|
|
52
64
|
- `rich>=13.7.0`
|
|
53
65
|
- `inquirerpy>=0.3.4`
|
|
54
66
|
- `python-dotenv>=1.0.0`
|
|
67
|
+
- `tree-sitter==0.20.4`
|
|
68
|
+
- `tree-sitter-languages==1.10.2`
|
|
55
69
|
|
|
56
70
|
## Getting Started
|
|
57
71
|
|
|
@@ -68,8 +82,10 @@ If you’re using CodeGraphContext in your project, feel free to open a PR and a
|
|
|
68
82
|
After setting up your database, the wizard will ask to configure your development environment. It can automatically detect and configure the following:
|
|
69
83
|
* VS Code
|
|
70
84
|
* Cursor
|
|
85
|
+
* Windsurf
|
|
71
86
|
* Claude
|
|
72
87
|
* Gemini CLI
|
|
88
|
+
* ChatGPT Codex
|
|
73
89
|
|
|
74
90
|
Upon successful configuration, `cgc setup` will generate and place the necessary configuration files:
|
|
75
91
|
* It creates an `mcp.json` file in your current directory for reference.
|
|
@@ -188,6 +204,6 @@ Once the server is running, you can interact with it through your AI assistant u
|
|
|
188
204
|
|
|
189
205
|
Contributions are welcome! 🎉
|
|
190
206
|
Please see our [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
|
|
191
|
-
If you have ideas for new features, integrations, or improvements, open an [issue](https://github.com/Shashankss1205/CodeGraphContext/issues) or submit a
|
|
207
|
+
If you have ideas for new features, integrations, or improvements, open an [issue](https://github.com/Shashankss1205/CodeGraphContext/issues) or submit a Pull Request.
|
|
192
208
|
|
|
193
209
|
Join discussions and help shape the future of CodeGraphContext.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codegraphcontext"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.14"
|
|
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"
|
|
@@ -23,6 +23,10 @@ dependencies = [
|
|
|
23
23
|
"rich>=13.7.0",
|
|
24
24
|
"inquirerpy>=0.3.4",
|
|
25
25
|
"python-dotenv>=1.0.0",
|
|
26
|
+
"tree-sitter==0.20.4",
|
|
27
|
+
"tree-sitter-languages==1.10.2",
|
|
28
|
+
"pyyaml",
|
|
29
|
+
"pytest"
|
|
26
30
|
]
|
|
27
31
|
|
|
28
32
|
[project.urls]
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# src/codegraphcontext/cli/main.py
|
|
2
|
+
"""
|
|
3
|
+
This module defines the command-line interface (CLI) for the CodeGraphContext application.
|
|
4
|
+
It uses the Typer library to create a user-friendly and well-documented CLI.
|
|
5
|
+
|
|
6
|
+
Commands:
|
|
7
|
+
- setup: Runs an interactive wizard to configure the Neo4j database connection.
|
|
8
|
+
- start: Launches the main MCP server.
|
|
9
|
+
- tool: A placeholder for directly calling server tools (for debugging).
|
|
10
|
+
- help: Displays help information.
|
|
11
|
+
- version: Show the installed version.
|
|
12
|
+
"""
|
|
13
|
+
import typer
|
|
14
|
+
from rich.console import Console
|
|
15
|
+
from rich.table import Table
|
|
16
|
+
from typing import Optional
|
|
17
|
+
import asyncio
|
|
18
|
+
import logging
|
|
19
|
+
import json
|
|
20
|
+
import os
|
|
21
|
+
import time
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from dotenv import load_dotenv, find_dotenv
|
|
24
|
+
from importlib.metadata import version as pkg_version, PackageNotFoundError
|
|
25
|
+
from codegraphcontext.server import MCPServer
|
|
26
|
+
from .setup_wizard import run_setup_wizard
|
|
27
|
+
|
|
28
|
+
# Set the log level for the noisy neo4j logger to WARNING to keep the output clean.
|
|
29
|
+
logging.getLogger("neo4j").setLevel(logging.WARNING)
|
|
30
|
+
|
|
31
|
+
# Initialize the Typer app and Rich console for formatted output.
|
|
32
|
+
app = typer.Typer(
|
|
33
|
+
name="cgc",
|
|
34
|
+
help="CodeGraphContext: An MCP server for AI-powered code analysis.",
|
|
35
|
+
add_completion=False,
|
|
36
|
+
)
|
|
37
|
+
console = Console(stderr=True)
|
|
38
|
+
|
|
39
|
+
# Configure basic logging for the application.
|
|
40
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_version() -> str:
|
|
44
|
+
"""
|
|
45
|
+
Try to read version from the installed package metadata.
|
|
46
|
+
Fallback to a dev version if not installed.
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
return pkg_version("codegraphcontext") # must match [project].name in pyproject.toml
|
|
50
|
+
except PackageNotFoundError:
|
|
51
|
+
return "0.0.0 (dev)"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@app.command()
|
|
55
|
+
def setup():
|
|
56
|
+
"""
|
|
57
|
+
Runs the interactive setup wizard to configure the server and database connection.
|
|
58
|
+
This helps users set up a local Docker-based Neo4j instance or connect to a remote one.
|
|
59
|
+
"""
|
|
60
|
+
run_setup_wizard()
|
|
61
|
+
|
|
62
|
+
def _load_credentials():
|
|
63
|
+
"""
|
|
64
|
+
Loads Neo4j credentials from various sources into environment variables.
|
|
65
|
+
Priority order:
|
|
66
|
+
1. Local `mcp.json`
|
|
67
|
+
2. Global `~/.codegraphcontext/.env`
|
|
68
|
+
3. Any `.env` file found in the directory tree.
|
|
69
|
+
"""
|
|
70
|
+
# 1. Prefer loading from mcp.json
|
|
71
|
+
mcp_file_path = Path.cwd() / "mcp.json"
|
|
72
|
+
if mcp_file_path.exists():
|
|
73
|
+
try:
|
|
74
|
+
with open(mcp_file_path, "r") as f:
|
|
75
|
+
mcp_config = json.load(f)
|
|
76
|
+
server_env = mcp_config.get("mcpServers", {}).get("CodeGraphContext", {}).get("env", {})
|
|
77
|
+
for key, value in server_env.items():
|
|
78
|
+
os.environ[key] = value
|
|
79
|
+
console.print("[green]Loaded Neo4j credentials from local mcp.json.[/green]")
|
|
80
|
+
return
|
|
81
|
+
except Exception as e:
|
|
82
|
+
console.print(f"[bold red]Error loading mcp.json:[/bold red] {e}")
|
|
83
|
+
|
|
84
|
+
# 2. Try global .env file
|
|
85
|
+
global_env_path = Path.home() / ".codegraphcontext" / ".env"
|
|
86
|
+
if global_env_path.exists():
|
|
87
|
+
try:
|
|
88
|
+
load_dotenv(dotenv_path=global_env_path)
|
|
89
|
+
console.print(f"[green]Loaded Neo4j credentials from global .env file: {global_env_path}[/green]")
|
|
90
|
+
return
|
|
91
|
+
except Exception as e:
|
|
92
|
+
console.print(f"[bold red]Error loading global .env file from {global_env_path}:[/bold red] {e}")
|
|
93
|
+
|
|
94
|
+
# 3. Fallback to any discovered .env
|
|
95
|
+
try:
|
|
96
|
+
dotenv_path = find_dotenv(usecwd=True, raise_error_if_not_found=False)
|
|
97
|
+
if dotenv_path:
|
|
98
|
+
load_dotenv(dotenv_path)
|
|
99
|
+
console.print(f"[green]Loaded Neo4j credentials from discovered .env file: {dotenv_path}[/green]")
|
|
100
|
+
else:
|
|
101
|
+
console.print("[yellow]No local mcp.json or .env file found. Credentials may not be set.[/yellow]")
|
|
102
|
+
except Exception as e:
|
|
103
|
+
console.print(f"[bold red]Error loading .env file:[/bold red] {e}")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@app.command()
|
|
107
|
+
def start():
|
|
108
|
+
"""
|
|
109
|
+
Starts the CodeGraphContext MCP server, which listens for JSON-RPC requests from stdin.
|
|
110
|
+
"""
|
|
111
|
+
console.print("[bold green]Starting CodeGraphContext Server...[/bold green]")
|
|
112
|
+
_load_credentials()
|
|
113
|
+
|
|
114
|
+
server = None
|
|
115
|
+
loop = asyncio.new_event_loop()
|
|
116
|
+
asyncio.set_event_loop(loop)
|
|
117
|
+
try:
|
|
118
|
+
# Initialize and run the main server.
|
|
119
|
+
server = MCPServer(loop=loop)
|
|
120
|
+
loop.run_until_complete(server.run())
|
|
121
|
+
except ValueError as e:
|
|
122
|
+
# This typically happens if credentials are still not found after all checks.
|
|
123
|
+
console.print(f"[bold red]Configuration Error:[/bold red] {e}")
|
|
124
|
+
console.print("Please run `cgc setup` to configure the server.")
|
|
125
|
+
except KeyboardInterrupt:
|
|
126
|
+
# Handle graceful shutdown on Ctrl+C.
|
|
127
|
+
console.print("\n[bold yellow]Server stopped by user.[/bold yellow]")
|
|
128
|
+
finally:
|
|
129
|
+
# Ensure server and event loop are properly closed.
|
|
130
|
+
if server:
|
|
131
|
+
server.shutdown()
|
|
132
|
+
loop.close()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _run_tool(tool_name: str, tool_args: dict):
|
|
137
|
+
"""Helper function to run a tool and handle the server lifecycle."""
|
|
138
|
+
_load_credentials()
|
|
139
|
+
try:
|
|
140
|
+
loop = asyncio.new_event_loop()
|
|
141
|
+
asyncio.set_event_loop(loop)
|
|
142
|
+
server = MCPServer(loop=loop)
|
|
143
|
+
|
|
144
|
+
result = loop.run_until_complete(server.handle_tool_call(tool_name, tool_args))
|
|
145
|
+
|
|
146
|
+
if isinstance(result, dict) and "job_id" in result:
|
|
147
|
+
job_id = result["job_id"]
|
|
148
|
+
console.print(f"[green]Successfully started job '{job_id}' for tool '{tool_name}'.[/green]")
|
|
149
|
+
console.print(f"Estimated files: {result.get('estimated_files')}, Estimated duration: {result.get('estimated_duration_human')}")
|
|
150
|
+
console.print(f"\n[bold yellow]Polling for completion...[/bold yellow]")
|
|
151
|
+
|
|
152
|
+
while True:
|
|
153
|
+
time.sleep(2)
|
|
154
|
+
status_result = loop.run_until_complete(server.handle_tool_call("check_job_status", {"job_id": job_id}))
|
|
155
|
+
job_status = status_result.get("job", {}).get("status")
|
|
156
|
+
processed_files = status_result.get("job", {}).get("processed_files", 0)
|
|
157
|
+
total_files = status_result.get("job", {}).get("total_files", 0)
|
|
158
|
+
console.print(f"Job status: {job_status} ({processed_files}/{total_files} files)")
|
|
159
|
+
if job_status in ["completed", "failed", "cancelled"]:
|
|
160
|
+
console.print(json.dumps(status_result, indent=2))
|
|
161
|
+
break
|
|
162
|
+
else:
|
|
163
|
+
console.print(json.dumps(result, indent=2))
|
|
164
|
+
|
|
165
|
+
except ValueError as e:
|
|
166
|
+
console.print(f"[bold red]Configuration Error:[/bold red] {e}")
|
|
167
|
+
except Exception as e:
|
|
168
|
+
console.print(f"[bold red]An unexpected error occurred:[/bold red] {e}")
|
|
169
|
+
finally:
|
|
170
|
+
if 'loop' in locals() and loop.is_running():
|
|
171
|
+
loop.close()
|
|
172
|
+
|
|
173
|
+
@app.command()
|
|
174
|
+
def index(path: Optional[str] = typer.Argument(None, help="Path to the directory or file to index. Defaults to the current directory.")):
|
|
175
|
+
"""
|
|
176
|
+
Indexes a directory or file by adding it to the code graph.
|
|
177
|
+
If no path is provided, it indexes the current directory.
|
|
178
|
+
"""
|
|
179
|
+
if path is None:
|
|
180
|
+
path = "."
|
|
181
|
+
_run_tool("add_code_to_graph", {"path": path})
|
|
182
|
+
|
|
183
|
+
@app.command()
|
|
184
|
+
def delete(path: str = typer.Argument(..., help="Path of the repository to delete from the code graph.")):
|
|
185
|
+
"""
|
|
186
|
+
Deletes a repository from the code graph.
|
|
187
|
+
"""
|
|
188
|
+
_run_tool("delete_repository", {"repo_path": path})
|
|
189
|
+
|
|
190
|
+
@app.command()
|
|
191
|
+
def visualize(query: Optional[str] = typer.Argument(None, help="The Cypher query to visualize.")):
|
|
192
|
+
"""
|
|
193
|
+
Generates a URL to visualize a Cypher query in the Neo4j Browser.
|
|
194
|
+
If no query is provided, a default query will be used.
|
|
195
|
+
"""
|
|
196
|
+
if query is None:
|
|
197
|
+
query = "MATCH p=()-->() RETURN p"
|
|
198
|
+
_run_tool("visualize_graph_query", {"cypher_query": query})
|
|
199
|
+
|
|
200
|
+
@app.command(name="list_repos")
|
|
201
|
+
def list_repos():
|
|
202
|
+
"""
|
|
203
|
+
Lists all indexed repositories.
|
|
204
|
+
"""
|
|
205
|
+
_run_tool("list_indexed_repositories", {})
|
|
206
|
+
|
|
207
|
+
@app.command(name="add_package")
|
|
208
|
+
def add_package(package_name: str = typer.Argument(..., help="Name of the Python package to add.")):
|
|
209
|
+
"""
|
|
210
|
+
Adds a Python package to the code graph.
|
|
211
|
+
"""
|
|
212
|
+
_run_tool("add_package_to_graph", {"package_name": package_name})
|
|
213
|
+
|
|
214
|
+
@app.command()
|
|
215
|
+
def cypher(query: str = typer.Argument(..., help="The read-only Cypher query to execute.")):
|
|
216
|
+
"""
|
|
217
|
+
Executes a read-only Cypher query.
|
|
218
|
+
"""
|
|
219
|
+
_run_tool("execute_cypher_query", {"cypher_query": query})
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@app.command(name="list_mcp_tools")
|
|
223
|
+
def list_mcp_tools():
|
|
224
|
+
"""
|
|
225
|
+
Lists all available tools and their descriptions.
|
|
226
|
+
"""
|
|
227
|
+
_load_credentials()
|
|
228
|
+
console.print("[bold green]Available Tools:[/bold green]")
|
|
229
|
+
try:
|
|
230
|
+
# Instantiate the server to access the tool definitions.
|
|
231
|
+
server = MCPServer()
|
|
232
|
+
tools = server.tools.values()
|
|
233
|
+
|
|
234
|
+
table = Table(show_header=True, header_style="bold magenta")
|
|
235
|
+
table.add_column("Tool Name", style="dim", width=30)
|
|
236
|
+
table.add_column("Description")
|
|
237
|
+
|
|
238
|
+
for tool in sorted(tools, key=lambda t: t['name']):
|
|
239
|
+
table.add_row(tool['name'], tool['description'])
|
|
240
|
+
|
|
241
|
+
console.print(table)
|
|
242
|
+
|
|
243
|
+
except ValueError as e:
|
|
244
|
+
console.print(f"[bold red]Error loading tools:[/bold red] {e}")
|
|
245
|
+
console.print("Please ensure your Neo4j credentials are set up correctly (`cgc setup`), as they are needed to initialize the server.")
|
|
246
|
+
except Exception as e:
|
|
247
|
+
console.print(f"[bold red]An unexpected error occurred:[/bold red] {e}")
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
@app.command()
|
|
251
|
+
def help(ctx: typer.Context):
|
|
252
|
+
"""Show the main help message and exit."""
|
|
253
|
+
root_ctx = ctx.parent or ctx
|
|
254
|
+
typer.echo(root_ctx.get_help())
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
@app.command("version")
|
|
258
|
+
def version_cmd():
|
|
259
|
+
"""Show the application version."""
|
|
260
|
+
console.print(f"CodeGraphContext [bold cyan]{get_version()}[/bold cyan]")
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@app.callback(invoke_without_command=True)
|
|
264
|
+
def main(
|
|
265
|
+
ctx: typer.Context,
|
|
266
|
+
version_: bool = typer.Option(
|
|
267
|
+
None,
|
|
268
|
+
"--version",
|
|
269
|
+
"-v",
|
|
270
|
+
help="Show the application version and exit.",
|
|
271
|
+
is_eager=True,
|
|
272
|
+
),
|
|
273
|
+
):
|
|
274
|
+
"""
|
|
275
|
+
Main entry point for the cgc CLI application.
|
|
276
|
+
If no subcommand is provided, it displays a welcome message with instructions.
|
|
277
|
+
"""
|
|
278
|
+
if version_:
|
|
279
|
+
console.print(f"CodeGraphContext [bold cyan]{get_version()}[/bold cyan]")
|
|
280
|
+
raise typer.Exit()
|
|
281
|
+
|
|
282
|
+
if ctx.invoked_subcommand is None:
|
|
283
|
+
console.print("[bold green]👋 Welcome to CodeGraphContext (cgc)![/bold green]\n")
|
|
284
|
+
console.print("👉 Run [cyan]cgc setup[/cyan] to configure the server and database.")
|
|
285
|
+
console.print("👉 Run [cyan]cgc start[/cyan] to launch the server.")
|
|
286
|
+
console.print("👉 Run [cyan]cgc help[/cyan] to see all available commands.\n")
|
|
287
|
+
console.print("👉 Run [cyan]cgc --version[/cyan] to check the version.\n")
|
|
288
|
+
console.print("👉 Running [green]codegraphcontext [white]works the same as using [green]cgc")
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# src/codegraphcontext/cli/setup_macos.py
|
|
2
|
+
import platform
|
|
3
|
+
import time
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
def _has_brew(run_command, console) -> bool:
|
|
7
|
+
return run_command(["which", "brew"], console, check=False) is not None
|
|
8
|
+
|
|
9
|
+
def _brew_install_neo4j(run_command, console) -> str:
|
|
10
|
+
if run_command(["brew", "install", "neo4j@5"], console, check=False):
|
|
11
|
+
return "neo4j@5"
|
|
12
|
+
if run_command(["brew", "install", "neo4j"], console, check=False):
|
|
13
|
+
return "neo4j"
|
|
14
|
+
return ""
|
|
15
|
+
|
|
16
|
+
def _brew_start(service: str, run_command, console) -> bool:
|
|
17
|
+
return run_command(["brew", "services", "start", service], console, check=False) is not None
|
|
18
|
+
|
|
19
|
+
def _set_initial_password(new_pw: str, run_command, console) -> bool:
|
|
20
|
+
cmd = [
|
|
21
|
+
"cypher-shell",
|
|
22
|
+
"-u", "neo4j",
|
|
23
|
+
"-p", "neo4j",
|
|
24
|
+
f"ALTER CURRENT USER SET PASSWORD FROM 'neo4j' TO '{new_pw}'",
|
|
25
|
+
]
|
|
26
|
+
return run_command(cmd, console, check=False) is not None
|
|
27
|
+
|
|
28
|
+
def setup_macos_binary(console, prompt, run_command, _generate_mcp_json):
|
|
29
|
+
"""Automates Neo4j install & config on macOS via Homebrew."""
|
|
30
|
+
os_name = platform.system()
|
|
31
|
+
console.print(f"Detected Operating System: [bold yellow]{os_name}[/bold yellow]")
|
|
32
|
+
|
|
33
|
+
if os_name != "Darwin":
|
|
34
|
+
console.print("[yellow]This installer is for macOS only.[/yellow]")
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
console.print("[bold]Starting automated Neo4j installation for macOS.[/bold]")
|
|
38
|
+
|
|
39
|
+
if not prompt([{
|
|
40
|
+
"type": "confirm",
|
|
41
|
+
"message": "Proceed with Homebrew-based install of Neo4j?",
|
|
42
|
+
"name": "proceed",
|
|
43
|
+
"default": True
|
|
44
|
+
}]).get("proceed"):
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
console.print("\n[bold]Step: Checking for Homebrew...[/bold]")
|
|
48
|
+
if not _has_brew(run_command, console):
|
|
49
|
+
console.print(
|
|
50
|
+
"[bold red]Homebrew not found.[/bold red] "
|
|
51
|
+
"Install from [bold blue]https://brew.sh[/bold blue] and re-run this setup."
|
|
52
|
+
)
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
console.print("\n[bold]Step: Installing Neo4j via Homebrew...[/bold]")
|
|
56
|
+
service = _brew_install_neo4j(run_command, console)
|
|
57
|
+
if not service:
|
|
58
|
+
console.print("[bold red]Failed to install Neo4j via Homebrew.[/bold red]")
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
console.print(f"\n[bold]Step: Starting Neo4j service ({service})...[/bold]")
|
|
62
|
+
if not _brew_start(service, run_command, console):
|
|
63
|
+
console.print("[bold red]Failed to start Neo4j with brew services.[/bold red]")
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
while True:
|
|
67
|
+
answers = prompt([
|
|
68
|
+
{"type": "password", "message": "Enter a new password for Neo4j:", "name": "pw"},
|
|
69
|
+
{"type": "password", "message": "Confirm the new password:", "name": "pw2"},
|
|
70
|
+
]) or {}
|
|
71
|
+
if not answers:
|
|
72
|
+
return
|
|
73
|
+
pw, pw2 = answers.get("pw"), answers.get("pw2")
|
|
74
|
+
if pw and pw == pw2:
|
|
75
|
+
new_password = pw
|
|
76
|
+
break
|
|
77
|
+
console.print("[red]Passwords do not match or are empty. Please try again.[/red]")
|
|
78
|
+
|
|
79
|
+
console.print("\n[yellow]Waiting 10 seconds for Neo4j to finish starting...[/yellow]")
|
|
80
|
+
time.sleep(10)
|
|
81
|
+
|
|
82
|
+
console.print("\n[bold]Step: Setting initial password with cypher-shell...[/bold]")
|
|
83
|
+
if not _set_initial_password(new_password, run_command, console):
|
|
84
|
+
console.print(
|
|
85
|
+
"[bold red]Failed to set the initial password.[/bold red]\n"
|
|
86
|
+
"Try manually:\n"
|
|
87
|
+
" cypher-shell -u neo4j -p neo4j \"ALTER CURRENT USER SET PASSWORD FROM 'neo4j' TO '<your_pw>'\""
|
|
88
|
+
)
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
creds = {"uri": "neo4j://localhost:7687", "username": "neo4j", "password": new_password}
|
|
92
|
+
_generate_mcp_json(creds)
|
|
93
|
+
|
|
94
|
+
env_path = Path.home() / ".codegraphcontext" / ".env"
|
|
95
|
+
console.print(f"\n[bold green]All done![/bold green] Neo4j running. Credentials saved to: [bold]{env_path}[/bold]")
|