drydock-cli 2.2.9__tar.gz → 2.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 (518) hide show
  1. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/PKG-INFO +1 -1
  2. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/agent_loop.py +21 -23
  3. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/skills/models.py +6 -0
  4. drydock_cli-2.3.1/drydock/core/tools/builtins/invoke_skill.py +204 -0
  5. drydock_cli-2.3.1/drydock/core/tools/builtins/mcp_resources.py +194 -0
  6. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/mcp/tools.py +106 -0
  7. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/pyproject.toml +1 -1
  8. drydock_cli-2.2.9/drydock/core/tools/builtins/invoke_skill.py +0 -100
  9. drydock_cli-2.2.9/drydock/core/tools/builtins/mcp_resources.py +0 -118
  10. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/CODEOWNERS +0 -0
  11. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  12. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  13. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  14. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/workflows/build-and-upload.yml +0 -0
  15. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/workflows/ci.yml +0 -0
  16. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/workflows/issue-labeler.yml +0 -0
  17. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.github/workflows/release.yml +0 -0
  18. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.gitignore +0 -0
  19. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.pre-commit-config.yaml +0 -0
  20. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.python-version +0 -0
  21. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.typos.toml +0 -0
  22. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.vscode/extensions.json +0 -0
  23. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.vscode/launch.json +0 -0
  24. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/.vscode/settings.json +0 -0
  25. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/AGENTS.md +0 -0
  26. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/CHANGELOG.md +0 -0
  27. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/CLAUDE.md +0 -0
  28. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/CONTRIBUTING.md +0 -0
  29. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/Drydock_rebrand.md +0 -0
  30. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/LICENSE +0 -0
  31. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/NOTICE +0 -0
  32. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/PRD.md +0 -0
  33. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/README.md +0 -0
  34. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/action.yml +0 -0
  35. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/distribution/zed/LICENSE +0 -0
  36. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/distribution/zed/extension.toml +0 -0
  37. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/distribution/zed/icons/mistral_vibe.svg +0 -0
  38. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/docs/README.md +0 -0
  39. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/docs/acp-setup.md +0 -0
  40. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/docs/proxy-setup.md +0 -0
  41. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/__init__.py +0 -0
  42. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/__init__.py +0 -0
  43. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/acp_agent_loop.py +0 -0
  44. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/acp_logger.py +0 -0
  45. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/entrypoint.py +0 -0
  46. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/__init__.py +0 -0
  47. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/base.py +0 -0
  48. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/builtins/bash.py +0 -0
  49. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/builtins/read_file.py +0 -0
  50. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/builtins/search_replace.py +0 -0
  51. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/builtins/todo.py +0 -0
  52. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/builtins/write_file.py +0 -0
  53. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/tools/session_update.py +0 -0
  54. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/acp/utils.py +0 -0
  55. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/__init__.py +0 -0
  56. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/autocompletion/__init__.py +0 -0
  57. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/autocompletion/base.py +0 -0
  58. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/autocompletion/path_completion.py +0 -0
  59. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/autocompletion/slash_command.py +0 -0
  60. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/cli.py +0 -0
  61. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/clipboard.py +0 -0
  62. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/commands.py +0 -0
  63. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/entrypoint.py +0 -0
  64. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/history_manager.py +0 -0
  65. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  66. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  67. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  68. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/terminal_setup.py +0 -0
  69. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/__init__.py +0 -0
  70. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  71. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/app.py +0 -0
  72. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/app.tcss +0 -0
  73. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/external_editor.py +0 -0
  74. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  75. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  76. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  77. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  78. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  79. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  80. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  81. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  82. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  83. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  84. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  85. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  86. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  87. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  88. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  89. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  90. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  91. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  92. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  93. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  94. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  95. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  96. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  97. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  98. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  99. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  100. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  101. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  102. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  103. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  104. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  105. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  106. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  107. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  108. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  109. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  110. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/windowing/history.py +0 -0
  111. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  112. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/textual_ui/windowing/state.py +0 -0
  113. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/__init__.py +0 -0
  114. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  115. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  116. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  117. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  118. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  119. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/update.py +0 -0
  120. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/cli/update_notifier/whats_new.py +0 -0
  121. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/__init__.py +0 -0
  122. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/agents/__init__.py +0 -0
  123. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/agents/manager.py +0 -0
  124. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/agents/models.py +0 -0
  125. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/auth/__init__.py +0 -0
  126. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/auth/crypto.py +0 -0
  127. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/auth/github.py +0 -0
  128. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/__init__.py +0 -0
  129. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/completers.py +0 -0
  130. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  131. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  132. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  133. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  134. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  135. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/fuzzy.py +0 -0
  136. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/path_prompt.py +0 -0
  137. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  138. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/build_orchestrator.py +0 -0
  139. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/config/__init__.py +0 -0
  140. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/config/_settings.py +0 -0
  141. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/config/harness_files/__init__.py +0 -0
  142. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  143. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/config/harness_files/_paths.py +0 -0
  144. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/consultant.py +0 -0
  145. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/drydock_states.py +0 -0
  146. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/hooks.py +0 -0
  147. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/__init__.py +0 -0
  148. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/backend/anthropic.py +0 -0
  149. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/backend/base.py +0 -0
  150. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/backend/factory.py +0 -0
  151. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/backend/generic.py +0 -0
  152. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/backend/mistral.py +0 -0
  153. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  154. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/backend/vertex.py +0 -0
  155. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/exceptions.py +0 -0
  156. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/format.py +0 -0
  157. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/message_utils.py +0 -0
  158. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/llm/types.py +0 -0
  159. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/logger.py +0 -0
  160. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/middleware.py +0 -0
  161. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/output_formatters.py +0 -0
  162. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/paths/__init__.py +0 -0
  163. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/paths/_local_config_walk.py +0 -0
  164. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/paths/_vibe_home.py +0 -0
  165. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/paths/conventions.py +0 -0
  166. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/plan_session.py +0 -0
  167. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/plugins.py +0 -0
  168. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/programmatic.py +0 -0
  169. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/__init__.py +0 -0
  170. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/builder.md +0 -0
  171. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/cli.md +0 -0
  172. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/compact.md +0 -0
  173. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/dangerous_directory.md +0 -0
  174. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/diagnostic.md +0 -0
  175. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/explore.md +0 -0
  176. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/planner.md +0 -0
  177. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/project_context.md +0 -0
  178. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/prompts/tests.md +0 -0
  179. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/proxy_setup.py +0 -0
  180. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/session/agent_memory.py +0 -0
  181. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/session/checkpoints.py +0 -0
  182. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/session/session_loader.py +0 -0
  183. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/session/session_logger.py +0 -0
  184. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/session/session_migration.py +0 -0
  185. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/session/state_file.py +0 -0
  186. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/skills/__init__.py +0 -0
  187. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/skills/manager.py +0 -0
  188. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/skills/parser.py +0 -0
  189. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/slug.py +0 -0
  190. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/system_prompt.py +0 -0
  191. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/telemetry/__init__.py +0 -0
  192. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/telemetry/send.py +0 -0
  193. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/teleport/errors.py +0 -0
  194. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/teleport/git.py +0 -0
  195. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/teleport/nuage.py +0 -0
  196. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/teleport/teleport.py +0 -0
  197. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/teleport/types.py +0 -0
  198. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/base.py +0 -0
  199. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  200. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/bash.py +0 -0
  201. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/cron.py +0 -0
  202. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  203. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/glob_tool.py +0 -0
  204. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/grep.py +0 -0
  205. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/lsp.py +0 -0
  206. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  207. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/powershell.py +0 -0
  208. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  209. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  210. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  211. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  212. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  213. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  214. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  215. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  216. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  217. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  218. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  219. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  220. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  221. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  222. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/task.md +0 -0
  223. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  224. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  225. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  226. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  227. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  228. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  229. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  230. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/read_file.py +0 -0
  231. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/search_replace.py +0 -0
  232. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/task.py +0 -0
  233. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/task_manager.py +0 -0
  234. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/todo.py +0 -0
  235. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/tool_search.py +0 -0
  236. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/webfetch.py +0 -0
  237. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/websearch.py +0 -0
  238. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/worktree.py +0 -0
  239. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/builtins/write_file.py +0 -0
  240. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/injection_guard.py +0 -0
  241. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/manager.py +0 -0
  242. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/mcp/__init__.py +0 -0
  243. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/mcp/registry.py +0 -0
  244. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/mcp_sampling.py +0 -0
  245. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/ui.py +0 -0
  246. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/tools/utils.py +0 -0
  247. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/trusted_folders.py +0 -0
  248. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/types.py +0 -0
  249. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/core/utils.py +0 -0
  250. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/onboarding/__init__.py +0 -0
  251. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/onboarding/base.py +0 -0
  252. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/onboarding/onboarding.tcss +0 -0
  253. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/onboarding/screens/__init__.py +0 -0
  254. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/onboarding/screens/api_key.py +0 -0
  255. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/onboarding/screens/welcome.py +0 -0
  256. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  257. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  258. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/__init__.py +0 -0
  259. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/batch/SKILL.md +0 -0
  260. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/create-presentation/SKILL.md +0 -0
  261. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/deep-research/SKILL.md +0 -0
  262. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/investigate/SKILL.md +0 -0
  263. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/review/SKILL.md +0 -0
  264. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/ship/SKILL.md +0 -0
  265. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/skills/simplify/SKILL.md +0 -0
  266. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock/whats_new.md +0 -0
  267. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock-acp.spec +0 -0
  268. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/drydock_terms.md +0 -0
  269. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/flake.lock +0 -0
  270. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/flake.nix +0 -0
  271. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/README.md +0 -0
  272. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/auto_test_loop.sh +0 -0
  273. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/backup.sh +0 -0
  274. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/bump_version.py +0 -0
  275. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/deploy_to_github.sh +0 -0
  276. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/install.sh +0 -0
  277. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/monitor_swebench.sh +0 -0
  278. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/monitor_test_battery.sh +0 -0
  279. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/notify_release.py +0 -0
  280. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/overnight_agents_test.sh +0 -0
  281. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/prepare_release.py +0 -0
  282. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/publish_to_pypi.sh +0 -0
  283. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/test_bank.sh +0 -0
  284. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/test_full.sh +0 -0
  285. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/scripts/test_smoke.sh +0 -0
  286. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/__init__.py +0 -0
  287. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/conftest.py +0 -0
  288. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_acp.py +0 -0
  289. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_agent_thought.py +0 -0
  290. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_bash.py +0 -0
  291. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_compact_session_updates.py +0 -0
  292. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_content.py +0 -0
  293. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_initialize.py +0 -0
  294. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_list_sessions.py +0 -0
  295. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_load_session.py +0 -0
  296. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_multi_session.py +0 -0
  297. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_new_session.py +0 -0
  298. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_proxy_setup_acp.py +0 -0
  299. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_read_file.py +0 -0
  300. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_search_replace.py +0 -0
  301. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_set_config_option.py +0 -0
  302. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_set_mode.py +0 -0
  303. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_set_model.py +0 -0
  304. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_tool_call_session_update.py +0 -0
  305. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_utils.py +0 -0
  306. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/acp/test_write_file.py +0 -0
  307. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_file_indexer.py +0 -0
  308. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_fuzzy.py +0 -0
  309. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  310. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  311. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_path_completion_controller.py +0 -0
  312. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  313. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_slash_command_controller.py +0 -0
  314. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  315. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/__init__.py +0 -0
  316. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/data/__init__.py +0 -0
  317. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/data/fireworks.py +0 -0
  318. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/data/mistral.py +0 -0
  319. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/test_anthropic_adapter.py +0 -0
  320. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/test_backend.py +0 -0
  321. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/test_reasoning_adapter.py +0 -0
  322. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  323. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  324. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  325. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  326. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_bell_notifications.py +0 -0
  327. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_braille_renderer.py +0 -0
  328. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_clipboard.py +0 -0
  329. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_commands.py +0 -0
  330. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_copy_shortcuts.py +0 -0
  331. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_external_editor.py +0 -0
  332. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_no_markup_static.py +0 -0
  333. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_question_app.py +0 -0
  334. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_spinner.py +0 -0
  335. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_switching_mode.py +0 -0
  336. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  337. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  338. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_ui_session_resume.py +0 -0
  339. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/test_ui_skill_dispatch.py +0 -0
  340. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/textual_ui/__init__.py +0 -0
  341. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/cli/textual_ui/test_session_picker.py +0 -0
  342. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/conftest.py +0 -0
  343. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_agents.py +0 -0
  344. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_auth_crypto.py +0 -0
  345. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_auth_github.py +0 -0
  346. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_config_load_dotenv.py +0 -0
  347. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_config_paths.py +0 -0
  348. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_config_resolution.py +0 -0
  349. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_file_logging.py +0 -0
  350. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_plan_session.py +0 -0
  351. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_proxy_setup.py +0 -0
  352. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_slug.py +0 -0
  353. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_telemetry_send.py +0 -0
  354. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_teleport_git.py +0 -0
  355. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_teleport_nuage.py +0 -0
  356. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_teleport_service.py +0 -0
  357. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_trusted_folders.py +0 -0
  358. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/core/test_utils.py +0 -0
  359. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/e2e/common.py +0 -0
  360. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/e2e/conftest.py +0 -0
  361. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/e2e/mock_server.py +0 -0
  362. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  363. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/e2e/test_cli_tui_streaming.py +0 -0
  364. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  365. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/mock/__init__.py +0 -0
  366. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/mock/mock_backend_factory.py +0 -0
  367. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/mock/mock_entrypoint.py +0 -0
  368. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/mock/utils.py +0 -0
  369. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/onboarding/test_run_onboarding.py +0 -0
  370. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/onboarding/test_ui_onboarding.py +0 -0
  371. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/session/test_session_loader.py +0 -0
  372. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/session/test_session_logger.py +0 -0
  373. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/session/test_session_migration.py +0 -0
  374. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/skills/conftest.py +0 -0
  375. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/skills/test_manager.py +0 -0
  376. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/skills/test_models.py +0 -0
  377. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/skills/test_parser.py +0 -0
  378. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  379. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  380. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  381. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  382. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  383. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  384. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  385. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  386. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  387. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  388. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  389. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  390. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  391. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  392. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  393. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  394. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  395. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  396. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  397. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  398. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  399. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  400. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  401. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  402. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  403. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  404. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  405. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  406. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  407. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  408. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  409. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  410. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  411. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  412. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  413. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  414. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  415. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  416. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  417. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  418. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  419. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  420. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  421. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  422. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  423. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  424. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  425. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  426. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  427. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  428. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  429. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  430. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  431. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  432. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  433. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  434. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  435. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  436. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  437. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  438. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/base_snapshot_test_app.py +0 -0
  439. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/conftest.py +0 -0
  440. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/snap_compare.py +0 -0
  441. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  442. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  443. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  444. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  445. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  446. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  447. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  448. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  449. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  450. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  451. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  452. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  453. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  454. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  455. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/stubs/fake_backend.py +0 -0
  456. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/stubs/fake_client.py +0 -0
  457. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/stubs/fake_tool.py +0 -0
  458. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_agent_auto_compact.py +0 -0
  459. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_agent_backend.py +0 -0
  460. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_agent_observer_streaming.py +0 -0
  461. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_agent_stats.py +0 -0
  462. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_agent_tasks.py +0 -0
  463. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_agent_tool_call.py +0 -0
  464. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_agents.py +0 -0
  465. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_bank_build.py +0 -0
  466. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_bank_debug.py +0 -0
  467. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_bank_multiagent.py +0 -0
  468. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_bank_prd.py +0 -0
  469. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_bank_prd_extended.py +0 -0
  470. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_bank_tools.py +0 -0
  471. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_bank_update.py +0 -0
  472. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_build_projects.py +0 -0
  473. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_cli_programmatic_preload.py +0 -0
  474. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_current_bugs.py +0 -0
  475. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_drydock_regression.py +0 -0
  476. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_drydock_tasks.py +0 -0
  477. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_full_regression.py +0 -0
  478. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_history_manager.py +0 -0
  479. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_integration.py +0 -0
  480. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_loop_detection.py +0 -0
  481. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_message_id.py +0 -0
  482. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_message_merging.py +0 -0
  483. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_middleware.py +0 -0
  484. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_multi_agent.py +0 -0
  485. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_real_failures.py +0 -0
  486. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_real_issues.py +0 -0
  487. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_real_workflow.py +0 -0
  488. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_reasoning_content.py +0 -0
  489. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_smoke.py +0 -0
  490. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_system_prompt.py +0 -0
  491. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_tagged_text.py +0 -0
  492. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_ui_external_editor.py +0 -0
  493. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_ui_input_history.py +0 -0
  494. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_user_issues.py +0 -0
  495. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/test_workloads.py +0 -0
  496. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/testbank_helpers.py +0 -0
  497. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_ask_user_question.py +0 -0
  498. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_bash.py +0 -0
  499. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_exit_plan_mode.py +0 -0
  500. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_grep.py +0 -0
  501. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_invoke_context.py +0 -0
  502. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_manager_get_tool_config.py +0 -0
  503. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_mcp.py +0 -0
  504. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_mcp_sampling.py +0 -0
  505. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_task.py +0 -0
  506. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_ui_bash_execution.py +0 -0
  507. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_webfetch.py +0 -0
  508. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/tools/test_websearch.py +0 -0
  509. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  510. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  511. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/test_do_update.py +0 -0
  512. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  513. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/test_github_update_gateway.py +0 -0
  514. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  515. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/test_ui_update_notification.py +0 -0
  516. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/test_update_use_case.py +0 -0
  517. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/tests/update_notifier/test_whats_new.py +0 -0
  518. {drydock_cli-2.2.9 → drydock_cli-2.3.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.2.9
3
+ Version: 2.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
@@ -2053,30 +2053,28 @@ class AgentLoop:
2053
2053
  except Exception:
2054
2054
  pass
2055
2055
 
2056
- # 2. Skill routing: match prompt to skill and inject content
2057
- skill_name = None
2058
- if any(kw in msg_lower for kw in ("review this", "review the", "code review", "audit")):
2059
- skill_name = "review"
2060
- elif any(kw in msg_lower for kw in ("investigate", "debug", "why does", "why is", "broken", "diagnose")):
2061
- skill_name = "investigate"
2062
- elif any(kw in msg_lower for kw in ("ship it", "commit and push", "create a pr", "open a pr")):
2063
- skill_name = "ship"
2064
- elif any(kw in msg_lower for kw in ("simplify", "clean up", "reduce complexity")):
2065
- skill_name = "simplify"
2056
+ # 2. Skill discovery: inject all skill descriptions so the model
2057
+ # can decide when to use them (replaces hardcoded keyword matching)
2058
+ try:
2059
+ skill_descriptions = []
2060
+ for name, info in self.skill_manager.list_skills().items():
2061
+ desc = info.description or name
2062
+ skill_descriptions.append(f" /{name} {desc[:100]}")
2063
+ if skill_descriptions:
2064
+ parts.append(
2065
+ "AVAILABLE SKILLS (use invoke_skill to activate):\n"
2066
+ + "\n".join(skill_descriptions[:10])
2067
+ )
2068
+ except Exception:
2069
+ pass
2066
2070
 
2067
- if skill_name:
2068
- skill_info = self.skill_manager.get_skill(skill_name)
2069
- if skill_info and skill_info.skill_path:
2070
- try:
2071
- content = skill_info.skill_path.read_text(encoding="utf-8")
2072
- # Strip frontmatter
2073
- if content.startswith("---"):
2074
- end = content.find("---", 3)
2075
- if end > 0:
2076
- content = content[end + 3:].strip()
2077
- parts.append(f"FOLLOW THIS WORKFLOW ({skill_name} skill):\n{content[:2000]}")
2078
- except Exception:
2079
- pass
2071
+ # 3. Subagent descriptions for delegation
2072
+ parts.append(
2073
+ "SUBAGENTS (use task tool to delegate):\n"
2074
+ " task(task='...', agent='explore') — Read-only codebase exploration\n"
2075
+ " task(task='...', agent='diagnostic') — Debug/investigate with bash access\n"
2076
+ " task(task='...', agent='planner') — Plan multi-file changes before coding"
2077
+ )
2080
2078
 
2081
2079
  # 3. Planning nudge for complex build tasks
2082
2080
  is_build = any(kw in msg_lower for kw in (
@@ -88,6 +88,9 @@ class SkillInfo(BaseModel):
88
88
  metadata: dict[str, str] = Field(default_factory=dict)
89
89
  allowed_tools: list[str] = Field(default_factory=list)
90
90
  user_invocable: bool = True
91
+ context: str = "" # 'fork' to run in subagent
92
+ agent: str = "" # subagent type when context='fork'
93
+ model: str = "" # model override
91
94
  skill_path: Path
92
95
 
93
96
  model_config = {"arbitrary_types_allowed": True}
@@ -106,5 +109,8 @@ class SkillInfo(BaseModel):
106
109
  metadata=meta.metadata,
107
110
  allowed_tools=meta.allowed_tools,
108
111
  user_invocable=meta.user_invocable,
112
+ context=meta.context,
113
+ agent=meta.agent,
114
+ model=meta.model,
109
115
  skill_path=skill_path.resolve(),
110
116
  )
@@ -0,0 +1,204 @@
1
+ """Invoke Skill tool — lets the model call skills programmatically.
2
+
3
+ The model can invoke any registered skill by name, equivalent to
4
+ the user typing /skill-name in the chat.
5
+
6
+ Supports:
7
+ - $ARGUMENTS, $0, $1 positional substitution in skill content
8
+ - !`command` shell preprocessing (runs at load time, output replaces command)
9
+ - context: fork for subagent execution
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import re
15
+ import subprocess
16
+ from collections.abc import AsyncGenerator
17
+ from pathlib import Path
18
+ from typing import ClassVar, final
19
+
20
+ from pydantic import BaseModel, Field
21
+
22
+ from drydock.core.tools.base import (
23
+ BaseTool, BaseToolConfig, BaseToolState, InvokeContext, ToolError, ToolPermission,
24
+ )
25
+ from drydock.core.tools.ui import ToolCallDisplay, ToolResultDisplay, ToolUIData
26
+ from drydock.core.types import ToolStreamEvent, ToolResultEvent
27
+
28
+
29
+ def _substitute_arguments(content: str, arguments: str, skill_dir: str = "") -> str:
30
+ """Replace $ARGUMENTS, $0, $1, ${SKILL_DIR} in skill content."""
31
+ if not arguments:
32
+ return content
33
+ content = content.replace("$ARGUMENTS", arguments)
34
+ arg_parts = arguments.split()
35
+ for i, arg in enumerate(arg_parts[:10]):
36
+ content = content.replace(f"$ARGUMENTS[{i}]", arg)
37
+ content = content.replace(f"${i}", arg)
38
+ if skill_dir:
39
+ content = content.replace("${SKILL_DIR}", skill_dir)
40
+ return content
41
+
42
+
43
+ def _preprocess_commands(content: str) -> str:
44
+ """Execute !`command` inline and replace with output."""
45
+ def _run(match):
46
+ cmd = match.group(1)
47
+ try:
48
+ result = subprocess.run(
49
+ cmd, shell=True, capture_output=True, text=True,
50
+ timeout=10, cwd=str(Path.cwd()),
51
+ )
52
+ return result.stdout.strip() or result.stderr.strip() or "(no output)"
53
+ except subprocess.TimeoutExpired:
54
+ return f"[command timed out: {cmd}]"
55
+ except Exception as e:
56
+ return f"[command failed: {e}]"
57
+ return re.sub(r'!`([^`]+)`', _run, content)
58
+
59
+
60
+ class InvokeSkillArgs(BaseModel):
61
+ skill_name: str = Field(description="Name of the skill to invoke (e.g., 'investigate', 'review')")
62
+ arguments: str = Field(default="", description="Arguments to pass to the skill (e.g., issue number, file path)")
63
+
64
+
65
+ class InvokeSkillResult(BaseModel):
66
+ skill_name: str
67
+ content: str
68
+ loaded: bool
69
+ forked: bool = False
70
+
71
+
72
+ class InvokeSkill(
73
+ BaseTool[InvokeSkillArgs, InvokeSkillResult, BaseToolConfig, BaseToolState],
74
+ ToolUIData[InvokeSkillArgs, InvokeSkillResult],
75
+ ):
76
+ description: ClassVar[str] = (
77
+ "Invoke a skill by name. Use this to activate specialized workflows "
78
+ "like /investigate, /review, /ship, /batch, etc."
79
+ )
80
+
81
+ @classmethod
82
+ def format_call_display(cls, args: InvokeSkillArgs) -> ToolCallDisplay:
83
+ return ToolCallDisplay(summary=f"skill: /{args.skill_name}")
84
+
85
+ @classmethod
86
+ def get_result_display(cls, event: ToolResultEvent) -> ToolResultDisplay:
87
+ if isinstance(event.result, InvokeSkillResult):
88
+ status = "forked" if event.result.forked else "loaded"
89
+ return ToolResultDisplay(success=event.result.loaded, message=f"/{event.result.skill_name} ({status})")
90
+ return ToolResultDisplay(success=True, message="Skill invoked")
91
+
92
+ @classmethod
93
+ def get_status_text(cls) -> str:
94
+ return "Loading skill"
95
+
96
+ def resolve_permission(self, args: InvokeSkillArgs) -> ToolPermission | None:
97
+ return ToolPermission.ALWAYS
98
+
99
+ @final
100
+ async def run(
101
+ self, args: InvokeSkillArgs, ctx: InvokeContext | None = None
102
+ ) -> AsyncGenerator[ToolStreamEvent | InvokeSkillResult, None]:
103
+ if not ctx or not ctx.agent_manager:
104
+ raise ToolError("No agent manager available")
105
+
106
+ try:
107
+ from drydock.core.skills.manager import SkillManager
108
+ config = ctx.agent_manager.config
109
+ manager = SkillManager(lambda: config)
110
+ skills = manager.available_skills
111
+
112
+ if args.skill_name not in skills:
113
+ available = ", ".join(sorted(skills.keys()))
114
+ raise ToolError(
115
+ f"Skill '{args.skill_name}' not found. "
116
+ f"Available: {available}"
117
+ )
118
+
119
+ skill_info = skills[args.skill_name]
120
+ raw_content = skill_info.skill_path.read_text(encoding="utf-8") if skill_info.skill_path else ""
121
+
122
+ # Strip frontmatter, keep it for metadata check
123
+ content = raw_content
124
+ meta_context = ""
125
+ meta_agent = ""
126
+ if content.startswith("---"):
127
+ parts = content.split("---", 2)
128
+ if len(parts) >= 3:
129
+ # Parse context/agent from frontmatter
130
+ import yaml
131
+ try:
132
+ fm = yaml.safe_load(parts[1]) or {}
133
+ meta_context = fm.get("context", "")
134
+ meta_agent = fm.get("agent", "")
135
+ except Exception:
136
+ pass
137
+ content = parts[2].strip()
138
+
139
+ # $ARGUMENTS substitution
140
+ skill_dir = str(skill_info.skill_path.parent) if skill_info.skill_path else ""
141
+ content = _substitute_arguments(content, args.arguments, skill_dir)
142
+
143
+ # !`command` preprocessing
144
+ content = _preprocess_commands(content)
145
+
146
+ # If no $ARGUMENTS were in the template, prepend args
147
+ if args.arguments and "$ARGUMENTS" not in raw_content and "$0" not in raw_content:
148
+ content = f"{args.arguments}\n\n{content}"
149
+
150
+ # context: fork — run in a subagent
151
+ if meta_context == "fork":
152
+ agent_name = meta_agent or "explore"
153
+ # Delegate to the task tool's subagent mechanism
154
+ from drydock.core.agents.models import BUILTIN_AGENTS, AgentType
155
+ agent_profile = BUILTIN_AGENTS.get(agent_name)
156
+ if agent_profile and agent_profile.agent_type == AgentType.SUBAGENT:
157
+ from drydock.core.agent_loop import AgentLoop
158
+ from drydock.core.config import SessionLoggingConfig, VibeConfig
159
+
160
+ session_logging = SessionLoggingConfig(
161
+ save_dir=str(ctx.session_dir / "skills") if ctx.session_dir else "",
162
+ session_prefix=f"skill-{args.skill_name}",
163
+ enabled=ctx.session_dir is not None,
164
+ )
165
+ sub_config = VibeConfig.load(session_logging=session_logging)
166
+ if agent_profile.model:
167
+ sub_config = agent_profile.apply_to_config(sub_config)
168
+
169
+ subagent = AgentLoop(
170
+ config=sub_config,
171
+ agent_name=agent_name,
172
+ max_turns=agent_profile.max_turns,
173
+ entrypoint_metadata=ctx.entrypoint_metadata,
174
+ )
175
+ if ctx.approval_callback:
176
+ subagent.set_approval_callback(ctx.approval_callback)
177
+
178
+ # Run the skill content as the subagent's task
179
+ response_parts = []
180
+ turns = 0
181
+ async for event in subagent.run(content):
182
+ from drydock.core.types import AssistantEvent
183
+ if isinstance(event, AssistantEvent) and event.content:
184
+ response_parts.append(event.content)
185
+ turns += 1
186
+
187
+ yield InvokeSkillResult(
188
+ skill_name=args.skill_name,
189
+ content="\n".join(response_parts) or "(subagent produced no output)",
190
+ loaded=True,
191
+ forked=True,
192
+ )
193
+ return
194
+
195
+ yield InvokeSkillResult(
196
+ skill_name=args.skill_name,
197
+ content=content,
198
+ loaded=True,
199
+ )
200
+
201
+ except ToolError:
202
+ raise
203
+ except Exception as e:
204
+ raise ToolError(f"Failed to load skill: {e}") from e
@@ -0,0 +1,194 @@
1
+ """MCP Resource tools — list and read MCP server resources.
2
+
3
+ MCP servers can expose resources (files, data) in addition to tools.
4
+ These tools let the agent discover and read them.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import asyncio
10
+ from collections.abc import AsyncGenerator
11
+ from typing import ClassVar, final
12
+
13
+ from pydantic import BaseModel, Field
14
+
15
+ from drydock.core.tools.base import (
16
+ BaseTool, BaseToolConfig, BaseToolState, InvokeContext, ToolError, ToolPermission,
17
+ )
18
+ from drydock.core.tools.ui import ToolCallDisplay, ToolResultDisplay, ToolUIData
19
+ from drydock.core.types import ToolStreamEvent, ToolResultEvent
20
+
21
+
22
+ class ListMcpResourcesArgs(BaseModel):
23
+ server_name: str = Field(default="", description="MCP server name (empty = all servers)")
24
+
25
+
26
+ class McpResource(BaseModel):
27
+ uri: str
28
+ name: str
29
+ description: str = ""
30
+ mime_type: str = ""
31
+ server: str = ""
32
+
33
+
34
+ class ListMcpResourcesResult(BaseModel):
35
+ resources: list[McpResource]
36
+ count: int
37
+
38
+
39
+ class ListMcpResources(
40
+ BaseTool[ListMcpResourcesArgs, ListMcpResourcesResult, BaseToolConfig, BaseToolState],
41
+ ToolUIData[ListMcpResourcesArgs, ListMcpResourcesResult],
42
+ ):
43
+ description: ClassVar[str] = "List resources available from MCP servers."
44
+
45
+ @classmethod
46
+ def format_call_display(cls, args: ListMcpResourcesArgs) -> ToolCallDisplay:
47
+ return ToolCallDisplay(summary=f"list_mcp_resources: {args.server_name or 'all'}")
48
+
49
+ @classmethod
50
+ def get_result_display(cls, event: ToolResultEvent) -> ToolResultDisplay:
51
+ if isinstance(event.result, ListMcpResourcesResult):
52
+ return ToolResultDisplay(success=True, message=f"{event.result.count} resources")
53
+ return ToolResultDisplay(success=True, message="Resources listed")
54
+
55
+ @classmethod
56
+ def get_status_text(cls) -> str:
57
+ return "Listing MCP resources"
58
+
59
+ def resolve_permission(self, args: ListMcpResourcesArgs) -> ToolPermission | None:
60
+ return ToolPermission.ALWAYS
61
+
62
+ @final
63
+ async def run(
64
+ self, args: ListMcpResourcesArgs, ctx: InvokeContext | None = None
65
+ ) -> AsyncGenerator[ToolStreamEvent | ListMcpResourcesResult, None]:
66
+ resources: list[McpResource] = []
67
+
68
+ try:
69
+ if ctx and hasattr(ctx, 'agent_manager') and ctx.agent_manager:
70
+ config = ctx.agent_manager.config
71
+ servers = config.mcp_servers or []
72
+
73
+ from drydock.core.tools.mcp.tools import (
74
+ list_resources_http, list_resources_stdio,
75
+ )
76
+ from drydock.core.config import MCPStdio, MCPHttp
77
+
78
+ tasks = []
79
+ for srv in servers:
80
+ if args.server_name and getattr(srv, 'alias', '') != args.server_name:
81
+ continue
82
+ if isinstance(srv, MCPHttp):
83
+ tasks.append(list_resources_http(
84
+ srv.url,
85
+ headers=srv.headers,
86
+ startup_timeout_sec=srv.startup_timeout_seconds,
87
+ ))
88
+ elif isinstance(srv, MCPStdio):
89
+ tasks.append(list_resources_stdio(
90
+ srv.command,
91
+ env=srv.env,
92
+ startup_timeout_sec=srv.startup_timeout_seconds,
93
+ ))
94
+
95
+ if tasks:
96
+ results = await asyncio.gather(*tasks, return_exceptions=True)
97
+ for result in results:
98
+ if isinstance(result, list):
99
+ for r in result:
100
+ resources.append(McpResource(
101
+ uri=r.uri, name=r.name,
102
+ description=r.description,
103
+ mime_type=r.mime_type,
104
+ server=r.server,
105
+ ))
106
+ except Exception as e:
107
+ raise ToolError(f"Failed to list MCP resources: {e}") from e
108
+
109
+ yield ListMcpResourcesResult(resources=resources, count=len(resources))
110
+
111
+
112
+ class ReadMcpResourceArgs(BaseModel):
113
+ uri: str = Field(description="Resource URI to read")
114
+ server_name: str = Field(default="", description="MCP server name (required if multiple servers)")
115
+
116
+
117
+ class ReadMcpResourceResult(BaseModel):
118
+ uri: str
119
+ content: str
120
+ mime_type: str = ""
121
+
122
+
123
+ class ReadMcpResource(
124
+ BaseTool[ReadMcpResourceArgs, ReadMcpResourceResult, BaseToolConfig, BaseToolState],
125
+ ToolUIData[ReadMcpResourceArgs, ReadMcpResourceResult],
126
+ ):
127
+ description: ClassVar[str] = "Read a resource from an MCP server by URI."
128
+
129
+ @classmethod
130
+ def format_call_display(cls, args: ReadMcpResourceArgs) -> ToolCallDisplay:
131
+ return ToolCallDisplay(summary=f"read_mcp_resource: {args.uri[:50]}")
132
+
133
+ @classmethod
134
+ def get_result_display(cls, event: ToolResultEvent) -> ToolResultDisplay:
135
+ return ToolResultDisplay(success=True, message="Resource read")
136
+
137
+ @classmethod
138
+ def get_status_text(cls) -> str:
139
+ return "Reading MCP resource"
140
+
141
+ def resolve_permission(self, args: ReadMcpResourceArgs) -> ToolPermission | None:
142
+ return ToolPermission.ALWAYS
143
+
144
+ @final
145
+ async def run(
146
+ self, args: ReadMcpResourceArgs, ctx: InvokeContext | None = None
147
+ ) -> AsyncGenerator[ToolStreamEvent | ReadMcpResourceResult, None]:
148
+ if not ctx or not hasattr(ctx, 'agent_manager') or not ctx.agent_manager:
149
+ raise ToolError("No agent manager available for MCP resource reading")
150
+
151
+ config = ctx.agent_manager.config
152
+ servers = config.mcp_servers or []
153
+
154
+ if not servers:
155
+ raise ToolError("No MCP servers configured. Add servers to ~/.drydock/config.toml")
156
+
157
+ from drydock.core.tools.mcp.tools import read_resource_http, read_resource_stdio
158
+ from drydock.core.config import MCPStdio, MCPHttp
159
+
160
+ # Try each server until we find the resource
161
+ last_error = None
162
+ for srv in servers:
163
+ if args.server_name and getattr(srv, 'alias', '') != args.server_name:
164
+ continue
165
+ try:
166
+ if isinstance(srv, MCPHttp):
167
+ content = await read_resource_http(
168
+ srv.url, args.uri,
169
+ headers=srv.headers,
170
+ startup_timeout_sec=srv.startup_timeout_seconds,
171
+ )
172
+ elif isinstance(srv, MCPStdio):
173
+ content = await read_resource_stdio(
174
+ srv.command, args.uri,
175
+ env=srv.env,
176
+ startup_timeout_sec=srv.startup_timeout_seconds,
177
+ )
178
+ else:
179
+ continue
180
+
181
+ yield ReadMcpResourceResult(
182
+ uri=args.uri,
183
+ content=content,
184
+ mime_type="",
185
+ )
186
+ return
187
+ except Exception as e:
188
+ last_error = e
189
+ continue
190
+
191
+ raise ToolError(
192
+ f"Could not read resource '{args.uri}' from any MCP server. "
193
+ f"Last error: {last_error}"
194
+ )
@@ -410,3 +410,109 @@ def create_mcp_stdio_proxy_tool_class(
410
410
 
411
411
  MCPStdioProxyTool.__name__ = f"MCP_STDIO_{computed_alias}__{remote.name}"
412
412
  return MCPStdioProxyTool
413
+
414
+
415
+ # ── MCP Resource listing/reading ─────────────────────────────────────────
416
+
417
+ class MCPResource:
418
+ """Simple container for an MCP resource."""
419
+ def __init__(self, uri: str, name: str, description: str = "", mime_type: str = "", server: str = ""):
420
+ self.uri = uri
421
+ self.name = name
422
+ self.description = description
423
+ self.mime_type = mime_type
424
+ self.server = server
425
+
426
+
427
+ async def list_resources_http(
428
+ url: str,
429
+ *,
430
+ headers: dict[str, str] | None = None,
431
+ startup_timeout_sec: float | None = None,
432
+ ) -> list[MCPResource]:
433
+ timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
434
+ async with streamablehttp_client(url, headers=headers) as (read, write, _):
435
+ async with ClientSession(read, write, read_timeout_seconds=timeout) as session:
436
+ await session.initialize()
437
+ resp = await session.list_resources()
438
+ return [
439
+ MCPResource(
440
+ uri=str(r.uri), name=r.name,
441
+ description=getattr(r, 'description', '') or '',
442
+ mime_type=getattr(r, 'mimeType', '') or '',
443
+ server=url,
444
+ )
445
+ for r in resp.resources
446
+ ]
447
+
448
+
449
+ async def list_resources_stdio(
450
+ command: list[str],
451
+ *,
452
+ env: dict[str, str] | None = None,
453
+ startup_timeout_sec: float | None = None,
454
+ ) -> list[MCPResource]:
455
+ params = StdioServerParameters(command=command[0], args=command[1:], env=env)
456
+ timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
457
+ async with (
458
+ _mcp_stderr_capture() as errlog,
459
+ stdio_client(params, errlog=errlog) as (read, write),
460
+ ClientSession(read, write, read_timeout_seconds=timeout) as session,
461
+ ):
462
+ await session.initialize()
463
+ resp = await session.list_resources()
464
+ return [
465
+ MCPResource(
466
+ uri=str(r.uri), name=r.name,
467
+ description=getattr(r, 'description', '') or '',
468
+ mime_type=getattr(r, 'mimeType', '') or '',
469
+ server=" ".join(command),
470
+ )
471
+ for r in resp.resources
472
+ ]
473
+
474
+
475
+ async def read_resource_http(
476
+ url: str,
477
+ resource_uri: str,
478
+ *,
479
+ headers: dict[str, str] | None = None,
480
+ startup_timeout_sec: float | None = None,
481
+ ) -> str:
482
+ timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
483
+ async with streamablehttp_client(url, headers=headers) as (read, write, _):
484
+ async with ClientSession(read, write, read_timeout_seconds=timeout) as session:
485
+ await session.initialize()
486
+ resp = await session.read_resource(resource_uri)
487
+ parts = []
488
+ for content in resp.contents:
489
+ if hasattr(content, 'text'):
490
+ parts.append(content.text)
491
+ elif hasattr(content, 'blob'):
492
+ parts.append(f"[binary data: {len(content.blob)} bytes]")
493
+ return "\n".join(parts)
494
+
495
+
496
+ async def read_resource_stdio(
497
+ command: list[str],
498
+ resource_uri: str,
499
+ *,
500
+ env: dict[str, str] | None = None,
501
+ startup_timeout_sec: float | None = None,
502
+ ) -> str:
503
+ params = StdioServerParameters(command=command[0], args=command[1:], env=env)
504
+ timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
505
+ async with (
506
+ _mcp_stderr_capture() as errlog,
507
+ stdio_client(params, errlog=errlog) as (read, write),
508
+ ClientSession(read, write, read_timeout_seconds=timeout) as session,
509
+ ):
510
+ await session.initialize()
511
+ resp = await session.read_resource(resource_uri)
512
+ parts = []
513
+ for content in resp.contents:
514
+ if hasattr(content, 'text'):
515
+ parts.append(content.text)
516
+ elif hasattr(content, 'blob'):
517
+ parts.append(f"[binary data: {len(content.blob)} bytes]")
518
+ return "\n".join(parts)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "2.2.9"
3
+ version = "2.3.1"
4
4
  description = "Drydock — nautical CLI coding agent"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"