ha-mcp-dev 8.3.0.dev2450__tar.gz → 8.3.0.dev2454__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ha_mcp_dev-8.3.0.dev2450/src/ha_mcp_dev.egg-info → ha_mcp_dev-8.3.0.dev2454}/PKG-INFO +1 -1
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/pyproject.toml +1 -1
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +3 -3
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +2 -2
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +112 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +1 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/AGENTS.md +99 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/CLAUDE.md +99 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +63 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/README.md +117 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/area-target-over-entity-list/case.yaml +49 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/arrive-home-automation/case.yaml +41 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/assist-shortcut-card/case.yaml +37 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/avg-temperature/case.yaml +50 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/backup-deletion-confirmation/case.yaml +52 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/blueprint-authoring/case.yaml +83 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/button-event-entity/case.yaml +61 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/device-id-trigger-migration/case.yaml +57 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/helper-flow-fields-not-platform-yaml/case.yaml +72 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/media-player-song/case.yaml +52 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/motion-light-automation-mode/case.yaml +52 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/rename-entity-impact-analysis/case.yaml +54 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/template-attributes-yaml-exception/case.yaml +65 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/timer-finished-automation/case.yaml +49 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/vacuum-last-clean/case.yaml +54 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/scripts/check_eval_cases.py +324 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +149 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +11 -9
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +18 -18
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/backups.md +6 -6
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +6 -4
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +1 -1
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +16 -34
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +97 -33
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +1 -31
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +350 -0
- ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +1283 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +58 -8
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +14 -12
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +207 -44
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +12 -4
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp_dev.egg-info/SOURCES.txt +16 -1
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -89
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -40
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -40
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -54
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/README.md +0 -87
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -152
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -101
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -326
- ha_mcp_dev-8.3.0.dev2450/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -1064
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/LICENSE +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/MANIFEST.in +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/README.md +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/setup.cfg +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_rich_compat.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/requirements.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/LICENSE +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/VENDORED +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/__main__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/asyncio/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/asyncio/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/asyncio/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/asyncio/messages.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/asyncio/router.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/asyncio/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/auth.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/cli.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/datastructures.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/exceptions.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/extensions/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/extensions/base.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/extensions/permessage_deflate.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/frames.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/headers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/http11.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/imports.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/auth.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/exceptions.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/framing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/handshake.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/http.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/protocol.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/legacy/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/protocol.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/proxy.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/py.typed +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/streams.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/sync/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/sync/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/sync/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/sync/messages.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/sync/router.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/sync/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/sync/utils.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/trio/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/trio/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/trio/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/trio/messages.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/trio/router.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/trio/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/trio/utils.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/typing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/uri.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/utils.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_vendor/websockets/version.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/auth/oidc_compat.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/browser_landing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/hacs_auto_refresh.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/llm_exposure.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/log_filters.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/editing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/redaction.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/renamed_tools.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_i18n.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_locale_policy.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_persistence.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_theme.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/README.md +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/cs.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/de.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/en.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/eo.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/es.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/fr.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/it.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/ko.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/nl.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/pl.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/sv.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/tlh.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/locales/zh-Hans.json +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/settings.html +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/settings_ui/settings.js +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/strict_bps.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/best_practice_result.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/best_practice_variables.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/bulk_selector.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/component_api.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/component_config_entries.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/component_config_reads.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/component_devices.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/component_registries.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/config_entry_flow_form.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/config_entry_flow_menu.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/config_entry_flow_walker.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/config_entry_identity.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/config_entry_reconfigure.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/config_entry_reload_watch.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/error_log_parsing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/hacs_registration.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/integration_reconfigure.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/log_common.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/log_sources.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/log_sources_supervisor.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/renamed_tool_middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_graph.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_assist_pipeline.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_dev.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_logs.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_security_policy.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/transport_security.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/config_write_lock.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/entity_membership.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/visibility/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/visibility/enforcement.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/visibility/model.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/visibility/persistence.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp/visibility/resolver.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/tests/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/tests/test_constants.py +0 -0
- {ha_mcp_dev-8.3.0.dev2450 → ha_mcp_dev-8.3.0.dev2454}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "8.3.0.
|
|
7
|
+
version = "8.3.0.dev2454"
|
|
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
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
"email": "homeassistant-mcp@qc-h.net"
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
|
-
"description": "Agent skills for Home Assistant: best practices for automations, helpers, templates, device control, and
|
|
9
|
-
"version": "0.
|
|
8
|
+
"description": "Agent skills for Home Assistant: best practices for automations, helpers, templates, scenes, blueprints, device control, dashboards, AppDaemon, and backups",
|
|
9
|
+
"version": "0.26.0"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "home-assistant-skills",
|
|
14
|
-
"description": "Best practices for Home Assistant automations, helpers, scripts, device
|
|
14
|
+
"description": "Best practices for Home Assistant automations, helpers, scripts, scenes, blueprints, device control, dashboards, AppDaemon apps, and backups",
|
|
15
15
|
"source": "./"
|
|
16
16
|
}
|
|
17
17
|
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "home-assistant-skills",
|
|
3
|
-
"description": "Agent skills for Home Assistant: best practices for automations, helpers, templates, device control, and
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "Agent skills for Home Assistant: best practices for automations, helpers, templates, scenes, blueprints, device control, dashboards, AppDaemon, and backups.",
|
|
4
|
+
"version": "0.26.0",
|
|
5
5
|
"repository": "https://github.com/homeassistant-ai/skills",
|
|
6
6
|
"license": "MIT"
|
|
7
7
|
}
|
ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Report Bad Skill Advice
|
|
3
|
+
about: A skill misled your agent. Have your agent fill out this report so we can fix the skill.
|
|
4
|
+
title: "[RCA] "
|
|
5
|
+
labels: rca
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<!--
|
|
9
|
+
HOW TO FILE
|
|
10
|
+
|
|
11
|
+
For the user: give your agent this template and ask it to fill the report in —
|
|
12
|
+
it holds the full context of what went wrong. The raw file is at
|
|
13
|
+
https://raw.githubusercontent.com/homeassistant-ai/skills/main/.github/ISSUE_TEMPLATE/skill-rca.md
|
|
14
|
+
|
|
15
|
+
For the agent: write the report in Markdown, then either file it yourself:
|
|
16
|
+
|
|
17
|
+
gh issue create --repo homeassistant-ai/skills \
|
|
18
|
+
--title "[RCA] <skill>: <one-line failure>" \
|
|
19
|
+
--body-file report.md --label rca
|
|
20
|
+
|
|
21
|
+
If --label is rejected (it needs triage access), either file through the
|
|
22
|
+
"New issue" web form — the template applies the label for you — or drop the
|
|
23
|
+
flag; the [RCA] title prefix is enough for triage. Without GitHub access at
|
|
24
|
+
all, hand the Markdown back to the user to paste into that form. Paste
|
|
25
|
+
Markdown, not rendered HTML.
|
|
26
|
+
|
|
27
|
+
INSTRUCTIONS FOR THE AGENT
|
|
28
|
+
|
|
29
|
+
A skill in this repository misled you, and your user saw the result.
|
|
30
|
+
|
|
31
|
+
BEFORE FILING:
|
|
32
|
+
- Search existing issues for the same skill and failure. If a matching
|
|
33
|
+
issue exists, react with thumbs-up or comment with additional context.
|
|
34
|
+
Open a new issue only when the failure is unreported.
|
|
35
|
+
- Did the skill actually load? If it never triggered, this is a triggering
|
|
36
|
+
failure, not a content failure: write "Skill did not trigger" in 3a, keep
|
|
37
|
+
the user's request verbatim apart from redactions (it is the prompt that
|
|
38
|
+
failed to trigger the skill), and skip 3b and 3c.
|
|
39
|
+
- Did you follow the skill's guidance? If you skipped guidance that would
|
|
40
|
+
have prevented the failure, that is not a skill bug. Report only what the
|
|
41
|
+
skill got wrong or left out.
|
|
42
|
+
- Redact before filing: tokens, URLs, IP addresses, email addresses, names,
|
|
43
|
+
and anything from the user's setup the public need not see — replace each
|
|
44
|
+
with [REDACTED] and keep the wording otherwise. Show the user the finished
|
|
45
|
+
report and get an explicit go-ahead before you file it.
|
|
46
|
+
|
|
47
|
+
Fill out each section below. Quote the skill content that misled you,
|
|
48
|
+
list affected entities and configs, and mark the first failure point.
|
|
49
|
+
|
|
50
|
+
Write "N/A" for any section that is irrelevant.
|
|
51
|
+
-->
|
|
52
|
+
|
|
53
|
+
## 1. Context
|
|
54
|
+
|
|
55
|
+
- **Skill name:** <!-- e.g. home-assistant-best-practices -->
|
|
56
|
+
- **Skill version:** <!-- metadata.version in SKILL.md frontmatter; plugin version 0.N.0 is skill version N. If main is ahead, say so — a stale install may already be fixed -->
|
|
57
|
+
- **What the user originally asked you to do:** <!-- verbatim apart from redactions -->
|
|
58
|
+
|
|
59
|
+
## 2. Timeline
|
|
60
|
+
|
|
61
|
+
List each action you took. For each, record what you did, what resulted, and its status (e.g., Success, Failure).
|
|
62
|
+
|
|
63
|
+
Mark the first failing step with **[GAP]** in the `Status` column.
|
|
64
|
+
|
|
65
|
+
| Step | Action | Result | Status |
|
|
66
|
+
|------|--------|--------|-----|
|
|
67
|
+
| 1 | | | |
|
|
68
|
+
| 2 | | | |
|
|
69
|
+
| 3 | | | |
|
|
70
|
+
|
|
71
|
+
<!-- Add or remove rows as needed. -->
|
|
72
|
+
|
|
73
|
+
## 3. Root Cause
|
|
74
|
+
|
|
75
|
+
### 3a. What skill instruction did you follow?
|
|
76
|
+
|
|
77
|
+
<!--
|
|
78
|
+
Quote the SKILL.md passage or reference file section that guided
|
|
79
|
+
your actions. Include the file name and section heading.
|
|
80
|
+
If the skill offered no guidance for this scenario, write:
|
|
81
|
+
"No guidance found in the skill for this scenario."
|
|
82
|
+
If the skill never loaded, write "Skill did not trigger" and skip 3b and 3c.
|
|
83
|
+
-->
|
|
84
|
+
|
|
85
|
+
### 3b. What did that instruction cause you to do (or not do)?
|
|
86
|
+
|
|
87
|
+
<!--
|
|
88
|
+
Describe the action or omission that caused the failure,
|
|
89
|
+
and tie it to the skill content you quoted in 3a.
|
|
90
|
+
-->
|
|
91
|
+
|
|
92
|
+
### 3c. What should the skill have told you instead?
|
|
93
|
+
|
|
94
|
+
<!--
|
|
95
|
+
Describe the guidance the skill should have included
|
|
96
|
+
to prevent this failure.
|
|
97
|
+
-->
|
|
98
|
+
|
|
99
|
+
## 4. Impact
|
|
100
|
+
|
|
101
|
+
<!--
|
|
102
|
+
How bad was it: what the user saw beyond the timeline (silent failures,
|
|
103
|
+
lost data, how long it went unnoticed) and every affected component:
|
|
104
|
+
dashboards, automations, configurations, entities, integrations, etc.
|
|
105
|
+
If the failure affected only the immediate task, say so.
|
|
106
|
+
-->
|
|
107
|
+
|
|
108
|
+
## 5. Environment
|
|
109
|
+
|
|
110
|
+
- **Home Assistant version and install type:** <!-- e.g. 2026.8.1 on Home Assistant OS; or Container, Core, Supervised -->
|
|
111
|
+
- **Agent platform, model, and HA access:** <!-- e.g. Claude Code with Opus 5 via an MCP server (name and version); Cursor with the REST API; Codex, files only -->
|
|
112
|
+
- **Integration / device type involved:** <!-- e.g. ZHA, Z2M, IKEA FYRTUR, or N/A -->
|
|
@@ -6,3 +6,4 @@
|
|
|
6
6
|
|
|
7
7
|
- [ ] Tested with real scenarios (if changing skill content)
|
|
8
8
|
- [ ] `README.md` Skill Contents table updated (if reference files were added or removed)
|
|
9
|
+
- [ ] Row descriptions and the **Included Skill** summary still match what the files cover (if a reference file's scope changed)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Repo Layout
|
|
6
|
+
|
|
7
|
+
Eval cases live in a top-level `evals/<case>/case.yaml`, **not** under `skills/`. `claude
|
|
8
|
+
plugin eval` rejects any eval directory whose first segment names a loaded component directory
|
|
9
|
+
(`commands`, `skills`, `agents`, `hooks`, `themes`, `output-styles`, `monitors`, `workflows`,
|
|
10
|
+
`bin`) — and rejects it *softly*: it warns, falls back to the default `evals/`, and finds
|
|
11
|
+
nothing, so cases in the wrong place silently never run. `evals/` at the plugin root is the
|
|
12
|
+
default and needs no `experimental.evals` key.
|
|
13
|
+
|
|
14
|
+
**SKILL.md is in context on every trigger; `references/` load only when read.** That is why
|
|
15
|
+
SKILL.md body size is capped and why domain-niche content belongs in a reference file behind
|
|
16
|
+
a single routing row, not in the always-loaded table.
|
|
17
|
+
|
|
18
|
+
## Skill Format
|
|
19
|
+
|
|
20
|
+
Every skill is a `SKILL.md` with `name`/`description` frontmatter. Full authoring constraints: `CONTRIBUTING.md`. The one CI cannot catch:
|
|
21
|
+
- `metadata.version` must be `"0"` on new skills — do not edit manually; CI assigns the real version on merge and syncs it into `.claude-plugin/plugin.json` (`.version`) and `.claude-plugin/marketplace.json` (`.metadata.version`) — three files, one source of truth
|
|
22
|
+
- `description` is capped at 1024 chars and runs close to it — measure the parsed length before adding trigger/symptom bullets: `uvx --from skills-ref agentskills read-properties skills/<skill-name> | jq '.description | length'`
|
|
23
|
+
|
|
24
|
+
## Skill Authoring Principles
|
|
25
|
+
|
|
26
|
+
The wording of these content-quality principles is mirrored in `CONTRIBUTING.md`
|
|
27
|
+
(contributors); each file also carries guidance the other omits. When you change a shared
|
|
28
|
+
principle, change both — they have drifted before.
|
|
29
|
+
|
|
30
|
+
- **Context window conservation** — keep what is HA-specific, cut general programming advice; the test is the content itself, not whether a given model already knows it (skills run on frontier and small local models alike)
|
|
31
|
+
- **Conciseness** — provide patterns and quick-reference tables, not tutorials
|
|
32
|
+
- **Consistent terminology** — one term per concept throughout a skill; contrasting code blocks are `# WRONG — why` / `# RIGHT — why` (emoji only in table status columns). A renamed HA term uses the new name and cites the old one with its version ("named Developer Tools before 2026.8") — never a bare swap, since readers on older releases still see the old label
|
|
33
|
+
- **Symptom-based triggering** — the `description` frontmatter should describe observable agent behaviors that signal the skill is needed
|
|
34
|
+
- **No tool names** — reference HA REST APIs and concepts, never specific MCP tool names (e.g. `ha_rename_entity`); tool names vary by agent setup
|
|
35
|
+
|
|
36
|
+
## Validation
|
|
37
|
+
|
|
38
|
+
To validate locally:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uvx --from skills-ref agentskills validate skills/<skill-name>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Four more checks gate a merge. `agnix` and `lychee` run as release binaries pinned in
|
|
45
|
+
`.github/workflows/` — install those versions (lychee's release tag is `lychee-vX.Y.Z`, not
|
|
46
|
+
`vX.Y.Z`); `claude plugin validate` ships with the Claude Code CLI; the eval-case checker is
|
|
47
|
+
in-repo and needs only PyYAML:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
agnix skills/ --target claude-code # spec conformance
|
|
51
|
+
lychee --offline --include-fragments --no-progress './**/*.md' # local links + #anchors
|
|
52
|
+
claude plugin validate . # plugin manifests
|
|
53
|
+
python scripts/check_eval_cases.py # evals/<case>/case.yaml
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
agnix catches what skills-ref's unenforced `metadata: dict[str, str]` annotation lets pass —
|
|
57
|
+
e.g. an unquoted integer version, which strict clients refuse. In CI (`links.yml`) lychee runs
|
|
58
|
+
that same local check on PRs touching `.md`/`.yaml`, plus external URLs weekly, dot-directories
|
|
59
|
+
excluded; it cannot see references written as inline code. `check_eval_cases.py` validates the
|
|
60
|
+
shape of eval cases against the `claude plugin eval` 1.1 schema — that command is gated behind
|
|
61
|
+
early access, so its own parser never runs here; the schema is transcribed by hand and needs
|
|
62
|
+
re-deriving if `schema_version` moves. It checks structure only and never runs a case. Regex
|
|
63
|
+
graders are compiled with `node`, not Python `re`: the two disagree (`re` rejects JS-valid
|
|
64
|
+
`(?<name>x)` and accepts Python-only `(?P<name>x)`), and without `node` that check is skipped
|
|
65
|
+
with a warning rather than failed.
|
|
66
|
+
|
|
67
|
+
Four things nothing checks, so all four stay review items: that every reference file is
|
|
68
|
+
still routed from SKILL.md, that `references/examples.yaml` still parses, that an eval
|
|
69
|
+
grader still means what it was written to mean, and that the descriptions in SKILL.md's
|
|
70
|
+
reference table and README's **Skill Contents** table still match what the files cover.
|
|
71
|
+
The last one drifts silently — link checking keeps the *file list* honest while the prose
|
|
72
|
+
beside it goes stale, so a row can point at the right file and still describe an older
|
|
73
|
+
version of it.
|
|
74
|
+
|
|
75
|
+
To check that a prompt actually triggers the skill (the eval suite cannot run yet), run it in
|
|
76
|
+
a fresh session from an empty directory and look for the `Skill` call in the stream:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
claude -p "<prompt>" --plugin-dir <repo-root> --output-format stream-json --verbose --max-turns 1 --allowedTools Skill
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`--max-turns 1` is enough — the call appears in the first response — so a check is one API
|
|
83
|
+
call (~25k tokens of system prompt and skill descriptions; `--model haiku` is the cheapest and
|
|
84
|
+
also the stricter test). `--plugin-dir` tests the working tree, not the installed plugin,
|
|
85
|
+
which may be releases behind. Disable other plugins for the run (`--settings` with an
|
|
86
|
+
`enabledPlugins` map): a plugin hook that orders skill use makes any prompt pass. The `Base
|
|
87
|
+
directory for this skill:` line in the output confirms which copy loaded. From inside a
|
|
88
|
+
Claude Code session, prefix `env -u CLAUDECODE` or the nested `claude` refuses to start.
|
|
89
|
+
|
|
90
|
+
## Reviewing Skill PRs
|
|
91
|
+
|
|
92
|
+
- Judge prose as agent-consumed context, not human docs — the Skill Authoring Principles above are the review bar (e.g. an operator→result lookup table beats narrative bullets, because agents land here holding one case to resolve)
|
|
93
|
+
- Skills make version-pinned claims about HA behavior — verify against source at the current tag (`gh api repos/home-assistant/core/releases --jq '.[0].tag_name'`): `gh api repos/home-assistant/core/contents/<path>?ref=<tag> --jq .content | base64 -d`
|
|
94
|
+
- Purpose-specific trigger/condition keys aren't enumerable from core source — list them from the docs repo: `gh api "repos/home-assistant/home-assistant.io/contents/source/_triggers?ref=current" --jq '.[].name'` (also `_conditions`, `_actions`)
|
|
95
|
+
- UI renames, terminology, and default changes appear only in release blog posts, not core source: `source/_posts/<date>-release-<version>.markdown` in the docs repo (e.g. `2026-08-05-release-20268.markdown`). Use `gh api` — plain `curl` is sandboxed here and returns empty
|
|
96
|
+
- **The blog says *what* changed, not *which version* it landed in.** Its prose often implies a feature pre-existed ("X now has conditions to match its triggers") when the whole component is new. Date a feature by fetching its path at the *previous* tag — a 404 at the previous tag that exists at the current one means the whole thing is new
|
|
97
|
+
- Community PRs come from forks: base-repo `?ref=<pr-branch>` 404s; get the fork with `gh pr view <pr> --json headRepository` and fetch files from there
|
|
98
|
+
- Helper claims need **both** `config_flow.py` (flow submission) and the platform file's `PLATFORM_SCHEMA` (YAML) — they diverge in key names, value types, and which keys exist. Traps: `vol.Required(` usually puts the `CONF_*` on the *next* line, so grep drops fields and mis-attributes Required/Optional; resolve `CONF_*` to its string (`CONF_ROUND_DIGITS` is `"round"` in derivative, `"round_digits"` in min_max); `options_flow`-only fields are rejected at creation
|
|
99
|
+
- Verifying a claim confirms what it says, not whether it over-generalizes. Add a pass that tries to disprove ("which helpers does this NOT hold for?"), mechanically where possible — e.g. diff the two schemas' key sets in a script
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Repo Layout
|
|
6
|
+
|
|
7
|
+
Eval cases live in a top-level `evals/<case>/case.yaml`, **not** under `skills/`. `claude
|
|
8
|
+
plugin eval` rejects any eval directory whose first segment names a loaded component directory
|
|
9
|
+
(`commands`, `skills`, `agents`, `hooks`, `themes`, `output-styles`, `monitors`, `workflows`,
|
|
10
|
+
`bin`) — and rejects it *softly*: it warns, falls back to the default `evals/`, and finds
|
|
11
|
+
nothing, so cases in the wrong place silently never run. `evals/` at the plugin root is the
|
|
12
|
+
default and needs no `experimental.evals` key.
|
|
13
|
+
|
|
14
|
+
**SKILL.md is in context on every trigger; `references/` load only when read.** That is why
|
|
15
|
+
SKILL.md body size is capped and why domain-niche content belongs in a reference file behind
|
|
16
|
+
a single routing row, not in the always-loaded table.
|
|
17
|
+
|
|
18
|
+
## Skill Format
|
|
19
|
+
|
|
20
|
+
Every skill is a `SKILL.md` with `name`/`description` frontmatter. Full authoring constraints: `CONTRIBUTING.md`. The one CI cannot catch:
|
|
21
|
+
- `metadata.version` must be `"0"` on new skills — do not edit manually; CI assigns the real version on merge and syncs it into `.claude-plugin/plugin.json` (`.version`) and `.claude-plugin/marketplace.json` (`.metadata.version`) — three files, one source of truth
|
|
22
|
+
- `description` is capped at 1024 chars and runs close to it — measure the parsed length before adding trigger/symptom bullets: `uvx --from skills-ref agentskills read-properties skills/<skill-name> | jq '.description | length'`
|
|
23
|
+
|
|
24
|
+
## Skill Authoring Principles
|
|
25
|
+
|
|
26
|
+
The wording of these content-quality principles is mirrored in `CONTRIBUTING.md`
|
|
27
|
+
(contributors); each file also carries guidance the other omits. When you change a shared
|
|
28
|
+
principle, change both — they have drifted before.
|
|
29
|
+
|
|
30
|
+
- **Context window conservation** — keep what is HA-specific, cut general programming advice; the test is the content itself, not whether a given model already knows it (skills run on frontier and small local models alike)
|
|
31
|
+
- **Conciseness** — provide patterns and quick-reference tables, not tutorials
|
|
32
|
+
- **Consistent terminology** — one term per concept throughout a skill; contrasting code blocks are `# WRONG — why` / `# RIGHT — why` (emoji only in table status columns). A renamed HA term uses the new name and cites the old one with its version ("named Developer Tools before 2026.8") — never a bare swap, since readers on older releases still see the old label
|
|
33
|
+
- **Symptom-based triggering** — the `description` frontmatter should describe observable agent behaviors that signal the skill is needed
|
|
34
|
+
- **No tool names** — reference HA REST APIs and concepts, never specific MCP tool names (e.g. `ha_rename_entity`); tool names vary by agent setup
|
|
35
|
+
|
|
36
|
+
## Validation
|
|
37
|
+
|
|
38
|
+
To validate locally:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uvx --from skills-ref agentskills validate skills/<skill-name>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Four more checks gate a merge. `agnix` and `lychee` run as release binaries pinned in
|
|
45
|
+
`.github/workflows/` — install those versions (lychee's release tag is `lychee-vX.Y.Z`, not
|
|
46
|
+
`vX.Y.Z`); `claude plugin validate` ships with the Claude Code CLI; the eval-case checker is
|
|
47
|
+
in-repo and needs only PyYAML:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
agnix skills/ --target claude-code # spec conformance
|
|
51
|
+
lychee --offline --include-fragments --no-progress './**/*.md' # local links + #anchors
|
|
52
|
+
claude plugin validate . # plugin manifests
|
|
53
|
+
python scripts/check_eval_cases.py # evals/<case>/case.yaml
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
agnix catches what skills-ref's unenforced `metadata: dict[str, str]` annotation lets pass —
|
|
57
|
+
e.g. an unquoted integer version, which strict clients refuse. In CI (`links.yml`) lychee runs
|
|
58
|
+
that same local check on PRs touching `.md`/`.yaml`, plus external URLs weekly, dot-directories
|
|
59
|
+
excluded; it cannot see references written as inline code. `check_eval_cases.py` validates the
|
|
60
|
+
shape of eval cases against the `claude plugin eval` 1.1 schema — that command is gated behind
|
|
61
|
+
early access, so its own parser never runs here; the schema is transcribed by hand and needs
|
|
62
|
+
re-deriving if `schema_version` moves. It checks structure only and never runs a case. Regex
|
|
63
|
+
graders are compiled with `node`, not Python `re`: the two disagree (`re` rejects JS-valid
|
|
64
|
+
`(?<name>x)` and accepts Python-only `(?P<name>x)`), and without `node` that check is skipped
|
|
65
|
+
with a warning rather than failed.
|
|
66
|
+
|
|
67
|
+
Four things nothing checks, so all four stay review items: that every reference file is
|
|
68
|
+
still routed from SKILL.md, that `references/examples.yaml` still parses, that an eval
|
|
69
|
+
grader still means what it was written to mean, and that the descriptions in SKILL.md's
|
|
70
|
+
reference table and README's **Skill Contents** table still match what the files cover.
|
|
71
|
+
The last one drifts silently — link checking keeps the *file list* honest while the prose
|
|
72
|
+
beside it goes stale, so a row can point at the right file and still describe an older
|
|
73
|
+
version of it.
|
|
74
|
+
|
|
75
|
+
To check that a prompt actually triggers the skill (the eval suite cannot run yet), run it in
|
|
76
|
+
a fresh session from an empty directory and look for the `Skill` call in the stream:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
claude -p "<prompt>" --plugin-dir <repo-root> --output-format stream-json --verbose --max-turns 1 --allowedTools Skill
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`--max-turns 1` is enough — the call appears in the first response — so a check is one API
|
|
83
|
+
call (~25k tokens of system prompt and skill descriptions; `--model haiku` is the cheapest and
|
|
84
|
+
also the stricter test). `--plugin-dir` tests the working tree, not the installed plugin,
|
|
85
|
+
which may be releases behind. Disable other plugins for the run (`--settings` with an
|
|
86
|
+
`enabledPlugins` map): a plugin hook that orders skill use makes any prompt pass. The `Base
|
|
87
|
+
directory for this skill:` line in the output confirms which copy loaded. From inside a
|
|
88
|
+
Claude Code session, prefix `env -u CLAUDECODE` or the nested `claude` refuses to start.
|
|
89
|
+
|
|
90
|
+
## Reviewing Skill PRs
|
|
91
|
+
|
|
92
|
+
- Judge prose as agent-consumed context, not human docs — the Skill Authoring Principles above are the review bar (e.g. an operator→result lookup table beats narrative bullets, because agents land here holding one case to resolve)
|
|
93
|
+
- Skills make version-pinned claims about HA behavior — verify against source at the current tag (`gh api repos/home-assistant/core/releases --jq '.[0].tag_name'`): `gh api repos/home-assistant/core/contents/<path>?ref=<tag> --jq .content | base64 -d`
|
|
94
|
+
- Purpose-specific trigger/condition keys aren't enumerable from core source — list them from the docs repo: `gh api "repos/home-assistant/home-assistant.io/contents/source/_triggers?ref=current" --jq '.[].name'` (also `_conditions`, `_actions`)
|
|
95
|
+
- UI renames, terminology, and default changes appear only in release blog posts, not core source: `source/_posts/<date>-release-<version>.markdown` in the docs repo (e.g. `2026-08-05-release-20268.markdown`). Use `gh api` — plain `curl` is sandboxed here and returns empty
|
|
96
|
+
- **The blog says *what* changed, not *which version* it landed in.** Its prose often implies a feature pre-existed ("X now has conditions to match its triggers") when the whole component is new. Date a feature by fetching its path at the *previous* tag — a 404 at the previous tag that exists at the current one means the whole thing is new
|
|
97
|
+
- Community PRs come from forks: base-repo `?ref=<pr-branch>` 404s; get the fork with `gh pr view <pr> --json headRepository` and fetch files from there
|
|
98
|
+
- Helper claims need **both** `config_flow.py` (flow submission) and the platform file's `PLATFORM_SCHEMA` (YAML) — they diverge in key names, value types, and which keys exist. Traps: `vol.Required(` usually puts the `CONF_*` on the *next* line, so grep drops fields and mis-attributes Required/Optional; resolve `CONF_*` to its string (`CONF_ROUND_DIGITS` is `"round"` in derivative, `"round_digits"` in min_max); `options_flow`-only fields are rejected at creation
|
|
99
|
+
- Verifying a claim confirms what it says, not whether it over-generalizes. Add a pass that tries to disprove ("which helpers does this NOT hold for?"), mechanically where possible — e.g. diff the two schemas' key sets in a script
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Skills for this repository follow the [Agent Skills open standard](https://agentskills.io). See the [specification](https://agentskills.io/specification) for the full format reference.
|
|
4
|
+
|
|
5
|
+
## Skill Format
|
|
6
|
+
|
|
7
|
+
Structure each skill as a folder under `skills/` with a `SKILL.md` file:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
skills/
|
|
11
|
+
your-skill-name/
|
|
12
|
+
SKILL.md # Required
|
|
13
|
+
references/ # Optional: additional docs loaded on demand
|
|
14
|
+
scripts/ # Optional: utility scripts
|
|
15
|
+
assets/ # Optional: static resources (templates, data files)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### SKILL.md requirements
|
|
19
|
+
|
|
20
|
+
- **YAML frontmatter** with `name` (letters, numbers, hyphens only; 64 chars max) and `description` (1024 chars max).
|
|
21
|
+
- **`metadata.version`** a monotonically incrementing integer written as a string (e.g. `"1"`) — the spec requires metadata values to be strings. Set to `0` when creating a new skill — CI assigns the real version automatically on merge. Do not edit this field manually.
|
|
22
|
+
- **`description`** in third person. Describe what the skill does and when to use it. Include keywords that help agents match tasks. Don't summarize the skill's workflow. Err toward over-triggering rather than under-triggering — a skill that loads when marginally relevant costs tokens; one that fails to load costs a wrong answer. Explicit `TRIGGER THIS SKILL WHEN` and `SYMPTOMS` sections listing observable agent behaviours match better than prose.
|
|
23
|
+
- **Body** under 500 lines. Split into reference files if approaching this limit.
|
|
24
|
+
- **Reference files** one level deep from SKILL.md—no nested references.
|
|
25
|
+
- **Cross-reference them with markdown links**, not inline code — CI validates both the path and the `#anchor`. Links resolve relative to the containing file, so inside `references/` a sibling is `x.md`, not `references/x.md`.
|
|
26
|
+
- **Forward slashes** in all file paths.
|
|
27
|
+
- **Bundled scripts**, if any, must be introduced by SKILL.md — when to reach for them and how to invoke them. An unreferenced script is dead weight the agent never finds.
|
|
28
|
+
|
|
29
|
+
See Anthropic's [skill authoring best practices](https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills/best-practices) for additional guidance.
|
|
30
|
+
|
|
31
|
+
## Guiding Principles
|
|
32
|
+
|
|
33
|
+
**The context window is a public good.** Every line is loaded on every invocation, by every agent. Challenge each paragraph: does its token cost justify its value?
|
|
34
|
+
|
|
35
|
+
**Domain-specific, not general.** The test is whether the knowledge is Home Assistant-specific — *not* whether a model already knows it. These skills install into agents ranging from frontier models to small local ones, so "the model knows this" is not something a reviewer can evaluate, and it is the wrong question anyway. Keep HA behaviour, version-pinned changes, and anywhere HA diverges from what the general syntax implies (`state_attr` returning `None` rather than an undefined, the `unavailable`/`unknown` sentinel states). Cut general programming tutorials, and text that only restates an identifier.
|
|
36
|
+
|
|
37
|
+
**Concise over verbose.** Provide patterns and quick-reference tables, not narrative explanations.
|
|
38
|
+
|
|
39
|
+
**Consistent terminology.** Choose one term for each concept and stick to it throughout the skill. Contrasting code blocks are marked `# WRONG — why` and `# RIGHT — why`, in that order; do not introduce AVOID/CORRECT, BAD/GOOD, or ❌/✅ variants. Reserve ❌/✅ for table status columns.
|
|
40
|
+
|
|
41
|
+
**Renamed HA terms keep a pointer to the old name.** When HA renames something user-facing, use the new term and note the old one with the version it changed in — `**Tools → Events** (named **Developer Tools** before 2026.8)`. Readers on older releases still see the old label in their UI, so a bare swap strands them. This has come up three times in two years: services → actions (2024.8), add-ons → Apps (2026.2), Developer Tools → Tools (2026.8).
|
|
42
|
+
|
|
43
|
+
**Explain the *why*, not bare commands.** A rule an agent understands survives paraphrase and transfers to the next case; a bare MUST/NEVER gets dropped the moment the situation differs slightly. Give the mechanism — *`device_id` breaks on re-add* beats *never use `device_id`*.
|
|
44
|
+
|
|
45
|
+
**Don't couple skills to specific tool names.** Reference HA concepts and REST APIs instead of naming specific MCP tools (e.g. `ha_rename_entity`, `ha_get_integration`). Tool names change and not all agents have the same toolset; the underlying HA APIs and concepts are stable.
|
|
46
|
+
|
|
47
|
+
**No opinionated conventions.** Skills in this repo are applied to any HA installation. Naming conventions, code style preferences, and other user-space opinions belong in a personal skill or instance-level `CLAUDE.md`, not here. Only include guidance that reflects official HA behaviour or well-established community consensus.
|
|
48
|
+
|
|
49
|
+
## Reporting Skill Problems
|
|
50
|
+
|
|
51
|
+
When a skill misleads your agent — broken dashboards, failed automations, wrong configurations — first search existing issues for the same skill and failure. If a matching issue exists, react with thumbs-up or comment with additional context. Otherwise, open a new issue with the **Report Bad Skill Advice** template. Let the agent fill it out — it holds the full context and can trace the failure to its source in the skill.
|
|
52
|
+
|
|
53
|
+
The template covers five sections: context, timeline, root cause, impact, and environment. A thorough report gives maintainers everything they need to fix the skill in one pass.
|
|
54
|
+
|
|
55
|
+
## Submitting a Skill
|
|
56
|
+
|
|
57
|
+
1. Fork this repository.
|
|
58
|
+
2. Create a folder under `skills/` with your skill name.
|
|
59
|
+
3. Write a `SKILL.md` following the format above.
|
|
60
|
+
4. Test your skill with real scenarios.
|
|
61
|
+
5. If you added or removed reference files, link them from `SKILL.md`'s reference table and update the **Skill Contents** table in `README.md`. CI checks that links resolve, but nothing detects a reference file that nothing links to.
|
|
62
|
+
6. If you materially changed what a reference file *covers* — a new section, a scope the old description no longer implies — update its row in both `SKILL.md`'s reference table and `README.md`'s **Skill Contents** table, and the coverage summary under **Included Skill**. The file list staying correct is not the same as the descriptions staying correct: nothing checks the descriptions, and they are what routes a reader to the right file.
|
|
63
|
+
7. Submit a pull request describing what your skill teaches and what problems it solves.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Home Assistant Agent Skills
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://agentskills.io)
|
|
5
|
+
|
|
6
|
+
An **Agent Skill** is a portable Markdown knowledge pack that teaches AI coding agents best practices for a specific technology. This repository provides one for Home Assistant, following the open [Agent Skills standard](https://agentskills.io/specification). Install it and your agent applies Home Assistant best practices in every session.
|
|
7
|
+
|
|
8
|
+
## Included Skill
|
|
9
|
+
|
|
10
|
+
**[home-assistant-best-practices](skills/home-assistant-best-practices/)** — a decision workflow and anti-pattern table in `SKILL.md`, backed by reference files the agent loads on demand. It covers:
|
|
11
|
+
|
|
12
|
+
- **Authoring** — native triggers and conditions over templates, helper selection, automation modes, device control and button/remote patterns, scenes, blueprints
|
|
13
|
+
- **Dashboards** — layout, views, cards, badges, custom cards
|
|
14
|
+
- **Operations** — YAML-only integration management, backups and recovery, safe refactoring of existing config
|
|
15
|
+
- **AppDaemon** — when to use it over native HA, and how to structure apps
|
|
16
|
+
|
|
17
|
+
Agents make a predictable set of mistakes with Home Assistant config — Jinja templates where a native trigger, condition, or helper exists, `device_id` where `entity_id` belongs, `mode: single` on a motion light, renames that silently break dashboards and scripts — and the anti-pattern table names each one with its fix. A typical entry:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# Without the skill — template condition: a typo or wrong entity ID surfaces only when it runs
|
|
21
|
+
condition: template
|
|
22
|
+
value_template: "{{ states('sensor.living_room_temperature') | float > 25 }}"
|
|
23
|
+
|
|
24
|
+
# With the skill — native condition: config validated when the automation loads
|
|
25
|
+
condition: numeric_state
|
|
26
|
+
entity_id: sensor.living_room_temperature
|
|
27
|
+
above: 25
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
See [Skill Contents](#skill-contents) for the file-by-file map.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
### Agent Skills installer
|
|
35
|
+
|
|
36
|
+
Requires [Node.js 22.20+](https://nodejs.org/).
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx skills add homeassistant-ai/skills
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Works with AI coding agents that support the [Agent Skills standard](https://agentskills.io): Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, and 70+ others. To update: `npx skills update`
|
|
43
|
+
|
|
44
|
+
### Claude Code plugin
|
|
45
|
+
|
|
46
|
+
Claude Code also accepts the installer above, which places the skill files in your `.claude/skills/` directory. The commands below install it as a plugin instead, kept in Claude Code's own plugin cache.
|
|
47
|
+
|
|
48
|
+
Run each command separately inside Claude Code:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
/plugin marketplace add homeassistant-ai/skills
|
|
52
|
+
```
|
|
53
|
+
```
|
|
54
|
+
/plugin install home-assistant-skills@home-assistant-skills
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Run `/reload-plugins` or restart Claude Code for the skill to take effect.
|
|
58
|
+
|
|
59
|
+
Auto-update is off by default for third-party marketplaces. To turn it on, run `/plugin`, open **Marketplaces**, choose `home-assistant-skills`, and select **Enable auto-update**. To update by hand instead, run `claude plugin update home-assistant-skills` from a shell, then `/reload-plugins`.
|
|
60
|
+
|
|
61
|
+
### Claude Desktop / claude.ai
|
|
62
|
+
|
|
63
|
+
Both apps share the same Customize UI, reached via the left sidebar (Claude Desktop) or [claude.ai/customize](https://claude.ai/customize) (browser).
|
|
64
|
+
|
|
65
|
+
1. Enable code execution: Settings → Capabilities → turn on **Cloud code execution and file creation** (required for skills)
|
|
66
|
+
2. Customize → Plugins → Add → Add marketplace → Add from a repository
|
|
67
|
+
3. Select or enter `homeassistant-ai/skills` (or the full URL, `https://github.com/homeassistant-ai/skills`) → Sync
|
|
68
|
+
|
|
69
|
+
This installs the skill as a plugin synced from this repo — no download or zip needed. **Sync automatically** is on by default, so later updates arrive on their own.
|
|
70
|
+
|
|
71
|
+
<details>
|
|
72
|
+
<summary>Alternative: upload the skill manually as a zip</summary>
|
|
73
|
+
|
|
74
|
+
1. Enable code execution: Settings → Capabilities → turn on **Cloud code execution and file creation** (required for skills)
|
|
75
|
+
2. Download or clone this repository
|
|
76
|
+
3. Zip the skill folder: `cd skills && zip -r home-assistant-best-practices.zip home-assistant-best-practices/`
|
|
77
|
+
4. Customize → Skills → Add → Upload a skill
|
|
78
|
+
|
|
79
|
+
</details>
|
|
80
|
+
|
|
81
|
+
## Usage
|
|
82
|
+
|
|
83
|
+
Once installed, the skill loads on its own whenever the agent works on automations, scripts, scenes, helpers, dashboards, blueprints, or backups — it needs no explicit invocation. Try:
|
|
84
|
+
|
|
85
|
+
> Create an automation that turns on the hallway light when motion is detected and turns it off five minutes after the motion stops.
|
|
86
|
+
|
|
87
|
+
## Skill Contents
|
|
88
|
+
|
|
89
|
+
The `home-assistant-best-practices` skill includes:
|
|
90
|
+
|
|
91
|
+
| File | Purpose |
|
|
92
|
+
|------|---------|
|
|
93
|
+
| [`SKILL.md`](skills/home-assistant-best-practices/SKILL.md) | Decision workflow, anti-pattern table, and pointers to the reference files below |
|
|
94
|
+
| [`references/safe-refactoring.md`](skills/home-assistant-best-practices/references/safe-refactoring.md) | Safe workflow for renaming entities, replacing helpers, restructuring automations; config-entry and storage-dashboard blind spots |
|
|
95
|
+
| [`references/automation-patterns.md`](skills/home-assistant-best-practices/references/automation-patterns.md) | Purpose-specific and native triggers/conditions, waits, variables, automation modes, control flow (choose, repeat, parallel), disabling automations |
|
|
96
|
+
| [`references/helper-selection.md`](skills/home-assistant-best-practices/references/helper-selection.md) | Built-in helpers vs template sensors (with decision matrix) |
|
|
97
|
+
| [`references/template-guidelines.md`](skills/home-assistant-best-practices/references/template-guidelines.md) | When to use templates, when to avoid them, template sensor best practices, reusable `custom_templates` macros |
|
|
98
|
+
| [`references/yaml-only-integrations.md`](skills/home-assistant-best-practices/references/yaml-only-integrations.md) | YAML-only integration types, post-edit actions (reload vs restart) |
|
|
99
|
+
| [`references/device-control.md`](skills/home-assistant-best-practices/references/device-control.md) | Actions and targeting, entity_id vs device_id, buttons and remotes, domain-specific patterns |
|
|
100
|
+
| [`references/scenes.md`](skills/home-assistant-best-practices/references/scenes.md) | Scene authoring: config shape, snapshot/restore, snapshot-vs-script distinction |
|
|
101
|
+
| [`references/dashboard-guide.md`](skills/home-assistant-best-practices/references/dashboard-guide.md) | Dashboard layout, view types, strategies, sections, cards, badges, custom cards, CSS styling, HACS |
|
|
102
|
+
| [`references/dashboard-cards.md`](skills/home-assistant-best-practices/references/dashboard-cards.md) | Card type lookup and card-specific documentation |
|
|
103
|
+
| [`references/domain-docs.md`](skills/home-assistant-best-practices/references/domain-docs.md) | Integration and domain documentation (actions, entity attributes); doc pages for specific triggers, conditions, and actions |
|
|
104
|
+
| [`references/examples.yaml`](skills/home-assistant-best-practices/references/examples.yaml) | Compound examples combining multiple best practices |
|
|
105
|
+
| [`references/appdaemon.md`](skills/home-assistant-best-practices/references/appdaemon.md) | AppDaemon apps: when to use vs. native HA, app structure, actions, scheduling, error handling, safe refactoring impact |
|
|
106
|
+
| [`references/blueprint-guide.md`](skills/home-assistant-best-practices/references/blueprint-guide.md) | Blueprint authoring: metadata & `source_url`, inputs & selectors, `target` vs `entity`, defaults, `!input` templating, versioning |
|
|
107
|
+
| [`references/backups.md`](skills/home-assistant-best-practices/references/backups.md) | Full instance backups vs rolling one object back, when an operation needs a backup first, what an archive contains, encryption keys, restore verification, backup deletion |
|
|
108
|
+
|
|
109
|
+
## Contributing
|
|
110
|
+
|
|
111
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on writing and submitting skills.
|
|
112
|
+
|
|
113
|
+
Skill misled your agent? Open an issue with the [Report Bad Skill Advice](https://github.com/homeassistant-ai/skills/issues/new?template=skill-rca.md) template and let the agent fill it in — it holds the context to trace the failure to its source in the skill.
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
schema_version: "1.1"
|
|
2
|
+
name: area-target-over-entity-list
|
|
3
|
+
description: >
|
|
4
|
+
The user states the maintenance requirement outright — they keep adding
|
|
5
|
+
sensors. An area or floor target follows membership; an enumerated entity list
|
|
6
|
+
does not.
|
|
7
|
+
tags: [automations, triggers]
|
|
8
|
+
|
|
9
|
+
execution:
|
|
10
|
+
prompt: >-
|
|
11
|
+
send me a phone notification if any motion sensor downstairs picks something up
|
|
12
|
+
while we're away. I keep adding sensors down there so I don't want to keep
|
|
13
|
+
editing this
|
|
14
|
+
allowed_tools: []
|
|
15
|
+
max_turns: 10
|
|
16
|
+
timeout_seconds: 300
|
|
17
|
+
runs: 3
|
|
18
|
+
|
|
19
|
+
graders:
|
|
20
|
+
- type: tool_used
|
|
21
|
+
name: skill-fired
|
|
22
|
+
tool: Skill
|
|
23
|
+
input_match: '"skill"\s*:\s*"(?:[\w-]+:)?home-assistant-best-practices"'
|
|
24
|
+
min: 1
|
|
25
|
+
|
|
26
|
+
- type: llm
|
|
27
|
+
name: uses-area-or-floor-target
|
|
28
|
+
criteria: >-
|
|
29
|
+
The trigger targets an area, floor, or label rather than a hardcoded list of
|
|
30
|
+
sensor entity IDs.
|
|
31
|
+
|
|
32
|
+
FAIL if the automation enumerates `binary_sensor.*` entity IDs.
|
|
33
|
+
|
|
34
|
+
- type: llm
|
|
35
|
+
name: uses-purpose-specific-trigger
|
|
36
|
+
criteria: >-
|
|
37
|
+
The response uses a purpose-specific motion trigger rather than a generic
|
|
38
|
+
`trigger: state` block over a list of entities.
|
|
39
|
+
|
|
40
|
+
- type: llm
|
|
41
|
+
name: addresses-the-maintenance-ask
|
|
42
|
+
criteria: >-
|
|
43
|
+
The response explains that sensors added to the area later are picked up
|
|
44
|
+
without editing the automation — answering the user's stated reason for
|
|
45
|
+
asking.
|
|
46
|
+
|
|
47
|
+
expected_outcome: >-
|
|
48
|
+
A purpose-specific motion trigger with an area/floor target, plus an explanation
|
|
49
|
+
that new sensors are picked up automatically.
|
ha_mcp_dev-8.3.0.dev2454/src/ha_mcp/resources/skills-vendor/evals/arrive-home-automation/case.yaml
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
schema_version: "1.1"
|
|
2
|
+
name: arrive-home-automation
|
|
3
|
+
description: >
|
|
4
|
+
The obvious presence automation. Guards against the `entered_home` device
|
|
5
|
+
trigger type, removed in 2026.5, which pre-2026.5 training data still suggests.
|
|
6
|
+
tags: [automations, triggers]
|
|
7
|
+
|
|
8
|
+
execution:
|
|
9
|
+
prompt: create an automation that turns on the lights when I get home
|
|
10
|
+
allowed_tools: []
|
|
11
|
+
max_turns: 10
|
|
12
|
+
timeout_seconds: 300
|
|
13
|
+
runs: 3
|
|
14
|
+
|
|
15
|
+
graders:
|
|
16
|
+
- type: tool_used
|
|
17
|
+
name: skill-fired
|
|
18
|
+
tool: Skill
|
|
19
|
+
input_match: '"skill"\s*:\s*"(?:[\w-]+:)?home-assistant-best-practices"'
|
|
20
|
+
min: 1
|
|
21
|
+
|
|
22
|
+
- type: llm
|
|
23
|
+
name: uses-state-trigger
|
|
24
|
+
criteria: >-
|
|
25
|
+
The automation triggers on a state change of a `person.*` or
|
|
26
|
+
`device_tracker.*` entity with `to: home` (a `trigger: state` block, or a
|
|
27
|
+
purpose-specific presence trigger that targets a person entity).
|
|
28
|
+
|
|
29
|
+
- type: llm
|
|
30
|
+
name: no-entered-home-trigger
|
|
31
|
+
criteria: >-
|
|
32
|
+
The automation does NOT use the `entered_home` device trigger type, which was
|
|
33
|
+
removed in Home Assistant 2026.5.
|
|
34
|
+
|
|
35
|
+
Judge the automation the response tells the user to create. PASS if
|
|
36
|
+
`entered_home` appears only in prose explaining that it was removed and must
|
|
37
|
+
not be used. FAIL if it appears in a trigger block the user is told to use.
|
|
38
|
+
|
|
39
|
+
expected_outcome: >-
|
|
40
|
+
A state trigger on a person or device_tracker entity with `to: home`. No
|
|
41
|
+
`entered_home` device trigger.
|