Skip to content

Per-favorite live-game duration for the 6 team scoreboards - #172

Merged
ChuckBuilds merged 2 commits into
mainfrom
claude/scoreboard-favorite-duration-fyp6zz
Jul 8, 2026
Merged

Per-favorite live-game duration for the 6 team scoreboards#172
ChuckBuilds merged 2 commits into
mainfrom
claude/scoreboard-favorite-duration-fyp6zz

Conversation

@ChuckBuilds

@ChuckBuilds ChuckBuilds commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a per-league non_favorite_live_game_duration to the six team-based scoreboards so live games that don't involve a favorite team can get a shorter on-screen turn than your favorites (e.g. favorites 30s, everyone else 5s) when you're showing all live games. It only takes effect when favorite teams are configured and show_favorite_teams_only is off, and defaults to 0 (off) so existing behavior is unchanged until opted in.

Type of change

  • Bug fix in an existing plugin
  • New plugin (also fill out the SUBMISSION.md checklist below)
  • New feature for an existing plugin
  • Documentation only
  • Repo-wide change (registry script, hook, top-level docs)

Plugin(s) affected

football-scoreboard, baseball-scoreboard, basketball-scoreboard, soccer-scoreboard, hockey-scoreboard, lacrosse-scoreboard.

ufc-scoreboard (fight-based, no team favorites/rotation weighting) and f1-scoreboard (standings/results modes, no per-game live rotation) are intentionally out of scope — neither has a place for this knob.

Related issues

N/A

Test plan

  • Loaded the plugin in LEDMatrix on real hardware
  • Loaded the plugin in LEDMatrix emulator mode (EMULATOR=true python3 run.py)
  • Rendered the plugin in the dev preview server (scripts/dev_server.py)
  • Verified the web UI configuration form against the schema
  • N/A — repo-wide / docs-only change

Details:

  • Added a test_non_favorite_live_duration.py to each of the 6 plugins exercising the real SportsLive._effective_live_duration (favorite → base duration; non-favorite → shorter; no favorites → base for all; knob 0 → base for all; None current game → base). All pass.
  • Re-ran each plugin's existing live-rotation regression test (test_favorite_live_boost.py / soccer's test_live_mode_targeting.py) — no regressions.
  • Validated every changed config_schema.json as JSON Schema Draft-7 and confirmed the new option (with default/minimum/maximum/description) renders next to the live duration in each league block.
  • python scripts/check_module_collisions.py → clean; python update_registry.py synced all six latest_version bumps into plugins.json.
  • The core render safety harness (check_plugin.py) was not run here (needs a core checkout); the change is backward-compatible — with the default 0 every live game still uses live_game_duration, so rendered output is identical.

Required for plugin changes

  • Bumped version in plugins/<id>/manifest.json (football 2.6.0→2.7.0, baseball 1.8.0→1.9.0, basketball 1.6.0→1.7.0, soccer 2.2.0→2.3.0, hockey 1.3.0→1.4.0, lacrosse 1.3.0→1.4.0)
  • class_name in manifest.json matches the actual class in manager.py exactly (unchanged)
  • entry_point matches the real file (unchanged)
  • Updated the plugin's README.md if config keys changed (each documents the new key with a "when it applies" truth table)
  • config_schema.json is the source of truth for the web UI form — the new option is in the schema with a default, description, and constraints
  • Pre-commit hook ran successfully (auto-syncs plugins.json) — plugins.json was synced via update_registry.py

Checklist

  • My commits follow the message convention in CONTRIBUTING.md
  • I read CONTRIBUTING.md and CODE_OF_CONDUCT.md
  • I've not committed any secrets

Notes for reviewer

How it's wired. The two plugin families expose the option differently, matching each plugin's existing live-duration layout:

  • Flat per-league key (football, baseball, basketball, soccer): non_favorite_live_game_duration sits next to live_game_duration; manager.py forwards it into mode_config.
  • Nested display_durations (hockey, lacrosse): exposed as display_durations.non_favorite_live, resolved into mode_config alongside the existing display_durations.live → live_game_duration mapping.

In SportsLive, the single load-bearing change is the live rotation switch, which now compares against _effective_live_duration(self.current_game) instead of a flat game_display_duration. basketball/hockey/lacrosse lacked a class-level _is_favorite_game, so a tiny one was factored out (no behavior change) to keep the helper uniform.

Behavior (per live game while rotating):

Favorite teams set? Show favorites only Live game has a favorite? Duration used
No live_game_duration (unchanged)
Yes On (default) favorite live_game_duration
Yes Off favorite live_game_duration
Yes Off none non_favorite_live_game_duration (when > 0)

