drydock-cli 1.5.4__tar.gz → 1.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/PKG-INFO +1 -1
  2. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/agent_loop.py +134 -14
  3. drydock_cli-1.6.0/drydock/core/build_orchestrator.py +422 -0
  4. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/__init__.py +1 -0
  5. drydock_cli-1.6.0/drydock/core/prompts/builder.md +16 -0
  6. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/cli.md +11 -5
  7. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/pyproject.toml +1 -1
  8. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/CODEOWNERS +0 -0
  9. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  10. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  11. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  12. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/workflows/build-and-upload.yml +0 -0
  13. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/workflows/ci.yml +0 -0
  14. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/workflows/issue-labeler.yml +0 -0
  15. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.github/workflows/release.yml +0 -0
  16. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.gitignore +0 -0
  17. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.pre-commit-config.yaml +0 -0
  18. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.python-version +0 -0
  19. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.typos.toml +0 -0
  20. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.vscode/extensions.json +0 -0
  21. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.vscode/launch.json +0 -0
  22. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/.vscode/settings.json +0 -0
  23. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/AGENTS.md +0 -0
  24. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/CHANGELOG.md +0 -0
  25. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/CLAUDE.md +0 -0
  26. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/CONTRIBUTING.md +0 -0
  27. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/Drydock_rebrand.md +0 -0
  28. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/LICENSE +0 -0
  29. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/NOTICE +0 -0
  30. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/PRD.md +0 -0
  31. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/README.md +0 -0
  32. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/action.yml +0 -0
  33. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/distribution/zed/LICENSE +0 -0
  34. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/distribution/zed/extension.toml +0 -0
  35. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/distribution/zed/icons/mistral_vibe.svg +0 -0
  36. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/docs/README.md +0 -0
  37. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/docs/acp-setup.md +0 -0
  38. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/docs/proxy-setup.md +0 -0
  39. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/__init__.py +0 -0
  40. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/__init__.py +0 -0
  41. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/acp_agent_loop.py +0 -0
  42. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/acp_logger.py +0 -0
  43. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/entrypoint.py +0 -0
  44. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/__init__.py +0 -0
  45. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/base.py +0 -0
  46. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/builtins/bash.py +0 -0
  47. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/builtins/read_file.py +0 -0
  48. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/builtins/search_replace.py +0 -0
  49. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/builtins/todo.py +0 -0
  50. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/builtins/write_file.py +0 -0
  51. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/tools/session_update.py +0 -0
  52. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/acp/utils.py +0 -0
  53. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/__init__.py +0 -0
  54. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/autocompletion/__init__.py +0 -0
  55. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/autocompletion/base.py +0 -0
  56. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/autocompletion/path_completion.py +0 -0
  57. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/autocompletion/slash_command.py +0 -0
  58. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/cli.py +0 -0
  59. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/clipboard.py +0 -0
  60. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/commands.py +0 -0
  61. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/entrypoint.py +0 -0
  62. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/history_manager.py +0 -0
  63. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  64. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  65. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  66. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/terminal_setup.py +0 -0
  67. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/__init__.py +0 -0
  68. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  69. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/app.py +0 -0
  70. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/app.tcss +0 -0
  71. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/external_editor.py +0 -0
  72. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  73. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  74. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  75. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  76. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  77. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  78. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  79. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  80. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  81. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  82. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  83. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  84. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  85. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  86. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  87. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  88. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  89. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  90. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  91. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  92. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  93. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  94. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  95. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  96. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  97. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  98. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  99. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  100. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  101. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  102. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  103. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  104. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  105. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  106. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  107. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  108. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/windowing/history.py +0 -0
  109. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  110. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/textual_ui/windowing/state.py +0 -0
  111. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/__init__.py +0 -0
  112. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  113. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  114. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  115. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  116. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  117. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/update.py +0 -0
  118. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/cli/update_notifier/whats_new.py +0 -0
  119. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/__init__.py +0 -0
  120. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/agents/__init__.py +0 -0
  121. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/agents/manager.py +0 -0
  122. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/agents/models.py +0 -0
  123. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/auth/__init__.py +0 -0
  124. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/auth/crypto.py +0 -0
  125. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/auth/github.py +0 -0
  126. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/__init__.py +0 -0
  127. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/completers.py +0 -0
  128. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  129. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  130. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  131. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  132. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  133. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/fuzzy.py +0 -0
  134. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/path_prompt.py +0 -0
  135. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  136. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/config/__init__.py +0 -0
  137. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/config/_settings.py +0 -0
  138. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/config/harness_files/__init__.py +0 -0
  139. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  140. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/config/harness_files/_paths.py +0 -0
  141. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/consultant.py +0 -0
  142. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/drydock_states.py +0 -0
  143. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/hooks.py +0 -0
  144. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/__init__.py +0 -0
  145. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/backend/anthropic.py +0 -0
  146. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/backend/base.py +0 -0
  147. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/backend/factory.py +0 -0
  148. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/backend/generic.py +0 -0
  149. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/backend/mistral.py +0 -0
  150. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  151. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/backend/vertex.py +0 -0
  152. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/exceptions.py +0 -0
  153. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/format.py +0 -0
  154. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/message_utils.py +0 -0
  155. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/llm/types.py +0 -0
  156. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/logger.py +0 -0
  157. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/middleware.py +0 -0
  158. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/output_formatters.py +0 -0
  159. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/paths/__init__.py +0 -0
  160. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/paths/_local_config_walk.py +0 -0
  161. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/paths/_vibe_home.py +0 -0
  162. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/paths/conventions.py +0 -0
  163. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/plan_session.py +0 -0
  164. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/plugins.py +0 -0
  165. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/programmatic.py +0 -0
  166. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/compact.md +0 -0
  167. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/dangerous_directory.md +0 -0
  168. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/diagnostic.md +0 -0
  169. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/explore.md +0 -0
  170. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/planner.md +0 -0
  171. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/project_context.md +0 -0
  172. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/prompts/tests.md +0 -0
  173. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/proxy_setup.py +0 -0
  174. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/session/agent_memory.py +0 -0
  175. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/session/checkpoints.py +0 -0
  176. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/session/session_loader.py +0 -0
  177. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/session/session_logger.py +0 -0
  178. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/session/session_migration.py +0 -0
  179. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/session/state_file.py +0 -0
  180. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/skills/__init__.py +0 -0
  181. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/skills/manager.py +0 -0
  182. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/skills/models.py +0 -0
  183. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/skills/parser.py +0 -0
  184. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/slug.py +0 -0
  185. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/system_prompt.py +0 -0
  186. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/telemetry/__init__.py +0 -0
  187. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/telemetry/send.py +0 -0
  188. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/teleport/errors.py +0 -0
  189. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/teleport/git.py +0 -0
  190. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/teleport/nuage.py +0 -0
  191. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/teleport/teleport.py +0 -0
  192. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/teleport/types.py +0 -0
  193. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/base.py +0 -0
  194. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  195. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/bash.py +0 -0
  196. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/cron.py +0 -0
  197. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  198. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/glob_tool.py +0 -0
  199. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/grep.py +0 -0
  200. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  201. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/lsp.py +0 -0
  202. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  203. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  204. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/powershell.py +0 -0
  205. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  206. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  207. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  208. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  209. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  210. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  211. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  212. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  213. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  214. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  215. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  216. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  217. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  218. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  219. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/task.md +0 -0
  220. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  221. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  222. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  223. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  224. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  225. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  226. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  227. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/read_file.py +0 -0
  228. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/search_replace.py +0 -0
  229. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/task.py +0 -0
  230. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/task_manager.py +0 -0
  231. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/todo.py +0 -0
  232. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/tool_search.py +0 -0
  233. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/webfetch.py +0 -0
  234. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/websearch.py +0 -0
  235. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/worktree.py +0 -0
  236. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/builtins/write_file.py +0 -0
  237. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/injection_guard.py +0 -0
  238. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/manager.py +0 -0
  239. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/mcp/__init__.py +0 -0
  240. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/mcp/registry.py +0 -0
  241. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/mcp/tools.py +0 -0
  242. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/mcp_sampling.py +0 -0
  243. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/ui.py +0 -0
  244. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/tools/utils.py +0 -0
  245. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/trusted_folders.py +0 -0
  246. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/types.py +0 -0
  247. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/core/utils.py +0 -0
  248. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/onboarding/__init__.py +0 -0
  249. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/onboarding/base.py +0 -0
  250. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/onboarding/onboarding.tcss +0 -0
  251. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/onboarding/screens/__init__.py +0 -0
  252. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/onboarding/screens/api_key.py +0 -0
  253. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/onboarding/screens/welcome.py +0 -0
  254. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  255. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  256. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/__init__.py +0 -0
  257. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/batch/SKILL.md +0 -0
  258. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/create-presentation/SKILL.md +0 -0
  259. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/deep-research/SKILL.md +0 -0
  260. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/investigate/SKILL.md +0 -0
  261. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/review/SKILL.md +0 -0
  262. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/ship/SKILL.md +0 -0
  263. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/skills/simplify/SKILL.md +0 -0
  264. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock/whats_new.md +0 -0
  265. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock-acp.spec +0 -0
  266. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/drydock_terms.md +0 -0
  267. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/flake.lock +0 -0
  268. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/flake.nix +0 -0
  269. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/README.md +0 -0
  270. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/backup.sh +0 -0
  271. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/bump_version.py +0 -0
  272. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/deploy_to_github.sh +0 -0
  273. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/install.sh +0 -0
  274. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/monitor_test_battery.sh +0 -0
  275. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/prepare_release.py +0 -0
  276. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/publish_to_pypi.sh +0 -0
  277. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/test_bank.sh +0 -0
  278. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/test_full.sh +0 -0
  279. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/scripts/test_smoke.sh +0 -0
  280. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/__init__.py +0 -0
  281. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/conftest.py +0 -0
  282. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_acp.py +0 -0
  283. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_agent_thought.py +0 -0
  284. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_bash.py +0 -0
  285. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_compact_session_updates.py +0 -0
  286. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_content.py +0 -0
  287. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_initialize.py +0 -0
  288. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_list_sessions.py +0 -0
  289. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_load_session.py +0 -0
  290. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_multi_session.py +0 -0
  291. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_new_session.py +0 -0
  292. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_proxy_setup_acp.py +0 -0
  293. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_read_file.py +0 -0
  294. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_search_replace.py +0 -0
  295. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_set_config_option.py +0 -0
  296. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_set_mode.py +0 -0
  297. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_set_model.py +0 -0
  298. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_tool_call_session_update.py +0 -0
  299. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_utils.py +0 -0
  300. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/acp/test_write_file.py +0 -0
  301. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_file_indexer.py +0 -0
  302. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_fuzzy.py +0 -0
  303. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  304. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  305. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_path_completion_controller.py +0 -0
  306. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  307. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_slash_command_controller.py +0 -0
  308. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  309. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/__init__.py +0 -0
  310. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/data/__init__.py +0 -0
  311. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/data/fireworks.py +0 -0
  312. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/data/mistral.py +0 -0
  313. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/test_anthropic_adapter.py +0 -0
  314. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/test_backend.py +0 -0
  315. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/test_reasoning_adapter.py +0 -0
  316. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  317. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  318. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  319. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  320. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_bell_notifications.py +0 -0
  321. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_braille_renderer.py +0 -0
  322. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_clipboard.py +0 -0
  323. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_commands.py +0 -0
  324. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_copy_shortcuts.py +0 -0
  325. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_external_editor.py +0 -0
  326. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_no_markup_static.py +0 -0
  327. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_question_app.py +0 -0
  328. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_spinner.py +0 -0
  329. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_switching_mode.py +0 -0
  330. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  331. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  332. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_ui_session_resume.py +0 -0
  333. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/test_ui_skill_dispatch.py +0 -0
  334. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/textual_ui/__init__.py +0 -0
  335. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/cli/textual_ui/test_session_picker.py +0 -0
  336. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/conftest.py +0 -0
  337. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_agents.py +0 -0
  338. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_auth_crypto.py +0 -0
  339. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_auth_github.py +0 -0
  340. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_config_load_dotenv.py +0 -0
  341. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_config_paths.py +0 -0
  342. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_config_resolution.py +0 -0
  343. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_file_logging.py +0 -0
  344. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_plan_session.py +0 -0
  345. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_proxy_setup.py +0 -0
  346. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_slug.py +0 -0
  347. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_telemetry_send.py +0 -0
  348. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_teleport_git.py +0 -0
  349. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_teleport_nuage.py +0 -0
  350. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_teleport_service.py +0 -0
  351. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_trusted_folders.py +0 -0
  352. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/core/test_utils.py +0 -0
  353. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/e2e/common.py +0 -0
  354. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/e2e/conftest.py +0 -0
  355. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/e2e/mock_server.py +0 -0
  356. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  357. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/e2e/test_cli_tui_streaming.py +0 -0
  358. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  359. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/mock/__init__.py +0 -0
  360. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/mock/mock_backend_factory.py +0 -0
  361. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/mock/mock_entrypoint.py +0 -0
  362. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/mock/utils.py +0 -0
  363. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/onboarding/test_run_onboarding.py +0 -0
  364. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/onboarding/test_ui_onboarding.py +0 -0
  365. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/session/test_session_loader.py +0 -0
  366. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/session/test_session_logger.py +0 -0
  367. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/session/test_session_migration.py +0 -0
  368. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/skills/conftest.py +0 -0
  369. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/skills/test_manager.py +0 -0
  370. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/skills/test_models.py +0 -0
  371. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/skills/test_parser.py +0 -0
  372. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  373. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  374. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  375. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  376. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  377. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  378. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  379. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  380. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  381. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  382. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  383. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  384. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  385. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  386. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  387. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  388. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  389. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  390. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  391. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  392. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  393. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  394. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  395. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  396. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  397. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  398. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  399. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  400. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  401. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  402. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  403. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  404. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  405. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  406. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  407. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  408. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  409. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  410. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  411. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  412. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  413. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  414. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  415. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  416. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  417. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  418. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  419. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  420. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  421. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  422. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  423. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  424. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  425. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  426. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  427. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  428. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  429. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  430. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  431. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  432. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/base_snapshot_test_app.py +0 -0
  433. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/conftest.py +0 -0
  434. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/snap_compare.py +0 -0
  435. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  436. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  437. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  438. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  439. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  440. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  441. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  442. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  443. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  444. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  445. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  446. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  447. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  448. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  449. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/stubs/fake_backend.py +0 -0
  450. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/stubs/fake_client.py +0 -0
  451. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/stubs/fake_tool.py +0 -0
  452. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_agent_auto_compact.py +0 -0
  453. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_agent_backend.py +0 -0
  454. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_agent_observer_streaming.py +0 -0
  455. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_agent_stats.py +0 -0
  456. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_agent_tasks.py +0 -0
  457. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_agent_tool_call.py +0 -0
  458. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_agents.py +0 -0
  459. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_bank_build.py +0 -0
  460. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_bank_debug.py +0 -0
  461. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_bank_multiagent.py +0 -0
  462. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_bank_prd.py +0 -0
  463. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_bank_prd_extended.py +0 -0
  464. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_bank_tools.py +0 -0
  465. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_bank_update.py +0 -0
  466. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_build_projects.py +0 -0
  467. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_cli_programmatic_preload.py +0 -0
  468. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_current_bugs.py +0 -0
  469. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_drydock_regression.py +0 -0
  470. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_drydock_tasks.py +0 -0
  471. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_full_regression.py +0 -0
  472. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_history_manager.py +0 -0
  473. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_integration.py +0 -0
  474. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_loop_detection.py +0 -0
  475. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_message_id.py +0 -0
  476. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_message_merging.py +0 -0
  477. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_middleware.py +0 -0
  478. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_multi_agent.py +0 -0
  479. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_real_failures.py +0 -0
  480. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_real_issues.py +0 -0
  481. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_real_workflow.py +0 -0
  482. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_reasoning_content.py +0 -0
  483. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_smoke.py +0 -0
  484. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_system_prompt.py +0 -0
  485. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_tagged_text.py +0 -0
  486. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_ui_external_editor.py +0 -0
  487. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_ui_input_history.py +0 -0
  488. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_user_issues.py +0 -0
  489. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/test_workloads.py +0 -0
  490. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/testbank_helpers.py +0 -0
  491. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_ask_user_question.py +0 -0
  492. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_bash.py +0 -0
  493. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_exit_plan_mode.py +0 -0
  494. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_grep.py +0 -0
  495. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_invoke_context.py +0 -0
  496. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_manager_get_tool_config.py +0 -0
  497. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_mcp.py +0 -0
  498. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_mcp_sampling.py +0 -0
  499. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_task.py +0 -0
  500. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_ui_bash_execution.py +0 -0
  501. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_webfetch.py +0 -0
  502. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/tools/test_websearch.py +0 -0
  503. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  504. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  505. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/test_do_update.py +0 -0
  506. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  507. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/test_github_update_gateway.py +0 -0
  508. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  509. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/test_ui_update_notification.py +0 -0
  510. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/test_update_use_case.py +0 -0
  511. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/tests/update_notifier/test_whats_new.py +0 -0
  512. {drydock_cli-1.5.4 → drydock_cli-1.6.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 1.5.4
3
+ Version: 1.6.0
4
4
  Summary: Drydock — nautical CLI coding agent
5
5
  Project-URL: Homepage, https://github.com/fbobe321/drydock
6
6
  Project-URL: Repository, https://github.com/fbobe321/drydock
@@ -474,12 +474,29 @@ class AgentLoop:
474
474
 
475
475
  yield UserMessageEvent(content=user_msg, message_id=user_message.message_id)
476
476
 
477
- # === AUTO-DELEGATION ===
478
- # Inject context automatically so the model doesn't have to choose to delegate.
479
- # This replaces relying on the model to call task()/invoke_skill().
480
- auto_context = self._build_auto_context(user_msg)
481
- if auto_context:
482
- self._inject_system_note(auto_context)
477
+ # === BUILD ORCHESTRATION ===
478
+ # For complex build tasks (PRD + multiple files), run the multi-phase
479
+ # pipeline instead of letting the model do everything in one context.
480
+ if self._is_build_task(user_msg):
481
+ try:
482
+ from drydock.core.build_orchestrator import run_build_pipeline
483
+ summary = await run_build_pipeline(
484
+ user_prompt=user_msg,
485
+ config=self.config,
486
+ base_dir=Path.cwd(),
487
+ )
488
+ self._inject_system_note(summary)
489
+ logger.info("Build orchestrator completed successfully")
490
+ except Exception as e:
491
+ logger.warning("Build orchestrator failed (%s), falling back to normal flow", e)
492
+ auto_context = self._build_auto_context(user_msg)
493
+ if auto_context:
494
+ self._inject_system_note(auto_context)
495
+ else:
496
+ # Normal flow: inject context for non-build tasks
497
+ auto_context = self._build_auto_context(user_msg)
498
+ if auto_context:
499
+ self._inject_system_note(auto_context)
483
500
 
484
501
  try:
485
502
  should_break_loop = False
@@ -585,6 +602,10 @@ class AgentLoop:
585
602
  except (json.JSONDecodeError, AttributeError):
586
603
  edit_path = ""
587
604
 
605
+ # AUTO-FIX: Fix packaging issues the model gets wrong
606
+ if edit_path and edit_path.endswith(".py"):
607
+ self._auto_fix_package(edit_path)
608
+
588
609
  # Auto-run diagnostics on edited Python files
589
610
  if edit_path and edit_path.endswith(".py"):
590
611
  try:
@@ -1658,6 +1679,98 @@ class AgentLoop:
1658
1679
 
1659
1680
  return None
1660
1681
 
1682
+ def _is_build_task(self, user_msg: str) -> bool:
1683
+ """Detect if a user message is a complex build task that needs orchestration."""
1684
+ msg_lower = user_msg.lower()
1685
+ has_build_verb = any(kw in msg_lower for kw in (
1686
+ "build", "create a", "implement", "get started",
1687
+ "set up", "scaffold", "review the prd", "review prd",
1688
+ ))
1689
+ has_complexity = (
1690
+ len(user_msg) > 200
1691
+ or any(kw in msg_lower for kw in (
1692
+ "prd", "multiple", "package", "modules", "cli",
1693
+ "features", "commands", "architecture", "structure",
1694
+ ))
1695
+ )
1696
+ # Check if a PRD.md exists in the working directory
1697
+ has_prd = Path.cwd().joinpath("PRD.md").exists() or Path.cwd().joinpath("prd.md").exists()
1698
+ return has_build_verb and (has_complexity or has_prd)
1699
+
1700
+ def _auto_fix_package(self, file_path: str) -> None:
1701
+ """Silently fix common packaging mistakes after model writes a file.
1702
+
1703
+ The model (devstral-24B) consistently fails at:
1704
+ 1. Creating __main__.py for packages
1705
+ 2. Using relative imports instead of absolute
1706
+ This runs after every write_file/search_replace and fixes both.
1707
+ """
1708
+ try:
1709
+ fp = Path(file_path)
1710
+ if not fp.exists() or not fp.is_file():
1711
+ return
1712
+
1713
+ pkg_dir = fp.parent
1714
+ init_file = pkg_dir / "__init__.py"
1715
+
1716
+ # Only fix files inside a package (has __init__.py)
1717
+ if not init_file.exists():
1718
+ return
1719
+
1720
+ pkg_name = pkg_dir.name
1721
+
1722
+ # 1. Create __main__.py if missing
1723
+ main_file = pkg_dir / "__main__.py"
1724
+ if not main_file.exists():
1725
+ # Find the most likely entry point (cli.py, main.py, app.py)
1726
+ entry = None
1727
+ entry_func = "main"
1728
+ for candidate in ["cli.py", "main.py", "app.py", "__init__.py"]:
1729
+ cand_path = pkg_dir / candidate
1730
+ if cand_path.exists() and candidate != "__init__.py":
1731
+ # Check if it has a main() function
1732
+ try:
1733
+ content = cand_path.read_text()
1734
+ if "def main(" in content:
1735
+ entry = candidate[:-3] # strip .py
1736
+ break
1737
+ except Exception:
1738
+ pass
1739
+ if entry:
1740
+ main_content = (
1741
+ f"from {pkg_name}.{entry} import {entry_func}\n\n"
1742
+ f"if __name__ == \"__main__\":\n"
1743
+ f" {entry_func}()\n"
1744
+ )
1745
+ main_file.write_text(main_content)
1746
+ logger.info("Auto-created %s/__main__.py (entry: %s.%s)", pkg_name, entry, entry_func)
1747
+
1748
+ # 2. Fix relative imports → absolute imports
1749
+ try:
1750
+ content = fp.read_text()
1751
+ if f"from .{'' if content else ''}" in content:
1752
+ import re
1753
+ # Replace from .module import X → from pkg.module import X
1754
+ fixed = re.sub(
1755
+ r"from \.([\w.]+) import",
1756
+ f"from {pkg_name}.\\1 import",
1757
+ content,
1758
+ )
1759
+ # Replace from . import X → from pkg import X
1760
+ fixed = re.sub(
1761
+ r"from \. import",
1762
+ f"from {pkg_name} import",
1763
+ fixed,
1764
+ )
1765
+ if fixed != content:
1766
+ fp.write_text(fixed)
1767
+ logger.info("Auto-fixed relative imports in %s", fp.name)
1768
+ except Exception:
1769
+ pass
1770
+
1771
+ except Exception as e:
1772
+ logger.debug("Auto-fix package failed for %s: %s", file_path, e)
1773
+
1661
1774
  def _build_auto_context(self, user_msg: str) -> str | None:
1662
1775
  """Build auto-delegation context based on the prompt and project state.
1663
1776
 
@@ -1727,17 +1840,24 @@ class AgentLoop:
1727
1840
  ))
1728
1841
  if is_build and is_complex:
1729
1842
  parts.append(
1730
- "PLANNING REQUIRED — This is a complex build task. Before writing code:\n"
1731
- "1. List ALL files you will create (with brief purpose)\n"
1732
- "2. Define the package structure\n"
1733
- "3. Use ABSOLUTE imports (from pkg.module import X), NOT relative imports\n"
1734
- "4. Create files in dependency order (utilities first, then modules that import them)\n"
1735
- "5. After creating all files, test with: python3 -m package_name\n"
1736
- "6. If tests fail, READ the error, then FIX with search_replace"
1843
+ "MANDATORY BUILD RULES:\n"
1844
+ "1. Plan first: list ALL files you will create\n"
1845
+ "2. ALWAYS create __main__.py so 'python3 -m package_name' works:\n"
1846
+ " ```python\n"
1847
+ " from package_name.cli import main\n"
1848
+ " if __name__ == '__main__':\n"
1849
+ " main()\n"
1850
+ " ```\n"
1851
+ "3. Use ABSOLUTE imports: 'from pkg.module import X', NOT 'from .module import X'\n"
1852
+ "4. Create test/sample data files BEFORE testing (the tool needs input to work)\n"
1853
+ "5. Test with: python3 -m package_name (NOT python3 package/file.py)\n"
1854
+ "6. If a test fails, read the error, fix with search_replace, then retry\n"
1855
+ "7. After 1-2 successful tests, STOP and tell the user it's done"
1737
1856
  )
1738
1857
  elif is_build:
1739
1858
  parts.append(
1740
- "REMINDER: Use write_file to create files. Use absolute imports. "
1859
+ "BUILD RULES: Use write_file to create files. Use absolute imports. "
1860
+ "Create __main__.py for packages. Create test data before testing. "
1741
1861
  "Test with python3 -m package_name (not python3 package/file.py)."
1742
1862
  )
1743
1863
 
@@ -0,0 +1,422 @@
1
+ """Multi-phase build orchestrator.
2
+
3
+ Instead of running everything in one context window (where the model wastes
4
+ turns on packaging/import errors), this splits project builds into phases:
5
+
6
+ Phase 1: PLAN — planner subagent reads the PRD, outputs a JSON build plan
7
+ Phase 2: SCAFFOLD — pure Python creates dirs, __init__.py, __main__.py
8
+ Phase 3: IMPLEMENT — one subagent per file, each with clean context
9
+ Phase 4: (back in main loop) — test and fix
10
+
11
+ Each phase gets a separate context window, so the model only does what
12
+ it's good at (writing logic) and the framework handles what it's bad at
13
+ (packaging, imports, project structure).
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ import logging
20
+ import re
21
+ from dataclasses import dataclass, field
22
+ from pathlib import Path
23
+ from typing import TYPE_CHECKING, Any
24
+
25
+ from drydock.core.config import VibeConfig
26
+
27
+ if TYPE_CHECKING:
28
+ from drydock.core.agents.manager import AgentManager
29
+ from drydock.core.types import EntrypointMetadata
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+
34
+ # ============================================================================
35
+ # Data structures
36
+ # ============================================================================
37
+
38
+ @dataclass
39
+ class FileSpec:
40
+ path: str
41
+ purpose: str
42
+ imports: list[str] = field(default_factory=list)
43
+
44
+
45
+ @dataclass
46
+ class BuildPlan:
47
+ package_name: str
48
+ description: str
49
+ entry_point: str
50
+ files: list[FileSpec]
51
+
52
+
53
+ # ============================================================================
54
+ # Phase 1: PLAN
55
+ # ============================================================================
56
+
57
+ PLAN_PROMPT = """Analyze this project request and output a JSON build plan.
58
+
59
+ PROJECT REQUEST:
60
+ {user_prompt}
61
+
62
+ Output a JSON block inside ```json fences with this EXACT structure:
63
+ ```json
64
+ {{
65
+ "package_name": "my_package",
66
+ "description": "One-line description of the project",
67
+ "entry_point": "cli",
68
+ "files": [
69
+ {{"path": "my_package/utils.py", "purpose": "Utility functions for X and Y", "imports": []}},
70
+ {{"path": "my_package/core.py", "purpose": "Core logic that does Z", "imports": ["my_package.utils"]}},
71
+ {{"path": "my_package/cli.py", "purpose": "CLI entry point with main() function using argparse", "imports": ["my_package.core"]}}
72
+ ]
73
+ }}
74
+ ```
75
+
76
+ RULES:
77
+ - package_name: valid Python identifier, lowercase, underscores OK
78
+ - entry_point: the module with main() function (usually "cli")
79
+ - files: list in DEPENDENCY ORDER (dependencies first, entry_point last)
80
+ - Each purpose must be specific enough to implement the file from
81
+ - Do NOT include __init__.py or __main__.py (created automatically)
82
+ - The entry_point module MUST have a main() function
83
+ """
84
+
85
+
86
+ def extract_plan(response_text: str) -> BuildPlan:
87
+ """Extract a BuildPlan from the planner's free-text response."""
88
+ # Try fenced JSON block first
89
+ match = re.search(r"```(?:json)?\s*\n(.*?)\n```", response_text, re.DOTALL)
90
+ if match:
91
+ raw = match.group(1)
92
+ else:
93
+ # Fallback: find first { ... } with "package_name"
94
+ match = re.search(r"\{[^{}]*\"package_name\".*\}", response_text, re.DOTALL)
95
+ if match:
96
+ raw = match.group(0)
97
+ else:
98
+ raise ValueError("No JSON build plan found in planner response")
99
+
100
+ data = json.loads(raw)
101
+
102
+ files = []
103
+ for f in data.get("files", []):
104
+ files.append(FileSpec(
105
+ path=f["path"],
106
+ purpose=f["purpose"],
107
+ imports=f.get("imports", []),
108
+ ))
109
+
110
+ return BuildPlan(
111
+ package_name=data["package_name"],
112
+ description=data.get("description", ""),
113
+ entry_point=data.get("entry_point", "cli"),
114
+ files=files,
115
+ )
116
+
117
+
118
+ async def run_planner(
119
+ user_prompt: str,
120
+ config: VibeConfig,
121
+ ) -> BuildPlan:
122
+ """Phase 1: Direct API call to create a build plan. No AgentLoop needed."""
123
+ import httpx
124
+
125
+ plan_prompt = PLAN_PROMPT.format(user_prompt=user_prompt)
126
+
127
+ provider = config.providers[0] if config.providers else None
128
+ if not provider:
129
+ raise RuntimeError("No provider configured")
130
+
131
+ messages = [
132
+ {"role": "system", "content": "You are a project planner. Output ONLY a JSON build plan."},
133
+ {"role": "user", "content": plan_prompt},
134
+ ]
135
+
136
+ # Truncate very long prompts to avoid timeout
137
+ if len(plan_prompt) > 6000:
138
+ plan_prompt = plan_prompt[:6000] + "\n\n[TRUNCATED — focus on the core features listed above]"
139
+
140
+ messages[1]["content"] = plan_prompt
141
+
142
+ async with httpx.AsyncClient(timeout=300) as client:
143
+ resp = await client.post(
144
+ f"{provider.api_base}/chat/completions",
145
+ json={
146
+ "model": config.active_model,
147
+ "messages": messages,
148
+ "max_tokens": 2048,
149
+ "temperature": 0.2,
150
+ },
151
+ )
152
+ resp.raise_for_status()
153
+ data = resp.json()
154
+
155
+ full_response = data["choices"][0]["message"]["content"]
156
+ logger.info("Planner response length: %d chars", len(full_response))
157
+
158
+ return extract_plan(full_response)
159
+
160
+
161
+ # ============================================================================
162
+ # Phase 2: SCAFFOLD
163
+ # ============================================================================
164
+
165
+ def scaffold_package(plan: BuildPlan, base_dir: Path) -> list[Path]:
166
+ """Phase 2: Create package structure deterministically. No LLM needed."""
167
+ pkg_dir = base_dir / plan.package_name
168
+ pkg_dir.mkdir(parents=True, exist_ok=True)
169
+
170
+ created = []
171
+
172
+ # __init__.py
173
+ init_path = pkg_dir / "__init__.py"
174
+ init_path.write_text(f'"""{plan.description}"""\n')
175
+ created.append(init_path)
176
+
177
+ # __main__.py with correct absolute import
178
+ main_path = pkg_dir / "__main__.py"
179
+ main_path.write_text(
180
+ f"from {plan.package_name}.{plan.entry_point} import main\n\n"
181
+ f'if __name__ == "__main__":\n'
182
+ f" main()\n"
183
+ )
184
+ created.append(main_path)
185
+
186
+ # Create stub files so imports resolve during implementation
187
+ for file_spec in plan.files:
188
+ fp = base_dir / file_spec.path
189
+ fp.parent.mkdir(parents=True, exist_ok=True)
190
+ fp.write_text(f'"""{file_spec.purpose}"""\n\n# TODO: implement\n')
191
+ created.append(fp)
192
+
193
+ return created
194
+
195
+
196
+ # ============================================================================
197
+ # Phase 3: IMPLEMENT (one subagent per file)
198
+ # ============================================================================
199
+
200
+ FILE_PROMPT = """Write the COMPLETE implementation for `{file_path}`.
201
+
202
+ Package: {package_name}
203
+ Purpose: {purpose}
204
+
205
+ Other modules in this package:
206
+ {module_listing}
207
+
208
+ {import_note}
209
+
210
+ RULES:
211
+ - Use write_file to write the complete file
212
+ - Use ABSOLUTE imports: `from {package_name}.module import X`
213
+ - Do NOT use relative imports (from .module)
214
+ - Write production-quality code with type hints and docstrings
215
+ - If this is the CLI module, it MUST have a `def main():` function using argparse
216
+ - After writing the file, STOP immediately
217
+ """
218
+
219
+
220
+ async def implement_file(
221
+ file_spec: FileSpec,
222
+ plan: BuildPlan,
223
+ config: VibeConfig,
224
+ base_dir: Path,
225
+ ) -> bool:
226
+ """Ask the LLM to generate code for one file via direct API call.
227
+
228
+ Instead of spawning a full AgentLoop (which causes recursion issues),
229
+ we make a direct chat completion call and write the result to disk.
230
+ This is much lighter — no tools, no loop, no context management.
231
+ """
232
+ module_lines = []
233
+ for f in plan.files:
234
+ marker = " <-- THIS FILE" if f.path == file_spec.path else ""
235
+ module_lines.append(f" {f.path}: {f.purpose}{marker}")
236
+ module_listing = "\n".join(module_lines)
237
+
238
+ import_note = ""
239
+ if file_spec.imports:
240
+ import_note = f"This file should import from: {', '.join(file_spec.imports)}"
241
+
242
+ prompt = FILE_PROMPT.format(
243
+ file_path=file_spec.path,
244
+ package_name=plan.package_name,
245
+ purpose=file_spec.purpose,
246
+ module_listing=module_listing,
247
+ import_note=import_note,
248
+ )
249
+
250
+ # Direct API call — no AgentLoop overhead
251
+ try:
252
+ import httpx
253
+
254
+ # Find the provider config
255
+ provider = config.providers[0] if config.providers else None
256
+ if not provider:
257
+ return False
258
+
259
+ messages = [
260
+ {"role": "system", "content": (
261
+ "You are a code implementation agent. Write the COMPLETE Python file. "
262
+ "Output ONLY the Python code, no markdown fences, no explanation. "
263
+ "Use absolute imports (from package.module import X, NOT from .module import X)."
264
+ )},
265
+ {"role": "user", "content": prompt},
266
+ ]
267
+
268
+ async with httpx.AsyncClient(timeout=300) as client:
269
+ resp = await client.post(
270
+ f"{provider.api_base}/chat/completions",
271
+ json={
272
+ "model": config.active_model,
273
+ "messages": messages,
274
+ "max_tokens": 4096,
275
+ "temperature": 0.3,
276
+ },
277
+ )
278
+ resp.raise_for_status()
279
+ data = resp.json()
280
+
281
+ content = data["choices"][0]["message"]["content"]
282
+
283
+ # Strip markdown fences if present
284
+ if "```python" in content:
285
+ content = content.split("```python", 1)[1]
286
+ if "```" in content:
287
+ content = content.split("```", 1)[0]
288
+ elif "```" in content:
289
+ parts = content.split("```")
290
+ if len(parts) >= 3:
291
+ content = parts[1]
292
+ if content.startswith("python\n"):
293
+ content = content[7:]
294
+
295
+ content = content.strip() + "\n"
296
+
297
+ # Write the file
298
+ file_path = base_dir / file_spec.path
299
+ file_path.parent.mkdir(parents=True, exist_ok=True)
300
+ file_path.write_text(content)
301
+
302
+ # Verify syntax
303
+ import ast
304
+ try:
305
+ ast.parse(content)
306
+ except SyntaxError as e:
307
+ logger.warning("Syntax error in generated %s: %s", file_spec.path, e)
308
+ return False
309
+
310
+ return True
311
+
312
+ except Exception as e:
313
+ logger.warning("Failed to implement %s: %s", file_spec.path, e)
314
+ return False
315
+
316
+
317
+ # ============================================================================
318
+ # Main orchestrator
319
+ # ============================================================================
320
+
321
+ async def run_build_pipeline(
322
+ user_prompt: str,
323
+ config: VibeConfig,
324
+ base_dir: Path | None = None,
325
+ ) -> str:
326
+ """Run the full multi-phase build pipeline.
327
+
328
+ Returns a summary string for the main agent to display.
329
+ """
330
+ if base_dir is None:
331
+ base_dir = Path.cwd()
332
+
333
+ # Phase 1: Plan
334
+ logger.info("BUILD PHASE 1: Planning...")
335
+ try:
336
+ plan = await run_planner(user_prompt, config)
337
+ except (ValueError, json.JSONDecodeError, KeyError) as e:
338
+ raise RuntimeError(f"Planning failed: {e}") from e
339
+
340
+ logger.info("Plan: package=%s, files=%d, entry=%s",
341
+ plan.package_name, len(plan.files), plan.entry_point)
342
+
343
+ # Phase 2: Scaffold
344
+ logger.info("BUILD PHASE 2: Scaffolding...")
345
+ created = scaffold_package(plan, base_dir)
346
+ logger.info("Scaffolded %d files", len(created))
347
+
348
+ # Phase 3: Implement each file
349
+ logger.info("BUILD PHASE 3: Implementing %d files...", len(plan.files))
350
+ results = []
351
+ for i, file_spec in enumerate(plan.files):
352
+ logger.info(" Implementing [%d/%d]: %s", i + 1, len(plan.files), file_spec.path)
353
+ # Try up to 2 times per file
354
+ success = False
355
+ for attempt in range(2):
356
+ try:
357
+ success = await implement_file(file_spec, plan, config, base_dir)
358
+ if success:
359
+ _fix_imports(base_dir / file_spec.path, plan.package_name)
360
+ break
361
+ else:
362
+ logger.warning(" Attempt %d failed for %s, retrying...", attempt + 1, file_spec.path)
363
+ except Exception as e:
364
+ logger.warning(" Attempt %d error for %s: %s", attempt + 1, file_spec.path, e)
365
+ results.append((file_spec.path, success))
366
+
367
+ # Build summary
368
+ succeeded = sum(1 for _, ok in results if ok)
369
+ failed_files = [path for path, ok in results if not ok]
370
+
371
+ summary_lines = [
372
+ f"PROJECT BUILT: {plan.package_name}",
373
+ f"Description: {plan.description}",
374
+ f"Files: {succeeded}/{len(plan.files)} implemented",
375
+ f"",
376
+ f"Package structure:",
377
+ ]
378
+ for f in plan.files:
379
+ status = "OK" if any(p == f.path and ok for p, ok in results) else "STUB"
380
+ summary_lines.append(f" {f.path} [{status}] — {f.purpose}")
381
+
382
+ summary_lines.extend([
383
+ f"",
384
+ f"Entry point: python3 -m {plan.package_name}",
385
+ f"",
386
+ f"Test the project now by running: python3 -m {plan.package_name} --help",
387
+ f"If it fails, read the error and fix with search_replace.",
388
+ ])
389
+
390
+ if failed_files:
391
+ summary_lines.extend([
392
+ f"",
393
+ f"NEEDS IMPLEMENTATION: {', '.join(failed_files)}",
394
+ f"These files have stubs only. Implement them with write_file.",
395
+ ])
396
+
397
+ return "\n".join(summary_lines)
398
+
399
+
400
+ def _fix_imports(file_path: Path, package_name: str) -> None:
401
+ """Fix relative imports in a file to absolute imports."""
402
+ try:
403
+ if not file_path.exists():
404
+ return
405
+ content = file_path.read_text()
406
+ if "from ." not in content:
407
+ return
408
+ fixed = re.sub(
409
+ r"from \.([\w.]+) import",
410
+ f"from {package_name}.\\1 import",
411
+ content,
412
+ )
413
+ fixed = re.sub(
414
+ r"from \. import",
415
+ f"from {package_name} import",
416
+ fixed,
417
+ )
418
+ if fixed != content:
419
+ file_path.write_text(fixed)
420
+ logger.info("Fixed relative imports in %s", file_path.name)
421
+ except Exception:
422
+ pass
@@ -21,6 +21,7 @@ class SystemPrompt(Prompt):
21
21
  CLI = auto()
22
22
  EXPLORE = auto()
23
23
  TESTS = auto()
24
+ BUILDER = auto()
24
25
 
25
26
 
26
27
  class UtilityPrompt(Prompt):
@@ -0,0 +1,16 @@
1
+ You are a code implementation agent. You write ONE file for a Python package.
2
+
3
+ You will be given:
4
+ - The file path to create
5
+ - The file's purpose
6
+ - The package structure (what other modules exist)
7
+ - Which modules this file imports from
8
+
9
+ Rules:
10
+ - Write the COMPLETE file using write_file. Include all imports, classes, functions.
11
+ - Use ABSOLUTE imports: `from package_name.module import X`, NOT `from .module import X`
12
+ - Do NOT create __init__.py or __main__.py (already done)
13
+ - Do NOT run bash commands or tests
14
+ - Do NOT read other files unless absolutely necessary
15
+ - After writing the file, STOP. Do not do anything else.
16
+ - Write production-quality code: type hints, docstrings, error handling.
@@ -223,12 +223,18 @@ Error Handling:
223
223
  - After ANY error, your next action must be DIFFERENT from what just failed.
224
224
  - Never run the same failing command twice — the result won't change.
225
225
 
226
- Python Package Rules:
226
+ Python Package Rules (MANDATORY):
227
227
  When creating Python packages (directories with __init__.py):
228
- - Use ABSOLUTE imports, not relative. Write `from mypackage.module import X`, NOT `from .module import X`
229
- - To run a package: `python3 -m mypackage` (requires __main__.py), NOT `python3 mypackage/main.py`
230
- - Relative imports (from .foo) ONLY work with `python3 -m`, not direct file execution
231
- - If you get "attempted relative import with no known parent package", switch to absolute imports
228
+ - ALWAYS create __main__.py so `python3 -m mypackage` works. Contents:
229
+ ```
230
+ from mypackage.cli import main
231
+ if __name__ == "__main__":
232
+ main()
233
+ ```
234
+ - Use ABSOLUTE imports: `from mypackage.module import X`, NOT `from .module import X`
235
+ - NEVER run `python3 mypackage/file.py` — ALWAYS use `python3 -m mypackage`
236
+ - Create sample/test data BEFORE running tests (e.g., create test.log before analyzing it)
237
+ - After 1-2 successful test runs, STOP testing and summarize what you built
232
238
 
233
239
  Debugging Best Practices:
234
240
  When fixing bugs, follow this cycle: RUN → READ → FIX → VERIFY.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "1.5.4"
3
+ version = "1.6.0"
4
4
  description = "Drydock — nautical CLI coding agent"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"