tree-sitter-analyzer 0.8.3__py3-none-any.whl → 0.9.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 tree-sitter-analyzer might be problematic. Click here for more details.
- tree_sitter_analyzer/__init__.py +132 -132
- tree_sitter_analyzer/__main__.py +11 -11
- tree_sitter_analyzer/api.py +533 -533
- tree_sitter_analyzer/cli/__init__.py +39 -39
- tree_sitter_analyzer/cli/__main__.py +12 -12
- tree_sitter_analyzer/cli/commands/__init__.py +26 -26
- tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
- tree_sitter_analyzer/cli/commands/base_command.py +182 -180
- tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
- tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
- tree_sitter_analyzer/core/__init__.py +15 -15
- tree_sitter_analyzer/core/analysis_engine.py +74 -78
- tree_sitter_analyzer/core/cache_service.py +320 -320
- tree_sitter_analyzer/core/engine.py +566 -566
- tree_sitter_analyzer/core/parser.py +293 -293
- tree_sitter_analyzer/encoding_utils.py +459 -459
- tree_sitter_analyzer/file_handler.py +210 -210
- tree_sitter_analyzer/formatters/__init__.py +1 -1
- tree_sitter_analyzer/formatters/base_formatter.py +167 -167
- tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
- tree_sitter_analyzer/formatters/java_formatter.py +18 -18
- tree_sitter_analyzer/formatters/python_formatter.py +19 -19
- tree_sitter_analyzer/interfaces/__init__.py +9 -9
- tree_sitter_analyzer/interfaces/cli.py +528 -528
- tree_sitter_analyzer/interfaces/cli_adapter.py +344 -343
- tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
- tree_sitter_analyzer/language_detector.py +53 -53
- tree_sitter_analyzer/languages/__init__.py +10 -10
- tree_sitter_analyzer/languages/java_plugin.py +1 -1
- tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
- tree_sitter_analyzer/languages/python_plugin.py +755 -755
- tree_sitter_analyzer/mcp/__init__.py +34 -31
- tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
- tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
- tree_sitter_analyzer/mcp/server.py +623 -436
- tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +10 -6
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -242
- tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
- tree_sitter_analyzer/mcp/tools/read_partial_tool.py +310 -308
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +386 -379
- tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +563 -559
- tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
- tree_sitter_analyzer/models.py +10 -10
- tree_sitter_analyzer/output_manager.py +253 -253
- tree_sitter_analyzer/plugins/__init__.py +280 -280
- tree_sitter_analyzer/plugins/base.py +529 -529
- tree_sitter_analyzer/plugins/manager.py +379 -379
- tree_sitter_analyzer/queries/__init__.py +26 -26
- tree_sitter_analyzer/queries/java.py +391 -391
- tree_sitter_analyzer/queries/javascript.py +148 -148
- tree_sitter_analyzer/queries/python.py +285 -285
- tree_sitter_analyzer/queries/typescript.py +229 -229
- tree_sitter_analyzer/query_loader.py +257 -257
- tree_sitter_analyzer/security/boundary_manager.py +237 -279
- tree_sitter_analyzer/security/validator.py +60 -58
- tree_sitter_analyzer/utils.py +294 -277
- {tree_sitter_analyzer-0.8.3.dist-info → tree_sitter_analyzer-0.9.2.dist-info}/METADATA +28 -19
- tree_sitter_analyzer-0.9.2.dist-info/RECORD +77 -0
- {tree_sitter_analyzer-0.8.3.dist-info → tree_sitter_analyzer-0.9.2.dist-info}/entry_points.txt +1 -0
- tree_sitter_analyzer-0.8.3.dist-info/RECORD +0 -77
- {tree_sitter_analyzer-0.8.3.dist-info → tree_sitter_analyzer-0.9.2.dist-info}/WHEEL +0 -0
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
MCP Tools package for Tree-sitter Analyzer
|
|
4
|
-
|
|
5
|
-
This package contains all MCP tools that provide specific functionality
|
|
6
|
-
through the Model Context Protocol.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
__version__ = "1.0.0"
|
|
12
|
-
|
|
13
|
-
# Tool registry for easy access
|
|
14
|
-
AVAILABLE_TOOLS: dict[str, dict[str, Any]] = {
|
|
15
|
-
"analyze_code_scale": {
|
|
16
|
-
"description": "Analyze code scale, complexity, and structure metrics",
|
|
17
|
-
"module": "analyze_scale_tool",
|
|
18
|
-
"class": "AnalyzeScaleTool",
|
|
19
|
-
},
|
|
20
|
-
# Future tools will be added here
|
|
21
|
-
# "read_code_partial": {
|
|
22
|
-
# "description": "Read partial content from code files",
|
|
23
|
-
# "module": "read_partial_tool",
|
|
24
|
-
# "class": "ReadPartialTool",
|
|
25
|
-
# },
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
__all__ = [
|
|
29
|
-
"AVAILABLE_TOOLS",
|
|
30
|
-
]
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
MCP Tools package for Tree-sitter Analyzer
|
|
4
|
+
|
|
5
|
+
This package contains all MCP tools that provide specific functionality
|
|
6
|
+
through the Model Context Protocol.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
__version__ = "1.0.0"
|
|
12
|
+
|
|
13
|
+
# Tool registry for easy access
|
|
14
|
+
AVAILABLE_TOOLS: dict[str, dict[str, Any]] = {
|
|
15
|
+
"analyze_code_scale": {
|
|
16
|
+
"description": "Analyze code scale, complexity, and structure metrics",
|
|
17
|
+
"module": "analyze_scale_tool",
|
|
18
|
+
"class": "AnalyzeScaleTool",
|
|
19
|
+
},
|
|
20
|
+
# Future tools will be added here
|
|
21
|
+
# "read_code_partial": {
|
|
22
|
+
# "description": "Read partial content from code files",
|
|
23
|
+
# "module": "read_partial_tool",
|
|
24
|
+
# "class": "ReadPartialTool",
|
|
25
|
+
# },
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"AVAILABLE_TOOLS",
|
|
30
|
+
]
|
|
@@ -255,7 +255,13 @@ class AnalyzeScaleTool:
|
|
|
255
255
|
guidance["recommended_tools"].append("read_code_partial")
|
|
256
256
|
|
|
257
257
|
# Ensure all required fields exist
|
|
258
|
-
required_fields = [
|
|
258
|
+
required_fields = [
|
|
259
|
+
"complexity_hotspots",
|
|
260
|
+
"classes",
|
|
261
|
+
"methods",
|
|
262
|
+
"fields",
|
|
263
|
+
"imports",
|
|
264
|
+
]
|
|
259
265
|
for field in required_fields:
|
|
260
266
|
if field not in structural_overview:
|
|
261
267
|
structural_overview[field] = []
|
|
@@ -348,10 +354,8 @@ class AnalyzeScaleTool:
|
|
|
348
354
|
include_details = arguments.get("include_details", False)
|
|
349
355
|
include_guidance = arguments.get("include_guidance", True)
|
|
350
356
|
|
|
351
|
-
# Security validation
|
|
352
|
-
is_valid, error_msg = self.security_validator.validate_file_path(
|
|
353
|
-
file_path, base_path=self.project_root
|
|
354
|
-
)
|
|
357
|
+
# Security validation
|
|
358
|
+
is_valid, error_msg = self.security_validator.validate_file_path(file_path)
|
|
355
359
|
if not is_valid:
|
|
356
360
|
logger.warning(
|
|
357
361
|
f"Security validation failed for file path: {file_path} - {error_msg}"
|
|
@@ -364,7 +368,7 @@ class AnalyzeScaleTool:
|
|
|
364
368
|
|
|
365
369
|
# Validate file exists
|
|
366
370
|
if not Path(file_path).exists():
|
|
367
|
-
raise
|
|
371
|
+
raise ValueError("Invalid file path: file does not exist")
|
|
368
372
|
|
|
369
373
|
# Detect language if not specified
|
|
370
374
|
if not language:
|
|
@@ -1,242 +1,247 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
CLI-Compatible Analyze Code Scale MCP Tool
|
|
4
|
-
|
|
5
|
-
This tool provides code scale analysis with output format
|
|
6
|
-
that matches the CLI --advanced --statistics output exactly.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import time
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
from typing import Any, cast
|
|
12
|
-
|
|
13
|
-
from ...core.analysis_engine import get_analysis_engine
|
|
14
|
-
from ...language_detector import detect_language_from_file
|
|
15
|
-
from ...utils import setup_logger
|
|
16
|
-
|
|
17
|
-
# Set up logging
|
|
18
|
-
logger = setup_logger(__name__)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class AnalyzeScaleToolCLICompatible:
|
|
22
|
-
"""
|
|
23
|
-
MCP Tool for analyzing code scale with CLI-compatible output format.
|
|
24
|
-
|
|
25
|
-
This tool matches the exact output format of CLI --advanced --statistics.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def __init__(self) -> None:
|
|
29
|
-
"""Initialize the CLI-compatible analyze scale tool."""
|
|
30
|
-
self.analysis_engine = get_analysis_engine()
|
|
31
|
-
logger.info("AnalyzeScaleToolCLICompatible initialized")
|
|
32
|
-
|
|
33
|
-
def get_tool_schema(self) -> dict[str, Any]:
|
|
34
|
-
"""
|
|
35
|
-
Get the MCP tool schema for analyze_code_scale.
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
Dictionary containing the tool schema
|
|
39
|
-
"""
|
|
40
|
-
return {
|
|
41
|
-
"type": "object",
|
|
42
|
-
"properties": {
|
|
43
|
-
"file_path": {
|
|
44
|
-
"type": "string",
|
|
45
|
-
"description": "Path to the code file to analyze",
|
|
46
|
-
},
|
|
47
|
-
"language": {
|
|
48
|
-
"type": "string",
|
|
49
|
-
"description": "Programming language (optional, auto-detected if not specified)",
|
|
50
|
-
},
|
|
51
|
-
"include_complexity": {
|
|
52
|
-
"type": "boolean",
|
|
53
|
-
"description": "Include complexity metrics in the analysis",
|
|
54
|
-
"default": True,
|
|
55
|
-
},
|
|
56
|
-
"include_details": {
|
|
57
|
-
"type": "boolean",
|
|
58
|
-
"description": "Include detailed element information",
|
|
59
|
-
"default": False,
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
"required": ["file_path"],
|
|
63
|
-
"additionalProperties": False,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async def execute(self, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
67
|
-
"""
|
|
68
|
-
Execute the analyze_code_scale tool with CLI-compatible output.
|
|
69
|
-
|
|
70
|
-
Args:
|
|
71
|
-
arguments: Tool arguments containing file_path and optional parameters
|
|
72
|
-
|
|
73
|
-
Returns:
|
|
74
|
-
Dictionary containing analysis results in CLI-compatible format
|
|
75
|
-
|
|
76
|
-
Raises:
|
|
77
|
-
ValueError: If required arguments are missing or invalid
|
|
78
|
-
FileNotFoundError: If the specified file doesn't exist
|
|
79
|
-
"""
|
|
80
|
-
# Validate required arguments
|
|
81
|
-
if "file_path" not in arguments:
|
|
82
|
-
raise ValueError("file_path is required")
|
|
83
|
-
|
|
84
|
-
file_path = arguments["file_path"]
|
|
85
|
-
language = arguments.get("language")
|
|
86
|
-
# include_complexity = arguments.get("include_complexity", True) # Not used currently
|
|
87
|
-
# include_details = arguments.get("include_details", False) # Not used currently
|
|
88
|
-
|
|
89
|
-
# Validate file exists
|
|
90
|
-
if not Path(file_path).exists():
|
|
91
|
-
raise FileNotFoundError(f"File not found: {file_path}")
|
|
92
|
-
|
|
93
|
-
# Detect language if not specified
|
|
94
|
-
if not language:
|
|
95
|
-
language = detect_language_from_file(file_path)
|
|
96
|
-
if language == "unknown":
|
|
97
|
-
raise ValueError(f"Could not detect language for file: {file_path}")
|
|
98
|
-
|
|
99
|
-
logger.info(f"Analyzing code scale for {file_path} (language: {language})")
|
|
100
|
-
|
|
101
|
-
try:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# Handle potential None result (for testing purposes with mocked engine)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
#
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if "
|
|
206
|
-
|
|
207
|
-
if not isinstance(
|
|
208
|
-
raise ValueError("
|
|
209
|
-
|
|
210
|
-
if "
|
|
211
|
-
|
|
212
|
-
if not isinstance(
|
|
213
|
-
raise ValueError("
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"""
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
CLI-Compatible Analyze Code Scale MCP Tool
|
|
4
|
+
|
|
5
|
+
This tool provides code scale analysis with output format
|
|
6
|
+
that matches the CLI --advanced --statistics output exactly.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import time
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, cast
|
|
12
|
+
|
|
13
|
+
from ...core.analysis_engine import get_analysis_engine
|
|
14
|
+
from ...language_detector import detect_language_from_file
|
|
15
|
+
from ...utils import setup_logger
|
|
16
|
+
|
|
17
|
+
# Set up logging
|
|
18
|
+
logger = setup_logger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AnalyzeScaleToolCLICompatible:
|
|
22
|
+
"""
|
|
23
|
+
MCP Tool for analyzing code scale with CLI-compatible output format.
|
|
24
|
+
|
|
25
|
+
This tool matches the exact output format of CLI --advanced --statistics.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self) -> None:
|
|
29
|
+
"""Initialize the CLI-compatible analyze scale tool."""
|
|
30
|
+
self.analysis_engine = get_analysis_engine()
|
|
31
|
+
logger.info("AnalyzeScaleToolCLICompatible initialized")
|
|
32
|
+
|
|
33
|
+
def get_tool_schema(self) -> dict[str, Any]:
|
|
34
|
+
"""
|
|
35
|
+
Get the MCP tool schema for analyze_code_scale.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Dictionary containing the tool schema
|
|
39
|
+
"""
|
|
40
|
+
return {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"properties": {
|
|
43
|
+
"file_path": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Path to the code file to analyze",
|
|
46
|
+
},
|
|
47
|
+
"language": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "Programming language (optional, auto-detected if not specified)",
|
|
50
|
+
},
|
|
51
|
+
"include_complexity": {
|
|
52
|
+
"type": "boolean",
|
|
53
|
+
"description": "Include complexity metrics in the analysis",
|
|
54
|
+
"default": True,
|
|
55
|
+
},
|
|
56
|
+
"include_details": {
|
|
57
|
+
"type": "boolean",
|
|
58
|
+
"description": "Include detailed element information",
|
|
59
|
+
"default": False,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
"required": ["file_path"],
|
|
63
|
+
"additionalProperties": False,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async def execute(self, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
67
|
+
"""
|
|
68
|
+
Execute the analyze_code_scale tool with CLI-compatible output.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
arguments: Tool arguments containing file_path and optional parameters
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Dictionary containing analysis results in CLI-compatible format
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
ValueError: If required arguments are missing or invalid
|
|
78
|
+
FileNotFoundError: If the specified file doesn't exist
|
|
79
|
+
"""
|
|
80
|
+
# Validate required arguments
|
|
81
|
+
if "file_path" not in arguments:
|
|
82
|
+
raise ValueError("file_path is required")
|
|
83
|
+
|
|
84
|
+
file_path = arguments["file_path"]
|
|
85
|
+
language = arguments.get("language")
|
|
86
|
+
# include_complexity = arguments.get("include_complexity", True) # Not used currently
|
|
87
|
+
# include_details = arguments.get("include_details", False) # Not used currently
|
|
88
|
+
|
|
89
|
+
# Validate file exists
|
|
90
|
+
if not Path(file_path).exists():
|
|
91
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
|
92
|
+
|
|
93
|
+
# Detect language if not specified
|
|
94
|
+
if not language:
|
|
95
|
+
language = detect_language_from_file(file_path)
|
|
96
|
+
if language == "unknown":
|
|
97
|
+
raise ValueError(f"Could not detect language for file: {file_path}")
|
|
98
|
+
|
|
99
|
+
logger.info(f"Analyzing code scale for {file_path} (language: {language})")
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
start_time = time.time()
|
|
103
|
+
|
|
104
|
+
# Use AdvancedAnalyzer for comprehensive analysis
|
|
105
|
+
analysis_result = await self.analysis_engine.analyze_file(file_path)
|
|
106
|
+
|
|
107
|
+
# Handle potential None result (for testing purposes with mocked engine)
|
|
108
|
+
# This can only happen in tests where the engine is mocked to return None
|
|
109
|
+
# Use cast to tell MyPy this is possible in testing scenarios
|
|
110
|
+
if cast(Any, analysis_result) is None:
|
|
111
|
+
return {
|
|
112
|
+
"file_path": file_path,
|
|
113
|
+
"success": False,
|
|
114
|
+
"package_name": None,
|
|
115
|
+
"element_counts": {
|
|
116
|
+
"imports": 0,
|
|
117
|
+
"classes": 0,
|
|
118
|
+
"methods": 0,
|
|
119
|
+
"fields": 0,
|
|
120
|
+
"annotations": 0,
|
|
121
|
+
},
|
|
122
|
+
"analysis_time_ms": round((time.time() - start_time) * 1000, 2),
|
|
123
|
+
"error_message": f"Failed to analyze file: {file_path}",
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# Calculate analysis time
|
|
127
|
+
analysis_time_ms = round((time.time() - start_time) * 1000, 2)
|
|
128
|
+
|
|
129
|
+
# Build CLI-compatible result structure (exact match with CLI --advanced --statistics)
|
|
130
|
+
result = {
|
|
131
|
+
"file_path": file_path,
|
|
132
|
+
"success": True,
|
|
133
|
+
"package_name": (
|
|
134
|
+
analysis_result.package.name
|
|
135
|
+
if analysis_result.package
|
|
136
|
+
and hasattr(analysis_result.package, "name")
|
|
137
|
+
else None
|
|
138
|
+
),
|
|
139
|
+
"element_counts": {
|
|
140
|
+
"imports": len(analysis_result.imports),
|
|
141
|
+
"classes": len(analysis_result.classes),
|
|
142
|
+
"methods": len(analysis_result.methods),
|
|
143
|
+
"fields": len(analysis_result.fields),
|
|
144
|
+
"annotations": len(getattr(analysis_result, "annotations", [])),
|
|
145
|
+
},
|
|
146
|
+
"analysis_time_ms": analysis_time_ms,
|
|
147
|
+
"error_message": None,
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
logger.info(
|
|
151
|
+
f"Successfully analyzed {file_path}: {len(analysis_result.classes)} classes, "
|
|
152
|
+
f"{len(analysis_result.methods)} methods, {analysis_time_ms}ms"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
return result
|
|
156
|
+
|
|
157
|
+
except Exception as e:
|
|
158
|
+
logger.error(f"Error analyzing {file_path}: {e}")
|
|
159
|
+
# Return CLI-compatible error format
|
|
160
|
+
return {
|
|
161
|
+
"file_path": file_path,
|
|
162
|
+
"success": False,
|
|
163
|
+
"package_name": None,
|
|
164
|
+
"element_counts": {
|
|
165
|
+
"imports": 0,
|
|
166
|
+
"classes": 0,
|
|
167
|
+
"methods": 0,
|
|
168
|
+
"fields": 0,
|
|
169
|
+
"annotations": 0,
|
|
170
|
+
},
|
|
171
|
+
"analysis_time_ms": 0.0,
|
|
172
|
+
"error_message": str(e),
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
def validate_arguments(self, arguments: dict[str, Any]) -> bool:
|
|
176
|
+
"""
|
|
177
|
+
Validate tool arguments against the schema.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
arguments: Arguments to validate
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
True if arguments are valid
|
|
184
|
+
|
|
185
|
+
Raises:
|
|
186
|
+
ValueError: If arguments are invalid
|
|
187
|
+
"""
|
|
188
|
+
schema = self.get_tool_schema()
|
|
189
|
+
required_fields = schema.get("required", [])
|
|
190
|
+
|
|
191
|
+
# Check required fields
|
|
192
|
+
for field in required_fields:
|
|
193
|
+
if field not in arguments:
|
|
194
|
+
raise ValueError(f"Required field '{field}' is missing")
|
|
195
|
+
|
|
196
|
+
# Validate file_path
|
|
197
|
+
if "file_path" in arguments:
|
|
198
|
+
file_path = arguments["file_path"]
|
|
199
|
+
if not isinstance(file_path, str):
|
|
200
|
+
raise ValueError("file_path must be a string")
|
|
201
|
+
if not file_path.strip():
|
|
202
|
+
raise ValueError("file_path cannot be empty")
|
|
203
|
+
|
|
204
|
+
# Validate optional fields
|
|
205
|
+
if "language" in arguments:
|
|
206
|
+
language = arguments["language"]
|
|
207
|
+
if not isinstance(language, str):
|
|
208
|
+
raise ValueError("language must be a string")
|
|
209
|
+
|
|
210
|
+
if "include_complexity" in arguments:
|
|
211
|
+
include_complexity = arguments["include_complexity"]
|
|
212
|
+
if not isinstance(include_complexity, bool):
|
|
213
|
+
raise ValueError("include_complexity must be a boolean")
|
|
214
|
+
|
|
215
|
+
if "include_details" in arguments:
|
|
216
|
+
include_details = arguments["include_details"]
|
|
217
|
+
if not isinstance(include_details, bool):
|
|
218
|
+
raise ValueError("include_details must be a boolean")
|
|
219
|
+
|
|
220
|
+
return True
|
|
221
|
+
|
|
222
|
+
def get_tool_definition(self) -> Any:
|
|
223
|
+
"""
|
|
224
|
+
Get the MCP tool definition for analyze_code_scale.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Tool definition object compatible with MCP server
|
|
228
|
+
"""
|
|
229
|
+
try:
|
|
230
|
+
from mcp.types import Tool
|
|
231
|
+
|
|
232
|
+
return Tool(
|
|
233
|
+
name="analyze_code_scale",
|
|
234
|
+
description="Analyze code scale, complexity, and structure metrics with CLI-compatible output format",
|
|
235
|
+
inputSchema=self.get_tool_schema(),
|
|
236
|
+
)
|
|
237
|
+
except ImportError:
|
|
238
|
+
# Fallback for when MCP is not available
|
|
239
|
+
return {
|
|
240
|
+
"name": "analyze_code_scale",
|
|
241
|
+
"description": "Analyze code scale, complexity, and structure metrics with CLI-compatible output format",
|
|
242
|
+
"inputSchema": self.get_tool_schema(),
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
# Tool instance for easy access
|
|
247
|
+
analyze_scale_tool_cli_compatible = AnalyzeScaleToolCLICompatible()
|