auto-coder 1.0.0__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- auto_coder-2.0.0.dist-info/LICENSE +158 -0
- auto_coder-2.0.0.dist-info/METADATA +558 -0
- auto_coder-2.0.0.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
- autocoder/__init__.py +31 -0
- autocoder/agent/auto_filegroup.py +32 -13
- autocoder/agent/auto_learn_from_commit.py +9 -1
- autocoder/agent/base_agentic/__init__.py +3 -0
- autocoder/agent/base_agentic/agent_hub.py +1 -1
- autocoder/agent/base_agentic/base_agent.py +235 -136
- autocoder/agent/base_agentic/default_tools.py +119 -118
- autocoder/agent/base_agentic/test_base_agent.py +1 -1
- autocoder/agent/base_agentic/tool_registry.py +32 -20
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
- autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
- autocoder/agent/base_agentic/types.py +42 -0
- autocoder/agent/entry_command_agent/chat.py +73 -59
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +970 -2345
- autocoder/auto_coder_terminal.py +26 -0
- autocoder/auto_coder_terminal_v3.py +190 -0
- autocoder/chat/conf_command.py +224 -124
- autocoder/chat/models_command.py +361 -299
- autocoder/chat/rules_command.py +79 -31
- autocoder/chat_auto_coder.py +988 -398
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +25 -8
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +44 -44
- autocoder/common/__init__.py +150 -128
- autocoder/common/ac_style_command_parser/__init__.py +39 -2
- autocoder/common/ac_style_command_parser/config.py +422 -0
- autocoder/common/ac_style_command_parser/parser.py +292 -78
- autocoder/common/ac_style_command_parser/test_parser.py +241 -16
- autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
- autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
- autocoder/common/action_yml_file_manager.py +25 -13
- autocoder/common/agent_events/__init__.py +52 -0
- autocoder/common/agent_events/agent_event_emitter.py +193 -0
- autocoder/common/agent_events/event_factory.py +177 -0
- autocoder/common/agent_events/examples.py +307 -0
- autocoder/common/agent_events/types.py +113 -0
- autocoder/common/agent_events/utils.py +68 -0
- autocoder/common/agent_hooks/__init__.py +44 -0
- autocoder/common/agent_hooks/examples.py +582 -0
- autocoder/common/agent_hooks/hook_executor.py +217 -0
- autocoder/common/agent_hooks/hook_manager.py +288 -0
- autocoder/common/agent_hooks/types.py +133 -0
- autocoder/common/agent_hooks/utils.py +99 -0
- autocoder/common/agent_query_queue/queue_executor.py +324 -0
- autocoder/common/agent_query_queue/queue_manager.py +325 -0
- autocoder/common/agents/__init__.py +11 -0
- autocoder/common/agents/agent_manager.py +323 -0
- autocoder/common/agents/agent_parser.py +189 -0
- autocoder/common/agents/example_usage.py +344 -0
- autocoder/common/agents/integration_example.py +330 -0
- autocoder/common/agents/test_agent_parser.py +545 -0
- autocoder/common/async_utils.py +101 -0
- autocoder/common/auto_coder_lang.py +23 -972
- autocoder/common/autocoderargs_parser/__init__.py +14 -0
- autocoder/common/autocoderargs_parser/parser.py +184 -0
- autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
- autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
- autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
- autocoder/common/autocoderargs_parser/token_parser.py +290 -0
- autocoder/common/buildin_tokenizer.py +2 -4
- autocoder/common/code_auto_generate.py +149 -74
- autocoder/common/code_auto_generate_diff.py +163 -70
- autocoder/common/code_auto_generate_editblock.py +179 -89
- autocoder/common/code_auto_generate_strict_diff.py +167 -72
- autocoder/common/code_auto_merge_editblock.py +13 -6
- autocoder/common/code_modification_ranker.py +1 -1
- autocoder/common/command_completer.py +3 -3
- autocoder/common/command_file_manager/manager.py +183 -47
- autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
- autocoder/common/command_templates.py +1 -1
- autocoder/common/conf_utils.py +2 -4
- autocoder/common/conversations/config.py +11 -3
- autocoder/common/conversations/get_conversation_manager.py +100 -2
- autocoder/common/conversations/llm_stats_models.py +264 -0
- autocoder/common/conversations/manager.py +112 -28
- autocoder/common/conversations/models.py +16 -2
- autocoder/common/conversations/storage/index_manager.py +134 -10
- autocoder/common/core_config/__init__.py +63 -0
- autocoder/common/core_config/agentic_mode_manager.py +109 -0
- autocoder/common/core_config/base_manager.py +123 -0
- autocoder/common/core_config/compatibility.py +151 -0
- autocoder/common/core_config/config_manager.py +156 -0
- autocoder/common/core_config/conversation_manager.py +31 -0
- autocoder/common/core_config/exclude_manager.py +72 -0
- autocoder/common/core_config/file_manager.py +177 -0
- autocoder/common/core_config/human_as_model_manager.py +129 -0
- autocoder/common/core_config/lib_manager.py +54 -0
- autocoder/common/core_config/main_manager.py +81 -0
- autocoder/common/core_config/mode_manager.py +126 -0
- autocoder/common/core_config/models.py +70 -0
- autocoder/common/core_config/test_memory_manager.py +1056 -0
- autocoder/common/env_manager.py +282 -0
- autocoder/common/env_manager_usage_example.py +211 -0
- autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
- autocoder/common/file_checkpoint/manager.py +264 -48
- autocoder/common/file_checkpoint/test_backup.py +1 -18
- autocoder/common/file_checkpoint/test_manager.py +270 -1
- autocoder/common/file_checkpoint/test_store.py +1 -17
- autocoder/common/file_handler/__init__.py +23 -0
- autocoder/common/file_handler/active_context_handler.py +159 -0
- autocoder/common/file_handler/add_files_handler.py +409 -0
- autocoder/common/file_handler/chat_handler.py +180 -0
- autocoder/common/file_handler/coding_handler.py +401 -0
- autocoder/common/file_handler/commit_handler.py +200 -0
- autocoder/common/file_handler/lib_handler.py +156 -0
- autocoder/common/file_handler/list_files_handler.py +111 -0
- autocoder/common/file_handler/mcp_handler.py +268 -0
- autocoder/common/file_handler/models_handler.py +493 -0
- autocoder/common/file_handler/remove_files_handler.py +172 -0
- autocoder/common/git_utils.py +44 -8
- autocoder/common/global_cancel.py +15 -6
- autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
- autocoder/common/international/__init__.py +31 -0
- autocoder/common/international/demo_international.py +92 -0
- autocoder/common/international/message_manager.py +157 -0
- autocoder/common/international/messages/__init__.py +56 -0
- autocoder/common/international/messages/async_command_messages.py +507 -0
- autocoder/common/international/messages/auto_coder_messages.py +2208 -0
- autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
- autocoder/common/international/messages/command_help_messages.py +986 -0
- autocoder/common/international/messages/conversation_command_messages.py +191 -0
- autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
- autocoder/common/international/messages/queue_command_messages.py +751 -0
- autocoder/common/international/messages/rules_command_messages.py +77 -0
- autocoder/common/international/messages/sdk_messages.py +1707 -0
- autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
- autocoder/common/international/messages/tool_display_messages.py +1212 -0
- autocoder/common/international/messages/workflow_exception_messages.py +473 -0
- autocoder/common/international/test_international.py +612 -0
- autocoder/common/linter_core/__init__.py +28 -0
- autocoder/common/linter_core/base_linter.py +61 -0
- autocoder/common/linter_core/config_loader.py +271 -0
- autocoder/common/linter_core/formatters/__init__.py +0 -0
- autocoder/common/linter_core/formatters/base_formatter.py +38 -0
- autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
- autocoder/common/linter_core/linter.py +166 -0
- autocoder/common/linter_core/linter_factory.py +216 -0
- autocoder/common/linter_core/linter_manager.py +333 -0
- autocoder/common/linter_core/linters/__init__.py +9 -0
- autocoder/common/linter_core/linters/java_linter.py +342 -0
- autocoder/common/linter_core/linters/python_linter.py +115 -0
- autocoder/common/linter_core/linters/typescript_linter.py +119 -0
- autocoder/common/linter_core/models/__init__.py +7 -0
- autocoder/common/linter_core/models/lint_result.py +91 -0
- autocoder/common/linter_core/models.py +33 -0
- autocoder/common/linter_core/tests/__init__.py +3 -0
- autocoder/common/linter_core/tests/test_config_loader.py +323 -0
- autocoder/common/linter_core/tests/test_config_loading.py +308 -0
- autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
- autocoder/common/linter_core/tests/test_formatters.py +147 -0
- autocoder/common/linter_core/tests/test_integration.py +317 -0
- autocoder/common/linter_core/tests/test_java_linter.py +496 -0
- autocoder/common/linter_core/tests/test_linters.py +265 -0
- autocoder/common/linter_core/tests/test_models.py +81 -0
- autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
- autocoder/common/linter_core/tests/verify_fixes.py +183 -0
- autocoder/common/llm_friendly_package/__init__.py +31 -0
- autocoder/common/llm_friendly_package/base_manager.py +102 -0
- autocoder/common/llm_friendly_package/docs_manager.py +121 -0
- autocoder/common/llm_friendly_package/library_manager.py +171 -0
- autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
- autocoder/common/llm_friendly_package/models.py +40 -0
- autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
- autocoder/common/llms/__init__.py +15 -0
- autocoder/common/llms/demo_error_handling.py +85 -0
- autocoder/common/llms/factory.py +142 -0
- autocoder/common/llms/manager.py +264 -0
- autocoder/common/llms/pricing.py +121 -0
- autocoder/common/llms/registry.py +288 -0
- autocoder/common/llms/schema.py +77 -0
- autocoder/common/llms/simple_demo.py +45 -0
- autocoder/common/llms/test_quick_model.py +116 -0
- autocoder/common/llms/test_remove_functionality.py +182 -0
- autocoder/common/llms/tests/__init__.py +1 -0
- autocoder/common/llms/tests/test_manager.py +330 -0
- autocoder/common/llms/tests/test_registry.py +364 -0
- autocoder/common/mcp_tools/__init__.py +62 -0
- autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
- autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
- autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
- autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
- autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
- autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
- autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
- autocoder/common/mcp_tools/verify_functionality.py +202 -0
- autocoder/common/model_speed_tester.py +32 -26
- autocoder/common/priority_directory_finder/__init__.py +142 -0
- autocoder/common/priority_directory_finder/examples.py +230 -0
- autocoder/common/priority_directory_finder/finder.py +283 -0
- autocoder/common/priority_directory_finder/models.py +236 -0
- autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
- autocoder/common/project_scanner/__init__.py +18 -0
- autocoder/common/project_scanner/compat.py +77 -0
- autocoder/common/project_scanner/scanner.py +436 -0
- autocoder/common/project_tracker/__init__.py +27 -0
- autocoder/common/project_tracker/api.py +228 -0
- autocoder/common/project_tracker/demo.py +272 -0
- autocoder/common/project_tracker/tracker.py +487 -0
- autocoder/common/project_tracker/types.py +53 -0
- autocoder/common/pruner/__init__.py +67 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
- autocoder/common/pruner/conversation_message_ids_api.py +386 -0
- autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
- autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
- autocoder/common/pruner/conversation_normalizer.py +347 -0
- autocoder/common/pruner/conversation_pruner.py +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
- autocoder/common/pruner/test_conversation_normalizer.py +502 -0
- autocoder/common/pruner/test_tool_content_detector.py +324 -0
- autocoder/common/pruner/tool_content_detector.py +227 -0
- autocoder/common/pruner/tools/__init__.py +18 -0
- autocoder/common/pruner/tools/query_message_ids.py +264 -0
- autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
- autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
- autocoder/common/pull_requests/__init__.py +9 -1
- autocoder/common/pull_requests/utils.py +122 -1
- autocoder/common/rag_manager/rag_manager.py +36 -40
- autocoder/common/rulefiles/__init__.py +53 -1
- autocoder/common/rulefiles/api.py +250 -0
- autocoder/common/rulefiles/core/__init__.py +14 -0
- autocoder/common/rulefiles/core/manager.py +241 -0
- autocoder/common/rulefiles/core/selector.py +805 -0
- autocoder/common/rulefiles/models/__init__.py +20 -0
- autocoder/common/rulefiles/models/index.py +16 -0
- autocoder/common/rulefiles/models/init_rule.py +18 -0
- autocoder/common/rulefiles/models/rule_file.py +18 -0
- autocoder/common/rulefiles/models/rule_relevance.py +14 -0
- autocoder/common/rulefiles/models/summary.py +16 -0
- autocoder/common/rulefiles/test_rulefiles.py +776 -0
- autocoder/common/rulefiles/utils/__init__.py +34 -0
- autocoder/common/rulefiles/utils/monitor.py +86 -0
- autocoder/common/rulefiles/utils/parser.py +230 -0
- autocoder/common/save_formatted_log.py +67 -10
- autocoder/common/search_replace.py +8 -1
- autocoder/common/search_replace_patch/__init__.py +24 -0
- autocoder/common/search_replace_patch/base.py +115 -0
- autocoder/common/search_replace_patch/manager.py +248 -0
- autocoder/common/search_replace_patch/patch_replacer.py +304 -0
- autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
- autocoder/common/search_replace_patch/string_replacer.py +181 -0
- autocoder/common/search_replace_patch/tests/__init__.py +3 -0
- autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
- autocoder/common/search_replace_patch/tests/test_base.py +188 -0
- autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
- autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
- autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
- autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
- autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
- autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
- autocoder/common/shell_commands/__init__.py +197 -0
- autocoder/common/shell_commands/background_process_notifier.py +346 -0
- autocoder/common/shell_commands/command_executor.py +1127 -0
- autocoder/common/shell_commands/error_recovery.py +541 -0
- autocoder/common/shell_commands/exceptions.py +120 -0
- autocoder/common/shell_commands/interactive_executor.py +476 -0
- autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
- autocoder/common/shell_commands/interactive_process.py +744 -0
- autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
- autocoder/common/shell_commands/monitoring.py +529 -0
- autocoder/common/shell_commands/process_cleanup.py +386 -0
- autocoder/common/shell_commands/process_manager.py +606 -0
- autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
- autocoder/common/shell_commands/tests/__init__.py +6 -0
- autocoder/common/shell_commands/tests/conftest.py +118 -0
- autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
- autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
- autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
- autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
- autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
- autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
- autocoder/common/shell_commands/tests/test_integration.py +664 -0
- autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
- autocoder/common/shell_commands/tests/test_performance.py +632 -0
- autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
- autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
- autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
- autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
- autocoder/common/shell_commands/timeout_config.py +315 -0
- autocoder/common/shell_commands/timeout_manager.py +352 -0
- autocoder/common/terminal_paste/__init__.py +14 -0
- autocoder/common/terminal_paste/demo.py +145 -0
- autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
- autocoder/common/terminal_paste/paste_handler.py +200 -0
- autocoder/common/terminal_paste/paste_manager.py +118 -0
- autocoder/common/terminal_paste/tests/__init__.py +1 -0
- autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
- autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
- autocoder/common/terminal_paste/utils.py +163 -0
- autocoder/common/test_autocoder_args.py +232 -0
- autocoder/common/test_env_manager.py +173 -0
- autocoder/common/test_env_manager_integration.py +159 -0
- autocoder/common/text_similarity/__init__.py +9 -0
- autocoder/common/text_similarity/demo.py +216 -0
- autocoder/common/text_similarity/examples.py +266 -0
- autocoder/common/text_similarity/test_text_similarity.py +306 -0
- autocoder/common/text_similarity/text_similarity.py +194 -0
- autocoder/common/text_similarity/utils.py +125 -0
- autocoder/common/todos/__init__.py +61 -0
- autocoder/common/todos/cache/__init__.py +16 -0
- autocoder/common/todos/cache/base_cache.py +89 -0
- autocoder/common/todos/cache/cache_manager.py +228 -0
- autocoder/common/todos/cache/memory_cache.py +225 -0
- autocoder/common/todos/config.py +155 -0
- autocoder/common/todos/exceptions.py +35 -0
- autocoder/common/todos/get_todo_manager.py +161 -0
- autocoder/common/todos/manager.py +537 -0
- autocoder/common/todos/models.py +239 -0
- autocoder/common/todos/storage/__init__.py +14 -0
- autocoder/common/todos/storage/base_storage.py +76 -0
- autocoder/common/todos/storage/file_storage.py +278 -0
- autocoder/common/tokens/counter.py +24 -2
- autocoder/common/tools_manager/__init__.py +17 -0
- autocoder/common/tools_manager/examples.py +162 -0
- autocoder/common/tools_manager/manager.py +385 -0
- autocoder/common/tools_manager/models.py +39 -0
- autocoder/common/tools_manager/test_tools_manager.py +303 -0
- autocoder/common/tools_manager/utils.py +191 -0
- autocoder/common/v2/agent/agentic_callbacks.py +270 -0
- autocoder/common/v2/agent/agentic_edit.py +2699 -1856
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
- autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
- autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
- autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
- autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
- autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
- autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
- autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
- autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
- autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
- autocoder/common/v2/agent/agentic_edit_types.py +343 -9
- autocoder/common/v2/agent/runner/__init__.py +3 -3
- autocoder/common/v2/agent/runner/base_runner.py +12 -26
- autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
- autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
- autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
- autocoder/common/v2/agent/runner/tool_display.py +557 -159
- autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
- autocoder/common/v2/agent/test_agentic_edit.py +194 -0
- autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
- autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
- autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
- autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
- autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
- autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
- autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
- autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
- autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
- autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
- autocoder/common/v2/code_auto_generate.py +136 -78
- autocoder/common/v2/code_auto_generate_diff.py +135 -79
- autocoder/common/v2/code_auto_generate_editblock.py +174 -99
- autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
- autocoder/common/v2/code_auto_merge.py +1 -1
- autocoder/common/v2/code_auto_merge_editblock.py +13 -1
- autocoder/common/v2/code_diff_manager.py +3 -3
- autocoder/common/v2/code_editblock_manager.py +4 -14
- autocoder/common/v2/code_manager.py +1 -1
- autocoder/common/v2/code_strict_diff_manager.py +2 -2
- autocoder/common/wrap_llm_hint/__init__.py +10 -0
- autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
- autocoder/common/wrap_llm_hint/utils.py +432 -0
- autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
- autocoder/completer/__init__.py +8 -0
- autocoder/completer/command_completer_v2.py +1051 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +165 -7
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +116 -124
- autocoder/{agent → index/filter}/agentic_filter.py +322 -333
- autocoder/index/filter/normal_filter.py +5 -11
- autocoder/index/filter/quick_filter.py +1 -1
- autocoder/index/index.py +36 -9
- autocoder/index/tests/__init__.py +1 -0
- autocoder/index/tests/run_tests.py +195 -0
- autocoder/index/tests/test_entry.py +303 -0
- autocoder/index/tests/test_index_manager.py +314 -0
- autocoder/index/tests/test_module_integration.py +300 -0
- autocoder/index/tests/test_symbols_utils.py +183 -0
- autocoder/inner/__init__.py +4 -0
- autocoder/inner/agentic.py +932 -0
- autocoder/inner/async_command_handler.py +992 -0
- autocoder/inner/conversation_command_handlers.py +623 -0
- autocoder/inner/merge_command_handler.py +213 -0
- autocoder/inner/queue_command_handler.py +684 -0
- autocoder/models.py +95 -266
- autocoder/plugins/git_helper_plugin.py +31 -29
- autocoder/plugins/token_helper_plugin.py +65 -46
- autocoder/pyproject/__init__.py +32 -29
- autocoder/rag/agentic_rag.py +215 -75
- autocoder/rag/cache/simple_cache.py +1 -2
- autocoder/rag/loaders/image_loader.py +1 -1
- autocoder/rag/long_context_rag.py +42 -26
- autocoder/rag/qa_conversation_strategy.py +1 -1
- autocoder/rag/terminal/__init__.py +17 -0
- autocoder/rag/terminal/args.py +581 -0
- autocoder/rag/terminal/bootstrap.py +61 -0
- autocoder/rag/terminal/command_handlers.py +653 -0
- autocoder/rag/terminal/formatters/__init__.py +20 -0
- autocoder/rag/terminal/formatters/base.py +70 -0
- autocoder/rag/terminal/formatters/json_format.py +66 -0
- autocoder/rag/terminal/formatters/stream_json.py +95 -0
- autocoder/rag/terminal/formatters/text.py +28 -0
- autocoder/rag/terminal/init.py +120 -0
- autocoder/rag/terminal/utils.py +106 -0
- autocoder/rag/test_agentic_rag.py +389 -0
- autocoder/rag/test_doc_filter.py +3 -3
- autocoder/rag/test_long_context_rag.py +1 -1
- autocoder/rag/test_token_limiter.py +517 -10
- autocoder/rag/token_counter.py +3 -0
- autocoder/rag/token_limiter.py +19 -15
- autocoder/rag/tools/__init__.py +26 -2
- autocoder/rag/tools/bochaai_example.py +343 -0
- autocoder/rag/tools/bochaai_sdk.py +541 -0
- autocoder/rag/tools/metaso_example.py +268 -0
- autocoder/rag/tools/metaso_sdk.py +417 -0
- autocoder/rag/tools/recall_tool.py +28 -7
- autocoder/rag/tools/run_integration_tests.py +204 -0
- autocoder/rag/tools/test_all_providers.py +318 -0
- autocoder/rag/tools/test_bochaai_integration.py +482 -0
- autocoder/rag/tools/test_final_integration.py +215 -0
- autocoder/rag/tools/test_metaso_integration.py +424 -0
- autocoder/rag/tools/test_metaso_real.py +171 -0
- autocoder/rag/tools/test_web_crawl_tool.py +639 -0
- autocoder/rag/tools/test_web_search_tool.py +509 -0
- autocoder/rag/tools/todo_read_tool.py +202 -0
- autocoder/rag/tools/todo_write_tool.py +412 -0
- autocoder/rag/tools/web_crawl_tool.py +634 -0
- autocoder/rag/tools/web_search_tool.py +558 -0
- autocoder/rag/tools/web_tools_example.py +119 -0
- autocoder/rag/types.py +16 -0
- autocoder/rag/variable_holder.py +4 -2
- autocoder/rags.py +86 -79
- autocoder/regexproject/__init__.py +23 -21
- autocoder/sdk/__init__.py +46 -190
- autocoder/sdk/api.py +370 -0
- autocoder/sdk/async_runner/__init__.py +26 -0
- autocoder/sdk/async_runner/async_executor.py +650 -0
- autocoder/sdk/async_runner/async_handler.py +356 -0
- autocoder/sdk/async_runner/markdown_processor.py +595 -0
- autocoder/sdk/async_runner/task_metadata.py +284 -0
- autocoder/sdk/async_runner/worktree_manager.py +438 -0
- autocoder/sdk/cli/__init__.py +2 -5
- autocoder/sdk/cli/formatters.py +28 -204
- autocoder/sdk/cli/handlers.py +77 -44
- autocoder/sdk/cli/main.py +154 -171
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -109
- autocoder/sdk/core/bridge.py +297 -115
- autocoder/sdk/exceptions.py +18 -12
- autocoder/sdk/formatters/__init__.py +19 -0
- autocoder/sdk/formatters/input.py +64 -0
- autocoder/sdk/formatters/output.py +247 -0
- autocoder/sdk/formatters/stream.py +54 -0
- autocoder/sdk/models/__init__.py +6 -5
- autocoder/sdk/models/options.py +55 -18
- autocoder/sdk/utils/formatters.py +27 -195
- autocoder/suffixproject/__init__.py +28 -25
- autocoder/terminal/__init__.py +14 -0
- autocoder/terminal/app.py +454 -0
- autocoder/terminal/args.py +32 -0
- autocoder/terminal/bootstrap.py +178 -0
- autocoder/terminal/command_processor.py +521 -0
- autocoder/terminal/command_registry.py +57 -0
- autocoder/terminal/help.py +97 -0
- autocoder/terminal/tasks/__init__.py +5 -0
- autocoder/terminal/tasks/background.py +77 -0
- autocoder/terminal/tasks/task_event.py +70 -0
- autocoder/terminal/ui/__init__.py +13 -0
- autocoder/terminal/ui/completer.py +268 -0
- autocoder/terminal/ui/keybindings.py +75 -0
- autocoder/terminal/ui/session.py +41 -0
- autocoder/terminal/ui/toolbar.py +64 -0
- autocoder/terminal/utils/__init__.py +13 -0
- autocoder/terminal/utils/errors.py +18 -0
- autocoder/terminal/utils/paths.py +19 -0
- autocoder/terminal/utils/shell.py +43 -0
- autocoder/terminal_v3/__init__.py +10 -0
- autocoder/terminal_v3/app.py +201 -0
- autocoder/terminal_v3/handlers/__init__.py +5 -0
- autocoder/terminal_v3/handlers/command_handler.py +131 -0
- autocoder/terminal_v3/models/__init__.py +6 -0
- autocoder/terminal_v3/models/conversation_buffer.py +214 -0
- autocoder/terminal_v3/models/message.py +50 -0
- autocoder/terminal_v3/models/tool_display.py +247 -0
- autocoder/terminal_v3/ui/__init__.py +7 -0
- autocoder/terminal_v3/ui/keybindings.py +56 -0
- autocoder/terminal_v3/ui/layout.py +141 -0
- autocoder/terminal_v3/ui/styles.py +43 -0
- autocoder/tsproject/__init__.py +23 -23
- autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
- autocoder/utils/llms.py +88 -80
- autocoder/utils/math_utils.py +101 -0
- autocoder/utils/model_provider_selector.py +16 -4
- autocoder/utils/operate_config_api.py +33 -5
- autocoder/utils/thread_utils.py +2 -2
- autocoder/version.py +4 -2
- autocoder/workflow_agents/__init__.py +84 -0
- autocoder/workflow_agents/agent.py +143 -0
- autocoder/workflow_agents/exceptions.py +573 -0
- autocoder/workflow_agents/executor.py +489 -0
- autocoder/workflow_agents/loader.py +737 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +172 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-1.0.0.dist-info/METADATA +0 -396
- auto_coder-1.0.0.dist-info/RECORD +0 -442
- auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
- autocoder/auto_coder_server.py +0 -672
- autocoder/benchmark.py +0 -138
- autocoder/common/ac_style_command_parser/example.py +0 -7
- autocoder/common/cleaner.py +0 -31
- autocoder/common/command_completer_v2.py +0 -615
- autocoder/common/context_pruner.py +0 -477
- autocoder/common/conversation_pruner.py +0 -132
- autocoder/common/directory_cache/__init__.py +0 -1
- autocoder/common/directory_cache/cache.py +0 -192
- autocoder/common/directory_cache/test_cache.py +0 -190
- autocoder/common/file_checkpoint/examples.py +0 -217
- autocoder/common/llm_friendly_package_example.py +0 -138
- autocoder/common/llm_friendly_package_test.py +0 -63
- autocoder/common/pull_requests/test_module.py +0 -1
- autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
- autocoder/common/text.py +0 -30
- autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
- autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
- autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
- autocoder/common/v2/agent/agentic_tool_display.py +0 -183
- autocoder/plugins/dynamic_completion_example.py +0 -148
- autocoder/plugins/sample_plugin.py +0 -160
- autocoder/sdk/cli/__main__.py +0 -26
- autocoder/sdk/cli/completion_wrapper.py +0 -38
- autocoder/sdk/cli/install_completion.py +0 -301
- autocoder/sdk/models/messages.py +0 -209
- autocoder/sdk/session/__init__.py +0 -32
- autocoder/sdk/session/session.py +0 -106
- autocoder/sdk/session/session_manager.py +0 -56
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for specific linter implementations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from unittest.mock import Mock, patch, MagicMock
|
|
7
|
+
import subprocess
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from autocoder.common.linter_core.linters.python_linter import PythonLinter
|
|
11
|
+
from autocoder.common.linter_core.linters.typescript_linter import TypeScriptLinter
|
|
12
|
+
from autocoder.common.linter_core.models.lint_result import LintResult
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestPythonLinter:
|
|
16
|
+
"""Test cases for PythonLinter."""
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def python_linter(self):
|
|
20
|
+
"""Create a PythonLinter instance."""
|
|
21
|
+
return PythonLinter()
|
|
22
|
+
|
|
23
|
+
def test_init_default_config(self):
|
|
24
|
+
"""Test PythonLinter initialization with default config."""
|
|
25
|
+
linter = PythonLinter()
|
|
26
|
+
assert linter.use_mypy is True
|
|
27
|
+
assert linter.flake8_args == []
|
|
28
|
+
assert linter.mypy_args == []
|
|
29
|
+
assert linter.flake8_timeout_secs == 30
|
|
30
|
+
assert linter.mypy_timeout_secs == 30
|
|
31
|
+
|
|
32
|
+
def test_init_custom_config(self):
|
|
33
|
+
"""Test PythonLinter initialization with custom config."""
|
|
34
|
+
config = {
|
|
35
|
+
'use_mypy': False,
|
|
36
|
+
'flake8_args': ['--max-line-length=120'],
|
|
37
|
+
'mypy_args': ['--strict'],
|
|
38
|
+
'flake8_timeout': 60,
|
|
39
|
+
'mypy_timeout': 45
|
|
40
|
+
}
|
|
41
|
+
linter = PythonLinter(config)
|
|
42
|
+
assert linter.use_mypy is False
|
|
43
|
+
assert linter.flake8_args == ['--max-line-length=120']
|
|
44
|
+
assert linter.mypy_args == ['--strict']
|
|
45
|
+
assert linter.flake8_timeout_secs == 60
|
|
46
|
+
assert linter.mypy_timeout_secs == 45
|
|
47
|
+
|
|
48
|
+
def test_supported_extensions(self, python_linter):
|
|
49
|
+
"""Test supported file extensions."""
|
|
50
|
+
assert python_linter.supported_extensions == ['.py', '.pyx', '.pyi']
|
|
51
|
+
|
|
52
|
+
def test_language_name(self, python_linter):
|
|
53
|
+
"""Test language name property."""
|
|
54
|
+
assert python_linter.language_name == "Python"
|
|
55
|
+
|
|
56
|
+
@patch('subprocess.run')
|
|
57
|
+
def test_is_available_true(self, mock_run, python_linter):
|
|
58
|
+
"""Test is_available when flake8 is installed."""
|
|
59
|
+
mock_run.return_value = MagicMock(returncode=0)
|
|
60
|
+
assert python_linter.is_available() is True
|
|
61
|
+
mock_run.assert_called_once_with(
|
|
62
|
+
['flake8', '--version'],
|
|
63
|
+
capture_output=True,
|
|
64
|
+
check=True,
|
|
65
|
+
timeout=10
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
@patch('subprocess.run')
|
|
69
|
+
def test_is_available_false(self, mock_run, python_linter):
|
|
70
|
+
"""Test is_available when flake8 is not installed."""
|
|
71
|
+
mock_run.side_effect = FileNotFoundError()
|
|
72
|
+
assert python_linter.is_available() is False
|
|
73
|
+
|
|
74
|
+
@patch('subprocess.run')
|
|
75
|
+
def test_lint_file_flake8_only(self, mock_run):
|
|
76
|
+
"""Test linting a file with only flake8."""
|
|
77
|
+
# Setup
|
|
78
|
+
linter = PythonLinter({'use_mypy': False})
|
|
79
|
+
mock_run.return_value = MagicMock(
|
|
80
|
+
stdout="test.py:1:1: E302 expected 2 blank lines, found 1",
|
|
81
|
+
stderr=""
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Execute
|
|
85
|
+
result = linter.lint_file('test.py')
|
|
86
|
+
|
|
87
|
+
# Verify
|
|
88
|
+
assert result.linter_name == "PythonLinter"
|
|
89
|
+
assert result.file_name == "test.py"
|
|
90
|
+
assert "=== flake8 ===" in result.lint_result
|
|
91
|
+
assert "E302 expected 2 blank lines" in result.lint_result
|
|
92
|
+
assert result.metadata['mypy_enabled'] is False
|
|
93
|
+
assert result.metadata['tools_used'] == ['flake8']
|
|
94
|
+
|
|
95
|
+
@patch('subprocess.run')
|
|
96
|
+
def test_lint_file_with_mypy(self, mock_run):
|
|
97
|
+
"""Test linting a file with both flake8 and mypy."""
|
|
98
|
+
# Setup
|
|
99
|
+
linter = PythonLinter({'use_mypy': True})
|
|
100
|
+
|
|
101
|
+
# Mock flake8 and mypy calls
|
|
102
|
+
mock_run.side_effect = [
|
|
103
|
+
# flake8 call
|
|
104
|
+
MagicMock(stdout="test.py:1:1: E302 expected 2 blank lines", stderr=""),
|
|
105
|
+
# mypy availability check
|
|
106
|
+
MagicMock(returncode=0),
|
|
107
|
+
# mypy call
|
|
108
|
+
MagicMock(stdout="test.py:5: error: Name 'foo' is not defined", stderr="")
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
# Execute
|
|
112
|
+
result = linter.lint_file('test.py')
|
|
113
|
+
|
|
114
|
+
# Verify
|
|
115
|
+
assert "=== flake8 ===" in result.lint_result
|
|
116
|
+
assert "=== mypy ===" in result.lint_result
|
|
117
|
+
assert "E302 expected 2 blank lines" in result.lint_result
|
|
118
|
+
assert "Name 'foo' is not defined" in result.lint_result
|
|
119
|
+
assert result.metadata['mypy_enabled'] is True
|
|
120
|
+
assert result.metadata['tools_used'] == ['flake8', 'mypy']
|
|
121
|
+
|
|
122
|
+
@patch('subprocess.run')
|
|
123
|
+
def test_lint_file_timeout(self, mock_run):
|
|
124
|
+
"""Test handling of timeout during linting."""
|
|
125
|
+
linter = PythonLinter()
|
|
126
|
+
mock_run.side_effect = subprocess.TimeoutExpired(['flake8'], 30)
|
|
127
|
+
|
|
128
|
+
result = linter.lint_file('test.py')
|
|
129
|
+
assert "Error: flake8 execution timed out" in result.lint_result
|
|
130
|
+
assert result.metadata.get('error') is True
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class TestTypeScriptLinter:
|
|
134
|
+
"""Test cases for TypeScriptLinter."""
|
|
135
|
+
|
|
136
|
+
@pytest.fixture
|
|
137
|
+
def ts_linter(self):
|
|
138
|
+
"""Create a TypeScriptLinter instance."""
|
|
139
|
+
return TypeScriptLinter()
|
|
140
|
+
|
|
141
|
+
def test_init_default_config(self):
|
|
142
|
+
"""Test TypeScriptLinter initialization with default config."""
|
|
143
|
+
linter = TypeScriptLinter()
|
|
144
|
+
assert linter.use_eslint is True
|
|
145
|
+
assert linter.tsc_args == ['--noEmit', '--strict']
|
|
146
|
+
assert linter.eslint_args == []
|
|
147
|
+
assert linter.tsconfig_path is None
|
|
148
|
+
assert linter.tsc_timeout_secs == 60
|
|
149
|
+
assert linter.eslint_timeout_secs == 30
|
|
150
|
+
|
|
151
|
+
def test_init_custom_config(self):
|
|
152
|
+
"""Test TypeScriptLinter initialization with custom config."""
|
|
153
|
+
config = {
|
|
154
|
+
'use_eslint': False,
|
|
155
|
+
'tsc_args': ['--noEmit'],
|
|
156
|
+
'eslint_args': ['--fix'],
|
|
157
|
+
'tsconfig_path': './tsconfig.json',
|
|
158
|
+
'tsc_timeout': 90,
|
|
159
|
+
'eslint_timeout': 45
|
|
160
|
+
}
|
|
161
|
+
linter = TypeScriptLinter(config)
|
|
162
|
+
assert linter.use_eslint is False
|
|
163
|
+
assert linter.tsc_args == ['--noEmit']
|
|
164
|
+
assert linter.eslint_args == ['--fix']
|
|
165
|
+
assert linter.tsconfig_path == './tsconfig.json'
|
|
166
|
+
assert linter.tsc_timeout_secs == 90
|
|
167
|
+
assert linter.eslint_timeout_secs == 45
|
|
168
|
+
|
|
169
|
+
def test_supported_extensions(self, ts_linter):
|
|
170
|
+
"""Test supported file extensions."""
|
|
171
|
+
assert ts_linter.supported_extensions == ['.ts', '.tsx', '.js', '.jsx']
|
|
172
|
+
|
|
173
|
+
def test_language_name(self, ts_linter):
|
|
174
|
+
"""Test language name property."""
|
|
175
|
+
assert ts_linter.language_name == "TypeScript"
|
|
176
|
+
|
|
177
|
+
@patch('subprocess.run')
|
|
178
|
+
def test_is_available_true(self, mock_run, ts_linter):
|
|
179
|
+
"""Test is_available when tsc is installed."""
|
|
180
|
+
mock_run.return_value = MagicMock(returncode=0)
|
|
181
|
+
assert ts_linter.is_available() is True
|
|
182
|
+
mock_run.assert_called_once_with(
|
|
183
|
+
['tsc', '--version'],
|
|
184
|
+
capture_output=True,
|
|
185
|
+
check=True,
|
|
186
|
+
timeout=10
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
@patch('subprocess.run')
|
|
190
|
+
def test_is_available_false(self, mock_run, ts_linter):
|
|
191
|
+
"""Test is_available when tsc is not installed."""
|
|
192
|
+
mock_run.side_effect = FileNotFoundError()
|
|
193
|
+
assert ts_linter.is_available() is False
|
|
194
|
+
|
|
195
|
+
@patch('subprocess.run')
|
|
196
|
+
@patch('time.time')
|
|
197
|
+
def test_lint_file_tsc_only(self, mock_time, mock_run):
|
|
198
|
+
"""Test linting a file with only tsc."""
|
|
199
|
+
# Setup
|
|
200
|
+
mock_time.side_effect = [0, 1] # Start and end time
|
|
201
|
+
linter = TypeScriptLinter({'use_eslint': False})
|
|
202
|
+
mock_run.return_value = MagicMock(
|
|
203
|
+
stdout="",
|
|
204
|
+
stderr="test.ts(1,5): error TS2322: Type 'string' is not assignable to type 'number'."
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# Execute
|
|
208
|
+
result = linter.lint_file('test.ts')
|
|
209
|
+
|
|
210
|
+
# Verify
|
|
211
|
+
assert result.linter_name == "TypeScriptLinter"
|
|
212
|
+
assert len(result.files_checked) == 1
|
|
213
|
+
assert 'test.ts' in result.files_checked[0]
|
|
214
|
+
assert result.has_issues
|
|
215
|
+
assert "=== tsc ===" in result.lint_output
|
|
216
|
+
assert "Type 'string' is not assignable" in result.lint_output
|
|
217
|
+
assert result.metadata['eslint_enabled'] is False
|
|
218
|
+
assert result.metadata['tools_used'] == ['tsc']
|
|
219
|
+
assert result.execution_time == 1
|
|
220
|
+
|
|
221
|
+
@patch('subprocess.run')
|
|
222
|
+
@patch('time.time')
|
|
223
|
+
def test_lint_file_with_eslint(self, mock_time, mock_run):
|
|
224
|
+
"""Test linting a file with both tsc and eslint."""
|
|
225
|
+
# Setup
|
|
226
|
+
mock_time.side_effect = [0, 2] # Start and end time
|
|
227
|
+
linter = TypeScriptLinter({'use_eslint': True})
|
|
228
|
+
|
|
229
|
+
# Mock tsc and eslint calls
|
|
230
|
+
mock_run.side_effect = [
|
|
231
|
+
# tsc call
|
|
232
|
+
MagicMock(stdout="", stderr="test.ts(1,5): error TS2322: Type error"),
|
|
233
|
+
# eslint availability check
|
|
234
|
+
MagicMock(returncode=0),
|
|
235
|
+
# eslint call
|
|
236
|
+
MagicMock(stdout="test.ts:2:10 warning Missing semicolon", stderr="")
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
# Execute
|
|
240
|
+
result = linter.lint_file('test.ts')
|
|
241
|
+
|
|
242
|
+
# Verify
|
|
243
|
+
assert result.has_issues
|
|
244
|
+
assert "=== tsc ===" in result.lint_output
|
|
245
|
+
assert "=== eslint ===" in result.lint_output
|
|
246
|
+
assert "Type error" in result.lint_output
|
|
247
|
+
assert "Missing semicolon" in result.lint_output
|
|
248
|
+
assert result.metadata['eslint_enabled'] is True
|
|
249
|
+
assert result.metadata['tools_used'] == ['tsc', 'eslint']
|
|
250
|
+
|
|
251
|
+
@patch('subprocess.run')
|
|
252
|
+
def test_lint_file_with_tsconfig(self, mock_run):
|
|
253
|
+
"""Test linting with custom tsconfig path."""
|
|
254
|
+
linter = TypeScriptLinter({
|
|
255
|
+
'tsconfig_path': './custom-tsconfig.json',
|
|
256
|
+
'use_eslint': False # Disable eslint to test only tsc
|
|
257
|
+
})
|
|
258
|
+
mock_run.return_value = MagicMock(stdout="", stderr="")
|
|
259
|
+
|
|
260
|
+
linter.lint_file('test.ts')
|
|
261
|
+
|
|
262
|
+
# Verify tsc was called with --project argument
|
|
263
|
+
call_args = mock_run.call_args[0][0]
|
|
264
|
+
assert '--project' in call_args
|
|
265
|
+
assert './custom-tsconfig.json' in call_args
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for lint result models.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from autocoder.common.linter_core.models.lint_result import LintResult
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestLintResult:
|
|
10
|
+
"""Test cases for LintResult model."""
|
|
11
|
+
|
|
12
|
+
def test_lint_result_creation(self):
|
|
13
|
+
"""Test creating a LintResult instance."""
|
|
14
|
+
result = LintResult(
|
|
15
|
+
linter_name="TestLinter",
|
|
16
|
+
files_checked=["test.py"],
|
|
17
|
+
metadata={"key": "value"}
|
|
18
|
+
)
|
|
19
|
+
# Set lint_result using property for backward compatibility
|
|
20
|
+
result.lint_result = "Some lint output"
|
|
21
|
+
|
|
22
|
+
assert result.linter_name == "TestLinter"
|
|
23
|
+
assert result.file_name == "test.py"
|
|
24
|
+
assert result.lint_result == "Some lint output"
|
|
25
|
+
assert result.metadata == {"key": "value"}
|
|
26
|
+
|
|
27
|
+
def test_lint_result_defaults(self):
|
|
28
|
+
"""Test LintResult with default values."""
|
|
29
|
+
result = LintResult(
|
|
30
|
+
linter_name="TestLinter",
|
|
31
|
+
files_checked=["test.py"]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
assert result.lint_result == ""
|
|
35
|
+
assert result.metadata == {}
|
|
36
|
+
|
|
37
|
+
def test_to_dict(self):
|
|
38
|
+
"""Test converting LintResult to dictionary."""
|
|
39
|
+
result = LintResult(
|
|
40
|
+
linter_name="TestLinter",
|
|
41
|
+
files_checked=["test.py"],
|
|
42
|
+
metadata={"tool": "flake8"}
|
|
43
|
+
)
|
|
44
|
+
result.lint_result = "Lint output"
|
|
45
|
+
|
|
46
|
+
data = result.to_dict()
|
|
47
|
+
expected_keys = {
|
|
48
|
+
'linter_name', 'files_checked', 'lint_output', 'execution_time',
|
|
49
|
+
'success', 'error_message', 'metadata', 'file_name', 'lint_result'
|
|
50
|
+
}
|
|
51
|
+
assert set(data.keys()) == expected_keys
|
|
52
|
+
assert data['linter_name'] == 'TestLinter'
|
|
53
|
+
assert data['file_name'] == 'test.py'
|
|
54
|
+
assert data['lint_result'] == 'Lint output'
|
|
55
|
+
assert data['metadata'] == {'tool': 'flake8'}
|
|
56
|
+
|
|
57
|
+
def test_from_dict(self):
|
|
58
|
+
"""Test creating LintResult from dictionary."""
|
|
59
|
+
data = {
|
|
60
|
+
'linter_name': 'TestLinter',
|
|
61
|
+
'file_name': 'test.py',
|
|
62
|
+
'lint_result': 'Lint output',
|
|
63
|
+
'metadata': {'tool': 'mypy'}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
result = LintResult.from_dict(data)
|
|
67
|
+
assert result.linter_name == "TestLinter"
|
|
68
|
+
assert result.file_name == "test.py"
|
|
69
|
+
assert result.lint_result == "Lint output"
|
|
70
|
+
assert result.metadata == {"tool": "mypy"}
|
|
71
|
+
|
|
72
|
+
def test_from_dict_missing_fields(self):
|
|
73
|
+
"""Test creating LintResult from incomplete dictionary."""
|
|
74
|
+
data = {
|
|
75
|
+
'linter_name': 'TestLinter',
|
|
76
|
+
'file_name': 'test.py'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
result = LintResult.from_dict(data)
|
|
80
|
+
assert result.lint_result == ""
|
|
81
|
+
assert result.metadata == {}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
验证 LinterManager 配置文件自动加载功能的脚本
|
|
5
|
+
|
|
6
|
+
这个脚本演示了如何使用新的配置文件自动加载功能,
|
|
7
|
+
并测试不同的配置文件位置和格式。
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import json
|
|
12
|
+
import yaml
|
|
13
|
+
import tempfile
|
|
14
|
+
import shutil
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from autocoder.common.linter_core.linter_manager import LinterManager
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def create_test_config_directories():
|
|
21
|
+
"""创建测试配置目录结构"""
|
|
22
|
+
print("=== 创建测试配置目录结构 ===")
|
|
23
|
+
|
|
24
|
+
# 创建临时目录作为项目根目录
|
|
25
|
+
project_root = tempfile.mkdtemp(prefix="linter_test_")
|
|
26
|
+
print(f"项目根目录: {project_root}")
|
|
27
|
+
|
|
28
|
+
# 创建不同优先级的配置目录
|
|
29
|
+
config_dirs = {
|
|
30
|
+
"project_level": os.path.join(project_root, ".autocoderlinters"),
|
|
31
|
+
"project_auto_coder": os.path.join(project_root, ".auto-coder", ".autocoderlinters"),
|
|
32
|
+
"global_level": os.path.expanduser("~/.auto-coder/.autocoderlinters")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for name, path in config_dirs.items():
|
|
36
|
+
os.makedirs(path, exist_ok=True)
|
|
37
|
+
print(f"创建目录: {name} -> {path}")
|
|
38
|
+
|
|
39
|
+
return project_root, config_dirs
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def create_sample_configs(config_dirs):
|
|
43
|
+
"""创建示例配置文件"""
|
|
44
|
+
print("\n=== 创建示例配置文件 ===")
|
|
45
|
+
|
|
46
|
+
# 项目级配置(最高优先级)
|
|
47
|
+
project_config = {
|
|
48
|
+
"max_workers": 8,
|
|
49
|
+
"timeout": 600,
|
|
50
|
+
"python_config": {
|
|
51
|
+
"use_mypy": True,
|
|
52
|
+
"flake8_args": ["--max-line-length=120"]
|
|
53
|
+
},
|
|
54
|
+
"source": "project_level"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
project_config_file = os.path.join(config_dirs["project_level"], "config.json")
|
|
58
|
+
with open(project_config_file, 'w') as f:
|
|
59
|
+
json.dump(project_config, f, indent=2)
|
|
60
|
+
print(f"创建项目级配置: {project_config_file}")
|
|
61
|
+
|
|
62
|
+
# .auto-coder 级配置(中等优先级)
|
|
63
|
+
auto_coder_config = {
|
|
64
|
+
"max_workers": 6,
|
|
65
|
+
"timeout": 500,
|
|
66
|
+
"typescript_config": {
|
|
67
|
+
"use_eslint": True,
|
|
68
|
+
"tsc_args": ["--strict"]
|
|
69
|
+
},
|
|
70
|
+
"source": "auto_coder_level"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
auto_coder_config_file = os.path.join(config_dirs["project_auto_coder"], "config.yaml")
|
|
74
|
+
with open(auto_coder_config_file, 'w') as f:
|
|
75
|
+
yaml.dump(auto_coder_config, f)
|
|
76
|
+
print(f"创建 .auto-coder 级配置: {auto_coder_config_file}")
|
|
77
|
+
|
|
78
|
+
# 全局配置(最低优先级)
|
|
79
|
+
global_config = {
|
|
80
|
+
"max_workers": 4,
|
|
81
|
+
"timeout": 300,
|
|
82
|
+
"java_config": {
|
|
83
|
+
"javac_args": ["-Xlint:all"]
|
|
84
|
+
},
|
|
85
|
+
"source": "global_level"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
global_config_file = os.path.join(config_dirs["global_level"], "config.yaml")
|
|
89
|
+
with open(global_config_file, 'w') as f:
|
|
90
|
+
yaml.dump(global_config, f)
|
|
91
|
+
print(f"创建全局配置: {global_config_file}")
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
"project": project_config,
|
|
95
|
+
"auto_coder": auto_coder_config,
|
|
96
|
+
"global": global_config
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_config_loading_priority(project_root, config_dirs, sample_configs):
|
|
101
|
+
"""测试配置加载优先级"""
|
|
102
|
+
print("\n=== 测试配置加载优先级 ===")
|
|
103
|
+
|
|
104
|
+
# 保存当前工作目录
|
|
105
|
+
original_cwd = os.getcwd()
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
# 切换到项目目录
|
|
109
|
+
os.chdir(project_root)
|
|
110
|
+
|
|
111
|
+
# 测试1: 所有配置文件都存在,应该加载项目级配置
|
|
112
|
+
print("\n1. 测试所有配置文件都存在的情况:")
|
|
113
|
+
manager = LinterManager()
|
|
114
|
+
print(f" 加载的配置源: {manager.global_config.get('source', 'unknown')}")
|
|
115
|
+
print(f" max_workers: {manager.max_workers}")
|
|
116
|
+
print(f" timeout: {manager.timeout}")
|
|
117
|
+
assert manager.global_config['source'] == 'project_level', "应该加载项目级配置"
|
|
118
|
+
|
|
119
|
+
# 测试2: 删除项目级配置,应该加载 .auto-coder 级配置
|
|
120
|
+
print("\n2. 测试删除项目级配置后:")
|
|
121
|
+
os.remove(os.path.join(config_dirs["project_level"], "config.json"))
|
|
122
|
+
manager = LinterManager()
|
|
123
|
+
print(f" 加载的配置源: {manager.global_config.get('source', 'unknown')}")
|
|
124
|
+
print(f" max_workers: {manager.max_workers}")
|
|
125
|
+
print(f" timeout: {manager.timeout}")
|
|
126
|
+
assert manager.global_config['source'] == 'auto_coder_level', "应该加载 .auto-coder 级配置"
|
|
127
|
+
|
|
128
|
+
# 测试3: 删除 .auto-coder 级配置,应该加载全局配置
|
|
129
|
+
print("\n3. 测试删除 .auto-coder 级配置后:")
|
|
130
|
+
os.remove(os.path.join(config_dirs["project_auto_coder"], "config.yaml"))
|
|
131
|
+
manager = LinterManager()
|
|
132
|
+
print(f" 加载的配置源: {manager.global_config.get('source', 'unknown')}")
|
|
133
|
+
print(f" max_workers: {manager.max_workers}")
|
|
134
|
+
print(f" timeout: {manager.timeout}")
|
|
135
|
+
assert manager.global_config['source'] == 'global_level', "应该加载全局配置"
|
|
136
|
+
|
|
137
|
+
# 测试4: 删除所有配置文件,应该使用默认配置
|
|
138
|
+
print("\n4. 测试删除所有配置文件后:")
|
|
139
|
+
os.remove(os.path.join(config_dirs["global_level"], "config.yaml"))
|
|
140
|
+
manager = LinterManager()
|
|
141
|
+
print(f" 配置为空: {manager.global_config == {}}")
|
|
142
|
+
print(f" max_workers (默认): {manager.max_workers}")
|
|
143
|
+
print(f" timeout (默认): {manager.timeout}")
|
|
144
|
+
assert manager.global_config == {}, "应该使用空配置"
|
|
145
|
+
assert manager.max_workers == 4, "应该使用默认 max_workers"
|
|
146
|
+
assert manager.timeout == 300, "应该使用默认 timeout"
|
|
147
|
+
|
|
148
|
+
finally:
|
|
149
|
+
# 恢复原始工作目录
|
|
150
|
+
os.chdir(original_cwd)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_different_config_formats(project_root):
|
|
154
|
+
"""测试不同的配置文件格式"""
|
|
155
|
+
print("\n=== 测试不同的配置文件格式 ===")
|
|
156
|
+
|
|
157
|
+
original_cwd = os.getcwd()
|
|
158
|
+
|
|
159
|
+
try:
|
|
160
|
+
os.chdir(project_root)
|
|
161
|
+
|
|
162
|
+
# 创建配置目录
|
|
163
|
+
config_dir = os.path.join(project_root, ".autocoderlinters")
|
|
164
|
+
os.makedirs(config_dir, exist_ok=True)
|
|
165
|
+
|
|
166
|
+
# 测试 JSON 格式
|
|
167
|
+
print("\n1. 测试 JSON 格式:")
|
|
168
|
+
json_config = {
|
|
169
|
+
"max_workers": 10,
|
|
170
|
+
"format": "json",
|
|
171
|
+
"python_config": {"use_mypy": True}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
json_file = os.path.join(config_dir, "config.json")
|
|
175
|
+
with open(json_file, 'w') as f:
|
|
176
|
+
json.dump(json_config, f)
|
|
177
|
+
|
|
178
|
+
manager = LinterManager()
|
|
179
|
+
print(f" 格式: {manager.global_config.get('format')}")
|
|
180
|
+
print(f" max_workers: {manager.max_workers}")
|
|
181
|
+
assert manager.global_config['format'] == 'json'
|
|
182
|
+
|
|
183
|
+
# 清理并测试 YAML 格式
|
|
184
|
+
os.remove(json_file)
|
|
185
|
+
|
|
186
|
+
print("\n2. 测试 YAML 格式:")
|
|
187
|
+
yaml_config = {
|
|
188
|
+
"max_workers": 12,
|
|
189
|
+
"format": "yaml",
|
|
190
|
+
"typescript_config": {"use_eslint": True}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
yaml_file = os.path.join(config_dir, "config.yaml")
|
|
194
|
+
with open(yaml_file, 'w') as f:
|
|
195
|
+
yaml.dump(yaml_config, f)
|
|
196
|
+
|
|
197
|
+
manager = LinterManager()
|
|
198
|
+
print(f" 格式: {manager.global_config.get('format')}")
|
|
199
|
+
print(f" max_workers: {manager.max_workers}")
|
|
200
|
+
assert manager.global_config['format'] == 'yaml'
|
|
201
|
+
|
|
202
|
+
# 清理并测试 YML 格式
|
|
203
|
+
os.remove(yaml_file)
|
|
204
|
+
|
|
205
|
+
print("\n3. 测试 YML 格式:")
|
|
206
|
+
yml_config = {
|
|
207
|
+
"max_workers": 14,
|
|
208
|
+
"format": "yml",
|
|
209
|
+
"java_config": {"javac_args": ["-Xlint:all"]}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
yml_file = os.path.join(config_dir, "config.yml")
|
|
213
|
+
with open(yml_file, 'w') as f:
|
|
214
|
+
yaml.dump(yml_config, f)
|
|
215
|
+
|
|
216
|
+
manager = LinterManager()
|
|
217
|
+
print(f" 格式: {manager.global_config.get('format')}")
|
|
218
|
+
print(f" max_workers: {manager.max_workers}")
|
|
219
|
+
assert manager.global_config['format'] == 'yml'
|
|
220
|
+
|
|
221
|
+
finally:
|
|
222
|
+
os.chdir(original_cwd)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def test_explicit_config_override():
|
|
226
|
+
"""测试显式配置覆盖自动加载"""
|
|
227
|
+
print("\n=== 测试显式配置覆盖自动加载 ===")
|
|
228
|
+
|
|
229
|
+
explicit_config = {
|
|
230
|
+
"max_workers": 20,
|
|
231
|
+
"timeout": 1000,
|
|
232
|
+
"source": "explicit"
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
manager = LinterManager(explicit_config)
|
|
236
|
+
print(f"配置源: {manager.global_config.get('source')}")
|
|
237
|
+
print(f"max_workers: {manager.max_workers}")
|
|
238
|
+
print(f"timeout: {manager.timeout}")
|
|
239
|
+
|
|
240
|
+
assert manager.global_config['source'] == 'explicit'
|
|
241
|
+
assert manager.max_workers == 20
|
|
242
|
+
assert manager.timeout == 1000
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def cleanup_test_directories(project_root, config_dirs):
|
|
246
|
+
"""清理测试目录"""
|
|
247
|
+
print("\n=== 清理测试目录 ===")
|
|
248
|
+
|
|
249
|
+
# 删除项目根目录
|
|
250
|
+
if os.path.exists(project_root):
|
|
251
|
+
shutil.rmtree(project_root)
|
|
252
|
+
print(f"删除项目目录: {project_root}")
|
|
253
|
+
|
|
254
|
+
# 删除全局配置目录(如果是我们创建的)
|
|
255
|
+
global_dir = config_dirs["global_level"]
|
|
256
|
+
if os.path.exists(global_dir):
|
|
257
|
+
try:
|
|
258
|
+
shutil.rmtree(global_dir)
|
|
259
|
+
print(f"删除全局配置目录: {global_dir}")
|
|
260
|
+
except OSError:
|
|
261
|
+
print(f"无法删除全局配置目录: {global_dir} (可能有其他文件)")
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def main():
|
|
265
|
+
"""主函数"""
|
|
266
|
+
print("开始验证 LinterManager 配置文件自动加载功能")
|
|
267
|
+
print("=" * 60)
|
|
268
|
+
|
|
269
|
+
try:
|
|
270
|
+
# 创建测试环境
|
|
271
|
+
project_root, config_dirs = create_test_config_directories()
|
|
272
|
+
sample_configs = create_sample_configs(config_dirs)
|
|
273
|
+
|
|
274
|
+
# 运行测试
|
|
275
|
+
test_config_loading_priority(project_root, config_dirs, sample_configs)
|
|
276
|
+
test_different_config_formats(project_root)
|
|
277
|
+
test_explicit_config_override()
|
|
278
|
+
|
|
279
|
+
print("\n" + "=" * 60)
|
|
280
|
+
print("✅ 所有测试通过!配置文件自动加载功能工作正常。")
|
|
281
|
+
|
|
282
|
+
except Exception as e:
|
|
283
|
+
print(f"\n❌ 测试失败: {e}")
|
|
284
|
+
raise
|
|
285
|
+
|
|
286
|
+
finally:
|
|
287
|
+
# 清理测试环境
|
|
288
|
+
if 'project_root' in locals() and 'config_dirs' in locals():
|
|
289
|
+
cleanup_test_directories(project_root, config_dirs)
|
|
290
|
+
|
|
291
|
+
print("\n验证完成!")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
if __name__ == '__main__':
|
|
295
|
+
main()
|
|
296
|
+
|