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.
Files changed (497) hide show
  1. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/PKG-INFO +2 -1
  2. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/PRD.md +19 -0
  3. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/entrypoint.py +5 -0
  4. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agents/models.py +18 -6
  5. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/harness_files/_harness_manager.py +10 -0
  6. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/hooks.py +9 -0
  7. drydock_cli-1.3.0/drydock/core/plugins.py +138 -0
  8. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/cli.md +36 -14
  9. drydock_cli-1.3.0/drydock/core/session/checkpoints.py +123 -0
  10. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/system_prompt.py +36 -0
  11. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/read_file.py +36 -0
  12. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/pyproject.toml +2 -1
  13. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/CODEOWNERS +0 -0
  14. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  15. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  16. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  17. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/build-and-upload.yml +0 -0
  18. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/ci.yml +0 -0
  19. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/issue-labeler.yml +0 -0
  20. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.github/workflows/release.yml +0 -0
  21. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.gitignore +0 -0
  22. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.pre-commit-config.yaml +0 -0
  23. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.python-version +0 -0
  24. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.typos.toml +0 -0
  25. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.vscode/extensions.json +0 -0
  26. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.vscode/launch.json +0 -0
  27. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/.vscode/settings.json +0 -0
  28. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/AGENTS.md +0 -0
  29. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/CHANGELOG.md +0 -0
  30. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/CLAUDE.md +0 -0
  31. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/CONTRIBUTING.md +0 -0
  32. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/Drydock_rebrand.md +0 -0
  33. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/LICENSE +0 -0
  34. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/NOTICE +0 -0
  35. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/README.md +0 -0
  36. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/action.yml +0 -0
  37. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/distribution/zed/LICENSE +0 -0
  38. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/distribution/zed/extension.toml +0 -0
  39. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/distribution/zed/icons/mistral_vibe.svg +0 -0
  40. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/docs/README.md +0 -0
  41. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/docs/acp-setup.md +0 -0
  42. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/docs/proxy-setup.md +0 -0
  43. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/__init__.py +0 -0
  44. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/__init__.py +0 -0
  45. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/acp_agent_loop.py +0 -0
  46. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/acp_logger.py +0 -0
  47. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/entrypoint.py +0 -0
  48. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/__init__.py +0 -0
  49. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/base.py +0 -0
  50. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/bash.py +0 -0
  51. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/read_file.py +0 -0
  52. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/search_replace.py +0 -0
  53. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/todo.py +0 -0
  54. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/builtins/write_file.py +0 -0
  55. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/tools/session_update.py +0 -0
  56. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/acp/utils.py +0 -0
  57. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/__init__.py +0 -0
  58. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/__init__.py +0 -0
  59. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/base.py +0 -0
  60. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/path_completion.py +0 -0
  61. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/autocompletion/slash_command.py +0 -0
  62. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/cli.py +0 -0
  63. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/clipboard.py +0 -0
  64. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/commands.py +0 -0
  65. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/history_manager.py +0 -0
  66. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  67. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  68. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  69. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/terminal_setup.py +0 -0
  70. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/__init__.py +0 -0
  71. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  72. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/app.py +0 -0
  73. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/app.tcss +0 -0
  74. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/external_editor.py +0 -0
  75. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  76. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  77. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  78. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  79. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  80. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  81. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  82. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  83. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  84. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  85. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  86. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  87. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  88. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  89. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  90. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  91. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  92. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  93. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  94. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  95. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  96. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  97. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  98. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  99. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  100. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  101. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  102. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  103. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  104. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  105. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  106. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  107. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  108. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  109. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  110. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  111. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/history.py +0 -0
  112. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  113. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/textual_ui/windowing/state.py +0 -0
  114. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/__init__.py +0 -0
  115. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  116. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  117. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  118. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  119. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  120. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/update.py +0 -0
  121. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/cli/update_notifier/whats_new.py +0 -0
  122. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/__init__.py +0 -0
  123. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agent_loop.py +0 -0
  124. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agents/__init__.py +0 -0
  125. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/agents/manager.py +0 -0
  126. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/auth/__init__.py +0 -0
  127. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/auth/crypto.py +0 -0
  128. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/auth/github.py +0 -0
  129. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/__init__.py +0 -0
  130. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/completers.py +0 -0
  131. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  132. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  133. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  134. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  135. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  136. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/fuzzy.py +0 -0
  137. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/path_prompt.py +0 -0
  138. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  139. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/__init__.py +0 -0
  140. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/_settings.py +0 -0
  141. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/harness_files/__init__.py +0 -0
  142. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/config/harness_files/_paths.py +0 -0
  143. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/consultant.py +0 -0
  144. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/drydock_states.py +0 -0
  145. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/__init__.py +0 -0
  146. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/anthropic.py +0 -0
  147. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/base.py +0 -0
  148. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/factory.py +0 -0
  149. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/generic.py +0 -0
  150. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/mistral.py +0 -0
  151. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  152. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/backend/vertex.py +0 -0
  153. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/exceptions.py +0 -0
  154. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/format.py +0 -0
  155. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/message_utils.py +0 -0
  156. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/llm/types.py +0 -0
  157. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/logger.py +0 -0
  158. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/middleware.py +0 -0
  159. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/output_formatters.py +0 -0
  160. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/__init__.py +0 -0
  161. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/_local_config_walk.py +0 -0
  162. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/_vibe_home.py +0 -0
  163. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/paths/conventions.py +0 -0
  164. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/plan_session.py +0 -0
  165. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/programmatic.py +0 -0
  166. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/__init__.py +0 -0
  167. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/compact.md +0 -0
  168. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/dangerous_directory.md +0 -0
  169. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/diagnostic.md +0 -0
  170. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/explore.md +0 -0
  171. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/planner.md +0 -0
  172. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/project_context.md +0 -0
  173. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/prompts/tests.md +0 -0
  174. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/proxy_setup.py +0 -0
  175. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/agent_memory.py +0 -0
  176. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/session_loader.py +0 -0
  177. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/session_logger.py +0 -0
  178. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/session_migration.py +0 -0
  179. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/session/state_file.py +0 -0
  180. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/__init__.py +0 -0
  181. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/manager.py +0 -0
  182. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/models.py +0 -0
  183. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/skills/parser.py +0 -0
  184. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/slug.py +0 -0
  185. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/telemetry/__init__.py +0 -0
  186. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/telemetry/send.py +0 -0
  187. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/errors.py +0 -0
  188. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/git.py +0 -0
  189. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/nuage.py +0 -0
  190. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/teleport.py +0 -0
  191. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/teleport/types.py +0 -0
  192. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/base.py +0 -0
  193. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  194. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/bash.py +0 -0
  195. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/cron.py +0 -0
  196. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  197. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/glob_tool.py +0 -0
  198. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/grep.py +0 -0
  199. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  200. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/lsp.py +0 -0
  201. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  202. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  203. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/powershell.py +0 -0
  204. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  205. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  206. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  207. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  208. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  209. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  210. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  211. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  212. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  213. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  214. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  215. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  216. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  217. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  218. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/task.md +0 -0
  219. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  220. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  221. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  222. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  223. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  224. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  225. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  226. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/search_replace.py +0 -0
  227. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/task.py +0 -0
  228. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/task_manager.py +0 -0
  229. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/todo.py +0 -0
  230. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/tool_search.py +0 -0
  231. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/webfetch.py +0 -0
  232. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/websearch.py +0 -0
  233. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/worktree.py +0 -0
  234. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/builtins/write_file.py +0 -0
  235. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/injection_guard.py +0 -0
  236. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/manager.py +0 -0
  237. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp/__init__.py +0 -0
  238. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp/registry.py +0 -0
  239. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp/tools.py +0 -0
  240. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/mcp_sampling.py +0 -0
  241. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/ui.py +0 -0
  242. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/tools/utils.py +0 -0
  243. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/trusted_folders.py +0 -0
  244. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/types.py +0 -0
  245. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/core/utils.py +0 -0
  246. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/__init__.py +0 -0
  247. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/base.py +0 -0
  248. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/onboarding.tcss +0 -0
  249. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/screens/__init__.py +0 -0
  250. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/screens/api_key.py +0 -0
  251. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/onboarding/screens/welcome.py +0 -0
  252. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  253. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  254. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/__init__.py +0 -0
  255. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/batch/SKILL.md +0 -0
  256. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/create-presentation/SKILL.md +0 -0
  257. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/deep-research/SKILL.md +0 -0
  258. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/investigate/SKILL.md +0 -0
  259. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/review/SKILL.md +0 -0
  260. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/ship/SKILL.md +0 -0
  261. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/skills/simplify/SKILL.md +0 -0
  262. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock/whats_new.md +0 -0
  263. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock-acp.spec +0 -0
  264. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/drydock_terms.md +0 -0
  265. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/flake.lock +0 -0
  266. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/flake.nix +0 -0
  267. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/README.md +0 -0
  268. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/backup.sh +0 -0
  269. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/bump_version.py +0 -0
  270. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/deploy_to_github.sh +0 -0
  271. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/install.sh +0 -0
  272. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/prepare_release.py +0 -0
  273. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/publish_to_pypi.sh +0 -0
  274. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/test_full.sh +0 -0
  275. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/scripts/test_smoke.sh +0 -0
  276. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/__init__.py +0 -0
  277. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/conftest.py +0 -0
  278. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_acp.py +0 -0
  279. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_agent_thought.py +0 -0
  280. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_bash.py +0 -0
  281. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_compact_session_updates.py +0 -0
  282. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_content.py +0 -0
  283. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_initialize.py +0 -0
  284. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_list_sessions.py +0 -0
  285. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_load_session.py +0 -0
  286. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_multi_session.py +0 -0
  287. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_new_session.py +0 -0
  288. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_proxy_setup_acp.py +0 -0
  289. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_read_file.py +0 -0
  290. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_search_replace.py +0 -0
  291. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_set_config_option.py +0 -0
  292. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_set_mode.py +0 -0
  293. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_set_model.py +0 -0
  294. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_tool_call_session_update.py +0 -0
  295. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_utils.py +0 -0
  296. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/acp/test_write_file.py +0 -0
  297. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_file_indexer.py +0 -0
  298. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_fuzzy.py +0 -0
  299. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  300. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  301. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_completion_controller.py +0 -0
  302. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  303. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_slash_command_controller.py +0 -0
  304. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  305. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/__init__.py +0 -0
  306. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/data/__init__.py +0 -0
  307. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/data/fireworks.py +0 -0
  308. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/data/mistral.py +0 -0
  309. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_anthropic_adapter.py +0 -0
  310. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_backend.py +0 -0
  311. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_reasoning_adapter.py +0 -0
  312. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  313. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  314. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  315. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  316. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_bell_notifications.py +0 -0
  317. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_braille_renderer.py +0 -0
  318. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_clipboard.py +0 -0
  319. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_commands.py +0 -0
  320. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_copy_shortcuts.py +0 -0
  321. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_external_editor.py +0 -0
  322. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_no_markup_static.py +0 -0
  323. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_question_app.py +0 -0
  324. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_spinner.py +0 -0
  325. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_switching_mode.py +0 -0
  326. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  327. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  328. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_session_resume.py +0 -0
  329. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/test_ui_skill_dispatch.py +0 -0
  330. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/textual_ui/__init__.py +0 -0
  331. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/cli/textual_ui/test_session_picker.py +0 -0
  332. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/conftest.py +0 -0
  333. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_agents.py +0 -0
  334. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_auth_crypto.py +0 -0
  335. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_auth_github.py +0 -0
  336. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_config_load_dotenv.py +0 -0
  337. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_config_paths.py +0 -0
  338. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_config_resolution.py +0 -0
  339. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_file_logging.py +0 -0
  340. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_plan_session.py +0 -0
  341. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_proxy_setup.py +0 -0
  342. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_slug.py +0 -0
  343. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_telemetry_send.py +0 -0
  344. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_teleport_git.py +0 -0
  345. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_teleport_nuage.py +0 -0
  346. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_teleport_service.py +0 -0
  347. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_trusted_folders.py +0 -0
  348. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/core/test_utils.py +0 -0
  349. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/common.py +0 -0
  350. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/conftest.py +0 -0
  351. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/mock_server.py +0 -0
  352. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  353. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/test_cli_tui_streaming.py +0 -0
  354. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  355. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/__init__.py +0 -0
  356. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/mock_backend_factory.py +0 -0
  357. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/mock_entrypoint.py +0 -0
  358. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/mock/utils.py +0 -0
  359. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/onboarding/test_run_onboarding.py +0 -0
  360. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/onboarding/test_ui_onboarding.py +0 -0
  361. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/session/test_session_loader.py +0 -0
  362. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/session/test_session_logger.py +0 -0
  363. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/session/test_session_migration.py +0 -0
  364. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/conftest.py +0 -0
  365. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/test_manager.py +0 -0
  366. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/test_models.py +0 -0
  367. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/skills/test_parser.py +0 -0
  368. {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
  369. {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
  370. {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
  371. {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
  372. {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
  373. {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
  374. {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
  375. {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
  376. {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
  377. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  378. {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
  379. {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
  380. {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
  381. {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
  382. {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
  383. {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
  384. {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
  385. {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
  386. {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
  387. {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
  388. {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
  389. {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
  390. {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
  391. {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
  392. {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
  393. {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
  394. {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
  395. {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
  396. {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
  397. {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
  398. {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
  399. {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
  400. {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
  401. {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
  402. {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
  403. {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
  404. {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
  405. {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
  406. {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
  407. {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
  408. {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
  409. {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
  410. {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
  411. {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
  412. {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
  413. {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
  414. {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
  415. {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
  416. {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
  417. {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
  418. {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
  419. {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
  420. {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
  421. {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
  422. {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
  423. {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
  424. {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
  425. {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
  426. {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
  427. {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
  428. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/base_snapshot_test_app.py +0 -0
  429. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/conftest.py +0 -0
  430. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/snap_compare.py +0 -0
  431. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  432. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  433. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  434. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  435. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  436. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  437. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  438. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  439. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  440. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  441. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  442. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  443. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  444. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  445. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/stubs/fake_backend.py +0 -0
  446. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/stubs/fake_client.py +0 -0
  447. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/stubs/fake_tool.py +0 -0
  448. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_auto_compact.py +0 -0
  449. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_backend.py +0 -0
  450. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_observer_streaming.py +0 -0
  451. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_stats.py +0 -0
  452. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_tasks.py +0 -0
  453. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agent_tool_call.py +0 -0
  454. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_agents.py +0 -0
  455. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_cli_programmatic_preload.py +0 -0
  456. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_current_bugs.py +0 -0
  457. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_drydock_regression.py +0 -0
  458. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_drydock_tasks.py +0 -0
  459. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_full_regression.py +0 -0
  460. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_history_manager.py +0 -0
  461. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_integration.py +0 -0
  462. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_loop_detection.py +0 -0
  463. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_message_id.py +0 -0
  464. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_message_merging.py +0 -0
  465. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_middleware.py +0 -0
  466. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_multi_agent.py +0 -0
  467. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_real_failures.py +0 -0
  468. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_real_issues.py +0 -0
  469. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_reasoning_content.py +0 -0
  470. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_smoke.py +0 -0
  471. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_system_prompt.py +0 -0
  472. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_tagged_text.py +0 -0
  473. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_ui_external_editor.py +0 -0
  474. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_ui_input_history.py +0 -0
  475. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/test_user_issues.py +0 -0
  476. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_ask_user_question.py +0 -0
  477. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_bash.py +0 -0
  478. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_exit_plan_mode.py +0 -0
  479. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_grep.py +0 -0
  480. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_invoke_context.py +0 -0
  481. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_manager_get_tool_config.py +0 -0
  482. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_mcp.py +0 -0
  483. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_mcp_sampling.py +0 -0
  484. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_task.py +0 -0
  485. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_ui_bash_execution.py +0 -0
  486. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_webfetch.py +0 -0
  487. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/tools/test_websearch.py +0 -0
  488. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  489. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  490. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_do_update.py +0 -0
  491. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  492. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_github_update_gateway.py +0 -0
  493. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  494. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_ui_update_notification.py +0 -0
  495. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_update_use_case.py +0 -0
  496. {drydock_cli-1.2.0 → drydock_cli-1.3.0}/tests/update_notifier/test_whats_new.py +0 -0
  497. {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.2.0
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="Read-only subagent for codebase exploration",
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="Subagent that analyzes test failures and suggests fixes",
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="Read-only subagent that analyzes bugs and identifies target files",
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
  )
@@ -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
- - For codebase exploration: `task(task="Explore the project structure and report what you find", agent="explore")`
23
- - For investigating bugs: `task(task="Find the root cause of the X error in module Y", agent="explore")`
24
- - For code review: `invoke_skill(skill_name="review")`
25
- - For security audits or architecture review: delegate to a subagent so your main context stays clean
26
-
27
- WHEN to delegate:
28
- - The project has 3+ files to examine → delegate exploration to a subagent
29
- - You need to understand a codebase before making changes → subagent explores, you fix
30
- - You're doing a review or audit use /review skill or delegate
31
- - A task has multiple independent partsrun subagents in parallel
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-2 tool calls
36
- - Tasks where you already know exactly what to do
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.2.0"
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