auto-coder 1.0.0__py3-none-any.whl → 2.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- auto_coder-2.0.1.dist-info/LICENSE +158 -0
- auto_coder-2.0.1.dist-info/METADATA +558 -0
- auto_coder-2.0.1.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.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 +77 -73
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +962 -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 +409 -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 +316 -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 +356 -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 +1094 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +400 -129
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- 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 +923 -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 +665 -0
- autocoder/workflow_agents/loader.py +749 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +173 -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.1.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simple base class for language-specific linters.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import List, Optional, Dict, Any, Union
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from .models.lint_result import LintResult
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseLinter(ABC):
|
|
13
|
+
"""Base class for all language linters."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
16
|
+
"""Initialize with optional configuration."""
|
|
17
|
+
self.config = config or {}
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def name(self) -> str:
|
|
21
|
+
"""Name of the linter."""
|
|
22
|
+
return self.__class__.__name__
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
@abstractmethod
|
|
26
|
+
def supported_extensions(self) -> List[str]:
|
|
27
|
+
"""Supported file extensions (e.g., ['.py', '.pyi'])."""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
@abstractmethod
|
|
32
|
+
def language_name(self) -> str:
|
|
33
|
+
"""Human-readable language name."""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def is_available(self) -> bool:
|
|
38
|
+
"""Check if the linter tools are available."""
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
def lint_file(self, file_path: Union[str, Path]) -> LintResult:
|
|
43
|
+
"""
|
|
44
|
+
Lint a single file and return the result.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
file_path: Path to the file to lint
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
LintResult with the linting output
|
|
51
|
+
"""
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
def can_lint_file(self, file_path: Union[str, Path]) -> bool:
|
|
55
|
+
"""Check if this linter can handle the given file."""
|
|
56
|
+
path = Path(file_path)
|
|
57
|
+
return path.suffix.lower() in self.supported_extensions
|
|
58
|
+
|
|
59
|
+
def get_config_value(self, key: str, default: Any = None) -> Any:
|
|
60
|
+
"""Get a configuration value."""
|
|
61
|
+
return self.config.get(key, default)
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Centralized configuration loader for the linter core module.
|
|
3
|
+
|
|
4
|
+
This module provides comprehensive configuration loading from multiple sources
|
|
5
|
+
with proper priority handling and format support.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import json
|
|
10
|
+
from typing import Dict, Any, Optional, List
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from loguru import logger
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LinterConfigLoader:
|
|
16
|
+
"""
|
|
17
|
+
Centralized configuration loader for linter configurations.
|
|
18
|
+
|
|
19
|
+
Loads configuration from multiple sources in priority order:
|
|
20
|
+
1. Explicit config path (if provided)
|
|
21
|
+
2. Environment variable AUTOCODER_LINTER_CONFIG
|
|
22
|
+
3. Project config file (.autocoderlinters/)
|
|
23
|
+
4. Global user config file (~/.auto-coder/.autocoderlinters/)
|
|
24
|
+
5. Default configuration
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
DEFAULT_CONFIG = {
|
|
28
|
+
'enabled': False, # Disabled by default for safety
|
|
29
|
+
'mode': 'warning',
|
|
30
|
+
'check_after_modification': True,
|
|
31
|
+
'report': {
|
|
32
|
+
'format': 'simple',
|
|
33
|
+
'include_in_result': True
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
def __init__(self, source_dir: Optional[str] = None):
|
|
38
|
+
"""
|
|
39
|
+
Initialize the config loader.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
source_dir: Base directory for relative path resolution
|
|
43
|
+
"""
|
|
44
|
+
self.source_dir = source_dir or "."
|
|
45
|
+
|
|
46
|
+
def load_config(self,
|
|
47
|
+
config_path: Optional[str] = None,
|
|
48
|
+
config_key: str = 'linter') -> Dict[str, Any]:
|
|
49
|
+
"""
|
|
50
|
+
Load configuration from multiple sources in priority order.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
config_path: Explicit path to configuration file
|
|
54
|
+
config_key: Key to extract from configuration files (for nested configs)
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Dictionary containing the loaded configuration
|
|
58
|
+
"""
|
|
59
|
+
# 1. Check explicit config path
|
|
60
|
+
if config_path:
|
|
61
|
+
config = self._load_from_file(config_path, config_key)
|
|
62
|
+
if config is not None:
|
|
63
|
+
logger.info(f"Loaded linter config from explicit path: {config_path}")
|
|
64
|
+
return config
|
|
65
|
+
|
|
66
|
+
# 2. Check environment variable
|
|
67
|
+
config = self._load_from_environment()
|
|
68
|
+
if config is not None:
|
|
69
|
+
return config
|
|
70
|
+
|
|
71
|
+
# 3. Check project config file
|
|
72
|
+
config = self._load_from_project_config(config_key)
|
|
73
|
+
if config is not None:
|
|
74
|
+
return config
|
|
75
|
+
|
|
76
|
+
# 4. Check global user config file
|
|
77
|
+
config = self._load_from_global_config(config_key)
|
|
78
|
+
if config is not None:
|
|
79
|
+
return config
|
|
80
|
+
|
|
81
|
+
# 5. Return default configuration
|
|
82
|
+
logger.debug("Using default linter configuration")
|
|
83
|
+
return self.DEFAULT_CONFIG.copy()
|
|
84
|
+
|
|
85
|
+
def _load_from_file(self, file_path: str, config_key: str = 'linter') -> Optional[Dict[str, Any]]:
|
|
86
|
+
"""Load configuration from a specific file."""
|
|
87
|
+
try:
|
|
88
|
+
path = Path(file_path)
|
|
89
|
+
if not path.exists():
|
|
90
|
+
logger.debug(f"Config file not found: {file_path}")
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
with open(path, 'r', encoding='utf-8') as f:
|
|
94
|
+
if path.suffix.lower() == '.json':
|
|
95
|
+
data = json.load(f)
|
|
96
|
+
else:
|
|
97
|
+
# Try YAML if available
|
|
98
|
+
try:
|
|
99
|
+
import yaml
|
|
100
|
+
data = yaml.safe_load(f)
|
|
101
|
+
except ImportError:
|
|
102
|
+
logger.warning(f"YAML support not available, treating {file_path} as JSON")
|
|
103
|
+
f.seek(0) # Reset file pointer
|
|
104
|
+
data = json.load(f)
|
|
105
|
+
|
|
106
|
+
# Extract the specified section if present, otherwise use the whole config
|
|
107
|
+
config = data.get(config_key, data) if isinstance(data, dict) else data
|
|
108
|
+
|
|
109
|
+
logger.info(f"Successfully loaded config from: {file_path}")
|
|
110
|
+
return config
|
|
111
|
+
|
|
112
|
+
except Exception as e:
|
|
113
|
+
logger.error(f"Failed to load config from {file_path}: {e}")
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
def _load_from_environment(self) -> Optional[Dict[str, Any]]:
|
|
117
|
+
"""Load configuration from environment variable."""
|
|
118
|
+
env_config = os.environ.get('AUTOCODER_LINTER_CONFIG')
|
|
119
|
+
if not env_config:
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
config = json.loads(env_config)
|
|
124
|
+
logger.info("Loaded linter config from environment variable")
|
|
125
|
+
return config
|
|
126
|
+
except json.JSONDecodeError as e:
|
|
127
|
+
logger.error(f"Failed to parse AUTOCODER_LINTER_CONFIG: {e}")
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
def _load_from_project_config(self, config_key: str = 'linter') -> Optional[Dict[str, Any]]:
|
|
131
|
+
"""Load configuration from project config directory."""
|
|
132
|
+
project_config_dir = Path(self.source_dir) / '.autocoderlinters'
|
|
133
|
+
|
|
134
|
+
# Try different config file formats in order of preference
|
|
135
|
+
config_files = [
|
|
136
|
+
project_config_dir / 'config.json',
|
|
137
|
+
project_config_dir / 'config.yaml',
|
|
138
|
+
project_config_dir / 'config.yml',
|
|
139
|
+
project_config_dir / 'linter.json',
|
|
140
|
+
project_config_dir / 'linter.yaml',
|
|
141
|
+
project_config_dir / 'linter.yml',
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
for config_file in config_files:
|
|
145
|
+
if config_file.exists():
|
|
146
|
+
config = self._load_from_file(str(config_file), config_key)
|
|
147
|
+
if config is not None:
|
|
148
|
+
logger.info(f"Loaded linter config from project: {config_file}")
|
|
149
|
+
return config
|
|
150
|
+
|
|
151
|
+
logger.debug(f"No project config found in: {project_config_dir}")
|
|
152
|
+
return None
|
|
153
|
+
|
|
154
|
+
def _load_from_global_config(self, config_key: str = 'linter') -> Optional[Dict[str, Any]]:
|
|
155
|
+
"""Load configuration from global user config directory."""
|
|
156
|
+
try:
|
|
157
|
+
# Use os.path.expanduser to handle ~ on all platforms
|
|
158
|
+
global_config_dir = Path(os.path.expanduser('~')) / '.auto-coder' / '.autocoderlinters'
|
|
159
|
+
|
|
160
|
+
# Try different config file formats in order of preference
|
|
161
|
+
config_files = [
|
|
162
|
+
global_config_dir / 'config.json',
|
|
163
|
+
global_config_dir / 'config.yaml',
|
|
164
|
+
global_config_dir / 'config.yml',
|
|
165
|
+
global_config_dir / 'linter.json',
|
|
166
|
+
global_config_dir / 'linter.yaml',
|
|
167
|
+
global_config_dir / 'linter.yml',
|
|
168
|
+
]
|
|
169
|
+
|
|
170
|
+
for config_file in config_files:
|
|
171
|
+
if config_file.exists():
|
|
172
|
+
config = self._load_from_file(str(config_file), config_key)
|
|
173
|
+
if config is not None:
|
|
174
|
+
logger.info(f"Loaded linter config from global user config: {config_file}")
|
|
175
|
+
return config
|
|
176
|
+
|
|
177
|
+
except Exception as e:
|
|
178
|
+
logger.debug(f"Error checking global user config: {e}")
|
|
179
|
+
|
|
180
|
+
logger.debug("No global user config found")
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
def validate_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
184
|
+
"""
|
|
185
|
+
Validate and normalize configuration.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
config: Raw configuration dictionary
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Validated and normalized configuration
|
|
192
|
+
"""
|
|
193
|
+
# Ensure all required keys exist with defaults
|
|
194
|
+
validated = self.DEFAULT_CONFIG.copy()
|
|
195
|
+
|
|
196
|
+
if isinstance(config, dict):
|
|
197
|
+
# Update with provided config
|
|
198
|
+
validated.update(config)
|
|
199
|
+
|
|
200
|
+
# Validate specific fields
|
|
201
|
+
if 'mode' in config and config['mode'] not in ['blocking', 'warning', 'silent']:
|
|
202
|
+
logger.warning(f"Invalid linter mode '{config['mode']}', using 'warning'")
|
|
203
|
+
validated['mode'] = 'warning'
|
|
204
|
+
|
|
205
|
+
if 'report' in config and isinstance(config['report'], dict):
|
|
206
|
+
report_config = validated['report']
|
|
207
|
+
report_config.update(config['report'])
|
|
208
|
+
|
|
209
|
+
if 'format' in config['report'] and config['report']['format'] not in ['simple', 'detailed', 'json']:
|
|
210
|
+
logger.warning(f"Invalid report format '{config['report']['format']}', using 'simple'")
|
|
211
|
+
report_config['format'] = 'simple'
|
|
212
|
+
|
|
213
|
+
return validated
|
|
214
|
+
|
|
215
|
+
@classmethod
|
|
216
|
+
def load_manager_config(cls, config_path: Optional[str] = None,
|
|
217
|
+
source_dir: Optional[str] = None) -> Dict[str, Any]:
|
|
218
|
+
"""
|
|
219
|
+
Load configuration specifically for LinterManager.
|
|
220
|
+
|
|
221
|
+
This is a convenience method that loads the full configuration
|
|
222
|
+
(not just the linter section) for use by LinterManager.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
config_path: Explicit path to configuration file
|
|
226
|
+
source_dir: Base directory for relative path resolution
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Full configuration dictionary for LinterManager
|
|
230
|
+
"""
|
|
231
|
+
loader = cls(source_dir)
|
|
232
|
+
|
|
233
|
+
# Try to load full config (without extracting just 'linter' section)
|
|
234
|
+
if config_path:
|
|
235
|
+
config = loader._load_from_file(config_path, config_key=None)
|
|
236
|
+
if config is not None:
|
|
237
|
+
return config
|
|
238
|
+
|
|
239
|
+
# Check environment variable for full config
|
|
240
|
+
env_config = os.environ.get('AUTOCODER_LINTER_CONFIG')
|
|
241
|
+
if env_config:
|
|
242
|
+
try:
|
|
243
|
+
return json.loads(env_config)
|
|
244
|
+
except json.JSONDecodeError:
|
|
245
|
+
pass
|
|
246
|
+
|
|
247
|
+
# Check project and global config files
|
|
248
|
+
for config_source in [loader._load_from_project_config, loader._load_from_global_config]:
|
|
249
|
+
config = config_source(config_key=None) # Load full config
|
|
250
|
+
if config is not None:
|
|
251
|
+
return config
|
|
252
|
+
|
|
253
|
+
# Return empty config if nothing found
|
|
254
|
+
return {}
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def load_linter_config(config_path: Optional[str] = None,
|
|
258
|
+
source_dir: Optional[str] = None) -> Dict[str, Any]:
|
|
259
|
+
"""
|
|
260
|
+
Convenience function to load and validate linter configuration.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
config_path: Explicit path to configuration file
|
|
264
|
+
source_dir: Base directory for relative path resolution
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Validated linter configuration dictionary
|
|
268
|
+
"""
|
|
269
|
+
loader = LinterConfigLoader(source_dir)
|
|
270
|
+
raw_config = loader.load_config(config_path)
|
|
271
|
+
return loader.validate_config(raw_config)
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base classes for formatting linter results.
|
|
3
|
+
|
|
4
|
+
This layer allows each linter to define how its results are presented
|
|
5
|
+
without changing the linting logic. By default, a raw formatter returns
|
|
6
|
+
results unchanged (as dictionaries), and consumers may subclass to
|
|
7
|
+
produce pretty text, tables, or other formats.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from abc import ABC, abstractmethod
|
|
13
|
+
from typing import Any, Dict
|
|
14
|
+
|
|
15
|
+
from ..models.lint_result import LintResult
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BaseLintOutputFormatter(ABC):
|
|
19
|
+
"""Abstract formatter for lint results.
|
|
20
|
+
|
|
21
|
+
Subclasses implement presentation logic for a single result and a
|
|
22
|
+
collection of results. The return type is intentionally flexible to
|
|
23
|
+
support dicts, strings, or other serializable structures.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
@abstractmethod
|
|
27
|
+
def format_result(self, result: LintResult) -> Any:
|
|
28
|
+
"""Format a single `LintResult` for presentation."""
|
|
29
|
+
raise NotImplementedError
|
|
30
|
+
|
|
31
|
+
def format_results(self, results: Dict[str, LintResult]) -> Dict[str, Any]:
|
|
32
|
+
"""Format multiple results.
|
|
33
|
+
|
|
34
|
+
Default implementation maps input keys to formatted entries using
|
|
35
|
+
`format_result`. Subclasses may override when a different aggregated
|
|
36
|
+
structure is desired (e.g., a single text blob, table, or summary).
|
|
37
|
+
"""
|
|
38
|
+
return {path: self.format_result(result) for path, result in results.items()}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Default raw formatter that returns lint results as dictionaries, unchanged.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from ..models.lint_result import LintResult
|
|
10
|
+
from .base_formatter import BaseLintOutputFormatter
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RawLintOutputFormatter(BaseLintOutputFormatter):
|
|
14
|
+
"""Return lint results as plain dictionaries with embedded summary."""
|
|
15
|
+
|
|
16
|
+
def format_result(self, result: LintResult) -> Any:
|
|
17
|
+
return result.to_dict()
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main Linter class that provides a simple interface for code checking.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import concurrent.futures
|
|
6
|
+
from typing import Dict, List, Optional, Union, Any
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from .base_linter import BaseLinter
|
|
10
|
+
from .models.lint_result import LintResult
|
|
11
|
+
from .linters import PythonLinter, TypeScriptLinter
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Linter:
|
|
15
|
+
"""Simple interface for linting files across multiple languages."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
18
|
+
"""
|
|
19
|
+
Initialize the linter.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
config: Optional configuration with keys:
|
|
23
|
+
- max_workers: Maximum parallel workers (default: 4)
|
|
24
|
+
- python: Python linter config
|
|
25
|
+
- typescript: TypeScript linter config
|
|
26
|
+
"""
|
|
27
|
+
self.config = config or {}
|
|
28
|
+
self.max_workers = self.config.get('max_workers', 4)
|
|
29
|
+
|
|
30
|
+
# Initialize available linters
|
|
31
|
+
self._linters: Dict[str, BaseLinter] = {}
|
|
32
|
+
self._init_linters()
|
|
33
|
+
|
|
34
|
+
def _init_linters(self) -> None:
|
|
35
|
+
"""Initialize all available linters."""
|
|
36
|
+
# Python linter
|
|
37
|
+
python_config = self.config.get('python', {})
|
|
38
|
+
python_linter = PythonLinter(python_config)
|
|
39
|
+
if python_linter.is_available():
|
|
40
|
+
self._linters['python'] = python_linter
|
|
41
|
+
|
|
42
|
+
# TypeScript linter
|
|
43
|
+
ts_config = self.config.get('typescript', {})
|
|
44
|
+
ts_linter = TypeScriptLinter(ts_config)
|
|
45
|
+
if ts_linter.is_available():
|
|
46
|
+
self._linters['typescript'] = ts_linter
|
|
47
|
+
|
|
48
|
+
def check_file(self, file_path: Union[str, Path]) -> Optional[LintResult]:
|
|
49
|
+
"""
|
|
50
|
+
Check a single file.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
file_path: Path to the file to check
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
LintResult if the file can be checked, None otherwise
|
|
57
|
+
"""
|
|
58
|
+
path = Path(file_path)
|
|
59
|
+
|
|
60
|
+
if not path.exists():
|
|
61
|
+
return LintResult(
|
|
62
|
+
file_path=str(path),
|
|
63
|
+
success=False,
|
|
64
|
+
error=f"File not found: {path}"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Find appropriate linter
|
|
68
|
+
for linter in self._linters.values():
|
|
69
|
+
if linter.can_check(path):
|
|
70
|
+
return linter.check_file(path)
|
|
71
|
+
|
|
72
|
+
return None # No linter available for this file type
|
|
73
|
+
|
|
74
|
+
def check_files(self, file_paths: List[Union[str, Path]],
|
|
75
|
+
parallel: bool = True) -> Dict[str, LintResult]:
|
|
76
|
+
"""
|
|
77
|
+
Check multiple files.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
file_paths: List of file paths to check
|
|
81
|
+
parallel: Whether to use parallel processing
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Dictionary mapping file paths to their results
|
|
85
|
+
"""
|
|
86
|
+
results = {}
|
|
87
|
+
|
|
88
|
+
if parallel and len(file_paths) > 1:
|
|
89
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=self.max_workers) as executor:
|
|
90
|
+
future_to_file = {
|
|
91
|
+
executor.submit(self.check_file, fp): str(fp)
|
|
92
|
+
for fp in file_paths
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for future in concurrent.futures.as_completed(future_to_file):
|
|
96
|
+
file_path = future_to_file[future]
|
|
97
|
+
try:
|
|
98
|
+
result = future.result()
|
|
99
|
+
if result:
|
|
100
|
+
results[file_path] = result
|
|
101
|
+
except Exception as e:
|
|
102
|
+
results[file_path] = LintResult(
|
|
103
|
+
file_path=file_path,
|
|
104
|
+
success=False,
|
|
105
|
+
error=str(e)
|
|
106
|
+
)
|
|
107
|
+
else:
|
|
108
|
+
for file_path in file_paths:
|
|
109
|
+
result = self.check_file(file_path)
|
|
110
|
+
if result:
|
|
111
|
+
results[str(file_path)] = result
|
|
112
|
+
|
|
113
|
+
return results
|
|
114
|
+
|
|
115
|
+
def check_directory(self, directory: Union[str, Path],
|
|
116
|
+
recursive: bool = True,
|
|
117
|
+
extensions: Optional[List[str]] = None) -> Dict[str, LintResult]:
|
|
118
|
+
"""
|
|
119
|
+
Check all supported files in a directory.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
directory: Directory to check
|
|
123
|
+
recursive: Whether to check subdirectories
|
|
124
|
+
extensions: Specific extensions to check (None = all supported)
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
Dictionary mapping file paths to their results
|
|
128
|
+
"""
|
|
129
|
+
path = Path(directory)
|
|
130
|
+
if not path.exists():
|
|
131
|
+
return {
|
|
132
|
+
str(path): LintResult(
|
|
133
|
+
file_path=str(path),
|
|
134
|
+
success=False,
|
|
135
|
+
error=f"Directory not found: {path}"
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# Get all supported extensions if not specified
|
|
140
|
+
if extensions is None:
|
|
141
|
+
extensions = []
|
|
142
|
+
for linter in self._linters.values():
|
|
143
|
+
extensions.extend(linter.extensions)
|
|
144
|
+
|
|
145
|
+
# Find files
|
|
146
|
+
files = []
|
|
147
|
+
pattern = "**/*" if recursive else "*"
|
|
148
|
+
for ext in set(extensions):
|
|
149
|
+
files.extend(path.glob(f"{pattern}{ext}"))
|
|
150
|
+
|
|
151
|
+
return self.check_files(files)
|
|
152
|
+
|
|
153
|
+
def get_supported_languages(self) -> List[str]:
|
|
154
|
+
"""Get list of supported languages."""
|
|
155
|
+
return list(self._linters.keys())
|
|
156
|
+
|
|
157
|
+
def get_supported_extensions(self) -> List[str]:
|
|
158
|
+
"""Get list of all supported file extensions."""
|
|
159
|
+
extensions = []
|
|
160
|
+
for linter in self._linters.values():
|
|
161
|
+
extensions.extend(linter.extensions)
|
|
162
|
+
return list(set(extensions))
|
|
163
|
+
|
|
164
|
+
def is_available(self, language: str) -> bool:
|
|
165
|
+
"""Check if a specific language linter is available."""
|
|
166
|
+
return language in self._linters
|