refactor: pass verify_ssl to remaining direct-Supervisor httpx callers - #1128
Conversation
Closes homeassistant-ai#1127. Mirrors the verify=self.verify_ssl propagation pattern established in homeassistant-ai#1126 (rest_client.py:_get_addon_logs_via_supervisor) at the two other direct-Supervisor httpx call sites: - tools_bug_report.py:_fetch_addon_logs uses get_global_settings().verify_ssl (module-level helper, no self/closure context). - settings_ui.py:_restart_addon uses server.client.verify_ssl (closure has access to server: HomeAssistantSmartMCPServer). Both paths effectively propagate Settings.verify_ssl via the access route appropriate to each call site's scope. The http://supervisor URL is plain HTTP and TLS-irrelevant in practice — the parameter keeps all three constructor sites consistent with the established HomeAssistantClient pattern.
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 standardizes the SSL verification configuration for Supervisor-related HTTP requests. By ensuring that all 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 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 counter productive. 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
|
Implementation SummaryChoices Made:
Problems Encountered:
Suggested Improvements (Optional Follow-ups):
|
There was a problem hiding this comment.
Code Review
This pull request introduces SSL verification for internal HTTP requests by updating httpx.AsyncClient calls in settings_ui.py and tools_bug_report.py. In tools_bug_report.py, the global configuration is now used to determine the SSL verification status. The review feedback suggests a more efficient way to access the SSL setting in settings_ui.py by using server.settings.verify_ssl directly, which avoids the unnecessary lazy instantiation of the HomeAssistantClient and its associated side effects.
Per Gemini review on PR homeassistant-ai#1128: server.client is a lazy @Property (server.py) — accessing it for a single config bool would instantiate the full HomeAssistantClient (httpx pool, settings re-read, log line) on first access. server.settings is eager-initialized in the HomeAssistantSmartMCPServer constructor and is the canonical source of truth for verify_ssl. Additional benefit: in OAuth deployment mode (__main__.py:868), HomeAssistantSmartMCPServer is constructed with an OAuthProxyClient whose __getattr__ proxies to a per-request OAuth client requiring an authenticated request context. _restart_addon is a plain admin POST without that context, so server.client.verify_ssl could have surfaced as an auth error in OAuth mode. server.settings.verify_ssl sidesteps it without depending on OAuthProxyClient's attribute-forwarding semantics.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request updates the httpx.AsyncClient instances in settings_ui.py and tools_bug_report.py to respect the SSL verification configuration. A suggestion was made to use server.client.verify_ssl instead of server.settings.verify_ssl in settings_ui.py to ensure consistency with other call sites and align with the PR's stated objectives.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request updates the internal HTTP clients used for supervisor interactions to respect the global SSL verification settings. Specifically, the verify parameter in httpx.AsyncClient is now explicitly set using server.settings.verify_ssl in the settings UI and get_global_settings().verify_ssl in the bug report tool. These changes ensure consistent SSL behavior across the application when restarting the add-on or fetching logs. I have no feedback to provide.
Adds unit-test coverage for the two previously-untested branches in settings_ui.py:_restart_addon: - Missing SUPERVISOR_TOKEN (settings_ui.py:780-789) — non-addon installs hit this when the user clicks Restart against a Docker/pyinstaller setup; the structured 400 must surface rather than ever reaching the Supervisor URL. - Connection-drop-as-success (settings_ui.py:798-801) — the Supervisor kills our process mid-request during a restart, so a ReadError / RemoteProtocolError / ConnectError from the POST is the documented success signal. Mirrors the _capture_handler pattern from TestSaveToolsValidation. The fixture-level server.settings.verify_ssl = True is required by this PR's post-G1 access path (httpx accepts only bool/SSLContext for verify=). Boy-Scout fix while already touching _restart_addon for the verify_ssl-propagation refactor — closes the test-coverage gap I'd flagged in homeassistant-ai#960's approve-body but never followed up on at the time.
|
Heads-up: pushed While touching
Both were flagged in #960's approve-body ("two short cases would close the loop; happy to follow up post-merge instead") but never followed up at the time. The fix-while-already-touching shape avoids a separate tracker issue — the Boy Scout Rule's "When to open an issue instead" carve-out ( PR body + IS comment updated to reflect the test additions. |
|
I haven't done formal review yet so I apologize if I'm overlooking something else here, but I see that this is based on some stuff you figured out with #1126 , and #1126 in its current state doesn't work, it needs some minor changes to work. See the comment and changes requested I placed on it. Once we get everything with #1126 addressed and have confirmed it is working, you should reevaluate to see if this PR and its related issue #1127 are still relevant. |
Critical (review items 1-4):
- Empty SUPERVISOR_TOKEN now fail-fast HomeAssistantAuthError with distinct
message ("absent at call time"), so detection/config mismatches don't
read as "token rejected" (item 1).
- 403 carved out as distinct branch with role-hint suggestion + warning log
before raise — most-likely cause for homeassistant-ai#1116-class failures is now hassio_role
too low (item 2).
- _get_supervisor_log docstring updated to describe the branch-on-
is_running_in_addon() behavior, drop homeassistant-ai#950-only framing (item 3).
- _get_addon_logs_via_supervisor docstring rewritten to enumerate
scope/role differences vs _fetch_addon_logs instead of claiming mirror (item 4).
Important (items 5-9):
- verify=self.verify_ssl kept with explicit symmetry comment citing homeassistant-ai#1128's
three-site convention (item 5, KP13's option B).
- Supervisor's {"result":"error","message":"..."} JSON envelope now parsed
before the raw-text fallback (item 6).
- Distinct timeout vs transport error messages (item 7).
- logger.warning fires before every 4xx raise so operators see status+path
without enabling debug (item 9).
Test gaps (items 10-15):
- New: test_raises_auth_error_on_empty_supervisor_token (item 10).
- New: test_raises_connection_error_on_remote_protocol_error (item 11).
- New: test_empty_body_no_reason_phrase_uses_placeholder for tier-3 fallback
parity with the proxy branch (item 12).
- ctor-kwargs (verify + timeout) asserted on the URL+auth happy path so a
regression that hard-codes either keeps CI red (item 13).
- TestGetAddonLogsBranchSelection::test_addon_install_uses_supervisor_direct
shrunk to gate-only — URL/auth contract delegated to dedicated class (item 14).
- patch path migrated from "ha_mcp.client.rest_client.httpx.AsyncClient" to
"httpx.AsyncClient" — robust to both \`import httpx\` and a future
\`from httpx import AsyncClient\` (item 15).
Comment trims (items 16-17):
- get_addon_logs docstring gate description corrected to is_running_in_addon()
rather than "SUPERVISOR_TOKEN env present" (item 16).
- Per-test/fixture/class-level redundant narration trimmed (item 17).
Decline:
- Item 8 (level applies to source="supervisor"): warning is already emitted
at tools_utility.py:139 — \`supervisor\` is in the level-not-applicable
warning tuple, pinned by test_level_param_emits_warning_for_supervisor_source.
This PR adds \`system_service\` to the same tuple plus a parallel test for
parity.
Scope additions per KP13's PR-comment 12:42:
- hassio_role: default → manager in both addon config.yamls, with comment
citing the live test result.
- New source="system_service" with slug enum {supervisor, host, core, dns,
audio, multicast, observer}. Hits http://supervisor/<service>/logs via the
same direct-Supervisor pattern (extracted to shared _supervisor_logs_get
helper). Caller-layer slug-enum validation gives users the allowed-set
before the request fires.
kingpanther13
left a comment
There was a problem hiding this comment.
Asks:
1. Narrow the connection-drop catch to (ReadError, RemoteProtocolError). settings_ui.py:822. ConnectError fires before a connection is established — DNS failure, TCP refused, supervisor socket misconfigured. None of those mean a restart was initiated; they mean Supervisor was unreachable. Currently the user clicks restart, sees "Restart initiated," and nothing happens. Let ConnectError fall through to the existing httpx.HTTPError handler (:826) which already returns 502 with CONNECTION_FAILED. Pre-existing, but the new test docstring codifies the broad catch as intentional — cleaner to close the loop here than a separate PR.
2. Parametrize the connection-drop test over (ReadError, RemoteProtocolError), and add a separate case asserting ConnectError returns 502. Locks the contract on both sides.
3. Pin the remaining two _restart_addon branches while you're already in TestRestartAddon. httpx.HTTPError → 502 (:826-834) and status_code >= 400 → 502 (:836+) are still uncovered. Same Boy-Scout pass.
4. Fix the line-number references in the new test docstrings. Class docstring + both method docstrings cite settings_ui.py:780-789 and :798-801, but in master _restart_addon starts at 803 — those ranges land inside _save_tools. Symbol-based references ("the if not token: guard", "the catch on (ReadError, RemoteProtocolError)") survive line shifts; the kwarg-split in this PR shifts them again.
5. Replace __import__("httpx").ReadError("kill") (line 380) with a top-level import httpx.
6. Trim "post-G1 state" from the verify_ssl = True comment. The rest (httpx rejects MagicMock for verify=) is the part that pays off in 6 months.
7. Move the #960 approve-body cross-reference out of the source docstring and into the PR body. Source-level pointers to closed-PR review history rot fast.
Otherwise: server.settings.verify_ssl over server.client.verify_ssl is the right call; pattern matches merged #1126.
Merge brings in homeassistant-ai#1126, homeassistant-ai#1135, homeassistant-ai#1136, homeassistant-ai#1138 and the dev-addon publish chain since the branch's previous head `147ad5f`. Conflict in `tests/src/unit/test_settings_ui.py` resolved by keeping both adjacent additions: master's `test_returns_500_when_save_fails` (read-only-fs 500-surfacing test from homeassistant-ai#1138) inside `TestSaveToolsValidation`, plus this PR's new `TestRestartAddon` class right after. KP13 round-1 review asks (CHANGES_REQUESTED 2026-05-06 20:38 UTC) all addressed: 1. **Narrow connection-drop catch** — the `except` tuple in `_restart_addon` (in `settings_ui.py`) is now `(httpx.ReadError, httpx.RemoteProtocolError)`. `httpx.ConnectError` is no longer treated as a successful restart; it falls through to the `httpx.HTTPError` handler returning 502 + `CONNECTION_FAILED`. Inline comment documents the deliberate exclusion (DNS / TCP-refused / supervisor-socket-misconfigured all mean Supervisor was unreachable, not that a restart was initiated). 2. **Parametrize connection-drop test** + separate `ConnectError` → 502 case. `test_treats_connection_drop_as_success` now parametrizes over `(httpx.ReadError, httpx.RemoteProtocolError)`. New `test_connect_error_returns_502` locks the contract that a connection-failure-before-handshake surfaces as 502. 3. **Boy-Scout: pin remaining `_restart_addon` branches.** Two new tests: `test_generic_http_error_returns_502` (uses `httpx.PoolTimeout` to exercise the `httpx.HTTPError` fall-through) and `test_supervisor_4xx_returns_502` (Supervisor returns 401 → handler maps to 502). 4. **Symbol-based test docstrings** — class-docstring + method docstrings now reference "the `if not token:` guard", "the catch on `(ReadError, RemoteProtocolError)`", "the `httpx.HTTPError` handler", "the `status_code >= 400` branch" instead of line numbers that shift with every kwarg-split / refactor. 5. **Top-level `import httpx`** in `tests/src/unit/test_settings_ui.py` replaces the inline `__import__("httpx").ReadError(...)` workaround. 6. **Trim "post-G1 state"** from the `verify_ssl = True` fixture comment. Kept the substantive part ("must resolve to a real bool, not a MagicMock, because httpx accepts only bool/SSLContext for `verify=`") that pays off in 6 months. 7. **Move homeassistant-ai#960 cross-reference** out of the `TestRestartAddon` class docstring. Closed-PR review history rots fast in source; the PR body is the right place for it. Local: 1762 unit tests pass, ruff lint + format clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Round-2 — addressed in
Local: 1762 unit tests pass at |
kingpanther13
left a comment
There was a problem hiding this comment.
All seven round-1 asks addressed cleanly. ConnectError narrowing is the substantive win — silent-success on Supervisor-unreachable would have been a real footgun. Boy-Scout pin now covers all five reachable error branches. LGTM.
🧪 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. |
…→ 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
What does this PR do?
Closes #1127. Mirrors the
verify=self.verify_sslpropagation pattern established in #1126 (rest_client.py:_get_addon_logs_via_supervisor) at the two other direct-Supervisorhttpx.AsyncClientcall sites in the codebase, so all three sites use averify=...verify_sslaccess path appropriate to their scope.src/ha_mcp/tools/tools_bug_report.py:_fetch_addon_logs→verify=get_global_settings().verify_ssl(module-level helper, noself/closure context — pulls from theSettingssingleton).src/ha_mcp/settings_ui.py:_restart_addon→verify=server.settings.verify_ssl(closure has access toserver: HomeAssistantSmartMCPServer; reads directly from the eager-initialized settings instance to avoid lazyHomeAssistantClientinstantiation — adopted from Gemini G1 review on this PR, see commit732a98a).The
http://supervisorURL is plain HTTP and TLS verification is semantically a no-op there — but the constructor shape is the kind of detail bot reviewers will keep flagging until all three sites match. After this PR, they do.Boy-Scout —
_restart_addontest coverage (Round-2 extended after KP13's CR)test_settings_ui.py::TestRestartAddonpins five previously-uncovered branches of_restart_addon:if not token:guard (noSUPERVISOR_TOKEN)test_returns_400_without_supervisor_tokenCONFIG_VALIDATION_FAILED(ReadError, RemoteProtocolError)(Supervisor kills mid-request)test_treats_connection_drop_as_success(parametrized)httpx.ConnectErrorfalls through tohttpx.HTTPError(Supervisor unreachable)test_connect_error_returns_502CONNECTION_FAILEDhttpx.HTTPErrorfall-through (e.g.PoolTimeout)test_generic_http_error_returns_502CONNECTION_FAILEDstatus_code >= 400)test_supervisor_4xx_returns_502The first two were flagged in #960's approve-body but never followed up at the time. The other three came from KP13's round-1 CR (
(ReadError, RemoteProtocolError)narrowing means the prior bare-Exception-equivalent intent had to be split across multiple test cases for accurate coverage).Test docstrings reference branches by symbol rather than line number — kwarg-splits and adjacent refactors keep shifting
_restart_addon's start line.Out of scope
A shared module-level helper that constructs the Supervisor
httpxclient once with the right defaults plus theAuthorization: Bearer ${SUPERVISOR_TOKEN}header (currently duplicated across all three call sites) — covered as the alternative in #1127's body. That's a refactor with new abstractions and design decisions and would benefit from its own dedicated discussion. Filed as #1130 for when there's appetite.Type of change
Testing
uv run pytest)uv run ruff check)Local: 1762 unit tests pass at
4b1e336, ruff lint + format clean.The
verify=kwarg itself is test-transparent — existing tests mockhttpx.AsyncClient.get/.post(the methods, not the constructor). The Boy-ScoutTestRestartAddonblock (5 branches above) is the additional coverage delta over master.Checklist