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,342 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Java linter implementation using javac for syntax checking with dependency support.
|
|
3
|
+
|
|
4
|
+
Supports Maven, Gradle, and local JAR dependencies for accurate type checking.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import subprocess
|
|
11
|
+
import time
|
|
12
|
+
import tempfile
|
|
13
|
+
import json
|
|
14
|
+
from typing import List, Optional, Dict, Any, Union, Tuple
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from functools import lru_cache
|
|
17
|
+
|
|
18
|
+
from ..base_linter import BaseLinter
|
|
19
|
+
from ..models.lint_result import LintResult
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class JavaLinter(BaseLinter):
|
|
23
|
+
"""Java linter using javac with support for project dependencies."""
|
|
24
|
+
|
|
25
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
26
|
+
super().__init__(config)
|
|
27
|
+
self.javac_args: List[str] = self.get_config_value('javac_args', [])
|
|
28
|
+
self.javac_timeout_secs: int = self.get_config_value('javac_timeout', 30)
|
|
29
|
+
|
|
30
|
+
# Dependency resolution configuration
|
|
31
|
+
self.project_type: str = self.get_config_value('project_type', 'auto') # auto/maven/gradle/local
|
|
32
|
+
self.source_paths: List[str] = self.get_config_value('source_paths', ['src', 'src/main/java'])
|
|
33
|
+
self.lib_dirs: List[str] = self.get_config_value('lib_dirs', ['lib', 'libs'])
|
|
34
|
+
self.enable_dependency_resolution: bool = self.get_config_value('enable_dependency_resolution', True)
|
|
35
|
+
self.cache_dependencies: bool = self.get_config_value('cache_dependencies', True)
|
|
36
|
+
self.release_version: str = self.get_config_value('release', '8') # Default to Java 8
|
|
37
|
+
self.use_release_flag: bool = self.get_config_value('use_release_flag', True) # Can be disabled for older javac
|
|
38
|
+
|
|
39
|
+
# Cache for resolved dependencies
|
|
40
|
+
self._classpath_cache: Optional[str] = None
|
|
41
|
+
self._project_root_cache: Optional[Path] = None
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def supported_extensions(self) -> List[str]:
|
|
45
|
+
return ['.java']
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def language_name(self) -> str:
|
|
49
|
+
return "Java"
|
|
50
|
+
|
|
51
|
+
def is_available(self) -> bool:
|
|
52
|
+
try:
|
|
53
|
+
subprocess.run(['javac', '-version'], capture_output=True, check=True, timeout=10)
|
|
54
|
+
return True
|
|
55
|
+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
def lint_file(self, file_path: Union[str, Path]) -> LintResult:
|
|
59
|
+
start_time = time.time()
|
|
60
|
+
path = Path(file_path)
|
|
61
|
+
result = LintResult(
|
|
62
|
+
linter_name=self.name,
|
|
63
|
+
files_checked=[str(path)]
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
# Find project root and resolve dependencies if enabled
|
|
68
|
+
project_root = self._find_project_root(path)
|
|
69
|
+
classpath = None
|
|
70
|
+
|
|
71
|
+
if self.enable_dependency_resolution and project_root:
|
|
72
|
+
classpath = self._resolve_classpath(project_root)
|
|
73
|
+
if classpath:
|
|
74
|
+
result.metadata['classpath_resolved'] = True
|
|
75
|
+
result.metadata['project_type'] = self._detect_project_type(project_root)
|
|
76
|
+
|
|
77
|
+
# Run javac for syntax checking
|
|
78
|
+
javac_output = self._run_javac(path, project_root, classpath)
|
|
79
|
+
|
|
80
|
+
if javac_output:
|
|
81
|
+
result.lint_output = f"=== javac ===\n{javac_output}"
|
|
82
|
+
|
|
83
|
+
result.metadata['tools_used'] = ['javac']
|
|
84
|
+
result.metadata['project_root'] = str(project_root) if project_root else None
|
|
85
|
+
result.success = True
|
|
86
|
+
except Exception as exc:
|
|
87
|
+
result.success = False
|
|
88
|
+
result.error_message = str(exc)
|
|
89
|
+
finally:
|
|
90
|
+
result.execution_time = time.time() - start_time
|
|
91
|
+
|
|
92
|
+
return result
|
|
93
|
+
|
|
94
|
+
def _find_project_root(self, file_path: Path) -> Optional[Path]:
|
|
95
|
+
"""Find the project root directory by looking for build files."""
|
|
96
|
+
if self._project_root_cache and file_path.is_relative_to(self._project_root_cache):
|
|
97
|
+
return self._project_root_cache
|
|
98
|
+
|
|
99
|
+
current = file_path.parent
|
|
100
|
+
markers = ['pom.xml', 'build.gradle', 'build.gradle.kts', '.git', 'settings.gradle', 'settings.gradle.kts']
|
|
101
|
+
|
|
102
|
+
while current != current.parent:
|
|
103
|
+
for marker in markers:
|
|
104
|
+
if (current / marker).exists():
|
|
105
|
+
self._project_root_cache = current
|
|
106
|
+
return current
|
|
107
|
+
current = current.parent
|
|
108
|
+
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
def _detect_project_type(self, project_root: Path) -> str:
|
|
112
|
+
"""Detect the project type (maven/gradle/local)."""
|
|
113
|
+
if self.project_type != 'auto':
|
|
114
|
+
return self.project_type
|
|
115
|
+
|
|
116
|
+
if (project_root / 'pom.xml').exists():
|
|
117
|
+
return 'maven'
|
|
118
|
+
elif (project_root / 'build.gradle').exists() or (project_root / 'build.gradle.kts').exists():
|
|
119
|
+
return 'gradle'
|
|
120
|
+
else:
|
|
121
|
+
return 'local'
|
|
122
|
+
|
|
123
|
+
@lru_cache(maxsize=1)
|
|
124
|
+
def _resolve_classpath(self, project_root: Path) -> Optional[str]:
|
|
125
|
+
"""Resolve project classpath based on project type."""
|
|
126
|
+
if self._classpath_cache and self.cache_dependencies:
|
|
127
|
+
return self._classpath_cache
|
|
128
|
+
|
|
129
|
+
project_type = self._detect_project_type(project_root)
|
|
130
|
+
classpath = None
|
|
131
|
+
|
|
132
|
+
if project_type == 'maven':
|
|
133
|
+
classpath = self._resolve_maven_classpath(project_root)
|
|
134
|
+
elif project_type == 'gradle':
|
|
135
|
+
classpath = self._resolve_gradle_classpath(project_root)
|
|
136
|
+
|
|
137
|
+
# Always check for local JARs as additional dependencies
|
|
138
|
+
local_jars = self._find_local_jars(project_root)
|
|
139
|
+
if local_jars:
|
|
140
|
+
if classpath:
|
|
141
|
+
classpath = f"{classpath}{os.pathsep}{local_jars}"
|
|
142
|
+
else:
|
|
143
|
+
classpath = local_jars
|
|
144
|
+
|
|
145
|
+
if self.cache_dependencies:
|
|
146
|
+
self._classpath_cache = classpath
|
|
147
|
+
|
|
148
|
+
return classpath
|
|
149
|
+
|
|
150
|
+
def _resolve_maven_classpath(self, project_root: Path) -> Optional[str]:
|
|
151
|
+
"""Resolve Maven dependencies using mvn command."""
|
|
152
|
+
try:
|
|
153
|
+
# Create a temporary file for the classpath output
|
|
154
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp:
|
|
155
|
+
tmp_path = tmp.name
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
# Run Maven to get compile classpath
|
|
159
|
+
cmd = [
|
|
160
|
+
'mvn', '-q',
|
|
161
|
+
'-DincludeScope=compile',
|
|
162
|
+
'-Dmdep.outputFile=' + tmp_path,
|
|
163
|
+
'dependency:build-classpath'
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
result = subprocess.run(
|
|
167
|
+
cmd,
|
|
168
|
+
cwd=str(project_root),
|
|
169
|
+
capture_output=True,
|
|
170
|
+
text=True,
|
|
171
|
+
timeout=30
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
if result.returncode == 0 and os.path.exists(tmp_path):
|
|
175
|
+
with open(tmp_path, 'r') as f:
|
|
176
|
+
classpath = f.read().strip()
|
|
177
|
+
return classpath if classpath else None
|
|
178
|
+
finally:
|
|
179
|
+
# Clean up temporary file
|
|
180
|
+
if os.path.exists(tmp_path):
|
|
181
|
+
os.unlink(tmp_path)
|
|
182
|
+
|
|
183
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
def _resolve_gradle_classpath(self, project_root: Path) -> Optional[str]:
|
|
189
|
+
"""Resolve Gradle dependencies using gradle/gradlew command."""
|
|
190
|
+
try:
|
|
191
|
+
# Create a temporary init script to print classpath
|
|
192
|
+
init_script = """
|
|
193
|
+
allprojects {
|
|
194
|
+
tasks.register("printCompileClasspath") {
|
|
195
|
+
doLast {
|
|
196
|
+
def conf = configurations.findByName("compileClasspath")
|
|
197
|
+
if (conf != null) {
|
|
198
|
+
println conf.resolve().collect{ it.absolutePath }.join(File.pathSeparator)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
"""
|
|
204
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.gradle', delete=False) as tmp:
|
|
205
|
+
tmp.write(init_script)
|
|
206
|
+
tmp_path = tmp.name
|
|
207
|
+
|
|
208
|
+
try:
|
|
209
|
+
# Prefer gradlew if available
|
|
210
|
+
gradle_cmd = './gradlew' if (project_root / 'gradlew').exists() else 'gradle'
|
|
211
|
+
|
|
212
|
+
cmd = [
|
|
213
|
+
gradle_cmd, '-q',
|
|
214
|
+
'-I', tmp_path,
|
|
215
|
+
'printCompileClasspath'
|
|
216
|
+
]
|
|
217
|
+
|
|
218
|
+
result = subprocess.run(
|
|
219
|
+
cmd,
|
|
220
|
+
cwd=str(project_root),
|
|
221
|
+
capture_output=True,
|
|
222
|
+
text=True,
|
|
223
|
+
timeout=30
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
if result.returncode == 0:
|
|
227
|
+
# Get the last line which should be the classpath
|
|
228
|
+
lines = result.stdout.strip().split('\n')
|
|
229
|
+
if lines:
|
|
230
|
+
classpath = lines[-1].strip()
|
|
231
|
+
return classpath if classpath and not classpath.startswith('BUILD') else None
|
|
232
|
+
finally:
|
|
233
|
+
# Clean up temporary file
|
|
234
|
+
if os.path.exists(tmp_path):
|
|
235
|
+
os.unlink(tmp_path)
|
|
236
|
+
|
|
237
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
238
|
+
pass
|
|
239
|
+
|
|
240
|
+
return None
|
|
241
|
+
|
|
242
|
+
def _find_local_jars(self, project_root: Path) -> Optional[str]:
|
|
243
|
+
"""Find JAR files in lib directories."""
|
|
244
|
+
jars = []
|
|
245
|
+
|
|
246
|
+
for lib_dir in self.lib_dirs:
|
|
247
|
+
lib_path = project_root / lib_dir
|
|
248
|
+
if lib_path.exists() and lib_path.is_dir():
|
|
249
|
+
# Find all JAR files in the directory
|
|
250
|
+
jar_files = list(lib_path.glob('**/*.jar'))
|
|
251
|
+
jars.extend(str(jar) for jar in jar_files)
|
|
252
|
+
|
|
253
|
+
return os.pathsep.join(jars) if jars else None
|
|
254
|
+
|
|
255
|
+
def _find_source_path(self, project_root: Path) -> Optional[str]:
|
|
256
|
+
"""Find the source path for the project."""
|
|
257
|
+
source_dirs = []
|
|
258
|
+
|
|
259
|
+
for source_path in self.source_paths:
|
|
260
|
+
full_path = project_root / source_path
|
|
261
|
+
if full_path.exists() and full_path.is_dir():
|
|
262
|
+
source_dirs.append(str(full_path))
|
|
263
|
+
|
|
264
|
+
return os.pathsep.join(source_dirs) if source_dirs else None
|
|
265
|
+
|
|
266
|
+
def _check_for_module_info(self, project_root: Path) -> bool:
|
|
267
|
+
"""Check if the project uses JPMS (has module-info.java)."""
|
|
268
|
+
for source_path in self.source_paths:
|
|
269
|
+
module_info = project_root / source_path / 'module-info.java'
|
|
270
|
+
if module_info.exists():
|
|
271
|
+
return True
|
|
272
|
+
return False
|
|
273
|
+
|
|
274
|
+
def _run_javac(self, file_path: Path, project_root: Optional[Path], classpath: Optional[str]) -> str:
|
|
275
|
+
"""Run javac with proper classpath and source path configuration."""
|
|
276
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
277
|
+
try:
|
|
278
|
+
# Try with --release flag first (if enabled)
|
|
279
|
+
if self.use_release_flag:
|
|
280
|
+
try:
|
|
281
|
+
return self._execute_javac_command(file_path, project_root, classpath, temp_dir, use_release=True)
|
|
282
|
+
except Exception as exc:
|
|
283
|
+
# If --release flag is not supported, retry without it
|
|
284
|
+
if 'invalid flag' in str(exc) or '--release' in str(exc):
|
|
285
|
+
return self._execute_javac_command(file_path, project_root, classpath, temp_dir, use_release=False)
|
|
286
|
+
else:
|
|
287
|
+
raise exc
|
|
288
|
+
else:
|
|
289
|
+
return self._execute_javac_command(file_path, project_root, classpath, temp_dir, use_release=False)
|
|
290
|
+
except subprocess.TimeoutExpired:
|
|
291
|
+
raise Exception('javac execution timed out')
|
|
292
|
+
except Exception as exc:
|
|
293
|
+
raise Exception(f'Error running javac: {str(exc)}')
|
|
294
|
+
|
|
295
|
+
def _execute_javac_command(self, file_path: Path, project_root: Optional[Path], classpath: Optional[str],
|
|
296
|
+
temp_dir: str, use_release: bool = True) -> str:
|
|
297
|
+
"""Execute the javac command with specified parameters."""
|
|
298
|
+
cmd = ['javac', '-d', temp_dir]
|
|
299
|
+
|
|
300
|
+
# Add release version if supported and requested
|
|
301
|
+
if use_release:
|
|
302
|
+
cmd.extend(['--release', self.release_version])
|
|
303
|
+
|
|
304
|
+
# Add lint options
|
|
305
|
+
cmd.append('-Xlint:all')
|
|
306
|
+
|
|
307
|
+
# Disable annotation processing for faster checking
|
|
308
|
+
cmd.append('-proc:none')
|
|
309
|
+
|
|
310
|
+
# Add source path if project root is found
|
|
311
|
+
if project_root:
|
|
312
|
+
source_path = self._find_source_path(project_root)
|
|
313
|
+
if source_path:
|
|
314
|
+
cmd.extend(['--source-path', source_path])
|
|
315
|
+
|
|
316
|
+
# Add classpath or module-path
|
|
317
|
+
if classpath:
|
|
318
|
+
# Check if using JPMS
|
|
319
|
+
if project_root and self._check_for_module_info(project_root):
|
|
320
|
+
cmd.extend(['--module-path', classpath])
|
|
321
|
+
else:
|
|
322
|
+
cmd.extend(['-classpath', classpath])
|
|
323
|
+
|
|
324
|
+
# Add custom javac arguments
|
|
325
|
+
cmd.extend(self.javac_args)
|
|
326
|
+
|
|
327
|
+
# Add the file to compile
|
|
328
|
+
cmd.append(str(file_path))
|
|
329
|
+
|
|
330
|
+
completed = subprocess.run(
|
|
331
|
+
cmd,
|
|
332
|
+
capture_output=True,
|
|
333
|
+
text=True,
|
|
334
|
+
timeout=self.javac_timeout_secs
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
# Check if command failed due to invalid flag
|
|
338
|
+
if completed.returncode != 0 and use_release and ('invalid flag' in completed.stderr or '--release' in completed.stderr):
|
|
339
|
+
raise Exception(f'Invalid flag error: {completed.stderr}')
|
|
340
|
+
|
|
341
|
+
# javac outputs errors to stderr
|
|
342
|
+
return completed.stderr.strip()
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Python linter implementation using flake8 and optionally mypy.
|
|
3
|
+
|
|
4
|
+
Simplified to pass raw output to formatters without parsing.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import subprocess
|
|
10
|
+
from typing import List, Optional, Dict, Any, Union
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from ..base_linter import BaseLinter
|
|
14
|
+
from ..models.lint_result import LintResult
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PythonLinter(BaseLinter):
|
|
18
|
+
"""Python linter using flake8 (and optionally mypy) with raw output."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
21
|
+
super().__init__(config)
|
|
22
|
+
self.use_mypy: bool = self.get_config_value('use_mypy', True)
|
|
23
|
+
self.flake8_args: List[str] = self.get_config_value('flake8_args', [])
|
|
24
|
+
self.mypy_args: List[str] = self.get_config_value('mypy_args', [])
|
|
25
|
+
self.flake8_timeout_secs: int = self.get_config_value('flake8_timeout', 30)
|
|
26
|
+
self.mypy_timeout_secs: int = self.get_config_value('mypy_timeout', 30)
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def supported_extensions(self) -> List[str]:
|
|
30
|
+
return ['.py', '.pyx', '.pyi']
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def language_name(self) -> str:
|
|
34
|
+
return "Python"
|
|
35
|
+
|
|
36
|
+
def is_available(self) -> bool:
|
|
37
|
+
try:
|
|
38
|
+
subprocess.run(['flake8', '--version'], capture_output=True, check=True, timeout=10)
|
|
39
|
+
return True
|
|
40
|
+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
def _is_mypy_available(self) -> bool:
|
|
44
|
+
try:
|
|
45
|
+
subprocess.run(['mypy', '--version'], capture_output=True, check=True, timeout=10)
|
|
46
|
+
return True
|
|
47
|
+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def lint_file(self, file_path: Union[str, Path]) -> LintResult:
|
|
51
|
+
path = Path(file_path)
|
|
52
|
+
result = LintResult(
|
|
53
|
+
linter_name=self.name,
|
|
54
|
+
files_checked=[str(path)]
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
raw_outputs: List[str] = []
|
|
59
|
+
|
|
60
|
+
# Run flake8
|
|
61
|
+
flake8_output = self._run_flake8(path)
|
|
62
|
+
if flake8_output:
|
|
63
|
+
raw_outputs.append(f"=== flake8 ===\n{flake8_output}")
|
|
64
|
+
|
|
65
|
+
# Run mypy if enabled and available
|
|
66
|
+
mypy_enabled = False
|
|
67
|
+
if self.use_mypy and self._is_mypy_available():
|
|
68
|
+
mypy_output = self._run_mypy(path)
|
|
69
|
+
if mypy_output:
|
|
70
|
+
raw_outputs.append(f"=== mypy ===\n{mypy_output}")
|
|
71
|
+
mypy_enabled = True
|
|
72
|
+
|
|
73
|
+
# Combine all output and create issues if there's output
|
|
74
|
+
if raw_outputs:
|
|
75
|
+
combined_output = "\n\n".join(raw_outputs)
|
|
76
|
+
# Use the lint_result property to maintain backward compatibility
|
|
77
|
+
result.lint_result = combined_output
|
|
78
|
+
|
|
79
|
+
result.metadata['mypy_enabled'] = mypy_enabled
|
|
80
|
+
result.metadata['tools_used'] = ['flake8'] + (['mypy'] if mypy_enabled else [])
|
|
81
|
+
result.success = True
|
|
82
|
+
except Exception as exc:
|
|
83
|
+
result.success = False
|
|
84
|
+
error_msg = f"Error: {str(exc)}"
|
|
85
|
+
result.error_message = error_msg
|
|
86
|
+
result.lint_result = error_msg # Also set for backward compatibility
|
|
87
|
+
result.metadata['error'] = True
|
|
88
|
+
|
|
89
|
+
return result
|
|
90
|
+
|
|
91
|
+
def _run_flake8(self, file_path: Path) -> str:
|
|
92
|
+
try:
|
|
93
|
+
cmd = ['flake8']
|
|
94
|
+
cmd.extend(self.flake8_args)
|
|
95
|
+
cmd.append(str(file_path))
|
|
96
|
+
|
|
97
|
+
completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.flake8_timeout_secs)
|
|
98
|
+
return completed.stdout.strip()
|
|
99
|
+
except subprocess.TimeoutExpired:
|
|
100
|
+
raise Exception('flake8 execution timed out')
|
|
101
|
+
except Exception as exc:
|
|
102
|
+
raise Exception(f'Error running flake8: {str(exc)}')
|
|
103
|
+
|
|
104
|
+
def _run_mypy(self, file_path: Path) -> str:
|
|
105
|
+
try:
|
|
106
|
+
cmd = ['mypy']
|
|
107
|
+
cmd.extend(self.mypy_args)
|
|
108
|
+
cmd.append(str(file_path))
|
|
109
|
+
|
|
110
|
+
completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.mypy_timeout_secs)
|
|
111
|
+
return completed.stdout.strip()
|
|
112
|
+
except subprocess.TimeoutExpired:
|
|
113
|
+
raise Exception('mypy execution timed out')
|
|
114
|
+
except Exception as exc:
|
|
115
|
+
raise Exception(f'Error running mypy: {str(exc)}')
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TypeScript linter implementation using tsc and optionally eslint.
|
|
3
|
+
|
|
4
|
+
Simplified to pass raw output to formatters without parsing.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import subprocess
|
|
10
|
+
import time
|
|
11
|
+
from typing import List, Optional, Dict, Any, Union
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from ..base_linter import BaseLinter
|
|
15
|
+
from ..models.lint_result import LintResult
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TypeScriptLinter(BaseLinter):
|
|
19
|
+
"""TypeScript linter using tsc (and optionally eslint) with raw output."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
22
|
+
super().__init__(config)
|
|
23
|
+
self.use_eslint: bool = self.get_config_value('use_eslint', True)
|
|
24
|
+
self.tsc_args: List[str] = self.get_config_value('tsc_args', ['--noEmit', '--strict'])
|
|
25
|
+
self.eslint_args: List[str] = self.get_config_value('eslint_args', [])
|
|
26
|
+
self.tsconfig_path: Optional[str] = self.get_config_value('tsconfig_path', None)
|
|
27
|
+
self.tsc_timeout_secs: int = self.get_config_value('tsc_timeout', 60)
|
|
28
|
+
self.eslint_timeout_secs: int = self.get_config_value('eslint_timeout', 30)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def supported_extensions(self) -> List[str]:
|
|
32
|
+
return ['.ts', '.tsx', '.js', '.jsx']
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def language_name(self) -> str:
|
|
36
|
+
return "TypeScript"
|
|
37
|
+
|
|
38
|
+
def is_available(self) -> bool:
|
|
39
|
+
try:
|
|
40
|
+
subprocess.run(['tsc', '--version'], capture_output=True, check=True, timeout=10)
|
|
41
|
+
return True
|
|
42
|
+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
def _is_eslint_available(self) -> bool:
|
|
46
|
+
try:
|
|
47
|
+
subprocess.run(['eslint', '--version'], capture_output=True, check=True, timeout=10)
|
|
48
|
+
return True
|
|
49
|
+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
def lint_file(self, file_path: Union[str, Path]) -> LintResult:
|
|
53
|
+
start_time = time.time()
|
|
54
|
+
path = Path(file_path)
|
|
55
|
+
result = LintResult(
|
|
56
|
+
linter_name=self.name,
|
|
57
|
+
files_checked=[str(path)]
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
raw_outputs: List[str] = []
|
|
62
|
+
|
|
63
|
+
# Run tsc
|
|
64
|
+
tsc_output = self._run_tsc(path)
|
|
65
|
+
if tsc_output:
|
|
66
|
+
raw_outputs.append(f"=== tsc ===\n{tsc_output}")
|
|
67
|
+
|
|
68
|
+
# Run eslint if enabled and available
|
|
69
|
+
eslint_enabled = False
|
|
70
|
+
if self.use_eslint and self._is_eslint_available():
|
|
71
|
+
eslint_output = self._run_eslint(path)
|
|
72
|
+
if eslint_output:
|
|
73
|
+
raw_outputs.append(f"=== eslint ===\n{eslint_output}")
|
|
74
|
+
eslint_enabled = True
|
|
75
|
+
|
|
76
|
+
# Combine all output
|
|
77
|
+
if raw_outputs:
|
|
78
|
+
combined_output = "\n\n".join(raw_outputs)
|
|
79
|
+
result.lint_output = combined_output
|
|
80
|
+
|
|
81
|
+
result.metadata['eslint_enabled'] = eslint_enabled
|
|
82
|
+
result.metadata['tools_used'] = ['tsc'] + (['eslint'] if eslint_enabled else [])
|
|
83
|
+
result.success = True
|
|
84
|
+
except Exception as exc:
|
|
85
|
+
result.success = False
|
|
86
|
+
result.error_message = str(exc)
|
|
87
|
+
finally:
|
|
88
|
+
result.execution_time = time.time() - start_time
|
|
89
|
+
|
|
90
|
+
return result
|
|
91
|
+
|
|
92
|
+
def _run_tsc(self, file_path: Path) -> str:
|
|
93
|
+
try:
|
|
94
|
+
cmd = ['tsc']
|
|
95
|
+
if self.tsconfig_path:
|
|
96
|
+
cmd.extend(['--project', self.tsconfig_path])
|
|
97
|
+
cmd.extend(self.tsc_args)
|
|
98
|
+
cmd.append(str(file_path))
|
|
99
|
+
|
|
100
|
+
completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.tsc_timeout_secs)
|
|
101
|
+
# tsc outputs to stderr
|
|
102
|
+
return completed.stderr.strip()
|
|
103
|
+
except subprocess.TimeoutExpired:
|
|
104
|
+
raise Exception('tsc execution timed out')
|
|
105
|
+
except Exception as exc:
|
|
106
|
+
raise Exception(f'Error running tsc: {str(exc)}')
|
|
107
|
+
|
|
108
|
+
def _run_eslint(self, file_path: Path) -> str:
|
|
109
|
+
try:
|
|
110
|
+
cmd = ['eslint']
|
|
111
|
+
cmd.extend(self.eslint_args)
|
|
112
|
+
cmd.append(str(file_path))
|
|
113
|
+
|
|
114
|
+
completed = subprocess.run(cmd, capture_output=True, text=True, timeout=self.eslint_timeout_secs)
|
|
115
|
+
return completed.stdout.strip()
|
|
116
|
+
except subprocess.TimeoutExpired:
|
|
117
|
+
raise Exception('eslint execution timed out')
|
|
118
|
+
except Exception as exc:
|
|
119
|
+
raise Exception(f'Error running eslint: {str(exc)}')
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Data models for lint results.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Dict, Any, List, Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class LintResult:
|
|
11
|
+
"""Represents the result of linting a file."""
|
|
12
|
+
|
|
13
|
+
linter_name: str
|
|
14
|
+
files_checked: List[str] = field(default_factory=list)
|
|
15
|
+
lint_output: str = "" # Raw output from linter
|
|
16
|
+
execution_time: float = 0.0
|
|
17
|
+
success: bool = True
|
|
18
|
+
error_message: str = ""
|
|
19
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
20
|
+
|
|
21
|
+
# Backward compatibility properties
|
|
22
|
+
@property
|
|
23
|
+
def file_name(self) -> str:
|
|
24
|
+
"""Get the first file name for backward compatibility."""
|
|
25
|
+
return self.files_checked[0] if self.files_checked else ""
|
|
26
|
+
|
|
27
|
+
@file_name.setter
|
|
28
|
+
def file_name(self, value: str) -> None:
|
|
29
|
+
"""Set the file name for backward compatibility."""
|
|
30
|
+
if not self.files_checked:
|
|
31
|
+
self.files_checked = [value]
|
|
32
|
+
else:
|
|
33
|
+
self.files_checked[0] = value
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def lint_result(self) -> str:
|
|
37
|
+
"""Get raw lint result for backward compatibility."""
|
|
38
|
+
return self.lint_output
|
|
39
|
+
|
|
40
|
+
@lint_result.setter
|
|
41
|
+
def lint_result(self, value: str) -> None:
|
|
42
|
+
"""Set raw lint result for backward compatibility."""
|
|
43
|
+
self.lint_output = value
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def has_issues(self) -> bool:
|
|
47
|
+
"""Check if the result has any issues."""
|
|
48
|
+
return bool(self.lint_output.strip())
|
|
49
|
+
|
|
50
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
51
|
+
"""Convert the result to a dictionary."""
|
|
52
|
+
result_dict = {
|
|
53
|
+
'linter_name': self.linter_name,
|
|
54
|
+
'files_checked': self.files_checked,
|
|
55
|
+
'lint_output': self.lint_output,
|
|
56
|
+
'execution_time': self.execution_time,
|
|
57
|
+
'success': self.success,
|
|
58
|
+
'error_message': self.error_message,
|
|
59
|
+
'metadata': self.metadata
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Add backward compatibility fields
|
|
63
|
+
result_dict['file_name'] = self.file_name
|
|
64
|
+
result_dict['lint_result'] = self.lint_result
|
|
65
|
+
|
|
66
|
+
return result_dict
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def from_dict(cls, data: Dict[str, Any]) -> 'LintResult':
|
|
70
|
+
"""Create a result from a dictionary."""
|
|
71
|
+
# Handle backward compatibility with old format
|
|
72
|
+
files_checked = data.get('files_checked', [])
|
|
73
|
+
if not files_checked and 'file_name' in data:
|
|
74
|
+
files_checked = [data['file_name']]
|
|
75
|
+
|
|
76
|
+
# Handle lint_output vs lint_result
|
|
77
|
+
lint_output = data.get('lint_output', '')
|
|
78
|
+
if not lint_output and 'lint_result' in data:
|
|
79
|
+
lint_output = data['lint_result']
|
|
80
|
+
|
|
81
|
+
result = cls(
|
|
82
|
+
linter_name=data['linter_name'],
|
|
83
|
+
files_checked=files_checked,
|
|
84
|
+
lint_output=lint_output,
|
|
85
|
+
execution_time=data.get('execution_time', 0.0),
|
|
86
|
+
success=data.get('success', True),
|
|
87
|
+
error_message=data.get('error_message', ''),
|
|
88
|
+
metadata=data.get('metadata', {})
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
return result
|