janito 3.3.0__py3-none-any.whl → 3.4.0__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.
Files changed (214) hide show
  1. janito/cli/cli_commands/list_plugins.py +48 -52
  2. janito/cli/core/getters.py +0 -3
  3. janito/cli/main_cli.py +12 -9
  4. janito/drivers/openai/driver.py +0 -1
  5. janito/drivers/zai/driver.py +0 -1
  6. janito/hello.txt +0 -0
  7. janito/llm/auth_utils.py +5 -14
  8. janito/plugins/__init__.py +7 -18
  9. janito/{plugins_backup_20250825_070018 → plugins}/auto_loader_fixed.py +11 -12
  10. janito/plugins/base.py +152 -57
  11. janito/plugins/builtin.py +1 -15
  12. janito/{plugins_backup_20250825_070018 → plugins}/core_adapter.py +9 -11
  13. janito/plugins/core_loader.py +34 -58
  14. janito/{plugin_system_backup_20250825_070018/core_loader.py → plugins/core_loader_fixed.py} +26 -45
  15. janito/plugins/discovery.py +3 -3
  16. janito/tools/__init__.py +7 -31
  17. janito/tools/adapters/__init__.py +1 -6
  18. janito/tools/adapters/local/__init__.py +70 -7
  19. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/ask_user.py +3 -3
  20. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/create_file.py +4 -4
  21. janito/{plugins/core/filemanager/tools → tools/adapters/local}/delete_text_in_file.py +0 -1
  22. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/fetch_url.py +3 -3
  23. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/replace_text_in_file.py +4 -4
  24. janito/{plugins_backup_20250825_070018/tools → tools/adapters/local}/show_image.py +6 -15
  25. janito/{plugins/core/imagedisplay/tools → tools/adapters/local}/show_image_grid.py +5 -13
  26. janito/tools/base.py +1 -31
  27. janito/tools/function_adapter.py +16 -127
  28. janito/tools/tool_base.py +114 -142
  29. janito/tools/tools_schema.py +6 -12
  30. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/METADATA +2 -1
  31. janito-3.4.0.dist-info/RECORD +264 -0
  32. janito/cli/cli_commands/check_tools.py +0 -212
  33. janito/plugin_system_backup_20250825_070018/__init__.py +0 -10
  34. janito/plugin_system_backup_20250825_070018/base.py +0 -155
  35. janito/plugin_system_backup_20250825_070018/core_loader_fixed.py +0 -149
  36. janito/plugins/__main__.py +0 -85
  37. janito/plugins/core/__init__.py +0 -7
  38. janito/plugins/core/codeanalyzer/__init__.py +0 -43
  39. janito/plugins/core/filemanager/__init__.py +0 -124
  40. janito/plugins/core/filemanager/tools/copy_file.py +0 -111
  41. janito/plugins/core/filemanager/tools/create_directory.py +0 -97
  42. janito/plugins/core/filemanager/tools/create_file.py +0 -111
  43. janito/plugins/core/filemanager/tools/replace_text_in_file.py +0 -270
  44. janito/plugins/core/imagedisplay/__init__.py +0 -14
  45. janito/plugins/core/imagedisplay/plugin.py +0 -51
  46. janito/plugins/core/imagedisplay/tools/__init__.py +0 -1
  47. janito/plugins/core/imagedisplay/tools/show_image.py +0 -83
  48. janito/plugins/core/system/__init__.py +0 -23
  49. janito/plugins/dev/__init__.py +0 -7
  50. janito/plugins/dev/pythondev/__init__.py +0 -37
  51. janito/plugins/dev/visualization/__init__.py +0 -23
  52. janito/plugins/example_plugin.py +0 -108
  53. janito/plugins/ui/__init__.py +0 -7
  54. janito/plugins/ui/userinterface/__init__.py +0 -16
  55. janito/plugins/ui/userinterface/tools/ask_user.py +0 -110
  56. janito/plugins/web/__init__.py +0 -7
  57. janito/plugins/web/webtools/__init__.py +0 -33
  58. janito/plugins/web/webtools/tools/fetch_url.py +0 -458
  59. janito/plugins_backup_20250825_070018/__init__.py +0 -36
  60. janito/plugins_backup_20250825_070018/builtin.py +0 -102
  61. janito/plugins_backup_20250825_070018/config.py +0 -84
  62. janito/plugins_backup_20250825_070018/core/__init__.py +0 -7
  63. janito/plugins_backup_20250825_070018/core/codeanalyzer/__init__.py +0 -43
  64. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/__init__.py +0 -1
  65. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/core.py +0 -122
  66. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/java_outline.py +0 -47
  67. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/markdown_outline.py +0 -14
  68. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/python_outline.py +0 -303
  69. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/search_outline.py +0 -36
  70. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/__init__.py +0 -1
  71. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/core.py +0 -205
  72. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/match_lines.py +0 -67
  73. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/pattern_utils.py +0 -73
  74. janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/traverse_directory.py +0 -145
  75. janito/plugins_backup_20250825_070018/core/filemanager/__init__.py +0 -124
  76. janito/plugins_backup_20250825_070018/core/filemanager/tools/create_file.py +0 -87
  77. janito/plugins_backup_20250825_070018/core/filemanager/tools/delete_text_in_file.py +0 -135
  78. janito/plugins_backup_20250825_070018/core/filemanager/tools/find_files.py +0 -143
  79. janito/plugins_backup_20250825_070018/core/filemanager/tools/move_file.py +0 -131
  80. janito/plugins_backup_20250825_070018/core/filemanager/tools/read_files.py +0 -58
  81. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_directory.py +0 -55
  82. janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_file.py +0 -58
  83. janito/plugins_backup_20250825_070018/core/filemanager/tools/replace_text_in_file.py +0 -270
  84. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/__init__.py +0 -1
  85. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/core.py +0 -114
  86. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/css_validator.py +0 -35
  87. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/html_validator.py +0 -100
  88. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/jinja2_validator.py +0 -50
  89. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/js_validator.py +0 -27
  90. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/json_validator.py +0 -6
  91. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/markdown_validator.py +0 -109
  92. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/ps1_validator.py +0 -32
  93. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/python_validator.py +0 -5
  94. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/xml_validator.py +0 -11
  95. janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/yaml_validator.py +0 -6
  96. janito/plugins_backup_20250825_070018/core/filemanager/tools/view_file.py +0 -172
  97. janito/plugins_backup_20250825_070018/core/imagedisplay/__init__.py +0 -14
  98. janito/plugins_backup_20250825_070018/core/imagedisplay/plugin.py +0 -51
  99. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/__init__.py +0 -1
  100. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image.py +0 -83
  101. janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image_grid.py +0 -84
  102. janito/plugins_backup_20250825_070018/core/system/__init__.py +0 -23
  103. janito/plugins_backup_20250825_070018/core/system/tools/run_bash_command.py +0 -183
  104. janito/plugins_backup_20250825_070018/core/system/tools/run_powershell_command.py +0 -218
  105. janito/plugins_backup_20250825_070018/dev/__init__.py +0 -7
  106. janito/plugins_backup_20250825_070018/dev/pythondev/__init__.py +0 -37
  107. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_code_run.py +0 -172
  108. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_command_run.py +0 -171
  109. janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_file_run.py +0 -172
  110. janito/plugins_backup_20250825_070018/dev/visualization/__init__.py +0 -23
  111. janito/plugins_backup_20250825_070018/dev/visualization/tools/read_chart.py +0 -259
  112. janito/plugins_backup_20250825_070018/discovery.py +0 -289
  113. janito/plugins_backup_20250825_070018/example_plugin.py +0 -108
  114. janito/plugins_backup_20250825_070018/manager.py +0 -243
  115. janito/plugins_backup_20250825_070018/tools/__init__.py +0 -10
  116. janito/plugins_backup_20250825_070018/tools/copy_file.py +0 -87
  117. janito/plugins_backup_20250825_070018/tools/core_tools_plugin.py +0 -88
  118. janito/plugins_backup_20250825_070018/tools/create_directory.py +0 -70
  119. janito/plugins_backup_20250825_070018/tools/decorators.py +0 -19
  120. janito/plugins_backup_20250825_070018/tools/delete_text_in_file.py +0 -135
  121. janito/plugins_backup_20250825_070018/tools/find_files.py +0 -143
  122. janito/plugins_backup_20250825_070018/tools/get_file_outline/__init__.py +0 -7
  123. janito/plugins_backup_20250825_070018/tools/get_file_outline/core.py +0 -122
  124. janito/plugins_backup_20250825_070018/tools/get_file_outline/java_outline.py +0 -47
  125. janito/plugins_backup_20250825_070018/tools/get_file_outline/markdown_outline.py +0 -14
  126. janito/plugins_backup_20250825_070018/tools/get_file_outline/python_outline.py +0 -303
  127. janito/plugins_backup_20250825_070018/tools/get_file_outline/search_outline.py +0 -36
  128. janito/plugins_backup_20250825_070018/tools/move_file.py +0 -131
  129. janito/plugins_backup_20250825_070018/tools/open_html_in_browser.py +0 -51
  130. janito/plugins_backup_20250825_070018/tools/open_url.py +0 -37
  131. janito/plugins_backup_20250825_070018/tools/python_code_run.py +0 -172
  132. janito/plugins_backup_20250825_070018/tools/python_command_run.py +0 -171
  133. janito/plugins_backup_20250825_070018/tools/python_file_run.py +0 -172
  134. janito/plugins_backup_20250825_070018/tools/read_chart.py +0 -259
  135. janito/plugins_backup_20250825_070018/tools/read_files.py +0 -58
  136. janito/plugins_backup_20250825_070018/tools/remove_directory.py +0 -55
  137. janito/plugins_backup_20250825_070018/tools/remove_file.py +0 -58
  138. janito/plugins_backup_20250825_070018/tools/run_bash_command.py +0 -183
  139. janito/plugins_backup_20250825_070018/tools/run_powershell_command.py +0 -218
  140. janito/plugins_backup_20250825_070018/tools/search_text/__init__.py +0 -7
  141. janito/plugins_backup_20250825_070018/tools/search_text/core.py +0 -205
  142. janito/plugins_backup_20250825_070018/tools/search_text/match_lines.py +0 -67
  143. janito/plugins_backup_20250825_070018/tools/search_text/pattern_utils.py +0 -73
  144. janito/plugins_backup_20250825_070018/tools/search_text/traverse_directory.py +0 -145
  145. janito/plugins_backup_20250825_070018/tools/show_image_grid.py +0 -85
  146. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/__init__.py +0 -7
  147. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/core.py +0 -114
  148. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/css_validator.py +0 -35
  149. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/html_validator.py +0 -100
  150. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/jinja2_validator.py +0 -50
  151. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/js_validator.py +0 -27
  152. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/json_validator.py +0 -6
  153. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/markdown_validator.py +0 -109
  154. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/ps1_validator.py +0 -32
  155. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/python_validator.py +0 -5
  156. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/xml_validator.py +0 -11
  157. janito/plugins_backup_20250825_070018/tools/validate_file_syntax/yaml_validator.py +0 -6
  158. janito/plugins_backup_20250825_070018/tools/view_file.py +0 -172
  159. janito/plugins_backup_20250825_070018/ui/__init__.py +0 -7
  160. janito/plugins_backup_20250825_070018/ui/userinterface/__init__.py +0 -16
  161. janito/plugins_backup_20250825_070018/ui/userinterface/tools/ask_user.py +0 -110
  162. janito/plugins_backup_20250825_070018/web/__init__.py +0 -7
  163. janito/plugins_backup_20250825_070018/web/webtools/__init__.py +0 -33
  164. janito/plugins_backup_20250825_070018/web/webtools/tools/fetch_url.py +0 -458
  165. janito/plugins_backup_20250825_070018/web/webtools/tools/open_html_in_browser.py +0 -51
  166. janito/plugins_backup_20250825_070018/web/webtools/tools/open_url.py +0 -37
  167. janito/tools/cli_initializer.py +0 -88
  168. janito/tools/initialize.py +0 -70
  169. janito-3.3.0.dist-info/RECORD +0 -400
  170. /janito/{plugins_backup_20250825_070018 → plugins}/auto_loader.py +0 -0
  171. /janito/{plugins_backup_20250825_070018 → plugins}/discovery_core.py +0 -0
  172. /janito/{plugins_backup_20250825_070018/core/filemanager/tools → tools/adapters/local}/copy_file.py +0 -0
  173. /janito/{plugins_backup_20250825_070018/core/filemanager/tools → tools/adapters/local}/create_directory.py +0 -0
  174. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/find_files.py +0 -0
  175. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/__init__.py +0 -0
  176. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/core.py +0 -0
  177. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/java_outline.py +0 -0
  178. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/markdown_outline.py +0 -0
  179. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/python_outline.py +0 -0
  180. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/get_file_outline/search_outline.py +0 -0
  181. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/move_file.py +0 -0
  182. /janito/{plugins/web/webtools/tools → tools/adapters/local}/open_html_in_browser.py +0 -0
  183. /janito/{plugins/web/webtools/tools → tools/adapters/local}/open_url.py +0 -0
  184. /janito/{plugins/dev/pythondev/tools → tools/adapters/local}/python_code_run.py +0 -0
  185. /janito/{plugins/dev/pythondev/tools → tools/adapters/local}/python_command_run.py +0 -0
  186. /janito/{plugins/dev/pythondev/tools → tools/adapters/local}/python_file_run.py +0 -0
  187. /janito/{plugins/dev/visualization/tools → tools/adapters/local}/read_chart.py +0 -0
  188. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/read_files.py +0 -0
  189. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/remove_directory.py +0 -0
  190. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/remove_file.py +0 -0
  191. /janito/{plugins/core/system/tools → tools/adapters/local}/run_bash_command.py +0 -0
  192. /janito/{plugins/core/system/tools → tools/adapters/local}/run_powershell_command.py +0 -0
  193. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/__init__.py +0 -0
  194. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/core.py +0 -0
  195. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/match_lines.py +0 -0
  196. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/pattern_utils.py +0 -0
  197. /janito/{plugins/core/codeanalyzer/tools → tools/adapters/local}/search_text/traverse_directory.py +0 -0
  198. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/__init__.py +0 -0
  199. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/core.py +0 -0
  200. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/css_validator.py +0 -0
  201. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/html_validator.py +0 -0
  202. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/jinja2_validator.py +0 -0
  203. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/js_validator.py +0 -0
  204. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/json_validator.py +0 -0
  205. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/markdown_validator.py +0 -0
  206. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/ps1_validator.py +0 -0
  207. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/python_validator.py +0 -0
  208. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/xml_validator.py +0 -0
  209. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/validate_file_syntax/yaml_validator.py +0 -0
  210. /janito/{plugins/core/filemanager/tools → tools/adapters/local}/view_file.py +0 -0
  211. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/WHEEL +0 -0
  212. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/entry_points.txt +0 -0
  213. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/licenses/LICENSE +0 -0
  214. {janito-3.3.0.dist-info → janito-3.4.0.dist-info}/top_level.txt +0 -0
