Skip to content

Latest commit

 

History

History
52 lines (40 loc) · 7.22 KB

AGENTS.md

File metadata and controls

52 lines (40 loc) · 7.22 KB

AI Agent Instructions for Home Assistant iOS

This is the router for AI coding agents (LLMs) working on the Home Assistant for Apple Platforms codebase. Detailed guidance lives in modular skills under .agents/skills/. Load the skill that matches your task instead of reading everything up front.

Home Assistant for Apple Platforms is a native Swift companion app for Home Assistant home automation. The primary user interaction is through a WKWebView displaying the Home Assistant web frontend, with native features for notifications, sensors, location tracking, widgets, CarPlay, Apple Watch, and more.

  • Language: Swift 5.8+
  • Platforms: iOS, watchOS, macOS (Catalyst), CarPlay
  • Build System: Xcode 27.0+, Swift Package Manager
  • Project: Open HomeAssistant.xcodeproj directly (dependencies are managed via Swift Package Manager)

Non-Negotiable Conventions

These apply to every change, even if you don't load the matching skill:

  • One type per file: each struct/class/enum lives in its own file named after the type — never stack multiple top-level types (especially SwiftUI View structs) in one file. Small private helper types nested inside the type are the only exception. Every SwiftUI view ships with a #Preview. See ha-ios-ui for the full UI rules.
  • No navigation title under an Apple-like header: a screen whose List starts with AppleLikeListTopRowHeader already shows its title in that header, so it must not also set .navigationTitle. Two titles stack as the user scrolls.
  • SwiftUI confirmations stay on the trigger: apply .confirmationDialog directly to the Button that opens it, not to a parent List, Section, or container view. This keeps confirmation ownership local and avoids dialogs firing from unrelated controls.
  • TestFlight gating is Current.isTestFlight, and always paired with an ungating PR: Current.isTestFlight is the only supported way to limit a feature to beta builds — never add a bespoke flag, build setting, or #if for it. Every change that puts a feature behind that gate must be accompanied by a parallel draft PR that removes the gate, so shipping the feature to everyone is a one-click merge. See ha-ios-workflow-ci for the full procedure.
  • User-facing changes ship with a documentation draft PR: any change that adds a feature, changes how one behaves, or removes something the docs describe is accompanied by a draft PR in home-assistant/companion.home-assistant, linked from the app PR's Documentation: line. Beta-only features are marked <span class='beta'>BETA</span> there. Bug fixes that restore documented behavior and internal-only changes need no docs PR. See ha-ios-workflow-ci for when it is needed and how to prepare it.
  • Every sensor is opt-in, always listed, and asks for its own permission: nothing reports until the user switches it on, so never add a sensor to a default-on list and never make installing an update start reporting something new (SensorRegistry.legacyEraSensorIDs is frozen at the release that introduced the allowlist, which is what keeps a new sensor out of the upgrade path; a new ID belongs in WebhookSensorId alone). A SensorProvider must still list its sensor when it cannot read one, reporting the state as unavailable rather than erroring out, because an errored provider drops out of the sensors list and takes the row that switches it on with it. Where a sensor needs an iOS permission, map its ID in SensorPermission.required(forSensorUniqueID:) so switching it on is what prompts for that permission. Only a device that can never produce the sensor is an error. Classify every new sensor in SensorEntityCategory.category(forSensorUniqueID:) — its switch is exhaustive, so adding a WebhookSensorId case without deciding won't compile — and never set entityCategory where the sensor is built. Enablement is per server — Current.sensors.isEnabled(uniqueID:for:) for what a given server receives, isEnabledForAnyServer(uniqueID:) for device-level work that happens once however many servers the values reach — and a server the user adds starts with nothing enabled, so never seed a new server from another one's selection.

Skills

Skill Load it when you are…
ha-ios-architecture Starting in the repo, deciding where code lives across targets, using the global Current (World pattern), or setting up dependencies and code signing
ha-ios-webview Working on WebViewController, the JavaScript external message bus, custom URL schemes, or deep links into the frontend
ha-ios-magicitem Adding or changing MagicItem types or actions shared by Widgets, Watch, CarPlay, and App Shortcuts
ha-ios-localization Adding or changing user-facing strings, using L10n, or dealing with Lokalise translations
ha-ios-code-style Writing or formatting Swift, running SwiftFormat/SwiftLint, referencing SF Symbols or Material Design icons, logging, or using with()
ha-ios-concurrency Writing async/await, actors, or Combine, deciding whether to touch PromiseKit, or calling the server via HAKit
ha-ios-persistence Adding or migrating a persistent model, or choosing between GRDB, Realm, and UserDefaults
ha-ios-push-live-activities Implementing or fixing push notifications or Live Activities across the local-push and remote-push flows
ha-ios-ui Building UI, choosing SwiftUI vs UIKit, or following the one-struct-per-file, inline-body, and #Preview rules
ha-ios-testing Writing unit or snapshot tests, or mocking dependencies by overriding Current
ha-ios-workflow-ci Preparing a change for commit or a PR, gating a feature behind TestFlight, opening the matching documentation draft PR, or understanding the CI gates that must pass before merge
ha-ios-skill-maintenance Adding, editing, or reorganizing these skills, or updating this router

Additional Resources

AI policy

This project follows the Open Home Foundation AI Policy. Autonomous contributions are not accepted: a human must review, understand, and be able to explain every change before it is submitted. Do not open issues or pull requests autonomously, and do not post comments on behalf of a user without their review.