ha-mcp-dev 8.6.0.dev2850__tar.gz → 8.6.0.dev2852__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.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/PKG-INFO +1 -1
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/pyproject.toml +1 -1
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/pyproject.toml.orig +1 -1
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/__init__.py +27 -16
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_i18n.py +10 -8
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/README.md +5 -5
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/01_i18n_state.js +470 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/02_tools_restart.js +428 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/03_render_save.js +584 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/04_backups.js +639 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/05_feature_flags.js +661 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/06_policy_cards.js +908 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/07_policy_actions.js +493 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/08_advanced.js +420 -0
- ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/09_prefs_visibility.js +425 -0
- ha_mcp_dev-8.6.0.dev2850/src/ha_mcp/settings_ui/settings.js +0 -5028
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/LICENSE +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/README.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_rich_compat.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/LICENSE +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/REQUIRES.txt +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/VENDORED +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/_compat.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/_install_hints.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/_warnings.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/app.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/approval.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/choice.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/config.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/file_upload.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/form.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/generative.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/__main__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/apps_dev.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/cimd.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/cli.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/authentication.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/command.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/configuration.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/credentials.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/horizon_client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/output.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/deploy/state.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/discovery.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/generate.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/claude_code.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/claude_desktop.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/cursor.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/gemini_cli.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/goose.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/mcp_json.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/shared.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/install/stdio.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/run.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/_sdk_context_shim.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/auth/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/auth/bearer.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/auth/client_credentials.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/auth/oauth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/caching.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/dependencies.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/elicitation.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/extension_hooks.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/group.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/logging.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/messages.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/mixins/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/mixins/prompts.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/mixins/resources.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/mixins/tools.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/oauth_callback.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/progress.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/roots.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/sampling/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/anthropic.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/google_genai.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/sampling/handlers/openai.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/telemetry.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/config.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/http.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/inference.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/memory.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/sse.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/transports/stdio.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/README.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/README.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/component_manager.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/component_manager/example.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/decorators.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/dependencies.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/exceptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/experimental/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/experimental/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/experimental/transforms/code_mode.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/mcp_config.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/prompts/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/prompts/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/prompts/function_prompt.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/py.typed +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/function_resource.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/security.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/template.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/types.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/cimd.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/handlers/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/handlers/authorize.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/identity_assertion.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/jwt_issuer.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/middleware.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/consent.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/models.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/proxy.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/ui.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/oauth_proxy/upstream.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/oidc_proxy.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/auth0.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/aws.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/azure.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/clerk.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/debug.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/descope.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/discord.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/github.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/google.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/huggingface.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/in_memory.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/introspection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/jwt.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/keycloak.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/oci.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/propelauth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/scalekit.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/supabase.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/providers/workos.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/redirect_validation.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/auth/ssrf.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/caching.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/completions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/context.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/dependencies.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/elicitation.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/event_store.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/extensions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/http.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/lifespan.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/low_level.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/authorization.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/caching.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/dereference.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/error_handling.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/logging.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/middleware.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/ping.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/rate_limiting.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/response_limiting.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/timing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/middleware/tool_injection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/mixins/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/mixins/lifespan.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/mixins/mcp_operations.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/mixins/transport.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/addressing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/aggregate.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/fastmcp_provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/filesystem.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/filesystem_discovery.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/prompts.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/resources.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/decorators/tools.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/local_provider/local_provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/README.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/components.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/openapi/routing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/prefab_payload.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/prefab_synthesis.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/proxy.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/_common.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/claude_provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/directory_provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/skill_provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/skills/vendor_providers.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/providers/wrapped_provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/session_scoped_event_store.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/sessions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/telemetry.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/catalog.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/namespace.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/prompts_as_tools.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/resources_as_tools.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/bm25.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/search/regex.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/tool_transform.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/version_filter.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/transforms/visibility.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/settings.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/telemetry.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/tools/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/tools/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/tools/function_parsing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/tools/function_tool.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/tools/tool_transform.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/types.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/asgi_transport.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/async_utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/authorization.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/cli.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/components.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/docstring_parsing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/exceptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/http.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/inspect.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/json_schema.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/json_schema_type.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/lifespan.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/logging.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/environments/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/environments/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/environments/uv.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/schema.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/sources/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/sources/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mime.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/README.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/director.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/formatters.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/json_schema_converter.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/models.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/parser.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/openapi/schemas.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/pagination.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/prefab.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/skills.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/tasks.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/tests.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/timeout.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/token_cache.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/types.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/ui.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/version_check.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/versions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/LICENSE +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/REQUIRES.txt +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/VENDORED +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/cli/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/cli/claude.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/cli/cli.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/__main__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/_input_required.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/_memory.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/_probe.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/_transport.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/auth/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/auth/exceptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/auth/extensions/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/auth/extensions/client_credentials.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/auth/extensions/identity_assertion.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/auth/oauth2.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/auth/utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/caching.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/context.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/extension.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/session.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/session_group.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/sse.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/stdio.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/streamable_http.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/subscriptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/os/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/os/posix/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/os/posix/utilities.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/os/win32/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/os/win32/utilities.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/py.typed +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/__main__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/_otel.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/_streamable_http_modern.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/apps.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/errors.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/handlers/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/handlers/authorize.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/handlers/metadata.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/handlers/register.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/handlers/revoke.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/handlers/token.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/json_response.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/middleware/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/middleware/auth_context.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/middleware/bearer_auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/middleware/client_auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/routes.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/auth/settings.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/caching.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/connection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/context.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/elicitation.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/extension.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/fastmcp.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/lowlevel/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/lowlevel/helper_types.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/lowlevel/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/context.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/exceptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/prompts/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/prompts/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/prompts/manager.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/resolve.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/resource_manager.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/templates.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/resources/types.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/tools/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/tools/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/tools/tool_manager.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/context_injection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/func_metadata.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/logging.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/mcpserver/utilities/types.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/models.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/request_state.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/runner.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/session.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/sse.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/stdio.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/streamable_http.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/streamable_http_manager.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/subscriptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/transport_security.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/validation.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_callable_inspection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_compat.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_context_streams.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_httpx_utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_otel.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_stream_protocols.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/auth_utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/context.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/direct_dispatcher.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/dispatcher.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/exceptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/extension.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/inbound.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/jsonrpc_dispatcher.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/memory.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/message.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/metadata_utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/path_security.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/peer.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/subscriptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/tool_name_validation.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/transport_context.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/uri_template.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/jsonrpc.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/methods.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/version.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/LICENSE +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/REQUIRES.txt +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/VENDORED +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/_types.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/_v2025_11_25/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/_v2026_07_28/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/_wire_base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/jsonrpc.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/methods.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/py.typed +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/version.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/requirements.txt +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/LICENSE +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/VENDORED +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/__main__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/connection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/messages.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/router.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/cli.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/connection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/datastructures.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/exceptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/extensions/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/extensions/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/extensions/permessage_deflate.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/frames.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/headers.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/http11.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/imports.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/auth.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/exceptions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/framing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/handshake.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/http.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/protocol.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/protocol.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/proxy.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/py.typed +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/streams.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/connection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/messages.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/router.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/connection.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/messages.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/router.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/typing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/uri.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/utils.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/version.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/oidc_compat.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/browser_landing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/admin_routes.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_backup.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_overrides.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_registry.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_settings.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/ha_request_queue.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/hacs_auto_refresh.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/http_transport.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/llm_exposure.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/log_filters.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/decision_pin.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/decisions.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/editing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/events.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/server_channels.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/redaction.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/renamed_tools.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-actions.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/backups.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/triggers-and-conditions.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/server_lifespan.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/server_tool_text.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_locale_policy.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_persistence.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_theme.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/az.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/cs.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/de.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/en.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/eo.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/es.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/fr.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/it.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/ko.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/nl.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/pl.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/sv.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/tlh.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/zh-Hans.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/zh-Hant.json +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/settings.html +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/strict_bps.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tool_dispatch.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/best_practice_result.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/best_practice_variables.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/blueprint_sources.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/blueprint_substitute.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/blueprint_write.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/bulk_selector.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_api.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_config_entries.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_config_reads.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_dashboard_edit.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_devices.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_registries.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_flow_form.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_flow_menu.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_flow_walker.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_identity.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_reconfigure.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_reload_watch.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/dashboard_edit_errors.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/dashboard_list_checks.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/device_enrichment.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/entity_registration.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/entity_update_fields.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/error_log_parsing.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/hacs_registration.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/integration_reconfigure.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_common.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_sources.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_sources_fault.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_sources_supervisor.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/renamed_tool_middleware.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/scene_discovery.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_graph.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_assist_pipeline.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_dev.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_logs.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_security_policy.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/component_search.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/write_tool_note.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transport_security.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/config_write_lock.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/dashboard_patch.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/device_registry_semantics.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/entity_membership.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/mcp_client_host.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/registry_update_lock.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/__init__.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/enforcement.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/model.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/persistence.py +0 -0
- {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/resolver.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "8.6.0.
|
|
7
|
+
version = "8.6.0.dev2852"
|
|
8
8
|
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13,<3.15"
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "8.6.0.
|
|
7
|
+
version = "8.6.0.dev2852"
|
|
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
|
|
@@ -82,36 +82,47 @@ if TYPE_CHECKING:
|
|
|
82
82
|
|
|
83
83
|
logger = logging.getLogger(__name__)
|
|
84
84
|
|
|
85
|
-
# The settings-UI client script lives in
|
|
86
|
-
# editor/JS tooling).
|
|
85
|
+
# The settings-UI client script lives in the numbered part files under
|
|
86
|
+
# settings_js/ (real files for editor/JS tooling). The parts are one script
|
|
87
|
+
# split at top-level statement boundaries; joining them in file-name order
|
|
88
|
+
# gives the whole script. It is a template with two sentinel tokens for the
|
|
87
89
|
# Python-injected constant lists; substitute them with the same values the
|
|
88
90
|
# inline literal used so the rendered HTML is byte-identical. Injected
|
|
89
91
|
# inline (not served) -- the serving model is unchanged.
|
|
90
92
|
#
|
|
91
93
|
# This is a module-import-time file read: importing settings_ui (done by
|
|
92
|
-
# server.py / __main__.py / the sidecar) now depends on
|
|
93
|
-
# present. If packaging drops
|
|
94
|
+
# server.py / __main__.py / the sidecar) now depends on the parts being
|
|
95
|
+
# present. If packaging drops them, fail with a packaging-specific ImportError
|
|
94
96
|
# rather than a bare FileNotFoundError so the cause is obvious.
|
|
95
|
-
|
|
97
|
+
_SETTINGS_JS_DIR = Path(__file__).parent / "settings_js"
|
|
96
98
|
try:
|
|
97
|
-
|
|
99
|
+
_settings_js_parts = sorted(_SETTINGS_JS_DIR.glob("*.js"))
|
|
100
|
+
_settings_js_template = "".join(
|
|
101
|
+
part.read_text(encoding="utf-8") for part in _settings_js_parts
|
|
102
|
+
)
|
|
98
103
|
except OSError as exc: # pragma: no cover - packaging guard
|
|
99
104
|
raise ImportError(
|
|
100
|
-
f"
|
|
105
|
+
f"settings_js/ missing at {_SETTINGS_JS_DIR}. It must ship in "
|
|
101
106
|
"the wheel, the sdist and the PyInstaller datas (binary) -- this is a "
|
|
102
107
|
"packaging bug, not a usage error."
|
|
103
108
|
) from exc
|
|
109
|
+
if not _settings_js_template: # pragma: no cover - packaging guard
|
|
110
|
+
raise ImportError(
|
|
111
|
+
f"settings_js/ at {_SETTINGS_JS_DIR} holds no .js parts. They must "
|
|
112
|
+
"ship in the wheel, the sdist and the PyInstaller datas (binary) -- "
|
|
113
|
+
"this is a packaging bug, not a usage error."
|
|
114
|
+
)
|
|
104
115
|
# str.replace() silently no-ops on an absent token, and a *renamed* sentinel
|
|
105
116
|
# (e.g. PINNED_DEFAULTS) slips past both the "__HA_MCP_" not-in test and the
|
|
106
117
|
# esbuild/jsdom JS harness (tests/js/harness.mjs) -- `const DEFAULT_PINNED =
|
|
107
118
|
# PINNED_DEFAULTS;` is valid JS (only a runtime ReferenceError), so a drifted
|
|
108
|
-
#
|
|
119
|
+
# settings_js/ would ship a broken page green. Assert both sentinels are present
|
|
109
120
|
# before substituting.
|
|
110
121
|
for _sentinel in ("__HA_MCP_DEFAULT_PINNED__", "__HA_MCP_MANDATORY__"):
|
|
111
122
|
if _sentinel not in _settings_js_template:
|
|
112
123
|
raise ImportError(
|
|
113
|
-
f"
|
|
114
|
-
"The Python injection and
|
|
124
|
+
f"settings_js/ is out of sync: sentinel {_sentinel} not found. "
|
|
125
|
+
"The Python injection and settings_js/ have drifted."
|
|
115
126
|
)
|
|
116
127
|
# sorted(), not list(): DEFAULT_PINNED_TOOLS / MANDATORY_TOOLS are sets, so
|
|
117
128
|
# json.dumps(list(...)) is per-process-ordered -- the only reason proving the
|
|
@@ -123,10 +134,10 @@ _SETTINGS_JS = _settings_js_template.replace(
|
|
|
123
134
|
|
|
124
135
|
|
|
125
136
|
# The settings-UI CSS lives in settings.css, extracted the same way as
|
|
126
|
-
#
|
|
137
|
+
# the settings_js/ parts. Unlike the JS it has no Python injection points -- a plain
|
|
127
138
|
# read, no token substitution -- and is injected inline between the same
|
|
128
139
|
# <style>/</style> tags so the served page stays byte-identical. It carries
|
|
129
|
-
# the same import-time packaging dependency as
|
|
140
|
+
# the same import-time packaging dependency as settings_js/, so the same
|
|
130
141
|
# OSError -> ImportError packaging guard applies.
|
|
131
142
|
_SETTINGS_CSS_PATH = Path(__file__).parent / "settings.css"
|
|
132
143
|
try:
|
|
@@ -140,18 +151,18 @@ except OSError as exc: # pragma: no cover - packaging guard
|
|
|
140
151
|
|
|
141
152
|
|
|
142
153
|
# The settings page HTML lives in settings.html, extracted the same way as
|
|
143
|
-
#
|
|
154
|
+
# settings_js/ / settings.css (real files for editor/HTML tooling). It carries
|
|
144
155
|
# six substitution markers — two filled once at import, four per request:
|
|
145
156
|
# __HA_MCP_CSS__ -> settings.css contents (inside <style>)
|
|
146
|
-
# __HA_MCP_JS__ ->
|
|
157
|
+
# __HA_MCP_JS__ -> settings_js/ contents (inside <script>)
|
|
147
158
|
# __HA_MCP_THEME_PREFS__ -> per-request server-seeded theme prefs JSON,
|
|
148
159
|
# substituted in _render_settings_html()
|
|
149
160
|
# __HA_MCP_I18N__ -> selected merged translation catalog JSON
|
|
150
161
|
# __HA_MCP_LANG__ -> selected locale code for the html lang attribute
|
|
151
162
|
# __HA_MCP_DIR__ -> selected catalog text direction (ltr / rtl)
|
|
152
|
-
# Same import-time packaging dependency as
|
|
163
|
+
# Same import-time packaging dependency as settings_js/css (wheel, sdist,
|
|
153
164
|
# PyInstaller datas) and the same OSError guard -- but this loader
|
|
154
|
-
# raises RuntimeError, not the ImportError that
|
|
165
|
+
# raises RuntimeError, not the ImportError that settings_js/css raise.
|
|
155
166
|
_SETTINGS_HTML_PATH = Path(__file__).parent / "settings.html"
|
|
156
167
|
try:
|
|
157
168
|
_settings_html_template = _SETTINGS_HTML_PATH.read_text(encoding="utf-8")
|
|
@@ -361,7 +361,7 @@ def _validate_placeholder_parity(catalogs: dict[str, dict[str, Any]]) -> None:
|
|
|
361
361
|
"""Reject catalog-backed translations with mismatched placeholders.
|
|
362
362
|
|
|
363
363
|
Tool metadata normally comes from the runtime API rather than ``en.json``;
|
|
364
|
-
``
|
|
364
|
+
``settings_js/`` performs the corresponding parity check against those
|
|
365
365
|
canonical values before displaying a translated tool field.
|
|
366
366
|
"""
|
|
367
367
|
english_messages = catalogs[DEFAULT_LOCALE]["messages"]
|
|
@@ -399,15 +399,16 @@ def _validate_placeholder_parity(catalogs: dict[str, dict[str, Any]]) -> None:
|
|
|
399
399
|
# Anything that looks like an HTML tag in a catalog message. A bare "<" in
|
|
400
400
|
# prose (e.g. "< 5") deliberately does not match — it renders fine escaped.
|
|
401
401
|
_TAG_LIKE_RE = re.compile(r"</?[a-zA-Z][^>]*>")
|
|
402
|
-
# The exact tag shapes
|
|
403
|
-
# sync with the restore regexes there — any other spelling
|
|
404
|
-
# attribute order) survives escaping and shows the user
|
|
402
|
+
# The exact tag shapes settings_js/01_i18n_state.js::tHtml restores after
|
|
403
|
+
# escaping. Keep in sync with the restore regexes there — any other spelling
|
|
404
|
+
# (case, spacing, attribute order) survives escaping and shows the user
|
|
405
|
+
# literal markup text.
|
|
405
406
|
_ALLOWED_TAGS_RE = re.compile(
|
|
406
407
|
r'</?code>|</?strong>|</a>|<a href="#" data-panel-link="[a-z][a-z-]*">'
|
|
407
408
|
)
|
|
408
409
|
# The tab a cross-panel link switches to. The allowlist above only accepts the
|
|
409
410
|
# tag *shape*, so "outils" or "backup" passes it and then silently does
|
|
410
|
-
# nothing:
|
|
411
|
+
# nothing: settings_js/ hands the value to activateTab, which no-ops on an
|
|
411
412
|
# unknown panel. Read the real ids out of the page rather than restating them.
|
|
412
413
|
# Matches the whole anchor, not a bare attribute: a message may legitimately
|
|
413
414
|
# show `<code>data-panel-link="example"</code>` as literal help text, and that
|
|
@@ -487,9 +488,10 @@ def _validate_panel_links(
|
|
|
487
488
|
def _validate_inline_markup(catalogs: dict[str, dict[str, Any]]) -> None:
|
|
488
489
|
"""Reject catalog messages whose markup ``tHtml`` cannot restore.
|
|
489
490
|
|
|
490
|
-
``
|
|
491
|
-
the exact allowlisted tag shapes, so a translation written
|
|
492
|
-
``<CODE>`` or ``<code >`` would silently render as literal escaped
|
|
491
|
+
``settings_js/01_i18n_state.js::tHtml`` escapes every translated value and
|
|
492
|
+
restores only the exact allowlisted tag shapes, so a translation written
|
|
493
|
+
with ``<CODE>`` or ``<code >`` would silently render as literal escaped
|
|
494
|
+
text.
|
|
493
495
|
Fail fast at load time instead, mirroring the placeholder-parity check.
|
|
494
496
|
Scoped to ``messages``: tool translations are plain text rendered through
|
|
495
497
|
``escapeHtml`` and carry no markup contract.
|
{ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/README.md
RENAMED
|
@@ -9,11 +9,11 @@ the wheel and sdist ship every file under `src/ha_mcp`, and
|
|
|
9
9
|
UI's own strings, each catalog carries the add-on option strings under
|
|
10
10
|
`addon.<key>.*` (with `features.<key>.*` for options the settings UI also
|
|
11
11
|
shows, and `addon_stable.<key>.*` for flavor-specific wording). Both add-on
|
|
12
|
-
flavors' `translations/*.yaml` and the `FEATURE_META` block in
|
|
13
|
-
are generated from these catalogs by
|
|
14
|
-
edit those by hand. Wherever one
|
|
15
|
-
|
|
16
|
-
cross-surface wording cannot drift.
|
|
12
|
+
flavors' `translations/*.yaml` and the `FEATURE_META` block in
|
|
13
|
+
`settings_js/05_feature_flags.js` are generated from these catalogs by
|
|
14
|
+
`scripts/generate_locales.py` — never edit those by hand. Wherever one
|
|
15
|
+
English string reaches the reader from more than one surface, the translation
|
|
16
|
+
is stored once here and projected, so cross-surface wording cannot drift.
|
|
17
17
|
|
|
18
18
|
## Adding a language
|
|
19
19
|
|
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
// The server embeds exactly one merged locale catalog in the page. English
|
|
2
|
+
// values are already merged as fallback, so an incomplete translation remains
|
|
3
|
+
// usable and adding a language requires only a new locales/<code>.json file.
|
|
4
|
+
const I18N_PAYLOAD = (() => {
|
|
5
|
+
const el = document.getElementById('ha-mcp-i18n');
|
|
6
|
+
if (!el) return {locale: 'en', dir: 'ltr', messages: {}, tool_groups: {}, tools: {}, languages: []};
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(el.textContent || '{}');
|
|
9
|
+
} catch (err) {
|
|
10
|
+
console.warn('[ha-mcp] invalid embedded translation catalog', err);
|
|
11
|
+
return {locale: 'en', dir: 'ltr', messages: {}, tool_groups: {}, tools: {}, languages: []};
|
|
12
|
+
}
|
|
13
|
+
})();
|
|
14
|
+
const LOCALE_COOKIE = 'ha_mcp_locale';
|
|
15
|
+
|
|
16
|
+
function t(key, params = {}, fallback = key) {
|
|
17
|
+
let value = Object.prototype.hasOwnProperty.call(I18N_PAYLOAD.messages || {}, key)
|
|
18
|
+
? I18N_PAYLOAD.messages[key]
|
|
19
|
+
: fallback;
|
|
20
|
+
Object.keys(params).forEach(name => {
|
|
21
|
+
value = value.replaceAll(`{${name}}`, String(params[name]));
|
|
22
|
+
});
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Translation for HTML contexts (innerHTML sinks). Catalog strings are data,
|
|
27
|
+
// not markup: the whole value is HTML-escaped first, then only the allowlist
|
|
28
|
+
// of inline formatting tags the catalogs use (<code>, <strong>, and the
|
|
29
|
+
// internal tab links) is restored, so a translated string can never
|
|
30
|
+
// contribute any other markup. Placeholders are substituted AFTER escaping:
|
|
31
|
+
// params are trusted HTML fragments built by the caller (escape any dynamic
|
|
32
|
+
// text inside them with escapeHtml at the call site).
|
|
33
|
+
function tHtml(key, params = {}, fallback = key) {
|
|
34
|
+
const raw = Object.prototype.hasOwnProperty.call(I18N_PAYLOAD.messages || {}, key)
|
|
35
|
+
? I18N_PAYLOAD.messages[key]
|
|
36
|
+
: fallback;
|
|
37
|
+
let value = escapeHtml(raw)
|
|
38
|
+
.replace(/<(\/?)(code|strong)>/g, '<$1$2>')
|
|
39
|
+
.replace(/<a href="#" data-panel-link="([a-z][a-z-]*)">/g, '<a href="#" data-panel-link="$1">')
|
|
40
|
+
.replace(/<\/a>/g, '</a>');
|
|
41
|
+
Object.keys(params).forEach(name => {
|
|
42
|
+
value = value.replaceAll(`{${name}}`, String(params[name]));
|
|
43
|
+
});
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function localizeMeta(section, field, meta) {
|
|
48
|
+
return {
|
|
49
|
+
...meta,
|
|
50
|
+
label: t(`${section}.${field}.label`, {}, meta.label || field),
|
|
51
|
+
help: t(`${section}.${field}.help`, {}, meta.help || ''),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function localizedToolGroup(group) {
|
|
56
|
+
return (I18N_PAYLOAD.tool_groups || {})[group] || group;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function _placeholderNames(value) {
|
|
60
|
+
return Array.from(new Set(Array.from(
|
|
61
|
+
String(value || '').matchAll(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g),
|
|
62
|
+
match => match[1]
|
|
63
|
+
))).sort();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function _translatedToolField(tool, field, expectedSource, fallback = expectedSource) {
|
|
67
|
+
const translated = ((I18N_PAYLOAD.tools || {})[tool.name] || {})[field];
|
|
68
|
+
if (!translated) return fallback;
|
|
69
|
+
const sourceFields = _placeholderNames(expectedSource);
|
|
70
|
+
const translatedFields = _placeholderNames(translated);
|
|
71
|
+
if (sourceFields.join('\0') !== translatedFields.join('\0')) {
|
|
72
|
+
console.warn(
|
|
73
|
+
`[ha-mcp] ignoring ${field} translation for ${tool.name}: placeholder mismatch`,
|
|
74
|
+
{source: sourceFields, translated: translatedFields}
|
|
75
|
+
);
|
|
76
|
+
return fallback;
|
|
77
|
+
}
|
|
78
|
+
return translated;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function localizedToolCopy(tool, description) {
|
|
82
|
+
const sourceTitle = tool.title || tool.name;
|
|
83
|
+
return {
|
|
84
|
+
title: _translatedToolField(tool, 'title', sourceTitle),
|
|
85
|
+
// Validate the translated description against the DISPLAYED condensed
|
|
86
|
+
// text (the same first-line summary shown in the row), not the full
|
|
87
|
+
// runtime docstring: deeper docstring lines carry API-path tokens like
|
|
88
|
+
// {slug}/{type} that never appear in the summary, and comparing against
|
|
89
|
+
// them would wrongly drop an otherwise-valid translation. Mirrors the
|
|
90
|
+
// title branch, which compares against the displayed sourceTitle.
|
|
91
|
+
description: _translatedToolField(tool, 'description', description),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function applyStaticTranslations(root = document) {
|
|
96
|
+
root.querySelectorAll('[data-i18n]').forEach(el => {
|
|
97
|
+
el.textContent = t(el.dataset.i18n, {}, el.textContent);
|
|
98
|
+
});
|
|
99
|
+
root.querySelectorAll('[data-i18n-html]').forEach(el => {
|
|
100
|
+
// Rewrite only from the catalog: the server-rendered markup already is
|
|
101
|
+
// the English copy, and routing it back through the escape+allowlist
|
|
102
|
+
// pipeline would depend on attribute serialization being round-trip
|
|
103
|
+
// stable, which it is not guaranteed to be.
|
|
104
|
+
const key = el.dataset.i18nHtml;
|
|
105
|
+
if (Object.prototype.hasOwnProperty.call(I18N_PAYLOAD.messages || {}, key)) {
|
|
106
|
+
el.innerHTML = tHtml(key);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
for (const attribute of ['placeholder', 'title', 'aria-label']) {
|
|
110
|
+
const dataName = `i18n${attribute.split('-').map(part => part[0].toUpperCase() + part.slice(1)).join('')}`;
|
|
111
|
+
root.querySelectorAll(`[data-i18n-${attribute}]`).forEach(el => {
|
|
112
|
+
const key = el.dataset[dataName];
|
|
113
|
+
el.setAttribute(attribute, t(key, {}, el.getAttribute(attribute) || ''));
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function _readLocaleCookie() {
|
|
119
|
+
const prefix = `${LOCALE_COOKIE}=`;
|
|
120
|
+
const entry = document.cookie.split(';').map(value => value.trim()).find(value => value.startsWith(prefix));
|
|
121
|
+
if (!entry) return '';
|
|
122
|
+
try {
|
|
123
|
+
return decodeURIComponent(entry.slice(prefix.length));
|
|
124
|
+
} catch (err) {
|
|
125
|
+
console.warn('[ha-mcp] ignoring malformed locale cookie', err);
|
|
126
|
+
return '';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function _writeLocaleCookie(locale) {
|
|
131
|
+
if (locale === 'auto') {
|
|
132
|
+
document.cookie = `${LOCALE_COOKIE}=; Max-Age=0; Path=/; SameSite=Lax`;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
document.cookie = `${LOCALE_COOKIE}=${encodeURIComponent(locale)}; Max-Age=31536000; Path=/; SameSite=Lax`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function initializeLanguageControl() {
|
|
139
|
+
document.documentElement.lang = I18N_PAYLOAD.locale || 'en';
|
|
140
|
+
document.documentElement.dir = I18N_PAYLOAD.dir || 'ltr';
|
|
141
|
+
applyStaticTranslations();
|
|
142
|
+
|
|
143
|
+
const select = document.getElementById('languageToggle');
|
|
144
|
+
if (!select) return;
|
|
145
|
+
select.innerHTML = '';
|
|
146
|
+
const auto = document.createElement('option');
|
|
147
|
+
auto.value = 'auto';
|
|
148
|
+
auto.textContent = t('language.auto', {}, 'Auto');
|
|
149
|
+
select.appendChild(auto);
|
|
150
|
+
(I18N_PAYLOAD.languages || []).forEach(language => {
|
|
151
|
+
const option = document.createElement('option');
|
|
152
|
+
option.value = language.code;
|
|
153
|
+
option.textContent = language.native_name;
|
|
154
|
+
select.appendChild(option);
|
|
155
|
+
});
|
|
156
|
+
const saved = _readLocaleCookie();
|
|
157
|
+
select.value = Array.from(select.options).some(option => option.value === saved)
|
|
158
|
+
? saved
|
|
159
|
+
: 'auto';
|
|
160
|
+
select.addEventListener('change', () => {
|
|
161
|
+
_writeLocaleCookie(select.value);
|
|
162
|
+
window.location.reload();
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
initializeLanguageControl();
|
|
167
|
+
|
|
168
|
+
// Catch top-level / async script errors and write them into the #status
|
|
169
|
+
// ARIA live region (now visually hidden — see settings.css). This still
|
|
170
|
+
// announces a script-eval failure to screen readers, but is NOT visible to
|
|
171
|
+
// sighted users and does not toast (showToast isn't defined yet this early
|
|
172
|
+
// in script eval). For visible diagnosis, use the browser console. Without
|
|
173
|
+
// this, a script-evaluation error in any of the function definitions below
|
|
174
|
+
// would abort the script before loadTools() is even called.
|
|
175
|
+
window.addEventListener('error', (e) => {
|
|
176
|
+
const el = document.getElementById('status');
|
|
177
|
+
if (!el) return;
|
|
178
|
+
const where = e.filename ? `${e.filename}:${e.lineno}:${e.colno}` : 'inline';
|
|
179
|
+
setStatusAlert(el, true);
|
|
180
|
+
el.textContent = t(
|
|
181
|
+
'errors.javascript',
|
|
182
|
+
{message: e.message, where},
|
|
183
|
+
`JS error: ${e.message} @ ${where}`
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
window.addEventListener('unhandledrejection', (e) => {
|
|
187
|
+
const el = document.getElementById('status');
|
|
188
|
+
if (!el) return;
|
|
189
|
+
setStatusAlert(el, true);
|
|
190
|
+
const message = e.reason && e.reason.message ? e.reason.message : String(e.reason);
|
|
191
|
+
el.textContent = t('errors.async', {message}, `Async error: ${message}`);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
let toolData = [];
|
|
195
|
+
let toolStates = {};
|
|
196
|
+
// Map of tool name → "disabled" | "pinned" for env-var-pinned tools.
|
|
197
|
+
// Populated from data.env_pinned in loadTools(); read by render() to
|
|
198
|
+
// lock rows and show the env-var name banner.
|
|
199
|
+
let toolEnvPinned = {};
|
|
200
|
+
// Tools locked enabled while strict best-practices mode
|
|
201
|
+
// (enable_mandatory_bps + enable_strict_mandatory_bps) is on (#1886).
|
|
202
|
+
// Populated from data.bps_locked_tools in loadTools(); rendered like
|
|
203
|
+
// mandatory tools plus a note naming the toggle to turn off first.
|
|
204
|
+
// Server-side saves reject the conflict too — this lock is the
|
|
205
|
+
// courteous UI half.
|
|
206
|
+
let bpsLockedTools = new Set();
|
|
207
|
+
// Conversation-agent LLM API exposure (#1745). toolLlm mirrors the
|
|
208
|
+
// server-computed EFFECTIVE value per tool (user override, else the
|
|
209
|
+
// deny-by-default for beta/dev/restart tools); toolLlmOverrides holds
|
|
210
|
+
// only the user-set overrides and is what saveConfig persists — tools
|
|
211
|
+
// never flipped keep tracking their defaults across releases.
|
|
212
|
+
let toolLlm = {};
|
|
213
|
+
let toolLlmOverrides = {};
|
|
214
|
+
// True only on the in-process custom-component (embedded) server, which
|
|
215
|
+
// registers the LLM API exposure surface. On the add-on / Docker / standalone
|
|
216
|
+
// server nothing consumes it, so the per-tool "LLM API" toggle is hidden
|
|
217
|
+
// rather than shown as a no-op. Set from data.llm_api_available (see
|
|
218
|
+
// settings_ui/__init__.py).
|
|
219
|
+
let llmApiAvailable = false;
|
|
220
|
+
let saveTimer = null;
|
|
221
|
+
let openGroups = new Set();
|
|
222
|
+
|
|
223
|
+
// Per-tool "security gated" toggle state mirrors the bare (condition-free)
|
|
224
|
+
// rules in policy.rules from /api/policy/config. Under the default
|
|
225
|
+
// require-approval list a bare rule gates its tool; under an allow list
|
|
226
|
+
// (rule_effect 'allow') it approves it, so there the toggle reads "gated"
|
|
227
|
+
// exactly when neither the tool nor `*` has a bare rule. The Tools tab uses isToolGated()
|
|
228
|
+
// to render the third toggle alongside enabled/pinned.
|
|
229
|
+
// `enabled` is tri-state: true/false from the addon-config flag, or
|
|
230
|
+
// null when the features fetch failed — downstream branches need to
|
|
231
|
+
// distinguish "definitively off" from "couldn't determine" so they
|
|
232
|
+
// don't false-confidently tell the user the feature is off.
|
|
233
|
+
const policyState = {
|
|
234
|
+
enabled: false,
|
|
235
|
+
enabledKnown: false,
|
|
236
|
+
bareRuleTools: new Set(),
|
|
237
|
+
// rule_effect each surface was last rendered under: the Tools-tab gate
|
|
238
|
+
// toggles (loadPolicyState) and the Policies-tab cards and selector
|
|
239
|
+
// (renderPolicyCards) load separately. null until that surface loaded.
|
|
240
|
+
// policyPut refuses a write from a surface whose mode is stale or was
|
|
241
|
+
// never read, so a mode switched elsewhere is neither written back nor
|
|
242
|
+
// used to save a rule meant for the other mode.
|
|
243
|
+
toolsEffect: null,
|
|
244
|
+
cardsEffect: null,
|
|
245
|
+
// enable_security_policy_tool — registers ha_manage_security_policy, the
|
|
246
|
+
// MCP tool that can rewrite these rules. Independent of `enabled`: it
|
|
247
|
+
// governs who may edit the policy, not whether it is enforced.
|
|
248
|
+
manageToolEnabled: false,
|
|
249
|
+
manageToolKnown: false,
|
|
250
|
+
// The raw /api/settings/features entries behind the two switches
|
|
251
|
+
// (origin / editable / env_var), or null when the fetch failed. An
|
|
252
|
+
// env-pinned flag reports editable:false and every save is rejected, so
|
|
253
|
+
// the switch must lock and explain — same as the generated feature rows.
|
|
254
|
+
masterFlag: null,
|
|
255
|
+
manageToolFlag: null,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// Read Only Mode (read_only_mode feature flag) — same tri-state shape
|
|
259
|
+
// as policyState. Mirrors the toggle above the Tools-tab search box and
|
|
260
|
+
// the Server Settings row. While enabled, render() forces write-capable
|
|
261
|
+
// tools off (visually, without rewriting toolStates — same
|
|
262
|
+
// non-destructive semantics as the beta master gate) except the
|
|
263
|
+
// server-provided READ_ONLY_EXEMPT mixed read/write tools.
|
|
264
|
+
const readOnlyState = {
|
|
265
|
+
enabled: false,
|
|
266
|
+
enabledKnown: false,
|
|
267
|
+
// Raw flag entry, as with the policy switches above: READ_ONLY_MODE can
|
|
268
|
+
// be env-pinned (Docker / standalone), and a switch that looks live
|
|
269
|
+
// while every save 4xxs is worse than one that says why it is locked.
|
|
270
|
+
flag: null,
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// Mixed read/write tools that stay enabled in Read Only Mode (their
|
|
274
|
+
// write operations are blocked server-side at call time). Populated
|
|
275
|
+
// from data.read_only_exempt in loadTools().
|
|
276
|
+
let READ_ONLY_EXEMPT = new Set();
|
|
277
|
+
|
|
278
|
+
// Whether the features payload actually reported one flag. "Known" is per
|
|
279
|
+
// FLAG, not per response: /api/settings/features emits `value` for every
|
|
280
|
+
// flag it knows, so a missing entry means this server build (or an overlay
|
|
281
|
+
// in front of it) did not report that flag — not that it is off. Treating
|
|
282
|
+
// absence as false renders the switch off-and-editable, and the next save
|
|
283
|
+
// would overwrite an enabled server value with it.
|
|
284
|
+
function flagReported(flag) {
|
|
285
|
+
return !!flag && flag.value !== undefined && flag.value !== null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Reset every flag-backed switch to "unknown". Shared by loadPolicyState's
|
|
289
|
+
// two failure paths so a transient 503 and a network error leave identical
|
|
290
|
+
// state — the switches then render indeterminate + disabled, not "off".
|
|
291
|
+
function _clearFlagSwitchState() {
|
|
292
|
+
policyState.enabled = false;
|
|
293
|
+
policyState.enabledKnown = false;
|
|
294
|
+
policyState.masterFlag = null;
|
|
295
|
+
policyState.manageToolEnabled = false;
|
|
296
|
+
policyState.manageToolKnown = false;
|
|
297
|
+
policyState.manageToolFlag = null;
|
|
298
|
+
readOnlyState.enabled = false;
|
|
299
|
+
readOnlyState.enabledKnown = false;
|
|
300
|
+
readOnlyState.flag = null;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
async function loadPolicyState() {
|
|
304
|
+
// policyState.enabled mirrors the addon-config flag
|
|
305
|
+
// (enable_tool_security_policies) — the single source of truth for
|
|
306
|
+
// whether the middleware is active. Read it from /api/settings/features
|
|
307
|
+
// where it appears via FEATURE_FLAG_FIELDS. readOnlyState piggybacks
|
|
308
|
+
// on the same fetch (read_only_mode is in the same flags payload).
|
|
309
|
+
try {
|
|
310
|
+
const fresp = await fetch('./api/settings/features');
|
|
311
|
+
if (fresp.ok) {
|
|
312
|
+
const fdata = await fresp.json();
|
|
313
|
+
// The payload also carries is_addon, which envLockedNoteHtml needs
|
|
314
|
+
// for its add-on-vs-standalone wording. Landing straight on the
|
|
315
|
+
// Policies tab never runs loadFeatureFlags(), so pick it up here too.
|
|
316
|
+
if (typeof fdata.is_addon === 'boolean') IS_ADDON_MODE = fdata.is_addon;
|
|
317
|
+
const flags = fdata.flags || {};
|
|
318
|
+
const flag = flags['enable_tool_security_policies'];
|
|
319
|
+
policyState.enabled = !!(flag && flag.value);
|
|
320
|
+
policyState.enabledKnown = flagReported(flag);
|
|
321
|
+
policyState.masterFlag = flag || null;
|
|
322
|
+
const toolFlag = flags['enable_security_policy_tool'];
|
|
323
|
+
policyState.manageToolEnabled = !!(toolFlag && toolFlag.value);
|
|
324
|
+
policyState.manageToolKnown = flagReported(toolFlag);
|
|
325
|
+
policyState.manageToolFlag = toolFlag || null;
|
|
326
|
+
const roFlag = flags['read_only_mode'];
|
|
327
|
+
readOnlyState.enabled = !!(roFlag && roFlag.value);
|
|
328
|
+
readOnlyState.enabledKnown = flagReported(roFlag);
|
|
329
|
+
readOnlyState.flag = roFlag || null;
|
|
330
|
+
} else {
|
|
331
|
+
// Log it: this handler is now the evidence the ambiguous-save path
|
|
332
|
+
// branches on, so "why did a security switch go unknown?" has to be
|
|
333
|
+
// answerable from the console.
|
|
334
|
+
console.warn(
|
|
335
|
+
'[ha-mcp] /api/settings/features returned HTTP ' + fresp.status +
|
|
336
|
+
'; flag switches shown as unknown');
|
|
337
|
+
_clearFlagSwitchState();
|
|
338
|
+
}
|
|
339
|
+
} catch (e) {
|
|
340
|
+
// A malformed payload lands here as a TypeError, indistinguishable from
|
|
341
|
+
// a network drop unless we say which we saw.
|
|
342
|
+
console.warn('[ha-mcp] failed to read feature flags', e);
|
|
343
|
+
_clearFlagSwitchState();
|
|
344
|
+
}
|
|
345
|
+
try {
|
|
346
|
+
const r = await fetch('./api/policy/config');
|
|
347
|
+
if (!r.ok) {
|
|
348
|
+
// Transient failure — keep the previously-loaded gate state rather
|
|
349
|
+
// than clobbering it to empty, so a blip doesn't make the Tools tab
|
|
350
|
+
// falsely claim nothing is gated.
|
|
351
|
+
console.warn('[ha-mcp] /api/policy/config returned HTTP ' + r.status + '; keeping prior gated-tools state');
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const p = await r.json();
|
|
355
|
+
// The Tools-tab gate toggle reflects the BARE unconditional rule only
|
|
356
|
+
// (no predicates); conditional rules are managed in the Policies tab.
|
|
357
|
+
policyState.bareRuleTools = new Set(
|
|
358
|
+
(p.rules || [])
|
|
359
|
+
.filter(rule => !rule.when || rule.when.length === 0)
|
|
360
|
+
.map(rule => rule.tool_name)
|
|
361
|
+
);
|
|
362
|
+
policyState.toolsEffect = effectOf(p);
|
|
363
|
+
} catch (e) {
|
|
364
|
+
// Policy endpoint unavailable (sidecar stub) or network blip — keep the
|
|
365
|
+
// prior gate state rather than resetting it to empty. On first load it
|
|
366
|
+
// is already an empty Set, so the default still holds.
|
|
367
|
+
console.warn('[ha-mcp] failed to load policy config', e);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Wrap PUT /api/policy/config so every caller gets identical handling of
|
|
372
|
+
// the 409 (optimistic-concurrency) and other failure paths. The full
|
|
373
|
+
// policy round-trips through every caller, so the version GET'd here
|
|
374
|
+
// goes back out in the PUT body and the server can reject stale writes.
|
|
375
|
+
function effectOf(policy) {
|
|
376
|
+
return (policy && policy.rule_effect) || 'require_approval';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
async function policyPut(policy, opLabel, surfaceEffect, expectedEffect = effectOf(policy)) {
|
|
380
|
+
// A rule reads the opposite way in the other mode, so never write on the
|
|
381
|
+
// strength of a mode the user was not shown.
|
|
382
|
+
if (surfaceEffect === null) {
|
|
383
|
+
throw new Error(t(
|
|
384
|
+
'policies.errors.effect_unknown', {operation: opLabel},
|
|
385
|
+
opLabel + ' failed: this page could not read what a matching rule does. Reload the page, then re-apply your changes.'
|
|
386
|
+
));
|
|
387
|
+
}
|
|
388
|
+
if (surfaceEffect !== expectedEffect) {
|
|
389
|
+
throw new Error(t(
|
|
390
|
+
'policies.errors.effect_changed', {operation: opLabel},
|
|
391
|
+
opLabel + ' failed: the policy changed what a matching rule does since this page loaded it. Reload the page, then re-apply your changes.'
|
|
392
|
+
));
|
|
393
|
+
}
|
|
394
|
+
const w = await fetch('./api/policy/config', {
|
|
395
|
+
method: 'PUT',
|
|
396
|
+
headers: {'Content-Type': 'application/json'},
|
|
397
|
+
body: JSON.stringify(policy),
|
|
398
|
+
});
|
|
399
|
+
if (w.status === 409) {
|
|
400
|
+
throw new Error(t(
|
|
401
|
+
'policies.errors.conflict',
|
|
402
|
+
{operation: opLabel},
|
|
403
|
+
opLabel + ' failed: policy was modified in another tab/session. Reload the page, then re-apply your changes.'
|
|
404
|
+
));
|
|
405
|
+
}
|
|
406
|
+
if (!w.ok) {
|
|
407
|
+
const detail = w.status + ' ' + await w.text();
|
|
408
|
+
throw new Error(t('common.operation_failed', {operation: opLabel, detail}, opLabel + ' failed: ' + detail));
|
|
409
|
+
}
|
|
410
|
+
return await w.json();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Where a NEW tool's rules belong in the rule list: before the first
|
|
414
|
+
// wildcard rule, else at the end. In a require-approval list
|
|
415
|
+
// find_matching_rule() is first-match (it supplies remember_minutes and the
|
|
416
|
+
// matched_rule shown to the user), so a tool-specific rule appended after a
|
|
417
|
+
// `*` rule would never be the match. An allow list does not depend on order.
|
|
418
|
+
function wildcardInsertIndex(rules) {
|
|
419
|
+
const idx = rules.findIndex(rule => rule.tool_name === '*');
|
|
420
|
+
return idx === -1 ? rules.length : idx;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Mirrors bare_rule_gates() in policy/model.py.
|
|
424
|
+
function bareRuleGates(bare, effect, toolName) {
|
|
425
|
+
if (effect === 'allow') return !bare.has(toolName) && !bare.has('*');
|
|
426
|
+
return bare.has(toolName);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function isToolGated(toolName) {
|
|
430
|
+
return bareRuleGates(policyState.bareRuleTools, policyState.toolsEffect, toolName);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
async function syncPolicyRule(toolName, gated) {
|
|
434
|
+
const r = await fetch('./api/policy/config');
|
|
435
|
+
if (!r.ok) throw new Error(t('policies.errors.load', {status: r.status}, 'Could not load policy: ' + r.status));
|
|
436
|
+
const policy = await r.json();
|
|
437
|
+
policy.rules = policy.rules || [];
|
|
438
|
+
// The gate toggle manages ONLY the bare, unconditional rule (empty `when`)
|
|
439
|
+
// for this tool; predicate-bearing rules authored in the policy editor are
|
|
440
|
+
// preserved. A conditional rule must not be mistaken for the gate (enabling
|
|
441
|
+
// would silently no-op) nor wiped on un-gate. Under an allow list the bare
|
|
442
|
+
// rule approves the tool, so gating it means removing that rule.
|
|
443
|
+
const isBareGate = rule =>
|
|
444
|
+
rule.tool_name === toolName && (!rule.when || rule.when.length === 0);
|
|
445
|
+
if (gated !== (policy.rule_effect === 'allow')) {
|
|
446
|
+
if (!policy.rules.some(isBareGate)) {
|
|
447
|
+
policy.rules.splice(wildcardInsertIndex(policy.rules), 0,
|
|
448
|
+
{tool_name: toolName, when: [], remember_minutes: 0});
|
|
449
|
+
}
|
|
450
|
+
} else {
|
|
451
|
+
policy.rules = policy.rules.filter(rule => !isBareGate(rule));
|
|
452
|
+
}
|
|
453
|
+
// An allow list's bare `*` rule approves every tool, so gating one would
|
|
454
|
+
// save a no-op; refuse instead (set_tool(gated=) refuses the same way).
|
|
455
|
+
// A mode change since the page loaded is left to policyPut, whose message
|
|
456
|
+
// (reload) is the one that applies then.
|
|
457
|
+
const bare = new Set(policy.rules
|
|
458
|
+
.filter(rule => !rule.when || rule.when.length === 0)
|
|
459
|
+
.map(rule => rule.tool_name));
|
|
460
|
+
if (effectOf(policy) === policyState.toolsEffect
|
|
461
|
+
&& bareRuleGates(bare, effectOf(policy), toolName) !== gated) {
|
|
462
|
+
throw new Error(t(
|
|
463
|
+
'policies.errors.wildcard_rule',
|
|
464
|
+
{},
|
|
465
|
+
'An unconditional "*" rule in this allow list approves every tool, so this switch cannot gate one. Remove that rule on the Tool Security Policies tab first.'
|
|
466
|
+
));
|
|
467
|
+
}
|
|
468
|
+
await policyPut(policy, t('policies.operations.sync_gated', {}, 'Sync gated toggle'), policyState.toolsEffect);
|
|
469
|
+
}
|
|
470
|
+
|