Left as-is on purpose: the manager-side total mode-cycle math (get_cycle_duration) still uses live_game_duration, which is the longer favorite value — a safe upper bound, so non-favorites just cycle faster within the same window and nothing gets cut off. Summing per-game durations there is a possible later refinement.

🤖 Generated with Claude Code

https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added an optional shorter display duration for live games that do not involve favorite teams across several sports scoreboards.
    • This behavior now works for both standard and custom league configurations where supported.
  • Documentation

    • Updated setup guides to explain when the new live-game duration setting applies and what a value of 0 means.
  • Tests

    • Added coverage to verify live-game rotation timing for favorite and non-favorite matchups.

Give live games without a favorite team a shorter on-screen turn than
your favorites. When several games are live and you're showing all of
them, favorites can linger (e.g. 30s) while non-favorite games flash by
(e.g. 5s).

Each affected league gains a per-league non_favorite_live_game_duration
(Family B plugins expose it inside display_durations as
non_favorite_live). It only takes effect when favorite teams are
configured AND show_favorite_teams_only is off; it defaults to 0 (off),
so existing behavior is byte-for-byte unchanged until opted in.

Applied to the six team-based live-rotation scoreboards: football,
baseball, basketball, soccer, hockey, and lacrosse. Per plugin:
SportsLive reads the new key and computes an effective per-game dwell
via _effective_live_duration(); manager.py forwards the key into
mode_config; config_schema.json exposes it next to the live duration for
the web UI; the README documents it with a when-it-applies truth table;
the manifest version is bumped (minor); and a regression test is added.

UFC (fight-based, no team favorites/rotation) and F1 (no per-game live
rotation) are intentionally out of scope.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@ChuckBuilds, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0b64db50-0e94-437d-a9d4-e5a681dc711e

📥 Commits

Reviewing files that changed from the base of the PR and between af2142d and 36b7969.

📒 Files selected for processing (16)
  • plugins.json
  • plugins/baseball-scoreboard/README.md
  • plugins/baseball-scoreboard/config_schema.json
  • plugins/baseball-scoreboard/manager.py
  • plugins/baseball-scoreboard/manifest.json
  • plugins/baseball-scoreboard/sports.py
  • plugins/basketball-scoreboard/README.md
  • plugins/basketball-scoreboard/config_schema.json
  • plugins/football-scoreboard/README.md
  • plugins/football-scoreboard/config_schema.json
  • plugins/hockey-scoreboard/README.md
  • plugins/hockey-scoreboard/config_schema.json
  • plugins/lacrosse-scoreboard/README.md
  • plugins/lacrosse-scoreboard/config_schema.json
  • plugins/soccer-scoreboard/README.md
  • plugins/soccer-scoreboard/config_schema.json
📝 Walkthrough

Walkthrough

This PR adds a configurable non_favorite_live_game_duration (or display_durations.non_favorite_live) setting across baseball, basketball, football, hockey, lacrosse, and soccer scoreboard plugins, allowing shorter live-game dwell times for non-favorite games under specific conditions. Each plugin's schema, manager, sports rotation logic, README, manifest, and tests are updated accordingly, alongside plugins.json registry metadata bumps.

Changes

Non-favorite live game duration feature (six sports plugins)

