From 2408309d84c404cf9e06ee5995416eab74c35b4d Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 23:56:15 +0000 Subject: [PATCH] docs: correct stale file:line references and the loader-fallback contradiction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLAUDE.md and .cursorrules disagreed about plugin-directory fallback behavior; the code (SchemaManager.get_schema_path) probes plugins/ BEFORE plugin-repos/, and the main discovery path has no fallback at all — both files now describe the real behavior, preferring symbol names over line numbers so the references rot slower. REST_API_REFERENCE.md pointed at app.py:144/:607 for mounts that live at :199/:799 and counted 92 routes where there are 94. PLUGIN_ARCHITECTURE_SPEC.md's historical banner gains a note that its example imports (src/plugin_system/base_classes/*_plugin.py) never shipped — the real base classes are src.base_classes.sports.SportsCore and src.base_classes.hockey.Hockey. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01SXb4mKcAkVaxkeTb3YnAdr --- .cursorrules | 10 +++++----- CLAUDE.md | 12 ++++++++---- docs/PLUGIN_ARCHITECTURE_SPEC.md | 5 ++++- docs/REST_API_REFERENCE.md | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/.cursorrules b/.cursorrules index 93b923fb..b89202dd 100644 --- a/.cursorrules +++ b/.cursorrules @@ -3,21 +3,21 @@ ## Plugin System Overview The LEDMatrix project uses a plugin-based architecture. All display -functionality (except core calendar) is implemented as plugins that are +functionality is implemented as plugins that are dynamically loaded from the directory configured by `plugin_system.plugins_directory` in `config.json` — the default is -`plugin-repos/` (per `config/config.template.json:130`). +`plugin-repos/` (per `config/config.template.json:167`). > **Fallback note (scoped):** `PluginManager.discover_plugins()` -> (`src/plugin_system/plugin_manager.py:154`) only scans the +> (`src/plugin_system/plugin_manager.py:208`) only scans the > configured directory — there is no fallback to `plugins/` in the > main discovery path. A fallback to `plugins/` does exist in two > narrower places: -> - `store_manager.py:1700-1718` — store operations (install/update/ +> - `store_manager.py:2342-2373` — store operations (install/update/ > uninstall) check `plugins/` if the plugin isn't found in the > configured directory, so plugin-store flows work even when your > dev symlinks live in `plugins/`. -> - `schema_manager.py:70-80` — `get_schema_path()` probes both +> - `schema_manager.py:48-80` — `get_schema_path()` probes both > `plugins/` and `plugin-repos/` for `config_schema.json` so the > web UI form generation finds the schema regardless of where the > plugin lives. diff --git a/CLAUDE.md b/CLAUDE.md index 496c4cce..01f4aa12 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,12 +6,16 @@ - `config/config.json` — User plugin configuration (persists across plugin reinstalls) - `plugin-repos/` — **Default** plugin install directory used by the Plugin Store, set by `plugin_system.plugins_directory` in - `config.json` (default per `config/config.template.json:130`). + `config.json` (default per `config/config.template.json:167`). Not gitignored. - `plugins/` — Legacy/dev plugin location. Gitignored (`plugins/*`). Used by `scripts/dev/dev_plugin_setup.sh` for symlinks. The plugin - loader falls back to it when something isn't found in `plugin-repos/` - (`src/plugin_system/schema_manager.py:77`). + loader does NOT fall back to it — `PluginManager.discover_plugins()` + (`src/plugin_system/plugin_manager.py`) scans only the configured + directory. Fallbacks exist in two narrower places: store operations + (`StoreManager._find_plugin_path()` in `store_manager.py`) and schema + lookup (`SchemaManager.get_schema_path()` in `schema_manager.py`, + which probes `plugins/` *before* `plugin-repos/`). ## Plugin System - Plugins inherit from `BasePlugin` in `src/plugin_system/base_plugin.py` @@ -33,7 +37,7 @@ ## Skin System (visual overlays for sports scoreboards) - Skins live in `skins//` (skin.json + skin.py), NOT in plugin dirs — plugin reinstall deletes plugin dirs -- Core: `src/skin_system/` (ScoreboardSkin, SkinContext, runtime); hook: `SportsCore._render_game()` in `src/base_classes/sports.py` +- Core: `src/skin_system/` (ScoreboardSkin, SkinContext, runtime); hook: `SportsCore._render_game()` in `src/base_classes/sports/core.py` - Skins render onto `ctx.canvas` only; fallback to built-in renderer on `False`/exception (3 strikes disables for session) - View-model guaranteed keys are frozen (see `test/test_skin_system.py::TestViewModelContract`) — renaming keys in `_extract_game_details_common` or sport extractors breaks published skins - Validate skins headlessly: `python scripts/validate_skin.py --skin `; docs: `docs/SKIN_SYSTEM.md`, `docs/CREATING_SKINS.md` diff --git a/docs/PLUGIN_ARCHITECTURE_SPEC.md b/docs/PLUGIN_ARCHITECTURE_SPEC.md index fbd45b34..00a2914d 100644 --- a/docs/PLUGIN_ARCHITECTURE_SPEC.md +++ b/docs/PLUGIN_ARCHITECTURE_SPEC.md @@ -8,9 +8,12 @@ > - Code paths reference `web_interface_v2.py`; the current web UI is > `web_interface/app.py` with v3 Blueprint-based templates. > - The example Flask routes use `/api/plugins/*`; the real API -> blueprint is mounted at `/api/v3` (`web_interface/app.py:144`). +> blueprint is mounted at `/api/v3` (`web_interface/app.py:199`). > - The default plugin location is `plugin-repos/` (configurable via > `plugin_system.plugins_directory`), not `./plugins/`. +> - Example imports use `src/plugin_system/base_classes/*_plugin.py`; +> the shipped base classes live in `src/base_classes/` (e.g. +> `src.base_classes.sports.SportsCore`, `src.base_classes.hockey.Hockey`). > - The "Migration Strategy" and "Implementation Roadmap" sections > describe work that has now shipped. > diff --git a/docs/REST_API_REFERENCE.md b/docs/REST_API_REFERENCE.md index 132547b0..f95cb84c 100644 --- a/docs/REST_API_REFERENCE.md +++ b/docs/REST_API_REFERENCE.md @@ -31,9 +31,9 @@ All endpoints return JSON responses with a standard format: - [Plugin-specific endpoints](#plugin-specific-endpoints) - [Starlark Apps](#starlark-apps) -> The API blueprint is mounted at `/api/v3` (`web_interface/app.py:144`). +> The API blueprint is mounted at `/api/v3` (`web_interface/app.py:199`). > SSE stream endpoints (`/api/v3/stream/*`) are defined directly on the -> Flask app at `app.py:607-615`. There are about 92 routes total — see +> Flask app at `app.py:799-809`. There are 94 routes total — see > `web_interface/blueprints/api_v3.py` for the canonical list. ---