drydock-cli 1.2.1__tar.gz → 1.3.1__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.1 → drydock_cli-1.3.1}/PKG-INFO +2 -1
  2. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/entrypoint.py +5 -0
  3. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/agent_loop.py +17 -0
  4. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/agents/models.py +18 -6
  5. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/config/harness_files/_harness_manager.py +10 -0
  6. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/hooks.py +9 -0
  7. drydock_cli-1.3.1/drydock/core/plugins.py +138 -0
  8. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/cli.md +7 -0
  9. drydock_cli-1.3.1/drydock/core/session/checkpoints.py +123 -0
  10. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/system_prompt.py +36 -0
  11. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/read_file.py +36 -0
  12. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/task.py +45 -0
  13. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/pyproject.toml +2 -1
  14. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/CODEOWNERS +0 -0
  15. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  16. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  17. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  18. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/workflows/build-and-upload.yml +0 -0
  19. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/workflows/ci.yml +0 -0
  20. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/workflows/issue-labeler.yml +0 -0
  21. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.github/workflows/release.yml +0 -0
  22. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.gitignore +0 -0
  23. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.pre-commit-config.yaml +0 -0
  24. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.python-version +0 -0
  25. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.typos.toml +0 -0
  26. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.vscode/extensions.json +0 -0
  27. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.vscode/launch.json +0 -0
  28. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/.vscode/settings.json +0 -0
  29. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/AGENTS.md +0 -0
  30. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/CHANGELOG.md +0 -0
  31. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/CLAUDE.md +0 -0
  32. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/CONTRIBUTING.md +0 -0
  33. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/Drydock_rebrand.md +0 -0
  34. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/LICENSE +0 -0
  35. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/NOTICE +0 -0
  36. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/PRD.md +0 -0
  37. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/README.md +0 -0
  38. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/action.yml +0 -0
  39. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/distribution/zed/LICENSE +0 -0
  40. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/distribution/zed/extension.toml +0 -0
  41. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/distribution/zed/icons/mistral_vibe.svg +0 -0
  42. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/docs/README.md +0 -0
  43. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/docs/acp-setup.md +0 -0
  44. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/docs/proxy-setup.md +0 -0
  45. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/__init__.py +0 -0
  46. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/__init__.py +0 -0
  47. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/acp_agent_loop.py +0 -0
  48. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/acp_logger.py +0 -0
  49. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/entrypoint.py +0 -0
  50. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/__init__.py +0 -0
  51. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/base.py +0 -0
  52. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/builtins/bash.py +0 -0
  53. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/builtins/read_file.py +0 -0
  54. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/builtins/search_replace.py +0 -0
  55. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/builtins/todo.py +0 -0
  56. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/builtins/write_file.py +0 -0
  57. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/tools/session_update.py +0 -0
  58. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/acp/utils.py +0 -0
  59. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/__init__.py +0 -0
  60. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/autocompletion/__init__.py +0 -0
  61. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/autocompletion/base.py +0 -0
  62. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/autocompletion/path_completion.py +0 -0
  63. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/autocompletion/slash_command.py +0 -0
  64. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/cli.py +0 -0
  65. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/clipboard.py +0 -0
  66. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/commands.py +0 -0
  67. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/history_manager.py +0 -0
  68. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  69. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  70. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  71. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/terminal_setup.py +0 -0
  72. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/__init__.py +0 -0
  73. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  74. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/app.py +0 -0
  75. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/app.tcss +0 -0
  76. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/external_editor.py +0 -0
  77. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  78. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  79. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  80. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  81. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  82. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  83. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  84. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  85. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  86. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  87. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  88. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  89. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  90. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  91. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  92. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  93. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  94. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  95. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  96. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  97. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  98. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  99. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  100. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  101. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  102. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  103. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  104. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  105. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  106. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  107. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  108. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  109. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  110. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  111. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  112. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  113. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/windowing/history.py +0 -0
  114. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  115. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/textual_ui/windowing/state.py +0 -0
  116. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/__init__.py +0 -0
  117. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  118. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  119. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  120. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  121. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  122. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/update.py +0 -0
  123. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/cli/update_notifier/whats_new.py +0 -0
  124. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/__init__.py +0 -0
  125. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/agents/__init__.py +0 -0
  126. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/agents/manager.py +0 -0
  127. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/auth/__init__.py +0 -0
  128. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/auth/crypto.py +0 -0
  129. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/auth/github.py +0 -0
  130. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/__init__.py +0 -0
  131. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/completers.py +0 -0
  132. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  133. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  134. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  135. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  136. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  137. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/fuzzy.py +0 -0
  138. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/path_prompt.py +0 -0
  139. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  140. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/config/__init__.py +0 -0
  141. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/config/_settings.py +0 -0
  142. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/config/harness_files/__init__.py +0 -0
  143. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/config/harness_files/_paths.py +0 -0
  144. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/consultant.py +0 -0
  145. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/drydock_states.py +0 -0
  146. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/__init__.py +0 -0
  147. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/backend/anthropic.py +0 -0
  148. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/backend/base.py +0 -0
  149. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/backend/factory.py +0 -0
  150. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/backend/generic.py +0 -0
  151. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/backend/mistral.py +0 -0
  152. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  153. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/backend/vertex.py +0 -0
  154. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/exceptions.py +0 -0
  155. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/format.py +0 -0
  156. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/message_utils.py +0 -0
  157. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/llm/types.py +0 -0
  158. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/logger.py +0 -0
  159. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/middleware.py +0 -0
  160. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/output_formatters.py +0 -0
  161. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/paths/__init__.py +0 -0
  162. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/paths/_local_config_walk.py +0 -0
  163. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/paths/_vibe_home.py +0 -0
  164. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/paths/conventions.py +0 -0
  165. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/plan_session.py +0 -0
  166. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/programmatic.py +0 -0
  167. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/__init__.py +0 -0
  168. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/compact.md +0 -0
  169. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/dangerous_directory.md +0 -0
  170. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/diagnostic.md +0 -0
  171. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/explore.md +0 -0
  172. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/planner.md +0 -0
  173. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/project_context.md +0 -0
  174. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/prompts/tests.md +0 -0
  175. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/proxy_setup.py +0 -0
  176. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/session/agent_memory.py +0 -0
  177. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/session/session_loader.py +0 -0
  178. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/session/session_logger.py +0 -0
  179. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/session/session_migration.py +0 -0
  180. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/session/state_file.py +0 -0
  181. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/skills/__init__.py +0 -0
  182. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/skills/manager.py +0 -0
  183. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/skills/models.py +0 -0
  184. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/skills/parser.py +0 -0
  185. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/slug.py +0 -0
  186. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/telemetry/__init__.py +0 -0
  187. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/telemetry/send.py +0 -0
  188. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/teleport/errors.py +0 -0
  189. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/teleport/git.py +0 -0
  190. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/teleport/nuage.py +0 -0
  191. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/teleport/teleport.py +0 -0
  192. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/teleport/types.py +0 -0
  193. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/base.py +0 -0
  194. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  195. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/bash.py +0 -0
  196. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/cron.py +0 -0
  197. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  198. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/glob_tool.py +0 -0
  199. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/grep.py +0 -0
  200. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  201. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/lsp.py +0 -0
  202. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  203. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  204. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/powershell.py +0 -0
  205. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  206. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  207. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  208. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  209. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  210. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  211. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  212. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  213. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  214. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  215. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  216. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  217. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  218. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  219. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/task.md +0 -0
  220. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  221. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  222. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  223. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  224. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  225. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  226. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  227. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/search_replace.py +0 -0
  228. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/task_manager.py +0 -0
  229. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/todo.py +0 -0
  230. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/tool_search.py +0 -0
  231. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/webfetch.py +0 -0
  232. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/websearch.py +0 -0
  233. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/worktree.py +0 -0
  234. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/builtins/write_file.py +0 -0
  235. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/injection_guard.py +0 -0
  236. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/manager.py +0 -0
  237. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/mcp/__init__.py +0 -0
  238. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/mcp/registry.py +0 -0
  239. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/mcp/tools.py +0 -0
  240. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/mcp_sampling.py +0 -0
  241. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/ui.py +0 -0
  242. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/tools/utils.py +0 -0
  243. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/trusted_folders.py +0 -0
  244. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/types.py +0 -0
  245. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/core/utils.py +0 -0
  246. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/onboarding/__init__.py +0 -0
  247. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/onboarding/base.py +0 -0
  248. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/onboarding/onboarding.tcss +0 -0
  249. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/onboarding/screens/__init__.py +0 -0
  250. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/onboarding/screens/api_key.py +0 -0
  251. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/onboarding/screens/welcome.py +0 -0
  252. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  253. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  254. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/__init__.py +0 -0
  255. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/batch/SKILL.md +0 -0
  256. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/create-presentation/SKILL.md +0 -0
  257. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/deep-research/SKILL.md +0 -0
  258. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/investigate/SKILL.md +0 -0
  259. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/review/SKILL.md +0 -0
  260. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/ship/SKILL.md +0 -0
  261. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/skills/simplify/SKILL.md +0 -0
  262. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock/whats_new.md +0 -0
  263. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock-acp.spec +0 -0
  264. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/drydock_terms.md +0 -0
  265. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/flake.lock +0 -0
  266. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/flake.nix +0 -0
  267. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/README.md +0 -0
  268. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/backup.sh +0 -0
  269. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/bump_version.py +0 -0
  270. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/deploy_to_github.sh +0 -0
  271. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/install.sh +0 -0
  272. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/prepare_release.py +0 -0
  273. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/publish_to_pypi.sh +0 -0
  274. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/test_full.sh +0 -0
  275. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/scripts/test_smoke.sh +0 -0
  276. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/__init__.py +0 -0
  277. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/conftest.py +0 -0
  278. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_acp.py +0 -0
  279. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_agent_thought.py +0 -0
  280. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_bash.py +0 -0
  281. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_compact_session_updates.py +0 -0
  282. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_content.py +0 -0
  283. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_initialize.py +0 -0
  284. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_list_sessions.py +0 -0
  285. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_load_session.py +0 -0
  286. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_multi_session.py +0 -0
  287. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_new_session.py +0 -0
  288. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_proxy_setup_acp.py +0 -0
  289. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_read_file.py +0 -0
  290. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_search_replace.py +0 -0
  291. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_set_config_option.py +0 -0
  292. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_set_mode.py +0 -0
  293. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_set_model.py +0 -0
  294. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_tool_call_session_update.py +0 -0
  295. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_utils.py +0 -0
  296. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/acp/test_write_file.py +0 -0
  297. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_file_indexer.py +0 -0
  298. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_fuzzy.py +0 -0
  299. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  300. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  301. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_path_completion_controller.py +0 -0
  302. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  303. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_slash_command_controller.py +0 -0
  304. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  305. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/__init__.py +0 -0
  306. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/data/__init__.py +0 -0
  307. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/data/fireworks.py +0 -0
  308. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/data/mistral.py +0 -0
  309. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/test_anthropic_adapter.py +0 -0
  310. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/test_backend.py +0 -0
  311. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/test_reasoning_adapter.py +0 -0
  312. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  313. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  314. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  315. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  316. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_bell_notifications.py +0 -0
  317. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_braille_renderer.py +0 -0
  318. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_clipboard.py +0 -0
  319. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_commands.py +0 -0
  320. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_copy_shortcuts.py +0 -0
  321. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_external_editor.py +0 -0
  322. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_no_markup_static.py +0 -0
  323. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_question_app.py +0 -0
  324. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_spinner.py +0 -0
  325. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_switching_mode.py +0 -0
  326. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  327. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  328. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_ui_session_resume.py +0 -0
  329. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/test_ui_skill_dispatch.py +0 -0
  330. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/textual_ui/__init__.py +0 -0
  331. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/cli/textual_ui/test_session_picker.py +0 -0
  332. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/conftest.py +0 -0
  333. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_agents.py +0 -0
  334. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_auth_crypto.py +0 -0
  335. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_auth_github.py +0 -0
  336. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_config_load_dotenv.py +0 -0
  337. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_config_paths.py +0 -0
  338. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_config_resolution.py +0 -0
  339. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_file_logging.py +0 -0
  340. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_plan_session.py +0 -0
  341. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_proxy_setup.py +0 -0
  342. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_slug.py +0 -0
  343. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_telemetry_send.py +0 -0
  344. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_teleport_git.py +0 -0
  345. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_teleport_nuage.py +0 -0
  346. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_teleport_service.py +0 -0
  347. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_trusted_folders.py +0 -0
  348. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/core/test_utils.py +0 -0
  349. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/e2e/common.py +0 -0
  350. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/e2e/conftest.py +0 -0
  351. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/e2e/mock_server.py +0 -0
  352. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  353. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/e2e/test_cli_tui_streaming.py +0 -0
  354. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  355. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/mock/__init__.py +0 -0
  356. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/mock/mock_backend_factory.py +0 -0
  357. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/mock/mock_entrypoint.py +0 -0
  358. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/mock/utils.py +0 -0
  359. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/onboarding/test_run_onboarding.py +0 -0
  360. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/onboarding/test_ui_onboarding.py +0 -0
  361. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/session/test_session_loader.py +0 -0
  362. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/session/test_session_logger.py +0 -0
  363. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/session/test_session_migration.py +0 -0
  364. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/skills/conftest.py +0 -0
  365. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/skills/test_manager.py +0 -0
  366. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/skills/test_models.py +0 -0
  367. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/skills/test_parser.py +0 -0
  368. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  369. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  370. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  371. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/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.1 → drydock_cli-1.3.1}/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.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  374. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  375. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  376. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  377. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  378. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  379. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  380. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  381. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  382. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  383. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  384. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  385. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  386. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  387. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  388. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  389. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  390. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  391. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  392. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  393. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  394. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  395. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  396. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  397. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  398. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  399. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  400. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  401. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  402. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  403. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  404. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  405. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  406. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  407. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  408. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  409. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  410. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  411. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  412. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  413. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  414. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  415. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  416. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  417. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  418. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  419. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  420. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  421. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  422. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  423. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  424. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  425. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  426. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  427. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  428. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/base_snapshot_test_app.py +0 -0
  429. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/conftest.py +0 -0
  430. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/snap_compare.py +0 -0
  431. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  432. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  433. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  434. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  435. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  436. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  437. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  438. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  439. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  440. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  441. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  442. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  443. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  444. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  445. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/stubs/fake_backend.py +0 -0
  446. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/stubs/fake_client.py +0 -0
  447. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/stubs/fake_tool.py +0 -0
  448. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_agent_auto_compact.py +0 -0
  449. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_agent_backend.py +0 -0
  450. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_agent_observer_streaming.py +0 -0
  451. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_agent_stats.py +0 -0
  452. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_agent_tasks.py +0 -0
  453. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_agent_tool_call.py +0 -0
  454. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_agents.py +0 -0
  455. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_cli_programmatic_preload.py +0 -0
  456. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_current_bugs.py +0 -0
  457. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_drydock_regression.py +0 -0
  458. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_drydock_tasks.py +0 -0
  459. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_full_regression.py +0 -0
  460. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_history_manager.py +0 -0
  461. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_integration.py +0 -0
  462. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_loop_detection.py +0 -0
  463. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_message_id.py +0 -0
  464. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_message_merging.py +0 -0
  465. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_middleware.py +0 -0
  466. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_multi_agent.py +0 -0
  467. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_real_failures.py +0 -0
  468. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_real_issues.py +0 -0
  469. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_reasoning_content.py +0 -0
  470. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_smoke.py +0 -0
  471. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_system_prompt.py +0 -0
  472. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_tagged_text.py +0 -0
  473. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_ui_external_editor.py +0 -0
  474. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_ui_input_history.py +0 -0
  475. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/test_user_issues.py +0 -0
  476. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_ask_user_question.py +0 -0
  477. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_bash.py +0 -0
  478. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_exit_plan_mode.py +0 -0
  479. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_grep.py +0 -0
  480. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_invoke_context.py +0 -0
  481. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_manager_get_tool_config.py +0 -0
  482. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_mcp.py +0 -0
  483. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_mcp_sampling.py +0 -0
  484. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_task.py +0 -0
  485. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_ui_bash_execution.py +0 -0
  486. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_webfetch.py +0 -0
  487. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/tools/test_websearch.py +0 -0
  488. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  489. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  490. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/test_do_update.py +0 -0
  491. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  492. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/test_github_update_gateway.py +0 -0
  493. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  494. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/test_ui_update_notification.py +0 -0
  495. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/test_update_use_case.py +0 -0
  496. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/tests/update_notifier/test_whats_new.py +0 -0
  497. {drydock_cli-1.2.1 → drydock_cli-1.3.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 1.2.1
3
+ Version: 1.3.1
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
@@ -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",
@@ -562,6 +562,23 @@ class AgentLoop:
562
562
  except (json.JSONDecodeError, AttributeError):
563
563
  edit_path = ""
564
564
 
565
+ # Auto-run diagnostics on edited Python files
566
+ if edit_path and edit_path.endswith(".py"):
567
+ try:
568
+ import asyncio
569
+ import subprocess
570
+ diag_result = subprocess.run(
571
+ ["python3", "-c", f"import ast; ast.parse(open('{edit_path}').read()); print('OK')"],
572
+ capture_output=True, text=True, timeout=5,
573
+ )
574
+ if diag_result.returncode != 0:
575
+ self._inject_system_note(
576
+ f"SYNTAX ERROR in {edit_path}: {diag_result.stderr.strip()[:200]}. "
577
+ f"Fix the syntax error before continuing."
578
+ )
579
+ except Exception:
580
+ pass
581
+
565
582
  # After first edit: prompt to check related files
566
583
  if first_edit and edit_path:
567
584
  self._inject_system_note(
@@ -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
@@ -38,10 +38,17 @@ HOW to delegate:
38
38
  task(task="Explore the project structure and list all modules", agent="explore")
39
39
  task(task="Analyze why test_auth fails with KeyError", agent="diagnostic")
40
40
  task(task="Plan the refactoring of the auth module", agent="planner")
41
+ task(task="Review the auth module for security issues", agent="explore", background=true)
41
42
  invoke_skill(skill_name="review")
42
43
  invoke_skill(skill_name="investigate", arguments="Fix the login timeout bug")
43
44
  ```
44
45
 
46
+ Background subagents (background=true):
47
+ - Run without blocking your main conversation
48
+ - Results saved to task list — check with task_list
49
+ - Use for parallel work: launch multiple subagents, then check results
50
+ - Example: `task(task="Explore module A", agent="explore", background=true)` then `task(task="Explore module B", agent="explore", background=true)` — both run simultaneously
51
+
45
52
  WHEN to delegate (ALWAYS do this):
46
53
  - Project has 3+ files to examine → `task(..., agent="explore")` FIRST
47
54
  - Need to understand unfamiliar code → explore subagent, then you fix
@@ -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,
@@ -38,6 +38,10 @@ class TaskArgs(BaseModel):
38
38
  default="explore",
39
39
  description="Name of the agent profile to use (must be a subagent)",
40
40
  )
41
+ background: bool = Field(
42
+ default=False,
43
+ description="Run in background (non-blocking). Results available via task_list.",
44
+ )
41
45
 
42
46
 
43
47
  class TaskResult(BaseModel):
@@ -128,15 +132,56 @@ class Task(
128
132
  enabled=ctx.session_dir is not None,
129
133
  )
130
134
  base_config = VibeConfig.load(session_logging=session_logging)
135
+
136
+ # Apply per-agent model if configured
137
+ if agent_profile.model:
138
+ base_config = agent_profile.apply_to_config(base_config)
139
+
131
140
  subagent_loop = AgentLoop(
132
141
  config=base_config,
133
142
  agent_name=args.agent,
143
+ max_turns=agent_profile.max_turns,
134
144
  entrypoint_metadata=ctx.entrypoint_metadata,
135
145
  )
136
146
 
137
147
  if ctx and ctx.approval_callback:
138
148
  subagent_loop.set_approval_callback(ctx.approval_callback)
139
149
 
150
+ # Background execution: launch and return immediately
151
+ if args.background:
152
+ import asyncio
153
+ from drydock.core.tools.builtins.task_manager import _TASKS
154
+
155
+ task_id = f"bg-{args.agent}-{len(_TASKS)+1}"
156
+ _TASKS[task_id] = {
157
+ "id": task_id,
158
+ "title": f"[background] {args.task[:60]}",
159
+ "description": args.task,
160
+ "status": "in_progress",
161
+ "agent": args.agent,
162
+ }
163
+
164
+ async def _run_background():
165
+ response_parts = []
166
+ try:
167
+ async for event in subagent_loop.act(args.task):
168
+ if isinstance(event, AssistantEvent) and event.content:
169
+ response_parts.append(event.content)
170
+ except Exception as e:
171
+ response_parts.append(f"[Error: {e}]")
172
+ _TASKS[task_id]["status"] = "completed"
173
+ _TASKS[task_id]["result"] = "".join(response_parts)
174
+
175
+ asyncio.create_task(_run_background())
176
+
177
+ yield TaskResult(
178
+ response=f"Subagent '{args.agent}' launched in background (task {task_id}). Check status with task_list.",
179
+ turns_used=0,
180
+ completed=False,
181
+ )
182
+ return
183
+
184
+ # Foreground execution: block and collect results
140
185
  accumulated_response: list[str] = []
141
186
  completed = True
142
187
  try:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "1.2.1"
3
+ version = "1.3.1"
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