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,77 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 兼容性接口,提供与 auto_coder_runner.py 中原有函数相同的接口
4
+ """
5
+
6
+ from typing import List, Optional
7
+ from .scanner import get_project_scanner, SymbolItem
8
+
9
+
10
+ def create_scanner_functions(project_root: str,
11
+ default_exclude_dirs: Optional[List[str]] = None,
12
+ get_extra_exclude_dirs_func=None):
13
+ """
14
+ 创建与原有接口兼容的函数集合
15
+
16
+ Args:
17
+ project_root: 项目根目录
18
+ default_exclude_dirs: 默认排除目录列表
19
+ get_extra_exclude_dirs_func: 获取额外排除目录的函数
20
+
21
+ Returns:
22
+ 包含所有兼容函数的字典
23
+ """
24
+
25
+ def _get_scanner():
26
+ """获取或创建扫描器实例"""
27
+ extra_exclude_dirs = []
28
+ if get_extra_exclude_dirs_func:
29
+ extra_exclude_dirs = get_extra_exclude_dirs_func()
30
+ return get_project_scanner(project_root, default_exclude_dirs, extra_exclude_dirs)
31
+
32
+ def get_all_file_names_in_project() -> List[str]:
33
+ """获取项目中所有文件名"""
34
+ scanner = _get_scanner()
35
+ return scanner.get_all_file_names()
36
+
37
+ def get_all_file_in_project() -> List[str]:
38
+ """获取项目中所有文件的完整路径"""
39
+ scanner = _get_scanner()
40
+ return scanner.get_all_file_paths()
41
+
42
+ def get_all_file_in_project_with_dot() -> List[str]:
43
+ """获取项目中所有文件的相对路径(以./开头)"""
44
+ scanner = _get_scanner()
45
+ return scanner.get_all_file_paths_with_dot()
46
+
47
+ def get_all_dir_names_in_project() -> List[str]:
48
+ """获取项目中所有目录名"""
49
+ scanner = _get_scanner()
50
+ # 原始实现只返回目录名,不是完整路径
51
+ import os
52
+ return [os.path.basename(path) for path in scanner.get_all_dir_paths()]
53
+
54
+ def get_symbol_list() -> List[SymbolItem]:
55
+ """获取符号列表"""
56
+ scanner = _get_scanner()
57
+ return scanner.get_symbol_list()
58
+
59
+ def find_files_in_project(patterns: List[str]) -> List[str]:
60
+ """根据模式查找文件"""
61
+ scanner = _get_scanner()
62
+ return scanner.find_files(patterns)
63
+
64
+ def refresh_scanner():
65
+ """手动刷新扫描器缓存"""
66
+ scanner = _get_scanner()
67
+ scanner.refresh()
68
+
69
+ return {
70
+ 'get_all_file_names_in_project': get_all_file_names_in_project,
71
+ 'get_all_file_in_project': get_all_file_in_project,
72
+ 'get_all_file_in_project_with_dot': get_all_file_in_project_with_dot,
73
+ 'get_all_dir_names_in_project': get_all_dir_names_in_project,
74
+ 'get_symbol_list': get_symbol_list,
75
+ 'find_files_in_project': find_files_in_project,
76
+ 'refresh_scanner': refresh_scanner
77
+ }
@@ -0,0 +1,436 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Project Scanner Module
4
+
5
+ 提供项目文件和目录扫描功能,支持文件监控和忽略规则。
6
+ """
7
+
8
+ import os
9
+ import json
10
+ import threading
11
+ import queue
12
+ import time
13
+ from pathlib import Path
14
+ from typing import List, Dict, Optional, Set, Any
15
+ from dataclasses import dataclass, field
16
+ from loguru import logger
17
+
18
+ from autocoder.common.file_monitor import FileMonitor
19
+ from autocoder.common.file_monitor.monitor import Change
20
+ from autocoder.common.ignorefiles import should_ignore
21
+ from autocoder.index.symbols_utils import extract_symbols, SymbolType
22
+
23
+
24
+ @dataclass
25
+ class SymbolItem:
26
+ """符号信息数据类"""
27
+ symbol_name: str
28
+ symbol_type: SymbolType
29
+ file_name: str
30
+
31
+
32
+ @dataclass
33
+ class ScanResult:
34
+ """扫描结果数据类"""
35
+ file_names: List[str] = field(default_factory=list)
36
+ file_paths: List[str] = field(default_factory=list)
37
+ file_paths_with_dot: List[str] = field(default_factory=list)
38
+ dir_paths: List[str] = field(default_factory=list)
39
+ symbols: List[SymbolItem] = field(default_factory=list)
40
+
41
+
42
+ class ProjectScanner:
43
+ """
44
+ 项目扫描器,提供文件和目录扫描功能。
45
+
46
+ 特性:
47
+ - 单例模式确保全局唯一实例
48
+ - 自动监控文件变化并更新缓存
49
+ - 集成忽略规则过滤
50
+ - 线程安全的缓存访问
51
+ """
52
+
53
+ _instance = None
54
+ _instance_lock = threading.Lock()
55
+
56
+ def __new__(cls, project_root: Optional[str] = None,
57
+ default_exclude_dirs: Optional[List[str]] = None,
58
+ extra_exclude_dirs: Optional[List[str]] = None):
59
+ """实现单例模式"""
60
+ with cls._instance_lock:
61
+ if cls._instance is None:
62
+ if project_root is None:
63
+ raise ValueError("First initialization requires project_root")
64
+ cls._instance = super(ProjectScanner, cls).__new__(cls)
65
+ cls._instance._initialized = False
66
+ elif project_root and cls._instance._project_root != os.path.abspath(project_root):
67
+ logger.warning(f"ProjectScanner already initialized with {cls._instance._project_root}")
68
+ return cls._instance
69
+
70
+ def __init__(self, project_root: str,
71
+ default_exclude_dirs: Optional[List[str]] = None,
72
+ extra_exclude_dirs: Optional[List[str]] = None):
73
+ """初始化扫描器"""
74
+ if hasattr(self, '_initialized') and self._initialized:
75
+ if set(extra_exclude_dirs) != set(self._extra_exclude_dirs):
76
+ self._extra_exclude_dirs = extra_exclude_dirs
77
+ self._scan_project()
78
+ else:
79
+ self._extra_exclude_dirs = extra_exclude_dirs
80
+ return
81
+
82
+ self._project_root = os.path.abspath(project_root)
83
+ self._default_exclude_dirs = default_exclude_dirs or [
84
+ ".git", "node_modules", "dist", "build", "__pycache__", ".auto-coder"
85
+ ]
86
+ self._extra_exclude_dirs = extra_exclude_dirs or []
87
+
88
+ # 缓存扫描结果
89
+ self._cache = ScanResult()
90
+ self._cache_lock = threading.RLock()
91
+
92
+ # 扫描任务队列管理
93
+ self._scan_queue = queue.Queue()
94
+ self._scan_thread_running = False
95
+ self._scan_thread_lock = threading.Lock()
96
+ self._scan_worker_thread = None
97
+
98
+ # 文件监控器
99
+ self._file_monitor = None
100
+ self._setup_file_monitor()
101
+
102
+ # 初始扫描
103
+ self._scan_project()
104
+
105
+ # 启动扫描任务处理线程
106
+ self._start_scan_worker()
107
+
108
+ self._initialized = True
109
+ logger.info(f"ProjectScanner initialized for {self._project_root}")
110
+
111
+ @classmethod
112
+ def get_instance(cls) -> Optional['ProjectScanner']:
113
+ """获取单例实例"""
114
+ return cls._instance
115
+
116
+ @classmethod
117
+ def reset_instance(cls):
118
+ """重置单例实例"""
119
+ with cls._instance_lock:
120
+ if cls._instance is not None:
121
+ # 停止扫描工作线程
122
+ if hasattr(cls._instance, '_scan_thread_running'):
123
+ cls._instance._scan_thread_running = False
124
+ if hasattr(cls._instance, '_scan_worker_thread') and cls._instance._scan_worker_thread:
125
+ try:
126
+ # 等待工作线程结束,最多等待3秒
127
+ cls._instance._scan_worker_thread.join(timeout=3.0)
128
+ except:
129
+ pass
130
+ # 清空队列
131
+ if hasattr(cls._instance, '_scan_queue'):
132
+ try:
133
+ while not cls._instance._scan_queue.empty():
134
+ cls._instance._scan_queue.get_nowait()
135
+ cls._instance._scan_queue.task_done()
136
+ except:
137
+ pass
138
+
139
+ # 停止文件监控
140
+ if cls._instance._file_monitor:
141
+ try:
142
+ cls._instance._file_monitor.stop()
143
+ except:
144
+ pass
145
+ cls._instance = None
146
+ logger.info("ProjectScanner singleton reset")
147
+
148
+ def _setup_file_monitor(self):
149
+ """设置文件监控"""
150
+ try:
151
+ self._file_monitor = FileMonitor(self._project_root)
152
+ # 监控整个项目目录
153
+ self._file_monitor.register(self._project_root, self._on_file_changed)
154
+ # 监控符号索引文件
155
+ index_file = os.path.join(self._project_root, ".auto-coder", "index.json")
156
+ if os.path.exists(os.path.dirname(index_file)):
157
+ self._file_monitor.register(index_file, self._on_index_changed)
158
+
159
+ # 启动监控
160
+ if not self._file_monitor.is_running():
161
+ self._file_monitor.start()
162
+ logger.info("File monitoring started for project scanner")
163
+ except Exception as e:
164
+ logger.error(f"Failed to setup file monitor: {e}")
165
+
166
+ def _start_scan_worker(self):
167
+ """启动扫描任务工作线程"""
168
+ with self._scan_thread_lock:
169
+ if not self._scan_thread_running:
170
+ self._scan_thread_running = True
171
+ self._scan_worker_thread = threading.Thread(
172
+ target=self._scan_worker,
173
+ daemon=True,
174
+ name="ProjectScanner-Worker"
175
+ )
176
+ self._scan_worker_thread.start()
177
+ logger.debug("Scan worker thread started")
178
+
179
+ def _scan_worker(self):
180
+ """扫描任务工作线程主循环"""
181
+ while self._scan_thread_running:
182
+ try:
183
+ # 阻塞等待任务,超时1秒检查是否需要停止
184
+ task = self._scan_queue.get(timeout=1.0)
185
+
186
+ # 清空队列中的其他待处理任务,只处理最新的
187
+ latest_task = task
188
+ while True:
189
+ try:
190
+ # 非阻塞获取,如果没有更多任务则跳出循环
191
+ latest_task = self._scan_queue.get_nowait()
192
+ # 标记之前的任务为完成(虽然没有实际执行)
193
+ self._scan_queue.task_done()
194
+ except queue.Empty:
195
+ break
196
+
197
+ # 执行最新的扫描任务
198
+ logger.debug("Executing scan task")
199
+ if latest_task == "scan_project":
200
+ self._scan_project()
201
+ elif latest_task == "scan_symbols":
202
+ self._load_symbols()
203
+
204
+ # 标记任务完成
205
+ self._scan_queue.task_done()
206
+
207
+ except queue.Empty:
208
+ # 超时,继续循环检查是否需要停止
209
+ continue
210
+ except Exception as e:
211
+ logger.error(f"Error in scan worker: {e}")
212
+ # 继续运行,不要因为单个错误而停止工作线程
213
+ continue
214
+
215
+ def _schedule_scan(self, task_type: str = "scan_project"):
216
+ """将扫描任务添加到队列"""
217
+ try:
218
+ # 非阻塞添加任务,如果队列满了会抛出异常
219
+ self._scan_queue.put_nowait(task_type)
220
+ logger.debug(f"Scheduled scan task: {task_type}")
221
+ except queue.Full:
222
+ logger.warning("Scan queue is full, dropping task")
223
+
224
+ def _on_file_changed(self, change_type: Change, changed_path: str):
225
+ """文件变化回调"""
226
+ # 检查是否需要更新缓存
227
+ need_update = False
228
+
229
+ if change_type == Change.added:
230
+ # 新增文件/目录
231
+ if not self._should_ignore(changed_path):
232
+ need_update = True
233
+ elif change_type == Change.deleted:
234
+ # 删除文件/目录
235
+ with self._cache_lock:
236
+ abs_path = os.path.abspath(changed_path)
237
+ if abs_path in self._cache.file_paths:
238
+ need_update = True
239
+ elif abs_path in self._cache.dir_paths:
240
+ need_update = True
241
+ elif change_type == Change.modified:
242
+ # 文件修改通常不需要重新扫描,除非是目录结构变化
243
+ pass
244
+
245
+ if need_update:
246
+ logger.debug(f"Project structure changed: {change_type.name} - {changed_path}")
247
+ # 将扫描任务添加到队列,避免阻塞文件监控
248
+ self._schedule_scan("scan_project")
249
+
250
+ def _on_index_changed(self, change_type: Change, changed_path: str):
251
+ """索引文件变化回调"""
252
+ if change_type in [Change.added, Change.modified]:
253
+ logger.debug("Symbol index changed, reloading symbols")
254
+ self._schedule_scan("scan_symbols")
255
+
256
+ def _should_ignore(self, path: str) -> bool:
257
+ """检查路径是否应被忽略"""
258
+ # 使用 ignorefiles 模块的规则
259
+ if should_ignore(path, self._project_root):
260
+ return True
261
+
262
+ # 检查默认和额外的排除目录
263
+ all_exclude_dirs = self._default_exclude_dirs + self._extra_exclude_dirs
264
+ abs_path = os.path.abspath(path)
265
+
266
+ for exclude_dir in all_exclude_dirs:
267
+ # 检查路径是否包含排除的目录名
268
+ parts = abs_path.split(os.sep)
269
+ if exclude_dir in parts:
270
+ return True
271
+
272
+ return False
273
+
274
+ def _scan_project(self):
275
+ """扫描整个项目"""
276
+ new_cache = ScanResult()
277
+
278
+ try:
279
+ for root, dirs, files in os.walk(self._project_root, followlinks=True):
280
+ # 过滤目录
281
+ dirs[:] = [d for d in dirs if not self._should_ignore(os.path.join(root, d))]
282
+
283
+ # 收集目录路径
284
+ for dir_name in dirs:
285
+ dir_path = os.path.join(root, dir_name)
286
+ if not self._should_ignore(dir_path):
287
+ new_cache.dir_paths.append(dir_path)
288
+
289
+ # 收集文件
290
+ for file_name in files:
291
+ file_path = os.path.join(root, file_name)
292
+ if not self._should_ignore(file_path):
293
+ new_cache.file_names.append(file_name)
294
+ new_cache.file_paths.append(file_path)
295
+ # 相对路径(以.开头)
296
+ rel_path = os.path.relpath(file_path, self._project_root)
297
+ new_cache.file_paths_with_dot.append(f"./{rel_path}")
298
+
299
+ # 加载符号信息
300
+ self._load_symbols_to_cache(new_cache)
301
+
302
+ # 更新缓存
303
+ with self._cache_lock:
304
+ self._cache = new_cache
305
+
306
+ except Exception as e:
307
+ logger.error(f"Error during project scan: {e}")
308
+
309
+ def _load_symbols(self):
310
+ """仅重新加载符号信息"""
311
+ with self._cache_lock:
312
+ self._load_symbols_to_cache(self._cache)
313
+
314
+ def _load_symbols_to_cache(self, cache: ScanResult):
315
+ """加载符号信息到缓存"""
316
+ cache.symbols.clear()
317
+
318
+ index_file = os.path.join(self._project_root, ".auto-coder", "index.json")
319
+ if not os.path.exists(index_file):
320
+ return
321
+
322
+ try:
323
+ with open(index_file, "r", encoding="utf-8") as f:
324
+ index_data = json.load(f)
325
+
326
+ for item in index_data.values():
327
+ symbols_str = item.get("symbols", "")
328
+ module_name = item.get("module_name", "")
329
+
330
+ if not symbols_str or not module_name:
331
+ continue
332
+
333
+ info = extract_symbols(symbols_str)
334
+
335
+ # 添加类符号
336
+ for name in info.classes:
337
+ cache.symbols.append(SymbolItem(
338
+ symbol_name=name,
339
+ symbol_type=SymbolType.CLASSES,
340
+ file_name=module_name
341
+ ))
342
+
343
+ # 添加函数符号
344
+ for name in info.functions:
345
+ cache.symbols.append(SymbolItem(
346
+ symbol_name=name,
347
+ symbol_type=SymbolType.FUNCTIONS,
348
+ file_name=module_name
349
+ ))
350
+
351
+ # 添加变量符号
352
+ for name in info.variables:
353
+ cache.symbols.append(SymbolItem(
354
+ symbol_name=name,
355
+ symbol_type=SymbolType.VARIABLES,
356
+ file_name=module_name
357
+ ))
358
+
359
+ except Exception as e:
360
+ logger.error(f"Error loading symbols: {e}")
361
+
362
+ def refresh(self):
363
+ """手动刷新扫描结果"""
364
+ self._schedule_scan("scan_project")
365
+
366
+ def update_extra_exclude_dirs(self, extra_exclude_dirs: List[str]):
367
+ """更新额外的排除目录"""
368
+ self._extra_exclude_dirs = extra_exclude_dirs
369
+ self._schedule_scan("scan_project")
370
+
371
+ # 公共接口方法
372
+ def get_all_file_names(self) -> List[str]:
373
+ """获取所有文件名(不含路径)"""
374
+ with self._cache_lock:
375
+ return self._cache.file_names.copy()
376
+
377
+ def get_all_file_paths(self) -> List[str]:
378
+ """获取所有文件的绝对路径"""
379
+ with self._cache_lock:
380
+ return self._cache.file_paths.copy()
381
+
382
+ def get_all_file_paths_with_dot(self) -> List[str]:
383
+ """获取所有文件的相对路径(以./开头)"""
384
+ with self._cache_lock:
385
+ return self._cache.file_paths_with_dot.copy()
386
+
387
+ def get_all_dir_paths(self) -> List[str]:
388
+ """获取所有目录的绝对路径"""
389
+ with self._cache_lock:
390
+ return self._cache.dir_paths.copy()
391
+
392
+ def get_symbol_list(self) -> List[SymbolItem]:
393
+ """获取符号列表"""
394
+ with self._cache_lock:
395
+ return self._cache.symbols.copy()
396
+
397
+ def find_files(self, patterns: List[str]) -> List[str]:
398
+ """根据模式查找文件"""
399
+ import glob
400
+ import fnmatch
401
+
402
+ matched_files = []
403
+
404
+ for pattern in patterns:
405
+ if "*" in pattern or "?" in pattern:
406
+ # 使用 glob 匹配
407
+ for file_path in glob.glob(pattern, recursive=True):
408
+ if os.path.isfile(file_path):
409
+ abs_path = os.path.abspath(file_path)
410
+ if not self._should_ignore(abs_path):
411
+ matched_files.append(abs_path)
412
+ else:
413
+ # 精确匹配或部分匹配
414
+ pattern_abs = os.path.abspath(pattern)
415
+ found = False
416
+
417
+ with self._cache_lock:
418
+ # 检查文件名匹配
419
+ for file_path in self._cache.file_paths:
420
+ file_name = os.path.basename(file_path)
421
+ if pattern == file_name or pattern_abs == file_path or pattern in file_path:
422
+ matched_files.append(file_path)
423
+ found = True
424
+
425
+ # 如果在项目内没找到,检查是否是外部文件
426
+ if not found and os.path.exists(pattern):
427
+ matched_files.append(os.path.abspath(pattern))
428
+
429
+ return list(set(matched_files)) # 去重
430
+
431
+
432
+ def get_project_scanner(project_root: str,
433
+ default_exclude_dirs: Optional[List[str]] = None,
434
+ extra_exclude_dirs: Optional[List[str]] = None) -> ProjectScanner:
435
+ """获取项目扫描器实例"""
436
+ return ProjectScanner(project_root, default_exclude_dirs, extra_exclude_dirs)
@@ -0,0 +1,27 @@
1
+ """
2
+ Project Tracker Module
3
+
4
+ A comprehensive project exploration and tracking system that uses AgenticEdit to analyze
5
+ AC modules and provide intelligent project insights for faster development workflows.
6
+ """
7
+
8
+ from .tracker import ProjectTracker
9
+ from .api import ProjectTrackerAPI, get_basic_project_info
10
+ from .types import (
11
+ ProjectTrackerRequest,
12
+ ProjectTrackerResponse,
13
+ ExplorationResult,
14
+ ModuleInfo,
15
+ ExplorationMode
16
+ )
17
+
18
+ __all__ = [
19
+ "ProjectTracker",
20
+ "ProjectTrackerAPI",
21
+ "ProjectTrackerRequest",
22
+ "ProjectTrackerResponse",
23
+ "ExplorationResult",
24
+ "ModuleInfo",
25
+ "ExplorationMode",
26
+ "get_basic_project_info"
27
+ ]