drydock-cli 2.6.22__tar.gz → 2.6.25__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-2.6.25/.auto_release.lock +1 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.gitignore +1 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/CLAUDE.md +221 -28
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/PKG-INFO +1 -1
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/agent_loop.py +206 -0
- drydock_cli-2.6.25/drydock/core/tools/builtins/write_file.py +412 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/pyproject.toml +1 -1
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/auto_release.sh +6 -0
- drydock_cli-2.6.25/scripts/run_pain_suite.sh +73 -0
- drydock_cli-2.6.25/scripts/user_pain_test.py +589 -0
- drydock_cli-2.6.25/tests/fixtures/doc_qa_system_prd.md +86 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_smoke.py +1 -1
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_tool_args.py +1 -1
- drydock_cli-2.6.22/.auto_release.lock +0 -1
- drydock_cli-2.6.22/drydock/core/tools/builtins/write_file.py +0 -202
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.python-version +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.typos.toml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.vscode/extensions.json +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.vscode/launch.json +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/.vscode/settings.json +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/AGENTS.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/CHANGELOG.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/LICENSE +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/NOTICE +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/PRD.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/README.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/action.yml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/docs/README.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/docs/acp-setup.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/logger.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/slug.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/base.py +0 -0
- /drydock_cli-2.6.22/drydock/core/tools/builtins/task_manager.py → /drydock_cli-2.6.25/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/types.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/core/utils.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock/whats_new.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock-acp.spec +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/drydock_terms.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/flake.lock +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/flake.nix +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/log_analyzer/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/log_analyzer/__main__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/log_analyzer/analyzer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/log_analyzer/cli.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/README.md +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/backup.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/bump_version.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/discover_cli_tools.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/install.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/notify_release.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/test_full.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/test_tui_path.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/tui_test.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/conftest.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/e2e/common.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/mock/utils.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_agents.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_integration.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_message_id.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_middleware.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/test_workloads.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.6.22 → drydock_cli-2.6.25}/uv.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
199791
|
|
@@ -4,17 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
Drydock is a local CLI coding agent (fork of mistral-vibe, Apache 2.0).
|
|
6
6
|
- **Repo:** https://github.com/fbobe321/drydock
|
|
7
|
-
- **PyPI:** https://pypi.org/project/drydock-cli/ (v2.
|
|
8
|
-
- **Goal:** Reliable TUI coding agent with local LLMs. PRD-driven project building
|
|
7
|
+
- **PyPI:** https://pypi.org/project/drydock-cli/ (v2.6.23 — v2.6.24 built but unreleased)
|
|
8
|
+
- **Goal:** Reliable TUI coding agent with local LLMs. PRD-driven project building.
|
|
9
9
|
- **Hardware:** 2x RTX 4060 Ti 16GB, Gemma 4 26B MoE (A4B) via vLLM Docker at localhost:8000
|
|
10
10
|
- **Server:** remus (Ubuntu 22.04, user: bobef)
|
|
11
11
|
- **Active model:** Gemma 4 26B-A4B-it-AWQ-4bit (only 4B active params, ~70 tok/s)
|
|
12
|
-
- **
|
|
13
|
-
-
|
|
14
|
-
|
|
12
|
+
- **The honest test:** `scripts/user_pain_test.py` user-pain harness — pass means real
|
|
13
|
+
user-perceptible behaviour, not tool-call counts. See `scripts/run_pain_suite.sh`
|
|
14
|
+
for the 10-project core set.
|
|
15
|
+
- **OLD harnesses you should NOT trust:** `scripts/tui_test.py` and
|
|
16
|
+
`core_tests_real.sh` count tool calls and `--help` and miss the things users
|
|
17
|
+
actually experience (loops the model ignores, hallucinated tool names that
|
|
18
|
+
hang the session, models that declare done with broken code, 2-minute
|
|
19
|
+
generation pauses). They produce passing scores while real usage fails.
|
|
15
20
|
- **Priority:** TUI experience first. Fix drydock bugs, don't simplify PRDs.
|
|
16
21
|
- **370 PRDs** at /data3/drydock_test_projects/ — the benchmark suite
|
|
17
|
-
- **Current version:** v2.
|
|
22
|
+
- **Current version:** v2.6.23 on PyPI / v2.6.24 built locally (unreleased)
|
|
18
23
|
|
|
19
24
|
## Build & Test
|
|
20
25
|
|
|
@@ -256,37 +261,217 @@ v3 is a from-scratch rewrite using nano-claude-code as foundation. 4 core files,
|
|
|
256
261
|
- ✅ Docker-based model serving (vLLM + Gemma 4)
|
|
257
262
|
- ✅ Multi-backend SWE-bench harness (v2/devstral + v3/gemma4)
|
|
258
263
|
- ✅ Thinking token filtering (Gemma 4 `<|channel>` leak)
|
|
264
|
+
- ✅ **User-pain harness** (`scripts/user_pain_test.py`) — drives real TUI
|
|
265
|
+
via pexpect, watches live session log, types `STOP` interrupts,
|
|
266
|
+
judges on user-perceptible criteria
|
|
267
|
+
- ✅ **Multi-PRD pain suite** (`scripts/run_pain_suite.sh`) — 10 core
|
|
268
|
+
projects through the user-pain harness
|
|
269
|
+
- ✅ **`_check_main_module_entry`** in write_file.py — catches
|
|
270
|
+
`__main__.py` files that import `main` but never call it (the codec
|
|
271
|
+
silent-exit bug)
|
|
272
|
+
- ✅ **`_check_missing_sibling_imports`** in write_file.py — catches
|
|
273
|
+
`from .cli import CLI` when `cli.py` doesn't exist on disk yet (the
|
|
274
|
+
minivc unimportable-package bug)
|
|
275
|
+
- ✅ **Escalating dedup message** in write_file.py — 2nd+ identical-content
|
|
276
|
+
write to a path returns the actual current directory listing plus
|
|
277
|
+
concrete next-action suggestions, instead of abstract "move to next file"
|
|
278
|
+
- ✅ **Loop-detection wiring** in agent_loop.py — `_check_tool_call_repetition()`
|
|
279
|
+
was defined but never called; now fires from `_handle_tool_response()`
|
|
280
|
+
and injects an advisory nudge via `_inject_system_note()`, rate-limited
|
|
281
|
+
every 3 turns
|
|
282
|
+
- ✅ **`_truncate_old_tool_results`** in agent_loop.py — proactive
|
|
283
|
+
shrinkage of stale tool results before each LLM call; keeps the last
|
|
284
|
+
6 in full, truncates older ones > 800 bytes to head + footer + size
|
|
285
|
+
marker; idempotent
|
|
286
|
+
- ✅ **`_task_manager.py` rename** — TaskCreate/Update/List were
|
|
287
|
+
duplicates of the `todo` tool that confused Gemma 4 into hanging.
|
|
288
|
+
Underscore prefix excludes them from tool discovery
|
|
289
|
+
- ✅ **Trust dialog auto-dismissal** in user_pain_test.py
|
|
290
|
+
- ✅ **Pause flags** for both `auto_release.sh` and `watchdog.sh` so
|
|
291
|
+
manual debugging doesn't get its work overwritten
|
|
259
292
|
|
|
260
293
|
**Legal note:** All patterns are standard design concepts implemented from scratch. No proprietary code copied.
|
|
261
294
|
|
|
262
295
|
## Key Learnings
|
|
263
296
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
297
|
+
### Most-recent (debugging the user's worst session, April 2026)
|
|
298
|
+
|
|
299
|
+
1. **Test-harness counts are not user pain.** `tui_test.py` and
|
|
300
|
+
`core_tests_real.sh` reported 80% pass while real users saw drydock
|
|
301
|
+
loop, hang, and produce broken code. The harnesses were structurally
|
|
302
|
+
incapable of catching what users experience because they measure
|
|
303
|
+
tool-call counts and `--help` exit codes, not progress. Build pass
|
|
304
|
+
criteria around user-perceptible state instead. See `user_pain_test.py`.
|
|
305
|
+
2. **Gemma 4 ignores advisory nudges.** The model received the dedup
|
|
306
|
+
message ("File already has this exact content. Move to the NEXT file."),
|
|
307
|
+
the loop-detection system note, the missing-import warning, AND a
|
|
308
|
+
user-typed `STOP` interrupt — its own thinking tokens ACKNOWLEDGED
|
|
309
|
+
the loop ("The user is pointing out that I am in a loop... I should
|
|
310
|
+
move to the next file") — and kept writing the same file 10 times
|
|
311
|
+
anyway. The advisory-only rule is correct in principle, but Gemma 4
|
|
312
|
+
cannot reliably respond to it. Hard blocks on pure no-op duplicates
|
|
313
|
+
may eventually be necessary.
|
|
314
|
+
3. **The auto_release.sh cron silently reverts site-packages every 6 hours.**
|
|
315
|
+
It runs at 0/6/12/18, builds a wheel from `/data3/drydock`, uploads to
|
|
316
|
+
PyPI, and `pip install --force-reinstall`s into the user's env. Direct
|
|
317
|
+
edits to `site-packages/drydock/...` disappear at the next cron tick.
|
|
318
|
+
Pause via `touch /data3/drydock/.pause_auto_release`.
|
|
319
|
+
4. **`/data3/drydock` is in `sys.path`, but site-packages comes first.**
|
|
320
|
+
`import drydock; print(drydock.__file__)` lies depending on cwd. From
|
|
321
|
+
`/data3/drydock` it reports the source tree (cwd is `""` at index 0).
|
|
322
|
+
From any project cwd it reports site-packages. **Always validate
|
|
323
|
+
imports from a neutral cwd.**
|
|
324
|
+
5. **PRDs get contaminated across sessions.** The model edits `PRD.md`
|
|
325
|
+
during a session (adds "✅ Completed" status tables, chat-style
|
|
326
|
+
filler text). The next test run sees a "completed" PRD and either
|
|
327
|
+
declares done immediately or hallucinates fix actions. Snapshot
|
|
328
|
+
`PRD.master.md` before each run; the harness restores it automatically.
|
|
329
|
+
6. **Hallucinated tool names hang the session.** The model called
|
|
330
|
+
`ralph_repo_index({"directory": "."})` — a tool that doesn't exist.
|
|
331
|
+
`_build_tool_call_events()` had `if tool_class is None: continue` which
|
|
332
|
+
silently dropped the call. Drydock waited forever for a tool result
|
|
333
|
+
that never came. `resolve_tool_calls()` correctly emits a `FailedToolCall`
|
|
334
|
+
downstream — both code paths exist; verify which one the model is hitting.
|
|
335
|
+
7. **The "Trust this folder?" dialog blocks all input.** Drydock pops a
|
|
336
|
+
blocking modal the first time it opens an unfamiliar directory. The
|
|
337
|
+
harness used to type the user prompt blindly into it; the dialog ate
|
|
338
|
+
the keystrokes and drydock waited forever. The fix: detect the dialog
|
|
339
|
+
in pexpect output, send Left+Enter to answer Yes. The harness now does
|
|
340
|
+
this. The CLI should never strand users on a modal dialog.
|
|
341
|
+
8. **Context-bloat eats first-turn latency.** Drydock includes the system
|
|
342
|
+
prompt + 24 tool definitions + AGENTS.md auto-injection + user message
|
|
343
|
+
on every turn. With Gemma 4 `thinking="high"` the first response can
|
|
344
|
+
take 60–130 seconds even on a small project, because the model is
|
|
345
|
+
generating ~1000 thinking tokens at ~70 tok/s. `auto_compact_threshold`
|
|
346
|
+
defaults to 200K (higher than Gemma 4's 131K max context) so it never
|
|
347
|
+
fires. Lower it per-model, and rely on `_truncate_old_tool_results()`
|
|
348
|
+
to shrink stale `read_file` outputs proactively.
|
|
349
|
+
9. **`task_manager.py` (TaskCreate/Update/List) confused Gemma 4** — the
|
|
350
|
+
model mixed it up with the existing `todo` tool, called `task_update`
|
|
351
|
+
on a `todo` ID, hung waiting on the response. Renamed to
|
|
352
|
+
`_task_manager.py` so the auto-discovery loop in `tools/manager.py`
|
|
353
|
+
skips it (it skips files starting with `_`). The classes are still
|
|
354
|
+
importable for tests via the new module name.
|
|
355
|
+
10. **Variance is the rule, not the exception.** Same code, same prompt,
|
|
356
|
+
same model: codec passed in run 1 of the suite and triggered all 3
|
|
357
|
+
pain criteria in run 2. Always state both numbers honestly. Don't
|
|
358
|
+
cherry-pick the run that worked.
|
|
359
|
+
|
|
360
|
+
### Older but still relevant
|
|
361
|
+
|
|
362
|
+
11. **Test the TUI, not headless.** Headless passes mask real bugs. TUI
|
|
363
|
+
has different code paths (streaming, approval, render_path_prompt).
|
|
364
|
+
ALL testing through TUI via pexpect.
|
|
365
|
+
12. **Use PRDs for testing.** Concrete PRDs with expected files give
|
|
366
|
+
clear pass/fail. The 370-PRD suite is at /data3/drydock_test_projects/.
|
|
367
|
+
13. **Scaffold per model.** Weaker models need more guardrails
|
|
368
|
+
(non-streaming, fewer tools, simpler prompts). As models improve,
|
|
369
|
+
remove scaffolding.
|
|
370
|
+
14. **Streaming breaks Gemma 4 tool calls.** Non-streaming gets the
|
|
371
|
+
complete response so JSON args are valid. Set `enable_streaming=False`
|
|
372
|
+
when model is Gemma 4.
|
|
373
|
+
15. **Fewer tools = better for local models.** 24 builtins is already a
|
|
374
|
+
lot for Gemma 4. The auto-injected list of 39 user-installed CLI
|
|
375
|
+
tools makes it worse.
|
|
376
|
+
16. **Simple prompts win.** The 125-line `cli.md` with phases/delegation
|
|
377
|
+
confused Gemma 4. The 20-line `gemma4.md` ("ACT IMMEDIATELY") works.
|
|
378
|
+
17. **AGENTS.md essential for devstral, not needed for Gemma 4.**
|
|
379
|
+
18. **Circuit breaker was net negative — removed entirely.**
|
|
380
|
+
19. **Loop detection should guide, never stop.** Per the user's rule.
|
|
381
|
+
See learning #2 for the limit of this rule.
|
|
382
|
+
20. **Auto-read on failed edit, temperature bump on loops, failed-approach
|
|
383
|
+
accumulator** — additive context techniques that help.
|
|
280
384
|
|
|
281
385
|
## Testing
|
|
282
386
|
|
|
283
|
-
###
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
387
|
+
### Use `scripts/user_pain_test.py` — anything else lies
|
|
388
|
+
|
|
389
|
+
The `user_pain_test.py` harness is the only test infrastructure that catches what
|
|
390
|
+
real users experience. Older harnesses (`tui_test.py`, `core_tests_real.sh`,
|
|
391
|
+
`run_real_tests.sh`) measure tool counts and `--help` exit codes; they pass
|
|
392
|
+
while real users see loops and hangs.
|
|
393
|
+
|
|
394
|
+
**How it works:**
|
|
395
|
+
- Drives the real `drydock` TUI via pexpect (no headless mode)
|
|
396
|
+
- Sends a vague user-style prompt ("review the PRD and build the package")
|
|
397
|
+
- Polls the live `~/.vibe/logs/session/session_<id>/messages.jsonl` in parallel
|
|
398
|
+
- Watches for write loops, search_replace cascades, hallucinated-tool hangs
|
|
399
|
+
- Types simulated `STOP` interrupts when loops are detected, then tracks
|
|
400
|
+
whether the model OBEYS them
|
|
401
|
+
- Distinguishes three end-states:
|
|
402
|
+
- **Active turn** (any new message in the last 120s) → keep going
|
|
403
|
+
- **Done** (last assistant has text content with no tool call) → grace 30s, then PASS
|
|
404
|
+
- **Dead silence** (no new messages of any kind for 120s) → FAIL
|
|
405
|
+
- Resets the cwd between runs (restores `PRD.md` from `PRD.master.md` if present,
|
|
406
|
+
wipes the package dir and stale data dirs)
|
|
407
|
+
- Auto-handles the "Trust this folder?" dialog drydock pops on new directories
|
|
408
|
+
|
|
409
|
+
**Pass criteria (ALL must hold):**
|
|
410
|
+
1. NO write loops (≥3 identical-content writes to a path)
|
|
411
|
+
2. NO ignored user `STOP` interrupts
|
|
412
|
+
3. NO search_replace failure cascade (≥3 in a row)
|
|
413
|
+
4. `python3 -m <pkg> --help` actually works
|
|
414
|
+
5. Session under `MAX_SESSION_SECONDS` (default 600)
|
|
415
|
+
|
|
416
|
+
**Run a single project:**
|
|
288
417
|
|
|
289
|
-
|
|
418
|
+
```bash
|
|
419
|
+
PYTHONUNBUFFERED=1 python3 -u scripts/user_pain_test.py \
|
|
420
|
+
--cwd /data3/test_drydock \
|
|
421
|
+
--prompt "review the PRD and get started" \
|
|
422
|
+
--pkg doc_qa_system
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
**Run the 10-project core suite:**
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
bash scripts/run_pain_suite.sh
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Real-world results from the harness (after recent fixes):**
|
|
432
|
+
- 4/4 on the small suite (roman_converter, prime_tool, todo_list, codec)
|
|
433
|
+
with real functional verification: codec round-trips work, todo_list
|
|
434
|
+
workflow works, prime check works.
|
|
435
|
+
- Variance is real — codec passed in one suite run and FAILED with a
|
|
436
|
+
3-criteria loop in the next. Same code, same prompt. Document this when
|
|
437
|
+
reporting.
|
|
438
|
+
|
|
439
|
+
### Fixture: `tests/fixtures/doc_qa_system_prd.md`
|
|
440
|
+
|
|
441
|
+
The PRD that originally exposed the user's worst session (10 identical
|
|
442
|
+
`__init__.py` writes, hallucinated `ralph_repo_index` tool, contaminated
|
|
443
|
+
PRD across sessions, 13-min runtime) is checked in. Use it as the canary
|
|
444
|
+
case for any harness work.
|
|
445
|
+
|
|
446
|
+
### Two cron pause flags you should know about
|
|
447
|
+
|
|
448
|
+
Both crons silently overwrite work mid-debug. Pause them when iterating:
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
touch /data3/drydock_test_projects/.pause_watchdog # stops watchdog.sh
|
|
452
|
+
touch /data3/drydock/.pause_auto_release # stops auto_release.sh
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
`auto_release.sh` runs at 0/6/12/18, builds a wheel from `/data3/drydock`,
|
|
456
|
+
uploads to PyPI, and `pip install --force-reinstall`s it into the user's env.
|
|
457
|
+
That overwrites any direct site-packages edits. **If your fix doesn't
|
|
458
|
+
survive the next cron run, it's because you only edited `/data3/drydock` —
|
|
459
|
+
auto_release rebuilds from there but ALSO replaces site-packages.** Commit
|
|
460
|
+
your fix to source AND verify it landed via `git log --oneline -5` before
|
|
461
|
+
expecting persistence.
|
|
462
|
+
|
|
463
|
+
### Why direct site-packages edits keep disappearing
|
|
464
|
+
|
|
465
|
+
`/home/bobef/miniforge3/envs/drydock/lib/python3.14/site-packages` comes
|
|
466
|
+
before `/data3/drydock` in `sys.path` from a project cwd, even though the
|
|
467
|
+
`_drydock.pth` file adds `/data3/drydock`. So a sanity check from
|
|
468
|
+
`/data3/drydock` (`import drydock; print(drydock.__file__)`) lies — it
|
|
469
|
+
reports `/data3/drydock/drydock/__init__.py` because cwd-`""` is at index 0.
|
|
470
|
+
From `/data3/drydock_test_projects/X` it reports the site-packages path.
|
|
471
|
+
**Always test imports from a neutral cwd**, OR commit to source AND let
|
|
472
|
+
auto_release rebuild.
|
|
473
|
+
|
|
474
|
+
### Test Levels (kept for reference, but the user-pain harness covers all of them)
|
|
290
475
|
1. **Build test (--help):** package runs — MEANINGLESS alone
|
|
291
476
|
2. **Functional test:** PRD test cases verified with correct output — THE REAL TEST
|
|
292
477
|
3. **Acceptance test:** specific expected outputs verified
|
|
@@ -298,6 +483,14 @@ v3 is a from-scratch rewrite using nano-claude-code as foundation. 4 core files,
|
|
|
298
483
|
- Safety mechanisms must be ADVISORY not BLOCKING
|
|
299
484
|
- NEVER add circuit breakers that prevent legitimate work
|
|
300
485
|
- The model should be able to answer questions without being forced to edit files
|
|
486
|
+
- **NEVER trust an old harness's pass result.** If `tui_test.py` or
|
|
487
|
+
`core_tests_real.sh` says PASS, run the same project through
|
|
488
|
+
`user_pain_test.py` to confirm. The old harnesses count `--help` and
|
|
489
|
+
silently miss the things users hate.
|
|
490
|
+
- **Always reset PRDs between runs.** The model edits PRD.md (adds
|
|
491
|
+
"✅ Completed" status tables, chat-style filler) and contaminates
|
|
492
|
+
subsequent test runs. The harness restores from `PRD.master.md`
|
|
493
|
+
automatically if present.
|
|
301
494
|
|
|
302
495
|
## When Compacting
|
|
303
496
|
|
|
@@ -1079,6 +1079,33 @@ class AgentLoop:
|
|
|
1079
1079
|
f"Do NOT run another bash command until you have fixed the code."
|
|
1080
1080
|
)
|
|
1081
1081
|
|
|
1082
|
+
# RECOVERY: hard-blocked duplicate write_file. When write_file raises
|
|
1083
|
+
# "BLOCKED: ... has been called N times with IDENTICAL content", the
|
|
1084
|
+
# model has a history full of identical no-op writes. Prune those from
|
|
1085
|
+
# message history so the model's next turn sees a cleaner context and
|
|
1086
|
+
# is less likely to re-trigger the same loop.
|
|
1087
|
+
#
|
|
1088
|
+
# Pruning is safe here because the duplicates are by definition no-ops
|
|
1089
|
+
# against the file on disk — deleting the history preserves actual
|
|
1090
|
+
# state. We keep the most recent write attempt (which is the one that
|
|
1091
|
+
# just got blocked) so the model sees the error.
|
|
1092
|
+
if (
|
|
1093
|
+
tool_call.tool_name == "write_file"
|
|
1094
|
+
and "BLOCKED:" in str(exc)
|
|
1095
|
+
and "IDENTICAL content" in str(exc)
|
|
1096
|
+
):
|
|
1097
|
+
try:
|
|
1098
|
+
target_path = ""
|
|
1099
|
+
try:
|
|
1100
|
+
wf_args = json.loads(tool_call.raw_arguments or "{}")
|
|
1101
|
+
target_path = wf_args.get("path", "")
|
|
1102
|
+
except (json.JSONDecodeError, AttributeError):
|
|
1103
|
+
pass
|
|
1104
|
+
if target_path:
|
|
1105
|
+
self._prune_duplicate_writes(target_path)
|
|
1106
|
+
except Exception as prune_exc:
|
|
1107
|
+
logger.debug("Prune after block failed: %s", prune_exc)
|
|
1108
|
+
|
|
1082
1109
|
yield ToolResultEvent(
|
|
1083
1110
|
tool_name=tool_call.tool_name,
|
|
1084
1111
|
tool_class=tool_call.tool_class,
|
|
@@ -1125,6 +1152,18 @@ class AgentLoop:
|
|
|
1125
1152
|
)
|
|
1126
1153
|
)
|
|
1127
1154
|
|
|
1155
|
+
# Advisory loop detection: inject nudge when the model keeps repeating
|
|
1156
|
+
# the same call. Never blocks, never stops — just steers the model toward
|
|
1157
|
+
# a different approach. Catches the 28-identical-bash-calls failure mode.
|
|
1158
|
+
try:
|
|
1159
|
+
repetition = self._check_tool_call_repetition()
|
|
1160
|
+
if repetition:
|
|
1161
|
+
nudge = self._build_repetition_nudge(repetition, tool_call)
|
|
1162
|
+
if nudge:
|
|
1163
|
+
self._inject_system_note(nudge)
|
|
1164
|
+
except Exception as e:
|
|
1165
|
+
logger.debug("Loop detection check failed: %s", e)
|
|
1166
|
+
|
|
1128
1167
|
self.telemetry_client.send_tool_call_finished(
|
|
1129
1168
|
tool_call=tool_call,
|
|
1130
1169
|
agent_profile_name=self.agent_profile.name,
|
|
@@ -1133,6 +1172,169 @@ class AgentLoop:
|
|
|
1133
1172
|
result=result,
|
|
1134
1173
|
)
|
|
1135
1174
|
|
|
1175
|
+
def _build_repetition_nudge(
|
|
1176
|
+
self, signal: str, tool_call: ResolvedToolCall
|
|
1177
|
+
) -> str | None:
|
|
1178
|
+
"""Build an advisory nudge for the model when a loop is detected.
|
|
1179
|
+
|
|
1180
|
+
Returns None if the tool call was already nudged recently (prevents
|
|
1181
|
+
spamming the model with the same message on every turn).
|
|
1182
|
+
"""
|
|
1183
|
+
# Rate-limit: don't nudge more than once every 3 turns for the same tool
|
|
1184
|
+
last_nudge_turn = getattr(self, "_last_nudge_turn", -10)
|
|
1185
|
+
current_turn = len(self.messages)
|
|
1186
|
+
if current_turn - last_nudge_turn < 3:
|
|
1187
|
+
return None
|
|
1188
|
+
self._last_nudge_turn = current_turn
|
|
1189
|
+
|
|
1190
|
+
tool_name = tool_call.tool_name
|
|
1191
|
+
if signal == "FORCE_STOP":
|
|
1192
|
+
return (
|
|
1193
|
+
f"You have called `{tool_name}` with the SAME arguments 8+ times "
|
|
1194
|
+
f"and gotten the same result each time. This is a dead end. "
|
|
1195
|
+
f"You MUST change your approach:\n"
|
|
1196
|
+
f"- For bash: if output is empty, read the source files to find the bug — "
|
|
1197
|
+
f" don't just re-run the command\n"
|
|
1198
|
+
f"- For write_file/search_replace: if the file already has your content, "
|
|
1199
|
+
f" move on to the NEXT file\n"
|
|
1200
|
+
f"- If stuck, inspect the actual file contents with read_file before editing"
|
|
1201
|
+
)
|
|
1202
|
+
if signal.startswith("WARNING|"):
|
|
1203
|
+
stuck_tool = signal.split("|", 1)[1] or tool_name
|
|
1204
|
+
if stuck_tool == "bash":
|
|
1205
|
+
return (
|
|
1206
|
+
f"You have run very similar `bash` commands several times in a row. "
|
|
1207
|
+
f"If the output is empty or unchanged, the command is not the problem — "
|
|
1208
|
+
f"the CODE is. Use read_file to inspect the source, then write_file or "
|
|
1209
|
+
f"search_replace to fix the bug. Do not re-run the same command again."
|
|
1210
|
+
)
|
|
1211
|
+
if stuck_tool in ("write_file", "search_replace"):
|
|
1212
|
+
return (
|
|
1213
|
+
f"You have written the same file multiple times in a row. "
|
|
1214
|
+
f"Move to the NEXT file in your plan. If no next file, run the code "
|
|
1215
|
+
f"with bash to verify it works."
|
|
1216
|
+
)
|
|
1217
|
+
return (
|
|
1218
|
+
f"You have called `{stuck_tool}` several times in a row with similar "
|
|
1219
|
+
f"arguments. Try a different tool or a different approach."
|
|
1220
|
+
)
|
|
1221
|
+
return None
|
|
1222
|
+
|
|
1223
|
+
def _prune_duplicate_writes(self, target_path: str) -> None:
|
|
1224
|
+
"""Remove assistant-write_file / tool-result pairs for a looping path.
|
|
1225
|
+
|
|
1226
|
+
Called after the hard-block fires on a write_file call. By that point
|
|
1227
|
+
the message history contains 3+ identical no-op write attempts to
|
|
1228
|
+
`target_path`, which bloats context and keeps nudging the model back
|
|
1229
|
+
toward the same action. Pruning them out gives the next turn a
|
|
1230
|
+
cleaner view.
|
|
1231
|
+
|
|
1232
|
+
We keep:
|
|
1233
|
+
- the system prompt + first user message (they anchor the task)
|
|
1234
|
+
- the MOST RECENT write_file+result pair for this path (the one
|
|
1235
|
+
that just triggered the block — its error message is what the
|
|
1236
|
+
model needs to see)
|
|
1237
|
+
- everything unrelated to target_path
|
|
1238
|
+
|
|
1239
|
+
We drop:
|
|
1240
|
+
- older write_file(path=target_path) assistant messages
|
|
1241
|
+
- their matching tool result messages
|
|
1242
|
+
|
|
1243
|
+
This only prunes write_file calls where the path matches exactly and
|
|
1244
|
+
where the write_file is the ONLY tool call in that assistant message
|
|
1245
|
+
(to avoid removing unrelated calls in a multi-tool turn).
|
|
1246
|
+
"""
|
|
1247
|
+
if len(self.messages) < 4:
|
|
1248
|
+
return
|
|
1249
|
+
|
|
1250
|
+
# Find indices of all write_file assistant messages targeting this path
|
|
1251
|
+
target_indices: list[int] = []
|
|
1252
|
+
for i, msg in enumerate(self.messages):
|
|
1253
|
+
if msg.role != Role.assistant:
|
|
1254
|
+
continue
|
|
1255
|
+
tcs = msg.tool_calls or []
|
|
1256
|
+
if len(tcs) != 1:
|
|
1257
|
+
continue
|
|
1258
|
+
fn = tcs[0].function
|
|
1259
|
+
if not fn or fn.name != "write_file":
|
|
1260
|
+
continue
|
|
1261
|
+
try:
|
|
1262
|
+
args = json.loads(fn.arguments or "{}")
|
|
1263
|
+
except (json.JSONDecodeError, AttributeError):
|
|
1264
|
+
continue
|
|
1265
|
+
if args.get("path", "") == target_path:
|
|
1266
|
+
target_indices.append(i)
|
|
1267
|
+
|
|
1268
|
+
if len(target_indices) < 2:
|
|
1269
|
+
return
|
|
1270
|
+
|
|
1271
|
+
# Keep the MOST RECENT one; prune the rest (and their tool result)
|
|
1272
|
+
to_drop: set[int] = set()
|
|
1273
|
+
for idx in target_indices[:-1]:
|
|
1274
|
+
to_drop.add(idx)
|
|
1275
|
+
# The matching tool result is the next tool message
|
|
1276
|
+
for j in range(idx + 1, min(idx + 3, len(self.messages))):
|
|
1277
|
+
if self.messages[j].role == Role.tool:
|
|
1278
|
+
to_drop.add(j)
|
|
1279
|
+
break
|
|
1280
|
+
|
|
1281
|
+
if not to_drop:
|
|
1282
|
+
return
|
|
1283
|
+
|
|
1284
|
+
kept = [m for i, m in enumerate(self.messages) if i not in to_drop]
|
|
1285
|
+
logger.info(
|
|
1286
|
+
"Pruning %d message(s) from write loop on %s (history now %d → %d)",
|
|
1287
|
+
len(to_drop), target_path, len(self.messages), len(kept),
|
|
1288
|
+
)
|
|
1289
|
+
self.messages.reset(kept)
|
|
1290
|
+
|
|
1291
|
+
def _truncate_old_tool_results(self) -> None:
|
|
1292
|
+
"""Shrink old verbose tool results before they bloat context.
|
|
1293
|
+
|
|
1294
|
+
For local models like Gemma 4 the per-turn cost grows quadratically
|
|
1295
|
+
with context size, so a session with 30+ messages and a few large
|
|
1296
|
+
read_file results becomes unusable. This method:
|
|
1297
|
+
|
|
1298
|
+
- Keeps the system prompt and the FIRST user message verbatim
|
|
1299
|
+
(instructions that should not be lost).
|
|
1300
|
+
- Keeps the last KEEP_RECENT tool results in full.
|
|
1301
|
+
- Truncates any older tool result whose content exceeds the
|
|
1302
|
+
per-result soft cap to a head + footer + size marker.
|
|
1303
|
+
|
|
1304
|
+
Runs every turn but is a no-op when nothing exceeds the caps.
|
|
1305
|
+
Truncation is in-place and idempotent.
|
|
1306
|
+
"""
|
|
1307
|
+
KEEP_RECENT = 6 # last N tool messages stay full
|
|
1308
|
+
SOFT_CAP_BYTES = 800 # tool result longer than this gets shrunk
|
|
1309
|
+
HEAD_BYTES = 400 # bytes kept from the head
|
|
1310
|
+
TAIL_BYTES = 100 # bytes kept from the tail
|
|
1311
|
+
|
|
1312
|
+
if len(self.messages) < KEEP_RECENT + 4:
|
|
1313
|
+
return
|
|
1314
|
+
|
|
1315
|
+
# Index of every tool message
|
|
1316
|
+
tool_idxs = [
|
|
1317
|
+
i for i, m in enumerate(self.messages) if m.role == Role.tool
|
|
1318
|
+
]
|
|
1319
|
+
if len(tool_idxs) <= KEEP_RECENT:
|
|
1320
|
+
return
|
|
1321
|
+
|
|
1322
|
+
# Truncate everything except the last KEEP_RECENT
|
|
1323
|
+
for idx in tool_idxs[:-KEEP_RECENT]:
|
|
1324
|
+
msg = self.messages[idx]
|
|
1325
|
+
content = str(msg.content or "")
|
|
1326
|
+
if len(content) <= SOFT_CAP_BYTES:
|
|
1327
|
+
continue
|
|
1328
|
+
# Idempotent guard — already truncated by us
|
|
1329
|
+
if "[…truncated " in content and "bytes…]" in content:
|
|
1330
|
+
continue
|
|
1331
|
+
head = content[:HEAD_BYTES]
|
|
1332
|
+
tail = content[-TAIL_BYTES:]
|
|
1333
|
+
removed = len(content) - HEAD_BYTES - TAIL_BYTES
|
|
1334
|
+
msg.content = (
|
|
1335
|
+
f"{head}\n[…truncated {removed} bytes…]\n{tail}"
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1136
1338
|
def _sanitize_message_ordering(self) -> None:
|
|
1137
1339
|
"""Fix any role ordering violations before sending to vLLM/Mistral.
|
|
1138
1340
|
|
|
@@ -1142,6 +1344,10 @@ class AgentLoop:
|
|
|
1142
1344
|
|
|
1143
1345
|
This runs as a safety net before every LLM call.
|
|
1144
1346
|
"""
|
|
1347
|
+
# Proactive context shrinkage runs first so the LLM call sees the
|
|
1348
|
+
# smaller payload.
|
|
1349
|
+
self._truncate_old_tool_results()
|
|
1350
|
+
|
|
1145
1351
|
if not self.messages:
|
|
1146
1352
|
return
|
|
1147
1353
|
|