tree-sitter-analyzer 0.9.1__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.

Files changed (61) hide show
  1. tree_sitter_analyzer/__init__.py +132 -132
  2. tree_sitter_analyzer/__main__.py +11 -11
  3. tree_sitter_analyzer/api.py +533 -533
  4. tree_sitter_analyzer/cli/__init__.py +39 -39
  5. tree_sitter_analyzer/cli/__main__.py +12 -12
  6. tree_sitter_analyzer/cli/commands/__init__.py +26 -26
  7. tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
  8. tree_sitter_analyzer/cli/commands/base_command.py +182 -178
  9. tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
  10. tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
  11. tree_sitter_analyzer/core/__init__.py +15 -15
  12. tree_sitter_analyzer/core/analysis_engine.py +74 -78
  13. tree_sitter_analyzer/core/cache_service.py +320 -320
  14. tree_sitter_analyzer/core/engine.py +566 -566
  15. tree_sitter_analyzer/core/parser.py +293 -293
  16. tree_sitter_analyzer/encoding_utils.py +459 -459
  17. tree_sitter_analyzer/file_handler.py +210 -210
  18. tree_sitter_analyzer/formatters/__init__.py +1 -1
  19. tree_sitter_analyzer/formatters/base_formatter.py +167 -167
  20. tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
  21. tree_sitter_analyzer/formatters/java_formatter.py +18 -18
  22. tree_sitter_analyzer/formatters/python_formatter.py +19 -19
  23. tree_sitter_analyzer/interfaces/__init__.py +9 -9
  24. tree_sitter_analyzer/interfaces/cli.py +528 -528
  25. tree_sitter_analyzer/interfaces/cli_adapter.py +344 -343
  26. tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
  27. tree_sitter_analyzer/language_detector.py +53 -53
  28. tree_sitter_analyzer/languages/__init__.py +10 -10
  29. tree_sitter_analyzer/languages/java_plugin.py +1 -1
  30. tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
  31. tree_sitter_analyzer/languages/python_plugin.py +755 -755
  32. tree_sitter_analyzer/mcp/__init__.py +34 -45
  33. tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
  34. tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
  35. tree_sitter_analyzer/mcp/server.py +623 -568
  36. tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
  37. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +681 -673
  38. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -247
  39. tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
  40. tree_sitter_analyzer/mcp/tools/read_partial_tool.py +310 -308
  41. tree_sitter_analyzer/mcp/tools/table_format_tool.py +386 -379
  42. tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +563 -559
  43. tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
  44. tree_sitter_analyzer/models.py +10 -10
  45. tree_sitter_analyzer/output_manager.py +253 -253
  46. tree_sitter_analyzer/plugins/__init__.py +280 -280
  47. tree_sitter_analyzer/plugins/base.py +529 -529
  48. tree_sitter_analyzer/plugins/manager.py +379 -379
  49. tree_sitter_analyzer/queries/__init__.py +26 -26
  50. tree_sitter_analyzer/queries/java.py +391 -391
  51. tree_sitter_analyzer/queries/javascript.py +148 -148
  52. tree_sitter_analyzer/queries/python.py +285 -285
  53. tree_sitter_analyzer/queries/typescript.py +229 -229
  54. tree_sitter_analyzer/query_loader.py +257 -257
  55. tree_sitter_analyzer/security/validator.py +246 -241
  56. tree_sitter_analyzer/utils.py +294 -277
  57. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.2.dist-info}/METADATA +1 -1
  58. tree_sitter_analyzer-0.9.2.dist-info/RECORD +77 -0
  59. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.2.dist-info}/entry_points.txt +1 -0
  60. tree_sitter_analyzer-0.9.1.dist-info/RECORD +0 -77
  61. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.2.dist-info}/WHEEL +0 -0
