codegraphcontext 0.4.13__py3-none-any.whl → 0.4.15__py3-none-any.whl

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.
@@ -234,7 +234,7 @@ def load_config() -> Dict[str, str]:
234
234
  # Load global config
235
235
  if CONFIG_FILE.exists():
236
236
  try:
237
- with open(CONFIG_FILE, "r") as f:
237
+ with open(CONFIG_FILE, "r", encoding="utf-8") as f:
238
238
  for line in f:
239
239
  line = line.strip()
240
240
  if line and not line.startswith("#") and "=" in line:
@@ -247,7 +247,7 @@ def load_config() -> Dict[str, str]:
247
247
  local_env = find_local_env()
248
248
  if local_env and local_env.exists():
249
249
  try:
250
- with open(local_env, "r") as f:
250
+ with open(local_env, "r", encoding="utf-8") as f:
251
251
  for line in f:
252
252
  line = line.strip()
253
253
  if line and not line.startswith("#") and "=" in line:
@@ -321,7 +321,7 @@ def save_config(config: Dict[str, str], preserve_db_credentials: bool = True):
321
321
  if preserve_db_credentials and CONFIG_FILE.exists():
322
322
  # Load existing credentials from file to preserve them
323
323
  try:
324
- with open(CONFIG_FILE, "r") as f:
324
+ with open(CONFIG_FILE, "r", encoding="utf-8") as f:
325
325
  for line in f:
326
326
  line = line.strip()
327
327
  if line and not line.startswith("#") and "=" in line:
@@ -342,7 +342,7 @@ def save_config(config: Dict[str, str], preserve_db_credentials: bool = True):
342
342
  credentials_to_write[key] = config[key]
343
343
 
344
344
  try:
345
- with open(CONFIG_FILE, "w") as f:
345
+ with open(CONFIG_FILE, "w", encoding="utf-8") as f:
346
346
  f.write("# CodeGraphContext Configuration\n")
347
347
  f.write(f"# Location: {CONFIG_FILE}\n\n")
348
348
 
@@ -696,7 +696,7 @@ def load_context_config() -> ContextConfig:
696
696
  return cfg
697
697
 
698
698
  try:
699
- with open(CONTEXT_CONFIG_FILE, "r") as f:
699
+ with open(CONTEXT_CONFIG_FILE, "r", encoding="utf-8") as f:
700
700
  raw = yaml.safe_load(f) or {}
701
701
 
702
702
  contexts: Dict[str, ContextInfo] = {}
@@ -746,7 +746,7 @@ def save_context_config(cfg: ContextConfig) -> None:
746
746
  }
747
747
 
748
748
  try:
749
- with open(CONTEXT_CONFIG_FILE, "w") as f:
749
+ with open(CONTEXT_CONFIG_FILE, "w", encoding="utf-8") as f:
750
750
  yaml.dump(raw, f, default_flow_style=False, sort_keys=False)
751
751
  except Exception as e:
752
752
  console.print(f"[red]Error saving config.yaml: {e}[/red]")
