drydock-cli 2.6.136__tar.gz → 2.6.138__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- drydock_cli-2.6.138/Admiral.md +186 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/PKG-INFO +1 -1
- drydock_cli-2.6.138/drydock/admiral/__init__.py +15 -0
- drydock_cli-2.6.138/drydock/admiral/detectors.py +104 -0
- drydock_cli-2.6.138/drydock/admiral/history.py +23 -0
- drydock_cli-2.6.138/drydock/admiral/interventions.py +21 -0
- drydock_cli-2.6.138/drydock/admiral/worker.py +93 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/app.py +9 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/messages.py +53 -23
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/pyproject.toml +1 -1
- drydock_cli-2.6.138/tests/test_admiral.py +75 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.claude/scheduled_tasks.lock +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.gitignore +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.python-version +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.typos.toml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.vscode/extensions.json +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.vscode/launch.json +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.vscode/settings.json +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/AGENTS.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/BASELINE_412.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/CHANGELOG.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/CLAUDE.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/LICENSE +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/NOTICE +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/PRD.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/README.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/action.yml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/README.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/docs/README.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/docs/acp-setup.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agent_loop.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/logger.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/slug.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/types.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/utils.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/choice.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/local_model.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/whats_new.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock-acp.spec +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock_terms.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/flake.lock +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/flake.nix +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/README.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/backup.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/bump_version.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/comprehensive_loop.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/discover_cli_tools.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/evolve_tests.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/install.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/mega_loop.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/meta_ralph_loop.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/notify_release.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/oss_task_harness.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/poll_issues.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/port_task.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/session_loop_audit.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_regression.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_full.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_tui_path.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/tui_test.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/conftest.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/common.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/utils.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agents.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_integration.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_issue_fixes.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_message_id.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_middleware.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_smoke.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_workloads.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/uv.lock +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/README.md +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# PRD: Admiral + Drydock (Adaptive Agent Orchestration System)
|
|
2
|
+
|
|
3
|
+
## 1. Overview
|
|
4
|
+
* **Execution Harness:** Drydock
|
|
5
|
+
* **Orchestration & Meta-Learning Layer:** Admiral
|
|
6
|
+
* **Vision:** Create an observable, self-tuning LLM harness. Drydock handles the deterministic execution of agentic tasks (tools, loops, file ops), while Admiral operates as an out-of-band supervisor that detects failure patterns, dynamically updates execution parameters, and controls the system's learning rate to prevent behavioral degradation.
|
|
7
|
+
|
|
8
|
+
## 2. Core Problem
|
|
9
|
+
Current agent harnesses suffer from architectural fragility:
|
|
10
|
+
* **Static Execution:** They rely on hardcoded routing logic and brittle system prompts.
|
|
11
|
+
* **Zero Self-Awareness:** They cannot detect when they are stuck in a logical loop or hallucinating tool calls.
|
|
12
|
+
* **Lack of Domain Adaptation:** A coding agent and a research agent require different tolerances for loops and errors, but standard harnesses treat them identically.
|
|
13
|
+
* **The Root Issue:** We are deploying non-deterministic intelligence inside rigid, deterministic boxes.
|
|
14
|
+
|
|
15
|
+
## 3. System Architecture
|
|
16
|
+
The system utilizes a dual-layer approach, strictly separating the "doing" from the "supervising."
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
[ User Interface (TUI / CLI) ]
|
|
20
|
+
|
|
|
21
|
+
v
|
|
22
|
+
[ ADMIRAL (Meta-Controller) ] <--- Telemetry & Logs
|
|
23
|
+
| |
|
|
24
|
+
State Config |
|
|
25
|
+
v |
|
|
26
|
+
[ DRYDOCK (Execution Engine) ] ----+
|
|
27
|
+
|
|
|
28
|
+
[ LLM Kernel ] <--> [ Tool / Env Runtime ]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 4. Core Components
|
|
32
|
+
|
|
33
|
+
### 4.1 Admiral (The Orchestrator)
|
|
34
|
+
Admiral does not execute tasks. It ingests telemetry, evaluates execution health, and pushes state updates to Drydock.
|
|
35
|
+
|
|
36
|
+
* **A. Telemetry Ingestion:** Processes structured logs from Drydock (token usage, tool call frequency, error stack traces, execution latency).
|
|
37
|
+
* **B. Pattern & Anomaly Detection:**
|
|
38
|
+
* *Loop Detection:* Identifies repeated sequential tool calls with identical outputs.
|
|
39
|
+
* *Struggle Detection:* Identifies high token burn with zero file modifications or task progression.
|
|
40
|
+
* **C. State-Driven Modification (Not Code-Rewriting):**
|
|
41
|
+
* Admiral modifies Drydock's behavior by updating its **State Config** (e.g., system prompt matrices, tool-access blocklists, max-loop constraints). It does *not* rewrite source code.
|
|
42
|
+
* **D. Learning Rate Scheduler:**
|
|
43
|
+
* Controls how fast Admiral can alter Drydock's baseline configuration.
|
|
44
|
+
* *Cold Start:* High tolerance for manual interventions, low threshold for prompt tweaks.
|
|
45
|
+
* *Stable:* High threshold for baseline changes; relies on localized session memory.
|
|
46
|
+
* **E. Interventions & Versioning:**
|
|
47
|
+
* Pauses Drydock when a failure threshold is crossed.
|
|
48
|
+
* Prompts the user via TUI: *"Loop detected. Propose dropping [WebSearch] tool and appending directive: 'Use grep instead'. Approve? (Y/N)"*
|
|
49
|
+
* Maintains a Git-like history of all config state changes for instant rollbacks.
|
|
50
|
+
|
|
51
|
+
### 4.2 Drydock (The Execution Harness)
|
|
52
|
+
Drydock is a highly modular, state-driven execution loop.
|
|
53
|
+
|
|
54
|
+
* **A. State-Hydrated Execution:** Drydock boots up by reading the config injected by Admiral. If Admiral alters the system prompt or revokes a tool mid-flight, Drydock adopts the new state on the next loop iteration.
|
|
55
|
+
* **B. Modular Primitives:**
|
|
56
|
+
* *Planner:* Maps the initial task.
|
|
57
|
+
* *Executor:* Formats the prompt and parses the LLM output.
|
|
58
|
+
* *Tool Router:* Safely executes the requested local commands.
|
|
59
|
+
* **C. Telemetry Emitter:** Emits a standardized JSON log for every step (e.g., `{"step": 4, "action": "tool_call", "tool": "bash", "status": "error", "latency": "1.2s"}`) directly to Admiral.
|
|
60
|
+
|
|
61
|
+
## 5. Example Execution Flow (Stuck State Mitigation)
|
|
62
|
+
1. **Drydock:** Attempts to run a broken Python script 4 times. Each time, the LLM hallucinates the same incorrect fix.
|
|
63
|
+
2. **Drydock:** Emits 4 identical error logs to the telemetry stream.
|
|
64
|
+
3. **Admiral:** Detects the pattern. The confidence score for a "Logic Loop" hits 0.95.
|
|
65
|
+
4. **Admiral:** Issues a `PAUSE` signal to Drydock.
|
|
66
|
+
5. **Admiral (via TUI):** *"Drydock is looping on a syntax error. Suggestion: Inject context directive 'Stop attempting to fix lines 40-50, rewrite the function from scratch.' Apply? (Y/n)"*
|
|
67
|
+
6. **User:** Hits 'Y'.
|
|
68
|
+
7. **Admiral:** Updates Drydock's temporary session config with the new directive. Issues `RESUME`.
|
|
69
|
+
8. **Drydock:** Re-evaluates the prompt with the new directive and breaks the loop.
|
|
70
|
+
|
|
71
|
+
## 6. Project Risks & Mitigations
|
|
72
|
+
* **Risk:** The system becomes too complex to debug (who broke it, Admiral or the LLM?).
|
|
73
|
+
* *Mitigation:* Strict, readable audit logs. Every change Admiral makes to Drydock's state must be written to a plain-text `admiral_history.log`.
|
|
74
|
+
* **Risk:** Overfitting to specific user quirks.
|
|
75
|
+
* *Mitigation:* Separate the memory stores. Maintain a `Session State` (wiped every run) and a `Global State` (persistent). Admiral must prove a fix works across multiple sessions before committing it to the Global State.
|
|
76
|
+
* **Risk:** "Hallucinated" fixes by Admiral.
|
|
77
|
+
* *Mitigation:* Admiral uses hardcoded heuristic triggers for Phase 1 MVP, *not* an LLM, to decide when to intervene.
|
|
78
|
+
|
|
79
|
+
## 7. MVP Scope (Phase 1)
|
|
80
|
+
* **Drydock:** Basic CLI/TUI that can execute shell commands, read/write files, and query an LLM. Must emit structured JSON logs.
|
|
81
|
+
* **Admiral:** A background Python thread that tails Drydock's logs.
|
|
82
|
+
* **Features:**
|
|
83
|
+
* Regex-based loop detection.
|
|
84
|
+
* Hard pause capability.
|
|
85
|
+
* Ability to let the user manually inject a new system prompt directive mid-run without restarting the context window.
|
|
86
|
+
|
|
87
|
+
***
|
|
88
|
+
|
|
89
|
+
## 8. Implementation Status (2026-04-17)
|
|
90
|
+
|
|
91
|
+
### Phase 1 — SHIPPED (module present in v2.6.137, wiring in flight for v2.6.138)
|
|
92
|
+
|
|
93
|
+
Architecture: **in-process** (option C). Admiral runs as an asyncio.Task
|
|
94
|
+
inside the Textual app's event loop — same process as the agent, no IPC.
|
|
95
|
+
Auto-apply default (no Y/N approval) per user directive.
|
|
96
|
+
|
|
97
|
+
Files:
|
|
98
|
+
* `drydock/admiral/__init__.py` — public API (`attach(agent_loop)`).
|
|
99
|
+
* `drydock/admiral/detectors.py` — `detect_tool_call_loop`,
|
|
100
|
+
`detect_struggle`, `run_all`. Pure functions; return `Finding(code, directive)`.
|
|
101
|
+
* `drydock/admiral/interventions.py` — `apply(agent_loop, finding)` →
|
|
102
|
+
calls `AgentLoop._inject_system_note` + appends to audit log.
|
|
103
|
+
* `drydock/admiral/history.py` — append-only timestamped log at
|
|
104
|
+
`~/.vibe/logs/admiral_history.log`.
|
|
105
|
+
* `drydock/admiral/worker.py` — `AdmiralWorker` async task that polls
|
|
106
|
+
every 5s, dedup window 60s per finding code.
|
|
107
|
+
* `tests/test_admiral.py` — 5 tests for detector correctness.
|
|
108
|
+
|
|
109
|
+
Integration:
|
|
110
|
+
* `drydock/cli/textual_ui/app.py::on_mount` — `admiral.attach(agent_loop)`
|
|
111
|
+
after approval callbacks are set. Stored on `self._admiral`. Any Admiral
|
|
112
|
+
import/startup error is logged but never prevents the TUI from starting.
|
|
113
|
+
|
|
114
|
+
Detectors (Phase 1):
|
|
115
|
+
1. **Loop detection** — 3+ identical (tool_name + arguments) calls in a
|
|
116
|
+
row → inject directive telling the model to stop the loop.
|
|
117
|
+
2. **Struggle detection** — 20+ non-write tool calls since the last
|
|
118
|
+
`write_file`/`search_replace`/`edit_file` → inject "write code or
|
|
119
|
+
tell the user you're stuck."
|
|
120
|
+
|
|
121
|
+
### Phase 2 — DESIGNED (target v2.6.139+)
|
|
122
|
+
|
|
123
|
+
Escalation ladder for when heuristics aren't enough:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
[Admiral detector fires]
|
|
127
|
+
|
|
|
128
|
+
v
|
|
129
|
+
[local Gemma 4 meta-analysis] — send the last N turns + the finding to
|
|
130
|
+
the local vLLM endpoint asking "what
|
|
131
|
+
is really going wrong? what directive
|
|
132
|
+
would unstick the agent?"
|
|
133
|
+
|
|
|
134
|
+
v (low confidence / model also stumped)
|
|
135
|
+
[Claude Code (Opus) escalation] — shell out to `claude -p "<analysis>"`
|
|
136
|
+
(or the Anthropic SDK) for a second
|
|
137
|
+
opinion. Cap at N escalations per
|
|
138
|
+
session.
|
|
139
|
+
|
|
|
140
|
+
v
|
|
141
|
+
[Admiral applies Opus's directive via _inject_system_note]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Open design questions for Phase 2:
|
|
145
|
+
* Local LLM reuse: should Admiral reuse the agent's own backend
|
|
146
|
+
connection, or open its own at a different temperature?
|
|
147
|
+
→ **Lean:** reuse `AgentLoop.backend` with a separate message list
|
|
148
|
+
and lower temperature (0.1 vs 0.7) so the analysis is deterministic.
|
|
149
|
+
* Opus access: `claude -p` CLI or `anthropic` SDK?
|
|
150
|
+
→ **Lean:** SDK when `ANTHROPIC_API_KEY` is set; fall back to
|
|
151
|
+
`claude -p` when not (so users who already have Claude Code auth
|
|
152
|
+
don't need to re-enter a key).
|
|
153
|
+
* Rate-limiting: prevent Opus blast during a bad run. Max 3 escalations
|
|
154
|
+
per session by default. Override via env var.
|
|
155
|
+
|
|
156
|
+
### Phase 3 — IDEAS (not started)
|
|
157
|
+
|
|
158
|
+
* **Learning-rate scheduler (PRD §4.1.D)** — cold start accepts many
|
|
159
|
+
tweaks, stable mode accepts few. Implement by tracking how many
|
|
160
|
+
interventions the user manually undid via slash-commands.
|
|
161
|
+
* **Session vs Global memory (PRD §6)** — session state wiped per run;
|
|
162
|
+
global state only promoted if a fix worked across ≥2 sessions.
|
|
163
|
+
* **TUI widget** — a collapsible Admiral panel showing recent findings
|
|
164
|
+
and their outcomes, so the user can audit the supervisor.
|
|
165
|
+
|
|
166
|
+
## 9. Continuity Notes (if this session is lost)
|
|
167
|
+
|
|
168
|
+
If you restart mid-Phase-2:
|
|
169
|
+
* **What ships:** `drydock/admiral/` (Phase 1, working) + PRD (this
|
|
170
|
+
file). Check `git log --oneline -20` — Phase 1 commit should name
|
|
171
|
+
"Admiral Phase 1".
|
|
172
|
+
* **What's missing:** `drydock/admiral/llm_analyzer.py` (local LLM)
|
|
173
|
+
and `drydock/admiral/opus_escalator.py` (Claude Code fallback).
|
|
174
|
+
Neither exists yet — start them from the Phase 2 section above.
|
|
175
|
+
* **Audit log:** `~/.vibe/logs/admiral_history.log` shows every
|
|
176
|
+
intervention Admiral has applied in real user sessions.
|
|
177
|
+
* **User directives recorded so far in this session:**
|
|
178
|
+
- Architecture: option C (in-process Textual worker).
|
|
179
|
+
- Approval: auto-apply, no Y/N dialog.
|
|
180
|
+
- Phase 2: Admiral uses local LLM first; escalates to Claude Code
|
|
181
|
+
(Opus) when stumped.
|
|
182
|
+
- Keep updating this PRD as work progresses so a session loss
|
|
183
|
+
doesn't cost context.
|
|
184
|
+
|
|
185
|
+
***
|
|
186
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.138
|
|
4
4
|
Summary: Local-first CLI coding agent — tested with Gemma 4 26B via vLLM
|
|
5
5
|
Project-URL: Homepage, https://github.com/fbobe321/drydock
|
|
6
6
|
Project-URL: Repository, https://github.com/fbobe321/drydock
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Admiral — meta-controller that supervises drydock sessions.
|
|
2
|
+
|
|
3
|
+
Phase 1: heuristic loop and struggle detection, auto-applied interventions
|
|
4
|
+
via the existing `_inject_system_note` channel. All interventions are
|
|
5
|
+
logged to `~/.vibe/logs/admiral_history.log` for post-hoc review.
|
|
6
|
+
|
|
7
|
+
The detectors read the live message list of an AgentLoop; the worker
|
|
8
|
+
runs as a Textual background task so it lives in the same event loop
|
|
9
|
+
as the agent (no threading, no IPC). See Admiral.md for the PRD.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from drydock.admiral.worker import AdmiralWorker, attach
|
|
14
|
+
|
|
15
|
+
__all__ = ["AdmiralWorker", "attach"]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Heuristic detectors that inspect the live message list.
|
|
2
|
+
|
|
3
|
+
Each detector is a pure function: take the messages, return a
|
|
4
|
+
`Finding(code, directive)` if it fires, or `None`. Findings are
|
|
5
|
+
idempotent within a short window — callers dedup before intervening.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from collections.abc import Sequence
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
12
|
+
from drydock.core.types import LLMMessage, Role
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
WRITE_TOOLS: frozenset[str] = frozenset({"write_file", "search_replace", "edit_file"})
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class Finding:
|
|
20
|
+
code: str # stable ID used for dedup, e.g. "loop:write_file:/p/x.py"
|
|
21
|
+
directive: str # text to inject into the conversation
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _tool_sig(tc) -> str: # ToolCall — keep loose to avoid circular import
|
|
25
|
+
name = tc.function.name or ""
|
|
26
|
+
args = tc.function.arguments or ""
|
|
27
|
+
return f"{name}::{args}"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def detect_tool_call_loop(messages: Sequence[LLMMessage], window: int = 3) -> Finding | None:
|
|
31
|
+
"""Fires when the last `window` assistant tool calls are byte-identical.
|
|
32
|
+
|
|
33
|
+
Drydock already has its own loop prevention; this catches the cases
|
|
34
|
+
where the existing system warns-but-doesn't-stop and the model
|
|
35
|
+
ignored the warning.
|
|
36
|
+
"""
|
|
37
|
+
sigs: list[str] = []
|
|
38
|
+
for m in reversed(messages):
|
|
39
|
+
if m.role != Role.assistant or not m.tool_calls:
|
|
40
|
+
continue
|
|
41
|
+
for tc in m.tool_calls:
|
|
42
|
+
sigs.append(_tool_sig(tc))
|
|
43
|
+
if len(sigs) >= window:
|
|
44
|
+
break
|
|
45
|
+
if len(sigs) >= window:
|
|
46
|
+
break
|
|
47
|
+
if len(sigs) < window:
|
|
48
|
+
return None
|
|
49
|
+
if len(set(sigs)) != 1:
|
|
50
|
+
return None
|
|
51
|
+
sig = sigs[0]
|
|
52
|
+
return Finding(
|
|
53
|
+
code=f"loop:{sig[:80]}",
|
|
54
|
+
directive=(
|
|
55
|
+
f"Admiral: you have called the same tool with identical arguments "
|
|
56
|
+
f"{window} times in a row. The next call will almost certainly "
|
|
57
|
+
f"produce the same result. Stop this path, try a different "
|
|
58
|
+
f"approach, or tell the user what's blocking you."
|
|
59
|
+
),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def detect_struggle(messages: Sequence[LLMMessage], threshold: int = 20) -> Finding | None:
|
|
64
|
+
"""Fires when `threshold` tool calls have happened without any write.
|
|
65
|
+
|
|
66
|
+
Reading + grepping forever without writing code is the classic
|
|
67
|
+
"stuck exploring" failure mode.
|
|
68
|
+
"""
|
|
69
|
+
calls_since_write = 0
|
|
70
|
+
last_write_tool: str | None = None
|
|
71
|
+
for m in messages:
|
|
72
|
+
if m.role != Role.assistant or not m.tool_calls:
|
|
73
|
+
continue
|
|
74
|
+
for tc in m.tool_calls:
|
|
75
|
+
name = tc.function.name or ""
|
|
76
|
+
if name in WRITE_TOOLS:
|
|
77
|
+
calls_since_write = 0
|
|
78
|
+
last_write_tool = name
|
|
79
|
+
else:
|
|
80
|
+
calls_since_write += 1
|
|
81
|
+
if calls_since_write < threshold:
|
|
82
|
+
return None
|
|
83
|
+
hint = (
|
|
84
|
+
"Either (a) you already have enough context — commit to a plan and "
|
|
85
|
+
"start writing code now, or (b) you're genuinely stuck — stop and "
|
|
86
|
+
"report what's blocking you to the user."
|
|
87
|
+
)
|
|
88
|
+
return Finding(
|
|
89
|
+
code=f"struggle:{calls_since_write}:{last_write_tool or 'none'}",
|
|
90
|
+
directive=(
|
|
91
|
+
f"Admiral: you have made {calls_since_write} tool calls without "
|
|
92
|
+
f"writing or editing any file. {hint}"
|
|
93
|
+
),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def run_all(messages: Sequence[LLMMessage]) -> list[Finding]:
|
|
98
|
+
"""Run every detector and return all findings that fire."""
|
|
99
|
+
results: list[Finding] = []
|
|
100
|
+
for fn in (detect_tool_call_loop, detect_struggle):
|
|
101
|
+
f = fn(messages)
|
|
102
|
+
if f is not None:
|
|
103
|
+
results.append(f)
|
|
104
|
+
return results
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Plain-text audit log for every intervention Admiral applies.
|
|
2
|
+
|
|
3
|
+
Per the PRD: "Every change Admiral makes to Drydock's state must be
|
|
4
|
+
written to a plain-text admiral_history.log." Kept simple on purpose —
|
|
5
|
+
no JSON, no rotation logic, just append-only timestamped lines.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _log_path() -> Path:
|
|
14
|
+
d = Path.home() / ".vibe" / "logs"
|
|
15
|
+
d.mkdir(parents=True, exist_ok=True)
|
|
16
|
+
return d / "admiral_history.log"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def append(event: str, detail: str) -> None:
|
|
20
|
+
ts = datetime.now(timezone.utc).isoformat(timespec="seconds")
|
|
21
|
+
line = f"{ts} | {event} | {detail}\n"
|
|
22
|
+
with _log_path().open("a") as f:
|
|
23
|
+
f.write(line)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Apply interventions by injecting into the running AgentLoop.
|
|
2
|
+
|
|
3
|
+
The injection path is the same `_inject_system_note` drydock's own
|
|
4
|
+
safety checks use — Admiral is just another source of directives.
|
|
5
|
+
Every intervention writes to the audit log.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from drydock.admiral import history
|
|
12
|
+
from drydock.admiral.detectors import Finding
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from drydock.core.agent_loop import AgentLoop
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def apply(agent_loop: AgentLoop, finding: Finding) -> None:
|
|
19
|
+
"""Inject the finding's directive into the live conversation."""
|
|
20
|
+
agent_loop._inject_system_note(finding.directive)
|
|
21
|
+
history.append("intervention", f"{finding.code} :: {finding.directive[:160]}")
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""AdmiralWorker — periodic supervisor running inside the Textual app.
|
|
2
|
+
|
|
3
|
+
Phase 1 behaviour:
|
|
4
|
+
- Every ~5s, inspect the live AgentLoop message list.
|
|
5
|
+
- Run all detectors.
|
|
6
|
+
- For each finding NOT seen in the last `DEDUP_WINDOW_SEC` seconds,
|
|
7
|
+
auto-apply the intervention.
|
|
8
|
+
- Log both findings (with auto-apply decision) and bootstrap/stop
|
|
9
|
+
events to ~/.vibe/logs/admiral_history.log.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
import logging
|
|
15
|
+
import time
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
from drydock.admiral import detectors, history, interventions
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from drydock.core.agent_loop import AgentLoop
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
POLL_INTERVAL_SEC = 5.0
|
|
26
|
+
DEDUP_WINDOW_SEC = 60.0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class AdmiralWorker:
|
|
30
|
+
"""Async task that supervises one AgentLoop.
|
|
31
|
+
|
|
32
|
+
Not a Textual worker class — it's just an asyncio.Task you spawn
|
|
33
|
+
from inside the TUI app's event loop. Lives alongside the agent,
|
|
34
|
+
stops when the agent stops.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, agent_loop: AgentLoop) -> None:
|
|
38
|
+
self.agent_loop = agent_loop
|
|
39
|
+
self._task: asyncio.Task | None = None
|
|
40
|
+
self._recent_findings: dict[str, float] = {} # code -> timestamp
|
|
41
|
+
|
|
42
|
+
def start(self) -> None:
|
|
43
|
+
if self._task is not None and not self._task.done():
|
|
44
|
+
return
|
|
45
|
+
self._task = asyncio.create_task(self._run(), name="admiral-worker")
|
|
46
|
+
history.append("bootstrap", "AdmiralWorker started")
|
|
47
|
+
|
|
48
|
+
def stop(self) -> None:
|
|
49
|
+
if self._task is None:
|
|
50
|
+
return
|
|
51
|
+
self._task.cancel()
|
|
52
|
+
self._task = None
|
|
53
|
+
history.append("shutdown", "AdmiralWorker stopped")
|
|
54
|
+
|
|
55
|
+
async def _run(self) -> None:
|
|
56
|
+
try:
|
|
57
|
+
while True:
|
|
58
|
+
await asyncio.sleep(POLL_INTERVAL_SEC)
|
|
59
|
+
try:
|
|
60
|
+
self._tick()
|
|
61
|
+
except Exception as e:
|
|
62
|
+
# Detector bugs must never crash the agent — log and continue.
|
|
63
|
+
logger.warning("Admiral tick error: %s", e)
|
|
64
|
+
history.append("error", f"tick failed: {e}")
|
|
65
|
+
except asyncio.CancelledError:
|
|
66
|
+
raise
|
|
67
|
+
|
|
68
|
+
def _tick(self) -> None:
|
|
69
|
+
now = time.monotonic()
|
|
70
|
+
# Garbage-collect old dedup entries so long sessions don't leak.
|
|
71
|
+
self._recent_findings = {
|
|
72
|
+
code: ts for code, ts in self._recent_findings.items()
|
|
73
|
+
if now - ts < DEDUP_WINDOW_SEC
|
|
74
|
+
}
|
|
75
|
+
findings = detectors.run_all(list(self.agent_loop.messages))
|
|
76
|
+
for f in findings:
|
|
77
|
+
last = self._recent_findings.get(f.code)
|
|
78
|
+
if last is not None and (now - last) < DEDUP_WINDOW_SEC:
|
|
79
|
+
continue
|
|
80
|
+
self._recent_findings[f.code] = now
|
|
81
|
+
interventions.apply(self.agent_loop, f)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def attach(agent_loop: AgentLoop) -> AdmiralWorker:
|
|
85
|
+
"""Start an AdmiralWorker supervising the given agent loop.
|
|
86
|
+
|
|
87
|
+
Returns the worker handle so the caller can stop it on shutdown.
|
|
88
|
+
Safe to call multiple times — a fresh worker replaces any prior
|
|
89
|
+
one, but that's the caller's responsibility to track.
|
|
90
|
+
"""
|
|
91
|
+
worker = AdmiralWorker(agent_loop)
|
|
92
|
+
worker.start()
|
|
93
|
+
return worker
|
|
@@ -288,6 +288,7 @@ class VibeApp(App): # noqa: PLR0904
|
|
|
288
288
|
self._last_escape_time: float | None = None
|
|
289
289
|
self._banner: Banner | None = None
|
|
290
290
|
self._whats_new_message: WhatsNewMessage | None = None
|
|
291
|
+
self._admiral = None # type: ignore[var-annotated]
|
|
291
292
|
self._cached_messages_area: Widget | None = None
|
|
292
293
|
self._cached_chat: ChatScroll | None = None
|
|
293
294
|
self._cached_loading_area: Widget | None = None
|
|
@@ -353,6 +354,14 @@ class VibeApp(App): # noqa: PLR0904
|
|
|
353
354
|
self.agent_loop.set_user_input_callback(self._user_input_callback)
|
|
354
355
|
self._refresh_profile_widgets()
|
|
355
356
|
|
|
357
|
+
try:
|
|
358
|
+
from drydock.admiral import attach as _admiral_attach
|
|
359
|
+
self._admiral = _admiral_attach(self.agent_loop)
|
|
360
|
+
except Exception as e:
|
|
361
|
+
# Admiral must never prevent the TUI from starting.
|
|
362
|
+
import logging
|
|
363
|
+
logging.getLogger(__name__).warning("Admiral failed to start: %s", e)
|
|
364
|
+
|
|
356
365
|
chat_input_container = self.query_one(ChatInputContainer)
|
|
357
366
|
chat_input_container.focus_input()
|
|
358
367
|
await self._resolve_plan()
|
|
@@ -114,32 +114,63 @@ class StreamingMessageBase(Static):
|
|
|
114
114
|
_INLINE_ENUM_RE = re.compile(r" (?=\d{1,2}\. [A-Z])")
|
|
115
115
|
_INLINE_HEADING_RE = re.compile(r" (?=\*\*[A-Z][A-Za-z ]{1,20}:\*\*)")
|
|
116
116
|
_INLINE_DASH_BULLET_RE = re.compile(r"(?<=[.!?]) (?=- [A-Z])")
|
|
117
|
+
_SENTENCE_BOUNDARY_RE = re.compile(r"(?<=[.!?]) (?=[A-Z])")
|
|
118
|
+
_INLINE_CAPWORD_HEADING_RE = re.compile(
|
|
119
|
+
r"(?<=[.!?]) (?=[A-Z][A-Za-z]{1,15}:\s)"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _sentence_chunks(text: str, group: int = 2) -> str:
|
|
124
|
+
"""Break a long flat string into paragraphs every `group` sentences.
|
|
125
|
+
|
|
126
|
+
Conservative: only fires when there are at least 2 sentences to
|
|
127
|
+
split between. Splits on real sentence boundaries (`. `, `! `, `? `
|
|
128
|
+
followed by a capital).
|
|
129
|
+
"""
|
|
130
|
+
sentences = _SENTENCE_BOUNDARY_RE.split(text)
|
|
131
|
+
if len(sentences) < 2:
|
|
132
|
+
return text
|
|
133
|
+
paragraphs: list[str] = []
|
|
134
|
+
for i in range(0, len(sentences), group):
|
|
135
|
+
paragraphs.append(" ".join(sentences[i:i + group]))
|
|
136
|
+
return "\n\n".join(paragraphs)
|
|
117
137
|
|
|
118
138
|
|
|
119
139
|
def _break_walls_of_text(text: str) -> str:
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
widget renders
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
140
|
+
"""Make flat, low-newline assistant responses readable.
|
|
141
|
+
|
|
142
|
+
Gemma 4 regularly emits responses with zero `\\n` — either a block
|
|
143
|
+
of enumerated items jammed together (`Changes: 1. A 2. B 3. C`) or
|
|
144
|
+
a long paragraph of prose (`I fixed X. The Y class now uses Z.
|
|
145
|
+
All tests pass.`). The Markdown widget renders both as one line.
|
|
146
|
+
|
|
147
|
+
Strategy, applied in order:
|
|
148
|
+
1. Break before inline `**Heading:**` markers.
|
|
149
|
+
2. Break before inline numbered items (` 1. Foo 2. Bar`).
|
|
150
|
+
3. Break before inline `CapWord:` mini-headings (`Changes: ...`).
|
|
151
|
+
4. If still a wall (long + zero newlines), split every 2 sentences
|
|
152
|
+
at real sentence boundaries so readers get paragraph breaks.
|
|
153
|
+
|
|
154
|
+
Conservative guards: nothing fires unless the chunk is >200 chars
|
|
155
|
+
and has fewer than 3 newlines. Short responses and already-
|
|
156
|
+
structured markdown pass through untouched.
|
|
134
157
|
"""
|
|
135
|
-
if not text or
|
|
158
|
+
if not text or len(text) < 200:
|
|
136
159
|
return text
|
|
137
|
-
|
|
138
|
-
if
|
|
160
|
+
nl = text.count("\n")
|
|
161
|
+
if nl >= 3:
|
|
139
162
|
return text
|
|
140
|
-
out =
|
|
141
|
-
out =
|
|
163
|
+
out = _INLINE_HEADING_RE.sub("\n\n", text)
|
|
164
|
+
out = _INLINE_ENUM_RE.sub("\n", out)
|
|
142
165
|
out = _INLINE_DASH_BULLET_RE.sub("\n", out)
|
|
166
|
+
out = _INLINE_CAPWORD_HEADING_RE.sub("\n\n", out)
|
|
167
|
+
# If inline markers didn't produce any breaks AND the text is long
|
|
168
|
+
# enough that one paragraph hurts readability, split at sentence
|
|
169
|
+
# boundaries. group=1 = each sentence on its own paragraph (most
|
|
170
|
+
# aggressive — user-requested in issue #8 reopen). Threshold is
|
|
171
|
+
# 250 so medium-length responses also get paragraphs.
|
|
172
|
+
if "\n" not in out and len(out) > 250:
|
|
173
|
+
out = _sentence_chunks(out, group=1)
|
|
143
174
|
return out
|
|
144
175
|
|
|
145
176
|
|
|
@@ -166,10 +197,9 @@ def _preserve_line_breaks(text: str) -> str:
|
|
|
166
197
|
"""
|
|
167
198
|
if not text:
|
|
168
199
|
return text
|
|
169
|
-
# First pass:
|
|
170
|
-
# inline
|
|
171
|
-
|
|
172
|
-
text = _break_walls_of_text(text)
|
|
200
|
+
# First pass: rescue wall-of-text responses (flat prose, inline
|
|
201
|
+
# enumerations, inline bold headings). See _break_walls_of_text.
|
|
202
|
+
text = _break_walls_of_text(text)
|
|
173
203
|
out: list[str] = []
|
|
174
204
|
in_fence = False
|
|
175
205
|
lines = text.split("\n")
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Unit tests for Admiral's Phase 1 detectors."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from drydock.admiral.detectors import detect_struggle, detect_tool_call_loop, run_all
|
|
5
|
+
from drydock.core.types import FunctionCall, LLMMessage, Role, ToolCall
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _assistant(tool: str, args: str = "{}") -> LLMMessage:
|
|
9
|
+
return LLMMessage(
|
|
10
|
+
role=Role.assistant,
|
|
11
|
+
content="",
|
|
12
|
+
tool_calls=[ToolCall(function=FunctionCall(name=tool, arguments=args))],
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_loop_fires_on_three_identical_tool_calls() -> None:
|
|
17
|
+
msgs = [
|
|
18
|
+
LLMMessage(role=Role.user, content="go"),
|
|
19
|
+
_assistant("read_file", '{"path":"x.py"}'),
|
|
20
|
+
LLMMessage(role=Role.tool, content="result"),
|
|
21
|
+
_assistant("read_file", '{"path":"x.py"}'),
|
|
22
|
+
LLMMessage(role=Role.tool, content="result"),
|
|
23
|
+
_assistant("read_file", '{"path":"x.py"}'),
|
|
24
|
+
LLMMessage(role=Role.tool, content="result"),
|
|
25
|
+
]
|
|
26
|
+
f = detect_tool_call_loop(msgs)
|
|
27
|
+
assert f is not None
|
|
28
|
+
assert "Admiral" in f.directive
|
|
29
|
+
assert f.code.startswith("loop:")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_loop_no_fire_on_varied_args() -> None:
|
|
33
|
+
msgs = [
|
|
34
|
+
_assistant("read_file", '{"path":"x.py"}'),
|
|
35
|
+
LLMMessage(role=Role.tool, content="r"),
|
|
36
|
+
_assistant("read_file", '{"path":"y.py"}'),
|
|
37
|
+
LLMMessage(role=Role.tool, content="r"),
|
|
38
|
+
_assistant("read_file", '{"path":"z.py"}'),
|
|
39
|
+
LLMMessage(role=Role.tool, content="r"),
|
|
40
|
+
]
|
|
41
|
+
assert detect_tool_call_loop(msgs) is None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_struggle_fires_after_many_reads_without_write() -> None:
|
|
45
|
+
msgs: list[LLMMessage] = [LLMMessage(role=Role.user, content="build it")]
|
|
46
|
+
for i in range(25):
|
|
47
|
+
msgs.append(_assistant("read_file", f'{{"path":"f{i}.py"}}'))
|
|
48
|
+
msgs.append(LLMMessage(role=Role.tool, content="..."))
|
|
49
|
+
f = detect_struggle(msgs)
|
|
50
|
+
assert f is not None
|
|
51
|
+
assert "without writing" in f.directive
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_struggle_resets_on_write() -> None:
|
|
55
|
+
msgs: list[LLMMessage] = []
|
|
56
|
+
for i in range(15):
|
|
57
|
+
msgs.append(_assistant("read_file", f'{{"path":"f{i}.py"}}'))
|
|
58
|
+
msgs.append(LLMMessage(role=Role.tool, content="..."))
|
|
59
|
+
msgs.append(_assistant("write_file", '{"path":"new.py","content":"x"}'))
|
|
60
|
+
msgs.append(LLMMessage(role=Role.tool, content="ok"))
|
|
61
|
+
for i in range(3):
|
|
62
|
+
msgs.append(_assistant("read_file", f'{{"path":"check{i}.py"}}'))
|
|
63
|
+
msgs.append(LLMMessage(role=Role.tool, content="..."))
|
|
64
|
+
assert detect_struggle(msgs) is None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_run_all_returns_multiple_findings() -> None:
|
|
68
|
+
msgs: list[LLMMessage] = []
|
|
69
|
+
for i in range(25):
|
|
70
|
+
msgs.append(_assistant("read_file", '{"path":"x.py"}')) # same args -> loop
|
|
71
|
+
msgs.append(LLMMessage(role=Role.tool, content="..."))
|
|
72
|
+
findings = run_all(msgs)
|
|
73
|
+
codes = {f.code.split(":")[0] for f in findings}
|
|
74
|
+
assert "loop" in codes
|
|
75
|
+
assert "struggle" in codes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|