Commit Graph
237 Commits
Author SHA1 Message Date
overseer d15a02fb48 Apply PR #144 review round 3: lifecycle tests for malformed-option fallback, comment/test hygiene
Add LIFECYCLE tests that wire an entry via make_entry(options=...) and
call async_setup_entry, covering the from_options_resilient fallback
production actually uses (P2): a fully malformed options dict
(horizon_days=True, day_rollover_time='99:99',
morning_summary_time='25:00') succeeds with the day-rollover listener
at the default 00:00 and the backfill over DEFAULT_HORIZON_DAYS; and a
bad sibling (horizon_days=5, morning_summary_time='25:00') keeps
horizon_days == 5. Swapping from_options_resilient for from_options in
setup now fails these tests.

Reword comments/tests describing review history rather than the code:
__init__.py setup comment, test_core_settings P2-3/P2-1/P2-5 markers,
the moved from_options horizon test, and the AST scanner docstrings.

Test hygiene: move freeze_nestquest_clock into tests/conftest.py and
use it from test_core_settings and test_timezones; simplify CORE_PKG to
a plain import plus Path(mod.__file__).parent; move
test_from_options_horizon_validates_and_defaults into test_core_settings.

1575 passed.
2026-09-21 15:51:47 -04:00
overseer d75ddc19bd Apply PR #144 review round 2: settings-based service kwargs, required settings, shim removal, hardened AST scan
P2: services._generation_kwargs now reads runtime.settings.horizon_days
instead of re-implementing the bool/non-int/<1 fallback against
runtime.options; drop the now-unused CONF_HORIZON_DAYS/DEFAULT_HORIZON_DAYS
imports. Remove NestQuestRuntimeData.options (kept only for that read; the
admin-id path reads entry.options directly) and the matching test assertion.

P3: _run_horizon_materialization's settings param is now REQUIRED (drop the
'| None = None' default + the NestQuestSettings() substitution branch);
update the test_timezones callers to pass NestQuestSettings() explicitly.

P3: __post_init__ normalises notify_target via _resolve_optional_str (strip)
so a hand-built NestQuestSettings(notify_target=' x ') behaves like the
options flow; keep the docstring accurate.

P3: delete the custom_components/nestquest/settings.py shim (settings is a
new module with no legacy import path) and import NestQuestSettings from
.core.settings directly in __init__.py, in alphabetical position.

P3: harden the AST scan for importlib.import_module('homeassistant...')
(string-based import) and call keyword names like hass= (ast.keyword);
add negative-control cases for each; explain in the failure message why
.config/.options/.data are banned (HA config-entry attributes with no
legitimate core use).

P3: drive from_options and from_options_resilient from one _FIELDS table of
(field, key, default, validator) to avoid three-way drift.

uv run pytest -q: 1573 passed.
2026-09-21 15:42:26 -04:00
overseer 33102f8806 Apply PR #144 review fixes: per-field settings fallback, strict validation, hardened AST scan (task 4dd8f870)
P2-1: replace the all-or-nothing from_options try/except in setup with
from_options_resilient, which falls back PER FIELD (logging a warning
naming the bad field) so a malformed sibling (e.g. morning_summary_time
'25:00') cannot silently reset horizon_days/day_rollover_time.
P2-2: drop _run_horizon_materialization's legacy horizon_days keyword and
branch; default settings to NestQuestSettings(); remove the legacy paragraph.
P2-3: _run_horizon_materialization now calls settings.horizon_window(today)
so the helper is real and shared; extend tests to run the integration path
(_run_horizon_materialization + _register_day_rollover_listener) with
horizon_days=3 / day_rollover_time='03:30'.
P2-4: harden the AST scan to forbid hass/config_entry names, .hass/.entry/
.config_entry and .config/.options/.data attributes, and getattr/hasattr
calls with those string args; add a negative-control test for each shape.
P2-5: __post_init__ is strict (rejects None for every field); the
None->default mapping lives ONLY in from_options via _option_value.
P3: remove dead shims (_day_rollover_hour_minute, _configured_horizon_days)
and repoint test_lifecycle at from_options; de-dup the two HH:MM
validators into one using a shared TIME_PATTERN in core/const; make
horizon_window's today required; reword the notify_target docstring to
not claim options-flow parity; document _option_value's None-as-absent
semantics; remove unused test helpers.
2026-09-21 15:37:12 -04:00
overseer 345bd200e1 Replace HA config reads with an explicit settings object (task 4dd8f870)
Add core/settings.py: a frozen, HA-free NestQuestSettings dataclass
carrying horizon_days, day_rollover_time, notify_target, the three
notification times, and the four enable toggles. from_options() reads
the CONF_* keys with the matching defaults and validates (horizon int
>= 1, strict HH:MM times, real booleans); horizon_window(today) returns
the rolling [today, today+horizon_days] window.

The integration builds the settings object once from entry.options and
threads it into the horizon materialization and daily-rollover listener;
core never reads HA config itself. A settings.py shim re-exports
core.settings so the integration keeps its shim-only import convention.