@@ -838,7 +838,7 @@ def resolve_context(
838
838
  local_db = "falkordb"
839
839
  if local_yaml.exists():
840
840
  try:
841
- with open(local_yaml) as f:
841
+ with open(local_yaml, encoding="utf-8") as f:
842
842
  local_raw = yaml.safe_load(f) or {}
843
843
  local_db = local_raw.get("database", "falkordb")
844
844
  except Exception:
@@ -1053,7 +1053,7 @@ def discover_child_contexts(
1053
1053
  local_yaml = candidate / "config.yaml"
1054
1054
  if local_yaml.exists():
1055
1055
  try:
1056
- with open(local_yaml) as f:
1056
+ with open(local_yaml, encoding="utf-8") as f:
1057
1057
  raw = yaml.safe_load(f) or {}
1058
1058
  local_db = raw.get("database", "falkordb")
1059
1059
  except Exception:
@@ -1082,7 +1082,7 @@ def _load_workspace_mappings() -> Dict[str, Dict[str, str]]:
1082
1082
  if not CONTEXT_CONFIG_FILE.exists():
1083
1083
  return {}
1084
1084
  try:
1085
- with open(CONTEXT_CONFIG_FILE, "r") as f:
1085
+ with open(CONTEXT_CONFIG_FILE, "r", encoding="utf-8") as f:
1086
1086
  raw = yaml.safe_load(f) or {}
1087
1087
  return raw.get("workspace_mappings", {}) or {}
1088
1088
  except Exception:
@@ -1096,13 +1096,13 @@ def _save_workspace_mappings(mappings: Dict[str, Dict[str, str]]) -> None:
1096
1096
  raw: Dict[str, Any] = {}
1097
1097
  if CONTEXT_CONFIG_FILE.exists():
1098
1098
  try:
1099
- with open(CONTEXT_CONFIG_FILE, "r") as f:
1099
+ with open(CONTEXT_CONFIG_FILE, "r", encoding="utf-8") as f:
1100
1100
  raw = yaml.safe_load(f) or {}
1101
1101
  except Exception:
1102
1102
  raw = {}
1103
1103
  raw["workspace_mappings"] = mappings
1104
1104
  try:
1105
- with open(CONTEXT_CONFIG_FILE, "w") as f:
1105
+ with open(CONTEXT_CONFIG_FILE, "w", encoding="utf-8") as f:
1106
1106
  yaml.dump(raw, f, default_flow_style=False, sort_keys=False)
1107
1107
  except Exception as e:
1108
1108
  console.print(f"[red]Error saving workspace mappings: {e}[/red]")
@@ -1124,7 +1124,7 @@ def save_workspace_mapping(cwd: Path, context_path: Path) -> None:
1124
1124
  local_yaml = context_path / "config.yaml"
1125
1125
  if local_yaml.exists():
1126
1126
  try:
1127
- with open(local_yaml) as f:
1127
+ with open(local_yaml, encoding="utf-8") as f:
1128
1128
  raw = yaml.safe_load(f) or {}
1129
1129
  local_db = raw.get("database", "falkordb")
1130
1130
  except Exception:
@@ -22,7 +22,6 @@ from pathlib import Path
22
22
  from importlib.metadata import version as pkg_version, PackageNotFoundError
23
23
 
24
24
  from codegraphcontext.server import MCPServer
25
- from codegraphcontext.core.database import DatabaseManager
26
25
  from .setup_wizard import run_neo4j_setup_wizard, configure_mcp_client
27
26
  from . import config_manager
28
27
  # Import the new helper functions
@@ -108,7 +107,7 @@ def mcp_setup():
108
107
  Configure MCP Client (IDE/CLI Integration).
109
108
 
110
109
  Sets up CodeGraphContext integration with your IDE or CLI tool:
111
- - VS Code, Cursor, Windsurf
110
+ - VS Code, Cursor, Windsurf, Zed
112
111
  - Claude Desktop, Gemini CLI
113
112
  - Cline, RooCode, Amazon Q Developer, Goose
114
113
  - OpenCode (prints stdio config + link to vendor docs)
@@ -125,7 +124,7 @@ def mcp_start():
125
124
  Start the CodeGraphContext MCP server.
126
125
 
127
126
  Starts the server which listens for JSON-RPC requests from stdin.
128
- This is used by IDE integrations (VS Code, Cursor, etc.).
127
+ This is used by IDE integrations (VS Code, Cursor, Zed, etc.).
129
128
  """
130
129
  console.print("[bold green]Starting CodeGraphContext Server...[/bold green]")
131
130
  _load_credentials()
@@ -979,6 +978,7 @@ def doctor():
979
978
  password = os.environ.get("NEO4J_PASSWORD")
980
979
  database_name = os.environ.get("NEO4J_DATABASE")
981
980
 
981
+ from codegraphcontext.core.database import DatabaseManager
982
982
  missing = DatabaseManager.get_missing_credentials(uri, username, password)
983
983
  console.print(f" [cyan]Credential check:[/cyan] {'OK' if not missing else 'Missing ' + ', '.join(missing)}")
984
984
  if missing:
@@ -177,6 +177,8 @@ def download_bundle(name: str, output_dir: Optional[str] = None, auto_load: bool
177
177
  and base names (e.g., 'python-bitcoin-utils' - picks most recent version).
178
178
  """
179
179
  console.print(f"[cyan]Looking for bundle '{name}'...[/cyan]")
180
+
181
+ lookup_name = name[:-4] if name.lower().endswith('.cgc') else name
180
182
 
181
183
  bundles = fetch_available_bundles()
182
184
 
@@ -187,7 +189,7 @@ def download_bundle(name: str, output_dir: Optional[str] = None, auto_load: bool
187
189
  # Strategy 1: Try exact match on full_name (with version)
188
190
  bundle = None
189
191
  for b in bundles:
190
- if b.get('full_name', '').lower() == name.lower():
192
+ if b.get('full_name', '').lower() == lookup_name.lower():
191
193
  bundle = b
192
194
  console.print(f"[dim]Found exact match: {b.get('full_name')}[/dim]")
193
195
  break
@@ -197,7 +199,7 @@ def download_bundle(name: str, output_dir: Optional[str] = None, auto_load: bool
197
199
  if not bundle:
198
200
  matching_bundles = []
199
201
  for b in bundles:
200
- if b.get('name', '').lower() == name.lower():
202
+ if b.get('name', '').lower() == lookup_name.lower():
201
203
  matching_bundles.append(b)
202
204
 
203
205
  if matching_bundles:
@@ -220,7 +222,7 @@ def download_bundle(name: str, output_dir: Optional[str] = None, auto_load: bool
220
222
  if not bundle:
221
223
  # Find bundles with similar base names
222
224
  suggestions = []
223
- name_lower = name.lower()
225
+ name_lower = lookup_name.lower()
224
226
  for b in bundles:
225
227
  base_name = b.get('name', '').lower()
226
228
  full_name = b.get('full_name', '').lower()
@@ -256,7 +256,7 @@ def _configure_ide(mcp_config):
256
256
  questions = [
257
257
  {
258
258
  "type": "confirm",
259
- "message": "Automatically configure your IDE/CLI (VS Code, Cursor, Windsurf, Claude, Gemini, Cline, RooCode, ChatGPT Codex, Amazon Q Developer, Aider, Kiro, Goose, Antigravity, OpenCode)?",
259
+ "message": "Automatically configure your IDE/CLI (VS Code, Cursor, Windsurf, Zed, Claude, Gemini, Cline, RooCode, ChatGPT Codex, Amazon Q Developer, Aider, Kiro, Goose, Antigravity, OpenCode)?",
260
260
  "name": "configure_ide",
261
261
  "default": True,
262
262
  }
@@ -270,7 +270,7 @@ def _configure_ide(mcp_config):
270
270
  {
271
271
  "type": "list",
272
272
  "message": "Choose your IDE/CLI to configure:",
273
- "choices": ["VS Code", "Cursor", "Windsurf", "Claude code", "Gemini CLI", "ChatGPT Codex", "Cline", "RooCode", "Amazon Q Developer", "JetBrainsAI", "Aider", "Kiro", "Goose", "Antigravity", "OpenCode", "None of the above"],
273
+ "choices": ["VS Code", "Cursor", "Windsurf", "Zed", "Claude code", "Gemini CLI", "ChatGPT Codex", "Cline", "RooCode", "Amazon Q Developer", "JetBrainsAI", "Aider", "Kiro", "Goose", "Antigravity", "OpenCode", "None of the above"],
274
274
  "name": "ide_choice",
275
275
  }
276
276
  ]
@@ -289,7 +289,7 @@ def _configure_ide(mcp_config):
289
289
  )
290
290
  return
291
291
 
292
- if ide_choice in ["VS Code", "Cursor", "Windsurf", "Claude code", "Gemini CLI", "ChatGPT Codex", "Cline", "RooCode", "Amazon Q Developer", "JetBrainsAI", "Aider", "Kiro", "Goose", "Antigravity"]:
292
+ if ide_choice in ["VS Code", "Cursor", "Windsurf", "Zed", "Claude code", "Gemini CLI", "ChatGPT Codex", "Cline", "RooCode", "Amazon Q Developer", "JetBrainsAI", "Aider", "Kiro", "Goose", "Antigravity"]:
293
293
  console.print(f"\n[bold cyan]Configuring for {ide_choice}...[/bold cyan]")
294
294
 
295
295
  if ide_choice == "Amazon Q Developer":
@@ -320,6 +320,10 @@ def _configure_ide(mcp_config):
320
320
  Path.home() / "AppData" / "Roaming" / "windsurf" / "settings.json",
321
321
  Path.home() / ".config" / "Windsurf" / "User" / "settings.json",
322
322
  ],
323
+ "Zed": [
324
+ Path.home() / ".config" / "zed" / "settings.json",
325
+ Path.home() / "AppData" / "Roaming" / "Zed" / "settings.json"
326
+ ],
323
327
  "Claude code": [
324
328
  Path.home() / ".claude.json"
325
329
  ],
@@ -398,10 +402,14 @@ def _configure_ide(mcp_config):
398
402
  console.print(f"[red]Error: Configuration file at {target_path} is not a valid JSON object.[/red]")
399
403
  return
400
404
 
401
- if "mcpServers" not in settings:
402
- settings["mcpServers"] = {}
403
-
404
- settings["mcpServers"].update(mcp_config["mcpServers"])
405
+ if ide_choice == "Zed":
406
+ if "context_servers" not in settings:
407
+ settings["context_servers"] = {}
408
+ settings["context_servers"].update(mcp_config["mcpServers"])
409
+ else:
410
+ if "mcpServers" not in settings:
411
+ settings["mcpServers"] = {}
412
+ settings["mcpServers"].update(mcp_config["mcpServers"])
405
413
 
406
414
  try:
407
415
  with open(target_path, "w") as f:
@@ -677,6 +685,7 @@ def setup_existing_db():
677
685
 
678
686
  # Validate the user input
679
687
  console.print("\n[cyan]🔍 Validating configuration...[/cyan]")
688
+ from codegraphcontext.core.database import DatabaseManager
680
689
  is_valid, validation_error = DatabaseManager.validate_config(
681
690
  manual_creds.get("uri", ""),
682
691
  manual_creds.get("username", ""),
@@ -795,6 +804,7 @@ def setup_hosted_db():
795
804
 
796
805
  # Validate the user input
797
806
  console.print("\n[cyan]🔍 Validating configuration...[/cyan]")
807
+ from codegraphcontext.core.database import DatabaseManager
798
808
  is_valid, validation_error = DatabaseManager.validate_config(
799
809
  manual_creds.get("uri", ""),
800
810
  manual_creds.get("username", ""),
@@ -913,6 +923,7 @@ volumes:
913
923
 
914
924
  # Validate configuration format before attempting Docker operations
915
925
  console.print("\n[cyan]🔍 Validating configuration...[/cyan]")
926
+ from codegraphcontext.core.database import DatabaseManager
916
927
  is_valid, validation_error = DatabaseManager.validate_config(
917
928
  DEFAULT_NEO4J_URI,
918
929
  DEFAULT_NEO4J_USERNAME,
@@ -972,6 +983,7 @@ volumes:
972
983
 
973
984
  # updated test_connection method
974
985
  console.print(f"[yellow]Testing connection... (attempt {attempt + 1}/{max_attempts})[/yellow]")
986
+ from codegraphcontext.core.database import DatabaseManager
975
987
  is_connected, error_msg = DatabaseManager.test_connection(DEFAULT_NEO4J_URI, DEFAULT_NEO4J_USERNAME, password)
976
988
 
977
989
  if is_connected:
@@ -101,6 +101,12 @@ def get_database_manager(db_path: Optional[str] = None) -> Union['DatabaseManage
101
101
  from .database_falkordb import FalkorDBManager, FalkorDBUnavailableError
102
102
  try:
103
103
  mgr = FalkorDBManager(db_path=db_path)
104
+ # Eagerly probe the connection so any FalkorDBUnavailableError
105
+ # (e.g. redis-py/falkordblite version mismatch — issue #1035)
106
+ # surfaces *here*, while we can still fall back to KùzuDB.
107
+ # ``get_driver`` is idempotent (singleton-guarded), so the
108
+ # subsequent real call from server.py costs nothing.
109
+ mgr.get_driver()
104
110
  info_logger(f"Using FalkorDB Lite (explicit) at {db_path or 'default path'}")
105
111
  return mgr
106
112
  except FalkorDBUnavailableError as falkor_err:
@@ -153,6 +159,9 @@ def get_database_manager(db_path: Optional[str] = None) -> Union['DatabaseManage
153
159
  from .database_falkordb import FalkorDBManager, FalkorDBUnavailableError
154
160
  try:
155
161
  mgr = FalkorDBManager(db_path=db_path)
162
+ # Eagerly probe so dep/version failures (issue #1035) surface here
163
+ # while we can still fall through to KùzuDB below.
164
+ mgr.get_driver()
156
165
  info_logger(f"Using FalkorDB Lite (default) at {db_path or 'default path'}")
157
166
  return mgr
158
167
  except FalkorDBUnavailableError as falkor_err:
@@ -196,6 +205,25 @@ def get_database_manager(db_path: Optional[str] = None) -> Union['DatabaseManage
196
205
 
197
206
  raise ValueError(error_msg)
198
207
 
208
+ # Lazy backward-compatibility exports — avoids crashing when optional
209
+ # database drivers (neo4j, falkordb, real_ladybug, …) are not installed.
210
+ # Uses PEP 562 module-level __getattr__ so that:
211
+ # from codegraphcontext.core import DatabaseManager
212
+ # still works, but only triggers the real import when actually accessed.
213
+ _LAZY_IMPORTS = {
214
+ 'DatabaseManager': '.database',
215
+ 'FalkorDBManager': '.database_falkordb',
216
+ 'FalkorDBRemoteManager': '.database_falkordb_remote',
217
+ 'KuzuDBManager': '.database_kuzu',
218
+ 'NornicDBManager': '.database_nornic',
219
+ }
220
+
221
+ def __getattr__(name: str):
222
+ if name in _LAZY_IMPORTS:
223
+ import importlib
224
+ module = importlib.import_module(_LAZY_IMPORTS[name], __package__)
225
+ return getattr(module, name)
226
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
199
227
  # For backward compatibility, export managers
200
228
  from .database import DatabaseManager
201
229
  from .database_falkordb import FalkorDBManager
@@ -139,7 +139,7 @@ class CGCBundle:
139
139
  from importlib.metadata import version as get_version
140
140
  py_version = get_version("codegraphcontext")
141
141
  except Exception:
142
- py_version = "0.4.13"
142
+ py_version = "0.4.15"
143
143
 
144
144
  metadata["format_version"] = "1.0.0"
145
145
  metadata["generator"] = f"PYv{py_version}"
@@ -23,17 +23,51 @@ from typing import Optional, Tuple
23
23
  from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger
24
24
 
25
25
  # ---------------------------------------------------------------------------
26
- # Compatibility patch: redis-py >= 5.x added OpenTelemetry error telemetry that
27
- # accesses conn.port inside its error handler. UnixDomainSocketConnection never
28
- # had a 'port' attribute, so any exception raised during a Unix-socket connection
29
- # (e.g. the sentinel-detection INFO call inside FalkorDB.__init__) would produce
30
- # a secondary AttributeError masking the real problem.
31
- # Patching the class at import time costs nothing and fixes all call-sites.
26
+ # Compatibility patch: newer redis-py releases assume every Connection exposes
27
+ # ``host`` and ``port`` attributes, but ``UnixDomainSocketConnection`` historically
28
+ # has neither. Two failure modes have been observed in the wild:
29
+ #
30
+ # 1. redis-py >= 5.x added OpenTelemetry error telemetry that reads ``conn.port``
31
+ # inside its error handler. The missing attribute raised a secondary
32
+ # ``AttributeError`` that masked the real connection error.
33
+ # 2. redis-py >= 6.x added a maintenance-notifications handshake
34
+ # (``activate_maint_notifications_handling_if_enabled`` →
35
+ # ``_enable_maintenance_notifications``) that raises ``ValueError`` on any
36
+ # connection without a ``host`` attribute — breaking FalkorDB Lite's
37
+ # Unix-socket connection entirely (upstream issue #1035).
38
+ #
39
+ # Patching the class at import time is cheap and fixes every call-site. The
40
+ # values themselves are inert sentinels: FalkorDB Lite never uses TCP, so no
41
+ # code path will dereference them as a real ``(host, port)`` pair.
32
42
  # ---------------------------------------------------------------------------
33
43
  try:
34
44
  from redis.connection import UnixDomainSocketConnection as _UDSC
45
+
46
+ # ``port`` was never an attribute on UDSC; if it is missing, install a sentinel.
35
47
  if not hasattr(_UDSC, 'port'):
36
48
  _UDSC.port = 0 # type: ignore[attr-defined]
49
+
50
+ # ``host`` is trickier. On redis-py >= 6 ``UDSC`` inherits an *abstract*
51
+ # ``host`` property (from ``MaintNotificationsAbstractConnection``) whose
52
+ # default body just returns ``None``. The maintenance-notifications
53
+ # handshake then does ``getattr(self, "host", None)``; because the property
54
+ # *exists* on the class, ``getattr`` returns ``None`` instead of falling
55
+ # through to its default — and the handshake raises ValueError.
56
+ #
57
+ # ``hasattr(_UDSC, 'host')`` is therefore the wrong check: we must inspect
58
+ # an instance. We probe a bare instance (``object.__new__`` skips
59
+ # ``__init__``, so we don't need a path) and override the class attribute
60
+ # with an inert string whenever the inherited property would yield ``None``.
61
+ try:
62
+ _probe = object.__new__(_UDSC)
63
+ if getattr(_probe, 'host', None) is None:
64
+ _UDSC.host = 'localhost' # type: ignore[attr-defined]
65
+ del _probe
66
+ except Exception:
67
+ # Probing failed for an unrelated reason; do the safe thing and
68
+ # install the sentinel anyway. Worst case we shadow a working property
69
+ # with a constant, which is still preferable to a crash.
70
+ _UDSC.host = 'localhost' # type: ignore[attr-defined]
37
71
  except Exception:
38
72
  pass # redis not installed or class structure changed — safe to ignore
39
73
 
@@ -149,8 +183,19 @@ class FalkorDBManager:
149
183
  from falkordb import FalkorDB
150
184
 
151
185
  info_logger(f"Connecting to FalkorDB Lite at {self.socket_path}")
152
- self._driver = FalkorDB(unix_socket_path=self.socket_path)
153
- self._graph = self._driver.select_graph(self.graph_name)
186
+ try:
187
+ self._driver = FalkorDB(unix_socket_path=self.socket_path)
188
+ self._graph = self._driver.select_graph(self.graph_name)
189
+ except ValueError as ve:
190
+ # redis-py >= 6 raises ValueError on Unix-socket connections that
191
+ # lack a 'host' attribute (see upstream issue #1035). Even with the
192
+ # import-time shim above, newer redis-py revisions may shift the
193
+ # check. Convert to FalkorDBUnavailableError so the caller can fall
194
+ # back to KùzuDB instead of crashing the whole MCP server.
195
+ raise FalkorDBUnavailableError(
196
+ f"FalkorDB Lite client refused the Unix-socket connection: {ve}. "
197
+ "This typically indicates a redis-py / falkordblite version mismatch."
198
+ ) from ve
154
199
 
155
200
  # Test the connection
156
201
  try:
@@ -167,6 +212,10 @@ class FalkorDBManager:
167
212
  " pip install falkordblite"
168
213
  )
169
214
  raise ValueError("FalkorDB client missing.") from e
215
+ except FalkorDBUnavailableError:
216
+ # Propagate as-is so get_database_manager() can trigger the
217
+ # documented KùzuDB fallback.
218
+ raise
170
219
  except Exception as e:
171
220
  error_logger(f"Failed to initialize FalkorDB: {e}")
172
221
  raise
@@ -195,6 +244,13 @@ class FalkorDBManager:
195
244
  test_graph.query("RETURN 1")
196
245
  info_logger("Connected to existing (functional) FalkorDB Lite process.")
197
246
  return
247
+ except ValueError as ve:
248
+ # redis-py >= 6 maintenance-notifications handshake (issue #1035) — this
249
+ # backend cannot work in the current environment regardless of socket state.
250
+ raise FalkorDBUnavailableError(
251
+ f"FalkorDB Lite client refused the Unix-socket connection: {ve}. "
252
+ "This typically indicates a redis-py / falkordblite version mismatch."
253
+ ) from ve
198
254
  except Exception as e:
199
255
  # Stale socket, unresponsive, or "brainless" (unknown command GRAPH.QUERY)
200
256
  info_logger(f"Existing FalkorDB process at {self.socket_path} is stale or non-functional: {e}")
@@ -247,6 +303,13 @@ class FalkorDBManager:
247
303
  test_graph = d.select_graph('__cgc_health_check')
248
304
  test_graph.query("RETURN 1")
249
305
  return
306
+ except ValueError as ve:
307
+ # redis-py version mismatch — no point retrying, the handshake
308
+ # will keep failing the same way until the user fixes deps.
309
+ raise FalkorDBUnavailableError(
310
+ f"FalkorDB Lite client refused the Unix-socket connection: {ve}. "
311
+ "This typically indicates a redis-py / falkordblite version mismatch."
312
+ ) from ve
250
313
  except Exception as e:
251
314
  last_error = e
252
315
 
@@ -265,7 +328,11 @@ class FalkorDBManager:
265
328
 
266
329
  time.sleep(0.5)
267
330
 
268
- raise RuntimeError(f"Timed out waiting for FalkorDB Lite to start. Last error: {last_error}")
331
+ # Timeout is also a "backend not usable here" signal raise the typed
332
+ # exception so the documented KùzuDB fallback fires instead of crashing.
333
+ raise FalkorDBUnavailableError(
334
+ f"Timed out waiting for FalkorDB Lite to start. Last error: {last_error}"
335
+ )
269
336
 
270
337
  def close_driver(self):
271
338
  """Closes the connection."""
@@ -743,13 +743,16 @@ class KuzuSessionWrapper:
743
743
  )
744
744
  if row_ref:
745
745
  val = item.get(row_ref.group(1))
746
- if val is not None:
746
+ # Consider -1 as missing for line numbers to force fallback,
747
+ # ensuring uniqueness when the primary key is incomplete
748
+ if val is not None and not (part in ("line_number", "function_line_number", "end_line") and val == -1):
747
749
  uid_components.append(str(val))
748
750
  else:
749
751
  # Missing values are common in parser output for some
750
752
  # languages. Use a deterministic placeholder component
751
753
  # to keep UID generation stable and unique enough.
752
- uid_components.append(f"__missing_{part}")
754
+ row_hash = hashlib.md5(str(sorted([(k, v) for k, v in item.items() if k != 'uid'])).encode()).hexdigest()[:8]
755
+ uid_components.append(f"__fallback_{row_hash}")
753
756
  elif param_ref:
754
757
  val = parameters.get(param_ref.group(1))
755
758
  if val is not None:
@@ -351,8 +351,18 @@ class MCPServer:
351
351
 
352
352
  def generate_report_tool(self, **args) -> Dict[str, Any]:
353
353
  from .tools.report_generator import generate_report
354
+
354
355
  output_path_raw = args.get("output_path")
355
356
  output_path = Path(output_path_raw) if output_path_raw else self.cwd / "CGC_REPORT.md"
357
+
358
+ base_dir = self.cwd.resolve()
359
+ output_path = output_path.resolve()
360
+
361
+ try:
362
+ output_path.relative_to(base_dir)
363
+ except ValueError:
364
+ return {"error": "Invalid output_path: path traversal is not allowed"}
365
+
356
366
  try:
357
367
  report = generate_report(
358
368
  self.db_manager,
@@ -361,7 +371,7 @@ class MCPServer:
361
371
  god_node_limit=int(args.get("god_node_limit", 15)),
362
372
  complexity_limit=int(args.get("complexity_limit", 15)),
363
373
  cross_module_limit=int(args.get("cross_module_limit", 20)),
364
- )
374
+ )
365
375
  return {"status": "ok", "output_path": str(output_path), "report": report}
366
376
  except Exception as exc:
367
377
  return {"error": str(exc)}
@@ -1,8 +1,9 @@
1
+ from __future__ import annotations
1
2
  # src/codegraphcontext/tools/advanced_language_query_tool.py
2
3
  import re
3
4
  import logging
4
-
5
- # importing all the language toolkits
5
+ from typing import TYPE_CHECKING
6
+ #importing all the language toolkits
6
7
  from ..tools.query_tool_languages.c_toolkit import CToolkit
7
8
  from ..tools.query_tool_languages.cpp_toolkit import CppToolkit
8
9
  from ..tools.query_tool_languages.go_toolkit import GoToolkit
@@ -17,7 +18,8 @@ from ..tools.query_tool_languages.dart_toolkit import DartToolkit
17
18
  from ..tools.query_tool_languages.elisp_toolkit import ElispToolkit
18
19
  from ..tools.query_tool_languages.perl_toolkit import PerlToolkit
19
20
 
20
- from ..core.database import DatabaseManager
21
+ if TYPE_CHECKING:
22
+ from ..core.database import DatabaseManager
21
23
  from ..utils.debug_log import debug_log
22
24
 
23
25
  logger = logging.getLogger(__name__)
@@ -1,11 +1,13 @@
1
1
  # src/codegraphcontext/tools/code_finder.py
2
+ from __future__ import annotations
2
3
  import logging
3
4
  from collections import Counter
4
5
 
5
- from typing import Any, Dict, List, Literal, Optional
6
+ from typing import Any, Dict, List, Literal, Optional, TYPE_CHECKING
6
7
  from pathlib import Path
7
8
 
8
- from ..core.database import DatabaseManager
9
+ if TYPE_CHECKING:
10
+ from ..core.database import DatabaseManager
9
11
  from ..utils.path_ignore import cypher_path_not_under_ignore_dirs
10
12
 
11
13
  logger = logging.getLogger(__name__)
@@ -2,14 +2,16 @@
2
2
 
3
3
  # src/codegraphcontext/tools/graph_builder.py
4
4
  """Facade for graph indexing; implementation lives in indexing/."""
5
+ from __future__ import annotations
5
6
 
6
7
  import asyncio
7
8
  from datetime import datetime
8
9
  from pathlib import Path
9
- from typing import Any, Dict, Optional, Tuple
10
+ from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING
10
11
 
11
12
  from ..cli.config_manager import get_config_value
12
- from ..core.database import DatabaseManager
13
+ if TYPE_CHECKING:
14
+ from ..core.database import DatabaseManager
13
15
  from ..core.jobs import JobManager, JobStatus
14
16
  from ..utils.debug_log import debug_log, error_logger, info_logger, warning_logger
15
17
  from .indexing.constants import DEFAULT_IGNORE_PATTERNS
@@ -43,6 +45,8 @@ class GraphBuilder:
43
45
  ".cjs": "javascript",
44
46
  ".go": "go",
45
47
  ".ts": "typescript",
48
+ ".mts": "typescript",
49
+ ".cts": "typescript",
46
50
  ".d.ts": "typescript",
47
51
  ".tsx": "tsx",
48
52
  ".cpp": "cpp",
@@ -1311,14 +1311,25 @@ class GraphWriter:
1311
1311
  info_logger(f"[SPRING_DATA] Written {written} READS/WRITES derived-query edges")
1312
1312
 
1313
1313
  def delete_repository_from_graph(self, repo_path: str) -> bool:
1314
- repo_path_str = repo_path
1314
+ # Normalize path separators for cross-platform compatibility (Windows uses \)
1315
+ repo_path_str = repo_path.replace("\\", "/")
1315
1316
  path_prefix = repo_path_str + "/"
1316
1317
  with self.driver.session() as session:
1318
+ # Try normalized path first
1317
1319
  result = session.run(
1318
1320
  "MATCH (r:Repository {path: $path}) RETURN count(r) as cnt", path=repo_path_str
1319
1321
  ).single()
1320
1322
  if not result or result["cnt"] == 0:
1321
- warning_logger(f"Attempted to delete non-existent repository: {repo_path_str}")
1323
+ # Fallback: try original path (Windows backslash)
1324
+ result = session.run(
1325
+ "MATCH (r:Repository {path: $path}) RETURN count(r) as cnt", path=repo_path
1326
+ ).single()
1327
+ # If found via original path, use original path for all subsequent operations
1328
+ if result and result["cnt"] > 0:
1329
+ repo_path_str = repo_path
1330
+ path_prefix = repo_path + "\\"
1331
+ if not result or result["cnt"] == 0:
1332
+ warning_logger(f"Attempted to delete non-existent repository: {repo_path}")
1322
1333
  return False
1323
1334
 
1324
1335
  for rel_type in ("CALLS", "INHERITS", "IMPORTS"):
@@ -1349,8 +1360,23 @@ class GraphWriter:
1349
1360
  break
1350
1361
  info_logger(f"[DELETE] Removed {deleted} CONTAINS rels for {repo_path_str}")
1351
1362
 
1352
- for label in ("Function", "Class", "Interface", "Trait", "Struct", "Enum", "Variable", "Macro", "Union", "Record", "Property", "File", "Module", "Mixin", "Extension", "Object", "Parameter", "Directory", "Repository", "ExternalClass", "DbTable"):
1363
+ # Discover the labels currently in use rather than hardcoding the
1364
+ # list. Every time the indexer learned a new node type (Variable,
1365
+ # Parameter, Directory, ExternalClass, DbTable, ...) the hardcoded
1366
+ # tuple here had to be kept in lockstep, and every miss leaked
1367
+ # orphan nodes on `delete_repository`. `CALL db.labels()` returns
1368
+ # exactly the set of labels that have at least one node in the
1369
+ # current database -- per-label DETACH DELETE with the same path
1370
+ # prefix is then label-agnostic and self-maintaining.
1371
+ #
1372
+ # Labels with no node matching the path prefix are cheap: the
1373
+ # label-scoped scan returns 0 rows, the while-True loop exits
1374
+ # immediately, and we move on.
1375
+ with self.driver.session() as session:
1376
+ label_records = session.run("CALL db.labels() YIELD label RETURN label")
1377
+ all_labels = sorted({record["label"] for record in label_records})
1353
1378
 
1379
+ for label in all_labels:
1354
1380
  while True:
1355
1381
  with self.driver.session() as session:
1356
1382
  result = session.run(
@@ -54,6 +54,8 @@ def _register_prescans() -> Dict[str, _PreScanFn]:
54
54
  ".cjs": make_js(".cjs"),
55
55
  ".go": lambda files, gp: go_lang_module.pre_scan_go(files, gp(".go")),
56
56
  ".ts": lambda files, gp: ts_lang_module.pre_scan_typescript(files, gp(".ts")),
57
+ ".mts": lambda files, gp: ts_lang_module.pre_scan_typescript(files, gp(".mts")),
58
+ ".cts": lambda files, gp: ts_lang_module.pre_scan_typescript(files, gp(".cts")),
57
59
  ".d.ts": lambda files, gp: ts_lang_module.pre_scan_typescript(files, gp(".d.ts")),
58
60
  ".tsx": lambda files, gp: tsx_lang_module.pre_scan_typescript(files, gp(".tsx")),
59
61
  ".cpp": lambda files, gp: cpp_lang_module.pre_scan_cpp(files, gp(".cpp")),
@@ -77,7 +77,7 @@ async def run_scip_index_async(
77
77
  index_root = path.resolve() if path.is_dir() else path.parent.resolve()
78
78
  for abs_path_str, file_data in files_data.items():
79
79
  file_path = Path(abs_path_str)
80
- if file_path.is_file() and file_path_has_ignore_dir_segment(file_path, index_root):
80
+ if file_path_has_ignore_dir_segment(file_path, index_root):
81
81
  continue
82
82
  file_data["repo_path"] = str(index_root)
83
83
  if job_id:
@@ -28,7 +28,7 @@ Supported SCIP indexers and their install commands:
28
28
  rust → cargo install scip-rust (or rustup component add rust-analyzer)
29
29
  java → https://github.com/sourcegraph/scip-java
30
30
  c / c++ → scip-clang (JSON compilation database: compile_commands.json)
31
- csharp → scip-dotnet (dotnet tool install -g Microsoft.CodeAnalysis.ScipDotnet)
31
+ csharp → scip-dotnet (dotnet tool install --global scip-dotnet)
32
32
 
33
33
  JavaScript indexing notes:
34
34
  - Pure JS projects (no tsconfig.json): scip-typescript index --infer-tsconfig
@@ -68,9 +68,10 @@ EXTENSION_TO_SCIP: Dict[str, Tuple[str, str, str, str]] = {
68
68
  ".dart": ("dart", "scip_dart", "dart pub global activate scip_dart", "dart:stable"),
69
69
  ".cpp": ("cpp", "scip-clang", "brew install llvm", "sourcegraph/scip-clang:sha-1704d3d"),
70
70
  ".hpp": ("cpp", "scip-clang", "brew install llvm", "sourcegraph/scip-clang:sha-1704d3d"),
71
+ ".hh": ("cpp", "scip-clang", "brew install llvm", "sourcegraph/scip-clang:sha-1704d3d"),
71
72
  ".c": ("c", "scip-clang", "brew install llvm", "sourcegraph/scip-clang:sha-1704d3d"),
72
73
  ".h": ("cpp", "scip-clang", "brew install llvm", "sourcegraph/scip-clang:sha-1704d3d"),
73
- ".cs": ("csharp", "scip-dotnet", "dotnet tool install -g Microsoft.CodeAnalysis.ScipDotnet", "sourcegraph/scip-dotnet"),
74
+ ".cs": ("csharp", "scip-dotnet", "dotnet tool install --global scip-dotnet", "sourcegraph/scip-dotnet"),
74
75
  ".php": ("php", "scip-php", "composer global require davidrjenni/scip-php", "davidrjenni/scip-php"),
75
76
  ".rb": ("ruby", "scip-ruby", "gem install scip-ruby", ""),
76
77
  ".swift": ("swift", "scip-swift", "brew install scip-swift", ""),
@@ -1,12 +1,17 @@
1
1
  # src/codegraphcontext/tools/system.py
2
+ from __future__ import annotations
2
3
  import logging
3
4
  from dataclasses import asdict
4
- from typing import Any, Dict
5
+ from typing import Any, Dict, TYPE_CHECKING
5
6
  from datetime import datetime, timedelta
6
7
 
7
- from neo4j.exceptions import CypherSyntaxError
8
+ try:
9
+ from neo4j.exceptions import CypherSyntaxError
10
+ except ImportError:
11
+ CypherSyntaxError = type('CypherSyntaxError', (Exception,), {})
8
12
 
9
- from ..core.database import DatabaseManager
13
+ if TYPE_CHECKING:
14
+ from ..core.database import DatabaseManager
10
15
  from ..core.jobs import JobManager, JobStatus
11
16
  from ..utils.debug_log import debug_log
12
17
 
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  # src/codegraphcontext/viz/server.py
2
3
  from fastapi import FastAPI, HTTPException, Query, Request
3
4
  from fastapi.staticfiles import StaticFiles
@@ -9,9 +10,10 @@ import uvicorn
9
10
  import json
10
11
  import os
11
12
  import sys
12
- from typing import Optional, List, Dict, Any
13
+ from typing import Optional, List, Dict, Any, TYPE_CHECKING
13
14
 
14
- from ..core.database import DatabaseManager
15
+ if TYPE_CHECKING:
16
+ from ..core.database import DatabaseManager
15
17
  from ..utils.debug_log import debug_log
16
18
 
17
19
  app = FastAPI()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegraphcontext
3
- Version: 0.4.13
3
+ Version: 0.4.15
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
@@ -50,18 +50,33 @@ Requires-Dist: pyyaml
50
50
  Requires-Dist: nbformat
51
51
  Requires-Dist: nbconvert>=7.16.6
52
52
  Requires-Dist: pathspec>=0.12.1
53
- Requires-Dist: falkordb>=0.1.0
53
+ Requires-Dist: redis<6,>=5
54
+ Requires-Dist: falkordb<1.6,>=1.0
55
+ Requires-Dist: falkordblite<0.10,>=0.7; sys_platform != "win32" and python_version >= "3.12"
54
56
  Requires-Dist: requests>=2.28.0
55
57
  Requires-Dist: protobuf<3.21,>=3.20
56
- Requires-Dist: falkordblite>=0.1.0; sys_platform != "win32" and python_version >= "3.12"
57
58
  Requires-Dist: kuzu; sys_platform == "win32" or (sys_platform != "win32" and python_version >= "3.10")
58
59
  Requires-Dist: ladybug; sys_platform == "win32" or (sys_platform != "win32" and python_version >= "3.10")
60
+ Requires-Dist: mcp>=1.0.0
59
61
  Requires-Dist: fastapi>=0.100.0
60
62
  Requires-Dist: uvicorn>=0.22.0
61
63
  Provides-Extra: parsing
62
64
  Requires-Dist: tree-sitter<0.26.0,>=0.21.0; python_version != "3.13" and extra == "parsing"
63
65
  Requires-Dist: tree-sitter-language-pack<1.0.0,>=0.6.0; python_version != "3.13" and extra == "parsing"
64
66
  Requires-Dist: tree-sitter-c-sharp>=0.21.0; python_version != "3.13" and extra == "parsing"
67
+ Provides-Extra: falkordb-embedded
68
+ Requires-Dist: falkordblite<0.10,>=0.7; (sys_platform != "win32" and python_version >= "3.12") and extra == "falkordb-embedded"
69
+ Requires-Dist: falkordb<1.6,>=1.0; extra == "falkordb-embedded"
70
+ Requires-Dist: redis<6,>=5; extra == "falkordb-embedded"
71
+ Provides-Extra: falkordb-remote
72
+ Requires-Dist: falkordb<1.6,>=1.0; extra == "falkordb-remote"
73
+ Requires-Dist: redis<6,>=5; extra == "falkordb-remote"
74
+ Provides-Extra: kuzu
75
+ Requires-Dist: kuzu; (sys_platform == "win32" or (sys_platform != "win32" and python_version >= "3.10")) and extra == "kuzu"
76
+ Provides-Extra: ladybug
77
+ Requires-Dist: ladybug; (sys_platform == "win32" or (sys_platform != "win32" and python_version >= "3.10")) and extra == "ladybug"
78
+ Provides-Extra: neo4j
79
+ Requires-Dist: neo4j>=5.15.0; extra == "neo4j"
65
80
  Provides-Extra: dev
66
81
  Requires-Dist: pytest>=7.4.0; extra == "dev"
67
82
  Requires-Dist: black>=23.11.0; extra == "dev"
@@ -74,11 +89,11 @@ Dynamic: license-file
74
89
 
75
90
  🌐 **Languages:**
76
91
  - 🇬🇧 [English](README.md)
77
- - 🇨🇳 [中文](README.zh-CN.md)
78
- - 🇰🇷 [한국어](README.kor.md)
79
- - 🇺🇦 [Українська](README.uk.md)
80
- - 🇷🇺 [Русский](README.ru-RU.md)
81
- - 🇯🇵 [日本語](README.ja.md)
92
+ - 🇨🇳 [中文](docs/translations/README.zh-CN.md)
93
+ - 🇰🇷 [한국어](docs/translations/README.kor.md)
94
+ - 🇺🇦 [Українська](docs/translations/README.uk.md)
95
+ - 🇷🇺 [Русский](docs/translations/README.ru-RU.md)
96
+ - 🇯🇵 [日本語](docs/translations/README.ja.md)
82
97
  - 🇪🇸 Español (Soon)
83
98
 
84
99
  🌍 **Help translate CodeGraphContext to your language by raising an issue & PR on https://github.com/Shashankss1205/CodeGraphContext/issues!**
@@ -168,7 +183,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
168
183
  ---
169
184
 
170
185
  ## Project Details
171
- - **Version:** 0.4.13
186
+ - **Version:** 0.4.15
172
187
  - **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
173
188
  - **License:** MIT License (See [LICENSE](LICENSE) for details)
174
189
  - **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
@@ -375,6 +390,7 @@ codegraphcontext find pattern "Auth" --viz
375
390
  * VS Code
376
391
  * Cursor
377
392
  * Windsurf
393
+ * Zed
378
394
  * Claude
379
395
  * Gemini CLI
380
396
  * ChatGPT Codex
@@ -382,6 +398,8 @@ codegraphcontext find pattern "Auth" --viz
382
398
  * RooCode
383
399
  * Amazon Q Developer
384
400
  * Kiro
401
+ * Goose
402
+ * OpenCode
385
403
 
386
404
  Upon successful configuration, `codegraphcontext mcp setup` will generate and place the necessary configuration files:
387
405
  * It creates an `mcp.json` file in your current directory for reference.
@@ -444,6 +462,10 @@ Add the following server configuration to your client's settings file (e.g., VS
444
462
  }
445
463
  ```
446
464
 
465
+ #### OpenCode Configuration
466
+
467
+ For instructions on installing and configuring MCP servers with OpenCode, see the [OpenCode MCP Guide](https://opencode.ai/docs/ko/mcp-servers/#_top).
468
+
447
469
  #### If installed via pipx
448
470
 
449
471
  If you installed CodeGraphContext using `pipx`, use the following configuration instead:
@@ -537,7 +559,7 @@ Once the server is running, you can interact with it through your AI assistant u
537
559
  ## Contributing
538
560
 
539
561
  Contributions are welcome! 🎉
540
- Please see our [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
562
+ Please see our [CONTRIBUTING.md](.github/CONTRIBUTING.md) for detailed guidelines.
541
563
  If you have ideas for new features, integrations, or improvements, open an [issue](https://github.com/CodeGraphContext/CodeGraphContext/issues) or submit a Pull Request.
542
564
 
543
565
  Join discussions and help shape the future of CodeGraphContext.
@@ -1,7 +1,7 @@
1
1
  codegraphcontext/__init__.py,sha256=mFY5raGZpG90gG6E8NH0R85mDl3Ikak2HQHOiwCXl-I,77
2
2
  codegraphcontext/__main__.py,sha256=21QjL_lfd6cy-clJYPBg6xKb_IuNDcvvWdaAJEvZ-HQ,99
3
3
  codegraphcontext/prompts.py,sha256=Ld-2tI5mngpitccT0umOejyPG-xIaX3-6s-d2VTAzw8,6773
4
- codegraphcontext/server.py,sha256=bwJwtQUoStJ83keDMET0-ZpE5DoHhxxxI0aEkC-tiX0,26506
4
+ codegraphcontext/server.py,sha256=NARDquhfX70pqOVaGkTANjuyULRaJ3TYB262OufBkv4,26765
5
5
  codegraphcontext/tool_definitions.py,sha256=cDFdNSP4bhPUtJFZtWtSF_1IN7i-3rCmpSQ10nl-igM,16912
6
6
  codegraphcontext/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  codegraphcontext/api/app.py,sha256=LAjs65t7ceqyDBOX9iCT69xpUoBpIIngddvFUMrRqAA,2830
@@ -10,34 +10,34 @@ codegraphcontext/api/router.py,sha256=8iEhjERfGI5Udn801wMGpZmcmAuwbt5cMCwnK-Evg9
10
10
  codegraphcontext/api/schemas.py,sha256=pGLuKtdn55pf8mS8wv8MwehbT_3-4OZuSYjI5LJxzOc,1034
11
11
  codegraphcontext/cli/__init__.py,sha256=2vUlnf7H09M9JbS2gS_LmMUBJWAWcGGHkkl4I2YrdSg,39
12
12
  codegraphcontext/cli/cli_helpers.py,sha256=_fksM3sBj9e96gQcHOaDmpmJG6444lWRaO0AM-6Wzu8,38773
13
- codegraphcontext/cli/config_manager.py,sha256=3o52O0_La66bkrrUYmOcwZ-mchhhsdCP247mUygUAU4,44647
14
- codegraphcontext/cli/main.py,sha256=MiiQA126FwlV6WO053WIS5MNegIVxIt_TKWyvxkcJdg,116806
15
- codegraphcontext/cli/registry_commands.py,sha256=fueLG9DcBLxA-T8R081Xh7HH7NabVWjfUdgpJ0xJhJg,16936
13
+ codegraphcontext/cli/config_manager.py,sha256=QX6IP5JqYFaItaLGAJjh2J2pQgcEOC58HVNK9iIyexU,44863
14
+ codegraphcontext/cli/main.py,sha256=yOhEZDh4jmeo6avbjS5DqLHMEEkrZJlVCWV7R_pAw3g,116828
15
+ codegraphcontext/cli/registry_commands.py,sha256=8irzcdPV53PtERuytFfzm8KO5nEUPrgy9ZzyKL5oZ_0,17029
16
16
  codegraphcontext/cli/setup_macos.py,sha256=Xjlv_9jk9qv8Gh7stpH1pvlalzC0Fg176y7jc5G1zh0,3575
17
- codegraphcontext/cli/setup_wizard.py,sha256=JN63nBqUhIhCQsVaZ4SOpvRkGMlRIb0YZQ8PwQV69xE,47045
17
+ codegraphcontext/cli/setup_wizard.py,sha256=_aZxOe3q4qIEQeaghDVsNPxMRcxJsvibrfqf39rSshI,47746
18
18
  codegraphcontext/cli/visualizer.py,sha256=md5HehQ9_8lBTejQqq2lxXtMRzDxCjjF9L9h2qu6KR0,1902
19
- codegraphcontext/core/__init__.py,sha256=-DWsKT5T0pTnNwE0yPFlj1Vle8MqWtuRBn0qDRUbO5E,9073
19
+ codegraphcontext/core/__init__.py,sha256=mXMX6gBJ6DMad6lTvQvrpTxaSt1QfPMn3t_x1pZF4cg,10492
20
20
  codegraphcontext/core/bundle_registry.py,sha256=k3QZAGaLo2DV5p1xhqzgl_bf7faHCBfWT6ETYylSbKU,5711
21
- codegraphcontext/core/cgc_bundle.py,sha256=ZXmopzaAu23p6A-AyUk7LLRut-E2xDrxMSiQTeBsCXY,41052
21
+ codegraphcontext/core/cgc_bundle.py,sha256=fO3hw2fCgNGxNFEa9_A7k9Cima9EA8OifHnnyxb7S1Q,41052
22
22
  codegraphcontext/core/cgcignore.py,sha256=6q7y11V_bNEhMC1167HiUyr7yxDCNg2OMr0DQAqCzlE,4213
23
23
  codegraphcontext/core/database.py,sha256=RWMdKKinoWewyTyTuIXX-fk7EHkba91LO18gZ12wwEg,14648
24
- codegraphcontext/core/database_falkordb.py,sha256=oXJ8Vs500Udb_E8LjJRRQI63Zen7ckpnUJuheLISGJA,21858
24
+ codegraphcontext/core/database_falkordb.py,sha256=iN7uSvXFVp1clSjF2q92Omh4k6TlgAlS1-1QL9FF50o,25989
25
25
  codegraphcontext/core/database_falkordb_remote.py,sha256=aMiuJTB_-2rBUpbAmX8ElZiZrYZbOXK-On3ncgMCyhY,7118
26
- codegraphcontext/core/database_kuzu.py,sha256=MqlPTa2hL0XsUHpceJpNO6ahZAGmto39AL1d3Gs8I38,62253
26
+ codegraphcontext/core/database_kuzu.py,sha256=CScoj_lml1AWhba4k0iD84KuJppTivoenh8ZdQooIZo,62673
27
27
  codegraphcontext/core/database_ladybug.py,sha256=2YlmvJhxUt82mbm3__u2B1uiNhf5IoFHQUhUp8E-cag,62088
28
28
  codegraphcontext/core/database_nornic.py,sha256=XJkHROH_ojss2c-Kyte81lDehLjKRUYYfKDSA7YHa-4,8294
29
29
  codegraphcontext/core/falkor_worker.py,sha256=-UHm71HnqOQOh85ZLTPUuJJ08NQo77gw5lmOPN9rha8,5003
30
30
  codegraphcontext/core/jobs.py,sha256=d6v_IERdEcDlIsz3CW3p0QMp3N-6dgQICs3FZRPgPgU,4809
31
31
  codegraphcontext/core/watcher.py,sha256=EFjKYK3wUQG2pQter_A2xSe8yIrkZwfjZ9anITAjftA,18949
32
32
  codegraphcontext/tools/__init__.py,sha256=iqQPEkDlGXO7rAaLNQrS_ZAbLSklBSK-OowpARq0mig,41
33
- codegraphcontext/tools/advanced_language_query_tool.py,sha256=PCtDF0WK03V-nlinjeOFcnz-Ei5QlD7c9dv65RkGvV8,3826
34
- codegraphcontext/tools/code_finder.py,sha256=AZV51kDFmwIhHKQmH36zuL9qTlrP_RaP3e-ZEN_wi3k,70514
35
- codegraphcontext/tools/graph_builder.py,sha256=XX7lePPuwijArOukOtdd6Gmjit91A9Ma-cO6upiwXSk,54514
33
+ codegraphcontext/tools/advanced_language_query_tool.py,sha256=sZ1_IjqyeIHW-KR4MjXQnEly8-B1hpsFctMdUCROODE,3914
34
+ codegraphcontext/tools/code_finder.py,sha256=rSoyezvOedIeejN9INyb4kbniRctO25DR3tczvKAImo,70586
35
+ codegraphcontext/tools/graph_builder.py,sha256=jb0j9q0JvbzXk5uCqvdvUP-iYmECiARJ3KX9fOvgrMo,54654
36
36
  codegraphcontext/tools/package_resolver.py,sha256=KtbdMReTezszjdsqYniL-Xb-QUsrAJWtf1NSiyIPkLI,18704
37
37
  codegraphcontext/tools/report_generator.py,sha256=K4AROEMZU--fX217JT6y7P7LfiqRnG8olwrj0vO1kKo,12499
38
- codegraphcontext/tools/scip_indexer.py,sha256=Nbx3fG33s955IrtvdP_nH2coAqJnirS6yROlAStty-4,36850
38
+ codegraphcontext/tools/scip_indexer.py,sha256=tHR362n_tVOhOykTKPnPpCdgk9iryu2DuxAfSNonvXM,36926
39
39
  codegraphcontext/tools/scip_pb2.py,sha256=jSMLR7ud4eaKrIkQN-XDWNaFCyUaueafUm9WgOhjqRA,98270
40
- codegraphcontext/tools/system.py,sha256=JFfAdqg4WGSwznkmsGt34Qo5A3p2ms4RirWO_Rwtpko,6423
40
+ codegraphcontext/tools/system.py,sha256=kaX0XGs3DPnWxhscYVD5cxOqZWcK0V_Su-RytCkhieA,6592
41
41
  codegraphcontext/tools/tree_sitter_parser.py,sha256=sNt7q_3nc21pHeYnE6VxUYokk173CXeh4yt2pOOBdWg,5251
42
42
  codegraphcontext/tools/type_utils.py,sha256=ZCJ9b1BwvL7LKl8Duhx-5uwX3Gemp5EGqLMso7zRY3E,472
43
43
  codegraphcontext/tools/datasources/__init__.py,sha256=EDY0_s7DJPRzJhfmYUz3Pxv0b6UIXP-l9KMp3xgg-WU,132
@@ -54,14 +54,14 @@ codegraphcontext/tools/indexing/constants.py,sha256=gFhARllsYYHIEg88380dbgn4p9oQ
54
54
  codegraphcontext/tools/indexing/discovery.py,sha256=YAu6wmmXFPSv4zSmRXLVUQIEeWZrRzpG8ITbGOYQeDo,5130
55
55
  codegraphcontext/tools/indexing/embeddings.py,sha256=XFWKS2CYgs7ne5OfxWx76Sp0WLt-WgzNPsi_7wCmaN0,10501
56
56
  codegraphcontext/tools/indexing/pipeline.py,sha256=QjDp4ryA3RtFS6kqZBvyiVGkMXyyKBfsW8s29Adhft4,10496
57
- codegraphcontext/tools/indexing/pre_scan.py,sha256=uwAFMw2fEVWTtHdUy4CbdgwAt6Oe_SLy2KeUWwDPFUM,5672
57
+ codegraphcontext/tools/indexing/pre_scan.py,sha256=MJ3Mza2v3tpoN4V-473zC6D2Y0Ig8r-XgT3ogKFrPDc,5850
58
58
  codegraphcontext/tools/indexing/sanitize.py,sha256=IaTP7Aztso3SsvjNZMEqJ1iktV4Tl75hXcYnCWBGpLs,1490
59
59
  codegraphcontext/tools/indexing/schema.py,sha256=U2jUdtqcoBCdjQ9BCJWdfQs7Bc_lAGZN9sA2H3GDVvI,6734
60
60
  codegraphcontext/tools/indexing/schema_contract.py,sha256=W8mU7HgvyVvNw3Mxrwc-tDGHf91CrcY3GwGpUTgxbnM,1670
61
- codegraphcontext/tools/indexing/scip_pipeline.py,sha256=pTLDXC2TC5tMXjWVlT0Yo7V5EXKw9QVOEXsy9MJDN30,9012
61
+ codegraphcontext/tools/indexing/scip_pipeline.py,sha256=Uc3kSLNN4G1epLle5BvIQ-jtYJDAC4k1_j_cVFf_Dd4,8988
62
62
  codegraphcontext/tools/indexing/vector_resolver.py,sha256=RK2sj3n9_UVPVbfe9Isyn1GpfJTNrmPb830m9PF5yp4,5119
63
63
  codegraphcontext/tools/indexing/persistence/__init__.py,sha256=hFRlNgiYS7uN9X4e4xfP3c1BvcYSxpmq0k_uaDRn2Fg,121
64
- codegraphcontext/tools/indexing/persistence/writer.py,sha256=utTuqeFws71pRT6TD6f0nBrisLVoMnf_CFhXvEzQAMY,66477
64
+ codegraphcontext/tools/indexing/persistence/writer.py,sha256=1KGK3UjEHygB4-AIfF2-O7dAt6G116YGvqUPo-GlROc,67887
65
65
  codegraphcontext/tools/indexing/resolution/__init__.py,sha256=SWaJlN5kpWPjLoLUTLC4VEDaubpf0_tl5g7igGCbWJM,310
66
66
  codegraphcontext/tools/indexing/resolution/calls.py,sha256=R7o5ryWGCYL4h_DfnLaqdwpzSWYB6gTc8dbBWm-tAcM,107280
67
67
  codegraphcontext/tools/indexing/resolution/inheritance.py,sha256=BOYw_-NiO4oX5dS0CIX-ebg2ZhQhJ1NRC6Vk_tnAX-M,4118
@@ -115,7 +115,7 @@ codegraphcontext/utils/repo_path.py,sha256=BxS3y6RV_WaZhg_WxgJygS4SnQa-Ryth2fsic
115
115
  codegraphcontext/utils/tool_limits.py,sha256=3d-QnlzxBNocz58VKNhdsta7ZpWThs1AX46_gYXl6pQ,2751
116
116
  codegraphcontext/utils/tree_sitter_manager.py,sha256=DHXEImSfXNx5mLbNPo0mwc3IBxHvwbRmAmhrlFezw2s,13146
117
117
  codegraphcontext/utils/visualize_graph.py,sha256=4m3i_FKQaxrQZ6GePmHwjQBCctg4Dy_UQqwvwS3XL1Q,48
118
- codegraphcontext/viz/server.py,sha256=TcMFgJhgKnaVTzLQmjmbc7BvC5F1vU7sEsXUQI6rx34,15132
118
+ codegraphcontext/viz/server.py,sha256=M0Bz8PXpi44NuOp8pHCujaxH6b4g6rUlzB7PVsX-IiQ,15204
119
119
  codegraphcontext/viz/dist/cgcIcon.png,sha256=lik7hnqvkqLc5uo9w9Q_YJXtRx7cWPrXqSLttGtW1sg,58703
120
120
  codegraphcontext/viz/dist/favicon.ico,sha256=AjhUxD_Eslt5XuSVHIAZ494Fk__rb5GLXR8qm0elfP4,1870
121
121
  codegraphcontext/viz/dist/index.html,sha256=uEaFo3uHWD2KojFiyfWRJoS1_t6zrllOnf_siaB0I5U,1946
@@ -154,9 +154,9 @@ codegraphcontext/viz/dist/wasm/tree-sitter-typescript.wasm,sha256=hRVATc7tOOHthq
154
154
  codegraphcontext/viz/dist/wasm/tree-sitter.wasm,sha256=CCeVuI_hXktkBD-DW01xYPv5XoAYVRIqzJUJI5te-RY,196763
155
155
  codegraphcontext/viz/dist/wasm/web-tree-sitter.js,sha256=DIaCNqRylrT_PBVw8g4ImeSnhP9uXNe_ycOlUiVGPko,153666
156
156
  codegraphcontext/viz/dist/wasm/web-tree-sitter.wasm,sha256=CCeVuI_hXktkBD-DW01xYPv5XoAYVRIqzJUJI5te-RY,196763
157
- codegraphcontext-0.4.13.dist-info/licenses/LICENSE,sha256=rh8M-bJpQYJnw2vtRVgt0t7piMZXh5QzaKeNEI0vqqA,1061
158
- codegraphcontext-0.4.13.dist-info/METADATA,sha256=SQAYzdfxMY6Ofe2qh1K-aMTmN3uvOTAx0RsSx9fD_ps,22720
159
- codegraphcontext-0.4.13.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
160
- codegraphcontext-0.4.13.dist-info/entry_points.txt,sha256=LCxWCWMshdvYGoHBPuQZ8C-e4CiNSHCLXofrNSGHkoE,103
161
- codegraphcontext-0.4.13.dist-info/top_level.txt,sha256=CBgc6LAPZIO5FS0nSYYkylDifHsZTIqw3Gf5UwDxeGI,17
162
- codegraphcontext-0.4.13.dist-info/RECORD,,
157
+ codegraphcontext-0.4.15.dist-info/licenses/LICENSE,sha256=rh8M-bJpQYJnw2vtRVgt0t7piMZXh5QzaKeNEI0vqqA,1061
158
+ codegraphcontext-0.4.15.dist-info/METADATA,sha256=An3PFo4XyoM65S_BOSdhrZWjb2_wVfiMUYzDvseR9tc,23904
159
+ codegraphcontext-0.4.15.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
160
+ codegraphcontext-0.4.15.dist-info/entry_points.txt,sha256=LCxWCWMshdvYGoHBPuQZ8C-e4CiNSHCLXofrNSGHkoE,103
161
+ codegraphcontext-0.4.15.dist-info/top_level.txt,sha256=CBgc6LAPZIO5FS0nSYYkylDifHsZTIqw3Gf5UwDxeGI,17
162
+ codegraphcontext-0.4.15.dist-info/RECORD,,