diff --git a/.claude/skills/plugin-development/SKILL.md b/.claude/skills/plugin-development/SKILL.md index 834e69d5a..a70cce240 100644 --- a/.claude/skills/plugin-development/SKILL.md +++ b/.claude/skills/plugin-development/SKILL.md @@ -61,6 +61,12 @@ Every mapped field (`objectPrimaryId`/`objectSecondaryId`/`watchedValue1-4`/`ext | `on_new_device` | When new device detected | | `on_notification` | When notification triggered | +## `all_plugins` Lifecycle - Cache Hot-Path Derivations by Identity + +`all_plugins` (every plugin's parsed `config.json`) is loaded once, in `initialise.py`'s `get_plugins_configs()` call, and reused as the same list object everywhere after that until an actual config reload replaces it. `update_api()` (`server/api.py`), which receives `all_plugins` as a parameter, runs far more often than that - on every scan cycle and every plugin completion (`server/__main__.py`, `server/plugin.py`), not just on reload. + +Any function deriving something from `all_plugins` that gets called from a hot path like `update_api()` should cache its result keyed by `id(all_plugins)`, not recompute on every call - the input is almost always the same object even though the call site fires constantly. `server/db/plugin_field_views.py`'s `get_all_device_field_views()` is the pattern: check `id(all_plugins)` against the last-seen id, recomputing only when a genuinely new object (an actual reload) appears. + ## Plugin Formats | Format | Purpose | Phase | diff --git a/.claude/skills/ux-design-patterns/SKILL.md b/.claude/skills/ux-design-patterns/SKILL.md index 355691b62..1f8fa55a4 100644 --- a/.claude/skills/ux-design-patterns/SKILL.md +++ b/.claude/skills/ux-design-patterns/SKILL.md @@ -11,6 +11,30 @@ Don't introduce new UX behavior or visual patterns unless a PRD explicitly calls Real, recent example: a presence-page Prev/Next pager was first built with custom `