Tests: an AST scan asserts no core module imports homeassistant or
accesses hass.config / entry.options / entry.data; a from_options test
covers defaults-when-absent and rejection of invalid horizon/rollover;
a materialization test drives a non-default horizon (3 days, 03:30
rollover) and asserts the resulting instance window matches.
2026-09-21 15:19:09 -04:00
dev_agent 315010b901 Extract the engines and business layer into core/ (task 510c1f78)
Extract the engines and business layer into core/ (task 510c1f78)
2026-09-21 15:07:50 -04:00
dev_agent 1503774e85 Extract the storage layer into core/ (bundled in the integration)
Extract the storage layer into core/ (bundled in the integration)
2026-09-21 14:48:01 -04:00
orchestrator-agent 87757aaaf9 Reconcile dev from main
Reconcile dev from main (hotfixes and release commits)
2026-09-21 13:54:50 -04:00
overseer 3ee4c99e5f Merge pull request 'Dev - add in logos' (#139) from dev into main
Reviewed-on: #139
2026-09-21 10:44:43 -04:00
overseer d4ea552ad7 Merge pull request 'Upload files to "design/logos"' (#138) from design/adding-logos into dev
Reviewed-on: #138
2026-09-21 10:44:12 -04:00
overseer 4e52e8dec8 Upload files to "design/logos" 2026-09-21 10:44:01 -04:00
overseer ee1fae984a Merge pull request 'Fix SensorDeviceClass.PERCENTAGE removed in HA 2025+' (#137) from fix/sensor-device-class-percentage into main
Reviewed-on: #137
2026-09-21 10:02:34 -04:00
overseer 418fc69f36 Remove removed SensorDeviceClass.PERCENTAGE 2026-09-21 10:02:08 -04:00
overseer b6b1ba65b4 Merge pull request 'Point HACS URLs at Maniacs-Mansion/NestQuest' (#136) from fix/hacs-repo-urls into main
Reviewed-on: #136
2026-09-21 07:52:09 -04:00
overseer 37f7d25cd6 Point HACS URLs at Maniacs-Mansion/NestQuest 2026-09-21 07:47:52 -04:00
overseer fe71d37bb0 Merge pull request 'Promote Feature 12 to main' (#135) from dev into main
Reviewed-on: #135
2026-09-21 06:57:15 -04:00
orchestrator-agent 1c08c793e3 Feature 12: Kid panel Lovelace cards
Feature 12: Kid panel Lovelace cards

Squash-merged PRs #125-#133. All Codex-reviewed. pytest 1496 passed.
2026-09-21 06:48:53 -04:00
dev_agent 7386999cf7 TouchHub setup runbook
TouchHub setup runbook
2026-09-20 20:20:52 -04:00
dev_agent 43ad44ee48 Panel card tests including the no-admin-controls assertion
Panel card tests including the no-admin-controls assertion
2026-09-20 19:41:57 -04:00
dev_agent 4cb07fbca4 Record 1920x1080 panel layout and TouchHub dock behaviour
Record 1920x1080 panel layout and TouchHub dock behaviour
2026-09-20 19:29:00 -04:00
dev_agent 030ba83b14 Subscribe panel cards to live NestQuest events (#130) 2026-09-20 19:17:52 -04:00
dev_agent a2c027deca Add the quest complete screen (1c)
Add the quest complete screen (1c)
2026-09-20 18:39:11 -04:00
dev_agent 2b45ebf035 Wire complete_quest with optimistic seal and parchment toast
Wire complete_quest with optimistic seal and parchment toast
2026-09-20 14:19:39 -04:00
dev_agent 028215fa38 Define and implement the panel's empty and error states
Define and implement the panel's empty and error states
2026-09-20 14:04:58 -04:00
dev_agent 0d2e0d6f26 Add the quest log card (1b) read-only
Add the quest log card (1b) read-only
2026-09-20 13:54:14 -04:00
dev_agent 1911b2bf6e Add the party board card (1a) read-only
Add the party board card (1a) read-only
2026-09-20 12:39:47 -04:00
grok 89f517b3ad Add bundled fonts, token CSS, and local font-face loading
Add bundled fonts, token CSS, and local font-face loading

Co-authored-by: grok <24+grok@code.cubecraftcreations.com>
Co-committed-by: grok <24+grok@code.cubecraftcreations.com>
2026-09-20 11:16:17 -04:00
overseer edca25affa Add the Lit card toolchain and auto-register the Lovelace bundle 2026-09-20 10:08:38 -04:00
orchestrator-agent 7c62c50526 Feature 11: Progress Automations and Notifications 2026-09-19 14:54:08 -04:00
orchestrator-agent ca93176768 Read the celebration payload from trigger.event.data
HA event triggers expose the payload as trigger.event.data, not
trigger.payload; fix the blueprint, its tests, and the README
examples, with a regression guard.
2026-09-19 14:54:03 -04:00
orchestrator-agent e508c80465 Document the automation package and test event validity 2026-09-19 14:52:26 -04:00
orchestrator-agent 3a2e6faa69 Document the automation package and test event validity
README gains the blueprint section: all four blueprints, their
inputs, the wiring table to the options-flow notification settings,
the celebration helper setup, event/sensor payload reference, and a
copy-pasteable example package. Tests assert every event trigger
references a real NestQuest event and no reminder is produced for an
absent child.
2026-09-19 14:52:12 -04:00
orchestrator-agent 5092369d49 Add the day-complete celebration blueprint 2026-09-19 14:51:01 -04:00
orchestrator-agent f6166f25d9 Compare celebration stamps as whole entries; queue events
Child ids sharing a prefix no longer suppress each other (split and
compare entries for equality), and queued mode keeps a second child's
day-complete event from being dropped while the first notify runs.
2026-09-19 14:50:59 -04:00
orchestrator-agent bf84793a1c Add the day-complete celebration blueprint
Triggers on nestquest_child_day_complete (never a zero-quest day),
notifies with the payload's child name, and dedupes per child per
day via an input_text helper holding <child_id>:<today> entries
pruned to today — a re-cleared day does not re-fire, but a second
child clearing the same day still celebrates.
2026-09-19 14:47:52 -04:00
orchestrator-agent 9d3cb30617 Add the end-of-day parent report blueprint 2026-09-19 14:47:38 -04:00
orchestrator-agent b913772007 Report when remaining counts are unavailable, not all-clear
A missing or non-numeric remaining sensor reads as -1 in the
all-clear guard, so a degraded day reaches the parent instead of
looking like a clear day.
2026-09-19 14:47:37 -04:00
orchestrator-agent d2f9c50930 Add the end-of-day parent report blueprint
Defaults to 20:00 local — deliberately before the midnight missed
sweep, reading the same day's data. Every present child gets a
completion line; owed lines name still-open quests; absent children
are omitted; nothing sends when all clear unless opted in.
2026-09-19 14:46:13 -04:00
orchestrator-agent 19a17b647d Add the afternoon open-quests reminder blueprint 2026-09-19 14:45:52 -04:00
orchestrator-agent 715aac994a Nest notify payload fields under the action's data key
The modern HA action schema passes title and message to the notify
service only under data; fix the morning summary and afternoon
reminder blueprints and the test accessors accordingly.
2026-09-19 14:45:50 -04:00
orchestrator-agent ad6f1768d7 Add the afternoon open-quests reminder blueprint
Lists only present children who still owe quests; sends nothing at
all when every present child is clear (a false template condition
stops the action). Blueprint test helpers move to a shared module.
2026-09-19 14:42:50 -04:00
orchestrator-agent fcc7a29f05 Add the morning summary blueprint 2026-09-19 14:31:02 -04:00
orchestrator-agent f31bda2714 Include collision-suffixed entity ids in the morning summary
Duplicate child names get HA registry suffixes (_2); the template now
iterates the due sensors (which carry present/child_id/child_name as
attributes) and pairs counts by child_id, so suffixed duplicates are
listed and the household rollup is excluded by the presence guard.
2026-09-19 14:31:00 -04:00
orchestrator-agent dc7a82f6e2 Add the morning summary blueprint
Iterates present children from the Feature 10 presence sensors, lists
what each owes today from the remaining sensor, omits absent children
entirely. Blueprint inputs (time, notify service, send toggle); the
notify target is the household's choice, never hard-coded. PyYAML and
Jinja2 join the dev-only dependencies for blueprint template tests.
2026-09-19 14:24:50 -04:00
orchestrator-agent 1d5143f850 Add the notification section to the options flow 2026-09-19 14:20:15 -04:00
orchestrator-agent fbde3eeaa1 Allow saving the empty default notify target
An empty target means notifications are not configured yet and is the
shipped default; only malformed strings (padded or whitespace-only)
reject.
2026-09-19 14:20:13 -04:00
orchestrator-agent 3c832c1cee Add the notification section to the options flow
Notify target (empty default, household fills their own service),
three strict HH:MM automation times (08:00/15:00/20:00 — the report
deliberately before the midnight sweep), and four independent enable
toggles, all leniently stored and round-tripped.
2026-09-19 14:18:18 -04:00
orchestrator-agent 8c421abeb2 Add the nightly missed-quest sweep 2026-09-19 14:16:51 -04:00
orchestrator-agent 8cd43141a9 Serialize the missed sweep's watermark claim
The whole watermark read-query-fire-write span runs under a
per-database sweep lock; a racing second sweep re-reads the watermark
inside the lock and announces nothing.
2026-09-19 14:16:50 -04:00
orchestrator-agent 3de9f4b970 Add the nightly missed-quest sweep
Fires one nestquest_quest_missed event per past-due open instance at
the configured rollover time and at startup, watermark-guarded in the
new nestquest_meta_state table (migration 7, strictly additive).
Read-only over the domain tables; never reports an instance that was
ever completed.
2026-09-19 14:15:21 -04:00
orchestrator-agent 25005cda77 Feature 10: Home Assistant Entity and Event Surface 2026-09-19 13:29:29 -04:00