drydock-cli 2.6.129__tar.gz → 2.6.131__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/PKG-INFO +1 -1
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/messages.py +18 -1
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/format.py +12 -1
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/bash.py +13 -1
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/todo.py +14 -1
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/setup/onboarding/__init__.py +8 -1
- drydock_cli-2.6.131/drydock/setup/onboarding/screens/__init__.py +13 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/setup/onboarding/screens/api_key.py +2 -2
- drydock_cli-2.6.131/drydock/setup/onboarding/screens/choice.py +65 -0
- drydock_cli-2.6.131/drydock/setup/onboarding/screens/local_model.py +138 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/setup/onboarding/screens/welcome.py +1 -1
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/pyproject.toml +1 -1
- drydock_cli-2.6.131/scripts/poll_issues.sh +102 -0
- drydock_cli-2.6.131/tests/test_issue_fixes.py +118 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_reasoning_content.py +42 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/uv.lock +1 -1
- drydock_cli-2.6.129/.auto_release.lock +0 -1
- drydock_cli-2.6.129/drydock/setup/onboarding/screens/__init__.py +0 -6
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.claude/scheduled_tasks.lock +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.gitignore +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.python-version +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.typos.toml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.vscode/extensions.json +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.vscode/launch.json +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/.vscode/settings.json +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/AGENTS.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/BASELINE_412.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/CHANGELOG.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/CLAUDE.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/LICENSE +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/NOTICE +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/PRD.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/README.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/action.yml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/README.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/docs/README.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/docs/acp-setup.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/agent_loop.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/logger.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/slug.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/types.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/core/utils.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock/whats_new.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock-acp.spec +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/drydock_terms.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/flake.lock +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/flake.nix +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/README.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/backup.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/bump_version.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/comprehensive_loop.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/discover_cli_tools.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/evolve_tests.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/install.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/mega_loop.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/meta_ralph_loop.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/notify_release.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/oss_task_harness.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/port_task.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/session_loop_audit.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/shakedown.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/shakedown_regression.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/test_full.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/test_tui_path.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/tui_test.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/conftest.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/e2e/common.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/mock/utils.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_agents.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_integration.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_message_id.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_middleware.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_smoke.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/test_workloads.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/worked_examples/README.md +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.6.129 → drydock_cli-2.6.131}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.131
|
|
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
|
|
@@ -163,7 +163,24 @@ class AssistantMessage(StreamingMessageBase):
|
|
|
163
163
|
self.add_class("assistant-message")
|
|
164
164
|
|
|
165
165
|
async def append_content(self, content: str) -> None:
|
|
166
|
-
|
|
166
|
+
# _preserve_line_breaks doubles \n → \n\n WITHIN a chunk. Streaming
|
|
167
|
+
# chunks routinely split on the newline boundary ("abc\n" then
|
|
168
|
+
# "def"), which that function can't upgrade — the single \n stays
|
|
169
|
+
# and markdown renders it as a space, collapsing lists and
|
|
170
|
+
# paragraphs. We bridge the gap here by checking the join point:
|
|
171
|
+
# if the accumulated content ends with a single \n and the new
|
|
172
|
+
# chunk starts with non-whitespace, inject an extra \n so markdown
|
|
173
|
+
# sees the paragraph break. Handles issue #5 (v2.6.130).
|
|
174
|
+
prepared = _preserve_line_breaks(content)
|
|
175
|
+
if (
|
|
176
|
+
prepared
|
|
177
|
+
and self._content.endswith("\n")
|
|
178
|
+
and not self._content.endswith("\n\n")
|
|
179
|
+
and not self._content.endswith("\t\n")
|
|
180
|
+
and prepared[0] not in ("\n", " ", "\t")
|
|
181
|
+
):
|
|
182
|
+
prepared = "\n" + prepared
|
|
183
|
+
await super().append_content(prepared)
|
|
167
184
|
|
|
168
185
|
def compose(self) -> ComposeResult:
|
|
169
186
|
if self._content:
|
|
@@ -228,6 +228,12 @@ class APIToolFormatHandler:
|
|
|
228
228
|
# Strip leading "thought"/"(thought)" filler and match the
|
|
229
229
|
# `call:name{...}` shape so the agent loop sees empty content
|
|
230
230
|
# and can fire its recovery nudge.
|
|
231
|
+
#
|
|
232
|
+
# IMPORTANT: `stripped` is for PATTERN MATCHING ONLY. We must
|
|
233
|
+
# NOT replace `content` with `stripped` in the no-match case —
|
|
234
|
+
# that ate leading/trailing spaces from every streaming chunk
|
|
235
|
+
# (issue #1: a Gemma chunk like " received" became "received"
|
|
236
|
+
# so the rendered text had no spaces between words).
|
|
231
237
|
stripped = content.strip()
|
|
232
238
|
# Peel "thought" or "(thought)" prefix (case-insensitive, optional
|
|
233
239
|
# whitespace)
|
|
@@ -250,7 +256,12 @@ class APIToolFormatHandler:
|
|
|
250
256
|
# this..." — only the bare-word leak with `/` or `\n`.
|
|
251
257
|
content = None
|
|
252
258
|
else:
|
|
253
|
-
|
|
259
|
+
# Preserve original whitespace. Only collapse to None when
|
|
260
|
+
# the chunk is genuinely empty after stripping (so we don't
|
|
261
|
+
# ship pure-whitespace chunks to downstream consumers).
|
|
262
|
+
if not stripped:
|
|
263
|
+
content = None
|
|
264
|
+
# else: leave `content` as-is (with leading/trailing spaces)
|
|
254
265
|
|
|
255
266
|
clean_message = {
|
|
256
267
|
"role": message.role,
|
|
@@ -370,7 +370,19 @@ class Bash(
|
|
|
370
370
|
return False
|
|
371
371
|
|
|
372
372
|
def is_allowlisted(command: str) -> bool:
|
|
373
|
-
|
|
373
|
+
# Direct prefix match first ("find . -name x" vs "find").
|
|
374
|
+
if any(command.startswith(pattern) for pattern in self.config.allowlist):
|
|
375
|
+
return True
|
|
376
|
+
# Also match on basename so "/usr/bin/find ..." or "./grep ..."
|
|
377
|
+
# auto-approve alongside bare "find" / "grep". Without this,
|
|
378
|
+
# the model invoking a fully-qualified path would drop to the
|
|
379
|
+
# approval prompt unnecessarily (GitHub issue #6).
|
|
380
|
+
parts = command.split(None, 1)
|
|
381
|
+
if not parts:
|
|
382
|
+
return False
|
|
383
|
+
base = os.path.basename(parts[0])
|
|
384
|
+
rest = f"{base} {parts[1]}" if len(parts) > 1 else base
|
|
385
|
+
return any(rest.startswith(pattern) for pattern in self.config.allowlist)
|
|
374
386
|
|
|
375
387
|
for part in command_parts:
|
|
376
388
|
if is_denylisted(part):
|
|
@@ -4,7 +4,7 @@ from collections.abc import AsyncGenerator
|
|
|
4
4
|
from enum import StrEnum, auto
|
|
5
5
|
from typing import Any, ClassVar
|
|
6
6
|
|
|
7
|
-
from pydantic import BaseModel, Field, field_validator
|
|
7
|
+
from pydantic import BaseModel, Field, field_validator, model_validator
|
|
8
8
|
|
|
9
9
|
from drydock.core.tools.base import (
|
|
10
10
|
BaseTool,
|
|
@@ -92,6 +92,19 @@ class TodoArgs(BaseModel):
|
|
|
92
92
|
return result
|
|
93
93
|
return v
|
|
94
94
|
|
|
95
|
+
@model_validator(mode="after")
|
|
96
|
+
def _infer_write_action(self) -> "TodoArgs":
|
|
97
|
+
"""Gemma 4 often calls todo with a todos list but forgets
|
|
98
|
+
action='write' (leaving it at the default 'read'). Drydock
|
|
99
|
+
would then silently do a read, return 0 todos, and the model
|
|
100
|
+
would loop trying to write and read empty. If todos is
|
|
101
|
+
populated, treat that as a write — the caller's intent is
|
|
102
|
+
clear. See GitHub issue #4.
|
|
103
|
+
"""
|
|
104
|
+
if self.todos and self.action == "read":
|
|
105
|
+
object.__setattr__(self, "action", "write")
|
|
106
|
+
return self
|
|
107
|
+
|
|
95
108
|
|
|
96
109
|
class TodoResult(BaseModel):
|
|
97
110
|
message: str
|
|
@@ -6,7 +6,12 @@ from rich import print as rprint
|
|
|
6
6
|
from textual.app import App
|
|
7
7
|
|
|
8
8
|
from drydock.core.paths import GLOBAL_ENV_FILE
|
|
9
|
-
from drydock.setup.onboarding.screens import
|
|
9
|
+
from drydock.setup.onboarding.screens import (
|
|
10
|
+
ApiKeyScreen,
|
|
11
|
+
ChoiceScreen,
|
|
12
|
+
LocalModelScreen,
|
|
13
|
+
WelcomeScreen,
|
|
14
|
+
)
|
|
10
15
|
|
|
11
16
|
|
|
12
17
|
class OnboardingApp(App[str | None]):
|
|
@@ -16,6 +21,8 @@ class OnboardingApp(App[str | None]):
|
|
|
16
21
|
self.theme = "textual-ansi"
|
|
17
22
|
|
|
18
23
|
self.install_screen(WelcomeScreen(), "welcome")
|
|
24
|
+
self.install_screen(ChoiceScreen(), "choice")
|
|
25
|
+
self.install_screen(LocalModelScreen(), "local_model")
|
|
19
26
|
self.install_screen(ApiKeyScreen(), "api_key")
|
|
20
27
|
self.push_screen("welcome")
|
|
21
28
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from drydock.setup.onboarding.screens.api_key import ApiKeyScreen
|
|
4
|
+
from drydock.setup.onboarding.screens.choice import ChoiceScreen
|
|
5
|
+
from drydock.setup.onboarding.screens.local_model import LocalModelScreen
|
|
6
|
+
from drydock.setup.onboarding.screens.welcome import WelcomeScreen
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"ApiKeyScreen",
|
|
10
|
+
"ChoiceScreen",
|
|
11
|
+
"LocalModelScreen",
|
|
12
|
+
"WelcomeScreen",
|
|
13
|
+
]
|
|
@@ -19,10 +19,10 @@ from drydock.core.telemetry.send import TelemetryClient
|
|
|
19
19
|
from drydock.setup.onboarding.base import OnboardingScreen
|
|
20
20
|
|
|
21
21
|
PROVIDER_HELP = {
|
|
22
|
-
"mistral": ("https://console.mistral.ai/codestral/cli", "Mistral AI Studio")
|
|
22
|
+
"mistral": ("https://console.mistral.ai/codestral/cli", "Mistral AI Studio"),
|
|
23
23
|
}
|
|
24
24
|
CONFIG_DOCS_URL = (
|
|
25
|
-
"https://github.com/
|
|
25
|
+
"https://github.com/fbobe321/drydock?tab=readme-ov-file#configuration"
|
|
26
26
|
)
|
|
27
27
|
|
|
28
28
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""Cloud-vs-local choice screen — step 2 of onboarding.
|
|
2
|
+
|
|
3
|
+
Asks the user which kind of LLM they're connecting to. Answers github
|
|
4
|
+
issue #3: a fresh install used to drop straight into a Mistral API key
|
|
5
|
+
prompt with no obvious way to use a local vLLM instead. Now the user
|
|
6
|
+
sees the choice up front.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import ClassVar
|
|
11
|
+
|
|
12
|
+
from textual.app import ComposeResult
|
|
13
|
+
from textual.binding import Binding, BindingType
|
|
14
|
+
from textual.containers import Center, Vertical
|
|
15
|
+
from textual.widgets import OptionList
|
|
16
|
+
from textual.widgets.option_list import Option
|
|
17
|
+
|
|
18
|
+
from drydock.cli.textual_ui.widgets.no_markup_static import NoMarkupStatic
|
|
19
|
+
from drydock.setup.onboarding.base import OnboardingScreen
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ChoiceScreen(OnboardingScreen):
|
|
23
|
+
BINDINGS: ClassVar[list[BindingType]] = [
|
|
24
|
+
Binding("ctrl+c", "cancel", "Cancel", show=False),
|
|
25
|
+
Binding("escape", "cancel", "Cancel", show=False),
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
NEXT_SCREEN = None # set dynamically based on selection
|
|
29
|
+
|
|
30
|
+
def compose(self) -> ComposeResult:
|
|
31
|
+
with Vertical(id="choice-outer"):
|
|
32
|
+
yield NoMarkupStatic("", classes="spacer")
|
|
33
|
+
yield Center(NoMarkupStatic(
|
|
34
|
+
"How will you connect to an LLM?",
|
|
35
|
+
id="choice-title",
|
|
36
|
+
))
|
|
37
|
+
with Center():
|
|
38
|
+
with Vertical(id="choice-content"):
|
|
39
|
+
yield OptionList(
|
|
40
|
+
Option(
|
|
41
|
+
"Local server (vLLM, Ollama, LM Studio, llama.cpp)",
|
|
42
|
+
id="local",
|
|
43
|
+
),
|
|
44
|
+
Option(
|
|
45
|
+
"Cloud API (Mistral)",
|
|
46
|
+
id="cloud",
|
|
47
|
+
),
|
|
48
|
+
id="choice-options",
|
|
49
|
+
)
|
|
50
|
+
yield NoMarkupStatic(
|
|
51
|
+
"[dim]↑↓ Navigate · Enter Select · Esc Cancel[/]",
|
|
52
|
+
id="choice-help",
|
|
53
|
+
)
|
|
54
|
+
yield NoMarkupStatic("", classes="spacer")
|
|
55
|
+
|
|
56
|
+
def on_mount(self) -> None:
|
|
57
|
+
self.query_one(OptionList).focus()
|
|
58
|
+
|
|
59
|
+
def on_option_list_option_selected(
|
|
60
|
+
self, event: OptionList.OptionSelected
|
|
61
|
+
) -> None:
|
|
62
|
+
if event.option.id == "local":
|
|
63
|
+
self.app.switch_screen("local_model")
|
|
64
|
+
elif event.option.id == "cloud":
|
|
65
|
+
self.app.switch_screen("api_key")
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Local-LLM setup screen — alternative to the Mistral API key path.
|
|
2
|
+
|
|
3
|
+
Asks the user for an api_base URL and a model name, writes a minimal
|
|
4
|
+
config.toml pointing at it, and exits onboarding marking it complete.
|
|
5
|
+
The user can refine later via `/setup-model` or by editing config.toml
|
|
6
|
+
directly. This is the "I'll run my own vLLM/Ollama/LM Studio" path
|
|
7
|
+
described in github issue #3.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import ClassVar
|
|
13
|
+
|
|
14
|
+
import tomli_w
|
|
15
|
+
from textual.app import ComposeResult
|
|
16
|
+
from textual.binding import Binding, BindingType
|
|
17
|
+
from textual.containers import Center, Horizontal, Vertical
|
|
18
|
+
from textual.validation import Length, Regex
|
|
19
|
+
from textual.widgets import Input
|
|
20
|
+
|
|
21
|
+
from drydock.cli.textual_ui.widgets.no_markup_static import NoMarkupStatic
|
|
22
|
+
from drydock.setup.onboarding.base import OnboardingScreen
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
_DEFAULT_API_BASE = "http://localhost:8000/v1"
|
|
26
|
+
_DEFAULT_MODEL = "local"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _write_local_config(api_base: str, model_name: str) -> Path:
|
|
30
|
+
"""Write a minimal local-model config to ~/.drydock/config.toml.
|
|
31
|
+
|
|
32
|
+
Adds a 'local' provider pointing at api_base, a 'local' model alias
|
|
33
|
+
pointing at the user's model name, and sets it as the active model.
|
|
34
|
+
Doesn't touch the existing Mistral defaults — the user can still
|
|
35
|
+
add a Mistral key later if they want.
|
|
36
|
+
"""
|
|
37
|
+
config_dir = Path.home() / ".drydock"
|
|
38
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
cfg_path = config_dir / "config.toml"
|
|
40
|
+
payload = {
|
|
41
|
+
"active_model": model_name or _DEFAULT_MODEL,
|
|
42
|
+
"providers": [
|
|
43
|
+
{
|
|
44
|
+
"name": "local",
|
|
45
|
+
"api_base": api_base,
|
|
46
|
+
"api_key_env_var": "",
|
|
47
|
+
"backend": "generic",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
"models": [
|
|
51
|
+
{
|
|
52
|
+
"name": model_name or _DEFAULT_MODEL,
|
|
53
|
+
"provider": "local",
|
|
54
|
+
"alias": model_name or _DEFAULT_MODEL,
|
|
55
|
+
"input_price": 0.0,
|
|
56
|
+
"output_price": 0.0,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
}
|
|
60
|
+
with cfg_path.open("wb") as f:
|
|
61
|
+
tomli_w.dump(payload, f)
|
|
62
|
+
return cfg_path
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class LocalModelScreen(OnboardingScreen):
|
|
66
|
+
"""Step-2 alternative: configure a local OpenAI-compatible endpoint."""
|
|
67
|
+
|
|
68
|
+
BINDINGS: ClassVar[list[BindingType]] = [
|
|
69
|
+
Binding("ctrl+c", "cancel", "Cancel", show=False),
|
|
70
|
+
Binding("escape", "cancel", "Cancel", show=False),
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
NEXT_SCREEN = None
|
|
74
|
+
|
|
75
|
+
def compose(self) -> ComposeResult:
|
|
76
|
+
self.api_base_input = Input(
|
|
77
|
+
value=_DEFAULT_API_BASE,
|
|
78
|
+
id="api-base",
|
|
79
|
+
placeholder=_DEFAULT_API_BASE,
|
|
80
|
+
validators=[
|
|
81
|
+
Length(minimum=1, failure_description="API base URL required."),
|
|
82
|
+
Regex(
|
|
83
|
+
r"^https?://.+",
|
|
84
|
+
failure_description="Must start with http:// or https://",
|
|
85
|
+
),
|
|
86
|
+
],
|
|
87
|
+
)
|
|
88
|
+
self.model_input = Input(
|
|
89
|
+
value="",
|
|
90
|
+
id="model-name",
|
|
91
|
+
placeholder="model name (e.g. gemma4, llama-3-8b)",
|
|
92
|
+
validators=[Length(minimum=1, failure_description="Model name required.")],
|
|
93
|
+
)
|
|
94
|
+
with Vertical(id="local-model-outer"):
|
|
95
|
+
yield NoMarkupStatic("", classes="spacer")
|
|
96
|
+
yield Center(NoMarkupStatic(
|
|
97
|
+
"Local LLM setup",
|
|
98
|
+
id="local-model-title",
|
|
99
|
+
))
|
|
100
|
+
with Center():
|
|
101
|
+
with Vertical(id="local-model-content"):
|
|
102
|
+
yield NoMarkupStatic(
|
|
103
|
+
"Point Drydock at any OpenAI-compatible endpoint "
|
|
104
|
+
"(vLLM, Ollama, LM Studio, llama.cpp, etc.):",
|
|
105
|
+
id="local-model-hint",
|
|
106
|
+
)
|
|
107
|
+
yield NoMarkupStatic("API base URL:")
|
|
108
|
+
yield Center(Horizontal(self.api_base_input, id="api-base-row"))
|
|
109
|
+
yield NoMarkupStatic("Model name (as your server reports it):")
|
|
110
|
+
yield Center(Horizontal(self.model_input, id="model-row"))
|
|
111
|
+
yield NoMarkupStatic("", id="feedback")
|
|
112
|
+
yield NoMarkupStatic(
|
|
113
|
+
"[dim]Tab to switch fields · Enter on the model "
|
|
114
|
+
"field to save · Esc to skip[/]",
|
|
115
|
+
id="local-model-help",
|
|
116
|
+
)
|
|
117
|
+
yield NoMarkupStatic("", classes="spacer")
|
|
118
|
+
|
|
119
|
+
def on_mount(self) -> None:
|
|
120
|
+
self.api_base_input.focus()
|
|
121
|
+
|
|
122
|
+
def on_input_submitted(self, event: Input.Submitted) -> None:
|
|
123
|
+
# Enter on api-base → jump to model field; Enter on model → save.
|
|
124
|
+
if event.input.id == "api-base":
|
|
125
|
+
self.model_input.focus()
|
|
126
|
+
return
|
|
127
|
+
if event.input.id == "model-name":
|
|
128
|
+
self._save_and_finish()
|
|
129
|
+
|
|
130
|
+
def _save_and_finish(self) -> None:
|
|
131
|
+
api_base = self.api_base_input.value.strip() or _DEFAULT_API_BASE
|
|
132
|
+
model_name = self.model_input.value.strip() or _DEFAULT_MODEL
|
|
133
|
+
try:
|
|
134
|
+
_write_local_config(api_base, model_name)
|
|
135
|
+
except OSError as err:
|
|
136
|
+
self.app.exit(f"save_error:{err}")
|
|
137
|
+
return
|
|
138
|
+
self.app.exit("completed")
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Hourly poller: notifies via Telegram about NEW open issues opened by
|
|
3
|
+
# fbobe321 in fbobe321/drydock since the last poll. Runs Mon-Fri 7am-5pm
|
|
4
|
+
# via cron. State pointer at ~/.drydock/last_issue_poll keeps track of
|
|
5
|
+
# which issues we've already alerted on so we don't re-notify.
|
|
6
|
+
#
|
|
7
|
+
# Cron line (added separately to crontab):
|
|
8
|
+
# 0 7-17 * * 1-5 /data3/drydock/scripts/poll_issues.sh >> /data3/drydock/logs/poll_issues.log 2>&1
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
PYTHON="/home/bobef/miniconda3/bin/python3"
|
|
12
|
+
TOKEN_FILE="$HOME/.config/drydock/github_token"
|
|
13
|
+
STATE_FILE="$HOME/.drydock/last_issue_poll.json"
|
|
14
|
+
DRYDOCK="/data3/drydock"
|
|
15
|
+
|
|
16
|
+
if [ ! -f "$TOKEN_FILE" ]; then
|
|
17
|
+
echo "[$(date)] ERROR: GitHub token missing at $TOKEN_FILE" >&2
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
mkdir -p "$(dirname "$STATE_FILE")"
|
|
22
|
+
|
|
23
|
+
$PYTHON - <<'PYEOF'
|
|
24
|
+
"""Find new issues opened by fbobe321 since last poll, notify Telegram."""
|
|
25
|
+
import json
|
|
26
|
+
import os
|
|
27
|
+
import sys
|
|
28
|
+
import urllib.request
|
|
29
|
+
from datetime import datetime, timezone
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
|
|
32
|
+
REPO = "fbobe321/drydock"
|
|
33
|
+
AUTHOR = "fbobe321"
|
|
34
|
+
TOKEN = Path.home().joinpath(".config/drydock/github_token").read_text().strip()
|
|
35
|
+
STATE = Path.home().joinpath(".drydock/last_issue_poll.json")
|
|
36
|
+
NOTIFY_SCRIPT = "/data3/drydock/scripts/notify_release.py"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def gh_get(url: str):
|
|
40
|
+
req = urllib.request.Request(url)
|
|
41
|
+
req.add_header("Authorization", f"token {TOKEN}")
|
|
42
|
+
req.add_header("Accept", "application/vnd.github+json")
|
|
43
|
+
with urllib.request.urlopen(req, timeout=15) as resp:
|
|
44
|
+
return json.loads(resp.read().decode())
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def load_state() -> dict:
|
|
48
|
+
if STATE.is_file():
|
|
49
|
+
try:
|
|
50
|
+
return json.loads(STATE.read_text())
|
|
51
|
+
except json.JSONDecodeError:
|
|
52
|
+
pass
|
|
53
|
+
return {"seen_issue_numbers": []}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def save_state(state: dict) -> None:
|
|
57
|
+
STATE.write_text(json.dumps(state, indent=2))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def notify_telegram(text: str) -> None:
|
|
61
|
+
"""Use the existing release notifier in 'status' mode (plain text)."""
|
|
62
|
+
import subprocess
|
|
63
|
+
subprocess.run(
|
|
64
|
+
[sys.executable, NOTIFY_SCRIPT, "status", text],
|
|
65
|
+
check=False, timeout=10,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
state = load_state()
|
|
70
|
+
seen = set(state.get("seen_issue_numbers", []))
|
|
71
|
+
|
|
72
|
+
issues = gh_get(
|
|
73
|
+
f"https://api.github.com/repos/{REPO}/issues"
|
|
74
|
+
f"?state=open&creator={AUTHOR}&per_page=50&sort=created&direction=desc"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
new_items = []
|
|
78
|
+
for it in issues:
|
|
79
|
+
if "pull_request" in it:
|
|
80
|
+
continue
|
|
81
|
+
n = it["number"]
|
|
82
|
+
if n in seen:
|
|
83
|
+
continue
|
|
84
|
+
new_items.append(it)
|
|
85
|
+
seen.add(n)
|
|
86
|
+
|
|
87
|
+
if new_items:
|
|
88
|
+
lines = [f"⚓ {len(new_items)} new drydock issue(s) from fbobe321:"]
|
|
89
|
+
for it in new_items[:5]:
|
|
90
|
+
lines.append(f" #{it['number']}: {it['title'][:80]}")
|
|
91
|
+
if len(new_items) > 5:
|
|
92
|
+
lines.append(f" ...and {len(new_items) - 5} more")
|
|
93
|
+
lines.append(f" https://github.com/{REPO}/issues")
|
|
94
|
+
notify_telegram("\n".join(lines))
|
|
95
|
+
print(f"[{datetime.now(timezone.utc).isoformat()}] notified {len(new_items)} new issues")
|
|
96
|
+
else:
|
|
97
|
+
print(f"[{datetime.now(timezone.utc).isoformat()}] no new issues")
|
|
98
|
+
|
|
99
|
+
state["seen_issue_numbers"] = sorted(seen)
|
|
100
|
+
state["last_poll"] = datetime.now(timezone.utc).isoformat()
|
|
101
|
+
save_state(state)
|
|
102
|
+
PYEOF
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Regression tests for GitHub issues #4, #5, #6."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Issue #4: todo broken — action defaults to read, silently ignores todos
|
|
9
|
+
|
|
10
|
+
class TestIssue4TodoInferWrite:
|
|
11
|
+
def test_todos_without_action_infers_write(self):
|
|
12
|
+
from drydock.core.tools.builtins.todo import TodoArgs
|
|
13
|
+
args = TodoArgs(todos=[{"content": "first", "status": "pending"}])
|
|
14
|
+
assert args.action == "write"
|
|
15
|
+
|
|
16
|
+
def test_empty_todos_stays_read(self):
|
|
17
|
+
from drydock.core.tools.builtins.todo import TodoArgs
|
|
18
|
+
args = TodoArgs()
|
|
19
|
+
assert args.action == "read"
|
|
20
|
+
|
|
21
|
+
def test_explicit_read_with_todos_still_writes(self):
|
|
22
|
+
"""Intent is clear from the todos list. Model's confused 'read'
|
|
23
|
+
shouldn't stomp a populated list."""
|
|
24
|
+
from drydock.core.tools.builtins.todo import TodoArgs
|
|
25
|
+
args = TodoArgs(action="read", todos=[{"content": "x"}])
|
|
26
|
+
assert args.action == "write"
|
|
27
|
+
|
|
28
|
+
def test_explicit_write_no_todos_still_writes(self):
|
|
29
|
+
"""User explicitly said write but sent nothing — honor it (empties)."""
|
|
30
|
+
from drydock.core.tools.builtins.todo import TodoArgs
|
|
31
|
+
args = TodoArgs(action="write", todos=[])
|
|
32
|
+
assert args.action == "write"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Issue #5: cross-chunk newlines collapse to spaces in streaming output
|
|
36
|
+
|
|
37
|
+
class TestIssue5StreamingLineBreaks:
|
|
38
|
+
@pytest.mark.asyncio
|
|
39
|
+
async def test_streaming_preserves_cross_chunk_paragraph_breaks(self, tmp_path):
|
|
40
|
+
"""AssistantMessage.append_content must upgrade a single \\n at a
|
|
41
|
+
chunk boundary to \\n\\n so markdown renders it as a paragraph
|
|
42
|
+
break. Without this, 'hello\\n' + 'world' becomes 'hello\\nworld'
|
|
43
|
+
which markdown prints as 'hello world'."""
|
|
44
|
+
from drydock.cli.textual_ui.widgets.messages import AssistantMessage
|
|
45
|
+
|
|
46
|
+
# Bypass Textual mount — directly test the content-building path.
|
|
47
|
+
# AssistantMessage.__init__ calls super().__init__ which sets
|
|
48
|
+
# self._content; append_content mutates it via super().append_content.
|
|
49
|
+
msg = object.__new__(AssistantMessage)
|
|
50
|
+
msg._content = ""
|
|
51
|
+
msg._content_initialized = False
|
|
52
|
+
msg._stream = None
|
|
53
|
+
|
|
54
|
+
async def fake_super_append(c: str) -> None:
|
|
55
|
+
msg._content += c
|
|
56
|
+
|
|
57
|
+
# Monkey-patch only the super().append_content invocation.
|
|
58
|
+
from drydock.cli.textual_ui.widgets.messages import (
|
|
59
|
+
StreamingMessageBase,
|
|
60
|
+
)
|
|
61
|
+
original = StreamingMessageBase.append_content
|
|
62
|
+
|
|
63
|
+
async def shim(self, content: str) -> None:
|
|
64
|
+
self._content += content
|
|
65
|
+
|
|
66
|
+
StreamingMessageBase.append_content = shim
|
|
67
|
+
try:
|
|
68
|
+
await AssistantMessage.append_content(msg, "hello\n")
|
|
69
|
+
await AssistantMessage.append_content(msg, "world")
|
|
70
|
+
finally:
|
|
71
|
+
StreamingMessageBase.append_content = original
|
|
72
|
+
|
|
73
|
+
# hello\n + world must yield hello\n\nworld so markdown renders
|
|
74
|
+
# it as two paragraphs, not "hello world".
|
|
75
|
+
assert "hello\n\nworld" in msg._content
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# Issue #6: /find and /grep via bash should auto-approve even with full paths
|
|
79
|
+
|
|
80
|
+
class TestIssue6BashAllowlistBasename:
|
|
81
|
+
def _bash_tool(self):
|
|
82
|
+
from drydock.core.tools.builtins.bash import Bash, BashToolConfig
|
|
83
|
+
from drydock.core.tools.base import BaseToolState
|
|
84
|
+
return Bash(config=BashToolConfig(), state=BaseToolState())
|
|
85
|
+
|
|
86
|
+
def test_bare_find_allowlisted(self):
|
|
87
|
+
from drydock.core.tools.builtins.bash import BashArgs
|
|
88
|
+
from drydock.core.tools.base import ToolPermission
|
|
89
|
+
tool = self._bash_tool()
|
|
90
|
+
res = tool.resolve_permission(BashArgs(command="find . -name '*.py'"))
|
|
91
|
+
assert res == ToolPermission.ALWAYS
|
|
92
|
+
|
|
93
|
+
def test_full_path_find_allowlisted(self):
|
|
94
|
+
"""New fix: /usr/bin/find must behave like bare find for
|
|
95
|
+
auto-approval (basename match)."""
|
|
96
|
+
from drydock.core.tools.builtins.bash import BashArgs
|
|
97
|
+
from drydock.core.tools.base import ToolPermission
|
|
98
|
+
tool = self._bash_tool()
|
|
99
|
+
res = tool.resolve_permission(BashArgs(command="/usr/bin/find . -name '*.py'"))
|
|
100
|
+
assert res == ToolPermission.ALWAYS
|
|
101
|
+
|
|
102
|
+
def test_relative_path_grep_allowlisted(self):
|
|
103
|
+
from drydock.core.tools.builtins.bash import BashArgs
|
|
104
|
+
from drydock.core.tools.base import ToolPermission
|
|
105
|
+
tool = self._bash_tool()
|
|
106
|
+
res = tool.resolve_permission(BashArgs(command="./grep -r pattern ."))
|
|
107
|
+
assert res == ToolPermission.ALWAYS
|
|
108
|
+
|
|
109
|
+
def test_unknown_command_still_asks(self):
|
|
110
|
+
"""Safety: basename match doesn't accidentally allow random
|
|
111
|
+
binaries. `/usr/bin/sudo` has basename `sudo` which isn't
|
|
112
|
+
allowlisted → no auto-approve."""
|
|
113
|
+
from drydock.core.tools.builtins.bash import BashArgs
|
|
114
|
+
tool = self._bash_tool()
|
|
115
|
+
res = tool.resolve_permission(BashArgs(command="/usr/bin/sudo whoami"))
|
|
116
|
+
# Returns None (caller prompts for approval) — not ALWAYS.
|
|
117
|
+
from drydock.core.tools.base import ToolPermission
|
|
118
|
+
assert res != ToolPermission.ALWAYS
|
|
@@ -287,6 +287,48 @@ class TestAPIToolFormatHandlerReasoningContent:
|
|
|
287
287
|
assert result.content == "Hello"
|
|
288
288
|
assert result.reasoning_content is None
|
|
289
289
|
|
|
290
|
+
def test_process_api_response_message_preserves_leading_space(self):
|
|
291
|
+
"""Streaming chunks like ' received' must keep their leading space —
|
|
292
|
+
otherwise the rendered text reads 'Whatwouldyoulikemetotest' (issue
|
|
293
|
+
#1: spaces stripped from streaming output with Gemma vLLM)."""
|
|
294
|
+
handler = APIToolFormatHandler()
|
|
295
|
+
mock_message = MagicMock(spec=["role", "content", "tool_calls"])
|
|
296
|
+
mock_message.role = "assistant"
|
|
297
|
+
mock_message.content = " received"
|
|
298
|
+
mock_message.tool_calls = None
|
|
299
|
+
result = handler.process_api_response_message(mock_message)
|
|
300
|
+
assert result.content == " received"
|
|
301
|
+
|
|
302
|
+
def test_process_api_response_message_preserves_trailing_space(self):
|
|
303
|
+
handler = APIToolFormatHandler()
|
|
304
|
+
mock_message = MagicMock(spec=["role", "content", "tool_calls"])
|
|
305
|
+
mock_message.role = "assistant"
|
|
306
|
+
mock_message.content = "What "
|
|
307
|
+
mock_message.tool_calls = None
|
|
308
|
+
result = handler.process_api_response_message(mock_message)
|
|
309
|
+
assert result.content == "What "
|
|
310
|
+
|
|
311
|
+
def test_process_api_response_message_preserves_internal_whitespace(self):
|
|
312
|
+
"""Multi-word chunks must preserve all internal whitespace too."""
|
|
313
|
+
handler = APIToolFormatHandler()
|
|
314
|
+
mock_message = MagicMock(spec=["role", "content", "tool_calls"])
|
|
315
|
+
mock_message.role = "assistant"
|
|
316
|
+
mock_message.content = " I am working\n correctly."
|
|
317
|
+
mock_message.tool_calls = None
|
|
318
|
+
result = handler.process_api_response_message(mock_message)
|
|
319
|
+
assert result.content == " I am working\n correctly."
|
|
320
|
+
|
|
321
|
+
def test_process_api_response_message_pure_whitespace_becomes_none(self):
|
|
322
|
+
"""A chunk that's entirely whitespace should still collapse to None
|
|
323
|
+
— we don't want to ship ' ' as a content chunk."""
|
|
324
|
+
handler = APIToolFormatHandler()
|
|
325
|
+
mock_message = MagicMock(spec=["role", "content", "tool_calls"])
|
|
326
|
+
mock_message.role = "assistant"
|
|
327
|
+
mock_message.content = " "
|
|
328
|
+
mock_message.tool_calls = None
|
|
329
|
+
result = handler.process_api_response_message(mock_message)
|
|
330
|
+
assert result.content is None
|
|
331
|
+
|
|
290
332
|
|
|
291
333
|
class TestAgentLoopStreamingReasoningEvents:
|
|
292
334
|
@pytest.mark.asyncio
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1768422
|