tree-sitter-analyzer 1.8.2__py3-none-any.whl → 1.8.4__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.

@@ -11,7 +11,7 @@ Architecture:
11
11
  - Data Models: Generic and language-specific code element representations
12
12
  """
13
13
 
14
- __version__ = "1.8.2"
14
+ __version__ = "1.8.4"
15
15
  __author__ = "aisheng.yu"
16
16
  __email__ = "aimasteracc@gmail.com"
17
17
 
@@ -27,7 +27,18 @@ class FindAndGrepTool(BaseMCPTool):
27
27
  def __init__(self, project_root: str | None = None) -> None:
28
28
  """Initialize the find and grep tool."""
29
29
  super().__init__(project_root)
30
- self.file_output_manager = FileOutputManager(project_root)
30
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_root)
31
+
32
+ def set_project_path(self, project_path: str) -> None:
33
+ """
34
+ Update the project path for all components.
35
+
36
+ Args:
37
+ project_path: New project root directory
38
+ """
39
+ super().set_project_path(project_path)
40
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_path)
41
+ logger.info(f"FindAndGrepTool project path updated to: {project_path}")
31
42
 
32
43
  def get_tool_definition(self) -> dict[str, Any]:
33
44
  return {
@@ -26,7 +26,7 @@ class QueryTool(BaseMCPTool):
26
26
  """Initialize query tool"""
27
27
  super().__init__(project_root)
28
28
  self.query_service = QueryService(project_root)
29
- self.file_output_manager = FileOutputManager(project_root)
29
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_root)
30
30
 
31
31
  def set_project_path(self, project_path: str) -> None:
32
32
  """
@@ -37,7 +37,7 @@ class QueryTool(BaseMCPTool):
37
37
  """
38
38
  super().set_project_path(project_path)
39
39
  self.query_service = QueryService(project_path)
40
- self.file_output_manager.set_project_root(project_path)
40
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_path)
41
41
  logger.info(f"QueryTool project path updated to: {project_path}")
42
42
 
43
43
  def get_tool_definition(self) -> dict[str, Any]:
@@ -37,7 +37,18 @@ class SearchContentTool(BaseMCPTool):
37
37
  """
38
38
  super().__init__(project_root)
39
39
  self.cache = get_default_cache() if enable_cache else None
40
- self.file_output_manager = FileOutputManager(project_root)
40
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_root)
41
+
42
+ def set_project_path(self, project_path: str) -> None:
43
+ """
44
+ Update the project path for all components.
45
+
46
+ Args:
47
+ project_path: New project root directory
48
+ """
49
+ super().set_project_path(project_path)
50
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_path)
51
+ logger.info(f"SearchContentTool project path updated to: {project_path}")
41
52
 
42
53
  def get_tool_definition(self) -> dict[str, Any]:
43
54
  return {
@@ -42,7 +42,7 @@ class TableFormatTool(BaseMCPTool):
42
42
  """Initialize the table format tool."""
43
43
  super().__init__(project_root)
44
44
  self.analysis_engine = get_analysis_engine(project_root)
45
- self.file_output_manager = FileOutputManager(project_root)
45
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_root)
46
46
  self.logger = logger
47
47
 
48
48
  def set_project_path(self, project_path: str) -> None:
@@ -54,7 +54,7 @@ class TableFormatTool(BaseMCPTool):
54
54
  """
55
55
  super().set_project_path(project_path)
56
56
  self.analysis_engine = get_analysis_engine(project_path)
57
- self.file_output_manager.set_project_root(project_path)
57
+ self.file_output_manager = FileOutputManager.get_managed_instance(project_path)
58
58
  logger.info(f"TableFormatTool project path updated to: {project_path}")
59
59
 
60
60
  def get_tool_schema(self) -> dict[str, Any]:
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ File Output Manager Factory
4
+
5
+ This module provides a Managed Singleton Factory Pattern for FileOutputManager
6
+ to prevent duplicate initialization and ensure consistent instance management
7
+ across MCP tools.
8
+ """
9
+
10
+ import threading
11
+ from pathlib import Path
12
+ from typing import Dict, Optional
13
+
14
+ from ...utils import setup_logger
15
+ from .file_output_manager import FileOutputManager
16
+
17
+ # Set up logging
18
+ logger = setup_logger(__name__)
19
+
20
+
21
+ class FileOutputManagerFactory:
22
+ """
23
+ Factory class that manages FileOutputManager instances using a Managed Singleton
24
+ pattern. Each project root gets its own singleton instance, ensuring consistency
25
+ across MCP tools while preventing duplicate initialization.
26
+ """
27
+
28
+ # Class-level lock for thread safety
29
+ _lock = threading.RLock()
30
+
31
+ # Dictionary to store instances by project root
32
+ _instances: Dict[str, FileOutputManager] = {}
33
+
34
+ @classmethod
35
+ def get_instance(cls, project_root: Optional[str] = None) -> FileOutputManager:
36
+ """
37
+ Get or create a FileOutputManager instance for the specified project root.
38
+
39
+ This method implements the Managed Singleton pattern - one instance per
40
+ project root, ensuring consistency across all MCP tools.
41
+
42
+ Args:
43
+ project_root: Project root directory. If None, uses current working directory.
44
+
45
+ Returns:
46
+ FileOutputManager instance for the specified project root
47
+ """
48
+ # Normalize project root path
49
+ normalized_root = cls._normalize_project_root(project_root)
50
+
51
+ # Double-checked locking pattern for thread safety
52
+ if normalized_root not in cls._instances:
53
+ with cls._lock:
54
+ if normalized_root not in cls._instances:
55
+ logger.info(f"Creating new FileOutputManager instance for project root: {normalized_root}")
56
+ cls._instances[normalized_root] = FileOutputManager(normalized_root)
57
+ else:
58
+ logger.debug(f"Using existing FileOutputManager instance for project root: {normalized_root}")
59
+ else:
60
+ logger.debug(f"Using existing FileOutputManager instance for project root: {normalized_root}")
61
+
62
+ return cls._instances[normalized_root]
63
+
64
+ @classmethod
65
+ def _normalize_project_root(cls, project_root: Optional[str]) -> str:
66
+ """
67
+ Normalize project root path for consistent key generation.
68
+
69
+ Args:
70
+ project_root: Raw project root path
71
+
72
+ Returns:
73
+ Normalized absolute path string
74
+ """
75
+ if project_root is None:
76
+ return str(Path.cwd().resolve())
77
+
78
+ try:
79
+ return str(Path(project_root).resolve())
80
+ except Exception as e:
81
+ logger.warning(f"Failed to resolve project root path '{project_root}': {e}")
82
+ return str(Path.cwd().resolve())
83
+
84
+ @classmethod
85
+ def clear_instance(cls, project_root: Optional[str] = None) -> bool:
86
+ """
87
+ Clear a specific FileOutputManager instance from the factory.
88
+
89
+ This method is primarily for testing purposes or when you need to
90
+ force recreation of an instance.
91
+
92
+ Args:
93
+ project_root: Project root directory. If None, uses current working directory.
94
+
95
+ Returns:
96
+ True if instance was cleared, False if it didn't exist
97
+ """
98
+ normalized_root = cls._normalize_project_root(project_root)
99
+
100
+ with cls._lock:
101
+ if normalized_root in cls._instances:
102
+ logger.info(f"Clearing FileOutputManager instance for project root: {normalized_root}")
103
+ del cls._instances[normalized_root]
104
+ return True
105
+ else:
106
+ logger.debug(f"No FileOutputManager instance found for project root: {normalized_root}")
107
+ return False
108
+
109
+ @classmethod
110
+ def clear_all_instances(cls) -> int:
111
+ """
112
+ Clear all FileOutputManager instances from the factory.
113
+
114
+ This method is primarily for testing purposes or cleanup.
115
+
116
+ Returns:
117
+ Number of instances that were cleared
118
+ """
119
+ with cls._lock:
120
+ count = len(cls._instances)
121
+ if count > 0:
122
+ logger.info(f"Clearing all {count} FileOutputManager instances")
123
+ cls._instances.clear()
124
+ else:
125
+ logger.debug("No FileOutputManager instances to clear")
126
+ return count
127
+
128
+ @classmethod
129
+ def get_instance_count(cls) -> int:
130
+ """
131
+ Get the current number of managed instances.
132
+
133
+ Returns:
134
+ Number of currently managed FileOutputManager instances
135
+ """
136
+ with cls._lock:
137
+ return len(cls._instances)
138
+
139
+ @classmethod
140
+ def get_managed_project_roots(cls) -> list[str]:
141
+ """
142
+ Get list of all currently managed project roots.
143
+
144
+ Returns:
145
+ List of project root paths that have managed instances
146
+ """
147
+ with cls._lock:
148
+ return list(cls._instances.keys())
149
+
150
+ @classmethod
151
+ def update_project_root(cls, old_root: Optional[str], new_root: str) -> bool:
152
+ """
153
+ Update the project root for an existing instance.
154
+
155
+ This method moves an existing instance from one project root key to another,
156
+ and updates the instance's internal project root.
157
+
158
+ Args:
159
+ old_root: Current project root (None for current working directory)
160
+ new_root: New project root
161
+
162
+ Returns:
163
+ True if update was successful, False if old instance didn't exist
164
+ """
165
+ old_normalized = cls._normalize_project_root(old_root)
166
+ new_normalized = cls._normalize_project_root(new_root)
167
+
168
+ if old_normalized == new_normalized:
169
+ logger.debug(f"Project root update not needed: {old_normalized}")
170
+ return True
171
+
172
+ with cls._lock:
173
+ if old_normalized in cls._instances:
174
+ instance = cls._instances[old_normalized]
175
+
176
+ # Update the instance's internal project root
177
+ instance.set_project_root(new_root)
178
+
179
+ # Move to new key
180
+ cls._instances[new_normalized] = instance
181
+ del cls._instances[old_normalized]
182
+
183
+ logger.info(f"Updated FileOutputManager project root: {old_normalized} -> {new_normalized}")
184
+ return True
185
+ else:
186
+ logger.warning(f"No FileOutputManager instance found for old project root: {old_normalized}")
187
+ return False
188
+
189
+
190
+ # Convenience function for backward compatibility and ease of use
191
+ def get_file_output_manager(project_root: Optional[str] = None) -> FileOutputManager:
192
+ """
193
+ Convenience function to get a FileOutputManager instance.
194
+
195
+ This function provides a simple interface to the factory while maintaining
196
+ the singleton behavior per project root.
197
+
198
+ Args:
199
+ project_root: Project root directory. If None, uses current working directory.
200
+
201
+ Returns:
202
+ FileOutputManager instance for the specified project root
203
+ """
204
+ return FileOutputManagerFactory.get_instance(project_root)
@@ -4,12 +4,15 @@ File Output Manager for MCP Tools
4
4
 
