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
Copy file name to clipboardExpand all lines: .claude/commands/ai-news-digest-yt.md
+51-9Lines changed: 51 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,14 @@ You are an AI news digest agent specializing in YouTube content from @AIDailyBri
2
2
3
3
Today's date is {{date}}.
4
4
5
+
## Step 0: Load State & Identify Incomplete Work
6
+
7
+
Read `.state/last-digest-yt.json` if it exists. Parse the `video_status` dict (treat as empty `{}` if missing — backward compatible with old state files).
8
+
9
+
For each entry in `video_status` where `completed` is `false` (or missing), note which steps are already `true` — these will be **skipped** when processing that video later. Incomplete videos are NOT in `posted_video_ids`, so `fetch_recent_videos.py` will re-fetch them automatically.
10
+
11
+
After each per-video step completes (Steps 2–6), **immediately** save state with that step marked `true` in `video_status`. This ensures progress is preserved if the pipeline crashes mid-run.
12
+
5
13
## Step 1: Fetch Recent Videos
6
14
7
15
Run the fetch script to get videos from the last 24 hours:
Capture the stdout output as the transcript text. If a video's transcript fails, log a warning and skip that video — continue with others.
36
44
45
+
After each successful transcript extraction, update `video_status[VIDEO_ID].steps.transcript = true` and save state. If Step 0 shows `transcript: true` for a video, skip transcript extraction and reuse the existing transcript file from `digest-yt/{{date}}/`.
46
+
37
47
## Step 2.5: Download Thumbnails
38
48
39
49
For each video, download the YouTube thumbnail to the digest directory:
If a thumbnail download fails, continue without it — the summary will just lack an image.
51
61
62
+
After each successful thumbnail download, update `video_status[VIDEO_ID].steps.thumbnail = true` and save state. Skip if already `true` from Step 0.
63
+
52
64
## Step 3: Summarize (Claude does this)
53
65
54
66
For each video with a successful transcript, YOU (Claude) will:
@@ -58,15 +70,16 @@ For each video with a successful transcript, YOU (Claude) will:
58
70
-**English summary**: 2-3 sentences covering the key points
59
71
-**繁體中文摘要**: 2-3 sentences in Traditional Chinese covering the same points
60
72
61
-
3. Save each summary as markdown to `digest-yt/{{date}}/VIDEO_ID.md` with this format:
73
+
3. Save each summary as markdown to `digest-yt/{{date}}/VIDEO_ID.md` with this format. Convert `upload_date` from YYYYMMDD → YYYY-MM-DD for display. Only include the **Last Modified** line if `modified_date` is present and different from `upload_date`:
@@ -79,32 +92,36 @@ For each video with a successful transcript, YOU (Claude) will:
79
92
80
93
4. Also create two combined digest files. **Each video section MUST include its thumbnail image** (use relative path). If the thumbnail file doesn't exist, omit the image line for that video.
81
94
82
-
**`digest-yt/{{date}}/summary_en.md`** — All English summaries combined:
95
+
**`digest-yt/{{date}}/summary_en.md`** — All English summaries combined. Include `*Published: YYYY-MM-DD*` (and `| Modified: YYYY-MM-DD` only when `modified_date` is present) below each video heading:
83
96
```markdown
84
97
# AI Daily Brief - YouTube Digest {{date}}
85
98
86
99
## Video Title 1
87
100

101
+
*Published: 2026-03-12 | Modified: 2026-03-13*
88
102
89
103
2-3 sentence English summary...
90
104
91
105
## Video Title 2
92
106

107
+
*Published: 2026-03-12*
93
108
94
109
2-3 sentence English summary...
95
110
```
96
111
97
-
**`digest-yt/{{date}}/summary_zh-tw.md`** — All zh-TW summaries combined:
112
+
**`digest-yt/{{date}}/summary_zh-tw.md`** — All zh-TW summaries combined, same date format:
98
113
```markdown
99
114
# AI Daily Brief - YouTube 摘要 {{date}}
100
115
101
116
## Video Title 1
102
117

118
+
*Published: 2026-03-12 | Modified: 2026-03-13*
103
119
104
120
繁體中文摘要...
105
121
106
122
## Video Title 2
107
123

124
+
*Published: 2026-03-12*
108
125
109
126
繁體中文摘要...
110
127
```
@@ -114,6 +131,8 @@ Create the `digest-yt/{{date}}/` directory first:
114
131
mkdir -p "digest-yt/{{date}}"
115
132
```
116
133
134
+
After writing summaries for each video, update `video_status[VIDEO_ID].steps.summary = true` and save state. Skip summary generation for videos where `summary: true` from Step 0 — reuse existing markdown files.
135
+
117
136
## Step 4: Generate HTML and PDF
118
137
119
138
For each language (en, zh-tw), build HTML then PDF:
If PDF generation fails, note this and continue — you'll post without PDF links.
132
151
152
+
After successful HTML+PDF generation, update `video_status[VIDEO_ID].steps.html = true` and `video_status[VIDEO_ID].steps.pdf = true` for all videos, then save state. Skip if already `true` from Step 0.
Capture the download URLs from stdout. If upload fails, continue without links.
143
164
165
+
After successful uploads, update `video_status[VIDEO_ID].steps.b2_upload = true` for all videos, then save state. Skip if already `true` from Step 0.
166
+
144
167
## Step 6: Post to Slack
145
168
146
169
Build a Slack mrkdwn message and post it. Use this exact format:
@@ -184,9 +207,11 @@ slack_send "$MSG"
184
207
185
208
If Slack fails, retry once. If it fails again, save to `.state/failed-digest-yt-{{date}}.md`.
186
209
187
-
## Step 7: Save State
210
+
After successful Slack post, update `video_status[VIDEO_ID].steps.slack_post = true` and `video_status[VIDEO_ID].completed = true` for each video, then save state.
211
+
212
+
## Step 7: Final State Save
188
213
189
-
Write `.state/last-digest-yt.json`:
214
+
Write `.state/last-digest-yt.json` with the full schema. Only add a video to `posted_video_ids` when its `completed` flag is `true` (all steps including slack_post succeeded):
Merge with existing state (keep max 30 video IDs from current + previous runs).
243
+
Merge with existing state. Keep max 30 entries in both `posted_video_ids` and `video_status` (trim oldest together). Backward compatible: if existing state lacks `video_status`, treat as empty `{}`.
203
244
204
245
```bash
205
246
mkdir -p .state
206
247
```
207
248
208
-
**Always save state**, even on partial failure.
249
+
**Always save state**, even on partial failure. Incomplete videos stay in `video_status` (with `completed: false`) but are NOT added to `posted_video_ids` — so they will be re-fetched on the next run.
209
250
210
251
## Error Handling Summary
211
252
@@ -215,3 +256,4 @@ mkdir -p .state
215
256
- B2 upload fails → post without download links, files stay local in `digest-yt/`
216
257
- Slack fails → retry once, then save to `.state/failed-digest-yt-{{date}}.md`
217
258
- State always saved even on partial failure
259
+
-**Resume on retry**: incomplete videos stay in `video_status` but not in `posted_video_ids` → re-fetched next run → completed steps skipped via `video_status.steps` booleans
0 commit comments