drydock-cli 2.3.0__tar.gz → 2.3.2__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.3.0 → drydock_cli-2.3.2}/PKG-INFO +1 -1
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/skills/models.py +6 -0
- drydock_cli-2.3.2/drydock/core/tools/builtins/invoke_skill.py +204 -0
- drydock_cli-2.3.2/drydock/core/tools/builtins/mcp_resources.py +194 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/mcp/tools.py +106 -0
- drydock_cli-2.3.2/drydock/skills/api-design/SKILL.md +32 -0
- drydock_cli-2.3.2/drydock/skills/commit-code/SKILL.md +27 -0
- drydock_cli-2.3.2/drydock/skills/context-summary/SKILL.md +19 -0
- drydock_cli-2.3.2/drydock/skills/deploy/SKILL.md +26 -0
- drydock_cli-2.3.2/drydock/skills/diff-review/SKILL.md +16 -0
- drydock_cli-2.3.2/drydock/skills/doc-gen/SKILL.md +28 -0
- drydock_cli-2.3.2/drydock/skills/explain-code/SKILL.md +27 -0
- drydock_cli-2.3.2/drydock/skills/explore-code/SKILL.md +42 -0
- drydock_cli-2.3.2/drydock/skills/fix-issue/SKILL.md +33 -0
- drydock_cli-2.3.2/drydock/skills/git-ops/SKILL.md +32 -0
- drydock_cli-2.3.2/drydock/skills/init-project/SKILL.md +33 -0
- drydock_cli-2.3.2/drydock/skills/loop/SKILL.md +22 -0
- drydock_cli-2.3.2/drydock/skills/migrate/SKILL.md +25 -0
- drydock_cli-2.3.2/drydock/skills/perf-analyze/SKILL.md +29 -0
- drydock_cli-2.3.2/drydock/skills/plan-impl/SKILL.md +45 -0
- drydock_cli-2.3.2/drydock/skills/pr-review/SKILL.md +32 -0
- drydock_cli-2.3.2/drydock/skills/refactor/SKILL.md +37 -0
- drydock_cli-2.3.2/drydock/skills/regex-help/SKILL.md +30 -0
- drydock_cli-2.3.2/drydock/skills/security-review/SKILL.md +31 -0
- drydock_cli-2.3.2/drydock/skills/test-verify/SKILL.md +27 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/pyproject.toml +1 -1
- drydock_cli-2.3.0/drydock/core/tools/builtins/invoke_skill.py +0 -100
- drydock_cli-2.3.0/drydock/core/tools/builtins/mcp_resources.py +0 -118
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.gitignore +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.python-version +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.typos.toml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.vscode/extensions.json +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.vscode/launch.json +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/.vscode/settings.json +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/AGENTS.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/CHANGELOG.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/CLAUDE.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/LICENSE +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/NOTICE +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/PRD.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/README.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/action.yml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/docs/README.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/docs/acp-setup.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/agent_loop.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/logger.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/slug.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/task_manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/types.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/core/utils.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock/whats_new.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock-acp.spec +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/drydock_terms.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/flake.lock +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/flake.nix +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/README.md +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/backup.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/bump_version.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/install.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/notify_release.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/test_full.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/conftest.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/e2e/common.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/mock/utils.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/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.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_agents.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_integration.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_message_id.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_middleware.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_smoke.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/test_workloads.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.3.0 → drydock_cli-2.3.2}/uv.lock +0 -0
|
@@ -88,6 +88,9 @@ class SkillInfo(BaseModel):
|
|
|
88
88
|
metadata: dict[str, str] = Field(default_factory=dict)
|
|
89
89
|
allowed_tools: list[str] = Field(default_factory=list)
|
|
90
90
|
user_invocable: bool = True
|
|
91
|
+
context: str = "" # 'fork' to run in subagent
|
|
92
|
+
agent: str = "" # subagent type when context='fork'
|
|
93
|
+
model: str = "" # model override
|
|
91
94
|
skill_path: Path
|
|
92
95
|
|
|
93
96
|
model_config = {"arbitrary_types_allowed": True}
|
|
@@ -106,5 +109,8 @@ class SkillInfo(BaseModel):
|
|
|
106
109
|
metadata=meta.metadata,
|
|
107
110
|
allowed_tools=meta.allowed_tools,
|
|
108
111
|
user_invocable=meta.user_invocable,
|
|
112
|
+
context=meta.context,
|
|
113
|
+
agent=meta.agent,
|
|
114
|
+
model=meta.model,
|
|
109
115
|
skill_path=skill_path.resolve(),
|
|
110
116
|
)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""Invoke Skill tool — lets the model call skills programmatically.
|
|
2
|
+
|
|
3
|
+
The model can invoke any registered skill by name, equivalent to
|
|
4
|
+
the user typing /skill-name in the chat.
|
|
5
|
+
|
|
6
|
+
Supports:
|
|
7
|
+
- $ARGUMENTS, $0, $1 positional substitution in skill content
|
|
8
|
+
- !`command` shell preprocessing (runs at load time, output replaces command)
|
|
9
|
+
- context: fork for subagent execution
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import re
|
|
15
|
+
import subprocess
|
|
16
|
+
from collections.abc import AsyncGenerator
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import ClassVar, final
|
|
19
|
+
|
|
20
|
+
from pydantic import BaseModel, Field
|
|
21
|
+
|
|
22
|
+
from drydock.core.tools.base import (
|
|
23
|
+
BaseTool, BaseToolConfig, BaseToolState, InvokeContext, ToolError, ToolPermission,
|
|
24
|
+
)
|
|
25
|
+
from drydock.core.tools.ui import ToolCallDisplay, ToolResultDisplay, ToolUIData
|
|
26
|
+
from drydock.core.types import ToolStreamEvent, ToolResultEvent
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _substitute_arguments(content: str, arguments: str, skill_dir: str = "") -> str:
|
|
30
|
+
"""Replace $ARGUMENTS, $0, $1, ${SKILL_DIR} in skill content."""
|
|
31
|
+
if not arguments:
|
|
32
|
+
return content
|
|
33
|
+
content = content.replace("$ARGUMENTS", arguments)
|
|
34
|
+
arg_parts = arguments.split()
|
|
35
|
+
for i, arg in enumerate(arg_parts[:10]):
|
|
36
|
+
content = content.replace(f"$ARGUMENTS[{i}]", arg)
|
|
37
|
+
content = content.replace(f"${i}", arg)
|
|
38
|
+
if skill_dir:
|
|
39
|
+
content = content.replace("${SKILL_DIR}", skill_dir)
|
|
40
|
+
return content
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _preprocess_commands(content: str) -> str:
|
|
44
|
+
"""Execute !`command` inline and replace with output."""
|
|
45
|
+
def _run(match):
|
|
46
|
+
cmd = match.group(1)
|
|
47
|
+
try:
|
|
48
|
+
result = subprocess.run(
|
|
49
|
+
cmd, shell=True, capture_output=True, text=True,
|
|
50
|
+
timeout=10, cwd=str(Path.cwd()),
|
|
51
|
+
)
|
|
52
|
+
return result.stdout.strip() or result.stderr.strip() or "(no output)"
|
|
53
|
+
except subprocess.TimeoutExpired:
|
|
54
|
+
return f"[command timed out: {cmd}]"
|
|
55
|
+
except Exception as e:
|
|
56
|
+
return f"[command failed: {e}]"
|
|
57
|
+
return re.sub(r'!`([^`]+)`', _run, content)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class InvokeSkillArgs(BaseModel):
|
|
61
|
+
skill_name: str = Field(description="Name of the skill to invoke (e.g., 'investigate', 'review')")
|
|
62
|
+
arguments: str = Field(default="", description="Arguments to pass to the skill (e.g., issue number, file path)")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class InvokeSkillResult(BaseModel):
|
|
66
|
+
skill_name: str
|
|
67
|
+
content: str
|
|
68
|
+
loaded: bool
|
|
69
|
+
forked: bool = False
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class InvokeSkill(
|
|
73
|
+
BaseTool[InvokeSkillArgs, InvokeSkillResult, BaseToolConfig, BaseToolState],
|
|
74
|
+
ToolUIData[InvokeSkillArgs, InvokeSkillResult],
|
|
75
|
+
):
|
|
76
|
+
description: ClassVar[str] = (
|
|
77
|
+
"Invoke a skill by name. Use this to activate specialized workflows "
|
|
78
|
+
"like /investigate, /review, /ship, /batch, etc."
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def format_call_display(cls, args: InvokeSkillArgs) -> ToolCallDisplay:
|
|
83
|
+
return ToolCallDisplay(summary=f"skill: /{args.skill_name}")
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def get_result_display(cls, event: ToolResultEvent) -> ToolResultDisplay:
|
|
87
|
+
if isinstance(event.result, InvokeSkillResult):
|
|
88
|
+
status = "forked" if event.result.forked else "loaded"
|
|
89
|
+
return ToolResultDisplay(success=event.result.loaded, message=f"/{event.result.skill_name} ({status})")
|
|
90
|
+
return ToolResultDisplay(success=True, message="Skill invoked")
|
|
91
|
+
|
|
92
|
+
@classmethod
|
|
93
|
+
def get_status_text(cls) -> str:
|
|
94
|
+
return "Loading skill"
|
|
95
|
+
|
|
96
|
+
def resolve_permission(self, args: InvokeSkillArgs) -> ToolPermission | None:
|
|
97
|
+
return ToolPermission.ALWAYS
|
|
98
|
+
|
|
99
|
+
@final
|
|
100
|
+
async def run(
|
|
101
|
+
self, args: InvokeSkillArgs, ctx: InvokeContext | None = None
|
|
102
|
+
) -> AsyncGenerator[ToolStreamEvent | InvokeSkillResult, None]:
|
|
103
|
+
if not ctx or not ctx.agent_manager:
|
|
104
|
+
raise ToolError("No agent manager available")
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
from drydock.core.skills.manager import SkillManager
|
|
108
|
+
config = ctx.agent_manager.config
|
|
109
|
+
manager = SkillManager(lambda: config)
|
|
110
|
+
skills = manager.available_skills
|
|
111
|
+
|
|
112
|
+
if args.skill_name not in skills:
|
|
113
|
+
available = ", ".join(sorted(skills.keys()))
|
|
114
|
+
raise ToolError(
|
|
115
|
+
f"Skill '{args.skill_name}' not found. "
|
|
116
|
+
f"Available: {available}"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
skill_info = skills[args.skill_name]
|
|
120
|
+
raw_content = skill_info.skill_path.read_text(encoding="utf-8") if skill_info.skill_path else ""
|
|
121
|
+
|
|
122
|
+
# Strip frontmatter, keep it for metadata check
|
|
123
|
+
content = raw_content
|
|
124
|
+
meta_context = ""
|
|
125
|
+
meta_agent = ""
|
|
126
|
+
if content.startswith("---"):
|
|
127
|
+
parts = content.split("---", 2)
|
|
128
|
+
if len(parts) >= 3:
|
|
129
|
+
# Parse context/agent from frontmatter
|
|
130
|
+
import yaml
|
|
131
|
+
try:
|
|
132
|
+
fm = yaml.safe_load(parts[1]) or {}
|
|
133
|
+
meta_context = fm.get("context", "")
|
|
134
|
+
meta_agent = fm.get("agent", "")
|
|
135
|
+
except Exception:
|
|
136
|
+
pass
|
|
137
|
+
content = parts[2].strip()
|
|
138
|
+
|
|
139
|
+
# $ARGUMENTS substitution
|
|
140
|
+
skill_dir = str(skill_info.skill_path.parent) if skill_info.skill_path else ""
|
|
141
|
+
content = _substitute_arguments(content, args.arguments, skill_dir)
|
|
142
|
+
|
|
143
|
+
# !`command` preprocessing
|
|
144
|
+
content = _preprocess_commands(content)
|
|
145
|
+
|
|
146
|
+
# If no $ARGUMENTS were in the template, prepend args
|
|
147
|
+
if args.arguments and "$ARGUMENTS" not in raw_content and "$0" not in raw_content:
|
|
148
|
+
content = f"{args.arguments}\n\n{content}"
|
|
149
|
+
|
|
150
|
+
# context: fork — run in a subagent
|
|
151
|
+
if meta_context == "fork":
|
|
152
|
+
agent_name = meta_agent or "explore"
|
|
153
|
+
# Delegate to the task tool's subagent mechanism
|
|
154
|
+
from drydock.core.agents.models import BUILTIN_AGENTS, AgentType
|
|
155
|
+
agent_profile = BUILTIN_AGENTS.get(agent_name)
|
|
156
|
+
if agent_profile and agent_profile.agent_type == AgentType.SUBAGENT:
|
|
157
|
+
from drydock.core.agent_loop import AgentLoop
|
|
158
|
+
from drydock.core.config import SessionLoggingConfig, VibeConfig
|
|
159
|
+
|
|
160
|
+
session_logging = SessionLoggingConfig(
|
|
161
|
+
save_dir=str(ctx.session_dir / "skills") if ctx.session_dir else "",
|
|
162
|
+
session_prefix=f"skill-{args.skill_name}",
|
|
163
|
+
enabled=ctx.session_dir is not None,
|
|
164
|
+
)
|
|
165
|
+
sub_config = VibeConfig.load(session_logging=session_logging)
|
|
166
|
+
if agent_profile.model:
|
|
167
|
+
sub_config = agent_profile.apply_to_config(sub_config)
|
|
168
|
+
|
|
169
|
+
subagent = AgentLoop(
|
|
170
|
+
config=sub_config,
|
|
171
|
+
agent_name=agent_name,
|
|
172
|
+
max_turns=agent_profile.max_turns,
|
|
173
|
+
entrypoint_metadata=ctx.entrypoint_metadata,
|
|
174
|
+
)
|
|
175
|
+
if ctx.approval_callback:
|
|
176
|
+
subagent.set_approval_callback(ctx.approval_callback)
|
|
177
|
+
|
|
178
|
+
# Run the skill content as the subagent's task
|
|
179
|
+
response_parts = []
|
|
180
|
+
turns = 0
|
|
181
|
+
async for event in subagent.run(content):
|
|
182
|
+
from drydock.core.types import AssistantEvent
|
|
183
|
+
if isinstance(event, AssistantEvent) and event.content:
|
|
184
|
+
response_parts.append(event.content)
|
|
185
|
+
turns += 1
|
|
186
|
+
|
|
187
|
+
yield InvokeSkillResult(
|
|
188
|
+
skill_name=args.skill_name,
|
|
189
|
+
content="\n".join(response_parts) or "(subagent produced no output)",
|
|
190
|
+
loaded=True,
|
|
191
|
+
forked=True,
|
|
192
|
+
)
|
|
193
|
+
return
|
|
194
|
+
|
|
195
|
+
yield InvokeSkillResult(
|
|
196
|
+
skill_name=args.skill_name,
|
|
197
|
+
content=content,
|
|
198
|
+
loaded=True,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
except ToolError:
|
|
202
|
+
raise
|
|
203
|
+
except Exception as e:
|
|
204
|
+
raise ToolError(f"Failed to load skill: {e}") from e
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""MCP Resource tools — list and read MCP server resources.
|
|
2
|
+
|
|
3
|
+
MCP servers can expose resources (files, data) in addition to tools.
|
|
4
|
+
These tools let the agent discover and read them.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
from collections.abc import AsyncGenerator
|
|
11
|
+
from typing import ClassVar, final
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, Field
|
|
14
|
+
|
|
15
|
+
from drydock.core.tools.base import (
|
|
16
|
+
BaseTool, BaseToolConfig, BaseToolState, InvokeContext, ToolError, ToolPermission,
|
|
17
|
+
)
|
|
18
|
+
from drydock.core.tools.ui import ToolCallDisplay, ToolResultDisplay, ToolUIData
|
|
19
|
+
from drydock.core.types import ToolStreamEvent, ToolResultEvent
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ListMcpResourcesArgs(BaseModel):
|
|
23
|
+
server_name: str = Field(default="", description="MCP server name (empty = all servers)")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class McpResource(BaseModel):
|
|
27
|
+
uri: str
|
|
28
|
+
name: str
|
|
29
|
+
description: str = ""
|
|
30
|
+
mime_type: str = ""
|
|
31
|
+
server: str = ""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ListMcpResourcesResult(BaseModel):
|
|
35
|
+
resources: list[McpResource]
|
|
36
|
+
count: int
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ListMcpResources(
|
|
40
|
+
BaseTool[ListMcpResourcesArgs, ListMcpResourcesResult, BaseToolConfig, BaseToolState],
|
|
41
|
+
ToolUIData[ListMcpResourcesArgs, ListMcpResourcesResult],
|
|
42
|
+
):
|
|
43
|
+
description: ClassVar[str] = "List resources available from MCP servers."
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def format_call_display(cls, args: ListMcpResourcesArgs) -> ToolCallDisplay:
|
|
47
|
+
return ToolCallDisplay(summary=f"list_mcp_resources: {args.server_name or 'all'}")
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def get_result_display(cls, event: ToolResultEvent) -> ToolResultDisplay:
|
|
51
|
+
if isinstance(event.result, ListMcpResourcesResult):
|
|
52
|
+
return ToolResultDisplay(success=True, message=f"{event.result.count} resources")
|
|
53
|
+
return ToolResultDisplay(success=True, message="Resources listed")
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def get_status_text(cls) -> str:
|
|
57
|
+
return "Listing MCP resources"
|
|
58
|
+
|
|
59
|
+
def resolve_permission(self, args: ListMcpResourcesArgs) -> ToolPermission | None:
|
|
60
|
+
return ToolPermission.ALWAYS
|
|
61
|
+
|
|
62
|
+
@final
|
|
63
|
+
async def run(
|
|
64
|
+
self, args: ListMcpResourcesArgs, ctx: InvokeContext | None = None
|
|
65
|
+
) -> AsyncGenerator[ToolStreamEvent | ListMcpResourcesResult, None]:
|
|
66
|
+
resources: list[McpResource] = []
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
if ctx and hasattr(ctx, 'agent_manager') and ctx.agent_manager:
|
|
70
|
+
config = ctx.agent_manager.config
|
|
71
|
+
servers = config.mcp_servers or []
|
|
72
|
+
|
|
73
|
+
from drydock.core.tools.mcp.tools import (
|
|
74
|
+
list_resources_http, list_resources_stdio,
|
|
75
|
+
)
|
|
76
|
+
from drydock.core.config import MCPStdio, MCPHttp
|
|
77
|
+
|
|
78
|
+
tasks = []
|
|
79
|
+
for srv in servers:
|
|
80
|
+
if args.server_name and getattr(srv, 'alias', '') != args.server_name:
|
|
81
|
+
continue
|
|
82
|
+
if isinstance(srv, MCPHttp):
|
|
83
|
+
tasks.append(list_resources_http(
|
|
84
|
+
srv.url,
|
|
85
|
+
headers=srv.headers,
|
|
86
|
+
startup_timeout_sec=srv.startup_timeout_seconds,
|
|
87
|
+
))
|
|
88
|
+
elif isinstance(srv, MCPStdio):
|
|
89
|
+
tasks.append(list_resources_stdio(
|
|
90
|
+
srv.command,
|
|
91
|
+
env=srv.env,
|
|
92
|
+
startup_timeout_sec=srv.startup_timeout_seconds,
|
|
93
|
+
))
|
|
94
|
+
|
|
95
|
+
if tasks:
|
|
96
|
+
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
97
|
+
for result in results:
|
|
98
|
+
if isinstance(result, list):
|
|
99
|
+
for r in result:
|
|
100
|
+
resources.append(McpResource(
|
|
101
|
+
uri=r.uri, name=r.name,
|
|
102
|
+
description=r.description,
|
|
103
|
+
mime_type=r.mime_type,
|
|
104
|
+
server=r.server,
|
|
105
|
+
))
|
|
106
|
+
except Exception as e:
|
|
107
|
+
raise ToolError(f"Failed to list MCP resources: {e}") from e
|
|
108
|
+
|
|
109
|
+
yield ListMcpResourcesResult(resources=resources, count=len(resources))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ReadMcpResourceArgs(BaseModel):
|
|
113
|
+
uri: str = Field(description="Resource URI to read")
|
|
114
|
+
server_name: str = Field(default="", description="MCP server name (required if multiple servers)")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ReadMcpResourceResult(BaseModel):
|
|
118
|
+
uri: str
|
|
119
|
+
content: str
|
|
120
|
+
mime_type: str = ""
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class ReadMcpResource(
|
|
124
|
+
BaseTool[ReadMcpResourceArgs, ReadMcpResourceResult, BaseToolConfig, BaseToolState],
|
|
125
|
+
ToolUIData[ReadMcpResourceArgs, ReadMcpResourceResult],
|
|
126
|
+
):
|
|
127
|
+
description: ClassVar[str] = "Read a resource from an MCP server by URI."
|
|
128
|
+
|
|
129
|
+
@classmethod
|
|
130
|
+
def format_call_display(cls, args: ReadMcpResourceArgs) -> ToolCallDisplay:
|
|
131
|
+
return ToolCallDisplay(summary=f"read_mcp_resource: {args.uri[:50]}")
|
|
132
|
+
|
|
133
|
+
@classmethod
|
|
134
|
+
def get_result_display(cls, event: ToolResultEvent) -> ToolResultDisplay:
|
|
135
|
+
return ToolResultDisplay(success=True, message="Resource read")
|
|
136
|
+
|
|
137
|
+
@classmethod
|
|
138
|
+
def get_status_text(cls) -> str:
|
|
139
|
+
return "Reading MCP resource"
|
|
140
|
+
|
|
141
|
+
def resolve_permission(self, args: ReadMcpResourceArgs) -> ToolPermission | None:
|
|
142
|
+
return ToolPermission.ALWAYS
|
|
143
|
+
|
|
144
|
+
@final
|
|
145
|
+
async def run(
|
|
146
|
+
self, args: ReadMcpResourceArgs, ctx: InvokeContext | None = None
|
|
147
|
+
) -> AsyncGenerator[ToolStreamEvent | ReadMcpResourceResult, None]:
|
|
148
|
+
if not ctx or not hasattr(ctx, 'agent_manager') or not ctx.agent_manager:
|
|
149
|
+
raise ToolError("No agent manager available for MCP resource reading")
|
|
150
|
+
|
|
151
|
+
config = ctx.agent_manager.config
|
|
152
|
+
servers = config.mcp_servers or []
|
|
153
|
+
|
|
154
|
+
if not servers:
|
|
155
|
+
raise ToolError("No MCP servers configured. Add servers to ~/.drydock/config.toml")
|
|
156
|
+
|
|
157
|
+
from drydock.core.tools.mcp.tools import read_resource_http, read_resource_stdio
|
|
158
|
+
from drydock.core.config import MCPStdio, MCPHttp
|
|
159
|
+
|
|
160
|
+
# Try each server until we find the resource
|
|
161
|
+
last_error = None
|
|
162
|
+
for srv in servers:
|
|
163
|
+
if args.server_name and getattr(srv, 'alias', '') != args.server_name:
|
|
164
|
+
continue
|
|
165
|
+
try:
|
|
166
|
+
if isinstance(srv, MCPHttp):
|
|
167
|
+
content = await read_resource_http(
|
|
168
|
+
srv.url, args.uri,
|
|
169
|
+
headers=srv.headers,
|
|
170
|
+
startup_timeout_sec=srv.startup_timeout_seconds,
|
|
171
|
+
)
|
|
172
|
+
elif isinstance(srv, MCPStdio):
|
|
173
|
+
content = await read_resource_stdio(
|
|
174
|
+
srv.command, args.uri,
|
|
175
|
+
env=srv.env,
|
|
176
|
+
startup_timeout_sec=srv.startup_timeout_seconds,
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
continue
|
|
180
|
+
|
|
181
|
+
yield ReadMcpResourceResult(
|
|
182
|
+
uri=args.uri,
|
|
183
|
+
content=content,
|
|
184
|
+
mime_type="",
|
|
185
|
+
)
|
|
186
|
+
return
|
|
187
|
+
except Exception as e:
|
|
188
|
+
last_error = e
|
|
189
|
+
continue
|
|
190
|
+
|
|
191
|
+
raise ToolError(
|
|
192
|
+
f"Could not read resource '{args.uri}' from any MCP server. "
|
|
193
|
+
f"Last error: {last_error}"
|
|
194
|
+
)
|
|
@@ -410,3 +410,109 @@ def create_mcp_stdio_proxy_tool_class(
|
|
|
410
410
|
|
|
411
411
|
MCPStdioProxyTool.__name__ = f"MCP_STDIO_{computed_alias}__{remote.name}"
|
|
412
412
|
return MCPStdioProxyTool
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
# ── MCP Resource listing/reading ─────────────────────────────────────────
|
|
416
|
+
|
|
417
|
+
class MCPResource:
|
|
418
|
+
"""Simple container for an MCP resource."""
|
|
419
|
+
def __init__(self, uri: str, name: str, description: str = "", mime_type: str = "", server: str = ""):
|
|
420
|
+
self.uri = uri
|
|
421
|
+
self.name = name
|
|
422
|
+
self.description = description
|
|
423
|
+
self.mime_type = mime_type
|
|
424
|
+
self.server = server
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
async def list_resources_http(
|
|
428
|
+
url: str,
|
|
429
|
+
*,
|
|
430
|
+
headers: dict[str, str] | None = None,
|
|
431
|
+
startup_timeout_sec: float | None = None,
|
|
432
|
+
) -> list[MCPResource]:
|
|
433
|
+
timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
|
|
434
|
+
async with streamablehttp_client(url, headers=headers) as (read, write, _):
|
|
435
|
+
async with ClientSession(read, write, read_timeout_seconds=timeout) as session:
|
|
436
|
+
await session.initialize()
|
|
437
|
+
resp = await session.list_resources()
|
|
438
|
+
return [
|
|
439
|
+
MCPResource(
|
|
440
|
+
uri=str(r.uri), name=r.name,
|
|
441
|
+
description=getattr(r, 'description', '') or '',
|
|
442
|
+
mime_type=getattr(r, 'mimeType', '') or '',
|
|
443
|
+
server=url,
|
|
444
|
+
)
|
|
445
|
+
for r in resp.resources
|
|
446
|
+
]
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
async def list_resources_stdio(
|
|
450
|
+
command: list[str],
|
|
451
|
+
*,
|
|
452
|
+
env: dict[str, str] | None = None,
|
|
453
|
+
startup_timeout_sec: float | None = None,
|
|
454
|
+
) -> list[MCPResource]:
|
|
455
|
+
params = StdioServerParameters(command=command[0], args=command[1:], env=env)
|
|
456
|
+
timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
|
|
457
|
+
async with (
|
|
458
|
+
_mcp_stderr_capture() as errlog,
|
|
459
|
+
stdio_client(params, errlog=errlog) as (read, write),
|
|
460
|
+
ClientSession(read, write, read_timeout_seconds=timeout) as session,
|
|
461
|
+
):
|
|
462
|
+
await session.initialize()
|
|
463
|
+
resp = await session.list_resources()
|
|
464
|
+
return [
|
|
465
|
+
MCPResource(
|
|
466
|
+
uri=str(r.uri), name=r.name,
|
|
467
|
+
description=getattr(r, 'description', '') or '',
|
|
468
|
+
mime_type=getattr(r, 'mimeType', '') or '',
|
|
469
|
+
server=" ".join(command),
|
|
470
|
+
)
|
|
471
|
+
for r in resp.resources
|
|
472
|
+
]
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
async def read_resource_http(
|
|
476
|
+
url: str,
|
|
477
|
+
resource_uri: str,
|
|
478
|
+
*,
|
|
479
|
+
headers: dict[str, str] | None = None,
|
|
480
|
+
startup_timeout_sec: float | None = None,
|
|
481
|
+
) -> str:
|
|
482
|
+
timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
|
|
483
|
+
async with streamablehttp_client(url, headers=headers) as (read, write, _):
|
|
484
|
+
async with ClientSession(read, write, read_timeout_seconds=timeout) as session:
|
|
485
|
+
await session.initialize()
|
|
486
|
+
resp = await session.read_resource(resource_uri)
|
|
487
|
+
parts = []
|
|
488
|
+
for content in resp.contents:
|
|
489
|
+
if hasattr(content, 'text'):
|
|
490
|
+
parts.append(content.text)
|
|
491
|
+
elif hasattr(content, 'blob'):
|
|
492
|
+
parts.append(f"[binary data: {len(content.blob)} bytes]")
|
|
493
|
+
return "\n".join(parts)
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
async def read_resource_stdio(
|
|
497
|
+
command: list[str],
|
|
498
|
+
resource_uri: str,
|
|
499
|
+
*,
|
|
500
|
+
env: dict[str, str] | None = None,
|
|
501
|
+
startup_timeout_sec: float | None = None,
|
|
502
|
+
) -> str:
|
|
503
|
+
params = StdioServerParameters(command=command[0], args=command[1:], env=env)
|
|
504
|
+
timeout = timedelta(seconds=startup_timeout_sec) if startup_timeout_sec else None
|
|
505
|
+
async with (
|
|
506
|
+
_mcp_stderr_capture() as errlog,
|
|
507
|
+
stdio_client(params, errlog=errlog) as (read, write),
|
|
508
|
+
ClientSession(read, write, read_timeout_seconds=timeout) as session,
|
|
509
|
+
):
|
|
510
|
+
await session.initialize()
|
|
511
|
+
resp = await session.read_resource(resource_uri)
|
|
512
|
+
parts = []
|
|
513
|
+
for content in resp.contents:
|
|
514
|
+
if hasattr(content, 'text'):
|
|
515
|
+
parts.append(content.text)
|
|
516
|
+
elif hasattr(content, 'blob'):
|
|
517
|
+
parts.append(f"[binary data: {len(content.blob)} bytes]")
|
|
518
|
+
return "\n".join(parts)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-design
|
|
3
|
+
description: Design and review REST/GraphQL APIs. Schema validation, endpoint design, error handling patterns.
|
|
4
|
+
allowed-tools: read_file grep glob write_file bash
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# API Design Review
|
|
9
|
+
|
|
10
|
+
Analyze or design an API ($ARGUMENTS).
|
|
11
|
+
|
|
12
|
+
## For existing APIs:
|
|
13
|
+
1. Find route/endpoint definitions
|
|
14
|
+
2. Check for consistency in naming, HTTP methods, status codes
|
|
15
|
+
3. Verify error handling and validation
|
|
16
|
+
4. Check authentication/authorization
|
|
17
|
+
5. Review request/response schemas
|
|
18
|
+
|
|
19
|
+
## For new APIs:
|
|
20
|
+
1. Define resources and relationships
|
|
21
|
+
2. Design endpoints following REST conventions
|
|
22
|
+
3. Define request/response schemas
|
|
23
|
+
4. Plan error codes and messages
|
|
24
|
+
5. Generate OpenAPI/Swagger spec if requested
|
|
25
|
+
|
|
26
|
+
## Best Practices
|
|
27
|
+
- Use plural nouns for resources (/users, not /user)
|
|
28
|
+
- Use HTTP methods correctly (GET=read, POST=create, PUT=update, DELETE=delete)
|
|
29
|
+
- Return appropriate status codes (201 for create, 204 for delete)
|
|
30
|
+
- Use consistent error format: `{"error": {"code": "...", "message": "..."}}`
|
|
31
|
+
- Version the API (/v1/, /v2/)
|
|
32
|
+
- Paginate list endpoints
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commit-code
|
|
3
|
+
description: Create a git commit with a well-crafted message. Stages changes, reviews diff, writes conventional commit.
|
|
4
|
+
allowed-tools: bash read_file grep
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Commit Workflow
|
|
9
|
+
|
|
10
|
+
1. Run `git status` and `git diff --stat` to see what changed
|
|
11
|
+
2. Run `git diff` to read the actual changes (limit to 200 lines)
|
|
12
|
+
3. Write a commit message following conventional commits:
|
|
13
|
+
- `fix:` for bug fixes
|
|
14
|
+
- `feat:` for new features
|
|
15
|
+
- `refactor:` for refactoring
|
|
16
|
+
- `docs:` for documentation
|
|
17
|
+
- `test:` for test changes
|
|
18
|
+
- `chore:` for maintenance
|
|
19
|
+
4. Stage relevant files with `git add` (specific files, not -A)
|
|
20
|
+
5. Create the commit with `git commit -m "message"`
|
|
21
|
+
6. Show `git log --oneline -3` to confirm
|
|
22
|
+
|
|
23
|
+
Rules:
|
|
24
|
+
- NEVER commit .env, credentials, or secrets
|
|
25
|
+
- Keep the first line under 72 characters
|
|
26
|
+
- Add a body if the change is complex
|
|
27
|
+
- If $ARGUMENTS is provided, use it as context for the commit message
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-summary
|
|
3
|
+
description: Summarize the current session context. What files were read, edited, what's the current state.
|
|
4
|
+
allowed-tools: bash read_file
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Context Summary
|
|
9
|
+
|
|
10
|
+
Produce a summary of the current working state:
|
|
11
|
+
|
|
12
|
+
1. **Git status**: `git status --short`
|
|
13
|
+
2. **Recent changes**: `git diff --stat`
|
|
14
|
+
3. **Recent commits**: `git log --oneline -5`
|
|
15
|
+
4. **Modified files**: List files changed in this session
|
|
16
|
+
5. **Current task**: What was the user's original request?
|
|
17
|
+
6. **Progress**: What's been done, what remains?
|
|
18
|
+
|
|
19
|
+
Output as a clean summary the user can quickly scan.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deploy
|
|
3
|
+
description: Deployment workflow. Build, test, tag, push, deploy. Supports PyPI, Docker, GitHub releases.
|
|
4
|
+
allowed-tools: bash read_file grep
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Deployment Workflow
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
1. Run tests: `python -m pytest -x -q`
|
|
12
|
+
2. Check version in pyproject.toml or setup.py
|
|
13
|
+
3. Build: `python -m build` or `docker build .`
|
|
14
|
+
4. Deploy based on target ($ARGUMENTS):
|
|
15
|
+
- **pypi**: `twine upload dist/*`
|
|
16
|
+
- **docker**: `docker push`
|
|
17
|
+
- **github**: `gh release create`
|
|
18
|
+
- **server**: `rsync` or `ssh` deploy
|
|
19
|
+
5. Tag: `git tag vX.Y.Z && git push --tags`
|
|
20
|
+
6. Notify: output deployment summary
|
|
21
|
+
|
|
22
|
+
## Rules
|
|
23
|
+
- ALWAYS run tests before deploying
|
|
24
|
+
- NEVER deploy with uncommitted changes
|
|
25
|
+
- Check that version was bumped
|
|
26
|
+
- Verify the deployment succeeded
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diff-review
|
|
3
|
+
description: Show and analyze uncommitted changes. Summarize what changed and why.
|
|
4
|
+
allowed-tools: bash read_file
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Diff Review
|
|
9
|
+
|
|
10
|
+
1. Show uncommitted changes: `git diff --stat`
|
|
11
|
+
2. Show the full diff: `git diff`
|
|
12
|
+
3. For each changed file, analyze:
|
|
13
|
+
- What was the intent of the change?
|
|
14
|
+
- Is the change correct and complete?
|
|
15
|
+
- Any issues or improvements?
|
|
16
|
+
4. Provide a summary suitable for a commit message
|