auto-coder 1.0.0__py3-none-any.whl → 2.0.1__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.1.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.1.dist-info/METADATA +558 -0
  3. auto_coder-2.0.1.dist-info/RECORD +795 -0
  4. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
  5. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.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 +77 -73
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +962 -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 +409 -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 +316 -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 +356 -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 +1094 -0
  398. autocoder/default_project/__init__.py +501 -0
  399. autocoder/dispacher/__init__.py +4 -12
  400. autocoder/dispacher/actions/action.py +400 -129
  401. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  402. autocoder/index/entry.py +117 -125
  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 +923 -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 +665 -0
  536. autocoder/workflow_agents/loader.py +749 -0
  537. autocoder/workflow_agents/runner.py +267 -0
  538. autocoder/workflow_agents/types.py +173 -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.1.dist-info}/top_level.txt +0 -0
  574. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,216 @@
1
+ """
2
+ Factory for creating language-specific linters.
3
+ """
4
+
5
+ from typing import Dict, Optional, Type, List, Any, Union
6
+ from pathlib import Path
7
+
8
+ from .base_linter import BaseLinter
9
+ from .linters.python_linter import PythonLinter
10
+ from .linters.typescript_linter import TypeScriptLinter
11
+ from .linters.java_linter import JavaLinter
12
+
13
+
14
+ class LinterFactory:
15
+ """
16
+ Factory class for creating language-specific linters.
17
+
18
+ This factory provides methods to create linters based on file extensions,
19
+ language names, or explicit linter types.
20
+ """
21
+
22
+ # Registry of available linters
23
+ _linter_registry: Dict[str, Type[BaseLinter]] = {
24
+ 'python': PythonLinter,
25
+ 'typescript': TypeScriptLinter,
26
+ 'java': JavaLinter,
27
+ }
28
+
29
+ # Extension to language mapping
30
+ _extension_mapping: Dict[str, str] = {
31
+ '.py': 'python',
32
+ '.pyx': 'python',
33
+ '.pyi': 'python',
34
+ '.ts': 'typescript',
35
+ '.tsx': 'typescript',
36
+ '.js': 'typescript', # Treat JS as TypeScript for linting
37
+ '.jsx': 'typescript',
38
+ '.java': 'java',
39
+ }
40
+
41
+ @classmethod
42
+ def create_linter(cls, language: str, config: Optional[Dict[str, Any]] = None) -> Optional[BaseLinter]:
43
+ """
44
+ Create a linter for the specified language.
45
+
46
+ Args:
47
+ language: The programming language name (e.g., 'python', 'typescript')
48
+ config: Optional configuration dictionary for the linter
49
+
50
+ Returns:
51
+ A linter instance for the specified language, or None if not supported
52
+ """
53
+ language = language.lower()
54
+ linter_class = cls._linter_registry.get(language)
55
+
56
+ if linter_class:
57
+ return linter_class(config)
58
+
59
+ return None
60
+
61
+ @classmethod
62
+ def create_linter_for_file(cls, file_path: Union[str, Path],
63
+ config: Optional[Dict[str, Any]] = None) -> Optional[BaseLinter]:
64
+ """
65
+ Create a linter for the specified file based on its extension.
66
+
67
+ Args:
68
+ file_path: Path to the file to lint
69
+ config: Optional configuration dictionary for the linter
70
+
71
+ Returns:
72
+ A linter instance for the file's language, or None if not supported
73
+ """
74
+ file_path = Path(file_path)
75
+ extension = file_path.suffix.lower()
76
+
77
+ language = cls._extension_mapping.get(extension)
78
+ if language:
79
+ return cls.create_linter(language, config)
80
+
81
+ return None
82
+
83
+ @classmethod
84
+ def get_supported_languages(cls) -> List[str]:
85
+ """
86
+ Get a list of supported programming languages.
87
+
88
+ Returns:
89
+ List of supported language names
90
+ """
91
+ return list(cls._linter_registry.keys())
92
+
93
+ @classmethod
94
+ def get_supported_extensions(cls) -> List[str]:
95
+ """
96
+ Get a list of supported file extensions.
97
+
98
+ Returns:
99
+ List of supported file extensions
100
+ """
101
+ return list(cls._extension_mapping.keys())
102
+
103
+ @classmethod
104
+ def is_file_supported(cls, file_path: Union[str, Path]) -> bool:
105
+ """
106
+ Check if a file is supported by any available linter.
107
+
108
+ Args:
109
+ file_path: Path to the file to check
110
+
111
+ Returns:
112
+ True if the file can be linted, False otherwise
113
+ """
114
+ file_path = Path(file_path)
115
+ extension = file_path.suffix.lower()
116
+ return extension in cls._extension_mapping
117
+
118
+ @classmethod
119
+ def register_linter(cls, language: str, linter_class: Type[BaseLinter],
120
+ extensions: List[str]) -> None:
121
+ """
122
+ Register a new linter class for a language.
123
+
124
+ This allows dynamic registration of new linters without modifying the core code.
125
+
126
+ Args:
127
+ language: The programming language name
128
+ linter_class: The linter class to register
129
+ extensions: List of file extensions this linter supports
130
+ """
131
+ if not issubclass(linter_class, BaseLinter):
132
+ raise ValueError("Linter class must inherit from BaseLinter")
133
+
134
+ # Register the linter
135
+ cls._linter_registry[language.lower()] = linter_class
136
+
137
+ # Register extensions
138
+ for ext in extensions:
139
+ if not ext.startswith('.'):
140
+ ext = '.' + ext
141
+ cls._extension_mapping[ext.lower()] = language.lower()
142
+
143
+ @classmethod
144
+ def unregister_linter(cls, language: str) -> None:
145
+ """
146
+ Unregister a linter for a language.
147
+
148
+ Args:
149
+ language: The programming language name to unregister
150
+ """
151
+ language = language.lower()
152
+
153
+ # Remove from registry
154
+ if language in cls._linter_registry:
155
+ del cls._linter_registry[language]
156
+
157
+ # Remove associated extensions
158
+ extensions_to_remove = [ext for ext, lang in cls._extension_mapping.items()
159
+ if lang == language]
160
+ for ext in extensions_to_remove:
161
+ del cls._extension_mapping[ext]
162
+
163
+ @classmethod
164
+ def get_available_linters(cls) -> Dict[str, bool]:
165
+ """
166
+ Get the availability status of all registered linters.
167
+
168
+ Returns:
169
+ Dictionary mapping language names to availability status
170
+ """
171
+ availability = {}
172
+
173
+ for language, linter_class in cls._linter_registry.items():
174
+ try:
175
+ # Create a temporary instance to check availability
176
+ linter = linter_class()
177
+ availability[language] = linter.is_available()
178
+ except Exception:
179
+ availability[language] = False
180
+
181
+ return availability
182
+
183
+ @classmethod
184
+ def get_linter_info(cls, language: str) -> Optional[Dict[str, Any]]:
185
+ """
186
+ Get information about a specific linter.
187
+
188
+ Args:
189
+ language: The programming language name
190
+
191
+ Returns:
192
+ Dictionary containing linter information, or None if not found
193
+ """
194
+ language = language.lower()
195
+ linter_class = cls._linter_registry.get(language)
196
+
197
+ if not linter_class:
198
+ return None
199
+
200
+ try:
201
+ # Create a temporary instance to get information
202
+ linter = linter_class()
203
+
204
+ return {
205
+ 'language': linter.language_name,
206
+ 'class_name': linter_class.__name__,
207
+ 'supported_extensions': linter.supported_extensions,
208
+ 'is_available': linter.is_available()
209
+ }
210
+ except Exception:
211
+ return {
212
+ 'language': language,
213
+ 'class_name': linter_class.__name__,
214
+ 'supported_extensions': [],
215
+ 'is_available': False
216
+ }
@@ -0,0 +1,333 @@
1
+ """
2
+ Linter manager for coordinating multiple linters and batch operations.
3
+ """
4
+
5
+ import concurrent.futures
6
+ from typing import List, Dict, Optional, Any, Union, Callable
7
+ from pathlib import Path
8
+ import time
9
+ from collections import defaultdict
10
+
11
+ from .base_linter import BaseLinter
12
+ from .linter_factory import LinterFactory
13
+ from .models.lint_result import LintResult
14
+ from .formatters.base_formatter import BaseLintOutputFormatter
15
+ from .formatters.raw_formatter import RawLintOutputFormatter
16
+ from .config_loader import LinterConfigLoader
17
+
18
+
19
+ class LinterManager:
20
+ """
21
+ Manager class for coordinating multiple linters and handling batch operations.
22
+
23
+ This class provides high-level interfaces for linting files and directories,
24
+ managing configurations, and coordinating multiple language linters.
25
+ """
26
+
27
+ def __init__(self, config: Optional[Dict[str, Any]] = None, source_dir: Optional[str] = None):
28
+ """
29
+ Initialize the linter manager.
30
+
31
+ Args:
32
+ config: Global configuration dictionary. If None, will try to load
33
+ configuration from files in priority order:
34
+ 1. Explicit config path (if provided via config_path)
35
+ 2. Environment variable AUTOCODER_LINTER_CONFIG
36
+ 3. Project config file (.autocoderlinters/)
37
+ 4. Global user config file (~/.auto-coder/.autocoderlinters/)
38
+ 5. Default configuration
39
+ source_dir: Base directory for configuration file resolution
40
+ """
41
+ self.source_dir = source_dir or "."
42
+ self.global_config = self._load_config(config)
43
+ self.linters: Dict[str, BaseLinter] = {}
44
+ self.max_workers = self.global_config.get('max_workers', 4)
45
+ self.timeout = self.global_config.get('timeout', 300) # 5 minutes default
46
+ self.output_formatter: BaseLintOutputFormatter = self._initialize_formatter()
47
+
48
+ # Initialize available linters
49
+ self._initialize_linters()
50
+
51
+ def _load_config(self, config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
52
+ """
53
+ Load configuration from user input or configuration files.
54
+
55
+ Args:
56
+ config: User provided configuration
57
+
58
+ Returns:
59
+ Dict[str, Any]: Merged configuration
60
+ """
61
+ if config is not None:
62
+ return config
63
+
64
+ # Use the new centralized configuration loader
65
+ return LinterConfigLoader.load_manager_config(source_dir=self.source_dir)
66
+
67
+ def _initialize_linters(self) -> None:
68
+ """Initialize available linters based on the factory."""
69
+ for language in LinterFactory.get_supported_languages():
70
+ linter_config = self.global_config.get(f'{language}_config', {})
71
+ linter = LinterFactory.create_linter(language, linter_config)
72
+
73
+ if linter and linter.is_available():
74
+ self.linters[language] = linter
75
+
76
+ def _initialize_formatter(self) -> BaseLintOutputFormatter:
77
+ """Initialize manager-level formatter; default to Raw.
78
+
79
+ Manager-level formatter can be used for aggregated formatting of
80
+ multi-file results. Individual linters still own their per-result
81
+ formatting via their own configured formatter.
82
+ """
83
+ candidate = self.global_config.get('formatter') or self.global_config.get('formatter_class')
84
+ if candidate is None:
85
+ return RawLintOutputFormatter()
86
+ if isinstance(candidate, BaseLintOutputFormatter):
87
+ return candidate
88
+ try:
89
+ if issubclass(candidate, BaseLintOutputFormatter): # type: ignore[arg-type]
90
+ return candidate() # type: ignore[call-arg]
91
+ except Exception:
92
+ pass
93
+ return RawLintOutputFormatter()
94
+
95
+ def lint_file(self, file_path: Union[str, Path],
96
+ language: Optional[str] = None) -> LintResult:
97
+ """
98
+ Lint a single file.
99
+
100
+ Args:
101
+ file_path: Path to the file to lint
102
+ language: Optional language override (auto-detected if not provided)
103
+
104
+ Returns:
105
+ LintResult containing any issues found
106
+ """
107
+ file_path = Path(file_path)
108
+
109
+ if not file_path.exists():
110
+ return LintResult(
111
+ linter_name="LinterManager",
112
+ success=False,
113
+ error_message=f"File not found: {file_path}"
114
+ )
115
+
116
+ # Determine the linter to use
117
+ if language:
118
+ linter = self.linters.get(language.lower())
119
+ if not linter:
120
+ return LintResult(
121
+ linter_name="LinterManager",
122
+ success=False,
123
+ error_message=f"No available linter for language: {language}"
124
+ )
125
+ else:
126
+ linter = self._get_linter_for_file(file_path)
127
+ if not linter:
128
+ return LintResult(
129
+ linter_name="LinterManager",
130
+ success=False,
131
+ error_message=f"No available linter for file: {file_path}"
132
+ )
133
+
134
+ # Lint the file
135
+ try:
136
+ return linter.lint_file(file_path)
137
+ except Exception as e:
138
+ return LintResult(
139
+ linter_name=linter.name,
140
+ success=False,
141
+ error_message=f"Error linting file {file_path}: {str(e)}"
142
+ )
143
+
144
+ def lint_files(self, file_paths: List[Union[str, Path]],
145
+ parallel: bool = True) -> Dict[str, LintResult]:
146
+ """
147
+ Lint multiple files.
148
+
149
+ Args:
150
+ file_paths: List of file paths to lint
151
+ parallel: Whether to use parallel processing
152
+
153
+ Returns:
154
+ Dictionary mapping file paths to their lint results
155
+ """
156
+ results = {}
157
+
158
+ if parallel and len(file_paths) > 1:
159
+ # Use parallel processing
160
+ with concurrent.futures.ThreadPoolExecutor(max_workers=self.max_workers) as executor:
161
+ # Submit all tasks
162
+ future_to_file = {
163
+ executor.submit(self.lint_file, file_path): str(file_path)
164
+ for file_path in file_paths
165
+ }
166
+
167
+ # Collect results
168
+ for future in concurrent.futures.as_completed(future_to_file):
169
+ file_path = future_to_file[future]
170
+ try:
171
+ results[file_path] = future.result()
172
+ except Exception as e:
173
+ results[file_path] = LintResult(
174
+ linter_name="LinterManager",
175
+ success=False,
176
+ error_message=f"Error processing {file_path}: {str(e)}"
177
+ )
178
+ else:
179
+ # Sequential processing
180
+ for file_path in file_paths:
181
+ results[str(file_path)] = self.lint_file(file_path)
182
+
183
+ return results
184
+
185
+ def format_results(self, results: Dict[str, LintResult]) -> Dict[str, Any]:
186
+ """Format multi-file results using the manager-level formatter."""
187
+ return self.output_formatter.format_results(results)
188
+
189
+ def lint_directory(self, directory: Union[str, Path],
190
+ recursive: bool = True,
191
+ include_patterns: Optional[List[str]] = None,
192
+ exclude_patterns: Optional[List[str]] = None,
193
+ parallel: bool = True) -> Dict[str, LintResult]:
194
+ """
195
+ Lint all supported files in a directory.
196
+
197
+ Args:
198
+ directory: Directory to scan for files
199
+ recursive: Whether to scan subdirectories recursively
200
+ include_patterns: Optional list of patterns to include (glob style)
201
+ exclude_patterns: Optional list of patterns to exclude (glob style)
202
+ parallel: Whether to use parallel processing
203
+
204
+ Returns:
205
+ Dictionary mapping file paths to their lint results
206
+ """
207
+ directory = Path(directory)
208
+
209
+ if not directory.exists():
210
+ return {
211
+ str(directory): LintResult(
212
+ linter_name="LinterManager",
213
+ success=False,
214
+ error_message=f"Directory not found: {directory}"
215
+ )
216
+ }
217
+
218
+ # Find files to lint
219
+ files_to_lint = self._find_files_to_lint(
220
+ directory, recursive, include_patterns, exclude_patterns
221
+ )
222
+
223
+ # Lint the files
224
+ return self.lint_files(files_to_lint, parallel)
225
+
226
+ def get_summary_report(self, results: Dict[str, LintResult]) -> Dict[str, Any]:
227
+ """
228
+ Generate a summary report from lint results.
229
+
230
+ Args:
231
+ results: Dictionary of lint results from lint_files or lint_directory
232
+
233
+ Returns:
234
+ Summary report dictionary
235
+ """
236
+ total_files = len(results)
237
+ successful_files = sum(1 for result in results.values() if result.success)
238
+ failed_files = total_files - successful_files
239
+
240
+ # Count files with issues
241
+ files_with_issues = sum(
242
+ 1 for result in results.values()
243
+ if result.success and result.has_issues
244
+ )
245
+
246
+ # Count total issues (files with non-empty lint_output)
247
+ total_issues = sum(
248
+ 1 for result in results.values()
249
+ if result.success and result.has_issues
250
+ )
251
+
252
+ # Calculate execution time
253
+ total_execution_time = sum(
254
+ result.execution_time for result in results.values() if result.success
255
+ )
256
+
257
+ return {
258
+ 'total_files': total_files,
259
+ 'successful_files': successful_files,
260
+ 'failed_files': failed_files,
261
+ 'files_with_issues': files_with_issues,
262
+ 'total_issues': total_issues,
263
+ 'total_execution_time': total_execution_time,
264
+ 'average_execution_time': total_execution_time / max(successful_files, 1)
265
+ }
266
+
267
+
268
+
269
+ def _get_linter_for_file(self, file_path: Path) -> Optional[BaseLinter]:
270
+ """Get the appropriate linter for a file."""
271
+ if not LinterFactory.is_file_supported(file_path):
272
+ return None
273
+
274
+ # Get the language for this file extension
275
+ extension = file_path.suffix.lower()
276
+ for language, linter in self.linters.items():
277
+ if extension in linter.supported_extensions:
278
+ return linter
279
+
280
+ return None
281
+
282
+ def _find_files_to_lint(self, directory: Path, recursive: bool,
283
+ include_patterns: Optional[List[str]],
284
+ exclude_patterns: Optional[List[str]]) -> List[Path]:
285
+ """Find files to lint in a directory."""
286
+ files = []
287
+ supported_extensions = LinterFactory.get_supported_extensions()
288
+
289
+ # Get all files
290
+ if recursive:
291
+ pattern = "**/*"
292
+ else:
293
+ pattern = "*"
294
+
295
+ for file_path in directory.glob(pattern):
296
+ if not file_path.is_file():
297
+ continue
298
+
299
+ # Check if file has supported extension
300
+ if file_path.suffix.lower() not in supported_extensions:
301
+ continue
302
+
303
+ # Apply include patterns
304
+ if include_patterns:
305
+ if not any(file_path.match(pattern) for pattern in include_patterns):
306
+ continue
307
+
308
+ # Apply exclude patterns
309
+ if exclude_patterns:
310
+ if any(file_path.match(pattern) for pattern in exclude_patterns):
311
+ continue
312
+
313
+ files.append(file_path)
314
+
315
+ return files
316
+
317
+ def get_available_linters(self) -> Dict[str, bool]:
318
+ """Get information about available linters."""
319
+ return {
320
+ language: linter.is_available()
321
+ for language, linter in self.linters.items()
322
+ }
323
+
324
+ def add_linter(self, language: str, linter: BaseLinter) -> None:
325
+ """Add a custom linter to the manager."""
326
+ if linter.is_available():
327
+ self.linters[language.lower()] = linter
328
+
329
+ def remove_linter(self, language: str) -> None:
330
+ """Remove a linter from the manager."""
331
+ language = language.lower()
332
+ if language in self.linters:
333
+ del self.linters[language]
@@ -0,0 +1,9 @@
1
+ """
2
+ Language-specific linter implementations.
3
+ """
4
+
5
+ from .python_linter import PythonLinter
6
+ from .typescript_linter import TypeScriptLinter
7
+ from .java_linter import JavaLinter
8
+
9
+ __all__ = ['PythonLinter', 'TypeScriptLinter', 'JavaLinter']