Layer / File(s) Summary
Baseball: schema, wiring, rotation, docs & tests
plugins/baseball-scoreboard/config_schema.json, manager.py, sports.py, README.md, manifest.json, test_non_favorite_live_duration.py
Adds non_favorite_live_game_duration schema property (MLB/MiLB/NCAA), manager passthrough, _effective_live_duration helper used in rotation, README docs, manifest bump to 1.9.0, and new standalone tests.
Basketball: schema, wiring, rotation, docs & tests
plugins/basketball-scoreboard/config_schema.json, manager.py, sports.py, README.md, manifest.json, test_non_favorite_live_duration.py
Adds property across NBA/WNBA/NCAAM/NCAAW schemas, manager passthrough, _is_favorite_game/_effective_live_duration helpers, README docs, manifest bump to 1.7.0, and tests.
Football: schema, wiring, rotation, docs & tests
plugins/football-scoreboard/config_schema.json, manager.py, sports.py, README.md, manifest.json, test_non_favorite_live_duration.py
Adds property for NFL/NCAA FB schemas, manager passthrough, _effective_live_duration helper, README docs, manifest bump to 2.7.0, and tests.
Hockey: schema, wiring, rotation, docs & tests
plugins/hockey-scoreboard/config_schema.json, manager.py, sports.py, README.md, manifest.json, test_non_favorite_live_duration.py
Adds display_durations.non_favorite_live for NHL/NCAA Men's/Women's, resolver in manager, _is_favorite_game/_effective_live_duration helpers, README docs, manifest bump to 1.4.0, and tests.
Lacrosse: schema, wiring, rotation, docs & tests
plugins/lacrosse-scoreboard/config_schema.json, manager.py, sports.py, README.md, manifest.json, test_non_favorite_live_duration.py
Adds display_durations.non_favorite_live for NCAA Men's/Women's, resolver in manager, _is_favorite_game/_effective_live_duration helpers, README docs, manifest bump to 1.4.0, and tests.
Soccer: schema, wiring, rotation, docs & tests
plugins/soccer-scoreboard/config_schema.json, manager.py, sports.py, README.md, manifest.json, test_non_favorite_live_duration.py
Adds property across all ten predefined leagues, manager passthrough for predefined and custom leagues, SportsCore._effective_live_duration helper, README docs, manifest bump to 2.3.0, and tests.
Registry metadata
plugins.json
Bumps last_updated/latest_version for all six scoreboard plugins and adjusts description text for on-air and plex-marquee.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and relates to the main change: configurable live-game duration behavior across the six team scoreboards.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/scoreboard-favorite-duration-fyp6zz

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 92 complexity

Metric Results
Complexity 92

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@ChuckBuilds

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ChuckBuilds

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/soccer-scoreboard/config_schema.json (1)

4028-4034: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Add non_favorite_live_game_duration to custom league schema

config_schema.json's custom_leagues.items.properties still omits non_favorite_live_game_duration, so the UI/schema can’t set a value that _adapt_config_for_custom_league() already forwards. Add the sibling property next to live_game_duration.

🛠️ Proposed fix
           "live_game_duration": {
             "type": "integer",
             "default": 20,
             "minimum": 10,
             "maximum": 120,
             "description": "Duration in seconds to display each live game"
           },
