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