drydock-cli 1.2.0__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/PKG-INFO +2 -1
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/PRD.md +19 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/entrypoint.py +5 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agents/models.py +18 -6
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/harness_files/_harness_manager.py +10 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/hooks.py +9 -0
- drydock_cli-1.3.0/drydock/core/plugins.py +138 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/cli.md +36 -14
- drydock_cli-1.3.0/drydock/core/session/checkpoints.py +123 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/system_prompt.py +36 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/read_file.py +36 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/pyproject.toml +2 -1
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/CODEOWNERS +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/ci.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/release.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.gitignore +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.pre-commit-config.yaml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.python-version +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.typos.toml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.vscode/extensions.json +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.vscode/launch.json +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.vscode/settings.json +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/AGENTS.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/CHANGELOG.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/CLAUDE.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/CONTRIBUTING.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/Drydock_rebrand.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/LICENSE +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/NOTICE +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/README.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/action.yml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/distribution/zed/LICENSE +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/distribution/zed/extension.toml +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/docs/README.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/docs/acp-setup.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/docs/proxy-setup.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/utils.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/cli.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/commands.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agent_loop.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/auth/github.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/consultant.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/format.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/types.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/logger.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/middleware.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/plan_session.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/programmatic.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/models.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/slug.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/base.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/task_manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/types.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/utils.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/whats_new.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock-acp.spec +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock_terms.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/flake.lock +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/flake.nix +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/README.md +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/backup.sh +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/bump_version.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/install.sh +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/prepare_release.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/test_full.sh +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/test_smoke.sh +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/conftest.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_acp.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_bash.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_content.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_utils.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_backend.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_commands.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/conftest.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_agents.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_slug.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_utils.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/common.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/conftest.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/__init__.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/utils.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/conftest.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/test_manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/test_models.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/test_parser.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_backend.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_stats.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agents.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_current_bugs.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_full_regression.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_history_manager.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_integration.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_loop_detection.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_message_id.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_message_merging.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_middleware.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_multi_agent.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_real_failures.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_real_issues.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_smoke.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_system_prompt.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_tagged_text.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_user_issues.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_bash.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_grep.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_task.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-1.2.0 → drydock_cli-1.3.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Drydock — nautical CLI coding agent
|
|
5
5
|
Project-URL: Homepage, https://github.com/fbobe321/drydock
|
|
6
6
|
Project-URL: Repository, https://github.com/fbobe321/drydock
|
|
@@ -39,6 +39,7 @@ Requires-Dist: packaging>=24.1
|
|
|
39
39
|
Requires-Dist: pexpect>=4.9.0
|
|
40
40
|
Requires-Dist: pydantic-settings>=2.12.0
|
|
41
41
|
Requires-Dist: pydantic>=2.12.4
|
|
42
|
+
Requires-Dist: pypdf>=4.0.0
|
|
42
43
|
Requires-Dist: pyperclip>=1.11.0
|
|
43
44
|
Requires-Dist: python-dotenv>=1.0.0
|
|
44
45
|
Requires-Dist: pyyaml>=6.0.0
|
|
@@ -229,3 +229,22 @@ drydock/
|
|
|
229
229
|
4. **Users find different bugs than benchmarks.** SWE-bench finds agent logic bugs. Real usage finds UI/UX bugs.
|
|
230
230
|
5. **Fix the #1 failure mode.** Bash abuse caused 88% of failures — one fix doubled the pass rate.
|
|
231
231
|
6. **I can't test the TUI.** I write code changes based on docs but can't verify visually. The user is the only tester for UI.
|
|
232
|
+
|
|
233
|
+
### Phase 10 (Mar 28): Multi-Agent Actually Works
|
|
234
|
+
|
|
235
|
+
The agent was NOT using subagents despite having them available since Phase 2.
|
|
236
|
+
Every previous "fix" added code but never told the model WHEN to use it.
|
|
237
|
+
|
|
238
|
+
**Test result (real backend, no hint in prompt):**
|
|
239
|
+
- Before fix: FAILED — 0 subagent calls for 5-file project review
|
|
240
|
+
- After fix: PASSED — model naturally calls `task(agent="explore")`
|
|
241
|
+
|
|
242
|
+
**Root cause:** System prompt had no instructions about multi-agent delegation.
|
|
243
|
+
Adding Python tools/agents doesn't matter if the prompt doesn't tell the model to use them.
|
|
244
|
+
|
|
245
|
+
**Fix:** Added comprehensive "Multi-Agent Delegation" section to system prompt:
|
|
246
|
+
- Lists all available agents (explore, diagnostic, planner)
|
|
247
|
+
- Lists all available skills (investigate, review, ship, batch, simplify, deep-research)
|
|
248
|
+
- Shows exact syntax for delegation
|
|
249
|
+
- Explicit WHEN to delegate rules (3+ files, reviews, bugs, planning)
|
|
250
|
+
- WHEN NOT to delegate (simple fixes, quick questions)
|
|
@@ -69,6 +69,11 @@ def parse_arguments() -> argparse.Namespace:
|
|
|
69
69
|
"for human-readable (default), 'json' for all messages at end, "
|
|
70
70
|
"'streaming' for newline-delimited JSON per message.",
|
|
71
71
|
)
|
|
72
|
+
parser.add_argument(
|
|
73
|
+
"--json-schema",
|
|
74
|
+
metavar="FILE",
|
|
75
|
+
help="Path to JSON Schema file. Constrains the final output to match the schema.",
|
|
76
|
+
)
|
|
72
77
|
parser.add_argument(
|
|
73
78
|
"--agent",
|
|
74
79
|
metavar="NAME",
|
|
@@ -178,20 +178,28 @@ AUTO_APPROVE = AgentProfile(
|
|
|
178
178
|
EXPLORE = AgentProfile(
|
|
179
179
|
name=BuiltinAgentName.EXPLORE,
|
|
180
180
|
display_name="Explore",
|
|
181
|
-
description=
|
|
181
|
+
description=(
|
|
182
|
+
"Read-only subagent for codebase exploration. Use when you need to "
|
|
183
|
+
"understand a project with 3+ files, map architecture, or find where "
|
|
184
|
+
"a function/class is defined. Has grep and read_file only — cannot edit."
|
|
185
|
+
),
|
|
182
186
|
safety=AgentSafety.SAFE,
|
|
183
187
|
agent_type=AgentType.SUBAGENT,
|
|
184
|
-
overrides={"enabled_tools": ["grep", "read_file"], "system_prompt_id": "explore"},
|
|
188
|
+
overrides={"enabled_tools": ["grep", "read_file", "glob"], "system_prompt_id": "explore"},
|
|
185
189
|
)
|
|
186
190
|
|
|
187
191
|
DIAGNOSTIC = AgentProfile(
|
|
188
192
|
name=BuiltinAgentName.DIAGNOSTIC,
|
|
189
193
|
display_name="Diagnostic",
|
|
190
|
-
description=
|
|
194
|
+
description=(
|
|
195
|
+
"Subagent that analyzes test failures, error traces, and runtime issues. "
|
|
196
|
+
"Use when tests fail and you need to understand WHY before fixing. "
|
|
197
|
+
"Can run tests via bash and read source code."
|
|
198
|
+
),
|
|
191
199
|
safety=AgentSafety.SAFE,
|
|
192
200
|
agent_type=AgentType.SUBAGENT,
|
|
193
201
|
overrides={
|
|
194
|
-
"enabled_tools": ["grep", "read_file", "bash"],
|
|
202
|
+
"enabled_tools": ["grep", "read_file", "bash", "glob"],
|
|
195
203
|
"system_prompt_id": "diagnostic",
|
|
196
204
|
},
|
|
197
205
|
)
|
|
@@ -199,11 +207,15 @@ DIAGNOSTIC = AgentProfile(
|
|
|
199
207
|
PLANNER = AgentProfile(
|
|
200
208
|
name=BuiltinAgentName.PLANNER,
|
|
201
209
|
display_name="Planner",
|
|
202
|
-
description=
|
|
210
|
+
description=(
|
|
211
|
+
"Read-only subagent that creates implementation plans before coding. "
|
|
212
|
+
"Use for complex changes that touch multiple modules — the planner "
|
|
213
|
+
"identifies target files, dependencies, and change order."
|
|
214
|
+
),
|
|
203
215
|
safety=AgentSafety.SAFE,
|
|
204
216
|
agent_type=AgentType.SUBAGENT,
|
|
205
217
|
overrides={
|
|
206
|
-
"enabled_tools": ["grep", "read_file"],
|
|
218
|
+
"enabled_tools": ["grep", "read_file", "glob"],
|
|
207
219
|
"system_prompt_id": "planner",
|
|
208
220
|
},
|
|
209
221
|
)
|
{drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/harness_files/_harness_manager.py
RENAMED
|
@@ -65,11 +65,21 @@ class HarnessFilesManager:
|
|
|
65
65
|
bundled = VIBE_ROOT / "skills"
|
|
66
66
|
if bundled.is_dir():
|
|
67
67
|
dirs.append(bundled)
|
|
68
|
+
# Project skills in .drydock/skills/ (current directory)
|
|
69
|
+
project_skills = Path.cwd() / ".drydock" / "skills"
|
|
70
|
+
if project_skills.is_dir():
|
|
71
|
+
dirs.append(project_skills)
|
|
68
72
|
# User skills in ~/.drydock/skills/
|
|
69
73
|
if "user" in self.sources:
|
|
70
74
|
d = GLOBAL_SKILLS_DIR.path
|
|
71
75
|
if d.is_dir():
|
|
72
76
|
dirs.append(d)
|
|
77
|
+
# Plugin skills
|
|
78
|
+
try:
|
|
79
|
+
from drydock.core.plugins import get_plugin_skill_dirs
|
|
80
|
+
dirs.extend(get_plugin_skill_dirs())
|
|
81
|
+
except Exception:
|
|
82
|
+
pass
|
|
73
83
|
return dirs
|
|
74
84
|
|
|
75
85
|
@property
|
|
@@ -40,10 +40,19 @@ logger = logging.getLogger(__name__)
|
|
|
40
40
|
class HookEvent(StrEnum):
|
|
41
41
|
PRE_TOOL_USE = auto()
|
|
42
42
|
POST_TOOL_USE = auto()
|
|
43
|
+
POST_TOOL_USE_FAILURE = auto()
|
|
43
44
|
SESSION_START = auto()
|
|
44
45
|
SESSION_END = auto()
|
|
45
46
|
PRE_EDIT = auto()
|
|
46
47
|
POST_EDIT = auto()
|
|
48
|
+
USER_PROMPT_SUBMIT = auto()
|
|
49
|
+
STOP = auto()
|
|
50
|
+
FILE_CHANGED = auto()
|
|
51
|
+
CWD_CHANGED = auto()
|
|
52
|
+
PRE_COMPACT = auto()
|
|
53
|
+
POST_COMPACT = auto()
|
|
54
|
+
SUBAGENT_START = auto()
|
|
55
|
+
SUBAGENT_STOP = auto()
|
|
47
56
|
|
|
48
57
|
|
|
49
58
|
class HookDecision(StrEnum):
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Plugin system for DryDock.
|
|
2
|
+
|
|
3
|
+
Plugins are directories with a plugin.json manifest that can provide:
|
|
4
|
+
- skills/ — Skill definitions (SKILL.md files)
|
|
5
|
+
- agents/ — Agent profiles (TOML or Markdown)
|
|
6
|
+
- hooks/ — Hook scripts
|
|
7
|
+
|
|
8
|
+
Install: drydock plugin install <path-or-url>
|
|
9
|
+
Location: ~/.drydock/plugins/<name>/
|
|
10
|
+
|
|
11
|
+
plugin.json format:
|
|
12
|
+
{
|
|
13
|
+
"name": "my-plugin",
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"description": "What this plugin does",
|
|
16
|
+
"author": "Name",
|
|
17
|
+
"skills": ["skill-name"],
|
|
18
|
+
"agents": ["agent-name"],
|
|
19
|
+
"hooks": ["hook-config.json"]
|
|
20
|
+
}
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import json
|
|
26
|
+
import logging
|
|
27
|
+
import shutil
|
|
28
|
+
from dataclasses import dataclass
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class PluginInfo:
|
|
36
|
+
name: str
|
|
37
|
+
version: str
|
|
38
|
+
description: str
|
|
39
|
+
path: Path
|
|
40
|
+
skills: list[str]
|
|
41
|
+
agents: list[str]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _plugins_dir() -> Path:
|
|
45
|
+
"""Get the plugins directory."""
|
|
46
|
+
try:
|
|
47
|
+
from drydock.core.paths import VIBE_HOME
|
|
48
|
+
return VIBE_HOME.path / "plugins"
|
|
49
|
+
except Exception:
|
|
50
|
+
return Path.home() / ".drydock" / "plugins"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def list_plugins() -> list[PluginInfo]:
|
|
54
|
+
"""List all installed plugins."""
|
|
55
|
+
plugins_dir = _plugins_dir()
|
|
56
|
+
if not plugins_dir.is_dir():
|
|
57
|
+
return []
|
|
58
|
+
|
|
59
|
+
plugins: list[PluginInfo] = []
|
|
60
|
+
for plugin_dir in sorted(plugins_dir.iterdir()):
|
|
61
|
+
manifest = plugin_dir / "plugin.json"
|
|
62
|
+
if manifest.is_file():
|
|
63
|
+
try:
|
|
64
|
+
data = json.loads(manifest.read_text())
|
|
65
|
+
plugins.append(PluginInfo(
|
|
66
|
+
name=data.get("name", plugin_dir.name),
|
|
67
|
+
version=data.get("version", "0.0.0"),
|
|
68
|
+
description=data.get("description", ""),
|
|
69
|
+
path=plugin_dir,
|
|
70
|
+
skills=data.get("skills", []),
|
|
71
|
+
agents=data.get("agents", []),
|
|
72
|
+
))
|
|
73
|
+
except (json.JSONDecodeError, KeyError) as e:
|
|
74
|
+
logger.warning("Invalid plugin at %s: %s", plugin_dir, e)
|
|
75
|
+
|
|
76
|
+
return plugins
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def install_plugin(source: str | Path) -> PluginInfo | None:
|
|
80
|
+
"""Install a plugin from a local directory."""
|
|
81
|
+
source_path = Path(source)
|
|
82
|
+
if not source_path.is_dir():
|
|
83
|
+
logger.error("Plugin source must be a directory: %s", source)
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
manifest = source_path / "plugin.json"
|
|
87
|
+
if not manifest.is_file():
|
|
88
|
+
logger.error("No plugin.json found in %s", source)
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
data = json.loads(manifest.read_text())
|
|
92
|
+
name = data.get("name", source_path.name)
|
|
93
|
+
|
|
94
|
+
dest = _plugins_dir() / name
|
|
95
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
96
|
+
|
|
97
|
+
# Copy plugin files
|
|
98
|
+
shutil.copytree(source_path, dest, dirs_exist_ok=True)
|
|
99
|
+
logger.info("Installed plugin '%s' to %s", name, dest)
|
|
100
|
+
|
|
101
|
+
return PluginInfo(
|
|
102
|
+
name=name,
|
|
103
|
+
version=data.get("version", "0.0.0"),
|
|
104
|
+
description=data.get("description", ""),
|
|
105
|
+
path=dest,
|
|
106
|
+
skills=data.get("skills", []),
|
|
107
|
+
agents=data.get("agents", []),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def uninstall_plugin(name: str) -> bool:
|
|
112
|
+
"""Uninstall a plugin by name."""
|
|
113
|
+
dest = _plugins_dir() / name
|
|
114
|
+
if dest.is_dir():
|
|
115
|
+
shutil.rmtree(dest)
|
|
116
|
+
logger.info("Uninstalled plugin '%s'", name)
|
|
117
|
+
return True
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def get_plugin_skill_dirs() -> list[Path]:
|
|
122
|
+
"""Get skill directories from all installed plugins."""
|
|
123
|
+
dirs: list[Path] = []
|
|
124
|
+
for plugin in list_plugins():
|
|
125
|
+
skills_dir = plugin.path / "skills"
|
|
126
|
+
if skills_dir.is_dir():
|
|
127
|
+
dirs.append(skills_dir)
|
|
128
|
+
return dirs
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_plugin_agent_dirs() -> list[Path]:
|
|
132
|
+
"""Get agent directories from all installed plugins."""
|
|
133
|
+
dirs: list[Path] = []
|
|
134
|
+
for plugin in list_plugins():
|
|
135
|
+
agents_dir = plugin.path / "agents"
|
|
136
|
+
if agents_dir.is_dir():
|
|
137
|
+
dirs.append(agents_dir)
|
|
138
|
+
return dirs
|
|
@@ -18,22 +18,44 @@ Change: user wants code created, modified, or fixed → proceed to Plan then Exe
|
|
|
18
18
|
If unclear, default to investigate. It is better to explain what you would do than to make an unwanted change.
|
|
19
19
|
|
|
20
20
|
Multi-Agent Delegation (IMPORTANT):
|
|
21
|
-
You have subagents that run in their own context. USE THEM
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
21
|
+
You have subagents that run in their own context window. USE THEM to keep your main context clean.
|
|
22
|
+
|
|
23
|
+
Available agents:
|
|
24
|
+
- `explore` — Read-only codebase exploration (grep, read_file only)
|
|
25
|
+
- `diagnostic` — Analyze test failures and errors
|
|
26
|
+
- `planner` — Create implementation plans before coding
|
|
27
|
+
|
|
28
|
+
Available skills (invoke with `invoke_skill`):
|
|
29
|
+
- `investigate` — Systematic debugging with 3-strike rule
|
|
30
|
+
- `review` — Two-pass code review (critical then informational)
|
|
31
|
+
- `ship` — Test → review → commit → push → PR pipeline
|
|
32
|
+
- `batch` — Apply same change across many files
|
|
33
|
+
- `simplify` — Three-pass code quality review
|
|
34
|
+
- `deep-research` — Web + code research → structured report
|
|
35
|
+
|
|
36
|
+
HOW to delegate:
|
|
37
|
+
```
|
|
38
|
+
task(task="Explore the project structure and list all modules", agent="explore")
|
|
39
|
+
task(task="Analyze why test_auth fails with KeyError", agent="diagnostic")
|
|
40
|
+
task(task="Plan the refactoring of the auth module", agent="planner")
|
|
41
|
+
invoke_skill(skill_name="review")
|
|
42
|
+
invoke_skill(skill_name="investigate", arguments="Fix the login timeout bug")
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
WHEN to delegate (ALWAYS do this):
|
|
46
|
+
- Project has 3+ files to examine → `task(..., agent="explore")` FIRST
|
|
47
|
+
- Need to understand unfamiliar code → explore subagent, then you fix
|
|
48
|
+
- Bug investigation → `invoke_skill(skill_name="investigate")`
|
|
49
|
+
- Code review or audit → `invoke_skill(skill_name="review")`
|
|
50
|
+
- Shipping changes → `invoke_skill(skill_name="ship")`
|
|
51
|
+
- Changing many files → `invoke_skill(skill_name="batch")`
|
|
52
|
+
- Test failures to diagnose → `task(..., agent="diagnostic")`
|
|
53
|
+
- Planning a big change → `task(..., agent="planner")` before coding
|
|
32
54
|
|
|
33
55
|
WHEN NOT to delegate:
|
|
34
|
-
- Simple single-file fixes
|
|
35
|
-
- Quick questions that need 1
|
|
36
|
-
- Tasks where you already know exactly what to
|
|
56
|
+
- Simple single-file fixes you can do in 2-3 tool calls
|
|
57
|
+
- Quick questions that need 1 grep + 1 read_file
|
|
58
|
+
- Tasks where you already know exactly what file and line to change
|
|
37
59
|
|
|
38
60
|
Explore. Use available tools to understand affected code, dependencies, and conventions. Never edit a file you haven't read in this session.
|
|
39
61
|
Identify constraints: language, framework, test setup, and any user restrictions on scope.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Checkpoint system — snapshot files before edits for rewind.
|
|
2
|
+
|
|
3
|
+
Tracks file state before each edit so users can rewind to any point.
|
|
4
|
+
Stores snapshots in memory (session-scoped, not persisted).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
import shutil
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class FileSnapshot:
|
|
20
|
+
path: str
|
|
21
|
+
content: str # Original content before edit
|
|
22
|
+
timestamp: str
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class Checkpoint:
|
|
27
|
+
id: int
|
|
28
|
+
description: str
|
|
29
|
+
snapshots: list[FileSnapshot] = field(default_factory=list)
|
|
30
|
+
message_count: int = 0 # Number of messages at this point
|
|
31
|
+
timestamp: str = ""
|
|
32
|
+
|
|
33
|
+
def __post_init__(self):
|
|
34
|
+
if not self.timestamp:
|
|
35
|
+
self.timestamp = datetime.now().strftime("%H:%M:%S")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CheckpointManager:
|
|
39
|
+
"""Manages file checkpoints for rewind capability."""
|
|
40
|
+
|
|
41
|
+
def __init__(self) -> None:
|
|
42
|
+
self._checkpoints: list[Checkpoint] = []
|
|
43
|
+
self._counter = 0
|
|
44
|
+
|
|
45
|
+
def create_checkpoint(self, description: str, message_count: int = 0) -> Checkpoint:
|
|
46
|
+
"""Create a new checkpoint."""
|
|
47
|
+
self._counter += 1
|
|
48
|
+
cp = Checkpoint(
|
|
49
|
+
id=self._counter,
|
|
50
|
+
description=description,
|
|
51
|
+
message_count=message_count,
|
|
52
|
+
)
|
|
53
|
+
self._checkpoints.append(cp)
|
|
54
|
+
logger.debug("Checkpoint %d: %s", cp.id, description)
|
|
55
|
+
return cp
|
|
56
|
+
|
|
57
|
+
def snapshot_file(self, file_path: str) -> None:
|
|
58
|
+
"""Save the current content of a file before editing it."""
|
|
59
|
+
if not self._checkpoints:
|
|
60
|
+
self.create_checkpoint("auto")
|
|
61
|
+
|
|
62
|
+
path = Path(file_path)
|
|
63
|
+
if not path.exists():
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
content = path.read_text(encoding="utf-8", errors="replace")
|
|
68
|
+
snapshot = FileSnapshot(
|
|
69
|
+
path=str(path.resolve()),
|
|
70
|
+
content=content,
|
|
71
|
+
timestamp=datetime.now().strftime("%H:%M:%S"),
|
|
72
|
+
)
|
|
73
|
+
self._checkpoints[-1].snapshots.append(snapshot)
|
|
74
|
+
except (OSError, PermissionError) as e:
|
|
75
|
+
logger.warning("Cannot snapshot %s: %s", file_path, e)
|
|
76
|
+
|
|
77
|
+
def list_checkpoints(self) -> list[Checkpoint]:
|
|
78
|
+
"""List all checkpoints."""
|
|
79
|
+
return list(self._checkpoints)
|
|
80
|
+
|
|
81
|
+
def rewind_to(self, checkpoint_id: int) -> list[str]:
|
|
82
|
+
"""Restore files from a checkpoint. Returns list of restored file paths."""
|
|
83
|
+
target = None
|
|
84
|
+
for cp in self._checkpoints:
|
|
85
|
+
if cp.id == checkpoint_id:
|
|
86
|
+
target = cp
|
|
87
|
+
break
|
|
88
|
+
|
|
89
|
+
if not target:
|
|
90
|
+
return []
|
|
91
|
+
|
|
92
|
+
restored: list[str] = []
|
|
93
|
+
|
|
94
|
+
# Collect all snapshots from this checkpoint forward (to undo)
|
|
95
|
+
# We restore the EARLIEST snapshot of each file
|
|
96
|
+
file_originals: dict[str, str] = {}
|
|
97
|
+
for cp in self._checkpoints:
|
|
98
|
+
if cp.id >= checkpoint_id:
|
|
99
|
+
for snap in cp.snapshots:
|
|
100
|
+
if snap.path not in file_originals:
|
|
101
|
+
file_originals[snap.path] = snap.content
|
|
102
|
+
|
|
103
|
+
for path_str, content in file_originals.items():
|
|
104
|
+
try:
|
|
105
|
+
Path(path_str).write_text(content, encoding="utf-8")
|
|
106
|
+
restored.append(path_str)
|
|
107
|
+
except (OSError, PermissionError) as e:
|
|
108
|
+
logger.warning("Cannot restore %s: %s", path_str, e)
|
|
109
|
+
|
|
110
|
+
# Remove checkpoints from the target onward
|
|
111
|
+
self._checkpoints = [cp for cp in self._checkpoints if cp.id < checkpoint_id]
|
|
112
|
+
|
|
113
|
+
return restored
|
|
114
|
+
|
|
115
|
+
def rewind_last(self) -> list[str]:
|
|
116
|
+
"""Rewind the most recent checkpoint."""
|
|
117
|
+
if not self._checkpoints:
|
|
118
|
+
return []
|
|
119
|
+
return self.rewind_to(self._checkpoints[-1].id)
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def count(self) -> int:
|
|
123
|
+
return len(self._checkpoints)
|
|
@@ -291,4 +291,40 @@ def get_universal_system_prompt(
|
|
|
291
291
|
if project_doc.strip():
|
|
292
292
|
sections.append(project_doc)
|
|
293
293
|
|
|
294
|
+
# Load DRYDOCK.md per-project instructions (like CLAUDE.md)
|
|
295
|
+
drydock_md = _load_project_instructions()
|
|
296
|
+
if drydock_md:
|
|
297
|
+
sections.append(f"## Project Instructions\n\n{drydock_md}")
|
|
298
|
+
|
|
294
299
|
return "\n\n".join(sections)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def _load_project_instructions(max_bytes: int = 16_000) -> str:
|
|
303
|
+
"""Load DRYDOCK.md and .drydock/rules/*.md for per-project instructions."""
|
|
304
|
+
parts: list[str] = []
|
|
305
|
+
|
|
306
|
+
# Check for DRYDOCK.md in project root
|
|
307
|
+
for name in ["DRYDOCK.md", "drydock.md", ".drydock/DRYDOCK.md"]:
|
|
308
|
+
path = Path.cwd() / name
|
|
309
|
+
try:
|
|
310
|
+
if path.is_file():
|
|
311
|
+
content = path.read_text("utf-8", errors="ignore")[:max_bytes]
|
|
312
|
+
parts.append(content)
|
|
313
|
+
break
|
|
314
|
+
except (OSError, PermissionError):
|
|
315
|
+
pass
|
|
316
|
+
|
|
317
|
+
# Load .drydock/rules/*.md for modular instructions
|
|
318
|
+
rules_dir = Path.cwd() / ".drydock" / "rules"
|
|
319
|
+
try:
|
|
320
|
+
if rules_dir.is_dir():
|
|
321
|
+
for rule_file in sorted(rules_dir.glob("*.md")):
|
|
322
|
+
try:
|
|
323
|
+
content = rule_file.read_text("utf-8", errors="ignore")[:4000]
|
|
324
|
+
parts.append(f"### {rule_file.stem}\n{content}")
|
|
325
|
+
except (OSError, PermissionError):
|
|
326
|
+
pass
|
|
327
|
+
except (OSError, PermissionError):
|
|
328
|
+
pass
|
|
329
|
+
|
|
330
|
+
return "\n\n".join(parts)
|
|
@@ -72,6 +72,26 @@ class ReadFile(
|
|
|
72
72
|
) -> AsyncGenerator[ToolStreamEvent | ReadFileResult, None]:
|
|
73
73
|
file_path = self._prepare_and_validate_path(args)
|
|
74
74
|
|
|
75
|
+
# Handle PDF files
|
|
76
|
+
if file_path.suffix.lower() == ".pdf":
|
|
77
|
+
content = self._read_pdf(file_path)
|
|
78
|
+
yield ReadFileResult(
|
|
79
|
+
path=str(file_path), content=content,
|
|
80
|
+
lines_read=content.count("\n"), was_truncated=False,
|
|
81
|
+
)
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
# Handle image files (describe what we can)
|
|
85
|
+
if file_path.suffix.lower() in (".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg"):
|
|
86
|
+
import os
|
|
87
|
+
size = os.path.getsize(file_path)
|
|
88
|
+
content = f"[Image file: {file_path.name}, {size} bytes, format: {file_path.suffix}]"
|
|
89
|
+
yield ReadFileResult(
|
|
90
|
+
path=str(file_path), content=content,
|
|
91
|
+
lines_read=1, was_truncated=False,
|
|
92
|
+
)
|
|
93
|
+
return
|
|
94
|
+
|
|
75
95
|
read_result = await self._read_file(args, file_path)
|
|
76
96
|
|
|
77
97
|
yield ReadFileResult(
|
|
@@ -81,6 +101,22 @@ class ReadFile(
|
|
|
81
101
|
was_truncated=read_result.was_truncated,
|
|
82
102
|
)
|
|
83
103
|
|
|
104
|
+
def _read_pdf(self, file_path: Path) -> str:
|
|
105
|
+
"""Extract text from a PDF file."""
|
|
106
|
+
try:
|
|
107
|
+
import pypdf
|
|
108
|
+
reader = pypdf.PdfReader(str(file_path))
|
|
109
|
+
pages = []
|
|
110
|
+
for i, page in enumerate(reader.pages[:20]): # Max 20 pages
|
|
111
|
+
text = page.extract_text()
|
|
112
|
+
if text:
|
|
113
|
+
pages.append(f"--- Page {i+1} ---\n{text}")
|
|
114
|
+
return "\n\n".join(pages) if pages else "[PDF has no extractable text]"
|
|
115
|
+
except ImportError:
|
|
116
|
+
return "[PDF reading requires pypdf: pip install pypdf]"
|
|
117
|
+
except Exception as e:
|
|
118
|
+
return f"[Error reading PDF: {e}]"
|
|
119
|
+
|
|
84
120
|
def resolve_permission(self, args: ReadFileArgs) -> ToolPermission | None:
|
|
85
121
|
return resolve_file_tool_permission(
|
|
86
122
|
args.path,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "drydock-cli"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.3.0"
|
|
4
4
|
description = "Drydock — nautical CLI coding agent"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -45,6 +45,7 @@ dependencies = [
|
|
|
45
45
|
"pexpect>=4.9.0",
|
|
46
46
|
"pydantic>=2.12.4",
|
|
47
47
|
"pydantic-settings>=2.12.0",
|
|
48
|
+
"pypdf>=4.0.0",
|
|
48
49
|
"pyperclip>=1.11.0",
|
|
49
50
|
"python-dotenv>=1.0.0",
|
|
50
51
|
"pyyaml>=6.0.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|