5
5
  This module provides functionality to save analysis results to files with
6
6
  appropriate extensions based on content type, with security validation.
7
+
8
+ Enhanced with Managed Singleton Factory Pattern support for consistent
9
+ instance management across MCP tools.
7
10
  """
8
11
 
9
12
  import json
10
13
  import os
11
14
  from pathlib import Path
12
- from typing import Any
15
+ from typing import Any, Optional
13
16
 
14
17
  from ...utils import setup_logger
15
18
 
@@ -21,9 +24,12 @@ class FileOutputManager:
21
24
  """
22
25
  Manages file output for analysis results with automatic extension detection
23
26
  and security validation.
27
+
28
+ Enhanced with factory method support for consistent instance management
29
+ across MCP tools while maintaining full backward compatibility.
24
30
  """
25
31
 
26
- def __init__(self, project_root: str | None = None):
32
+ def __init__(self, project_root: Optional[str] = None):
27
33
  """
28
34
  Initialize the file output manager.
29
35
 
@@ -33,6 +39,50 @@ class FileOutputManager:
33
39
  self.project_root = project_root
34
40
  self._output_path = None
35
41
  self._initialize_output_path()
42
+
43
+ @classmethod
44
+ def get_managed_instance(cls, project_root: Optional[str] = None) -> 'FileOutputManager':
45
+ """
46
+ Get a managed FileOutputManager instance using the factory pattern.
47
+
48
+ This method provides access to the Managed Singleton Factory Pattern,
49
+ ensuring one instance per project root for optimal resource usage
50
+ and consistency across MCP tools.
51
+
52
+ Args:
53
+ project_root: Project root directory. If None, uses current working directory.
54
+
55
+ Returns:
56
+ FileOutputManager instance managed by the factory
57
+
58
+ Note:
59
+ This method requires the factory module to be available. If the factory
60
+ is not available, it falls back to creating a new instance directly.
61
+ """
62
+ try:
63
+ # Import here to avoid circular imports
64
+ from .file_output_factory import FileOutputManagerFactory
65
+ return FileOutputManagerFactory.get_instance(project_root)
66
+ except ImportError as e:
67
+ logger.warning(f"Factory not available, creating new instance directly: {e}")
68
+ return cls(project_root)
69
+
70
+ @classmethod
71
+ def create_instance(cls, project_root: Optional[str] = None) -> 'FileOutputManager':
72
+ """
73
+ Create a new FileOutputManager instance directly (bypass factory).
74
+
75
+ This method creates a new instance without using the factory pattern.
76
+ Use this when you specifically need a separate instance that won't
77
+ be managed by the factory.
78
+
79
+ Args:
80
+ project_root: Project root directory. If None, uses current working directory.
81
+
82
+ Returns:
83
+ New FileOutputManager instance
84
+ """
85
+ return cls(project_root)
36
86
 
37
87
  def _initialize_output_path(self) -> None:
38
88
  """Initialize the output path from environment variables or project root."""
@@ -9,7 +9,9 @@ import atexit
9
9
  import logging
10
10
  import os
11
11
  import sys
12
+ import tempfile
12
13
  from functools import wraps
14
+ from pathlib import Path
13
15
  from typing import Any
14
16
 
15
17
 
