codegraphcontext 0.1.6__tar.gz → 0.1.7__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 (27) hide show
  1. {codegraphcontext-0.1.6/src/codegraphcontext.egg-info → codegraphcontext-0.1.7}/PKG-INFO +4 -1
  2. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/README.md +3 -1
  3. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/pyproject.toml +2 -1
  4. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/cli/setup_wizard.py +135 -14
  5. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/server.py +1 -1
  6. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/tools/import_extractor.py +15 -13
  7. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7/src/codegraphcontext.egg-info}/PKG-INFO +4 -1
  8. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext.egg-info/requires.txt +1 -0
  9. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/LICENSE +0 -0
  10. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/setup.cfg +0 -0
  11. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/__init__.py +0 -0
  12. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/__main__.py +0 -0
  13. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/cli/__init__.py +0 -0
  14. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/cli/main.py +0 -0
  15. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/core/__init__.py +0 -0
  16. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/core/database.py +0 -0
  17. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/core/jobs.py +0 -0
  18. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/core/watcher.py +0 -0
  19. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/prompts.py +0 -0
  20. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/tools/__init__.py +0 -0
  21. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/tools/code_finder.py +0 -0
  22. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/tools/graph_builder.py +0 -0
  23. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext/tools/system.py +0 -0
  24. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext.egg-info/SOURCES.txt +0 -0
  25. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
  26. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
  27. {codegraphcontext-0.1.6 → codegraphcontext-0.1.7}/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.6
3
+ Version: 0.1.7
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
@@ -47,9 +47,12 @@ Requires-Dist: python-dotenv>=1.0.0
47
47
  Provides-Extra: dev
48
48
  Requires-Dist: pytest>=7.4.0; extra == "dev"
49
49
  Requires-Dist: black>=23.11.0; extra == "dev"
50
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
50
51
  Dynamic: license-file
51
52
 
52
53
  # CodeGraphContext
54
+ [![Build Status](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml/badge.svg)](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml)
55
+
53
56
 
54
57
  An MCP server that indexes local code into a graph database to provide context to AI assistants.
55
58
 
@@ -1,4 +1,6 @@
1
1
  # CodeGraphContext
2
+ [![Build Status](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml/badge.svg)](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml)
3
+
2
4
 
3
5
  An MCP server that indexes local code into a graph database to provide context to AI assistants.
4
6
 
@@ -96,4 +98,4 @@ Once the server is running, you can interact with it through your AI assistant u
96
98
  - "Find all implementations of the `render` method."
97
99
 
98
100
  - **Code Quality and Maintenance:**
99
- - "Is there any dead or unused code in this project?"
101
+ - "Is there any dead or unused code in this project?"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codegraphcontext"
3
- version = "0.1.6"
3
+ version = "0.1.7"
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"
@@ -36,6 +36,7 @@ cgc = "codegraphcontext.cli.main:app"
36
36
  dev = [
37
37
  "pytest>=7.4.0",
38
38
  "black>=23.11.0",
39
+ "pytest-asyncio>=0.21.0",
39
40
  ]
40
41
 
41
42
  [tool.setuptools]
@@ -229,20 +229,141 @@ def setup_local_db():
229
229
  setup_local_binary()
230
230
 
231
231
  def setup_docker():
