tree-sitter-analyzer 1.7.2__py3-none-any.whl → 1.7.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.

Potentially problematic release.


This version of tree-sitter-analyzer might be problematic. Click here for more details.

@@ -126,7 +126,8 @@ class PythonElementExtractor(ElementExtractor):
126
126
 
127
127
  language = tree.language if hasattr(tree, "language") else None
128
128
  if language:
129
- query = language.query(class_query)
129
+ import tree_sitter
130
+ query = tree_sitter.Query(language, class_query)
130
131
  captures = query.captures(tree.root_node)
131
132
 
132
133
  if isinstance(captures, dict):
@@ -729,26 +730,83 @@ class PythonElementExtractor(ElementExtractor):
729
730
  language = tree.language if hasattr(tree, "language") else None
730
731
  if language:
731
732
  for query_string in import_queries:
732
- query = language.query(query_string)
733
- captures = query.captures(tree.root_node)
734
-
735
- if isinstance(captures, dict):
736
- # Process different types of imports
737
- for key, nodes in captures.items():
738
- if key.endswith("statement"):
739
- import_type = key.split(".")[0]
740
- for node in nodes:
741
- imp = self._extract_import_info(
742
- node, source_code, import_type
743
- )
744
- if imp:
745
- imports.append(imp)
733
+ try:
734
+ import tree_sitter
735
+ query = tree_sitter.Query(language, query_string)
736
+ captures = query.captures(tree.root_node)
737
+
738
+ if isinstance(captures, dict):
739
+ # Process different types of imports
740
+ for key, nodes in captures.items():
741
+ if key.endswith("statement"):
742
+ import_type = key.split(".")[0]
743
+ for node in nodes:
744
+ imp = self._extract_import_info(
745
+ node, source_code, import_type
746
+ )
747
+ if imp:
748
+ imports.append(imp)
749
+ except Exception as query_error:
750
+ # Fallback to manual extraction for tree-sitter 0.25.x compatibility
751
+ log_warning(f"Query execution failed, using manual extraction: {query_error}")
752
+ imports.extend(self._extract_imports_manual(tree.root_node, source_code))
753
+ break
746
754
 
747
755
  except Exception as e:
748
756
  log_warning(f"Could not extract Python imports: {e}")
757
+ # Final fallback
758
+ imports.extend(self._extract_imports_manual(tree.root_node, source_code))
749
759
 
750
760
  return imports
751
761
 
762
+ def _extract_imports_manual(self, root_node: "tree_sitter.Node", source_code: str) -> list[Import]:
763
+ """Manual import extraction for tree-sitter 0.25.x compatibility"""
764
+ imports = []
765
+
766
+ def walk_tree(node):
767
+ if node.type in ["import_statement", "import_from_statement"]:
768
+ try:
769
+ start_line = node.start_point[0] + 1
770
+ end_line = node.end_point[0] + 1
771
+ raw_text = source_code[node.start_byte:node.end_byte] if hasattr(node, 'start_byte') else ""
772
+
773
+ # Extract module name from the import statement
774
+ module_name = ""
775
+ imported_names = []
776
+
777
+ if node.type == "import_statement":
778
+ # Simple import: import os, sys
779
+ for child in node.children:
780
+ if child.type == "dotted_name":
781
+ module_name = source_code[child.start_byte:child.end_byte] if hasattr(child, 'start_byte') else ""
782
+ imported_names.append(module_name)
783
+ elif node.type == "import_from_statement":
784
+ # From import: from os import path
785
+ for child in node.children:
786
+ if child.type == "dotted_name" and not module_name:
787
+ module_name = source_code[child.start_byte:child.end_byte] if hasattr(child, 'start_byte') else ""
788
+
789
+ if module_name or imported_names:
790
+ import_obj = Import(
791
+ name=module_name or imported_names[0] if imported_names else "unknown",
792
+ start_line=start_line,
793
+ end_line=end_line,
794
+ raw_text=raw_text,
795
+ module_name=module_name,
796
+ imported_names=imported_names,
797
+ element_type="import"
798
+ )
799
+ imports.append(import_obj)
800
+ except Exception as e:
801
+ log_warning(f"Failed to extract import manually: {e}")
802
+
803
+ # Recursively process children
804
+ for child in node.children:
805
+ walk_tree(child)
806
+
807
+ walk_tree(root_node)
808
+ return imports
809
+
752
810
  def _extract_detailed_function_info(
753
811
  self, node: "tree_sitter.Node", source_code: str, is_async: bool = False
754
812
  ) -> Function | None:
