drydock-cli 2.5.6__tar.gz → 2.5.8__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.5.6 → drydock_cli-2.5.8}/CLAUDE.md +22 -18
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/PKG-INFO +1 -1
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/cli.py +11 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/search_replace.py +11 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/write_file.py +17 -1
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/pyproject.toml +1 -1
- drydock_cli-2.5.8/scripts/auto_release.sh +104 -0
- drydock_cli-2.5.8/scripts/telegram_bot.py +423 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.gitignore +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.python-version +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.typos.toml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.vscode/extensions.json +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.vscode/launch.json +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/.vscode/settings.json +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/AGENTS.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/CHANGELOG.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/LICENSE +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/NOTICE +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/PRD.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/README.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/action.yml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/docs/README.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/docs/acp-setup.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/agent_loop.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/logger.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/slug.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/task_manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/types.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/core/utils.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock/whats_new.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock-acp.spec +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/drydock_terms.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/flake.lock +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/flake.nix +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/log_analyzer/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/log_analyzer/__main__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/log_analyzer/analyzer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/log_analyzer/cli.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/README.md +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/backup.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/bump_version.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/discover_cli_tools.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/install.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/notify_release.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/test_full.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/test_tui_path.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/scripts/tui_test.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/conftest.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/e2e/common.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/mock/utils.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/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.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_agents.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_integration.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_message_id.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_middleware.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_smoke.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/test_workloads.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.5.6 → drydock_cli-2.5.8}/uv.lock +0 -0
|
@@ -9,9 +9,12 @@ Drydock is a local CLI coding agent (fork of mistral-vibe, Apache 2.0).
|
|
|
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
|
-
- **TUI
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
12
|
+
- **TUI build tests:** 303/320 pass --help (94%) — BUT --help IS MEANINGLESS
|
|
13
|
+
- **TUI real functional tests:** 35/63 pass (56%) — the honest number
|
|
14
|
+
- **SWE-bench:** 70% file match (v3 baseline)
|
|
15
|
+
- **Priority:** TUI experience first. Fix drydock bugs, don't simplify PRDs.
|
|
16
|
+
- **370 PRDs** at /data3/drydock_test_projects/ — the benchmark suite
|
|
17
|
+
- **Current version:** v2.5.6 (PyPI + GitHub + user's env)
|
|
15
18
|
|
|
16
19
|
## Build & Test
|
|
17
20
|
|
|
@@ -279,21 +282,22 @@ v3 is a from-scratch rewrite using nano-claude-code as foundation. 4 core files,
|
|
|
279
282
|
|
|
280
283
|
### TUI Test Harness
|
|
281
284
|
- **Script:** `scripts/tui_test.py` — pexpect-based, drives the REAL TUI binary
|
|
282
|
-
- **
|
|
283
|
-
- **
|
|
284
|
-
- **
|
|
285
|
-
|
|
286
|
-
###
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
-
|
|
295
|
-
-
|
|
296
|
-
-
|
|
285
|
+
- **Real test runner:** `run_real_tests.sh` — functional testing, not just --help
|
|
286
|
+
- **Results:** `real_test_results.txt` — honest pass/fail with functional verification
|
|
287
|
+
- **370 PRDs** at `/data3/drydock_test_projects/` covering CLI tools, integration, edge cases, best practices
|
|
288
|
+
|
|
289
|
+
### Test Levels
|
|
290
|
+
1. **Build test (--help):** package runs — MEANINGLESS alone
|
|
291
|
+
2. **Functional test:** PRD test cases verified with correct output — THE REAL TEST
|
|
292
|
+
3. **Acceptance test:** specific expected outputs verified
|
|
293
|
+
4. **Quality test:** code quality checks (docstrings, no eval, error handling)
|
|
294
|
+
|
|
295
|
+
### Critical Testing Rules
|
|
296
|
+
- PRD failures = DryDock bugs. Fix the agent, NOT the PRD.
|
|
297
|
+
- --help passing proves nothing about code quality
|
|
298
|
+
- Safety mechanisms must be ADVISORY not BLOCKING
|
|
299
|
+
- NEVER add circuit breakers that prevent legitimate work
|
|
300
|
+
- The model should be able to answer questions without being forced to edit files
|
|
297
301
|
|
|
298
302
|
## When Compacting
|
|
299
303
|
|
|
@@ -176,6 +176,17 @@ def run_cli(args: argparse.Namespace) -> None:
|
|
|
176
176
|
"task",
|
|
177
177
|
"invoke_skill",
|
|
178
178
|
"tool_search",
|
|
179
|
+
"cron_create",
|
|
180
|
+
"cron_delete",
|
|
181
|
+
"cron_list",
|
|
182
|
+
"enter_worktree",
|
|
183
|
+
"exit_worktree",
|
|
184
|
+
"exit_plan_mode",
|
|
185
|
+
"list_mcp_resources",
|
|
186
|
+
"read_mcp_resource",
|
|
187
|
+
"notebook_edit",
|
|
188
|
+
"web_fetch",
|
|
189
|
+
"web_search",
|
|
179
190
|
]
|
|
180
191
|
except (ValueError, AttributeError):
|
|
181
192
|
pass
|
|
@@ -166,6 +166,17 @@ class SearchReplace(
|
|
|
166
166
|
|
|
167
167
|
await self._write_file(file_path, modified_content)
|
|
168
168
|
|
|
169
|
+
# Auto-verify syntax for Python files
|
|
170
|
+
if file_path.suffix == ".py":
|
|
171
|
+
try:
|
|
172
|
+
import ast
|
|
173
|
+
ast.parse(modified_content)
|
|
174
|
+
except SyntaxError as e:
|
|
175
|
+
block_result.warnings.append(
|
|
176
|
+
f"⚠ SYNTAX ERROR after edit at line {e.lineno}: {e.msg}. "
|
|
177
|
+
f"Fix this before continuing."
|
|
178
|
+
)
|
|
179
|
+
|
|
169
180
|
yield SearchReplaceResult(
|
|
170
181
|
file=str(file_path),
|
|
171
182
|
blocks_applied=block_result.applied,
|
|
@@ -92,12 +92,28 @@ class WriteFile(
|
|
|
92
92
|
|
|
93
93
|
await self._write_file(args, file_path)
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
# Auto-verify syntax for Python files
|
|
96
|
+
syntax_warning = ""
|
|
97
|
+
if file_path.suffix == ".py":
|
|
98
|
+
try:
|
|
99
|
+
import ast
|
|
100
|
+
ast.parse(args.content)
|
|
101
|
+
except SyntaxError as e:
|
|
102
|
+
syntax_warning = (
|
|
103
|
+
f"\n\n⚠ SYNTAX ERROR in {file_path.name} line {e.lineno}: {e.msg}"
|
|
104
|
+
f"\n {e.text.rstrip() if e.text else ''}"
|
|
105
|
+
f"\n Fix this before moving to the next file."
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
result = WriteFileResult(
|
|
96
109
|
path=str(file_path),
|
|
97
110
|
bytes_written=content_bytes,
|
|
98
111
|
file_existed=file_existed,
|
|
99
112
|
content=args.content,
|
|
100
113
|
)
|
|
114
|
+
if syntax_warning:
|
|
115
|
+
result.content = syntax_warning # Override content with the warning
|
|
116
|
+
yield result
|
|
101
117
|
|
|
102
118
|
_BINARY_EXTENSIONS = frozenset({
|
|
103
119
|
".pptx", ".xlsx", ".docx", ".pdf", ".zip", ".tar", ".gz", ".bz2",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Auto-release DryDock every 6 hours
|
|
3
|
+
# Checks if there are new commits since last release, builds, publishes, deploys
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
export PATH="/home/bobef/miniconda3/bin:$PATH"
|
|
7
|
+
PYTHON="/home/bobef/miniconda3/bin/python3"
|
|
8
|
+
DRYDOCK="/data3/drydock"
|
|
9
|
+
LOCKFILE="$DRYDOCK/.auto_release.lock"
|
|
10
|
+
|
|
11
|
+
# Prevent concurrent runs
|
|
12
|
+
if [ -f "$LOCKFILE" ]; then
|
|
13
|
+
pid=$(cat "$LOCKFILE")
|
|
14
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
rm -f "$LOCKFILE"
|
|
18
|
+
fi
|
|
19
|
+
echo $$ > "$LOCKFILE"
|
|
20
|
+
trap "rm -f $LOCKFILE" EXIT
|
|
21
|
+
|
|
22
|
+
cd "$DRYDOCK"
|
|
23
|
+
|
|
24
|
+
# Check if there are commits since last tag
|
|
25
|
+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
|
|
26
|
+
COMMITS_SINCE=$(git rev-list "$LAST_TAG"..HEAD --count 2>/dev/null || echo "0")
|
|
27
|
+
|
|
28
|
+
if [ "$COMMITS_SINCE" -eq 0 ]; then
|
|
29
|
+
echo "[$(date)] No new commits since $LAST_TAG. Skipping release."
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
echo "[$(date)] $COMMITS_SINCE commits since $LAST_TAG. Building release..."
|
|
34
|
+
|
|
35
|
+
# Syntax check all modified .py files
|
|
36
|
+
ERRORS=0
|
|
37
|
+
for f in $(git diff --name-only "$LAST_TAG"..HEAD -- '*.py' 2>/dev/null); do
|
|
38
|
+
if [ -f "$f" ]; then
|
|
39
|
+
$PYTHON -c "import ast; ast.parse(open('$f').read())" 2>/dev/null || {
|
|
40
|
+
echo "SYNTAX ERROR: $f"
|
|
41
|
+
ERRORS=$((ERRORS + 1))
|
|
42
|
+
}
|
|
43
|
+
fi
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
if [ "$ERRORS" -gt 0 ]; then
|
|
47
|
+
echo "[$(date)] $ERRORS syntax errors found. Aborting release."
|
|
48
|
+
$PYTHON "$DRYDOCK/scripts/notify_release.py" "release" "Auto-release ABORTED: $ERRORS syntax errors in modified files" 2>/dev/null
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Get current version and bump patch
|
|
53
|
+
CURRENT=$(grep 'version = ' "$DRYDOCK/pyproject.toml" | head -1 | grep -oP '\d+\.\d+\.\d+')
|
|
54
|
+
MAJOR=$(echo "$CURRENT" | cut -d. -f1)
|
|
55
|
+
MINOR=$(echo "$CURRENT" | cut -d. -f2)
|
|
56
|
+
PATCH=$(echo "$CURRENT" | cut -d. -f3)
|
|
57
|
+
NEW_PATCH=$((PATCH + 1))
|
|
58
|
+
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
|
|
59
|
+
|
|
60
|
+
echo "[$(date)] Bumping $CURRENT -> $NEW_VERSION"
|
|
61
|
+
|
|
62
|
+
# Update version
|
|
63
|
+
sed -i "s/version = \"$CURRENT\"/version = \"$NEW_VERSION\"/" "$DRYDOCK/pyproject.toml"
|
|
64
|
+
git add "$DRYDOCK/pyproject.toml"
|
|
65
|
+
git commit -m "v$NEW_VERSION: Auto-release (${COMMITS_SINCE} commits)" --no-verify 2>/dev/null || true
|
|
66
|
+
|
|
67
|
+
# Build
|
|
68
|
+
rm -rf dist/
|
|
69
|
+
$PYTHON -m build 2>/dev/null
|
|
70
|
+
|
|
71
|
+
# Publish to PyPI
|
|
72
|
+
PYPI_TOKEN=$(cat ~/.config/drydock/pypi_token)
|
|
73
|
+
$PYTHON -m twine upload dist/drydock_cli-${NEW_VERSION}* -u __token__ -p "$PYPI_TOKEN" 2>/dev/null
|
|
74
|
+
|
|
75
|
+
# Deploy to GitHub
|
|
76
|
+
TMPDIR=$(mktemp -d)
|
|
77
|
+
GITHUB_TOKEN=$(cat ~/.config/drydock/github_token)
|
|
78
|
+
git clone --depth 1 "https://${GITHUB_TOKEN}@github.com/fbobe321/drydock.git" "$TMPDIR/repo" 2>/dev/null
|
|
79
|
+
rsync -a --delete \
|
|
80
|
+
--exclude='.git' --exclude='.github/workflows' --exclude='logs/' \
|
|
81
|
+
--exclude='__pycache__/' --exclude='*.pyc' --exclude='.pytest_cache/' \
|
|
82
|
+
--exclude='*.egg-info/' --exclude='dist/' \
|
|
83
|
+
"$DRYDOCK/" "$TMPDIR/repo/"
|
|
84
|
+
cd "$TMPDIR/repo"
|
|
85
|
+
git add -A
|
|
86
|
+
git -c user.name="Drydock Deploy" -c user.email="deploy@drydock" \
|
|
87
|
+
commit -m "v$NEW_VERSION: Auto-release" 2>/dev/null
|
|
88
|
+
git push 2>/dev/null
|
|
89
|
+
rm -rf "$TMPDIR"
|
|
90
|
+
cd "$DRYDOCK"
|
|
91
|
+
|
|
92
|
+
# Install on user's env (retry PyPI propagation)
|
|
93
|
+
for i in 1 2 3; do
|
|
94
|
+
sleep 60
|
|
95
|
+
/home/bobef/miniforge3/envs/drydock/bin/pip install --force-reinstall --no-deps --no-cache-dir "drydock-cli==$NEW_VERSION" 2>/dev/null && break
|
|
96
|
+
done
|
|
97
|
+
|
|
98
|
+
# Tag
|
|
99
|
+
git tag "v$NEW_VERSION" 2>/dev/null || true
|
|
100
|
+
|
|
101
|
+
# Notify
|
|
102
|
+
$PYTHON "$DRYDOCK/scripts/notify_release.py" "$NEW_VERSION" "Auto-release: $COMMITS_SINCE commits since $LAST_TAG" 2>/dev/null
|
|
103
|
+
|
|
104
|
+
echo "[$(date)] Released v$NEW_VERSION successfully"
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""DryDock Telegram Bot — check status, run tests, trigger actions.
|
|
3
|
+
|
|
4
|
+
Commands:
|
|
5
|
+
/status — Current test results and system status
|
|
6
|
+
/failures — List top failures with reasons
|
|
7
|
+
/report — Full failure analysis report
|
|
8
|
+
/rerun — Restart the parallel test runner
|
|
9
|
+
/version — Current drydock version
|
|
10
|
+
/release — Trigger a release now
|
|
11
|
+
/vllm — Check vLLM model status
|
|
12
|
+
/tests N — Run test harness on project N (test-only, no rebuild)
|
|
13
|
+
/rebuild N — Rebuild project N via TUI and test
|
|
14
|
+
/help — Show available commands
|
|
15
|
+
"""
|
|
16
|
+
import json
|
|
17
|
+
import os
|
|
18
|
+
import re
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
import time
|
|
22
|
+
import urllib.request
|
|
23
|
+
import urllib.parse
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
BOT_TOKEN = "8488479213:AAGd2tMUrqc-Xse14IQ6yfoMudAAal7odio"
|
|
27
|
+
CHAT_ID = 8431425848
|
|
28
|
+
PROJECTS_DIR = Path("/data3/drydock_test_projects")
|
|
29
|
+
RESULTS_FILE = PROJECTS_DIR / "real_test_results.txt"
|
|
30
|
+
RESULTS_JSON = PROJECTS_DIR / "real_test_results.json"
|
|
31
|
+
PYTHON = "/home/bobef/miniconda3/bin/python3"
|
|
32
|
+
LAST_UPDATE_FILE = Path("/tmp/telegram_bot_last_update")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def send(text: str):
|
|
36
|
+
"""Send message to Telegram."""
|
|
37
|
+
# Truncate to Telegram's 4096 char limit
|
|
38
|
+
if len(text) > 4000:
|
|
39
|
+
text = text[:4000] + "\n...(truncated)"
|
|
40
|
+
data = urllib.parse.urlencode({
|
|
41
|
+
"chat_id": CHAT_ID,
|
|
42
|
+
"text": text,
|
|
43
|
+
"parse_mode": "Markdown",
|
|
44
|
+
}).encode()
|
|
45
|
+
try:
|
|
46
|
+
urllib.request.urlopen(
|
|
47
|
+
f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
|
|
48
|
+
data, timeout=10,
|
|
49
|
+
)
|
|
50
|
+
except Exception as e:
|
|
51
|
+
# Retry without markdown
|
|
52
|
+
data = urllib.parse.urlencode({
|
|
53
|
+
"chat_id": CHAT_ID,
|
|
54
|
+
"text": text,
|
|
55
|
+
}).encode()
|
|
56
|
+
try:
|
|
57
|
+
urllib.request.urlopen(
|
|
58
|
+
f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
|
|
59
|
+
data, timeout=10,
|
|
60
|
+
)
|
|
61
|
+
except Exception:
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def get_updates() -> list:
|
|
66
|
+
"""Get new messages from Telegram."""
|
|
67
|
+
last_id = 0
|
|
68
|
+
if LAST_UPDATE_FILE.exists():
|
|
69
|
+
try:
|
|
70
|
+
last_id = int(LAST_UPDATE_FILE.read_text().strip())
|
|
71
|
+
except ValueError:
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
url = f"https://api.telegram.org/bot{BOT_TOKEN}/getUpdates?offset={last_id + 1}&timeout=1"
|
|
75
|
+
try:
|
|
76
|
+
resp = urllib.request.urlopen(url, timeout=5)
|
|
77
|
+
data = json.loads(resp.read())
|
|
78
|
+
if data.get("ok") and data.get("result"):
|
|
79
|
+
updates = data["result"]
|
|
80
|
+
if updates:
|
|
81
|
+
LAST_UPDATE_FILE.write_text(str(updates[-1]["update_id"]))
|
|
82
|
+
return updates
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
85
|
+
return []
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def cmd_status() -> str:
|
|
89
|
+
"""Current test status."""
|
|
90
|
+
version = "?"
|
|
91
|
+
try:
|
|
92
|
+
r = subprocess.run([PYTHON, "-c", "import drydock; print(drydock.__version__)"],
|
|
93
|
+
capture_output=True, text=True, timeout=5)
|
|
94
|
+
version = r.stdout.strip()
|
|
95
|
+
except Exception:
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
# Test results
|
|
99
|
+
if RESULTS_FILE.exists():
|
|
100
|
+
lines = RESULTS_FILE.read_text().strip().split("\n")
|
|
101
|
+
total = len(lines)
|
|
102
|
+
passed = sum(1 for l in lines if l.endswith("|PASS"))
|
|
103
|
+
failed = sum(1 for l in lines if l.endswith("|FAIL"))
|
|
104
|
+
else:
|
|
105
|
+
total = passed = failed = 0
|
|
106
|
+
|
|
107
|
+
# Runner status
|
|
108
|
+
runners = subprocess.run("ps aux | grep -E 'parallel_tests|tui_test' | grep -v grep | wc -l",
|
|
109
|
+
shell=True, capture_output=True, text=True).stdout.strip()
|
|
110
|
+
|
|
111
|
+
# vLLM
|
|
112
|
+
try:
|
|
113
|
+
urllib.request.urlopen("http://localhost:8000/v1/models", timeout=3)
|
|
114
|
+
vllm = "UP"
|
|
115
|
+
except Exception:
|
|
116
|
+
vllm = "DOWN"
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
f"DryDock v{version}\n"
|
|
120
|
+
f"Tests: {passed}/{total} pass ({failed} fail)\n"
|
|
121
|
+
f"Runner: {'active' if int(runners) > 0 else 'stopped'}\n"
|
|
122
|
+
f"vLLM: {vllm}\n"
|
|
123
|
+
f"Remaining: {400 - total} untested"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def cmd_failures() -> str:
|
|
128
|
+
"""Top failures."""
|
|
129
|
+
if not RESULTS_FILE.exists():
|
|
130
|
+
return "No results yet"
|
|
131
|
+
|
|
132
|
+
failures = []
|
|
133
|
+
for line in RESULTS_FILE.read_text().strip().split("\n"):
|
|
134
|
+
if line.endswith("|FAIL"):
|
|
135
|
+
parts = line.split("|")
|
|
136
|
+
if len(parts) >= 8:
|
|
137
|
+
failures.append(f" {parts[0]}: files={parts[2]} help={parts[3]} func={parts[4]}")
|
|
138
|
+
|
|
139
|
+
if not failures:
|
|
140
|
+
return "No failures!"
|
|
141
|
+
|
|
142
|
+
return f"Failures ({len(failures)}):\n" + "\n".join(failures[:15])
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def cmd_report() -> str:
|
|
146
|
+
"""Full failure report."""
|
|
147
|
+
report_path = PROJECTS_DIR / "failure_report.md"
|
|
148
|
+
if report_path.exists():
|
|
149
|
+
return report_path.read_text()[:4000]
|
|
150
|
+
# Generate fresh
|
|
151
|
+
subprocess.run(["/bin/bash", str(PROJECTS_DIR / "analyze_failures.sh")],
|
|
152
|
+
timeout=30, capture_output=True)
|
|
153
|
+
if report_path.exists():
|
|
154
|
+
return report_path.read_text()[:4000]
|
|
155
|
+
return "No report available"
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def cmd_rerun() -> str:
|
|
159
|
+
"""Restart test runner."""
|
|
160
|
+
subprocess.run("pkill -f run_parallel_tests", shell=True, capture_output=True)
|
|
161
|
+
time.sleep(2)
|
|
162
|
+
|
|
163
|
+
tested = 0
|
|
164
|
+
if RESULTS_FILE.exists():
|
|
165
|
+
tested = len(RESULTS_FILE.read_text().strip().split("\n"))
|
|
166
|
+
|
|
167
|
+
subprocess.Popen(
|
|
168
|
+
f"nohup bash {PROJECTS_DIR}/run_parallel_tests.sh 1 > {PROJECTS_DIR}/parallel_test.log 2>&1 &",
|
|
169
|
+
shell=True,
|
|
170
|
+
)
|
|
171
|
+
return f"Runner restarted. {tested} already tested, continuing from where stopped."
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def cmd_version() -> str:
|
|
175
|
+
"""Current version."""
|
|
176
|
+
try:
|
|
177
|
+
r = subprocess.run([PYTHON, "-c", "import drydock; print(drydock.__version__)"],
|
|
178
|
+
capture_output=True, text=True, timeout=5)
|
|
179
|
+
v = r.stdout.strip()
|
|
180
|
+
|
|
181
|
+
r2 = subprocess.run(["git", "log", "--oneline", "-5"], capture_output=True, text=True,
|
|
182
|
+
timeout=5, cwd="/data3/drydock")
|
|
183
|
+
log = r2.stdout.strip()
|
|
184
|
+
return f"DryDock v{v}\n\nRecent commits:\n{log}"
|
|
185
|
+
except Exception as e:
|
|
186
|
+
return f"Error: {e}"
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def cmd_release() -> str:
|
|
190
|
+
"""Trigger release."""
|
|
191
|
+
try:
|
|
192
|
+
r = subprocess.run(
|
|
193
|
+
["/bin/bash", "/data3/drydock/scripts/auto_release.sh"],
|
|
194
|
+
capture_output=True, text=True, timeout=300,
|
|
195
|
+
)
|
|
196
|
+
return f"Release result:\n{r.stdout[-500:]}"
|
|
197
|
+
except subprocess.TimeoutExpired:
|
|
198
|
+
return "Release timed out (300s)"
|
|
199
|
+
except Exception as e:
|
|
200
|
+
return f"Release error: {e}"
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def cmd_vllm() -> str:
|
|
204
|
+
"""vLLM status."""
|
|
205
|
+
try:
|
|
206
|
+
resp = urllib.request.urlopen("http://localhost:8000/v1/models", timeout=3)
|
|
207
|
+
data = json.loads(resp.read())
|
|
208
|
+
model = data["data"][0]["id"]
|
|
209
|
+
return f"vLLM: UP\nModel: {model}\nMax context: {data['data'][0].get('max_model_len', '?')}"
|
|
210
|
+
except Exception as e:
|
|
211
|
+
return f"vLLM: DOWN\nError: {e}"
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def cmd_tests(arg: str) -> str:
|
|
215
|
+
"""Run test on specific project."""
|
|
216
|
+
try:
|
|
217
|
+
num = int(arg.strip())
|
|
218
|
+
r = subprocess.run(
|
|
219
|
+
[PYTHON, str(PROJECTS_DIR / "test_harness.py"), "--run", str(num), str(num), "--test-only"],
|
|
220
|
+
capture_output=True, text=True, timeout=60,
|
|
221
|
+
cwd=str(PROJECTS_DIR),
|
|
222
|
+
)
|
|
223
|
+
return r.stdout[-1000:] or r.stderr[-500:] or "No output"
|
|
224
|
+
except ValueError:
|
|
225
|
+
return "Usage: /tests N (project number)"
|
|
226
|
+
except subprocess.TimeoutExpired:
|
|
227
|
+
return "Test timed out"
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def cmd_rebuild(arg: str) -> str:
|
|
231
|
+
"""Rebuild project via TUI."""
|
|
232
|
+
try:
|
|
233
|
+
num = int(arg.strip())
|
|
234
|
+
r = subprocess.run(
|
|
235
|
+
[PYTHON, str(PROJECTS_DIR / "test_harness.py"), "--run", str(num), str(num), "--rebuild"],
|
|
236
|
+
capture_output=True, text=True, timeout=360,
|
|
237
|
+
cwd=str(PROJECTS_DIR),
|
|
238
|
+
)
|
|
239
|
+
return r.stdout[-1000:] or r.stderr[-500:] or "No output"
|
|
240
|
+
except ValueError:
|
|
241
|
+
return "Usage: /rebuild N (project number)"
|
|
242
|
+
except subprocess.TimeoutExpired:
|
|
243
|
+
return "Rebuild timed out (360s)"
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def cmd_help() -> str:
|
|
247
|
+
return (
|
|
248
|
+
"DryDock Bot Commands:\n\n"
|
|
249
|
+
"Status:\n"
|
|
250
|
+
" /status — Test results & system status\n"
|
|
251
|
+
" /failures — List top failures\n"
|
|
252
|
+
" /report — Full failure analysis\n"
|
|
253
|
+
" /version — Current version + commits\n"
|
|
254
|
+
" /vllm — Check model server\n\n"
|
|
255
|
+
"Testing:\n"
|
|
256
|
+
" /tests N — Test project N (no rebuild)\n"
|
|
257
|
+
" /rebuild N — Rebuild project N via TUI\n"
|
|
258
|
+
" /rerun — Restart parallel test runner\n\n"
|
|
259
|
+
"Fixes:\n"
|
|
260
|
+
" /dryfix <issue> — Launch Claude to fix a drydock bug\n"
|
|
261
|
+
" /fixtest N — Diagnose why project N fails\n\n"
|
|
262
|
+
"Deploy:\n"
|
|
263
|
+
" /release — Trigger PyPI+GitHub release\n\n"
|
|
264
|
+
"Example:\n"
|
|
265
|
+
" /dryfix search_replace crashes with missing file_path\n"
|
|
266
|
+
" /fixtest 42\n"
|
|
267
|
+
" /rebuild 10"
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def cmd_dryfix(arg: str) -> str:
|
|
272
|
+
"""Launch Claude Code to fix an issue."""
|
|
273
|
+
if not arg.strip():
|
|
274
|
+
return "Usage: /dryfix <description of the issue>\nExample: /dryfix search_replace crashes when file_path is missing"
|
|
275
|
+
|
|
276
|
+
issue = arg.strip()
|
|
277
|
+
send(f"Starting fix for: {issue}\nThis may take a few minutes...")
|
|
278
|
+
|
|
279
|
+
# Build a focused prompt
|
|
280
|
+
prompt = (
|
|
281
|
+
f"You are fixing a bug in DryDock (CLI coding agent at /data3/drydock). "
|
|
282
|
+
f"Read CLAUDE.md first for context. The issue reported by the user is:\n\n"
|
|
283
|
+
f" {issue}\n\n"
|
|
284
|
+
f"Steps:\n"
|
|
285
|
+
f"1. Find the relevant code (grep for keywords from the issue)\n"
|
|
286
|
+
f"2. Read the file and understand the bug\n"
|
|
287
|
+
f"3. Fix it with a minimal edit\n"
|
|
288
|
+
f"4. Run: python3 -c \"import ast; ast.parse(open('file').read())\" to verify syntax\n"
|
|
289
|
+
f"5. Respond with EXACTLY what you changed and why (under 200 words)\n\n"
|
|
290
|
+
f"Do NOT refactor, add features, or change unrelated code. Minimal fix only."
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
try:
|
|
294
|
+
r = subprocess.run(
|
|
295
|
+
["claude", "--dangerously-skip-permissions", "-p", prompt],
|
|
296
|
+
capture_output=True, text=True, timeout=300,
|
|
297
|
+
cwd="/data3/drydock",
|
|
298
|
+
)
|
|
299
|
+
output = r.stdout.strip()
|
|
300
|
+
if len(output) > 3500:
|
|
301
|
+
output = output[-3500:]
|
|
302
|
+
return f"Fix attempt complete:\n\n{output}" if output else f"No output (exit {r.returncode})"
|
|
303
|
+
except subprocess.TimeoutExpired:
|
|
304
|
+
return "Fix timed out after 5 minutes"
|
|
305
|
+
except Exception as e:
|
|
306
|
+
return f"Fix error: {e}"
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def cmd_fixtest(arg: str) -> str:
|
|
310
|
+
"""Fix a specific failing test project."""
|
|
311
|
+
try:
|
|
312
|
+
num = int(arg.strip())
|
|
313
|
+
except ValueError:
|
|
314
|
+
return "Usage: /fixtest N (project number)\nLaunches Claude to diagnose and fix why project N fails"
|
|
315
|
+
|
|
316
|
+
# Find the project
|
|
317
|
+
dirs = sorted(PROJECTS_DIR.glob(f"{num:02d}_*")) + sorted(PROJECTS_DIR.glob(f"{num:03d}_*"))
|
|
318
|
+
if not dirs:
|
|
319
|
+
return f"Project {num} not found"
|
|
320
|
+
|
|
321
|
+
proj_dir = dirs[0]
|
|
322
|
+
pkg = proj_dir.name.split("_", 1)[1] if "_" in proj_dir.name else proj_dir.name
|
|
323
|
+
|
|
324
|
+
send(f"Analyzing failure for {proj_dir.name}...")
|
|
325
|
+
|
|
326
|
+
prompt = (
|
|
327
|
+
f"A DryDock test project failed. Diagnose and fix the DryDock agent code (NOT the PRD).\n\n"
|
|
328
|
+
f"Project: {proj_dir.name}\n"
|
|
329
|
+
f"Package: {pkg}\n"
|
|
330
|
+
f"PRD: {proj_dir}/PRD.md\n"
|
|
331
|
+
f"TUI output: {proj_dir}/tui_output.txt\n\n"
|
|
332
|
+
f"Steps:\n"
|
|
333
|
+
f"1. Read the PRD to understand what was requested\n"
|
|
334
|
+
f"2. Read tui_output.txt to see what went wrong\n"
|
|
335
|
+
f"3. Check if the issue is in DryDock code (agent_loop, tools, prompts)\n"
|
|
336
|
+
f"4. If it's a DryDock bug, fix it. If it's a model behavior issue, update gemma4.md\n"
|
|
337
|
+
f"5. Respond with what you found and what you changed (under 200 words)"
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
try:
|
|
341
|
+
r = subprocess.run(
|
|
342
|
+
["claude", "--dangerously-skip-permissions", "-p", prompt],
|
|
343
|
+
capture_output=True, text=True, timeout=300,
|
|
344
|
+
cwd="/data3/drydock",
|
|
345
|
+
)
|
|
346
|
+
output = r.stdout.strip()
|
|
347
|
+
if len(output) > 3500:
|
|
348
|
+
output = output[-3500:]
|
|
349
|
+
return f"Analysis complete:\n\n{output}" if output else f"No output (exit {r.returncode})"
|
|
350
|
+
except subprocess.TimeoutExpired:
|
|
351
|
+
return "Analysis timed out after 5 minutes"
|
|
352
|
+
except Exception as e:
|
|
353
|
+
return f"Error: {e}"
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
COMMANDS = {
|
|
357
|
+
"/status": lambda _: cmd_status(),
|
|
358
|
+
"/failures": lambda _: cmd_failures(),
|
|
359
|
+
"/report": lambda _: cmd_report(),
|
|
360
|
+
"/rerun": lambda _: cmd_rerun(),
|
|
361
|
+
"/version": lambda _: cmd_version(),
|
|
362
|
+
"/release": lambda _: cmd_release(),
|
|
363
|
+
"/vllm": lambda _: cmd_vllm(),
|
|
364
|
+
"/tests": cmd_tests,
|
|
365
|
+
"/rebuild": cmd_rebuild,
|
|
366
|
+
"/dryfix": cmd_dryfix,
|
|
367
|
+
"/fixtest": cmd_fixtest,
|
|
368
|
+
"/help": lambda _: cmd_help(),
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def process_message(text: str) -> str | None:
|
|
373
|
+
"""Process a command and return response."""
|
|
374
|
+
text = text.strip()
|
|
375
|
+
if not text.startswith("/"):
|
|
376
|
+
return None
|
|
377
|
+
|
|
378
|
+
parts = text.split(None, 1)
|
|
379
|
+
cmd = parts[0].lower()
|
|
380
|
+
arg = parts[1] if len(parts) > 1 else ""
|
|
381
|
+
|
|
382
|
+
handler = COMMANDS.get(cmd)
|
|
383
|
+
if handler:
|
|
384
|
+
try:
|
|
385
|
+
return handler(arg)
|
|
386
|
+
except Exception as e:
|
|
387
|
+
return f"Error: {e}"
|
|
388
|
+
return None
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def poll_once():
|
|
392
|
+
"""Check for new messages and respond."""
|
|
393
|
+
updates = get_updates()
|
|
394
|
+
for update in updates:
|
|
395
|
+
msg = update.get("message", {})
|
|
396
|
+
text = msg.get("text", "")
|
|
397
|
+
chat_id = msg.get("chat", {}).get("id")
|
|
398
|
+
|
|
399
|
+
if chat_id != CHAT_ID:
|
|
400
|
+
continue
|
|
401
|
+
|
|
402
|
+
response = process_message(text)
|
|
403
|
+
if response:
|
|
404
|
+
send(response)
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
if __name__ == "__main__":
|
|
408
|
+
import argparse
|
|
409
|
+
parser = argparse.ArgumentParser()
|
|
410
|
+
parser.add_argument("--once", action="store_true", help="Poll once and exit")
|
|
411
|
+
parser.add_argument("--daemon", action="store_true", help="Run as daemon, poll every 5s")
|
|
412
|
+
args = parser.parse_args()
|
|
413
|
+
|
|
414
|
+
if args.daemon:
|
|
415
|
+
print(f"DryDock Telegram bot running (polling every 5s)...")
|
|
416
|
+
while True:
|
|
417
|
+
try:
|
|
418
|
+
poll_once()
|
|
419
|
+
except Exception as e:
|
|
420
|
+
print(f"Error: {e}")
|
|
421
|
+
time.sleep(5)
|
|
422
|
+
else:
|
|
423
|
+
poll_once()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|