Fetch recent tweets from a curated account list, triage them against its rubric, save an org digest, and update last-run state. Use twitter for direct lookups, twitter-discover for finding accounts, and twitter-vet for account scoring.
Scanned 9/20/2026
Install to Claude Code
npx -y skills add benthamite/dotfiles --skill twitter-digest --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Twitter Digest?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/benthamite-twitter-digest-dotfiles)More formats (shields.io, HTML) on the badges page.
---
name: twitter-digest
description: Fetch recent tweets from a curated account list, triage them against its rubric, save an org digest, and update last-run state. Use twitter for direct lookups, twitter-discover for finding accounts, and twitter-vet for account scoring.
---
# Twitter digest
When Step 3 runs, read the active `twitter-vet` skill copy:
- Codex: `/.codex/programmatic-skills/twitter-vet/SKILL.md`
- Claude: `/.claude/programmatic-skills/twitter-vet/SKILL.md`
For each Bash command below, set paths for the current agent before using them:
- Codex: `DIGEST_DIR="/.codex/programmatic-skills/twitter-digest"; DIGEST_REPO_DIR="codex/programmatic-skills/twitter-digest"; VET_SKILL_DIR="/.codex/programmatic-skills/twitter-vet"; TWITTERAPI="/.codex/programmatic-skills/twitter/lib/twitterapi.sh"`
- Claude: `DIGEST_DIR="/.claude/programmatic-skills/twitter-digest"; DIGEST_REPO_DIR="claude/programmatic-skills/twitter-digest"; VET_SKILL_DIR="/.claude/programmatic-skills/twitter-vet"; TWITTERAPI="/.claude/programmatic-skills/twitter/lib/twitterapi.sh"`
Shared paired data:
- Curated list files must stay synchronized in both `claude/programmatic-skills/twitter-digest/lists/` and `codex/programmatic-skills/twitter-digest/lists/`.
- The vet registry source of truth is `VET_REGISTRY_DIR="/.claude/programmatic-skills/twitter-vet/vetted"` (`VET_REGISTRY_REPO_DIR="claude/programmatic-skills/twitter-vet/vetted"`), as documented by `twitter-vet`.
Digest archives and last-run timestamps are active-tool runtime state; do not write those into the other tool's skill tree.
## COST RULE — READ THIS FIRST
Each tool call resends ~20K tokens of system context. Core digest creation is **exactly 2 Bash calls**; the final commit is one additional Bash call. Vetting discovered accounts adds N read-only API calls through the `twitterapi.sh` wrapper (typically 0-5, ~$0.003 each):
1. **Bash**: run `fetch-tweets.sh` (handles list reading, cutoff, fetching, RT discovery)
2. **Bash**: write org file + open in Emacs + update last-run timestamp + save digest (one heredoc command)
3. **Bash/API** (0-5 calls): vet discovered accounts — see Step 3
4. **Bash**: commit all changed files — see Step 4
Any extra tool calls (Read, Write, separate Bash) waste $0.02-0.05 each. Do NOT read list files or last-run files separately — the fetch script handles that.
Never use MCP twitter tools for the digest itself or for discovered-account vetting. Use the digest script and the active `twitterapi.sh` wrapper only.
Treat resolved API keys and account-specific environment variables as secrets: do not echo `TWITTERAPI_API_KEY*`, do not enable shell xtrace, and do not print curl headers.
## Step 1: Fetch
```bash
DIGEST_DIR="<active twitter-digest skill dir from above>"
bash "$DIGEST_DIR/fetch-tweets.sh" <list-name>
```
Output:
```
LIST:<name>
CUTOFF:<iso-timestamp>
DESCRIPTION:<triage rubric or empty>
---TWEETS---
@user|date|likes|views|OG/RT|tweet_id|rt_user|text
...
---RT_DISCOVERY---
@user|date|likes|views|OG/RT|tweet_id|rt_user|text
---RT_AUTHORS---
@user|followers|bio_text
```
If no cutoff file exists and running non-interactively, defaults to 48h. If interactive, ask the user.
## Step 2: Triage + output
If DESCRIPTION is non-empty, triage tweets: keep only tweets that **directly match** the rubric. The rubric is a hard filter, not a soft signal — if a tweet doesn't clearly fit the described topic, drop it regardless of engagement. Be aggressive — 5-15 tweets from 20+ accounts. Skip noise, hype, self-promotion, low-signal RTs, and anything the rubric's "skip" list covers (read it carefully).
For RT-discovered authors (after `---RT_DISCOVERY---`), triage separately. **Before including any discovered account in the output**, check `$VET_REGISTRY_DIR/<list-name>.md` — if the account appears in "Rejected", "Below threshold", or "Skipped" sections, exclude their tweets from the digest entirely.
Then emit ONE bash command that does everything:
```bash
DIGEST_DIR="<active twitter-digest skill dir from above>"
TMPFILE=$(mktemp /tmp/twitter-digest-XXXXXX.org) && cat > "$TMPFILE" <<'ORGEOF'
#+title: Twitter digest: <name> — YYYY-MM-DD
* Notable
** @username (Mon Mar 17 14:30)
Tweet text
Likes: N | Views: N | Like rate: X.X%
[[https://x.com/username/status/ID][View on X]]
* Discovered accounts
...
* Accounts with nothing notable
@user1, @user2, ...
ORGEOF
emacsclient -e "(progn (find-file \"$TMPFILE\") (goto-char (point-min)) (org-fold-show-all))" && echo "<iso-timestamp-of-newest-tweet>" > "$DIGEST_DIR/last-run/<name>.txt" && cp "$TMPFILE" "$DIGEST_DIR/digests/<name>-YYYY-MM-DD.org"
```
Order by like rate (likes÷views) descending. Omit "Discovered accounts" if none. Unfiltered lists (no description): show all tweets reverse-chrono under `* All tweets`, no other sections.
## Saving digests
Always save a copy of the digest to `$DIGEST_DIR/digests/<name>-YYYY-MM-DD.org`. For multi-list digests, use the combined filename (e.g. `ai-tools-ai-macrostrategy-2026-03-20.org`).
## Step 3: Vet discovered accounts
If `---RT_DISCOVERY---` yielded accounts:
1. **Check registry**: read `$VET_REGISTRY_DIR/<list-name>.md` if it exists. Any RT-discovered account already listed there: skip re-vetting, use the recorded score directly.
2. **Quick filter** (Procedure A from twitter-vet): use `---RT_AUTHORS---` metadata (bio, followers) and `---RT_DISCOVERY---` tweets to filter remaining accounts. Cap at top 5 candidates by quick-filter confidence. Skip the rest.
3. **Full scoring** (Procedure B from twitter-vet): for each account that passes, call `"$TWITTERAPI" tweets <username>`. Score 1-10 against the list's `description`.
4. **Auto-add**: score >= 7 (or `vet-threshold` from list YAML) → append `- @username` to both paired list files (`claude/programmatic-skills/twitter-digest/lists/<list-name>.md` and `codex/programmatic-skills/twitter-digest/lists/<list-name>.md`). Score 5-6 → report as borderline in the digest. Score <= 4 → skip.
5. **Update digest and lists**: emit one final Bash call to append a `* Vetted accounts` section to the org file (replacing `* Discovered accounts`) showing each account's score and rationale, and append any new `- @username` lines to both paired list files.
6. **Update vet registry**: append newly scored accounts to `$VET_REGISTRY_DIR/<list-name>.md` (creating the file with the standard header if it doesn't exist). Include all accounts that went through full scoring, regardless of outcome.
If the API returns an auth/rate-limit/error response during vetting, report the failure directly. Do not auto-add accounts or advance the vet registry based on incomplete data.
## Step 4: Commit
After all steps are complete, commit all changed files in one commit:
```bash
DIGEST_REPO_DIR="<active repo-relative twitter-digest dir from above>"
VET_REGISTRY_REPO_DIR="claude/programmatic-skills/twitter-vet/vetted"
git -C "$HOME/My Drive/dotfiles" add "$DIGEST_REPO_DIR/digests/" "$DIGEST_REPO_DIR/last-run/" "claude/programmatic-skills/twitter-digest/lists/" "codex/programmatic-skills/twitter-digest/lists/" "$VET_REGISTRY_REPO_DIR/" && git -C "$HOME/My Drive/dotfiles" commit -m "twitter-digest: <list-name(s)> YYYY-MM-DD"
```
Only stage paths that actually changed. If vetting didn't run, omit the list and vet registry paths.
## Multiple lists
Run fetch-tweets.sh once per list. Combine into one org buffer with `* <list-name>` top-level headings.
## List management
Lists: `$DIGEST_DIR/lists/<name>.md`. YAML frontmatter with optional `description` (triage rubric), then `- @username` lines. No arg + 1 list → use it; multiple → ask. Treat list files as paired source data: any list membership edit must be applied to both Claude and Codex copies.
## Verification
Before committing or reporting completion:
1. Confirm fetch output includes `LIST:`, `CUTOFF:`, `DESCRIPTION:`, and `---TWEETS---`. If the script exits with "no listed account fetches succeeded", stop and report the credential/connectivity problem.
2. Confirm the saved digest exists and is non-empty at `$DIGEST_DIR/digests/<name>-YYYY-MM-DD.org`.
3. Confirm `$DIGEST_DIR/last-run/<name>.txt` contains the newest returned tweet timestamp used for the run.
4. Run `git -C "$HOME/My Drive/dotfiles" diff --check -- "$DIGEST_REPO_DIR" claude/programmatic-skills/twitter-digest/lists codex/programmatic-skills/twitter-digest/lists "$VET_REGISTRY_REPO_DIR"` and inspect `git status --short` so unrelated dirty files are not staged.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!