refactor(internal): extract _fetch_dashboards_list helper (#1193)#1207
Conversation
Three call sites in tools_config_dashboards.py duplicated the same lovelace/dashboards/list fetch + shape-normalisation + warning logic. Extract a shared _fetch_dashboards_list(client, logger) helper that: - fetches via send_websocket_message - normalises dict-with-result vs bare-list response shapes - emits a single logger.warning on unexpected shapes - returns list[dict[str, Any]] | None (None on shape failure) Route all three call sites through it: - _resolve_dashboard: None → return None, None (unchanged behaviour) - ha_config_get_dashboard list_only: None → fallback [] (now emits warning that was previously missing at this site) - ha_config_set_dashboard existence-check: None → fallback [] (removes inline duplication of warning added in ac52f74) Closes homeassistant-ai#1193
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request refactors the dashboard list fetching logic within the configuration tools. By centralizing the WebSocket communication and response normalization into a single helper function, the codebase becomes more maintainable and consistent in its error reporting. The changes preserve existing functionality while ensuring that future API response format changes are handled uniformly across the application. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request centralizes the logic for fetching and normalizing Home Assistant dashboard lists by introducing a new private helper function, _fetch_dashboards_list, and refactoring several tools to use it. Feedback focuses on improving the helper function's robustness by ensuring the API response is explicitly checked for the expected list type and simplifying the function signature by removing the redundant logger parameter in favor of the module-level logger. Additionally, suggestions were made to align the docstring and parameter naming with the repository's style guidelines.
Adds TestGetDashboardListOnlyUnexpectedShape to the get-dashboard unit tests. The _fetch_dashboards_list helper now emits a warning when HA returns an unrecognised response shape; without this test the new behaviour at the list_only path had no coverage.
Use the module-level logger directly (removes the unused-parameter
naming issue and the redundant argument at all three call sites).
Also tighten the dict-branch guard to isinstance(result.get("result"),
list) so a non-list "result" value doesn't slip through as-is.
SealKan
left a comment
There was a problem hiding this comment.
Addressed Gemini's review feedback in a228b8c:
- Dropped the
log: logging.Loggerparameter from_fetch_dashboards_list; the helper now uses the module-levelloggerdirectly (removes the leading-underscore-on-used-param issue at all three call sites). - Tightened the dict-branch guard to
isinstance(result.get("result"), list)so a non-list value inresult["result"]no longer slips through. - Added
TestGetDashboardListOnlyUnexpectedShapeunit test (e0443ed) to cover the new warning behavior at thelist_only=Truepath (Site 2), which previously had no test coverage for unexpected shapes.
kingpanther13
left a comment
There was a problem hiding this comment.
Thanks for the cleanup — the helper shape, per-site None-vs-[] semantics, and
the new Site 2 test all match what #1193 asked for. Two things to address
before this can land, plus a couple of nits, and two side questions that
don't gate the merge.
Requested changes (blocking)
-
PR description undersells what changed. The body frames this as a pure
extraction, but two behavioural deltas slipped in alongside the refactor:- The dict-branch guard tightened from
"result" in resultto
isinstance(result.get("result"), list). Pre-PR, a response like
{"result": "string"}or{"result": None}took the happy path and
blew up downstream on iteration; post-PR it falls through to the
warning. Strictly safer, but it is a behaviour change. ha_config_get_dashboard(list_only=True)(Site 2) now emits the
unexpected-shape warning that was previously missing there.
Both shifts are exactly what #1193 wanted. Please call them out in
the PR description so a future spelunker reading "extract helper"
doesn't miss them. - The dict-branch guard tightened from
While you're in there (blocking)
tests/src/unit/test_config_get_dashboard_search_error.py:117— the new
test docstring uses internal "Site 2" shorthand. Inline the meaning
("at theha_config_get_dashboardlist path") so pytest -v output
stands on its own.- Same file, the warning assertion checks only
"unexpected shape" in rec.message. Mirror the precision of
test_canonical_url_path_branch_warns_on_unexpected_shapein
test_set_dashboard_metadata.py:289and also assert"type=str"—
catches placeholder-formatting regressions, not just message rot.
Side questions (non-blocking, won't hold up merge)
Two things stood out while reviewing. Answers help me understand who I'm
working with on future PRs — they don't gate this one.
-
The PR is opened from `SealKan` (account created today) but the commits
are authored under `Kan-nguyen` (`nguyenanhkhoa301199@gmail.com`, a much
older account). Are both accounts yours? Happy to take a yes here, just
want it on the record. -
Your `SealKan/bounty-workspace` repo describes itself as an "Autonomous
OSS bounty contributor workspace," and the commit log there reads like a
Claude-Code agent loop. Is this PR generated/driven by that agent,
hand-authored, or some mix? No judgment either way — I want to know
what the iteration loop will look like if I leave review feedback
(you, the agent, both?).
Once the PR body is updated and the two test nits are in, I'm happy to
merge.
|
Thanks — happy to answer both directly. 1. Accounts: Yes. 2. Workflow: I identify the problem, decide the approach, and judge whether feedback makes sense to accept. Claude Code handles the implementation. I review diffs before pushing — nothing goes out unread. For your review: I read your comments, agreed the two blocking items are right, and the nits are reasonable. That call is mine. Claude Code executes the fix. If I disagreed with something, I'd say so here directly. The iteration loop: you leave feedback → I decide what to do with it → implementation follows. Faster than solo, same judgment on every decision. Addressing the blocking items in the next commit. |
…en warning assertion to also check type=str
kingpanther13
left a comment
There was a problem hiding this comment.
All blocking items addressed:
- PR description now calls out both behaviour deltas (`## Behaviour deltas` section).
- Test docstring inlines the meaning ("at the `ha_config_get_dashboard` list path (`list_only=True` branch)").
- Warning assertion now checks `"unexpected shape"` AND `"type=str"`.
Thanks for the straight answers on the side questions — useful context for future PRs. Approving.
🧪 Your changes are now in the dev channel!Your PR has been merged to master and is available for testing in the dev channel. Test your changes before the next stable release (biweekly Wednesday): Quick start# Run dev version
uvx ha-mcp-dev
# Check version
uvx ha-mcp-dev --versionDocker: docker pull ghcr.io/homeassistant-ai/ha-mcp:dev
docker run --rm -i \
-e HOMEASSISTANT_URL=http://your-ha:8123 \
-e HOMEASSISTANT_TOKEN=your_token \
ghcr.io/homeassistant-ai/ha-mcp:devFound an issue? Please open a new bug report and mention this PR for context. |
|
Yes, both accounts are mine. I've now fixed the git config so all future commits (and all existing commits in open PRs) are authored under |
|
Ok, sounds good to me! It's not a big deal, it just seemed weird especially considering SealKan was just created today, so I appreciate the explanation. |
…→ 7.5.0) (#455) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/homeassistant-ai/ha-mcp](https://github.com/homeassistant-ai/ha-mcp) | minor | `7.4.0` → `7.5.0` | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/3) for more information. --- ### Release Notes <details> <summary>homeassistant-ai/ha-mcp (ghcr.io/homeassistant-ai/ha-mcp)</summary> ### [`v7.5.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v750-2026-05-13) [Compare Source](homeassistant-ai/ha-mcp@v7.4.0...v7.5.0) ##### Added - Add ENABLE\_LITE\_DOCSTRINGS beta toggle ([#​1259](homeassistant-ai/ha-mcp#1259)) - Add ha\_call\_event tool for publishing events on the HA event bus ([#​996](homeassistant-ai/ha-mcp#996)) ([#​1239](homeassistant-ai/ha-mcp#1239)) - Pinpoint backslash-escape mistake in python\_sandbox errors ([#​1204](homeassistant-ai/ha-mcp#1204)) - Reject empty-trigger automations targeting scene.create ([#​1187](homeassistant-ai/ha-mcp#1187)) - Add scene config tools — ha\_config\_get/set/remove\_scene ([#​1168](homeassistant-ai/ha-mcp#1168)) - **addon**: Optional OAuth 2.1 mode for webhook proxy (beta) ([#​1184](homeassistant-ai/ha-mcp#1184)) - Surface helper schema inline in ha\_config\_set\_helper validation errors ([#​1149](homeassistant-ai/ha-mcp#1149)) ([#​1179](homeassistant-ai/ha-mcp#1179)) - Emit progress via FastMCP Context in long-running tools ([#​1124](homeassistant-ai/ha-mcp#1124)) - Broaden python\_transform AST allowlist + improve error UX ([#​1163](homeassistant-ai/ha-mcp#1163)) - Add ha\_manage\_custom\_tool — sandboxed code execution escape hatch ([#​854](homeassistant-ai/ha-mcp#854)) - Always-on skills; rename list/read resource tools with ha\_ prefix ([#​1136](homeassistant-ai/ha-mcp#1136)) - Expose device\_class + options on ha\_set\_entity / ha\_get\_entity (Show As) ([#​1135](homeassistant-ai/ha-mcp#1135)) - **site**: Inline wizard data into setup.astro, migrate setup nuggets, drop content collections ([#​1120](homeassistant-ai/ha-mcp#1120)) - Add "Advanced debug logging" toggle for kill-signal diagnostics ([#​1117](homeassistant-ai/ha-mcp#1117)) - **yaml**: Scoped lovelace.dashboards.\<url\_path> support (issue [#​1034](homeassistant-ai/ha-mcp#1034)) ([#​1103](homeassistant-ai/ha-mcp#1103)) - Add HA\_VERIFY\_SSL toggle to disable TLS verification ([#​1104](homeassistant-ai/ha-mcp#1104)) - Per-top-level-key config\_hash for ha\_manage\_energy\_prefs ([#​1049](homeassistant-ai/ha-mcp#1049)) ([#​1098](homeassistant-ai/ha-mcp#1098)) - **site**: Add gemini-cli setup notes + compose hardening to wizard ([#​1027](homeassistant-ai/ha-mcp#1027)) ([#​1087](homeassistant-ai/ha-mcp#1087)) - Add convenience modes to ha\_manage\_energy\_prefs ([#​1050](homeassistant-ai/ha-mcp#1050)) ([#​1073](homeassistant-ai/ha-mcp#1073)) - Surface integration log levels in ha\_get\_logs/integration/addon ([#​956](homeassistant-ai/ha-mcp#956)) ([#​1003](homeassistant-ai/ha-mcp#1003)) - Expose allowlist\_external\_dirs in ha\_get\_overview full system\_info ([#​1053](homeassistant-ai/ha-mcp#1053)) - **dashboards**: Unify identifier handling in ha\_config\_\*\_dashboard tools ([#​981](homeassistant-ai/ha-mcp#981)) ([#​1075](homeassistant-ai/ha-mcp#1075)) - Include addon container logs in bug reports ([#​934](homeassistant-ai/ha-mcp#934)) - Add WebSocket response-shaping controls to ha\_manage\_addon ([#​1009](homeassistant-ai/ha-mcp#1009)) - Web-based settings UI for per-tool enable/disable/pin ([#​960](homeassistant-ai/ha-mcp#960)) - **site**: Add OpenCode support to setup wizard ([#​1080](homeassistant-ai/ha-mcp#1080)) ##### Changed - Clarify standard-mode HTTP deployment guidance ([#​1185](homeassistant-ai/ha-mcp#1185)) - Add Cloudflared add-on hostname alternative for tunnel service ([#​1183](homeassistant-ai/ha-mcp#1183)) - Align tool naming convention between AGENTS.md and styleguide ([#​943](homeassistant-ai/ha-mcp#943)) ([#​1174](homeassistant-ai/ha-mcp#1174)) - **addon**: Note tool-list ([#​985](homeassistant-ai/ha-mcp#985 divergence; fix [#​1139](https://github.com/homeassistant-ai/ha-mcp/issues/1139)/[#​1162](https://github.com/homeassistant-ai/ha-mcp/issues/1162) test conflict ([#​1172](homeassistant-ai/ha-mcp#1172)) - Add brew install option for mcp-proxy on macOS ([#​1171](homeassistant-ai/ha-mcp#1171)) - Update contributors list \[contributors-updated] ([`aba01a1`](homeassistant-ai/ha-mcp@aba01a1)) - Warn against enable\_tool\_search on Claude Sonnet/Opus ([#​1088](homeassistant-ai/ha-mcp#1088)) ([#​1140](homeassistant-ai/ha-mcp#1140)) - Address [#​1094](homeassistant-ai/ha-mcp#1094) review nits on OpenCode mirror comments ([#​1105](homeassistant-ai/ha-mcp#1105)) ##### Fixed - **integrations**: Surface ConfigEntry.options via OptionsFlow probe ([#​1245](homeassistant-ai/ha-mcp#1245)) - **backup**: Discover local agent at call time instead of hardcoding hassio.local ([#​1244](homeassistant-ai/ha-mcp#1244)) - Triage all 10 ha\_search\_entities behaviors from [#​1170](homeassistant-ai/ha-mcp#1170) ([#​1195](homeassistant-ai/ha-mcp#1195)) - Replace cron with systemd for demo server (prevents process leak) ([#​1110](homeassistant-ai/ha-mcp#1110)) - Improve ha\_manage\_addon discoverability (BM25 keywords + slug examples) ([#​1200](homeassistant-ai/ha-mcp#1200)) - Route Supervisor 401s to structured tool errors + add E2E coverage ([#​1129](homeassistant-ai/ha-mcp#1129)) ([#​1192](homeassistant-ai/ha-mcp#1192)) - Harden \_validate\_category\_id gate to cover dict-promoted category ([#​1190](homeassistant-ai/ha-mcp#1190)) - Broaden template anti-pattern detection + skill discoverability ([#​1011](homeassistant-ai/ha-mcp#1011)) ([#​1181](homeassistant-ai/ha-mcp#1181)) - Return newest automation traces, add offset+order pagination ([#​1177](homeassistant-ai/ha-mcp#1177)) ([#​1178](homeassistant-ai/ha-mcp#1178)) - **security**: Write YAML backups outside www/ (GHSA-g39v-cvjh-8fpf) ([#​1180](homeassistant-ai/ha-mcp#1180)) - **search**: Apply domain\_filter when area\_filter is set ([#​1162](homeassistant-ai/ha-mcp#1162)) ([#​1165](homeassistant-ai/ha-mcp#1165)) - **resources**: Reject HA-config YAML in dashboard resource content ([#​1160](homeassistant-ai/ha-mcp#1160)) - Close 19 bugs in ha\_config\_set\_helper (issue [#​1150](homeassistant-ai/ha-mcp#1150)) ([#​1151](homeassistant-ai/ha-mcp#1151)) - Route addon log fetches directly to supervisor on addon installs ([#​1126](homeassistant-ai/ha-mcp#1126)) - Survive read-only filesystems at startup ([#​1138](homeassistant-ai/ha-mcp#1138)) - **helpers**: Clarify name-required-on-create for ha\_config\_set\_helper ([#​1143](homeassistant-ai/ha-mcp#1143)) - Resolve disabled entities via entity\_registry in helper deletion ([#​1119](homeassistant-ai/ha-mcp#1119)) - Allow unary operators in python\_transform sandbox ([#​1118](homeassistant-ai/ha-mcp#1118)) - **site**: Add github-copilot-agents wizard branch + delete unreferenced data/clients.ts ([#​1108](homeassistant-ai/ha-mcp#1108)) - **addons**: Route addon API calls through HA Core ingress proxy ([#​1069](homeassistant-ai/ha-mcp#1069)) - **webhook-proxy**: Surface webhook registration failures instead of silently loading ([#​1101](homeassistant-ai/ha-mcp#1101)) - **site**: Resolve client display-order collisions and anchor OpenCode shape ([#​1094](homeassistant-ai/ha-mcp#1094)) ##### Performance Improvements - Dedupe lovelace/dashboards/list in ha\_config\_set\_dashboard ([#​1085](homeassistant-ai/ha-mcp#1085)) ([#​1191](homeassistant-ai/ha-mcp#1191)) ##### Refactoring - Drop obsolete ha\_mcp\_tools defensive ruamel.yaml imports ([post-#​1268](https://github.com/post-/ha-mcp/issues/1268)) ([#​1269](homeassistant-ai/ha-mcp#1269)) - Extract shared Supervisor httpx client helper ([#​1130](homeassistant-ai/ha-mcp#1130)) ([#​1203](homeassistant-ai/ha-mcp#1203)) - Surface client identity, AI model, config toggles, and prompt context in ha\_report\_issue ([#​1189](homeassistant-ai/ha-mcp#1189)) - Harden Context injection with safe-emit + branch coverage ([#​1173](homeassistant-ai/ha-mcp#1173)) - Consolidate area/floor set+remove tools (revisit of [#​813](homeassistant-ai/ha-mcp#813)) ([#​1139](homeassistant-ai/ha-mcp#1139)) - Pass verify\_ssl to remaining direct-Supervisor httpx callers ([#​1128](homeassistant-ai/ha-mcp#1128)) - Validate only new entries on convenience-mode writes ([#​1086](homeassistant-ai/ha-mcp#1086)) ([#​1100](homeassistant-ai/ha-mcp#1100)) *** <details> <summary>Internal Changes</summary> ##### Fixed - **ci**: Align pr.yml E2E with --dist loadscope ([#​1206](homeassistant-ai/ha-mcp#1206)) ([#​1247](homeassistant-ai/ha-mcp#1247)) - **ci**: Switch Renovate to a GitHub App token to allow workflow-file pushes ([#​1229](homeassistant-ai/ha-mcp#1229)) - **ci**: Break gemini-triage retrigger loop and bump turn budget ([#​1131](homeassistant-ai/ha-mcp#1131)) - **ci**: Harden gemini-triage so failures stop spamming user issues ([#​1122](homeassistant-ai/ha-mcp#1122)) - **ci**: Unbreak hotfix-release semantic-release run ([#​1091](homeassistant-ai/ha-mcp#1091)) ##### Chores - **addon**: Publish dev addon version 7.4.1.dev299 \[skip ci] ([`397aa6d`](homeassistant-ai/ha-mcp@397aa6d)) - **addon**: Publish dev addon version 7.4.1.dev298 \[skip ci] ([`942b7e0`](homeassistant-ai/ha-mcp@942b7e0)) - Sync tool docs after merge \[skip ci] ([`6823c47`](homeassistant-ai/ha-mcp@6823c47)) - **addon**: Publish dev addon version 7.4.1.dev297 \[skip ci] ([`6eac062`](homeassistant-ai/ha-mcp@6eac062)) - **addon**: Publish dev addon version 7.4.1.dev296 \[skip ci] ([`b2afe93`](homeassistant-ai/ha-mcp@b2afe93)) - **addon**: Publish dev addon version 7.4.1.dev295 \[skip ci] ([`4f4c4f3`](homeassistant-ai/ha-mcp@4f4c4f3)) - **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.1 ([#​1236](homeassistant-ai/ha-mcp#1236)) - **addon**: Publish dev addon version 7.4.1.dev294 \[skip ci] ([`fd24991`](homeassistant-ai/ha-mcp@fd24991)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.13 ([#​1233](homeassistant-ai/ha-mcp#1233)) - **addon**: Publish dev addon version 7.4.1.dev293 \[skip ci] ([`fcc6496`](homeassistant-ai/ha-mcp@fcc6496)) - **addon**: Publish dev addon version 7.4.1.dev292 \[skip ci] ([`2961650`](homeassistant-ai/ha-mcp@2961650)) - **addon**: Publish dev addon version 7.4.1.dev291 \[skip ci] ([`5703112`](homeassistant-ai/ha-mcp@5703112)) - **addon**: Publish dev addon version 7.4.1.dev290 \[skip ci] ([`19b2f65`](homeassistant-ai/ha-mcp@19b2f65)) - **addon**: Publish dev addon version 7.4.1.dev289 \[skip ci] ([`e5a1365`](homeassistant-ai/ha-mcp@e5a1365)) - Sync tool docs after merge \[skip ci] ([`d2ff93b`](homeassistant-ai/ha-mcp@d2ff93b)) - **addon**: Publish dev addon version 7.4.1.dev288 \[skip ci] ([`0f62400`](homeassistant-ai/ha-mcp@0f62400)) - Sync tool docs after merge \[skip ci] ([`c7e2066`](homeassistant-ai/ha-mcp@c7e2066)) - **addon**: Publish dev addon version 7.4.1.dev287 \[skip ci] ([`c1133d4`](homeassistant-ai/ha-mcp@c1133d4)) - **addon**: Publish dev addon version 7.4.1.dev286 \[skip ci] ([`1ae790e`](homeassistant-ai/ha-mcp@1ae790e)) - **addon**: Publish dev addon version 7.4.1.dev285 \[skip ci] ([`2387d0c`](homeassistant-ai/ha-mcp@2387d0c)) - **addon**: Publish dev addon version 7.4.1.dev284 \[skip ci] ([`dd3a4a5`](homeassistant-ai/ha-mcp@dd3a4a5)) - **addon**: Publish dev addon version 7.4.1.dev283 \[skip ci] ([`78af8eb`](homeassistant-ai/ha-mcp@78af8eb)) - Sync tool docs after merge \[skip ci] ([`093fd74`](homeassistant-ai/ha-mcp@093fd74)) - **addon**: Publish dev addon version 7.4.1.dev282 \[skip ci] ([`2141e15`](homeassistant-ai/ha-mcp@2141e15)) - Sync tool docs after merge \[skip ci] ([`7810c95`](homeassistant-ai/ha-mcp@7810c95)) - **addon**: Publish dev addon version 7.4.1.dev281 \[skip ci] ([`7d79ec2`](homeassistant-ai/ha-mcp@7d79ec2)) - Sync tool docs after merge \[skip ci] ([`a73dc81`](homeassistant-ai/ha-mcp@a73dc81)) - **addon**: Publish dev addon version 7.4.1.dev280 \[skip ci] ([`c858ce3`](homeassistant-ai/ha-mcp@c858ce3)) - Sync tool docs after merge \[skip ci] ([`a587be0`](homeassistant-ai/ha-mcp@a587be0)) - **addon**: Publish dev addon version 7.4.1.dev279 \[skip ci] ([`b78ddb2`](homeassistant-ai/ha-mcp@b78ddb2)) - Sync tool docs after merge \[skip ci] ([`1210725`](homeassistant-ai/ha-mcp@1210725)) - **addon**: Publish dev addon version 7.4.1.dev278 \[skip ci] ([`a282c17`](homeassistant-ai/ha-mcp@a282c17)) - **addon**: Publish dev addon version 7.4.1.dev277 \[skip ci] ([`1081768`](homeassistant-ai/ha-mcp@1081768)) - Sync tool docs after merge \[skip ci] ([`e03f5d2`](homeassistant-ai/ha-mcp@e03f5d2)) - **addon**: Publish dev addon version 7.4.1.dev276 \[skip ci] ([`c4ef680`](homeassistant-ai/ha-mcp@c4ef680)) - **addon**: Publish dev addon version 7.4.1.dev275 \[skip ci] ([`780422d`](homeassistant-ai/ha-mcp@780422d)) - Sync tool docs after merge \[skip ci] ([`8a2bd1a`](homeassistant-ai/ha-mcp@8a2bd1a)) - **addon**: Publish dev addon version 7.4.1.dev274 \[skip ci] ([`f0f09de`](homeassistant-ai/ha-mcp@f0f09de)) - **addon**: Publish dev addon version 7.4.1.dev273 \[skip ci] ([`cb49f68`](homeassistant-ai/ha-mcp@cb49f68)) - **addon**: Publish dev addon version 7.4.1.dev272 \[skip ci] ([`5097186`](homeassistant-ai/ha-mcp@5097186)) - **addon**: Publish dev addon version 7.4.1.dev271 \[skip ci] ([`4714342`](homeassistant-ai/ha-mcp@4714342)) - **addon**: Publish dev addon version 7.4.1.dev270 \[skip ci] ([`217982a`](homeassistant-ai/ha-mcp@217982a)) - **addon**: Publish dev addon version 7.4.1.dev269 \[skip ci] ([`a65dd5f`](homeassistant-ai/ha-mcp@a65dd5f)) - Sync tool docs after merge \[skip ci] ([`0e6b54f`](homeassistant-ai/ha-mcp@0e6b54f)) - **addon**: Publish dev addon version 7.4.1.dev268 \[skip ci] ([`60ba1f2`](homeassistant-ai/ha-mcp@60ba1f2)) - **addon**: Publish dev addon version 7.4.1.dev267 \[skip ci] ([`13412aa`](homeassistant-ai/ha-mcp@13412aa)) - Sync tool docs after merge \[skip ci] ([`2702a0f`](homeassistant-ai/ha-mcp@2702a0f)) - **addon**: Publish dev addon version 7.4.1.dev266 \[skip ci] ([`77abe0b`](homeassistant-ai/ha-mcp@77abe0b)) - **addon**: Publish dev addon version 7.4.1.dev265 \[skip ci] ([`08b69db`](homeassistant-ai/ha-mcp@08b69db)) - Sync tool docs after merge \[skip ci] ([`c1f24b5`](homeassistant-ai/ha-mcp@c1f24b5)) - **addon**: Publish dev addon version 7.4.1.dev264 \[skip ci] ([`f2583f6`](homeassistant-ai/ha-mcp@f2583f6)) - Sync tool docs after merge \[skip ci] ([`c2ed2d3`](homeassistant-ai/ha-mcp@c2ed2d3)) - **addon**: Publish dev addon version 7.4.1.dev263 \[skip ci] ([`9d43e54`](homeassistant-ai/ha-mcp@9d43e54)) - **addon**: Publish dev addon version 7.4.1.dev262 \[skip ci] ([`a7355c8`](homeassistant-ai/ha-mcp@a7355c8)) - Sync tool docs after merge \[skip ci] ([`085bd8a`](homeassistant-ai/ha-mcp@085bd8a)) - Convert agents to skills ([#​1084](homeassistant-ai/ha-mcp#1084)) - **addon**: Publish dev addon version 7.4.1.dev261 \[skip ci] ([`0d1af36`](homeassistant-ai/ha-mcp@0d1af36)) - **addon**: Publish dev addon version 7.4.1.dev260 \[skip ci] ([`29397dc`](homeassistant-ai/ha-mcp@29397dc)) - **addon**: Publish dev addon version 7.4.1.dev259 \[skip ci] ([`4bbc74b`](homeassistant-ai/ha-mcp@4bbc74b)) - Sync tool docs after merge \[skip ci] ([`0f6d41e`](homeassistant-ai/ha-mcp@0f6d41e)) - **addon**: Publish dev addon version 7.4.1.dev258 \[skip ci] ([`6751d08`](homeassistant-ai/ha-mcp@6751d08)) - **addon**: Publish dev addon version 7.4.1.dev257 \[skip ci] ([`2213c89`](homeassistant-ai/ha-mcp@2213c89)) - **addon**: Publish dev addon version 7.4.1.dev256 \[skip ci] ([`18a366e`](homeassistant-ai/ha-mcp@18a366e)) - **addon**: Publish dev addon version 7.4.1.dev255 \[skip ci] ([`0e9b18d`](homeassistant-ai/ha-mcp@0e9b18d)) - **addon**: Publish dev addon version 7.4.1.dev254 \[skip ci] ([`39fc65b`](homeassistant-ai/ha-mcp@39fc65b)) - Sync tool docs after merge \[skip ci] ([`9fa0aea`](homeassistant-ai/ha-mcp@9fa0aea)) - **addon**: Publish dev addon version 7.4.1.dev253 \[skip ci] ([`0dcc59e`](homeassistant-ai/ha-mcp@0dcc59e)) - Sync tool docs after merge \[skip ci] ([`ec7413f`](homeassistant-ai/ha-mcp@ec7413f)) - **addon**: Publish dev addon version 7.4.1.dev252 \[skip ci] ([`345640c`](homeassistant-ai/ha-mcp@345640c)) - **addon**: Publish dev addon version 7.4.1.dev251 \[skip ci] ([`bab9d49`](homeassistant-ai/ha-mcp@bab9d49)) - Sync tool docs after merge \[skip ci] ([`726f0a5`](homeassistant-ai/ha-mcp@726f0a5)) - **addon**: Publish dev addon version 7.4.1.dev250 \[skip ci] ([`ded04ea`](homeassistant-ai/ha-mcp@ded04ea)) - **addon**: Publish dev addon version 7.4.1.dev249 \[skip ci] ([`37d5628`](homeassistant-ai/ha-mcp@37d5628)) - **addon**: Publish dev addon version 7.4.1.dev248 \[skip ci] ([`530786a`](homeassistant-ai/ha-mcp@530786a)) - Sync tool docs after merge \[skip ci] ([`36719c3`](homeassistant-ai/ha-mcp@36719c3)) - **addon**: Publish dev addon version 7.4.1.dev247 \[skip ci] ([`4dc47b5`](homeassistant-ai/ha-mcp@4dc47b5)) - **addon**: Publish dev addon version 7.4.1.dev246 \[skip ci] ([`6ffbd6a`](homeassistant-ai/ha-mcp@6ffbd6a)) - Sync tool docs after merge \[skip ci] ([`add66e3`](homeassistant-ai/ha-mcp@add66e3)) - **addon**: Publish dev addon version 7.4.1.dev245 \[skip ci] ([`d0114af`](homeassistant-ai/ha-mcp@d0114af)) - Sync tool docs after merge \[skip ci] ([`0ca41af`](homeassistant-ai/ha-mcp@0ca41af)) - **addon**: Publish dev addon version 7.4.1.dev244 \[skip ci] ([`d052dd0`](homeassistant-ai/ha-mcp@d052dd0)) - **addon**: Publish dev addon version 7.4.0.dev243 \[skip ci] ([`827bc65`](homeassistant-ai/ha-mcp@827bc65)) - Bump package version to 7.4.1 to match released addon ([`4f65497`](homeassistant-ai/ha-mcp@4f65497)) - **addon**: Publish dev addon version 7.4.0.dev242 \[skip ci] ([`8ba80ae`](homeassistant-ai/ha-mcp@8ba80ae)) - **addon**: Publish hotfix version 7.4.1 ([`bda75e6`](homeassistant-ai/ha-mcp@bda75e6)) - **addon**: Publish dev addon version 7.4.0.dev241 \[skip ci] ([`2126428`](homeassistant-ai/ha-mcp@2126428)) ##### Continuous Integration - **deps**: Bump renovatebot/github-action in the github-actions group ([#​1218](homeassistant-ai/ha-mcp#1218)) - **deps**: Bump renovatebot/github-action in the github-actions group ([#​1111](homeassistant-ai/ha-mcp#1111)) ##### Refactoring - Extract \_fetch\_dashboards\_list helper ([#​1193](homeassistant-ai/ha-mcp#1193)) ([#​1207](homeassistant-ai/ha-mcp#1207)) ##### Testing - **e2e**: Module-scope bulk\_automations + bulk\_scripts fixtures (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1275](homeassistant-ai/ha-mcp#1275)) - **e2e**: Lower INPUT\_BOOLEAN\_WAIT from 30s to 10s (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1273](homeassistant-ai/ha-mcp#1273)) - **e2e**: Generalize readiness-gate diagnostics helper (closes [#​1267](homeassistant-ai/ha-mcp#1267)) ([#​1271](homeassistant-ai/ha-mcp#1271)) - **e2e**: Narrow except clauses in e2e polling helpers (closes [#​1266](homeassistant-ai/ha-mcp#1266)) ([#​1270](homeassistant-ai/ha-mcp#1270)) - **e2e**: Drop ha\_mcp\_tools retry-path + pre-install manifest requirements ([#​1268](homeassistant-ai/ha-mcp#1268)) - **e2e**: Instrument and retry ha\_mcp\_tools readiness wait ([#​1262](homeassistant-ai/ha-mcp#1262)) - Use time.monotonic() in UAT runner and test\_env\_manager ([#​1254](homeassistant-ai/ha-mcp#1254)) - **e2e**: Detect partial/corrupt hacs\_frontend dir in fast-path guard ([#​1253](homeassistant-ai/ha-mcp#1253)) - **e2e**: Remove unused wait/assert helpers ([post-#​1249](https://github.com/post-/ha-mcp/issues/1249) audit) ([#​1256](homeassistant-ai/ha-mcp#1256)) - **e2e**: Clear stale .hacs\_frontend.lock from prior crashed runs ([#​1252](homeassistant-ai/ha-mcp#1252)) - **e2e**: Use time.monotonic() in workflow polling loops ([#​1258](homeassistant-ai/ha-mcp#1258)) - **e2e**: Use time.monotonic() for duration polling ([#​1234](homeassistant-ai/ha-mcp#1234)) ([#​1249](homeassistant-ai/ha-mcp#1249)) - **e2e**: Close ARM ha\_mcp\_tools readiness race under loadscope ([#​1208](homeassistant-ai/ha-mcp#1208)) - **hacs**: Tighten is\_hacs\_unavailable to not match legitimate "Repository not found" ([#​1246](homeassistant-ai/ha-mcp#1246)) - **seed**: Unblock 3 silent-skip pagination/state tests via baked recorder DB ([#​1240](homeassistant-ai/ha-mcp#1240)) - **seed**: Register a writable local\_calendar to unblock event-creation test ([#​1243](homeassistant-ai/ha-mcp#1243)) - **addon**: Fix base64 padding-bit flake in token tamper tests ([#​1238](homeassistant-ai/ha-mcp#1238)) ([#​1241](homeassistant-ai/ha-mcp#1241)) - **seed**: Add a writable scene for test\_call\_service\_scene\_turn\_on ([#​1231](homeassistant-ai/ha-mcp#1231)) - **seed**: Assign demo device to living\_room area for filter test ([#​1230](homeassistant-ai/ha-mcp#1230)) - **e2e**: Drop nonexistent sun service from session readiness wait ([#​1227](homeassistant-ai/ha-mcp#1227)) - **e2e**: Self-contain dashboard register/remove to fix ARM xdist race ([#​1196](homeassistant-ai/ha-mcp#1196)) ([#​1201](homeassistant-ai/ha-mcp#1201)) - Fix EN dash in docstring causing RUF002 lint failure ([`eac5916`](homeassistant-ai/ha-mcp@eac5916)) - Address Gemini review feedback on host detection and port allocation ([`960305e`](homeassistant-ai/ha-mcp@960305e)) - Fix three categories of E2E test flakiness ([`39417ff`](homeassistant-ai/ha-mcp@39417ff)) - **e2e**: Pin config\_hash stability for dashboards ([#​1132](homeassistant-ai/ha-mcp#1132)) </details> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/455
….0 ) (#26) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/homeassistant-ai/ha-mcp](https://github.com/homeassistant-ai/ha-mcp) | minor | `7.4.0` → `7.5.0` | --- ### Release Notes <details> <summary>homeassistant-ai/ha-mcp (ghcr.io/homeassistant-ai/ha-mcp)</summary> ### [`v7.5.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v750-2026-05-13) [Compare Source](homeassistant-ai/ha-mcp@v7.4.0...v7.5.0) ##### Added - Add ENABLE\_LITE\_DOCSTRINGS beta toggle ([#​1259](homeassistant-ai/ha-mcp#1259)) - Add ha\_call\_event tool for publishing events on the HA event bus ([#​996](homeassistant-ai/ha-mcp#996)) ([#​1239](homeassistant-ai/ha-mcp#1239)) - Pinpoint backslash-escape mistake in python\_sandbox errors ([#​1204](homeassistant-ai/ha-mcp#1204)) - Reject empty-trigger automations targeting scene.create ([#​1187](homeassistant-ai/ha-mcp#1187)) - Add scene config tools — ha\_config\_get/set/remove\_scene ([#​1168](homeassistant-ai/ha-mcp#1168)) - **addon**: Optional OAuth 2.1 mode for webhook proxy (beta) ([#​1184](homeassistant-ai/ha-mcp#1184)) - Surface helper schema inline in ha\_config\_set\_helper validation errors ([#​1149](homeassistant-ai/ha-mcp#1149)) ([#​1179](homeassistant-ai/ha-mcp#1179)) - Emit progress via FastMCP Context in long-running tools ([#​1124](homeassistant-ai/ha-mcp#1124)) - Broaden python\_transform AST allowlist + improve error UX ([#​1163](homeassistant-ai/ha-mcp#1163)) - Add ha\_manage\_custom\_tool — sandboxed code execution escape hatch ([#​854](homeassistant-ai/ha-mcp#854)) - Always-on skills; rename list/read resource tools with ha\_ prefix ([#​1136](homeassistant-ai/ha-mcp#1136)) - Expose device\_class + options on ha\_set\_entity / ha\_get\_entity (Show As) ([#​1135](homeassistant-ai/ha-mcp#1135)) - **site**: Inline wizard data into setup.astro, migrate setup nuggets, drop content collections ([#​1120](homeassistant-ai/ha-mcp#1120)) - Add "Advanced debug logging" toggle for kill-signal diagnostics ([#​1117](homeassistant-ai/ha-mcp#1117)) - **yaml**: Scoped lovelace.dashboards.\<url\_path> support (issue [#​1034](homeassistant-ai/ha-mcp#1034)) ([#​1103](homeassistant-ai/ha-mcp#1103)) - Add HA\_VERIFY\_SSL toggle to disable TLS verification ([#​1104](homeassistant-ai/ha-mcp#1104)) - Per-top-level-key config\_hash for ha\_manage\_energy\_prefs ([#​1049](homeassistant-ai/ha-mcp#1049)) ([#​1098](homeassistant-ai/ha-mcp#1098)) - **site**: Add gemini-cli setup notes + compose hardening to wizard ([#​1027](homeassistant-ai/ha-mcp#1027)) ([#​1087](homeassistant-ai/ha-mcp#1087)) - Add convenience modes to ha\_manage\_energy\_prefs ([#​1050](homeassistant-ai/ha-mcp#1050)) ([#​1073](homeassistant-ai/ha-mcp#1073)) - Surface integration log levels in ha\_get\_logs/integration/addon ([#​956](homeassistant-ai/ha-mcp#956)) ([#​1003](homeassistant-ai/ha-mcp#1003)) - Expose allowlist\_external\_dirs in ha\_get\_overview full system\_info ([#​1053](homeassistant-ai/ha-mcp#1053)) - **dashboards**: Unify identifier handling in ha\_config\_\*\_dashboard tools ([#​981](homeassistant-ai/ha-mcp#981)) ([#​1075](homeassistant-ai/ha-mcp#1075)) - Include addon container logs in bug reports ([#​934](homeassistant-ai/ha-mcp#934)) - Add WebSocket response-shaping controls to ha\_manage\_addon ([#​1009](homeassistant-ai/ha-mcp#1009)) - Web-based settings UI for per-tool enable/disable/pin ([#​960](homeassistant-ai/ha-mcp#960)) - **site**: Add OpenCode support to setup wizard ([#​1080](homeassistant-ai/ha-mcp#1080)) ##### Changed - Clarify standard-mode HTTP deployment guidance ([#​1185](homeassistant-ai/ha-mcp#1185)) - Add Cloudflared add-on hostname alternative for tunnel service ([#​1183](homeassistant-ai/ha-mcp#1183)) - Align tool naming convention between AGENTS.md and styleguide ([#​943](homeassistant-ai/ha-mcp#943)) ([#​1174](homeassistant-ai/ha-mcp#1174)) - **addon**: Note tool-list ([#​985](homeassistant-ai/ha-mcp#985 divergence; fix [#​1139](https://github.com/homeassistant-ai/ha-mcp/issues/1139)/[#​1162](https://github.com/homeassistant-ai/ha-mcp/issues/1162) test conflict ([#​1172](homeassistant-ai/ha-mcp#1172)) - Add brew install option for mcp-proxy on macOS ([#​1171](homeassistant-ai/ha-mcp#1171)) - Update contributors list \[contributors-updated] ([`aba01a1`](homeassistant-ai/ha-mcp@aba01a1)) - Warn against enable\_tool\_search on Claude Sonnet/Opus ([#​1088](homeassistant-ai/ha-mcp#1088)) ([#​1140](homeassistant-ai/ha-mcp#1140)) - Address [#​1094](homeassistant-ai/ha-mcp#1094) review nits on OpenCode mirror comments ([#​1105](homeassistant-ai/ha-mcp#1105)) ##### Fixed - **integrations**: Surface ConfigEntry.options via OptionsFlow probe ([#​1245](homeassistant-ai/ha-mcp#1245)) - **backup**: Discover local agent at call time instead of hardcoding hassio.local ([#​1244](homeassistant-ai/ha-mcp#1244)) - Triage all 10 ha\_search\_entities behaviors from [#​1170](homeassistant-ai/ha-mcp#1170) ([#​1195](homeassistant-ai/ha-mcp#1195)) - Replace cron with systemd for demo server (prevents process leak) ([#​1110](homeassistant-ai/ha-mcp#1110)) - Improve ha\_manage\_addon discoverability (BM25 keywords + slug examples) ([#​1200](homeassistant-ai/ha-mcp#1200)) - Route Supervisor 401s to structured tool errors + add E2E coverage ([#​1129](homeassistant-ai/ha-mcp#1129)) ([#​1192](homeassistant-ai/ha-mcp#1192)) - Harden \_validate\_category\_id gate to cover dict-promoted category ([#​1190](homeassistant-ai/ha-mcp#1190)) - Broaden template anti-pattern detection + skill discoverability ([#​1011](homeassistant-ai/ha-mcp#1011)) ([#​1181](homeassistant-ai/ha-mcp#1181)) - Return newest automation traces, add offset+order pagination ([#​1177](homeassistant-ai/ha-mcp#1177)) ([#​1178](homeassistant-ai/ha-mcp#1178)) - **security**: Write YAML backups outside www/ (GHSA-g39v-cvjh-8fpf) ([#​1180](homeassistant-ai/ha-mcp#1180)) - **search**: Apply domain\_filter when area\_filter is set ([#​1162](homeassistant-ai/ha-mcp#1162)) ([#​1165](homeassistant-ai/ha-mcp#1165)) - **resources**: Reject HA-config YAML in dashboard resource content ([#​1160](homeassistant-ai/ha-mcp#1160)) - Close 19 bugs in ha\_config\_set\_helper (issue [#​1150](homeassistant-ai/ha-mcp#1150)) ([#​1151](homeassistant-ai/ha-mcp#1151)) - Route addon log fetches directly to supervisor on addon installs ([#​1126](homeassistant-ai/ha-mcp#1126)) - Survive read-only filesystems at startup ([#​1138](homeassistant-ai/ha-mcp#1138)) - **helpers**: Clarify name-required-on-create for ha\_config\_set\_helper ([#​1143](homeassistant-ai/ha-mcp#1143)) - Resolve disabled entities via entity\_registry in helper deletion ([#​1119](homeassistant-ai/ha-mcp#1119)) - Allow unary operators in python\_transform sandbox ([#​1118](homeassistant-ai/ha-mcp#1118)) - **site**: Add github-copilot-agents wizard branch + delete unreferenced data/clients.ts ([#​1108](homeassistant-ai/ha-mcp#1108)) - **addons**: Route addon API calls through HA Core ingress proxy ([#​1069](homeassistant-ai/ha-mcp#1069)) - **webhook-proxy**: Surface webhook registration failures instead of silently loading ([#​1101](homeassistant-ai/ha-mcp#1101)) - **site**: Resolve client display-order collisions and anchor OpenCode shape ([#​1094](homeassistant-ai/ha-mcp#1094)) ##### Performance Improvements - Dedupe lovelace/dashboards/list in ha\_config\_set\_dashboard ([#​1085](homeassistant-ai/ha-mcp#1085)) ([#​1191](homeassistant-ai/ha-mcp#1191)) ##### Refactoring - Drop obsolete ha\_mcp\_tools defensive ruamel.yaml imports ([post-#​1268](https://github.com/post-/ha-mcp/issues/1268)) ([#​1269](homeassistant-ai/ha-mcp#1269)) - Extract shared Supervisor httpx client helper ([#​1130](homeassistant-ai/ha-mcp#1130)) ([#​1203](homeassistant-ai/ha-mcp#1203)) - Surface client identity, AI model, config toggles, and prompt context in ha\_report\_issue ([#​1189](homeassistant-ai/ha-mcp#1189)) - Harden Context injection with safe-emit + branch coverage ([#​1173](homeassistant-ai/ha-mcp#1173)) - Consolidate area/floor set+remove tools (revisit of [#​813](homeassistant-ai/ha-mcp#813)) ([#​1139](homeassistant-ai/ha-mcp#1139)) - Pass verify\_ssl to remaining direct-Supervisor httpx callers ([#​1128](homeassistant-ai/ha-mcp#1128)) - Validate only new entries on convenience-mode writes ([#​1086](homeassistant-ai/ha-mcp#1086)) ([#​1100](homeassistant-ai/ha-mcp#1100)) *** <details> <summary>Internal Changes</summary> ##### Fixed - **ci**: Align pr.yml E2E with --dist loadscope ([#​1206](homeassistant-ai/ha-mcp#1206)) ([#​1247](homeassistant-ai/ha-mcp#1247)) - **ci**: Switch Renovate to a GitHub App token to allow workflow-file pushes ([#​1229](homeassistant-ai/ha-mcp#1229)) - **ci**: Break gemini-triage retrigger loop and bump turn budget ([#​1131](homeassistant-ai/ha-mcp#1131)) - **ci**: Harden gemini-triage so failures stop spamming user issues ([#​1122](homeassistant-ai/ha-mcp#1122)) - **ci**: Unbreak hotfix-release semantic-release run ([#​1091](homeassistant-ai/ha-mcp#1091)) ##### Chores - **addon**: Publish dev addon version 7.4.1.dev299 \[skip ci] ([`397aa6d`](homeassistant-ai/ha-mcp@397aa6d)) - **addon**: Publish dev addon version 7.4.1.dev298 \[skip ci] ([`942b7e0`](homeassistant-ai/ha-mcp@942b7e0)) - Sync tool docs after merge \[skip ci] ([`6823c47`](homeassistant-ai/ha-mcp@6823c47)) - **addon**: Publish dev addon version 7.4.1.dev297 \[skip ci] ([`6eac062`](homeassistant-ai/ha-mcp@6eac062)) - **addon**: Publish dev addon version 7.4.1.dev296 \[skip ci] ([`b2afe93`](homeassistant-ai/ha-mcp@b2afe93)) - **addon**: Publish dev addon version 7.4.1.dev295 \[skip ci] ([`4f4c4f3`](homeassistant-ai/ha-mcp@4f4c4f3)) - **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.1 ([#​1236](homeassistant-ai/ha-mcp#1236)) - **addon**: Publish dev addon version 7.4.1.dev294 \[skip ci] ([`fd24991`](homeassistant-ai/ha-mcp@fd24991)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.13 ([#​1233](homeassistant-ai/ha-mcp#1233)) - **addon**: Publish dev addon version 7.4.1.dev293 \[skip ci] ([`fcc6496`](homeassistant-ai/ha-mcp@fcc6496)) - **addon**: Publish dev addon version 7.4.1.dev292 \[skip ci] ([`2961650`](homeassistant-ai/ha-mcp@2961650)) - **addon**: Publish dev addon version 7.4.1.dev291 \[skip ci] ([`5703112`](homeassistant-ai/ha-mcp@5703112)) - **addon**: Publish dev addon version 7.4.1.dev290 \[skip ci] ([`19b2f65`](homeassistant-ai/ha-mcp@19b2f65)) - **addon**: Publish dev addon version 7.4.1.dev289 \[skip ci] ([`e5a1365`](homeassistant-ai/ha-mcp@e5a1365)) - Sync tool docs after merge \[skip ci] ([`d2ff93b`](homeassistant-ai/ha-mcp@d2ff93b)) - **addon**: Publish dev addon version 7.4.1.dev288 \[skip ci] ([`0f62400`](homeassistant-ai/ha-mcp@0f62400)) - Sync tool docs after merge \[skip ci] ([`c7e2066`](homeassistant-ai/ha-mcp@c7e2066)) - **addon**: Publish dev addon version 7.4.1.dev287 \[skip ci] ([`c1133d4`](homeassistant-ai/ha-mcp@c1133d4)) - **addon**: Publish dev addon version 7.4.1.dev286 \[skip ci] ([`1ae790e`](homeassistant-ai/ha-mcp@1ae790e)) - **addon**: Publish dev addon version 7.4.1.dev285 \[skip ci] ([`2387d0c`](homeassistant-ai/ha-mcp@2387d0c)) - **addon**: Publish dev addon version 7.4.1.dev284 \[skip ci] ([`dd3a4a5`](homeassistant-ai/ha-mcp@dd3a4a5)) - **addon**: Publish dev addon version 7.4.1.dev283 \[skip ci] ([`78af8eb`](homeassistant-ai/ha-mcp@78af8eb)) - Sync tool docs after merge \[skip ci] ([`093fd74`](homeassistant-ai/ha-mcp@093fd74)) - **addon**: Publish dev addon version 7.4.1.dev282 \[skip ci] ([`2141e15`](homeassistant-ai/ha-mcp@2141e15)) - Sync tool docs after merge \[skip ci] ([`7810c95`](homeassistant-ai/ha-mcp@7810c95)) - **addon**: Publish dev addon version 7.4.1.dev281 \[skip ci] ([`7d79ec2`](homeassistant-ai/ha-mcp@7d79ec2)) - Sync tool docs after merge \[skip ci] ([`a73dc81`](homeassistant-ai/ha-mcp@a73dc81)) - **addon**: Publish dev addon version 7.4.1.dev280 \[skip ci] ([`c858ce3`](homeassistant-ai/ha-mcp@c858ce3)) - Sync tool docs after merge \[skip ci] ([`a587be0`](homeassistant-ai/ha-mcp@a587be0)) - **addon**: Publish dev addon version 7.4.1.dev279 \[skip ci] ([`b78ddb2`](homeassistant-ai/ha-mcp@b78ddb2)) - Sync tool docs after merge \[skip ci] ([`1210725`](homeassistant-ai/ha-mcp@1210725)) - **addon**: Publish dev addon version 7.4.1.dev278 \[skip ci] ([`a282c17`](homeassistant-ai/ha-mcp@a282c17)) - **addon**: Publish dev addon version 7.4.1.dev277 \[skip ci] ([`1081768`](homeassistant-ai/ha-mcp@1081768)) - Sync tool docs after merge \[skip ci] ([`e03f5d2`](homeassistant-ai/ha-mcp@e03f5d2)) - **addon**: Publish dev addon version 7.4.1.dev276 \[skip ci] ([`c4ef680`](homeassistant-ai/ha-mcp@c4ef680)) - **addon**: Publish dev addon version 7.4.1.dev275 \[skip ci] ([`780422d`](homeassistant-ai/ha-mcp@780422d)) - Sync tool docs after merge \[skip ci] ([`8a2bd1a`](homeassistant-ai/ha-mcp@8a2bd1a)) - **addon**: Publish dev addon version 7.4.1.dev274 \[skip ci] ([`f0f09de`](homeassistant-ai/ha-mcp@f0f09de)) - **addon**: Publish dev addon version 7.4.1.dev273 \[skip ci] ([`cb49f68`](homeassistant-ai/ha-mcp@cb49f68)) - **addon**: Publish dev addon version 7.4.1.dev272 \[skip ci] ([`5097186`](homeassistant-ai/ha-mcp@5097186)) - **addon**: Publish dev addon version 7.4.1.dev271 \[skip ci] ([`4714342`](homeassistant-ai/ha-mcp@4714342)) - **addon**: Publish dev addon version 7.4.1.dev270 \[skip ci] ([`217982a`](homeassistant-ai/ha-mcp@217982a)) - **addon**: Publish dev addon version 7.4.1.dev269 \[skip ci] ([`a65dd5f`](homeassistant-ai/ha-mcp@a65dd5f)) - Sync tool docs after merge \[skip ci] ([`0e6b54f`](homeassistant-ai/ha-mcp@0e6b54f)) - **addon**: Publish dev addon version 7.4.1.dev268 \[skip ci] ([`60ba1f2`](homeassistant-ai/ha-mcp@60ba1f2)) - **addon**: Publish dev addon version 7.4.1.dev267 \[skip ci] ([`13412aa`](homeassistant-ai/ha-mcp@13412aa)) - Sync tool docs after merge \[skip ci] ([`2702a0f`](homeassistant-ai/ha-mcp@2702a0f)) - **addon**: Publish dev addon version 7.4.1.dev266 \[skip ci] ([`77abe0b`](homeassistant-ai/ha-mcp@77abe0b)) - **addon**: Publish dev addon version 7.4.1.dev265 \[skip ci] ([`08b69db`](homeassistant-ai/ha-mcp@08b69db)) - Sync tool docs after merge \[skip ci] ([`c1f24b5`](homeassistant-ai/ha-mcp@c1f24b5)) - **addon**: Publish dev addon version 7.4.1.dev264 \[skip ci] ([`f2583f6`](homeassistant-ai/ha-mcp@f2583f6)) - Sync tool docs after merge \[skip ci] ([`c2ed2d3`](homeassistant-ai/ha-mcp@c2ed2d3)) - **addon**: Publish dev addon version 7.4.1.dev263 \[skip ci] ([`9d43e54`](homeassistant-ai/ha-mcp@9d43e54)) - **addon**: Publish dev addon version 7.4.1.dev262 \[skip ci] ([`a7355c8`](homeassistant-ai/ha-mcp@a7355c8)) - Sync tool docs after merge \[skip ci] ([`085bd8a`](homeassistant-ai/ha-mcp@085bd8a)) - Convert agents to skills ([#​1084](homeassistant-ai/ha-mcp#1084)) - **addon**: Publish dev addon version 7.4.1.dev261 \[skip ci] ([`0d1af36`](homeassistant-ai/ha-mcp@0d1af36)) - **addon**: Publish dev addon version 7.4.1.dev260 \[skip ci] ([`29397dc`](homeassistant-ai/ha-mcp@29397dc)) - **addon**: Publish dev addon version 7.4.1.dev259 \[skip ci] ([`4bbc74b`](homeassistant-ai/ha-mcp@4bbc74b)) - Sync tool docs after merge \[skip ci] ([`0f6d41e`](homeassistant-ai/ha-mcp@0f6d41e)) - **addon**: Publish dev addon version 7.4.1.dev258 \[skip ci] ([`6751d08`](homeassistant-ai/ha-mcp@6751d08)) - **addon**: Publish dev addon version 7.4.1.dev257 \[skip ci] ([`2213c89`](homeassistant-ai/ha-mcp@2213c89)) - **addon**: Publish dev addon version 7.4.1.dev256 \[skip ci] ([`18a366e`](homeassistant-ai/ha-mcp@18a366e)) - **addon**: Publish dev addon version 7.4.1.dev255 \[skip ci] ([`0e9b18d`](homeassistant-ai/ha-mcp@0e9b18d)) - **addon**: Publish dev addon version 7.4.1.dev254 \[skip ci] ([`39fc65b`](homeassistant-ai/ha-mcp@39fc65b)) - Sync tool docs after merge \[skip ci] ([`9fa0aea`](homeassistant-ai/ha-mcp@9fa0aea)) - **addon**: Publish dev addon version 7.4.1.dev253 \[skip ci] ([`0dcc59e`](homeassistant-ai/ha-mcp@0dcc59e)) - Sync tool docs after merge \[skip ci] ([`ec7413f`](homeassistant-ai/ha-mcp@ec7413f)) - **addon**: Publish dev addon version 7.4.1.dev252 \[skip ci] ([`345640c`](homeassistant-ai/ha-mcp@345640c)) - **addon**: Publish dev addon version 7.4.1.dev251 \[skip ci] ([`bab9d49`](homeassistant-ai/ha-mcp@bab9d49)) - Sync tool docs after merge \[skip ci] ([`726f0a5`](homeassistant-ai/ha-mcp@726f0a5)) - **addon**: Publish dev addon version 7.4.1.dev250 \[skip ci] ([`ded04ea`](homeassistant-ai/ha-mcp@ded04ea)) - **addon**: Publish dev addon version 7.4.1.dev249 \[skip ci] ([`37d5628`](homeassistant-ai/ha-mcp@37d5628)) - **addon**: Publish dev addon version 7.4.1.dev248 \[skip ci] ([`530786a`](homeassistant-ai/ha-mcp@530786a)) - Sync tool docs after merge \[skip ci] ([`36719c3`](homeassistant-ai/ha-mcp@36719c3)) - **addon**: Publish dev addon version 7.4.1.dev247 \[skip ci] ([`4dc47b5`](homeassistant-ai/ha-mcp@4dc47b5)) - **addon**: Publish dev addon version 7.4.1.dev246 \[skip ci] ([`6ffbd6a`](homeassistant-ai/ha-mcp@6ffbd6a)) - Sync tool docs after merge \[skip ci] ([`add66e3`](homeassistant-ai/ha-mcp@add66e3)) - **addon**: Publish dev addon version 7.4.1.dev245 \[skip ci] ([`d0114af`](homeassistant-ai/ha-mcp@d0114af)) - Sync tool docs after merge \[skip ci] ([`0ca41af`](homeassistant-ai/ha-mcp@0ca41af)) - **addon**: Publish dev addon version 7.4.1.dev244 \[skip ci] ([`d052dd0`](homeassistant-ai/ha-mcp@d052dd0)) - **addon**: Publish dev addon version 7.4.0.dev243 \[skip ci] ([`827bc65`](homeassistant-ai/ha-mcp@827bc65)) - Bump package version to 7.4.1 to match released addon ([`4f65497`](homeassistant-ai/ha-mcp@4f65497)) - **addon**: Publish dev addon version 7.4.0.dev242 \[skip ci] ([`8ba80ae`](homeassistant-ai/ha-mcp@8ba80ae)) - **addon**: Publish hotfix version 7.4.1 ([`bda75e6`](homeassistant-ai/ha-mcp@bda75e6)) - **addon**: Publish dev addon version 7.4.0.dev241 \[skip ci] ([`2126428`](homeassistant-ai/ha-mcp@2126428)) ##### Continuous Integration - **deps**: Bump renovatebot/github-action in the github-actions group ([#​1218](homeassistant-ai/ha-mcp#1218)) - **deps**: Bump renovatebot/github-action in the github-actions group ([#​1111](homeassistant-ai/ha-mcp#1111)) ##### Refactoring - Extract \_fetch\_dashboards\_list helper ([#​1193](homeassistant-ai/ha-mcp#1193)) ([#​1207](homeassistant-ai/ha-mcp#1207)) ##### Testing - **e2e**: Module-scope bulk\_automations + bulk\_scripts fixtures (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1275](homeassistant-ai/ha-mcp#1275)) - **e2e**: Lower INPUT\_BOOLEAN\_WAIT from 30s to 10s (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1273](homeassistant-ai/ha-mcp#1273)) - **e2e**: Generalize readiness-gate diagnostics helper (closes [#​1267](homeassistant-ai/ha-mcp#1267)) ([#​1271](homeassistant-ai/ha-mcp#1271)) - **e2e**: Narrow except clauses in e2e polling helpers (closes [#​1266](homeassistant-ai/ha-mcp#1266)) ([#​1270](homeassistant-ai/ha-mcp#1270)) - **e2e**: Drop ha\_mcp\_tools retry-path + pre-install manifest requirements ([#​1268](homeassistant-ai/ha-mcp#1268)) - **e2e**: Instrument and retry ha\_mcp\_tools readiness wait ([#​1262](homeassistant-ai/ha-mcp#1262)) - Use time.monotonic() in UAT runner and test\_env\_manager ([#​1254](homeassistant-ai/ha-mcp#1254)) - **e2e**: Detect partial/corrupt hacs\_frontend dir in fast-path guard ([#​1253](homeassistant-ai/ha-mcp#1253)) - **e2e**: Remove unused wait/assert helpers ([post-#​1249](https://github.com/post-/ha-mcp/issues/1249) audit) ([#​1256](homeassistant-ai/ha-mcp#1256)) - **e2e**: Clear stale .hacs\_frontend.lock from prior crashed runs ([#​1252](homeassistant-ai/ha-mcp#1252)) - **e2e**: Use time.monotonic() in workflow polling loops ([#​1258](homeassistant-ai/ha-mcp#1258)) - **e2e**: Use time.monotonic() for duration polling ([#​1234](homeassistant-ai/ha-mcp#1234)) ([#​1249](homeassistant-ai/ha-mcp#1249)) - **e2e**: Close ARM ha\_mcp\_tools readiness race under loadscope ([#​1208](homeassistant-ai/ha-mcp#1208)) - **hacs**: Tighten is\_hacs\_unavailable to not match legitimate "Repository not found" ([#​1246](homeassistant-ai/ha-mcp#1246)) - **seed**: Unblock 3 silent-skip pagination/state tests via baked recorder DB ([#​1240](homeassistant-ai/ha-mcp#1240)) - **seed**: Register a writable local\_calendar to unblock event-creation test ([#​1243](homeassistant-ai/ha-mcp#1243)) - **addon**: Fix base64 padding-bit flake in token tamper tests ([#​1238](homeassistant-ai/ha-mcp#1238)) ([#​1241](homeassistant-ai/ha-mcp#1241)) - **seed**: Add a writable scene for test\_call\_service\_scene\_turn\_on ([#​1231](homeassistant-ai/ha-mcp#1231)) - **seed**: Assign demo device to living\_room area for filter test ([#​1230](homeassistant-ai/ha-mcp#1230)) - **e2e**: Drop nonexistent sun service from session readiness wait ([#​1227](homeassistant-ai/ha-mcp#1227)) - **e2e**: Self-contain dashboard register/remove to fix ARM xdist race ([#​1196](homeassistant-ai/ha-mcp#1196)) ([#​1201](homeassistant-ai/ha-mcp#1201)) - Fix EN dash in docstring causing RUF002 lint failure ([`eac5916`](homeassistant-ai/ha-mcp@eac5916)) - Address Gemini review feedback on host detection and port allocation ([`960305e`](homeassistant-ai/ha-mcp@960305e)) - Fix three categories of E2E test flakiness ([`39417ff`](homeassistant-ai/ha-mcp@39417ff)) - **e2e**: Pin config\_hash stability for dashboards ([#​1132](homeassistant-ai/ha-mcp#1132)) </details> </details> --- ### Configuration 📅 **Schedule**: (in timezone America/New_York) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNjAuNyIsInVwZGF0ZWRJblZlciI6IjQzLjE2MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Co-authored-by: todd <tpunderson@greyrock.io> Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/26
Closes #1193
Three call sites in
tools_config_dashboards.pyduplicated the samelovelace/dashboards/listfetch + shape-normalisation + warning logic.This PR extracts a shared
_fetch_dashboards_list(client)helper androutes all three sites through it.
What changed
New private helper
_fetch_dashboards_list(client):send_websocket_message({"type": "lovelace/dashboards/list"})result(guarded withisinstance(..., list)) vs bare-list response shapeslogger.warningon unexpected shapes (module-level logger; no extra parameter)list[dict[str, Any]] | None—Noneon shape failureRefactored call sites (all three preserve existing caller semantics):
_resolve_dashboard:None→return None, Noneha_config_get_dashboard(list_only=True):None→ fallback[];now emits the shape-change warning that was previously missing at this site
ha_config_set_dashboardexistence-check:None→ fallback[];removes the inline warning duplication added in ac52f74
Behaviour deltas (alongside the refactor)
Two small behavioural changes came in with the extraction — both intentional and strictly safer:
Guard tightened at the dict branch — from
"result" in resulttoisinstance(result.get("result"), list). Previously a response like{"result": "string"}or{"result": None}would take the happy pathand blow up downstream on iteration; now it falls through to the warning path.
ha_config_get_dashboard(list_only=True)now emits the unexpected-shape warning.Before this PR, an unexpected HA response at the
list_onlypath silentlyreturned
[]with no operator signal. After: same[]fallback, but thewarning is emitted — consistent with the other two sites.
Testing
TestGetDashboardListOnlyUnexpectedShapeadded totest_config_get_dashboard_search_error.py: pins the new warningbehaviour at the
ha_config_get_dashboardlist_only=Truepath,which had no unexpected-shape coverage before this PR
ruffandmypyboth pass on the changed files