ha-mcp-dev 7.14.2.dev2091__tar.gz → 7.14.2.dev2093__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 (188) hide show
  1. {ha_mcp_dev-7.14.2.dev2091/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.14.2.dev2093}/PKG-INFO +1 -1
  2. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/pyproject.toml +1 -1
  3. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/config_entry_flow.py +156 -48
  4. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  5. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/LICENSE +0 -0
  6. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/MANIFEST.in +0 -0
  7. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/README.md +0 -0
  8. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/setup.cfg +0 -0
  9. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/__init__.py +0 -0
  10. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/__main__.py +0 -0
  11. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/_pypi_marker +0 -0
  12. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/_version.py +0 -0
  13. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/auth/__init__.py +0 -0
  14. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/auth/consent_form.py +0 -0
  15. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/auth/provider.py +0 -0
  16. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/backup_manager.py +0 -0
  17. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/browser_landing.py +0 -0
  18. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/client/__init__.py +0 -0
  19. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/client/rest_client.py +0 -0
  20. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/client/supervisor_client.py +0 -0
  21. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/client/websocket_client.py +0 -0
  22. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/client/websocket_listener.py +0 -0
  23. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/config.py +0 -0
  24. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
  25. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
  26. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
  27. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
  28. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
  29. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
  30. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/errors.py +0 -0
  31. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/llm_exposure.py +0 -0
  32. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/__init__.py +0 -0
  33. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/approval_queue.py +0 -0
  34. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/evaluator.py +0 -0
  35. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/handlers.py +0 -0
  36. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/middleware.py +0 -0
  37. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/model.py +0 -0
  38. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/persistence.py +0 -0
  39. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/policy/value_sources.py +0 -0
  40. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/py.typed +0 -0
  41. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/read_only.py +0 -0
  42. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  43. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  44. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  45. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  46. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
  47. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  48. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  49. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  50. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  51. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  52. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  53. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  54. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
  55. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  56. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
  57. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  58. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  59. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  60. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  61. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  62. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  63. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  64. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
  65. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  66. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
  67. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/server.py +0 -0
  68. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/__init__.py +0 -0
  69. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
  70. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
  71. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
  72. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
  73. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
  74. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
  75. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_i18n.py +0 -0
  76. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_persistence.py +0 -0
  77. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
  78. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_theme.py +0 -0
  79. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
  80. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/locales/README.md +0 -0
  81. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/locales/de.json +0 -0
  82. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/locales/en.json +0 -0
  83. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
  84. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/locales/zh-Hans.json +0 -0
  85. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/settings.css +0 -0
  86. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/settings.html +0 -0
  87. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/settings_ui/settings.js +0 -0
  88. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/smoke_test.py +0 -0
  89. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  90. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/strict_bps.py +0 -0
  91. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/__init__.py +0 -0
  92. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/auto_backup.py +0 -0
  93. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/backup.py +0 -0
  94. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  95. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/component_api.py +0 -0
  96. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/component_config_reads.py +0 -0
  97. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/component_devices.py +0 -0
  98. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/component_registries.py +0 -0
  99. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
  100. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/device_control.py +0 -0
  101. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/enhanced.py +0 -0
  102. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/helpers.py +0 -0
  103. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/radio/__init__.py +0 -0
  104. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/radio/base.py +0 -0
  105. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/radio/matter.py +0 -0
  106. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/radio/thread.py +0 -0
  107. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/radio/zigbee.py +0 -0
  108. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/radio/zwave.py +0 -0
  109. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/reference_validator.py +0 -0
  110. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/registry.py +0 -0
  111. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  112. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  113. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  114. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  115. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  116. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  117. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  118. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  119. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  120. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
  121. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_addons.py +0 -0
  122. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_areas.py +0 -0
  123. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  124. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  125. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_calendar.py +0 -0
  126. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_camera.py +0 -0
  127. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_categories.py +0 -0
  128. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_code.py +0 -0
  129. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  130. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  131. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  132. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  133. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  134. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
  135. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_dev.py +0 -0
  136. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_energy.py +0 -0
  137. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_entities.py +0 -0
  138. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  139. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_groups.py +0 -0
  140. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_hacs.py +0 -0
  141. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_history.py +0 -0
  142. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_integrations.py +0 -0
  143. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_labels.py +0 -0
  144. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_radio.py +0 -0
  145. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_registry.py +0 -0
  146. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_resources.py +0 -0
  147. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_search.py +0 -0
  148. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_service.py +0 -0
  149. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_services.py +0 -0
  150. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_system.py +0 -0
  151. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_themes.py +0 -0
  152. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_todo.py +0 -0
  153. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_traces.py +0 -0
  154. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_updates.py +0 -0
  155. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_utility.py +0 -0
  156. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  157. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  158. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
  159. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/tools_zones.py +0 -0
  160. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/util_helpers.py +0 -0
  161. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/tools/validation_middleware.py +0 -0
  162. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/transforms/__init__.py +0 -0
  163. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/transforms/categorized_search.py +0 -0
  164. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  165. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/transport_security.py +0 -0
  166. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/update_check.py +0 -0
  167. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/__init__.py +0 -0
  168. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/config_hash.py +0 -0
  169. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/data_paths.py +0 -0
  170. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/domain_handlers.py +0 -0
  171. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  172. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  173. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/operation_manager.py +0 -0
  174. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/python_sandbox.py +0 -0
  175. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/skill_loader.py +0 -0
  176. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/utils/usage_logger.py +0 -0
  177. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/visibility/__init__.py +0 -0
  178. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/visibility/model.py +0 -0
  179. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/visibility/persistence.py +0 -0
  180. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp/visibility/resolver.py +0 -0
  181. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  182. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  183. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  184. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  185. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  186. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/tests/__init__.py +0 -0
  187. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/tests/test_constants.py +0 -0
  188. {ha_mcp_dev-7.14.2.dev2091 → ha_mcp_dev-7.14.2.dev2093}/tests/test_env_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.14.2.dev2091
