drydock-cli 1.3.9__tar.gz → 1.5.0__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.
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/PKG-INFO +1 -1
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/PRD.md +32 -1
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/agent_loop.py +72 -17
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/cli.md +15 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/search_replace.py +0 -10
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/pyproject.toml +1 -1
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/deploy_to_github.sh +2 -1
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/publish_to_pypi.sh +2 -1
- drydock_cli-1.5.0/scripts/test_bank.sh +78 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/test_full.sh +4 -0
- drydock_cli-1.5.0/tests/test_bank_build.py +572 -0
- drydock_cli-1.5.0/tests/test_bank_debug.py +1111 -0
- drydock_cli-1.5.0/tests/test_bank_multiagent.py +698 -0
- drydock_cli-1.5.0/tests/test_bank_tools.py +472 -0
- drydock_cli-1.5.0/tests/test_bank_update.py +938 -0
- drydock_cli-1.5.0/tests/test_build_projects.py +272 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_drydock_regression.py +2 -2
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_drydock_tasks.py +36 -12
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_loop_detection.py +65 -35
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_smoke.py +2 -3
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_user_issues.py +16 -11
- drydock_cli-1.5.0/tests/test_workloads.py +441 -0
- drydock_cli-1.5.0/tests/testbank_helpers.py +967 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/CODEOWNERS +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/workflows/ci.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.github/workflows/release.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.gitignore +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.pre-commit-config.yaml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.python-version +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.typos.toml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.vscode/extensions.json +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.vscode/launch.json +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/.vscode/settings.json +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/AGENTS.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/CHANGELOG.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/CLAUDE.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/CONTRIBUTING.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/Drydock_rebrand.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/LICENSE +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/NOTICE +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/README.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/action.yml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/distribution/zed/LICENSE +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/distribution/zed/extension.toml +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/docs/README.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/docs/acp-setup.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/docs/proxy-setup.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/acp/utils.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/cli.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/commands.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/agents/models.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/auth/github.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/consultant.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/hooks.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/format.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/llm/types.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/logger.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/middleware.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/plan_session.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/plugins.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/programmatic.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/skills/models.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/slug.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/base.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/task_manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/types.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/core/utils.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock/whats_new.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock-acp.spec +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/drydock_terms.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/flake.lock +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/flake.nix +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/README.md +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/backup.sh +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/bump_version.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/install.sh +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/prepare_release.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/scripts/test_smoke.sh +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/conftest.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_acp.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_bash.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_content.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_utils.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/test_backend.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_commands.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/conftest.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_agents.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_slug.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/core/test_utils.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/e2e/common.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/e2e/conftest.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/mock/__init__.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/mock/utils.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/skills/conftest.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/skills/test_manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/skills/test_models.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/skills/test_parser.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_agent_backend.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_agent_stats.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_agents.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_current_bugs.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_full_regression.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_history_manager.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_integration.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_message_id.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_message_merging.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_middleware.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_multi_agent.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_real_failures.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_real_issues.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_real_workflow.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_system_prompt.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_tagged_text.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_bash.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_grep.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_task.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-1.3.9 → drydock_cli-1.5.0}/uv.lock +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# DryDock — Local CLI Coding Agent
|
|
2
2
|
|
|
3
3
|
**Repository:** https://github.com/fbobe321/drydock
|
|
4
|
-
**PyPI:** https://pypi.org/project/drydock-cli/ (v1.
|
|
4
|
+
**PyPI:** https://pypi.org/project/drydock-cli/ (v1.5.0)
|
|
5
5
|
**License:** Apache 2.0 (fork of [mistralai/mistral-vibe](https://github.com/mistralai/mistral-vibe))
|
|
6
6
|
**Status:** Active development — continuous improvement running
|
|
7
7
|
|
|
@@ -21,6 +21,7 @@ Every change follows this pipeline:
|
|
|
21
21
|
Scripts:
|
|
22
22
|
- `scripts/test_smoke.sh` — quick smoke tests (every deploy)
|
|
23
23
|
- `scripts/test_full.sh` — smoke + full regression (nightly)
|
|
24
|
+
- `scripts/test_bank.sh` — 83-test regression bank (10-18 hours, real vLLM)
|
|
24
25
|
- `scripts/deploy_to_github.sh` — smoke tests → sync to GitHub (daily 4 AM)
|
|
25
26
|
- `scripts/publish_to_pypi.sh` — smoke tests → bump → build → PyPI → GitHub
|
|
26
27
|
- `scripts/backup.sh` — rsync to NAS (daily 3 AM)
|
|
@@ -248,3 +249,33 @@ Adding Python tools/agents doesn't matter if the prompt doesn't tell the model t
|
|
|
248
249
|
- Shows exact syntax for delegation
|
|
249
250
|
- Explicit WHEN to delegate rules (3+ files, reviews, bugs, planning)
|
|
250
251
|
- WHEN NOT to delegate (simple fixes, quick questions)
|
|
252
|
+
|
|
253
|
+
### Phase 11 (Mar 28): Agent Loop Hardening + 83-Test Regression Bank
|
|
254
|
+
|
|
255
|
+
User reported DryDock was unusable — model looped 12+ times running the same command, search_replace blocked legitimate files, basic tasks couldn't complete.
|
|
256
|
+
|
|
257
|
+
**Agent loop fixes (5 bugs):**
|
|
258
|
+
- Empty model response: retry 3x with nudge (model sometimes returns nothing)
|
|
259
|
+
- Invalid tool name recovery: model hallucinates `task_agent:`, now gets correct tool list
|
|
260
|
+
- Bash traceback guidance: extracts file:line from crash, directs model to read source
|
|
261
|
+
- Circuit breaker for successful repeats: blocks after 4 identical bash calls (was unlimited)
|
|
262
|
+
- Tighter loop detection: warning at 4 (was 8), force-stop at 8 (was 25)
|
|
263
|
+
|
|
264
|
+
**System prompt improvements:**
|
|
265
|
+
- Added debugging best practices: RUN → READ → FIX → VERIFY cycle
|
|
266
|
+
- Common bug pattern hints (TypeError, KeyError, IndexError, off-by-one)
|
|
267
|
+
|
|
268
|
+
**83-test regression bank (real vLLM backend, ~90 min):**
|
|
269
|
+
|
|
270
|
+
| Suite | Tests | Pass Rate |
|
|
271
|
+
|---|---|---|
|
|
272
|
+
| BUILD (easy/medium/hard) | 25 | 100% |
|
|
273
|
+
| DEBUG (easy/medium/hard) | 20 | 75% |
|
|
274
|
+
| UPDATE (easy/medium/hard) | 15 | 100% |
|
|
275
|
+
| MULTIAGENT | 10 | 100% |
|
|
276
|
+
| TOOLS | 13 | 100% |
|
|
277
|
+
| **Total** | **83** | **94%** |
|
|
278
|
+
|
|
279
|
+
Run with: `./scripts/test_bank.sh` (full) or `./scripts/test_bank.sh quick` (easy only, ~2h)
|
|
280
|
+
|
|
281
|
+
**Removed:** False-positive test file guard in search_replace that blocked any file in a directory containing "test" in its name.
|
|
@@ -124,8 +124,8 @@ class ToolDecision(BaseModel):
|
|
|
124
124
|
|
|
125
125
|
MAX_TOOL_TURNS = 200 # Bug fixes rarely need more than 50 turns; 200 is generous ceiling
|
|
126
126
|
MAX_API_ERRORS = 5
|
|
127
|
-
REPEAT_WARNING_THRESHOLD =
|
|
128
|
-
REPEAT_FORCE_STOP_THRESHOLD =
|
|
127
|
+
REPEAT_WARNING_THRESHOLD = 4 # Same exact call 4+ times before warning
|
|
128
|
+
REPEAT_FORCE_STOP_THRESHOLD = 8 # Same exact call 8+ times before force-stop
|
|
129
129
|
|
|
130
130
|
logger = logging.getLogger(__name__)
|
|
131
131
|
|
|
@@ -192,6 +192,7 @@ class AgentLoop:
|
|
|
192
192
|
# Key: hash(tool_name + args), Value: (count, last_result_snippet)
|
|
193
193
|
self._tool_call_history: dict[str, tuple[int, str]] = {}
|
|
194
194
|
self._consecutive_circuit_breaker_fires: int = 0
|
|
195
|
+
self._empty_responses: int = 0
|
|
195
196
|
|
|
196
197
|
system_prompt = get_universal_system_prompt(
|
|
197
198
|
self.tool_manager, self.config, self.skill_manager, self.agent_manager
|
|
@@ -534,9 +535,19 @@ class AgentLoop:
|
|
|
534
535
|
stopped_by_middleware=True,
|
|
535
536
|
)
|
|
536
537
|
return
|
|
537
|
-
#
|
|
538
|
-
|
|
539
|
-
|
|
538
|
+
# Check if the error is about invalid function/tool name
|
|
539
|
+
error_str = str(e)
|
|
540
|
+
if "Function name" in error_str or "function" in error_str.lower() and "must be" in error_str.lower():
|
|
541
|
+
# Model hallucinated a tool name — give it the correct list
|
|
542
|
+
available = ", ".join(sorted(self.tool_manager.available_tools.keys())[:15])
|
|
543
|
+
error_text = (
|
|
544
|
+
f"ERROR: You tried to call a tool that does not exist. "
|
|
545
|
+
f"Available tools: {available}. "
|
|
546
|
+
f"Use one of these exact tool names. "
|
|
547
|
+
f"For subagent delegation, use 'task'. For file search, use 'grep'."
|
|
548
|
+
)
|
|
549
|
+
else:
|
|
550
|
+
error_text = f"API error occurred: {e}. Please continue with your task."
|
|
540
551
|
self._inject_system_note(error_text)
|
|
541
552
|
continue
|
|
542
553
|
|
|
@@ -670,10 +681,26 @@ class AgentLoop:
|
|
|
670
681
|
|
|
671
682
|
should_break_loop = last_message.role != Role.tool
|
|
672
683
|
|
|
684
|
+
# Handle empty response (no content AND no tools) — retry
|
|
685
|
+
if (should_break_loop and last_message.role == Role.assistant
|
|
686
|
+
and not last_message.content and not last_message.tool_calls):
|
|
687
|
+
empty_response_count = getattr(self, '_empty_responses', 0) + 1
|
|
688
|
+
self._empty_responses = empty_response_count
|
|
689
|
+
if empty_response_count <= 3:
|
|
690
|
+
should_break_loop = False
|
|
691
|
+
self._inject_system_note(
|
|
692
|
+
"Your response was empty. You MUST call a tool. "
|
|
693
|
+
"Start by reading the relevant file with read_file, "
|
|
694
|
+
"or run the failing command with bash to see the error."
|
|
695
|
+
)
|
|
696
|
+
logger.warning("Empty model response — nudging (attempt %d)", empty_response_count)
|
|
697
|
+
continue
|
|
698
|
+
# After 3 empty responses, let it exit
|
|
699
|
+
|
|
673
700
|
# If model gives text without tool calls and hasn't edited anything,
|
|
674
701
|
# nudge it to make an edit instead of just describing what to do.
|
|
675
702
|
# Never let the agent exit without at least attempting an edit.
|
|
676
|
-
if should_break_loop and not has_made_edit and tool_turns >=
|
|
703
|
+
if should_break_loop and not has_made_edit and tool_turns >= 1:
|
|
677
704
|
text_without_action += 1
|
|
678
705
|
# Always continue — don't let the agent exit without editing
|
|
679
706
|
should_break_loop = False
|
|
@@ -742,8 +769,8 @@ class AgentLoop:
|
|
|
742
769
|
if rep == "FORCE_STOP":
|
|
743
770
|
repeat_warnings += 1
|
|
744
771
|
logger.warning("Detected infinite loop: same tool call %d+ times (warning %d)", REPEAT_FORCE_STOP_THRESHOLD, repeat_warnings)
|
|
745
|
-
if repeat_warnings >=
|
|
746
|
-
#
|
|
772
|
+
if repeat_warnings >= 5:
|
|
773
|
+
# Stop after 5 redirects — model is not recovering
|
|
747
774
|
yield AssistantEvent(
|
|
748
775
|
content="\n\n[Stopping: exhausted all retry attempts.]\n",
|
|
749
776
|
stopped_by_middleware=True,
|
|
@@ -773,7 +800,7 @@ class AgentLoop:
|
|
|
773
800
|
else:
|
|
774
801
|
repeat_warnings += 1
|
|
775
802
|
logger.warning("Detected repeated tool calls (warning %.1f, investigation=%s)", repeat_warnings, is_investigation_warning)
|
|
776
|
-
if repeat_warnings >=
|
|
803
|
+
if repeat_warnings >= 6:
|
|
777
804
|
yield AssistantEvent(
|
|
778
805
|
content="\n\n[Stopping: too many repeated actions despite warnings.]\n",
|
|
779
806
|
stopped_by_middleware=True,
|
|
@@ -792,7 +819,13 @@ class AgentLoop:
|
|
|
792
819
|
elif stuck_tool in ("grep",):
|
|
793
820
|
nudge = " You have been SEARCHING repeatedly. Pick the most relevant file from your search results and READ it, then make your edit."
|
|
794
821
|
elif stuck_tool in ("bash", "run_command"):
|
|
795
|
-
nudge =
|
|
822
|
+
nudge = (
|
|
823
|
+
" You have been running the SAME bash command repeatedly. "
|
|
824
|
+
"Running the same command again will give the same result. "
|
|
825
|
+
"If it succeeded but didn't do what you expected, READ the source code "
|
|
826
|
+
"to understand WHY, then FIX the code with search_replace. "
|
|
827
|
+
"If it failed, try a DIFFERENT command or approach."
|
|
828
|
+
)
|
|
796
829
|
if repeat_warnings >= 4:
|
|
797
830
|
# Escalated: replace tool result with strong directive
|
|
798
831
|
warning_text = (
|
|
@@ -935,10 +968,19 @@ class AgentLoop:
|
|
|
935
968
|
count, last_result = self._tool_call_history.get(sig, (0, ""))
|
|
936
969
|
is_failed = last_result.startswith("FAILED:") if last_result else False
|
|
937
970
|
|
|
938
|
-
#
|
|
939
|
-
#
|
|
940
|
-
#
|
|
941
|
-
|
|
971
|
+
# Block failed commands after 2 repeats.
|
|
972
|
+
# Block SUCCESSFUL commands after 4 repeats — the model should not
|
|
973
|
+
# run the exact same command with the exact same args 5+ times.
|
|
974
|
+
# Read-only checks (ls, pwd, git status) get a higher threshold.
|
|
975
|
+
tool_name = tool_call.tool_name
|
|
976
|
+
is_readonly = tool_name in ("grep", "read_file", "glob", "ls")
|
|
977
|
+
success_threshold = 6 if is_readonly else 4
|
|
978
|
+
|
|
979
|
+
if is_failed and count >= 2:
|
|
980
|
+
pass # will be blocked below
|
|
981
|
+
elif not is_failed and count >= success_threshold:
|
|
982
|
+
pass # will be blocked below
|
|
983
|
+
else:
|
|
942
984
|
return None
|
|
943
985
|
|
|
944
986
|
if count >= 2:
|
|
@@ -1161,6 +1203,19 @@ class AgentLoop:
|
|
|
1161
1203
|
"Add more surrounding context lines to old_str to make it unique.]"
|
|
1162
1204
|
)
|
|
1163
1205
|
|
|
1206
|
+
# RECOVERY: After bash failure with traceback, extract file/line and nudge
|
|
1207
|
+
if tool_call.tool_name in ("bash", "run_command") and "Traceback" in str(exc):
|
|
1208
|
+
import re
|
|
1209
|
+
# Extract last File "path", line N from traceback
|
|
1210
|
+
tb_matches = re.findall(r'File "([^"]+)", line (\d+)', str(exc))
|
|
1211
|
+
if tb_matches:
|
|
1212
|
+
tb_file, tb_line = tb_matches[-1]
|
|
1213
|
+
if not tb_file.startswith("/home") and not "site-packages" in tb_file:
|
|
1214
|
+
error_msg += (
|
|
1215
|
+
f"\n\n[NEXT STEP: Read the source at {tb_file} around line {tb_line} "
|
|
1216
|
+
f"with read_file to understand the bug, then fix it with search_replace.]"
|
|
1217
|
+
)
|
|
1218
|
+
|
|
1164
1219
|
yield ToolResultEvent(
|
|
1165
1220
|
tool_name=tool_call.tool_name,
|
|
1166
1221
|
tool_class=tool_call.tool_class,
|
|
@@ -1485,11 +1540,11 @@ class AgentLoop:
|
|
|
1485
1540
|
# Lower thresholds catch loops where the model uses the same tool
|
|
1486
1541
|
# with slightly different args (e.g., grep with different paths).
|
|
1487
1542
|
if last_tool in ("bash", "run_command"):
|
|
1488
|
-
same_tool_limit =
|
|
1543
|
+
same_tool_limit = 5
|
|
1489
1544
|
elif last_tool in ("grep", "read_file"):
|
|
1490
|
-
same_tool_limit =
|
|
1545
|
+
same_tool_limit = 7 # investigation tools need some room
|
|
1491
1546
|
else:
|
|
1492
|
-
same_tool_limit =
|
|
1547
|
+
same_tool_limit = 5
|
|
1493
1548
|
if (
|
|
1494
1549
|
len(tool_names) >= same_tool_limit
|
|
1495
1550
|
and all(n == tool_names[-1] for n in tool_names[-same_tool_limit:])
|
|
@@ -223,6 +223,21 @@ Error Handling:
|
|
|
223
223
|
- After ANY error, your next action must be DIFFERENT from what just failed.
|
|
224
224
|
- Never run the same failing command twice — the result won't change.
|
|
225
225
|
|
|
226
|
+
Debugging Best Practices:
|
|
227
|
+
When fixing bugs, follow this cycle: RUN → READ → FIX → VERIFY.
|
|
228
|
+
1. RUN the failing command to see the exact error (traceback, assertion, etc.)
|
|
229
|
+
2. READ the source file at the line mentioned in the traceback
|
|
230
|
+
3. FIX the bug with search_replace — common patterns:
|
|
231
|
+
- TypeError (str + int): add type conversion (int(), float(), str())
|
|
232
|
+
- KeyError: add .get() with default, or check key existence
|
|
233
|
+
- IndexError: fix loop bounds or add bounds check
|
|
234
|
+
- ImportError: fix the import path or module name
|
|
235
|
+
- Off-by-one: check if index starts at 0 or 1
|
|
236
|
+
- Missing return value: check if function returns in all paths
|
|
237
|
+
4. VERIFY by running the command again — if it still fails, read the NEW error
|
|
238
|
+
|
|
239
|
+
CRITICAL: After fixing a bug, ALWAYS run the command again to verify. Never assume your fix worked.
|
|
240
|
+
|
|
226
241
|
Context Budget:
|
|
227
242
|
Your context window is your most important resource. Every grep result and file read consumes it.
|
|
228
243
|
Performance degrades as context fills. Budget your investigation:
|
|
@@ -119,16 +119,6 @@ class SearchReplace(
|
|
|
119
119
|
) -> AsyncGenerator[ToolStreamEvent | SearchReplaceResult, None]:
|
|
120
120
|
file_path, search_replace_blocks = self._prepare_and_validate_args(args)
|
|
121
121
|
|
|
122
|
-
# BLOCK editing test files — the bug is in source code, not tests
|
|
123
|
-
file_str = str(file_path)
|
|
124
|
-
if ("/tests/" in file_str or "/test_" in file_str or
|
|
125
|
-
file_str.endswith("_test.py") or "/testing/" in file_str):
|
|
126
|
-
raise ToolError(
|
|
127
|
-
f"BLOCKED: You are trying to edit a test file ({file_path.name}). "
|
|
128
|
-
f"The bug is in LIBRARY SOURCE code, not tests. "
|
|
129
|
-
f"Use grep to find the corresponding source file and edit that instead."
|
|
130
|
-
)
|
|
131
|
-
|
|
132
122
|
# Injection guard: scan replacement content for suspicious patterns
|
|
133
123
|
from drydock.core.tools.injection_guard import check_content_for_injection
|
|
134
124
|
if warning := check_content_for_injection(args.content, args.file_path):
|
|
@@ -37,7 +37,8 @@ AUTH_URL="https://${GITHUB_TOKEN}@github.com/fbobe321/drydock.git"
|
|
|
37
37
|
|
|
38
38
|
log "Running regression tests..."
|
|
39
39
|
cd "$DRYDOCK_SRC"
|
|
40
|
-
|
|
40
|
+
python3 -m pip install -q "pytest>=9.0" 2>/dev/null
|
|
41
|
+
if ! python3 -m pytest tests/test_drydock_regression.py tests/test_drydock_tasks.py tests/test_loop_detection.py tests/test_agent_tasks.py tests/test_integration.py tests/test_user_issues.py tests/test_real_issues.py \
|
|
41
42
|
-p no:xdist -p no:cov --override-ini="addopts=" -q 2>&1; then
|
|
42
43
|
log "TESTS FAILED — deploy aborted. Fix the tests before deploying."
|
|
43
44
|
exit 1
|
|
@@ -25,7 +25,8 @@ PYPI_TOKEN=$(cat "$TOKEN_FILE")
|
|
|
25
25
|
|
|
26
26
|
# --- Run tests ---
|
|
27
27
|
log "Running regression tests..."
|
|
28
|
-
|
|
28
|
+
$PYTHON -m pip install -q "pytest>=9.0" 2>/dev/null
|
|
29
|
+
if ! $PYTHON -m pytest tests/test_drydock_regression.py tests/test_drydock_tasks.py tests/test_loop_detection.py tests/test_agent_tasks.py tests/test_integration.py tests/test_user_issues.py tests/test_real_issues.py \
|
|
29
30
|
-p no:xdist -p no:cov --override-ini="addopts=" -q 2>&1; then
|
|
30
31
|
log "TESTS FAILED — publish aborted."
|
|
31
32
|
exit 1
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# TEST BANK — Full regression suite against real vLLM backend.
|
|
3
|
+
# Requires vLLM at localhost:8000. Takes 10-18 hours.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./scripts/test_bank.sh # Run everything
|
|
7
|
+
# ./scripts/test_bank.sh build # Run only build tests
|
|
8
|
+
# ./scripts/test_bank.sh debug # Run only debug tests
|
|
9
|
+
# ./scripts/test_bank.sh update # Run only update tests
|
|
10
|
+
# ./scripts/test_bank.sh multi # Run only multi-agent tests
|
|
11
|
+
# ./scripts/test_bank.sh tools # Run only tool integration tests
|
|
12
|
+
# ./scripts/test_bank.sh quick # Run only easy tests (~2 hours)
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
cd "$(dirname "$0")/.."
|
|
16
|
+
|
|
17
|
+
pip install -q "pytest>=9.0" pytest-asyncio httpx 2>/dev/null
|
|
18
|
+
|
|
19
|
+
COMMON_ARGS="-v -s -p no:xdist -p no:cov --override-ini=addopts="
|
|
20
|
+
CATEGORY="${1:-all}"
|
|
21
|
+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
22
|
+
LOG_DIR="test_bank_results"
|
|
23
|
+
mkdir -p "$LOG_DIR"
|
|
24
|
+
|
|
25
|
+
run_suite() {
|
|
26
|
+
local name="$1"
|
|
27
|
+
local file="$2"
|
|
28
|
+
local extra="${3:-}"
|
|
29
|
+
echo ""
|
|
30
|
+
echo "================================================================"
|
|
31
|
+
echo " $name — $(date)"
|
|
32
|
+
echo "================================================================"
|
|
33
|
+
local logfile="$LOG_DIR/${name}_${TIMESTAMP}.log"
|
|
34
|
+
python3 -m pytest "$file" $COMMON_ARGS $extra 2>&1 | tee "$logfile"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Results saved to: $logfile"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
case "$CATEGORY" in
|
|
40
|
+
build)
|
|
41
|
+
run_suite "BUILD" "tests/test_bank_build.py"
|
|
42
|
+
;;
|
|
43
|
+
debug)
|
|
44
|
+
run_suite "DEBUG" "tests/test_bank_debug.py"
|
|
45
|
+
;;
|
|
46
|
+
update)
|
|
47
|
+
run_suite "UPDATE" "tests/test_bank_update.py"
|
|
48
|
+
;;
|
|
49
|
+
multi)
|
|
50
|
+
run_suite "MULTI-AGENT" "tests/test_bank_multiagent.py"
|
|
51
|
+
;;
|
|
52
|
+
tools)
|
|
53
|
+
run_suite "TOOLS" "tests/test_bank_tools.py"
|
|
54
|
+
;;
|
|
55
|
+
quick)
|
|
56
|
+
echo "=== QUICK TEST BANK (Easy tests only, ~2 hours) ==="
|
|
57
|
+
run_suite "BUILD-EASY" "tests/test_bank_build.py" "-k TestBuildEasy"
|
|
58
|
+
run_suite "DEBUG-EASY" "tests/test_bank_debug.py" "-k TestDebugEasy"
|
|
59
|
+
run_suite "UPDATE-EASY" "tests/test_bank_update.py" "-k TestUpdateEasy"
|
|
60
|
+
run_suite "TOOLS" "tests/test_bank_tools.py"
|
|
61
|
+
;;
|
|
62
|
+
all)
|
|
63
|
+
echo "=== FULL TEST BANK — Estimated 10-18 hours ==="
|
|
64
|
+
echo "=== Started: $(date) ==="
|
|
65
|
+
run_suite "BUILD" "tests/test_bank_build.py"
|
|
66
|
+
run_suite "DEBUG" "tests/test_bank_debug.py"
|
|
67
|
+
run_suite "UPDATE" "tests/test_bank_update.py"
|
|
68
|
+
run_suite "MULTI-AGENT" "tests/test_bank_multiagent.py"
|
|
69
|
+
run_suite "TOOLS" "tests/test_bank_tools.py"
|
|
70
|
+
echo ""
|
|
71
|
+
echo "=== FULL TEST BANK COMPLETE — $(date) ==="
|
|
72
|
+
echo "Results in: $LOG_DIR/"
|
|
73
|
+
;;
|
|
74
|
+
*)
|
|
75
|
+
echo "Usage: $0 {all|build|debug|update|multi|tools|quick}"
|
|
76
|
+
exit 1
|
|
77
|
+
;;
|
|
78
|
+
esac
|
|
@@ -11,3 +11,7 @@ python3 -m pytest tests/test_smoke.py -p no:xdist -p no:cov --override-ini="addo
|
|
|
11
11
|
echo ""
|
|
12
12
|
echo "=== FULL REGRESSION (real backend) ==="
|
|
13
13
|
python3 -m pytest tests/test_full_regression.py -v -p no:xdist -p no:cov --override-ini="addopts="
|
|
14
|
+
|
|
15
|
+
echo ""
|
|
16
|
+
echo "=== BUILD PROJECT TESTS (real backend, 30-60 min) ==="
|
|
17
|
+
python3 -m pytest tests/test_build_projects.py -v -s -p no:xdist -p no:cov --override-ini="addopts="
|