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,145 @@
1
+ #!/usr/bin/env python3
2
+ """Demo script for terminal_paste module functionality.
3
+
4
+ This script demonstrates how the terminal_paste module works:
5
+ 1. Simulates paste events by saving content to files
6
+ 2. Shows placeholder resolution
7
+ 3. Demonstrates cleanup functionality
8
+ """
9
+
10
+ import os
11
+ import sys
12
+ from autocoder.common.terminal_paste import (
13
+ PasteManager,
14
+ resolve_paste_placeholders
15
+ )
16
+ from autocoder.common.terminal_paste.paste_handler import (
17
+ cleanup_old_pastes,
18
+ list_paste_files
19
+ )
20
+
21
+
22
+ def demo_basic_functionality():
23
+ """Demonstrate basic paste functionality."""
24
+ print("=== Terminal Paste Module Demo ===\n")
25
+
26
+ # Initialize paste manager
27
+ pm = PasteManager()
28
+ print(f"Paste directory: {pm.paste_dir}")
29
+
30
+ # Simulate saving some paste content
31
+ print("\n1. Saving paste content...")
32
+ content1 = """def hello_world():
33
+ print("Hello, World!")
34
+ return "success"
35
+ """
36
+
37
+ content2 = """# This is a markdown example
38
+ ## Features
39
+ - Feature 1
40
+ - Feature 2
41
+ - Feature 3
42
+ """
43
+
44
+ file_id1 = pm.save_paste(content1)
45
+ file_id2 = pm.save_paste(content2)
46
+
47
+ print(f" Saved Python code as: {file_id1}")
48
+ print(f" Saved Markdown as: {file_id2}")
49
+
50
+ # Show placeholder resolution
51
+ print("\n2. Demonstrating placeholder resolution...")
52
+ test_command = f"/coding Please review this code: [{file_id1}] and update the documentation: [{file_id2}]"
53
+ print(f" Original command: {test_command}")
54
+
55
+ resolved_command = resolve_paste_placeholders(test_command)
56
+ print(f" Resolved command: {resolved_command}")
57
+
58
+ # List all paste files
59
+ print("\n3. Listing all paste files...")
60
+ paste_files = list_paste_files()
61
+ for i, paste_file in enumerate(paste_files, 1):
62
+ print(f" {i}. {paste_file}")
63
+
64
+ # Read back content
65
+ print("\n4. Reading back content...")
66
+ read_content1 = pm.read_paste(file_id1)
67
+ print(f" Content from {file_id1}:")
68
+ if read_content1:
69
+ print(f" {repr(read_content1[:50])}...")
70
+ else:
71
+ print(" Content not found")
72
+
73
+ # Cleanup demonstration
74
+ print("\n5. Cleanup demonstration...")
75
+ print(f" Files before cleanup: {len(paste_files)}")
76
+ cleaned_count = cleanup_old_pastes(max_age_hours=0) # Clean all files
77
+ print(f" Files cleaned: {cleaned_count}")
78
+
79
+ remaining_files = list_paste_files()
80
+ print(f" Files after cleanup: {len(remaining_files)}")
81
+
82
+
83
+ def demo_error_handling():
84
+ """Demonstrate error handling."""
85
+ print("\n=== Error Handling Demo ===\n")
86
+
87
+ pm = PasteManager()
88
+
89
+ # Try to read non-existent file
90
+ print("1. Reading non-existent file...")
91
+ non_existent = pm.read_paste("pasted-nonexistent12345")
92
+ print(f" Result: {non_existent}")
93
+
94
+ # Try to resolve invalid placeholder
95
+ print("\n2. Resolving invalid placeholder...")
96
+ invalid_text = "Command with [pasted-invalidid] placeholder"
97
+ resolved = resolve_paste_placeholders(invalid_text)
98
+ print(f" Original: {invalid_text}")
99
+ print(f" Resolved: {resolved}")
100
+
101
+
102
+ def demo_integration_example():
103
+ """Show how this would integrate with chat_auto_coder.py."""
104
+ print("\n=== Integration Example ===\n")
105
+
106
+ # Simulate what happens in chat_auto_coder.py
107
+ pm = PasteManager()
108
+
109
+ # User pastes some content (simulated)
110
+ pasted_content = """SELECT users.name, COUNT(orders.id) as order_count
111
+ FROM users
112
+ LEFT JOIN orders ON users.id = orders.user_id
113
+ WHERE users.created_at > '2023-01-01'
114
+ GROUP BY users.id, users.name
115
+ ORDER BY order_count DESC;"""
116
+
117
+ # Save the paste (this would happen in the paste handler)
118
+ file_id = pm.save_paste(pasted_content)
119
+ print(f"User pastes SQL query, saved as: {file_id}")
120
+
121
+ # User types command with placeholder (what they see in terminal)
122
+ user_input = f"/coding Please optimize this SQL query: [{file_id}]"
123
+ print(f"User types: {user_input}")
124
+
125
+ # Before processing, resolve placeholders (happens in main loop)
126
+ resolved_input = resolve_paste_placeholders(user_input)
127
+ print(f"System processes: {resolved_input}")
128
+
129
+ print("\nThis way, the user sees a clean command line, but the system gets the full content!")
130
+
131
+
132
+ if __name__ == "__main__":
133
+ try:
134
+ demo_basic_functionality()
135
+ demo_error_handling()
136
+ demo_integration_example()
137
+ print("\n=== Demo Complete ===")
138
+ except KeyboardInterrupt:
139
+ print("\n\nDemo interrupted by user.")
140
+ sys.exit(0)
141
+ except Exception as e:
142
+ print(f"\nDemo failed with error: {e}")
143
+ import traceback
144
+ traceback.print_exc()
145
+ sys.exit(1)
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ 演示新的粘贴功能
4
+
5
+ 这个脚本展示了如何使用新的粘贴处理功能:
6
+ 1. Ctrl+P 粘贴多行内容并自动保存为文件
7
+ 2. 占位符自动解析为实际内容
8
+ """
9
+
10
+ import os
11
+ import tempfile
12
+ from prompt_toolkit import PromptSession
13
+ from prompt_toolkit.key_binding import KeyBindings
14
+ from prompt_toolkit.clipboard import ClipboardData
15
+ from autocoder.common.terminal_paste import register_paste_handler, resolve_paste_placeholders
16
+
17
+
18
+ def demo_paste_functionality():
19
+ """演示粘贴功能的完整流程"""
20
+ print("🎯 Terminal Paste 功能演示")
21
+ print("=" * 50)
22
+
23
+ # 创建键绑定
24
+ kb = KeyBindings()
25
+ register_paste_handler(kb)
26
+
27
+ print("✅ 粘贴处理器已注册")
28
+ print("📋 使用说明:")
29
+ print(" - 复制多行文本到剪贴板")
30
+ print(" - 按 Ctrl+P 粘贴 (多行内容会保存为文件)")
31
+ print(" - 按 Ctrl+V 正常粘贴 (单行内容)")
32
+ print(" - 输入 'quit' 退出演示")
33
+ print()
34
+
35
+ # 创建 PromptSession
36
+ session = PromptSession(
37
+ key_bindings=kb
38
+ # 注意:bracketed paste 通过 Keys.BracketedPaste 绑定处理
39
+ )
40
+
41
+ while True:
42
+ try:
43
+ # 获取用户输入
44
+ user_input = session.prompt("📝 请输入命令 (或按 Ctrl+P 粘贴): ")
45
+
46
+ if user_input.lower() in ['quit', 'exit', 'q']:
47
+ print("👋 演示结束")
48
+ break
49
+
50
+ # 解析占位符
51
+ resolved_input = resolve_paste_placeholders(user_input)
52
+
53
+ # 显示结果
54
+ if resolved_input != user_input:
55
+ print("🔄 占位符已解析:")
56
+ print(f" 原始输入: {user_input}")
57
+ print(f" 解析后: {resolved_input}")
58
+ else:
59
+ print(f"📤 您输入了: {resolved_input}")
60
+
61
+ print()
62
+
63
+ except KeyboardInterrupt:
64
+ print("\n👋 演示结束")
65
+ break
66
+ except Exception as e:
67
+ print(f"❌ 错误: {e}")
68
+
69
+
70
+ def create_sample_clipboard_content():
71
+ """创建示例剪贴板内容用于测试"""
72
+ sample_content = """def hello_world():
73
+ print("Hello, World!")
74
+ return "success"
75
+
76
+ if __name__ == "__main__":
77
+ result = hello_world()
78
+ print(f"Result: {result}")"""
79
+
80
+ print("📋 示例多行内容:")
81
+ print(sample_content)
82
+ print()
83
+ print("💡 提示: 复制上面的代码,然后在演示中按 Ctrl+P 粘贴")
84
+ print()
85
+
86
+
87
+ if __name__ == "__main__":
88
+ print("🚀 开始 Terminal Paste 功能演示")
89
+ print()
90
+
91
+ # 显示示例内容
92
+ create_sample_clipboard_content()
93
+
94
+ # 运行演示
95
+ demo_paste_functionality()
@@ -0,0 +1,200 @@
1
+ """Terminal paste event handler and placeholder resolver."""
2
+
3
+ import re
4
+ from typing import Optional, Callable
5
+ from prompt_toolkit.key_binding import KeyBindings
6
+ from prompt_toolkit.application import get_app
7
+ from prompt_toolkit.clipboard import ClipboardData
8
+ from prompt_toolkit.keys import Keys
9
+ from .paste_manager import PasteManager
10
+
11
+
12
+ # Global paste manager instance
13
+ _paste_manager: Optional[PasteManager] = None
14
+
15
+ # 占位符正则表达式,匹配 [pasted-<uuid>] 格式(32位十六进制,无连字符)
16
+ PLACEHOLDER_PATTERN = re.compile(r"\[pasted-([0-9a-f]{32})\]")
17
+
18
+
19
+ def get_paste_manager() -> PasteManager:
20
+ """Get or create global paste manager instance."""
21
+ global _paste_manager
22
+ if _paste_manager is None:
23
+ _paste_manager = PasteManager()
24
+ return _paste_manager
25
+
26
+
27
+ def register_paste_handler(kb: KeyBindings) -> None:
28
+ """Register paste handler with prompt_toolkit key bindings.
29
+
30
+ Args:
31
+ kb: KeyBindings instance to register with
32
+
33
+ Note:
34
+ This function sets up a custom paste handler that intercepts multi-line
35
+ paste operations and saves them to files with placeholder replacement.
36
+
37
+ Supports multiple paste methods:
38
+ - Bracketed paste (automatic detection of pasted content)
39
+ - Ctrl+V (standard paste shortcut)
40
+ - Ctrl+P (legacy binding)
41
+ - Cmd+V (Mac paste shortcut, mapped as Meta+V)
42
+ """
43
+
44
+ def paste_handler_impl(event):
45
+ """Handle paste operations with file saving for multi-line content."""
46
+ try:
47
+ # Get the current application
48
+ app = event.app
49
+
50
+ # Get clipboard content
51
+ clipboard_data = app.clipboard.get_data()
52
+ if not clipboard_data:
53
+ return
54
+
55
+ text = clipboard_data.text
56
+ if not text:
57
+ return
58
+
59
+ # Check if it's multi-line content (more than 1 line)
60
+ lines = text.splitlines()
61
+ if len(lines) > 1:
62
+ # Save multi-line content to file and insert placeholder
63
+ paste_manager = get_paste_manager()
64
+ file_id = paste_manager.save_paste(text)
65
+
66
+ # Create placeholder - file_id already contains "pasted-" prefix
67
+ placeholder = f"[{file_id}]"
68
+
69
+ # Insert placeholder instead of actual content
70
+ event.current_buffer.insert_text(placeholder)
71
+ else:
72
+ # For single-line content, just paste normally
73
+ event.current_buffer.insert_text(text)
74
+
75
+ except Exception as e:
76
+ print(f"\033[91m✗ Error in paste handler: {e}\033[0m")
77
+ # Fall back to normal paste behavior
78
+ try:
79
+ clipboard_data = event.app.clipboard.get_data()
80
+ if clipboard_data and clipboard_data.text:
81
+ event.current_buffer.insert_text(clipboard_data.text)
82
+ except:
83
+ pass
84
+
85
+ # Bind to bracketed paste event (most reliable for all paste operations)
86
+ @kb.add(Keys.BracketedPaste)
87
+ def bracketed_paste_handler(event):
88
+ """Handle bracketed paste events (automatic paste detection)."""
89
+ try:
90
+ # For bracketed paste, the pasted text is directly available in event.data
91
+ text = event.data
92
+ if not text:
93
+ return
94
+
95
+ # Check if it's multi-line content (more than 1 line)
96
+ lines = text.splitlines()
97
+ if len(lines) > 1:
98
+ # Save multi-line content to file and insert placeholder
99
+ paste_manager = get_paste_manager()
100
+ file_id = paste_manager.save_paste(text)
101
+
102
+ # Create placeholder - file_id already contains "pasted-" prefix
103
+ placeholder = f"[{file_id}]"
104
+
105
+ # Insert placeholder instead of actual content
106
+ event.current_buffer.insert_text(placeholder)
107
+ else:
108
+ # For single-line content, just paste normally
109
+ event.current_buffer.insert_text(text)
110
+
111
+ except Exception as e:
112
+ print(f"\033[91m✗ Error in bracketed paste handler: {e}\033[0m")
113
+ # Fall back to inserting the text directly
114
+ try:
115
+ if hasattr(event, 'data') and event.data:
116
+ event.current_buffer.insert_text(event.data)
117
+ except:
118
+ pass
119
+
120
+ # Bind to standard paste shortcuts as backup
121
+ @kb.add('c-v') # Ctrl+V (standard paste)
122
+ def ctrl_v_paste_handler(event):
123
+ """Handle Ctrl+V paste events."""
124
+ paste_handler_impl(event)
125
+
126
+ @kb.add('c-p') # Ctrl+P (legacy binding)
127
+ def ctrl_p_paste_handler(event):
128
+ """Handle Ctrl+P paste events (legacy)."""
129
+ paste_handler_impl(event)
130
+
131
+ # For Mac users: Cmd+V is often mapped as Meta+V in terminals
132
+ @kb.add('escape', 'v') # Meta+V (often mapped from Cmd+V on Mac)
133
+ def meta_v_paste_handler(event):
134
+ """Handle Meta+V paste events (Mac Cmd+V equivalent)."""
135
+ paste_handler_impl(event)
136
+
137
+
138
+ def resolve_paste_placeholders(text: str) -> str:
139
+ """Resolve paste placeholders in text to actual content.
140
+
141
+ Args:
142
+ text: Input text that may contain placeholders
143
+
144
+ Returns:
145
+ Text with placeholders replaced by actual content
146
+ """
147
+ if not text or "[pasted-" not in text:
148
+ return text
149
+
150
+ paste_manager = get_paste_manager()
151
+
152
+ def replace_placeholder(match) -> str:
153
+ """Replace a single placeholder with its content."""
154
+ uuid_part = match.group(1) # Extract UUID from [pasted-<uuid>]
155
+ file_id = f"pasted-{uuid_part}" # Reconstruct full file_id
156
+
157
+ try:
158
+ content = paste_manager.read_paste(file_id)
159
+ if content is not None:
160
+ return content
161
+ else:
162
+ # File not found, keep placeholder for debugging
163
+ print(f"\033[93m⚠ Paste file not found: {file_id}\033[0m")
164
+ return match.group(0)
165
+ except Exception as e:
166
+ print(f"\033[91m✗ Error reading paste file: {e}\033[0m")
167
+ return match.group(0)
168
+
169
+ # Replace all placeholders in the text
170
+ resolved_text = PLACEHOLDER_PATTERN.sub(replace_placeholder, text)
171
+
172
+ # Show user if any replacements were made
173
+ if resolved_text != text:
174
+ placeholder_count = len(PLACEHOLDER_PATTERN.findall(text))
175
+ print(f"\033[92m✓ Resolved {placeholder_count} paste placeholder(s)\033[0m")
176
+
177
+ return resolved_text
178
+
179
+
180
+ def cleanup_old_pastes(max_age_hours: int = 24) -> int:
181
+ """Clean up old paste files.
182
+
183
+ Args:
184
+ max_age_hours: Maximum age in hours for paste files
185
+
186
+ Returns:
187
+ Number of files cleaned up
188
+ """
189
+ paste_manager = get_paste_manager()
190
+ return paste_manager.cleanup_old_pastes(max_age_hours)
191
+
192
+
193
+ def list_paste_files() -> list[str]:
194
+ """List all paste file IDs.
195
+
196
+ Returns:
197
+ List of paste file IDs
198
+ """
199
+ paste_manager = get_paste_manager()
200
+ return paste_manager.list_pastes()
@@ -0,0 +1,118 @@
1
+ """Paste manager for handling paste file operations."""
2
+
3
+ import os
4
+ import uuid
5
+ from typing import Optional
6
+ from pathlib import Path
7
+
8
+
9
+ class PasteManager:
10
+ """Manager for handling paste file operations."""
11
+
12
+ def __init__(self, base_dir: Optional[str] = None):
13
+ """Initialize paste manager.
14
+
15
+ Args:
16
+ base_dir: Base directory for paste files. If None, uses current working directory.
17
+ """
18
+ self.base_dir = base_dir or os.getcwd()
19
+ self.paste_dir = os.path.join(self.base_dir, ".auto-coder", "pastes")
20
+ self._ensure_paste_dir()
21
+
22
+ def _ensure_paste_dir(self) -> None:
23
+ """Ensure paste directory exists."""
24
+ os.makedirs(self.paste_dir, exist_ok=True)
25
+
26
+ def save_paste(self, content: str) -> str:
27
+ """Save paste content to file and return file ID.
28
+
29
+ Args:
30
+ content: Content to save
31
+
32
+ Returns:
33
+ File ID (without path)
34
+ """
35
+ file_id = f"pasted-{uuid.uuid4().hex}"
36
+ file_path = os.path.join(self.paste_dir, file_id)
37
+
38
+ try:
39
+ with open(file_path, "w", encoding="utf-8") as f:
40
+ f.write(content)
41
+ return file_id
42
+ except Exception as e:
43
+ raise RuntimeError(f"Failed to save paste content: {e}")
44
+
45
+ def read_paste(self, file_id: str) -> Optional[str]:
46
+ """Read paste content from file.
47
+
48
+ Args:
49
+ file_id: File ID to read
50
+
51
+ Returns:
52
+ File content or None if file not found
53
+ """
54
+ # Handle both "pasted-<uuid>" and just "<uuid>" formats
55
+ if not file_id.startswith("pasted-"):
56
+ file_id = f"pasted-{file_id}"
57
+
58
+ file_path = os.path.join(self.paste_dir, file_id)
59
+
60
+ try:
61
+ with open(file_path, "r", encoding="utf-8") as f:
62
+ return f.read()
63
+ except FileNotFoundError:
64
+ return None
65
+ except Exception as e:
66
+ raise RuntimeError(f"Failed to read paste file {file_id}: {e}")
67
+
68
+ def cleanup_old_pastes(self, max_age_hours: int = 24) -> int:
69
+ """Clean up old paste files.
70
+
71
+ Args:
72
+ max_age_hours: Maximum age in hours for paste files
73
+
74
+ Returns:
75
+ Number of files cleaned up
76
+ """
77
+ import time
78
+
79
+ if not os.path.exists(self.paste_dir):
80
+ return 0
81
+
82
+ current_time = time.time()
83
+ max_age_seconds = max_age_hours * 3600
84
+ cleaned_count = 0
85
+
86
+ try:
87
+ for filename in os.listdir(self.paste_dir):
88
+ if filename.startswith("pasted-"):
89
+ file_path = os.path.join(self.paste_dir, filename)
90
+ if os.path.isfile(file_path):
91
+ file_age = current_time - os.path.getmtime(file_path)
92
+ if file_age > max_age_seconds:
93
+ os.remove(file_path)
94
+ cleaned_count += 1
95
+ except Exception as e:
96
+ raise RuntimeError(f"Failed to cleanup old pastes: {e}")
97
+
98
+ return cleaned_count
99
+
100
+ def list_pastes(self) -> list[str]:
101
+ """List all paste file IDs.
102
+
103
+ Returns:
104
+ List of paste file IDs
105
+ """
106
+ if not os.path.exists(self.paste_dir):
107
+ return []
108
+
109
+ try:
110
+ files = []
111
+ for filename in os.listdir(self.paste_dir):
112
+ if filename.startswith("pasted-") and os.path.isfile(
113
+ os.path.join(self.paste_dir, filename)
114
+ ):
115
+ files.append(filename)
116
+ return sorted(files)
117
+ except Exception as e:
118
+ raise RuntimeError(f"Failed to list paste files: {e}")
@@ -0,0 +1 @@
1
+ """Test module for terminal_paste."""