Not in the top 1,000 by GitHub stars

zarazhangrui/youtube-to-ebook

Claude skill for turning YouTube transcripts from your favorite channels into EPUB ebooks, delivered to your email inbox regularly

History

Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.

View weekly changes

SKILL.md

Week of Nov 2, 2026 · +0 / −0 lines

Before Network or broad shell → After Network or broad shell

7f67fd6b55a2 → 7f67fd6b55a2

Diff text is unavailable under the recorded licenses. Line counts and the GitHub link remain available.

Compare on GitHub

Week of Oct 26, 2026 · Line counts unavailable

Before Not checked yet → After Network or broad shell

First observation → 7f67fd6b55a2

No earlier version was observed for comparison.

Compare on GitHub

View on GitHubAdd to my skills

Verified commit 7f67fd6b55a272012df3767cf6d8c54bd2d7a9f3

586GitHub stars
2stars in 7 days
1skill in this repository
0commits in 30 days

Heat

2.4
  • Star growth, last 7 daysNot available
  • Star growth, last 24 hoursNot available
  • Rank movement, last 7 daysNot available
  • Commits, last 30 daysNot available
  • Accounts asking about it through MCP, last 7 daysNot available
  • Hot votes this weekNot available

Heat never changes the order by stars, and sponsorship never touches it. How heat works

Stars over time

Oct 25, 2026Nov 6, 2026587

30-day change not yet available: not enough history.

Individual skills in this repository

How it works

youtube-to-ebook

When your agent uses it

Transform YouTube videos into beautifully formatted ebook articles with transcripts

What it loads into context

Frontmatter

20 tokens

Always available to the agent

SKILL.md

1,184 tokens

When the skill is activated

Reference documents

802 tokens

Loaded on request

Token counts are estimates. Scripts run separately; they are not counted as reference context.

The playbook

  1. What This Skill Does
  2. Quick Start
  3. Requirements
  4. Commands
  5. Key Files
  6. Known Pitfalls & Solutions
  7. Customization
  8. Workflow
  9. Example Output

Scripts executed separately

  • dashboard.py
  • get_transcripts.py
  • get_videos.py
  • launch_dashboard.command
  • main.py
  • run_newsletter.sh
  • send_email.py
  • video_tracker.py
  • write_articles.py

Files

  • .env.exampleasset577 bytes
  • .github/workflows/newsletter.ymlasset1,547 bytes
  • .gitignoreasset204 bytes
  • README.mddoc3,436 bytes
  • SKILL.mdcore5,135 bytes
  • SKILL.mdcore5,135 bytes
  • SKILL.mdcore5,135 bytes
  • SKILL.mdcore5,135 bytes
  • SKILL.mdcore5,135 bytes
  • com.youtube.newsletter.dashboard.plistasset1,102 bytes
  • com.youtube.newsletter.plistasset1,028 bytes
  • dashboard.pyruns27,677 bytes
  • get_transcripts.pyruns4,829 bytes
  • get_videos.pyruns4,807 bytes
  • launch_dashboard.commandruns179 bytes
  • main.pyruns2,323 bytes
  • requirements.txtdoc99 bytes
  • run_newsletter.shruns578 bytes
  • send_email.pyruns11,820 bytes
  • video_tracker.pyruns2,361 bytes
  • write_articles.pyruns3,791 bytes

No excerpt is shown for this license. Read the source on GitHub.

View the complete source on GitHub

Skills included

  • youtube-to-ebook

Repository facts

License
No license detected
Created
Jan 21, 2026
Last pushed
Jan 28, 2026
Forks
122
Open issues
2
Project activity
Slowing

Before you install

Network or broad shell

Automated signals, not a guarantee

Checked Nov 6, 2026

Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.

Show 4 notes
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
Show all 74 signals by file

.env.example

  • Access to secretsline 2
    [Credential-related source omitted]
  • Network accessline 4
    # YouTube Data API Key (free from Google Cloud Console) # Get it at: https://console.cloud.google.com/apis/credentials
  • Network accessline 5
    # Get it at: https://console.cloud.google.com/apis/credentials
  • Access to secretsline 6
    [Credential-related source omitted]
  • Network accessline 8
    # Anthropic API Key (for Claude) # Get it at: https://console.anthropic.com/
  • Network accessline 9
    # Get it at: https://console.anthropic.com/
  • Access to secretsline 10
    [Credential-related source omitted]
  • Network accessline 12
    # Gmail credentials (optional - for email delivery) # Create an App Password at: https://myaccount.google.com/apppasswords
  • Network accessline 13
    # Create an App Password at: https://myaccount.google.com/apppasswords

.github/workflows/newsletter.yml

  • Access to secretsline 38
    [Credential-related source omitted]
  • Access to secretsline 39
    [Credential-related source omitted]
  • Access to secretsline 42
    [Credential-related source omitted]

.gitignore

  • Access to secretsline 2
    [Credential-related source omitted]

README.md

  • Network accessline 18
    git clone https://github.com/YOUR_USERNAME/youtube-to-ebook.git
  • Access to secretsline 25
    [Credential-related source omitted]
  • Access to secretsline 26
    [Credential-related source omitted]
  • Network accessline 44
    ### YouTube Data API (Free) 1. Go to [Google Cloud Console](https://console.cloud.google.com/)
  • Network accessline 45
    1. Go to [Google Cloud Console](https://console.cloud.google.com/)
  • Network accessline 51
    ### Anthropic API 1. Go to [Anthropic Console](https://console.anthropic.com/)
  • Network accessline 52
    1. Go to [Anthropic Console](https://console.anthropic.com/)
  • Network accessline 96
    | Shorts not filtered by duration | Check `/shorts/` URL pattern | | Search API not chronological | Use uploads playlist instead | | Transcript API syntax changed | Use instance method `ytt_api.fetch()` |
  • Network accessline 97
    | Search API not chronological | Use uploads playlist instead | | Transcript API syntax changed | Use instance method `ytt_api.fetch()` | | Cloud servers blocked | Run locally, not GitHub Actions |
  • Network accessline 98
    | Transcript API syntax changed | Use instance method `ytt_api.fetch()` |
  • Access to secretsline 116
    [Credential-related source omitted]

SKILL.md

  • Access to secretsline 51
    [Credential-related source omitted]
  • Network accessline 61
    def is_youtube_short(video_id):     shorts_url = f"https://www.youtube.com/shorts/{video_id}"     response = requests.head(shorts_url, allow_redirects=True, timeout=5)
  • Network accessline 62
    shorts_url = f"https://www.youtube.com/shorts/{video_id}"     response = requests.head(shorts_url, allow_redirects=True, timeout=5)     return "/shorts/" in response.url
  • Network accessline 63
    response = requests.head(shorts_url, allow_redirects=True, timeout=5)
  • Network accessline 94
    ytt_api = YouTubeTranscriptApi() transcript = ytt_api.fetch(video_id)
  • Network accessline 95
    transcript = ytt_api.fetch(video_id)

com.youtube.newsletter.dashboard.plist

  • Network accessline 1
    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  • Network accessline 2
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

com.youtube.newsletter.plist

  • Network accessline 1
    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  • Network accessline 2
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

dashboard.py

  • Executable scriptline 1
    Executable file
  • Network accessline 35
    st.markdown(""" <style>     @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500&family=Sora:wght@300;400;500;600&display=swap');
  • Network accessline 37
    @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500&family=Sora:wght@300;400;500;600&display=swap');
  • Network accessline 667
    new_input = st.text_input(                 "Channel URL or handle",                 placeholder="https://youtube.com/@channelname or @channelname",
  • Network accessline 668
    "Channel URL or handle",                 placeholder="https://youtube.com/@channelname or @channelname",                 label_visibility="collapsed"
  • Network accessline 669
    placeholder="https://youtube.com/@channelname or @channelname",
  • Network accessline 832
    st.markdown(f"[Watch on YouTube](https://www.youtube.com/watch?v={video_id})")

get_transcripts.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 12
    [Credential-related source omitted]
  • Access to secretsline 14
    [Credential-related source omitted]
  • Network accessline 17
    SUPADATA_TRANSCRIPT_URL = "https://api.supadata.ai/v1/transcript"
  • Access to secretsline 32
    [Credential-related source omitted]
  • Access to secretsline 33
    [Credential-related source omitted]
  • Network accessline 38
    youtube_url = f"https://www.youtube.com/watch?v={video_id}"
  • Network accessline 42
    response = requests.get(
  • Access to secretsline 49
    [Credential-related source omitted]
  • Access to secretsline 132
    [Credential-related source omitted]

get_videos.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 12
    [Credential-related source omitted]
  • Access to secretsline 14
    [Credential-related source omitted]
  • Network accessline 64
    shorts_url = f"https://www.youtube.com/shorts/{video_id}"
  • Network accessline 68
    response = requests.head(shorts_url, allow_redirects=True, timeout=5)
  • Network accessline 104
    "description": item["snippet"]["description"],             "channel": channel_name,             "url": f"https://www.youtube.com/watch?v={video_id}"
  • Network accessline 105
    "channel": channel_name,             "url": f"https://www.youtube.com/watch?v={video_id}"         }
  • Network accessline 106
    "url": f"https://www.youtube.com/watch?v={video_id}"
  • Access to secretsline 117
    [Credential-related source omitted]

launch_dashboard.command

  • Executable scriptline 1
    #!/bin/bash

main.py

  • Executable scriptline 1
    Executable file

run_newsletter.sh

  • Executable scriptline 1
    #!/bin/bash

send_email.py

  • Executable scriptline 1
    Executable file
  • Network accessline 396
    "title": "Test Article",             "channel": "Test Channel",             "url": "https://youtube.com/watch?v=test",
  • Network accessline 397
    "channel": "Test Channel",             "url": "https://youtube.com/watch?v=test",             "article": "# Test Headline\n\nThis is a test article with **bold** and *italic* text.\n\n## Section 1\n\nSome content here."
  • Network accessline 398
    "url": "https://youtube.com/watch?v=test",

video_tracker.py

  • Executable scriptline 1
    Executable file

write_articles.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 12
    [Credential-related source omitted]
  • Access to secretsline 15
    [Credential-related source omitted]
  • Network accessline 98
    "title": "Test Video",         "channel": "Test Channel",         "url": "https://youtube.com/watch?v=test",
  • Network accessline 99
    "channel": "Test Channel",         "url": "https://youtube.com/watch?v=test",         "transcript": "Hello everyone, today we're going to talk about something really exciting. I've been working on this project for months and I can't wait to
  • Network accessline 100
    "url": "https://youtube.com/watch?v=test",

How the signals fit together

Facts from a static read of the files at the pinned commit. They describe what the code does, not why.

Some files could not be read; the facts below still hold.

Declared and executed: 2 facts
  • Contacts fonts.googleapis.com, which SKILL.md, the README and the plugin manifest do not mentiondashboard.py:37High confidence
  • Contacts api.supadata.ai, which SKILL.md, the README and the plugin manifest do not mentionget_transcripts.py:17High confidence
Signal confidence: 57 facts
  • Network access in code of documentationREADME.md:18Low confidence
  • Access to secrets in code of documentationREADME.md:25Low confidence
  • Access to secrets in code of documentationREADME.md:26Low confidence
  • Network access in prose of documentationREADME.md:44Low confidence
  • Network access in prose of documentationREADME.md:45Low confidence
  • Network access in prose of documentationREADME.md:51Low confidence
  • Network access in prose of documentationREADME.md:52Low confidence
  • Network access in prose of documentationREADME.md:96Low confidence
  • Network access in prose of documentationREADME.md:97Low confidence
  • Network access in prose of documentationREADME.md:98Low confidence
  • Access to secrets in code of documentation: a variable, placeholder or call, not a stored valueREADME.md:116Low confidence
  • Access to secrets in code of the SKILL.mdSKILL.md:51High confidence
  • Network access in code of the SKILL.mdSKILL.md:61High confidence
  • Network access in code of the SKILL.mdSKILL.md:62High confidence
  • Network access in code of the SKILL.mdSKILL.md:63High confidence
  • Network access in code of the SKILL.mdSKILL.md:94High confidence
  • Network access in code of the SKILL.mdSKILL.md:95High confidence
  • Executable script in prose of a file that runsdashboard.py:1Low confidence
  • Network access in code of a file that runsdashboard.py:35High confidence
  • Network access in code of a file that runsdashboard.py:37High confidence
  • Network access in code of a file that runsdashboard.py:667High confidence
  • Network access in code of a file that runsdashboard.py:668High confidence
  • Network access in code of a file that runsdashboard.py:669High confidence
  • Network access in code of a file that runsdashboard.py:832High confidence
  • Executable script in prose of a file that runsget_transcripts.py:1Low confidence
  • Access to secrets in a comment of a file that runsget_transcripts.py:12Low confidence
  • Access to secrets in code of a file that runs: a variable, placeholder or call, not a stored valueget_transcripts.py:14Low confidence
  • Network access in code of a file that runsget_transcripts.py:17High confidence
  • Access to secrets in code of a file that runsget_transcripts.py:32High confidence
  • Access to secrets in code of a file that runs: a variable, placeholder or call, not a stored valueget_transcripts.py:33Low confidence
  • Network access in code of a file that runsget_transcripts.py:38High confidence
  • Network access in code of a file that runsget_transcripts.py:42High confidence
  • Access to secrets in code of a file that runsget_transcripts.py:49High confidence
  • Access to secrets in code of a file that runs: a variable, placeholder or call, not a stored valueget_transcripts.py:132Low confidence
  • Executable script in prose of a file that runsget_videos.py:1Low confidence
  • Access to secrets in a comment of a file that runs: a variable, placeholder or call, not a stored valueget_videos.py:12Low confidence
  • Access to secrets in code of a file that runs: a variable, placeholder or call, not a stored valueget_videos.py:14Low confidence
  • Network access in code of a file that runsget_videos.py:64High confidence
  • Network access in code of a file that runsget_videos.py:68High confidence
  • Network access in code of a file that runsget_videos.py:104High confidence
  • Network access in code of a file that runsget_videos.py:105High confidence
  • Network access in code of a file that runsget_videos.py:106High confidence
  • Access to secrets in code of a file that runs: a variable, placeholder or call, not a stored valueget_videos.py:117Low confidence
  • Executable script in code of a file that runslaunch_dashboard.command:1High confidence
  • Executable script in prose of a file that runsmain.py:1Low confidence
  • Executable script in code of a file that runsrun_newsletter.sh:1High confidence
  • Executable script in prose of a file that runssend_email.py:1Low confidence
  • Network access in code of a file that runssend_email.py:396High confidence
  • Network access in code of a file that runssend_email.py:397High confidence
  • Network access in code of a file that runssend_email.py:398High confidence

and 7 more

Works with

Agent compatibility, from the files in this repository
AgentStatusEvidenceInstall to
Claude CodeCompatibleStandard SKILL.md SKILL.md.claude/skills/<skill-name>/
CodexCompatibleStandard SKILL.md SKILL.md.agents/skills/<skill-name>/
CursorCompatibleStandard SKILL.md SKILL.md.cursor/skills/<skill-name>/
Gemini CLICompatibleStandard SKILL.md SKILL.md.gemini/skills/<skill-name>/
GitHub CopilotCompatibleStandard SKILL.md SKILL.md.github/skills/<skill-name>/
OpenCodeCompatibleStandard SKILL.md SKILL.md.opencode/skills/<skill-name>/
  • Native The repository ships a manifest, folder or frontmatter field for this agent.
  • Compatible A standard SKILL.md that this agent can read.
  • Unknown No evidence either way.

Derived automatically from paths, manifests and frontmatter. Not tested on each agent.