drydock-cli 2.7.38__tar.gz → 2.7.40__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.7.40/.auto_release.lock +1 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/PKG-INFO +1 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/messages.py +14 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agent_loop.py +197 -4
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/_settings.py +12 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/local_detect.py +13 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/gemma4.md +9 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/steering_hook.py +18 -6
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/bash.py +71 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/search_replace.py +11 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/pyproject.toml +1 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/hle_eval.py +8 -3
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/notify_release.py +11 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_issue_fixes.py +101 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_local_detect.py +74 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_wall_of_text_rescue.py +30 -0
- drydock_cli-2.7.40/tests/tools/test_bash_exact_cmd_loop_breaker.py +59 -0
- drydock_cli-2.7.40/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +57 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/trip_log.md +287 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/uv.lock +1 -1
- drydock_cli-2.7.38/.auto_release.lock +0 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.claude/scheduled_tasks.lock +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.gitignore +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.perf_baseline_done +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.python-version +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.typos.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.vscode/extensions.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.vscode/launch.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.vscode/settings.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/AGENTS.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/Admiral.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/BASELINE_412.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/CHANGELOG.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/CLAUDE.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/DEPLOYMENT.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/HLE_PRD.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/JETSON_BENCH.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/LICENSE +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/NOTICE +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/OVERNIGHT_PROGRESS.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/PERF_SWEEP_PLAN.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/PRD.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/SOVEREIGN_PRD.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/TRIAGE_v1.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/action.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/docs/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/docs/acp-setup.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/detectors.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/detectors_proposed.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/history.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/interventions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/llm_analyzer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/metrics.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/opus_escalator.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/persistence.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/policy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/proposer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/stager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/task_classifier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/tuning.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/validator.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/worker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/__main__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/classifier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/dispatcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/rules.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/signal.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/context_recovery.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/_drydock_home.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/slug.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/retrieve.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/retrieve.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/types.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/__main__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/code_indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/retriever.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/storage.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/text_indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/choice.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/local_model.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/__main__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/applier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/config.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/registry.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/sandbox.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/vectors.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/whats_new.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock-acp.spec +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock_terms.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/flake.lock +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/flake.nix +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/nohup.out +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777672181.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777672218.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777672322.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777732278.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777811293.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777811401.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/config_base.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/config_best.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/domain_spec.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/experimenter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/kernel.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/mini_prd.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/mini_prompts.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/proposer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/results.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/resume.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/admiral_probe.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/autonomous_review.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/autonomous_review_prompt.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/backup.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/bump_version.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/classify_pulse.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/comprehensive_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/consume_retrieval_queue.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/discover_cli_tools.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/evolve_tests.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/hle_eval_seed.jsonl +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/install.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/mega_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/meta_ralph_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/oss_task_harness.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/perf_baseline_when_idle.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/perf_sweep.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/poll_issues.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/port_task.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/queue_top.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/research_babysitter.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/session_loop_audit.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_regression.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_babysitter.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_realuser.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_watcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_full.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_tui_path.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/tui_test.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/test/project/dummy +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_generic_adapter_sanitize.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_circuit_breaker_count_escalation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/common.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/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.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral_phase3.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral_proposed.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral_struggle_dedup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agents.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_classifier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_context_recovery.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_dispatcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_fake_tool_call_paren_syntax.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_graphrag.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_hallucinated_tool_suppression.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_integration.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_message_id.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_middleware.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_read_file_not_found_listing.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_retrieval_consumer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_retrieve_tool.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_search_replace_args_not_truncated.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_smoke.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_steering.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_steering_hook.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_task_complete_nudge.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncate_args_valid_json.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncated_arg_path_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncated_search_replace_escalation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncated_write_escalation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_workloads.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_write_file_missing_path.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_binary_grep_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_consec_empty_search.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_empty_search_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_error_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_heredoc_confirmation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_kill_exit1_annotation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_hallucinated_retrieval_redirect.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_manager_gemma_derived_models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_dedup_alternating_offset.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_dedup_reembed.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_directory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_limit_truncation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_append_fallback.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_dir_path.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_empty_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_file_not_found.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_first_failure_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_hard_stop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_malformed_block.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_placeholder.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_write_file_missing_path_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2806441
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.40
|
|
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
|
|
@@ -118,6 +118,16 @@ _SENTENCE_BOUNDARY_RE = re.compile(r"(?<=[.!?]) (?=[A-Z])")
|
|
|
118
118
|
_INLINE_CAPWORD_HEADING_RE = re.compile(
|
|
119
119
|
r"(?<=[.!?]) (?=[A-Z][A-Za-z]{1,15}:\s)"
|
|
120
120
|
)
|
|
121
|
+
# Issue #16: quantized Gemma 4 (Q3_K_M) strips whitespace tokens, jamming
|
|
122
|
+
# `### Header text body` and `* item * item * item` runs onto one line.
|
|
123
|
+
# These patterns insert paragraph breaks before inline markdown headers
|
|
124
|
+
# and asterisk bullets that weren't preceded by a real newline.
|
|
125
|
+
_INLINE_ATX_HEADING_RE = re.compile(r"(?<=[.!?\)]) (?=#{1,4} [A-Z])")
|
|
126
|
+
# Asterisk-bullet rescue. Accepts either case for the first bullet word
|
|
127
|
+
# (file names start lowercase, sentences start uppercase). Requires the
|
|
128
|
+
# bullet word to be ≥3 alpha chars + dot/space — guards against math
|
|
129
|
+
# (`2 * 3`) and inline emphasis (`a * b`).
|
|
130
|
+
_INLINE_ASTERISK_BULLET_RE = re.compile(r"(?<=[a-zA-Z.!?\)]) (?=\* [A-Za-z][A-Za-z0-9_]{2,})")
|
|
121
131
|
|
|
122
132
|
|
|
123
133
|
def _sentence_chunks(text: str, group: int = 2) -> str:
|
|
@@ -164,6 +174,10 @@ def _break_walls_of_text(text: str) -> str:
|
|
|
164
174
|
out = _INLINE_ENUM_RE.sub("\n", out)
|
|
165
175
|
out = _INLINE_DASH_BULLET_RE.sub("\n", out)
|
|
166
176
|
out = _INLINE_CAPWORD_HEADING_RE.sub("\n\n", out)
|
|
177
|
+
# Issue #16: rescue inline ATX headers (`### Foo`) and asterisk bullets
|
|
178
|
+
# (`* item`) that quantized Gemma 4 emits without surrounding newlines.
|
|
179
|
+
out = _INLINE_ATX_HEADING_RE.sub("\n\n", out)
|
|
180
|
+
out = _INLINE_ASTERISK_BULLET_RE.sub("\n", out)
|
|
167
181
|
# If inline markers didn't produce any breaks AND the text is long
|
|
168
182
|
# enough that one paragraph hurts readability, split at sentence
|
|
169
183
|
# boundaries. group=1 = each sentence on its own paragraph (most
|
|
@@ -693,6 +693,25 @@ class AgentLoop:
|
|
|
693
693
|
_ar_t1 = time.perf_counter()
|
|
694
694
|
logger.warning("[TIMING] _auto_route_task: %.2fs", _ar_t1 - _ar_t0)
|
|
695
695
|
|
|
696
|
+
# === AUTO-PREFETCH RETRIEVE ===
|
|
697
|
+
# HLE Phase 1 finding (memory: project_graphrag_underused.md): Gemma 4
|
|
698
|
+
# almost never calls retrieve() on its own for general-knowledge
|
|
699
|
+
# questions — it defaults to web_search instead. So a curated
|
|
700
|
+
# GraphRAG corpus is invisible to the model unless we surface it
|
|
701
|
+
# automatically. This hook runs retrieve(query=user_msg[:300]) and,
|
|
702
|
+
# if there are real hits (above a quality threshold), prepends them
|
|
703
|
+
# as a system note BEFORE the first LLM call. Zero behavior change
|
|
704
|
+
# when the index has nothing relevant; pure lift when it does.
|
|
705
|
+
#
|
|
706
|
+
# Env-gated via DRYDOCK_AUTO_RETRIEVE so existing workflows are
|
|
707
|
+
# unaffected. Set to "1" or "true" to enable.
|
|
708
|
+
if os.environ.get("DRYDOCK_AUTO_RETRIEVE", "").strip().lower() in ("1", "true", "yes"):
|
|
709
|
+
logger.warning("[AUTO-RETRIEVE] hook entry, query=%r", (user_msg or "")[:80])
|
|
710
|
+
try:
|
|
711
|
+
self._auto_prefetch_retrieve(user_msg)
|
|
712
|
+
except Exception as _e:
|
|
713
|
+
logger.warning("auto-prefetch retrieve failed (skipped): %s", _e, exc_info=True)
|
|
714
|
+
|
|
696
715
|
try:
|
|
697
716
|
should_break_loop = False
|
|
698
717
|
tool_turns = 0
|
|
@@ -1885,7 +1904,39 @@ class AgentLoop:
|
|
|
1885
1904
|
if len(cleaned) != len(self.messages):
|
|
1886
1905
|
self.messages.reset(cleaned)
|
|
1887
1906
|
|
|
1888
|
-
# Fix 2:
|
|
1907
|
+
# Fix 2: Drop empty assistant messages (no content AND no tool_calls).
|
|
1908
|
+
# These violate the OpenAI schema and cause 400 errors on the next LLM
|
|
1909
|
+
# call. They arise when the model returns only thinking/reasoning tokens
|
|
1910
|
+
# (which get stripped) and stall-retry exhaustion leaves the empty msg
|
|
1911
|
+
# in history. An assistant message that follows a tool result must have
|
|
1912
|
+
# either content or tool_calls; if neither, drop it along with any
|
|
1913
|
+
# orphaned tool result messages that precede it (to keep role ordering
|
|
1914
|
+
# valid).
|
|
1915
|
+
cleaned2: list[LLMMessage] = []
|
|
1916
|
+
for msg in self.messages:
|
|
1917
|
+
if (msg.role == Role.assistant
|
|
1918
|
+
and not (msg.content or "").strip()
|
|
1919
|
+
and not msg.tool_calls):
|
|
1920
|
+
# Skip empty assistant — also drop any immediately preceding
|
|
1921
|
+
# tool result that would be truly orphaned (no matching
|
|
1922
|
+
# assistant.tool_calls entry in the preceding messages).
|
|
1923
|
+
while cleaned2 and cleaned2[-1].role == Role.tool:
|
|
1924
|
+
preceding_tool = cleaned2[-1]
|
|
1925
|
+
tcid = getattr(preceding_tool, "tool_call_id", None)
|
|
1926
|
+
if tcid and any(
|
|
1927
|
+
m.role == Role.assistant
|
|
1928
|
+
and m.tool_calls
|
|
1929
|
+
and any(tc.id == tcid for tc in m.tool_calls)
|
|
1930
|
+
for m in cleaned2[:-1]
|
|
1931
|
+
):
|
|
1932
|
+
break # tool result has a valid match; keep it
|
|
1933
|
+
cleaned2.pop()
|
|
1934
|
+
else:
|
|
1935
|
+
cleaned2.append(msg)
|
|
1936
|
+
if len(cleaned2) != len(self.messages):
|
|
1937
|
+
self.messages.reset(cleaned2)
|
|
1938
|
+
|
|
1939
|
+
# Fix 3: If last message is assistant, add a user "Continue." prompt.
|
|
1889
1940
|
# The auto-Continue exists so Gemma 4 keeps executing multi-step plans
|
|
1890
1941
|
# without stopping prematurely at an intermediate text response. For
|
|
1891
1942
|
# stress runs against prompts that don't need tool calls (pure
|
|
@@ -2032,22 +2083,37 @@ class AgentLoop:
|
|
|
2032
2083
|
temp = active_model.temperature
|
|
2033
2084
|
extra_sampling: dict | None = None
|
|
2034
2085
|
|
|
2086
|
+
# Per-model `extra_params` (top_k, top_p, frequency_penalty,
|
|
2087
|
+
# max_tokens, etc.) declared in config.toml flow through
|
|
2088
|
+
# extra_sampling. This is the seam llama.cpp users need to
|
|
2089
|
+
# pass top_k=40, top_p=0.95, frequency_penalty=1.1 per the
|
|
2090
|
+
# Gemma 4 loop-fix recipe.
|
|
2091
|
+
cfg_extra = getattr(active_model, "extra_params", None) or {}
|
|
2092
|
+
if cfg_extra:
|
|
2093
|
+
extra_sampling = dict(cfg_extra)
|
|
2094
|
+
|
|
2035
2095
|
# Token-level loop-breaker: when repetition is detected, bump
|
|
2036
2096
|
# temperature and add frequency_penalty + a fresh seed so the
|
|
2037
2097
|
# model's next completion is mechanically likely to diverge.
|
|
2038
2098
|
# Mistral/OpenAI-compat backends pass these straight through
|
|
2039
|
-
# to vLLM's SamplingParams.
|
|
2099
|
+
# to vLLM's SamplingParams. These OVERRIDE config.extra_params
|
|
2100
|
+
# for the duration of the loop-break.
|
|
2040
2101
|
if getattr(self, "_loop_detected", False):
|
|
2041
2102
|
signal = getattr(self, "_loop_signal", "") or ""
|
|
2042
2103
|
# Heavier bump if we've already hit the FORCE_STOP signal
|
|
2043
2104
|
# (=8 repeats) vs a WARNING (=3-5 repeats).
|
|
2044
2105
|
heavy = signal == "FORCE_STOP"
|
|
2045
2106
|
temp = min(1.0, temp + (0.5 if heavy else 0.3))
|
|
2046
|
-
|
|
2107
|
+
# Merge loop-breaker overrides on top of any cfg_extra so
|
|
2108
|
+
# config-declared sampling params survive when a loop is
|
|
2109
|
+
# NOT detected, and get overridden when one IS detected.
|
|
2110
|
+
if extra_sampling is None:
|
|
2111
|
+
extra_sampling = {}
|
|
2112
|
+
extra_sampling.update({
|
|
2047
2113
|
"frequency_penalty": 0.7 if heavy else 0.4,
|
|
2048
2114
|
"presence_penalty": 0.3,
|
|
2049
2115
|
"seed": int(time.time() * 1000) & 0x7FFFFFFF,
|
|
2050
|
-
}
|
|
2116
|
+
})
|
|
2051
2117
|
logger.info(
|
|
2052
2118
|
"[LOOP-BREAK] %s → temp %.2f, freq_pen %.2f, seed %d",
|
|
2053
2119
|
signal, temp, extra_sampling["frequency_penalty"],
|
|
@@ -2776,6 +2842,133 @@ class AgentLoop:
|
|
|
2776
2842
|
|
|
2777
2843
|
return None
|
|
2778
2844
|
|
|
2845
|
+
def _auto_prefetch_retrieve(self, user_msg: str) -> None:
|
|
2846
|
+
"""Auto-fetch relevant chunks from GraphRAG and inject as system note.
|
|
2847
|
+
|
|
2848
|
+
Runs synchronously (the GraphRAG retriever is a fast SQLite query).
|
|
2849
|
+
Caps the query length at 300 chars and the injected context at 2000
|
|
2850
|
+
chars to avoid blowing context budget on long user prompts.
|
|
2851
|
+
|
|
2852
|
+
Quality gate: only inject if at least one text-chunk hit has score
|
|
2853
|
+
>= 8.0 (the indexer's score is roughly TF-IDF magnitude). Below
|
|
2854
|
+
that, the retrieval is probably noise and would just bloat the
|
|
2855
|
+
prompt.
|
|
2856
|
+
|
|
2857
|
+
See memory/project_graphrag_underused.md for why this exists:
|
|
2858
|
+
Gemma 4 doesn't call retrieve() on its own for general-knowledge
|
|
2859
|
+
questions, so a curated index is invisible without a hook like
|
|
2860
|
+
this one.
|
|
2861
|
+
"""
|
|
2862
|
+
try:
|
|
2863
|
+
from drydock.graphrag import Index
|
|
2864
|
+
db = os.environ.get("DRYDOCK_GRAPHRAG_DB") or str(
|
|
2865
|
+
Path.home() / ".drydock" / "graphrag.sqlite"
|
|
2866
|
+
)
|
|
2867
|
+
if not Path(db).is_file():
|
|
2868
|
+
logger.warning("[AUTO-RETRIEVE] db missing: %s", db)
|
|
2869
|
+
return
|
|
2870
|
+
idx = Index(db)
|
|
2871
|
+
except Exception as e:
|
|
2872
|
+
logger.warning("[AUTO-RETRIEVE] setup failed: %s", e, exc_info=True)
|
|
2873
|
+
return
|
|
2874
|
+
|
|
2875
|
+
# Extract the actual question from boilerplate. HLE-style prompts
|
|
2876
|
+
# are wrapped: "Answer this question. End your response with...
|
|
2877
|
+
# QUESTION: <real text>". Without this strip the retrieve query
|
|
2878
|
+
# matches scaffolding (CLAUDE.md learnings, etc.) instead of the
|
|
2879
|
+
# actual content. Also strip "FINAL ANSWER:" trailing instructions.
|
|
2880
|
+
raw = (user_msg or "")
|
|
2881
|
+
q_marker = raw.find("QUESTION:")
|
|
2882
|
+
if q_marker >= 0:
|
|
2883
|
+
raw = raw[q_marker + len("QUESTION:"):]
|
|
2884
|
+
# Drop trailing answer-format instructions
|
|
2885
|
+
for stopper in ("FINAL ANSWER:", "Your answer", "Format your", "End your response"):
|
|
2886
|
+
idx_ = raw.find(stopper)
|
|
2887
|
+
if idx_ > 50: # only strip if there's still meaningful content
|
|
2888
|
+
raw = raw[:idx_]
|
|
2889
|
+
query = raw.strip()[:400]
|
|
2890
|
+
if len(query) < 10:
|
|
2891
|
+
logger.warning("[AUTO-RETRIEVE] query too short (%d chars)", len(query))
|
|
2892
|
+
return
|
|
2893
|
+
logger.warning("[AUTO-RETRIEVE] extracted query: %r", query[:120])
|
|
2894
|
+
|
|
2895
|
+
try:
|
|
2896
|
+
result = idx.retrieve(query, symbol_limit=0, text_limit=4)
|
|
2897
|
+
except Exception as e:
|
|
2898
|
+
logger.warning("[AUTO-RETRIEVE] query failed: %s", e, exc_info=True)
|
|
2899
|
+
return
|
|
2900
|
+
|
|
2901
|
+
text_hits = getattr(result, "text", None) or getattr(result, "text_hits", []) or []
|
|
2902
|
+
QUALITY_THRESHOLD = 8.0
|
|
2903
|
+
good_hits = [h for h in text_hits if getattr(h, "score", 0) >= QUALITY_THRESHOLD]
|
|
2904
|
+
logger.warning("[AUTO-RETRIEVE] %d total hits, %d above threshold %.1f",
|
|
2905
|
+
len(text_hits), len(good_hits), QUALITY_THRESHOLD)
|
|
2906
|
+
if not good_hits:
|
|
2907
|
+
return
|
|
2908
|
+
|
|
2909
|
+
# Build the system note. Cap at ~2000 chars total.
|
|
2910
|
+
chunks = []
|
|
2911
|
+
budget = 2000
|
|
2912
|
+
for h in good_hits[:3]:
|
|
2913
|
+
text = (getattr(h, "content", "") or "").strip()
|
|
2914
|
+
score = float(getattr(h, "score", 0))
|
|
2915
|
+
file_ = getattr(h, "file", "") or "?"
|
|
2916
|
+
s, e = getattr(h, "start_line", 0), getattr(h, "end_line", 0)
|
|
2917
|
+
piece = f"--- {file_}:{s}-{e} (score={score:.1f}) ---\n{text}"
|
|
2918
|
+
if len(piece) > budget:
|
|
2919
|
+
piece = piece[:budget] + "..."
|
|
2920
|
+
chunks.append(piece)
|
|
2921
|
+
budget -= len(piece) + 4
|
|
2922
|
+
if budget <= 0:
|
|
2923
|
+
break
|
|
2924
|
+
|
|
2925
|
+
# SYNTHETIC TOOL CALL: instead of mutating the user message
|
|
2926
|
+
# (which iter6-9 proved is treated as scaffolding by Gemma 4 — it
|
|
2927
|
+
# ignores inline references and trusts its training prior), spawn
|
|
2928
|
+
# a fake assistant->tool message pair that LOOKS like the model
|
|
2929
|
+
# called retrieve() and got results. Models trust tool outputs
|
|
2930
|
+
# as authoritative input.
|
|
2931
|
+
#
|
|
2932
|
+
# Sequence:
|
|
2933
|
+
# user -> [our synthetic assistant with tool_call retrieve]
|
|
2934
|
+
# -> [our synthetic tool result with the chunks]
|
|
2935
|
+
# -> real LLM turn begins from there
|
|
2936
|
+
from drydock.core.types import ToolCall, FunctionCall as _FC
|
|
2937
|
+
import uuid
|
|
2938
|
+
|
|
2939
|
+
tool_call_id = f"auto-retrieve-{uuid.uuid4().hex[:16]}"
|
|
2940
|
+
tool_args = json.dumps({"query": (user_msg or "")[:200]})
|
|
2941
|
+
synth_assistant = LLMMessage(
|
|
2942
|
+
role=Role.assistant,
|
|
2943
|
+
content="",
|
|
2944
|
+
tool_calls=[
|
|
2945
|
+
ToolCall(
|
|
2946
|
+
id=tool_call_id,
|
|
2947
|
+
function=_FC(name="retrieve", arguments=tool_args),
|
|
2948
|
+
type="function",
|
|
2949
|
+
)
|
|
2950
|
+
],
|
|
2951
|
+
)
|
|
2952
|
+
# Format chunks as the retrieve tool's actual output shape.
|
|
2953
|
+
formatted = "=== TEXT ===\n\n" + "\n\n".join(chunks)
|
|
2954
|
+
synth_tool = LLMMessage(
|
|
2955
|
+
role=Role.tool,
|
|
2956
|
+
content=formatted,
|
|
2957
|
+
name="retrieve",
|
|
2958
|
+
tool_call_id=tool_call_id,
|
|
2959
|
+
)
|
|
2960
|
+
self.messages.append(synth_assistant)
|
|
2961
|
+
self.messages.append(synth_tool)
|
|
2962
|
+
|
|
2963
|
+
logger.warning(
|
|
2964
|
+
"[AUTO-RETRIEVE] synthesized retrieve tool result: %d chunks "
|
|
2965
|
+
"(top score %.1f, content %d chars), msgs now %d",
|
|
2966
|
+
len(chunks),
|
|
2967
|
+
max(float(getattr(h, "score", 0)) for h in good_hits),
|
|
2968
|
+
len(formatted),
|
|
2969
|
+
len(self.messages),
|
|
2970
|
+
)
|
|
2971
|
+
|
|
2779
2972
|
async def _auto_route_task(self, user_msg: str) -> None:
|
|
2780
2973
|
"""Lightweight auto-context: list project files and key docs.
|
|
2781
2974
|
|
|
@@ -238,6 +238,18 @@ class ModelConfig(BaseModel):
|
|
|
238
238
|
output_price: float = 0.0 # Price per million output tokens
|
|
239
239
|
thinking: Literal["off", "low", "medium", "high"] = "off"
|
|
240
240
|
auto_compact_threshold: int = 200_000
|
|
241
|
+
# Free-form sampling overrides forwarded to the LLM backend's
|
|
242
|
+
# extra_sampling (top_k, top_p, frequency_penalty, repeat_penalty,
|
|
243
|
+
# min_p, max_tokens, etc). Anything supported by the OpenAI-compat
|
|
244
|
+
# server. For llama.cpp + Gemma 4 the article-recommended config is:
|
|
245
|
+
# [models.extra_params]
|
|
246
|
+
# top_k = 40
|
|
247
|
+
# top_p = 0.95
|
|
248
|
+
# frequency_penalty = 1.1
|
|
249
|
+
# max_tokens = 2048
|
|
250
|
+
# Set temperature via the top-level `temperature` field; do not
|
|
251
|
+
# duplicate it here.
|
|
252
|
+
extra_params: dict[str, Any] = Field(default_factory=dict)
|
|
241
253
|
|
|
242
254
|
@model_validator(mode="before")
|
|
243
255
|
@classmethod
|
|
@@ -117,4 +117,17 @@ def patch_config_for_local(
|
|
|
117
117
|
for model in models:
|
|
118
118
|
if isinstance(model, dict) and model.get("alias") == "local":
|
|
119
119
|
model["name"] = info.model_name
|
|
120
|
+
# When the detected backend is llama.cpp, bake in the
|
|
121
|
+
# Gemma 4 anti-loop sampling recipe (article: i-built-a-
|
|
122
|
+
# gemma-4-ai-agent-it-kept-looping). Temperature must be
|
|
123
|
+
# 1.0; lower values reinforce loops on quantized GGUF.
|
|
124
|
+
# Don't clobber user-defined values if config was already
|
|
125
|
+
# touched.
|
|
126
|
+
if info.label == "llama.cpp":
|
|
127
|
+
model.setdefault("temperature", 1.0)
|
|
128
|
+
extra = model.setdefault("extra_params", {})
|
|
129
|
+
extra.setdefault("top_k", 40)
|
|
130
|
+
extra.setdefault("top_p", 0.95)
|
|
131
|
+
extra.setdefault("frequency_penalty", 1.1)
|
|
132
|
+
extra.setdefault("max_tokens", 2048)
|
|
120
133
|
break
|
|
@@ -140,3 +140,12 @@ When you're asked to BUILD a package: always also write a
|
|
|
140
140
|
`strong_tests.sh` that exercises the PRD's specific examples and
|
|
141
141
|
roundtrip/state properties. A package with only `functional_tests.sh`
|
|
142
142
|
is not finished.
|
|
143
|
+
|
|
144
|
+
FORMATTING — when answering with prose (not tool calls):
|
|
145
|
+
- Always put a BLANK LINE before any `###`/`##`/`#` header.
|
|
146
|
+
- Always put a BLANK LINE between paragraphs.
|
|
147
|
+
- Always put a BLANK LINE before the FIRST item of a bullet list and a
|
|
148
|
+
newline between items. Do NOT pack `* a * b * c` onto one line.
|
|
149
|
+
- Use `\n\n` between sections. Quantized models drop whitespace tokens
|
|
150
|
+
to save length; the renderer cannot always recover the original
|
|
151
|
+
structure if you do.
|
|
@@ -52,7 +52,9 @@ def _initialize() -> _CachedSteering | None:
|
|
|
52
52
|
|
|
53
53
|
try:
|
|
54
54
|
from drydock.steering import (
|
|
55
|
+
LogitBiasSteeringApplier,
|
|
55
56
|
LogOnlySteeringApplier,
|
|
57
|
+
NullSteeringApplier,
|
|
56
58
|
SteeringConfig,
|
|
57
59
|
load_registry,
|
|
58
60
|
)
|
|
@@ -63,13 +65,23 @@ def _initialize() -> _CachedSteering | None:
|
|
|
63
65
|
root = os.environ.get("DRYDOCK_STEERING_ROOT") or None
|
|
64
66
|
registry = load_registry(root)
|
|
65
67
|
config = SteeringConfig.from_mode_names(mode_names)
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
|
|
68
|
+
# Applier selection via DRYDOCK_STEERING_APPLIER:
|
|
69
|
+
# "log_only" (default) : log-only, no inference change
|
|
70
|
+
# "logit_bias" : token-level steering via vLLM logit_bias
|
|
71
|
+
# (manifest must carry tags.tokens_boost
|
|
72
|
+
# and/or tags.tokens_suppress)
|
|
73
|
+
# "null" : no-op (same as not setting MODES at all)
|
|
74
|
+
# Real activation steering (VllmSidecarSteeringApplier) lands later.
|
|
75
|
+
kind = os.environ.get("DRYDOCK_STEERING_APPLIER", "log_only").strip().lower()
|
|
76
|
+
if kind == "logit_bias":
|
|
77
|
+
applier = LogitBiasSteeringApplier()
|
|
78
|
+
elif kind == "null":
|
|
79
|
+
applier = NullSteeringApplier()
|
|
80
|
+
else:
|
|
81
|
+
applier = LogOnlySteeringApplier()
|
|
69
82
|
logger.info(
|
|
70
|
-
"steering: enabled, modes=%s, registry=%s",
|
|
71
|
-
mode_names,
|
|
72
|
-
registry.root,
|
|
83
|
+
"steering: enabled, modes=%s, applier=%s, registry=%s",
|
|
84
|
+
mode_names, applier.kind, registry.root,
|
|
73
85
|
)
|
|
74
86
|
return _CachedSteering(config=config, registry=registry, applier=applier)
|
|
75
87
|
|
|
@@ -586,6 +586,10 @@ class Bash(
|
|
|
586
586
|
state = self.state.__dict__.setdefault("_bash_history", {})
|
|
587
587
|
# Track total error-exit calls per command (regardless of output).
|
|
588
588
|
err_state = self.state.__dict__.setdefault("_bash_err_count", {})
|
|
589
|
+
# Track total run count per exact command regardless of output or
|
|
590
|
+
# exit code. Catches benchmark/timeit loops where output varies
|
|
591
|
+
# each run (timings differ) so the hash check never fires.
|
|
592
|
+
run_count_state = self.state.__dict__.setdefault("_bash_run_count", {})
|
|
589
593
|
# Track consecutive empty-stdout search commands (any command, not
|
|
590
594
|
# just identical ones). The model semantic-loops by trying different
|
|
591
595
|
# search terms for a non-existent target:
|
|
@@ -595,6 +599,73 @@ class Bash(
|
|
|
595
599
|
_consec_empty_search_state = self.state.__dict__.setdefault(
|
|
596
600
|
"_consec_empty_searches", {"count": 0}
|
|
597
601
|
)
|
|
602
|
+
# python -c / python3 -c SyntaxError loop-breaker.
|
|
603
|
+
# The model truncates multi-line inline scripts; each re-run
|
|
604
|
+
# produces a SyntaxError but with slightly different stderr
|
|
605
|
+
# (different column/line), so the hash check never fires.
|
|
606
|
+
# Track cross-command: any python3 -c that hits SyntaxError.
|
|
607
|
+
_python_c_err_state = self.state.__dict__.setdefault(
|
|
608
|
+
"_python_c_syntaxerr_count", 0
|
|
609
|
+
)
|
|
610
|
+
_is_python_c_syntaxerr = (
|
|
611
|
+
returncode != 0
|
|
612
|
+
and "SyntaxError" in stderr_raw
|
|
613
|
+
and bool(__import__("re").search(r"\bpython3?\s+-c\b", args.command))
|
|
614
|
+
)
|
|
615
|
+
if _is_python_c_syntaxerr:
|
|
616
|
+
self.state.__dict__["_python_c_syntaxerr_count"] = _python_c_err_state + 1
|
|
617
|
+
if _python_c_err_state >= 1:
|
|
618
|
+
_cnt = _python_c_err_state + 1
|
|
619
|
+
yield self._build_result(
|
|
620
|
+
command=args.command,
|
|
621
|
+
stdout=(
|
|
622
|
+
f"[LOOP-BREAKER: `python3 -c '...'` has hit SyntaxError "
|
|
623
|
+
f"{_cnt} times. Inline -c scripts get truncated by the "
|
|
624
|
+
f"shell when they contain newlines or quotes. "
|
|
625
|
+
f"Write the script to a file first, then run it:\n"
|
|
626
|
+
f" write_file path='/tmp/script.py' content='...'\n"
|
|
627
|
+
f" bash command='python3 /tmp/script.py'\n"
|
|
628
|
+
f"Do NOT retry the inline -c form again.]"
|
|
629
|
+
),
|
|
630
|
+
stderr="",
|
|
631
|
+
returncode=returncode,
|
|
632
|
+
)
|
|
633
|
+
return
|
|
634
|
+
|
|
635
|
+
# Exact-command repetition loop-breaker: fires when the same
|
|
636
|
+
# command text is run 5+ times regardless of output or exit code.
|
|
637
|
+
# Catches benchmark/timeit/import-check loops where each run has
|
|
638
|
+
# varying output (timings, object ids) that defeats the hash check.
|
|
639
|
+
# Excludes commands that write files (heredoc, redirect, sed -i)
|
|
640
|
+
# since those legitimately run the same form multiple times.
|
|
641
|
+
_is_write_cmd = bool(
|
|
642
|
+
__import__("re").search(
|
|
643
|
+
r"(>|>>|\bsed\s+-i\b|\btee\b|\bcat\s+<<|\bprintf\b.*>)",
|
|
644
|
+
args.command,
|
|
645
|
+
)
|
|
646
|
+
)
|
|
647
|
+
if not _is_write_cmd:
|
|
648
|
+
_run_cnt = run_count_state.get(args.command, 0) + 1
|
|
649
|
+
run_count_state[args.command] = _run_cnt
|
|
650
|
+
if _run_cnt >= 5:
|
|
651
|
+
cmd_preview = args.command[:80]
|
|
652
|
+
yield self._build_result(
|
|
653
|
+
command=args.command,
|
|
654
|
+
stdout=(
|
|
655
|
+
f"[LOOP-BREAKER: `{cmd_preview}` has been run "
|
|
656
|
+
f"{_run_cnt} times this session with the same "
|
|
657
|
+
f"command text. The output is stable — re-running "
|
|
658
|
+
f"it will not produce new information. "
|
|
659
|
+
f"Stop repeating this command and move on to the "
|
|
660
|
+
f"next task step. If you are benchmarking, one "
|
|
661
|
+
f"run is enough. If you are checking an import, "
|
|
662
|
+
f"the result is already known.]\n{stdout}"
|
|
663
|
+
),
|
|
664
|
+
stderr=stderr,
|
|
665
|
+
returncode=returncode,
|
|
666
|
+
)
|
|
667
|
+
return
|
|
668
|
+
|
|
598
669
|
if returncode != 0:
|
|
599
670
|
err_count = err_state.get(args.command, 0) + 1
|
|
600
671
|
err_state[args.command] = err_count
|
|
@@ -1069,6 +1069,17 @@ class SearchReplace(
|
|
|
1069
1069
|
|
|
1070
1070
|
if fuzzy_context:
|
|
1071
1071
|
error_msg += f"\n{fuzzy_context}"
|
|
1072
|
+
elif "not found anywhere" in context:
|
|
1073
|
+
# First search line not found at all — embed file head so the
|
|
1074
|
+
# model can craft a correct SEARCH block without calling read_file.
|
|
1075
|
+
head_lines = current_content.split("\n")[:30]
|
|
1076
|
+
head = "\n".join(head_lines)
|
|
1077
|
+
error_msg += (
|
|
1078
|
+
f"\nFile head (first {len(head_lines)} lines of actual content):\n"
|
|
1079
|
+
f"```\n{head}\n```\n"
|
|
1080
|
+
"Read the file head above and craft your SEARCH block using "
|
|
1081
|
+
"text that actually appears in the file."
|
|
1082
|
+
)
|
|
1072
1083
|
|
|
1073
1084
|
error_msg += (
|
|
1074
1085
|
"\nDebugging tips:\n"
|
|
@@ -210,10 +210,15 @@ def score_answer(q: dict, pred: str) -> dict:
|
|
|
210
210
|
def notify_telegram(tag: str, message: str) -> None:
|
|
211
211
|
"""Fire-and-forget Telegram ping via the existing notify_release.py.
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
Default OFF: HLE eval is too noisy for routine notifications and the
|
|
214
|
+
user explicitly asked to stop. Opt in via HLE_TELEGRAM=1 if you want
|
|
215
|
+
start/milestone/final/crash pings for a specific run.
|
|
216
|
+
|
|
217
|
+
Failures are silent — a missed Telegram is never worth crashing
|
|
218
|
+
the eval.
|
|
216
219
|
"""
|
|
220
|
+
if os.environ.get("HLE_TELEGRAM", "").strip().lower() not in ("1", "true", "yes"):
|
|
221
|
+
return
|
|
217
222
|
if not NOTIFY.exists():
|
|
218
223
|
return
|
|
219
224
|
import subprocess
|
|
@@ -51,6 +51,17 @@ if __name__ == "__main__":
|
|
|
51
51
|
version = sys.argv[1] if len(sys.argv) > 1 else "unknown"
|
|
52
52
|
summary = "New release"
|
|
53
53
|
|
|
54
|
+
# User explicitly asked to stop HLE telegram spam (2026-05-04).
|
|
55
|
+
# Drop HLE-prefixed tags by default; override with HLE_TELEGRAM=1.
|
|
56
|
+
# This silences the in-flight overnight HLE process too — it shells
|
|
57
|
+
# out to this script per ping, so the filter applies retroactively.
|
|
58
|
+
import os as _os
|
|
59
|
+
if (version.startswith("hle-")
|
|
60
|
+
and _os.environ.get("HLE_TELEGRAM", "").strip().lower()
|
|
61
|
+
not in ("1", "true", "yes")):
|
|
62
|
+
print(f"[notify_release] dropped HLE-tagged ping: {version}")
|
|
63
|
+
sys.exit(0)
|
|
64
|
+
|
|
54
65
|
if version == "status":
|
|
55
66
|
# Hourly status — plain text, no Markdown parsing issues
|
|
56
67
|
msg = f"⚓ {summary}"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Regression tests for GitHub issues #4, #5, #6."""
|
|
1
|
+
"""Regression tests for GitHub issues #4, #5, #6, #14."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
import os
|
|
@@ -116,3 +116,103 @@ class TestIssue6BashAllowlistBasename:
|
|
|
116
116
|
# Returns None (caller prompts for approval) — not ALWAYS.
|
|
117
117
|
from drydock.core.tools.base import ToolPermission
|
|
118
118
|
assert res != ToolPermission.ALWAYS
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# Issue #14: empty assistant messages (no content, no tool_calls) persist in
|
|
122
|
+
# history after stall-retry exhaustion and cause 400 errors on the next turn.
|
|
123
|
+
# _sanitize_message_ordering must drop them before the next LLM call.
|
|
124
|
+
|
|
125
|
+
class TestIssue14EmptyAssistantDropped:
|
|
126
|
+
def _make_minimal_agent(self):
|
|
127
|
+
from drydock.core.agent_loop import AgentLoop
|
|
128
|
+
from drydock.core.types import MessageList
|
|
129
|
+
al = object.__new__(AgentLoop)
|
|
130
|
+
al.messages = MessageList()
|
|
131
|
+
# stubs for methods called by _sanitize_message_ordering
|
|
132
|
+
al._truncate_old_tool_results = lambda: None
|
|
133
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
134
|
+
import os as _os
|
|
135
|
+
al._os = _os
|
|
136
|
+
return al
|
|
137
|
+
|
|
138
|
+
def test_empty_assistant_dropped(self):
|
|
139
|
+
"""Empty assistant message (no content, no tool_calls) is dropped."""
|
|
140
|
+
from drydock.core.agent_loop import AgentLoop
|
|
141
|
+
from drydock.core.types import LLMMessage, Role, MessageList
|
|
142
|
+
import os
|
|
143
|
+
al = object.__new__(AgentLoop)
|
|
144
|
+
al.messages = MessageList()
|
|
145
|
+
al._truncate_old_tool_results = lambda: None
|
|
146
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
147
|
+
|
|
148
|
+
al.messages.append(LLMMessage(role=Role.user, content="hello"))
|
|
149
|
+
al.messages.append(LLMMessage(role=Role.assistant, content=None)) # empty — bug
|
|
150
|
+
|
|
151
|
+
original_env = os.environ.get("DRYDOCK_AUTO_CONTINUE_DISABLE")
|
|
152
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
|
|
153
|
+
try:
|
|
154
|
+
al._sanitize_message_ordering()
|
|
155
|
+
finally:
|
|
156
|
+
if original_env is None:
|
|
157
|
+
os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
|
|
158
|
+
else:
|
|
159
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = original_env
|
|
160
|
+
|
|
161
|
+
roles = [m.role for m in al.messages]
|
|
162
|
+
assert Role.assistant not in roles, f"Empty assistant must be dropped; got {roles}"
|
|
163
|
+
|
|
164
|
+
def test_empty_assistant_with_preceding_tool_result_both_dropped(self):
|
|
165
|
+
"""Tool result immediately before an empty assistant is also dropped
|
|
166
|
+
to avoid a dangling tool message with no matching assistant turn."""
|
|
167
|
+
from drydock.core.agent_loop import AgentLoop
|
|
168
|
+
from drydock.core.types import LLMMessage, Role, MessageList, ToolCall, FunctionCall
|
|
169
|
+
import os
|
|
170
|
+
al = object.__new__(AgentLoop)
|
|
171
|
+
al.messages = MessageList()
|
|
172
|
+
al._truncate_old_tool_results = lambda: None
|
|
173
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
174
|
+
|
|
175
|
+
al.messages.append(LLMMessage(role=Role.user, content="do it"))
|
|
176
|
+
al.messages.append(LLMMessage(
|
|
177
|
+
role=Role.assistant,
|
|
178
|
+
content=None,
|
|
179
|
+
tool_calls=[ToolCall(id="c1", function=FunctionCall(name="bash", arguments="{}"))],
|
|
180
|
+
))
|
|
181
|
+
al.messages.append(LLMMessage(role=Role.tool, content="ok", tool_call_id="c1"))
|
|
182
|
+
al.messages.append(LLMMessage(role=Role.assistant, content=None)) # empty — bug
|
|
183
|
+
|
|
184
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
|
|
185
|
+
try:
|
|
186
|
+
al._sanitize_message_ordering()
|
|
187
|
+
finally:
|
|
188
|
+
os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
|
|
189
|
+
|
|
190
|
+
roles = [m.role for m in al.messages]
|
|
191
|
+
# The empty assistant AND its preceding orphan tool result should be gone
|
|
192
|
+
assert roles == [Role.user, Role.assistant, Role.tool] or roles == [Role.user], \
|
|
193
|
+
f"Unexpected roles after sanitize: {roles}"
|
|
194
|
+
# The productive assistant (with tool_calls) must survive
|
|
195
|
+
productive = [m for m in al.messages if m.role == Role.assistant]
|
|
196
|
+
assert all(m.tool_calls for m in productive), "Non-empty assistant must keep tool_calls"
|
|
197
|
+
|
|
198
|
+
def test_non_empty_assistant_preserved(self):
|
|
199
|
+
"""Assistant messages with content are never dropped."""
|
|
200
|
+
from drydock.core.agent_loop import AgentLoop
|
|
201
|
+
from drydock.core.types import LLMMessage, Role, MessageList
|
|
202
|
+
import os
|
|
203
|
+
al = object.__new__(AgentLoop)
|
|
204
|
+
al.messages = MessageList()
|
|
205
|
+
al._truncate_old_tool_results = lambda: None
|
|
206
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
207
|
+
|
|
208
|
+
al.messages.append(LLMMessage(role=Role.user, content="hi"))
|
|
209
|
+
al.messages.append(LLMMessage(role=Role.assistant, content="I'm here"))
|
|
210
|
+
|
|
211
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
|
|
212
|
+
try:
|
|
213
|
+
al._sanitize_message_ordering()
|
|
214
|
+
finally:
|
|
215
|
+
os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
|
|
216
|
+
|
|
217
|
+
roles = [m.role for m in al.messages]
|
|
218
|
+
assert Role.assistant in roles, "Non-empty assistant must not be dropped"
|