mcp-vector-search 0.6.0__py3-none-any.whl → 0.7.0__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.

Potentially problematic release.


This version of mcp-vector-search might be problematic. Click here for more details.

@@ -1,7 +1,7 @@
1
1
  """MCP Vector Search - CLI-first semantic code search with MCP integration."""
2
2
 
3
- __version__ = "0.6.0"
4
- __build__ = "20"
3
+ __version__ = "0.7.0"
4
+ __build__ = "22"
5
5
  __author__ = "Robert Matsuoka"
6
6
  __email__ = "bobmatnyc@gmail.com"
7
7
 
@@ -347,5 +347,35 @@ def _show_available_keys() -> None:
347
347
  )
348
348
 
349
349
 
350
+ # ============================================================================
351
+ # CONFIG SUBCOMMANDS
352
+ # ============================================================================
353
+
354
+
355
+ @config_app.command("models")
356
+ def list_embedding_models() -> None:
357
+ """📚 List available embedding models.
358
+
359
+ Shows all available embedding models that can be used for semantic search.
360
+ You can also use any model from Hugging Face that's compatible with sentence-transformers.
361
+
362
+ Examples:
363
+ mcp-vector-search config models
364
+ """
365
+ from ...config.defaults import DEFAULT_EMBEDDING_MODELS
366
+
367
+ console.print("[bold blue]Available Embedding Models:[/bold blue]\n")
368
+
369
+ for category, model in DEFAULT_EMBEDDING_MODELS.items():
370
+ console.print(f"[cyan]{category.title()}:[/cyan] {model}")
371
+
372
+ console.print(
373
+ "\n[dim]You can also use any model from Hugging Face that's compatible with sentence-transformers[/dim]"
374
+ )
375
+ console.print(
376
+ "[dim]Set model: [cyan]mcp-vector-search config set embedding_model MODEL_NAME[/cyan][/dim]"
377
+ )
378
+
379
+
350
380
  if __name__ == "__main__":
351
381
  config_app()
@@ -22,11 +22,14 @@ from ..output import (
22
22
  print_tip,
23
23
  )
24
24
 
25
- # Create index subcommand app
26
- index_app = typer.Typer(help="Index codebase for semantic search")
25
+ # Create index subcommand app with callback for direct usage
26
+ index_app = typer.Typer(
27
+ help="Index codebase for semantic search",
28
+ invoke_without_command=True,
29
+ )
27
30
 
28
31
 
