mcp-vector-search 0.4.13__py3-none-any.whl → 0.5.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.
- mcp_vector_search/__init__.py +2 -2
- mcp_vector_search/cli/commands/index.py +73 -31
- mcp_vector_search/cli/commands/init.py +189 -113
- mcp_vector_search/cli/commands/install.py +525 -113
- mcp_vector_search/cli/commands/mcp.py +201 -151
- mcp_vector_search/cli/commands/reset.py +41 -41
- mcp_vector_search/cli/commands/search.py +73 -14
- mcp_vector_search/cli/commands/status.py +51 -17
- mcp_vector_search/cli/didyoumean.py +254 -246
- mcp_vector_search/cli/main.py +171 -52
- mcp_vector_search/cli/output.py +152 -0
- mcp_vector_search/cli/suggestions.py +246 -197
- mcp_vector_search/core/database.py +81 -49
- mcp_vector_search/core/indexer.py +10 -4
- mcp_vector_search/core/search.py +17 -6
- mcp_vector_search/mcp/__main__.py +1 -1
- mcp_vector_search/mcp/server.py +211 -203
- mcp_vector_search/parsers/__init__.py +6 -0
- mcp_vector_search/parsers/dart.py +605 -0
- mcp_vector_search/parsers/php.py +694 -0
- mcp_vector_search/parsers/registry.py +16 -1
- mcp_vector_search/parsers/ruby.py +678 -0
- mcp_vector_search/parsers/text.py +31 -25
- mcp_vector_search/utils/gitignore.py +72 -71
- {mcp_vector_search-0.4.13.dist-info → mcp_vector_search-0.5.0.dist-info}/METADATA +59 -2
- {mcp_vector_search-0.4.13.dist-info → mcp_vector_search-0.5.0.dist-info}/RECORD +29 -26
- {mcp_vector_search-0.4.13.dist-info → mcp_vector_search-0.5.0.dist-info}/WHEEL +0 -0
- {mcp_vector_search-0.4.13.dist-info → mcp_vector_search-0.5.0.dist-info}/entry_points.txt +0 -0
- {mcp_vector_search-0.4.13.dist-info → mcp_vector_search-0.5.0.dist-info}/licenses/LICENSE +0 -0
mcp_vector_search/cli/main.py
CHANGED
|
@@ -12,14 +12,17 @@ from .commands.auto_index import auto_index_app
|
|
|
12
12
|
from .commands.config import config_app
|
|
13
13
|
from .commands.index import index_app
|
|
14
14
|
from .commands.init import (
|
|
15
|
-
init_app,
|
|
16
|
-
main as init_main,
|
|
17
15
|
check_initialization as init_check,
|
|
16
|
+
)
|
|
17
|
+
from .commands.init import (
|
|
18
18
|
init_mcp_integration,
|
|
19
19
|
list_embedding_models,
|
|
20
20
|
)
|
|
21
|
-
from .commands.
|
|
21
|
+
from .commands.init import (
|
|
22
|
+
main as init_main,
|
|
23
|
+
)
|
|
22
24
|
from .commands.mcp import mcp_app
|
|
25
|
+
from .commands.reset import health_main, reset_app
|
|
23
26
|
from .commands.search import (
|
|
24
27
|
search_app,
|
|
25
28
|
search_context_cmd,
|
|
@@ -28,10 +31,9 @@ from .commands.search import (
|
|
|
28
31
|
)
|
|
29
32
|
from .commands.status import status_app
|
|
30
33
|
from .commands.watch import app as watch_app
|
|
31
|
-
from .
|
|
32
|
-
from .didyoumean import create_enhanced_typer, add_common_suggestions
|
|
33
|
-
from .suggestions import get_contextual_suggestions, ContextualSuggestionProvider
|
|
34
|
+
from .didyoumean import add_common_suggestions, create_enhanced_typer
|
|
34
35
|
from .output import print_error, setup_logging
|
|
36
|
+
from .suggestions import get_contextual_suggestions
|
|
35
37
|
|
|
36
38
|
# Install rich traceback handler
|
|
37
39
|
install(show_locals=True)
|
|
@@ -42,15 +44,41 @@ console = Console()
|
|
|
42
44
|
# Create main Typer app with "did you mean" functionality
|
|
43
45
|
app = create_enhanced_typer(
|
|
44
46
|
name="mcp-vector-search",
|
|
45
|
-
help="
|
|
47
|
+
help="""
|
|
48
|
+
🔍 [bold]CLI-first semantic code search with MCP integration[/bold]
|
|
49
|
+
|
|
50
|
+
Semantic search finds code by meaning, not just keywords. Perfect for exploring
|
|
51
|
+
unfamiliar codebases, finding similar patterns, and integrating with AI tools.
|
|
52
|
+
|
|
53
|
+
[bold cyan]Quick Start:[/bold cyan]
|
|
54
|
+
1. Initialize: [green]mcp-vector-search init[/green]
|
|
55
|
+
2. Search code: [green]mcp-vector-search search "your query"[/green]
|
|
56
|
+
3. Check status: [green]mcp-vector-search status[/green]
|
|
57
|
+
|
|
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]
|
|
71
|
+
""",
|
|
46
72
|
add_completion=False,
|
|
47
73
|
rich_markup_mode="rich",
|
|
48
74
|
)
|
|
49
75
|
|
|
50
76
|
# Import command functions for direct registration and aliases
|
|
51
|
-
from .commands.install import main as install_main, demo as install_demo
|
|
52
|
-
from .commands.status import main as status_main
|
|
53
77
|
from .commands.index import main as index_main
|
|
78
|
+
from .commands.install import demo as install_demo
|
|
79
|
+
from .commands.install import main as install_main
|
|
80
|
+
from .commands.status import main as status_main
|
|
81
|
+
|
|
54
82
|
# Note: config doesn't have a main function, it uses subcommands via config_app
|
|
55
83
|
app.command("install", help="🚀 Install mcp-vector-search in projects")(install_main)
|
|
56
84
|
app.command("demo", help="🎬 Run installation demo with sample project")(install_demo)
|
|
@@ -59,8 +87,12 @@ app.command("status", help="📊 Show project status and statistics")(status_mai
|
|
|
59
87
|
app.command("init", help="🔧 Initialize project for semantic search")(init_main)
|
|
60
88
|
# Add init subcommands as separate commands
|
|
61
89
|
app.command("init-check", help="Check if project is initialized")(init_check)
|
|
62
|
-
app.command("init-mcp", help="Install/fix Claude Code MCP integration")(
|
|
63
|
-
|
|
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
|
+
)
|
|
64
96
|
app.add_typer(index_app, name="index", help="Index codebase for semantic search")
|
|
65
97
|
app.add_typer(config_app, name="config", help="Manage project configuration")
|
|
66
98
|
app.add_typer(watch_app, name="watch", help="Watch for file changes and update index")
|
|
@@ -72,23 +104,43 @@ app.add_typer(reset_app, name="reset", help="Reset and recovery operations")
|
|
|
72
104
|
app.command("search", help="Search code semantically")(search_main)
|
|
73
105
|
|
|
74
106
|
# Keep old nested structure for backward compatibility
|
|
75
|
-
app.add_typer(
|
|
76
|
-
|
|
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
|
+
)
|
|
77
113
|
|
|
78
114
|
# Add command aliases for better user experience
|
|
79
115
|
app.command("find", help="Search code semantically (alias for search)")(search_main)
|
|
80
|
-
app.command("f", help="Search code semantically (short alias)", hidden=True)(
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
83
125
|
|
|
84
126
|
# Index aliases
|
|
85
|
-
app.command("i", help="Index codebase (short alias)", hidden=True)(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
app.command("
|
|
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
|
|
92
144
|
|
|
93
145
|
# Config aliases - Since config uses subcommands, these will be handled by the enhanced typer error resolution
|
|
94
146
|
# app.command("c", help="Manage configuration (short alias)", hidden=True) # Will be handled by typo resolution
|
|
@@ -112,7 +164,15 @@ def interactive_search(
|
|
|
112
164
|
None, "--project-root", "-p", help="Project root directory"
|
|
113
165
|
),
|
|
114
166
|
) -> None:
|
|
115
|
-
"""Start an interactive search session with filtering and refinement.
|
|
167
|
+
"""Start an interactive search session with filtering and refinement.
|
|
168
|
+
|
|
169
|
+
The interactive mode provides a rich terminal interface for searching your codebase
|
|
170
|
+
with real-time filtering, query refinement, and result navigation.
|
|
171
|
+
|
|
172
|
+
Examples:
|
|
173
|
+
mcp-vector-search interactive
|
|
174
|
+
mcp-vector-search interactive --project-root /path/to/project
|
|
175
|
+
"""
|
|
116
176
|
import asyncio
|
|
117
177
|
|
|
118
178
|
from .interactive import start_interactive_search
|
|
@@ -137,7 +197,15 @@ def show_history(
|
|
|
137
197
|
None, "--project-root", "-p", help="Project root directory"
|
|
138
198
|
),
|
|
139
199
|
) -> None:
|
|
140
|
-
"""Show search history.
|
|
200
|
+
"""Show search history.
|
|
201
|
+
|
|
202
|
+
Displays your recent search queries with timestamps and result counts.
|
|
203
|
+
Use this to revisit previous searches or track your search patterns.
|
|
204
|
+
|
|
205
|
+
Examples:
|
|
206
|
+
mcp-vector-search history
|
|
207
|
+
mcp-vector-search history --limit 50
|
|
208
|
+
"""
|
|
141
209
|
from .history import show_search_history
|
|
142
210
|
|
|
143
211
|
root = project_root or ctx.obj.get("project_root") or Path.cwd()
|
|
@@ -151,7 +219,14 @@ def show_favorites_cmd(
|
|
|
151
219
|
None, "--project-root", "-p", help="Project root directory"
|
|
152
220
|
),
|
|
153
221
|
) -> None:
|
|
154
|
-
"""Show favorite queries.
|
|
222
|
+
"""Show favorite queries.
|
|
223
|
+
|
|
224
|
+
Displays your saved favorite search queries. Favorites allow you to quickly
|
|
225
|
+
access frequently used searches without typing them again.
|
|
226
|
+
|
|
227
|
+
Examples:
|
|
228
|
+
mcp-vector-search favorites
|
|
229
|
+
"""
|
|
155
230
|
from .history import show_favorites
|
|
156
231
|
|
|
157
232
|
root = project_root or ctx.obj.get("project_root") or Path.cwd()
|
|
@@ -167,7 +242,15 @@ def add_favorite(
|
|
|
167
242
|
None, "--project-root", "-p", help="Project root directory"
|
|
168
243
|
),
|
|
169
244
|
) -> None:
|
|
170
|
-
"""Add a query to favorites.
|
|
245
|
+
"""Add a query to favorites.
|
|
246
|
+
|
|
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.
|
|
249
|
+
|
|
250
|
+
Examples:
|
|
251
|
+
mcp-vector-search add-favorite "authentication functions"
|
|
252
|
+
mcp-vector-search add-favorite "error handling" --desc "Error handling patterns"
|
|
253
|
+
"""
|
|
171
254
|
from .history import SearchHistory
|
|
172
255
|
|
|
173
256
|
root = project_root or ctx.obj.get("project_root") or Path.cwd()
|
|
@@ -183,7 +266,13 @@ def remove_favorite(
|
|
|
183
266
|
None, "--project-root", "-p", help="Project root directory"
|
|
184
267
|
),
|
|
185
268
|
) -> None:
|
|
186
|
-
"""Remove a query from favorites.
|
|
269
|
+
"""Remove a query from favorites.
|
|
270
|
+
|
|
271
|
+
Remove a previously saved favorite query from your favorites list.
|
|
272
|
+
|
|
273
|
+
Examples:
|
|
274
|
+
mcp-vector-search remove-favorite "authentication functions"
|
|
275
|
+
"""
|
|
187
276
|
from .history import SearchHistory
|
|
188
277
|
|
|
189
278
|
root = project_root or ctx.obj.get("project_root") or Path.cwd()
|
|
@@ -195,10 +284,24 @@ def remove_favorite(
|
|
|
195
284
|
def main(
|
|
196
285
|
ctx: typer.Context,
|
|
197
286
|
version: bool = typer.Option(
|
|
198
|
-
False,
|
|
287
|
+
False,
|
|
288
|
+
"--version",
|
|
289
|
+
"-v",
|
|
290
|
+
help="Show version and exit",
|
|
291
|
+
rich_help_panel="ℹ️ Information",
|
|
292
|
+
),
|
|
293
|
+
verbose: bool = typer.Option(
|
|
294
|
+
False,
|
|
295
|
+
"--verbose",
|
|
296
|
+
help="Enable verbose logging",
|
|
297
|
+
rich_help_panel="🔧 Global Options",
|
|
298
|
+
),
|
|
299
|
+
quiet: bool = typer.Option(
|
|
300
|
+
False,
|
|
301
|
+
"--quiet",
|
|
302
|
+
help="Suppress non-error output",
|
|
303
|
+
rich_help_panel="🔧 Global Options",
|
|
199
304
|
),
|
|
200
|
-
verbose: bool = typer.Option(False, "--verbose", help="Enable verbose logging"),
|
|
201
|
-
quiet: bool = typer.Option(False, "--quiet", help="Suppress non-error output"),
|
|
202
305
|
project_root: Path | None = typer.Option(
|
|
203
306
|
None,
|
|
204
307
|
"--project-root",
|
|
@@ -208,6 +311,7 @@ def main(
|
|
|
208
311
|
file_okay=False,
|
|
209
312
|
dir_okay=True,
|
|
210
313
|
readable=True,
|
|
314
|
+
rich_help_panel="🔧 Global Options",
|
|
211
315
|
),
|
|
212
316
|
) -> None:
|
|
213
317
|
"""MCP Vector Search - CLI-first semantic code search with MCP integration.
|
|
@@ -254,19 +358,21 @@ def handle_command_error(ctx, param, value):
|
|
|
254
358
|
|
|
255
359
|
# This will be called when a command is not found
|
|
256
360
|
import click
|
|
361
|
+
|
|
257
362
|
try:
|
|
258
363
|
return value
|
|
259
364
|
except click.UsageError as e:
|
|
260
365
|
if "No such command" in str(e):
|
|
261
366
|
# Extract the command name from the error
|
|
262
367
|
import re
|
|
368
|
+
|
|
263
369
|
match = re.search(r"No such command '([^']+)'", str(e))
|
|
264
370
|
if match:
|
|
265
371
|
command_name = match.group(1)
|
|
266
|
-
|
|
372
|
+
|
|
267
373
|
# Use both the original suggestions and contextual suggestions
|
|
268
374
|
add_common_suggestions(ctx, command_name)
|
|
269
|
-
|
|
375
|
+
|
|
270
376
|
# Add contextual suggestions based on project state
|
|
271
377
|
try:
|
|
272
378
|
project_root = ctx.obj.get("project_root") if ctx.obj else None
|
|
@@ -277,23 +383,32 @@ def handle_command_error(ctx, param, value):
|
|
|
277
383
|
raise
|
|
278
384
|
|
|
279
385
|
|
|
280
|
-
|
|
281
|
-
|
|
282
386
|
@app.command()
|
|
283
387
|
def help_contextual() -> None:
|
|
284
388
|
"""Show contextual help and suggestions based on project state."""
|
|
285
389
|
try:
|
|
286
390
|
project_root = Path.cwd()
|
|
287
|
-
console.print(
|
|
391
|
+
console.print(
|
|
392
|
+
f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green]"
|
|
393
|
+
)
|
|
288
394
|
console.print("[dim]CLI-first semantic code search with MCP integration[/dim]")
|
|
289
395
|
get_contextual_suggestions(project_root)
|
|
290
|
-
except Exception
|
|
291
|
-
console.print(
|
|
396
|
+
except Exception:
|
|
397
|
+
console.print(
|
|
398
|
+
"\n[dim]Use [bold]mcp-vector-search --help[/bold] for more information.[/dim]"
|
|
399
|
+
)
|
|
292
400
|
|
|
293
401
|
|
|
294
402
|
@app.command()
|
|
295
403
|
def doctor() -> None:
|
|
296
|
-
"""Check system dependencies and configuration.
|
|
404
|
+
"""Check system dependencies and configuration.
|
|
405
|
+
|
|
406
|
+
Runs diagnostic checks to ensure all required dependencies are installed
|
|
407
|
+
and properly configured. Use this command to troubleshoot installation issues.
|
|
408
|
+
|
|
409
|
+
Examples:
|
|
410
|
+
mcp-vector-search doctor
|
|
411
|
+
"""
|
|
297
412
|
from .commands.status import check_dependencies
|
|
298
413
|
|
|
299
414
|
console.print("[bold blue]MCP Vector Search - System Check[/bold blue]\n")
|
|
@@ -310,14 +425,12 @@ def doctor() -> None:
|
|
|
310
425
|
)
|
|
311
426
|
|
|
312
427
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
428
|
def cli_with_suggestions():
|
|
317
429
|
"""CLI wrapper that catches errors and provides suggestions."""
|
|
318
430
|
import sys
|
|
431
|
+
|
|
319
432
|
import click
|
|
320
|
-
|
|
433
|
+
|
|
321
434
|
try:
|
|
322
435
|
# Call the app with standalone_mode=False to get exceptions instead of sys.exit
|
|
323
436
|
app(standalone_mode=False)
|
|
@@ -326,40 +439,46 @@ def cli_with_suggestions():
|
|
|
326
439
|
if "No such command" in str(e):
|
|
327
440
|
# Extract the command name from the error
|
|
328
441
|
import re
|
|
442
|
+
|
|
329
443
|
match = re.search(r"No such command '([^']+)'", str(e))
|
|
330
444
|
if match:
|
|
331
445
|
command_name = match.group(1)
|
|
332
|
-
|
|
446
|
+
|
|
333
447
|
# Show enhanced suggestions
|
|
334
448
|
from rich.console import Console
|
|
449
|
+
|
|
335
450
|
console = Console(stderr=True)
|
|
336
451
|
console.print(f"\\n[red]Error:[/red] {e}")
|
|
337
|
-
|
|
452
|
+
|
|
338
453
|
# Show enhanced suggestions
|
|
339
454
|
add_common_suggestions(None, command_name)
|
|
340
|
-
|
|
455
|
+
|
|
341
456
|
# Show contextual suggestions too
|
|
342
457
|
try:
|
|
343
458
|
project_root = Path.cwd()
|
|
344
459
|
get_contextual_suggestions(project_root, command_name)
|
|
345
460
|
except Exception:
|
|
346
461
|
pass
|
|
347
|
-
|
|
462
|
+
|
|
348
463
|
sys.exit(2) # Exit with error code
|
|
349
|
-
|
|
464
|
+
|
|
350
465
|
# For other usage errors, show the default message and exit
|
|
351
466
|
click.echo(f"Error: {e}", err=True)
|
|
352
467
|
sys.exit(2)
|
|
353
468
|
except click.Abort:
|
|
354
469
|
# User interrupted (Ctrl+C)
|
|
355
470
|
sys.exit(1)
|
|
356
|
-
except SystemExit
|
|
471
|
+
except SystemExit:
|
|
357
472
|
# Re-raise system exits
|
|
358
473
|
raise
|
|
359
474
|
except Exception as e:
|
|
360
|
-
# For other exceptions, show error and exit
|
|
361
|
-
|
|
362
|
-
sys.
|
|
475
|
+
# For other exceptions, show error and exit if verbose logging is enabled
|
|
476
|
+
# Suppress internal framework errors in normal operation
|
|
477
|
+
if "--verbose" in sys.argv or "-v" in sys.argv:
|
|
478
|
+
click.echo(f"Unexpected error: {e}", err=True)
|
|
479
|
+
sys.exit(1)
|
|
480
|
+
# Otherwise, just exit silently to avoid confusing error messages
|
|
481
|
+
pass
|
|
363
482
|
|
|
364
483
|
|
|
365
484
|
if __name__ == "__main__":
|
mcp_vector_search/cli/output.py
CHANGED
|
@@ -258,3 +258,155 @@ def print_json(data: Any, title: str | None = None) -> None:
|
|
|
258
258
|
console.print(Panel(syntax, title=title, border_style="blue"))
|
|
259
259
|
else:
|
|
260
260
|
console.print(syntax)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def print_panel(
|
|
264
|
+
content: str,
|
|
265
|
+
title: str | None = None,
|
|
266
|
+
border_style: str = "blue",
|
|
267
|
+
padding: tuple[int, int] = (1, 2),
|
|
268
|
+
) -> None:
|
|
269
|
+
"""Print content in a Rich panel.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
content: The content to display in the panel
|
|
273
|
+
title: Optional title for the panel
|
|
274
|
+
border_style: Border color/style (default: "blue")
|
|
275
|
+
padding: Tuple of (vertical, horizontal) padding
|
|
276
|
+
"""
|
|
277
|
+
console.print(
|
|
278
|
+
Panel(
|
|
279
|
+
content,
|
|
280
|
+
title=title,
|
|
281
|
+
border_style=border_style,
|
|
282
|
+
padding=padding,
|
|
283
|
+
)
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def print_next_steps(steps: list[str], title: str = "Next Steps") -> None:
|
|
288
|
+
"""Print next step hints after a command execution.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
steps: List of next step descriptions
|
|
292
|
+
title: Panel title (default: "Next Steps")
|
|
293
|
+
"""
|
|
294
|
+
content = "\n".join(f" {i}. {step}" for i, step in enumerate(steps, 1))
|
|
295
|
+
print_panel(content, title=f"🚀 {title}", border_style="blue")
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def print_tip(message: str) -> None:
|
|
299
|
+
"""Print a helpful tip message.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
message: The tip message to display
|
|
303
|
+
"""
|
|
304
|
+
console.print(f"[dim]💡 Tip: {message}[/dim]")
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def print_completion_status(
|
|
308
|
+
title: str,
|
|
309
|
+
completed_items: list[str],
|
|
310
|
+
pending_items: list[str] | None = None,
|
|
311
|
+
) -> None:
|
|
312
|
+
"""Print completion status with checkmarks.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
title: Status title
|
|
316
|
+
completed_items: List of completed items
|
|
317
|
+
pending_items: Optional list of pending items
|
|
318
|
+
"""
|
|
319
|
+
content_lines = []
|
|
320
|
+
|
|
321
|
+
if completed_items:
|
|
322
|
+
content_lines.append("[bold green]✨ Completed:[/bold green]")
|
|
323
|
+
for item in completed_items:
|
|
324
|
+
content_lines.append(f" ✅ {item}")
|
|
325
|
+
|
|
326
|
+
if pending_items:
|
|
327
|
+
content_lines.append("\n[bold yellow]📋 Pending:[/bold yellow]")
|
|
328
|
+
for item in pending_items:
|
|
329
|
+
content_lines.append(f" ☐ {item}")
|
|
330
|
+
|
|
331
|
+
print_panel("\n".join(content_lines), title=title, border_style="green")
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def print_setup_progress(
|
|
335
|
+
completed_steps: list[str],
|
|
336
|
+
all_steps: list[tuple[str, str]] | None = None,
|
|
337
|
+
) -> None:
|
|
338
|
+
"""Display setup workflow progress.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
completed_steps: List of completed step IDs
|
|
342
|
+
all_steps: Optional list of (step_id, step_name) tuples
|
|
343
|
+
"""
|
|
344
|
+
if all_steps is None:
|
|
345
|
+
all_steps = [
|
|
346
|
+
("initialize", "Initialize project"),
|
|
347
|
+
("configure", "Configure settings"),
|
|
348
|
+
("index", "Index codebase"),
|
|
349
|
+
("mcp_setup", "Setup MCP integration"),
|
|
350
|
+
("verify", "Verify installation"),
|
|
351
|
+
]
|
|
352
|
+
|
|
353
|
+
completed = len([s for s, _ in all_steps if s in completed_steps])
|
|
354
|
+
total = len(all_steps)
|
|
355
|
+
percentage = (completed / total) * 100
|
|
356
|
+
|
|
357
|
+
console.print(f"\n🚀 Setup Progress: {completed}/{total} ({percentage:.0f}%)")
|
|
358
|
+
|
|
359
|
+
for step_id, step_name in all_steps:
|
|
360
|
+
status = "✓" if step_id in completed_steps else "☐"
|
|
361
|
+
style = "green" if step_id in completed_steps else "dim"
|
|
362
|
+
console.print(f" {status} {step_name}", style=style)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def print_error_with_recovery(error_message: str, recovery_steps: list[str]) -> None:
|
|
366
|
+
"""Print error message with recovery hints.
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
error_message: The error message
|
|
370
|
+
recovery_steps: List of recovery step descriptions
|
|
371
|
+
"""
|
|
372
|
+
print_error(error_message)
|
|
373
|
+
|
|
374
|
+
console.print("\n[bold]How to fix:[/bold]")
|
|
375
|
+
for i, step in enumerate(recovery_steps, 1):
|
|
376
|
+
console.print(f" {i}. {step}")
|
|
377
|
+
|
|
378
|
+
console.print("\n[dim]For more help: mcp-vector-search --help[/dim]")
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def print_command_examples(
|
|
382
|
+
command: str,
|
|
383
|
+
examples: list[tuple[str, str]],
|
|
384
|
+
) -> None:
|
|
385
|
+
"""Print command examples in a formatted table.
|
|
386
|
+
|
|
387
|
+
Args:
|
|
388
|
+
command: Base command name
|
|
389
|
+
examples: List of (description, example) tuples
|
|
390
|
+
"""
|
|
391
|
+
table = Table(
|
|
392
|
+
title=f"Examples: {command}",
|
|
393
|
+
show_header=True,
|
|
394
|
+
header_style="bold cyan",
|
|
395
|
+
)
|
|
396
|
+
table.add_column("Description", style="white", no_wrap=False)
|
|
397
|
+
table.add_column("Command", style="green", no_wrap=False)
|
|
398
|
+
|
|
399
|
+
for description, example in examples:
|
|
400
|
+
table.add_row(description, example)
|
|
401
|
+
|
|
402
|
+
console.print(table)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def print_config_hint(config_type: str, config_path: str) -> None:
|
|
406
|
+
"""Print configuration file location hint.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
config_type: Type of configuration (e.g., "Claude Code", "Project")
|
|
410
|
+
config_path: Path to the configuration file
|
|
411
|
+
"""
|
|
412
|
+
console.print(f"[dim]💡 {config_type} config: {config_path}[/dim]")
|