@@ -1,43 +0,0 @@
1
- """
2
- Code Analyzer Plugin
3
-
4
- Tools for understanding and searching code structure.
5
- """
6
-
7
- from typing import List, Optional
8
-
9
-
10
- def get_file_outline(path: str) -> str:
11
- """Get file structure (classes, functions, etc.)"""
12
- return f"get_file_outline(path='{path}')"
13
-
14
-
15
- get_file_outline.tool_name = "get_file_outline"
16
-
17
-
18
- def search_outline(path: str) -> str:
19
- """Search within file outlines"""
20
- return f"search_outline(path='{path}')"
21
-
22
-
23
- search_outline.tool_name = "search_outline"
24
-
25
-
26
- def search_text(
27
- paths: str,
28
- query: str,
29
- use_regex: bool = False,
30
- case_sensitive: bool = True,
31
- max_depth: Optional[int] = None,
32
- ) -> str:
33
- """Full-text search across files with regex support"""
34
- return f"search_text(paths='{paths}', query='{query}', regex={use_regex})"
35
-
36
-
37
- search_text.tool_name = "search_text"
38
-
39
-
40
- # Plugin metadata
41
- __plugin_name__ = "core.codeanalyzer"
42
- __plugin_description__ = "Code analysis and structure understanding"
43
- __plugin_tools__ = [get_file_outline, search_outline, search_text]
@@ -1 +0,0 @@
1
- # Outline tools and parsers package
@@ -1,122 +0,0 @@
1
- from janito.tools.adapters.local.adapter import register_local_tool
2
- from .python_outline import parse_python_outline
3
- from .markdown_outline import parse_markdown_outline
4
- from janito.formatting import OutlineFormatter
5
- from .java_outline import parse_java_outline
6
- import os
7
- from janito.tools.path_utils import expand_path
8
- from janito.tools.tool_base import ToolBase, ToolPermissions
9
- from janito.report_events import ReportAction
10
- from janito.tools.tool_utils import display_path, pluralize
11
- from janito.i18n import tr
12
-
13
- from janito.tools.adapters.local.adapter import register_local_tool as register_tool
14
- from janito.tools.loop_protection_decorator import protect_against_loops
15
-
16
-
17
- @register_tool
18
- class GetFileOutlineTool(ToolBase):
19
- """
20
- Get an outline of a file's structure. Supports Python and Markdown files.
21
-
22
- Args:
23
- path (str): Path to the file to outline.
24
- """
25
-
26
- permissions = ToolPermissions(read=True)
27
- tool_name = "get_file_outline"
28
-
29
- @protect_against_loops(max_calls=5, time_window=10.0, key_field="path")
30
- def run(self, path: str) -> str:
31
- try:
32
- path = expand_path(path)
33
- self.report_action(
34
- tr(
35
- "📄 Outline file '{disp_path}' ...",
36
- disp_path=display_path(path),
37
- ),
38
- ReportAction.READ,
39
- )
40
- ext = os.path.splitext(path)[1].lower()
41
- with open(path, "r", encoding="utf-8", errors="replace") as f:
42
- lines = f.readlines()
43
- return self._outline_by_extension(ext, lines)
44
- except Exception as e:
45
- self.report_error(
46
- tr("❌ Error reading file: {error}", error=e),
47
- ReportAction.READ,
48
- )
49
- return tr("Error reading file: {error}", error=e)
50
-
51
- def _outline_by_extension(self, ext, lines):
52
- if ext == ".py":
53
- outline_items = parse_python_outline(lines)
54
- outline_type = "python"
55
- table = OutlineFormatter.format_outline_table(outline_items)
56
- self.report_success(
57
- tr(
58
- "✅ Outlined {count} {item_word}",
59
- count=len(outline_items),
60
- item_word=pluralize("item", len(outline_items)),
61
- ),
62
- ReportAction.READ,
63
- )
64
- return (
65
- tr(
66
- "Outline: {count} items ({outline_type})\n",
67
- count=len(outline_items),
68
- outline_type=outline_type,
69
- )
70
- + table
71
- )
72
- elif ext == ".md":
73
- outline_items = parse_markdown_outline(lines)
74
- outline_type = "markdown"
75
- table = OutlineFormatter.format_markdown_outline_table(outline_items)
76
- self.report_success(
77
- tr(
78
- "✅ Outlined {count} {item_word}",
79
- count=len(outline_items),
80
- item_word=pluralize("item", len(outline_items)),
81
- ),
82
- ReportAction.READ,
83
- )
84
- return (
85
- tr(
86
- "Outline: {count} items ({outline_type})\n",
87
- count=len(outline_items),
88
- outline_type=outline_type,
89
- )
90
- + table
91
- )
92
- elif ext == ".java":
93
- outline_items = parse_java_outline(lines)
94
- outline_type = "java"
95
- table = OutlineFormatter.format_outline_table(outline_items)
96
- self.report_success(
97
- tr(
98
- "✅ Outlined {count} {item_word}",
99
- count=len(outline_items),
100
- item_word=pluralize("item", len(outline_items)),
101
- ),
102
- ReportAction.READ,
103
- )
104
- return (
105
- tr(
106
- "Outline: {count} items ({outline_type})\n",
107
- count=len(outline_items),
108
- outline_type=outline_type,
109
- )
110
- + table
111
- )
112
- else:
113
- outline_type = "default"
114
- self.report_success(
115
- tr("✅ Outlined {count} items", count=len(lines)),
116
- ReportAction.READ,
117
- )
118
- return tr(
119
- "Outline: {count} lines ({outline_type})\nFile has {count} lines.",
120
- count=len(lines),
121
- outline_type=outline_type,
122
- )
@@ -1,47 +0,0 @@
1
- import re
2
- from typing import List, Dict
3
-
4
-
5
- def parse_java_outline(lines: List[str]) -> List[Dict]:
6
- """
7
- Parses Java source code lines and extracts classes and methods with their signatures.
8
- Returns a list of outline items: {type, name, return_type, parameters, generics, line}
9
- """
10
- outline = []
11
- class_pattern = re.compile(r"\bclass\s+(\w+)(\s*<[^>]+>)?")
12
- # Match methods with or without visibility modifiers (including package-private)
13
- method_pattern = re.compile(
14
- r"^(?:\s*(public|protected|private)\s+)?(?:static\s+)?([\w<>\[\]]+)\s+(\w+)\s*\(([^)]*)\)"
15
- )
16
- current_class = None
17
- for idx, line in enumerate(lines, 1):
18
- class_match = class_pattern.search(line)
19
- if class_match:
20
- class_name = class_match.group(1)
21
- generics = class_match.group(2) or ""
22
- outline.append(
23
- {
24
- "type": "class",
25
- "name": class_name,
26
- "generics": generics.strip("<>") if generics else None,
27
- "line": idx,
28
- }
29
- )
30
- current_class = class_name
31
- else:
32
- method_match = method_pattern.search(line)
33
- if method_match:
34
- return_type = method_match.group(2)
35
- method_name = method_match.group(3)
36
- params = method_match.group(4)
37
- outline.append(
38
- {
39
- "type": "method",
40
- "class": current_class,
41
- "name": method_name,
42
- "return_type": return_type,
43
- "parameters": params.strip(),
44
- "line": idx,
45
- }
46
- )
47
- return outline
@@ -1,14 +0,0 @@
1
- import re
2
- from typing import List
3
-
4
-
5
- def parse_markdown_outline(lines: List[str]):
6
- header_pat = re.compile(r"^(#+)\s+(.*)")
7
- outline = []
8
- for idx, line in enumerate(lines):
9
- match = header_pat.match(line)
10
- if match:
11
- level = len(match.group(1))
12
- title = match.group(2).strip()
13
- outline.append({"level": level, "title": title, "line": idx + 1})
14
- return outline
@@ -1,303 +0,0 @@
1
- import re
2
- from typing import List
3
-
4
-
5
- def handle_assignment(idx, assign_match, outline):
6
- var_name = assign_match.group(2)
7
- var_type = "const" if var_name.isupper() else "var"
8
- outline.append(
9
- {
10
- "type": var_type,
11
- "name": var_name,
12
- "start": idx + 1,
13
- "end": idx + 1,
14
- "parent": "",
15
- "docstring": "",
16
- }
17
- )
18
-
19
-
20
- def handle_main(idx, outline):
21
- outline.append(
22
- {
23
- "type": "main",
24
- "name": "__main__",
25
- "start": idx + 1,
26
- "end": idx + 1,
27
- "parent": "",
28
- "docstring": "",
29
- }
30
- )
31
-
32
-
33
- def close_stack_objects(idx, indent, stack, obj_ranges):
34
- while stack and indent < stack[-1][2]:
35
- popped = stack.pop()
36
- obj_ranges.append((popped[0], popped[1], popped[3], idx, popped[4], popped[2]))
37
-
38
-
39
- def close_last_top_obj(idx, last_top_obj, stack, obj_ranges):
40
- if last_top_obj and last_top_obj in stack:
41
- stack.remove(last_top_obj)
42
- obj_ranges.append(
43
- (
44
- last_top_obj[0],
45
- last_top_obj[1],
46
- last_top_obj[3],
47
- idx,
48
- last_top_obj[4],
49
- last_top_obj[2],
50
- )
51
- )
52
- return None
53
- return last_top_obj
54
-
55
-
56
- def handle_class(idx, class_match, indent, stack, last_top_obj):
57
- name = class_match.group(2)
58
- parent = stack[-1][1] if stack and stack[-1][0] == "class" else ""
59
- obj = ("class", name, indent, idx + 1, parent)
60
- stack.append(obj)
61
- if indent == 0:
62
- last_top_obj = obj
63
- return last_top_obj
64
-
65
-
66
- def handle_function(idx, func_match, indent, stack, last_top_obj):
67
- name = func_match.group(2)
68
- parent = ""
69
- for s in reversed(stack):
70
- if s[0] == "class" and indent > s[2]:
71
- parent = s[1]
72
- break
73
- obj = ("function", name, indent, idx + 1, parent)
74
- stack.append(obj)
75
- if indent == 0:
76
- last_top_obj = obj
77
- return last_top_obj
78
-
79
-
80
- def process_line(idx, line, regexes, stack, obj_ranges, outline, last_top_obj):
81
- class_pat, func_pat, assign_pat, main_pat = regexes
82
- class_match = class_pat.match(line)
83
- func_match = func_pat.match(line)
84
- assign_match = assign_pat.match(line)
85
- indent = len(line) - len(line.lstrip())
86
- # If a new top-level class or function starts, close the previous one
87
- if (class_match or func_match) and indent == 0 and last_top_obj:
88
- last_top_obj = close_last_top_obj(idx, last_top_obj, stack, obj_ranges)
89
- if class_match:
90
- last_top_obj = handle_class(idx, class_match, indent, stack, last_top_obj)
91
- elif func_match:
92
- last_top_obj = handle_function(idx, func_match, indent, stack, last_top_obj)
93
- elif assign_match and indent == 0:
94
- handle_assignment(idx, assign_match, outline)
95
- main_match = main_pat.match(line)
96
- if main_match:
97
- handle_main(idx, outline)
98
- close_stack_objects(idx, indent, stack, obj_ranges)
99
- return last_top_obj
100
-
101
-
102
- def extract_signature_and_decorators(lines, start_idx):
103
- """
104
- Extracts the signature line and leading decorators for a given function/class/method.
105
- Returns (signature:str, decorators:List[str], signature_lineno:int)
106
- """
107
- decorators = []
108
- sig_line = None
109
- sig_lineno = start_idx
110
- for i in range(start_idx - 1, -1, -1):
111
- striped = lines[i].strip()
112
- if striped.startswith("@"):
113
- decorators.insert(0, striped)
114
- sig_lineno = i
115
- elif not striped:
116
- continue
117
- else:
118
- break
119
- # Find the signature line itself
120
- for k in range(start_idx, len(lines)):
121
- striped = lines[k].strip()
122
- if striped.startswith("def ") or striped.startswith("class "):
123
- sig_line = striped
124
- sig_lineno = k
125
- break
126
- return sig_line, decorators, sig_lineno
127
-
128
-
129
- def extract_docstring(lines, start_idx, end_idx):
130
- """Extracts a docstring from lines[start_idx:end_idx] if present."""
131
- for i in range(start_idx, min(end_idx, len(lines))):
132
- line = lines[i].lstrip()
133
- if not line:
134
- continue
135
- if line.startswith('"""') or line.startswith("'''"):
136
- quote = line[:3]
137
- doc = line[3:]
138
- if doc.strip().endswith(quote):
139
- return doc.strip()[:-3].strip()
140
- docstring_lines = [doc]
141
- for j in range(i + 1, min(end_idx, len(lines))):
142
- line = lines[j]
143
- if line.strip().endswith(quote):
144
- docstring_lines.append(line.strip()[:-3])
145
- return "\n".join([d.strip() for d in docstring_lines]).strip()
146
- docstring_lines.append(line)
147
- break
148
- else:
149
- break
150
- return ""
151
-
152
-
153
- def build_outline_entry(obj, lines, outline):
154
- obj_type, name, start, end, parent, indent = obj
155
- # Determine if this is a method
156
- if obj_type == "function" and parent:
157
- outline_type = "method"
158
- elif obj_type == "function":
159
- outline_type = "function"
160
- else:
161
- outline_type = obj_type
162
- docstring = extract_docstring(lines, start, end)
163
- outline.append(
164
- {
165
- "type": outline_type,
166
- "name": name,
167
- "start": start,
168
- "end": end,
169
- "parent": parent,
170
- "docstring": docstring,
171
- }
172
- )
173
-
174
-
175
- def process_lines(lines, regexes):
176
- outline = []
177
- stack = []
178
- obj_ranges = []
179
- last_top_obj = None
180
- for idx, line in enumerate(lines):
181
- last_top_obj = process_line(
182
- idx, line, regexes, stack, obj_ranges, outline, last_top_obj
183
- )
184
- # Close any remaining open objects
185
- for popped in stack:
186
- obj_ranges.append(
187
- (popped[0], popped[1], popped[3], len(lines), popped[4], popped[2])
188
- )
189
- return outline, obj_ranges
190
-
191
-
192
- def build_outline(obj_ranges, lines, outline):
193
- for obj in obj_ranges:
194
- build_outline_entry(obj, lines, outline)
195
- return outline
196
-
197
-
198
- def parse_python_outline(lines: List[str]):
199
- class_pat = re.compile(r"^(\s*)class\s+(\w+)")
200
- func_pat = re.compile(r"^(\s*)def\s+(\w+)")
201
- assign_pat = re.compile(r"^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=.*")
202
- main_pat = re.compile(r"^\s*if\s+__name__\s*==\s*[\'\"]__main__[\'\"]\s*:")
203
- outline = []
204
- stack = []
205
- obj_ranges = []
206
- last_top_obj = None
207
- for idx, line in enumerate(lines):
208
- class_match = class_pat.match(line)
209
- func_match = func_pat.match(line)
210
- assign_match = assign_pat.match(line)
211
- indent = len(line) - len(line.lstrip())
212
- parent = ""
213
- for s in reversed(stack):
214
- if s[0] == "class" and indent > s[2]:
215
- parent = s[1]
216
- break
217
- if class_match:
218
- obj = ("class", class_match.group(2), idx + 1, None, parent, indent)
219
- stack.append(obj)
220
- last_top_obj = obj
221
- elif func_match:
222
- obj = ("function", func_match.group(2), idx + 1, None, parent, indent)
223
- stack.append(obj)
224
- last_top_obj = obj
225
- elif assign_match and indent == 0:
226
- outline.append(
227
- {
228
- "type": "const" if assign_match.group(2).isupper() else "var",
229
- "name": assign_match.group(2),
230
- "start": idx + 1,
231
- "end": idx + 1,
232
- "parent": "",
233
- "signature": line.strip(),
234
- "decorators": [],
235
- "docstring": "",
236
- }
237
- )
238
- if line.strip().startswith("if __name__ == "):
239
- outline.append(
240
- {
241
- "type": "main",
242
- "name": "__main__",
243
- "start": idx + 1,
244
- "end": idx + 1,
245
- "parent": "",
246
- "signature": line.strip(),
247
- "decorators": [],
248
- "docstring": "",
249
- }
250
- )
251
- # Close stack objects if indent falls back
252
- while stack and indent <= stack[-1][5] and idx + 1 > stack[-1][2]:
253
- finished = stack.pop()
254
- outline_entry = finished[:2] + (
255
- finished[2],
256
- idx + 1,
257
- finished[4],
258
- finished[5],
259
- )
260
- build_outline_entry(outline_entry, lines, outline)
261
- # Close any remaining objects
262
- while stack:
263
- finished = stack.pop()
264
- outline_entry = finished[:2] + (
265
- finished[2],
266
- len(lines),
267
- finished[4],
268
- finished[5],
269
- )
270
- build_outline_entry(outline_entry, lines, outline)
271
- return outline
272
-
273
- class_pat = re.compile(r"^(\s*)class\s+(\w+)")
274
- func_pat = re.compile(r"^(\s*)def\s+(\w+)")
275
- assign_pat = re.compile(r"^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=.*")
276
- main_pat = re.compile(r"^\s*if\s+__name__\s*==\s*[\'\"]__main__[\'\"]\s*:")
277
- regexes = (class_pat, func_pat, assign_pat, main_pat)
278
- outline, obj_ranges = process_lines(lines, regexes)
279
- return build_outline(obj_ranges, lines, outline)
280
-
281
-
282
- def extract_docstring(lines, start_idx, end_idx):
283
- """Extracts a docstring from lines[start_idx:end_idx] if present."""
284
- for i in range(start_idx, min(end_idx, len(lines))):
285
- line = lines[i].lstrip()
286
- if not line:
287
- continue
288
- if line.startswith('"""') or line.startswith("'''"):
289
- quote = line[:3]
290
- doc = line[3:]
291
- if doc.strip().endswith(quote):
292
- return doc.strip()[:-3].strip()
293
- docstring_lines = [doc]
294
- for j in range(i + 1, min(end_idx, len(lines))):
295
- line = lines[j]
296
- if line.strip().endswith(quote):
297
- docstring_lines.append(line.strip()[:-3])
298
- return "\n".join([d.strip() for d in docstring_lines]).strip()
299
- docstring_lines.append(line)
300
- break
301
- else:
302
- break
303
- return ""
@@ -1,36 +0,0 @@
1
- from janito.tools.tool_base import ToolBase, ToolPermissions
2
- from janito.report_events import ReportAction
3
- from janito.tools.loop_protection_decorator import protect_against_loops
4
-
5
-
6
- class SearchOutlineTool(ToolBase):
7
- """
8
- Tool for searching outlines in files.
9
-
10
- Args:
11
- path (str): Path to the file for which to generate an outline.
12
- Returns:
13
- str: Outline search result or status message.
14
- """
15
-
16
- permissions = ToolPermissions(read=True)
17
- tool_name = "search_outline"
18
-
19
- @protect_against_loops(max_calls=5, time_window=10.0, key_field="path")
20
- def run(self, path: str) -> str:
21
- from janito.tools.tool_utils import display_path
22
- from janito.i18n import tr
23
-
24
- self.report_action(
25
- tr(
26
- "🔍 Searching for outline in '{disp_path}'",
27
- disp_path=display_path(path),
28
- ),
29
- ReportAction.READ,
30
- )
31
- # ... rest of implementation ...
32
- # Example warnings and successes:
33
- # self.report_warning(tr("No files found with supported extensions."))
34
- # self.report_warning(tr("Error reading {path}: {error}", path=path, error=e))
35
- # self.report_success(tr("✅ {count} {match_word} found", count=len(output), match_word=pluralize('match', len(output))))
36
- pass
@@ -1 +0,0 @@
1
- from .core import SearchTextTool