@@ -51,6 +53,10 @@ def setup_logger(
51
53
  if name.startswith("test_"):
52
54
  logger.handlers.clear()
53
55
 
56
+ # Initialize file logging variables at function scope
57
+ enable_file_log = os.environ.get("TREE_SITTER_ANALYZER_ENABLE_FILE_LOG", "").lower() == "true"
58
+ file_log_level = level # Default to main logger level
59
+
54
60
  if not logger.handlers: # Avoid duplicate handlers
55
61
  # Create a safe handler that writes to stderr to avoid breaking MCP stdio
56
62
  handler = SafeStreamHandler()
@@ -60,27 +66,68 @@ def setup_logger(
60
66
  handler.setFormatter(formatter)
61
67
  logger.addHandler(handler)
62
68
 
63
- # Also log to a local file for debugging when launched by clients (e.g., Cursor)
69
+ # Optional file logging for debugging when launched by clients (e.g., Cursor)
64
70
  # This helps diagnose cases where stdio is captured by the client and logs are hidden.
65
- try:
66
- file_handler = logging.FileHandler(
67
- "cursor_mcp_server.log", encoding="utf-8"
68
- )
69
- file_handler.setFormatter(formatter)
70
- logger.addHandler(file_handler)
71
- except Exception as e:
72
- # Never let logging configuration break runtime behavior; log to stderr if possible
73
- if hasattr(sys, "stderr") and hasattr(sys.stderr, "write"):
74
- try:
75
- sys.stderr.write(
76
- f"[logging_setup] file handler init skipped: {e}\n"
77
- )
78
- except Exception:
79
- ...
71
+ # Only enabled when TREE_SITTER_ANALYZER_ENABLE_FILE_LOG is set to 'true'
72
+ if enable_file_log:
73
+ try:
74
+ # Determine log directory
75
+ log_dir = os.environ.get("TREE_SITTER_ANALYZER_LOG_DIR")
76
+ if log_dir:
77
+ # Use specified directory
78
+ log_path = Path(log_dir) / "tree_sitter_analyzer.log"
79
+ # Ensure directory exists
80
+ Path(log_dir).mkdir(parents=True, exist_ok=True)
81
+ else:
82
+ # Use system temporary directory
83
+ temp_dir = tempfile.gettempdir()
84
+ log_path = Path(temp_dir) / "tree_sitter_analyzer.log"
85
+
86
+ # Determine file log level
87
+ file_log_level_str = os.environ.get("TREE_SITTER_ANALYZER_FILE_LOG_LEVEL", "").upper()
88
+ if file_log_level_str and file_log_level_str in ["DEBUG", "INFO", "WARNING", "ERROR"]:
89
+ if file_log_level_str == "DEBUG":
90
+ file_log_level = logging.DEBUG
91
+ elif file_log_level_str == "INFO":
92
+ file_log_level = logging.INFO
93
+ elif file_log_level_str == "WARNING":
94
+ file_log_level = logging.WARNING
95
+ elif file_log_level_str == "ERROR":
96
+ file_log_level = logging.ERROR
97
+ else:
98
+ # Use same level as main logger
99
+ file_log_level = level
100
+
101
+ file_handler = logging.FileHandler(str(log_path), encoding="utf-8")
102
+ file_handler.setFormatter(formatter)
103
+ file_handler.setLevel(file_log_level)
104
+ logger.addHandler(file_handler)
105
+
106
+ # Log the file location for debugging purposes
107
+ if hasattr(sys, "stderr") and hasattr(sys.stderr, "write"):
108
+ try:
109
+ sys.stderr.write(f"[logging_setup] File logging enabled: {log_path}\n")
110
+ except Exception:
111
+ ...
112
+
113
+ except Exception as e:
114
+ # Never let logging configuration break runtime behavior; log to stderr if possible
115
+ if hasattr(sys, "stderr") and hasattr(sys.stderr, "write"):
116
+ try:
117
+ sys.stderr.write(
118
+ f"[logging_setup] file handler init skipped: {e}\n"
119
+ )
120
+ except Exception:
121
+ ...
80
122
 
81
- # Always set the level, even if handlers already exist
82
- # Ensure the level is properly set, not inherited
83
- logger.setLevel(level)
123
+ # Set the logger level to the minimum of main level and file log level
124
+ # This ensures that all messages that should go to any handler are processed
125
+ final_level = level
126
+ if enable_file_log:
127
+ # Use the minimum level to ensure all messages reach their intended handlers
128
+ final_level = min(level, file_log_level)
129
+
130
+ logger.setLevel(final_level)
84
131
 
85
132
  # For test loggers, ensure they don't inherit from parent and force level
86
133
  if logger.name.startswith("test_"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tree-sitter-analyzer
3
- Version: 1.8.2
3
+ Version: 1.8.4
4
4
  Summary: AI-era enterprise-grade code analysis tool with comprehensive HTML/CSS support, dynamic plugin architecture, and MCP integration
5
5
  Project-URL: Homepage, https://github.com/aimasteracc/tree-sitter-analyzer
6
6
  Project-URL: Documentation, https://github.com/aimasteracc/tree-sitter-analyzer#readme
@@ -198,11 +198,11 @@ Description-Content-Type: text/markdown
198
198
 
199
199
  [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)
200
200
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
201
- [![Tests](https://img.shields.io/badge/tests-3342%20passed-brightgreen.svg)](#quality-assurance)
201
+ [![Tests](https://img.shields.io/badge/tests-3380%20passed-brightgreen.svg)](#quality-assurance)
202
202
  [![Coverage](https://codecov.io/gh/aimasteracc/tree-sitter-analyzer/branch/main/graph/badge.svg)](https://codecov.io/gh/aimasteracc/tree-sitter-analyzer)
203
203
  [![Quality](https://img.shields.io/badge/quality-enterprise%20grade-blue.svg)](#quality-assurance)
204
204
  [![PyPI](https://img.shields.io/pypi/v/tree-sitter-analyzer.svg)](https://pypi.org/project/tree-sitter-analyzer/)
205
- [![Version](https://img.shields.io/badge/version-1.8.2-blue.svg)](https://github.com/aimasteracc/tree-sitter-analyzer/releases)
205
+ [![Version](https://img.shields.io/badge/version-1.8.4-blue.svg)](https://github.com/aimasteracc/tree-sitter-analyzer/releases)
206
206
  [![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/aimasteracc/tree-sitter-analyzer)
207
207
  [![GitHub Stars](https://img.shields.io/github/stars/aimasteracc/tree-sitter-analyzer.svg?style=social)](https://github.com/aimasteracc/tree-sitter-analyzer)
208
208
 
@@ -255,7 +255,7 @@ Tree-sitter Analyzer is an enterprise-grade code analysis tool designed for the
255
255
  | **Go** | Basic Support | Basic syntax parsing |
256
256
 
257
257
  ### 🏆 Production Ready
258
- - **3,342 Tests** - 100% pass rate, enterprise-grade quality assurance
258
+ - **3,380 Tests** - 100% pass rate, enterprise-grade quality assurance
259
259
  - **High Coverage** - Comprehensive test coverage
260
260
  - **Cross-platform Support** - Compatible with Windows, macOS, Linux
261
261
  - **Continuous Maintenance** - Active development and community support
@@ -373,6 +373,7 @@ rg --version
373
373
  - **Roo Code**: Supports MCP protocol, use the same configuration format
374
374
  - **Other MCP-compatible clients**: Use the same server configuration
375
375
 
376
+
376
377
  ---
377
378
 
378
379
  ### 3.2 💻 CLI Users (Command Line Tools)
@@ -633,13 +634,37 @@ Tree-sitter Analyzer provides a rich set of MCP tools designed for AI assistants
633
634
  | | `analyze_code_structure` | Code structure analysis and table generation | 🆕 suppress_output parameter, multiple formats (full/compact/csv/json/html), automatic language detection |
634
635
  | | `extract_code_section` | Precise code section extraction | Specified line range extraction, large file efficient processing, original format preservation |
635
636
  | **🔍 Intelligent Search** | `list_files` | High-performance file discovery | fd-based, glob patterns, file type filters, time range control |
636
- | | `search_content` | Regex content search | ripgrep-based, multiple output formats, context control, encoding handling |
637
- | | `find_and_grep` | Two-stage search | File discovery → content search, fd+ripgrep combination, intelligent cache optimization |
637
+ | | `search_content` | Regex content search | ripgrep-based, multiple output formats, context control, encoding handling, 🆕 unified `set_project_path` support |
638
+ | | `find_and_grep` | Two-stage search | File discovery → content search, fd+ripgrep combination, intelligent cache optimization, 🆕 unified `set_project_path` support |
638
639
  | **🔧 Advanced Queries** | `query_code` | tree-sitter queries | Predefined query keys, custom query strings, filter expression support |
639
- | **⚙️ System Management** | `set_project_path` | Project root path setting | Security boundary control, automatic path validation |
640
+ | **⚙️ System Management** | `set_project_path` | Project root path setting | Security boundary control, automatic path validation, 🆕 unified across all MCP tools |
640
641
  | **📁 Resource Access** | Code file resources | URI code file access | File content access via URI identification |
641
642
  | | Project statistics resources | Project statistics data access | Project analysis data and statistical information |
642
643
 
644
+ ### 🆕 v1.8.4 New Feature: Configurable File Logging
645
+
646
+ Revolutionary environment variable-controlled file logging system:
647
+
648
+ - **🔧 Environment Variable Control**: Flexible file logging behavior control through environment variables
649
+ - `TREE_SITTER_ANALYZER_ENABLE_FILE_LOG`: Enable/disable file logging
650
+ - `TREE_SITTER_ANALYZER_LOG_DIR`: Custom log directory path
651
+ - `TREE_SITTER_ANALYZER_FILE_LOG_LEVEL`: Control file log level
652
+ - **🛡️ Improved Default Behavior**: File logging disabled by default to prevent user project pollution
653
+ - **📁 Smart Directory Selection**: Uses system temp directory when enabled, keeping projects clean
654
+ - **🔄 Backward Compatibility**: Maintains all existing functionality unchanged
655
+ - **📚 Complete Documentation Support**: Includes debugging guides and troubleshooting documentation
656
+
657
+ ### 🆕 v1.8.3 New Feature: MCP Tools Design Consistency Enhancement
658
+
659
+ Comprehensive MCP tools unification and design consistency improvements:
660
+
661
+ - **🔧 Unified `set_project_path` Implementation**: SearchContentTool and FindAndGrepTool now have consistent `set_project_path` method implementation
662
+ - **🏗️ Design Consistency Across All MCP Tools**: All 4 MCP tools (QueryTool, TableFormatTool, SearchContentTool, FindAndGrepTool) now have unified interface design
663
+ - **📁 FileOutputManager Integration**: Unified FileOutputManager factory pattern for consistent file output management
664
+ - **🔄 Dynamic Project Path Changes**: All MCP tools now support dynamic project path changes through unified interface
665
+ - **🛡️ Enhanced Security Boundaries**: Consistent security boundary protection across all MCP tools
666
+ - **📋 Improved Developer Experience**: Unified interface makes MCP tool development and usage more consistent
667
+
643
668
  ### 🆕 v1.8.2 New Feature: CLI Security and Argument Validation Enhancement
644
669
 
645
670
  Comprehensive CLI security improvements and argument validation optimization:
@@ -848,12 +873,12 @@ uv run python -m tree_sitter_analyzer --show-query-languages
848
873
  ## 8. 🏆 Quality Assurance
849
874
 
850
875
  ### 📊 Quality Metrics
851
- - **3,342 tests** - 100% pass rate ✅
876
+ - **3,380 tests** - 100% pass rate ✅
852
877
  - **High code coverage** - Comprehensive test suite
853
878
  - **Zero test failures** - Production ready
854
879
  - **Cross-platform support** - Windows, macOS, Linux
855
880
 
856
- ### ⚡ Latest Quality Achievements (v1.8.2)
881
+ ### ⚡ Latest Quality Achievements (v1.8.3)
857
882
  - ✅ **🔒 CLI Security Enhancement** - Fixed CLI mode security boundary errors, ensuring file access security
858
883
  - ✅ **✅ Argument Validation Improvement** - Implemented complete CLI argument validation system, preventing invalid parameter combinations
859
884
  - ✅ **🚫 Exclusive Parameter Control** - `--table` and `--query-key` parameters properly implement exclusive control
@@ -863,22 +888,6 @@ uv run python -m tree_sitter_analyzer --show-query-languages
863
888
  - ✅ **🧪 Test Environment Support** - Temporary directory access permission in test environments
864
889
  - ✅ **📋 User Experience Improvement** - More intuitive command-line interface and error handling mechanisms
865
890
 
866
- ### ⚡ v1.7.5 Quality Achievements
867
- - ✅ **📊 Enhanced Quality Metrics** - Test count increased to 3,342 coverage maintained at high levels
868
- - ✅ **🔧 System Stability** - All tests passing with enhanced system stability and reliability
869
- - ✅ **🆕 Complete Markdown Support** - Added new complete Markdown language plugin supporting all major Markdown elements
870
- - ✅ **📝 Enhanced Document Analysis** - Support for intelligent extraction of headers, code blocks, links, images, tables, task lists
871
- - ✅ **🔍 Markdown Query System** - 17 predefined query types with alias and custom query support
872
- - ✅ **🧪 Comprehensive Test Validation** - Added extensive Markdown test cases ensuring feature stability
873
- - ✅ **📊 Structured Output** - Convert Markdown documents to structured data for easy AI processing
874
- - ✅ **File output optimization** - MCP search tools now include `suppress_output` and `output_file` parameters for massive token savings
875
- - ✅ **Intelligent format detection** - Automatic selection of optimal file formats (JSON/Markdown) for storage and reading optimization
876
- - ✅ **ROO rules documentation** - Added comprehensive tree-sitter-analyzer MCP optimization usage guide
877
- - ✅ **Enhanced token management** - Response size reduced by up to 99% when outputting search results to files
878
- - ✅ **Enterprise-grade test coverage** - Comprehensive test suite including complete validation of file output optimization features
879
- - ✅ **Complete MCP tools** - Complete MCP server tool set supporting advanced file search and content analysis
880
- - ✅ **Cross-platform path compatibility** - Fixed differences between Windows short path names and macOS symbolic links
881
- - ✅ **GitFlow implementation** - Professional development/release branch strategy
882
891
 
883
892
  ### ⚙️ Running Tests
884
893
  ```bash
@@ -930,6 +939,9 @@ This project provides complete documentation support, including:
930
939
  - **MCP Configuration Guide** - See the [AI Users Configuration](#31--ai-users-claude-desktop-cursor-etc) section
931
940
  - **CLI Usage Guide** - See the [Complete CLI Commands](#6--complete-cli-commands) section
932
941
  - **Core Features Documentation** - See the [Core Features](#7-️-core-features) section
942
+ - **Contributing Guide** - See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) for development guidelines and document management
943
+ - **Analysis Results** - See [docs/analysis/](docs/analysis/) for project analysis reports and metrics
944
+ - **Feature Specifications** - See [specs/](specs/) for detailed feature specifications and implementation plans
933
945
 
934
946
  ### 🤖 AI Collaboration Support
935
947
  This project supports AI-assisted development with professional quality control:
@@ -1,4 +1,4 @@
1
- tree_sitter_analyzer/__init__.py,sha256=h6zUP8Chm-_bNNKaCIY25G3h_JKBLIed582ErUTq0Zc,3067
1
+ tree_sitter_analyzer/__init__.py,sha256=Bg7okJtLa1BS4OaksNMVLvvdDXWbdWF0AKsoRp5aTig,3067
2
2
  tree_sitter_analyzer/__main__.py,sha256=Zl79tpe4UaMu-7yeztc06tgP0CVMRnvGgas4ZQP5SCs,228
3
3
  tree_sitter_analyzer/api.py,sha256=gqHatRpVm8k0jEfFm45iokHRPYJjEcud6MtrCSg1V0A,22169
4
4
  tree_sitter_analyzer/cli_main.py,sha256=RAPn4VGHVOfC2vrU1Sef7PEPcypMwuI5GgWiwoYL1PE,11100
@@ -13,7 +13,7 @@ tree_sitter_analyzer/output_manager.py,sha256=hRAp6Aa9k05UVvZkOyRCEz2Lf7blx05fWn
13
13
  tree_sitter_analyzer/project_detector.py,sha256=-zmtm12EvVD_6TDxS_6KpzuswP2Bpppnxq50kAEDyMA,9430
14
14
  tree_sitter_analyzer/query_loader.py,sha256=rtUZ_ZBhacb2uvM8aPrf0XiigUDtxflfjbenfKcatEI,10407
15
15
  tree_sitter_analyzer/table_formatter.py,sha256=tPKw77LLlQ7k5MMs9_Ez7qsSroNaSzZPoplyPtKHLhA,28577
16
- tree_sitter_analyzer/utils.py,sha256=hezEhJ4TGAFTRa-Ii_i42jPLkspAme-GRsZR5e38OBQ,13650
16
+ tree_sitter_analyzer/utils.py,sha256=YN4n_XDJQAvcP2eKqYV7AzsZW1UMtks9O4BLR2youjs,16110
17
17
  tree_sitter_analyzer/cli/__init__.py,sha256=O_3URpbdu5Ilb2-r48LjbZuWtOWQu_BhL3pa6C0G3Bk,871
18
18
  tree_sitter_analyzer/cli/__main__.py,sha256=Xq8o8-0dPnMDU9WZqmqhzr98rx8rvoffTUHAkAwl-L8,218
19
19
  tree_sitter_analyzer/cli/argument_validator.py,sha256=n336uNVWE9FFWc5s1ADKNQq53_BSnqdTtqEFk90UDBI,2574
@@ -72,16 +72,17 @@ tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py,sha256=Yb9lpUPGuvRbawmE15ic
72
72
  tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py,sha256=mssed7bEfGeGxW4mOf7dg8BDS1oqHLolIBNX9DaZ3DM,8997
73
73
  tree_sitter_analyzer/mcp/tools/base_tool.py,sha256=qf2My325azlnKOugNVMN_R1jtZcjXVy354sGVKzvZls,3546
74
74
  tree_sitter_analyzer/mcp/tools/fd_rg_utils.py,sha256=9jQ4D5yREs7Nt8L0s-NdVtmaKXJAAOKqAAI8mkW3T2o,18664
75
- tree_sitter_analyzer/mcp/tools/find_and_grep_tool.py,sha256=9p_Olh6wjuUAVqHfXnsUj3crZtUV4_R6zAfKRqe8jTY,31623
75
+ tree_sitter_analyzer/mcp/tools/find_and_grep_tool.py,sha256=OLJToDgLj74irikqC5kJQ_k5isAw9YzkVVOrQIRrQnc,32063
76
76
  tree_sitter_analyzer/mcp/tools/list_files_tool.py,sha256=nd6uiOqbsr8NUqNL46d8QnOM-XpMTDOFiaccjBaGLl8,18268
77
- tree_sitter_analyzer/mcp/tools/query_tool.py,sha256=BgkfLYGcRpRk7cNbhD1rOSnSvoZv2H9nPqnwX3DpXQs,17011
77
+ tree_sitter_analyzer/mcp/tools/query_tool.py,sha256=3_TVIfkkZSJo0WNBsiTnctYlq59OVgZYI4IMX2-zsuA,17056
78
78
  tree_sitter_analyzer/mcp/tools/read_partial_tool.py,sha256=lC3Zigp3_v8RU_fi5Fz0O_idjP6z_AmgoqVQOethL3I,18493
79
- tree_sitter_analyzer/mcp/tools/search_content_tool.py,sha256=wGYjP5OZqqcKnLwF5sdpH3xMuUaxJmwYWU6Rg3R7CAw,32463
80
- tree_sitter_analyzer/mcp/tools/table_format_tool.py,sha256=pL0QAr1aINaTYqGKcutuENEwfvy60Cfcl9AVk5sG2VU,22559
79
+ tree_sitter_analyzer/mcp/tools/search_content_tool.py,sha256=t-ui0KA78vKqIA5VCD_ep2dl0wexkRgqx9dvYvedies,32905
80
+ tree_sitter_analyzer/mcp/tools/table_format_tool.py,sha256=lbE2GQKllsV0vGyhmX5wMPhGn9BT0FoRMV17FcE0FWo,22604
81
81
  tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py,sha256=-zZnqN9WcoyRTKM_16ADH859LSebzi34BGYwQL2zCOs,25084
82
82
  tree_sitter_analyzer/mcp/utils/__init__.py,sha256=TgTTKsRJAqF95g1fAp5SR_zQVDkImpc_5R0Dw529UUw,3126
83
83
  tree_sitter_analyzer/mcp/utils/error_handler.py,sha256=msrQHX67K3vhJsEc3OPRz5mmWU_yoHz55Lnxy0IZuy4,18404
84
- tree_sitter_analyzer/mcp/utils/file_output_manager.py,sha256=4R-evFZgb7KJpxQjgrz3WMPjL4zJhUH_9aaEbMQTCN4,8747
84
+ tree_sitter_analyzer/mcp/utils/file_output_factory.py,sha256=qhLP4p8wfqz0oM19iTlStxak8fu0Aq40OKdPmqkhPBg,7454
85
+ tree_sitter_analyzer/mcp/utils/file_output_manager.py,sha256=_MideWK9KexXHpbEtxXpHyGA2Rp4m3xKVCvtIx4-Y-Q,10829
85
86
  tree_sitter_analyzer/mcp/utils/gitignore_detector.py,sha256=_KKd2tIqudG95Pn53wScDr5wZWEijuUA6CFc04J7Ubo,11942
86
87
  tree_sitter_analyzer/mcp/utils/path_resolver.py,sha256=77BmbyEuJCuDPNH9POcTOS4tYBorPu-IXFGpBC1DxOk,15006
87
88
  tree_sitter_analyzer/mcp/utils/search_cache.py,sha256=ZNv84st6PeejDY1B50AKTbItpXs9HS6JrpR-Ozjyc1c,12991
@@ -102,7 +103,7 @@ tree_sitter_analyzer/security/regex_checker.py,sha256=jWK6H8PTPgzbwRPfK_RZ8bBTS6
102
103
  tree_sitter_analyzer/security/validator.py,sha256=PJ2CxYANMi7Ot4rPq2sUgfEF0f7EXoS_3mWqEG4Y-8w,21966
103
104
  tree_sitter_analyzer/utils/__init__.py,sha256=U2zLA7-80BE7NB9nV5coL2hdS-TPey22U4il9VkPfRA,3747
104
105
  tree_sitter_analyzer/utils/tree_sitter_compat.py,sha256=9hvig3RQp_9H-YN1AWjW1Dl8fugYOPF-M8TRb41LMZU,10861
105
- tree_sitter_analyzer-1.8.2.dist-info/METADATA,sha256=ty5HIz_tOpOkNlGLuVpUyk6aSD6x9mKtvI4k7pu2MiI,48668
106
- tree_sitter_analyzer-1.8.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
107
- tree_sitter_analyzer-1.8.2.dist-info/entry_points.txt,sha256=TJmEXxAMz3og3VPphTHsuE8tNJxf7GuAPjNHwVhXRnc,972
108
- tree_sitter_analyzer-1.8.2.dist-info/RECORD,,
106
+ tree_sitter_analyzer-1.8.4.dist-info/METADATA,sha256=WWE_1AkppJ-PZ6PsD5aAa1jDwl7_vyPARYHEWSpduFA,49119
107
+ tree_sitter_analyzer-1.8.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
108
+ tree_sitter_analyzer-1.8.4.dist-info/entry_points.txt,sha256=TJmEXxAMz3og3VPphTHsuE8tNJxf7GuAPjNHwVhXRnc,972
109
+ tree_sitter_analyzer-1.8.4.dist-info/RECORD,,