3
+ Version: 7.14.2.dev2093
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Author-email: Julien <github@qc-h.net>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ha-mcp-dev"
7
- version = "7.14.2.dev2091"
7
+ version = "7.14.2.dev2093"
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
@@ -11,6 +11,7 @@ for the 15 helper types listed in FLOW_HELPER_TYPES.
11
11
  """
12
12
 
13
13
  import asyncio
14
+ import copy
14
15
  import logging
15
16
  from collections.abc import Iterator
16
17
  from enum import StrEnum
@@ -78,6 +79,7 @@ _RECONFIGURE_SUCCESS_REASONS = frozenset(
78
79
  "reconfigure_successful",
79
80
  }
80
81
  )
82
+ _MISSING_DEFAULT = object()
81
83
 
82
84
 
83
85
  class _FlowType(StrEnum):
@@ -172,6 +174,47 @@ def _record_ignored_section_keys(
172
174
  )
173
175
 
174
176
 
177
+ def _field_default_value(field: dict[str, Any]) -> Any:
178
+ """Return a serialized schema field's default/suggested value, if present."""
179
+ description = field.get("description")
180
+ if isinstance(description, dict) and description.get("suggested_value") is not None:
181
+ return copy.deepcopy(description["suggested_value"])
182
+ if field.get("suggested_value") is not None:
183
+ return copy.deepcopy(field["suggested_value"])
184
+ if "default" in field:
185
+ return copy.deepcopy(field["default"])
186
+ return _MISSING_DEFAULT
187
+
188
+
189
+ def _schema_default_values(data_schema: list[Any]) -> dict[str, Any]:
190
+ """Build default form data from serialized schema suggestions/defaults."""
191
+ defaults: dict[str, Any] = {}
192
+ for field in data_schema:
193
+ if not isinstance(field, dict):
194
+ continue
195
+ name = field.get("name")
196
+ nested_schema = field.get("schema")
197
+ if not isinstance(name, str):
198
+ continue
199
+ if isinstance(nested_schema, list):
200
+ nested_defaults = _schema_default_values(nested_schema)
201
+ if nested_defaults:
202
+ defaults[name] = nested_defaults
203
+ continue
204
+ default = _field_default_value(field)
205
+ if default is not _MISSING_DEFAULT:
206
+ defaults[name] = default
207
+ return defaults
208
+
209
+
210
+ def _required_section_defaults(field: dict[str, Any]) -> dict[str, Any]:
211
+ """Return default data for a required section, otherwise an empty dict."""
212
+ nested_schema = field.get("schema")
213
+ if not field.get("required") or not isinstance(nested_schema, list):
214
+ return {}
215
+ return _schema_default_values(nested_schema)
216
+
217
+
175
218
  def _ignored_keys_warnings(
176
219
  ignored_config_keys: set[str], remaining_config: dict[str, Any]
177
220
  ) -> list[str]:
@@ -194,10 +237,89 @@ def _ignored_keys_warnings(
194
237
  return warnings
195
238
 
196
239
 
240
+ def _consume_section_schema(
241
+ field: dict[str, Any],
242
+ explicit_section: dict[str, Any] | None,
243
+ remaining_config: dict[str, Any],
244
+ ignored_config_keys: set[str] | None,
245
+ consumed_config_keys: set[str] | None,
246
+ path_prefix: str,
247
+ ) -> dict[str, Any]:
248
+ """Consume config values for a nested flow section."""
249
+ nested_schema = field.get("schema")
250
+ if not isinstance(nested_schema, list):
251
+ return {}
252
+
253
+ name = field.get("name")
254
+ section_path = _section_path(path_prefix, name)
255
+ nested_data = _required_section_defaults(field)
256
+
257
+ if explicit_section is not None:
258
+ explicit_remaining = dict(explicit_section)
259
+ nested_data.update(
260
+ _consume_form_schema(
261
+ nested_schema,
262
+ explicit_remaining,
263
+ ignored_config_keys,
264
+ consumed_config_keys,
265
+ section_path,
266
+ )
267
+ )
268
+ _record_ignored_section_keys(
269
+ ignored_config_keys,
270
+ explicit_remaining,
271
+ section_path,
272
+ )
273
+
274
+ nested_data.update(
275
+ _consume_form_schema(
276
+ nested_schema,
277
+ remaining_config,
278
+ ignored_config_keys,
279
+ consumed_config_keys,
280
+ section_path,
281
+ )
282
+ )
283
+ return nested_data
284
+
285
+
286
+ def _mark_consumed(
287
+ consumed_config_keys: set[str] | None,
288
+ path_prefix: str,
289
+ name: str,
290
+ ) -> None:
291
+ """Record that a caller-supplied form key, not an injected default, was used."""
292
+ if consumed_config_keys is not None:
293
+ consumed_config_keys.add(_section_path(path_prefix, name))
294
+
295
+
296
+ def _auto_confirm_form_payload(current_step: dict[str, Any]) -> dict[str, Any] | None:
297
+ """Return payload for HA preview/confirmation-only forms we can safely advance."""
298
+ if "preview" not in current_step:
299
+ return None
300
+ data_schema = current_step.get("data_schema")
301
+ if not isinstance(data_schema, list) or len(data_schema) != 1:
302
+ return None
303
+ field = data_schema[0]
304
+ if not isinstance(field, dict) or not field.get("required"):
305
+ return None
306
+ name = field.get("name")
307
+ if not isinstance(name, str) or name in _MENU_SELECTION_KEYS:
308
+ return None
309
+ default = _field_default_value(field)
310
+ if default is not False:
311
+ return None
312
+ selector = field.get("selector")
313
+ if isinstance(selector, dict) and selector and "boolean" not in selector:
314
+ return None
315
+ return {name: True}
316
+
317
+
197
318
  def _consume_form_schema(
198
319
  data_schema: list[Any],
199
320
  remaining_config: dict[str, Any],
200
321
  ignored_config_keys: set[str] | None = None,
322
+ consumed_config_keys: set[str] | None = None,
201
323
  path_prefix: str = "",
202
324
  ) -> dict[str, Any]:
203
325
  """Consume matching config values and shape nested flow sections.
@@ -208,7 +330,6 @@ def _consume_form_schema(
208
330
  ``ignored_config_keys`` with their dotted section path.
209
331
  """
210
332
  form_data: dict[str, Any] = {}
211
- missing = object()
212
333
 
213
334
  for field in data_schema:
214
335
  if not isinstance(field, dict):
@@ -217,47 +338,27 @@ def _consume_form_schema(
217
338
  name = field.get("name")
218
339
  nested_schema = field.get("schema")
219
340
  if isinstance(nested_schema, list):
220
- section_path = _section_path(path_prefix, name)
221
- explicit_section = (
222
- remaining_config.pop(name, missing)
223
- if isinstance(name, str)
224
- else missing
225
- )
226
- if explicit_section is not missing and not isinstance(
227
- explicit_section, dict
228
- ):
229
- if isinstance(name, str):
230
- form_data[name] = explicit_section
231
- continue
232
-
233
- nested_data: dict[str, Any] = {}
234
- if isinstance(explicit_section, dict):
235
- explicit_remaining = dict(explicit_section)
236
- nested_data.update(
237
- _consume_form_schema(
238
- nested_schema,
239
- explicit_remaining,
240
- ignored_config_keys,
241
- section_path,
242
- )
243
- )
244
- _record_ignored_section_keys(
245
- ignored_config_keys,
246
- explicit_remaining,
247
- section_path,
248
- )
249
- nested_data.update(
250
- _consume_form_schema(
251
- nested_schema,
252
- remaining_config,
253
- ignored_config_keys,
254
- section_path,
255
- )
341
+ section_name = name if isinstance(name, str) else None
342
+ explicit_section = None
343
+ if section_name is not None and section_name in remaining_config:
344
+ explicit_value = remaining_config.pop(section_name)
345
+ if not isinstance(explicit_value, dict):
346
+ form_data[section_name] = explicit_value
347
+ _mark_consumed(consumed_config_keys, path_prefix, section_name)
348
+ continue
349
+ explicit_section = explicit_value
350
+
351
+ nested_data = _consume_section_schema(
352
+ field,
353
+ explicit_section,
354
+ remaining_config,
355
+ ignored_config_keys,
356
+ consumed_config_keys,
357
+ path_prefix,
256
358
  )
257
-
258
359
  if nested_data:
259
- if isinstance(name, str):
260
- form_data[name] = nested_data
360
+ if section_name is not None:
361
+ form_data[section_name] = nested_data
261
362
  else:
262
363
  form_data.update(nested_data)
263
364
  continue
@@ -268,6 +369,7 @@ def _consume_form_schema(
268
369
  and name in remaining_config
269
370
  ):
270
371
  form_data[name] = remaining_config.pop(name)
372
+ _mark_consumed(consumed_config_keys, path_prefix, name)
271
373
 
272
374
  return form_data
273
375
 
@@ -296,6 +398,7 @@ def _handle_form_step(
296
398
  current_step: dict[str, Any],
297
399
  remaining_config: dict[str, Any],
298
400
  ignored_config_keys: set[str] | None = None,
401
+ consumed_config_keys: set[str] | None = None,
299
402
  ) -> dict[str, Any]:
300
403
  """Validate a form step and return form data to submit.
301
404
 
@@ -337,9 +440,10 @@ def _handle_form_step(
337
440
  if key in _MENU_SELECTION_KEYS:
338
441
  continue
339
442
  form_data[key] = remaining_config.pop(key)
443
+ _mark_consumed(consumed_config_keys, "", key)
340
444
  else:
341
445
  form_data = _consume_form_schema(
342
- data_schema, remaining_config, ignored_config_keys
446
+ data_schema, remaining_config, ignored_config_keys, consumed_config_keys
343
447
  )
344
448
 
345
449
  return form_data
@@ -783,13 +887,17 @@ async def _handle_flow_steps(
783
887
  # for subsequent steps (HA can present multi-step forms, e.g.
784
888
  # statistics: user step then pick-characteristic step).
785
889
  saw_form_step = True
786
- form_data = _handle_form_step(
787
- flow_id,
788
- current_step,
789
- remaining_config,
790
- ignored_config_keys,
791
- )
792
- if form_data:
890
+ consumed_form_keys: set[str] = set()
891
+ form_data = _auto_confirm_form_payload(current_step)
892
+ if form_data is None:
893
+ form_data = _handle_form_step(
894
+ flow_id,
895
+ current_step,
896
+ remaining_config,
897
+ ignored_config_keys,
898
+ consumed_form_keys,
899
+ )
900
+ if consumed_form_keys:
793
901
  any_form_key_consumed = True
794
902
  logger.debug(
795
903
  f"Flow step {step_num}: form submit "
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.14.2.dev2091
3
+ Version: 7.14.2.dev2093
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Author-email: Julien <github@qc-h.net>
6
6
  License: MIT