auto-coder 1.0.0__py3-none-any.whl → 2.0.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.

Potentially problematic release.


This version of auto-coder might be problematic. Click here for more details.

Files changed (574) hide show
  1. auto_coder-2.0.0.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.0.dist-info/METADATA +558 -0
  3. auto_coder-2.0.0.dist-info/RECORD +795 -0
  4. {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
  5. {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
  6. autocoder/__init__.py +31 -0
  7. autocoder/agent/auto_filegroup.py +32 -13
  8. autocoder/agent/auto_learn_from_commit.py +9 -1
  9. autocoder/agent/base_agentic/__init__.py +3 -0
  10. autocoder/agent/base_agentic/agent_hub.py +1 -1
  11. autocoder/agent/base_agentic/base_agent.py +235 -136
  12. autocoder/agent/base_agentic/default_tools.py +119 -118
  13. autocoder/agent/base_agentic/test_base_agent.py +1 -1
  14. autocoder/agent/base_agentic/tool_registry.py +32 -20
  15. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
  16. autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
  17. autocoder/agent/base_agentic/types.py +42 -0
  18. autocoder/agent/entry_command_agent/chat.py +73 -59
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +970 -2345
  22. autocoder/auto_coder_terminal.py +26 -0
  23. autocoder/auto_coder_terminal_v3.py +190 -0
  24. autocoder/chat/conf_command.py +224 -124
  25. autocoder/chat/models_command.py +361 -299
  26. autocoder/chat/rules_command.py +79 -31
  27. autocoder/chat_auto_coder.py +988 -398
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +25 -8
  30. autocoder/commands/auto_web.py +1 -1
  31. autocoder/commands/tools.py +44 -44
  32. autocoder/common/__init__.py +150 -128
  33. autocoder/common/ac_style_command_parser/__init__.py +39 -2
  34. autocoder/common/ac_style_command_parser/config.py +422 -0
  35. autocoder/common/ac_style_command_parser/parser.py +292 -78
  36. autocoder/common/ac_style_command_parser/test_parser.py +241 -16
  37. autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
  38. autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
  39. autocoder/common/action_yml_file_manager.py +25 -13
  40. autocoder/common/agent_events/__init__.py +52 -0
  41. autocoder/common/agent_events/agent_event_emitter.py +193 -0
  42. autocoder/common/agent_events/event_factory.py +177 -0
  43. autocoder/common/agent_events/examples.py +307 -0
  44. autocoder/common/agent_events/types.py +113 -0
  45. autocoder/common/agent_events/utils.py +68 -0
  46. autocoder/common/agent_hooks/__init__.py +44 -0
  47. autocoder/common/agent_hooks/examples.py +582 -0
  48. autocoder/common/agent_hooks/hook_executor.py +217 -0
  49. autocoder/common/agent_hooks/hook_manager.py +288 -0
  50. autocoder/common/agent_hooks/types.py +133 -0
  51. autocoder/common/agent_hooks/utils.py +99 -0
  52. autocoder/common/agent_query_queue/queue_executor.py +324 -0
  53. autocoder/common/agent_query_queue/queue_manager.py +325 -0
  54. autocoder/common/agents/__init__.py +11 -0
  55. autocoder/common/agents/agent_manager.py +323 -0
  56. autocoder/common/agents/agent_parser.py +189 -0
  57. autocoder/common/agents/example_usage.py +344 -0
  58. autocoder/common/agents/integration_example.py +330 -0
  59. autocoder/common/agents/test_agent_parser.py +545 -0
  60. autocoder/common/async_utils.py +101 -0
  61. autocoder/common/auto_coder_lang.py +23 -972
  62. autocoder/common/autocoderargs_parser/__init__.py +14 -0
  63. autocoder/common/autocoderargs_parser/parser.py +184 -0
  64. autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
  65. autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
  66. autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
  67. autocoder/common/autocoderargs_parser/token_parser.py +290 -0
  68. autocoder/common/buildin_tokenizer.py +2 -4
  69. autocoder/common/code_auto_generate.py +149 -74
  70. autocoder/common/code_auto_generate_diff.py +163 -70
  71. autocoder/common/code_auto_generate_editblock.py +179 -89
  72. autocoder/common/code_auto_generate_strict_diff.py +167 -72
  73. autocoder/common/code_auto_merge_editblock.py +13 -6
  74. autocoder/common/code_modification_ranker.py +1 -1
  75. autocoder/common/command_completer.py +3 -3
  76. autocoder/common/command_file_manager/manager.py +183 -47
  77. autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
  78. autocoder/common/command_templates.py +1 -1
  79. autocoder/common/conf_utils.py +2 -4
  80. autocoder/common/conversations/config.py +11 -3
  81. autocoder/common/conversations/get_conversation_manager.py +100 -2
  82. autocoder/common/conversations/llm_stats_models.py +264 -0
  83. autocoder/common/conversations/manager.py +112 -28
  84. autocoder/common/conversations/models.py +16 -2
  85. autocoder/common/conversations/storage/index_manager.py +134 -10
  86. autocoder/common/core_config/__init__.py +63 -0
  87. autocoder/common/core_config/agentic_mode_manager.py +109 -0
  88. autocoder/common/core_config/base_manager.py +123 -0
  89. autocoder/common/core_config/compatibility.py +151 -0
  90. autocoder/common/core_config/config_manager.py +156 -0
  91. autocoder/common/core_config/conversation_manager.py +31 -0
  92. autocoder/common/core_config/exclude_manager.py +72 -0
  93. autocoder/common/core_config/file_manager.py +177 -0
  94. autocoder/common/core_config/human_as_model_manager.py +129 -0
  95. autocoder/common/core_config/lib_manager.py +54 -0
  96. autocoder/common/core_config/main_manager.py +81 -0
  97. autocoder/common/core_config/mode_manager.py +126 -0
  98. autocoder/common/core_config/models.py +70 -0
  99. autocoder/common/core_config/test_memory_manager.py +1056 -0
  100. autocoder/common/env_manager.py +282 -0
  101. autocoder/common/env_manager_usage_example.py +211 -0
  102. autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
  103. autocoder/common/file_checkpoint/manager.py +264 -48
  104. autocoder/common/file_checkpoint/test_backup.py +1 -18
  105. autocoder/common/file_checkpoint/test_manager.py +270 -1
  106. autocoder/common/file_checkpoint/test_store.py +1 -17
  107. autocoder/common/file_handler/__init__.py +23 -0
  108. autocoder/common/file_handler/active_context_handler.py +159 -0
  109. autocoder/common/file_handler/add_files_handler.py +409 -0
  110. autocoder/common/file_handler/chat_handler.py +180 -0
  111. autocoder/common/file_handler/coding_handler.py +401 -0
  112. autocoder/common/file_handler/commit_handler.py +200 -0
  113. autocoder/common/file_handler/lib_handler.py +156 -0
  114. autocoder/common/file_handler/list_files_handler.py +111 -0
  115. autocoder/common/file_handler/mcp_handler.py +268 -0
  116. autocoder/common/file_handler/models_handler.py +493 -0
  117. autocoder/common/file_handler/remove_files_handler.py +172 -0
  118. autocoder/common/git_utils.py +44 -8
  119. autocoder/common/global_cancel.py +15 -6
  120. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  121. autocoder/common/international/__init__.py +31 -0
  122. autocoder/common/international/demo_international.py +92 -0
  123. autocoder/common/international/message_manager.py +157 -0
  124. autocoder/common/international/messages/__init__.py +56 -0
  125. autocoder/common/international/messages/async_command_messages.py +507 -0
  126. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  127. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  128. autocoder/common/international/messages/command_help_messages.py +986 -0
  129. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  130. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  131. autocoder/common/international/messages/queue_command_messages.py +751 -0
  132. autocoder/common/international/messages/rules_command_messages.py +77 -0
  133. autocoder/common/international/messages/sdk_messages.py +1707 -0
  134. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  135. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  136. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  137. autocoder/common/international/test_international.py +612 -0
  138. autocoder/common/linter_core/__init__.py +28 -0
  139. autocoder/common/linter_core/base_linter.py +61 -0
  140. autocoder/common/linter_core/config_loader.py +271 -0
  141. autocoder/common/linter_core/formatters/__init__.py +0 -0
  142. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  143. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  144. autocoder/common/linter_core/linter.py +166 -0
  145. autocoder/common/linter_core/linter_factory.py +216 -0
  146. autocoder/common/linter_core/linter_manager.py +333 -0
  147. autocoder/common/linter_core/linters/__init__.py +9 -0
  148. autocoder/common/linter_core/linters/java_linter.py +342 -0
  149. autocoder/common/linter_core/linters/python_linter.py +115 -0
  150. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  151. autocoder/common/linter_core/models/__init__.py +7 -0
  152. autocoder/common/linter_core/models/lint_result.py +91 -0
  153. autocoder/common/linter_core/models.py +33 -0
  154. autocoder/common/linter_core/tests/__init__.py +3 -0
  155. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  156. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  157. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  158. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  159. autocoder/common/linter_core/tests/test_integration.py +317 -0
  160. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  161. autocoder/common/linter_core/tests/test_linters.py +265 -0
  162. autocoder/common/linter_core/tests/test_models.py +81 -0
  163. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  164. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  165. autocoder/common/llm_friendly_package/__init__.py +31 -0
  166. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  167. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  168. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  169. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  170. autocoder/common/llm_friendly_package/models.py +40 -0
  171. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  172. autocoder/common/llms/__init__.py +15 -0
  173. autocoder/common/llms/demo_error_handling.py +85 -0
  174. autocoder/common/llms/factory.py +142 -0
  175. autocoder/common/llms/manager.py +264 -0
  176. autocoder/common/llms/pricing.py +121 -0
  177. autocoder/common/llms/registry.py +288 -0
  178. autocoder/common/llms/schema.py +77 -0
  179. autocoder/common/llms/simple_demo.py +45 -0
  180. autocoder/common/llms/test_quick_model.py +116 -0
  181. autocoder/common/llms/test_remove_functionality.py +182 -0
  182. autocoder/common/llms/tests/__init__.py +1 -0
  183. autocoder/common/llms/tests/test_manager.py +330 -0
  184. autocoder/common/llms/tests/test_registry.py +364 -0
  185. autocoder/common/mcp_tools/__init__.py +62 -0
  186. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  187. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  188. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  189. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  190. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  191. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  192. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  193. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  194. autocoder/common/model_speed_tester.py +32 -26
  195. autocoder/common/priority_directory_finder/__init__.py +142 -0
  196. autocoder/common/priority_directory_finder/examples.py +230 -0
  197. autocoder/common/priority_directory_finder/finder.py +283 -0
  198. autocoder/common/priority_directory_finder/models.py +236 -0
  199. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  200. autocoder/common/project_scanner/__init__.py +18 -0
  201. autocoder/common/project_scanner/compat.py +77 -0
  202. autocoder/common/project_scanner/scanner.py +436 -0
  203. autocoder/common/project_tracker/__init__.py +27 -0
  204. autocoder/common/project_tracker/api.py +228 -0
  205. autocoder/common/project_tracker/demo.py +272 -0
  206. autocoder/common/project_tracker/tracker.py +487 -0
  207. autocoder/common/project_tracker/types.py +53 -0
  208. autocoder/common/pruner/__init__.py +67 -0
  209. autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
  210. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  211. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  212. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  213. autocoder/common/pruner/conversation_normalizer.py +347 -0
  214. autocoder/common/pruner/conversation_pruner.py +26 -6
  215. autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
  216. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  217. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  218. autocoder/common/pruner/tool_content_detector.py +227 -0
  219. autocoder/common/pruner/tools/__init__.py +18 -0
  220. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  221. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  222. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  223. autocoder/common/pull_requests/__init__.py +9 -1
  224. autocoder/common/pull_requests/utils.py +122 -1
  225. autocoder/common/rag_manager/rag_manager.py +36 -40
  226. autocoder/common/rulefiles/__init__.py +53 -1
  227. autocoder/common/rulefiles/api.py +250 -0
  228. autocoder/common/rulefiles/core/__init__.py +14 -0
  229. autocoder/common/rulefiles/core/manager.py +241 -0
  230. autocoder/common/rulefiles/core/selector.py +805 -0
  231. autocoder/common/rulefiles/models/__init__.py +20 -0
  232. autocoder/common/rulefiles/models/index.py +16 -0
  233. autocoder/common/rulefiles/models/init_rule.py +18 -0
  234. autocoder/common/rulefiles/models/rule_file.py +18 -0
  235. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  236. autocoder/common/rulefiles/models/summary.py +16 -0
  237. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  238. autocoder/common/rulefiles/utils/__init__.py +34 -0
  239. autocoder/common/rulefiles/utils/monitor.py +86 -0
  240. autocoder/common/rulefiles/utils/parser.py +230 -0
  241. autocoder/common/save_formatted_log.py +67 -10
  242. autocoder/common/search_replace.py +8 -1
  243. autocoder/common/search_replace_patch/__init__.py +24 -0
  244. autocoder/common/search_replace_patch/base.py +115 -0
  245. autocoder/common/search_replace_patch/manager.py +248 -0
  246. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  247. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  248. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  249. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  250. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  251. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  252. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  253. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  254. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  255. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  256. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  257. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  258. autocoder/common/shell_commands/__init__.py +197 -0
  259. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  260. autocoder/common/shell_commands/command_executor.py +1127 -0
  261. autocoder/common/shell_commands/error_recovery.py +541 -0
  262. autocoder/common/shell_commands/exceptions.py +120 -0
  263. autocoder/common/shell_commands/interactive_executor.py +476 -0
  264. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  265. autocoder/common/shell_commands/interactive_process.py +744 -0
  266. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  267. autocoder/common/shell_commands/monitoring.py +529 -0
  268. autocoder/common/shell_commands/process_cleanup.py +386 -0
  269. autocoder/common/shell_commands/process_manager.py +606 -0
  270. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  271. autocoder/common/shell_commands/tests/__init__.py +6 -0
  272. autocoder/common/shell_commands/tests/conftest.py +118 -0
  273. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  274. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  275. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  276. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  277. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  278. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  279. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  280. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  281. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  282. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  283. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  284. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  285. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  286. autocoder/common/shell_commands/timeout_config.py +315 -0
  287. autocoder/common/shell_commands/timeout_manager.py +352 -0
  288. autocoder/common/terminal_paste/__init__.py +14 -0
  289. autocoder/common/terminal_paste/demo.py +145 -0
  290. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  291. autocoder/common/terminal_paste/paste_handler.py +200 -0
  292. autocoder/common/terminal_paste/paste_manager.py +118 -0
  293. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  294. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  295. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  296. autocoder/common/terminal_paste/utils.py +163 -0
  297. autocoder/common/test_autocoder_args.py +232 -0
  298. autocoder/common/test_env_manager.py +173 -0
  299. autocoder/common/test_env_manager_integration.py +159 -0
  300. autocoder/common/text_similarity/__init__.py +9 -0
  301. autocoder/common/text_similarity/demo.py +216 -0
  302. autocoder/common/text_similarity/examples.py +266 -0
  303. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  304. autocoder/common/text_similarity/text_similarity.py +194 -0
  305. autocoder/common/text_similarity/utils.py +125 -0
  306. autocoder/common/todos/__init__.py +61 -0
  307. autocoder/common/todos/cache/__init__.py +16 -0
  308. autocoder/common/todos/cache/base_cache.py +89 -0
  309. autocoder/common/todos/cache/cache_manager.py +228 -0
  310. autocoder/common/todos/cache/memory_cache.py +225 -0
  311. autocoder/common/todos/config.py +155 -0
  312. autocoder/common/todos/exceptions.py +35 -0
  313. autocoder/common/todos/get_todo_manager.py +161 -0
  314. autocoder/common/todos/manager.py +537 -0
  315. autocoder/common/todos/models.py +239 -0
  316. autocoder/common/todos/storage/__init__.py +14 -0
  317. autocoder/common/todos/storage/base_storage.py +76 -0
  318. autocoder/common/todos/storage/file_storage.py +278 -0
  319. autocoder/common/tokens/counter.py +24 -2
  320. autocoder/common/tools_manager/__init__.py +17 -0
  321. autocoder/common/tools_manager/examples.py +162 -0
  322. autocoder/common/tools_manager/manager.py +385 -0
  323. autocoder/common/tools_manager/models.py +39 -0
  324. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  325. autocoder/common/tools_manager/utils.py +191 -0
  326. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  327. autocoder/common/v2/agent/agentic_edit.py +2699 -1856
  328. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  329. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
  330. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  331. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
  332. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
  338. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  340. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  344. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
  346. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  347. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
  349. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  350. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  352. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
  353. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
  354. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
  355. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  356. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  359. autocoder/common/v2/agent/agentic_edit_types.py +343 -9
  360. autocoder/common/v2/agent/runner/__init__.py +3 -3
  361. autocoder/common/v2/agent/runner/base_runner.py +12 -26
  362. autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
  363. autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
  364. autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
  365. autocoder/common/v2/agent/runner/tool_display.py +557 -159
  366. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  367. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  368. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  369. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  370. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  371. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  372. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  373. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  374. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  375. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  376. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  377. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  378. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  379. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  380. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  381. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  382. autocoder/common/v2/code_auto_generate.py +136 -78
  383. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  384. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  385. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  386. autocoder/common/v2/code_auto_merge.py +1 -1
  387. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  388. autocoder/common/v2/code_diff_manager.py +3 -3
  389. autocoder/common/v2/code_editblock_manager.py +4 -14
  390. autocoder/common/v2/code_manager.py +1 -1
  391. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  392. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  393. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  394. autocoder/common/wrap_llm_hint/utils.py +432 -0
  395. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  396. autocoder/completer/__init__.py +8 -0
  397. autocoder/completer/command_completer_v2.py +1051 -0
  398. autocoder/default_project/__init__.py +501 -0
  399. autocoder/dispacher/__init__.py +4 -12
  400. autocoder/dispacher/actions/action.py +165 -7
  401. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  402. autocoder/index/entry.py +116 -124
  403. autocoder/{agent → index/filter}/agentic_filter.py +322 -333
  404. autocoder/index/filter/normal_filter.py +5 -11
  405. autocoder/index/filter/quick_filter.py +1 -1
  406. autocoder/index/index.py +36 -9
  407. autocoder/index/tests/__init__.py +1 -0
  408. autocoder/index/tests/run_tests.py +195 -0
  409. autocoder/index/tests/test_entry.py +303 -0
  410. autocoder/index/tests/test_index_manager.py +314 -0
  411. autocoder/index/tests/test_module_integration.py +300 -0
  412. autocoder/index/tests/test_symbols_utils.py +183 -0
  413. autocoder/inner/__init__.py +4 -0
  414. autocoder/inner/agentic.py +932 -0
  415. autocoder/inner/async_command_handler.py +992 -0
  416. autocoder/inner/conversation_command_handlers.py +623 -0
  417. autocoder/inner/merge_command_handler.py +213 -0
  418. autocoder/inner/queue_command_handler.py +684 -0
  419. autocoder/models.py +95 -266
  420. autocoder/plugins/git_helper_plugin.py +31 -29
  421. autocoder/plugins/token_helper_plugin.py +65 -46
  422. autocoder/pyproject/__init__.py +32 -29
  423. autocoder/rag/agentic_rag.py +215 -75
  424. autocoder/rag/cache/simple_cache.py +1 -2
  425. autocoder/rag/loaders/image_loader.py +1 -1
  426. autocoder/rag/long_context_rag.py +42 -26
  427. autocoder/rag/qa_conversation_strategy.py +1 -1
  428. autocoder/rag/terminal/__init__.py +17 -0
  429. autocoder/rag/terminal/args.py +581 -0
  430. autocoder/rag/terminal/bootstrap.py +61 -0
  431. autocoder/rag/terminal/command_handlers.py +653 -0
  432. autocoder/rag/terminal/formatters/__init__.py +20 -0
  433. autocoder/rag/terminal/formatters/base.py +70 -0
  434. autocoder/rag/terminal/formatters/json_format.py +66 -0
  435. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  436. autocoder/rag/terminal/formatters/text.py +28 -0
  437. autocoder/rag/terminal/init.py +120 -0
  438. autocoder/rag/terminal/utils.py +106 -0
  439. autocoder/rag/test_agentic_rag.py +389 -0
  440. autocoder/rag/test_doc_filter.py +3 -3
  441. autocoder/rag/test_long_context_rag.py +1 -1
  442. autocoder/rag/test_token_limiter.py +517 -10
  443. autocoder/rag/token_counter.py +3 -0
  444. autocoder/rag/token_limiter.py +19 -15
  445. autocoder/rag/tools/__init__.py +26 -2
  446. autocoder/rag/tools/bochaai_example.py +343 -0
  447. autocoder/rag/tools/bochaai_sdk.py +541 -0
  448. autocoder/rag/tools/metaso_example.py +268 -0
  449. autocoder/rag/tools/metaso_sdk.py +417 -0
  450. autocoder/rag/tools/recall_tool.py +28 -7
  451. autocoder/rag/tools/run_integration_tests.py +204 -0
  452. autocoder/rag/tools/test_all_providers.py +318 -0
  453. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  454. autocoder/rag/tools/test_final_integration.py +215 -0
  455. autocoder/rag/tools/test_metaso_integration.py +424 -0
  456. autocoder/rag/tools/test_metaso_real.py +171 -0
  457. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  458. autocoder/rag/tools/test_web_search_tool.py +509 -0
  459. autocoder/rag/tools/todo_read_tool.py +202 -0
  460. autocoder/rag/tools/todo_write_tool.py +412 -0
  461. autocoder/rag/tools/web_crawl_tool.py +634 -0
  462. autocoder/rag/tools/web_search_tool.py +558 -0
  463. autocoder/rag/tools/web_tools_example.py +119 -0
  464. autocoder/rag/types.py +16 -0
  465. autocoder/rag/variable_holder.py +4 -2
  466. autocoder/rags.py +86 -79
  467. autocoder/regexproject/__init__.py +23 -21
  468. autocoder/sdk/__init__.py +46 -190
  469. autocoder/sdk/api.py +370 -0
  470. autocoder/sdk/async_runner/__init__.py +26 -0
  471. autocoder/sdk/async_runner/async_executor.py +650 -0
  472. autocoder/sdk/async_runner/async_handler.py +356 -0
  473. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  474. autocoder/sdk/async_runner/task_metadata.py +284 -0
  475. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  476. autocoder/sdk/cli/__init__.py +2 -5
  477. autocoder/sdk/cli/formatters.py +28 -204
  478. autocoder/sdk/cli/handlers.py +77 -44
  479. autocoder/sdk/cli/main.py +154 -171
  480. autocoder/sdk/cli/options.py +95 -22
  481. autocoder/sdk/constants.py +139 -51
  482. autocoder/sdk/core/auto_coder_core.py +484 -109
  483. autocoder/sdk/core/bridge.py +297 -115
  484. autocoder/sdk/exceptions.py +18 -12
  485. autocoder/sdk/formatters/__init__.py +19 -0
  486. autocoder/sdk/formatters/input.py +64 -0
  487. autocoder/sdk/formatters/output.py +247 -0
  488. autocoder/sdk/formatters/stream.py +54 -0
  489. autocoder/sdk/models/__init__.py +6 -5
  490. autocoder/sdk/models/options.py +55 -18
  491. autocoder/sdk/utils/formatters.py +27 -195
  492. autocoder/suffixproject/__init__.py +28 -25
  493. autocoder/terminal/__init__.py +14 -0
  494. autocoder/terminal/app.py +454 -0
  495. autocoder/terminal/args.py +32 -0
  496. autocoder/terminal/bootstrap.py +178 -0
  497. autocoder/terminal/command_processor.py +521 -0
  498. autocoder/terminal/command_registry.py +57 -0
  499. autocoder/terminal/help.py +97 -0
  500. autocoder/terminal/tasks/__init__.py +5 -0
  501. autocoder/terminal/tasks/background.py +77 -0
  502. autocoder/terminal/tasks/task_event.py +70 -0
  503. autocoder/terminal/ui/__init__.py +13 -0
  504. autocoder/terminal/ui/completer.py +268 -0
  505. autocoder/terminal/ui/keybindings.py +75 -0
  506. autocoder/terminal/ui/session.py +41 -0
  507. autocoder/terminal/ui/toolbar.py +64 -0
  508. autocoder/terminal/utils/__init__.py +13 -0
  509. autocoder/terminal/utils/errors.py +18 -0
  510. autocoder/terminal/utils/paths.py +19 -0
  511. autocoder/terminal/utils/shell.py +43 -0
  512. autocoder/terminal_v3/__init__.py +10 -0
  513. autocoder/terminal_v3/app.py +201 -0
  514. autocoder/terminal_v3/handlers/__init__.py +5 -0
  515. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  516. autocoder/terminal_v3/models/__init__.py +6 -0
  517. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  518. autocoder/terminal_v3/models/message.py +50 -0
  519. autocoder/terminal_v3/models/tool_display.py +247 -0
  520. autocoder/terminal_v3/ui/__init__.py +7 -0
  521. autocoder/terminal_v3/ui/keybindings.py +56 -0
  522. autocoder/terminal_v3/ui/layout.py +141 -0
  523. autocoder/terminal_v3/ui/styles.py +43 -0
  524. autocoder/tsproject/__init__.py +23 -23
  525. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  526. autocoder/utils/llms.py +88 -80
  527. autocoder/utils/math_utils.py +101 -0
  528. autocoder/utils/model_provider_selector.py +16 -4
  529. autocoder/utils/operate_config_api.py +33 -5
  530. autocoder/utils/thread_utils.py +2 -2
  531. autocoder/version.py +4 -2
  532. autocoder/workflow_agents/__init__.py +84 -0
  533. autocoder/workflow_agents/agent.py +143 -0
  534. autocoder/workflow_agents/exceptions.py +573 -0
  535. autocoder/workflow_agents/executor.py +489 -0
  536. autocoder/workflow_agents/loader.py +737 -0
  537. autocoder/workflow_agents/runner.py +267 -0
  538. autocoder/workflow_agents/types.py +172 -0
  539. autocoder/workflow_agents/utils.py +434 -0
  540. autocoder/workflow_agents/workflow_manager.py +211 -0
  541. auto_coder-1.0.0.dist-info/METADATA +0 -396
  542. auto_coder-1.0.0.dist-info/RECORD +0 -442
  543. auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
  544. autocoder/auto_coder_server.py +0 -672
  545. autocoder/benchmark.py +0 -138
  546. autocoder/common/ac_style_command_parser/example.py +0 -7
  547. autocoder/common/cleaner.py +0 -31
  548. autocoder/common/command_completer_v2.py +0 -615
  549. autocoder/common/context_pruner.py +0 -477
  550. autocoder/common/conversation_pruner.py +0 -132
  551. autocoder/common/directory_cache/__init__.py +0 -1
  552. autocoder/common/directory_cache/cache.py +0 -192
  553. autocoder/common/directory_cache/test_cache.py +0 -190
  554. autocoder/common/file_checkpoint/examples.py +0 -217
  555. autocoder/common/llm_friendly_package_example.py +0 -138
  556. autocoder/common/llm_friendly_package_test.py +0 -63
  557. autocoder/common/pull_requests/test_module.py +0 -1
  558. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  559. autocoder/common/text.py +0 -30
  560. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  561. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  562. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  563. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  564. autocoder/plugins/dynamic_completion_example.py +0 -148
  565. autocoder/plugins/sample_plugin.py +0 -160
  566. autocoder/sdk/cli/__main__.py +0 -26
  567. autocoder/sdk/cli/completion_wrapper.py +0 -38
  568. autocoder/sdk/cli/install_completion.py +0 -301
  569. autocoder/sdk/models/messages.py +0 -209
  570. autocoder/sdk/session/__init__.py +0 -32
  571. autocoder/sdk/session/session.py +0 -106
  572. autocoder/sdk/session/session_manager.py +0 -56
  573. {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
  574. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,342 @@
1
+ """
2
+ Java linter implementation using javac for syntax checking with dependency support.
3
+
4
+ Supports Maven, Gradle, and local JAR dependencies for accurate type checking.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import subprocess
11
+ import time
12
+ import tempfile
13
+ import json
14
+ from typing import List, Optional, Dict, Any, Union, Tuple
15
+ from pathlib import Path
16
+ from functools import lru_cache
17
+
18
+ from ..base_linter import BaseLinter
19
+ from ..models.lint_result import LintResult
20
+
21
+
22
+ class JavaLinter(BaseLinter):
23
+ """Java linter using javac with support for project dependencies."""
24
+
25
+ def __init__(self, config: Optional[Dict[str, Any]] = None):
26
+ super().__init__(config)
27
+ self.javac_args: List[str] = self.get_config_value('javac_args', [])
28
+ self.javac_timeout_secs: int = self.get_config_value('javac_timeout', 30)
29
+
30
+ # Dependency resolution configuration
31
+ self.project_type: str = self.get_config_value('project_type', 'auto') # auto/maven/gradle/local
32
+ self.source_paths: List[str] = self.get_config_value('source_paths', ['src', 'src/main/java'])
33
+ self.lib_dirs: List[str] = self.get_config_value('lib_dirs', ['lib', 'libs'])
34
+ self.enable_dependency_resolution: bool = self.get_config_value('enable_dependency_resolution', True)
35
+ self.cache_dependencies: bool = self.get_config_value('cache_dependencies', True)
36
+ self.release_version: str = self.get_config_value('release', '8') # Default to Java 8
37
+ self.use_release_flag: bool = self.get_config_value('use_release_flag', True) # Can be disabled for older javac
38
+
39
+ # Cache for resolved dependencies
40
+ self._classpath_cache: Optional[str] = None
41
+ self._project_root_cache: Optional[Path] = None
42
+
43
+ @property
44
+ def supported_extensions(self) -> List[str]:
45
+ return ['.java']
46
+
47
+ @property
48
+ def language_name(self) -> str:
49
+ return "Java"
50
+
51
+ def is_available(self) -> bool:
52
+ try:
53
+ subprocess.run(['javac', '-version'], capture_output=True, check=True, timeout=10)
54
+ return True
55
+ except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
56
+ return False
57
+
58
+ def lint_file(self, file_path: Union[str, Path]) -> LintResult:
59
+ start_time = time.time()
60
+ path = Path(file_path)
61
+ result = LintResult(
62
+ linter_name=self.name,
63
+ files_checked=[str(path)]
64
+ )
65
+
66
+ try:
67
+ # Find project root and resolve dependencies if enabled
68
+ project_root = self._find_project_root(path)
69
+ classpath = None
70
+
71
+ if self.enable_dependency_resolution and project_root:
72
+ classpath = self._resolve_classpath(project_root)
73
+ if classpath:
74
+ result.metadata['classpath_resolved'] = True
75
+ result.metadata['project_type'] = self._detect_project_type(project_root)
76
+
77
+ # Run javac for syntax checking
78
+ javac_output = self._run_javac(path, project_root, classpath)
79
+
80
+ if javac_output:
81
+ result.lint_output = f"=== javac ===\n{javac_output}"
82
+
83
+ result.metadata['tools_used'] = ['javac']
84
+ result.metadata['project_root'] = str(project_root) if project_root else None
85
+ result.success = True
86
+ except Exception as exc:
87
+ result.success = False
88
+ result.error_message = str(exc)
89
+ finally:
90
+ result.execution_time = time.time() - start_time
91
+
92
+ return result
93
+
94
+ def _find_project_root(self, file_path: Path) -> Optional[Path]:
95
+ """Find the project root directory by looking for build files."""
96
+ if self._project_root_cache and file_path.is_relative_to(self._project_root_cache):
97
+ return self._project_root_cache
98
+
99
+ current = file_path.parent
100
+ markers = ['pom.xml', 'build.gradle', 'build.gradle.kts', '.git', 'settings.gradle', 'settings.gradle.kts']
101
+
102
+ while current != current.parent:
103
+ for marker in markers:
104
+ if (current / marker).exists():
105
+ self._project_root_cache = current
106
+ return current
107
+ current = current.parent
108
+
109
+ return None
110
+
111
+ def _detect_project_type(self, project_root: Path) -> str:
112
+ """Detect the project type (maven/gradle/local)."""
113
+ if self.project_type != 'auto':
114
+ return self.project_type
115
+
116
+ if (project_root / 'pom.xml').exists():
117
+ return 'maven'
118
+ elif (project_root / 'build.gradle').exists() or (project_root / 'build.gradle.kts').exists():
119
+ return 'gradle'
120
+ else:
121
+ return 'local'
122
+
123
+ @lru_cache(maxsize=1)
124
+ def _resolve_classpath(self, project_root: Path) -> Optional[str]:
125
+ """Resolve project classpath based on project type."""
126
+ if self._classpath_cache and self.cache_dependencies:
127
+ return self._classpath_cache
128
+
129
+ project_type = self._detect_project_type(project_root)
130
+ classpath = None
131
+
132
+ if project_type == 'maven':
133
+ classpath = self._resolve_maven_classpath(project_root)
134
+ elif project_type == 'gradle':
135
+ classpath = self._resolve_gradle_classpath(project_root)
136
+
137
+ # Always check for local JARs as additional dependencies
138
+ local_jars = self._find_local_jars(project_root)
139
+ if local_jars:
140
+ if classpath:
141
+ classpath = f"{classpath}{os.pathsep}{local_jars}"
142
+ else:
143
+ classpath = local_jars
144
+
145
+ if self.cache_dependencies:
146
+ self._classpath_cache = classpath
147
+
148
+ return classpath
149
+
150
+ def _resolve_maven_classpath(self, project_root: Path) -> Optional[str]:
151
+ """Resolve Maven dependencies using mvn command."""
152
+ try:
153
+ # Create a temporary file for the classpath output
154
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp:
155
+ tmp_path = tmp.name
156
+
157
+ try:
158
+ # Run Maven to get compile classpath
159
+ cmd = [
160
+ 'mvn', '-q',
161
+ '-DincludeScope=compile',
162
+ '-Dmdep.outputFile=' + tmp_path,
163
+ 'dependency:build-classpath'
164
+ ]
165
+
166
+ result = subprocess.run(
167
+ cmd,
168
+ cwd=str(project_root),
169
+ capture_output=True,
170
+ text=True,
171
+ timeout=30
172
+ )
173
+
174
+ if result.returncode == 0 and os.path.exists(tmp_path):
175
+ with open(tmp_path, 'r') as f:
176
+ classpath = f.read().strip()
177
+ return classpath if classpath else None
178
+ finally:
179
+ # Clean up temporary file
180
+ if os.path.exists(tmp_path):
181
+ os.unlink(tmp_path)
182
+
183
+ except (subprocess.TimeoutExpired, FileNotFoundError):
184
+ pass
185
+
186
+ return None
187
+
188
+ def _resolve_gradle_classpath(self, project_root: Path) -> Optional[str]:
189
+ """Resolve Gradle dependencies using gradle/gradlew command."""
190
+ try:
191
+ # Create a temporary init script to print classpath
192
+ init_script = """
193
+ allprojects {
194
+ tasks.register("printCompileClasspath") {
195
+ doLast {
196
+ def conf = configurations.findByName("compileClasspath")
197
+ if (conf != null) {
198
+ println conf.resolve().collect{ it.absolutePath }.join(File.pathSeparator)
199
+ }
200
+ }
201
+ }
202
+ }
203
+ """
204
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.gradle', delete=False) as tmp:
205
+ tmp.write(init_script)
206
+ tmp_path = tmp.name
207
+
208
+ try:
209
+ # Prefer gradlew if available
210
+ gradle_cmd = './gradlew' if (project_root / 'gradlew').exists() else 'gradle'
211
+
212
+ cmd = [
213
+ gradle_cmd, '-q',
214
+ '-I', tmp_path,
215
+ 'printCompileClasspath'
216
+ ]
217
+
218
+ result = subprocess.run(
219
+ cmd,
220
+ cwd=str(project_root),
221
+ capture_output=True,
222
+ text=True,
223
+ timeout=30
224
+ )
225
+
226
+ if result.returncode == 0:
227
+ # Get the last line which should be the classpath
228
+ lines = result.stdout.strip().split('\n')
229
+ if lines:
230
+ classpath = lines[-1].strip()
231
+ return classpath if classpath and not classpath.startswith('BUILD') else None
232
+ finally:
233
+ # Clean up temporary file
234
+ if os.path.exists(tmp_path):
235
+ os.unlink(tmp_path)
236
+
237
+ except (subprocess.TimeoutExpired, FileNotFoundError):
238
+ pass
239
+
240
+ return None
241
+
242
+ def _find_local_jars(self, project_root: Path) -> Optional[str]:
243
+ """Find JAR files in lib directories."""
244
+ jars = []
245
+
246
+ for lib_dir in self.lib_dirs:
247
+ lib_path = project_root / lib_dir
248
+ if lib_path.exists() and lib_path.is_dir():
249
+ # Find all JAR files in the directory
250
+ jar_files = list(lib_path.glob('**/*.jar'))
251
+ jars.extend(str(jar) for jar in jar_files)
252
+
253
+ return os.pathsep.join(jars) if jars else None
254
+
255
+ def _find_source_path(self, project_root: Path) -> Optional[str]:
256
+ """Find the source path for the project."""
257
+ source_dirs = []
258
+
259
+ for source_path in self.source_paths:
260
+ full_path = project_root / source_path
261
+ if full_path.exists() and full_path.is_dir():
262
+ source_dirs.append(str(full_path))
263
+
264
+ return os.pathsep.join(source_dirs) if source_dirs else None
265
+
266
+ def _check_for_module_info(self, project_root: Path) -> bool:
267
+ """Check if the project uses JPMS (has module-info.java)."""
268
+ for source_path in self.source_paths:
269
+ module_info = project_root / source_path / 'module-info.java'
270
+ if module_info.exists():
271
+ return True
272
+ return False
273
+
274
+ def _run_javac(self, file_path: Path, project_root: Optional[Path], classpath: Optional[str]) -> str:
275
+ """Run javac with proper classpath and source path configuration."""
276
+ with tempfile.TemporaryDirectory() as temp_dir:
277
+ try:
278
+ # Try with --release flag first (if enabled)
279
+ if self.use_release_flag:
280
+ try:
281
+ return self._execute_javac_command(file_path, project_root, classpath, temp_dir, use_release=True)
282
+ except Exception as exc:
283
+ # If --release flag is not supported, retry without it
284
+ if 'invalid flag' in str(exc) or '--release' in str(exc):
285
+ return self._execute_javac_command(file_path, project_root, classpath, temp_dir, use_release=False)
286
+ else:
287
+ raise exc
288
+ else:
289
+ return self._execute_javac_command(file_path, project_root, classpath, temp_dir, use_release=False)
290
+ except subprocess.TimeoutExpired:
291
+ raise Exception('javac execution timed out')
292
+ except Exception as exc:
293
+ raise Exception(f'Error running javac: {str(exc)}')
294
+
295
+ def _execute_javac_command(self, file_path: Path, project_root: Optional[Path], classpath: Optional[str],
296
+ temp_dir: str, use_release: bool = True) -> str:
297
+ """Execute the javac command with specified parameters."""
298
+ cmd = ['javac', '-d', temp_dir]
299
+
300
+ # Add release version if supported and requested
301
+ if use_release:
302
+ cmd.extend(['--release', self.release_version])
303
+
304
+ # Add lint options
305
+ cmd.append('-Xlint:all')
306
+
307
+ # Disable annotation processing for faster checking
308
+ cmd.append('-proc:none')
309
+
310
+ # Add source path if project root is found
311
+ if project_root:
312
+ source_path = self._find_source_path(project_root)
313
+ if source_path:
314
+ cmd.extend(['--source-path', source_path])
315
+
316
+ # Add classpath or module-path
317
+ if classpath:
318
+ # Check if using JPMS
319
+ if project_root and self._check_for_module_info(project_root):
320
+ cmd.extend(['--module-path', classpath])
321
+ else:
322
+ cmd.extend(['-classpath', classpath])
323
+
324
+ # Add custom javac arguments
325
+ cmd.extend(self.javac_args)
326
+
327
+ # Add the file to compile
328
+ cmd.append(str(file_path))
329
+
330
+ completed = subprocess.run(
331
+ cmd,
332
+ capture_output=True,
333
+ text=True,
334
+ timeout=self.javac_timeout_secs
335
+ )
336
+
337
+ # Check if command failed due to invalid flag
338
+ if completed.returncode != 0 and use_release and ('invalid flag' in completed.stderr or '--release' in completed.stderr):
339
+ raise Exception(f'Invalid flag error: {completed.stderr}')
340
+
341
+ # javac outputs errors to stderr
342
+ return completed.stderr.strip()
@@ -0,0 +1,115 @@
1
+ """
2
+ Python linter implementation using flake8 and optionally mypy.
3
+
4
+ Simplified to pass raw output to formatters without parsing.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import subprocess
10
+ from typing import List, Optional, Dict, Any, Union
11
+ from pathlib import Path
12
+
13
+ from ..base_linter import BaseLinter
14
+ from ..models.lint_result import LintResult
15
+
16
+
17
+ class PythonLinter(BaseLinter):
18
+ """Python linter using flake8 (and optionally mypy) with raw output."""
19
+
20
+ def __init__(self, config: Optional[Dict[str, Any]] = None):
21
+ super().__init__(config)
22
+ self.use_mypy: bool = self.get_config_value('use_mypy', True)
23
+ self.flake8_args: List[str] = self.get_config_value('flake8_args', [])
24
+ self.mypy_args: List[str] = self.get_config_value('mypy_args', [])
25
+ self.flake8_timeout_secs: int = self.get_config_value('flake8_timeout', 30)
26
+ self.mypy_timeout_secs: int = self.get_config_value('mypy_timeout', 30)
27
+
28
+ @property
29
+ def supported_extensions(self) -> List[str]:
30
+ return ['.py', '.pyx', '.pyi']
31
+
32
+ @property
33
+ def language_name(self) -> str:
34
+ return "Python"
35
+
36
+ def is_available(self) -> bool:
37
+ try:
38
+ subprocess.run(['flake8', '--version'], capture_output=True, check=True, timeout=10)
39
+ return True
40
+ except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
41
+ return False
42
+
43
+ def _is_mypy_available(self) -> bool:
44
+ try:
45
+ subprocess.run(['mypy', '--version'], capture_output=True, check=True, timeout=10)
46
+ return True
47
+ except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
48
+ return False
49
+
50
+ def lint_file(self, file_path: Union[str, Path]) -> LintResult:
51
+ path = Path(file_path)
52
+ result = LintResult(
53
+ linter_name=self.name,
54
+ files_checked=[str(path)]
55
+ )
56
+
57
+ try:
58
+ raw_outputs: List[str] = []
59
+
60
+ # Run flake8
61
+ flake8_output = self._run_flake8(path)
62
+ if flake8_output:
63
+ raw_outputs.append(f"=== flake8 ===\n{flake8_output}")
64
+
65
+ # Run mypy if enabled and available
66
+ mypy_enabled = False
67
+ if self.use_mypy and self._is_mypy_available():
68
+ mypy_output = self._run_mypy(path)
69
+ if mypy_output:
70
+ raw_outputs.append(f"=== mypy ===\n{mypy_output}")
71
+ mypy_enabled = True
72
+
73
+ # Combine all output and create issues if there's output
74
+ if raw_outputs:
75
+ combined_output = "\n\n".join(raw_outputs)
76
+ # Use the lint_result property to maintain backward compatibility
77
+ result.lint_result = combined_output
78
+
79
+ result.metadata['mypy_enabled'] = mypy_enabled
80
+ result.metadata['tools_used'] = ['flake8'] + (['mypy'] if mypy_enabled else [])
81
+ result.success = True
82
+ except Exception as exc:
83
+ result.success = False
84
+ error_msg = f"Error: {str(exc)}"
85
+ result.error_message = error_msg
86
+ result.lint_result = error_msg # Also set for backward compatibility
87
+ result.metadata['error'] = True
88
+
89
+ return result
90
+
91
+ def _run_flake8(self, file_path: Path) -> str:
92
+ try:
93
+ cmd = ['flake8']
94
+ cmd.extend(self.flake8_args)
95
+ cmd.append(str(file_path))
96
+
97
+ completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.flake8_timeout_secs)
98
+ return completed.stdout.strip()
99
+ except subprocess.TimeoutExpired:
100
+ raise Exception('flake8 execution timed out')
101
+ except Exception as exc:
102
+ raise Exception(f'Error running flake8: {str(exc)}')
103
+
104
+ def _run_mypy(self, file_path: Path) -> str:
105
+ try:
106
+ cmd = ['mypy']
107
+ cmd.extend(self.mypy_args)
108
+ cmd.append(str(file_path))
109
+
110
+ completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.mypy_timeout_secs)
111
+ return completed.stdout.strip()
112
+ except subprocess.TimeoutExpired:
113
+ raise Exception('mypy execution timed out')
114
+ except Exception as exc:
115
+ raise Exception(f'Error running mypy: {str(exc)}')
@@ -0,0 +1,119 @@
1
+ """
2
+ TypeScript linter implementation using tsc and optionally eslint.
3
+
4
+ Simplified to pass raw output to formatters without parsing.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import subprocess
10
+ import time
11
+ from typing import List, Optional, Dict, Any, Union
12
+ from pathlib import Path
13
+
14
+ from ..base_linter import BaseLinter
15
+ from ..models.lint_result import LintResult
16
+
17
+
18
+ class TypeScriptLinter(BaseLinter):
19
+ """TypeScript linter using tsc (and optionally eslint) with raw output."""
20
+
21
+ def __init__(self, config: Optional[Dict[str, Any]] = None):
22
+ super().__init__(config)
23
+ self.use_eslint: bool = self.get_config_value('use_eslint', True)
24
+ self.tsc_args: List[str] = self.get_config_value('tsc_args', ['--noEmit', '--strict'])
25
+ self.eslint_args: List[str] = self.get_config_value('eslint_args', [])
26
+ self.tsconfig_path: Optional[str] = self.get_config_value('tsconfig_path', None)
27
+ self.tsc_timeout_secs: int = self.get_config_value('tsc_timeout', 60)
28
+ self.eslint_timeout_secs: int = self.get_config_value('eslint_timeout', 30)
29
+
30
+ @property
31
+ def supported_extensions(self) -> List[str]:
32
+ return ['.ts', '.tsx', '.js', '.jsx']
33
+
34
+ @property
35
+ def language_name(self) -> str:
36
+ return "TypeScript"
37
+
38
+ def is_available(self) -> bool:
39
+ try:
40
+ subprocess.run(['tsc', '--version'], capture_output=True, check=True, timeout=10)
41
+ return True
42
+ except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
43
+ return False
44
+
45
+ def _is_eslint_available(self) -> bool:
46
+ try:
47
+ subprocess.run(['eslint', '--version'], capture_output=True, check=True, timeout=10)
48
+ return True
49
+ except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
50
+ return False
51
+
52
+ def lint_file(self, file_path: Union[str, Path]) -> LintResult:
53
+ start_time = time.time()
54
+ path = Path(file_path)
55
+ result = LintResult(
56
+ linter_name=self.name,
57
+ files_checked=[str(path)]
58
+ )
59
+
60
+ try:
61
+ raw_outputs: List[str] = []
62
+
63
+ # Run tsc
64
+ tsc_output = self._run_tsc(path)
65
+ if tsc_output:
66
+ raw_outputs.append(f"=== tsc ===\n{tsc_output}")
67
+
68
+ # Run eslint if enabled and available
69
+ eslint_enabled = False
70
+ if self.use_eslint and self._is_eslint_available():
71
+ eslint_output = self._run_eslint(path)
72
+ if eslint_output:
73
+ raw_outputs.append(f"=== eslint ===\n{eslint_output}")
74
+ eslint_enabled = True
75
+
76
+ # Combine all output
77
+ if raw_outputs:
78
+ combined_output = "\n\n".join(raw_outputs)
79
+ result.lint_output = combined_output
80
+
81
+ result.metadata['eslint_enabled'] = eslint_enabled
82
+ result.metadata['tools_used'] = ['tsc'] + (['eslint'] if eslint_enabled else [])
83
+ result.success = True
84
+ except Exception as exc:
85
+ result.success = False
86
+ result.error_message = str(exc)
87
+ finally:
88
+ result.execution_time = time.time() - start_time
89
+
90
+ return result
91
+
92
+ def _run_tsc(self, file_path: Path) -> str:
93
+ try:
94
+ cmd = ['tsc']
95
+ if self.tsconfig_path:
96
+ cmd.extend(['--project', self.tsconfig_path])
97
+ cmd.extend(self.tsc_args)
98
+ cmd.append(str(file_path))
99
+
100
+ completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.tsc_timeout_secs)
101
+ # tsc outputs to stderr
102
+ return completed.stderr.strip()
103
+ except subprocess.TimeoutExpired:
104
+ raise Exception('tsc execution timed out')
105
+ except Exception as exc:
106
+ raise Exception(f'Error running tsc: {str(exc)}')
107
+
108
+ def _run_eslint(self, file_path: Path) -> str:
109
+ try:
110
+ cmd = ['eslint']
111
+ cmd.extend(self.eslint_args)
112
+ cmd.append(str(file_path))
113
+
114
+ completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.eslint_timeout_secs)
115
+ return completed.stdout.strip()
116
+ except subprocess.TimeoutExpired:
117
+ raise Exception('eslint execution timed out')
118
+ except Exception as exc:
119
+ raise Exception(f'Error running eslint: {str(exc)}')
@@ -0,0 +1,7 @@
1
+ """
2
+ Data models for the linter core module.
3
+ """
4
+
5
+ from .lint_result import LintResult
6
+
7
+ __all__ = ['LintResult']
@@ -0,0 +1,91 @@
1
+ """
2
+ Data models for lint results.
3
+ """
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Dict, Any, List, Optional
7
+
8
+
9
+ @dataclass
10
+ class LintResult:
11
+ """Represents the result of linting a file."""
12
+
13
+ linter_name: str
14
+ files_checked: List[str] = field(default_factory=list)
15
+ lint_output: str = "" # Raw output from linter
16
+ execution_time: float = 0.0
17
+ success: bool = True
18
+ error_message: str = ""
19
+ metadata: Dict[str, Any] = field(default_factory=dict)
20
+
21
+ # Backward compatibility properties
22
+ @property
23
+ def file_name(self) -> str:
24
+ """Get the first file name for backward compatibility."""
25
+ return self.files_checked[0] if self.files_checked else ""
26
+
27
+ @file_name.setter
28
+ def file_name(self, value: str) -> None:
29
+ """Set the file name for backward compatibility."""
30
+ if not self.files_checked:
31
+ self.files_checked = [value]
32
+ else:
33
+ self.files_checked[0] = value
34
+
35
+ @property
36
+ def lint_result(self) -> str:
37
+ """Get raw lint result for backward compatibility."""
38
+ return self.lint_output
39
+
40
+ @lint_result.setter
41
+ def lint_result(self, value: str) -> None:
42
+ """Set raw lint result for backward compatibility."""
43
+ self.lint_output = value
44
+
45
+ @property
46
+ def has_issues(self) -> bool:
47
+ """Check if the result has any issues."""
48
+ return bool(self.lint_output.strip())
49
+
50
+ def to_dict(self) -> Dict[str, Any]:
51
+ """Convert the result to a dictionary."""
52
+ result_dict = {
53
+ 'linter_name': self.linter_name,
54
+ 'files_checked': self.files_checked,
55
+ 'lint_output': self.lint_output,
56
+ 'execution_time': self.execution_time,
57
+ 'success': self.success,
58
+ 'error_message': self.error_message,
59
+ 'metadata': self.metadata
60
+ }
61
+
62
+ # Add backward compatibility fields
63
+ result_dict['file_name'] = self.file_name
64
+ result_dict['lint_result'] = self.lint_result
65
+
66
+ return result_dict
67
+
68
+ @classmethod
69
+ def from_dict(cls, data: Dict[str, Any]) -> 'LintResult':
70
+ """Create a result from a dictionary."""
71
+ # Handle backward compatibility with old format
72
+ files_checked = data.get('files_checked', [])
73
+ if not files_checked and 'file_name' in data:
74
+ files_checked = [data['file_name']]
75
+
76
+ # Handle lint_output vs lint_result
77
+ lint_output = data.get('lint_output', '')
78
+ if not lint_output and 'lint_result' in data:
79
+ lint_output = data['lint_result']
80
+
81
+ result = cls(
82
+ linter_name=data['linter_name'],
83
+ files_checked=files_checked,
84
+ lint_output=lint_output,
85
+ execution_time=data.get('execution_time', 0.0),
86
+ success=data.get('success', True),
87
+ error_message=data.get('error_message', ''),
88
+ metadata=data.get('metadata', {})
89
+ )
90
+
91
+ return result