## Summary
Follow-up fixes after #4444 merged, addressing issues found during Mac
Catalyst testing:
- **Fix `›` character in Frequent Updates footer** — `.strings` files
don't interpret `\uXXXX` escapes at runtime; replaced with the literal
`›` character
- **Fix Mac Catalyst compilation** — `ActivityKit` APIs
(`ActivityAttributes`, `Activity`, `ActivityUIDismissalPolicy`, etc.)
are marked unavailable on Mac Catalyst even though
`canImport(ActivityKit)` returns true there. Replaced all `#if
canImport(ActivityKit)` and bare `#if os(iOS)` guards around ActivityKit
code with `#if os(iOS) && !targetEnvironment(macCatalyst)`. Files
affected:
- `HALiveActivityAttributes.swift`
- `LiveActivityRegistry.swift`
- `HandlerLiveActivity.swift`
- `LiveActivitySettingsView.swift`
- `HADynamicIslandView.swift`
- `HALockScreenView.swift`
- `HALiveActivityConfiguration.swift`
- `Widgets.swift` (three `HALiveActivityConfiguration()` call sites)
- `Environment.swift`, `AppDelegate.swift`, `HAAPI.swift`,
`NotificationsCommandManager.swift`, `SettingsItem.swift` (inline
guards)
## Test plan
- [x] iOS builds and runs
- [x] macOS (Mac Catalyst) builds and launches
- [ ] Live Activities settings entry does not appear on macOS (filtered
by `isTestFlight` + `#available(iOS 17.2, *)`)
- [ ] Live Activities work as expected on iOS TestFlight build
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
Remove the portWithFallback helper and update port comparisons to use
URL.port directly. baseIsEqual now compares ports via url.port (no
80/443 fallback), and SafeScriptMessageHandler passes url.port ?? 0 when
building origin keys (security origin uses port 0 when unspecified).
This simplifies port handling and avoids implicit defaulting to standard
ports.
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
## Summary
> For architecture decisions, data model details, iOS version strategy,
push token flow, and rate limiting — see
[technical-brief.pdf](https://github.com/user-attachments/files/26280274/technical-brief.pdf)
Adds iOS Live Activities support, letting Home Assistant automations
push real-time state to the Lock Screen — washing machine countdowns, EV
charging progress, delivery tracking, alarm states, or anything
time-sensitive that benefits from glanceable visibility without
unlocking the phone.
When an automation sends a notification with `live_update: true` in the
data payload, the companion app starts a Live Activity instead of (or in
addition to) a standard notification banner. Subsequent pushes with the
same `tag` update it in-place silently. `clear_notification` + `tag`
ends it.
Field names (`tag`, `title`, `message`, `progress`, `progress_max`,
`chronometer`, `when`, `when_relative`, `notification_icon`,
`notification_icon_color`) are intentionally shared with Android's Live
Notifications API. Both platforms use the same `live_update: true`
trigger — a single YAML block targets iOS 17.2+ and Android 16+ with no
platform-specific keys.
```yaml
data:
title: "Washing Machine"
message: "Cycle in progress"
data:
tag: washer_cycle
live_update: true # Android 16+ and iOS 17.2+
progress: 2700
progress_max: 3600
chronometer: true
when: 2700
when_relative: true
notification_icon: mdi:washing-machine
notification_icon_color: "#2196F3"
```
**New files:**
- `Sources/Shared/LiveActivity/HALiveActivityAttributes.swift` — the
`ActivityAttributes` type. Field names match the Android payload spec.
**Struct name and `CodingKeys` are wire-format frozen** — APNs
push-to-start payloads reference the Swift type name directly.
- `Sources/Shared/LiveActivity/LiveActivityRegistry.swift` — Swift
`actor` managing `Activity<HALiveActivityAttributes>` lifecycle. Uses a
reservation pattern to prevent duplicate activities when two pushes with
the same `tag` arrive simultaneously.
-
`Sources/Shared/Notifications/NotificationCommands/HandlerLiveActivity.swift`
— start/update and end `NotificationCommandHandler` implementations,
guarded against the `PushProvider` extension process where ActivityKit
is unavailable.
- `Sources/Extensions/Widgets/LiveActivity/` — `ActivityConfiguration`
wrapper, Lock Screen / StandBy view, and compact / minimal / expanded
Dynamic Island views.
- `Sources/App/Settings/LiveActivity/LiveActivitySettingsView.swift` —
activity status, active list, privacy disclosure, and 11 debug scenarios
for pre-server-side testing.
**Modified files:**
- `Widgets.swift` — registers `HALiveActivityConfiguration` in all three
`WidgetBundle` variants behind `#available(iOSApplicationExtension 17.2,
*)`
- `NotificationsCommandManager.swift` — registers new handlers;
`HandlerClearNotification` now also ends a matching Live Activity when
`tag` is present
- `HAAPI.swift` — adds `supports_live_activities`,
`supports_live_activities_frequent_updates`,
`live_activity_push_to_start_token`,
`live_activity_push_to_start_apns_environment` to registration payload
under a single `#available(iOS 17.2, *)` check
- `AppDelegate.swift` — reattaches surviving activities at launch and
starts observing push-to-start tokens under a single `#available(iOS
17.2, *)` check
- `Info.plist` — `NSSupportsLiveActivities` +
`NSSupportsLiveActivitiesFrequentUpdates`
- `SettingsItem.swift` / `SettingsView.swift` — Live Activities settings
row is gated behind `Current.isTestFlight` and shows a `BetaLabel` badge
**Tests:**
- *Unit Tests*
- 45 new tests (36 handler tests, 9 command manager routing tests). All
490 existing tests continue to pass.
- *Device Tests*
- I tried to test with my physical device, however I do not have a paid
account. Turns out I could not deploy without disabling a lot of
entitlements for compilation. Even so, once I did get it deployed and
running Live Activities wouldn't show unless some of those settings that
I disable were re-enable and leaving me in a particular spot.
- I mainly tested with the simulator which is what is shown below
## Screenshots

## Link to pull request in Documentation repository
Documentation: home-assistant/companion.home-assistant#1303
## Link to pull request in push relay repository
Relay server: home-assistant/mobile-apps-fcm-push#278
## Link to pull request in HA core
Core: home-assistant/core#166072
## Any other notes
**iOS version gating at 17.2.** The entire feature is gated at
`#available(iOS 17.2, *)` — this is the minimum for push-to-start (the
primary server-side start mechanism). A single availability check now
covers all Live Activity APIs: `supports_live_activities`,
`frequentPushesEnabled`, push-to-start token, and all ActivityKit usage.
This eliminates the nested 16.2/17.2 check pattern.
**Push-to-start (iOS 17.2+) is client-complete.** The token is observed,
stored in Keychain, and included in registration payloads. All companion
server-side PRs are now open — relay server at
home-assistant/mobile-apps-fcm-push#278 and HA core webhook handlers at
home-assistant/core#166072. The relay server uses FCM's native
`apns.liveActivityToken` support (Firebase Admin SDK v13.5.0+) — no
custom APNs client or credentials needed.
> **Server-side work** — all PRs now open:
> - ~~`supports_live_activities` field handling in device registration~~
✓ home-assistant/core#166072
> - ~~`mobile_app_live_activity_token` webhook handler~~ ✓
home-assistant/core#166072
> - ~~`mobile_app_live_activity_dismissed` webhook handler~~ ✓
home-assistant/core#166072
> - ~~Relay server: Live Activity delivery via FCM
`apns.liveActivityToken`~~ ✓ home-assistant/mobile-apps-fcm-push#278
> - ~~`notify.py` routing: includes Live Activity APNs token alongside
FCM token~~ ✓ home-assistant/core#166072
**Live Activities entry in Settings is gated behind TestFlight.** The
settings row only appears when `Current.isTestFlight` is true,
preventing it from surfacing in a release build before the feature is
fully tested. A `BetaLabel` badge is shown alongside the row title.
**iPad:** `areActivitiesEnabled` is always `false` on iPad — Apple
system restriction. The Settings screen shows "Not available on iPad."
The registry silently no-ops. HA receives `supports_live_activities:
false` in the device registration for iPad.
**`HALiveActivityAttributes` is frozen post-ship.** The struct name
appears as `attributes-type` in APNs push-to-start payloads. Renaming it
silently breaks all remote starts. The `ContentState` `CodingKeys` are
equally frozen — only additions are safe. Both have comments in the
source calling this out.
**The debug section in Settings is intentional.** Gated behind `#if
DEBUG` so it only appears in debug builds — it never ships to TestFlight
or the App Store. It exercises the full ActivityKit lifecycle without
requiring the server-side chain.
**`UNUserNotificationCenter` in tests.** The `clear_notification` +
`tag` → Live Activity dismissal path is covered by code review rather
than a unit test. `HandlerClearNotification` calls
`UNUserNotificationCenter.current().removeDeliveredNotifications`
synchronously, which requires a real app bundle and throws
`NSInternalInconsistencyException` in the XCTest host. A comment in the
test file explains this.
**Rate limiting on iOS 18.** Apple throttles Live Activity updates to
~15 seconds between renders. Automations should trigger on state change
events, not polling timers.
**Related:**
- Community discussion:
https://github.com/orgs/home-assistant/discussions/84
- Android companion reference: https://github.com/home-assistant/android
- Roadmap: https://github.com/home-assistant/roadmap/issues/52
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Bruno Pantaleão Gonçalves <5808343+bgoncal@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
<img width="800" height="480" alt="Simulator Screenshot - Daily tester 2
- 2026-03-31 at 16 45 28"
src="https://github.com/user-attachments/assets/927764c8-9de7-49e9-98c4-8cc8fd0bcf6b"
/>
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
<img width="2030" height="494" alt="CleanShot 2026-03-31 at 10 36 48@2x"
src="https://github.com/user-attachments/assets/539853f4-f8dc-46d6-a167-25af8ca0b399"
/>
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
## Summary
Rebrand the `BetaLabel` component: replace "BETA" text with "Labs" and
add a leading MaterialDesignIcons test-tube icon.
- Replace `"BETA"` → `"Labs"` in both the capsule label and the info
sheet navigation title
- Add `MaterialDesignIcons.testTubeIcon` (15×15, white) as a leading
element in the HStack, consistent with how `ExternalLinkButton` and
`SettingsButton` use MDI icons
## Screenshots
## Link to pull request in Documentation repository
Documentation: home-assistant/companion.home-assistant#
## Any other notes
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
## Summary
Remove 3 unused localization strings flagged by the unused strings check
in #4451:
- `kiosk.auth.try_again`
- `kiosk.exit_button`
- `kiosk.exit_hint`
Removed from all 34 `Localizable.strings` language files and the
SwiftGen-generated `Strings.swift`.
## Screenshots
N/A — no UI changes; these strings had no references in the codebase.
## Link to pull request in Documentation repository
N/A
## Any other notes
Pure deletions only (108 lines removed across 35 files). Verified zero
references to these strings exist in Swift source.
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
## Summary
Reopening kiosk mode PR (previously #4218) after addressing all review
feedback from @bgoncal. Apologies for the delay — some family matters
pulled me away, but I'm excited to get this implemented and am fully
committed to seeing it through.
This PR adds the foundational infrastructure for **kiosk mode** — a
feature designed for wall-mounted iPad displays running Home Assistant
dashboards.
### What's included:
- **KioskModeManager** — Central coordinator singleton with
KioskModeObserver protocol (no NotificationCenter)
- **KioskSettings** — Comprehensive settings model with GRDB persistence
(camelCase columns, Codable)
- **Screensaver system** — Clock screensaver with 4 styles, pixel shift
for OLED burn-in prevention
- **Secret exit gesture** — Configurable corner tap to access settings
when locked down
- **Status bar hiding** — StatusBarForwardingNavigationController for
proper UIKit integration
- **Settings UI** — SwiftUI settings accessible via Settings menu and
secret gesture
- **28 unit tests** — Covering settings serialization, time logic,
orientations, enums
### Changes since #4218 (all review feedback addressed):
- ✅ Fixed settings modal dismissal on iOS 15 (UINavigationController +
explicit onDismiss closure)
- ✅ Fixed status bar hiding (StatusBarForwardingNavigationController +
statusBarView integration)
- ✅ Removed non-functional settings (navigationLockdown,
TouchFeedbackManager, IconMapper)
- ✅ Replaced `Date()` with `Current.date()` for testability
- ✅ GRDB persistence follows CarPlayConfig/WatchConfig pattern with
DatabaseTableProtocol
- ✅ All strings localized via L10n (SwiftGen)
- ✅ SFSafeSymbols used throughout (no string-based systemName)
- ✅ KioskModeObserver protocol (no NotificationCenter)
- ✅ Kiosk files prefixed with `Kiosk`
- ✅ UIKit screensaver container (required for status bar/home indicator
control)
- ✅ macCatalyst filtered out
- ✅ Merged with latest upstream/main (adapted to Frontend/ directory
restructure)
- ✅ Idle timer pauses when settings view is open
- ✅ TODO comments (no PR-specific comments)
### Testing Instructions
1. **Settings → Companion App → Kiosk Mode** → Enable "Enable Kiosk
Mode"
2. Set screensaver timeout to **30 seconds** for quick testing
3. Wait for screensaver → tap to wake
4. Use secret gesture (default: 3 taps in top-left corner) to access
settings
### Previous review context
All feedback from @bgoncal in #4218 has been addressed. See that PR for
full discussion history.
## Test plan
- [ ] Enable/disable kiosk mode from Settings
- [ ] Screensaver activates after timeout
- [ ] Tap to wake from screensaver
- [ ] Secret gesture opens settings
- [ ] Status bar hides when kiosk mode active (full-screen iPad only)
- [ ] Device authentication toggle works
- [ ] Settings persist across app restart
- [ ] Clock screensaver styles (large, minimal, digital, analog)
- [ ] Pixel shift moves clock position periodically
- [ ] Kiosk entry hidden on macCatalyst
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Nick Stefanelli <nstefanelli@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
Introduce HAAppUsedContent to centralize the list of Home Assistant
domains and provide rawValues. Use HAAppUsedContent.rawValues in
AppEntitiesModel to filter entities (removing the local domains list).
Update EntityAddToHandler to only add CustomWidgetAction when the
entity's Domain can be constructed and is included in
HAAppUsedContent.domains. Change MagicItem's default interactionType
from a refresh app intent to a navigateIntent that opens the entity deep
link (AppConstants.openEntityDeeplinkURL). These changes restrict widget
availability to supported domains and make default item interactions
navigate directly to the entity.
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
<img width="603" height="1311" alt="Captura de Tela 2026-03-09 à(s) 15
16 13"
src="https://github.com/user-attachments/assets/17c166ec-815e-4311-acaa-127e431e655a"
/>
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
Attempt to copy the leaf certificate from the SecIdentity using
SecIdentityCopyCertificate and include it in the URLCredential
certificates array when successful. This ensures TLS client-auth sends a
non-empty certificate list; if copying fails we log a warning and fall
back to an identity-only credential.
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
## Summary
This PR aims to fix a couple of bugs I noticed while testing the new
watch folders feature in the latest Test Flight build:
1) Changing the folder name, icon, and icon after it was created did not
work.
2) When adding a folder, the folder name should be a placeholder, not a
pre-filled field.
3) When switching between a folder and the root view, the items should
not resize after rendering (see the last item here):
https://github.com/user-attachments/assets/262cb313-f307-455f-ba21-7a189a3f7589
Note: I could not reproduce the resizing bug in the simulator, and
haven't been able to get Xcode to let me build to my devices locally.
Would you be up for trying to reproduce it/verify my fix on your end?
## Link to pull request in Documentation repository
N/A
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
- HAProgressView had a glitch when positioned inside a NavigationView,
where it would animate incorrectly, this PR fixes it
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
This PR works in combination with
https://github.com/home-assistant/HAKit/pull/96 to provide the missing
certificate evaluation when executing commands through the rest API
while using mTLS
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
This PR adds experimental mTLS support, it does not work properly on
older iOS versions neither on Apple Watch yet. Mac Catalyst TBD how well
it works.
This PR modifies:
- WebView connection
- Alamofire token exchange
- Webhook
- Websocket (pending HAKit PR)
Pending implementation/check
- [ ] Apple Watch
- [ ] Background usage (widgets, shortcuts, notifications)
- [x] Mac Catalyst
- [ ] Background refresh
- [x] [HAKit
PR](https://github.com/home-assistant/HAKit/pull/92/changes#diff-1ccd1173574d21603ee9aab6340ee5c825e62b94f112362346a931b10463594b)
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
Happy path:
https://github.com/user-attachments/assets/8d41d871-8cb8-4498-8e09-24716fff6971
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
Prevent generic usage of "toggle" action when executing entity MagicItem
Fixes#4356
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
## Bug
When the **Location Sent** setting is set to **Zone Only**, automations
that trigger on entering a passive zone stop working while the same
automations work correctly with **Exact** location.
### Root cause
In zone-only mode, `SubmitLocation` derives the current zone by GPS
lookup via `RLMZone.zone(of:in:)` rather than using the zone associated
with the incoming region event (the event zone may be the one being
*exited*, so a fresh lookup is needed). That lookup filtered using
`trackablePredicate`:
```swift
.init(format: "TrackingEnabled == true && isPassive == false")
```
The `isPassive == false` condition meant that when the device was inside
a passive zone, the lookup returned `nil`, causing the payload to report
`not_home` to Home Assistant instead of the passive zone so no
automation triggered.
In **Exact** mode this doesn't occur because raw GPS coordinates are
sent and Home Assistant resolves the zone server-side, where passive
zones are handled correctly.
Note that passive zones *are* monitored for region enter/exit events by
the iOS app (`ZoneManager` filters only on `TrackingEnabled`, not
`isPassive`), so the region event does fire, the zone is simply lost
during the zone-only lookup step.
## Fix
Remove `isPassive == false` from the filter in `RLMZone.zone(of:in:)`,
replacing `trackablePredicate` with a `TrackingEnabled == true`-only
filter. This method performs a GPS-to-zone lookup and has no reason to
exclude passive zones.
`trackablePredicate` is left unchanged and continues to be used
correctly in `GeocoderSensor`.
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
## Summary
Widget todo items due within 1 hour displayed as "in 1 hour" due to
`RelativeDateTimeFormatter` rounding. Now shows minute precision ("in 15
minutes", "in 30 minutes") for better time awareness with full
localization support.
**Implementation:**
- Added `DateComponentsFormatter` for minute-level formatting
- Enhanced `dueDisplay` to detect `abs(timeInterval) < 3600`
- Checks `abs(timeInterval) < 60` directly for "Now" threshold before
calculating minutes
- Uses `ceil()` for future times and `floor()` for past times to avoid
rounding boundary issues
- Displays localized strings via `L10n.Widgets.TodoList.DueDate.now`,
`.inFormat()`, and `.agoFormat()`
- Preserves existing formatter for ≥1 hour durations
**Localization:**
- Added 3 new localization strings to all 34 locale files (English
placeholders for translation team)
- Updated `Strings.swift` with corresponding L10n accessor functions
- All time displays now properly localized via `L10n` infrastructure
**Code Quality:**
- Made `dueDisplay` internal (not private) for testability via
`@testable import`
- Restored family-based widget row spacing logic that was accidentally
removed
- Fixed accessibility issues by replacing `.hidden()` and `.overlay()`
patterns with proper conditional rendering
- Tests made locale-agnostic using helper methods that generate expected
strings with same formatter
**Testing:**
- Added `WidgetTodoListViewTests.swift` with comprehensive coverage for
all time ranges
- Tests validate behavior for items due in 15, 30, 45 minutes, 1 minute,
<1 minute, overdue items, and >1 hour items
- Tests use same `DateComponentsFormatter` and L10n functions as
implementation for locale independence
## Screenshots
N/A - Text-only change
## Link to pull request in Documentation repository
Documentation: home-assistant/companion.home-assistant#
## Any other notes
Uses `DateComponentsFormatter.allowedUnits = [.minute]` for proper
localization. English placeholder strings have been added to all 34
locale files for the translation team to localize. The implementation
ensures consistent formatting across all supported languages using the
iOS localization system.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
> The widget To-Do List shows items with due dates less than 1 hour as
"in 1 hour" where it should display the time in minutes (e.g., "in x
minutes"). The issue lies in the `dueDisplay` method in the
`WidgetTodoListView` struct (file path:
`Sources/Extensions/Widgets/TodoList/WidgetTodoListView.swift`).
Specifically, this function uses the `numericRelativeFormatter` but does
not account for cases where the remaining due time is less than 1 hour.
>
> The `numericRelativeFormatter` is currently used in the following
block:
> ```swift
> if item.hasDueTime {
> let text = Self.numericRelativeFormatter.localizedString(for: due,
relativeTo: now)
> return DueDisplay(text: capitalizeLeadingCharacter(in: text),
isPastDateOnly: false)
> }
> ```
> This produces a generic "in 1 hour" string for times under an hour. To
fix this, we need to enhance the logic to check if the remaining time is
less than 1 hour. If so, explicitly calculate and display the remaining
minutes using custom logic.
>
> ### Proposed Fix:
> 1. Modify the `dueDisplay` method to check if the due time difference
is less than 1 hour.
> 2. If the remaining time is below one hour, calculate the difference
in minutes and format it as "in x minutes."
> 3. Otherwise, use the `numericRelativeFormatter` as before.
>
> ### Resources for the Fix:
> - `DateComponentsFormatter` for better control over minute formatting.
> - Update the logic in the `dueDisplay` method to handle the special
case explicitly.
>
> ### Testing
> - Add unit tests or predefined timelines with entries for due dates at
15, 30, and 45 minutes to confirm the enhanced functionality is applied
correctly.
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
*This pull request was created from Copilot chat.*
>
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/home-assistant/iOS/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
<img width="2058" height="1342" alt="CleanShot 2026-02-16 at 10 48
03@2x"
src="https://github.com/user-attachments/assets/49cf17c8-219d-46f6-aa82-eed163f5d03b"
/>
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
Replace @Observable macro with ObservableObject pattern to fix crash
during app launch on iOS 15-16 devices.
Root cause:
- PassThroughWindow used @Observable macro (iOS 17+ API)
- Despite @available(iOS 18, *), Swift compiled metadata into binary
- During app launch, Realm's objc_copyClassList() triggered metadata
loading for all classes
- @Observable generated code referenced symbols unavailable on iOS 15/16
- Result: null pointer dereference crash at startup
The fix:
- Replace @Observable with ObservableObject + @Published properties
- These patterns work on iOS 13+, safe for iOS 15/16
- No behavioral changes, same observation mechanism
- Maintains @available(iOS 18, *) for class usage
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Refactored loader visibility logic by introducing a showLoader state in
CameraPlayerView and passing it to WebRTCVideoPlayerView. The loader is
now displayed at the top level, and its state is synchronized with the
WebRTC view model. Also updated a connection security tip string for
clarity.
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
<img width="1206" height="2622" alt="Simulator Screenshot - iPhone 17 -
2026-01-30 at 11 22 13"
src="https://github.com/user-attachments/assets/7035aa1f-f6ff-4edf-8be3-7ea6169730b5"
/>
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->
## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->
<img width="1658" height="1142" alt="CleanShot 2026-01-30 at 11 00
58@2x"
src="https://github.com/user-attachments/assets/a06062c9-f373-499e-b42a-1b07b244019c"
/>
## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#
## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->