mcp-vector-search 0.12.6__py3-none-any.whl → 1.0.3__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.
- mcp_vector_search/__init__.py +2 -2
- mcp_vector_search/analysis/__init__.py +64 -0
- mcp_vector_search/analysis/collectors/__init__.py +39 -0
- mcp_vector_search/analysis/collectors/base.py +164 -0
- mcp_vector_search/analysis/collectors/complexity.py +743 -0
- mcp_vector_search/analysis/metrics.py +341 -0
- mcp_vector_search/analysis/reporters/__init__.py +5 -0
- mcp_vector_search/analysis/reporters/console.py +222 -0
- mcp_vector_search/cli/commands/analyze.py +408 -0
- mcp_vector_search/cli/commands/chat.py +1262 -0
- mcp_vector_search/cli/commands/index.py +21 -3
- mcp_vector_search/cli/commands/init.py +13 -0
- mcp_vector_search/cli/commands/install.py +597 -335
- mcp_vector_search/cli/commands/install_old.py +8 -4
- mcp_vector_search/cli/commands/mcp.py +78 -6
- mcp_vector_search/cli/commands/reset.py +68 -26
- mcp_vector_search/cli/commands/search.py +30 -7
- mcp_vector_search/cli/commands/setup.py +1133 -0
- mcp_vector_search/cli/commands/status.py +37 -2
- mcp_vector_search/cli/commands/uninstall.py +276 -357
- mcp_vector_search/cli/commands/visualize/__init__.py +39 -0
- mcp_vector_search/cli/commands/visualize/cli.py +276 -0
- mcp_vector_search/cli/commands/visualize/exporters/__init__.py +12 -0
- mcp_vector_search/cli/commands/visualize/exporters/html_exporter.py +33 -0
- mcp_vector_search/cli/commands/visualize/exporters/json_exporter.py +29 -0
- mcp_vector_search/cli/commands/visualize/graph_builder.py +714 -0
- mcp_vector_search/cli/commands/visualize/layout_engine.py +469 -0
- mcp_vector_search/cli/commands/visualize/server.py +311 -0
- mcp_vector_search/cli/commands/visualize/state_manager.py +428 -0
- mcp_vector_search/cli/commands/visualize/templates/__init__.py +16 -0
- mcp_vector_search/cli/commands/visualize/templates/base.py +180 -0
- mcp_vector_search/cli/commands/visualize/templates/scripts.py +2507 -0
- mcp_vector_search/cli/commands/visualize/templates/styles.py +1313 -0
- mcp_vector_search/cli/commands/visualize.py.original +2536 -0
- mcp_vector_search/cli/didyoumean.py +22 -2
- mcp_vector_search/cli/main.py +115 -159
- mcp_vector_search/cli/output.py +24 -8
- mcp_vector_search/config/__init__.py +4 -0
- mcp_vector_search/config/default_thresholds.yaml +52 -0
- mcp_vector_search/config/settings.py +12 -0
- mcp_vector_search/config/thresholds.py +185 -0
- mcp_vector_search/core/auto_indexer.py +3 -3
- mcp_vector_search/core/boilerplate.py +186 -0
- mcp_vector_search/core/config_utils.py +394 -0
- mcp_vector_search/core/database.py +369 -94
- mcp_vector_search/core/exceptions.py +11 -0
- mcp_vector_search/core/git_hooks.py +4 -4
- mcp_vector_search/core/indexer.py +221 -4
- mcp_vector_search/core/llm_client.py +751 -0
- mcp_vector_search/core/models.py +3 -0
- mcp_vector_search/core/project.py +17 -0
- mcp_vector_search/core/scheduler.py +11 -11
- mcp_vector_search/core/search.py +179 -29
- mcp_vector_search/mcp/server.py +24 -5
- mcp_vector_search/utils/__init__.py +2 -0
- mcp_vector_search/utils/gitignore_updater.py +212 -0
- mcp_vector_search/utils/monorepo.py +66 -4
- mcp_vector_search/utils/timing.py +10 -6
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/METADATA +182 -52
- mcp_vector_search-1.0.3.dist-info/RECORD +97 -0
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/WHEEL +1 -1
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/entry_points.txt +1 -0
- mcp_vector_search/cli/commands/visualize.py +0 -1467
- mcp_vector_search-0.12.6.dist-info/RECORD +0 -68
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -212,6 +212,17 @@ COMMON_TYPOS = {
|
|
|
212
212
|
"grep": "search",
|
|
213
213
|
"s": "search", # Single letter shortcut
|
|
214
214
|
"f": "search", # Alternative shortcut for find
|
|
215
|
+
# Chat command variations
|
|
216
|
+
"cht": "chat",
|
|
217
|
+
"caht": "chat",
|
|
218
|
+
"chta": "chat",
|
|
219
|
+
"ask": "chat",
|
|
220
|
+
"question": "chat",
|
|
221
|
+
"qa": "chat",
|
|
222
|
+
"llm": "chat",
|
|
223
|
+
"gpt": "chat",
|
|
224
|
+
"explain": "chat",
|
|
225
|
+
"answer": "chat",
|
|
215
226
|
# Index command variations
|
|
216
227
|
"indx": "index",
|
|
217
228
|
"idx": "index",
|
|
@@ -333,9 +344,18 @@ COMMAND_INFO = {
|
|
|
333
344
|
"examples": [
|
|
334
345
|
'mcp-vector-search search "authentication function"',
|
|
335
346
|
'mcp-vector-search search "error handling" --limit 5',
|
|
336
|
-
'mcp-vector-search
|
|
347
|
+
'mcp-vector-search search --files "*.ts" "query"',
|
|
337
348
|
],
|
|
338
|
-
"related": ["
|
|
349
|
+
"related": ["chat", "index", "status"],
|
|
350
|
+
},
|
|
351
|
+
"chat": {
|
|
352
|
+
"description": "Ask AI questions about your code (requires API key)",
|
|
353
|
+
"examples": [
|
|
354
|
+
'mcp-vector-search chat "where is the database configured?"',
|
|
355
|
+
'mcp-vector-search chat "how does authentication work?"',
|
|
356
|
+
'mcp-vector-search chat --limit 3 "explain error handling"',
|
|
357
|
+
],
|
|
358
|
+
"related": ["search", "status", "index"],
|
|
339
359
|
},
|
|
340
360
|
"index": {
|
|
341
361
|
"description": "Index codebase for semantic search",
|
mcp_vector_search/cli/main.py
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""Main CLI application for MCP Vector Search."""
|
|
2
2
|
|
|
3
|
+
import faulthandler
|
|
4
|
+
import signal
|
|
5
|
+
import sys
|
|
3
6
|
from pathlib import Path
|
|
4
7
|
|
|
5
8
|
import typer
|
|
@@ -9,9 +12,52 @@ from rich.traceback import install
|
|
|
9
12
|
|
|
10
13
|
from .. import __build__, __version__
|
|
11
14
|
from .didyoumean import add_common_suggestions, create_enhanced_typer
|
|
12
|
-
from .output import
|
|
15
|
+
from .output import setup_logging
|
|
13
16
|
from .suggestions import get_contextual_suggestions
|
|
14
17
|
|
|
18
|
+
|
|
19
|
+
# ============================================================================
|
|
20
|
+
# SIGNAL HANDLERS - Register early for crash diagnostics
|
|
21
|
+
# ============================================================================
|
|
22
|
+
def _handle_segfault(signum: int, frame) -> None:
|
|
23
|
+
"""Handle segmentation faults with helpful error message.
|
|
24
|
+
|
|
25
|
+
Segmentation faults typically occur due to corrupted ChromaDB index data
|
|
26
|
+
or issues with native libraries (sentence-transformers, tree-sitter).
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
signum: Signal number (SIGSEGV = 11)
|
|
30
|
+
frame: Current stack frame (unused)
|
|
31
|
+
"""
|
|
32
|
+
error_message = """
|
|
33
|
+
╭─────────────────────────────────────────────────────────────────╮
|
|
34
|
+
│ ⚠️ Segmentation Fault Detected │
|
|
35
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
36
|
+
│ This usually indicates corrupted index data or a crash in │
|
|
37
|
+
│ native libraries (ChromaDB, sentence-transformers, tree-sitter).│
|
|
38
|
+
│ │
|
|
39
|
+
│ To fix this, please run: │
|
|
40
|
+
│ 1. mcp-vector-search reset index --force │
|
|
41
|
+
│ 2. mcp-vector-search index │
|
|
42
|
+
│ │
|
|
43
|
+
│ This will rebuild your search index from scratch. │
|
|
44
|
+
│ │
|
|
45
|
+
│ If the problem persists: │
|
|
46
|
+
│ - Try updating dependencies: pip install -U mcp-vector-search │
|
|
47
|
+
│ - Check GitHub issues: github.com/bobmatnyc/mcp-vector-search │
|
|
48
|
+
╰─────────────────────────────────────────────────────────────────╯
|
|
49
|
+
"""
|
|
50
|
+
print(error_message, file=sys.stderr)
|
|
51
|
+
sys.exit(139) # Standard segfault exit code (128 + 11)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# Register signal handler for segmentation faults
|
|
55
|
+
signal.signal(signal.SIGSEGV, _handle_segfault)
|
|
56
|
+
|
|
57
|
+
# Enable faulthandler for better crash diagnostics
|
|
58
|
+
# This prints Python traceback on segfaults before signal handler runs
|
|
59
|
+
faulthandler.enable()
|
|
60
|
+
|
|
15
61
|
# Install rich traceback handler
|
|
16
62
|
install(show_locals=True)
|
|
17
63
|
|
|
@@ -22,45 +68,65 @@ console = Console()
|
|
|
22
68
|
app = create_enhanced_typer(
|
|
23
69
|
name="mcp-vector-search",
|
|
24
70
|
help="""
|
|
25
|
-
🔍 [bold]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
unfamiliar
|
|
29
|
-
|
|
30
|
-
[bold cyan]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
[bold cyan]
|
|
71
|
+
🔍 [bold]MCP Vector Search - Semantic Code Search CLI[/bold]
|
|
72
|
+
|
|
73
|
+
Search your codebase by meaning, not just keywords. Find similar code patterns,
|
|
74
|
+
explore unfamiliar projects, and integrate with AI coding tools via MCP.
|
|
75
|
+
|
|
76
|
+
[bold cyan]QUICK START:[/bold cyan]
|
|
77
|
+
mcp-vector-search setup # One-time setup (recommended)
|
|
78
|
+
mcp-vector-search search "query" # Search by meaning
|
|
79
|
+
mcp-vector-search chat "question" # Ask AI about your code
|
|
80
|
+
|
|
81
|
+
[bold cyan]MAIN COMMANDS:[/bold cyan]
|
|
82
|
+
setup 🚀 Zero-config setup (indexes + configures MCP)
|
|
83
|
+
search 🔍 Semantic search (finds code by meaning)
|
|
84
|
+
chat 🤖 LLM-powered Q&A about your code (needs API key)
|
|
85
|
+
status 📊 Show project status
|
|
86
|
+
visualize 📊 Interactive code graph
|
|
87
|
+
|
|
88
|
+
[bold cyan]AI CHAT SETUP:[/bold cyan]
|
|
89
|
+
The 'chat' command requires an OpenRouter API key:
|
|
90
|
+
1. Get key: [cyan]https://openrouter.ai/keys[/cyan]
|
|
91
|
+
2. Set: [yellow]export OPENROUTER_API_KEY='your-key'[/yellow]
|
|
92
|
+
|
|
93
|
+
[bold cyan]EXAMPLES:[/bold cyan]
|
|
94
|
+
mcp-vector-search search "error handling"
|
|
95
|
+
mcp-vector-search search --files "*.ts" "authentication"
|
|
96
|
+
mcp-vector-search chat "where is the database configured?"
|
|
97
|
+
mcp-vector-search chat "how does auth work in this project?"
|
|
98
|
+
|
|
99
|
+
[bold cyan]MORE COMMANDS:[/bold cyan]
|
|
36
100
|
install 📦 Install project and MCP integrations
|
|
37
101
|
uninstall 🗑️ Remove MCP integrations
|
|
38
|
-
init 🔧 Initialize project (
|
|
102
|
+
init 🔧 Initialize project (advanced)
|
|
39
103
|
demo 🎬 Run interactive demo
|
|
40
104
|
doctor 🩺 Check system health
|
|
41
|
-
status 📊 Show project status
|
|
42
|
-
search 🔍 Search code semantically
|
|
43
105
|
index 📇 Index codebase
|
|
106
|
+
reset 🔄 Reset and recovery operations
|
|
44
107
|
mcp 🔌 MCP server operations
|
|
45
108
|
config ⚙️ Configure settings
|
|
46
|
-
visualize 📊 Visualize code relationships
|
|
47
109
|
help ❓ Get help
|
|
48
110
|
version ℹ️ Show version
|
|
49
111
|
|
|
50
|
-
[dim]For
|
|
112
|
+
[dim]For more: [cyan]mcp-vector-search COMMAND --help[/cyan][/dim]
|
|
51
113
|
""",
|
|
52
114
|
add_completion=False,
|
|
53
115
|
rich_markup_mode="rich",
|
|
54
116
|
)
|
|
55
117
|
|
|
56
118
|
# Import command modules
|
|
119
|
+
from .commands.analyze import analyze_app # noqa: E402
|
|
120
|
+
from .commands.chat import chat_app # noqa: E402
|
|
57
121
|
from .commands.config import config_app # noqa: E402
|
|
58
122
|
from .commands.demo import demo_app # noqa: E402
|
|
59
123
|
from .commands.index import index_app # noqa: E402
|
|
60
124
|
from .commands.init import init_app # noqa: E402
|
|
61
125
|
from .commands.install import install_app # noqa: E402
|
|
62
126
|
from .commands.mcp import mcp_app # noqa: E402
|
|
127
|
+
from .commands.reset import reset_app # noqa: E402
|
|
63
128
|
from .commands.search import search_app, search_main # noqa: E402, F401
|
|
129
|
+
from .commands.setup import setup_app # noqa: E402
|
|
64
130
|
from .commands.status import main as status_main # noqa: E402
|
|
65
131
|
from .commands.uninstall import uninstall_app # noqa: E402
|
|
66
132
|
from .commands.visualize import app as visualize_app # noqa: E402
|
|
@@ -69,6 +135,9 @@ from .commands.visualize import app as visualize_app # noqa: E402
|
|
|
69
135
|
# MAIN COMMANDS - Clean hierarchy
|
|
70
136
|
# ============================================================================
|
|
71
137
|
|
|
138
|
+
# 0. SETUP - Smart zero-config setup (RECOMMENDED!)
|
|
139
|
+
app.add_typer(setup_app, name="setup", help="🚀 Smart zero-config setup (recommended)")
|
|
140
|
+
|
|
72
141
|
# 1. INSTALL - Install project and MCP integrations (NEW!)
|
|
73
142
|
app.add_typer(
|
|
74
143
|
install_app, name="install", help="📦 Install project and MCP integrations"
|
|
@@ -95,6 +164,9 @@ app.command("status", help="📊 Show project status and statistics")(status_mai
|
|
|
95
164
|
# Register search as both a command and a typer group
|
|
96
165
|
app.add_typer(search_app, name="search", help="🔍 Search code semantically")
|
|
97
166
|
|
|
167
|
+
# 7.5. CHAT - LLM-powered intelligent search
|
|
168
|
+
app.add_typer(chat_app, name="chat", help="🤖 Ask questions about code with LLM")
|
|
169
|
+
|
|
98
170
|
# 8. INDEX - Index codebase
|
|
99
171
|
app.add_typer(index_app, name="index", help="📇 Index codebase for semantic search")
|
|
100
172
|
|
|
@@ -104,152 +176,26 @@ app.add_typer(mcp_app, name="mcp", help="🔌 MCP server operations")
|
|
|
104
176
|
# 10. CONFIG - Configuration
|
|
105
177
|
app.add_typer(config_app, name="config", help="⚙️ Manage project configuration")
|
|
106
178
|
|
|
107
|
-
#
|
|
179
|
+
# 10.5. RESET - Reset and recovery operations
|
|
180
|
+
app.add_typer(reset_app, name="reset", help="🔄 Reset and recovery operations")
|
|
181
|
+
|
|
182
|
+
# 11. ANALYZE - Code complexity analysis
|
|
183
|
+
app.add_typer(
|
|
184
|
+
analyze_app, name="analyze", help="📈 Analyze code complexity and quality"
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# 12. VISUALIZE - Code graph visualization
|
|
108
188
|
app.add_typer(
|
|
109
189
|
visualize_app, name="visualize", help="📊 Visualize code chunk relationships"
|
|
110
190
|
)
|
|
111
191
|
|
|
112
|
-
#
|
|
192
|
+
# 13. HELP - Enhanced help
|
|
113
193
|
# (defined below inline)
|
|
114
194
|
|
|
115
|
-
#
|
|
195
|
+
# 14. VERSION - Version info
|
|
116
196
|
# (defined below inline)
|
|
117
197
|
|
|
118
198
|
|
|
119
|
-
# ============================================================================
|
|
120
|
-
# DEPRECATED COMMANDS - With helpful suggestions
|
|
121
|
-
# ============================================================================
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def _deprecated_command(old_cmd: str, new_cmd: str):
|
|
125
|
-
"""Helper to create deprecated command with suggestion."""
|
|
126
|
-
|
|
127
|
-
def wrapper(*args, **kwargs):
|
|
128
|
-
print_warning(
|
|
129
|
-
f"⚠️ The command '{old_cmd}' is deprecated.\n"
|
|
130
|
-
f" Please use '{new_cmd}' instead.\n"
|
|
131
|
-
f" Run: [cyan]mcp-vector-search {new_cmd} --help[/cyan] for details."
|
|
132
|
-
)
|
|
133
|
-
raise typer.Exit(1)
|
|
134
|
-
|
|
135
|
-
return wrapper
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# NOTE: 'install' command is now the primary command for project installation
|
|
139
|
-
# Old 'install' was deprecated in favor of 'init' in v0.7.0
|
|
140
|
-
# Now 'install' is back as the hierarchical installation command in v0.13.0
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# Deprecated: find -> search
|
|
144
|
-
@app.command("find", hidden=True)
|
|
145
|
-
def deprecated_find():
|
|
146
|
-
"""[DEPRECATED] Use 'search' instead."""
|
|
147
|
-
_deprecated_command("find", "search")()
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
# Deprecated: search-similar -> search --similar
|
|
151
|
-
@app.command("search-similar", hidden=True)
|
|
152
|
-
def deprecated_search_similar():
|
|
153
|
-
"""[DEPRECATED] Use 'search --similar' instead."""
|
|
154
|
-
_deprecated_command("search-similar", "search --similar")()
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
# Deprecated: search-context -> search --context
|
|
158
|
-
@app.command("search-context", hidden=True)
|
|
159
|
-
def deprecated_search_context():
|
|
160
|
-
"""[DEPRECATED] Use 'search --context' instead."""
|
|
161
|
-
_deprecated_command("search-context", "search --context")()
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
# Deprecated: interactive -> search interactive
|
|
165
|
-
@app.command("interactive", hidden=True)
|
|
166
|
-
def deprecated_interactive():
|
|
167
|
-
"""[DEPRECATED] Use 'search interactive' instead."""
|
|
168
|
-
_deprecated_command("interactive", "search interactive")()
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
# Deprecated: history -> search history
|
|
172
|
-
@app.command("history", hidden=True)
|
|
173
|
-
def deprecated_history():
|
|
174
|
-
"""[DEPRECATED] Use 'search history' instead."""
|
|
175
|
-
_deprecated_command("history", "search history")()
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
# Deprecated: favorites -> search favorites
|
|
179
|
-
@app.command("favorites", hidden=True)
|
|
180
|
-
def deprecated_favorites():
|
|
181
|
-
"""[DEPRECATED] Use 'search favorites' instead."""
|
|
182
|
-
_deprecated_command("favorites", "search favorites")()
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
# Deprecated: add-favorite -> search favorites add
|
|
186
|
-
@app.command("add-favorite", hidden=True)
|
|
187
|
-
def deprecated_add_favorite():
|
|
188
|
-
"""[DEPRECATED] Use 'search favorites add' instead."""
|
|
189
|
-
_deprecated_command("add-favorite", "search favorites add")()
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
# Deprecated: remove-favorite -> search favorites remove
|
|
193
|
-
@app.command("remove-favorite", hidden=True)
|
|
194
|
-
def deprecated_remove_favorite():
|
|
195
|
-
"""[DEPRECATED] Use 'search favorites remove' instead."""
|
|
196
|
-
_deprecated_command("remove-favorite", "search favorites remove")()
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
# Deprecated: health -> index health
|
|
200
|
-
@app.command("health", hidden=True)
|
|
201
|
-
def deprecated_health():
|
|
202
|
-
"""[DEPRECATED] Use 'index health' instead."""
|
|
203
|
-
_deprecated_command("health", "index health")()
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
# Deprecated: watch -> index watch
|
|
207
|
-
@app.command("watch", hidden=True)
|
|
208
|
-
def deprecated_watch():
|
|
209
|
-
"""[DEPRECATED] Use 'index watch' instead."""
|
|
210
|
-
_deprecated_command("watch", "index watch")()
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
# Deprecated: auto-index -> index auto
|
|
214
|
-
@app.command("auto-index", hidden=True)
|
|
215
|
-
def deprecated_auto_index():
|
|
216
|
-
"""[DEPRECATED] Use 'index auto' instead."""
|
|
217
|
-
_deprecated_command("auto-index", "index auto")()
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
# Deprecated: reset -> mcp reset or config reset
|
|
221
|
-
@app.command("reset", hidden=True)
|
|
222
|
-
def deprecated_reset():
|
|
223
|
-
"""[DEPRECATED] Use 'mcp reset' or 'config reset' instead."""
|
|
224
|
-
print_warning(
|
|
225
|
-
"⚠️ The 'reset' command is deprecated.\n"
|
|
226
|
-
" Use [cyan]mcp-vector-search mcp reset[/cyan] for MCP reset\n"
|
|
227
|
-
" Use [cyan]mcp-vector-search config reset[/cyan] for config reset"
|
|
228
|
-
)
|
|
229
|
-
raise typer.Exit(1)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
# Deprecated: init-check -> init check
|
|
233
|
-
@app.command("init-check", hidden=True)
|
|
234
|
-
def deprecated_init_check():
|
|
235
|
-
"""[DEPRECATED] Use 'init check' instead."""
|
|
236
|
-
_deprecated_command("init-check", "init check")()
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
# Deprecated: init-mcp -> mcp install
|
|
240
|
-
@app.command("init-mcp", hidden=True)
|
|
241
|
-
def deprecated_init_mcp():
|
|
242
|
-
"""[DEPRECATED] Use 'mcp install' instead."""
|
|
243
|
-
_deprecated_command("init-mcp", "mcp install")()
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
# Deprecated: init-models -> config models
|
|
247
|
-
@app.command("init-models", hidden=True)
|
|
248
|
-
def deprecated_init_models():
|
|
249
|
-
"""[DEPRECATED] Use 'config models' instead."""
|
|
250
|
-
_deprecated_command("init-models", "config models")()
|
|
251
|
-
|
|
252
|
-
|
|
253
199
|
# ============================================================================
|
|
254
200
|
# MAIN INLINE COMMANDS
|
|
255
201
|
# ============================================================================
|
|
@@ -329,6 +275,15 @@ def version_command() -> None:
|
|
|
329
275
|
console.print("[dim]Built with ChromaDB, Tree-sitter, and modern Python[/dim]")
|
|
330
276
|
|
|
331
277
|
|
|
278
|
+
def _version_callback(value: bool) -> None:
|
|
279
|
+
"""Handle --version flag eagerly before command parsing."""
|
|
280
|
+
if value:
|
|
281
|
+
console.print(
|
|
282
|
+
f"[bold blue]mcp-vector-search[/bold blue] version [green]{__version__}[/green] [dim](build {__build__})[/dim]"
|
|
283
|
+
)
|
|
284
|
+
raise typer.Exit()
|
|
285
|
+
|
|
286
|
+
|
|
332
287
|
@app.callback()
|
|
333
288
|
def main(
|
|
334
289
|
ctx: typer.Context,
|
|
@@ -338,6 +293,8 @@ def main(
|
|
|
338
293
|
"-v",
|
|
339
294
|
help="Show version and exit",
|
|
340
295
|
rich_help_panel="ℹ️ Information",
|
|
296
|
+
is_eager=True,
|
|
297
|
+
callback=lambda v: _version_callback(v),
|
|
341
298
|
),
|
|
342
299
|
verbose: bool = typer.Option(
|
|
343
300
|
False,
|
|
@@ -368,9 +325,8 @@ def main(
|
|
|
368
325
|
A modern, lightweight tool for semantic code search using ChromaDB and Tree-sitter.
|
|
369
326
|
Designed for local development with optional MCP server integration.
|
|
370
327
|
"""
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
raise typer.Exit()
|
|
328
|
+
# Note: --version is handled by _version_callback with is_eager=True
|
|
329
|
+
# This ensures it runs before no_args_is_help check
|
|
374
330
|
|
|
375
331
|
# Setup logging
|
|
376
332
|
log_level = "DEBUG" if verbose else "ERROR" if quiet else "WARNING"
|
|
@@ -439,8 +395,8 @@ def cli_with_suggestions():
|
|
|
439
395
|
except click.Abort:
|
|
440
396
|
# User interrupted (Ctrl+C)
|
|
441
397
|
sys.exit(1)
|
|
442
|
-
except SystemExit:
|
|
443
|
-
# Re-raise system exits
|
|
398
|
+
except (SystemExit, click.exceptions.Exit):
|
|
399
|
+
# Re-raise system exits and typer.Exit
|
|
444
400
|
raise
|
|
445
401
|
except Exception as e:
|
|
446
402
|
# For other exceptions, show error and exit if verbose logging is enabled
|
mcp_vector_search/cli/output.py
CHANGED
|
@@ -97,9 +97,11 @@ def print_project_info(project_info: ProjectInfo) -> None:
|
|
|
97
97
|
table.add_row("Initialized", "✓" if project_info.is_initialized else "✗")
|
|
98
98
|
table.add_row(
|
|
99
99
|
"Languages",
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
(
|
|
101
|
+
", ".join(project_info.languages)
|
|
102
|
+
if project_info.languages
|
|
103
|
+
else "None detected"
|
|
104
|
+
),
|
|
103
105
|
)
|
|
104
106
|
table.add_row("Indexable Files", str(project_info.file_count))
|
|
105
107
|
|
|
@@ -248,16 +250,30 @@ def print_dependency_status(
|
|
|
248
250
|
|
|
249
251
|
|
|
250
252
|
def print_json(data: Any, title: str | None = None) -> None:
|
|
251
|
-
"""Print data as formatted JSON.
|
|
252
|
-
|
|
253
|
+
"""Print data as formatted JSON.
|
|
254
|
+
|
|
255
|
+
When title is None (typical for --json flag), outputs raw JSON to stdout
|
|
256
|
+
for machine consumption (e.g., piping to json.tool).
|
|
257
|
+
When title is provided, uses Rich formatting for human-readable display.
|
|
253
258
|
|
|
254
|
-
|
|
255
|
-
|
|
259
|
+
Args:
|
|
260
|
+
data: Data to serialize as JSON
|
|
261
|
+
title: Optional title for Rich panel display
|
|
262
|
+
"""
|
|
263
|
+
import json
|
|
256
264
|
|
|
257
265
|
if title:
|
|
266
|
+
# Human-readable display with Rich formatting
|
|
267
|
+
json_str = json.dumps(data, indent=2, default=str)
|
|
268
|
+
syntax = Syntax(json_str, "json", theme="monokai")
|
|
258
269
|
console.print(Panel(syntax, title=title, border_style="blue"))
|
|
259
270
|
else:
|
|
260
|
-
|
|
271
|
+
# Machine-readable output: raw JSON to stdout
|
|
272
|
+
# Use sys.stdout.write to bypass Rich console formatting
|
|
273
|
+
json_str = json.dumps(data, indent=2, default=str, ensure_ascii=False)
|
|
274
|
+
sys.stdout.write(json_str)
|
|
275
|
+
sys.stdout.write("\n")
|
|
276
|
+
sys.stdout.flush()
|
|
261
277
|
|
|
262
278
|
|
|
263
279
|
def print_panel(
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Code Quality Threshold Configuration
|
|
2
|
+
# Customize these values to match your project's standards
|
|
3
|
+
|
|
4
|
+
complexity:
|
|
5
|
+
# Cognitive complexity grade thresholds
|
|
6
|
+
cognitive_a: 5 # Grade A: 0-5 (excellent)
|
|
7
|
+
cognitive_b: 10 # Grade B: 6-10 (good)
|
|
8
|
+
cognitive_c: 20 # Grade C: 11-20 (acceptable)
|
|
9
|
+
cognitive_d: 30 # Grade D: 21-30 (needs improvement)
|
|
10
|
+
# Grade F: 31+ (refactor recommended)
|
|
11
|
+
|
|
12
|
+
# Cyclomatic complexity thresholds
|
|
13
|
+
cyclomatic_low: 4 # Low: 1-4
|
|
14
|
+
cyclomatic_moderate: 10 # Moderate: 5-10
|
|
15
|
+
cyclomatic_high: 20 # High: 11-20
|
|
16
|
+
# Very high: 21+
|
|
17
|
+
|
|
18
|
+
# Nesting depth thresholds
|
|
19
|
+
nesting_warning: 3 # Warning level
|
|
20
|
+
nesting_error: 5 # Error level
|
|
21
|
+
|
|
22
|
+
# Parameter count thresholds
|
|
23
|
+
parameters_warning: 4 # Warning level
|
|
24
|
+
parameters_error: 7 # Error level
|
|
25
|
+
|
|
26
|
+
# Method count thresholds (per class)
|
|
27
|
+
methods_warning: 10 # Warning level
|
|
28
|
+
methods_error: 20 # Error level
|
|
29
|
+
|
|
30
|
+
smells:
|
|
31
|
+
# Long method (lines of code)
|
|
32
|
+
long_method_lines: 50
|
|
33
|
+
|
|
34
|
+
# Too many parameters
|
|
35
|
+
too_many_parameters: 5
|
|
36
|
+
|
|
37
|
+
# Deep nesting
|
|
38
|
+
deep_nesting_depth: 4
|
|
39
|
+
|
|
40
|
+
# High complexity
|
|
41
|
+
high_complexity: 15
|
|
42
|
+
|
|
43
|
+
# God class (too many methods)
|
|
44
|
+
god_class_methods: 20
|
|
45
|
+
|
|
46
|
+
# Feature envy (external calls)
|
|
47
|
+
feature_envy_external_calls: 5
|
|
48
|
+
|
|
49
|
+
# Quality gate settings
|
|
50
|
+
fail_on_f_grade: true # Fail quality gate on F grade
|
|
51
|
+
fail_on_smell_count: 10 # Fail if more than N smells total
|
|
52
|
+
warn_on_d_grade: true # Warn on D grade
|
|
@@ -49,6 +49,18 @@ class ProjectConfig(BaseSettings):
|
|
|
49
49
|
default=True,
|
|
50
50
|
description="Respect .gitignore patterns when indexing files",
|
|
51
51
|
)
|
|
52
|
+
openrouter_api_key: str | None = Field(
|
|
53
|
+
default=None,
|
|
54
|
+
description="OpenRouter API key for chat command (optional, can also use env var)",
|
|
55
|
+
)
|
|
56
|
+
openai_api_key: str | None = Field(
|
|
57
|
+
default=None,
|
|
58
|
+
description="OpenAI API key for chat command (optional, can also use env var)",
|
|
59
|
+
)
|
|
60
|
+
preferred_llm_provider: str | None = Field(
|
|
61
|
+
default=None,
|
|
62
|
+
description="Preferred LLM provider: 'openai' or 'openrouter' (auto-detect if not set)",
|
|
63
|
+
)
|
|
52
64
|
|
|
53
65
|
@field_validator("project_root", "index_path", mode="before")
|
|
54
66
|
@classmethod
|