drydock-cli 2.8.12__tar.gz → 2.8.14__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.8.14/.auto_release.lock +1 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/PKG-INFO +1 -1
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/detectors_proposed.py +29 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/worker.py +57 -2
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/agent_loop.py +6 -3
- drydock_cli-2.8.14/outlook_draft_assistant.tar.gz +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/pyproject.toml +1 -1
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/hle_eval.py +30 -1
- drydock_cli-2.8.14/tests/test_admiral_hallucinated_tool_filter.py +89 -0
- drydock_cli-2.8.14/tests/test_admiral_intervention_outcome.py +155 -0
- drydock_cli-2.8.14/tests/test_admiral_session_id.py +95 -0
- drydock_cli-2.8.14/tests/test_hle_typing.py +90 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/trip_log.md +216 -0
- drydock_cli-2.8.12/.auto_release.lock +0 -1
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.gitignore +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.python-version +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.typos.toml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.vscode/extensions.json +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.vscode/launch.json +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/.vscode/settings.json +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/AGENTS.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/Admiral.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/CHANGELOG.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/CLAUDE.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/DEEP_NOIR_PRD.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/DEPLOYMENT.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/HLE_PRD.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/JETSON_BENCH.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/LICENSE +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/NOTICE +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/README.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/SOVEREIGN_PRD.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/TRIAGE_v1.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/action.yml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/README.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/README.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/acp-setup.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/BASELINE_412.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/Drydock_rebrand.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/OVERNIGHT_PROGRESS.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/PERF_SWEEP_PLAN.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/PRD.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/drydock_terms.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/archive/resume.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/__main__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/detectors.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/history.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/interventions.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/llm_analyzer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/metrics.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/opus_escalator.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/persistence.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/policy.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/proposer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/stager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/task_classifier.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/tuning.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/admiral/validator.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/fix_windows_path.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/classifier/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/classifier/__main__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/classifier/classifier.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/classifier/dispatcher.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/classifier/rules.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/classifier/signal.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/_dotenv.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/local_detect.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/config/migrate.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/context_recovery.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/logger.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/paths/_drydock_home.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/slug.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/steering_hook.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/retrieve.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/retrieve.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/types.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/core/utils.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/graphrag/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/graphrag/__main__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/graphrag/code_indexer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/graphrag/retriever.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/graphrag/storage.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/graphrag/text_indexer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/screens/choice.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/screens/local_model.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/__main__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/applier.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/config.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/registry.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/sandbox.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/sidecar/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/sidecar/header_parser.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/sidecar/hooks.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/sidecar/loader.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/sidecar/server.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/train/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/train/capture.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/train/compute_vector.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/train/extract_pairs.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/steering/vectors.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock/whats_new.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/drydock-acp.spec +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/flake.lock +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/flake.nix +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/README.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/config_base.toml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/config_best.toml +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/domain_spec.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/experimenter.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/kernel.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/mini_prd.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/mini_prompts.txt +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/proposer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/research/results.tsv +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/README.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/admiral_probe.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/archive/auto_test_loop.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/archive/monitor_test_battery.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/archive/overnight_agents_test.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/archive/test_bank.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/archive/test_full.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/archive/test_smoke.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/archive/tui_test.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/autonomous_review.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/autonomous_review_prompt.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/backup.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/bump_version.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/classify_pulse.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/consume_retrieval_queue.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/fetch_arxiv_abstracts.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/hle_eval_seed.jsonl +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/notify_release.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/perf_baseline_when_idle.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/perf_sweep.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/poll_issues.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/queue_top.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/research_babysitter.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/shakedown.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/start_steering_sidecar.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_babysitter.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_prompts_realuser.txt +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/stress_watcher.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/test_generic_adapter_sanitize.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/conftest.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_circuit_breaker_count_escalation.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/e2e/common.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/mock/utils.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/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.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_admiral.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_admiral_phase3.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_admiral_proposed.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_admiral_struggle_dedup.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_agents.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_classifier.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_config_migration.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_context_recovery.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_dispatcher.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_fake_tool_call_paren_syntax.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_graphrag.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_hallucinated_tool_suppression.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_integration.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_issue_fixes.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_local_detect.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_message_id.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_middleware.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_read_file_not_found_listing.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_retrieval_consumer.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_retrieve_tool.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_search_replace_args_not_truncated.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_smoke.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_steering.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_steering_capture.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_steering_compute_vector.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_steering_extract_pairs.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_steering_hook.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_steering_sidecar_hooks.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_task_complete_nudge.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_truncate_args_valid_json.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_truncated_arg_path_hint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_truncated_search_replace_escalation.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_truncated_write_escalation.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_wall_of_text_rescue.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_workloads.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/test_write_file_missing_path.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_binary_grep_hint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_consec_empty_search.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_empty_search_loop_breaker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_error_loop_breaker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_exact_cmd_loop_breaker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_heredoc_confirmation.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_kill_exit1_annotation.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_hallucinated_retrieval_redirect.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_manager_gemma_derived_models.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_read_file_dedup_alternating_offset.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_read_file_dedup_reembed.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_read_file_directory.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_read_file_limit_truncation.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_append_fallback.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_dir_path.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_empty_content.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_file_not_found.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_first_failure_hint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_hard_stop.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_malformed_block.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_placeholder.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/tools/test_write_file_missing_path_hint.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/uv.lock +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/worked_examples/README.md +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.8.12 → drydock_cli-2.8.14}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
411933
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.14
|
|
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
|
|
@@ -58,6 +58,24 @@ def _tool_result_errored(m: LLMMessage) -> bool:
|
|
|
58
58
|
return any(marker in content for marker in _TOOL_ERROR_MARKERS)
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
def _is_hallucinated_tool_result(m: LLMMessage) -> bool:
|
|
62
|
+
"""A hallucinated-tool result has the format produced by
|
|
63
|
+
`_silence_suppressed_failures` in agent_loop.py: the content is
|
|
64
|
+
wrapped in `<tool_error>...</tool_error>` and includes the redirect
|
|
65
|
+
string "does not exist". When we see this, we know:
|
|
66
|
+
- the model invented a tool name (ralph_repo_index, exit_plan_mode, ...)
|
|
67
|
+
- format.py routed it to suppressed_failures + redirect message
|
|
68
|
+
- drydock injected a system note pointing at real tools
|
|
69
|
+
The empty turn that follows is a *different* failure mode than
|
|
70
|
+
empty-after-real-tool — the recovery is already wired and the
|
|
71
|
+
fire just adds noise to admiral_state.
|
|
72
|
+
"""
|
|
73
|
+
if m.role is not Role.tool:
|
|
74
|
+
return False
|
|
75
|
+
raw = str(getattr(m, "content", "") or "")
|
|
76
|
+
return "<tool_error>" in raw and "does not exist" in raw
|
|
77
|
+
|
|
78
|
+
|
|
61
79
|
def detect_empty_after_tool(
|
|
62
80
|
messages: Sequence[LLMMessage],
|
|
63
81
|
) -> Optional[Finding]:
|
|
@@ -69,6 +87,13 @@ def detect_empty_after_tool(
|
|
|
69
87
|
"Previous turn ended; awaiting your next instruction." — a user-facing
|
|
70
88
|
sign that the model's thinking channel produced nothing usable.
|
|
71
89
|
|
|
90
|
+
Hallucinated-tool results (e.g. `ralph_repo_index`) are EXCLUDED:
|
|
91
|
+
`_silence_suppressed_failures` already injects a system note redirecting
|
|
92
|
+
the model to real tools, and the empty turn that follows is a separate
|
|
93
|
+
failure mode whose recovery is wired elsewhere. Pre-filter, this code
|
|
94
|
+
fired 318 times against `ralph_repo_index` alone — drowning out the
|
|
95
|
+
real signal (`empty_after_tool:bash` at 150 fires).
|
|
96
|
+
|
|
72
97
|
Admiral intervention should:
|
|
73
98
|
(a) inject a directive asking the model to summarize the tool output
|
|
74
99
|
and commit to a next action, and
|
|
@@ -91,6 +116,10 @@ def detect_empty_after_tool(
|
|
|
91
116
|
if prev.role is not Role.tool:
|
|
92
117
|
return None
|
|
93
118
|
|
|
119
|
+
# Skip hallucinated-tool results: separate failure mode, separate fix.
|
|
120
|
+
if _is_hallucinated_tool_result(prev):
|
|
121
|
+
return None
|
|
122
|
+
|
|
94
123
|
# Two ways this fires:
|
|
95
124
|
# (1) Live: the assistant returned neither content nor tool_calls. Admiral
|
|
96
125
|
# sees this BEFORE drydock's _ensure_assistant_after_tools appends
|
|
@@ -30,6 +30,12 @@ POLL_INTERVAL_SEC = 5.0
|
|
|
30
30
|
DEDUP_WINDOW_SEC = 60.0
|
|
31
31
|
MAX_OPUS_PER_SESSION = opus_escalator.MAX_ESCALATIONS_PER_SESSION
|
|
32
32
|
|
|
33
|
+
# Intervention-outcome window: per persistence.py docstring, "same code
|
|
34
|
+
# re-firing within 10 turns after an intervention = failed." A turn is
|
|
35
|
+
# one assistant message; we count messages (any role) as a proxy because
|
|
36
|
+
# a re-fire necessarily comes after at least 1 assistant turn.
|
|
37
|
+
INTERVENTION_FAIL_WINDOW_TURNS = 10
|
|
38
|
+
|
|
33
39
|
|
|
34
40
|
class AdmiralWorker:
|
|
35
41
|
"""Async task that supervises one AgentLoop.
|
|
@@ -45,6 +51,10 @@ class AdmiralWorker:
|
|
|
45
51
|
self._recent_findings: dict[str, float] = {} # code -> timestamp
|
|
46
52
|
self._opus_calls_used: int = 0
|
|
47
53
|
self._in_flight: set[str] = set() # codes currently being escalated
|
|
54
|
+
# Pending interventions awaiting outcome classification.
|
|
55
|
+
# code -> message-count at apply time. On re-fire within
|
|
56
|
+
# INTERVENTION_FAIL_WINDOW_TURNS messages → failed; otherwise → unstuck.
|
|
57
|
+
self._pending_interventions: dict[str, int] = {}
|
|
48
58
|
|
|
49
59
|
def start(self) -> None:
|
|
50
60
|
if self._task is not None and not self._task.done():
|
|
@@ -79,8 +89,21 @@ class AdmiralWorker:
|
|
|
79
89
|
code: ts for code, ts in self._recent_findings.items()
|
|
80
90
|
if now - ts < DEDUP_WINDOW_SEC
|
|
81
91
|
}
|
|
92
|
+
|
|
93
|
+
# Resolve any pending interventions whose fail-window has elapsed
|
|
94
|
+
# without a re-fire — those count as `unstuck=True`.
|
|
95
|
+
msg_count_now = len(self.agent_loop.messages)
|
|
96
|
+
self._resolve_elapsed_interventions(msg_count_now)
|
|
97
|
+
|
|
82
98
|
findings = detectors.run_all(list(self.agent_loop.messages))
|
|
83
99
|
for f in findings:
|
|
100
|
+
# Re-fire while a prior intervention is still inside its
|
|
101
|
+
# fail window → that intervention failed.
|
|
102
|
+
applied_at = self._pending_interventions.get(f.code)
|
|
103
|
+
if applied_at is not None and (msg_count_now - applied_at) <= INTERVENTION_FAIL_WINDOW_TURNS:
|
|
104
|
+
self._record_outcome(f.code, unstuck=False)
|
|
105
|
+
self._pending_interventions.pop(f.code, None)
|
|
106
|
+
|
|
84
107
|
last = self._recent_findings.get(f.code)
|
|
85
108
|
if last is not None and (now - last) < DEDUP_WINDOW_SEC:
|
|
86
109
|
continue
|
|
@@ -92,6 +115,29 @@ class AdmiralWorker:
|
|
|
92
115
|
self._handle_finding(f), name=f"admiral-handle:{f.code[:32]}"
|
|
93
116
|
)
|
|
94
117
|
|
|
118
|
+
def _resolve_elapsed_interventions(self, msg_count_now: int) -> None:
|
|
119
|
+
"""Mark interventions as `unstuck=True` if their fail window
|
|
120
|
+
elapsed without the same code re-firing."""
|
|
121
|
+
elapsed: list[str] = []
|
|
122
|
+
for code, applied_at in self._pending_interventions.items():
|
|
123
|
+
if (msg_count_now - applied_at) > INTERVENTION_FAIL_WINDOW_TURNS:
|
|
124
|
+
elapsed.append(code)
|
|
125
|
+
for code in elapsed:
|
|
126
|
+
self._record_outcome(code, unstuck=True)
|
|
127
|
+
self._pending_interventions.pop(code, None)
|
|
128
|
+
|
|
129
|
+
def _record_outcome(self, code: str, *, unstuck: bool) -> None:
|
|
130
|
+
"""Persist the intervention outcome — never raise (Admiral must
|
|
131
|
+
not crash drydock). Logs both outcomes to history for visibility."""
|
|
132
|
+
try:
|
|
133
|
+
persistence.record_intervention_outcome(code, unstuck=unstuck)
|
|
134
|
+
history.append(
|
|
135
|
+
"intervention-outcome",
|
|
136
|
+
f"{code} :: {'unstuck' if unstuck else 'failed'}",
|
|
137
|
+
)
|
|
138
|
+
except Exception as e:
|
|
139
|
+
logger.debug("record_intervention_outcome failed: %s", e)
|
|
140
|
+
|
|
95
141
|
async def _handle_finding(self, finding: Finding) -> None:
|
|
96
142
|
"""Escalation ladder: local LLM → Opus → canned directive.
|
|
97
143
|
|
|
@@ -101,8 +147,12 @@ class AdmiralWorker:
|
|
|
101
147
|
proposal in the background.
|
|
102
148
|
"""
|
|
103
149
|
try:
|
|
104
|
-
# Record for Phase 3b promotion criteria.
|
|
105
|
-
session_id
|
|
150
|
+
# Record for Phase 3b promotion criteria. Use the live
|
|
151
|
+
# `session_id` (matches the on-disk session log dir) so
|
|
152
|
+
# M5/Deep Noir can extract contrastive pairs from the dir.
|
|
153
|
+
# Pre-fix this read `_admiral_session_id`, a phantom uuid
|
|
154
|
+
# that never resolved to anything on disk.
|
|
155
|
+
session_id = getattr(self.agent_loop, "session_id", "")
|
|
106
156
|
persistence.record_finding(finding.code, session_id)
|
|
107
157
|
|
|
108
158
|
directive, source = await self._resolve_directive(finding)
|
|
@@ -113,6 +163,11 @@ class AdmiralWorker:
|
|
|
113
163
|
finding_with_text = type(finding)(code=finding.code, directive=directive)
|
|
114
164
|
interventions.apply(self.agent_loop, finding_with_text)
|
|
115
165
|
|
|
166
|
+
# Watch for re-fires within the fail window to classify this
|
|
167
|
+
# intervention's outcome. Without this, prompt_failed stays at
|
|
168
|
+
# 0 forever and Phase 3b promotion criteria never trigger.
|
|
169
|
+
self._pending_interventions[finding.code] = len(self.agent_loop.messages)
|
|
170
|
+
|
|
116
171
|
# Phase 3b: if same finding qualifies and proposer is enabled,
|
|
117
172
|
# kick off a code-proposal draft in the background.
|
|
118
173
|
if persistence.finding_qualifies_for_code_change(finding.code):
|
|
@@ -278,13 +278,16 @@ class AgentLoop:
|
|
|
278
278
|
logger.debug("Admiral tuning apply failed: %s", _e)
|
|
279
279
|
|
|
280
280
|
# Admiral Phase 3a: record session metrics on interpreter exit.
|
|
281
|
+
# Use the live `session_id` (set above and matching the on-disk
|
|
282
|
+
# session dir) — NOT a fresh uuid. Findings recorded against a
|
|
283
|
+
# phantom uuid never resolved to a session log, so M5's offline
|
|
284
|
+
# Deep Noir loop couldn't extract pairs from them.
|
|
281
285
|
try:
|
|
282
|
-
import atexit
|
|
286
|
+
import atexit
|
|
283
287
|
from drydock.admiral import metrics as _admiral_metrics
|
|
284
|
-
self._admiral_session_id = str(_uuid.uuid4())
|
|
285
288
|
atexit.register(
|
|
286
289
|
lambda al=self: _admiral_metrics.record(
|
|
287
|
-
_admiral_metrics.collect(al, al.
|
|
290
|
+
_admiral_metrics.collect(al, al.session_id, outcome="unknown")
|
|
288
291
|
)
|
|
289
292
|
)
|
|
290
293
|
except Exception as _e:
|
|
Binary file
|
|
@@ -249,6 +249,35 @@ def _question_prompt(q: dict) -> str:
|
|
|
249
249
|
)
|
|
250
250
|
|
|
251
251
|
|
|
252
|
+
def _send_prompt_as_paste(child, text: str) -> None:
|
|
253
|
+
"""Send a one-shot prompt to the TUI as a bracketed paste, then Enter.
|
|
254
|
+
|
|
255
|
+
Why not `sk.type_message`: it sends char-by-char at 10ms/char, which
|
|
256
|
+
on a ~1500-char HLE prompt takes ~15s and races the Textual input
|
|
257
|
+
handler. In real captured sessions we observed 13 stray `\\n` chars
|
|
258
|
+
injected mid-word (`'Answer th\\n\\n...\\n\\nis question'`) — the
|
|
259
|
+
model then reads garbage and either bails or grinds in tool-call
|
|
260
|
+
loops without ever emitting `FINAL ANSWER:`. Bracketed paste
|
|
261
|
+
(xterm convention also recognised by Textual >=0.40) tells the
|
|
262
|
+
receiving widget "this is a single literal block — do not interpret
|
|
263
|
+
embedded chars as keypresses or trigger paste-detection logic."
|
|
264
|
+
|
|
265
|
+
Sequence:
|
|
266
|
+
ESC [ 2 0 0 ~ <text-with-newlines-stripped> ESC [ 2 0 1 ~ <Enter>
|
|
267
|
+
|
|
268
|
+
Newlines inside the prompt are stripped because Textual's Input
|
|
269
|
+
widget commits on Enter regardless of paste markers. HLE prompts
|
|
270
|
+
are a single line by construction (`_question_prompt`), so this is
|
|
271
|
+
a no-op for the supported case.
|
|
272
|
+
"""
|
|
273
|
+
safe_text = text.replace("\r", " ").replace("\n", " ")
|
|
274
|
+
PASTE_START = "\x1b[200~"
|
|
275
|
+
PASTE_END = "\x1b[201~"
|
|
276
|
+
child.send(PASTE_START + safe_text + PASTE_END)
|
|
277
|
+
time.sleep(0.3) # let the widget commit the paste
|
|
278
|
+
child.send("\r")
|
|
279
|
+
|
|
280
|
+
|
|
252
281
|
def _extract_answer(messages: list[dict]) -> str:
|
|
253
282
|
"""Pull the FINAL ANSWER line out of the last assistant message that
|
|
254
283
|
has text content. Falls back to the full last assistant content if no
|
|
@@ -306,7 +335,7 @@ def run_one(q: dict, sk, run_dir: Path) -> dict:
|
|
|
306
335
|
pass
|
|
307
336
|
|
|
308
337
|
watcher = sk.SessionWatcher(cwd, since=start)
|
|
309
|
-
|
|
338
|
+
_send_prompt_as_paste(child, _question_prompt(q))
|
|
310
339
|
time.sleep(1)
|
|
311
340
|
|
|
312
341
|
# Wait for session dir to appear
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Regression: detect_empty_after_tool must skip hallucinated-tool results.
|
|
2
|
+
|
|
3
|
+
Pre-filter, `empty_after_tool:ralph_repo_index` was the highest-fire
|
|
4
|
+
finding in admiral_state (318 fires, 164 sessions) — out-volume-ing
|
|
5
|
+
real signals like `empty_after_tool:bash` (150 fires, 85 sessions).
|
|
6
|
+
|
|
7
|
+
The hallucinated-tool path already has its own recovery wired
|
|
8
|
+
(`_silence_suppressed_failures` in agent_loop.py injects a system note
|
|
9
|
+
that redirects the model to real tools). The empty turn that follows
|
|
10
|
+
is a *different* failure mode and conflating it with real-tool empty
|
|
11
|
+
stalls confused both admiral analytics and the Phase 3b proposer.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from drydock.admiral.detectors_proposed import detect_empty_after_tool
|
|
16
|
+
from drydock.core.types import LLMMessage, Role
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _user(text: str) -> LLMMessage:
|
|
20
|
+
return LLMMessage(role=Role.user, content=text)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _assistant_empty() -> LLMMessage:
|
|
24
|
+
return LLMMessage(role=Role.assistant, content="", tool_calls=[])
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _tool_result(name: str, content: str) -> LLMMessage:
|
|
28
|
+
m = LLMMessage(role=Role.tool, content=content)
|
|
29
|
+
m.name = name # detect_empty_after_tool reads getattr(prev, "name", "")
|
|
30
|
+
return m
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_empty_after_real_tool_still_fires() -> None:
|
|
34
|
+
"""The detector must still fire on legitimate empty-after-real-tool stalls."""
|
|
35
|
+
msgs = [
|
|
36
|
+
_user("read the config"),
|
|
37
|
+
_tool_result("read_file", "the contents of config.toml"),
|
|
38
|
+
_assistant_empty(),
|
|
39
|
+
]
|
|
40
|
+
f = detect_empty_after_tool(msgs)
|
|
41
|
+
assert f is not None
|
|
42
|
+
assert f.code == "empty_after_tool:read_file"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_empty_after_hallucinated_tool_is_filtered() -> None:
|
|
46
|
+
"""`<tool_error>...does not exist...</tool_error>` content marks a
|
|
47
|
+
hallucinated-tool result. Empty turn after it must NOT fire — the
|
|
48
|
+
system-note recovery handles this case."""
|
|
49
|
+
halluc_content = (
|
|
50
|
+
"<tool_error>ralph_repo_index: 'ralph_repo_index' does not exist "
|
|
51
|
+
"— do not call it again. To list project files: call glob...</tool_error>"
|
|
52
|
+
)
|
|
53
|
+
msgs = [
|
|
54
|
+
_user("explore the repo"),
|
|
55
|
+
_tool_result("ralph_repo_index", halluc_content),
|
|
56
|
+
_assistant_empty(),
|
|
57
|
+
]
|
|
58
|
+
f = detect_empty_after_tool(msgs)
|
|
59
|
+
assert f is None, (
|
|
60
|
+
f"Hallucinated-tool empty turn should NOT fire; got {f.code if f else None}"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_empty_after_other_hallucinated_names_filtered() -> None:
|
|
65
|
+
"""Same filter applies regardless of hallucinated tool name (
|
|
66
|
+
exit_plan_mode, lsp, etc.)."""
|
|
67
|
+
for name in ("exit_plan_mode", "lsp", "ralph_file_summary", "list_mcp_resources"):
|
|
68
|
+
content = f"<tool_error>{name}: '{name}' does not exist — stop calling it.</tool_error>"
|
|
69
|
+
msgs = [
|
|
70
|
+
_user("go"),
|
|
71
|
+
_tool_result(name, content),
|
|
72
|
+
_assistant_empty(),
|
|
73
|
+
]
|
|
74
|
+
f = detect_empty_after_tool(msgs)
|
|
75
|
+
assert f is None, f"Should be filtered for hallucinated tool {name!r}; got {f.code if f else None}"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_real_tool_with_error_still_fires() -> None:
|
|
79
|
+
"""A real tool that errored normally (not via hallucination suppression)
|
|
80
|
+
should still fire — the marker is the specific
|
|
81
|
+
`<tool_error>...does not exist` shape, not just any error."""
|
|
82
|
+
msgs = [
|
|
83
|
+
_user("read it"),
|
|
84
|
+
_tool_result("read_file", "Error: file not found at /tmp/missing.py"),
|
|
85
|
+
_assistant_empty(),
|
|
86
|
+
]
|
|
87
|
+
f = detect_empty_after_tool(msgs)
|
|
88
|
+
assert f is not None
|
|
89
|
+
assert f.code == "empty_after_tool:read_file"
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Regression: AdmiralWorker must classify each intervention's outcome
|
|
2
|
+
(unstuck vs. failed) and persist it via `record_intervention_outcome`.
|
|
3
|
+
|
|
4
|
+
Pre-fix, `record_intervention_outcome` was defined in persistence.py
|
|
5
|
+
and unit-tested but had ZERO production call sites. Result:
|
|
6
|
+
`prompt_failed` stayed at 0 forever, so
|
|
7
|
+
`finding_qualifies_for_code_change` (which requires prompt_failed >= 1)
|
|
8
|
+
never returned True. The whole Phase 3b proposer pipeline was silently
|
|
9
|
+
dormant — 1010 admiral findings accumulated, 0 ever qualified.
|
|
10
|
+
|
|
11
|
+
Post-fix, the worker tracks `_pending_interventions[code] = msg_count`
|
|
12
|
+
at apply time. On _tick:
|
|
13
|
+
- If the same code re-fires within INTERVENTION_FAIL_WINDOW_TURNS
|
|
14
|
+
messages → record `unstuck=False`
|
|
15
|
+
- If the window elapses without a re-fire → record `unstuck=True`
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import asyncio
|
|
20
|
+
import inspect
|
|
21
|
+
from dataclasses import dataclass, field
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
import pytest
|
|
25
|
+
|
|
26
|
+
from drydock.admiral import history, interventions, persistence, worker
|
|
27
|
+
from drydock.admiral.detectors import Finding
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class _StubAgentLoop:
|
|
32
|
+
session_id: str = "sess-test"
|
|
33
|
+
# Mutable list so tests can grow it to simulate turns passing.
|
|
34
|
+
messages: list = field(default_factory=list)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.fixture
|
|
38
|
+
def patched_world(monkeypatch):
|
|
39
|
+
"""Stub out persistence + history so we can observe outcome calls
|
|
40
|
+
without touching disk."""
|
|
41
|
+
captured = {"outcomes": [], "findings": []}
|
|
42
|
+
|
|
43
|
+
monkeypatch.setattr(
|
|
44
|
+
persistence, "record_finding",
|
|
45
|
+
lambda code, sid: captured["findings"].append((code, sid)) or {
|
|
46
|
+
"sessions": [sid], "total_fires": 1, "last_seen": "now"
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
monkeypatch.setattr(
|
|
50
|
+
persistence, "record_intervention_outcome",
|
|
51
|
+
lambda code, unstuck: captured["outcomes"].append((code, unstuck)),
|
|
52
|
+
)
|
|
53
|
+
monkeypatch.setattr(
|
|
54
|
+
persistence, "finding_qualifies_for_code_change",
|
|
55
|
+
lambda code, **kw: False,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
async def _stub_resolve(self, finding):
|
|
59
|
+
return finding.directive, "canned"
|
|
60
|
+
|
|
61
|
+
monkeypatch.setattr(worker.AdmiralWorker, "_resolve_directive", _stub_resolve)
|
|
62
|
+
monkeypatch.setattr(history, "append", lambda *a, **kw: None)
|
|
63
|
+
monkeypatch.setattr(interventions, "apply", lambda agent, finding: None)
|
|
64
|
+
return captured
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _drain_pending(w: worker.AdmiralWorker):
|
|
68
|
+
"""Trigger any awaited tasks in the running loop."""
|
|
69
|
+
pass # asyncio.run handles this for us
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_intervention_marked_failed_on_refire(patched_world):
|
|
73
|
+
"""Re-fire within the fail window → record outcome unstuck=False."""
|
|
74
|
+
al = _StubAgentLoop(messages=[1, 2, 3, 4, 5]) # 5 messages at apply
|
|
75
|
+
w = worker.AdmiralWorker(al)
|
|
76
|
+
|
|
77
|
+
# Apply intervention via the public path
|
|
78
|
+
finding = Finding(code="loop:read_file", directive="stop")
|
|
79
|
+
asyncio.run(w._handle_finding(finding))
|
|
80
|
+
|
|
81
|
+
# Worker recorded the apply-time message count
|
|
82
|
+
assert w._pending_interventions == {"loop:read_file": 5}
|
|
83
|
+
|
|
84
|
+
# Simulate 3 more messages, then the same finding fires again via _tick.
|
|
85
|
+
al.messages.extend([6, 7, 8])
|
|
86
|
+
|
|
87
|
+
# Patch detectors to return our re-fire and stub create_task (the
|
|
88
|
+
# outcome-record path runs inline in _tick, before create_task).
|
|
89
|
+
import drydock.admiral.worker as wmod
|
|
90
|
+
original_run_all = wmod.detectors.run_all
|
|
91
|
+
original_create = wmod.asyncio.create_task
|
|
92
|
+
wmod.detectors.run_all = lambda msgs: [Finding(code="loop:read_file", directive="stop")]
|
|
93
|
+
wmod.asyncio.create_task = lambda coro, **kw: coro.close() or None
|
|
94
|
+
try:
|
|
95
|
+
# Bypass dedup so the re-fire is observed
|
|
96
|
+
w._recent_findings.clear()
|
|
97
|
+
w._tick()
|
|
98
|
+
finally:
|
|
99
|
+
wmod.detectors.run_all = original_run_all
|
|
100
|
+
wmod.asyncio.create_task = original_create
|
|
101
|
+
|
|
102
|
+
assert ("loop:read_file", False) in patched_world["outcomes"], (
|
|
103
|
+
"Expected `unstuck=False` outcome on re-fire within window"
|
|
104
|
+
)
|
|
105
|
+
# Pending entry must be cleared so we don't double-record
|
|
106
|
+
assert "loop:read_file" not in w._pending_interventions
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_intervention_marked_unstuck_when_window_elapses(patched_world):
|
|
110
|
+
"""No re-fire within window → record outcome unstuck=True."""
|
|
111
|
+
al = _StubAgentLoop(messages=list(range(5)))
|
|
112
|
+
w = worker.AdmiralWorker(al)
|
|
113
|
+
|
|
114
|
+
finding = Finding(code="empty_after_tool:bash", directive="continue")
|
|
115
|
+
asyncio.run(w._handle_finding(finding))
|
|
116
|
+
assert "empty_after_tool:bash" in w._pending_interventions
|
|
117
|
+
|
|
118
|
+
# Push past the fail window (10 turns) without any re-fires
|
|
119
|
+
al.messages.extend(list(range(20))) # 25 total, delta 20 > 10
|
|
120
|
+
|
|
121
|
+
import drydock.admiral.worker as wmod
|
|
122
|
+
original = wmod.detectors.run_all
|
|
123
|
+
wmod.detectors.run_all = lambda msgs: [] # no findings this tick
|
|
124
|
+
try:
|
|
125
|
+
w._tick()
|
|
126
|
+
finally:
|
|
127
|
+
wmod.detectors.run_all = original
|
|
128
|
+
|
|
129
|
+
assert ("empty_after_tool:bash", True) in patched_world["outcomes"], (
|
|
130
|
+
"Expected `unstuck=True` outcome after window elapsed without re-fire"
|
|
131
|
+
)
|
|
132
|
+
assert "empty_after_tool:bash" not in w._pending_interventions
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def test_intervention_outcome_persistence_swallows_errors(patched_world, monkeypatch):
|
|
136
|
+
"""Persistence failure must NOT crash Admiral (rule: Admiral never
|
|
137
|
+
takes drydock down)."""
|
|
138
|
+
def boom(code, unstuck):
|
|
139
|
+
raise RuntimeError("disk full")
|
|
140
|
+
monkeypatch.setattr(persistence, "record_intervention_outcome", boom)
|
|
141
|
+
|
|
142
|
+
w = worker.AdmiralWorker(_StubAgentLoop())
|
|
143
|
+
# Should not raise
|
|
144
|
+
w._record_outcome("loop:foo", unstuck=True)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_record_intervention_outcome_has_production_callsite():
|
|
148
|
+
"""Belt-and-suspenders: catch a future revert that would re-orphan
|
|
149
|
+
this function. Only worker.py + tests should reference it."""
|
|
150
|
+
src = inspect.getsource(worker)
|
|
151
|
+
assert "record_intervention_outcome" in src, (
|
|
152
|
+
"AdmiralWorker no longer wires intervention outcomes to "
|
|
153
|
+
"persistence — Phase 3b promotion criteria will be dormant. "
|
|
154
|
+
"See worker._record_outcome / _resolve_elapsed_interventions."
|
|
155
|
+
)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Regression: Admiral must record findings against the live
|
|
2
|
+
`AgentLoop.session_id` (which matches the on-disk session log dir),
|
|
3
|
+
NOT a fresh phantom uuid.
|
|
4
|
+
|
|
5
|
+
Pre-fix, agent_loop.py:284 set `self._admiral_session_id = uuid4()`
|
|
6
|
+
and worker.py:105 read that attribute. The result was 1010 admiral
|
|
7
|
+
findings keyed to UUIDs that never resolved to any session dir under
|
|
8
|
+
~/.drydock/logs/session/, breaking M5/Deep Noir's pair extraction.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
import inspect
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
19
|
+
from drydock.admiral import history, interventions, llm_analyzer, persistence, worker
|
|
20
|
+
from drydock.admiral.detectors import Finding
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class _StubAgentLoop:
|
|
25
|
+
"""Minimal stand-in for AgentLoop — only the attrs the worker reads."""
|
|
26
|
+
session_id: str = "real-session-abc-123"
|
|
27
|
+
messages: tuple = ()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_worker_records_finding_with_live_session_id(monkeypatch):
|
|
31
|
+
"""When _handle_finding fires, persistence.record_finding must
|
|
32
|
+
receive the agent_loop's `session_id` — not a fresh uuid, not "".
|
|
33
|
+
"""
|
|
34
|
+
captured: list[tuple[str, str]] = []
|
|
35
|
+
|
|
36
|
+
monkeypatch.setattr(
|
|
37
|
+
persistence, "record_finding",
|
|
38
|
+
lambda code, sid: captured.append((code, sid)) or {
|
|
39
|
+
"sessions": [sid], "total_fires": 1, "last_seen": "now"
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
monkeypatch.setattr(
|
|
43
|
+
persistence, "finding_qualifies_for_code_change",
|
|
44
|
+
lambda code, **kw: False,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
async def _stub_resolve(self, finding):
|
|
48
|
+
return finding.directive, "canned"
|
|
49
|
+
|
|
50
|
+
monkeypatch.setattr(worker.AdmiralWorker, "_resolve_directive", _stub_resolve)
|
|
51
|
+
monkeypatch.setattr(history, "append", lambda *a, **kw: None)
|
|
52
|
+
monkeypatch.setattr(interventions, "apply", lambda agent, finding: None)
|
|
53
|
+
|
|
54
|
+
al = _StubAgentLoop(session_id="known-real-session-xyz")
|
|
55
|
+
w = worker.AdmiralWorker(al)
|
|
56
|
+
finding = Finding(code="loop:read_file", directive="stop reading")
|
|
57
|
+
|
|
58
|
+
asyncio.run(w._handle_finding(finding))
|
|
59
|
+
|
|
60
|
+
assert captured == [("loop:read_file", "known-real-session-xyz")], (
|
|
61
|
+
"Admiral recorded finding against wrong session id — pair extraction "
|
|
62
|
+
"will fail. See agent_loop.py:280 + worker.py:105."
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_worker_source_does_not_reference_phantom_uuid_attr():
|
|
67
|
+
"""Belt-and-suspenders: the source must read `session_id`, not the
|
|
68
|
+
pre-fix `_admiral_session_id` attribute. Catches accidental reverts."""
|
|
69
|
+
src = inspect.getsource(worker.AdmiralWorker._handle_finding)
|
|
70
|
+
assert "_admiral_session_id" not in src or src.find("_admiral_session_id") > src.find("Pre-fix"), (
|
|
71
|
+
"_handle_finding still reads `_admiral_session_id` outside of a "
|
|
72
|
+
"comment. Use `agent_loop.session_id` so M5 can resolve sessions "
|
|
73
|
+
"to on-disk dirs."
|
|
74
|
+
)
|
|
75
|
+
assert "agent_loop, \"session_id\"" in src or "agent_loop, 'session_id'" in src, (
|
|
76
|
+
"_handle_finding must read `session_id` from the live agent_loop."
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_agent_loop_does_not_set_phantom_uuid_attr():
|
|
81
|
+
"""The AgentLoop init must NOT create a separate `_admiral_session_id`
|
|
82
|
+
attribute that diverges from `session_id`."""
|
|
83
|
+
from drydock.core import agent_loop as agent_loop_mod
|
|
84
|
+
src = inspect.getsource(agent_loop_mod)
|
|
85
|
+
# The attribute may appear in a comment explaining the fix; it must
|
|
86
|
+
# not appear as an assignment outside a comment.
|
|
87
|
+
for line in src.splitlines():
|
|
88
|
+
stripped = line.strip()
|
|
89
|
+
if stripped.startswith("#"):
|
|
90
|
+
continue
|
|
91
|
+
assert "self._admiral_session_id" not in stripped, (
|
|
92
|
+
"agent_loop.py still assigns `self._admiral_session_id` — "
|
|
93
|
+
"this UUID never resolves to an on-disk session dir. Use "
|
|
94
|
+
"`self.session_id` directly."
|
|
95
|
+
)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Regression: HLE prompts must reach the TUI as a single literal block.
|
|
2
|
+
|
|
3
|
+
Prior to the fix, `sk.type_message` typed char-by-char at 10ms/char,
|
|
4
|
+
racing Textual's input handler. In real captured sessions
|
|
5
|
+
(/home/bobef/.vibe/logs/session/session_20260509_015004_1fa9ac60),
|
|
6
|
+
the prompt `"Answer this question..."` arrived as
|
|
7
|
+
`"Answer th\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nis question..."`
|
|
8
|
+
— 13 stray newlines injected mid-word. The model then grinds in
|
|
9
|
+
tool-call loops and never emits `FINAL ANSWER:`, so 20/20 of the
|
|
10
|
+
phase1_steered run had empty predictions.
|
|
11
|
+
|
|
12
|
+
Post-fix, `_send_prompt_as_paste` wraps the prompt in xterm bracketed-
|
|
13
|
+
paste markers and writes once. The Textual Input widget treats the
|
|
14
|
+
contents as a literal block — no paste-detection, no per-char races.
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import importlib.util
|
|
19
|
+
import sys
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
REPO = Path(__file__).resolve().parent.parent
|
|
23
|
+
HLE_EVAL = REPO / "scripts" / "hle_eval.py"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _load_hle_eval():
|
|
27
|
+
spec = importlib.util.spec_from_file_location("hle_eval_under_test", HLE_EVAL)
|
|
28
|
+
mod = importlib.util.module_from_spec(spec)
|
|
29
|
+
# Skip optional sk import dance — we only need _send_prompt_as_paste.
|
|
30
|
+
sys.modules["hle_eval_under_test"] = mod
|
|
31
|
+
spec.loader.exec_module(mod)
|
|
32
|
+
return mod
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class _CaptureChild:
|
|
36
|
+
"""Minimal pexpect.spawn stand-in: records every send() call."""
|
|
37
|
+
def __init__(self):
|
|
38
|
+
self.sent: list[str] = []
|
|
39
|
+
def send(self, text: str) -> None:
|
|
40
|
+
self.sent.append(text)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_send_prompt_as_paste_uses_bracketed_paste_markers():
|
|
44
|
+
he = _load_hle_eval()
|
|
45
|
+
child = _CaptureChild()
|
|
46
|
+
prompt = "Answer this question. End your response with 'FINAL ANSWER:' followed by your answer on the same line. QUESTION: What is 2+2?"
|
|
47
|
+
|
|
48
|
+
he._send_prompt_as_paste(child, prompt)
|
|
49
|
+
|
|
50
|
+
# Two sends: paste-block, then Enter
|
|
51
|
+
assert len(child.sent) == 2, f"expected 2 sends, got {len(child.sent)}: {child.sent!r}"
|
|
52
|
+
assert child.sent[0].startswith("\x1b[200~"), "paste must open with ESC[200~"
|
|
53
|
+
assert child.sent[0].endswith("\x1b[201~"), "paste must close with ESC[201~"
|
|
54
|
+
assert child.sent[1] == "\r", "second send must be Enter"
|
|
55
|
+
|
|
56
|
+
# The literal prompt must appear inside the paste block, intact and
|
|
57
|
+
# contiguous — no whitespace or newlines injected mid-word.
|
|
58
|
+
payload = child.sent[0][len("\x1b[200~"):-len("\x1b[201~")]
|
|
59
|
+
assert payload == prompt, (
|
|
60
|
+
f"prompt was mangled inside paste markers:\n"
|
|
61
|
+
f" expected: {prompt!r}\n"
|
|
62
|
+
f" got: {payload!r}"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_send_prompt_strips_embedded_newlines():
|
|
67
|
+
"""Textual Input commits on Enter regardless of paste markers, so
|
|
68
|
+
embedded newlines would still split the message. Strip them before
|
|
69
|
+
sending — HLE prompts are single-line by `_question_prompt`'s contract."""
|
|
70
|
+
he = _load_hle_eval()
|
|
71
|
+
child = _CaptureChild()
|
|
72
|
+
he._send_prompt_as_paste(child, "line one\nline two\rline three")
|
|
73
|
+
payload = child.sent[0][len("\x1b[200~"):-len("\x1b[201~")]
|
|
74
|
+
assert "\n" not in payload, f"newline leaked through: {payload!r}"
|
|
75
|
+
assert "\r" not in payload, f"carriage return leaked through: {payload!r}"
|
|
76
|
+
assert payload == "line one line two line three"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def test_send_prompt_does_not_use_per_char_typing():
|
|
80
|
+
"""Per-char typing is the bug — verify exactly two send() calls
|
|
81
|
+
(paste-block, Enter), not one per character. A long prompt would
|
|
82
|
+
produce 1000+ sends in the broken path."""
|
|
83
|
+
he = _load_hle_eval()
|
|
84
|
+
child = _CaptureChild()
|
|
85
|
+
long_prompt = "x" * 2000
|
|
86
|
+
he._send_prompt_as_paste(child, long_prompt)
|
|
87
|
+
assert len(child.sent) == 2, (
|
|
88
|
+
f"per-char typing has regressed; got {len(child.sent)} sends "
|
|
89
|
+
f"for a 2000-char prompt"
|
|
90
|
+
)
|