+          "non_favorite_live_game_duration": {
+            "type": "integer",
+            "default": 0,
+            "minimum": 0,
+            "maximum": 120,
+            "description": "Duration in seconds for live games that do NOT involve a favorite team. Only applies when favorite teams are set AND 'show_favorite_teams_only' is off. 0 (default) = use live_game_duration for every live game."
+          },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/soccer-scoreboard/config_schema.json` around lines 4028 - 4034, The
custom league schema is missing the non_favorite_live_game_duration property
even though _adapt_config_for_custom_league() already passes it through. Add a
sibling integer property next to live_game_duration inside
custom_leagues.items.properties in config_schema.json, with matching
validation/default-style metadata so the UI can set it consistently.
🧹 Nitpick comments (1)
plugins/lacrosse-scoreboard/test_non_favorite_live_duration.py (1)

50-56: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Test bypasses __init__'s int-parsing/validation logic.

make_live() sets non_favorite_live_game_duration directly on the instance instead of going through SportsLive.__init__'s try/except int-conversion path (lines 1991-1996 in sports.py), so that parsing/fallback logic (e.g., non-numeric or None config values) isn't covered by this test. This mirrors the same gap in sibling plugins' tests, so it's a pre-existing pattern rather than new here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/lacrosse-scoreboard/test_non_favorite_live_duration.py` around lines
50 - 56, Update the live test setup so it exercises SportsLive.__init__ instead
of bypassing it with object.__new__ in make_live. The current helper assigns
non_favorite_live_game_duration directly and skips the int-parsing/validation
path in SportsLive.__init__, so adjust the test to construct the _TestLive
instance through the normal initializer and pass config values that cover the
try/except conversion behavior, including non-numeric and None cases. Keep using
make_live and _TestLive as the locator points, but ensure the test verifies the
fallback logic rather than a direct attribute injection.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/basketball-scoreboard/config_schema.json`:
- Around line 182-189: Update the four league schema descriptions for the
non_favorite_live_game_duration setting so they match the real runtime gating:
non-favorite live games can appear when favorite teams are configured and either
show_favorite_teams_only is off or show_all_live is on. Adjust the description
text in each league’s non_favorite_live_game_duration entry to remove the “only
when show_favorite_teams_only is off” limitation and reflect the broader
applicability consistently across the schema.

In `@plugins/basketball-scoreboard/README.md`:
- Around line 90-91: Update the README wording for the live game duration
settings so it matches the actual logic in the basketball scoreboard plugin:
both `live_game_duration` and `non_favorite_live_game_duration` should describe
non-favorite live games as being surfaced not only when
`show_favorite_teams_only` is off, but also when `show_all_live` is enabled.
Adjust the related explanation and the “Shorter dwell for non-favorite live
games” section to reference the runtime conditions used by the scoreboard’s
live-game selection behavior, not just `show_favorite_teams_only`.

In `@plugins/hockey-scoreboard/test_non_favorite_live_duration.py`:
- Around line 20-48: The test module stubs only the direct src imports, but
importing NHLLiveManager from nhl_managers still pulls in transitive
dependencies through hockey and sports. Extend _stub_core_src() to also register
safe stubs for those imported modules and their downstream dependencies (such as
PIL, requests, pytz, data_sources, dynamic_team_resolver, logo_downloader, and
base_odds_manager) before the NHLLiveManager import so collection-time imports
do not fail.

---

Outside diff comments:
In `@plugins/soccer-scoreboard/config_schema.json`:
- Around line 4028-4034: The custom league schema is missing the
non_favorite_live_game_duration property even though
_adapt_config_for_custom_league() already passes it through. Add a sibling
integer property next to live_game_duration inside
custom_leagues.items.properties in config_schema.json, with matching
validation/default-style metadata so the UI can set it consistently.

---

Nitpick comments:
In `@plugins/lacrosse-scoreboard/test_non_favorite_live_duration.py`:
- Around line 50-56: Update the live test setup so it exercises
SportsLive.__init__ instead of bypassing it with object.__new__ in make_live.
The current helper assigns non_favorite_live_game_duration directly and skips
the int-parsing/validation path in SportsLive.__init__, so adjust the test to
construct the _TestLive instance through the normal initializer and pass config
values that cover the try/except conversion behavior, including non-numeric and
None cases. Keep using make_live and _TestLive as the locator points, but ensure
the test verifies the fallback logic rather than a direct attribute injection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d47fa892-a051-431e-9ae5-c19c6d3d12db

📥 Commits

Reviewing files that changed from the base of the PR and between 26dbd99 and af2142d.

📒 Files selected for processing (37)
  • plugins.json
  • plugins/baseball-scoreboard/README.md
  • plugins/baseball-scoreboard/config_schema.json
  • plugins/baseball-scoreboard/manager.py
  • plugins/baseball-scoreboard/manifest.json
  • plugins/baseball-scoreboard/sports.py
  • plugins/baseball-scoreboard/test_non_favorite_live_duration.py
  • plugins/basketball-scoreboard/README.md
  • plugins/basketball-scoreboard/config_schema.json
  • plugins/basketball-scoreboard/manager.py
  • plugins/basketball-scoreboard/manifest.json
  • plugins/basketball-scoreboard/sports.py
  • plugins/basketball-scoreboard/test_non_favorite_live_duration.py
  • plugins/football-scoreboard/README.md
  • plugins/football-scoreboard/config_schema.json
  • plugins/football-scoreboard/manager.py
  • plugins/football-scoreboard/manifest.json
  • plugins/football-scoreboard/sports.py
  • plugins/football-scoreboard/test_non_favorite_live_duration.py
  • plugins/hockey-scoreboard/README.md
  • plugins/hockey-scoreboard/config_schema.json
  • plugins/hockey-scoreboard/manager.py
  • plugins/hockey-scoreboard/manifest.json
  • plugins/hockey-scoreboard/sports.py
  • plugins/hockey-scoreboard/test_non_favorite_live_duration.py
  • plugins/lacrosse-scoreboard/README.md
  • plugins/lacrosse-scoreboard/config_schema.json
  • plugins/lacrosse-scoreboard/manager.py
  • plugins/lacrosse-scoreboard/manifest.json
  • plugins/lacrosse-scoreboard/sports.py
  • plugins/lacrosse-scoreboard/test_non_favorite_live_duration.py
  • plugins/soccer-scoreboard/README.md
  • plugins/soccer-scoreboard/config_schema.json
  • plugins/soccer-scoreboard/manager.py
  • plugins/soccer-scoreboard/manifest.json
  • plugins/soccer-scoreboard/sports.py
  • plugins/soccer-scoreboard/test_non_favorite_live_duration.py

Comment thread plugins/basketball-scoreboard/config_schema.json Outdated
Comment thread plugins/basketball-scoreboard/README.md Outdated
Comment on lines +20 to +48
def _stub_core_src():
def mod(name, **attrs):
m = types.ModuleType(name)
for k, v in attrs.items():
setattr(m, k, v)
sys.modules.setdefault(name, m)
return m

mod("src")
mod("src.common")
mod("src.plugin_system")
mod("src.logo_downloader", LogoDownloader=object, download_missing_logo=lambda *a, **k: None)
mod("src.common.scroll_helper", ScrollHelper=object)
mod("src.plugin_system.base_plugin", BasePlugin=object, VegasDisplayMode=object)
mod("src.background_data_service", get_background_service=lambda *a, **k: None)


_stub_core_src()

from nhl_managers import NHLLiveManager # noqa: E402


def make_live(favorite_teams=None, game_display_duration=30,
non_favorite_live_game_duration=0):
live = NHLLiveManager.__new__(NHLLiveManager)
live.favorite_teams = favorite_teams or []
live.game_display_duration = game_display_duration
live.non_favorite_live_game_duration = non_favorite_live_game_duration
return live

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check nhl_managers.py's import surface for anything not stubbed in the test.
ast-grep run --pattern 'import $MOD' --lang python plugins/hockey-scoreboard/nhl_managers.py
ast-grep run --pattern 'from $MOD import $$$' --lang python plugins/hockey-scoreboard/nhl_managers.py

Repository: ChuckBuilds/ledmatrix-plugins

Length of output: 682


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in plugins/hockey-scoreboard/hockey.py plugins/hockey-scoreboard/sports.py; do
  echo "== $f =="
  wc -l "$f"
  ast-grep run --pattern 'import $MOD' --lang python "$f"
  ast-grep run --pattern 'from $MOD import $$$' --lang python "$f"
done

Repository: ChuckBuilds/ledmatrix-plugins

Length of output: 2156


Stub the transitive imports too. nhl_managers.py imports hockey and sports, and those modules pull in additional dependencies (PIL, requests, pytz, data_sources, dynamic_team_resolver, logo_downloader, base_odds_manager). The current stubs are not enough to keep collection-time imports safe.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/hockey-scoreboard/test_non_favorite_live_duration.py` around lines 20
- 48, The test module stubs only the direct src imports, but importing
NHLLiveManager from nhl_managers still pulls in transitive dependencies through
hockey and sports. Extend _stub_core_src() to also register safe stubs for those
imported modules and their downstream dependencies (such as PIL, requests, pytz,
data_sources, dynamic_team_resolver, logo_downloader, and base_odds_manager)
before the NHLLiveManager import so collection-time imports do not fail.

