fplkit 2.3.1__tar.gz → 2.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fplkit-2.3.1 → fplkit-2.3.2}/CHANGELOG.md +8 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/PKG-INFO +1 -1
- {fplkit-2.3.1 → fplkit-2.3.2}/docs/command-reference.md +1 -1
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/_version.py +2 -2
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_league_recap_history.py +13 -2
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_league_recap.py +67 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/README.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/TOOLS.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/create-pr/SKILL.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/SKILL.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/references/output-template.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/references/rules.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/scripts/_bootstrap.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/scripts/bench_order.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/scripts/extract_classic_squad.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/scripts/starting_xi.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/scripts/transfer_eval.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/gw-prep/scripts/validate_draft_waivers.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/preview-ingest/SKILL.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/release/SKILL.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/release-notes/SKILL.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/squad-builder/SKILL.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/squad-builder/references/output-template.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/squad-builder/references/rules.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.agents/skills/update-gw-prep/SKILL.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.claude/output-styles/fpl-mate.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.claude/settings.json +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.env.example +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.github/workflows/ci.yml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.github/workflows/pr-title.yml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.github/workflows/release.yml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/.gitignore +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/AGENTS.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/CLAUDE.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/CONTRIBUTING.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/LICENSE +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/README.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/cliff.toml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/config/team_ratings_overrides.yaml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/docs/architecture.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/docs/custom-analysis.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/docs/fpl-rules.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/docs/images/fpl-player-demo-v1-0.png +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/action/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/action/waiver.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/analysis/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/analysis/bench_order.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/analysis/captain.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/analysis/squad_analyzer.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/analysis/starting_xi.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/analysis/stats.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/analysis/transfer_eval.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/base.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/common.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/data/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/data/fixture.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/data/price.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/data/scout.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/orchestration/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/agents/orchestration/report.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/contract.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/core_insights.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/dataset_fetcher.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/football_data.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/fpl.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/fpl_draft.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/historical.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/historical_types.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/providers/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/providers/_models.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/providers/anthropic.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/providers/openai_compat.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/providers/perplexity.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/understat.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/api/vaastav.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_banner.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_context.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_fines.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_fines_config.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_helpers.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_json.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_league_recap_data.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_league_recap_types.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_plan_grid.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_review_analysis.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_review_classic.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_review_draft.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/_review_summarisation.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/allocate.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/captain.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/chips.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/credentials.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/differentials.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/doctor.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/doctor_providers.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/fdr.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/fixtures.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/history.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/init.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/intel.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/league.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/league_fines.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/league_recap.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/player.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/preview.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/price_changes.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/price_history.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/ratings.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/returnees.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/review.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/sell_prices.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/squad.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/stats.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/status.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/targets.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/transfer_eval.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/waivers.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/cli/xg.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/config/defaults.yaml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/config/fixture_predictions.yaml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/config/previews/EXAMPLE.yaml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/config/team_managers.yaml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/constants.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/models/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/models/chip_plan.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/models/fixture.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/models/league_history.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/models/player.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/models/team.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/models/types.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/parsers/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/parsers/recommendations.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/paths.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/prompts/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/prompts/league_recap.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/prompts/returnees.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/prompts/review.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/prompts/scout.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/scraper/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/scraper/fpl_prices.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/season.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/fixture_predictions.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/league_history.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/league_history_counters.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/league_history_fines.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/league_history_notes.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/matchup.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/player_prior.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/returnee_radar.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/constants.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/data_prep.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/display.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/evaluation.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/ownership.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/shrinkage.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/signals.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/single_gw.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/scoring/value_quality.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/season_previews.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/squad_allocator.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/team_form.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/team_ratings.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/services/team_ratings_prior.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/templates/gw_league_recap.md.j2 +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/templates/gw_preview.md.j2 +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/templates/gw_review.md.j2 +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/utils/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/utils/files.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/utils/gameweek.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/utils/markdown.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/utils/teams.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/utils/text.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/fpl_cli/utils/time.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/pyproject.toml +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/pyrightconfig.json +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/requirements.lock +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/scripts/backtest_early_season_prior_blend.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/scripts/calibrate_promoted_prior.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/scripts/calibrate_quality_ceilings.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/__init__.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/conftest.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/fixtures/classic_squad_fixture.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/fixtures/recommendations_fixture.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/fixtures/validate_draft_waivers/recs_clean.md +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/fixtures/validate_draft_waivers/squad_grid.json +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/fixtures/validate_draft_waivers/waivers.json +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/fixtures/waiver_ranked_golden.json +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_agents_action.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_agents_analysis.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_agents_analysis_squad.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_agents_base.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_agents_data.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_agents_data_price.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_agents_orchestration.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_allocate.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_client.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_core_insights.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_dataset_fetcher.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_draft.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_football_data.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_historical.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_understat.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_api_vaastav.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_bench_order_script.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_classic_squad_extraction.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_allocate.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_banner.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_captain.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_chips.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_credentials.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_custom_analysis.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_differentials.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_doctor.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_doctor_providers.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_fdr.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_fdr_blanks.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_fixtures.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_format.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_format_suppression.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_history.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_init.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_intel.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_json.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_json_contract.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_league.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_league_fines.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_plan_grid.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_player.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_preview.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_price_changes.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_price_history.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_returnees.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_review.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_sell_prices.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_settings_warning.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_squad.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_stats.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_status.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_targets.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_transfer_eval.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_waivers.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_warnings_stderr.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_cli_xg.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_common.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_common_scoring.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_data_prep_harmonisation.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_doc_consistency.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_fines.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_fines_config.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_fixture_predictions.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_fpl_prices.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_init.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_init_fines.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_league_history_counters.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_league_history_fines.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_league_history_notes.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_league_history_store.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_league_recap.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_matchup_service.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_models.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_paths.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_player_prior.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_player_resolution.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_preseason.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_providers.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_recommendations_parser.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_report_agent.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_report_paths.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_returnee_radar.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_review.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_rolling_pts_per_m.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_scoring.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_scraper.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_season.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_season_awareness.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_season_previews.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_sell_prices.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_squad_allocator.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_starting_xi_agent.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_stats.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_team_ratings.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_team_ratings_prior.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_transfer_eval_agent.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_utils_gameweek.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_utils_markdown.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_utils_text.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_utils_time.py +0 -0
- {fplkit-2.3.1 → fplkit-2.3.2}/tests/test_validate_draft_waivers.py +0 -0
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
|
+
## [2.3.1] - 2026-08-26
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
- keep draft players matched to the main game when FPL renames them (#171)
|
|
9
|
+
- judge a replayed gameweek's blanks by the clubs players had then (#173)
|
|
10
|
+
- keep the club and name a replayed gameweek already recorded (#175)
|
|
11
|
+
|
|
4
12
|
## [2.3.0] - 2026-08-26
|
|
5
13
|
|
|
6
14
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: fplkit
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.2
|
|
4
4
|
Summary: CLI tool for Fantasy Premier League analysis - classic and draft formats
|
|
5
5
|
Project-URL: Homepage, https://github.com/rossgroomio/fpl-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/rossgroomio/fpl-cli
|
|
@@ -794,7 +794,7 @@ it shares the channel: `synthesis_provider_unavailable`.
|
|
|
794
794
|
| `league_history_backfill_manager_unreachable` | One manager's history could not be fetched; their gameweeks stay unknown and are re-attempted next run |
|
|
795
795
|
| `league_history_backfill_replay_failed` | One gameweek could not be replayed in detail; the others are unaffected |
|
|
796
796
|
| `league_history_backfill_write_failed` | A backfilled gameweek could not be written; the rest of the backfill continues |
|
|
797
|
-
| `league_history_identity_carried` | A
|
|
797
|
+
| `league_history_identity_carried` | A finished gameweek kept the name, club or position it already had recorded for one or more players rather than the ones today's bootstrap gives them, or restored a player reference this capture had lost. Raised by a re-capture of a finished gameweek as well as by a replay; any one of the four on its own raises it |
|
|
798
798
|
| `synthesis_provider_unavailable` | `--summarise` was asked for but the synthesis provider had no usable key; everything else in the recap, the capture included, ran normally |
|
|
799
799
|
|
|
800
800
|
None of these change the exit code — `league-recap` exits 0 whenever the recap itself
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '2.3.
|
|
22
|
-
__version_tuple__ = version_tuple = (2, 3,
|
|
21
|
+
__version__ = version = '2.3.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (2, 3, 2)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -944,8 +944,8 @@ def _carry_recorded_identity(
|
|
|
944
944
|
warnings, HISTORY_WARNING_IDENTITY_CARRIED,
|
|
945
945
|
f"League history: GW{gameweek} kept the name, club, position or player "
|
|
946
946
|
f"reference already recorded for {carried} player(s) rather than the ones "
|
|
947
|
-
f"they carry today.
|
|
948
|
-
f"which has moved on.",
|
|
947
|
+
f"they carry today. Picks are resolved against the current bootstrap, "
|
|
948
|
+
f"which has moved on since the gameweek was played.",
|
|
949
949
|
)
|
|
950
950
|
return carried
|
|
951
951
|
|
|
@@ -1408,6 +1408,17 @@ async def capture_recap_history(
|
|
|
1408
1408
|
captured_at=datetime.now(tz=timezone.utc),
|
|
1409
1409
|
is_live_gw=is_live_gw,
|
|
1410
1410
|
)
|
|
1411
|
+
# A gameweek whose fixtures have all finished is done moving: its picks,
|
|
1412
|
+
# captain and transfers are fixed, and this run's rows are resolved
|
|
1413
|
+
# against *today's* bootstrap, which may have moved on since (issue #178).
|
|
1414
|
+
# `finished_gameweeks` -- not `is_live_gw` -- is the gate, because a
|
|
1415
|
+
# gameweek stays "current" (and so keeps landing on this path) for the
|
|
1416
|
+
# whole window between its last fixture and the next deadline, and that
|
|
1417
|
+
# window is exactly when a transfer can restamp a correct recorded row.
|
|
1418
|
+
# `_carry_recorded_identity` already no-ops when nothing is recorded yet,
|
|
1419
|
+
# so a genuine first capture is unaffected.
|
|
1420
|
+
if data["gameweek"] in finished_gameweeks:
|
|
1421
|
+
_carry_recorded_identity(store, data["gameweek"], rows, warnings=warnings)
|
|
1411
1422
|
if fpl_format == "draft" and rows:
|
|
1412
1423
|
_fill_draft_cumulative_totals(
|
|
1413
1424
|
store, rows,
|
|
@@ -2914,6 +2914,73 @@ class TestReplayKeepsRecordedIdentity:
|
|
|
2914
2914
|
assert resolved[1].transfers[0].player_out_code == 222
|
|
2915
2915
|
|
|
2916
2916
|
|
|
2917
|
+
# ---------------------------------------------------------------------------
|
|
2918
|
+
# issue #178: a current-gameweek recapture must not restamp a recorded row
|
|
2919
|
+
# ---------------------------------------------------------------------------
|
|
2920
|
+
|
|
2921
|
+
|
|
2922
|
+
class TestLiveCaptureKeepsRecordedIdentity:
|
|
2923
|
+
"""`capture_recap_history`'s direct write path -- no `replay_gameweek`
|
|
2924
|
+
involved -- is what the ordinary `league-recap` command runs every time.
|
|
2925
|
+
A gameweek stays "current" (and so keeps landing on this path) for the
|
|
2926
|
+
whole window between its last fixture and the next deadline, and FPL
|
|
2927
|
+
keeps processing transfers throughout that window (issue #178)."""
|
|
2928
|
+
|
|
2929
|
+
def _data(self, squad, *, gameweek: int = 1, **manager_kwargs):
|
|
2930
|
+
return _recap_data(
|
|
2931
|
+
gameweek=gameweek,
|
|
2932
|
+
managers=[_manager(name="Alice", entry_id=1, squad=squad, **manager_kwargs)],
|
|
2933
|
+
cohort=_cohort((1, "Alice", 1, 60, 300)),
|
|
2934
|
+
)
|
|
2935
|
+
|
|
2936
|
+
async def test_a_recapture_of_a_finished_gameweek_keeps_the_recorded_club(self):
|
|
2937
|
+
await capture_recap_history(
|
|
2938
|
+
self._data([_player(name="Mover", code=510_281, team="MCI", is_captain=True)]),
|
|
2939
|
+
season=SEASON, finished_gameweeks=[1],
|
|
2940
|
+
)
|
|
2941
|
+
await capture_recap_history(
|
|
2942
|
+
self._data([_player(name="Mover", code=510_281, team="TOT", is_captain=True)]),
|
|
2943
|
+
season=SEASON, finished_gameweeks=[1],
|
|
2944
|
+
)
|
|
2945
|
+
resolved = _store().resolved_gameweek(1)
|
|
2946
|
+
assert resolved[1].squad[0].team == "MCI"
|
|
2947
|
+
|
|
2948
|
+
async def test_a_recapture_reports_the_carry(self):
|
|
2949
|
+
await capture_recap_history(
|
|
2950
|
+
self._data([_player(name="Mover", code=510_281, team="MCI", is_captain=True)]),
|
|
2951
|
+
season=SEASON, finished_gameweeks=[1],
|
|
2952
|
+
)
|
|
2953
|
+
result = await capture_recap_history(
|
|
2954
|
+
self._data([_player(name="Mover", code=510_281, team="TOT", is_captain=True)]),
|
|
2955
|
+
season=SEASON, finished_gameweeks=[1],
|
|
2956
|
+
)
|
|
2957
|
+
assert any(w["code"] == HISTORY_WARNING_IDENTITY_CARRIED for w in result.warnings)
|
|
2958
|
+
|
|
2959
|
+
async def test_a_gameweek_not_yet_finished_is_not_gated_into_carrying(self):
|
|
2960
|
+
"""Absent from `finished_gameweeks`, the gameweek is still being
|
|
2961
|
+
played, so its squad can legitimately change between captures -- the
|
|
2962
|
+
carry must not run."""
|
|
2963
|
+
await capture_recap_history(
|
|
2964
|
+
self._data([_player(name="Mover", code=510_281, team="MCI", is_captain=True)]),
|
|
2965
|
+
season=SEASON, finished_gameweeks=[],
|
|
2966
|
+
)
|
|
2967
|
+
await capture_recap_history(
|
|
2968
|
+
self._data([_player(name="Mover", code=510_281, team="TOT", is_captain=True)]),
|
|
2969
|
+
season=SEASON, finished_gameweeks=[],
|
|
2970
|
+
)
|
|
2971
|
+
resolved = _store().resolved_gameweek(1)
|
|
2972
|
+
assert resolved[1].squad[0].team == "TOT"
|
|
2973
|
+
|
|
2974
|
+
async def test_a_first_capture_is_unaffected(self):
|
|
2975
|
+
result = await capture_recap_history(
|
|
2976
|
+
self._data([_player(name="Mover", code=510_281, team="TOT", is_captain=True)]),
|
|
2977
|
+
season=SEASON, finished_gameweeks=[1],
|
|
2978
|
+
)
|
|
2979
|
+
resolved = _store().resolved_gameweek(1)
|
|
2980
|
+
assert resolved[1].squad[0].team == "TOT"
|
|
2981
|
+
assert not any(w["code"] == HISTORY_WARNING_IDENTITY_CARRIED for w in result.warnings)
|
|
2982
|
+
|
|
2983
|
+
|
|
2917
2984
|
class TestPairSquads:
|
|
2918
2985
|
"""issue #175 review: which recorded entry each replayed one supersedes."""
|
|
2919
2986
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|