mcp-vector-search 0.4.14__py3-none-any.whl → 0.5.1__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 +114 -43
- 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 +7 -0
- mcp_vector_search/parsers/dart.py +605 -0
- mcp_vector_search/parsers/html.py +413 -0
- mcp_vector_search/parsers/php.py +694 -0
- mcp_vector_search/parsers/registry.py +21 -1
- mcp_vector_search/parsers/ruby.py +678 -0
- mcp_vector_search/parsers/text.py +32 -26
- mcp_vector_search/utils/gitignore.py +72 -71
- {mcp_vector_search-0.4.14.dist-info → mcp_vector_search-0.5.1.dist-info}/METADATA +76 -5
- {mcp_vector_search-0.4.14.dist-info → mcp_vector_search-0.5.1.dist-info}/RECORD +30 -26
- {mcp_vector_search-0.4.14.dist-info → mcp_vector_search-0.5.1.dist-info}/WHEEL +0 -0
- {mcp_vector_search-0.4.14.dist-info → mcp_vector_search-0.5.1.dist-info}/entry_points.txt +0 -0
- {mcp_vector_search-0.4.14.dist-info → mcp_vector_search-0.5.1.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
|
|
@@ -232,10 +284,24 @@ def remove_favorite(
|
|
|
232
284
|
def main(
|
|
233
285
|
ctx: typer.Context,
|
|
234
286
|
version: bool = typer.Option(
|
|
235
|
-
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",
|
|
236
304
|
),
|
|
237
|
-
verbose: bool = typer.Option(False, "--verbose", help="Enable verbose logging"),
|
|
238
|
-
quiet: bool = typer.Option(False, "--quiet", help="Suppress non-error output"),
|
|
239
305
|
project_root: Path | None = typer.Option(
|
|
240
306
|
None,
|
|
241
307
|
"--project-root",
|
|
@@ -245,6 +311,7 @@ def main(
|
|
|
245
311
|
file_okay=False,
|
|
246
312
|
dir_okay=True,
|
|
247
313
|
readable=True,
|
|
314
|
+
rich_help_panel="🔧 Global Options",
|
|
248
315
|
),
|
|
249
316
|
) -> None:
|
|
250
317
|
"""MCP Vector Search - CLI-first semantic code search with MCP integration.
|
|
@@ -291,19 +358,21 @@ def handle_command_error(ctx, param, value):
|
|
|
291
358
|
|
|
292
359
|
# This will be called when a command is not found
|
|
293
360
|
import click
|
|
361
|
+
|
|
294
362
|
try:
|
|
295
363
|
return value
|
|
296
364
|
except click.UsageError as e:
|
|
297
365
|
if "No such command" in str(e):
|
|
298
366
|
# Extract the command name from the error
|
|
299
367
|
import re
|
|
368
|
+
|
|
300
369
|
match = re.search(r"No such command '([^']+)'", str(e))
|
|
301
370
|
if match:
|
|
302
371
|
command_name = match.group(1)
|
|
303
|
-
|
|
372
|
+
|
|
304
373
|
# Use both the original suggestions and contextual suggestions
|
|
305
374
|
add_common_suggestions(ctx, command_name)
|
|
306
|
-
|
|
375
|
+
|
|
307
376
|
# Add contextual suggestions based on project state
|
|
308
377
|
try:
|
|
309
378
|
project_root = ctx.obj.get("project_root") if ctx.obj else None
|
|
@@ -314,18 +383,20 @@ def handle_command_error(ctx, param, value):
|
|
|
314
383
|
raise
|
|
315
384
|
|
|
316
385
|
|
|
317
|
-
|
|
318
|
-
|
|
319
386
|
@app.command()
|
|
320
387
|
def help_contextual() -> None:
|
|
321
388
|
"""Show contextual help and suggestions based on project state."""
|
|
322
389
|
try:
|
|
323
390
|
project_root = Path.cwd()
|
|
324
|
-
console.print(
|
|
391
|
+
console.print(
|
|
392
|
+
f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green]"
|
|
393
|
+
)
|
|
325
394
|
console.print("[dim]CLI-first semantic code search with MCP integration[/dim]")
|
|
326
395
|
get_contextual_suggestions(project_root)
|
|
327
|
-
except Exception
|
|
328
|
-
console.print(
|
|
396
|
+
except Exception:
|
|
397
|
+
console.print(
|
|
398
|
+
"\n[dim]Use [bold]mcp-vector-search --help[/bold] for more information.[/dim]"
|
|
399
|
+
)
|
|
329
400
|
|
|
330
401
|
|
|
331
402
|
@app.command()
|
|
@@ -354,14 +425,12 @@ def doctor() -> None:
|
|
|
354
425
|
)
|
|
355
426
|
|
|
356
427
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
428
|
def cli_with_suggestions():
|
|
361
429
|
"""CLI wrapper that catches errors and provides suggestions."""
|
|
362
430
|
import sys
|
|
431
|
+
|
|
363
432
|
import click
|
|
364
|
-
|
|
433
|
+
|
|
365
434
|
try:
|
|
366
435
|
# Call the app with standalone_mode=False to get exceptions instead of sys.exit
|
|
367
436
|
app(standalone_mode=False)
|
|
@@ -370,34 +439,36 @@ def cli_with_suggestions():
|
|
|
370
439
|
if "No such command" in str(e):
|
|
371
440
|
# Extract the command name from the error
|
|
372
441
|
import re
|
|
442
|
+
|
|
373
443
|
match = re.search(r"No such command '([^']+)'", str(e))
|
|
374
444
|
if match:
|
|
375
445
|
command_name = match.group(1)
|
|
376
|
-
|
|
446
|
+
|
|
377
447
|
# Show enhanced suggestions
|
|
378
448
|
from rich.console import Console
|
|
449
|
+
|
|
379
450
|
console = Console(stderr=True)
|
|
380
451
|
console.print(f"\\n[red]Error:[/red] {e}")
|
|
381
|
-
|
|
452
|
+
|
|
382
453
|
# Show enhanced suggestions
|
|
383
454
|
add_common_suggestions(None, command_name)
|
|
384
|
-
|
|
455
|
+
|
|
385
456
|
# Show contextual suggestions too
|
|
386
457
|
try:
|
|
387
458
|
project_root = Path.cwd()
|
|
388
459
|
get_contextual_suggestions(project_root, command_name)
|
|
389
460
|
except Exception:
|
|
390
461
|
pass
|
|
391
|
-
|
|
462
|
+
|
|
392
463
|
sys.exit(2) # Exit with error code
|
|
393
|
-
|
|
464
|
+
|
|
394
465
|
# For other usage errors, show the default message and exit
|
|
395
466
|
click.echo(f"Error: {e}", err=True)
|
|
396
467
|
sys.exit(2)
|
|
397
468
|
except click.Abort:
|
|
398
469
|
# User interrupted (Ctrl+C)
|
|
399
470
|
sys.exit(1)
|
|
400
|
-
except SystemExit
|
|
471
|
+
except SystemExit:
|
|
401
472
|
# Re-raise system exits
|
|
402
473
|
raise
|
|
403
474
|
except Exception as e:
|
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]")
|