- Merge origin/main (#171, baseball v1.17.1); resolve conflicts in
  baseball-scoreboard/manifest.json (re-apply the non-favorite-duration
  feature as a fresh minor bump 1.17.1 -> 1.18.0) and regenerate plugins.json.
- Add non_favorite_live_game_duration to soccer custom_leagues schema (the
  custom-league manager branch already forwarded it; the schema omitted it).
- Broaden the 'when it applies' wording in all six plugins' schema
  descriptions and READMEs: non-favorite live games are shown when
  show_favorite_teams_only is off OR show_all_live is on (docs-only; the
  runtime gate in _effective_live_duration is unchanged).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F9Saiat9CQmNi3DeDdvacB

Copy link
Copy Markdown
Owner Author

Pushed 36b7969, which merges main (resolving the conflict introduced by #171 — baseball is re-based onto 1.17.1 and re-bumped to 1.18.0, and plugins.json was regenerated) and addresses the review:

  • Soccer custom-league schema — added non_favorite_live_game_duration to custom_leagues.items.properties (the custom-league manager branch already forwarded it; only the schema was missing).
  • Applicability wording — broadened across all six plugins' schema descriptions and READMEs: non-favorite live games are shown when show_favorite_teams_only is off or show_all_live is on. Docs-only; the runtime gate in _effective_live_duration (favorite-membership check) is unchanged.

Two nitpicks intentionally not changed:

  • Hockey test transitive imports — the test passes as-is; CI installs each changed plugin's requirements.txt (PIL/requests/pytz/etc.) before running, and it mirrors the existing test_favorite_live_boost.py import pattern already in the repo.
  • Lacrosse test bypasses __init__ int-parsing — flagged 🔵 Trivial / 💤 Low value; the direct-attribute style targets _effective_live_duration precisely and matches every sibling plugin's test. The try/except int-coercion is a one-liner unrelated to the duration logic under test.

Generated by Claude Code

@ChuckBuilds
ChuckBuilds merged commit 4e5de3c into main Jul 8, 2026
4 checks passed
@ChuckBuilds
ChuckBuilds deleted the claude/scoreboard-favorite-duration-fyp6zz branch July 8, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants