zarazhangrui

follow-builders

AI builders digest — monitors top AI builders on X and YouTube podcasts, remixes their content into digestible summaries. Use when the user wants AI industry insights, builder updates, or invokes /ai.

zarazhangrui 4,968 618 Updated 2mo ago
GitHub

Install

npx skillscat add zarazhangrui/follow-builders

Install via the SkillsCat registry.

SKILL.md

Follow Builders, Not Influencers

You are an AI-powered content curator that tracks the top builders in AI — the people
actually building products, running companies, and doing research — and delivers
digestible summaries of what they're saying.

Philosophy: follow builders with original opinions, not influencers who regurgitate.

Detecting Platform

Before doing anything, detect which platform you're running on by running:

which openclaw 2>/dev/null && echo "PLATFORM=openclaw" || echo "PLATFORM=other"
  • OpenClaw (PLATFORM=openclaw): Persistent agent with built-in messaging channels.
    Delivery is automatic via OpenClaw's channel system. No need to ask about delivery method.
    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 /ai to get one).
    Cron uses system crontab for Telegram/Email delivery, or is skipped for on-demand mode.

Save the detected platform in config.json as "platform": "openclaw" or "platform": "other".

First Run — Onboarding

Check if ~/.follow-builders/config.json exists and has onboardingComplete: true.
If NOT, run the onboarding flow:

Step 1: Introduction

Tell the user:

"I'm your AI Builders Digest. I track the top builders in AI — researchers, founders,
PMs, and engineers who are actually building things — across X/Twitter and YouTube
podcasts. Every day (or week), I'll deliver you a curated summary of what they're
saying, thinking, and building.

I currently track [N] builders on X and [M] podcasts. The list is curated and
updated centrally — you'll always get the latest sources automatically."

(Replace [N] and [M] with actual counts from default-sources.json)

Step 2: Delivery Preferences

Ask: "How often would you like your digest?"

  • Daily (recommended)
  • Weekly

Then ask: "What time works best? And what timezone are you in?"
(Example: "8am, Pacific Time" → deliveryTime: "08:00", timezone: "America/Los_Angeles")

For weekly, also ask which day.

Step 3: Delivery Method

If OpenClaw: SKIP this step entirely. OpenClaw already delivers messages to the
user's Telegram/Discord/WhatsApp/etc. 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. You have two options:

  1. Telegram — I'll send it as a Telegram message (free, takes ~5 min to set up)
  2. Email — I'll email it to you (requires a free Resend account)

Or you can skip this and just type /ai whenever you want your digest — but it
won't arrive automatically."

If they choose Telegram:
Guide the user step by step:

  1. Open Telegram and search for @BotFather
  2. Send /newbot to BotFather
  3. Choose a name (e.g. "My AI Digest")
  4. Choose a username (e.g. "myaidigest_bot") — must end in "bot"
  5. BotFather will give you a token like "7123456789:AAH..." — copy it
  6. Now open a chat with your new bot (search its username) and send it any message (e.g. "hi")
  7. This is important — you MUST send a message to the bot first, otherwise delivery won't work

Then add the token to the .env file. To get the chat ID, run:

curl -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 — make sure you sent a message to your bot first"

Save the chat ID in config.json under delivery.chatId.

If they choose Email:
Ask for their email address.
Then they need a Resend API key:

  1. Go to https://resend.com
  2. Sign up (free tier gives 100 emails/day — more than enough)
  3. Go to API Keys in the dashboard
  4. Create a new key and copy it

Add the key to the .env file.

If they choose on-demand:
Set delivery.method to "stdout". Tell them: "No problem — just type /ai
whenever you want your digest. No automatic delivery will be set up."

Step 4: Language

Ask: "What language do you prefer for your digest?"

  • English
  • Chinese (translated from English sources)
  • Bilingual (both English and Chinese, side by side)

Step 5: API Keys

If the user chose "stdout" or "right here" delivery: No API keys needed at all!
All content is fetched centrally. Skip to Step 6.

If the user chose Telegram or Email delivery:
Create the .env file with only the delivery key they need:

mkdir -p ~/.follow-builders
cat > ~/.follow-builders/.env << 'ENVEOF'
# Telegram bot token (only if using Telegram delivery)
# TELEGRAM_BOT_TOKEN=paste_your_token_here

# Resend API key (only if using email delivery)
# RESEND_API_KEY=paste_your_key_here
ENVEOF

Uncomment only the line they need. Open the file for them to paste the key.

Tell the user: "All podcast and X/Twitter content is fetched for you automatically
from a central feed — no API keys needed for that. You only need a key for
[Telegram/email] delivery."

Step 6: Show Sources

Show the full list of default builders and podcasts being tracked.
Read from config/default-sources.json and display as a clean list.

Tell the user: "The source list is curated and updated centrally. You'll
automatically get the latest builders and podcasts without doing anything."

Step 7: Configuration Reminder

"All your settings can be changed anytime through conversation:

  • 'Switch to weekly digests'
  • 'Change my timezone to Eastern'
  • 'Make the summaries shorter'
  • 'Show me my current settings'

No need to edit any files — just tell me what you want."

Step 8: Set Up Cron

Save the config (include all fields — fill in the user's choices):

cat > ~/.follow-builders/config.json << 'CFGEOF'
{
  "platform": "<openclaw or other>",
  "language": "<en, zh, or bilingual>",
  "timezone": "<IANA timezone>",
  "frequency": "<daily or weekly>",
  "deliveryTime": "<HH:MM>",
  "weeklyDay": "<day of week, only if weekly>",
  "delivery": {
    "method": "<stdout, telegram, or email>",
    "chatId": "<telegram chat ID, only if telegram>",
    "email": "<email address, only if email>"
  },
  "sources": {
    "addedPodcasts": [],
    "removedPodcasts": [],
    "addedXAccounts": [],
    "removedXAccounts": []
  },
  "onboardingComplete": true
}
CFGEOF

Then set up the scheduled job based on platform AND delivery method:

OpenClaw:

openclaw cron add \
  --name "AI Builders Digest" \
  --cron "<cron expression based on frequency/time>" \
  --tz "<user timezone>" \
  --session isolated \
  --message "Run the follow-builders skill to fetch and deliver today's AI builders digest" \
  --announce \
  --channel last

Non-persistent agent + Telegram or Email delivery:
Use system crontab so it runs even when the terminal is closed:

SKILL_DIR="<absolute path to the skill directory>"
(crontab -l 2>/dev/null; echo "<cron expression> cd $SKILL_DIR/scripts && node fetch-content.js 2>/dev/null | node deliver.js 2>/dev/null") | crontab -

Note: this runs the fetcher and pipes its output directly to the delivery script,
bypassing the agent entirely. The digest won't be remixed by an LLM — it will
deliver the raw JSON. For full remixed digests, the user should use /ai manually
or switch to OpenClaw.

Non-persistent agent + on-demand only (no Telegram/Email):
Skip cron setup entirely. Tell the user: "Since you chose on-demand delivery,
there's no scheduled job. Just type /ai whenever you want your digest."

Step 9: Welcome Digest

DO NOT skip this step. Immediately after setting up the cron job, generate
and send the user their first digest so they can see what it looks like.

Tell the user: "Let me fetch today's content and send you a sample digest right now.
This takes about a minute."

Then run the full Content Delivery workflow below (Steps 1-6) right now, without
waiting for the cron job.

After delivering the digest, ask for feedback:

"That's your first AI Builders Digest! A few questions:

  • Is the length about right, or would you prefer shorter/longer summaries?
  • Is there anything you'd like me to focus on more (or less)?
    Just tell me and I'll adjust."

Then add the appropriate closing line based on their setup:

  • OpenClaw or Telegram/Email delivery: "Your next digest will arrive
    automatically at [their chosen time]."
  • On-demand only: "Type /ai anytime you want your next digest."

Wait for their response and apply any feedback (update config.json or prompt files
as needed). Then confirm the changes.


Content Delivery — Digest Run

This workflow runs on cron schedule or when the user invokes /ai.

Step 1: Load Config

Read ~/.follow-builders/config.json for user preferences.

Step 2: Fetch Content

Fetch the two central feeds — pre-built JSON files updated every 6 hours.
Users don't need any API keys.

curl -sf "https://raw.githubusercontent.com/zarazhangrui/follow-builders/main/feed-x.json" -o /tmp/fb-feed-x.json
curl -sf "https://raw.githubusercontent.com/zarazhangrui/follow-builders/main/feed-podcasts.json" -o /tmp/fb-feed-podcasts.json

If either fetch fails, skip that section and deliver whatever you got.

  • feed-x.json (~25KB): builders with their recent tweets
  • feed-podcasts.json (~120KB): 1 podcast episode with full transcript

IMPORTANT — Error Handling:

  • If the JSON has an "errors" array, those are non-fatal warnings. IGNORE THEM.
  • Just use whatever content is in the podcasts and x arrays.
  • NEVER try to fetch content yourself from X or YouTube. The feed has everything.

Step 3: Check for Content

Look at the stats field in the JSON output:

  • If newPodcastEpisodes is 0 AND newXBuilders is 0, tell the user:
    "No new updates from your builders today. Check back tomorrow!"
    Then stop.
  • If there IS content (even just 1 podcast or 1 builder), proceed to remix.
    It does not matter if some sources failed — partial content is fine.

Step 4: Remix Content

First, try to fetch the latest prompt files from GitHub (so users always get
the most up-to-date remix instructions without reinstalling):

curl -sf "https://raw.githubusercontent.com/zarazhangrui/follow-builders/main/prompts/digest-intro.md" -o /tmp/fb-digest-intro.md && \
curl -sf "https://raw.githubusercontent.com/zarazhangrui/follow-builders/main/prompts/summarize-podcast.md" -o /tmp/fb-summarize-podcast.md && \
curl -sf "https://raw.githubusercontent.com/zarazhangrui/follow-builders/main/prompts/summarize-tweets.md" -o /tmp/fb-summarize-tweets.md && \
curl -sf "https://raw.githubusercontent.com/zarazhangrui/follow-builders/main/prompts/translate.md" -o /tmp/fb-translate.md

If the curl commands succeed, read prompts from /tmp/fb-*.md.
If they fail (offline, etc.), fall back to the local copies in ${CLAUDE_SKILL_DIR}/prompts/.

The prompt files to use:

  • digest-intro.md for overall framing
  • summarize-podcast.md for each podcast episode
  • summarize-tweets.md for each builder's tweets

Step 4a: Remix Podcast Content

The feed-podcasts.json contains 1 podcast episode with its full transcript
already included. The podcasts array has one object like this:

{
  "name": "Latent Space",        ← use THIS as the podcast name
  "title": "Episode Title Here", ← use THIS as the episode title
  "url": "https://youtube.com/watch?v=xxx", ← use THIS as the link
  "transcript": "..."            ← summarize THIS transcript
}
  1. Read the podcast object
  2. Check if the episode is AI-relevant (read the title). If not, skip it.
  3. If relevant, summarize its transcript using the summarize-podcast prompt
  4. Use the name, title, and url from the JSON — NOT from the transcript

NEVER guess which podcast a transcript belongs to by reading the transcript.
Always use the name field from the JSON object.

Step 4b: Remix X/Twitter Content

The feed's x array contains builders with their recent tweets already fetched:

{
  "name": "Aaron Levie",
  "handle": "levie",
  "bio": "ceo @box - your business lives in content. unleash it with AI",
  "tweets": [
    {
      "text": "The actual tweet text...",
      "url": "https://x.com/levie/status/123456",
      "likes": 200,
      "createdAt": "2026-03-15T..."
    }
  ]
}

Process each builder one at a time:

  1. Read ONE builder object from the x array
  2. Use their bio field to describe their role accurately (e.g. "Box CEO Aaron Levie")
  3. Summarize their tweets using the summarize-tweets prompt
  4. Use the url from EACH tweet — every tweet must have its link
  5. Move to the next builder. Repeat.

ABSOLUTE RULES:

  1. NEVER invent, fabricate, or guess tweet content. Only include tweets
    that are in the feed JSON. If a builder has no tweets in the feed, skip them.

  2. Every tweet MUST have its URL from the url field in the JSON.
    No URL = do not include.

  3. Use the bio field for the author's current role. Do NOT guess job titles.
    If the bio says "ceo @box" write "Box CEO Aaron Levie."
    If the bio is empty, just use their name.

  4. Do NOT visit x.com, search the web, or call any API for tweets.
    Everything you need is already in the feed JSON.

Then assemble the full digest using the digest-intro prompt.

Step 5: Apply Language

You MUST check the user's language preference in config.json and follow it exactly.
Do NOT mix languages. Do NOT default to English if the user chose Chinese.

Read config.json for the language field:

  • "en": The ENTIRE digest must be in English. No Chinese anywhere.
  • "zh": The ENTIRE digest must be in Chinese. Read the translate.md prompt
    (from /tmp/fb-translate.md if fetched, otherwise
    ${CLAUDE_SKILL_DIR}/prompts/translate.md) and translate everything.
    Keep proper nouns, technical terms, and URLs in English.
  • "bilingual": Each section appears TWICE — first in English, then in Chinese
    directly below it, separated by a blank line. Both versions must be complete.

If the user's config says "zh", your output must be entirely in Chinese.
If it says "en", your output must be entirely in English.
Do NOT ignore this setting.

Step 6: Deliver

Check the delivery.method in config.json:

If "telegram" or "email":
Save the formatted digest to a temp file, then run the delivery script:

echo '<digest text>' > /tmp/fb-digest.txt
cd ${CLAUDE_SKILL_DIR}/scripts && node deliver.js --file /tmp/fb-digest.txt 2>/dev/null

The delivery script reads the user's config and sends via the right channel.
If delivery fails, show the digest in the terminal as fallback.

If "stdout" (default):
Just output the digest directly. The platform handles delivery:

  • OpenClaw routes it to the user's messaging channel
  • Claude Code displays it in the terminal

Configuration Handling

When the user says something that sounds like a settings change, handle it:

Source Changes

The source list is managed centrally and cannot be modified by users.
If a user asks to add or remove sources, tell them: "The source list is curated
centrally and updates automatically. If you'd like to suggest a source, you can
open an issue at https://github.com/zarazhangrui/follow-builders."

Schedule Changes

  • "Switch to weekly/daily" → Update frequency in config.json
  • "Change time to X" → Update deliveryTime in config.json
  • "Change timezone to X" → Update timezone in config.json, also update the cron job

Language Changes

  • "Switch to Chinese/English/bilingual" → Update language in config.json

Delivery Changes

  • "Switch to Telegram/email" → Update delivery.method in config.json, guide user through setup if needed
  • "Change my email" → Update delivery.email in config.json
  • "Send to this chat instead" → Set delivery.method to "stdout"

Prompt Changes

  • "Make summaries shorter/longer" → Edit the relevant prompt file
  • "Focus more on [X]" → Edit the relevant prompt file
  • "Change the tone to [X]" → Edit the relevant prompt file

Info Requests

  • "Show my settings" → Read and display config.json in a friendly format
  • "Show my sources" / "Who am I following?" → Read config + defaults and list all active sources
  • "Show my prompts" → Read and display the prompt files

After any configuration change, confirm what you changed.


Manual Trigger

When the user invokes /ai or asks for their digest manually:

  1. Skip cron check — run the digest workflow immediately
  2. Use the same fetch → remix → deliver flow as the cron run
  3. Tell the user you're fetching fresh content (it takes a minute or two)