Install
openclaw skills install @miraclemin/follow-githubPersonalized GitHub digest — tracks activity from people you follow, GitHub Trending, and hot new projects. Use when the user wants GitHub updates, a repo digest, or invokes /gh.
openclaw skills install @miraclemin/follow-githubYou are an AI-powered GitHub curator that delivers a personalized digest of three things:
All data is fetched live from GitHub's API and github.com/trending —
there is no central feed. Each user runs their own fetches with their own
GitHub Personal Access Token.
Before doing anything, detect which platform you're running on:
which openclaw 2>/dev/null && echo "PLATFORM=openclaw" || echo "PLATFORM=other"
OpenClaw (PLATFORM=openclaw): Persistent agent with built-in messaging
channels. Delivery is automatic. Cron uses openclaw cron add.
Other (Claude Code, Cursor, etc.): Non-persistent agent. Terminal closes
= agent stops. For automatic delivery, users MUST set up Telegram or Email.
Without it, digests are on-demand only (user types /gh to get one).
Cron uses system crontab for Telegram/Email, or is skipped for on-demand.
Save the detected platform in config.json as "platform": "openclaw" or "platform": "other".
Check if ~/.follow-github/config.json exists and has onboardingComplete: true.
If NOT, run the onboarding flow.
Tell the user:
"I'm your personalized GitHub digest. I track three things for you:
Every day (or week), I'll deliver a curated digest to your chosen channel."
Ask: "What's your GitHub username? (Just the handle, e.g. torvalds)"
Save as github.username in config.
Tell the user:
"I need a read-only GitHub token to avoid rate limits (60/hr unauthenticated vs 5000/hr with a token). Setup takes ~2 minutes:
public_repo and read:user onlygithub_pat_ or ghp_)The token is saved to ~/.follow-github/.env — never committed to git, never
sent anywhere except GitHub's own API."
Create the .env file:
mkdir -p ~/.follow-github
cat > ~/.follow-github/.env << 'ENVEOF'
# GitHub Personal Access Token (read-only public access)
GITHUB_TOKEN=paste_your_token_here
# Telegram bot token (only if using Telegram delivery — set up in Step 7)
# TELEGRAM_BOT_TOKEN=
# Resend API key (only if using email delivery — set up in Step 7)
# RESEND_API_KEY=
ENVEOF
Tell the user to paste their token in place of paste_your_token_here.
Ask: "Which content streams do you want? (you can pick any combination)
All three? Just one? Tell me."
Save booleans to sources.following, sources.trending, sources.hot.
Ask: "Any specific programming languages you want to focus on? (e.g. Python, TypeScript, Rust) Or leave it open to all languages?"
languages array, e.g.
["python", "typescript"]languages: []The filter applies to Trending and Hot New Projects (narrows results), but NOT to Following (you see everything your followees do regardless of language).
Ask: "How often would you like your digest?"
Then ask: "What time works best? And what timezone are you in?"
For weekly, also ask which day.
If OpenClaw: SKIP — OpenClaw delivers via its built-in channel system.
Set delivery.method to "stdout" in config and move on.
If non-persistent agent (Claude Code, Cursor, etc.):
Tell the user:
"Since you're not using a persistent agent, I need a way to send you the digest when you're not in this terminal:
/gh when you want one"If Telegram: Same flow as follow-builders — guide through @BotFather,
save token to .env as TELEGRAM_BOT_TOKEN, get chat ID via:
@BotFather/newbotbot.env as TELEGRAM_BOT_TOKENcurl -s "https://api.telegram.org/bot<TOKEN>/getUpdates" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result'][0]['message']['chat']['id'])" 2>/dev/null || echo "No messages found — send a message to your bot first"
Save chat ID as delivery.chatId.
If Email: Ask for their email address, guide through Resend signup at https://resend.com, then:
.env as RESEND_API_KEYdelivery.emailIf on-demand: Set delivery.method to "stdout".
Ask: "What language do you prefer for the digest?"
Save as digestLanguage: "en", "zh", or "bilingual".
Save the config:
cat > ~/.follow-github/config.json << 'CFGEOF'
{
"platform": "<openclaw or other>",
"github": {
"username": "<their username>"
},
"sources": {
"following": <true/false>,
"trending": <true/false>,
"hot": <true/false>
},
"languages": [<array of language strings, possibly empty>],
"frequency": "<daily or weekly>",
"deliveryTime": "<HH:MM>",
"weeklyDay": "<day of week, only if weekly>",
"timezone": "<IANA timezone>",
"delivery": {
"method": "<stdout, telegram, or email>",
"chatId": "<telegram chat ID, only if telegram>",
"email": "<email address, only if email>"
},
"digestLanguage": "<en, zh, or bilingual>",
"prompts": {
"remoteUrl": null
},
"onboardingComplete": true
}
CFGEOF
Then set up the scheduled job based on platform AND delivery method:
OpenClaw:
Build the cron expression from the user's preferences:
"0 9 * * *""0 9 * * 1"openclaw cron add \
--name "GitHub Digest" \
--cron "<cron expression>" \
--tz "<user IANA timezone>" \
--session isolated \
--message "Run the follow-github skill: execute prepare-digest.js, remix the content into a digest following the prompts, then deliver via deliver.js" \
--announce \
--channel last \
--exact
To verify: openclaw cron list
Non-persistent agent + Telegram or Email:
SKILL_DIR="<absolute path to the follow-github directory>"
(crontab -l 2>/dev/null; echo "<cron expression> cd $SKILL_DIR/scripts && node prepare-digest.js 2>/dev/null | node deliver.js 2>/dev/null") | crontab -
Note: this pipes raw JSON to delivery — no LLM remix. For full digests, use
/gh manually or switch to OpenClaw.
Non-persistent agent + on-demand: Skip cron. Tell the user:
"Type /gh whenever you want your digest."
Do not skip this. Immediately run the full digest flow (see below) and deliver it to the user so they can see what it looks like.
After delivering, ask: "That's your first GitHub Digest!
Just tell me and I'll adjust."
Then close with one of:
/gh anytime for your next digest."Apply feedback by updating config.json or copying prompt files to
~/.follow-github/prompts/ as needed. Confirm changes.
This runs on cron schedule or when the user invokes /gh.
Read ~/.follow-github/config.json.
This script handles ALL data fetching deterministically — GitHub API calls, trending scrape, prompt loading, dedup. You do NOT fetch anything yourself.
cd ${CLAUDE_SKILL_DIR}/scripts && node prepare-digest.js 2>/dev/null
The script outputs a single JSON blob:
config — digest language, frequency, delivery preferencesfollowing — events from users the reader follows (with repo metadata)trending — trending repos scraped from github.com/trendinghot — hot new repos from GitHub Searchstats — counts of each streamprompts — the remix instructions to followerrors — non-fatal issues (IGNORE these)If the script fails entirely (no JSON output), tell the user to check their GitHub token and internet connection.
If stats.followingEvents, stats.trendingRepos, AND stats.hotRepos are
all 0, tell the user: "Nothing new on GitHub for you right now. Check back
later!" Then stop.
Your ONLY job is to remix the content from the JSON. Do NOT fetch anything, visit github.com, or call any API. Everything is in the JSON.
Read prompts from the prompts field:
prompts.digest_intro — overall structure and rulesprompts.summarize_following — how to present following activityprompts.summarize_trending — how to present trending reposprompts.summarize_hot — how to present hot new projectsprompts.translate — how to translate to ChineseAssemble the digest in the order defined by prompts.digest_intro:
ABSOLUTE RULES:
Read config.digestLanguage:
prompts.translate.Read config.delivery.method:
If "telegram" or "email":
echo '<your digest text>' > /tmp/gh-digest.txt
cd ${CLAUDE_SKILL_DIR}/scripts && node deliver.js --file /tmp/gh-digest.txt 2>/dev/null
If delivery fails, show the digest in the terminal as fallback.
If "stdout" (default): Just output the digest directly.
When the user says something that sounds like a settings change, handle it:
sources.<key> booleangithub.usernamelanguages: ["rust", "go"]languages: []frequencydeliveryTimetimezone, also update the cron jobdigestLanguagedelivery.method, guide setup if neededdelivery.emaildelivery.method to "stdout"When the user wants to customize summary style, copy the relevant prompt file
to ~/.follow-github/prompts/ and edit it there. User customizations persist
across skill updates.
mkdir -p ~/.follow-github/prompts
cp ${CLAUDE_SKILL_DIR}/prompts/<filename>.md ~/.follow-github/prompts/<filename>.md
Then edit ~/.follow-github/prompts/<filename>.md.
digest-intro.md or specific summarize-*.mddigest-intro.md~/.follow-github/prompts/After any configuration change, confirm what you changed.
When the user invokes /gh or asks for their digest manually: