codegraphcontext 0.1.34__tar.gz → 0.1.35__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.34/src/codegraphcontext.egg-info → codegraphcontext-0.1.35}/PKG-INFO +2 -2
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/README.md +1 -1
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/pyproject.toml +1 -1
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/cli_helpers.py +12 -15
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/main.py +8 -3
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/registry_commands.py +135 -29
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/cgc_bundle.py +23 -2
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/database.py +5 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/database_falkordb.py +5 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35/src/codegraphcontext.egg-info}/PKG-INFO +2 -2
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/LICENSE +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/MANIFEST.in +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/setup.cfg +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/config_manager.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/setup_macos.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/setup_wizard.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/visualizer.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/__init__.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/falkor_worker.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/watcher.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/server.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tool_definitions.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/code_finder.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/graph_builder.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/c.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/cpp.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/csharp.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/go.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/java.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/javascript.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/php.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/python.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/ruby.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/rust.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/scala.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/swift.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/typescript.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/package_resolver.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/utils/debug_log.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/utils/visualize_graph.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/SOURCES.txt +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/requires.txt +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/top_level.txt +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_cpp_parser.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_database_validation.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_end_to_end.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_graph_indexing.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_graph_indexing_js.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_kotlin_parser.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_swift_parser.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_tree_sitter_manager.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_typescript_parser.py +0 -0
- {codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/tests/test_visualization.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codegraphcontext
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.35
|
|
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
|
|
@@ -91,7 +91,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
91
91
|

|
|
92
92
|
|
|
93
93
|
## Project Details
|
|
94
|
-
- **Version:** 0.1.
|
|
94
|
+
- **Version:** 0.1.35
|
|
95
95
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
96
96
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
97
97
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -29,7 +29,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
29
29
|

|
|
30
30
|
|
|
31
31
|
## Project Details
|
|
32
|
-
- **Version:** 0.1.
|
|
32
|
+
- **Version:** 0.1.35
|
|
33
33
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
34
34
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
35
35
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codegraphcontext"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.35"
|
|
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"
|
|
@@ -572,28 +572,25 @@ def stats_helper(path: str = None):
|
|
|
572
572
|
console.print("[cyan]📊 Overall Database Statistics[/cyan]\n")
|
|
573
573
|
|
|
574
574
|
with db_manager.get_driver().session() as session:
|
|
575
|
-
# Get overall counts
|
|
575
|
+
# Get overall counts using separate queries to avoid empty results
|
|
576
|
+
# when some node types don't exist
|
|
576
577
|
stats_query = """
|
|
577
578
|
MATCH (r:Repository)
|
|
578
|
-
|
|
579
|
-
MATCH (
|
|
580
|
-
|
|
581
|
-
MATCH (
|
|
582
|
-
WITH repo_count, file_count, count(func) as function_count
|
|
583
|
-
MATCH (cls:Class)
|
|
584
|
-
WITH repo_count, file_count, function_count, count(cls) as class_count
|
|
585
|
-
MATCH (m:Module)
|
|
579
|
+
OPTIONAL MATCH (f:File)
|
|
580
|
+
OPTIONAL MATCH (func:Function)
|
|
581
|
+
OPTIONAL MATCH (cls:Class)
|
|
582
|
+
OPTIONAL MATCH (m:Module)
|
|
586
583
|
RETURN
|
|
587
|
-
repo_count,
|
|
588
|
-
file_count,
|
|
589
|
-
function_count,
|
|
590
|
-
class_count,
|
|
591
|
-
count(m) as module_count
|
|
584
|
+
count(DISTINCT r) as repo_count,
|
|
585
|
+
count(DISTINCT f) as file_count,
|
|
586
|
+
count(DISTINCT func) as function_count,
|
|
587
|
+
count(DISTINCT cls) as class_count,
|
|
588
|
+
count(DISTINCT m) as module_count
|
|
592
589
|
"""
|
|
593
590
|
result = session.run(stats_query)
|
|
594
591
|
record = result.single()
|
|
595
592
|
|
|
596
|
-
if record:
|
|
593
|
+
if record and record["repo_count"] > 0:
|
|
597
594
|
table = Table(show_header=True, header_style="bold magenta")
|
|
598
595
|
table.add_column("Metric", style="cyan")
|
|
599
596
|
table.add_column("Count", style="green", justify="right")
|
|
@@ -44,9 +44,11 @@ from .cli_helpers import (
|
|
|
44
44
|
list_watching_helper,
|
|
45
45
|
)
|
|
46
46
|
|
|
47
|
-
# Set the log level for the noisy neo4j and
|
|
47
|
+
# Set the log level for the noisy neo4j, asyncio, and urllib3 loggers to WARNING to keep the output clean.
|
|
48
48
|
logging.getLogger("neo4j").setLevel(logging.WARNING)
|
|
49
49
|
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
|
50
|
+
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
|
51
|
+
|
|
50
52
|
|
|
51
53
|
# Import visualization module
|
|
52
54
|
from .visualizer import (
|
|
@@ -552,19 +554,22 @@ app.add_typer(registry_app, name="registry")
|
|
|
552
554
|
|
|
553
555
|
@registry_app.command("list")
|
|
554
556
|
def registry_list(
|
|
555
|
-
verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed information including download URLs")
|
|
557
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed information including download URLs"),
|
|
558
|
+
unique: bool = typer.Option(False, "--unique", "-u", help="Show only one version per package (most recent)")
|
|
556
559
|
):
|
|
557
560
|
"""
|
|
558
561
|
List all available bundles in the registry.
|
|
559
562
|
|
|
560
563
|
Shows bundles from both weekly pre-indexed releases and on-demand generations.
|
|
564
|
+
By default, shows all versions. Use --unique to see only the most recent version per package.
|
|
561
565
|
|
|
562
566
|
Examples:
|
|
563
567
|
cgc registry list
|
|
564
568
|
cgc registry list --verbose
|
|
569
|
+
cgc registry list --unique
|
|
565
570
|
"""
|
|
566
571
|
from .registry_commands import list_bundles
|
|
567
|
-
list_bundles(verbose=verbose)
|
|
572
|
+
list_bundles(verbose=verbose, unique=unique)
|
|
568
573
|
|
|
569
574
|
@registry_app.command("search")
|
|
570
575
|
def registry_search(
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/registry_commands.py
RENAMED
|
@@ -25,6 +25,7 @@ def fetch_available_bundles() -> List[Dict[str, Any]]:
|
|
|
25
25
|
"""
|
|
26
26
|
Fetch all available bundles from GitHub Releases.
|
|
27
27
|
Returns a list of bundle dictionaries with metadata.
|
|
28
|
+
Preserves all versions - no deduplication.
|
|
28
29
|
"""
|
|
29
30
|
all_bundles = []
|
|
30
31
|
|
|
@@ -37,6 +38,10 @@ def fetch_available_bundles() -> List[Dict[str, Any]]:
|
|
|
37
38
|
if manifest.get('bundles'):
|
|
38
39
|
for bundle in manifest['bundles']:
|
|
39
40
|
bundle['source'] = 'on-demand'
|
|
41
|
+
# Ensure bundle has a full_name field (with version info)
|
|
42
|
+
if 'bundle_name' in bundle:
|
|
43
|
+
# Extract full name without .cgc extension
|
|
44
|
+
bundle['full_name'] = bundle['bundle_name'].replace('.cgc', '')
|
|
40
45
|
all_bundles.append(bundle)
|
|
41
46
|
except Exception as e:
|
|
42
47
|
console.print(f"[dim]Note: Could not fetch on-demand bundles: {e}[/dim]")
|
|
@@ -56,10 +61,14 @@ def fetch_available_bundles() -> List[Dict[str, Any]]:
|
|
|
56
61
|
|
|
57
62
|
for asset in latest_weekly.get('assets', []):
|
|
58
63
|
if asset['name'].endswith('.cgc'):
|
|
64
|
+
# Full bundle name without extension
|
|
65
|
+
full_name = asset['name'].replace('.cgc', '')
|
|
66
|
+
|
|
59
67
|
# Parse bundle name
|
|
60
|
-
name_parts =
|
|
68
|
+
name_parts = full_name.split('-')
|
|
61
69
|
bundle = {
|
|
62
|
-
'name': name_parts[0],
|
|
70
|
+
'name': name_parts[0], # Base package name
|
|
71
|
+
'full_name': full_name, # Complete name with version
|
|
63
72
|
'repo': f"{name_parts[0]}/{name_parts[0]}", # Simplified
|
|
64
73
|
'bundle_name': asset['name'],
|
|
65
74
|
'version': name_parts[1] if len(name_parts) > 1 else 'latest',
|
|
@@ -73,32 +82,60 @@ def fetch_available_bundles() -> List[Dict[str, Any]]:
|
|
|
73
82
|
except Exception as e:
|
|
74
83
|
console.print(f"[dim]Note: Could not fetch weekly bundles: {e}[/dim]")
|
|
75
84
|
|
|
76
|
-
#
|
|
77
|
-
unique_bundles = {}
|
|
85
|
+
# Normalize all bundles to have required fields
|
|
78
86
|
for bundle in all_bundles:
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
87
|
+
# Ensure 'name' field exists (base package name)
|
|
88
|
+
if 'name' not in bundle:
|
|
89
|
+
repo = bundle.get('repo', '')
|
|
90
|
+
if '/' in repo:
|
|
91
|
+
bundle['name'] = repo.split('/')[-1]
|
|
92
|
+
else:
|
|
93
|
+
# Extract from full_name or bundle_name
|
|
94
|
+
full_name = bundle.get('full_name', bundle.get('bundle_name', 'unknown'))
|
|
95
|
+
bundle['name'] = full_name.split('-')[0]
|
|
85
96
|
|
|
86
|
-
#
|
|
87
|
-
if '
|
|
88
|
-
bundle['
|
|
89
|
-
|
|
90
|
-
if name not in unique_bundles or bundle.get('source') == 'on-demand':
|
|
91
|
-
unique_bundles[name] = bundle
|
|
97
|
+
# Ensure 'full_name' exists
|
|
98
|
+
if 'full_name' not in bundle:
|
|
99
|
+
bundle['full_name'] = bundle.get('bundle_name', bundle.get('name', 'unknown')).replace('.cgc', '')
|
|
92
100
|
|
|
93
|
-
|
|
101
|
+
# NO DEDUPLICATION - Keep all versions
|
|
102
|
+
return all_bundles
|
|
94
103
|
|
|
95
104
|
except Exception as e:
|
|
96
105
|
console.print(f"[bold red]Error fetching bundles: {e}[/bold red]")
|
|
97
106
|
return []
|
|
98
107
|
|
|
99
108
|
|
|
100
|
-
def
|
|
101
|
-
"""
|
|
109
|
+
def _get_base_package_name(bundle_name: str) -> str:
|
|
110
|
+
"""
|
|
111
|
+
Extract base package name from full bundle name.
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
'python-bitcoin-utils-main-61d1969' -> 'python-bitcoin-utils'
|
|
115
|
+
'flask-main-abc123' -> 'flask'
|
|
116
|
+
'requests' -> 'requests'
|
|
117
|
+
"""
|
|
118
|
+
# Remove .cgc extension if present
|
|
119
|
+
name = bundle_name.replace('.cgc', '')
|
|
120
|
+
|
|
121
|
+
# Split by hyphen and take the first part
|
|
122
|
+
# This assumes package names don't contain hyphens (may need refinement)
|
|
123
|
+
parts = name.split('-')
|
|
124
|
+
|
|
125
|
+
# For multi-word package names like 'python-bitcoin-utils',
|
|
126
|
+
# we need smarter logic. For now, take first part.
|
|
127
|
+
# TODO: Improve this with a known package list or better heuristics
|
|
128
|
+
return parts[0]
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def list_bundles(verbose: bool = False, unique: bool = False):
|
|
132
|
+
"""
|
|
133
|
+
Display all available bundles in a table.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
verbose: Show additional details like download URLs
|
|
137
|
+
unique: Show only one version per package (most recent)
|
|
138
|
+
"""
|
|
102
139
|
console.print("[cyan]Fetching available bundles...[/cyan]")
|
|
103
140
|
|
|
104
141
|
bundles = fetch_available_bundles()
|
|
@@ -108,9 +145,25 @@ def list_bundles(verbose: bool = False):
|
|
|
108
145
|
console.print("[dim]The registry may be empty or unreachable.[/dim]")
|
|
109
146
|
return
|
|
110
147
|
|
|
148
|
+
# If unique flag is set, keep only the most recent version per package
|
|
149
|
+
if unique:
|
|
150
|
+
unique_bundles = {}
|
|
151
|
+
for bundle in bundles:
|
|
152
|
+
base_name = bundle.get('name', 'unknown')
|
|
153
|
+
# Keep the one with the most recent timestamp
|
|
154
|
+
if base_name not in unique_bundles:
|
|
155
|
+
unique_bundles[base_name] = bundle
|
|
156
|
+
else:
|
|
157
|
+
# Compare timestamps (generated_at field)
|
|
158
|
+
current_time = bundle.get('generated_at', '')
|
|
159
|
+
existing_time = unique_bundles[base_name].get('generated_at', '')
|
|
160
|
+
if current_time > existing_time:
|
|
161
|
+
unique_bundles[base_name] = bundle
|
|
162
|
+
bundles = list(unique_bundles.values())
|
|
163
|
+
|
|
111
164
|
# Create table
|
|
112
165
|
table = Table(show_header=True, header_style="bold magenta", title="Available Bundles")
|
|
113
|
-
table.add_column("Name", style="cyan", no_wrap=True)
|
|
166
|
+
table.add_column("Bundle Name", style="cyan", no_wrap=True)
|
|
114
167
|
table.add_column("Repository", style="dim")
|
|
115
168
|
table.add_column("Version", style="green")
|
|
116
169
|
table.add_column("Size", justify="right")
|
|
@@ -119,11 +172,12 @@ def list_bundles(verbose: bool = False):
|
|
|
119
172
|
if verbose:
|
|
120
173
|
table.add_column("Download URL", style="blue", no_wrap=False)
|
|
121
174
|
|
|
122
|
-
# Sort by
|
|
123
|
-
bundles.sort(key=lambda b: b.get('name', ''))
|
|
175
|
+
# Sort by full_name to group versions together
|
|
176
|
+
bundles.sort(key=lambda b: (b.get('name', ''), b.get('full_name', '')))
|
|
124
177
|
|
|
125
178
|
for bundle in bundles:
|
|
126
|
-
|
|
179
|
+
# Use full_name for display (includes version info)
|
|
180
|
+
display_name = bundle.get('full_name', bundle.get('name', 'unknown'))
|
|
127
181
|
repo = bundle.get('repo', 'unknown')
|
|
128
182
|
version = bundle.get('version', bundle.get('tag', 'latest'))
|
|
129
183
|
size = bundle.get('size', 'unknown')
|
|
@@ -131,12 +185,16 @@ def list_bundles(verbose: bool = False):
|
|
|
131
185
|
|
|
132
186
|
if verbose:
|
|
133
187
|
download_url = bundle.get('download_url', 'N/A')
|
|
134
|
-
table.add_row(
|
|
188
|
+
table.add_row(display_name, repo, version, size, source, download_url)
|
|
135
189
|
else:
|
|
136
|
-
table.add_row(
|
|
190
|
+
table.add_row(display_name, repo, version, size, source)
|
|
137
191
|
|
|
138
192
|
console.print(table)
|
|
139
193
|
console.print(f"\n[dim]Total bundles: {len(bundles)}[/dim]")
|
|
194
|
+
if unique:
|
|
195
|
+
console.print("[dim]Showing only most recent version per package. Use without --unique to see all versions.[/dim]")
|
|
196
|
+
else:
|
|
197
|
+
console.print("[dim]Use --unique to show only one version per package[/dim]")
|
|
140
198
|
console.print("[dim]Use 'cgc registry download <name>' to download a bundle[/dim]")
|
|
141
199
|
|
|
142
200
|
|
|
@@ -183,7 +241,12 @@ def search_bundles(query: str):
|
|
|
183
241
|
|
|
184
242
|
|
|
185
243
|
def download_bundle(name: str, output_dir: Optional[str] = None, auto_load: bool = False):
|
|
186
|
-
"""
|
|
244
|
+
"""
|
|
245
|
+
Download a bundle from the registry.
|
|
246
|
+
|
|
247
|
+
Supports both full names (e.g., 'python-bitcoin-utils-main-61d1969')
|
|
248
|
+
and base names (e.g., 'python-bitcoin-utils' - picks most recent version).
|
|
249
|
+
"""
|
|
187
250
|
console.print(f"[cyan]Looking for bundle '{name}'...[/cyan]")
|
|
188
251
|
|
|
189
252
|
bundles = fetch_available_bundles()
|
|
@@ -192,16 +255,59 @@ def download_bundle(name: str, output_dir: Optional[str] = None, auto_load: bool
|
|
|
192
255
|
console.print("[bold red]Could not fetch bundle registry.[/bold red]")
|
|
193
256
|
raise typer.Exit(code=1)
|
|
194
257
|
|
|
195
|
-
#
|
|
258
|
+
# Strategy 1: Try exact match on full_name (with version)
|
|
196
259
|
bundle = None
|
|
197
260
|
for b in bundles:
|
|
198
|
-
if b.get('
|
|
261
|
+
if b.get('full_name', '').lower() == name.lower():
|
|
199
262
|
bundle = b
|
|
263
|
+
console.print(f"[dim]Found exact match: {b.get('full_name')}[/dim]")
|
|
200
264
|
break
|
|
201
265
|
|
|
266
|
+
# Strategy 2: If no exact match, try matching base package name
|
|
267
|
+
# and pick the most recent version
|
|
202
268
|
if not bundle:
|
|
269
|
+
matching_bundles = []
|
|
270
|
+
for b in bundles:
|
|
271
|
+
if b.get('name', '').lower() == name.lower():
|
|
272
|
+
matching_bundles.append(b)
|
|
273
|
+
|
|
274
|
+
if matching_bundles:
|
|
275
|
+
# Sort by timestamp and pick the most recent
|
|
276
|
+
matching_bundles.sort(key=lambda x: x.get('generated_at', ''), reverse=True)
|
|
277
|
+
bundle = matching_bundles[0]
|
|
278
|
+
|
|
279
|
+
console.print(f"[yellow]Multiple versions found for '{name}'. Using most recent:[/yellow]")
|
|
280
|
+
console.print(f"[cyan] → {bundle.get('full_name')}[/cyan]")
|
|
281
|
+
|
|
282
|
+
if len(matching_bundles) > 1:
|
|
283
|
+
console.print(f"\n[dim]Other available versions:[/dim]")
|
|
284
|
+
for b in matching_bundles[1:4]: # Show up to 3 alternatives
|
|
285
|
+
console.print(f"[dim] • {b.get('full_name')}[/dim]")
|
|
286
|
+
if len(matching_bundles) > 4:
|
|
287
|
+
console.print(f"[dim] ... and {len(matching_bundles) - 4} more[/dim]")
|
|
288
|
+
console.print()
|
|
289
|
+
|
|
290
|
+
# Strategy 3: No match found - show suggestions
|
|
291
|
+
if not bundle:
|
|
292
|
+
# Find bundles with similar base names
|
|
293
|
+
suggestions = []
|
|
294
|
+
name_lower = name.lower()
|
|
295
|
+
for b in bundles:
|
|
296
|
+
base_name = b.get('name', '').lower()
|
|
297
|
+
full_name = b.get('full_name', '').lower()
|
|
298
|
+
|
|
299
|
+
# Fuzzy matching: check if search term is in base or full name
|
|
300
|
+
if name_lower in base_name or name_lower in full_name:
|
|
301
|
+
suggestions.append(b.get('full_name', b.get('name', 'unknown')))
|
|
302
|
+
|
|
203
303
|
console.print(f"[bold red]Bundle '{name}' not found in registry.[/bold red]")
|
|
204
|
-
|
|
304
|
+
|
|
305
|
+
if suggestions:
|
|
306
|
+
console.print("\n[yellow]Did you mean one of these?[/yellow]")
|
|
307
|
+
for suggestion in suggestions[:5]: # Show top 5
|
|
308
|
+
console.print(f" • {suggestion}")
|
|
309
|
+
|
|
310
|
+
console.print("\n[dim]Use 'cgc registry list' to see all available bundles[/dim]")
|
|
205
311
|
raise typer.Exit(code=1)
|
|
206
312
|
|
|
207
313
|
# Get download URL
|
|
@@ -44,6 +44,21 @@ class CGCBundle:
|
|
|
44
44
|
"""
|
|
45
45
|
self.db_manager = db_manager
|
|
46
46
|
|
|
47
|
+
def _get_id_function(self) -> str:
|
|
48
|
+
"""
|
|
49
|
+
Get the appropriate ID function based on the database backend.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
str: 'elementId' for Neo4j, 'id' for FalkorDB
|
|
53
|
+
"""
|
|
54
|
+
# Check if we're using Neo4j or FalkorDB
|
|
55
|
+
backend = self.db_manager.get_backend_type()
|
|
56
|
+
if backend == 'neo4j':
|
|
57
|
+
return 'elementId'
|
|
58
|
+
else: # FalkorDB or other backends
|
|
59
|
+
return 'id'
|
|
60
|
+
|
|
61
|
+
|
|
47
62
|
def export_to_bundle(
|
|
48
63
|
self,
|
|
49
64
|
output_path: Path,
|
|
@@ -622,13 +637,16 @@ cgc import <bundle-file>.cgc
|
|
|
622
637
|
|
|
623
638
|
def _import_node_batch(self, session, batch: List[Tuple], id_mapping: Dict) -> int:
|
|
624
639
|
"""Import a batch of nodes."""
|
|
640
|
+
# Detect database backend to use appropriate ID function
|
|
641
|
+
id_function = self._get_id_function()
|
|
642
|
+
|
|
625
643
|
for labels, properties, old_id in batch:
|
|
626
644
|
if not labels:
|
|
627
645
|
continue
|
|
628
646
|
|
|
629
647
|
# Create node with labels
|
|
630
648
|
label_str = ':'.join(labels)
|
|
631
|
-
query = f"CREATE (n:{label_str}) SET n = $props RETURN
|
|
649
|
+
query = f"CREATE (n:{label_str}) SET n = $props RETURN {id_function}(n) as new_id"
|
|
632
650
|
|
|
633
651
|
result = session.run(query, props=properties)
|
|
634
652
|
record = result.single()
|
|
@@ -663,6 +681,8 @@ cgc import <bundle-file>.cgc
|
|
|
663
681
|
def _import_edge_batch(self, session, batch: List[Dict]) -> int:
|
|
664
682
|
"""Import a batch of edges."""
|
|
665
683
|
id_mapping = getattr(self, '_id_mapping', {})
|
|
684
|
+
# Detect database backend to use appropriate ID function
|
|
685
|
+
id_function = self._get_id_function()
|
|
666
686
|
|
|
667
687
|
for edge in batch:
|
|
668
688
|
old_from = edge.get('from')
|
|
@@ -681,7 +701,7 @@ cgc import <bundle-file>.cgc
|
|
|
681
701
|
# Create relationship
|
|
682
702
|
query = f"""
|
|
683
703
|
MATCH (a), (b)
|
|
684
|
-
WHERE
|
|
704
|
+
WHERE {id_function}(a) = $from_id AND {id_function}(b) = $to_id
|
|
685
705
|
CREATE (a)-[r:{rel_type}]->(b)
|
|
686
706
|
SET r = $props
|
|
687
707
|
"""
|
|
@@ -689,3 +709,4 @@ cgc import <bundle-file>.cgc
|
|
|
689
709
|
session.run(query, from_id=new_from, to_id=new_to, props=properties)
|
|
690
710
|
|
|
691
711
|
return len(batch)
|
|
712
|
+
|
|
@@ -121,6 +121,11 @@ class DatabaseManager:
|
|
|
121
121
|
return True
|
|
122
122
|
except Exception:
|
|
123
123
|
return False
|
|
124
|
+
|
|
125
|
+
def get_backend_type(self) -> str:
|
|
126
|
+
"""Returns the database backend type."""
|
|
127
|
+
return 'neo4j'
|
|
128
|
+
|
|
124
129
|
|
|
125
130
|
@staticmethod
|
|
126
131
|
def validate_config(uri: str, username: str, password: str) -> Tuple[bool, Optional[str]]:
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/database_falkordb.py
RENAMED
|
@@ -225,6 +225,11 @@ class FalkorDBManager:
|
|
|
225
225
|
return True
|
|
226
226
|
except Exception:
|
|
227
227
|
return False
|
|
228
|
+
|
|
229
|
+
def get_backend_type(self) -> str:
|
|
230
|
+
"""Returns the database backend type."""
|
|
231
|
+
return 'falkordb'
|
|
232
|
+
|
|
228
233
|
|
|
229
234
|
@staticmethod
|
|
230
235
|
def validate_config(db_path: str = None) -> Tuple[bool, Optional[str]]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codegraphcontext
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.35
|
|
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
|
|
@@ -91,7 +91,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
91
91
|

|
|
92
92
|
|
|
93
93
|
## Project Details
|
|
94
|
-
- **Version:** 0.1.
|
|
94
|
+
- **Version:** 0.1.35
|
|
95
95
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
96
96
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
97
97
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/config_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/cli/setup_wizard.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/core/falkor_worker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tool_definitions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/code_finder.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/graph_builder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/c.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/cpp.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/csharp.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/go.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/java.py
RENAMED
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/kotlin.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/php.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/python.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/ruby.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/rust.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/scala.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/languages/swift.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/tools/package_resolver.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext/utils/visualize_graph.py
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/requires.txt
RENAMED
|
File without changes
|
{codegraphcontext-0.1.34 → codegraphcontext-0.1.35}/src/codegraphcontext.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|