Skip to content

Commit 5017fbf

Browse files
JRemitzclaude
andauthored
feat: v0.0.38 — render queue, logo overlay, plugin auth (#20)
* chore: add TikTok plugin to registry Co-Authored-By: Claude <noreply@anthropic.com> * docs: add smart zoom section and reeln-dock callout to README Links to the Medium article, live debug example, and adds the debug-preview screenshot for the smart zoom feature. Co-Authored-By: Claude <noreply@anthropic.com> * feat: team logo overlay on goal shorts Resolve team logo from TeamProfile and overlay it on the right side of the goal overlay box. Logo is scaled to 80% of box height, positioned right-aligned with margin. ASS text lines are clipped so they don't run under the logo, and font sizing adapts to the reduced text area. Supports all four filter chain paths: simple pad/crop, smart pad, speed segments, and speed segments + smart pad. Multi-input ffmpeg commands use -loop 1 for the static image and explicit -map 0:a? to avoid audio stream selection issues. Co-Authored-By: Claude <noreply@anthropic.com> * feat: render queue for staged render-then-publish workflow Decouples rendering from publishing with a new --queue flag on render short and render apply. Rendered clips are queued for review with auto-generated title/description, then selectively published to individual platform targets (YouTube, Instagram, TikTok, etc.) without re-rendering. New CLI: reeln queue list/show/edit/publish/publish-all/remove/targets New hooks: ON_QUEUE, ON_PUBLISH Supports both Uploader protocol and POST_RENDER hook-based plugins. Per-item config_profile ensures correct plugin settings at publish time. Co-Authored-By: Claude <noreply@anthropic.com> * feat: plugin auth, uninstall, docs update, release v0.0.38 Add `reeln plugins auth` for credential verification and token renewal, `reeln plugins uninstall` for clean plugin removal, and the Authenticator capability protocol. Update all documentation for the release: changelog, CLI reference, overlay templates guide, README, and architecture docs. Bump version to 0.0.38. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 383796b commit 5017fbf

51 files changed

Lines changed: 6036 additions & 75 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/rules/plugin-development.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,25 @@ class MyPlugin:
3737

3838
## Hook System
3939

40-
**Hook enum** (`reeln.plugins.hooks.Hook`) — 13 lifecycle hooks:
40+
**Hook enum** (`reeln.plugins.hooks.Hook`) — 16 lifecycle hooks:
4141

4242
| Hook | Emitted when |
4343
|------|-------------|
4444
| `PRE_RENDER` | Before a render operation starts |
45-
| `POST_RENDER` | After a render completes |
45+
| `POST_RENDER` | After a render completes (fast-track publish) |
4646
| `ON_CLIP_AVAILABLE` | A new clip file is ready |
4747
| `ON_EVENT_CREATED` | A new event is created |
4848
| `ON_EVENT_TAGGED` | An event is tagged/categorized |
4949
| `ON_GAME_INIT` | `reeln game init` sets up a new game |
5050
| `ON_GAME_READY` | After all `ON_GAME_INIT` handlers complete — plugins read shared context from init phase |
5151
| `ON_GAME_FINISH` | `reeln game finish` finalizes a game |
52+
| `ON_POST_GAME_FINISH` | After all `ON_GAME_FINISH` handlers complete |
5253
| `ON_HIGHLIGHTS_MERGED` | Segment highlights are merged into a reel |
5354
| `ON_SEGMENT_START` | A new segment begins |
5455
| `ON_SEGMENT_COMPLETE` | A segment finishes |
5556
| `ON_FRAMES_EXTRACTED` | Frames extracted from a clip for smart zoom analysis |
57+
| `ON_QUEUE` | A render result is added to the queue (`--queue` flag) |
58+
| `ON_PUBLISH` | A queued item is published to an external target |
5659
| `ON_ERROR` | An error occurs during any operation |
5760

5861
**HookContext** — frozen dataclass passed to every handler:
@@ -92,6 +95,7 @@ Plugins can implement typed protocols for specific capabilities (`reeln.plugins.
9295
| `MetadataEnricher` | `enrich(event_data) -> dict` | Enrich event metadata |
9396
| `Notifier` | `notify(message, *, metadata) -> None` | Send notifications |
9497
| `Generator` | `generate(context) -> GeneratorResult` | Generate media assets |
98+
| `Authenticator` | `auth_check() -> list[AuthCheckResult]`, `auth_refresh() -> list[AuthCheckResult]` | Test credentials and refresh tokens |
9599

96100
## Config Schema
97101

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/),
66
and this project adheres to [Semantic Versioning](https://semver.org/).
77

8+
## [0.0.38] - 2026-04-07
9+
10+
### Added
11+
- `reeln queue` command group for staged render-then-publish workflow: list, show, edit, publish, publish-all, remove, targets
12+
- `--queue` / `-q` flag on `render short` and `render apply` — renders but queues for review instead of publishing immediately
13+
- Per-target publish tracking — publish to YouTube, review, then selectively push to Instagram/TikTok without re-rendering
14+
- `ON_QUEUE` and `ON_PUBLISH` lifecycle hooks for plugin integration with the queue workflow
15+
- Centralized metadata generation (`core/metadata.py`) — auto-generates title and description from game/event context
16+
- `QueueItem` stores config profile name — `queue publish` loads the same plugin settings used at queue time
17+
- Queue persistence via `render_queue.json` (per-game directory) with advisory central index for cross-game listing
18+
- `QueueError` exception class for queue operation errors
19+
- Team logo overlay on goal shorts — resolves logo from `TeamProfile.logo_path`, scales to 80% of box height, right-aligned with text clipping. Supports all four filter chain paths (simple pad/crop, smart pad, speed segments, speed segments + smart pad)
20+
- `reeln plugins auth` command — test authentication for plugins (`--json` for machine output, `--refresh` to force reauthentication)
21+
- `reeln plugins uninstall` command — uninstall a plugin and remove from config (`--force` to skip confirmation, `--dry-run` to preview)
22+
- `Authenticator` capability protocol — plugins implement `auth_check()` and `auth_refresh()` for credential verification and token renewal
23+
- `AuthCheckResult`, `AuthStatus`, `PluginAuthReport` models (`reeln/models/auth.py`) for structured auth status reporting
24+
825
## [0.0.37] - 2026-04-03
926

1027
### Added

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ reeln doctor # checks ffmpeg, codecs, config, permissions, plugins
5858
- **Render profiles** — save and reuse rendering settings, chain them with iterations
5959
- **Smart zoom** — AI-powered tracking that follows the action (via plugin)
6060
- **Player overlays** — roster-aware goal overlays with jersey number lookup
61+
- **Render queue** — stage renders for review, then selectively publish to YouTube, Instagram, TikTok
62+
- **Team logo overlays** — automatic logo placement on goal shorts from team profiles
6163
- **Plugin architecture** — lifecycle hooks for YouTube, Instagram, cloud uploads, and more
6264
- **Flexible configuration** — JSON config, XDG paths, env var overrides, named profiles
6365
- **Cross-platform** — macOS, Linux, Windows
@@ -85,6 +87,8 @@ reeln game finish
8587

8688
See the [examples](examples/) for detailed walkthroughs of every workflow.
8789

90+
> Looking for a GUI? [reeln dock](https://github.com/StreamnDad/reeln-dock) is a cross-platform desktop companion for reeln — visual render profiles, clip review, and game management without touching the terminal. Coming soon.
91+
8892
## Supported sports
8993

9094
| Sport | Segment name | Count | Example directories |
@@ -128,6 +132,18 @@ See the [examples](examples/) for detailed walkthroughs of every workflow.
128132
| `reeln render apply` | Apply a render profile (full-frame, no crop) |
129133
| `reeln render reel` | Assemble rendered shorts into a reel |
130134

135+
### Queue
136+
137+
| Command | Description |
138+
|---|---|
139+
| `reeln queue list` | List queued render items |
140+
| `reeln queue show <ID>` | Show detailed queue item info |
141+
| `reeln queue edit <ID>` | Edit title/description before publishing |
142+
| `reeln queue publish <ID>` | Publish to one or all targets (`--target <name>`) |
143+
| `reeln queue publish-all` | Publish all rendered items |
144+
| `reeln queue remove <ID>` | Soft-delete queue item |
145+
| `reeln queue targets` | List available publish targets |
146+
131147
### Configuration
132148

133149
| Command | Description |
@@ -147,6 +163,8 @@ See the [examples](examples/) for detailed walkthroughs of every workflow.
147163
| `reeln plugins list` | List installed plugins |
148164
| `reeln plugins enable <name>` | Enable a plugin |
149165
| `reeln plugins disable <name>` | Disable a plugin |
166+
| `reeln plugins uninstall <name>` | Uninstall a plugin |
167+
| `reeln plugins auth` | Test plugin authentication |
150168

151169
## Configuration
152170

@@ -161,6 +179,20 @@ reeln uses a layered JSON config system:
161179
reeln config show
162180
```
163181

182+
## Smart zoom — AI-powered action tracking
183+
184+
`reeln render short --smart` uses the [OpenAI plugin](https://github.com/StreamnDad/reeln-plugin-openai) to analyse extracted frames and track the action — dynamically cropping and panning the camera to follow the play in your 9:16 short. Read [What happened when I let AI edit my youth hockey videos](https://streamn-dad.medium.com/what-happened-when-i-let-ai-edit-my-youth-hockey-videos-d7ece1883905) for the full story.
185+
186+
Add `--debug` to see exactly what the AI sees: annotated frames with crosshair tracking, crop regions, the full zoom path, and every ffmpeg filter chain.
187+
188+
[Live debug example](https://streamn.dad/examples/reeln-debug/) — real game clip with 16-frame smart zoom tracking.
189+
190+
<p align="center">
191+
<a href="https://streamn.dad/examples/reeln-debug/">
192+
<img src="https://raw.githubusercontent.com/StreamnDad/reeln-cli/main/assets/debug-preview.png" alt="Smart zoom debug — annotated frame showing crosshair tracking and crop region" width="600">
193+
</a>
194+
</p>
195+
164196
## Documentation
165197

166198
- [Full documentation](https://reeln-cli.readthedocs.io) — install, guides, CLI reference

assets/debug-preview.png

1.83 MB
Loading

docs/cli/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ reeln provides a hierarchical command structure organized by domain.
2020
| `reeln render` | Video rendering: short, preview, reel | Available | {doc}`render` |
2121
| `reeln media` | Media management: prune | Available | {doc}`media` |
2222
| `reeln plugins` | Plugin management: list, enable, disable | Available | {doc}`plugins` |
23+
| `reeln queue` | Render queue: list, show, edit, publish, remove, targets | Available | {doc}`queue` |
2324

2425
## Global options
2526

docs/cli/plugins.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,64 @@ reeln plugins disable <NAME>
142142

143143
Adds the plugin to the `plugins.disabled` list and removes it from `plugins.enabled` in your config file.
144144

145+
### `reeln plugins uninstall`
146+
147+
Uninstall a plugin and remove it from config.
148+
149+
```bash
150+
reeln plugins uninstall <NAME>
151+
reeln plugins uninstall <NAME> --force
152+
reeln plugins uninstall <NAME> --dry-run
153+
```
154+
155+
| Argument | Description |
156+
|---|---|
157+
| `NAME` | Plugin name to uninstall |
158+
159+
| Option | Description |
160+
|---|---|
161+
| `--force`, `-f` | Skip confirmation prompt |
162+
| `--dry-run` | Preview the uninstall command without executing |
163+
| `--installer` | Force a specific installer (`pip` or `uv`) |
164+
165+
Prompts for confirmation before uninstalling. Removes the plugin from `plugins.enabled` and adds it to `plugins.disabled` in your config.
166+
167+
### `reeln plugins auth`
168+
169+
Test authentication for plugins, or force reauthentication.
170+
171+
```bash
172+
reeln plugins auth
173+
reeln plugins auth google
174+
reeln plugins auth google --refresh
175+
reeln plugins auth --json
176+
```
177+
178+
| Argument | Description |
179+
|---|---|
180+
| `NAME` | Plugin name (empty = test all plugins with auth support) |
181+
182+
| Option | Description |
183+
|---|---|
184+
| `--refresh`, `-r` | Force reauthentication (requires a plugin name) |
185+
| `--json` | Output as JSON |
186+
| `--profile` | Named config profile |
187+
| `--config` | Explicit config file path |
188+
189+
Checks each plugin that implements the `Authenticator` protocol. Reports per-service status:
190+
191+
| Status | Badge | Meaning |
192+
|---|---|---|
193+
| `ok` | `authenticated` | Credentials are valid |
194+
| `warn` | `warning` | Credentials work but with caveats (e.g., missing scopes) |
195+
| `expired` | `expired` | Token has expired |
196+
| `not_configured` | `not configured` | No credentials found |
197+
| `fail` | `failed` | Authentication check failed |
198+
199+
With `--refresh`, the plugin's `auth_refresh()` method is called to force token renewal (e.g., OAuth refresh flow).
200+
201+
Exits with code 1 if any result is `fail` or `expired`.
202+
145203
## Plugin registry
146204

147205
reeln maintains a remote plugin registry that lists available plugins, their packages, and capabilities. The registry is fetched from GitHub and cached locally for 1 hour.
@@ -189,6 +247,9 @@ reeln exposes lifecycle hooks that plugins can subscribe to:
189247
| `ON_HIGHLIGHTS_MERGED` | After game highlights are merged |
190248
| `ON_SEGMENT_START` | Before segment file I/O begins |
191249
| `ON_SEGMENT_COMPLETE` | After segment merge and state update |
250+
| `ON_FRAMES_EXTRACTED` | After frames are extracted for smart zoom analysis |
251+
| `ON_QUEUE` | After a render result is added to the queue (`--queue` flag) |
252+
| `ON_PUBLISH` | After a queued item is published to an external target |
192253
| `ON_ERROR` | When an error occurs in core operations |
193254

194255
Hooks receive a `HookContext` with three fields:
@@ -212,6 +273,7 @@ Plugins can implement typed capability interfaces:
212273
- **Uploader** — upload rendered media to external services (YouTube, social media, cloud storage)
213274
- **MetadataEnricher** — enrich event metadata with additional information (LLM descriptions, statistics)
214275
- **Notifier** — send notifications when events occur (Slack, Discord, email)
276+
- **Authenticator** — test credentials and refresh tokens (`auth_check()` returns `list[AuthCheckResult]`, `auth_refresh()` forces token renewal)
215277

216278
## Orchestration pipeline
217279

docs/cli/queue.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# reeln queue
2+
3+
Render queue management for staged render-then-publish workflows.
4+
5+
## Overview
6+
7+
The render queue decouples rendering from publishing. Instead of `POST_RENDER`
8+
plugin hooks firing immediately after a render, the `--queue` flag on
9+
`render short` or `render apply` saves the rendered output to a queue for
10+
review. You can then edit metadata (title, description), selectively publish
11+
to specific platforms, and track per-target publish status.
12+
13+
Queue files are stored per-game as `render_queue.json` alongside `game.json`.
14+
15+
## Commands
16+
17+
### `reeln queue list`
18+
19+
List queued render items.
20+
21+
```bash
22+
reeln queue list [OPTIONS]
23+
```
24+
25+
| Option | Description |
26+
|---|---|
27+
| `--game-dir`, `-g` | Game directory (default: cwd) |
28+
| `--all`, `-a` | List across all games (uses central index) |
29+
| `--status`, `-s` | Filter by status: rendered, published, partial, failed |
30+
31+
Removed items are hidden by default.
32+
33+
### `reeln queue show`
34+
35+
Show detailed info for a queue item.
36+
37+
```bash
38+
reeln queue show <ID> [OPTIONS]
39+
```
40+
41+
| Option | Description |
42+
|---|---|
43+
| `--game-dir`, `-g` | Game directory (default: cwd) |
44+
45+
Displays output path, duration, file size, game context, player info, render
46+
profile, publish targets with status and URLs.
47+
48+
ID supports prefix matching (e.g., `abc` matches `abc123def456`).
49+
50+
### `reeln queue edit`
51+
52+
Edit title or description before publishing.
53+
54+
```bash
55+
reeln queue edit <ID> [OPTIONS]
56+
```
57+
58+
| Option | Description |
59+
|---|---|
60+
| `--title`, `-t` | New title |
61+
| `--description`, `-d` | New description |
62+
| `--game-dir`, `-g` | Game directory (default: cwd) |
63+
64+
At least one of `--title` or `--description` is required.
65+
66+
### `reeln queue publish`
67+
68+
Publish a queue item to one or all targets.
69+
70+
```bash
71+
reeln queue publish <ID> [OPTIONS]
72+
```
73+
74+
| Option | Description |
75+
|---|---|
76+
| `--target`, `-t` | Publish to specific target only (e.g., `google`, `meta`) |
77+
| `--game-dir`, `-g` | Game directory (default: cwd) |
78+
| `--profile` | Override config profile (default: profile stored at queue time) |
79+
| `--config` | Explicit config file path |
80+
81+
Without `--target`, publishes to all pending targets. Each target is tracked
82+
independently — you can publish to YouTube first, review, then push to
83+
Instagram later.
84+
85+
The config profile stored in the queue item is used by default, ensuring the
86+
same plugin settings (API keys, channel IDs, etc.) apply. Use `--profile` to
87+
override.
88+
89+
### `reeln queue publish-all`
90+
91+
Publish all rendered items in the queue.
92+
93+
```bash
94+
reeln queue publish-all [OPTIONS]
95+
```
96+
97+
| Option | Description |
98+
|---|---|
99+
| `--game-dir`, `-g` | Game directory (default: cwd) |
100+
| `--profile` | Named config profile |
101+
| `--config` | Explicit config file path |
102+
103+
Only items with status `rendered` are published. Items already published,
104+
failed, or removed are skipped.
105+
106+
### `reeln queue remove`
107+
108+
Soft-delete a queue item.
109+
110+
```bash
111+
reeln queue remove <ID> [OPTIONS]
112+
```
113+
114+
| Option | Description |
115+
|---|---|
116+
| `--game-dir`, `-g` | Game directory (default: cwd) |
117+
118+
Marks the item as removed. Does not delete the rendered file.
119+
120+
### `reeln queue targets`
121+
122+
List available publish targets from loaded uploader plugins.
123+
124+
```bash
125+
reeln queue targets [OPTIONS]
126+
```
127+
128+
| Option | Description |
129+
|---|---|
130+
| `--profile` | Named config profile |
131+
| `--config` | Explicit config file path |
132+
133+
Targets are discovered from installed plugins that implement the `Uploader`
134+
capability protocol.
135+
136+
## Status lifecycle
137+
138+
Queue items progress through these statuses:
139+
140+
| Status | Meaning |
141+
|---|---|
142+
| `rendered` | Render complete, not yet published |
143+
| `publishing` | Publish in progress |
144+
| `published` | All targets published successfully |
145+
| `partial` | Some targets published, others pending or failed |
146+
| `failed` | All target publishes failed |
147+
| `removed` | Soft-deleted |
148+
149+
Each publish target has its own status: `pending`, `published`, `failed`, or
150+
`skipped`.
151+
152+
## Examples
153+
154+
```bash
155+
# Render and queue
156+
reeln render short clip.mkv --queue --profile tournament-stream
157+
158+
# Review what's queued
159+
reeln queue list
160+
reeln queue show abc123
161+
162+
# Fix the title
163+
reeln queue edit abc123 --title "Smith Goal - North vs South"
164+
165+
# Publish to YouTube first
166+
reeln queue publish abc123 --target google
167+
168+
# Review the YouTube upload, then push to Instagram
169+
reeln queue publish abc123 --target meta
170+
171+
# See all available targets
172+
reeln queue targets
173+
```

0 commit comments

Comments
 (0)