mcp-vector-search 0.6.1__py3-none-any.whl → 0.7.2__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.1"
4
- __build__ = "21"
3
+ __version__ = "0.7.2"
4
+ __build__ = "24"
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()
@@ -495,5 +495,87 @@ async def _clean_index(project_root: Path) -> None:
495
495
  print_success("Index cleaned successfully")
496
496
 
497
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
+
498
580
  if __name__ == "__main__":
499
581
  index_app()
@@ -27,9 +27,14 @@ from ..output import (
27
27
  )
28
28
 
29
29
  # Create init subcommand app
30
- init_app = typer.Typer(help="Initialize project for semantic search")
30
+ init_app = typer.Typer(
31
+ help="Initialize project for semantic search",
32
+ invoke_without_command=True,
33
+ no_args_is_help=False,
34
+ )
31
35
 
32
36
 
37
+ @init_app.callback()
33
38
  def main(
34
39
  ctx: typer.Context,
35
40
  config_file: Path | None = typer.Option(
@@ -126,6 +131,10 @@ def main(
126
131
  [dim]💡 Tip: The command creates .mcp-vector-search/ for project config
127
132
  and .mcp.json for MCP integration.[/dim]
128
133
  """
134
+ # Only run main logic if no subcommand was invoked
135
+ if ctx.invoked_subcommand is not None:
136
+ return
137
+
129
138
  try:
130
139
  # Get project root from context or auto-detect
131
140
  project_root = ctx.obj.get("project_root")
@@ -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,289 @@ 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.mcp import mcp_app # noqa: E402
57
+ from .commands.search import search_app, search_main # noqa: E402, F401
80
58
  from .commands.status import main as status_main # noqa: E402
81
59
 
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)
60
+ # ============================================================================
61
+ # MAIN COMMANDS - Clean hierarchy
62
+ # ============================================================================
63
+
64
+ # 1. INIT - Initialize project
65
+ # Use Typer group for init to support both direct call and subcommands
66
+ app.add_typer(init_app, name="init", help="🔧 Initialize project for semantic search")
67
+
68
+ # 2. DOCTOR - System health check
69
+ # (defined below inline)
70
+
71
+ # 3. STATUS - Project status
85
72
  app.command("status", help="📊 Show project status and statistics")(status_main)
86
- # Register init as a direct command
87
- 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
- )
113
73
 
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)
74
+ # 4. SEARCH - Search code
75
+ # Register search as both a command and a typer group
76
+ app.add_typer(search_app, name="search", help="🔍 Search code semantically")
157
77
 
78
+ # 5. INDEX - Index codebase
79
+ app.add_typer(index_app, name="index", help="📇 Index codebase for semantic search")
158
80
 
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.
81
+ # 6. MCP - MCP integration
82
+ app.add_typer(mcp_app, name="mcp", help="🤖 Manage Claude Code MCP integration")
168
83
 
169
- The interactive mode provides a rich terminal interface for searching your codebase
170
- with real-time filtering, query refinement, and result navigation.
84
+ # 7. CONFIG - Configuration
85
+ app.add_typer(config_app, name="config", help="⚙️ Manage project configuration")
171
86
 
172
- Examples:
173
- mcp-vector-search interactive
174
- mcp-vector-search interactive --project-root /path/to/project
175
- """
176
- import asyncio
87
+ # 8. HELP - Enhanced help
88
+ # (defined below inline)
177
89
 
178
- from .interactive import start_interactive_search
90
+ # 9. VERSION - Version info
91
+ # (defined below inline)
179
92
 
180
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
181
93
 
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}")
94
+ # ============================================================================
95
+ # DEPRECATED COMMANDS - With helpful suggestions
96
+ # ============================================================================
97
+
98
+
99
+ def _deprecated_command(old_cmd: str, new_cmd: str):
100
+ """Helper to create deprecated command with suggestion."""
101
+
102
+ def wrapper(*args, **kwargs):
103
+ print_warning(
104
+ f"⚠️ The command '{old_cmd}' is deprecated.\n"
105
+ f" Please use '{new_cmd}' instead.\n"
106
+ f" Run: [cyan]mcp-vector-search {new_cmd} --help[/cyan] for details."
107
+ )
188
108
  raise typer.Exit(1)
189
109
 
110
+ return wrapper
190
111
 
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
112
 
202
- Displays your recent search queries with timestamps and result counts.
203
- Use this to revisit previous searches or track your search patterns.
113
+ # Deprecated: install -> init
114
+ @app.command("install", hidden=True)
115
+ def deprecated_install():
116
+ """[DEPRECATED] Use 'init' instead."""
117
+ _deprecated_command("install", "init")()
204
118
 
205
- Examples:
206
- mcp-vector-search history
207
- mcp-vector-search history --limit 50
208
- """
209
- from .history import show_search_history
210
119
 
211
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
212
- show_search_history(root, limit)
120
+ # Deprecated: demo -> removed
121
+ @app.command("demo", hidden=True)
122
+ def deprecated_demo():
123
+ """[DEPRECATED] Command removed."""
124
+ print_warning(
125
+ "⚠️ The 'demo' command has been removed.\n"
126
+ " Use [cyan]mcp-vector-search init --help[/cyan] for setup instructions."
127
+ )
128
+ raise typer.Exit(1)
213
129
 
214
130
 
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.
131
+ # Deprecated: find -> search
132
+ @app.command("find", hidden=True)
133
+ def deprecated_find():
134
+ """[DEPRECATED] Use 'search' instead."""
135
+ _deprecated_command("find", "search")()
223
136
 
224
- Displays your saved favorite search queries. Favorites allow you to quickly
225
- access frequently used searches without typing them again.
226
137
 
227
- Examples:
228
- mcp-vector-search favorites
229
- """
230
- from .history import show_favorites
138
+ # Deprecated: search-similar -> search --similar
139
+ @app.command("search-similar", hidden=True)
140
+ def deprecated_search_similar():
141
+ """[DEPRECATED] Use 'search --similar' instead."""
142
+ _deprecated_command("search-similar", "search --similar")()
231
143
 
232
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
233
- show_favorites(root)
234
144
 
145
+ # Deprecated: search-context -> search --context
146
+ @app.command("search-context", hidden=True)
147
+ def deprecated_search_context():
148
+ """[DEPRECATED] Use 'search --context' instead."""
149
+ _deprecated_command("search-context", "search --context")()
150
+
151
+
152
+ # Deprecated: interactive -> search interactive
153
+ @app.command("interactive", hidden=True)
154
+ def deprecated_interactive():
155
+ """[DEPRECATED] Use 'search interactive' instead."""
156
+ _deprecated_command("interactive", "search interactive")()
157
+
158
+
159
+ # Deprecated: history -> search history
160
+ @app.command("history", hidden=True)
161
+ def deprecated_history():
162
+ """[DEPRECATED] Use 'search history' instead."""
163
+ _deprecated_command("history", "search history")()
164
+
165
+
166
+ # Deprecated: favorites -> search favorites
167
+ @app.command("favorites", hidden=True)
168
+ def deprecated_favorites():
169
+ """[DEPRECATED] Use 'search favorites' instead."""
170
+ _deprecated_command("favorites", "search favorites")()
171
+
172
+
173
+ # Deprecated: add-favorite -> search favorites add
174
+ @app.command("add-favorite", hidden=True)
175
+ def deprecated_add_favorite():
176
+ """[DEPRECATED] Use 'search favorites add' instead."""
177
+ _deprecated_command("add-favorite", "search favorites add")()
178
+
179
+
180
+ # Deprecated: remove-favorite -> search favorites remove
181
+ @app.command("remove-favorite", hidden=True)
182
+ def deprecated_remove_favorite():
183
+ """[DEPRECATED] Use 'search favorites remove' instead."""
184
+ _deprecated_command("remove-favorite", "search favorites remove")()
185
+
186
+
187
+ # Deprecated: health -> index health
188
+ @app.command("health", hidden=True)
189
+ def deprecated_health():
190
+ """[DEPRECATED] Use 'index health' instead."""
191
+ _deprecated_command("health", "index health")()
192
+
193
+
194
+ # Deprecated: watch -> index watch
195
+ @app.command("watch", hidden=True)
196
+ def deprecated_watch():
197
+ """[DEPRECATED] Use 'index watch' instead."""
198
+ _deprecated_command("watch", "index watch")()
199
+
200
+
201
+ # Deprecated: auto-index -> index auto
202
+ @app.command("auto-index", hidden=True)
203
+ def deprecated_auto_index():
204
+ """[DEPRECATED] Use 'index auto' instead."""
205
+ _deprecated_command("auto-index", "index auto")()
206
+
207
+
208
+ # Deprecated: reset -> mcp reset or config reset
209
+ @app.command("reset", hidden=True)
210
+ def deprecated_reset():
211
+ """[DEPRECATED] Use 'mcp reset' or 'config reset' instead."""
212
+ print_warning(
213
+ "⚠️ The 'reset' command is deprecated.\n"
214
+ " Use [cyan]mcp-vector-search mcp reset[/cyan] for MCP reset\n"
215
+ " Use [cyan]mcp-vector-search config reset[/cyan] for config reset"
216
+ )
217
+ raise typer.Exit(1)
235
218
 
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
219
 
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.
220
+ # Deprecated: init-check -> init check
221
+ @app.command("init-check", hidden=True)
222
+ def deprecated_init_check():
223
+ """[DEPRECATED] Use 'init check' instead."""
224
+ _deprecated_command("init-check", "init check")()
225
+
226
+
227
+ # Deprecated: init-mcp -> mcp install
228
+ @app.command("init-mcp", hidden=True)
229
+ def deprecated_init_mcp():
230
+ """[DEPRECATED] Use 'mcp install' instead."""
231
+ _deprecated_command("init-mcp", "mcp install")()
232
+
233
+
234
+ # Deprecated: init-models -> config models
235
+ @app.command("init-models", hidden=True)
236
+ def deprecated_init_models():
237
+ """[DEPRECATED] Use 'config models' instead."""
238
+ _deprecated_command("init-models", "config models")()
239
+
240
+
241
+ # ============================================================================
242
+ # MAIN INLINE COMMANDS
243
+ # ============================================================================
244
+
245
+
246
+ @app.command("doctor")
247
+ def doctor_command() -> None:
248
+ """🩺 Check system dependencies and configuration.
249
+
250
+ Runs diagnostic checks to ensure all required dependencies are installed
251
+ and properly configured. Use this to troubleshoot installation issues.
249
252
 
250
253
  Examples:
251
- mcp-vector-search add-favorite "authentication functions"
252
- mcp-vector-search add-favorite "error handling" --desc "Error handling patterns"
254
+ mcp-vector-search doctor
253
255
  """
254
- from .history import SearchHistory
256
+ from .commands.status import check_dependencies
255
257
 
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)
258
+ console.print("[bold blue]🩺 MCP Vector Search - System Check[/bold blue]\n")
259
259
 
260
+ # Check dependencies
261
+ deps_ok = check_dependencies()
260
262
 
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"
263
+ if deps_ok:
264
+ console.print("\n[green]✓ All dependencies are available[/green]")
265
+ else:
266
+ console.print("\n[red]✗ Some dependencies are missing[/red]")
267
+ console.print(
268
+ "Run [code]pip install mcp-vector-search[/code] to install missing dependencies"
269
+ )
270
+
271
+
272
+ @app.command("help")
273
+ def help_command(
274
+ command: str | None = typer.Argument(
275
+ None, help="Command to get help for (optional)"
267
276
  ),
268
277
  ) -> None:
269
- """Remove a query from favorites.
278
+ """ Show contextual help and suggestions.
270
279
 
271
- Remove a previously saved favorite query from your favorites list.
280
+ Get detailed help about specific commands or general usage guidance
281
+ based on your project state.
272
282
 
273
283
  Examples:
274
- mcp-vector-search remove-favorite "authentication functions"
284
+ mcp-vector-search help # General help
285
+ mcp-vector-search help search # Help for search command
286
+ mcp-vector-search help init # Help for init command
275
287
  """
276
- from .history import SearchHistory
288
+ try:
289
+ project_root = Path.cwd()
290
+ console.print(
291
+ f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green]"
292
+ )
293
+ console.print("[dim]CLI-first semantic code search with MCP integration[/dim]")
277
294
 
278
- root = project_root or ctx.obj.get("project_root") or Path.cwd()
279
- history_manager = SearchHistory(root)
280
- history_manager.remove_favorite(query)
295
+ if command:
296
+ # Show help for specific command
297
+ console.print(
298
+ f"\n[dim]Run: [bold]mcp-vector-search {command} --help[/bold] for detailed help[/dim]"
299
+ )
300
+ else:
301
+ # Show general contextual suggestions
302
+ get_contextual_suggestions(project_root)
303
+ except Exception as e:
304
+ logger.debug(f"Failed to show contextual help: {e}")
305
+ console.print(
306
+ "\n[dim]Use [bold]mcp-vector-search --help[/bold] for more information.[/dim]"
307
+ )
308
+
309
+
310
+ @app.command("version")
311
+ def version_command() -> None:
312
+ """ℹ️ Show version information."""
313
+ console.print(
314
+ f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green] [dim](build {__build__})[/dim]"
315
+ )
316
+ console.print("\n[dim]CLI-first semantic code search with MCP integration[/dim]")
317
+ console.print("[dim]Built with ChromaDB, Tree-sitter, and modern Python[/dim]")
281
318
 
282
319
 
283
320
  @app.callback()
@@ -338,93 +375,10 @@ def main(
338
375
  if project_root:
339
376
  logger.info(f"Using project root: {project_root}")
340
377
 
341
- # Note: Contextual help moved to a separate command to avoid interfering with didyoumean
342
-
343
378
 
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
-
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
- )
379
+ # ============================================================================
380
+ # CLI ENTRY POINT WITH ERROR HANDLING
381
+ # ============================================================================
428
382
 
429
383
 
430
384
  def cli_with_suggestions():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-vector-search
3
- Version: 0.6.1
3
+ Version: 0.7.2
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
@@ -63,7 +63,7 @@ Description-Content-Type: text/markdown
63
63
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
64
64
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
65
65
 
66
- > ⚠️ **Alpha Release (v0.6.0)**: This is an early-stage project under active development. Expect breaking changes and rough edges. Feedback and contributions are welcome!
66
+ > ⚠️ **Alpha Release (v0.7.1)**: This is an early-stage project under active development. Expect breaking changes and rough edges. Feedback and contributions are welcome!
67
67
 
68
68
  A modern, fast, and intelligent code search tool that understands your codebase through semantic analysis and AST parsing. Built with Python, powered by ChromaDB, and designed for developer productivity.
69
69
 
@@ -1,22 +1,22 @@
1
- mcp_vector_search/__init__.py,sha256=7RjW6QzohQ-IjqQ-eJnvKjAlZ7tIsfxbJILz4NVfxFA,299
1
+ mcp_vector_search/__init__.py,sha256=tIFqRnEICQ-gzROWyTGRNKs2S3M0l39WR3wt9tZuMjA,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=ZmTuPFIIqiZzn7Ml04EkzgNveBm4uIXe0kA6t4jysB8,14602
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=haEj8MfCzHvv4wGaPryd01aJKFt_AGGT-zwyvSnp9fQ,15639
15
- mcp_vector_search/cli/commands/init.py,sha256=1kK2YmWnMCnAmWjI3Om3d_NE89APisL-vvUFfKcyp2I,26408
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
+ mcp_vector_search/cli/commands/init.py,sha256=D2nuJ4yrcL_6xeAjpcbYBVOO8aruTduy5E3mKlbtA4Y,26610
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.1.dist-info/METADATA,sha256=C_UHz8WxHNfvbm2YMNmvhvC8PFFaF4nBCueGUq1pKQA,19120
59
- mcp_vector_search-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
60
- mcp_vector_search-0.6.1.dist-info/entry_points.txt,sha256=y3Ygtc_JiBchNEIL-tPABo7EbzBExGAxwGdkkeP5D2I,86
61
- mcp_vector_search-0.6.1.dist-info/licenses/LICENSE,sha256=FqZUgGJH_tZKZLQsMCpXaLawRyLmyFKRVfMwYyEcyTs,1072
62
- mcp_vector_search-0.6.1.dist-info/RECORD,,
58
+ mcp_vector_search-0.7.2.dist-info/METADATA,sha256=4CqoR4Fb4entY138D68UMZeQBp0Fd7d3fW1Y__sl7aY,19120
59
+ mcp_vector_search-0.7.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
60
+ mcp_vector_search-0.7.2.dist-info/entry_points.txt,sha256=y3Ygtc_JiBchNEIL-tPABo7EbzBExGAxwGdkkeP5D2I,86
61
+ mcp_vector_search-0.7.2.dist-info/licenses/LICENSE,sha256=FqZUgGJH_tZKZLQsMCpXaLawRyLmyFKRVfMwYyEcyTs,1072
62
+ mcp_vector_search-0.7.2.dist-info/RECORD,,