232
- """Creates Docker files and runs docker-compose."""
233
- console.print("This will create a `docker-compose.yml` and `.env` file in your current directory.")
234
- # Here you would write the file contents
235
- console.print("[green]docker-compose.yml and .env created.[/green]")
236
- console.print("Please set your NEO4J_PASSWORD in the .env file.")
237
- confirm_q = [{"type": "confirm", "message": "Ready to launch Docker containers?", "name": "proceed"}]
238
- if prompt(confirm_q).get("proceed"):
239
- try:
240
- # Using our run_command to handle the subprocess call
241
- docker_process = run_command(["docker", "compose", "up", "-d"], console, check=True)
242
- if docker_process:
243
- console.print("[bold green]Docker containers started successfully![/bold green]")
244
- except Exception as e:
245
- console.print(f"[bold red]Failed to start Docker containers:[/bold red] {e}")
232
+ """Creates Docker files and runs docker-compose for Neo4j."""
233
+ console.print("\n[bold cyan]Setting up Neo4j with Docker...[/bold cyan]")
234
+
235
+ # Prompt for password first
236
+ console.print("Please set a secure password for your Neo4j database:")
237
+ password_questions = [
238
+ {"type": "password", "message": "Enter Neo4j password:", "name": "password"},
239
+ {"type": "password", "message": "Confirm password:", "name": "password_confirm"},
240
+ ]
241
+
242
+ while True:
243
+ passwords = prompt(password_questions)
244
+ if not passwords:
245
+ return # User cancelled
246
+
247
+ password = passwords.get("password", "")
248
+ if password and password == passwords.get("password_confirm"):
249
+ break
250
+ console.print("[red]Passwords do not match or are empty. Please try again.[/red]")
251
+
252
+ # Create data directories
253
+ neo4j_dir = Path.cwd() / "neo4j_data"
254
+ for subdir in ["data", "logs", "conf", "plugins"]:
255
+ (neo4j_dir / subdir).mkdir(parents=True, exist_ok=True)
256
+
257
+ # Fixed docker-compose.yml content
258
+ docker_compose_content = f"""
259
+ services:
260
+ neo4j:
261
+ image: neo4j:5.21
262
+ container_name: neo4j-cgc
263
+ restart: unless-stopped
264
+ ports:
265
+ - "7474:7474"
266
+ - "7687:7687"
267
+ environment:
268
+ - NEO4J_AUTH=neo4j/12345678
269
+ - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
270
+ volumes:
271
+ - neo4j_data:/data
272
+ - neo4j_logs:/logs
273
+
274
+ volumes:
275
+ neo4j_data:
276
+ neo4j_logs:
277
+ """
278
+
279
+ # Write docker-compose.yml
280
+ compose_file = Path.cwd() / "docker-compose.yml"
281
+ with open(compose_file, "w") as f:
282
+ f.write(docker_compose_content)
283
+
284
+ console.print("[green]✅ docker-compose.yml created with secure password.[/green]")
285
+
286
+ # Check if Docker is running
287
+ docker_check = run_command(["docker", "--version"], console, check=False)
288
+ if not docker_check:
289
+ console.print("[red]❌ Docker is not installed or not running. Please install Docker first.[/red]")
290
+ return
291
+
292
+ # Check if docker-compose is available
293
+ compose_check = run_command(["docker", "compose", "version"], console, check=False)
294
+ if not compose_check:
295
+ console.print("[red]❌ Docker Compose is not available. Please install Docker Compose.[/red]")
296
+ return
297
+
298
+ confirm_q = [{"type": "confirm", "message": "Ready to launch Neo4j in Docker?", "name": "proceed", "default": True}]
299
+ if not prompt(confirm_q).get("proceed"):
300
+ return
301
+
302
+ try:
303
+ # Pull the image first
304
+ console.print("[cyan]Pulling Neo4j Docker image...[/cyan]")
305
+ pull_process = run_command(["docker", "pull", "neo4j:5.21"], console, check=True)
306
+ if not pull_process:
307
+ console.print("[yellow]⚠️ Could not pull image, but continuing anyway...[/yellow]")
308
+
309
+ # Start containers
310
+ console.print("[cyan]Starting Neo4j container...[/cyan]")
311
+ docker_process = run_command(["docker", "compose", "up", "-d"], console, check=True)
312
+
313
+ if docker_process:
314
+ console.print("[bold green]🚀 Neo4j Docker container started successfully![/bold green]")
315
+
316
+ # Wait for Neo4j to be ready
317
+ console.print("[cyan]Waiting for Neo4j to be ready (this may take 30-60 seconds)...[/cyan]")
318
+
319
+ # Try to connect for up to 2 minutes
320
+ max_attempts = 24 # 24 * 5 seconds = 2 minutes
321
+ for attempt in range(max_attempts):
322
+ time.sleep(5)
323
+
324
+ # Check if container is still running
325
+ status_check = run_command(["docker", "compose", "ps", "-q", "neo4j"], console, check=False)
326
+ if not status_check or not status_check.stdout.strip():
327
+ console.print("[red]❌ Neo4j container stopped unexpectedly. Check logs with: docker compose logs neo4j[/red]")
328
+ return
329
+
330
+ # Try to connect
331
+ health_check = run_command([
332
+ "docker", "exec", "neo4j-cgc", "cypher-shell",
333
+ "-u", "neo4j", "-p", password,
334
+ "RETURN 'Connection successful' as status"
335
+ ], console, check=False)
336
+
337
+ if health_check and health_check.returncode == 0:
338
+ console.print("[bold green]✅ Neo4j is ready and accepting connections![/bold green]")
339
+ break
340
+
341
+ if attempt < max_attempts - 1:
342
+ console.print(f"[yellow]Still waiting... (attempt {attempt + 1}/{max_attempts})[/yellow]")
343
+ else:
344
+ console.print("[red]❌ Neo4j did not become ready within 2 minutes. Check logs with: docker compose logs neo4j[/red]")
345
+ return
346
+
347
+ # Generate MCP configuration
348
+ creds = {
349
+ "uri": "neo4j://localhost:7687", # Use neo4j:// protocol for Neo4j 5.x
350
+ "username": "neo4j",
351
+ "password": password
352
+ }
353
+ _generate_mcp_json(creds)
354
+
355
+ console.print("\n[bold green]🎉 Setup complete![/bold green]")
356
+ console.print("Neo4j is running at:")
357
+ console.print(" • Web interface: http://localhost:7474")
358
+ console.print(" • Bolt connection: neo4j://localhost:7687")
359
+ console.print("\n[cyan]Useful commands:[/cyan]")
360
+ console.print(" • Stop: docker compose down")
361
+ console.print(" • Restart: docker compose restart")
362
+ console.print(" • View logs: docker compose logs neo4j")
363
+
364
+ except Exception as e:
365
+ console.print(f"[bold red]❌ Failed to start Neo4j Docker container:[/bold red] {e}")
366
+ console.print("[cyan]Try checking the logs with: docker compose logs neo4j[/cyan]")
246
367
 
247
368
  def setup_local_binary():
248
369
  """Automates the installation and configuration of Neo4j on Ubuntu/Debian."""
@@ -125,7 +125,7 @@ class MCPServer:
125
125
  },
126
126
  "execute_cypher_query": {
127
127
  "name": "execute_cypher_query",
128
- "description": "Fallback tool to run a direct, read-only Cypher query against the code graph.",
128
+ "description": "Fallback tool to run a direct, read-only Cypher query against the code graph. Use this for complex questions not covered by other tools. The graph contains nodes representing code structures and relationships between them. **Schema Overview:**\n- **Nodes:** `Repository`, `File`, `Module`, `Class`, `Function`.\n- **Properties:** Nodes have properties like `name`, `path`, `cyclomatic_complexity` (on Function nodes), and `code`.\n- **Relationships:** `CONTAINS` (e.g., File-[:CONTAINS]->Function), `CALLS` (Function-[:CALLS]->Function or File-[:CALLS]->Function), `IMPORTS` (File-[:IMPORTS]->Module), `INHERITS` (Class-[:INHERITS]->Class).",
129
129
  "inputSchema": {
130
130
  "type": "object",
131
131
  "properties": { "cypher_query": {"type": "string", "description": "The read-only Cypher query to execute."} },
@@ -1,4 +1,5 @@
1
1
  # src/codegraphcontext/tools/import_extractor.py
2
+ import ast
2
3
  import logging
3
4
  import re
4
5
  from pathlib import Path
@@ -13,23 +14,24 @@ class ImportExtractor:
13
14
 
14
15
  @staticmethod
15
16
  def extract_python_imports(file_path: str) -> Set[str]:
16
- """Extract imports from a Python file"""
17
+ """Extract imports from a Python file using AST parsing."""
17
18
  imports = set()
18
19
  try:
19
20
  with open(file_path, 'r', encoding='utf-8') as f:
20
- content = f.read()
21
- patterns = [
22
- r'^\s*import\s+([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)',
23
- r'^\s*from\s+([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)\s+import',
24
- ]
25
- for line in content.split('\n'):
26
- for pattern in patterns:
27
- match = re.match(pattern, line.strip())
28
- if match:
29
- import_name = match.group(1).split('.')[0]
30
- imports.add(import_name)
21
+ tree = ast.parse(f.read(), filename=file_path)
22
+
23
+ for node in ast.walk(tree):
24
+ if isinstance(node, ast.Import):
25
+ for alias in node.names:
26
+ imports.add(alias.name.split('.')[0]) # Get top-level package
27
+ elif isinstance(node, ast.ImportFrom):
28
+ if node.level > 0: # Relative import
29
+ # As per the user's request, do not list relative imports
30
+ pass
31
+ elif node.module:
32
+ imports.add(node.module.split('.')[0]) # Get top-level package
31
33
  except Exception as e:
32
- logger.warning(f"Error reading {file_path}: {e}")
34
+ logger.warning(f"Error parsing or reading {file_path}: {e}")
33
35
  return imports
34
36
 
35
37
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegraphcontext
3
- Version: 0.1.6
3
+ Version: 0.1.7
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
@@ -47,9 +47,12 @@ Requires-Dist: python-dotenv>=1.0.0
47
47
  Provides-Extra: dev
48
48
  Requires-Dist: pytest>=7.4.0; extra == "dev"
49
49
  Requires-Dist: black>=23.11.0; extra == "dev"
50
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
50
51
  Dynamic: license-file
51
52
 
52
53
  # CodeGraphContext
54
+ [![Build Status](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml/badge.svg)](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml)
55
+
53
56
 
54
57
  An MCP server that indexes local code into a graph database to provide context to AI assistants.
55
58
 
@@ -10,3 +10,4 @@ python-dotenv>=1.0.0
10
10
  [dev]
11
11
  pytest>=7.4.0
12
12
  black>=23.11.0
13
+ pytest-asyncio>=0.21.0