You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add YouTube publisher skill and upload CLI (#4)
* feat: add YouTube publisher skill and upload CLI
Add scripts/youtube_publish.py, a YouTube Data API v3 CLI with OAuth
auth, resumable uploads, thumbnails, SRT captions, playlists, scheduled
publishing, status checks, and metadata updates. Uploads default to
private and support --dry-run previews.
Add the podguy-youtube-publisher skill and /publish-youtube prompt so pi
composes titles, descriptions, chapters, and tags from existing analysis
artifacts, plus a [youtube] profile section for show defaults and a
youtube uv dependency group. Wire the skill into the startup header and
add a smoke test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: address code review findings in youtube_publish.py
- carry defaultLanguage through videos.update so it is not wiped
- validate 5000-char description limit in the update path
- print 100% on the final upload chunk
- include video_id in playlist/thumbnail/caption failure messages
- re-apply 0600 mode after token refresh writes
- require seconds in --publish-at timestamps
- strip whitespace-only playlist_id profile values
- document update --description-file asymmetry and TOML fallback limits
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: address second-pass review findings
- make the TOML fallback parser quote-aware when stripping # comments so
hashtags in quoted values (e.g. description_footer) survive
- only enforce the 5000-char description limit in update when the
description is actually being changed
- cover the hashtag-footer case in the smoke test
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: AGENTS.md
+5-1Lines changed: 5 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
This repository is primarily operated through `pi` for podcast post-production work.
4
4
5
-
Default to the `podguy-post-production` workflow unless the user explicitly asks for something else. Use `podguy-clip-cutter` when the user asks to export or cut social clips.
5
+
Default to the `podguy-post-production` workflow unless the user explicitly asks for something else. Use `podguy-clip-cutter` when the user asks to export or cut social clips. Use `podguy-youtube-publisher` when the user asks to upload, schedule, or manage episodes on YouTube.
6
6
7
7
## Primary tasks
8
8
@@ -12,6 +12,7 @@ Default to the `podguy-post-production` workflow unless the user explicitly asks
12
12
- give editorial feedback such as cuts, highlights, weak sections, and insert opportunities
13
13
- cut selected highlight moments into review exports for TikTok, Reels, YouTube Shorts, trailers, or social posts
14
14
- draft publishing assets such as show notes, quote sheets, and proper noun review
15
+
- upload finished episodes to YouTube with metadata composed from analysis artifacts
15
16
16
17
## Podcast profile
17
18
@@ -28,6 +29,7 @@ Default to the `podguy-post-production` workflow unless the user explicitly asks
28
29
- skip the visual scanner for audio-only inputs
29
30
- use transcript evidence and timecodes whenever possible when giving editorial feedback
30
31
- treat generated clip media as review exports, not final mastered social edits
32
+
- never upload to YouTube without explicit user confirmation of the final metadata; default uploads to private
31
33
- use `scripts/download_sample_media.sh` when a real open-license video-podcast sample is helpful; keep downloaded samples under gitignored `dist/`
32
34
33
35
## Interaction guidance
@@ -55,10 +57,12 @@ For synthetic or test fixture inputs, default to a leaner evaluation mindset:
Copy file name to clipboardExpand all lines: README.md
+26-1Lines changed: 26 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,7 @@ Pi-first post-production tooling for podcast and video-podcast editors who want
12
12
- Scans video episodes for likely interstitials and non-host inserts.
13
13
- Generates chapters, clip candidates, cut reports, show notes, quotes, and proper noun checks.
14
14
- Cuts selected highlight ranges into review exports for TikTok, Reels, YouTube Shorts, trailers, or social posts.
15
+
- Uploads finished episodes to YouTube with metadata composed from analysis artifacts.
15
16
16
17
Generated transcripts, scans, thumbnails, notes, and clip exports go under gitignored `dist/` by default.
17
18
@@ -157,6 +158,29 @@ uv run python scripts/cut_clips.py \
157
158
158
159
The cutter writes generated media plus `manifest.json`. Vertical and square modes use center-crop framing, so treat them as review exports unless the framing has been checked.
159
160
161
+
### Publish to YouTube
162
+
163
+
One-time setup: create a Google Cloud project with the YouTube Data API v3 enabled, create a Desktop-app OAuth client, save the JSON to `~/.config/podguy/youtube/client_secret.json`, then authenticate:
164
+
165
+
```bash
166
+
uv sync --group youtube
167
+
uv run --group youtube python scripts/youtube_publish.py auth
168
+
```
169
+
170
+
Upload an episode (private by default; use `--dry-run` first to preview the request):
171
+
172
+
```bash
173
+
uv run --group youtube python scripts/youtube_publish.py upload \
Other subcommands cover thumbnails, SRT captions, playlists, scheduled publishing (`--publish-at`), status checks, and metadata updates. Defaults like privacy, category, tags, and a description footer come from the `[youtube]` section of `podguy.toml`.
181
+
182
+
Each upload costs 1600 of the default 10000 daily YouTube API quota units, and videos uploaded through unverified API projects may stay locked private until the project passes a YouTube API audit.
183
+
160
184
### Download real sample media
161
185
162
186
Use the Cordkillers open-license video-podcast excerpt for local evaluation:
description: Upload an episode video to YouTube with metadata drafted from analysis artifacts
3
+
---
4
+
5
+
Publish to YouTube: $@
6
+
7
+
Workflow:
8
+
9
+
1. Identify the episode slug and the final episode video file (a real export, not a review cut).
10
+
2. Check auth: if `~/.config/podguy/youtube/token.json` is missing, walk through the one-time setup in the `podguy-youtube-publisher` skill before anything else.
11
+
3. Draft metadata from existing artifacts and the `[youtube]` section of `podguy.toml`:
12
+
- Title (max 100 characters) from show notes or the user's wording.
13
+
- Description body written to `dist/analysis/<slug>/youtube-description.md`.
14
+
- Chapters from `dist/analysis/<slug>/chapters.md` when present (first chapter must start at `00:00`).
15
+
- Tags from proper-noun review or profile `default_tags`.
16
+
4. Show the user the drafted metadata and confirm privacy/timing (private default, unlisted, public, or `--publish-at`).
17
+
5. Preview the request with `--dry-run`, then upload:
0 commit comments