@@ -1,45 +1,34 @@
1
- #!/usr/bin/env python3
2
- """
3
- MCP (Model Context Protocol) integration for Tree-sitter Analyzer
4
-
5
- This module provides MCP server functionality that exposes the tree-sitter
6
- analyzer capabilities through the Model Context Protocol.
7
- """
8
-
9
- from typing import Any
10
-
11
- __version__ = "0.2.1"
12
- __author__ = "Tree-sitter Analyzer Team"
13
-
14
- # MCP module metadata
15
- MCP_INFO: dict[str, Any] = {
16
- "name": "tree-sitter-analyzer-mcp",
17
- "version": __version__,
18
- "description": "Tree-sitter based code analyzer with MCP support - Solve LLM token limit problems for large code files",
19
- "protocol_version": "2024-11-05",
20
- "capabilities": {
21
- "tools": {
22
- "description": "Three-step workflow for analyzing large code files",
23
- "available_tools": [
24
- "check_code_scale",
25
- "analyze_code_structure",
26
- "extract_code_section"
27
- ],
28
- "workflow": [
29
- "1. check_code_scale - Get file metrics and complexity",
30
- "2. analyze_code_structure - Generate structure tables for large files",
31
- "3. extract_code_section - Get specific code sections by line range"
32
- ]
33
- },
34
- "resources": {},
35
- "prompts": {
36
- "usage_guide": "See README.md AI Assistant Integration section for complete workflow guide"
37
- },
38
- "logging": {},
39
- },
40
- }
41
-
42
- __all__ = [
43
- "MCP_INFO",
44
- "__version__",
45
- ]
1
+ #!/usr/bin/env python3
2
+ """
3
+ MCP (Model Context Protocol) integration for Tree-sitter Analyzer
4
+
5
+ This module provides MCP server functionality that exposes the tree-sitter
6
+ analyzer capabilities through the Model Context Protocol.
7
+ """
8
+
9
+ from typing import Any
10
+
11
+ # Import main package version for consistency
12
+ try:
13
+ from .. import __version__ as main_version
14
+
15
+ __version__ = main_version
16
+ except ImportError:
17
+ # Fallback version if main package not available
18
+ __version__ = "0.9.1"
19
+
20
+ __author__ = "Tree-sitter Analyzer Team"
21
+
22
+ # MCP module metadata
23
+ MCP_INFO: dict[str, Any] = {
24
+ "name": "tree-sitter-analyzer-mcp",
25
+ "version": __version__,
26
+ "description": "Tree-sitter based code analyzer with MCP support - Solve LLM token limit problems for large code files",
27
+ "protocol_version": "2024-11-05",
28
+ "capabilities": {"tools": {}, "resources": {}, "prompts": {}, "logging": {}},
29
+ }
30
+
31
+ __all__ = [
32
+ "MCP_INFO",
33
+ "__version__",
34
+ ]
@@ -1,44 +1,44 @@
1
- #!/usr/bin/env python3
2
- """
3
- MCP Resources Module
4
-
5
- This module provides MCP (Model Context Protocol) resource implementations
6
- for the tree-sitter-analyzer project. Resources provide dynamic content
7
- access through URI-based identification.
8
-
9
- Resources:
10
- - CodeFileResource: Access to code file content
11
- - ProjectStatsResource: Access to project statistics and analysis data
12
-
13
- The resources integrate with existing analyzer components to provide
14
- seamless access to code analysis functionality through the MCP protocol.
15
- """
16
-
17
- # Export main resource classes
18
- from .code_file_resource import CodeFileResource
19
- from .project_stats_resource import ProjectStatsResource
20
-
21
- # Resource metadata
22
- __version__ = "1.0.0"
23
- __author__ = "Tree-Sitter Analyzer Team"
24
-
25
- # MCP Resource capabilities
26
- MCP_RESOURCE_CAPABILITIES = {
27
- "version": "2024-11-05",
28
- "resources": [
29
- {
30
- "name": "code_file",
31
- "description": "Access to code file content",
32
- "uri_template": "code://file/{file_path}",
33
- "mime_type": "text/plain",
34
- },
35
- {
36
- "name": "project_stats",
37
- "description": "Access to project statistics and analysis data",
38
- "uri_template": "code://stats/{stats_type}",
39
- "mime_type": "application/json",
40
- },
41
- ],
42
- }
43
-
44
- __all__ = ["CodeFileResource", "ProjectStatsResource", "MCP_RESOURCE_CAPABILITIES"]
1
+ #!/usr/bin/env python3
2
+ """
3
+ MCP Resources Module
4
+
5
+ This module provides MCP (Model Context Protocol) resource implementations
6
+ for the tree-sitter-analyzer project. Resources provide dynamic content
7
+ access through URI-based identification.
8
+
9
+ Resources:
10
+ - CodeFileResource: Access to code file content
11
+ - ProjectStatsResource: Access to project statistics and analysis data
12
+
13
+ The resources integrate with existing analyzer components to provide
14
+ seamless access to code analysis functionality through the MCP protocol.
15
+ """
16
+
17
+ # Export main resource classes
18
+ from .code_file_resource import CodeFileResource
19
+ from .project_stats_resource import ProjectStatsResource
20
+
21
+ # Resource metadata
22
+ __version__ = "1.0.0"
23
+ __author__ = "Tree-Sitter Analyzer Team"
24
+
25
+ # MCP Resource capabilities
26
+ MCP_RESOURCE_CAPABILITIES = {
27
+ "version": "2024-11-05",
28
+ "resources": [
29
+ {
30
+ "name": "code_file",
31
+ "description": "Access to code file content",
32
+ "uri_template": "code://file/{file_path}",
33
+ "mime_type": "text/plain",
34
+ },
35
+ {
36
+ "name": "project_stats",
37
+ "description": "Access to project statistics and analysis data",
38
+ "uri_template": "code://stats/{stats_type}",
39
+ "mime_type": "application/json",
40
+ },
41
+ ],
42
+ }
43
+
44
+ __all__ = ["CodeFileResource", "ProjectStatsResource", "MCP_RESOURCE_CAPABILITIES"]
@@ -1,209 +1,209 @@
1
- #!/usr/bin/env python3
2
- """
3
- Code File Resource for MCP
4
-
5
- This module provides MCP resource implementation for accessing code file content.
6
- The resource allows dynamic access to file content through URI-based identification.
7
- """
8
-
9
- import logging
10
- import re
11
- from pathlib import Path
12
- from typing import Any
13
-
14
- from tree_sitter_analyzer.encoding_utils import read_file_safe
15
-
16
- logger = logging.getLogger(__name__)
17
-
18
-
19
- class CodeFileResource:
20
- """
21
- MCP resource for accessing code file content
22
-
23
- This resource provides access to code file content through the MCP protocol.
24
- It supports reading files with proper encoding detection and error handling.
25
-
26
- URI Format: code://file/{file_path}
27
-
28
- Examples:
29
- - code://file/src/main/java/Example.java
30
- - code://file/scripts/helper.py
31
- - code://file/test.js
32
- """
33
-
34
- def __init__(self) -> None:
35
- """Initialize the code file resource"""
36
- self._uri_pattern = re.compile(r"^code://file/(.+)$")
37
-
38
- def get_resource_info(self) -> dict[str, Any]:
39
- """
40
- Get resource information for MCP registration
41
-
42
- Returns:
43
- Dict containing resource metadata
44
- """
45
- return {
46
- "name": "code_file",
47
- "description": "Access to code file content through URI-based identification",
48
- "uri_template": "code://file/{file_path}",
49
- "mime_type": "text/plain",
50
- }
51
-
52
- def matches_uri(self, uri: str) -> bool:
53
- """
54
- Check if the URI matches this resource pattern
55
-
56
- Args:
57
- uri: The URI to check
58
-
59
- Returns:
60
- True if the URI matches the code file pattern
61
- """
62
- return bool(self._uri_pattern.match(uri))
63
-
64
- def _extract_file_path(self, uri: str) -> str:
65
- """
66
- Extract file path from URI
67
-
68
- Args:
69
- uri: The URI to extract path from
70
-
71
- Returns:
72
- The extracted file path
73
-
74
- Raises:
75
- ValueError: If URI format is invalid
76
- """
77
- match = self._uri_pattern.match(uri)
78
- if not match:
79
- raise ValueError(f"Invalid URI format: {uri}")
80
-
81
- return match.group(1)
82
-
83
- async def _read_file_content(self, file_path: str) -> str:
84
- """
85
- Read file content with proper encoding detection
86
-
87
- Args:
88
- file_path: Path to the file to read
89
-
90
- Returns:
91
- File content as string
92
-
93
- Raises:
94
- FileNotFoundError: If file doesn't exist
95
- PermissionError: If file cannot be read due to permissions
96
- OSError: If file cannot be read due to other OS errors
97
- """
98
- try:
99
- # Use existing encoding-safe file reader
100
- # Check if file exists first
101
- if not Path(file_path).exists():
102
- raise FileNotFoundError(f"File not found: {file_path}")
103
-
104
- content, encoding = read_file_safe(file_path)
105
- return content
106
-
107
- except FileNotFoundError:
108
- logger.error(f"File not found: {file_path}")
109
- raise
110
- except PermissionError:
111
- logger.error(f"Permission denied reading file: {file_path}")
112
- raise
113
- except OSError as e:
114
- logger.error(f"OS error reading file {file_path}: {e}")
115
- raise
116
- except Exception as e:
117
- logger.error(f"Unexpected error reading file {file_path}: {e}")
118
- raise OSError(f"Failed to read file: {e}") from e
119
-
120
- def _validate_file_path(self, file_path: str) -> None:
121
- """
122
- Validate file path for security and correctness
123
-
124
- Args:
125
- file_path: The file path to validate
126
-
127
- Raises:
128
- ValueError: If file path is invalid or potentially dangerous
129
- """
130
- if not file_path:
131
- raise ValueError("File path cannot be empty")
132
-
133
- # Check for null bytes
134
- if "\x00" in file_path:
135
- raise ValueError("File path contains null bytes")
136
-
137
- # Check for potentially dangerous path traversal
138
- # normalized_path = Path(file_path).resolve() # Not used currently
139
- if ".." in file_path:
140
- logger.warning(f"Potentially dangerous path traversal in: {file_path}")
141
-
142
- # Additional security checks could be added here
143
- # For example, restricting to certain directories
144
-
145
- async def read_resource(self, uri: str) -> str:
146
- """
147
- Read resource content from URI
148
-
149
- Args:
150
- uri: The resource URI to read
151
-
152
- Returns:
153
- Resource content as string
154
-
155
- Raises:
156
- ValueError: If URI format is invalid
157
- FileNotFoundError: If file doesn't exist
158
- PermissionError: If file cannot be read due to permissions
159
- OSError: If file cannot be read due to other errors
160
- """
161
- logger.debug(f"Reading resource: {uri}")
162
-
163
- # Validate URI format
164
- if not self.matches_uri(uri):
165
- raise ValueError(f"URI does not match code file pattern: {uri}")
166
-
167
- # Extract file path
168
- file_path = self._extract_file_path(uri)
169
-
170
- # Validate file path
171
- self._validate_file_path(file_path)
172
-
173
- # Read file content
174
- try:
175
- content = await self._read_file_content(file_path)
176
- logger.debug(
177
- f"Successfully read {len(content)} characters from {file_path}"
178
- )
179
- return content
180
-
181
- except Exception as e:
182
- logger.error(f"Failed to read resource {uri}: {e}")
183
- raise
184
-
185
- def get_supported_schemes(self) -> list[str]:
186
- """
187
- Get list of supported URI schemes
188
-
189
- Returns:
190
- List of supported schemes
191
- """
192
- return ["code"]
193
-
194
- def get_supported_resource_types(self) -> list[str]:
195
- """
196
- Get list of supported resource types
197
-
198
- Returns:
199
- List of supported resource types
200
- """
201
- return ["file"]
202
-
203
- def __str__(self) -> str:
204
- """String representation of the resource"""
205
- return "CodeFileResource(pattern=code://file/{file_path})"
206
-
207
- def __repr__(self) -> str:
208
- """Detailed string representation of the resource"""
209
- return f"CodeFileResource(uri_pattern={self._uri_pattern.pattern})"
1
+ #!/usr/bin/env python3
2
+ """
3
+ Code File Resource for MCP
4
+
5
+ This module provides MCP resource implementation for accessing code file content.
6
+ The resource allows dynamic access to file content through URI-based identification.
7
+ """
8
+
9
+ import logging
10
+ import re
11
+ from pathlib import Path
12
+ from typing import Any
13
+
14
+ from tree_sitter_analyzer.encoding_utils import read_file_safe
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class CodeFileResource:
20
+ """
21
+ MCP resource for accessing code file content
22
+
23
+ This resource provides access to code file content through the MCP protocol.
24
+ It supports reading files with proper encoding detection and error handling.
25
+
26
+ URI Format: code://file/{file_path}
27
+
28
+ Examples:
29
+ - code://file/src/main/java/Example.java
30
+ - code://file/scripts/helper.py
31
+ - code://file/test.js
32
+ """
33
+
34
+ def __init__(self) -> None:
35
+ """Initialize the code file resource"""
36
+ self._uri_pattern = re.compile(r"^code://file/(.+)$")
37
+
38
+ def get_resource_info(self) -> dict[str, Any]:
39
+ """
40
+ Get resource information for MCP registration
41
+
42
+ Returns:
43
+ Dict containing resource metadata
44
+ """
45
+ return {
46
+ "name": "code_file",
47
+ "description": "Access to code file content through URI-based identification",
48
+ "uri_template": "code://file/{file_path}",
49
+ "mime_type": "text/plain",
50
+ }
51
+
52
+ def matches_uri(self, uri: str) -> bool:
53
+ """
54
+ Check if the URI matches this resource pattern
55
+
56
+ Args:
57
+ uri: The URI to check
58
+
59
+ Returns:
60
+ True if the URI matches the code file pattern
61
+ """
62
+ return bool(self._uri_pattern.match(uri))
63
+
64
+ def _extract_file_path(self, uri: str) -> str:
65
+ """
66
+ Extract file path from URI
67
+
68
+ Args:
69
+ uri: The URI to extract path from
70
+
71
+ Returns:
72
+ The extracted file path
73
+
74
+ Raises:
75
+ ValueError: If URI format is invalid
76
+ """
77
+ match = self._uri_pattern.match(uri)
78
+ if not match:
79
+ raise ValueError(f"Invalid URI format: {uri}")
80
+
81
+ return match.group(1)
82
+
83
+ async def _read_file_content(self, file_path: str) -> str:
84
+ """
85
+ Read file content with proper encoding detection
86
+
87
+ Args:
88
+ file_path: Path to the file to read
89
+
90
+ Returns:
91
+ File content as string
92
+
93
+ Raises:
94
+ FileNotFoundError: If file doesn't exist
95
+ PermissionError: If file cannot be read due to permissions
96
+ OSError: If file cannot be read due to other OS errors
97
+ """
98
+ try:
99
+ # Use existing encoding-safe file reader
100
+ # Check if file exists first
101
+ if not Path(file_path).exists():
102
+ raise FileNotFoundError(f"File not found: {file_path}")
103
+
104
+ content, encoding = read_file_safe(file_path)
105
+ return content
106
+
107
+ except FileNotFoundError:
108
+ logger.error(f"File not found: {file_path}")
109
+ raise
110
+ except PermissionError:
111
+ logger.error(f"Permission denied reading file: {file_path}")
112
+ raise
113
+ except OSError as e:
114
+ logger.error(f"OS error reading file {file_path}: {e}")
115
+ raise
116
+ except Exception as e:
117
+ logger.error(f"Unexpected error reading file {file_path}: {e}")
118
+ raise OSError(f"Failed to read file: {e}") from e
119
+
120
+ def _validate_file_path(self, file_path: str) -> None:
121
+ """
122
+ Validate file path for security and correctness
123
+
124
+ Args:
125
+ file_path: The file path to validate
126
+
127
+ Raises:
128
+ ValueError: If file path is invalid or potentially dangerous
129
+ """
130
+ if not file_path:
131
+ raise ValueError("File path cannot be empty")
132
+
133
+ # Check for null bytes
134
+ if "\x00" in file_path:
135
+ raise ValueError("File path contains null bytes")
136
+
137
+ # Check for potentially dangerous path traversal
138
+ # normalized_path = Path(file_path).resolve() # Not used currently
139
+ if ".." in file_path:
140
+ logger.warning(f"Potentially dangerous path traversal in: {file_path}")
141
+
142
+ # Additional security checks could be added here
143
+ # For example, restricting to certain directories
144
+
145
+ async def read_resource(self, uri: str) -> str:
146
+ """
147
+ Read resource content from URI
148
+
149
+ Args:
150
+ uri: The resource URI to read
151
+
152
+ Returns:
153
+ Resource content as string
154
+
155
+ Raises:
156
+ ValueError: If URI format is invalid
157
+ FileNotFoundError: If file doesn't exist
158
+ PermissionError: If file cannot be read due to permissions
159
+ OSError: If file cannot be read due to other errors
160
+ """
161
+ logger.debug(f"Reading resource: {uri}")
162
+
163
+ # Validate URI format
164
+ if not self.matches_uri(uri):
165
+ raise ValueError(f"URI does not match code file pattern: {uri}")
166
+
167
+ # Extract file path
168
+ file_path = self._extract_file_path(uri)
169
+
170
+ # Validate file path
171
+ self._validate_file_path(file_path)
172
+
173
+ # Read file content
174
+ try:
175
+ content = await self._read_file_content(file_path)
176
+ logger.debug(
177
+ f"Successfully read {len(content)} characters from {file_path}"
178
+ )
179
+ return content
180
+
181
+ except Exception as e:
182
+ logger.error(f"Failed to read resource {uri}: {e}")
183
+ raise
184
+
185
+ def get_supported_schemes(self) -> list[str]:
186
+ """
187
+ Get list of supported URI schemes
188
+
189
+ Returns:
190
+ List of supported schemes
191
+ """
192
+ return ["code"]
193
+
194
+ def get_supported_resource_types(self) -> list[str]:
195
+ """
196
+ Get list of supported resource types
197
+
198
+ Returns:
199
+ List of supported resource types
200
+ """
201
+ return ["file"]
202
+
203
+ def __str__(self) -> str:
204
+ """String representation of the resource"""
205
+ return "CodeFileResource(pattern=code://file/{file_path})"
206
+
207
+ def __repr__(self) -> str:
208
+ """Detailed string representation of the resource"""
209
+ return f"CodeFileResource(uri_pattern={self._uri_pattern.pattern})"