@@ -1272,7 +1330,8 @@ class PythonPlugin(LanguagePlugin):
1272
1330
  else:
1273
1331
  return {"error": f"Unknown query: {query_name}"}
1274
1332
 
1275
- query = language.query(query_string)
1333
+ import tree_sitter
1334
+ query = tree_sitter.Query(language, query_string)
1276
1335
  captures = query.captures(tree.root_node)
1277
1336
  return {"captures": captures, "query": query_string}
1278
1337
 
@@ -0,0 +1,379 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Markdown Query Definitions
4
+
5
+ Tree-sitter queries for extracting Markdown elements including headers,
6
+ links, code blocks, lists, and other structural elements.
7
+ """
8
+
9
+ from typing import Dict, List
10
+
11
+ # Markdown element extraction queries
12
+ MARKDOWN_QUERIES: Dict[str, str] = {
13
+ # Headers (H1-H6)
14
+ "headers": """
15
+ (atx_heading
16
+ (atx_h1_marker) @h1.marker
17
+ heading_content: (inline) @h1.content) @h1.heading
18
+
19
+ (atx_heading
20
+ (atx_h2_marker) @h2.marker
21
+ heading_content: (inline) @h2.content) @h2.heading
22
+
23
+ (atx_heading
24
+ (atx_h3_marker) @h3.marker
25
+ heading_content: (inline) @h3.content) @h3.heading
26
+
27
+ (atx_heading
28
+ (atx_h4_marker) @h4.marker
29
+ heading_content: (inline) @h4.content) @h4.heading
30
+
31
+ (atx_heading
32
+ (atx_h5_marker) @h5.marker
33
+ heading_content: (inline) @h5.content) @h5.heading
34
+
35
+ (atx_heading
36
+ (atx_h6_marker) @h6.marker
37
+ heading_content: (inline) @h6.content) @h6.heading
38
+
39
+ (setext_heading
40
+ heading_content: (paragraph) @setext.content
41
+ (setext_h1_underline) @setext.h1) @setext.h1.heading
42
+
43
+ (setext_heading
44
+ heading_content: (paragraph) @setext.content
45
+ (setext_h2_underline) @setext.h2) @setext.h2.heading
46
+ """,
47
+
48
+ # Code blocks
49
+ "code_blocks": """
50
+ (fenced_code_block
51
+ (fenced_code_block_delimiter) @code.start
52
+ (info_string)? @code.language
53
+ (code_fence_content) @code.content
54
+ (fenced_code_block_delimiter) @code.end) @code.block
55
+
56
+ (indented_code_block
57
+ (code_fence_content) @indented_code.content) @indented_code.block
58
+ """,
59
+
60
+ # Inline code
61
+ "inline_code": """
62
+ (code_span
63
+ (code_span_delimiter) @inline_code.start
64
+ (code_span_content) @inline_code.content
65
+ (code_span_delimiter) @inline_code.end) @inline_code.span
66
+ """,
67
+
68
+ # Links
69
+ "links": """
70
+ (link
71
+ (link_text) @link.text
72
+ (link_destination) @link.url
73
+ (link_title)? @link.title) @link.element
74
+
75
+ (autolink
76
+ (uri_autolink) @autolink.uri) @autolink.element
77
+
78
+ (autolink
79
+ (email_autolink) @autolink.email) @autolink.element
80
+
81
+ (reference_link
82
+ (link_text) @ref_link.text
83
+ (link_label) @ref_link.label) @ref_link.element
84
+
85
+ (link_reference_definition
86
+ (link_label) @link_def.label
87
+ (link_destination) @link_def.url
88
+ (link_title)? @link_def.title) @link_def.element
89
+ """,
90
+
91
+ # Images
92
+ "images": """
93
+ (image
94
+ (image_description) @image.alt
95
+ (link_destination) @image.url
96
+ (link_title)? @image.title) @image.element
97
+
98
+ (reference_image
99
+ (image_description) @ref_image.alt
100
+ (link_label) @ref_image.label) @ref_image.element
101
+ """,
102
+
103
+ # Lists
104
+ "lists": """
105
+ (list
106
+ (list_item
107
+ (list_marker) @list_item.marker
108
+ (paragraph)? @list_item.content) @list_item.element) @list.element
109
+
110
+ (tight_list
111
+ (list_item
112
+ (list_marker) @tight_list_item.marker
113
+ (paragraph)? @tight_list_item.content) @tight_list_item.element) @tight_list.element
114
+ """,
115
+
116
+ # Emphasis and strong
117
+ "emphasis": """
118
+ (emphasis
119
+ (emphasis_delimiter) @emphasis.start
120
+ (inline) @emphasis.content
121
+ (emphasis_delimiter) @emphasis.end) @emphasis.element
122
+
123
+ (strong_emphasis
124
+ (strong_emphasis_delimiter) @strong.start
125
+ (inline) @strong.content
126
+ (strong_emphasis_delimiter) @strong.end) @strong.element
127
+ """,
128
+
129
+ # Blockquotes
130
+ "blockquotes": """
131
+ (block_quote
132
+ (block_quote_marker) @blockquote.marker
133
+ (paragraph) @blockquote.content) @blockquote.element
134
+ """,
135
+
136
+ # Tables
137
+ "tables": """
138
+ (pipe_table
139
+ (pipe_table_header
140
+ (pipe_table_cell) @table_header.cell) @table.header
141
+ (pipe_table_delimiter_row) @table.delimiter
142
+ (pipe_table_row
143
+ (pipe_table_cell) @table_row.cell) @table.row) @table.element
144
+ """,
145
+
146
+ # Horizontal rules
147
+ "horizontal_rules": """
148
+ (thematic_break) @hr.element
149
+ """,
150
+
151
+ # HTML blocks
152
+ "html_blocks": """
153
+ (html_block) @html.block
154
+ """,
155
+
156
+ # Inline HTML
157
+ "inline_html": """
158
+ (html_tag) @html.inline
159
+ """,
160
+
161
+ # Strikethrough (if supported)
162
+ "strikethrough": """
163
+ (strikethrough
164
+ (strikethrough_delimiter) @strike.start
165
+ (inline) @strike.content
166
+ (strikethrough_delimiter) @strike.end) @strike.element
167
+ """,
168
+
169
+ # Task lists (if supported)
170
+ "task_lists": """
171
+ (list_item
172
+ (list_marker) @task.marker
173
+ (task_list_marker_checked) @task.checked) @task.checked_item
174
+
175
+ (list_item
176
+ (list_marker) @task.marker
177
+ (task_list_marker_unchecked) @task.unchecked) @task.unchecked_item
178
+ """,
179
+
180
+ # Footnotes
181
+ "footnotes": """
182
+ (footnote_reference
183
+ (footnote_label) @footnote.ref_label) @footnote.reference
184
+
185
+ (footnote_definition
186
+ (footnote_label) @footnote.def_label
187
+ (paragraph) @footnote.content) @footnote.definition
188
+ """,
189
+
190
+ # All text content
191
+ "text_content": """
192
+ (paragraph
193
+ (inline) @text.content) @text.paragraph
194
+
195
+ (inline) @text.inline
196
+ """,
197
+
198
+ # Document structure
199
+ "document": """
200
+ (document) @document.root
201
+ """,
202
+
203
+ # All elements (comprehensive)
204
+ "all_elements": """
205
+ (atx_heading) @element.heading
206
+ (setext_heading) @element.heading
207
+ (fenced_code_block) @element.code_block
208
+ (indented_code_block) @element.code_block
209
+ (code_span) @element.inline_code
210
+ (link) @element.link
211
+ (autolink) @element.autolink
212
+ (reference_link) @element.ref_link
213
+ (image) @element.image
214
+ (reference_image) @element.ref_image
215
+ (list) @element.list
216
+ (tight_list) @element.list
217
+ (emphasis) @element.emphasis
218
+ (strong_emphasis) @element.strong
219
+ (strikethrough) @element.strikethrough
220
+ (block_quote) @element.blockquote
221
+ (pipe_table) @element.table
222
+ (thematic_break) @element.hr
223
+ (html_block) @element.html_block
224
+ (html_tag) @element.html_inline
225
+ (footnote_reference) @element.footnote_ref
226
+ (footnote_definition) @element.footnote_def
227
+ (paragraph) @element.paragraph
228
+ """,
229
+ }
230
+
231
+ # Query aliases for convenience
232
+ QUERY_ALIASES: Dict[str, str] = {
233
+ "heading": "headers",
234
+ "h1": "headers",
235
+ "h2": "headers",
236
+ "h3": "headers",
237
+ "h4": "headers",
238
+ "h5": "headers",
239
+ "h6": "headers",
240
+ "code": "code_blocks",
241
+ "fenced_code": "code_blocks",
242
+ "code_span": "inline_code",
243
+ "link": "links",
244
+ "url": "links",
245
+ "image": "images",
246
+ "img": "images",
247
+ "list": "lists",
248
+ "ul": "lists",
249
+ "ol": "lists",
250
+ "em": "emphasis",
251
+ "strong": "emphasis",
252
+ "bold": "emphasis",
253
+ "italic": "emphasis",
254
+ "quote": "blockquotes",
255
+ "blockquote": "blockquotes",
256
+ "table": "tables",
257
+ "hr": "horizontal_rules",
258
+ "html": "html_blocks",
259
+ "strike": "strikethrough",
260
+ "task": "task_lists",
261
+ "todo": "task_lists",
262
+ "footnote": "footnotes",
263
+ "note": "footnotes",
264
+ "text": "text_content",
265
+ "paragraph": "text_content",
266
+ "all": "all_elements",
267
+ "everything": "all_elements",
268
+ }
269
+
270
+ def get_query(query_name: str) -> str:
271
+ """
272
+ Get a query by name, supporting aliases
273
+
274
+ Args:
275
+ query_name: Name of the query or alias
276
+
277
+ Returns:
278
+ Query string
279
+
280
+ Raises:
281
+ KeyError: If query name is not found
282
+ """
283
+ # Check direct queries first
284
+ if query_name in MARKDOWN_QUERIES:
285
+ return MARKDOWN_QUERIES[query_name]
286
+
287
+ # Check aliases
288
+ if query_name in QUERY_ALIASES:
289
+ actual_query = QUERY_ALIASES[query_name]
290
+ return MARKDOWN_QUERIES[actual_query]
291
+
292
+ raise KeyError(f"Unknown query: {query_name}")
293
+
294
+ def get_available_queries() -> List[str]:
295
+ """
296
+ Get list of all available query names including aliases
297
+
298
+ Returns:
299
+ List of query names
300
+ """
301
+ queries = list(MARKDOWN_QUERIES.keys())
302
+ aliases = list(QUERY_ALIASES.keys())
303
+ return sorted(queries + aliases)
304
+
305
+ def get_query_info(query_name: str) -> Dict[str, str]:
306
+ """
307
+ Get information about a query
308
+
309
+ Args:
310
+ query_name: Name of the query
311
+
312
+ Returns:
313
+ Dictionary with query information
314
+ """
315
+ try:
316
+ query_string = get_query(query_name)
317
+ is_alias = query_name in QUERY_ALIASES
318
+ actual_name = QUERY_ALIASES.get(query_name, query_name) if is_alias else query_name
319
+
320
+ return {
321
+ "name": query_name,
322
+ "actual_name": actual_name,
323
+ "is_alias": is_alias,
324
+ "query": query_string,
325
+ "description": _get_query_description(actual_name)
326
+ }
327
+ except KeyError:
328
+ return {"error": f"Query '{query_name}' not found"}
329
+
330
+ def _get_query_description(query_name: str) -> str:
331
+ """Get description for a query"""
332
+ descriptions = {
333
+ "headers": "Extract all heading elements (H1-H6, both ATX and Setext styles)",
334
+ "code_blocks": "Extract fenced and indented code blocks",
335
+ "inline_code": "Extract inline code spans",
336
+ "links": "Extract all types of links (inline, reference, autolinks)",
337
+ "images": "Extract image elements (inline and reference)",
338
+ "lists": "Extract ordered and unordered lists",
339
+ "emphasis": "Extract emphasis and strong emphasis elements",
340
+ "blockquotes": "Extract blockquote elements",
341
+ "tables": "Extract pipe table elements",
342
+ "horizontal_rules": "Extract horizontal rule elements",
343
+ "html_blocks": "Extract HTML block elements",
344
+ "inline_html": "Extract inline HTML elements",
345
+ "strikethrough": "Extract strikethrough elements",
346
+ "task_lists": "Extract task list items (checkboxes)",
347
+ "footnotes": "Extract footnote references and definitions",
348
+ "text_content": "Extract all text content",
349
+ "document": "Extract document root",
350
+ "all_elements": "Extract all Markdown elements"
351
+ }
352
+ return descriptions.get(query_name, "No description available")
353
+
354
+ def get_all_queries() -> dict[str, str]:
355
+ """
356
+ Get all queries for the query loader
357
+
358
+ Returns:
359
+ Dictionary mapping query names to query strings
360
+ """
361
+ # Combine direct queries and aliases
362
+ all_queries = MARKDOWN_QUERIES.copy()
363
+
364
+ # Add aliases that point to actual queries
365
+ for alias, target in QUERY_ALIASES.items():
366
+ if target in MARKDOWN_QUERIES:
367
+ all_queries[alias] = MARKDOWN_QUERIES[target]
368
+
369
+ return all_queries
370
+
371
+ # Export main functions and constants
372
+ __all__ = [
373
+ "MARKDOWN_QUERIES",
374
+ "QUERY_ALIASES",
375
+ "get_query",
376
+ "get_available_queries",
377
+ "get_query_info",
378
+ "get_all_queries"
379
+ ]
@@ -156,6 +156,7 @@ class QueryLoader:
156
156
  "cpp",
157
157
  "rust",
158
158
  "go",
159
+ "markdown",
159
160
  ]
160
161
 
161
162
  for language in known_languages:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tree-sitter-analyzer
3
- Version: 1.7.2
3
+ Version: 1.7.3
4
4
  Summary: Extensible multi-language code analyzer framework using Tree-sitter with dynamic plugin architecture
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
@@ -37,8 +37,9 @@ Requires-Dist: mcp>=1.12.3
37
37
  Requires-Dist: tree-sitter-cpp<0.25.0,>=0.23.4
38
38
  Requires-Dist: tree-sitter-java<0.25.0,>=0.23.5
39
39
  Requires-Dist: tree-sitter-javascript<0.25.0,>=0.23.1
40
+ Requires-Dist: tree-sitter-markdown>=0.3.1
40
41
  Requires-Dist: tree-sitter-python<0.25.0,>=0.23.6
41
- Requires-Dist: tree-sitter==0.24.0
42
+ Requires-Dist: tree-sitter>=0.25.0
42
43
  Provides-Extra: all
43
44
  Requires-Dist: anyio>=4.0.0; extra == 'all'
44
45
  Requires-Dist: black>=24.0.0; extra == 'all'
@@ -61,6 +62,7 @@ Requires-Dist: tree-sitter-cpp<0.25.0,>=0.23.4; extra == 'all'
61
62
  Requires-Dist: tree-sitter-go<0.25.0,>=0.20.0; extra == 'all'
62
63
  Requires-Dist: tree-sitter-java<0.25.0,>=0.23.5; extra == 'all'
63
64
  Requires-Dist: tree-sitter-javascript<0.25.0,>=0.23.1; extra == 'all'
65
+ Requires-Dist: tree-sitter-markdown>=0.3.1; extra == 'all'
64
66
  Requires-Dist: tree-sitter-python<0.25.0,>=0.23.0; extra == 'all'
65
67
  Requires-Dist: tree-sitter-rust<0.25.0,>=0.20.0; extra == 'all'
66
68
  Requires-Dist: tree-sitter-typescript<0.25.0,>=0.20.0; extra == 'all'
@@ -71,6 +73,7 @@ Requires-Dist: tree-sitter-cpp<0.25.0,>=0.23.4; extra == 'all-languages'
71
73
  Requires-Dist: tree-sitter-go<0.25.0,>=0.20.0; extra == 'all-languages'
72
74
  Requires-Dist: tree-sitter-java<0.25.0,>=0.23.5; extra == 'all-languages'
73
75
  Requires-Dist: tree-sitter-javascript<0.25.0,>=0.23.1; extra == 'all-languages'
76
+ Requires-Dist: tree-sitter-markdown>=0.3.1; extra == 'all-languages'
74
77
  Requires-Dist: tree-sitter-python<0.25.0,>=0.23.0; extra == 'all-languages'
75
78
  Requires-Dist: tree-sitter-rust<0.25.0,>=0.20.0; extra == 'all-languages'
76
79
  Requires-Dist: tree-sitter-typescript<0.25.0,>=0.20.0; extra == 'all-languages'
@@ -113,6 +116,7 @@ Requires-Dist: tree-sitter-cpp<0.25.0,>=0.23.4; extra == 'full'
113
116
  Requires-Dist: tree-sitter-go<0.25.0,>=0.20.0; extra == 'full'
114
117
  Requires-Dist: tree-sitter-java<0.25.0,>=0.23.5; extra == 'full'
115
118
  Requires-Dist: tree-sitter-javascript<0.25.0,>=0.23.1; extra == 'full'
119
+ Requires-Dist: tree-sitter-markdown>=0.3.1; extra == 'full'
116
120
  Requires-Dist: tree-sitter-python<0.25.0,>=0.23.0; extra == 'full'
117
121
  Requires-Dist: tree-sitter-rust<0.25.0,>=0.20.0; extra == 'full'
118
122
  Requires-Dist: tree-sitter-typescript<0.25.0,>=0.20.0; extra == 'full'
@@ -123,6 +127,8 @@ Provides-Extra: java
123
127
  Requires-Dist: tree-sitter-java<0.25.0,>=0.23.5; extra == 'java'
124
128
  Provides-Extra: javascript
125
129
  Requires-Dist: tree-sitter-javascript<0.25.0,>=0.23.1; extra == 'javascript'
130
+ Provides-Extra: markdown
131
+ Requires-Dist: tree-sitter-markdown>=0.3.1; extra == 'markdown'
126
132
  Provides-Extra: mcp
127
133
  Requires-Dist: anyio>=4.0.0; extra == 'mcp'
128
134
  Requires-Dist: httpx<1.0.0,>=0.27.0; extra == 'mcp'
@@ -165,11 +171,11 @@ Description-Content-Type: text/markdown
165
171
 
166
172
  [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)
167
173
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
168
- [![Tests](https://img.shields.io/badge/tests-2675%20passed-brightgreen.svg)](#quality-assurance)
169
- [![Coverage](https://img.shields.io/badge/coverage-78.85%25-green.svg)](#quality-assurance)
174
+ [![Tests](https://img.shields.io/badge/tests-2831%20passed-brightgreen.svg)](#quality-assurance)
175
+ [![Coverage](https://img.shields.io/badge/coverage-79.19%25-green.svg)](#quality-assurance)
170
176
  [![Quality](https://img.shields.io/badge/quality-enterprise%20grade-blue.svg)](#quality-assurance)
171
177
  [![PyPI](https://img.shields.io/pypi/v/tree-sitter-analyzer.svg)](https://pypi.org/project/tree-sitter-analyzer/)
172
- [![Version](https://img.shields.io/badge/version-1.7.2-blue.svg)](https://github.com/aimasteracc/tree-sitter-analyzer/releases)
178
+ [![Version](https://img.shields.io/badge/version-1.7.3-blue.svg)](https://github.com/aimasteracc/tree-sitter-analyzer/releases)
173
179
  [![GitHub Stars](https://img.shields.io/github/stars/aimasteracc/tree-sitter-analyzer.svg?style=social)](https://github.com/aimasteracc/tree-sitter-analyzer)
174
180
 
175
181
  ## 🚀 Enterprise-Grade Code Analysis Tool for the AI Era
@@ -213,13 +219,14 @@ Tree-sitter Analyzer is an enterprise-grade code analysis tool designed for the
213
219
  | **Python** | Complete Support | Type annotations, decorators, modern Python features |
214
220
  | **JavaScript** | Complete Support | ES6+, React/Vue/Angular, JSX |
215
221
  | **TypeScript** | Complete Support | Interfaces, types, decorators, TSX/JSX, framework detection |
222
+ | **Markdown** | 🆕 Complete Support | Headers, code blocks, links, images, tables, task lists, blockquotes |
216
223
  | **C/C++** | Basic Support | Basic syntax parsing |
217
224
  | **Rust** | Basic Support | Basic syntax parsing |
218
225
  | **Go** | Basic Support | Basic syntax parsing |
219
226
 
220
227
  ### 🏆 Production Ready
221
- - **2,675 Tests** - 100% pass rate, enterprise-grade quality assurance
222
- - **78.85% Coverage** - Comprehensive test coverage
228
+ - **2,831 Tests** - 100% pass rate, enterprise-grade quality assurance
229
+ - **79.19% Coverage** - Comprehensive test coverage
223
230
  - **Cross-platform Support** - Compatible with Windows, macOS, Linux
224
231
  - **Continuous Maintenance** - Active development and community support
225
232
 
@@ -585,7 +592,18 @@ Tree-sitter Analyzer provides a rich set of MCP tools designed for AI assistants
585
592
  | **📁 Resource Access** | Code file resources | URI code file access | File content access via URI identification |
586
593
  | | Project statistics resources | Project statistics data access | Project analysis data and statistical information |
587
594
 
588
- ### 🆕 v1.7.2 New Feature: File Output Optimization
595
+ ### 🆕 v1.7.3 New Feature: Complete Markdown Support
596
+
597
+ Brand new Markdown language support provides powerful capabilities for document analysis and AI assistants:
598
+
599
+ - **📝 Complete Markdown Parsing**: Support for all major elements including ATX headers, Setext headers, code blocks, links, images, tables
600
+ - **🔍 Intelligent Element Extraction**: Automatically recognize and extract header levels, code languages, link URLs, image information
601
+ - **📊 Structured Analysis**: Convert Markdown documents to structured data for easy AI understanding and processing
602
+ - **🎯 Task List Support**: Complete support for GitHub-style task lists (checkboxes)
603
+ - **🔧 Query System Integration**: Support for all existing query and filtering functionality
604
+ - **📁 Multiple Extension Support**: Support for .md, .markdown, .mdown, .mkd, .mkdn, .mdx formats
605
+
606
+ ### 🆕 v1.7.2 Feature: File Output Optimization
589
607
 
590
608
  MCP search tools' newly added file output optimization feature is a revolutionary token-saving solution:
591
609
 
@@ -709,7 +727,7 @@ uv run python -m tree_sitter_analyzer --show-query-languages
709
727
  | **✂️ Intelligent Code Extraction** | Precision Extraction Tool | Precise extraction by line range<br>Preserves original formatting and indentation<br>Includes position metadata<br>Efficient processing of large files | Zero-loss format preservation<br>Memory-optimized algorithms<br>Streaming processing support |
710
728
  | **🔍 Advanced Query Filtering** | Multi-dimensional Filters | **Exact match**: `--filter "name=main"`<br>**Pattern match**: `--filter "name=~auth*"`<br>**Parameter filter**: `--filter "params=2"`<br>**Modifier filter**: `--filter "static=true,public=true"`<br>**Compound conditions**: Combine multiple conditions for precise queries | Flexible query syntax<br>High-performance indexing<br>Intelligent caching mechanisms |
711
729
  | **🔗 AI Assistant Integration** | MCP Protocol Support | **Claude Desktop** - Full MCP support<br>**Cursor IDE** - Built-in MCP integration<br>**Roo Code** - MCP protocol support<br>**Other MCP-compatible tools** - Universal MCP server | Standard MCP protocol<br>Plug-and-play design<br>Cross-platform compatibility |
712
- | **🌍 Multi-language Support** | Enterprise Language Engine | **Java** - Complete support, including Spring, JPA frameworks<br>**Python** - Complete support, including type annotations, decorators<br>**JavaScript** - Enterprise-grade support, including ES6+, React/Vue/Angular, JSX<br>**TypeScript** - **Complete support**, including interfaces, types, decorators, TSX/JSX, framework detection<br>**C/C++, Rust, Go** - Basic support | Framework-aware parsing<br>Syntax extension support<br>Continuous language updates |
730
+ | **🌍 Multi-language Support** | Enterprise Language Engine | **Java** - Complete support, including Spring, JPA frameworks<br>**Python** - Complete support, including type annotations, decorators<br>**JavaScript** - Enterprise-grade support, including ES6+, React/Vue/Angular, JSX<br>**TypeScript** - **Complete support**, including interfaces, types, decorators, TSX/JSX, framework detection<br>**Markdown** - **🆕 Complete support**, including headers, code blocks, links, images, tables, task lists, blockquotes<br>**C/C++, Rust, Go** - Basic support | Framework-aware parsing<br>Syntax extension support<br>Continuous language updates |
713
731
  | **📁 Advanced File Search** | fd+ripgrep Integration | **ListFilesTool** - Intelligent file discovery with multiple filtering conditions<br>**SearchContentTool** - Intelligent content search using regular expressions<br>**FindAndGrepTool** - Combined discovery and search, two-stage workflow | Rust-based high-performance tools<br>Parallel processing capabilities<br>Intelligent cache optimization |
714
732
  | **🏗️ Unified Element System** | Revolutionary Architecture Design | **Single element list** - Unified management of all code elements (classes, methods, fields, imports, packages)<br>**Consistent element types** - Each element has an `element_type` attribute<br>**Simplified API** - Clearer interfaces and reduced complexity<br>**Better maintainability** - Single source of truth for all code elements | Unified data model<br>Type safety guarantees<br>Extensible design |
715
733
 
@@ -718,12 +736,18 @@ uv run python -m tree_sitter_analyzer --show-query-languages
718
736
  ## 8. 🏆 Quality Assurance
719
737
 
720
738
  ### 📊 Quality Metrics
721
- - **2,675 tests** - 100% pass rate ✅
722
- - **78.85% code coverage** - Comprehensive test suite
739
+ - **2,831 tests** - 100% pass rate ✅
740
+ - **79.19% code coverage** - Comprehensive test suite
723
741
  - **Zero test failures** - Production ready
724
742
  - **Cross-platform support** - Windows, macOS, Linux
725
743
 
726
- ### ⚡ Latest Quality Achievements (v1.7.2)
744
+ ### ⚡ Latest Quality Achievements (v1.7.3)
745
+ - ✅ **🆕 Complete Markdown Support** - Added new complete Markdown language plugin supporting all major Markdown elements
746
+ - ✅ **📝 Enhanced Document Analysis** - Support for intelligent extraction of headers, code blocks, links, images, tables, task lists
747
+ - ✅ **🔍 Markdown Query System** - 17 predefined query types with alias and custom query support
748
+ - ✅ **🧪 Comprehensive Test Validation** - Added extensive Markdown test cases ensuring feature stability
749
+ - ✅ **📊 Structured Output** - Convert Markdown documents to structured data for easy AI processing
750
+ - ✅ **🔧 Test Stability Improvement** - Fixed 28 test errors, all 2831 tests now passing 100%
727
751
  - ✅ **File output optimization** - MCP search tools now include `suppress_output` and `output_file` parameters for massive token savings
728
752
  - ✅ **Intelligent format detection** - Automatic selection of optimal file formats (JSON/Markdown) for storage and reading optimization
729
753
  - ✅ **ROO rules documentation** - Added comprehensive tree-sitter-analyzer MCP optimization usage guide