mcp-vector-search 0.12.6__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.
Files changed (68) hide show
  1. mcp_vector_search/__init__.py +10 -0
  2. mcp_vector_search/cli/__init__.py +1 -0
  3. mcp_vector_search/cli/commands/__init__.py +1 -0
  4. mcp_vector_search/cli/commands/auto_index.py +397 -0
  5. mcp_vector_search/cli/commands/config.py +393 -0
  6. mcp_vector_search/cli/commands/demo.py +358 -0
  7. mcp_vector_search/cli/commands/index.py +744 -0
  8. mcp_vector_search/cli/commands/init.py +645 -0
  9. mcp_vector_search/cli/commands/install.py +675 -0
  10. mcp_vector_search/cli/commands/install_old.py +696 -0
  11. mcp_vector_search/cli/commands/mcp.py +1182 -0
  12. mcp_vector_search/cli/commands/reset.py +393 -0
  13. mcp_vector_search/cli/commands/search.py +773 -0
  14. mcp_vector_search/cli/commands/status.py +549 -0
  15. mcp_vector_search/cli/commands/uninstall.py +485 -0
  16. mcp_vector_search/cli/commands/visualize.py +1467 -0
  17. mcp_vector_search/cli/commands/watch.py +287 -0
  18. mcp_vector_search/cli/didyoumean.py +500 -0
  19. mcp_vector_search/cli/export.py +320 -0
  20. mcp_vector_search/cli/history.py +295 -0
  21. mcp_vector_search/cli/interactive.py +342 -0
  22. mcp_vector_search/cli/main.py +461 -0
  23. mcp_vector_search/cli/output.py +412 -0
  24. mcp_vector_search/cli/suggestions.py +375 -0
  25. mcp_vector_search/config/__init__.py +1 -0
  26. mcp_vector_search/config/constants.py +24 -0
  27. mcp_vector_search/config/defaults.py +200 -0
  28. mcp_vector_search/config/settings.py +134 -0
  29. mcp_vector_search/core/__init__.py +1 -0
  30. mcp_vector_search/core/auto_indexer.py +298 -0
  31. mcp_vector_search/core/connection_pool.py +360 -0
  32. mcp_vector_search/core/database.py +1214 -0
  33. mcp_vector_search/core/directory_index.py +318 -0
  34. mcp_vector_search/core/embeddings.py +294 -0
  35. mcp_vector_search/core/exceptions.py +89 -0
  36. mcp_vector_search/core/factory.py +318 -0
  37. mcp_vector_search/core/git_hooks.py +345 -0
  38. mcp_vector_search/core/indexer.py +1002 -0
  39. mcp_vector_search/core/models.py +294 -0
  40. mcp_vector_search/core/project.py +333 -0
  41. mcp_vector_search/core/scheduler.py +330 -0
  42. mcp_vector_search/core/search.py +952 -0
  43. mcp_vector_search/core/watcher.py +322 -0
  44. mcp_vector_search/mcp/__init__.py +5 -0
  45. mcp_vector_search/mcp/__main__.py +25 -0
  46. mcp_vector_search/mcp/server.py +733 -0
  47. mcp_vector_search/parsers/__init__.py +8 -0
  48. mcp_vector_search/parsers/base.py +296 -0
  49. mcp_vector_search/parsers/dart.py +605 -0
  50. mcp_vector_search/parsers/html.py +413 -0
  51. mcp_vector_search/parsers/javascript.py +643 -0
  52. mcp_vector_search/parsers/php.py +694 -0
  53. mcp_vector_search/parsers/python.py +502 -0
  54. mcp_vector_search/parsers/registry.py +223 -0
  55. mcp_vector_search/parsers/ruby.py +678 -0
  56. mcp_vector_search/parsers/text.py +186 -0
  57. mcp_vector_search/parsers/utils.py +265 -0
  58. mcp_vector_search/py.typed +1 -0
  59. mcp_vector_search/utils/__init__.py +40 -0
  60. mcp_vector_search/utils/gitignore.py +250 -0
  61. mcp_vector_search/utils/monorepo.py +277 -0
  62. mcp_vector_search/utils/timing.py +334 -0
  63. mcp_vector_search/utils/version.py +47 -0
  64. mcp_vector_search-0.12.6.dist-info/METADATA +754 -0
  65. mcp_vector_search-0.12.6.dist-info/RECORD +68 -0
  66. mcp_vector_search-0.12.6.dist-info/WHEEL +4 -0
  67. mcp_vector_search-0.12.6.dist-info/entry_points.txt +2 -0
  68. mcp_vector_search-0.12.6.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,461 @@
