plugins/home-assistant-dev/skills/ha-options-flow/SKILL.md
Home Assistant options flow for post-setup user preferences. Use when adding or fixing an options flow, allowing users to change integration settings after initial setup, or implementing reauth when credentials expire.
npx skillsauth add l3digitalnet/claude-code-plugins ha-options-flowInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Options flow lets users adjust integration settings after initial setup (scan interval, feature toggles, etc.).
from homeassistant.config_entries import ConfigEntry, ConfigFlowResult, OptionsFlow
import voluptuous as vol
class {Name}OptionsFlow(OptionsFlow):
"""Handle options."""
# NOTE: Do NOT use __init__ to store config_entry - deprecated since 2025.12
# Access via self.config_entry (automatically set by HA)
async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
if user_input is not None:
return self.async_create_entry(title="", data=user_input)
return self.async_show_form(
step_id="init",
data_schema=vol.Schema({
vol.Optional(
"scan_interval",
default=self.config_entry.options.get("scan_interval", 30),
): vol.All(vol.Coerce(int), vol.Range(min=10, max=300)),
}),
)
Wire it to the config flow class with async_get_options_flow:
from homeassistant.core import callback
class {Name}ConfigFlow(ConfigFlow, domain=DOMAIN):
...
@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
return {Name}OptionsFlow()
{
"options": {
"step": {
"init": {
"title": "Settings",
"data": {
"scan_interval": "Update interval (seconds)"
},
"data_description": {
"scan_interval": "How often to poll the device (10-300 seconds)"
}
}
}
}
}
Reauth handles expired credentials without removing the integration. Add to the ConfigFlow class (not OptionsFlow):
async def async_step_reauth(
self, entry_data: dict[str, Any]
) -> ConfigFlowResult:
"""Handle reauth when credentials expire."""
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Collect new credentials for reauth."""
errors: dict[str, str] = {}
if user_input is not None:
reauth_entry = self._get_reauth_entry()
data = {**reauth_entry.data, **user_input}
try:
await self._async_validate_input(data)
except CannotConnect:
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
else:
return self.async_update_reload_and_abort(reauth_entry, data=data)
return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema({
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}),
errors=errors,
)
Trigger reauth from the coordinator when an API call fails with 401:
raise ConfigEntryAuthFailed("Credentials expired")
entry.data — Connection info (host, credentials). Set once at setup.entry.options — User preferences (scan interval, feature flags). Changed via options flow.Never store user preferences in entry.data — they belong in entry.options so the options flow can update them without requiring re-setup.
development
Use when you're stuck or missing current information mid-task - the same command/API/approach failed twice, an error looks like a changed or deprecated API, or you need the current version of something, a fact from after your training cutoff, or to verify something you cannot confirm from the code in context. Starts with a cheap inline lookup and only escalates to a full research sweep if that fails. Do not use for routine pre-emptive checks before ordinary library work - for deliberate research, use /qdev:research.
documentation
Update Outline wiki documentation with implementation-level details from the current session by dispatching the up-docs-propagate-wiki sub-agent. This skill should be used when the user runs /up-docs:wiki.
documentation
Update repository documentation (README.md, docs/, CLAUDE.md) based on session changes by dispatching the up-docs-propagate-repo sub-agent. This skill should be used when the user runs /up-docs:repo.
documentation
Update Notion pages with strategic and organizational context from the current session by dispatching the up-docs-propagate-notion sub-agent. This skill should be used when the user runs /up-docs:notion.