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.
Files changed (721) hide show
  1. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/PKG-INFO +1 -1
  2. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/pyproject.toml +1 -1
  3. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/pyproject.toml.orig +1 -1
  4. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/__init__.py +27 -16
  5. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_i18n.py +10 -8
  6. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/README.md +5 -5
  7. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/01_i18n_state.js +470 -0
  8. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/02_tools_restart.js +428 -0
  9. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/03_render_save.js +584 -0
  10. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/04_backups.js +639 -0
  11. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/05_feature_flags.js +661 -0
  12. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/06_policy_cards.js +908 -0
  13. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/07_policy_actions.js +493 -0
  14. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/08_advanced.js +420 -0
  15. ha_mcp_dev-8.6.0.dev2852/src/ha_mcp/settings_ui/settings_js/09_prefs_visibility.js +425 -0
  16. ha_mcp_dev-8.6.0.dev2850/src/ha_mcp/settings_ui/settings.js +0 -5028
  17. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/LICENSE +0 -0
  18. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/README.md +0 -0
  19. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/__init__.py +0 -0
  20. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/__main__.py +0 -0
  21. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_pypi_marker +0 -0
  22. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_rich_compat.py +0 -0
  23. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/__init__.py +0 -0
  24. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/LICENSE +0 -0
  25. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/MANIFEST.sha256 +0 -0
  26. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/REQUIRES.txt +0 -0
  27. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/VENDORED +0 -0
  28. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/__init__.py +0 -0
  29. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/_compat.py +0 -0
  30. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/_install_hints.py +0 -0
  31. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/_warnings.py +0 -0
  32. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/__init__.py +0 -0
  33. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/app.py +0 -0
  34. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/approval.py +0 -0
  35. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/choice.py +0 -0
  36. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/config.py +0 -0
  37. {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
  38. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/form.py +0 -0
  39. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/apps/generative.py +0 -0
  40. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/__init__.py +0 -0
  41. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/__main__.py +0 -0
  42. {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
  43. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/auth.py +0 -0
  44. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/cimd.py +0 -0
  45. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/cli.py +0 -0
  46. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/client.py +0 -0
  47. {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
  48. {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
  49. {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
  50. {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
  51. {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
  52. {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
  53. {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
  54. {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
  55. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/discovery.py +0 -0
  56. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/generate.py +0 -0
  57. {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
  58. {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
  59. {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
  60. {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
  61. {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
  62. {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
  63. {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
  64. {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
  65. {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
  66. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/cli/run.py +0 -0
  67. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/__init__.py +0 -0
  68. {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
  69. {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
  70. {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
  71. {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
  72. {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
  73. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/caching.py +0 -0
  74. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/client.py +0 -0
  75. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/dependencies.py +0 -0
  76. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/elicitation.py +0 -0
  77. {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
  78. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/group.py +0 -0
  79. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/logging.py +0 -0
  80. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/messages.py +0 -0
  81. {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
  82. {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
  83. {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
  84. {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
  85. {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
  86. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/progress.py +0 -0
  87. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/roots.py +0 -0
  88. {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
  89. {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
  90. {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
  91. {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
  92. {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
  93. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/client/telemetry.py +0 -0
  94. {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
  95. {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
  96. {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
  97. {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
  98. {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
  99. {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
  100. {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
  101. {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
  102. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/contrib/README.md +0 -0
  103. {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
  104. {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
  105. {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
  106. {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
  107. {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
  108. {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
  109. {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
  110. {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
  111. {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
  112. {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
  113. {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
  114. {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
  115. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/decorators.py +0 -0
  116. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/dependencies.py +0 -0
  117. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/exceptions.py +0 -0
  118. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/experimental/__init__.py +0 -0
  119. {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
  120. {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
  121. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/mcp_config.py +0 -0
  122. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/prompts/__init__.py +0 -0
  123. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/prompts/base.py +0 -0
  124. {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
  125. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/py.typed +0 -0
  126. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/__init__.py +0 -0
  127. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/base.py +0 -0
  128. {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
  129. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/security.py +0 -0
  130. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/template.py +0 -0
  131. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/resources/types.py +0 -0
  132. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/__init__.py +0 -0
  133. {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
  134. {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
  135. {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
  136. {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
  137. {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
  138. {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
  139. {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
  140. {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
  141. {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
  142. {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
  143. {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
  144. {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
  145. {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
  146. {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
  147. {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
  148. {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
  149. {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
  150. {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
  151. {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
  152. {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
  153. {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
  154. {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
  155. {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
  156. {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
  157. {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
  158. {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
  159. {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
  160. {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
  161. {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
  162. {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
  163. {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
  164. {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
  165. {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
  166. {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
  167. {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
  168. {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
  169. {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
  170. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/caching.py +0 -0
  171. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/completions.py +0 -0
  172. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/context.py +0 -0
  173. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/dependencies.py +0 -0
  174. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/elicitation.py +0 -0
  175. {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
  176. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/extensions.py +0 -0
  177. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/http.py +0 -0
  178. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/lifespan.py +0 -0
  179. {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
  180. {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
  181. {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
  182. {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
  183. {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
  184. {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
  185. {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
  186. {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
  187. {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
  188. {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
  189. {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
  190. {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
  191. {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
  192. {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
  193. {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
  194. {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
  195. {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
  196. {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
  197. {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
  198. {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
  199. {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
  200. {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
  201. {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
  202. {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
  203. {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
  204. {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
  205. {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
  206. {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
  207. {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
  208. {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
  209. {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
  210. {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
  211. {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
  212. {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
  213. {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
  214. {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
  215. {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
  216. {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
  217. {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
  218. {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
  219. {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
  220. {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
  221. {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
  222. {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
  223. {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
  224. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/server.py +0 -0
  225. {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
  226. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/sessions.py +0 -0
  227. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/server/telemetry.py +0 -0
  228. {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
  229. {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
  230. {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
  231. {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
  232. {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
  233. {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
  234. {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
  235. {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
  236. {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
  237. {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
  238. {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
  239. {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
  240. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/settings.py +0 -0
  241. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/telemetry.py +0 -0
  242. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/tools/__init__.py +0 -0
  243. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/tools/base.py +0 -0
  244. {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
  245. {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
  246. {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
  247. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/types.py +0 -0
  248. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/__init__.py +0 -0
  249. {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
  250. {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
  251. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/auth.py +0 -0
  252. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/authorization.py +0 -0
  253. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/cli.py +0 -0
  254. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/components.py +0 -0
  255. {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
  256. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/exceptions.py +0 -0
  257. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/http.py +0 -0
  258. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/inspect.py +0 -0
  259. {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
  260. {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
  261. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/lifespan.py +0 -0
  262. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/logging.py +0 -0
  263. {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
  264. {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
  265. {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
  266. {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
  267. {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
  268. {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
  269. {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
  270. {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
  271. {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
  272. {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
  273. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/mime.py +0 -0
  274. {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
  275. {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
  276. {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
  277. {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
  278. {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
  279. {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
  280. {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
  281. {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
  282. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/pagination.py +0 -0
  283. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/prefab.py +0 -0
  284. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/skills.py +0 -0
  285. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/tasks.py +0 -0
  286. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/tests.py +0 -0
  287. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/timeout.py +0 -0
  288. {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
  289. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/types.py +0 -0
  290. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/ui.py +0 -0
  291. {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
  292. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/fastmcp/utilities/versions.py +0 -0
  293. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/LICENSE +0 -0
  294. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/MANIFEST.sha256 +0 -0
  295. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/REQUIRES.txt +0 -0
  296. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/VENDORED +0 -0
  297. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/__init__.py +0 -0
  298. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/cli/__init__.py +0 -0
  299. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/cli/claude.py +0 -0
  300. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/cli/cli.py +0 -0
  301. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/__init__.py +0 -0
  302. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/__main__.py +0 -0
  303. {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
  304. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/_memory.py +0 -0
  305. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/_probe.py +0 -0
  306. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/_transport.py +0 -0
  307. {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
  308. {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
  309. {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
  310. {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
  311. {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
  312. {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
  313. {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
  314. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/caching.py +0 -0
  315. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/client.py +0 -0
  316. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/context.py +0 -0
  317. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/extension.py +0 -0
  318. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/session.py +0 -0
  319. {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
  320. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/sse.py +0 -0
  321. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/stdio.py +0 -0
  322. {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
  323. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/client/subscriptions.py +0 -0
  324. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/os/__init__.py +0 -0
  325. {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
  326. {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
  327. {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
  328. {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
  329. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/py.typed +0 -0
  330. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/__init__.py +0 -0
  331. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/__main__.py +0 -0
  332. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/_otel.py +0 -0
  333. {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
  334. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/apps.py +0 -0
  335. {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
  336. {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
  337. {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
  338. {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
  339. {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
  340. {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
  341. {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
  342. {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
  343. {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
  344. {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
  345. {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
  346. {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
  347. {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
  348. {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
  349. {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
  350. {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
  351. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/caching.py +0 -0
  352. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/connection.py +0 -0
  353. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/context.py +0 -0
  354. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/elicitation.py +0 -0
  355. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/extension.py +0 -0
  356. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/fastmcp.py +0 -0
  357. {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
  358. {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
  359. {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
  360. {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
  361. {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
  362. {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
  363. {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
  364. {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
  365. {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
  366. {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
  367. {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
  368. {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
  369. {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
  370. {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
  371. {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
  372. {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
  373. {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
  374. {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
  375. {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
  376. {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
  377. {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
  378. {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
  379. {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
  380. {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
  381. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/models.py +0 -0
  382. {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
  383. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/runner.py +0 -0
  384. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/session.py +0 -0
  385. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/sse.py +0 -0
  386. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/stdio.py +0 -0
  387. {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
  388. {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
  389. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/subscriptions.py +0 -0
  390. {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
  391. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/server/validation.py +0 -0
  392. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/__init__.py +0 -0
  393. {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
  394. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_compat.py +0 -0
  395. {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
  396. {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
  397. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/_otel.py +0 -0
  398. {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
  399. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/auth.py +0 -0
  400. {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
  401. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/context.py +0 -0
  402. {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
  403. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/dispatcher.py +0 -0
  404. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/exceptions.py +0 -0
  405. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/extension.py +0 -0
  406. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/inbound.py +0 -0
  407. {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
  408. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/memory.py +0 -0
  409. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/message.py +0 -0
  410. {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
  411. {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
  412. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/peer.py +0 -0
  413. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/shared/subscriptions.py +0 -0
  414. {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
  415. {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
  416. {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
  417. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/__init__.py +0 -0
  418. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/jsonrpc.py +0 -0
  419. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/methods.py +0 -0
  420. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp/types/version.py +0 -0
  421. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/LICENSE +0 -0
  422. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/MANIFEST.sha256 +0 -0
  423. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/REQUIRES.txt +0 -0
  424. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/VENDORED +0 -0
  425. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/__init__.py +0 -0
  426. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/_types.py +0 -0
  427. {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
  428. {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
  429. {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
  430. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/jsonrpc.py +0 -0
  431. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/methods.py +0 -0
  432. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/py.typed +0 -0
  433. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/mcp_types/version.py +0 -0
  434. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/requirements.txt +0 -0
  435. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/LICENSE +0 -0
  436. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/MANIFEST.sha256 +0 -0
  437. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/VENDORED +0 -0
  438. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/__init__.py +0 -0
  439. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/__main__.py +0 -0
  440. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/__init__.py +0 -0
  441. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/client.py +0 -0
  442. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/connection.py +0 -0
  443. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/messages.py +0 -0
  444. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/router.py +0 -0
  445. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/asyncio/server.py +0 -0
  446. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/auth.py +0 -0
  447. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/cli.py +0 -0
  448. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/client.py +0 -0
  449. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/connection.py +0 -0
  450. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/datastructures.py +0 -0
  451. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/exceptions.py +0 -0
  452. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/extensions/__init__.py +0 -0
  453. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/extensions/base.py +0 -0
  454. {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
  455. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/frames.py +0 -0
  456. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/headers.py +0 -0
  457. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/http11.py +0 -0
  458. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/imports.py +0 -0
  459. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/__init__.py +0 -0
  460. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/auth.py +0 -0
  461. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/client.py +0 -0
  462. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/exceptions.py +0 -0
  463. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/framing.py +0 -0
  464. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/handshake.py +0 -0
  465. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/http.py +0 -0
  466. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/protocol.py +0 -0
  467. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/legacy/server.py +0 -0
  468. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/protocol.py +0 -0
  469. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/proxy.py +0 -0
  470. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/py.typed +0 -0
  471. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/server.py +0 -0
  472. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/streams.py +0 -0
  473. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/__init__.py +0 -0
  474. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/client.py +0 -0
  475. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/connection.py +0 -0
  476. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/messages.py +0 -0
  477. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/router.py +0 -0
  478. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/server.py +0 -0
  479. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/sync/utils.py +0 -0
  480. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/__init__.py +0 -0
  481. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/client.py +0 -0
  482. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/connection.py +0 -0
  483. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/messages.py +0 -0
  484. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/router.py +0 -0
  485. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/server.py +0 -0
  486. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/trio/utils.py +0 -0
  487. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/typing.py +0 -0
  488. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/uri.py +0 -0
  489. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/utils.py +0 -0
  490. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_vendor/websockets/version.py +0 -0
  491. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/_version.py +0 -0
  492. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/__init__.py +0 -0
  493. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/consent_form.py +0 -0
  494. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/oidc_compat.py +0 -0
  495. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/auth/provider.py +0 -0
  496. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/backup_manager.py +0 -0
  497. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/browser_landing.py +0 -0
  498. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/__init__.py +0 -0
  499. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/admin_routes.py +0 -0
  500. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/rest_client.py +0 -0
  501. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/supervisor_client.py +0 -0
  502. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/websocket_client.py +0 -0
  503. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/client/websocket_listener.py +0 -0
  504. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config.py +0 -0
  505. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_backup.py +0 -0
  506. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_overrides.py +0 -0
  507. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_registry.py +0 -0
  508. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/config_settings.py +0 -0
  509. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
  510. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
  511. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
  512. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
  513. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
  514. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
  515. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/errors.py +0 -0
  516. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/ha_request_queue.py +0 -0
  517. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/hacs_auto_refresh.py +0 -0
  518. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/http_transport.py +0 -0
  519. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/llm_exposure.py +0 -0
  520. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/log_filters.py +0 -0
  521. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/__init__.py +0 -0
  522. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/approval_queue.py +0 -0
  523. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/decision_pin.py +0 -0
  524. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/decisions.py +0 -0
  525. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/editing.py +0 -0
  526. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/evaluator.py +0 -0
  527. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/events.py +0 -0
  528. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/handlers.py +0 -0
  529. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/middleware.py +0 -0
  530. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/model.py +0 -0
  531. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/persistence.py +0 -0
  532. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/server_channels.py +0 -0
  533. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/policy/value_sources.py +0 -0
  534. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/py.typed +0 -0
  535. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/read_only.py +0 -0
  536. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/redaction.py +0 -0
  537. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/renamed_tools.py +0 -0
  538. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  539. {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
  540. {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
  541. {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
  542. {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
  543. {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
  544. {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
  545. {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
  546. {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
  547. {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
  548. {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
  549. {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
  550. {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
  551. {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
  552. {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
  553. {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
  554. {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
  555. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/server.py +0 -0
  556. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/server_lifespan.py +0 -0
  557. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/server_tool_text.py +0 -0
  558. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
  559. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
  560. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
  561. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
  562. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
  563. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
  564. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_locale_policy.py +0 -0
  565. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_persistence.py +0 -0
  566. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
  567. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_theme.py +0 -0
  568. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
  569. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/az.json +0 -0
  570. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/cs.json +0 -0
  571. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/de.json +0 -0
  572. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/en.json +0 -0
  573. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/eo.json +0 -0
  574. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/es.json +0 -0
  575. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/fr.json +0 -0
  576. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/it.json +0 -0
  577. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/ko.json +0 -0
  578. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/nl.json +0 -0
  579. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/pl.json +0 -0
  580. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
  581. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/sv.json +0 -0
  582. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/locales/tlh.json +0 -0
  583. {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
  584. {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
  585. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/settings.css +0 -0
  586. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/settings_ui/settings.html +0 -0
  587. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/smoke_test.py +0 -0
  588. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  589. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/strict_bps.py +0 -0
  590. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tool_dispatch.py +0 -0
  591. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/__init__.py +0 -0
  592. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/auto_backup.py +0 -0
  593. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/backup.py +0 -0
  594. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  595. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/best_practice_result.py +0 -0
  596. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/best_practice_variables.py +0 -0
  597. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/blueprint_sources.py +0 -0
  598. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/blueprint_substitute.py +0 -0
  599. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/blueprint_write.py +0 -0
  600. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/bulk_selector.py +0 -0
  601. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_api.py +0 -0
  602. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_config_entries.py +0 -0
  603. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_config_reads.py +0 -0
  604. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_dashboard_edit.py +0 -0
  605. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_devices.py +0 -0
  606. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_registries.py +0 -0
  607. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
  608. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_flow.py +0 -0
  609. {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
  610. {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
  611. {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
  612. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_identity.py +0 -0
  613. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/config_entry_reconfigure.py +0 -0
  614. {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
  615. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/dashboard_edit_errors.py +0 -0
  616. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/dashboard_list_checks.py +0 -0
  617. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/device_control.py +0 -0
  618. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/device_enrichment.py +0 -0
  619. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/entity_registration.py +0 -0
  620. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/entity_update_fields.py +0 -0
  621. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/error_log_parsing.py +0 -0
  622. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/hacs_registration.py +0 -0
  623. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/helpers.py +0 -0
  624. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/integration_reconfigure.py +0 -0
  625. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_common.py +0 -0
  626. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_sources.py +0 -0
  627. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_sources_fault.py +0 -0
  628. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/log_sources_supervisor.py +0 -0
  629. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/__init__.py +0 -0
  630. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/base.py +0 -0
  631. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/matter.py +0 -0
  632. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/thread.py +0 -0
  633. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/zigbee.py +0 -0
  634. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/radio/zwave.py +0 -0
  635. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/reference_validator.py +0 -0
  636. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/registry.py +0 -0
  637. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/renamed_tool_middleware.py +0 -0
  638. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/scene_discovery.py +0 -0
  639. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  640. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  641. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  642. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  643. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  644. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  645. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_graph.py +0 -0
  646. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  647. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  648. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  649. {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
  650. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_addons.py +0 -0
  651. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_areas.py +0 -0
  652. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_assist_pipeline.py +0 -0
  653. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  654. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  655. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_calendar.py +0 -0
  656. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_camera.py +0 -0
  657. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_categories.py +0 -0
  658. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_code.py +0 -0
  659. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  660. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  661. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  662. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  663. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  664. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
  665. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_dev.py +0 -0
  666. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_energy.py +0 -0
  667. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_entities.py +0 -0
  668. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  669. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_groups.py +0 -0
  670. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_hacs.py +0 -0
  671. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_history.py +0 -0
  672. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_integrations.py +0 -0
  673. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_labels.py +0 -0
  674. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_logs.py +0 -0
  675. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_radio.py +0 -0
  676. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_registry.py +0 -0
  677. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_resources.py +0 -0
  678. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_search.py +0 -0
  679. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_security_policy.py +0 -0
  680. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_service.py +0 -0
  681. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_services.py +0 -0
  682. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_system.py +0 -0
  683. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_themes.py +0 -0
  684. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_todo.py +0 -0
  685. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_traces.py +0 -0
  686. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_updates.py +0 -0
  687. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_utility.py +0 -0
  688. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  689. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  690. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
  691. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/tools_zones.py +0 -0
  692. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/util_helpers.py +0 -0
  693. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/tools/validation_middleware.py +0 -0
  694. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/__init__.py +0 -0
  695. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/categorized_search.py +0 -0
  696. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/component_search.py +0 -0
  697. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  698. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transforms/write_tool_note.py +0 -0
  699. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/transport_security.py +0 -0
  700. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/update_check.py +0 -0
  701. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/__init__.py +0 -0
  702. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/config_hash.py +0 -0
  703. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/config_write_lock.py +0 -0
  704. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/dashboard_patch.py +0 -0
  705. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/data_paths.py +0 -0
  706. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/device_registry_semantics.py +0 -0
  707. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/domain_handlers.py +0 -0
  708. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/entity_membership.py +0 -0
  709. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  710. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  711. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/mcp_client_host.py +0 -0
  712. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/operation_manager.py +0 -0
  713. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/python_sandbox.py +0 -0
  714. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/registry_update_lock.py +0 -0
  715. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/skill_loader.py +0 -0
  716. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/utils/usage_logger.py +0 -0
  717. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/__init__.py +0 -0
  718. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/enforcement.py +0 -0
  719. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/model.py +0 -0
  720. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/persistence.py +0 -0
  721. {ha_mcp_dev-8.6.0.dev2850 → ha_mcp_dev-8.6.0.dev2852}/src/ha_mcp/visibility/resolver.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 8.6.0.dev2850
3
+ Version: 8.6.0.dev2852
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Keywords: mcp,home-assistant,ai,automation,smart-home
6
6
  Author: Julien
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "ha-mcp-dev"
7
- version = "8.6.0.dev2850"
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.dev2850"
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 settings.js (a real file for
86
- # editor/JS tooling). It is a template with two sentinel tokens for the
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 settings.js being
93
- # present. If packaging drops it, fail with a packaging-specific ImportError
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
- _SETTINGS_JS_PATH = Path(__file__).parent / "settings.js"
97
+ _SETTINGS_JS_DIR = Path(__file__).parent / "settings_js"
96
98
  try:
97
- _settings_js_template = _SETTINGS_JS_PATH.read_text(encoding="utf-8")
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"settings.js missing at {_SETTINGS_JS_PATH}. It must ship in "
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
- # settings.js would ship a broken page green. Assert both sentinels are present
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"settings.js is out of sync: sentinel {_sentinel} not found. "
114
- "The Python injection and settings.js have drifted."
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
- # settings.js. Unlike the JS it has no Python injection points -- a plain
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 settings.js, so the same
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
- # settings.js / settings.css (a real file for editor/HTML tooling). It carries
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__ -> settings.js contents (inside <script>)
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 settings.js/css (wheel, sdist,
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 settings.js/css raise.
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
- ``settings.js`` performs the corresponding parity check against those
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 settings.js::tHtml restores after escaping. Keep in
403
- # sync with the restore regexes there — any other spelling (case, spacing,
404
- # attribute order) survives escaping and shows the user literal markup text.
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: settings.js hands the value to activateTab, which no-ops on an
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
- ``settings.js::tHtml`` escapes every translated value and restores only
491
- the exact allowlisted tag shapes, so a translation written with
492
- ``<CODE>`` or ``<code >`` would silently render as literal escaped text.
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.
@@ -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 `settings.js`
13
- are generated from these catalogs by `scripts/generate_locales.py` — never
14
- edit those by hand. Wherever one English string reaches the reader from more
15
- than one surface, the translation is stored once here and projected, so
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(/&lt;(\/?)(code|strong)&gt;/g, '<$1$2>')
39
+ .replace(/&lt;a href=&quot;#&quot; data-panel-link=&quot;([a-z][a-z-]*)&quot;&gt;/g, '<a href="#" data-panel-link="$1">')
40
+ .replace(/&lt;\/a&gt;/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
+