1
+ """Main CLI application for MCP Vector Search."""
2
+
3
+ from pathlib import Path
4
+
5
+ import typer
6
+ from loguru import logger
7
+ from rich.console import Console
8
+ from rich.traceback import install
9
+
10
+ from .. import __build__, __version__
11
+ from .didyoumean import add_common_suggestions, create_enhanced_typer
12
+ from .output import print_warning, setup_logging
13
+ from .suggestions import get_contextual_suggestions
14
+
15
+ # Install rich traceback handler
16
+ install(show_locals=True)
17
+
18
+ # Create console for rich output
19
+ console = Console()
20
+
21
+ # Create main Typer app with "did you mean" functionality
22
+ app = create_enhanced_typer(
23
+ name="mcp-vector-search",
24
+ help="""
25
+ 🔍 [bold]CLI-first semantic code search with MCP integration[/bold]
26
+
27
+ Semantic search finds code by meaning, not just keywords. Perfect for exploring
28
+ unfamiliar codebases, finding similar patterns, and integrating with AI tools.
29
+
30
+ [bold cyan]Quick Start:[/bold cyan]
31
+ 1. Initialize: [green]mcp-vector-search init[/green]
32
+ 2. Search code: [green]mcp-vector-search search "your query"[/green]
33
+ 3. Check status: [green]mcp-vector-search status[/green]
34
+
35
+ [bold cyan]Main Commands:[/bold cyan]
36
+ install đŸ“Ļ Install project and MCP integrations
37
+ uninstall đŸ—‘ī¸ Remove MCP integrations
38
+ init 🔧 Initialize project (simple)
39
+ demo đŸŽŦ Run interactive demo
40
+ doctor đŸŠē Check system health
41
+ status 📊 Show project status
42
+ search 🔍 Search code semantically
43
+ index 📇 Index codebase
44
+ mcp 🔌 MCP server operations
45
+ config âš™ī¸ Configure settings
46
+ visualize 📊 Visualize code relationships
47
+ help ❓ Get help
48
+ version â„šī¸ Show version
49
+
50
+ [dim]For detailed help: [cyan]mcp-vector-search COMMAND --help[/cyan][/dim]
51
+ """,
52
+ add_completion=False,
53
+ rich_markup_mode="rich",
54
+ )
55
+
56
+ # Import command modules
57
+ from .commands.config import config_app # noqa: E402
58
+ from .commands.demo import demo_app # noqa: E402
59
+ from .commands.index import index_app # noqa: E402
60
+ from .commands.init import init_app # noqa: E402
61
+ from .commands.install import install_app # noqa: E402
62
+ from .commands.mcp import mcp_app # noqa: E402
63
+ from .commands.search import search_app, search_main # noqa: E402, F401
64
+ from .commands.status import main as status_main # noqa: E402
65
+ from .commands.uninstall import uninstall_app # noqa: E402
66
+ from .commands.visualize import app as visualize_app # noqa: E402
67
+
68
+ # ============================================================================
69
+ # MAIN COMMANDS - Clean hierarchy
70
+ # ============================================================================
71
+
72
+ # 1. INSTALL - Install project and MCP integrations (NEW!)
73
+ app.add_typer(
74
+ install_app, name="install", help="đŸ“Ļ Install project and MCP integrations"
75
+ )
76
+
77
+ # 2. UNINSTALL - Remove MCP integrations (NEW!)
78
+ app.add_typer(uninstall_app, name="uninstall", help="đŸ—‘ī¸ Remove MCP integrations")
79
+ app.add_typer(uninstall_app, name="remove", help="đŸ—‘ī¸ Remove MCP integrations (alias)")
80
+
81
+ # 3. INIT - Initialize project (simplified)
82
+ # Use Typer group for init to support both direct call and subcommands
83
+ app.add_typer(init_app, name="init", help="🔧 Initialize project for semantic search")
84
+
85
+ # 4. DEMO - Interactive demo
86
+ app.add_typer(demo_app, name="demo", help="đŸŽŦ Run interactive demo with sample project")
87
+
88
+ # 5. DOCTOR - System health check
89
+ # (defined below inline)
90
+
91
+ # 6. STATUS - Project status
92
+ app.command("status", help="📊 Show project status and statistics")(status_main)
93
+
94
+ # 7. SEARCH - Search code
95
+ # Register search as both a command and a typer group
96
+ app.add_typer(search_app, name="search", help="🔍 Search code semantically")
97
+
98
+ # 8. INDEX - Index codebase
99
+ app.add_typer(index_app, name="index", help="📇 Index codebase for semantic search")
100
+
101
+ # 9. MCP - MCP server operations (RESERVED for server ops only!)
102
+ app.add_typer(mcp_app, name="mcp", help="🔌 MCP server operations")
103
+
104
+ # 10. CONFIG - Configuration
105
+ app.add_typer(config_app, name="config", help="âš™ī¸ Manage project configuration")
106
+
107
+ # 11. VISUALIZE - Code graph visualization
108
+ app.add_typer(
109
+ visualize_app, name="visualize", help="📊 Visualize code chunk relationships"
110
+ )
111
+
112
+ # 12. HELP - Enhanced help
113
+ # (defined below inline)
114
+
115
+ # 13. VERSION - Version info
116
+ # (defined below inline)
117
+
118
+
119
+ # ============================================================================
120
+ # DEPRECATED COMMANDS - With helpful suggestions
121
+ # ============================================================================
122
+
123
+
124
+ def _deprecated_command(old_cmd: str, new_cmd: str):
125
+ """Helper to create deprecated command with suggestion."""
126
+
127
+ def wrapper(*args, **kwargs):
128
+ print_warning(
129
+ f"âš ī¸ The command '{old_cmd}' is deprecated.\n"
130
+ f" Please use '{new_cmd}' instead.\n"
131
+ f" Run: [cyan]mcp-vector-search {new_cmd} --help[/cyan] for details."
132
+ )
133
+ raise typer.Exit(1)
134
+
135
+ return wrapper
136
+
137
+
138
+ # NOTE: 'install' command is now the primary command for project installation
139
+ # Old 'install' was deprecated in favor of 'init' in v0.7.0
140
+ # Now 'install' is back as the hierarchical installation command in v0.13.0
141
+
142
+
143
+ # Deprecated: find -> search
144
+ @app.command("find", hidden=True)
145
+ def deprecated_find():
146
+ """[DEPRECATED] Use 'search' instead."""
147
+ _deprecated_command("find", "search")()
148
+
149
+
150
+ # Deprecated: search-similar -> search --similar
151
+ @app.command("search-similar", hidden=True)
152
+ def deprecated_search_similar():
153
+ """[DEPRECATED] Use 'search --similar' instead."""
154
+ _deprecated_command("search-similar", "search --similar")()
155
+
156
+
157
+ # Deprecated: search-context -> search --context
158
+ @app.command("search-context", hidden=True)
159
+ def deprecated_search_context():
160
+ """[DEPRECATED] Use 'search --context' instead."""
161
+ _deprecated_command("search-context", "search --context")()
162
+
163
+
164
+ # Deprecated: interactive -> search interactive
165
+ @app.command("interactive", hidden=True)
166
+ def deprecated_interactive():
167
+ """[DEPRECATED] Use 'search interactive' instead."""
168
+ _deprecated_command("interactive", "search interactive")()
169
+
170
+
171
+ # Deprecated: history -> search history
172
+ @app.command("history", hidden=True)
173
+ def deprecated_history():
174
+ """[DEPRECATED] Use 'search history' instead."""
175
+ _deprecated_command("history", "search history")()
176
+
177
+
178
+ # Deprecated: favorites -> search favorites
179
+ @app.command("favorites", hidden=True)
180
+ def deprecated_favorites():
181
+ """[DEPRECATED] Use 'search favorites' instead."""
182
+ _deprecated_command("favorites", "search favorites")()
183
+
184
+
185
+ # Deprecated: add-favorite -> search favorites add
186
+ @app.command("add-favorite", hidden=True)
187
+ def deprecated_add_favorite():
188
+ """[DEPRECATED] Use 'search favorites add' instead."""
189
+ _deprecated_command("add-favorite", "search favorites add")()
190
+
191
+
192
+ # Deprecated: remove-favorite -> search favorites remove
193
+ @app.command("remove-favorite", hidden=True)
194
+ def deprecated_remove_favorite():
195
+ """[DEPRECATED] Use 'search favorites remove' instead."""
196
+ _deprecated_command("remove-favorite", "search favorites remove")()
197
+
198
+
199
+ # Deprecated: health -> index health
200
+ @app.command("health", hidden=True)
201
+ def deprecated_health():
202
+ """[DEPRECATED] Use 'index health' instead."""
203
+ _deprecated_command("health", "index health")()
204
+
205
+
206
+ # Deprecated: watch -> index watch
207
+ @app.command("watch", hidden=True)
208
+ def deprecated_watch():
209
+ """[DEPRECATED] Use 'index watch' instead."""
210
+ _deprecated_command("watch", "index watch")()
211
+
212
+
213
+ # Deprecated: auto-index -> index auto
214
+ @app.command("auto-index", hidden=True)
215
+ def deprecated_auto_index():
216
+ """[DEPRECATED] Use 'index auto' instead."""
217
+ _deprecated_command("auto-index", "index auto")()
218
+
219
+
220
+ # Deprecated: reset -> mcp reset or config reset
221
+ @app.command("reset", hidden=True)
222
+ def deprecated_reset():
223
+ """[DEPRECATED] Use 'mcp reset' or 'config reset' instead."""
224
+ print_warning(
225
+ "âš ī¸ The 'reset' command is deprecated.\n"
226
+ " Use [cyan]mcp-vector-search mcp reset[/cyan] for MCP reset\n"
227
+ " Use [cyan]mcp-vector-search config reset[/cyan] for config reset"
228
+ )
229
+ raise typer.Exit(1)
230
+
231
+
232
+ # Deprecated: init-check -> init check
233
+ @app.command("init-check", hidden=True)
234
+ def deprecated_init_check():
235
+ """[DEPRECATED] Use 'init check' instead."""
236
+ _deprecated_command("init-check", "init check")()
237
+
238
+
239
+ # Deprecated: init-mcp -> mcp install
240
+ @app.command("init-mcp", hidden=True)
241
+ def deprecated_init_mcp():
242
+ """[DEPRECATED] Use 'mcp install' instead."""
243
+ _deprecated_command("init-mcp", "mcp install")()
244
+
245
+
246
+ # Deprecated: init-models -> config models
247
+ @app.command("init-models", hidden=True)
248
+ def deprecated_init_models():
249
+ """[DEPRECATED] Use 'config models' instead."""
250
+ _deprecated_command("init-models", "config models")()
251
+
252
+
253
+ # ============================================================================
254
+ # MAIN INLINE COMMANDS
255
+ # ============================================================================
256
+
257
+
258
+ @app.command("doctor")
259
+ def doctor_command() -> None:
260
+ """đŸŠē Check system dependencies and configuration.
261
+
262
+ Runs diagnostic checks to ensure all required dependencies are installed
263
+ and properly configured. Use this to troubleshoot installation issues.
264
+
265
+ Examples:
266
+ mcp-vector-search doctor
267
+ """
268
+ from .commands.status import check_dependencies
269
+
270
+ console.print("[bold blue]đŸŠē MCP Vector Search - System Check[/bold blue]\n")
271
+
272
+ # Check dependencies
273
+ deps_ok = check_dependencies()
274
+
275
+ if deps_ok:
276
+ console.print("\n[green]✓ All dependencies are available[/green]")
277
+ else:
278
+ console.print("\n[red]✗ Some dependencies are missing[/red]")
279
+ console.print(
280
+ "Run [code]pip install mcp-vector-search[/code] to install missing dependencies"
281
+ )
282
+
283
+
284
+ @app.command("help")
285
+ def help_command(
286
+ command: str | None = typer.Argument(
287
+ None, help="Command to get help for (optional)"
288
+ ),
289
+ ) -> None:
290
+ """❓ Show contextual help and suggestions.
291
+
292
+ Get detailed help about specific commands or general usage guidance
293
+ based on your project state.
294
+
295
+ Examples:
296
+ mcp-vector-search help # General help
297
+ mcp-vector-search help search # Help for search command
298
+ mcp-vector-search help init # Help for init command
299
+ """
300
+ try:
301
+ project_root = Path.cwd()
302
+ console.print(
303
+ f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green]"
304
+ )
305
+ console.print("[dim]CLI-first semantic code search with MCP integration[/dim]")
306
+
307
+ if command:
308
+ # Show help for specific command
309
+ console.print(
310
+ f"\n[dim]Run: [bold]mcp-vector-search {command} --help[/bold] for detailed help[/dim]"
311
+ )
312
+ else:
313
+ # Show general contextual suggestions
314
+ get_contextual_suggestions(project_root)
315
+ except Exception as e:
316
+ logger.debug(f"Failed to show contextual help: {e}")
317
+ console.print(
318
+ "\n[dim]Use [bold]mcp-vector-search --help[/bold] for more information.[/dim]"
319
+ )
320
+
321
+
322
+ @app.command("version")
323
+ def version_command() -> None:
324
+ """â„šī¸ Show version information."""
325
+ console.print(
326
+ f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green] [dim](build {__build__})[/dim]"
327
+ )
328
+ console.print("\n[dim]CLI-first semantic code search with MCP integration[/dim]")
329
+ console.print("[dim]Built with ChromaDB, Tree-sitter, and modern Python[/dim]")
330
+
331
+
332
+ @app.callback()
333
+ def main(
334
+ ctx: typer.Context,
335
+ version: bool = typer.Option(
336
+ False,
337
+ "--version",
338
+ "-v",
339
+ help="Show version and exit",
340
+ rich_help_panel="â„šī¸ Information",
341
+ ),
342
+ verbose: bool = typer.Option(
343
+ False,
344
+ "--verbose",
345
+ help="Enable verbose logging",
346
+ rich_help_panel="🔧 Global Options",
347
+ ),
348
+ quiet: bool = typer.Option(
349
+ False,
350
+ "--quiet",
351
+ help="Suppress non-error output",
352
+ rich_help_panel="🔧 Global Options",
353
+ ),
354
+ project_root: Path | None = typer.Option(
355
+ None,
356
+ "--project-root",
357
+ "-p",
358
+ help="Project root directory (auto-detected if not specified)",
359
+ exists=True,
360
+ file_okay=False,
361
+ dir_okay=True,
362
+ readable=True,
363
+ rich_help_panel="🔧 Global Options",
364
+ ),
365
+ ) -> None:
366
+ """MCP Vector Search - CLI-first semantic code search with MCP integration.
367
+
368
+ A modern, lightweight tool for semantic code search using ChromaDB and Tree-sitter.
369
+ Designed for local development with optional MCP server integration.
370
+ """
371
+ if version:
372
+ console.print(f"mcp-vector-search version {__version__} (build {__build__})")
373
+ raise typer.Exit()
374
+
375
+ # Setup logging
376
+ log_level = "DEBUG" if verbose else "ERROR" if quiet else "WARNING"
377
+ setup_logging(log_level)
378
+
379
+ # Store global options in context
380
+ ctx.ensure_object(dict)
381
+ ctx.obj["verbose"] = verbose
382
+ ctx.obj["quiet"] = quiet
383
+ ctx.obj["project_root"] = project_root
384
+
385
+ if verbose:
386
+ logger.info(f"MCP Vector Search v{__version__} (build {__build__})")
387
+ if project_root:
388
+ logger.info(f"Using project root: {project_root}")
389
+
390
+
391
+ # ============================================================================
392
+ # CLI ENTRY POINT WITH ERROR HANDLING
393
+ # ============================================================================
394
+
395
+
396
+ def cli_with_suggestions():
397
+ """CLI wrapper that catches errors and provides suggestions."""
398
+ import sys
399
+
400
+ import click
401
+
402
+ try:
403
+ # Call the app with standalone_mode=False to get exceptions instead of sys.exit
404
+ app(standalone_mode=False)
405
+ except click.UsageError as e:
406
+ # Check if it's a "No such command" error
407
+ if "No such command" in str(e):
408
+ # Extract the command name from the error
409
+ import re
410
+
411
+ match = re.search(r"No such command '([^']+)'", str(e))
412
+ if match:
413
+ command_name = match.group(1)
414
+
415
+ # Show enhanced suggestions
416
+ from rich.console import Console
417
+
418
+ console = Console(stderr=True)
419
+ console.print(f"\\n[red]Error:[/red] {e}")
420
+
421
+ # Show enhanced suggestions
422
+ add_common_suggestions(None, command_name)
423
+
424
+ # Show contextual suggestions too
425
+ try:
426
+ project_root = Path.cwd()
427
+ get_contextual_suggestions(project_root, command_name)
428
+ except Exception as e:
429
+ logger.debug(
430
+ f"Failed to get contextual suggestions for error handling: {e}"
431
+ )
432
+ pass
433
+
434
+ sys.exit(2) # Exit with error code
435
+
436
+ # For other usage errors, show the default message and exit
437
+ click.echo(f"Error: {e}", err=True)
438
+ sys.exit(2)
439
+ except click.Abort:
440
+ # User interrupted (Ctrl+C)
441
+ sys.exit(1)
442
+ except SystemExit:
443
+ # Re-raise system exits
444
+ raise
445
+ except Exception as e:
446
+ # For other exceptions, show error and exit if verbose logging is enabled
447
+ # Suppress internal framework errors in normal operation
448
+
449
+ # Suppress harmless didyoumean framework AttributeError (known issue)
450
+ # This occurs during Click/Typer cleanup after successful command completion
451
+ if isinstance(e, AttributeError) and "attribute" in str(e) and "name" in str(e):
452
+ pass # Ignore - this is a harmless framework cleanup error
453
+ elif "--verbose" in sys.argv or "-v" in sys.argv:
454
+ click.echo(f"Unexpected error: {e}", err=True)
455
+ sys.exit(1)
456
+ # Otherwise, just exit silently to avoid confusing error messages
457
+ pass
458
+
459
+
460
+ if __name__ == "__main__":
461
+ cli_with_suggestions()