docs(plugins): README↔schema parity + missing titles — 5 plugins (audit phase 2)#175
Conversation
…:// retry mount Neglected-plugin hygiene pass (plugin audit, phase 1): - Add LICENSE files matching each manifest's declared license: MIT for geochron, nfl-draft, on-air, tide-display; GPL-3.0 for march-madness (previously undeclared — license field added to its manifest). - march-madness: add a README (it was the only plugin shipping without one) documenting features, display mode, per-key config, and data source; and mount the HTTP retry adapter on http:// as well as https:// so redirected ESPN requests keep the retry/backoff policy. - Bump manifest versions + add changelog entries; sync plugins.json. ledmatrix-elections (third-party author) LICENSE intentionally deferred pending the contributor's licensing choice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
The safety CI validates each changed plugin's manifest against the core manifest_schema.json. Two pre-existing issues surfaced once these plugins became "changed" in this PR: - march-madness: add the required `compatible_versions` field ([">=2.0.0"]). - on-air: remove `update_interval: 0`, which violates the schema's minimum of 1. on-air is MQTT push-driven and does not poll; the sibling mqtt-notifications plugin omits the field entirely. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
The core manifest_schema.json requires `dependencies` to be an array;
march-madness declared it as an empty object `{}`. It has no plugin
dependencies, so `[]` is correct.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
… static-image) Plugin audit phase 2a — realign these READMEs with their config_schema.json (the source of truth for the web UI form): - 7-segment-clock: remove the documented-but-removed sunrise/sunset color transition feature (location lat/lng/locality, color_daytime/nighttime, min_fade_elevation, astral dependency) — it no longer exists in the schema or manager; document the real color and digit_spacing options; fix the placeholder license section (GPL-3.0, matching the LICENSE file). - on-air: replace the removed pulsing/glow/tally-dot options with the actual text color, background color, font, and Home Assistant discovery fields; correct the per-message color/bg MQTT payload docs; drop the broken preview.png reference. - static-image: document all rotation_mode values (add time_based/date_based), describe images as scheduled image entries rather than plain paths, and add a Per-Image Scheduling section. Also normalizes each manifest's versions[] changelog key to ledmatrix_min (some mixed the old ledmatrix_min_version). Version bumps + plugins.json sync. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
Up to standards ✅🟢 Issues
|
|
Warning Review limit reached
Next review available in: 12 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Audit phase 2 (README parity, continued): - calendar: convert the prose config bullets to a per-key table that also documents the previously-undocumented customization fonts. Kept credentials_file/token_file — both are real config-only keys the manager reads (manager.py:72-73), not schema drift. Added web-UI titles to the untitled options (Enabled, Max Events, Show All-Day Events, Event Rotation Interval, Display Duration, Update Interval). - countdown: replace the stale prose config section with per-key tables covering the v3 keys (target_time, mode until/since, layout_preset, text_align, and the per-countdown style/layout overrides); add a title to the top-level enabled option. Normalizes both manifests' versions[] key to ledmatrix_min. Version bumps + plugins.json sync. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
Per project policy the whole repo is GPL-3.0. This PR originally added MIT LICENSE files (matching those plugins' declared MIT manifests); switch them to GPL-3.0 instead so nothing ships as MIT: - geochron, nfl-draft, on-air, tide-display: LICENSE file + manifest "license" field MIT -> GPL-3.0. All are first-party (ChuckBuilds), so the relicense is the copyright holder's call; MIT is GPL-compatible. - ledmatrix-elections: add a GPL-3.0 LICENSE (it shipped without one) and declare it in the manifest; bump 1.1.0 -> 1.1.1. This plugin is a third-party contribution (rpierce99) — under the repo's inbound=outbound GPL policy (CONTRIBUTING.md) it is already GPL-licensed to the project. No code changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
…n-audit-phase2-docs
countdown's LICENSE file was already GPL-3.0 but its manifest declared MIT; align the manifest to the file (project standard). Folded into the pending 3.1.1 changelog entry — no extra version bump. Rides on a merge of the #173 branch, which flips geochron/nfl-draft/on-air/ tide-display to GPL-3.0 and adds ledmatrix-elections' LICENSE, keeping this stacked branch consistent with #173's licensing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
The README license line still said "MIT License"; align it with the GPL-3.0 manifest + LICENSE (repo-wide MIT -> GPL-3.0 standardization). Docs only; countdown is already version-bumped in this PR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
Resolves conflicts after #173 (phase-1) landed on main: - on-air/manifest.json: the branch's versions[] (1.2.2 -> 1.2.1 -> ...) is a clean superset of main's (1.2.1 -> ...), so kept the branch's manifest. - plugins.json: regenerated from manifests (deterministic). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
This PR's changelog normalization went the wrong direction: it converted each touched plugin's versions[] entries from ledmatrix_min_version to ledmatrix_min. The core's own validator (store_manager.py, _validate_manifest_version_fields) explicitly flags ledmatrix_min as deprecated and expects ledmatrix_min_version, so every real device install/update of these 5 plugins would start logging a fresh "deprecated field" warning that wasn't there before. Revert the field name direction (and the changelog notes describing the change) so it actually matches the core's documented, non-deprecated field.
Follows the maintainer's correction on #175: the core's manifest validator flags `ledmatrix_min` as deprecated and expects `ledmatrix_min_version`. Switch the music versions[] entries (1.0.8, 1.0.7, 1.0.6) to `ledmatrix_min_version` so device installs don't log a deprecated-field warning. Also merges the latest main (#174, #175) and regenerates plugins.json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
Follows the maintainer's correction on #175: the core's manifest validator flags `ledmatrix_min` as deprecated and expects `ledmatrix_min_version`. Normalize every versions[] entry in the flights and stocks manifests to `ledmatrix_min_version` so device installs don't log deprecated-field warnings. (Latest main, incl. #174/#175, was merged in the preceding commit.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
* chore(license): standardize flights, music, stocks to GPL-3.0 Completes the repo-wide MIT -> GPL-3.0 pass for the plugins not covered by the other audit PRs. All first-party: - ledmatrix-flights (1.10.0 -> 1.10.1): manifest "license" + README MIT -> GPL-3.0 (its LICENSE file was already GPL). - ledmatrix-music (1.0.6 -> 1.0.7): LICENSE file + manifest "license" + README MIT -> GPL-3.0. - ledmatrix-stocks (2.3.0 -> 2.3.1): manifest "license" MIT -> GPL-3.0 (its LICENSE file was already GPL). No code changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB * fix(ledmatrix-stocks): guard process_deferred_updates for harness compatibility The plugin-safety harness renders each changed plugin, and its BoundsCheckingDisplayManager does not implement process_deferred_updates(), so stocks crashed at every size once the license bump made it a "changed" plugin. Guard the call with hasattr — production DisplayManager still runs it; harness/other managers that lack it are skipped. No production behavior change. Note: leaderboard, odds-ticker, news, and stock-news call the same method and would hit this too when next touched — the core harness double is missing it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB * chore: defer ledmatrix-music relicense (pre-existing 64px overflow) Relicensing made music a "changed" plugin, so the safety harness rendered it and caught a PRE-EXISTING overflow on the 64px-wide panels ([FAIL] 64x32 / 64x64 now_playing overflow bbox=(64,...)) — album-art + text don't fit a 64px width. That's a narrow-panel layout bug, not a licensing issue, and needs a real rendering fix (best verified against the core harness). Revert music to its current state so this PR (flights + stocks -> GPL-3.0) can land; music's relicense will follow once the overflow is fixed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB * Use non-deprecated ledmatrix_min_version in flights + stocks manifests Follows the maintainer's correction on #175: the core's manifest validator flags `ledmatrix_min` as deprecated and expects `ledmatrix_min_version`. Normalize every versions[] entry in the flights and stocks manifests to `ledmatrix_min_version` so device installs don't log deprecated-field warnings. (Latest main, incl. #174/#175, was merged in the preceding commit.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB --------- Co-authored-by: Claude <noreply@anthropic.com>
…wing (+ GPL-3.0) (#179) * fix(ledmatrix-music): clip scrolling text to viewport (fix 64px overflow) + GPL-3.0 The now-playing title/artist/album marquee drew the full (rotated) string at the text-area x with no right-edge clip, so long text ran past the panel's right edge. The safety harness flagged this as an overflow on the 64px-wide panels (64x32 / 64x64), where the text area is only ~29px wide. Add _clip_text_to_width() and apply it to all four text draws so the marquee stays inside its viewport: long text still scrolls (the char-based rotation is unchanged) — it's just clipped on the right instead of overflowing the panel. Also relicense to GPL-3.0 (LICENSE + manifest + README). music was the plugin deferred from the repo-wide MIT -> GPL-3.0 pass because of this overflow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB * fix(ledmatrix-music): draw no text when the panel has no text room (square panels) Follow-up to the viewport clip: on square panels (e.g. 64x64) the album art is sized to the panel height, so it fills the full width and text_area_width goes negative. The clip helper's `max_width <= 0` guard returned the text UNCLIPPED, so it was still drawn off-panel (overflow bbox=(64,28,91,36) at 64x64). Now return an empty string when there's no room, and skip the progress bar too. Album art fills the panel; no text is drawn rather than overflowing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB * fix(ledmatrix-music): clip the "Nothing Playing" screen to the panel width That was the real overflow the harness caught (CI has no auth -> no track -> the "Nothing Playing" idle screen renders). The text is centered via x = (width - text_width)//2, which goes negative when the text is wider than the panel (64px), spilling off both edges — matching the failing bbox exactly (y = height//2 - 4 = 12 at 64x32, 28 at 64x64). Clip the text to the panel width and clamp x to >= 0. (The earlier marquee viewport clip is still correct for the now-playing view with a real track.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB * fix(ledmatrix-music): keep the ellipsis when truncating non-scrolling text When scrolling is disabled, the title/artist/album were truncated with a rough char-count estimate (`text[:width//6] + "..."`) and then passed through the draw-time viewport clip, which could trim the trailing "..." back off — leaving no truncation indicator. Add `_truncate_text_with_ellipsis`, which reserves room for the ellipsis before clipping so the "..." always survives and the result fits the text-area viewport. Bumps ledmatrix-music to 1.0.8. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB * Merge main + use non-deprecated ledmatrix_min_version in music manifest Follows the maintainer's correction on #175: the core's manifest validator flags `ledmatrix_min` as deprecated and expects `ledmatrix_min_version`. Switch the music versions[] entries (1.0.8, 1.0.7, 1.0.6) to `ledmatrix_min_version` so device installs don't log a deprecated-field warning. Also merges the latest main (#174, #175) and regenerates plugins.json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB --------- Co-authored-by: Claude <noreply@anthropic.com>
Same recurring issue as PRs #175/#177/#178: the core's store_manager.py validator flags ledmatrix_min as deprecated and expects ledmatrix_min_version. This PR's new 1.19.0 changelog entry used the deprecated name; corrected to match the non-deprecated field (older entries below 1.6.2 already have this same pre-existing issue but are untouched by this PR, so left as-is -- out of scope here).
…ayer card (v1.19.0) (#180) * feat(baseball-scoreboard): team-color grid, clearer at-bat labels, player card (v1.19.0) Three enhancements to the baseball plugin: 1. Traditional scoreboard: subtle team-color row tint (~12% brightness wash) plus a solid left-edge accent strip per team, reusing the already-fetched away/home ESPN colors. Gated by a new show_team_color_backgrounds toggle (default on; requires use_team_colors). Text stays legible via its black outline. 2. Pitcher/Batter screen: labels spelled out ("Pitcher:" / "Batter:") so "B" is no longer ambiguous with the grid's Balls indicator. 3. New Player Card screen (show_player_card, MLB & NCAA): rotates in a masters-style card for the current batter/pitcher with headshot, jersey number, position, bat/throw, and season stats (AVG/HR/RBI for hitters, ERA/W-L/K for pitchers). Bio + headshot fetched from ESPN's athlete API and cached (memory + disk); the headshot hides on tiny panels and the card degrades to text-only when unavailable. Skipped for MiLB (no ESPN player data). All new code lives in existing files (no new bare-name modules, per the cross-plugin collision rule). Adds config schema (grid toggle, per-league show_player_card, player_card customization block), manager plumbing, docs, and tests (test_player_card.py + grid-tint tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9 * fix(baseball-scoreboard): harden headshot cache path + download URL Address a Codacy medium security finding on the new player-card headshot loader: - Sanitize the ESPN-provided player_id and league before using them as filesystem path segments (_safe_filename strips to [A-Za-z0-9_-]) so an unexpected id can't escape the headshot cache directory via '..' or path separators. - Only fetch headshots over http(s), refusing file://, ftp://, etc. Adds a unit test for the filename sanitization. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9 * fix(baseball-scoreboard): log player-bio cache errors instead of silent pass Resolve the Codacy/Bandit B110 (try/except/pass) medium finding in _fetch_player_bio: the two cache_manager get/set guards swallowed exceptions with a bare `pass`. Log them at debug level instead so cache issues are diagnosable, matching how the rest of the plugin handles non-fatal cache errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9 * fix(baseball-scoreboard): harden + de-block headshot fetch (CodeRabbit review) Address two CodeRabbit review findings on the player-card headshot loader: 1. SSRF + unbounded response (security): the ESPN-supplied headshot URL was fetched with only a scheme check. Now restrict the host to ESPN domains (*.espncdn.com / *.espn.com) via an allowlist, and stream the download with a hard 5 MB size cap (Content-Length check + bounded iter_content) to prevent memory exhaustion. 2. Render-path blocking (stability): load_headshot() previously did a synchronous requests.get on a cache miss straight from _draw_player_card_screen, freezing the display up to 5s when a new batter/pitcher rotated in. The render path is now cache-only (allow_download=False); BaseballLive.update() prefetches headshot bytes off-thread (daemon thread, throttled) to warm the disk cache, mirroring the existing _fetch_player_bio pattern. A cold cache degrades to a text-only card until the prefetch completes. Adds tests for the host allowlist (incl. metadata-IP and look-alike-host rejection) and for the render path never downloading. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R1z28MrGx56x6eiJvibDg9 * fix(baseball-scoreboard): use ledmatrix_min_version in new 1.19.0 entry Same recurring issue as PRs #175/#177/#178: the core's store_manager.py validator flags ledmatrix_min as deprecated and expects ledmatrix_min_version. This PR's new 1.19.0 changelog entry used the deprecated name; corrected to match the non-deprecated field (older entries below 1.6.2 already have this same pre-existing issue but are untouched by this PR, so left as-is -- out of scope here). --------- Co-authored-by: Claude <noreply@anthropic.com>
Summary
Audit phase 2: realign five plugins' READMEs with their
config_schema.json(the source of truth for the web-UI form) and fill in missing web-UI titles. Several documented options that don't exist, omitted ones that do, or were prose-only. Docs + schematitle/changelog metadata only — no config behavior changes.Plugin(s) affected
7-segment-clock,on-air,static-image,calendar,countdownWhat changed per plugin
location.lat/lng/locality,color_daytime/nighttime,min_fade_elevation, anastraldep) that no longer exists in the schema ormanager.py, and omitted the realcolor/digit_spacing. Rewrote the config table to match; fixed the placeholder license → GPL-3.0.color/bgMQTT payload docs; dropped the brokenpreview.pngreference.rotation_modevalues (was missingtime_based/date_based), describedimagesas scheduled image entries, and added a Per-Image Scheduling section.customizationfonts (keptcredentials_file/token_file, which are real config-only keys the manager reads); added titles to six untitled options.target_time,mode,layout_preset,text_align, per-countdownstyle/layout); added a title to the top-levelenabled.Type of change
Test plan
config_schema.jsonandmanager.pyby hand (incl. confirmingtoken_fileis a live config key and7-segment-clock's sunrise feature is truly gone).python update_registry.py(5 bumps),python scripts/check_module_collisions.py(clean), JSON validity of all touched manifests + schemas.Notes for reviewer
Each touched manifest also had its
versions[]key normalized toledmatrix_min(some mixed the oldledmatrix_min_version) to pre-empt core manifest-validation failures. Still queued in this audit: an optional per-fieldtitlebulk-pass for the remaining zero-title schemas andenumNameson cryptic dropdowns — both verify-first, since the schema renderer lives in the core repo and I can't confirm here whether the UI humanizes raw keys or rendersenumNames.🤖 Generated with Claude Code
https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB