reeln 0.0.23__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.
- reeln-0.0.23/.coveragerc +13 -0
- reeln-0.0.23/.github/workflows/ci.yml +59 -0
- reeln-0.0.23/.github/workflows/release.yml +45 -0
- reeln-0.0.23/.gitignore +52 -0
- reeln-0.0.23/.readthedocs.yaml +18 -0
- reeln-0.0.23/CHANGELOG.md +105 -0
- reeln-0.0.23/LICENSE +661 -0
- reeln-0.0.23/Makefile +45 -0
- reeln-0.0.23/PKG-INFO +167 -0
- reeln-0.0.23/README.md +142 -0
- reeln-0.0.23/assets/logo.jpg +0 -0
- reeln-0.0.23/docs/changelog.md +5 -0
- reeln-0.0.23/docs/cli/config.md +36 -0
- reeln-0.0.23/docs/cli/doctor.md +86 -0
- reeln-0.0.23/docs/cli/game.md +358 -0
- reeln-0.0.23/docs/cli/index.md +30 -0
- reeln-0.0.23/docs/cli/media.md +47 -0
- reeln-0.0.23/docs/cli/plugins.md +230 -0
- reeln-0.0.23/docs/cli/render.md +236 -0
- reeln-0.0.23/docs/conf.py +67 -0
- reeln-0.0.23/docs/guide/configuration.md +340 -0
- reeln-0.0.23/docs/guide/sports.md +52 -0
- reeln-0.0.23/docs/index.md +54 -0
- reeln-0.0.23/docs/install.md +76 -0
- reeln-0.0.23/docs/quickstart.md +273 -0
- reeln-0.0.23/docs/requirements.txt +4 -0
- reeln-0.0.23/pyproject.toml +64 -0
- reeln-0.0.23/pytest.ini +3 -0
- reeln-0.0.23/reeln/__init__.py +5 -0
- reeln-0.0.23/reeln/__main__.py +7 -0
- reeln-0.0.23/reeln/cli.py +103 -0
- reeln-0.0.23/reeln/commands/__init__.py +0 -0
- reeln-0.0.23/reeln/commands/config_cmd.py +57 -0
- reeln-0.0.23/reeln/commands/event.py +161 -0
- reeln-0.0.23/reeln/commands/game.py +483 -0
- reeln-0.0.23/reeln/commands/media.py +41 -0
- reeln-0.0.23/reeln/commands/plugins_cmd.py +269 -0
- reeln-0.0.23/reeln/commands/render.py +775 -0
- reeln-0.0.23/reeln/core/__init__.py +0 -0
- reeln-0.0.23/reeln/core/config.py +413 -0
- reeln-0.0.23/reeln/core/debug.py +324 -0
- reeln-0.0.23/reeln/core/doctor.py +284 -0
- reeln-0.0.23/reeln/core/errors.py +71 -0
- reeln-0.0.23/reeln/core/events.py +228 -0
- reeln-0.0.23/reeln/core/ffmpeg.py +474 -0
- reeln-0.0.23/reeln/core/finish.py +77 -0
- reeln-0.0.23/reeln/core/highlights.py +625 -0
- reeln-0.0.23/reeln/core/iterations.py +166 -0
- reeln-0.0.23/reeln/core/log.py +83 -0
- reeln-0.0.23/reeln/core/orchestrator.py +133 -0
- reeln-0.0.23/reeln/core/overlay.py +183 -0
- reeln-0.0.23/reeln/core/plugin_config.py +100 -0
- reeln-0.0.23/reeln/core/plugin_registry.py +419 -0
- reeln-0.0.23/reeln/core/profiles.py +220 -0
- reeln-0.0.23/reeln/core/prompts.py +284 -0
- reeln-0.0.23/reeln/core/prune.py +262 -0
- reeln-0.0.23/reeln/core/renderer.py +99 -0
- reeln-0.0.23/reeln/core/segment.py +162 -0
- reeln-0.0.23/reeln/core/shorts.py +226 -0
- reeln-0.0.23/reeln/core/teams.py +102 -0
- reeln-0.0.23/reeln/core/templates.py +141 -0
- reeln-0.0.23/reeln/core/throttle.py +82 -0
- reeln-0.0.23/reeln/data/__init__.py +1 -0
- reeln-0.0.23/reeln/data/templates/__init__.py +1 -0
- reeln-0.0.23/reeln/data/templates/goal_overlay.ass +24 -0
- reeln-0.0.23/reeln/models/__init__.py +0 -0
- reeln-0.0.23/reeln/models/config.py +56 -0
- reeln-0.0.23/reeln/models/debug.py +51 -0
- reeln-0.0.23/reeln/models/doctor.py +33 -0
- reeln-0.0.23/reeln/models/game.py +175 -0
- reeln-0.0.23/reeln/models/plugin.py +100 -0
- reeln-0.0.23/reeln/models/plugin_schema.py +93 -0
- reeln-0.0.23/reeln/models/profile.py +137 -0
- reeln-0.0.23/reeln/models/render_plan.py +88 -0
- reeln-0.0.23/reeln/models/segment.py +26 -0
- reeln-0.0.23/reeln/models/short.py +68 -0
- reeln-0.0.23/reeln/models/team.py +57 -0
- reeln-0.0.23/reeln/models/template.py +29 -0
- reeln-0.0.23/reeln/plugins/__init__.py +24 -0
- reeln-0.0.23/reeln/plugins/capabilities.py +48 -0
- reeln-0.0.23/reeln/plugins/hooks.py +37 -0
- reeln-0.0.23/reeln/plugins/loader.py +184 -0
- reeln-0.0.23/reeln/plugins/registry.py +68 -0
- reeln-0.0.23/registry/plugins.json +15 -0
- reeln-0.0.23/tests/__init__.py +0 -0
- reeln-0.0.23/tests/conftest.py +30 -0
- reeln-0.0.23/tests/integration/__init__.py +0 -0
- reeln-0.0.23/tests/integration/conftest.py +172 -0
- reeln-0.0.23/tests/integration/test_cli_lifecycle.py +398 -0
- reeln-0.0.23/tests/integration/test_ffmpeg_lifecycle.py +187 -0
- reeln-0.0.23/tests/integration/test_ffmpeg_real.py +30 -0
- reeln-0.0.23/tests/integration/test_game_lifecycle.py +315 -0
- reeln-0.0.23/tests/unit/__init__.py +0 -0
- reeln-0.0.23/tests/unit/commands/__init__.py +0 -0
- reeln-0.0.23/tests/unit/commands/test_cli.py +229 -0
- reeln-0.0.23/tests/unit/commands/test_config_cmd.py +118 -0
- reeln-0.0.23/tests/unit/commands/test_event.py +496 -0
- reeln-0.0.23/tests/unit/commands/test_game.py +1937 -0
- reeln-0.0.23/tests/unit/commands/test_media.py +148 -0
- reeln-0.0.23/tests/unit/commands/test_plugins_cmd.py +747 -0
- reeln-0.0.23/tests/unit/commands/test_render.py +3332 -0
- reeln-0.0.23/tests/unit/core/__init__.py +0 -0
- reeln-0.0.23/tests/unit/core/test_config.py +853 -0
- reeln-0.0.23/tests/unit/core/test_debug.py +544 -0
- reeln-0.0.23/tests/unit/core/test_doctor.py +396 -0
- reeln-0.0.23/tests/unit/core/test_errors.py +158 -0
- reeln-0.0.23/tests/unit/core/test_events.py +563 -0
- reeln-0.0.23/tests/unit/core/test_ffmpeg.py +697 -0
- reeln-0.0.23/tests/unit/core/test_finish.py +174 -0
- reeln-0.0.23/tests/unit/core/test_highlights.py +1237 -0
- reeln-0.0.23/tests/unit/core/test_iterations.py +668 -0
- reeln-0.0.23/tests/unit/core/test_log.py +95 -0
- reeln-0.0.23/tests/unit/core/test_orchestrator.py +311 -0
- reeln-0.0.23/tests/unit/core/test_overlay.py +317 -0
- reeln-0.0.23/tests/unit/core/test_plugin_config.py +231 -0
- reeln-0.0.23/tests/unit/core/test_plugin_registry.py +809 -0
- reeln-0.0.23/tests/unit/core/test_profiles.py +415 -0
- reeln-0.0.23/tests/unit/core/test_prompts.py +638 -0
- reeln-0.0.23/tests/unit/core/test_prune.py +551 -0
- reeln-0.0.23/tests/unit/core/test_renderer.py +271 -0
- reeln-0.0.23/tests/unit/core/test_segment.py +279 -0
- reeln-0.0.23/tests/unit/core/test_shorts.py +401 -0
- reeln-0.0.23/tests/unit/core/test_teams.py +293 -0
- reeln-0.0.23/tests/unit/core/test_templates.py +292 -0
- reeln-0.0.23/tests/unit/core/test_throttle.py +157 -0
- reeln-0.0.23/tests/unit/models/__init__.py +0 -0
- reeln-0.0.23/tests/unit/models/test_config.py +124 -0
- reeln-0.0.23/tests/unit/models/test_debug.py +135 -0
- reeln-0.0.23/tests/unit/models/test_doctor.py +74 -0
- reeln-0.0.23/tests/unit/models/test_game.py +695 -0
- reeln-0.0.23/tests/unit/models/test_plugin.py +280 -0
- reeln-0.0.23/tests/unit/models/test_plugin_schema.py +237 -0
- reeln-0.0.23/tests/unit/models/test_profile.py +267 -0
- reeln-0.0.23/tests/unit/models/test_render_plan.py +319 -0
- reeln-0.0.23/tests/unit/models/test_segment.py +53 -0
- reeln-0.0.23/tests/unit/models/test_short.py +152 -0
- reeln-0.0.23/tests/unit/models/test_team.py +166 -0
- reeln-0.0.23/tests/unit/models/test_template.py +63 -0
- reeln-0.0.23/tests/unit/plugins/__init__.py +0 -0
- reeln-0.0.23/tests/unit/plugins/test_capabilities.py +114 -0
- reeln-0.0.23/tests/unit/plugins/test_hooks.py +84 -0
- reeln-0.0.23/tests/unit/plugins/test_init.py +67 -0
- reeln-0.0.23/tests/unit/plugins/test_loader.py +411 -0
- reeln-0.0.23/tests/unit/plugins/test_registry.py +135 -0
- reeln-0.0.23/tests/unit/test_init.py +17 -0
- reeln-0.0.23/tests/unit/test_main.py +15 -0
- reeln-0.0.23/uv.lock +1126 -0
reeln-0.0.23/.coveragerc
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
NO_COLOR: "1"
|
|
11
|
+
_TYPER_FORCE_DISABLE_TERMINAL: "1"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- uses: astral-sh/setup-uv@v5
|
|
24
|
+
with:
|
|
25
|
+
enable-cache: true
|
|
26
|
+
|
|
27
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
28
|
+
run: uv python install ${{ matrix.python-version }}
|
|
29
|
+
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: uv sync --extra dev --extra interactive
|
|
32
|
+
|
|
33
|
+
- name: Lint
|
|
34
|
+
run: uv run ruff check .
|
|
35
|
+
|
|
36
|
+
- name: Type check
|
|
37
|
+
run: uv run mypy reeln/
|
|
38
|
+
|
|
39
|
+
- name: Test
|
|
40
|
+
run: uv run python -m pytest tests/ -n auto --cov=reeln --cov-branch --cov-fail-under=100 -m "not integration" -q
|
|
41
|
+
|
|
42
|
+
docs:
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
|
|
48
|
+
- uses: astral-sh/setup-uv@v5
|
|
49
|
+
with:
|
|
50
|
+
enable-cache: true
|
|
51
|
+
|
|
52
|
+
- name: Set up Python
|
|
53
|
+
run: uv python install 3.11
|
|
54
|
+
|
|
55
|
+
- name: Install dependencies
|
|
56
|
+
run: uv sync --extra docs
|
|
57
|
+
|
|
58
|
+
- name: Build docs
|
|
59
|
+
run: uv run python -m sphinx -W docs/ docs/_build/html
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
NO_COLOR: "1"
|
|
10
|
+
_TYPER_FORCE_DISABLE_TERMINAL: "1"
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
environment: release
|
|
16
|
+
permissions:
|
|
17
|
+
id-token: write
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- uses: astral-sh/setup-uv@v5
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
|
|
26
|
+
- name: Set up Python
|
|
27
|
+
run: uv python install 3.11
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: uv sync --extra dev --extra interactive
|
|
31
|
+
|
|
32
|
+
- name: Lint
|
|
33
|
+
run: uv run ruff check .
|
|
34
|
+
|
|
35
|
+
- name: Type check
|
|
36
|
+
run: uv run mypy reeln/
|
|
37
|
+
|
|
38
|
+
- name: Test
|
|
39
|
+
run: uv run python -m pytest tests/ -n auto --cov=reeln --cov-branch --cov-fail-under=100 -m "not integration" -q
|
|
40
|
+
|
|
41
|
+
- name: Build
|
|
42
|
+
run: uv build
|
|
43
|
+
|
|
44
|
+
- name: Publish to PyPI
|
|
45
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
reeln-0.0.23/.gitignore
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
*.whl
|
|
12
|
+
|
|
13
|
+
# Testing / Coverage
|
|
14
|
+
.coverage
|
|
15
|
+
htmlcov/
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.tox/
|
|
18
|
+
|
|
19
|
+
# Media — prevent accidental video commits
|
|
20
|
+
*.mkv
|
|
21
|
+
*.mp4
|
|
22
|
+
*.mov
|
|
23
|
+
*.avi
|
|
24
|
+
*.webm
|
|
25
|
+
*.ts
|
|
26
|
+
|
|
27
|
+
# Project artifacts
|
|
28
|
+
secrets/
|
|
29
|
+
output/
|
|
30
|
+
.tmp/
|
|
31
|
+
|
|
32
|
+
# Sphinx docs build
|
|
33
|
+
docs/_build/
|
|
34
|
+
|
|
35
|
+
# AI dev docs — dev-only, not tracked
|
|
36
|
+
CLAUDE.md
|
|
37
|
+
AGENTS.md
|
|
38
|
+
|
|
39
|
+
# IDE
|
|
40
|
+
.idea/
|
|
41
|
+
.vscode/
|
|
42
|
+
*.swp
|
|
43
|
+
*.swo
|
|
44
|
+
*~
|
|
45
|
+
|
|
46
|
+
# OS
|
|
47
|
+
.DS_Store
|
|
48
|
+
Thumbs.db
|
|
49
|
+
|
|
50
|
+
# Environment
|
|
51
|
+
.env
|
|
52
|
+
.env.*
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Read the Docs configuration file
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
|
|
6
|
+
build:
|
|
7
|
+
os: ubuntu-22.04
|
|
8
|
+
tools:
|
|
9
|
+
python: "3.11"
|
|
10
|
+
|
|
11
|
+
sphinx:
|
|
12
|
+
configuration: docs/conf.py
|
|
13
|
+
|
|
14
|
+
python:
|
|
15
|
+
install:
|
|
16
|
+
- requirements: docs/requirements.txt
|
|
17
|
+
- method: pip
|
|
18
|
+
path: .
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.0.23] - 2026-03-03
|
|
11
|
+
|
|
12
|
+
First feature-complete release of reeln — platform-agnostic CLI toolkit for livestreamers.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
#### CLI Commands
|
|
17
|
+
- `reeln --version` — show version, ffmpeg info, and installed plugin versions
|
|
18
|
+
- `reeln doctor` — comprehensive health check: ffmpeg, codecs, hardware acceleration, config, permissions
|
|
19
|
+
- `reeln config show` — display current configuration as JSON
|
|
20
|
+
- `reeln config doctor` — validate config, warn on issues
|
|
21
|
+
- `reeln game init` — initialize game workspace with sport-specific segment subdirectories
|
|
22
|
+
- `reeln game segment <N>` — merge replays in a segment directory into a highlight video
|
|
23
|
+
- `reeln game highlights` — merge all segment highlights into a full-game highlight reel
|
|
24
|
+
- `reeln game finish` — mark a game as finished with summary
|
|
25
|
+
- `reeln game prune` — remove generated artifacts from a finished game directory
|
|
26
|
+
- `reeln game event list` — list events with filters (`--segment`, `--type`, `--untagged`)
|
|
27
|
+
- `reeln game event tag` — tag an event with type, player, and metadata
|
|
28
|
+
- `reeln game event tag-all` — bulk-tag all events in a segment
|
|
29
|
+
- `reeln game compile` — compile raw event clips into a single video by criteria
|
|
30
|
+
- `reeln render short` — render a 9:16 short from a clip
|
|
31
|
+
- `reeln render preview` — fast low-res preview render
|
|
32
|
+
- `reeln render apply` — apply a named render profile to a clip (full-frame, no crop/scale)
|
|
33
|
+
- `reeln render reel` — assemble rendered shorts into a concatenated reel
|
|
34
|
+
- `reeln media prune` — scan and prune all finished game directories
|
|
35
|
+
- `reeln plugins list` — list installed plugins with version info
|
|
36
|
+
- `reeln plugins search` — search the plugin registry
|
|
37
|
+
- `reeln plugins info <name>` — show detailed plugin information
|
|
38
|
+
- `reeln plugins install <name>` — install a plugin from the registry with auto-enable
|
|
39
|
+
- `reeln plugins update [name]` — update a plugin or all installed plugins
|
|
40
|
+
- `reeln plugins enable <name>` / `reeln plugins disable <name>` — enable/disable plugins
|
|
41
|
+
|
|
42
|
+
#### Core Features
|
|
43
|
+
- Package skeleton: `pyproject.toml`, Makefile, `.coveragerc`, `pytest.ini`, `python -m reeln` support
|
|
44
|
+
- Structured logging module with JSON and human formatters
|
|
45
|
+
- Error hierarchy: `ReelnError` base with typed subclasses
|
|
46
|
+
- FFmpeg discovery with cross-platform support (PATH, brew, apt, choco), version checking (5.0+ minimum)
|
|
47
|
+
- Media probe helpers: duration, fps, resolution via ffprobe
|
|
48
|
+
- Deterministic ffmpeg command builders (concat, render) with golden test assertions
|
|
49
|
+
- `FFmpegRenderer` implementation with `render()` and `preview()` methods
|
|
50
|
+
- Config system: JSON loading, schema validation, `config_version`, XDG-compliant paths, env var overrides (`REELN_<SECTION>_<KEY>`), deep merge, atomic writes, named profiles
|
|
51
|
+
- Segment model: generic time division abstraction with sport alias registry (hockey, basketball, soccer, football, baseball, lacrosse, generic) and custom sport registration
|
|
52
|
+
- Game lifecycle: `GameInfo`, `GameState`, `GameEvent` models with JSON serialization, double-header auto-detection, `game.json` state tracking
|
|
53
|
+
- `GameEvent` model for first-class event tracking with UUID-based IDs, prefix matching, extensible metadata, and idempotent creation
|
|
54
|
+
- Render state tracking in `game.json` via `RenderEntry` with event auto-linking
|
|
55
|
+
- ShortConfig model with crop modes (pad, crop), output formats (vertical, square), anchor positions
|
|
56
|
+
- Filter graph builders: scale, pad, crop, speed, LUT, subtitle — composable and golden-tested
|
|
57
|
+
- Render profiles: named configuration sets for reusable rendering parameter overrides (speed, LUT, subtitle template, encoding)
|
|
58
|
+
- Multi-iteration rendering: run a clip through N render profiles sequentially and concatenate results
|
|
59
|
+
- Template engine: `{{key}}` placeholder substitution for `.ass` subtitle files
|
|
60
|
+
- `TemplateContext`, `TemplateProvider` protocol, `build_base_context()` for game/event context
|
|
61
|
+
- ASS subtitle helpers: `rgb_to_ass()`, `format_ass_time()`
|
|
62
|
+
- Bundled `goal_overlay` ASS subtitle template with dynamic font sizing and team-colored background
|
|
63
|
+
- `builtin:` prefix for `subtitle_template` in render profiles (e.g. `"builtin:goal_overlay"`)
|
|
64
|
+
- `build_overlay_context()` for computing overlay-specific template variables from event metadata
|
|
65
|
+
- `--player` and `--assists` CLI flags on `render short`, `render preview`, and `render apply` — populate overlay template variables without game event tagging; override event data when both are present
|
|
66
|
+
- Default `player-overlay` render profile and `goal` iteration mapping in bundled config
|
|
67
|
+
- `TeamProfile` model with metadata (logo, roster, colors, jersey colors, period length)
|
|
68
|
+
- Team profile management: load, save, list, delete with atomic writes
|
|
69
|
+
- Interactive team selection and game time prompting in `game init`
|
|
70
|
+
- `--game-time`, `--level`, `--period-length`, `--venue` options on `game init`
|
|
71
|
+
- `--debug` flag on game and render commands — writes pipeline debug artifacts with ffmpeg commands, filter chains, and metadata
|
|
72
|
+
- HTML debug index (`debug/index.html`) with summary table and per-operation sections
|
|
73
|
+
- `--dry-run` support across all destructive and render commands
|
|
74
|
+
- `PruneResult` model, `format_bytes()`, `find_game_dirs()` helpers
|
|
75
|
+
- `CompilationResult` model for compilation output tracking
|
|
76
|
+
- `questionary` as optional dependency (`pip install reeln[interactive]`)
|
|
77
|
+
|
|
78
|
+
#### Plugin System
|
|
79
|
+
- Plugin system foundation: lifecycle hooks, capability protocols, hook registry
|
|
80
|
+
- `Hook` enum with 11 lifecycle hooks: `PRE_RENDER`, `POST_RENDER`, `ON_CLIP_AVAILABLE`, `ON_EVENT_CREATED`, `ON_EVENT_TAGGED`, `ON_GAME_INIT`, `ON_GAME_FINISH`, `ON_HIGHLIGHTS_MERGED`, `ON_ERROR`, `ON_SEGMENT_START`, `ON_SEGMENT_COMPLETE`
|
|
81
|
+
- `HookRegistry` with safe emission — handler exceptions are caught and logged
|
|
82
|
+
- Capability protocols: `Uploader`, `MetadataEnricher`, `Notifier`, `Generator`
|
|
83
|
+
- Plugin orchestrator: sequential pipeline (Generator -> MetadataEnricher -> Uploader -> Notifier)
|
|
84
|
+
- Plugin loader: `discover_plugins()`, `load_plugin()`, `load_enabled_plugins()`, `activate_plugins()`
|
|
85
|
+
- Plugin config schema declaration with `ConfigField` and `PluginConfigSchema`
|
|
86
|
+
- Remote plugin registry with cache, search, install, update, and auto-enable
|
|
87
|
+
- `author` and `license` fields on plugin registry entries
|
|
88
|
+
- `ThrottledReader` for upload throughput limiting, `upload_lock()` for serialization
|
|
89
|
+
- `filelock>=3.0` dependency
|
|
90
|
+
|
|
91
|
+
#### CI/CD & Docs
|
|
92
|
+
- GitHub Actions CI workflow (Python 3.11/3.12/3.13 matrix, lint, type check, tests, docs build)
|
|
93
|
+
- GitHub Actions release workflow (tag-based PyPI publish via trusted publisher)
|
|
94
|
+
- CI and docs badges in README
|
|
95
|
+
- Documentation infrastructure: Sphinx + MyST, Furo theme, Read the Docs config
|
|
96
|
+
- Full docs site: install guide, quickstart tutorial, CLI reference, configuration guide, sports guide
|
|
97
|
+
|
|
98
|
+
### Fixed
|
|
99
|
+
- `render short --render-profile` now correctly resolves `subtitle_template` from the profile — previously the template was silently dropped in the single-profile path
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
- `--rink` CLI flag renamed to `--venue` for sport-agnostic terminology
|
|
103
|
+
- Segment merge and highlights merge output written to `paths.output_dir` for discoverability
|
|
104
|
+
- `period_length` moved from `TeamProfile` to `GameInfo`
|
|
105
|
+
- Full test suite with 100% line + branch coverage
|