tunacode-cli 0.0.32__tar.gz → 0.0.34__tar.gz
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 tunacode-cli might be problematic. Click here for more details.
- {tunacode_cli-0.0.32/src/tunacode_cli.egg-info → tunacode_cli-0.0.34}/PKG-INFO +20 -1
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/README.md +19 -0
- tunacode_cli-0.0.34/TUNACODE.md +27 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/pyproject.toml +1 -1
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/cli/commands.py +42 -8
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/cli/repl.py +7 -3
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/configuration/defaults.py +1 -1
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/constants.py +1 -1
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/agents/main.py +35 -2
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/setup/config_setup.py +15 -9
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/user_configuration.py +20 -3
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34/src/tunacode_cli.egg-info}/PKG-INFO +20 -1
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode_cli.egg-info/SOURCES.txt +12 -2
- tunacode_cli-0.0.34/src/tunacode_cli.egg-info/top_level.txt +1 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/test_agent_creation.py +32 -26
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/test_process_request.py +5 -5
- tunacode_cli-0.0.34/tests/characterization/commands/__init__.py +1 -0
- tunacode_cli-0.0.34/tests/characterization/commands/test_init_command.py +252 -0
- tunacode_cli-0.0.34/tests/characterization/context/__init__.py +1 -0
- tunacode_cli-0.0.34/tests/characterization/context/test_context_acceptance.py +94 -0
- tunacode_cli-0.0.34/tests/characterization/context/test_context_integration.py +106 -0
- tunacode_cli-0.0.34/tests/characterization/context/test_context_loading.py +143 -0
- tunacode_cli-0.0.34/tests/characterization/context/test_tunacode_logging.py +80 -0
- tunacode_cli-0.0.34/tests/test_characterization_grep_performance.py +287 -0
- tunacode_cli-0.0.34/tests/test_characterization_iteration_limits.py +145 -0
- tunacode_cli-0.0.34/tests/test_characterization_tool_ui_behavior.py +464 -0
- tunacode_cli-0.0.34/tests/test_config_directory_creation.py +105 -0
- tunacode_cli-0.0.34/tests/test_tool_handler_ui_messages.py +105 -0
- tunacode_cli-0.0.32/TUNACODE.md +0 -0
- tunacode_cli-0.0.32/src/api/auth.py +0 -13
- tunacode_cli-0.0.32/src/api/users.py +0 -8
- tunacode_cli-0.0.32/src/tunacode_cli.egg-info/top_level.txt +0 -3
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/CLAUDE.md +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/LICENSE +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/MANIFEST.in +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/setup.cfg +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/setup.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/cli/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/cli/main.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/cli/textual_app.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/cli/textual_bridge.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/configuration/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/configuration/models.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/configuration/settings.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/context.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/agents/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/background/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/background/manager.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/code_index.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/llm/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/setup/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/setup/agent_setup.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/setup/base.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/setup/coordinator.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/setup/environment_setup.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/setup/git_safety_setup.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/state.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/core/tool_handler.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/exceptions.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/prompts/system.md +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/py.typed +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/services/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/services/mcp.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/setup.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/base.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/bash.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/glob.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/grep.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/list_dir.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/read_file.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/read_file_async_poc.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/run_command.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/update_file.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/tools/write_file.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/types.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/completers.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/console.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/constants.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/decorators.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/input.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/keybindings.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/lexers.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/output.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/panels.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/prompt_manager.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/tool_ui.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/ui/validators.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/bm25.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/diff_utils.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/file_utils.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/import_cache.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/ripgrep.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/system.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/text_utils.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode/utils/token_counter.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode_cli.egg-info/dependency_links.txt +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode_cli.egg-info/entry_points.txt +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/src/tunacode_cli.egg-info/requires.txt +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/conftest.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/test_json_tool_parsing.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/test_process_node.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/test_tool_message_patching.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/background/test_background_edge_cases.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/background/test_cleanup.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/background/test_task_cancellation.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/background/test_task_creation.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/background/test_task_execution.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/code_index/test_cache_management.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/code_index/test_file_scanning.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/code_index/test_index_building.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/code_index/test_search_operations.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/code_index/test_symbol_extraction.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/conftest.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/repl/test_command_parsing.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/repl/test_input_handling.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/repl/test_keyboard_interrupts.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/repl/test_multiline_input.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/repl/test_repl_initialization.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/repl/test_session_flow.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/services/test_error_recovery.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/services/test_llm_routing.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/services/test_mcp_integration.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/services/test_service_lifecycle.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/state/test_agent_tracking.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/state/test_message_history.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/state/test_permissions.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/state/test_session_management.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/state/test_state_initialization.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/state/test_user_config.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/test_characterization_commands.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/ui/test_async_ui.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/ui/test_console_output.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/ui/test_diff_display.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/ui/test_prompt_rendering.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/ui/test_tool_confirmations.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/utils/test_file_operations.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/utils/test_git_commands.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/utils/test_token_counting.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/utils/test_utils_edge_cases.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/conftest.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/crud/test_core_file_operations.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/fixtures/__init__.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/fixtures/file_operations.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/integration/test_error_recovery_flow.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/integration/test_full_session_flow.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/integration/test_mcp_tool_flow.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/integration/test_multi_tool_operations.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/integration/test_performance_scenarios.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_actual_parallelism.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_agent_initialization.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_background_manager.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_agent_main.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_bash.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_commands_system.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_glob.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_grep.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_list_dir.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_read_file.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_repl_utils.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_run_command.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_setup_system.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_update_file.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_utilities.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_characterization_write_file.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_cli_command_flow.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_cli_file_operations_integration.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_config_setup_async.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_enhanced_visual_feedback.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_fallback_responses.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_fast_glob_search.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_file_operations_edge_cases.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_file_operations_stress.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_file_reference_context_tracking.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_file_reference_expansion.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_grep_fast_glob.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_grep_legacy_compat.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_grep_timeout.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_json_tool_parsing.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_list_dir.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_parallel_execution_demo.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_parallel_execution_freeze_fix.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_parallel_execution_integration.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_parallel_read_only_tools.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_parallel_tool_execution.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_read_only_confirmation.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_tool_categorization.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_tool_combinations.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_update_command.py +0 -0
- {tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/test_visual_parallel_feedback.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tunacode-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.34
|
|
4
4
|
Summary: Your agentic CLI developer.
|
|
5
5
|
Author-email: larock22 <noreply@github.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -40,6 +40,7 @@ Dynamic: license-file
|
|
|
40
40
|
<div align="center">
|
|
41
41
|
|
|
42
42
|
[](https://badge.fury.io/py/tunacode-cli)
|
|
43
|
+
[](https://pepy.tech/project/tunacode-cli)
|
|
43
44
|
[](https://www.python.org/downloads/)
|
|
44
45
|
[](https://opensource.org/licenses/MIT)
|
|
45
46
|
|
|
@@ -78,6 +79,17 @@ tunacode --model "openrouter:openai/gpt-4o" --key "sk-or-your-openrouter-key"
|
|
|
78
79
|
|
|
79
80
|
Your config is saved to `~/.config/tunacode.json` (edit directly with `nvim ~/.config/tunacode.json`)
|
|
80
81
|
|
|
82
|
+
### Recommended Models
|
|
83
|
+
|
|
84
|
+
Based on extensive testing, these models provide the best performance:
|
|
85
|
+
- `google/gemini-2.5-pro` - Excellent for complex reasoning
|
|
86
|
+
- `openai/gpt-4.1` - Strong general-purpose model
|
|
87
|
+
- `deepseek/deepseek-r1-0528` - Great for code generation
|
|
88
|
+
- `openai/gpt-4.1-mini` - Fast and cost-effective
|
|
89
|
+
- `anthropic/claude-4-sonnet-20250522` - Superior context handling
|
|
90
|
+
|
|
91
|
+
*Note: Formal evaluations coming soon. Any model can work, but these have shown the best results in practice.*
|
|
92
|
+
|
|
81
93
|
## Start Coding
|
|
82
94
|
|
|
83
95
|
```bash
|
|
@@ -105,6 +117,13 @@ TunaCode leverages parallel execution for read-only operations, achieving **3x f
|
|
|
105
117
|
|
|
106
118
|
Multiple file reads, directory listings, and searches execute concurrently using async I/O, making code exploration significantly faster.
|
|
107
119
|
|
|
120
|
+
## Features in Development
|
|
121
|
+
|
|
122
|
+
- **Streaming UI**: Currently working on implementing streaming responses for better user experience
|
|
123
|
+
- **Bug Fixes**: Actively addressing issues - please report any bugs you encounter!
|
|
124
|
+
|
|
125
|
+
*Note: While the tool is fully functional, we're focusing on stability and core features before optimizing for speed.*
|
|
126
|
+
|
|
108
127
|
## Safety First
|
|
109
128
|
|
|
110
129
|
⚠️ **Important**: TunaCode can modify your codebase. Always:
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/py/tunacode-cli)
|
|
6
|
+
[](https://pepy.tech/project/tunacode-cli)
|
|
6
7
|
[](https://www.python.org/downloads/)
|
|
7
8
|
[](https://opensource.org/licenses/MIT)
|
|
8
9
|
|
|
@@ -41,6 +42,17 @@ tunacode --model "openrouter:openai/gpt-4o" --key "sk-or-your-openrouter-key"
|
|
|
41
42
|
|
|
42
43
|
Your config is saved to `~/.config/tunacode.json` (edit directly with `nvim ~/.config/tunacode.json`)
|
|
43
44
|
|
|
45
|
+
### Recommended Models
|
|
46
|
+
|
|
47
|
+
Based on extensive testing, these models provide the best performance:
|
|
48
|
+
- `google/gemini-2.5-pro` - Excellent for complex reasoning
|
|
49
|
+
- `openai/gpt-4.1` - Strong general-purpose model
|
|
50
|
+
- `deepseek/deepseek-r1-0528` - Great for code generation
|
|
51
|
+
- `openai/gpt-4.1-mini` - Fast and cost-effective
|
|
52
|
+
- `anthropic/claude-4-sonnet-20250522` - Superior context handling
|
|
53
|
+
|
|
54
|
+
*Note: Formal evaluations coming soon. Any model can work, but these have shown the best results in practice.*
|
|
55
|
+
|
|
44
56
|
## Start Coding
|
|
45
57
|
|
|
46
58
|
```bash
|
|
@@ -68,6 +80,13 @@ TunaCode leverages parallel execution for read-only operations, achieving **3x f
|
|
|
68
80
|
|
|
69
81
|
Multiple file reads, directory listings, and searches execute concurrently using async I/O, making code exploration significantly faster.
|
|
70
82
|
|
|
83
|
+
## Features in Development
|
|
84
|
+
|
|
85
|
+
- **Streaming UI**: Currently working on implementing streaming responses for better user experience
|
|
86
|
+
- **Bug Fixes**: Actively addressing issues - please report any bugs you encounter!
|
|
87
|
+
|
|
88
|
+
*Note: While the tool is fully functional, we're focusing on stability and core features before optimizing for speed.*
|
|
89
|
+
|
|
71
90
|
## Safety First
|
|
72
91
|
|
|
73
92
|
⚠️ **Important**: TunaCode can modify your codebase. Always:
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# TUNACODE.md
|
|
2
|
+
|
|
3
|
+
## Build Commands
|
|
4
|
+
- Run all tests: `make test`
|
|
5
|
+
- Run single test: `pytest tests/test_file.py::test_name`
|
|
6
|
+
- Run quick tests: `pytest -m "not slow"`
|
|
7
|
+
- Lint code: `make lint`
|
|
8
|
+
- Build package: `make build`
|
|
9
|
+
- Clean artifacts: `make clean`
|
|
10
|
+
|
|
11
|
+
## Code Style
|
|
12
|
+
- Use type hints for all function signatures
|
|
13
|
+
- Prefer guard clauses over nested conditionals
|
|
14
|
+
- Keep functions focused and under 50 lines
|
|
15
|
+
- Use descriptive variable names
|
|
16
|
+
- Follow PEP 8 conventions
|
|
17
|
+
- Maximum line length: 120 characters
|
|
18
|
+
- Use black for formatting
|
|
19
|
+
- Use isort for imports
|
|
20
|
+
- Use snake_case for variables and functions
|
|
21
|
+
- Use PascalCase for classes
|
|
22
|
+
- Prefer explicit error handling, avoid bare excepts
|
|
23
|
+
|
|
24
|
+
## Architecture Notes
|
|
25
|
+
- Agent creation loads this file and appends to system prompt
|
|
26
|
+
- Context is loaded synchronously to avoid event loop issues
|
|
27
|
+
- TUNACODE.md is walked up directory tree (closest first)
|
|
@@ -6,7 +6,7 @@ from enum import Enum
|
|
|
6
6
|
from typing import Any, Dict, List, Optional, Type
|
|
7
7
|
|
|
8
8
|
from .. import utils
|
|
9
|
-
from ..exceptions import ValidationError
|
|
9
|
+
from ..exceptions import ConfigurationError, ValidationError
|
|
10
10
|
from ..types import CommandArgs, CommandContext, CommandResult, ProcessRequestCallback
|
|
11
11
|
from ..ui import console as ui
|
|
12
12
|
|
|
@@ -184,8 +184,8 @@ class IterationsCommand(SimpleCommand):
|
|
|
184
184
|
if args:
|
|
185
185
|
try:
|
|
186
186
|
new_limit = int(args[0])
|
|
187
|
-
if new_limit < 1 or new_limit >
|
|
188
|
-
await ui.error("Iterations must be between 1 and
|
|
187
|
+
if new_limit < 1 or new_limit > 100:
|
|
188
|
+
await ui.error("Iterations must be between 1 and 100")
|
|
189
189
|
return
|
|
190
190
|
|
|
191
191
|
# Update the user config
|
|
@@ -198,9 +198,9 @@ class IterationsCommand(SimpleCommand):
|
|
|
198
198
|
except ValueError:
|
|
199
199
|
await ui.error("Please provide a valid number")
|
|
200
200
|
else:
|
|
201
|
-
current = state.user_config.get("settings", {}).get("max_iterations",
|
|
201
|
+
current = state.user_config.get("settings", {}).get("max_iterations", 40)
|
|
202
202
|
await ui.info(f"Current maximum iterations: {current}")
|
|
203
|
-
await ui.muted("Usage: /iterations <number> (1-
|
|
203
|
+
await ui.muted("Usage: /iterations <number> (1-100)")
|
|
204
204
|
|
|
205
205
|
|
|
206
206
|
class ClearCommand(SimpleCommand):
|
|
@@ -628,9 +628,13 @@ class ModelCommand(SimpleCommand):
|
|
|
628
628
|
|
|
629
629
|
# Check if setting as default
|
|
630
630
|
if len(args) > 1 and args[1] == "default":
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
631
|
+
try:
|
|
632
|
+
utils.user_configuration.set_default_model(model_name, context.state_manager)
|
|
633
|
+
await ui.muted("Updating default model")
|
|
634
|
+
return "restart"
|
|
635
|
+
except ConfigurationError as e:
|
|
636
|
+
await ui.error(str(e))
|
|
637
|
+
return None
|
|
634
638
|
|
|
635
639
|
# Show success message with the new model
|
|
636
640
|
await ui.success(f"Switched to model: {model_name}")
|
|
@@ -669,6 +673,35 @@ class CommandFactory:
|
|
|
669
673
|
setattr(self.dependencies, key, value)
|
|
670
674
|
|
|
671
675
|
|
|
676
|
+
class InitCommand(SimpleCommand):
|
|
677
|
+
"""Creates or updates TUNACODE.md with project-specific context."""
|
|
678
|
+
|
|
679
|
+
spec = CommandSpec(
|
|
680
|
+
name="/init",
|
|
681
|
+
aliases=[],
|
|
682
|
+
description="Analyze codebase and create/update TUNACODE.md file",
|
|
683
|
+
category=CommandCategory.DEVELOPMENT,
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
async def execute(self, args, context: CommandContext) -> CommandResult:
|
|
687
|
+
"""Execute the init command."""
|
|
688
|
+
# Minimal implementation to make test pass
|
|
689
|
+
prompt = """Please analyze this codebase and create a TUNACODE.md file containing:
|
|
690
|
+
1. Build/lint/test commands - especially for running a single test
|
|
691
|
+
2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.
|
|
692
|
+
|
|
693
|
+
The file you create will be given to agentic coding agents (such as yourself) that operate in this repository.
|
|
694
|
+
Make it about 20 lines long.
|
|
695
|
+
If there's already a TUNACODE.md, improve it.
|
|
696
|
+
If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md),
|
|
697
|
+
make sure to include them."""
|
|
698
|
+
|
|
699
|
+
# Call the agent to analyze and create/update the file
|
|
700
|
+
await context.process_request(prompt, context.state_manager)
|
|
701
|
+
|
|
702
|
+
return None
|
|
703
|
+
|
|
704
|
+
|
|
672
705
|
class CommandRegistry:
|
|
673
706
|
"""Registry for managing commands with auto-discovery and categories."""
|
|
674
707
|
|
|
@@ -726,6 +759,7 @@ class CommandRegistry:
|
|
|
726
759
|
BranchCommand,
|
|
727
760
|
CompactCommand,
|
|
728
761
|
ModelCommand,
|
|
762
|
+
InitCommand,
|
|
729
763
|
]
|
|
730
764
|
|
|
731
765
|
# Register all discovered commands
|
|
@@ -88,12 +88,16 @@ async def _tool_confirm(tool_call, node, state_manager: StateManager):
|
|
|
88
88
|
|
|
89
89
|
async def _tool_handler(part, node, state_manager: StateManager):
|
|
90
90
|
"""Handle tool execution with separated business logic and UI."""
|
|
91
|
-
|
|
91
|
+
# Create tool handler with state first to check if confirmation is needed
|
|
92
|
+
tool_handler = ToolHandler(state_manager)
|
|
93
|
+
|
|
94
|
+
# Only show tool info for tools that require confirmation
|
|
95
|
+
if tool_handler.should_confirm(part.tool_name):
|
|
96
|
+
await ui.info(f"Tool({part.tool_name})")
|
|
97
|
+
|
|
92
98
|
state_manager.session.spinner.stop()
|
|
93
99
|
|
|
94
100
|
try:
|
|
95
|
-
# Create tool handler with state
|
|
96
|
-
tool_handler = ToolHandler(state_manager)
|
|
97
101
|
args = _parse_args(part.args)
|
|
98
102
|
|
|
99
103
|
# Use a synchronous function in run_in_terminal to avoid async deadlocks
|
|
@@ -345,6 +345,11 @@ async def _process_node(
|
|
|
345
345
|
# Check if ALL tools in this node are read-only
|
|
346
346
|
all_read_only = all(part.tool_name in READ_ONLY_TOOLS for part in tool_parts)
|
|
347
347
|
|
|
348
|
+
# TODO: Currently only batches if ALL tools are read-only. Should be updated to use
|
|
349
|
+
# batch_read_only_tools() function to group consecutive read-only tools and execute
|
|
350
|
+
# them in parallel even when mixed with write/execute tools. For example:
|
|
351
|
+
# [read, read, write, read] should execute as: [read||read], [write], [read]
|
|
352
|
+
# instead of all sequential. The batch_read_only_tools() function exists but is unused.
|
|
348
353
|
if all_read_only and len(tool_parts) > 1 and buffering_callback:
|
|
349
354
|
# Execute read-only tools in parallel!
|
|
350
355
|
import time
|
|
@@ -452,6 +457,26 @@ def get_or_create_agent(model: ModelName, state_manager: StateManager) -> Pydant
|
|
|
452
457
|
# Use a default system prompt if neither file exists
|
|
453
458
|
system_prompt = "You are a helpful AI assistant for software development tasks."
|
|
454
459
|
|
|
460
|
+
# Load TUNACODE.md context
|
|
461
|
+
# Use sync version of get_code_style to avoid nested event loop issues
|
|
462
|
+
try:
|
|
463
|
+
from pathlib import Path as PathlibPath
|
|
464
|
+
|
|
465
|
+
tunacode_path = PathlibPath.cwd() / "TUNACODE.md"
|
|
466
|
+
if tunacode_path.exists():
|
|
467
|
+
tunacode_content = tunacode_path.read_text(encoding="utf-8")
|
|
468
|
+
if tunacode_content.strip():
|
|
469
|
+
# Log that we found TUNACODE.md
|
|
470
|
+
print("📄 TUNACODE.md located: Loading context...")
|
|
471
|
+
|
|
472
|
+
system_prompt += "\n\n# Project Context from TUNACODE.md\n" + tunacode_content
|
|
473
|
+
else:
|
|
474
|
+
# Log that TUNACODE.md was not found
|
|
475
|
+
print("📄 TUNACODE.md not found: Using default context")
|
|
476
|
+
except Exception:
|
|
477
|
+
# Ignore errors loading TUNACODE.md
|
|
478
|
+
pass
|
|
479
|
+
|
|
455
480
|
state_manager.session.agents[model] = Agent(
|
|
456
481
|
model=model,
|
|
457
482
|
system_prompt=system_prompt,
|
|
@@ -651,8 +676,8 @@ async def process_request(
|
|
|
651
676
|
) -> AgentRun:
|
|
652
677
|
agent = get_or_create_agent(model, state_manager)
|
|
653
678
|
mh = state_manager.session.messages.copy()
|
|
654
|
-
# Get max iterations from config (default:
|
|
655
|
-
max_iterations = state_manager.session.user_config.get("settings", {}).get("max_iterations",
|
|
679
|
+
# Get max iterations from config (default: 40)
|
|
680
|
+
max_iterations = state_manager.session.user_config.get("settings", {}).get("max_iterations", 40)
|
|
656
681
|
fallback_enabled = state_manager.session.user_config.get("settings", {}).get(
|
|
657
682
|
"fallback_response", True
|
|
658
683
|
)
|
|
@@ -665,6 +690,14 @@ async def process_request(
|
|
|
665
690
|
# Create a request-level buffer for batching read-only tools across nodes
|
|
666
691
|
tool_buffer = ToolBuffer()
|
|
667
692
|
|
|
693
|
+
# Show TUNACODE.md preview if it was loaded and thoughts are enabled
|
|
694
|
+
if state_manager.session.show_thoughts and hasattr(state_manager, "tunacode_preview"):
|
|
695
|
+
from tunacode.ui import console as ui
|
|
696
|
+
|
|
697
|
+
await ui.muted(state_manager.tunacode_preview)
|
|
698
|
+
# Clear the preview after displaying it once
|
|
699
|
+
delattr(state_manager, "tunacode_preview")
|
|
700
|
+
|
|
668
701
|
# Show what we're sending to the API when thoughts are enabled
|
|
669
702
|
if state_manager.session.show_thoughts:
|
|
670
703
|
from tunacode.ui import console as ui
|
|
@@ -82,9 +82,13 @@ class ConfigSetup(BaseSetup):
|
|
|
82
82
|
):
|
|
83
83
|
self.state_manager.session.user_config = {}
|
|
84
84
|
self.state_manager.session.user_config = DEFAULT_USER_CONFIG.copy()
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
try:
|
|
86
|
+
user_configuration.save_config(
|
|
87
|
+
self.state_manager
|
|
88
|
+
) # Save the default config initially
|
|
89
|
+
except ConfigurationError as e:
|
|
90
|
+
await ui.error(str(e))
|
|
91
|
+
raise
|
|
88
92
|
await self._onboarding()
|
|
89
93
|
else:
|
|
90
94
|
# No config found - show CLI usage instead of onboarding
|
|
@@ -172,11 +176,12 @@ class ConfigSetup(BaseSetup):
|
|
|
172
176
|
# Compare configs to see if anything changed
|
|
173
177
|
current_config = json.dumps(self.state_manager.session.user_config, sort_keys=True)
|
|
174
178
|
if initial_config != current_config:
|
|
175
|
-
|
|
179
|
+
try:
|
|
180
|
+
user_configuration.save_config(self.state_manager)
|
|
176
181
|
message = f"Config saved to: [bold]{self.config_file}[/bold]"
|
|
177
182
|
await ui.panel("Finished", message, top=0, border_style=UI_COLORS["success"])
|
|
178
|
-
|
|
179
|
-
await ui.error(
|
|
183
|
+
except ConfigurationError as e:
|
|
184
|
+
await ui.error(str(e))
|
|
180
185
|
else:
|
|
181
186
|
await ui.panel(
|
|
182
187
|
"Setup canceled",
|
|
@@ -320,8 +325,9 @@ class ConfigSetup(BaseSetup):
|
|
|
320
325
|
]
|
|
321
326
|
|
|
322
327
|
# Save the configuration
|
|
323
|
-
|
|
328
|
+
try:
|
|
329
|
+
user_configuration.save_config(self.state_manager)
|
|
324
330
|
await ui.warning("Model set without validation - verify the model name is correct")
|
|
325
331
|
await ui.success(f"Configuration saved to: {self.config_file}")
|
|
326
|
-
|
|
327
|
-
await ui.error(
|
|
332
|
+
except ConfigurationError as e:
|
|
333
|
+
await ui.error(str(e))
|
|
@@ -58,11 +58,23 @@ def save_config(state_manager: "StateManager") -> bool:
|
|
|
58
58
|
"""Save user config to file"""
|
|
59
59
|
app_settings = ApplicationSettings()
|
|
60
60
|
try:
|
|
61
|
+
# Ensure config directory exists
|
|
62
|
+
app_settings.paths.config_dir.mkdir(mode=0o700, parents=True, exist_ok=True)
|
|
63
|
+
|
|
64
|
+
# Write config file
|
|
61
65
|
with open(app_settings.paths.config_file, "w") as f:
|
|
62
66
|
json.dump(state_manager.session.user_config, f, indent=4)
|
|
63
67
|
return True
|
|
64
|
-
except
|
|
65
|
-
|
|
68
|
+
except PermissionError as e:
|
|
69
|
+
raise ConfigurationError(
|
|
70
|
+
f"Permission denied writing to {app_settings.paths.config_file}: {e}"
|
|
71
|
+
)
|
|
72
|
+
except OSError as e:
|
|
73
|
+
raise ConfigurationError(
|
|
74
|
+
f"Failed to save configuration to {app_settings.paths.config_file}: {e}"
|
|
75
|
+
)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
raise ConfigurationError(f"Unexpected error saving configuration: {e}")
|
|
66
78
|
|
|
67
79
|
|
|
68
80
|
def get_mcp_servers(state_manager: "StateManager") -> MCPServers:
|
|
@@ -73,4 +85,9 @@ def get_mcp_servers(state_manager: "StateManager") -> MCPServers:
|
|
|
73
85
|
def set_default_model(model_name: ModelName, state_manager: "StateManager") -> bool:
|
|
74
86
|
"""Set the default model in the user config and save"""
|
|
75
87
|
state_manager.session.user_config["default_model"] = model_name
|
|
76
|
-
|
|
88
|
+
try:
|
|
89
|
+
save_config(state_manager)
|
|
90
|
+
return True
|
|
91
|
+
except ConfigurationError:
|
|
92
|
+
# Re-raise ConfigurationError to be handled by caller
|
|
93
|
+
raise
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tunacode-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.34
|
|
4
4
|
Summary: Your agentic CLI developer.
|
|
5
5
|
Author-email: larock22 <noreply@github.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -40,6 +40,7 @@ Dynamic: license-file
|
|
|
40
40
|
<div align="center">
|
|
41
41
|
|
|
42
42
|
[](https://badge.fury.io/py/tunacode-cli)
|
|
43
|
+
[](https://pepy.tech/project/tunacode-cli)
|
|
43
44
|
[](https://www.python.org/downloads/)
|
|
44
45
|
[](https://opensource.org/licenses/MIT)
|
|
45
46
|
|
|
@@ -78,6 +79,17 @@ tunacode --model "openrouter:openai/gpt-4o" --key "sk-or-your-openrouter-key"
|
|
|
78
79
|
|
|
79
80
|
Your config is saved to `~/.config/tunacode.json` (edit directly with `nvim ~/.config/tunacode.json`)
|
|
80
81
|
|
|
82
|
+
### Recommended Models
|
|
83
|
+
|
|
84
|
+
Based on extensive testing, these models provide the best performance:
|
|
85
|
+
- `google/gemini-2.5-pro` - Excellent for complex reasoning
|
|
86
|
+
- `openai/gpt-4.1` - Strong general-purpose model
|
|
87
|
+
- `deepseek/deepseek-r1-0528` - Great for code generation
|
|
88
|
+
- `openai/gpt-4.1-mini` - Fast and cost-effective
|
|
89
|
+
- `anthropic/claude-4-sonnet-20250522` - Superior context handling
|
|
90
|
+
|
|
91
|
+
*Note: Formal evaluations coming soon. Any model can work, but these have shown the best results in practice.*
|
|
92
|
+
|
|
81
93
|
## Start Coding
|
|
82
94
|
|
|
83
95
|
```bash
|
|
@@ -105,6 +117,13 @@ TunaCode leverages parallel execution for read-only operations, achieving **3x f
|
|
|
105
117
|
|
|
106
118
|
Multiple file reads, directory listings, and searches execute concurrently using async I/O, making code exploration significantly faster.
|
|
107
119
|
|
|
120
|
+
## Features in Development
|
|
121
|
+
|
|
122
|
+
- **Streaming UI**: Currently working on implementing streaming responses for better user experience
|
|
123
|
+
- **Bug Fixes**: Actively addressing issues - please report any bugs you encounter!
|
|
124
|
+
|
|
125
|
+
*Note: While the tool is fully functional, we're focusing on stability and core features before optimizing for speed.*
|
|
126
|
+
|
|
108
127
|
## Safety First
|
|
109
128
|
|
|
110
129
|
⚠️ **Important**: TunaCode can modify your codebase. Always:
|
|
@@ -5,8 +5,6 @@ README.md
|
|
|
5
5
|
TUNACODE.md
|
|
6
6
|
pyproject.toml
|
|
7
7
|
setup.py
|
|
8
|
-
src/api/auth.py
|
|
9
|
-
src/api/users.py
|
|
10
8
|
src/tunacode/__init__.py
|
|
11
9
|
src/tunacode/constants.py
|
|
12
10
|
src/tunacode/context.py
|
|
@@ -92,16 +90,20 @@ tests/test_characterization_bash.py
|
|
|
92
90
|
tests/test_characterization_commands_system.py
|
|
93
91
|
tests/test_characterization_glob.py
|
|
94
92
|
tests/test_characterization_grep.py
|
|
93
|
+
tests/test_characterization_grep_performance.py
|
|
94
|
+
tests/test_characterization_iteration_limits.py
|
|
95
95
|
tests/test_characterization_list_dir.py
|
|
96
96
|
tests/test_characterization_read_file.py
|
|
97
97
|
tests/test_characterization_repl_utils.py
|
|
98
98
|
tests/test_characterization_run_command.py
|
|
99
99
|
tests/test_characterization_setup_system.py
|
|
100
|
+
tests/test_characterization_tool_ui_behavior.py
|
|
100
101
|
tests/test_characterization_update_file.py
|
|
101
102
|
tests/test_characterization_utilities.py
|
|
102
103
|
tests/test_characterization_write_file.py
|
|
103
104
|
tests/test_cli_command_flow.py
|
|
104
105
|
tests/test_cli_file_operations_integration.py
|
|
106
|
+
tests/test_config_directory_creation.py
|
|
105
107
|
tests/test_config_setup_async.py
|
|
106
108
|
tests/test_enhanced_visual_feedback.py
|
|
107
109
|
tests/test_fallback_responses.py
|
|
@@ -123,6 +125,7 @@ tests/test_parallel_tool_execution.py
|
|
|
123
125
|
tests/test_read_only_confirmation.py
|
|
124
126
|
tests/test_tool_categorization.py
|
|
125
127
|
tests/test_tool_combinations.py
|
|
128
|
+
tests/test_tool_handler_ui_messages.py
|
|
126
129
|
tests/test_update_command.py
|
|
127
130
|
tests/test_visual_parallel_feedback.py
|
|
128
131
|
tests/characterization/conftest.py
|
|
@@ -144,6 +147,13 @@ tests/characterization/code_index/test_file_scanning.py
|
|
|
144
147
|
tests/characterization/code_index/test_index_building.py
|
|
145
148
|
tests/characterization/code_index/test_search_operations.py
|
|
146
149
|
tests/characterization/code_index/test_symbol_extraction.py
|
|
150
|
+
tests/characterization/commands/__init__.py
|
|
151
|
+
tests/characterization/commands/test_init_command.py
|
|
152
|
+
tests/characterization/context/__init__.py
|
|
153
|
+
tests/characterization/context/test_context_acceptance.py
|
|
154
|
+
tests/characterization/context/test_context_integration.py
|
|
155
|
+
tests/characterization/context/test_context_loading.py
|
|
156
|
+
tests/characterization/context/test_tunacode_logging.py
|
|
147
157
|
tests/characterization/repl/test_command_parsing.py
|
|
148
158
|
tests/characterization/repl/test_input_handling.py
|
|
149
159
|
tests/characterization/repl/test_keyboard_interrupts.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tunacode
|
{tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/test_agent_creation.py
RENAMED
|
@@ -38,20 +38,22 @@ class TestAgentCreation:
|
|
|
38
38
|
with patch('tunacode.core.agents.main.get_agent_tool', return_value=(mock_agent_class, mock_tool_class)):
|
|
39
39
|
with patch('builtins.open', mock_open(read_data=system_prompt)):
|
|
40
40
|
with patch('tunacode.core.agents.main.get_mcp_servers', return_value=[]):
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
# Mock TUNACODE.md not existing to get predictable system prompt
|
|
42
|
+
with patch('pathlib.Path.exists', return_value=False):
|
|
43
|
+
# Act
|
|
44
|
+
result = get_or_create_agent(model, self.state_manager)
|
|
45
|
+
|
|
46
|
+
# Assert - Golden master
|
|
47
|
+
assert model in self.state_manager.session.agents
|
|
48
|
+
assert self.state_manager.session.agents[model] == mock_agent_class.return_value
|
|
49
|
+
|
|
50
|
+
# Verify agent was created with correct parameters
|
|
51
|
+
mock_agent_class.assert_called_once()
|
|
52
|
+
call_kwargs = mock_agent_class.call_args.kwargs
|
|
53
|
+
assert call_kwargs['model'] == model
|
|
54
|
+
assert call_kwargs['system_prompt'] == system_prompt
|
|
55
|
+
assert len(call_kwargs['tools']) == 8 # All 8 tools registered
|
|
56
|
+
assert call_kwargs['mcp_servers'] == []
|
|
55
57
|
|
|
56
58
|
def test_get_or_create_agent_cached(self):
|
|
57
59
|
"""Capture behavior when agent already exists."""
|
|
@@ -83,12 +85,14 @@ class TestAgentCreation:
|
|
|
83
85
|
with patch('tunacode.core.agents.main.get_agent_tool', return_value=(mock_agent_class, mock_tool_class)):
|
|
84
86
|
with patch('builtins.open', side_effect=mock_open_side_effect):
|
|
85
87
|
with patch('tunacode.core.agents.main.get_mcp_servers', return_value=[]):
|
|
86
|
-
#
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
# Mock TUNACODE.md not existing
|
|
89
|
+
with patch('pathlib.Path.exists', return_value=False):
|
|
90
|
+
# Act
|
|
91
|
+
result = get_or_create_agent(model, self.state_manager)
|
|
92
|
+
|
|
93
|
+
# Assert - Golden master
|
|
94
|
+
call_kwargs = mock_agent_class.call_args.kwargs
|
|
95
|
+
assert call_kwargs['system_prompt'] == fallback_prompt
|
|
92
96
|
|
|
93
97
|
def test_get_or_create_agent_default_prompt(self):
|
|
94
98
|
"""Capture behavior when neither prompt file exists."""
|
|
@@ -100,12 +104,14 @@ class TestAgentCreation:
|
|
|
100
104
|
with patch('tunacode.core.agents.main.get_agent_tool', return_value=(mock_agent_class, mock_tool_class)):
|
|
101
105
|
with patch('builtins.open', side_effect=FileNotFoundError):
|
|
102
106
|
with patch('tunacode.core.agents.main.get_mcp_servers', return_value=[]):
|
|
103
|
-
#
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
# Mock TUNACODE.md not existing
|
|
108
|
+
with patch('pathlib.Path.exists', return_value=False):
|
|
109
|
+
# Act
|
|
110
|
+
result = get_or_create_agent(model, self.state_manager)
|
|
111
|
+
|
|
112
|
+
# Assert - Golden master
|
|
113
|
+
call_kwargs = mock_agent_class.call_args.kwargs
|
|
114
|
+
assert call_kwargs['system_prompt'] == "You are a helpful AI assistant for software development tasks."
|
|
109
115
|
|
|
110
116
|
def test_get_or_create_agent_tools_registered(self):
|
|
111
117
|
"""Capture behavior of tool registration with max_retries."""
|
{tunacode_cli-0.0.32 → tunacode_cli-0.0.34}/tests/characterization/agent/test_process_request.py
RENAMED
|
@@ -37,7 +37,7 @@ class TestProcessRequest:
|
|
|
37
37
|
self.state_manager.session.user_config = {
|
|
38
38
|
"settings": {
|
|
39
39
|
"max_retries": 3,
|
|
40
|
-
"max_iterations":
|
|
40
|
+
"max_iterations": 40,
|
|
41
41
|
"fallback_response": True,
|
|
42
42
|
"fallback_verbosity": "normal"
|
|
43
43
|
}
|
|
@@ -250,11 +250,11 @@ class TestProcessRequest:
|
|
|
250
250
|
await process_request("openai:gpt-4", message, self.state_manager, AsyncMock())
|
|
251
251
|
|
|
252
252
|
# Assert - Golden master
|
|
253
|
-
calls = [call[0][0] for call in mock_muted.call_args_list]
|
|
253
|
+
calls = [str(call[0][0]) if call[0] else "" for call in mock_muted.call_args_list]
|
|
254
254
|
|
|
255
|
-
# Should show iteration progress
|
|
256
|
-
assert any("ITERATION: 1/
|
|
257
|
-
assert any("ITERATION: 2/
|
|
255
|
+
# Should show iteration progress (default is now 40)
|
|
256
|
+
assert any("ITERATION: 1/40" in call for call in calls)
|
|
257
|
+
assert any("ITERATION: 2/40" in call for call in calls)
|
|
258
258
|
|
|
259
259
|
# Should show tool summary
|
|
260
260
|
assert any("TOOLS USED: read_file: 2, bash: 1" in call for call in calls)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Characterization tests for individual commands."""
|