ha-mcp-dev 8.5.0.dev2725__tar.gz → 8.5.0.dev2726__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.
- {ha_mcp_dev-8.5.0.dev2725/src/ha_mcp_dev.egg-info → ha_mcp_dev-8.5.0.dev2726}/PKG-INFO +1 -1
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/pyproject.toml +1 -1
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/client/websocket_client.py +227 -2
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/approval_queue.py +94 -25
- ha_mcp_dev-8.5.0.dev2726/src/ha_mcp/policy/decision_pin.py +277 -0
- ha_mcp_dev-8.5.0.dev2726/src/ha_mcp/policy/decisions.py +556 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/editing.py +32 -0
- ha_mcp_dev-8.5.0.dev2726/src/ha_mcp/policy/events.py +241 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/handlers.py +168 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/middleware.py +128 -2
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/model.py +7 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/server.py +107 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/__init__.py +24 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/en.json +19 -1
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/settings.html +69 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/settings.js +107 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/stdio_settings_sidecar.py +18 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_dev.py +7 -2
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_security_policy.py +9 -3
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp_dev.egg-info/SOURCES.txt +3 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/LICENSE +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/MANIFEST.in +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/setup.cfg +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_rich_compat.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/LICENSE +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/REQUIRES.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/VENDORED +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/_compat.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/_install_hints.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/_warnings.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/app.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/approval.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/choice.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/config.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/file_upload.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/form.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/apps/generative.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/__main__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/apps_dev.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/cimd.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/cli.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/authentication.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/command.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/configuration.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/credentials.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/horizon_client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/output.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/deploy/state.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/discovery.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/generate.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/claude_code.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/claude_desktop.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/cursor.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/gemini_cli.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/goose.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/mcp_json.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/shared.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/install/stdio.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/cli/run.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/_sdk_context_shim.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/auth/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/auth/bearer.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/auth/client_credentials.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/auth/oauth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/caching.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/dependencies.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/elicitation.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/extension_hooks.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/group.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/logging.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/messages.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/mixins/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/mixins/prompts.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/mixins/resources.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/mixins/tools.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/oauth_callback.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/progress.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/roots.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/sampling/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/anthropic.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/google_genai.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/openai.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/telemetry.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/config.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/http.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/inference.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/memory.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/sse.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/client/transports/stdio.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/component_manager.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/example.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/decorators.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/dependencies.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/exceptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/experimental/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/experimental/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/experimental/transforms/code_mode.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/mcp_config.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/prompts/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/prompts/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/prompts/function_prompt.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/py.typed +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/resources/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/resources/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/resources/function_resource.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/resources/security.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/resources/template.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/resources/types.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/cimd.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/handlers/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/handlers/authorize.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/identity_assertion.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/jwt_issuer.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/middleware.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/consent.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/models.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/proxy.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/ui.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/upstream.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/oidc_proxy.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/auth0.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/aws.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/azure.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/clerk.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/debug.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/descope.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/discord.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/github.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/google.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/huggingface.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/in_memory.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/introspection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/jwt.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/keycloak.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/oci.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/propelauth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/scalekit.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/supabase.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/workos.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/redirect_validation.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/auth/ssrf.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/caching.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/completions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/context.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/dependencies.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/elicitation.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/event_store.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/extensions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/http.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/lifespan.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/low_level.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/authorization.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/caching.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/dereference.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/error_handling.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/logging.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/middleware.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/ping.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/rate_limiting.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/response_limiting.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/timing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/middleware/tool_injection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/mixins/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/mixins/lifespan.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/mixins/mcp_operations.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/mixins/transport.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/addressing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/aggregate.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/fastmcp_provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/filesystem.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/filesystem_discovery.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/prompts.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/resources.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/tools.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/local_provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/components.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/routing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/prefab_payload.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/prefab_synthesis.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/proxy.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/_common.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/claude_provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/directory_provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/skill_provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/vendor_providers.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/providers/wrapped_provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/session_scoped_event_store.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/sessions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/telemetry.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/catalog.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/namespace.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/prompts_as_tools.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/resources_as_tools.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/bm25.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/regex.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/tool_transform.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/version_filter.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/server/transforms/visibility.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/settings.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/telemetry.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/tools/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/tools/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/tools/function_parsing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/tools/function_tool.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/tools/tool_transform.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/types.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/asgi_transport.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/async_utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/authorization.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/cli.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/components.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/docstring_parsing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/exceptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/http.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/inspect.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/json_schema.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/json_schema_type.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/lifespan.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/logging.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/environments/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/environments/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/environments/uv.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/schema.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/sources/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/sources/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/mime.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/director.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/formatters.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/json_schema_converter.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/models.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/parser.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/schemas.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/pagination.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/prefab.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/skills.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/tasks.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/tests.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/timeout.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/token_cache.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/types.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/ui.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/version_check.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/fastmcp/utilities/versions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/LICENSE +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/REQUIRES.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/VENDORED +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/cli/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/cli/claude.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/cli/cli.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/__main__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/_input_required.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/_memory.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/_probe.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/_transport.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/auth/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/auth/exceptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/auth/extensions/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/auth/extensions/client_credentials.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/auth/extensions/identity_assertion.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/auth/oauth2.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/auth/utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/caching.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/context.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/extension.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/session.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/session_group.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/sse.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/stdio.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/streamable_http.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/client/subscriptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/os/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/os/posix/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/os/posix/utilities.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/os/win32/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/os/win32/utilities.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/py.typed +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/__main__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/_otel.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/_streamable_http_modern.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/apps.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/errors.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/handlers/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/handlers/authorize.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/handlers/metadata.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/handlers/register.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/handlers/revoke.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/handlers/token.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/json_response.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/middleware/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/middleware/auth_context.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/middleware/bearer_auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/middleware/client_auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/routes.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/auth/settings.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/caching.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/connection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/context.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/elicitation.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/extension.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/fastmcp.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/lowlevel/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/lowlevel/helper_types.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/lowlevel/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/context.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/exceptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/prompts/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/prompts/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/prompts/manager.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/resolve.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/resource_manager.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/templates.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/types.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/tools/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/tools/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/tools/tool_manager.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/context_injection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/func_metadata.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/logging.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/types.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/models.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/request_state.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/runner.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/session.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/sse.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/stdio.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/streamable_http.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/streamable_http_manager.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/subscriptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/transport_security.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/server/validation.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/_callable_inspection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/_compat.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/_context_streams.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/_httpx_utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/_otel.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/_stream_protocols.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/auth_utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/context.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/direct_dispatcher.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/dispatcher.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/exceptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/extension.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/inbound.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/jsonrpc_dispatcher.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/memory.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/message.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/metadata_utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/path_security.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/peer.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/subscriptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/tool_name_validation.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/transport_context.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/shared/uri_template.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/types/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/types/jsonrpc.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/types/methods.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp/types/version.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/LICENSE +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/REQUIRES.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/VENDORED +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/_types.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/_v2025_11_25/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/_v2026_07_28/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/_wire_base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/jsonrpc.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/methods.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/py.typed +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/mcp_types/version.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/requirements.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/LICENSE +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/VENDORED +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/__main__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/asyncio/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/asyncio/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/asyncio/connection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/asyncio/messages.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/asyncio/router.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/asyncio/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/cli.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/connection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/datastructures.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/exceptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/extensions/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/extensions/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/extensions/permessage_deflate.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/frames.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/headers.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/http11.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/imports.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/auth.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/exceptions.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/framing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/handshake.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/http.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/protocol.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/legacy/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/protocol.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/proxy.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/py.typed +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/streams.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/sync/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/sync/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/sync/connection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/sync/messages.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/sync/router.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/sync/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/sync/utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/trio/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/trio/client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/trio/connection.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/trio/messages.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/trio/router.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/trio/server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/trio/utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/typing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/uri.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/utils.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_vendor/websockets/version.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/auth/oidc_compat.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/browser_landing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/ha_request_queue.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/hacs_auto_refresh.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/http_transport.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/llm_exposure.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/log_filters.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/redaction.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/renamed_tools.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/area-target-over-entity-list/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/arrive-home-automation/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/assist-shortcut-card/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/avg-temperature/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/backup-deletion-confirmation/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/blueprint-authoring/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/button-event-entity/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/device-id-trigger-migration/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/helper-flow-fields-not-platform-yaml/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/media-player-song/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/motion-light-automation-mode/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/rename-entity-impact-analysis/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/template-attributes-yaml-exception/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/timer-finished-automation/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/evals/vacuum-last-clean/case.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/scripts/check_eval_cases.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/backups.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_i18n.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_locale_policy.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_persistence.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_theme.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/README.md +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/az.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/cs.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/de.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/eo.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/es.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/fr.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/it.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/ko.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/nl.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/pl.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/sv.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/tlh.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/zh-Hans.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/locales/zh-Hant.json +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/strict_bps.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tool_dispatch.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/best_practice_result.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/best_practice_variables.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/blueprint_sources.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/blueprint_substitute.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/blueprint_write.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/bulk_selector.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/component_api.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/component_config_entries.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/component_config_reads.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/component_dashboard_edit.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/component_devices.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/component_registries.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/config_entry_flow_form.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/config_entry_flow_menu.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/config_entry_flow_walker.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/config_entry_identity.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/config_entry_reconfigure.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/config_entry_reload_watch.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/dashboard_edit_errors.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/entity_registration.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/error_log_parsing.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/hacs_registration.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/integration_reconfigure.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/log_common.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/log_sources.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/log_sources_fault.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/log_sources_supervisor.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/renamed_tool_middleware.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/scene_discovery.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_graph.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_assist_pipeline.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_logs.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/transforms/component_search.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/transforms/write_tool_note.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/transport_security.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/config_write_lock.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/dashboard_patch.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/device_registry_semantics.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/entity_membership.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/mcp_client_host.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/registry_update_lock.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/visibility/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/visibility/enforcement.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/visibility/model.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/visibility/persistence.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp/visibility/resolver.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/tests/__init__.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/tests/test_constants.py +0 -0
- {ha_mcp_dev-8.5.0.dev2725 → ha_mcp_dev-8.5.0.dev2726}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "8.5.0.
|
|
7
|
+
version = "8.5.0.dev2726"
|
|
8
8
|
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# Upper bound widened to <3.15 so the package installs on Home Assistant's
|
|
@@ -15,10 +15,12 @@ import logging
|
|
|
15
15
|
import ssl
|
|
16
16
|
import time
|
|
17
17
|
from collections import defaultdict
|
|
18
|
-
from collections.abc import Awaitable, Callable
|
|
18
|
+
from collections.abc import Awaitable, Callable, Coroutine
|
|
19
19
|
from typing import Any
|
|
20
20
|
from urllib.parse import urlparse
|
|
21
21
|
|
|
22
|
+
import anyio
|
|
23
|
+
|
|
22
24
|
# The vendored copy, NEVER the shared site-packages one: inside Home
|
|
23
25
|
# Assistant that copy is unowned — ~20 integration libraries drag it in with
|
|
24
26
|
# conflicting version demands and any of their installs can replace or tear
|
|
@@ -46,6 +48,28 @@ logger = logging.getLogger(__name__)
|
|
|
46
48
|
# overflowed the previous 20MB cap (#1721).
|
|
47
49
|
MAX_WS_MESSAGE_BYTES = 64 * 1024 * 1024
|
|
48
50
|
|
|
51
|
+
|
|
52
|
+
# How long a cancellation path waits for its own cleanup. Bounded because
|
|
53
|
+
# the caller is already being torn down and must not be held indefinitely;
|
|
54
|
+
# awaited rather than abandoned because a cleanup that outlives its call
|
|
55
|
+
# acts on whatever the client looks like later, not on what it was cleaning
|
|
56
|
+
# up. Matches the theme-guard session close, which solves the same problem.
|
|
57
|
+
CLEANUP_TIMEOUT_SECONDS = 2.0
|
|
58
|
+
|
|
59
|
+
# Structured error codes that mean the subscription is already gone, which
|
|
60
|
+
# is the ordinary outcome when releasing one that was abandoned before Home
|
|
61
|
+
# Assistant registered it. Everything else is a refusal of the release, and
|
|
62
|
+
# leaves the subscription open.
|
|
63
|
+
#
|
|
64
|
+
# An absent code counts as gone rather than as a refusal. Home Assistant's
|
|
65
|
+
# unsubscribe handler answers either success or not_found and nothing else,
|
|
66
|
+
# so for THIS command an error without a structured code is still that same
|
|
67
|
+
# answer from a build that did not send one. The codes worth distinguishing
|
|
68
|
+
# -- unauthorised, malformed, unknown command -- come from the layer above
|
|
69
|
+
# the handler and do carry one. Treating a missing code as a refusal would
|
|
70
|
+
# put a warning on the routine path, which fires on every cancelled
|
|
71
|
+
# subscribe.
|
|
72
|
+
_SUBSCRIPTION_GONE_CODES = frozenset({"not_found"})
|
|
49
73
|
# How long :meth:`HomeAssistantWebSocketClient.send_command` waits for a reply
|
|
50
74
|
# when the caller names no ``_wait_timeout``. Named rather than inlined because
|
|
51
75
|
# callers that schedule retries have to budget around it: a caller whose retry
|
|
@@ -53,6 +77,49 @@ MAX_WS_MESSAGE_BYTES = 64 * 1024 * 1024
|
|
|
53
77
|
# later than it planned when the command hangs instead.
|
|
54
78
|
DEFAULT_COMMAND_WAIT_TIMEOUT = 30.0
|
|
55
79
|
|
|
80
|
+
# Field names whose value must never reach the log, matched case-insensitively
|
|
81
|
+
# wherever they appear in a received frame. The approval-response event carries
|
|
82
|
+
# the user's approval PIN in ``event.data.pin`` (issue #2502), and the debug
|
|
83
|
+
# line below prints whole decoded frames -- so without this, turning on debug
|
|
84
|
+
# logging would write that PIN into Home Assistant's log in clear text.
|
|
85
|
+
_REDACTED_LOG_FIELDS = frozenset({"pin"})
|
|
86
|
+
_REDACTED_PLACEHOLDER = "<redacted>"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _redacted_for_log(value: Any) -> Any:
|
|
90
|
+
"""A copy of ``value`` with ``_REDACTED_LOG_FIELDS`` masked.
|
|
91
|
+
|
|
92
|
+
Only for logging: the caller keeps handling the original, so redaction
|
|
93
|
+
cannot change what the client does with a frame -- verification still
|
|
94
|
+
sees the real PIN. Containers are rebuilt rather than mutated for the
|
|
95
|
+
same reason. Anything that is not a dict or a list is returned as it
|
|
96
|
+
is, which is why this stays cheap enough to run per frame; the caller
|
|
97
|
+
runs it only when DEBUG is actually enabled.
|
|
98
|
+
"""
|
|
99
|
+
if isinstance(value, dict):
|
|
100
|
+
return {
|
|
101
|
+
key: (
|
|
102
|
+
_REDACTED_PLACEHOLDER
|
|
103
|
+
if isinstance(key, str) and key.lower() in _REDACTED_LOG_FIELDS
|
|
104
|
+
else _redacted_for_log(item)
|
|
105
|
+
)
|
|
106
|
+
for key, item in value.items()
|
|
107
|
+
}
|
|
108
|
+
if isinstance(value, list):
|
|
109
|
+
return [_redacted_for_log(item) for item in value]
|
|
110
|
+
return value
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _log_received_frame(data: Any) -> None:
|
|
114
|
+
"""Debug-log one received frame, with secret fields masked.
|
|
115
|
+
|
|
116
|
+
Its own function so the redaction cannot cost the message loop a
|
|
117
|
+
branch it does not need: the guard keeps the copy from being built at
|
|
118
|
+
all when DEBUG is off, which is every production deployment.
|
|
119
|
+
"""
|
|
120
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
121
|
+
logger.debug("WebSocket received: %s", _redacted_for_log(data))
|
|
122
|
+
|
|
56
123
|
|
|
57
124
|
def _extract_ws_error(error: Any) -> tuple[str, str | None]:
|
|
58
125
|
"""Split an HA WebSocket ``error`` payload into ``(message, code)``.
|
|
@@ -419,6 +486,19 @@ class HomeAssistantWebSocketClient:
|
|
|
419
486
|
await self.disconnect()
|
|
420
487
|
return False
|
|
421
488
|
|
|
489
|
+
except BaseException:
|
|
490
|
+
# Everything that is not an ``Exception`` -- a cancellation above
|
|
491
|
+
# all -- used to skip the clause above entirely, leaving the
|
|
492
|
+
# reader task started earlier and the open socket behind with
|
|
493
|
+
# nothing tracking them: the pool only takes the client once
|
|
494
|
+
# connect has returned True, so nothing else would ever close
|
|
495
|
+
# them. Ordered after the ``Exception`` handler so the ordinary
|
|
496
|
+
# failure path is unchanged, and it re-raises unconditionally --
|
|
497
|
+
# only the tidying happens here, and it is bounded because
|
|
498
|
+
# awaiting it plainly would be cancelled in turn.
|
|
499
|
+
await self._run_cleanup(self.disconnect(), "cancelled connect")
|
|
500
|
+
raise
|
|
501
|
+
|
|
422
502
|
async def disconnect(self) -> None:
|
|
423
503
|
"""Disconnect from WebSocket."""
|
|
424
504
|
if self.background_task:
|
|
@@ -473,7 +553,7 @@ class HomeAssistantWebSocketClient:
|
|
|
473
553
|
async for message in self.websocket:
|
|
474
554
|
try:
|
|
475
555
|
data = json.loads(message)
|
|
476
|
-
|
|
556
|
+
_log_received_frame(data)
|
|
477
557
|
await self._process_message(data)
|
|
478
558
|
except json.JSONDecodeError as e:
|
|
479
559
|
logger.error(f"Invalid JSON received: {e}")
|
|
@@ -854,7 +934,21 @@ class HomeAssistantWebSocketClient:
|
|
|
854
934
|
except BaseException:
|
|
855
935
|
# Cancellation mid-send: skips the clause above and would leave the
|
|
856
936
|
# pending future registered — drop it before propagating.
|
|
937
|
+
#
|
|
938
|
+
# And a cancelled send is not proof that Home Assistant received
|
|
939
|
+
# nothing. The vendored implementation writes the frame before it
|
|
940
|
+
# awaits flow-control drainage, so a cancellation landing in that
|
|
941
|
+
# wait can leave the subscription registered on a socket this
|
|
942
|
+
# process keeps using -- the same orphan the acknowledgment path
|
|
943
|
+
# below releases, reached one await earlier. The id is allocated
|
|
944
|
+
# before the send, so it is still known here; an unsubscribe for
|
|
945
|
+
# something that was never registered answers not_found, which
|
|
946
|
+
# the release treats as its ordinary outcome.
|
|
857
947
|
self.cancel_pending_response(message_id)
|
|
948
|
+
await self._run_cleanup(
|
|
949
|
+
self._release_abandoned_subscription(message_id),
|
|
950
|
+
f"abandoned subscribe_events({message_id})",
|
|
951
|
+
)
|
|
858
952
|
raise
|
|
859
953
|
|
|
860
954
|
try:
|
|
@@ -864,7 +958,16 @@ class HomeAssistantWebSocketClient:
|
|
|
864
958
|
# resolves once the caller is gone. The cleanup is
|
|
865
959
|
# exception-type-independent and the original exception re-raises
|
|
866
960
|
# unchanged.
|
|
961
|
+
#
|
|
962
|
+
# The command is already on the wire by this point, so Home
|
|
963
|
+
# Assistant may well have registered the subscription: releasing
|
|
964
|
+
# it is this operation's job, not the caller's, because the id it
|
|
965
|
+
# needs is the one the caller never receives.
|
|
867
966
|
self.cancel_pending_response(message_id)
|
|
967
|
+
await self._run_cleanup(
|
|
968
|
+
self._release_abandoned_subscription(message_id),
|
|
969
|
+
f"abandoned subscribe_events({message_id})",
|
|
970
|
+
)
|
|
868
971
|
raise
|
|
869
972
|
|
|
870
973
|
if response.get("type") == "result" and response.get("success"):
|
|
@@ -916,6 +1019,128 @@ class HomeAssistantWebSocketClient:
|
|
|
916
1019
|
e,
|
|
917
1020
|
)
|
|
918
1021
|
|
|
1022
|
+
async def _run_cleanup(self, coro: Coroutine[Any, Any, None], what: str) -> None:
|
|
1023
|
+
"""Run ``coro`` to completion or to a deadline, from a cancelled path.
|
|
1024
|
+
|
|
1025
|
+
Cleanup scheduled while a cancellation is propagating cannot simply
|
|
1026
|
+
be awaited: the await is cancelled in turn, and under a cancel scope
|
|
1027
|
+
again at every suspension, so the tidying never happens. It also
|
|
1028
|
+
must not merely be detached. A detached task reads the client's
|
|
1029
|
+
state when it eventually runs, not when it was scheduled, so a
|
|
1030
|
+
second ``connect()`` on the same object races it -- measured, the
|
|
1031
|
+
stale task closed the NEW socket and left the old one open, the
|
|
1032
|
+
exact failure this cleanup exists to prevent.
|
|
1033
|
+
|
|
1034
|
+
So the work is owned by a task, which makes it survive the
|
|
1035
|
+
cancellation, and awaited through a shield with a deadline, which
|
|
1036
|
+
makes it finish before control returns to anyone. The same shape as
|
|
1037
|
+
the theme-guard session cleanup, for the same reason.
|
|
1038
|
+
|
|
1039
|
+
The shield holds against an anyio cancel scope, which is the shape
|
|
1040
|
+
this is reached under. A plain ``asyncio.Task.cancel()`` -- what
|
|
1041
|
+
``asyncio.timeout`` issues -- goes through it: measured, the wait
|
|
1042
|
+
below then ends at the caller's deadline with the cleanup untouched.
|
|
1043
|
+
"""
|
|
1044
|
+
task = asyncio.ensure_future(coro)
|
|
1045
|
+
# Shielded with anyio's scope rather than asyncio's, and around the
|
|
1046
|
+
# WAIT as much as around the drain: a cancel scope re-delivers its
|
|
1047
|
+
# cancellation to the HOST TASK on every tick while that task is
|
|
1048
|
+
# still inside it, and ``asyncio.shield`` only governs propagation
|
|
1049
|
+
# from one awaited future -- it does not stop a second ``cancel()``
|
|
1050
|
+
# landing on the task at its next await. Such a scope is how this
|
|
1051
|
+
# method is reached in the first place: the approval listener opens
|
|
1052
|
+
# its subscription inside a ``move_on_after`` setup budget, and a
|
|
1053
|
+
# cancelled ``subscribe_events`` is what calls this. Shielding only
|
|
1054
|
+
# the drain leaves the wait below cancelled on its first tick, and
|
|
1055
|
+
# the ``finally`` then stops the work before it ever had its own
|
|
1056
|
+
# budget -- collecting a task is not the same as letting it finish,
|
|
1057
|
+
# and cleanup that has to suspend (an unsubscribe waiting for the
|
|
1058
|
+
# shared send lock) never reaches its release.
|
|
1059
|
+
#
|
|
1060
|
+
# What this does NOT do is re-deliver the cancellation it shielded:
|
|
1061
|
+
# measured, an enclosing ``move_on_after`` ends with
|
|
1062
|
+
# ``cancelled_caught`` False when this returns normally. Each call
|
|
1063
|
+
# site raises on its way out, and that raise is what delivers the
|
|
1064
|
+
# caller's cancellation -- after the cleanup rather than instead of
|
|
1065
|
+
# it. A caller added on a non-raising path would swallow its own
|
|
1066
|
+
# deadline here.
|
|
1067
|
+
with anyio.CancelScope(shield=True):
|
|
1068
|
+
try:
|
|
1069
|
+
await asyncio.wait_for(
|
|
1070
|
+
asyncio.shield(task), timeout=CLEANUP_TIMEOUT_SECONDS
|
|
1071
|
+
)
|
|
1072
|
+
except (Exception, TimeoutError) as e:
|
|
1073
|
+
logger.debug("%s: cleanup did not finish cleanly: %s", what, e)
|
|
1074
|
+
except asyncio.CancelledError:
|
|
1075
|
+
logger.debug("%s: cleanup cancelled before it finished", what)
|
|
1076
|
+
raise
|
|
1077
|
+
finally:
|
|
1078
|
+
# The inner ``asyncio.shield`` is what lets the deadline
|
|
1079
|
+
# expire without killing the work -- and it is equally what
|
|
1080
|
+
# would let the work outlive this call, which is the failure
|
|
1081
|
+
# being fixed. A task still running here reads the client's
|
|
1082
|
+
# state whenever it gets there, so it must not get there:
|
|
1083
|
+
# stop it, then collect the outcome so a late failure does
|
|
1084
|
+
# not surface as an orphaned "exception was never
|
|
1085
|
+
# retrieved".
|
|
1086
|
+
if not task.done():
|
|
1087
|
+
task.cancel()
|
|
1088
|
+
await asyncio.gather(task, return_exceptions=True)
|
|
1089
|
+
|
|
1090
|
+
async def _release_abandoned_subscription(self, message_id: int) -> None:
|
|
1091
|
+
"""Ask Home Assistant to drop a subscription we can no longer name.
|
|
1092
|
+
|
|
1093
|
+
``subscribe_events`` allocates the message id before sending, so a
|
|
1094
|
+
cancelled call still knows the id Home Assistant would have used --
|
|
1095
|
+
the id is only lost to the *caller*, which never gets its return
|
|
1096
|
+
value. Without this the subscription stays open on a socket this
|
|
1097
|
+
process keeps using, the next attempt opens a second one, and every
|
|
1098
|
+
event is then delivered once per orphan.
|
|
1099
|
+
|
|
1100
|
+
"Subscription not found" is the ordinary outcome here rather than a
|
|
1101
|
+
surprise: the command may never have reached Home Assistant, which
|
|
1102
|
+
is exactly the case that needs no cleanup. It is logged at debug for
|
|
1103
|
+
that reason, where ``unsubscribe_events`` logs a warning -- there,
|
|
1104
|
+
a rejection means a subscription that was known to exist.
|
|
1105
|
+
"""
|
|
1106
|
+
if not self._state.is_ready:
|
|
1107
|
+
logger.debug(
|
|
1108
|
+
"abandoned subscribe_events(%s): socket not ready, nothing to release",
|
|
1109
|
+
message_id,
|
|
1110
|
+
)
|
|
1111
|
+
return
|
|
1112
|
+
try:
|
|
1113
|
+
await self.send_command("unsubscribe_events", subscription=message_id)
|
|
1114
|
+
except OSError as e:
|
|
1115
|
+
logger.debug(
|
|
1116
|
+
"abandoned subscribe_events(%s): transport lost before cleanup: %s",
|
|
1117
|
+
message_id,
|
|
1118
|
+
e,
|
|
1119
|
+
)
|
|
1120
|
+
except HomeAssistantCommandError as e:
|
|
1121
|
+
if e.code is None or e.code in _SUBSCRIPTION_GONE_CODES:
|
|
1122
|
+
logger.debug(
|
|
1123
|
+
"abandoned subscribe_events(%s): Home Assistant has no such "
|
|
1124
|
+
"subscription, so the command did not reach it: %s",
|
|
1125
|
+
message_id,
|
|
1126
|
+
e,
|
|
1127
|
+
)
|
|
1128
|
+
else:
|
|
1129
|
+
# Anything else is a rejection of the unsubscribe itself --
|
|
1130
|
+
# not authorised, malformed, a command this build does not
|
|
1131
|
+
# know. The subscription is then still open on a socket this
|
|
1132
|
+
# process keeps using, which is the leak this method exists
|
|
1133
|
+
# to prevent, so it must not disappear at debug level with
|
|
1134
|
+
# the routine case.
|
|
1135
|
+
logger.warning(
|
|
1136
|
+
"abandoned subscribe_events(%s): Home Assistant refused "
|
|
1137
|
+
"the release (code %s); the subscription may still be "
|
|
1138
|
+
"open: %s",
|
|
1139
|
+
message_id,
|
|
1140
|
+
e.code,
|
|
1141
|
+
e,
|
|
1142
|
+
)
|
|
1143
|
+
|
|
919
1144
|
async def subscribe_command(
|
|
920
1145
|
self,
|
|
921
1146
|
command_type: str,
|
|
@@ -8,6 +8,7 @@ import logging
|
|
|
8
8
|
import secrets
|
|
9
9
|
from dataclasses import dataclass, field
|
|
10
10
|
from datetime import UTC, datetime, timedelta
|
|
11
|
+
from enum import StrEnum
|
|
11
12
|
from typing import Any, Literal
|
|
12
13
|
|
|
13
14
|
import anyio
|
|
@@ -34,6 +35,7 @@ class PendingApproval:
|
|
|
34
35
|
_decision: Decision = "pending"
|
|
35
36
|
_event: anyio.Event = field(default_factory=anyio.Event)
|
|
36
37
|
_claimed: bool = False
|
|
38
|
+
_notified: bool = False
|
|
37
39
|
|
|
38
40
|
@property
|
|
39
41
|
def decision(self) -> Decision:
|
|
@@ -72,11 +74,38 @@ class PendingApproval:
|
|
|
72
74
|
self._claimed = True
|
|
73
75
|
return True
|
|
74
76
|
|
|
77
|
+
def mark_notified(self) -> bool:
|
|
78
|
+
"""Take ownership of announcing this entry. False if already taken.
|
|
79
|
+
|
|
80
|
+
Concurrent identical calls share one entry (``find_or_create``), and
|
|
81
|
+
a caller that joins an existing row must not fire a second Home
|
|
82
|
+
Assistant event for the request the user has already been told
|
|
83
|
+
about. Same one-shot shape as ``claim()``: there is no ``await``
|
|
84
|
+
here, so the check-and-set cannot interleave with another task.
|
|
85
|
+
"""
|
|
86
|
+
if self._notified:
|
|
87
|
+
return False
|
|
88
|
+
self._notified = True
|
|
89
|
+
return True
|
|
90
|
+
|
|
75
91
|
def __post_init__(self) -> None:
|
|
76
92
|
if self.expires_at <= self.created_at:
|
|
77
93
|
raise ValueError("expires_at must be after created_at")
|
|
78
94
|
|
|
79
95
|
|
|
96
|
+
# What a decision did, for a caller that has to report it rather than just
|
|
97
|
+
# branch on it. ``approve``/``deny`` keep returning a bool because that is
|
|
98
|
+
# all their callers in the settings UI and the developer tool ever needed;
|
|
99
|
+
# a decision arriving over the event bus has to say WHY it did not apply,
|
|
100
|
+
# and the queue is the only place that knows. The values are part of the
|
|
101
|
+
# event payload, so they are a stable vocabulary rather than prose.
|
|
102
|
+
class DecisionOutcome(StrEnum):
|
|
103
|
+
APPLIED = "applied"
|
|
104
|
+
EXPIRED = "expired"
|
|
105
|
+
UNKNOWN_TOKEN = "unknown_token"
|
|
106
|
+
ALREADY_DECIDED = "already_decided"
|
|
107
|
+
|
|
108
|
+
|
|
80
109
|
class ApprovalQueue:
|
|
81
110
|
"""In-memory per-process approval queue with args-hash binding.
|
|
82
111
|
|
|
@@ -202,40 +231,80 @@ class ApprovalQueue:
|
|
|
202
231
|
self._sweep_expired()
|
|
203
232
|
return [e for e in self._by_token.values() if e.decision == "pending"]
|
|
204
233
|
|
|
205
|
-
def
|
|
206
|
-
|
|
234
|
+
def decide_with_outcome(
|
|
235
|
+
self, token: str, decision: Literal["approve", "deny"]
|
|
236
|
+
) -> DecisionOutcome:
|
|
237
|
+
"""Decide ``token`` and say what happened, not merely whether it worked.
|
|
238
|
+
|
|
239
|
+
Same work as ``approve``/``deny`` -- those delegate here -- with the
|
|
240
|
+
distinction the logs already draw kept in the return value: a TTL
|
|
241
|
+
that ran out while a phone notification sat unread is a different
|
|
242
|
+
thing from a token nobody ever issued, and a caller that has to
|
|
243
|
+
tell the user which one it was cannot get that from a bool.
|
|
244
|
+
"""
|
|
245
|
+
action = "approve" if decision == "approve" else "deny"
|
|
246
|
+
if self._expire(token, action):
|
|
247
|
+
return DecisionOutcome.EXPIRED
|
|
207
248
|
entry = self._by_token.get(token)
|
|
208
249
|
if entry is None:
|
|
209
250
|
# WARNING because on a security-gating endpoint this means
|
|
210
251
|
# either a UI bug, a stale tab racing the sweeper, or an
|
|
211
|
-
# attacker probing tokens
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
252
|
+
# attacker probing tokens -- operator should see it. An entry
|
|
253
|
+
# that merely ran out of TTL is handled above, at INFO, so a
|
|
254
|
+
# late click on a phone notification does not read as a probe.
|
|
255
|
+
logger.warning("approval_queue.%s: unknown token %s", action, token)
|
|
256
|
+
return DecisionOutcome.UNKNOWN_TOKEN
|
|
257
|
+
if entry.decide("approved" if decision == "approve" else "denied"):
|
|
258
|
+
return DecisionOutcome.APPLIED
|
|
259
|
+
# INFO -- could be a legitimate race (two approvers, or a quick
|
|
260
|
+
# double-click) rather than a security signal.
|
|
261
|
+
logger.info(
|
|
262
|
+
"approval_queue.%s: token %s already decided as %s",
|
|
263
|
+
action,
|
|
264
|
+
token,
|
|
265
|
+
entry.decision,
|
|
266
|
+
)
|
|
267
|
+
return DecisionOutcome.ALREADY_DECIDED
|
|
268
|
+
|
|
269
|
+
def approve(self, token: str) -> bool:
|
|
270
|
+
"""Mark the entry approved. False if unknown, expired or already decided.
|
|
271
|
+
|
|
272
|
+
The sweep is what makes the TTL binding for every decider, not only
|
|
273
|
+
for the ones that happen to read the queue first. The settings UI
|
|
274
|
+
calls ``get`` before approving and so expires the entry on the way
|
|
275
|
+
in; a decision arriving on the event bus does not, and without this
|
|
276
|
+
an entry whose TTL elapsed while its caller was retrying could still
|
|
277
|
+
be approved -- waking a retry that is holding the same row and
|
|
278
|
+
dispatching the tool long after the window closed.
|
|
279
|
+
"""
|
|
280
|
+
return self.decide_with_outcome(token, "approve") is DecisionOutcome.APPLIED
|
|
224
281
|
|
|
225
282
|
def deny(self, token: str) -> bool:
|
|
226
|
-
"""Mark the entry denied.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
283
|
+
"""Mark the entry denied. False if unknown, expired or already decided.
|
|
284
|
+
|
|
285
|
+
Expires first, for the reason ``approve`` gives: the TTL has to mean
|
|
286
|
+
the same thing to a decision from the bus as to one from the tab.
|
|
287
|
+
"""
|
|
288
|
+
return self.decide_with_outcome(token, "deny") is DecisionOutcome.APPLIED
|
|
289
|
+
|
|
290
|
+
def _expire(self, token: str, action: str) -> bool:
|
|
291
|
+
"""Sweep, and report whether ``token`` is gone because its TTL ran out.
|
|
292
|
+
|
|
293
|
+
The sweep is what makes the TTL binding for a decision, and the
|
|
294
|
+
return value is what keeps an ordinary expiry distinguishable from
|
|
295
|
+
an unknown token: both leave the queue without the entry, but only
|
|
296
|
+
one of them is worth an operator's attention.
|
|
297
|
+
"""
|
|
298
|
+
known_before = token in self._by_token
|
|
299
|
+
self._sweep_expired()
|
|
300
|
+
if known_before and token not in self._by_token:
|
|
233
301
|
logger.info(
|
|
234
|
-
"approval_queue
|
|
302
|
+
"approval_queue.%s: token %s expired before the decision reached it",
|
|
303
|
+
action,
|
|
235
304
|
token,
|
|
236
|
-
entry.decision,
|
|
237
305
|
)
|
|
238
|
-
|
|
306
|
+
return True
|
|
307
|
+
return False
|
|
239
308
|
|
|
240
309
|
def remove(self, token: str) -> None:
|
|
241
310
|
self._by_token.pop(token, None)
|