ha-mcp-dev 8.3.0.dev2436__tar.gz → 8.3.0.dev2440__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.dev2436/src/ha_mcp_dev.egg-info → ha_mcp_dev-8.3.0.dev2440}/PKG-INFO +1 -1
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/pyproject.toml +1 -1
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_i18n.py +247 -37
- ha_mcp_dev-8.3.0.dev2440/src/ha_mcp/settings_ui/_locale_policy.py +13 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/README.md +9 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/cs.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/de.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/eo.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/es.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/fr.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/it.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/ko.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/nl.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/pl.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/ru.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/sv.json +2 -2
- ha_mcp_dev-8.3.0.dev2440/src/ha_mcp/settings_ui/locales/tlh.json +832 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/zh-Hans.json +2 -2
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp_dev.egg-info/SOURCES.txt +2 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/LICENSE +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/MANIFEST.in +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/README.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/setup.cfg +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_rich_compat.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/requirements.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/LICENSE +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/MANIFEST.sha256 +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/VENDORED +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/__main__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/asyncio/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/asyncio/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/asyncio/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/asyncio/messages.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/asyncio/router.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/asyncio/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/auth.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/cli.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/datastructures.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/exceptions.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/extensions/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/extensions/base.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/extensions/permessage_deflate.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/frames.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/headers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/http11.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/imports.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/auth.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/exceptions.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/framing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/handshake.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/http.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/protocol.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/legacy/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/protocol.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/proxy.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/py.typed +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/streams.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/sync/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/sync/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/sync/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/sync/messages.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/sync/router.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/sync/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/sync/utils.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/trio/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/trio/client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/trio/connection.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/trio/messages.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/trio/router.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/trio/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/trio/utils.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/typing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/uri.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/utils.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_vendor/websockets/version.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/auth/oidc_compat.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/browser_landing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/hacs_auto_refresh.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/llm_exposure.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/log_filters.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/editing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/redaction.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/renamed_tools.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_persistence.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_theme.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/en.json +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/settings.html +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/settings.js +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/strict_bps.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/best_practice_result.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/best_practice_variables.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/bulk_selector.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/component_api.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/component_config_entries.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/component_config_reads.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/component_devices.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/component_registries.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/config_entry_flow_form.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/config_entry_flow_menu.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/config_entry_flow_walker.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/config_entry_identity.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/config_entry_reconfigure.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/config_entry_reload_watch.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/error_log_parsing.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/hacs_registration.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/integration_reconfigure.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/renamed_tool_middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_graph.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_assist_pipeline.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_dev.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_security_policy.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/transport_security.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/config_write_lock.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/entity_membership.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/visibility/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/visibility/enforcement.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/visibility/model.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/visibility/persistence.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/visibility/resolver.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/tests/__init__.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/tests/test_constants.py +0 -0
- {ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/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.dev2440"
|
|
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
|
|
@@ -8,11 +8,16 @@ individual translations may be incomplete and safely inherit missing values.
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
import json
|
|
11
|
+
import logging
|
|
11
12
|
import re
|
|
12
13
|
from collections import Counter
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from typing import Any
|
|
15
16
|
|
|
17
|
+
from . import _locale_policy
|
|
18
|
+
|
|
19
|
+
_LOGGER = logging.getLogger(__name__)
|
|
20
|
+
|
|
16
21
|
DEFAULT_LOCALE = "en"
|
|
17
22
|
LOCALE_COOKIE = "ha_mcp_locale"
|
|
18
23
|
LOCALES_DIR = Path(__file__).parent / "locales"
|
|
@@ -87,6 +92,220 @@ def _validate_tools(value: Any, *, context: str) -> dict[str, dict[str, str]]:
|
|
|
87
92
|
return result
|
|
88
93
|
|
|
89
94
|
|
|
95
|
+
def _warn_best_effort_catalog(locale: str, path: Path, exc: Exception) -> None:
|
|
96
|
+
_LOGGER.warning("Skipping best-effort locale %s from %s: %s", locale, path, exc)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _warn_best_effort_entry(locale: str, entry: str, exc: Exception) -> None:
|
|
100
|
+
_LOGGER.warning(
|
|
101
|
+
"Ignoring invalid best-effort locale %s %s; using English fallback: %s",
|
|
102
|
+
locale,
|
|
103
|
+
entry,
|
|
104
|
+
exc,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _validate_best_effort_string_map(
|
|
109
|
+
value: Any,
|
|
110
|
+
*,
|
|
111
|
+
locale: str,
|
|
112
|
+
context: str,
|
|
113
|
+
entry_kind: str,
|
|
114
|
+
) -> dict[str, str]:
|
|
115
|
+
"""Drop invalid best-effort strings while preserving valid siblings."""
|
|
116
|
+
if value is None:
|
|
117
|
+
return {}
|
|
118
|
+
if not isinstance(value, dict):
|
|
119
|
+
raise ValueError(f"{context} must be an object")
|
|
120
|
+
|
|
121
|
+
result: dict[str, str] = {}
|
|
122
|
+
for key, text in value.items():
|
|
123
|
+
try:
|
|
124
|
+
result.update(_validate_string_map({key: text}, context=context))
|
|
125
|
+
except ValueError as exc:
|
|
126
|
+
_warn_best_effort_entry(locale, f"{entry_kind} {key!r}", exc)
|
|
127
|
+
return result
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _validate_best_effort_tools(
|
|
131
|
+
value: Any, *, locale: str, context: str
|
|
132
|
+
) -> dict[str, dict[str, str]]:
|
|
133
|
+
"""Drop invalid best-effort tool fields while preserving valid siblings."""
|
|
134
|
+
if value is None:
|
|
135
|
+
return {}
|
|
136
|
+
if not isinstance(value, dict):
|
|
137
|
+
raise ValueError(f"{context} must be an object")
|
|
138
|
+
|
|
139
|
+
result: dict[str, dict[str, str]] = {}
|
|
140
|
+
for tool_name, tool_values in value.items():
|
|
141
|
+
if not isinstance(tool_name, str) or not isinstance(tool_values, dict):
|
|
142
|
+
exc = ValueError(f"{context} entries must be objects keyed by tool name")
|
|
143
|
+
_warn_best_effort_entry(locale, f"tool {tool_name!r}", exc)
|
|
144
|
+
continue
|
|
145
|
+
|
|
146
|
+
translated: dict[str, str] = {}
|
|
147
|
+
for field, field_value in tool_values.items():
|
|
148
|
+
if field not in ("title", "description"):
|
|
149
|
+
exc = ValueError(
|
|
150
|
+
f"{context}.{tool_name} has unsupported field: {field!r}"
|
|
151
|
+
)
|
|
152
|
+
_warn_best_effort_entry(
|
|
153
|
+
locale, f"tool {tool_name!r} field {field!r}", exc
|
|
154
|
+
)
|
|
155
|
+
continue
|
|
156
|
+
try:
|
|
157
|
+
validated = _validate_tools(
|
|
158
|
+
{tool_name: {field: field_value}}, context=context
|
|
159
|
+
)
|
|
160
|
+
except ValueError as exc:
|
|
161
|
+
_warn_best_effort_entry(
|
|
162
|
+
locale, f"tool {tool_name!r} field {field!r}", exc
|
|
163
|
+
)
|
|
164
|
+
continue
|
|
165
|
+
if field in validated[tool_name]:
|
|
166
|
+
translated[field] = validated[tool_name][field]
|
|
167
|
+
if translated:
|
|
168
|
+
result[tool_name] = translated
|
|
169
|
+
return result
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _load_catalog_file(
|
|
173
|
+
path: Path, *, best_effort_locale: str | None = None
|
|
174
|
+
) -> dict[str, Any]:
|
|
175
|
+
"""Load and validate one catalog without coupling it to its siblings."""
|
|
176
|
+
try:
|
|
177
|
+
raw = json.loads(path.read_text(encoding="utf-8"))
|
|
178
|
+
except (OSError, UnicodeError, json.JSONDecodeError) as exc:
|
|
179
|
+
raise ImportError(f"Invalid settings UI locale catalog: {path}") from exc
|
|
180
|
+
if not isinstance(raw, dict):
|
|
181
|
+
raise ValueError(f"Locale catalog {path} must contain a JSON object")
|
|
182
|
+
|
|
183
|
+
meta = raw.get("meta")
|
|
184
|
+
if not isinstance(meta, dict):
|
|
185
|
+
raise ValueError(f"Locale catalog {path} must define a meta object")
|
|
186
|
+
native_name = meta.get("native_name")
|
|
187
|
+
direction = meta.get("dir", "ltr")
|
|
188
|
+
if not isinstance(native_name, str) or not native_name.strip():
|
|
189
|
+
raise ValueError(f"Locale catalog {path} needs meta.native_name")
|
|
190
|
+
if direction not in ("ltr", "rtl"):
|
|
191
|
+
raise ValueError(f"Locale catalog {path} meta.dir must be ltr or rtl")
|
|
192
|
+
|
|
193
|
+
unknown_sections = set(raw) - {"meta", "messages", "tool_groups", "tools"}
|
|
194
|
+
if unknown_sections:
|
|
195
|
+
raise ValueError(
|
|
196
|
+
f"Locale catalog {path} has unsupported sections: "
|
|
197
|
+
f"{sorted(unknown_sections)}"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
if best_effort_locale is None:
|
|
201
|
+
messages = _validate_string_map(
|
|
202
|
+
raw.get("messages"), context=f"{path.name}.messages"
|
|
203
|
+
)
|
|
204
|
+
tool_groups = _validate_string_map(
|
|
205
|
+
raw.get("tool_groups"), context=f"{path.name}.tool_groups"
|
|
206
|
+
)
|
|
207
|
+
tools = _validate_tools(raw.get("tools"), context=f"{path.name}.tools")
|
|
208
|
+
else:
|
|
209
|
+
messages = _validate_best_effort_string_map(
|
|
210
|
+
raw.get("messages"),
|
|
211
|
+
locale=best_effort_locale,
|
|
212
|
+
context=f"{path.name}.messages",
|
|
213
|
+
entry_kind="message",
|
|
214
|
+
)
|
|
215
|
+
tool_groups = _validate_best_effort_string_map(
|
|
216
|
+
raw.get("tool_groups"),
|
|
217
|
+
locale=best_effort_locale,
|
|
218
|
+
context=f"{path.name}.tool_groups",
|
|
219
|
+
entry_kind="tool group",
|
|
220
|
+
)
|
|
221
|
+
tools = _validate_best_effort_tools(
|
|
222
|
+
raw.get("tools"),
|
|
223
|
+
locale=best_effort_locale,
|
|
224
|
+
context=f"{path.name}.tools",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
"meta": {"native_name": native_name, "dir": direction},
|
|
229
|
+
"messages": messages,
|
|
230
|
+
"tool_groups": tool_groups,
|
|
231
|
+
"tools": tools,
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _catalog_fragment(
|
|
236
|
+
catalog: dict[str, Any],
|
|
237
|
+
*,
|
|
238
|
+
messages: dict[str, str] | None = None,
|
|
239
|
+
tools: dict[str, dict[str, str]] | None = None,
|
|
240
|
+
) -> dict[str, Any]:
|
|
241
|
+
"""Return a minimal catalog used to validate one translated entry."""
|
|
242
|
+
return {
|
|
243
|
+
"meta": catalog["meta"],
|
|
244
|
+
"messages": messages or {},
|
|
245
|
+
"tool_groups": {},
|
|
246
|
+
"tools": tools or {},
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _sanitize_best_effort_catalog(
|
|
251
|
+
locale: str,
|
|
252
|
+
catalog: dict[str, Any],
|
|
253
|
+
english: dict[str, Any],
|
|
254
|
+
settings_html: Path,
|
|
255
|
+
) -> dict[str, Any]:
|
|
256
|
+
"""Drop only invalid translated entries so the rest of a locale survives."""
|
|
257
|
+
sanitized = {
|
|
258
|
+
"meta": dict(catalog["meta"]),
|
|
259
|
+
"messages": dict(catalog["messages"]),
|
|
260
|
+
"tool_groups": dict(catalog["tool_groups"]),
|
|
261
|
+
"tools": {
|
|
262
|
+
tool_name: dict(fields) for tool_name, fields in catalog["tools"].items()
|
|
263
|
+
},
|
|
264
|
+
}
|
|
265
|
+
known_panels = _known_panels(settings_html)
|
|
266
|
+
|
|
267
|
+
for key, translated in tuple(sanitized["messages"].items()):
|
|
268
|
+
english_messages = (
|
|
269
|
+
{key: english["messages"][key]} if key in english["messages"] else {}
|
|
270
|
+
)
|
|
271
|
+
candidate = {
|
|
272
|
+
DEFAULT_LOCALE: _catalog_fragment(english, messages=english_messages),
|
|
273
|
+
locale: _catalog_fragment(sanitized, messages={key: translated}),
|
|
274
|
+
}
|
|
275
|
+
try:
|
|
276
|
+
_validate_placeholder_parity(candidate)
|
|
277
|
+
_validate_inline_markup(candidate)
|
|
278
|
+
_validate_panel_links(candidate, settings_html, known_panels=known_panels)
|
|
279
|
+
except ValueError as exc:
|
|
280
|
+
del sanitized["messages"][key]
|
|
281
|
+
_warn_best_effort_entry(locale, f"message {key!r}", exc)
|
|
282
|
+
|
|
283
|
+
for tool_name, translated_tool in tuple(sanitized["tools"].items()):
|
|
284
|
+
for field, translated in tuple(translated_tool.items()):
|
|
285
|
+
english_field = english["tools"].get(tool_name, {}).get(field)
|
|
286
|
+
english_tools = (
|
|
287
|
+
{tool_name: {field: english_field}} if english_field is not None else {}
|
|
288
|
+
)
|
|
289
|
+
candidate = {
|
|
290
|
+
DEFAULT_LOCALE: _catalog_fragment(english, tools=english_tools),
|
|
291
|
+
locale: _catalog_fragment(
|
|
292
|
+
sanitized,
|
|
293
|
+
tools={tool_name: {field: translated}},
|
|
294
|
+
),
|
|
295
|
+
}
|
|
296
|
+
try:
|
|
297
|
+
_validate_placeholder_parity(candidate)
|
|
298
|
+
except ValueError as exc:
|
|
299
|
+
del translated_tool[field]
|
|
300
|
+
_warn_best_effort_entry(
|
|
301
|
+
locale, f"tool {tool_name!r} field {field!r}", exc
|
|
302
|
+
)
|
|
303
|
+
if not translated_tool:
|
|
304
|
+
del sanitized["tools"][tool_name]
|
|
305
|
+
|
|
306
|
+
return sanitized
|
|
307
|
+
|
|
308
|
+
|
|
90
309
|
def load_catalogs(
|
|
91
310
|
directory: Path = LOCALES_DIR, settings_html: Path = _SETTINGS_HTML
|
|
92
311
|
) -> dict[str, dict[str, Any]]:
|
|
@@ -106,47 +325,35 @@ def load_catalogs(
|
|
|
106
325
|
for path in paths:
|
|
107
326
|
locale = path.stem.lower().replace("_", "-")
|
|
108
327
|
try:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
meta = raw.get("meta")
|
|
116
|
-
if not isinstance(meta, dict):
|
|
117
|
-
raise ValueError(f"Locale catalog {path} must define a meta object")
|
|
118
|
-
native_name = meta.get("native_name")
|
|
119
|
-
direction = meta.get("dir", "ltr")
|
|
120
|
-
if not isinstance(native_name, str) or not native_name.strip():
|
|
121
|
-
raise ValueError(f"Locale catalog {path} needs meta.native_name")
|
|
122
|
-
if direction not in ("ltr", "rtl"):
|
|
123
|
-
raise ValueError(f"Locale catalog {path} meta.dir must be ltr or rtl")
|
|
124
|
-
|
|
125
|
-
unknown_sections = set(raw) - {"meta", "messages", "tool_groups", "tools"}
|
|
126
|
-
if unknown_sections:
|
|
127
|
-
raise ValueError(
|
|
128
|
-
f"Locale catalog {path} has unsupported sections: "
|
|
129
|
-
f"{sorted(unknown_sections)}"
|
|
328
|
+
catalogs[locale] = _load_catalog_file(
|
|
329
|
+
path,
|
|
330
|
+
best_effort_locale=(
|
|
331
|
+
locale if _locale_policy.is_best_effort_locale(locale) else None
|
|
332
|
+
),
|
|
130
333
|
)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
raw.get("messages"), context=f"{path.name}.messages"
|
|
136
|
-
),
|
|
137
|
-
"tool_groups": _validate_string_map(
|
|
138
|
-
raw.get("tool_groups"), context=f"{path.name}.tool_groups"
|
|
139
|
-
),
|
|
140
|
-
"tools": _validate_tools(raw.get("tools"), context=f"{path.name}.tools"),
|
|
141
|
-
}
|
|
334
|
+
except (ImportError, ValueError) as exc:
|
|
335
|
+
if not _locale_policy.is_best_effort_locale(locale):
|
|
336
|
+
raise
|
|
337
|
+
_warn_best_effort_catalog(locale, path, exc)
|
|
142
338
|
|
|
143
339
|
if DEFAULT_LOCALE not in catalogs:
|
|
144
340
|
raise ImportError(
|
|
145
341
|
f"The settings UI requires {DEFAULT_LOCALE}.json in {directory}"
|
|
146
342
|
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
343
|
+
|
|
344
|
+
strict_catalogs = {
|
|
345
|
+
locale: catalog
|
|
346
|
+
for locale, catalog in catalogs.items()
|
|
347
|
+
if not _locale_policy.is_best_effort_locale(locale)
|
|
348
|
+
}
|
|
349
|
+
_validate_placeholder_parity(strict_catalogs)
|
|
350
|
+
_validate_inline_markup(strict_catalogs)
|
|
351
|
+
_validate_panel_links(strict_catalogs, settings_html)
|
|
352
|
+
|
|
353
|
+
for locale in sorted(set(catalogs) - set(strict_catalogs)):
|
|
354
|
+
catalogs[locale] = _sanitize_best_effort_catalog(
|
|
355
|
+
locale, catalogs[locale], catalogs[DEFAULT_LOCALE], settings_html
|
|
356
|
+
)
|
|
150
357
|
return catalogs
|
|
151
358
|
|
|
152
359
|
|
|
@@ -234,7 +441,10 @@ def _known_panels(settings_html: Path = _SETTINGS_HTML) -> set[str]:
|
|
|
234
441
|
|
|
235
442
|
|
|
236
443
|
def _validate_panel_links(
|
|
237
|
-
catalogs: dict[str, dict[str, Any]],
|
|
444
|
+
catalogs: dict[str, dict[str, Any]],
|
|
445
|
+
settings_html: Path = _SETTINGS_HTML,
|
|
446
|
+
*,
|
|
447
|
+
known_panels: set[str] | None = None,
|
|
238
448
|
) -> None:
|
|
239
449
|
"""Reject cross-panel links that point at a tab which does not exist.
|
|
240
450
|
|
|
@@ -247,7 +457,7 @@ def _validate_panel_links(
|
|
|
247
457
|
and group labels go through ``escapeHtml``, so a link written there shows
|
|
248
458
|
as visible garbled markup rather than a dead link — wrong, but not silent.
|
|
249
459
|
"""
|
|
250
|
-
panels = _known_panels(settings_html)
|
|
460
|
+
panels = known_panels if known_panels is not None else _known_panels(settings_html)
|
|
251
461
|
english_messages = catalogs[DEFAULT_LOCALE]["messages"]
|
|
252
462
|
for locale, catalog in catalogs.items():
|
|
253
463
|
for key, value in catalog["messages"].items():
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Maintenance policy for intentionally best-effort locale catalogs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
# Klingon is a novelty translation maintained by hand. It must never consume
|
|
6
|
+
# machine-translation quota or block delivery for supported localizations.
|
|
7
|
+
BEST_EFFORT_LOCALES = frozenset({"tlh"})
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def is_best_effort_locale(locale: str) -> bool:
|
|
11
|
+
"""Return whether ``locale`` is isolated from hard localization gates."""
|
|
12
|
+
normalized = locale.lower().replace("_", "-")
|
|
13
|
+
return normalized in BEST_EFFORT_LOCALES
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/README.md
RENAMED
|
@@ -24,6 +24,15 @@ Home Assistant language code names every file:
|
|
|
24
24
|
- `homeassistant-addon/translations/<code>.yaml` (generated)
|
|
25
25
|
- `homeassistant-addon-dev/translations/<code>.yaml` (generated)
|
|
26
26
|
|
|
27
|
+
Klingon (`tlh`) is the one best-effort exception. Its catalogs may be edited
|
|
28
|
+
manually and still ship, but the automatic translation planner never queues
|
|
29
|
+
them. Missing strings use English fallback; invalid or stale Klingon catalogs
|
|
30
|
+
produce warnings instead of failing CI or the daily locale sync. The runtime
|
|
31
|
+
loader skips an invalid Klingon settings catalog, and the generator can project
|
|
32
|
+
English into its add-on catalogs, so Klingon cannot prevent any other locale
|
|
33
|
+
from loading or updating. All other language codes remain subject to every
|
|
34
|
+
hard gate below.
|
|
35
|
+
|
|
27
36
|
Add the two authored catalogs, then run `python scripts/generate_locales.py`
|
|
28
37
|
and merge: the post-merge `locale-sync.yml` workflow machine-fills every string
|
|
29
38
|
over its next daily runs. The component catalog may start as an empty object;
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/cs.json
RENAMED
|
@@ -622,7 +622,7 @@
|
|
|
622
622
|
},
|
|
623
623
|
"ha_get_app": {
|
|
624
624
|
"title": "Získat aplikace (doplňky)",
|
|
625
|
-
"description": "Získat
|
|
625
|
+
"description": "Získat nainstalované nebo dostupné aplikace (doplňky) Home Assistant, nebo podrobnosti o jedné z nich."
|
|
626
626
|
},
|
|
627
627
|
"ha_get_automation_traces": {
|
|
628
628
|
"title": "Získat trasování automatizací",
|
|
@@ -710,7 +710,7 @@
|
|
|
710
710
|
},
|
|
711
711
|
"ha_manage_app": {
|
|
712
712
|
"title": "Spravovat aplikaci (doplněk)",
|
|
713
|
-
"description": "Spravovat
|
|
713
|
+
"description": "Spravovat aplikace (doplňky) Home Assistant nebo zajistit proxy pro API aplikace."
|
|
714
714
|
},
|
|
715
715
|
"ha_manage_backup": {
|
|
716
716
|
"title": "Spravovat zálohy",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/de.json
RENAMED
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
},
|
|
654
654
|
"ha_get_app": {
|
|
655
655
|
"title": "Apps (Add-ons) abrufen",
|
|
656
|
-
"description": "Home Assistant
|
|
656
|
+
"description": "Installierte oder verfügbare Home Assistant Apps (Add-ons) oder Details zu einer abrufen."
|
|
657
657
|
},
|
|
658
658
|
"ha_get_automation_traces": {
|
|
659
659
|
"title": "Traces abrufen",
|
|
@@ -741,7 +741,7 @@
|
|
|
741
741
|
},
|
|
742
742
|
"ha_manage_app": {
|
|
743
743
|
"title": "App (Add-on) verwalten",
|
|
744
|
-
"description": "
|
|
744
|
+
"description": "Home Assistant Apps (Add-ons) verwalten oder eine App-API proxyn."
|
|
745
745
|
},
|
|
746
746
|
"ha_manage_backup": {
|
|
747
747
|
"title": "Backups verwalten",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/eo.json
RENAMED
|
@@ -622,7 +622,7 @@
|
|
|
622
622
|
},
|
|
623
623
|
"ha_get_app": {
|
|
624
624
|
"title": "Akiri programojn (aldonaĵojn)",
|
|
625
|
-
"description": "Akiri Home Assistant
|
|
625
|
+
"description": "Akiri instalitajn aŭ disponeblajn Home Assistant-aplikaĵojn (aldonaĵojn), aŭ detalojn pri unu."
|
|
626
626
|
},
|
|
627
627
|
"ha_get_automation_traces": {
|
|
628
628
|
"title": "Akiri Aŭtomatigajn Spurojn",
|
|
@@ -710,7 +710,7 @@
|
|
|
710
710
|
},
|
|
711
711
|
"ha_manage_app": {
|
|
712
712
|
"title": "Administri programon (aldonaĵon)",
|
|
713
|
-
"description": "Administri Home Assistant
|
|
713
|
+
"description": "Administri Home Assistant-aplikaĵojn (aldonaĵojn) aŭ proksiigi aplikaĵan API-on."
|
|
714
714
|
},
|
|
715
715
|
"ha_manage_backup": {
|
|
716
716
|
"title": "Administri Rezervojn",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/es.json
RENAMED
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
},
|
|
654
654
|
"ha_get_app": {
|
|
655
655
|
"title": "Obtener Apps (add-ons)",
|
|
656
|
-
"description": "Obtener
|
|
656
|
+
"description": "Obtener las aplicaciones (complementos) de Home Assistant instaladas o disponibles, o los detalles de una."
|
|
657
657
|
},
|
|
658
658
|
"ha_get_automation_traces": {
|
|
659
659
|
"title": "Obtener trazas de automatización",
|
|
@@ -741,7 +741,7 @@
|
|
|
741
741
|
},
|
|
742
742
|
"ha_manage_app": {
|
|
743
743
|
"title": "Administrar App (add-on)",
|
|
744
|
-
"description": "
|
|
744
|
+
"description": "Gestionar las aplicaciones (complementos) de Home Assistant o hacer proxy de una API de aplicación."
|
|
745
745
|
},
|
|
746
746
|
"ha_manage_backup": {
|
|
747
747
|
"title": "Gestionar copias de seguridad",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/fr.json
RENAMED
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
},
|
|
654
654
|
"ha_get_app": {
|
|
655
655
|
"title": "Obtenir des applications (add-ons)",
|
|
656
|
-
"description": "
|
|
656
|
+
"description": "Obtenez les applications (add-ons) Home Assistant installées ou disponibles, ou les détails de l'une d'entre elles."
|
|
657
657
|
},
|
|
658
658
|
"ha_get_automation_traces": {
|
|
659
659
|
"title": "Obtenir les traces",
|
|
@@ -741,7 +741,7 @@
|
|
|
741
741
|
},
|
|
742
742
|
"ha_manage_app": {
|
|
743
743
|
"title": "Gérer l'application (add-on)",
|
|
744
|
-
"description": "
|
|
744
|
+
"description": "Gérez les applications (add-ons) Home Assistant ou agissez comme proxy pour l'API d'une application."
|
|
745
745
|
},
|
|
746
746
|
"ha_manage_backup": {
|
|
747
747
|
"title": "Gérer les sauvegardes",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/it.json
RENAMED
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
},
|
|
654
654
|
"ha_get_app": {
|
|
655
655
|
"title": "Ottieni app (componenti aggiuntivi)",
|
|
656
|
-
"description": "Ottieni le app
|
|
656
|
+
"description": "Ottieni le app (componenti aggiuntivi) di Home Assistant installate o disponibili, oppure i dettagli per una."
|
|
657
657
|
},
|
|
658
658
|
"ha_get_automation_traces": {
|
|
659
659
|
"title": "Ottieni le tracce delle automazioni",
|
|
@@ -741,7 +741,7 @@
|
|
|
741
741
|
},
|
|
742
742
|
"ha_manage_app": {
|
|
743
743
|
"title": "Gestisci app (componente aggiuntivo)",
|
|
744
|
-
"description": "Gestisci
|
|
744
|
+
"description": "Gestisci le app (componenti aggiuntivi) di Home Assistant o fai da proxy per l'API di un'app."
|
|
745
745
|
},
|
|
746
746
|
"ha_manage_backup": {
|
|
747
747
|
"title": "Gestisci i backup",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/ko.json
RENAMED
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
},
|
|
654
654
|
"ha_get_app": {
|
|
655
655
|
"title": "앱(애드온) 조회",
|
|
656
|
-
"description": "Home Assistant 앱(
|
|
656
|
+
"description": "설치되었거나 사용 가능한 Home Assistant 앱(애드온) 또는 특정 앱의 상세 정보를 가져옵니다."
|
|
657
657
|
},
|
|
658
658
|
"ha_get_automation_traces": {
|
|
659
659
|
"title": "자동화 추적 기록 조회",
|
|
@@ -741,7 +741,7 @@
|
|
|
741
741
|
},
|
|
742
742
|
"ha_manage_app": {
|
|
743
743
|
"title": "앱(애드온) 관리",
|
|
744
|
-
"description": "Home Assistant 앱(
|
|
744
|
+
"description": "Home Assistant 앱(애드온)을 관리하거나 앱 API를 프록시합니다."
|
|
745
745
|
},
|
|
746
746
|
"ha_manage_backup": {
|
|
747
747
|
"title": "백업 관리",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/nl.json
RENAMED
|
@@ -622,7 +622,7 @@
|
|
|
622
622
|
},
|
|
623
623
|
"ha_get_app": {
|
|
624
624
|
"title": "Apps ophalen (add-ons)",
|
|
625
|
-
"description": "Haal Home Assistant-apps
|
|
625
|
+
"description": "Haal geïnstalleerde of beschikbare Home Assistant-apps (add-ons) op, of details voor één ervan."
|
|
626
626
|
},
|
|
627
627
|
"ha_get_automation_traces": {
|
|
628
628
|
"title": "Haal Automatiseringstraceringen op",
|
|
@@ -710,7 +710,7 @@
|
|
|
710
710
|
},
|
|
711
711
|
"ha_manage_app": {
|
|
712
712
|
"title": "App beheren (add-on)",
|
|
713
|
-
"description": "Beheer
|
|
713
|
+
"description": "Beheer Home Assistant-apps (add-ons) of proxy een app-API."
|
|
714
714
|
},
|
|
715
715
|
"ha_manage_backup": {
|
|
716
716
|
"title": "Back-ups Beheren",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/pl.json
RENAMED
|
@@ -622,7 +622,7 @@
|
|
|
622
622
|
},
|
|
623
623
|
"ha_get_app": {
|
|
624
624
|
"title": "Pobierz aplikacje (dodatki)",
|
|
625
|
-
"description": "Pobierz
|
|
625
|
+
"description": "Pobierz zainstalowane lub dostępne aplikacje (dodatki) Home Assistant albo szczegóły jednej z nich."
|
|
626
626
|
},
|
|
627
627
|
"ha_get_automation_traces": {
|
|
628
628
|
"title": "Pobierz ślady automatyzacji",
|
|
@@ -710,7 +710,7 @@
|
|
|
710
710
|
},
|
|
711
711
|
"ha_manage_app": {
|
|
712
712
|
"title": "Zarządzaj aplikacją (dodatkiem)",
|
|
713
|
-
"description": "Zarządzaj
|
|
713
|
+
"description": "Zarządzaj aplikacjami (dodatkami) Home Assistant lub przekaż zapytanie do API aplikacji."
|
|
714
714
|
},
|
|
715
715
|
"ha_manage_backup": {
|
|
716
716
|
"title": "Zarządzaj kopiami zapasowymi",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/ru.json
RENAMED
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
},
|
|
654
654
|
"ha_get_app": {
|
|
655
655
|
"title": "Получить приложения (аддоны)",
|
|
656
|
-
"description": "Получить
|
|
656
|
+
"description": "Получить список установленных или доступных приложений (аддонов) Home Assistant либо подробную информацию об одном из них."
|
|
657
657
|
},
|
|
658
658
|
"ha_get_automation_traces": {
|
|
659
659
|
"title": "Получить трассировки",
|
|
@@ -741,7 +741,7 @@
|
|
|
741
741
|
},
|
|
742
742
|
"ha_manage_app": {
|
|
743
743
|
"title": "Управление приложением (аддоном)",
|
|
744
|
-
"description": "
|
|
744
|
+
"description": "Управлять приложениями (аддонами) Home Assistant или выполнять проксирование API приложения."
|
|
745
745
|
},
|
|
746
746
|
"ha_manage_backup": {
|
|
747
747
|
"title": "Управлять резервными копиями",
|
{ha_mcp_dev-8.3.0.dev2436 → ha_mcp_dev-8.3.0.dev2440}/src/ha_mcp/settings_ui/locales/sv.json
RENAMED
|
@@ -622,7 +622,7 @@
|
|
|
622
622
|
},
|
|
623
623
|
"ha_get_app": {
|
|
624
624
|
"title": "Hämta appar (tillägg)",
|
|
625
|
-
"description": "Hämta Home Assistant-appar (
|
|
625
|
+
"description": "Hämta installerade eller tillgängliga Home Assistant-appar (tillägg), eller detaljer för en."
|
|
626
626
|
},
|
|
627
627
|
"ha_get_automation_traces": {
|
|
628
628
|
"title": "Hämta Automatiseringsspårningar",
|
|
@@ -710,7 +710,7 @@
|
|
|
710
710
|
},
|
|
711
711
|
"ha_manage_app": {
|
|
712
712
|
"title": "Hantera app (tillägg)",
|
|
713
|
-
"description": "Hantera
|
|
713
|
+
"description": "Hantera Home Assistant-appar (tillägg) eller proxyanvänd ett app-API."
|
|
714
714
|
},
|
|
715
715
|
"ha_manage_backup": {
|
|
716
716
|
"title": "Hantera säkerhetskopior",
|