29
- @index_app.command()
32
+ @index_app.callback(invoke_without_command=True)
30
33
  def main(
31
34
  ctx: typer.Context,
32
35
  watch: bool = typer.Option(
@@ -95,8 +98,12 @@ def main(
95
98
 
96
99
  [dim]💡 Tip: Use incremental indexing (default) for faster updates on subsequent runs.[/dim]
97
100
  """
101
+ # If a subcommand was invoked, don't run the indexing logic
102
+ if ctx.invoked_subcommand is not None:
103
+ return
104
+
98
105
  try:
99
- project_root = ctx.obj.get("project_root") or Path.cwd()
106
+ project_root = (ctx.obj.get("project_root") if ctx.obj else None) or Path.cwd()
100
107
 
101
108
  # Run async indexing
102
109
  asyncio.run(
@@ -488,5 +495,87 @@ async def _clean_index(project_root: Path) -> None:
488
495
  print_success("Index cleaned successfully")
489
496
 
490
497
 
498
+ # ============================================================================
499
+ # INDEX SUBCOMMANDS
500
+ # ============================================================================
501
+
502
+
503
+ @index_app.command("watch")
504
+ def watch_cmd(
505
+ project_root: Path = typer.Argument(
506
+ Path.cwd(),
507
+ help="Project root directory to watch",
508
+ exists=True,
509
+ file_okay=False,
510
+ dir_okay=True,
511
+ readable=True,
512
+ ),
513
+ ) -> None:
514
+ """👀 Watch for file changes and auto-update index.
515
+
516
+ Monitors your project directory for file changes and automatically updates
517
+ the search index when files are modified, added, or deleted.
518
+
519
+ Examples:
520
+ mcp-vector-search index watch
521
+ mcp-vector-search index watch /path/to/project
522
+ """
523
+ from .watch import app as watch_app
524
+
525
+ # Import and run watch command
526
+ watch_app()
527
+
528
+
529
+ @index_app.command("auto")
530
+ def auto_cmd() -> None:
531
+ """🔄 Manage automatic indexing.
532
+
533
+ Configure automatic indexing strategies like git hooks and scheduled tasks.
534
+ This command provides subcommands for setup, status, and checking.
535
+
536
+ Examples:
537
+ mcp-vector-search index auto setup
538
+ mcp-vector-search index auto status
539
+ mcp-vector-search index auto check
540
+ """
541
+ from .auto_index import auto_index_app
542
+
543
+ # This will show help for the auto subcommands
544
+ auto_index_app()
545
+
546
+
547
+ @index_app.command("health")
548
+ def health_cmd(
549
+ project_root: Path | None = typer.Option(
550
+ None,
551
+ "--project-root",
552
+ "-p",
553
+ help="Project root directory",
554
+ exists=True,
555
+ file_okay=False,
556
+ dir_okay=True,
557
+ readable=True,
558
+ ),
559
+ repair: bool = typer.Option(
560
+ False,
561
+ "--repair",
562
+ help="Attempt to repair index issues",
563
+ ),
564
+ ) -> None:
565
+ """🩺 Check index health and optionally repair.
566
+
567
+ Validates the search index integrity and provides diagnostic information.
568
+ Can attempt to repair common issues automatically.
569
+
570
+ Examples:
571
+ mcp-vector-search index health
572
+ mcp-vector-search index health --repair
573
+ """
574
+ from .reset import health_main
575
+
576
+ # Call the health function from reset.py
577
+ health_main(project_root=project_root, repair=repair)
578
+
579
+
491
580
  if __name__ == "__main__":
492
581
  index_app()
@@ -20,13 +20,24 @@ from ..output import (
20
20
  print_tip,
21
21
  )
22
22
 
23
- # Create search subcommand app with "did you mean" functionality (kept for backward compatibility)
24
- search_app = create_enhanced_typer(help="Search code semantically")
23
+ # Create search subcommand app with "did you mean" functionality
24
+ search_app = create_enhanced_typer(
25
+ help="🔍 Search code semantically",
26
+ invoke_without_command=True,
27
+ )
28
+
25
29
 
30
+ # Define search_main as the callback for the search command
31
+ # This makes `mcp-vector-search search "query"` work as main search
32
+ # and `mcp-vector-search search SUBCOMMAND` work for subcommands
26
33
 
34
+
35
+ @search_app.callback(invoke_without_command=True)
27
36
  def search_main(
28
37
  ctx: typer.Context,
29
- query: str = typer.Argument(..., help="Search query or file path (for --similar)"),
38
+ query: str | None = typer.Argument(
39
+ None, help="Search query or file path (for --similar)"
40
+ ),
30
41
  project_root: Path | None = typer.Option(
31
42
  None,
32
43
  "--project-root",
@@ -161,6 +172,15 @@ def search_main(
161
172
 
162
173
  [dim]💡 Tip: Use quotes for multi-word queries. Adjust --threshold for more/fewer results.[/dim]
163
174
  """
175
+ # If no query provided and no subcommand invoked, exit (show help)
176
+ if query is None:
177
+ if ctx.invoked_subcommand is None:
178
+ # No query and no subcommand - show help
179
+ raise typer.Exit()
180
+ else:
181
+ # A subcommand was invoked - let it handle the request
182
+ return
183
+
164
184
  try:
165
185
  project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
166
186
 
@@ -640,10 +660,113 @@ async def run_context_search(
640
660
  )
641
661
 
642
662
 
643
- # Add commands to search_app for backward compatibility
663
+ # ============================================================================
664
+ # SEARCH SUBCOMMANDS
665
+ # ============================================================================
666
+
667
+
668
+ @search_app.command("interactive")
669
+ def interactive_search(
670
+ ctx: typer.Context,
671
+ project_root: Path | None = typer.Option(
672
+ None, "--project-root", "-p", help="Project root directory"
673
+ ),
674
+ ) -> None:
675
+ """🎯 Start an interactive search session.
676
+
677
+ Provides a rich terminal interface for searching your codebase with real-time
678
+ filtering, query refinement, and result navigation.
679
+
680
+ Examples:
681
+ mcp-vector-search search interactive
682
+ mcp-vector-search search interactive --project-root /path/to/project
683
+ """
684
+ import asyncio
685
+
686
+ from ..interactive import start_interactive_search
687
+ from ..output import console
688
+
689
+ root = project_root or ctx.obj.get("project_root") or Path.cwd()
690
+
691
+ try:
692
+ asyncio.run(start_interactive_search(root))
693
+ except KeyboardInterrupt:
694
+ console.print("\n[yellow]Interactive search cancelled[/yellow]")
695
+ except Exception as e:
696
+ print_error(f"Interactive search failed: {e}")
697
+ raise typer.Exit(1)
698
+
699
+
700
+ @search_app.command("history")
701
+ def show_history(
702
+ ctx: typer.Context,
703
+ limit: int = typer.Option(20, "--limit", "-l", help="Number of entries to show"),
704
+ project_root: Path | None = typer.Option(
705
+ None, "--project-root", "-p", help="Project root directory"
706
+ ),
707
+ ) -> None:
708
+ """📜 Show search history.
709
+
710
+ Displays your recent search queries with timestamps and result counts.
711
+ Use this to revisit previous searches or track your search patterns.
712
+
713
+ Examples:
714
+ mcp-vector-search search history
715
+ mcp-vector-search search history --limit 50
716
+ """
717
+ from ..history import show_search_history
718
+
719
+ root = project_root or ctx.obj.get("project_root") or Path.cwd()
720
+ show_search_history(root, limit)
721
+
722
+
723
+ @search_app.command("favorites")
724
+ def show_favorites_cmd(
725
+ ctx: typer.Context,
726
+ action: str | None = typer.Argument(None, help="Action: list, add, remove"),
727
+ query: str | None = typer.Argument(None, help="Query to add/remove"),
728
+ description: str | None = typer.Option(
729
+ None, "--desc", help="Description for favorite"
730
+ ),
731
+ project_root: Path | None = typer.Option(
732
+ None, "--project-root", "-p", help="Project root directory"
733
+ ),
734
+ ) -> None:
735
+ """⭐ Manage favorite queries.
736
+
737
+ List, add, or remove favorite search queries for quick access.
738
+
739
+ Examples:
740
+ mcp-vector-search search favorites # List all favorites
741
+ mcp-vector-search search favorites list # List all favorites
742
+ mcp-vector-search search favorites add "auth" # Add favorite
743
+ mcp-vector-search search favorites remove "auth" # Remove favorite
744
+ """
745
+ from ..history import SearchHistory, show_favorites
746
+
747
+ root = project_root or ctx.obj.get("project_root") or Path.cwd()
748
+ history_manager = SearchHistory(root)
749
+
750
+ # Default to list if no action provided
751
+ if not action or action == "list":
752
+ show_favorites(root)
753
+ elif action == "add":
754
+ if not query:
755
+ print_error("Query is required for 'add' action")
756
+ raise typer.Exit(1)
757
+ history_manager.add_favorite(query, description)
758
+ elif action == "remove":
759
+ if not query:
760
+ print_error("Query is required for 'remove' action")
761
+ raise typer.Exit(1)
762
+ history_manager.remove_favorite(query)
763
+ else:
764
+ print_error(f"Unknown action: {action}. Use: list, add, or remove")
765
+ raise typer.Exit(1)
766
+
767
+
768
+ # Add main command to search_app (allows: mcp-vector-search search main "query")
644
769
  search_app.command("main")(search_main)
645
- search_app.command("similar")(search_similar_cmd)
646
- search_app.command("context")(search_context_cmd)
647
770
 
648
771
 
649
772
  if __name__ == "__main__":
@@ -8,31 +8,8 @@ from rich.console import Console
8
8
  from rich.traceback import install
9
9
 
10
10
  from .. import __build__, __version__
11
- from .commands.auto_index import auto_index_app
12
- from .commands.config import config_app
13
- from .commands.index import index_app
14
- from .commands.init import (
15
- check_initialization as init_check,
16
- )
17
- from .commands.init import (
18
- init_mcp_integration,
19
- list_embedding_models,
20
- )
21
- from .commands.init import (
22
- main as init_main,
23
- )
24
- from .commands.mcp import mcp_app
25
- from .commands.reset import health_main, reset_app
26
- from .commands.search import (
27
- search_app,
28
- search_context_cmd,
29
- search_main,
30
- search_similar_cmd,
31
- )
32
- from .commands.status import status_app
33
- from .commands.watch import app as watch_app
34
11
  from .didyoumean import add_common_suggestions, create_enhanced_typer
35
- from .output import print_error, setup_logging
12
+ from .output import print_warning, setup_logging
36
13
  from .suggestions import get_contextual_suggestions
37
14
 
38
15
  # Install rich traceback handler
@@ -55,229 +32,290 @@ unfamiliar codebases, finding similar patterns, and integrating with AI tools.
55
32
  2. Search code: [green]mcp-vector-search search "your query"[/green]
56
33
  3. Check status: [green]mcp-vector-search status[/green]
57
34
 
58
- [bold cyan]Key Features:[/bold cyan]
59
- 🤖 MCP Integration: Works with Claude Code, Cursor, and AI tools
60
- Fast Indexing: Incremental updates with file watching
61
- 🎯 Semantic Search: Find code by meaning, not just keywords
62
- 📊 Rich Output: Beautiful terminal formatting with syntax highlighting
63
-
64
- [bold cyan]Configuration Files:[/bold cyan]
65
- Project: .mcp-vector-search/config.json
66
- Claude Code: .claude/settings.local.json
67
- Global cache: ~/.cache/mcp-vector-search/
68
-
69
- [dim]For detailed help on any command: [cyan]mcp-vector-search COMMAND --help[/cyan][/dim]
70
- [dim]Documentation: [cyan]https://github.com/yourusername/mcp-vector-search[/cyan][/dim]
35
+ [bold cyan]Main Commands:[/bold cyan]
36
+ init 🔧 Initialize project
37
+ doctor 🩺 Check system health
38
+ status 📊 Show project status
39
+ search 🔍 Search code semantically
40
+ index 📇 Index codebase
41
+ mcp 🤖 MCP integration
42
+ config ⚙️ Configure settings
43
+ help ❓ Get help
44
+ version ℹ️ Show version
45
+
46
+ [dim]For detailed help: [cyan]mcp-vector-search COMMAND --help[/cyan][/dim]
71
47
  """,
72
48
  add_completion=False,
73
49
  rich_markup_mode="rich",
74
50
  )
75
51
 
76
- # Import command functions for direct registration and aliases
77
- from .commands.index import main as index_main # noqa: E402
78
- from .commands.install import demo as install_demo # noqa: E402
79
- from .commands.install import main as install_main # noqa: E402
52
+ # Import command modules
53
+ from .commands.config import config_app # noqa: E402
54
+ from .commands.index import index_app # noqa: E402
55
+ from .commands.init import init_app # noqa: E402
56
+ from .commands.init import main as init_main # noqa: E402
57
+ from .commands.mcp import mcp_app # noqa: E402
58
+ from .commands.search import search_app, search_main # noqa: E402, F401
80
59
  from .commands.status import main as status_main # noqa: E402
81
60
 
82
- # Note: config doesn't have a main function, it uses subcommands via config_app
83
- app.command("install", help="🚀 Install mcp-vector-search in projects")(install_main)
84
- app.command("demo", help="🎬 Run installation demo with sample project")(install_demo)
85
- app.command("status", help="📊 Show project status and statistics")(status_main)
86
- # Register init as a direct command
61
+ # ============================================================================
62
+ # MAIN COMMANDS - Clean hierarchy
63
+ # ============================================================================
64
+
65
+ # 1. INIT - Initialize project
87
66
  app.command("init", help="🔧 Initialize project for semantic search")(init_main)
88
- # Add init subcommands as separate commands
89
- app.command("init-check", help="Check if project is initialized")(init_check)
90
- app.command("init-mcp", help="Install/fix Claude Code MCP integration")(
91
- init_mcp_integration
92
- )
93
- app.command("init-models", help="List available embedding models")(
94
- list_embedding_models
95
- )
96
- app.add_typer(index_app, name="index", help="Index codebase for semantic search")
97
- app.add_typer(config_app, name="config", help="Manage project configuration")
98
- app.add_typer(watch_app, name="watch", help="Watch for file changes and update index")
99
- app.add_typer(auto_index_app, name="auto-index", help="Manage automatic indexing")
100
- app.add_typer(mcp_app, name="mcp", help="Manage Claude Code MCP integration")
101
- app.add_typer(reset_app, name="reset", help="Reset and recovery operations")
102
-
103
- # Add search command - simplified syntax as default
104
- app.command("search", help="Search code semantically")(search_main)
105
-
106
- # Keep old nested structure for backward compatibility
107
- app.add_typer(
108
- search_app, name="search-legacy", help="Legacy search commands", hidden=True
109
- )
110
- app.add_typer(
111
- status_app, name="status-legacy", help="Legacy status commands", hidden=True
112
- )
67
+ app.add_typer(init_app, name="init", hidden=True) # Subcommands under init
113
68
 
114
- # Add command aliases for better user experience
115
- app.command("find", help="Search code semantically (alias for search)")(search_main)
116
- app.command("f", help="Search code semantically (short alias)", hidden=True)(
117
- search_main
118
- ) # Hidden short alias
119
- app.command("s", help="Search code semantically (short alias)", hidden=True)(
120
- search_main
121
- ) # Hidden short alias
122
- app.command("query", help="Search code semantically (alias for search)", hidden=True)(
123
- search_main
124
- ) # Hidden alias
125
-
126
- # Index aliases
127
- app.command("i", help="Index codebase (short alias)", hidden=True)(
128
- index_main
129
- ) # Hidden short alias
130
- app.command("build", help="Index codebase (alias for index)", hidden=True)(
131
- index_main
132
- ) # Hidden alias
133
- app.command("scan", help="Index codebase (alias for index)", hidden=True)(
134
- index_main
135
- ) # Hidden alias
136
-
137
- # Status aliases
138
- app.command("st", help="Show status (short alias)", hidden=True)(
139
- status_main
140
- ) # Hidden short alias
141
- app.command("info", help="Show project information (alias for status)", hidden=True)(
142
- status_main
143
- ) # Hidden alias
144
-
145
- # Config aliases - Since config uses subcommands, these will be handled by the enhanced typer error resolution
146
- # app.command("c", help="Manage configuration (short alias)", hidden=True) # Will be handled by typo resolution
147
- # app.command("cfg", help="Manage configuration (alias for config)", hidden=True) # Will be handled by typo resolution
148
-
149
- # Specialized search commands
150
- app.command("search-similar", help="Find code similar to a specific file or function")(
151
- search_similar_cmd
152
- )
153
- app.command("search-context", help="Search for code based on contextual description")(
154
- search_context_cmd
155
- )
156
- app.command("health", help="Check index health and optionally repair")(health_main)
69
+ # 2. DOCTOR - System health check
70
+ # (defined below inline)
157
71
 
72
+ # 3. STATUS - Project status
73
+ app.command("status", help="📊 Show project status and statistics")(status_main)
158
74
 
159
- # Add interactive search command
160
- @app.command("interactive")
161
- def interactive_search(
162
- ctx: typer.Context,
163
- project_root: Path | None = typer.Option(
164
- None, "--project-root", "-p", help="Project root directory"
165
- ),
166
- ) -> None:
167
- """Start an interactive search session with filtering and refinement.
75
+ # 4. SEARCH - Search code
76
+ # Register search as both a command and a typer group
77
+ app.add_typer(search_app, name="search", help="🔍 Search code semantically")
168
78
 
169
- The interactive mode provides a rich terminal interface for searching your codebase
170
- with real-time filtering, query refinement, and result navigation.
79
+ # 5. INDEX - Index codebase
80
+ app.add_typer(index_app, name="index", help="📇 Index codebase for semantic search")
171
81
 
172
- Examples:
173
- mcp-vector-search interactive
174
- mcp-vector-search interactive --project-root /path/to/project
175
- """
176
- import asyncio
82
+ # 6. MCP - MCP integration
83
+ app.add_typer(mcp_app, name="mcp", help="🤖 Manage Claude Code MCP integration")
177
84
 
178
- from .interactive import start_interactive_search
85
+ # 7. CONFIG - Configuration
86
+ app.add_typer(config_app, name="config", help="⚙️ Manage project configuration")
179
87
 
180
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
88
+ # 8. HELP - Enhanced help
89
+ # (defined below inline)
181
90
 
182
- try:
183
- asyncio.run(start_interactive_search(root))
184
- except KeyboardInterrupt:
185
- console.print("\n[yellow]Interactive search cancelled[/yellow]")
186
- except Exception as e:
187
- print_error(f"Interactive search failed: {e}")
91
+ # 9. VERSION - Version info
92
+ # (defined below inline)
93
+
94
+
95
+ # ============================================================================
96
+ # DEPRECATED COMMANDS - With helpful suggestions
97
+ # ============================================================================
98
+
99
+
100
+ def _deprecated_command(old_cmd: str, new_cmd: str):
101
+ """Helper to create deprecated command with suggestion."""
102
+
103
+ def wrapper(*args, **kwargs):
104
+ print_warning(
105
+ f"⚠️ The command '{old_cmd}' is deprecated.\n"
106
+ f" Please use '{new_cmd}' instead.\n"
107
+ f" Run: [cyan]mcp-vector-search {new_cmd} --help[/cyan] for details."
108
+ )
188
109
  raise typer.Exit(1)
189
110
 
111
+ return wrapper
190
112
 
191
- # Add history management commands
192
- @app.command("history")
193
- def show_history(
194
- ctx: typer.Context,
195
- limit: int = typer.Option(20, "--limit", "-l", help="Number of entries to show"),
196
- project_root: Path | None = typer.Option(
197
- None, "--project-root", "-p", help="Project root directory"
198
- ),
199
- ) -> None:
200
- """Show search history.
201
113
 
202
- Displays your recent search queries with timestamps and result counts.
203
- Use this to revisit previous searches or track your search patterns.
114
+ # Deprecated: install -> init
115
+ @app.command("install", hidden=True)
116
+ def deprecated_install():
117
+ """[DEPRECATED] Use 'init' instead."""
118
+ _deprecated_command("install", "init")()
204
119
 
205
- Examples:
206
- mcp-vector-search history
207
- mcp-vector-search history --limit 50
208
- """
209
- from .history import show_search_history
210
120
 
211
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
212
- show_search_history(root, limit)
121
+ # Deprecated: demo -> removed
122
+ @app.command("demo", hidden=True)
123
+ def deprecated_demo():
124
+ """[DEPRECATED] Command removed."""
125
+ print_warning(
126
+ "⚠️ The 'demo' command has been removed.\n"
127
+ " Use [cyan]mcp-vector-search init --help[/cyan] for setup instructions."
128
+ )
129
+ raise typer.Exit(1)
213
130
 
214
131
 
215
- @app.command("favorites")
216
- def show_favorites_cmd(
217
- ctx: typer.Context,
218
- project_root: Path | None = typer.Option(
219
- None, "--project-root", "-p", help="Project root directory"
220
- ),
221
- ) -> None:
222
- """Show favorite queries.
132
+ # Deprecated: find -> search
133
+ @app.command("find", hidden=True)
134
+ def deprecated_find():
135
+ """[DEPRECATED] Use 'search' instead."""
136
+ _deprecated_command("find", "search")()
223
137
 
224
- Displays your saved favorite search queries. Favorites allow you to quickly
225
- access frequently used searches without typing them again.
226
138
 
227
- Examples:
228
- mcp-vector-search favorites
229
- """
230
- from .history import show_favorites
139
+ # Deprecated: search-similar -> search --similar
140
+ @app.command("search-similar", hidden=True)
141
+ def deprecated_search_similar():
142
+ """[DEPRECATED] Use 'search --similar' instead."""
143
+ _deprecated_command("search-similar", "search --similar")()
231
144
 
232
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
233
- show_favorites(root)
234
145
 
146
+ # Deprecated: search-context -> search --context
147
+ @app.command("search-context", hidden=True)
148
+ def deprecated_search_context():
149
+ """[DEPRECATED] Use 'search --context' instead."""
150
+ _deprecated_command("search-context", "search --context")()
235
151
 
236
- @app.command("add-favorite")
237
- def add_favorite(
238
- ctx: typer.Context,
239
- query: str = typer.Argument(..., help="Query to add to favorites"),
240
- description: str | None = typer.Option(None, "--desc", help="Optional description"),
241
- project_root: Path | None = typer.Option(
242
- None, "--project-root", "-p", help="Project root directory"
243
- ),
244
- ) -> None:
245
- """Add a query to favorites.
246
152
 
247
- Save a search query to your favorites list for quick access later.
248
- Optionally include a description to help remember what the query is for.
153
+ # Deprecated: interactive -> search interactive
154
+ @app.command("interactive", hidden=True)
155
+ def deprecated_interactive():
156
+ """[DEPRECATED] Use 'search interactive' instead."""
157
+ _deprecated_command("interactive", "search interactive")()
158
+
159
+
160
+ # Deprecated: history -> search history
161
+ @app.command("history", hidden=True)
162
+ def deprecated_history():
163
+ """[DEPRECATED] Use 'search history' instead."""
164
+ _deprecated_command("history", "search history")()
165
+
166
+
167
+ # Deprecated: favorites -> search favorites
168
+ @app.command("favorites", hidden=True)
169
+ def deprecated_favorites():
170
+ """[DEPRECATED] Use 'search favorites' instead."""
171
+ _deprecated_command("favorites", "search favorites")()
172
+
173
+
174
+ # Deprecated: add-favorite -> search favorites add
175
+ @app.command("add-favorite", hidden=True)
176
+ def deprecated_add_favorite():
177
+ """[DEPRECATED] Use 'search favorites add' instead."""
178
+ _deprecated_command("add-favorite", "search favorites add")()
179
+
180
+
181
+ # Deprecated: remove-favorite -> search favorites remove
182
+ @app.command("remove-favorite", hidden=True)
183
+ def deprecated_remove_favorite():
184
+ """[DEPRECATED] Use 'search favorites remove' instead."""
185
+ _deprecated_command("remove-favorite", "search favorites remove")()
186
+
187
+
188
+ # Deprecated: health -> index health
189
+ @app.command("health", hidden=True)
190
+ def deprecated_health():
191
+ """[DEPRECATED] Use 'index health' instead."""
192
+ _deprecated_command("health", "index health")()
193
+
194
+
195
+ # Deprecated: watch -> index watch
196
+ @app.command("watch", hidden=True)
197
+ def deprecated_watch():
198
+ """[DEPRECATED] Use 'index watch' instead."""
199
+ _deprecated_command("watch", "index watch")()
200
+
201
+
202
+ # Deprecated: auto-index -> index auto
203
+ @app.command("auto-index", hidden=True)
204
+ def deprecated_auto_index():
205
+ """[DEPRECATED] Use 'index auto' instead."""
206
+ _deprecated_command("auto-index", "index auto")()
207
+
208
+
209
+ # Deprecated: reset -> mcp reset or config reset
210
+ @app.command("reset", hidden=True)
211
+ def deprecated_reset():
212
+ """[DEPRECATED] Use 'mcp reset' or 'config reset' instead."""
213
+ print_warning(
214
+ "⚠️ The 'reset' command is deprecated.\n"
215
+ " Use [cyan]mcp-vector-search mcp reset[/cyan] for MCP reset\n"
216
+ " Use [cyan]mcp-vector-search config reset[/cyan] for config reset"
217
+ )
218
+ raise typer.Exit(1)
219
+
220
+
221
+ # Deprecated: init-check -> init check
222
+ @app.command("init-check", hidden=True)
223
+ def deprecated_init_check():
224
+ """[DEPRECATED] Use 'init check' instead."""
225
+ _deprecated_command("init-check", "init check")()
226
+
227
+
228
+ # Deprecated: init-mcp -> mcp install
229
+ @app.command("init-mcp", hidden=True)
230
+ def deprecated_init_mcp():
231
+ """[DEPRECATED] Use 'mcp install' instead."""
232
+ _deprecated_command("init-mcp", "mcp install")()
233
+
234
+
235
+ # Deprecated: init-models -> config models
236
+ @app.command("init-models", hidden=True)
237
+ def deprecated_init_models():
238
+ """[DEPRECATED] Use 'config models' instead."""
239
+ _deprecated_command("init-models", "config models")()
240
+
241
+
242
+ # ============================================================================
243
+ # MAIN INLINE COMMANDS
244
+ # ============================================================================
245
+
246
+
247
+ @app.command("doctor")
248
+ def doctor_command() -> None:
249
+ """🩺 Check system dependencies and configuration.
250
+
251
+ Runs diagnostic checks to ensure all required dependencies are installed
252
+ and properly configured. Use this to troubleshoot installation issues.
249
253
 
250
254
  Examples:
251
- mcp-vector-search add-favorite "authentication functions"
252
- mcp-vector-search add-favorite "error handling" --desc "Error handling patterns"
255
+ mcp-vector-search doctor
253
256
  """
254
- from .history import SearchHistory
257
+ from .commands.status import check_dependencies
255
258
 
256
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
257
- history_manager = SearchHistory(root)
258
- history_manager.add_favorite(query, description)
259
+ console.print("[bold blue]🩺 MCP Vector Search - System Check[/bold blue]\n")
259
260
 
261
+ # Check dependencies
262
+ deps_ok = check_dependencies()
260
263
 
261
- @app.command("remove-favorite")
262
- def remove_favorite(
263
- ctx: typer.Context,
264
- query: str = typer.Argument(..., help="Query to remove from favorites"),
265
- project_root: Path | None = typer.Option(
266
- None, "--project-root", "-p", help="Project root directory"
264
+ if deps_ok:
265
+ console.print("\n[green]✓ All dependencies are available[/green]")
266
+ else:
267
+ console.print("\n[red]✗ Some dependencies are missing[/red]")
268
+ console.print(
269
+ "Run [code]pip install mcp-vector-search[/code] to install missing dependencies"
270
+ )
271
+
272
+
273
+ @app.command("help")
274
+ def help_command(
275
+ command: str | None = typer.Argument(
276
+ None, help="Command to get help for (optional)"
267
277
  ),
268
278
  ) -> None:
269
- """Remove a query from favorites.
279
+ """ Show contextual help and suggestions.
270
280
 
271
- Remove a previously saved favorite query from your favorites list.
281
+ Get detailed help about specific commands or general usage guidance
282
+ based on your project state.
272
283
 
273
284
  Examples:
274
- mcp-vector-search remove-favorite "authentication functions"
285
+ mcp-vector-search help # General help
286
+ mcp-vector-search help search # Help for search command
287
+ mcp-vector-search help init # Help for init command
275
288
  """
276
- from .history import SearchHistory
289
+ try:
290
+ project_root = Path.cwd()
291
+ console.print(
292
+ f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green]"
293
+ )
294
+ console.print("[dim]CLI-first semantic code search with MCP integration[/dim]")
277
295
 
278
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
279
- history_manager = SearchHistory(root)
280
- history_manager.remove_favorite(query)
296
+ if command:
297
+ # Show help for specific command
298
+ console.print(
299
+ f"\n[dim]Run: [bold]mcp-vector-search {command} --help[/bold] for detailed help[/dim]"
300
+ )
301
+ else:
302
+ # Show general contextual suggestions
303
+ get_contextual_suggestions(project_root)
304
+ except Exception as e:
305
+ logger.debug(f"Failed to show contextual help: {e}")
306
+ console.print(
307
+ "\n[dim]Use [bold]mcp-vector-search --help[/bold] for more information.[/dim]"
308
+ )
309
+
310
+
311
+ @app.command("version")
312
+ def version_command() -> None:
313
+ """ℹ️ Show version information."""
314
+ console.print(
315
+ f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green] [dim](build {__build__})[/dim]"
316
+ )
317
+ console.print("\n[dim]CLI-first semantic code search with MCP integration[/dim]")
318
+ console.print("[dim]Built with ChromaDB, Tree-sitter, and modern Python[/dim]")
281
319
 
282
320
 
283
321
  @app.callback()
@@ -338,93 +376,10 @@ def main(
338
376
  if project_root:
339
377
  logger.info(f"Using project root: {project_root}")
340
378
 
341
- # Note: Contextual help moved to a separate command to avoid interfering with didyoumean
342
-
343
-
344
- @app.command()
345
- def version() -> None:
346
- """Show version information."""
347
- console.print(
348
- f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green] [dim](build {__build__})[/dim]"
349
- )
350
- console.print("\n[dim]CLI-first semantic code search with MCP integration[/dim]")
351
- console.print("[dim]Built with ChromaDB, Tree-sitter, and modern Python[/dim]")
352
-
353
-
354
- def handle_command_error(ctx, param, value):
355
- """Handle command errors with enhanced suggestions."""
356
- if ctx.resilient_parsing:
357
- return
358
-
359
- # This will be called when a command is not found
360
- import click
361
-
362
- try:
363
- return value
364
- except click.UsageError as e:
365
- if "No such command" in str(e):
366
- # Extract the command name from the error
367
- import re
368
-
369
- match = re.search(r"No such command '([^']+)'", str(e))
370
- if match:
371
- command_name = match.group(1)
372
-
373
- # Use both the original suggestions and contextual suggestions
374
- add_common_suggestions(ctx, command_name)
375
-
376
- # Add contextual suggestions based on project state
377
- try:
378
- project_root = ctx.obj.get("project_root") if ctx.obj else None
379
- get_contextual_suggestions(project_root, command_name)
380
- except Exception as e:
381
- # If contextual suggestions fail, don't break the error flow
382
- logger.debug(f"Failed to get contextual suggestions: {e}")
383
- pass
384
- raise
385
-
386
-
387
- @app.command()
388
- def help_contextual() -> None:
389
- """Show contextual help and suggestions based on project state."""
390
- try:
391
- project_root = Path.cwd()
392
- console.print(
393
- f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green]"
394
- )
395
- console.print("[dim]CLI-first semantic code search with MCP integration[/dim]")
396
- get_contextual_suggestions(project_root)
397
- except Exception as e:
398
- logger.debug(f"Failed to show contextual help: {e}")
399
- console.print(
400
- "\n[dim]Use [bold]mcp-vector-search --help[/bold] for more information.[/dim]"
401
- )
402
-
403
-
404
- @app.command()
405
- def doctor() -> None:
406
- """Check system dependencies and configuration.
407
-
408
- Runs diagnostic checks to ensure all required dependencies are installed
409
- and properly configured. Use this command to troubleshoot installation issues.
410
-
411
- Examples:
412
- mcp-vector-search doctor
413
- """
414
- from .commands.status import check_dependencies
415
-
416
- console.print("[bold blue]MCP Vector Search - System Check[/bold blue]\n")
417
379
 
418
- # Check dependencies
419
- deps_ok = check_dependencies()
420
-
421
- if deps_ok:
422
- console.print("\n[green]✓ All dependencies are available[/green]")
423
- else:
424
- console.print("\n[red]✗ Some dependencies are missing[/red]")
425
- console.print(
426
- "Run [code]pip install mcp-vector-search[/code] to install missing dependencies"
427
- )
380
+ # ============================================================================
381
+ # CLI ENTRY POINT WITH ERROR HANDLING
382
+ # ============================================================================
428
383
 
429
384
 
430
385
  def cli_with_suggestions():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-vector-search
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: CLI-first semantic code search with MCP integration
5
5
  Project-URL: Homepage, https://github.com/bobmatnyc/mcp-vector-search
6
6
  Project-URL: Documentation, https://mcp-vector-search.readthedocs.io
@@ -1,22 +1,22 @@
1
- mcp_vector_search/__init__.py,sha256=WdjRcgYzYCEwrp2yc382O83RTxum5rX2oE_-xoPhV_8,299
1
+ mcp_vector_search/__init__.py,sha256=ho6kD5LiKg5_bjlfaFha23peWF_iCKd3FsCslGTEpsQ,299
2
2
  mcp_vector_search/py.typed,sha256=lCKeV9Qcn9sGtbRsgg-LJO2ZwWRuknnnlmomq3bJFH0,43
3
3
  mcp_vector_search/cli/__init__.py,sha256=TNB7CaOASz8u3yHWLbNmo8-GtHF0qwUjVKWAuNphKgo,40
4
4
  mcp_vector_search/cli/didyoumean.py,sha256=F_ss-EX4F9RgnMsEhdTwLpyNCah9SqnBZc2tBtzASck,15918
5
5
  mcp_vector_search/cli/export.py,sha256=iluxuRT2KELdKlQeDAlVkteiel4GGrng153UAw9H0as,10804
6
6
  mcp_vector_search/cli/history.py,sha256=6wRrSfxpUe9hJXuaEeVxOVkFlcpqkIiGfwzDgd5N6c8,9323
7
7
  mcp_vector_search/cli/interactive.py,sha256=T7P4dAdvbglznzQYgiePv5YNyOx9FeE57Y3OKYnnbYE,12744
8
- mcp_vector_search/cli/main.py,sha256=VsW2U-E-_9jB6UfA4vTE0K-d657WZyLyIM2hvXgre9c,17057
8
+ mcp_vector_search/cli/main.py,sha256=iUixejFrC7HO6m-0tzPWu_LXTScvg1Zg_nUZkEpDroQ,14660
9
9
  mcp_vector_search/cli/output.py,sha256=7ShIk_UKzhDzRGxI6JluPu0gGkbmKOevqgIAKR4oCa0,12560
10
10
  mcp_vector_search/cli/suggestions.py,sha256=h-UaxoLcHmFbhZSm0WG7nKJXAIRIqhv7aGsXijp7vA8,13273
11
11
  mcp_vector_search/cli/commands/__init__.py,sha256=vQls-YKZ54YEwmf7g1dL0T2SS9D4pdQljXzsUChG_V4,42
12
12
  mcp_vector_search/cli/commands/auto_index.py,sha256=imVVbxWRlA128NPdK9BetNNl3ELrsdq-hqcsLqyAmoM,12712
13
- mcp_vector_search/cli/commands/config.py,sha256=EHLqToCXrZs3gjIAg7pV8Bq8yVslUXWC4AnTcZQgSPQ,11337
14
- mcp_vector_search/cli/commands/index.py,sha256=soupoLR3EBsSzjqvzxurT9I6A8ZYM9asWVmJY3bDqMI,15394
13
+ mcp_vector_search/cli/commands/config.py,sha256=mKE8gUgAOqCM__4yzEEu9HJPbx9X15lN264zkDJBRxg,12399
14
+ mcp_vector_search/cli/commands/index.py,sha256=AWQk_nc5vOW0nxy2yjRre_2uktA4J32D-302IS3dT3M,17862
15
15
  mcp_vector_search/cli/commands/init.py,sha256=1kK2YmWnMCnAmWjI3Om3d_NE89APisL-vvUFfKcyp2I,26408
16
16
  mcp_vector_search/cli/commands/install.py,sha256=phk7Eb7UOU5IsRfJyaDPdOfdUWli9gyA4cHjhgXcNEI,24609
17
17
  mcp_vector_search/cli/commands/mcp.py,sha256=FKZNxYrDc7HfPTFBUEypCv-8atsrHEdbtU6Yfg9QUMA,18569
18
18
  mcp_vector_search/cli/commands/reset.py,sha256=bsIT6zjDf6gsvIkVaRaUClYzlTyNe--8t0NWkBY0ldU,13724
19
- mcp_vector_search/cli/commands/search.py,sha256=JFEkXQjevx2XZJhHTH8xy7G7XVcH5nGazJfacKSyEA4,20650
19
+ mcp_vector_search/cli/commands/search.py,sha256=yyou7wO9qZ_w2oiKdyOrk2WUxvkFpc-Up8hpflxYlyw,24802
20
20
  mcp_vector_search/cli/commands/status.py,sha256=7ro6M3aifV0cuCqqxJ278P9g-fbhzvjoOABUoitMrPo,18929
21
21
  mcp_vector_search/cli/commands/watch.py,sha256=2pyWRoo4fIppFnyQ4sW4IBLHmpb_IwnTjRnzHkVBPcQ,8927
22
22
  mcp_vector_search/config/__init__.py,sha256=r_qAQkU5gc0EQ2pv8EQARACe4klhrR_WRJqCb9lfGc0,54
@@ -55,8 +55,8 @@ mcp_vector_search/utils/__init__.py,sha256=Eq6lY-oPMfCt-GpPUbg9QbmTHuQVmTaVDBMU2
55
55
  mcp_vector_search/utils/gitignore.py,sha256=bzie3V5gOGIN7j3FNVLLCx8O_hfZJDUqqAy5T3lT3Ek,7685
56
56
  mcp_vector_search/utils/timing.py,sha256=THC7mfbTYnUpnnDcblgQacYMzbEkfFoIShx6plmhCgg,11285
57
57
  mcp_vector_search/utils/version.py,sha256=d7fS-CLemxb8UzZ9j18zH0Y0Ud097ljKKYYOPulnGPE,1138
58
- mcp_vector_search-0.6.0.dist-info/METADATA,sha256=do--B4P_ROSsUmBn1n9xsO8ANdVOXkSYAcqY2YF_c7w,19120
59
- mcp_vector_search-0.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
60
- mcp_vector_search-0.6.0.dist-info/entry_points.txt,sha256=y3Ygtc_JiBchNEIL-tPABo7EbzBExGAxwGdkkeP5D2I,86
61
- mcp_vector_search-0.6.0.dist-info/licenses/LICENSE,sha256=FqZUgGJH_tZKZLQsMCpXaLawRyLmyFKRVfMwYyEcyTs,1072
62
- mcp_vector_search-0.6.0.dist-info/RECORD,,
58
+ mcp_vector_search-0.7.0.dist-info/METADATA,sha256=OPh6-HFukz8BtVkxPBP7yHps009YlISZthb8oHv2YS0,19120
59
+ mcp_vector_search-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
60
+ mcp_vector_search-0.7.0.dist-info/entry_points.txt,sha256=y3Ygtc_JiBchNEIL-tPABo7EbzBExGAxwGdkkeP5D2I,86
61
+ mcp_vector_search-0.7.0.dist-info/licenses/LICENSE,sha256=FqZUgGJH_tZKZLQsMCpXaLawRyLmyFKRVfMwYyEcyTs,1072
62
+ mcp_vector_search-0.7.0.dist-info/RECORD,,