Newsletter digest

01What is it?
Aggregates RSS feeds from the past week, synthesizes the top stories using Gemini, and publishes a newsletter digest to Ghost CMS. Optionally outputs formatted Markdown for Substack or any other platform. What sets it apart is how it narrows email marketing into one specific workflow rather than a broad, generic prompt.
02Inputs
Context for email marketing: your goals, audience, constraints, and any source material the skill asks for.
03Output
A ready-to-use result for email marketing: the analysis, copy, or recommendations the agent produces.
Install-only

Install as a package

Installs this one skill package for your coding agent, including any supporting files that skill ships with — not every skill in the repository. Read the tutorial.

Terminal
$ npx skills add varnan-tech/opendirectory --skill newsletter-digest

Skill instructions

The instruction file for this skill. The skill also includes other files you need to install to use it.

SKILL.md

Newsletter Digest

Aggregate content from RSS feeds, synthesize the week's top stories with Gemini, and publish a digest to Ghost CMS. Supports weekly digests, topic-focused roundups, and curated picks formats.

Writing Style

Apply to all generated digest content:

  • Active voice only
  • Short sentences, one idea per sentence
  • No em dashes — use a period or comma instead
  • No semicolons
  • No markdown or asterisks in the final newsletter body
  • No hashtags

Banned words — do not use any of these in the digest: incredible, amazing, leveraging, synergize, game-changing, game changer, delve, harness, unlock, groundbreaking, cutting-edge, remarkable, paradigm, revolutionize, disruptive, transformative, thrilled, excited to share, powerful, innovative, comprehensive, actionable, crucial, vital, pivotal, elucidate, utilize, dive deep, tapestry, illuminate, revolutionize

CRITICAL RULE

Every claim, statistic, and summary in the digest must come from the fetched articles. Never fabricate data points, quotes, or facts. If a source article has no meaningful content, skip it.


Step 1: Check Setup

1a. Verify feeds are configured

Check if feeds.json exists in the skill directory:

ls /Users/ksd/Desktop/Varnan_skills/newsletter-digest/feeds.json 2>/dev/null

If missing, ask the user: "Which RSS feeds should I monitor? Share a list of URLs and I'll create feeds.json."

The format is:

[
  { "url": "https://example.com/feed", "name": "Source Name" },
  { "url": "https://another.com/rss", "name": "Another Source" }
]

1b. Verify required environment variables

Check that these are set:

  • GEMINI_API_KEY (required): for synthesis
  • GHOST_URL and GHOST_ADMIN_KEY (required for Ghost publishing, optional if output-only)

If GEMINI_API_KEY is missing, stop and ask the user to set it.

GHOST config is optional. If not set, the skill outputs formatted Markdown instead of publishing.

1c. Verify script dependencies

ls /Users/ksd/Desktop/Varnan_skills/newsletter-digest/node_modules 2>/dev/null | head -1

If missing:

cd /Users/ksd/Desktop/Varnan_skills/newsletter-digest && npm install

Step 2: Fetch and Parse Feeds

Run the fetch script:

node /Users/ksd/Desktop/Varnan_skills/newsletter-digest/scripts/fetch-feeds.js

The script:

  • Reads feeds.json for the list of feeds
  • Fetches each feed using rss-parser
  • Filters items published in the last 7 days
  • Deduplicates by URL
  • Sorts by publish date, newest first
  • Saves results to /tmp/newsletter-digest-articles.json

If the script errors on a specific feed, it logs a warning and continues. One bad feed does not stop the run.

After the script completes, verify the output:

node -e "
const fs = require('fs');
const data = JSON.parse(fs.readFileSync('/tmp/newsletter-digest-articles.json', 'utf8'));
console.log('Total articles:', data.articles.length);
console.log('From feeds:', data.feedsSummary.map(f => f.name + ': ' + f.count).join(', '));
console.log('Date range:', data.dateRange.from, 'to', data.dateRange.to);
"

If fewer than 3 articles are found, warn the user and ask if they want to extend the date range to 14 days. Pass --days=14 to the script to widen the window.


Step 3: Read Format Rules

Read references/digest-format.md in full before generating any content. Internalize:

  • Three digest formats (Weekly Roundup, Topic Deep Dive, Curated Picks) and when to use each
  • Section structure and length requirements per format
  • Attribution rules (every claim links to a source)
  • Tone and voice guidelines

Read references/output-template.md and select the template matching the requested format.

If the user did not specify a format, default to Weekly Roundup.


Step 4: Synthesize with Gemini

Read /tmp/newsletter-digest-articles.json and build a synthesis prompt.

Prompt structure:

You are a newsletter editor writing a digest of this week's top stories.

Sources (use ONLY these — do not invent facts):
[For each article: Title | Source | Date | Summary]

Task:
Write a [FORMAT] digest following this structure:
[Paste the selected template from references/output-template.md]

Rules:
- Every claim, statistic, and quote must come from the sources above
- Write in active voice, short sentences, contractions allowed
- Do not use: incredible, amazing, leveraging, game-changing, delve, groundbreaking, cutting-edge, revolutionize
- No em dashes, no semicolons, no hashtags
- Include [Source: Name](URL) attribution after each major claim
- Output plain text with HTML heading tags only (no markdown asterisks)

Call Gemini with this prompt. Target model: gemini-2.0-flash or the latest available.

If the response contains any banned words or invented statistics not present in the source articles, regenerate with a stricter prompt.


Step 5: Self-QA

Run every check before presenting. Fix violations first.

  • Every claim, statistic, and quote traces to a source article
  • No banned words in any section
  • No em dashes in the text
  • No semicolons in the text
  • Every section has at least one source attribution with URL
  • Word count is within the format's target range (see references/digest-format.md)
  • No section repeated the same story twice
  • Title is specific (includes the date range or issue number, not just "Weekly Digest")
  • HTML output is valid (no unclosed tags if Ghost publishing)

Fix all violations before presenting to the user.


Step 6: Format and Preview

Present the digest to the user in this order:

  1. Title — Issue date range or topic
  2. Digest content — Full formatted text
  3. Source list — All articles used, with URLs
  4. Word count and article count

Ask: "Ready to publish to Ghost as a draft, or would you like to edit first?"


Step 7: Publish to Ghost or Output

If GHOST_URL and GHOST_ADMIN_KEY are set and user confirms:

Run the publish script:

node /Users/ksd/Desktop/Varnan_skills/newsletter-digest/scripts/ghost-publish.js \
  --title "DIGEST_TITLE" \
  --status "draft"

The script reads /tmp/newsletter-digest-output.json (written by the agent in Step 6) and posts to Ghost.

After posting, the script returns the Ghost admin URL for the draft. Present this to the user: "Draft saved at: [URL]. Review and publish from your Ghost dashboard."

If the user wants to publish immediately, pass --status "published" to the script.

If Ghost is not configured or user says "output only":

Output the digest in three formats:

  1. HTML — ready to paste into any CMS
  2. Markdown — for Substack, Notion, or Hashnode
  3. Plain text — for email clients

Add: "Substack does not offer a public API. Copy the Markdown version into your Substack editor directly."


Notes on Substack

Substack has no public API. Programmatic posting is not possible without reverse-engineering internal endpoints, which violates their terms. The skill outputs a formatted Markdown digest ready to paste into the Substack editor. This is the correct approach.


Supporting file: evals/evals.json

{ "skill_name": "newsletter-digest", "evals": [ { "id": 1, "prompt": "Generate a weekly digest from my RSS feeds", "expected_output": "Agent checks feeds.json exists and GEMINI_API_KEY is set. Runs scripts/fetch-feeds.js. Verifies output JSON contains at least 3 articles. Reads references/digest-format.md and references/output-template.md. Calls Gemini with the fetched articles and Weekly Roundup template. Returns a digest with a Top Story section (100-150 words), 3+ Also Worth Reading entries (40-60 words each), Quick Takes bullets, and a closing line. Every claim in the digest has a source attribution with a real URL from the fetched articles. No banned words. No invented statistics. Word count is 350-500 words. Asks user to confirm before publishing to Ghost.", "files": [] }, { "id": 2, "prompt": "Create a topic deep dive newsletter about AI agent frameworks from this week's news", "expected_output": "Agent runs fetch-feeds.js. Filters fetched articles to those related to AI agents and frameworks. Reads digest-format.md and selects Topic Deep Dive format. Calls Gemini with filtered articles and Topic Deep Dive template. Returns a digest with 'The Big Picture' section, 3-4 Key Development sections each with a linked article title, a 'What to Watch' bullet list, and a sources list. All claims trace to fetched articles. If fewer than 3 relevant articles are found, agent warns the user and asks if they want to extend the window to 14 days (re-run with --days=14).", "files": [] }, { "id": 3, "prompt": "Generate this week's digest and publish it to Ghost as a draft", "expected_output": "Agent checks GHOST_URL and GHOST_ADMIN_KEY are set. Runs fetch-feeds.js. Synthesizes digest. Writes digest HTML and metadata to /tmp/newsletter-digest-output.json. Runs scripts/ghost-publish.js with --title and --status=draft. Script generates Ghost JWT from GHOST_ADMIN_KEY (id:secret format, hex-decoded, HS256, 5-minute expiry). POSTs to /ghost/api/admin/posts/?source=html. Script returns the Ghost admin editor URL. Agent presents the URL to the user: 'Draft saved at [URL]. Review and publish from your Ghost dashboard.'", "files": [] }, { "id": 4, "prompt": "Generate a newsletter digest for Substack", "expected_output": "Agent generates the digest normally. When presenting output, provides three formats: HTML (for any CMS), Markdown (for Substack), and plain text. Includes a clear note: 'Substack does not offer a public API. Copy the Markdown version into your Substack editor directly.' Does not attempt any Substack API calls. The Markdown version uses ## headings, text (url) links, and - bullet points.", "files": [] }, { "id": 5, "prompt": "The feeds only returned 2 articles this week — can you extend the window?", "expected_output": "Agent re-runs fetch-feeds.js with --days=14 flag. Fetches articles from the last 14 days instead of 7. Reports the new article count. Continues with synthesis using the extended article set. If still fewer than 3 articles after 14 days, agent warns that the feeds may not be updating frequently and asks the user to check that the feed URLs are correct.", "files": [] } ] }


Supporting file: feeds.json

[ { "url": "https://feeds.feedburner.com/TheHackersNews", "name": "The Hacker News" }, { "url": "https://hnrss.org/frontpage", "name": "Hacker News Front Page" }, { "url": "https://www.infoq.com/feed/", "name": "InfoQ" }, { "url": "https://changelog.com/feed", "name": "Changelog" }, { "url": "https://css-tricks.com/feed/", "name": "CSS-Tricks" } ]


Supporting file: package.json

{ "name": "newsletter-digest", "version": "1.0.0", "description": "RSS aggregation and newsletter digest generation scripts", "type": "module", "scripts": { "fetch": "node scripts/fetch-feeds.js", "fetch:extended": "node scripts/fetch-feeds.js --days=14", "publish": "node scripts/ghost-publish.js" }, "dependencies": { "jsonwebtoken": "^9.0.2", "rss-parser": "^3.13.0" } }


Supporting file: README.md

newsletter-digest

<img width="1280" height="640" alt="newsletter-digest" src="https://github.com/user-attachments/assets/cb2879ae-eb5c-4727-a1a2-47b4462a699b" />

Aggregate RSS feeds, synthesize the week's top stories with Gemini, and publish a newsletter digest to Ghost CMS. Supports three digest formats and outputs HTML, Markdown, and plain text for any platform.

Install

Option A: npx CLI (Recommended)

No global install. Always runs the latest version.

npx "@opendirectory.dev/skills" install newsletter-digest --target claude

Option B: skills.sh

npx skills add Varnan-Tech/opendirectory --skill newsletter-digest

Requires Node.js. Add --global to install to ~/.claude/skills/ instead of the current project.

Option C: Claude Desktop App

<video src="https://github.com/user-attachments/assets/cea8b565-2002-4a87-8857-d902bfcfdc1c" controls width="100%"></video>

Step 1: Download the skill from GitHub

  1. Copy the URL of this specific skill folder from your browser's address bar.
  2. Go to download-directory.github.io (https://download-directory.github.io/).
  3. Paste the URL and click Enter to download.

Step 2: Install in Claude

  1. Open your Claude desktop app.
  2. Go to the sidebar on the left side and click on the Customize section.
  3. Click on the Skills tab, then click on the + button to create a new skill.
  4. Choose Upload a skill, then drag and drop the .zip file or extracted folder.

Note: For some skills, the SKILL.md file might be located inside a subfolder. Always upload the specific folder that contains the SKILL.md file.

Option D: Claude Code Native

Run these commands inside Claude Code:

/plugin marketplace add Varnan-Tech/opendirectory
/plugin install opendirectory-gtm-skills@opendirectory-marketplace

Option E: Manus AI

<video src="https://github.com/user-attachments/assets/17cbee2a-9e17-4bd4-ac46-68e0e92ffab4" controls width="100%"></video>

Install in Manus AI

Manus AI users can import a skill directly from its OpenDirectory skill page. This is the easiest path when you want Manus to pull the skill from GitHub for you.

  1. Open the skill you want from the opendirectory homepage (https://opendirectory.dev).
  2. In the install panel, select the Manus AI tab.
  3. Click Install in Manus AI - this opens Manus with the skill GitHub URL already attached.
  4. Confirm the import inside Manus AI.

If your Manus workspace prefers file uploads, use the Download tab instead and upload the downloaded .skill.zip file inside Manus.

What It Does

  • Reads your RSS/Atom feed list from feeds.json
  • Fetches all articles published in the last 7 days (configurable)
  • Deduplicates across feeds and sorts by date
  • Uses Gemini to synthesize a digest in your chosen format
  • Publishes to Ghost as a draft or live post
  • Outputs formatted Markdown for Substack, Notion, or any other platform

Digest Formats

FormatUse WhenTarget Length
Weekly RoundupGeneral digest covering top stories across all feeds350-500 words
Topic Deep DiveFocused issue on a single topic (AI, security, etc.)450-650 words
Curated Picks5 selected articles with editorial context250-350 words

Requirements

RequirementPurposeWhere to Get It
GEMINI_API_KEYDigest synthesishttps://ai.google.dev
GHOST_URL + GHOST_ADMIN_KEYGhost publishing (optional)Ghost Admin, Settings, Integrations
Node.js 20+Running scriptshttps://nodejs.org

Tavily is not required. The skill uses article excerpts from RSS feeds directly.

Setup

1. Set up dependencies

cd /path/to/newsletter-digest
npm install

2. Configure environment variables

cp .env.example .env
# Edit .env with your keys

3. Configure your feeds

Edit feeds.json with the RSS feeds you want to monitor:

[
  { "url": "https://hnrss.org/frontpage", "name": "Hacker News" },
  { "url": "https://feeds.feedburner.com/TheHackersNews", "name": "The Hacker News" },
  { "url": "https://changelog.com/feed", "name": "Changelog" }
]

The file ships with 5 example feeds. Replace them with your own.

4. Set up Ghost publishing (optional)

  1. Go to Ghost Admin, Settings, Integrations
  2. Click "Add custom integration"
  3. Name it "newsletter-digest"
  4. Copy the Admin API Key (format: key_id:secret)
  5. Set GHOST_ADMIN_KEY=key_id:secret in .env
  6. Set GHOST_URL=https://your-ghost-site.com in .env

How to Use

Generate a weekly digest:

"Generate a weekly digest from my RSS feeds"
"Create this week's newsletter"
"Summarize my feeds from the last 7 days"

Choose a specific format:

"Create a topic deep dive about AI agents from this week's news"
"Generate a curated picks digest for this week"
"Write a weekly roundup newsletter"

Extend the date window:

"Generate a digest from the last 14 days"
"Not many articles this week, extend the window to 2 weeks"

Publish to Ghost:

"Generate this week's digest and publish it to Ghost as a draft"
"Create the newsletter and publish it to Ghost"

Output for Substack:

"Generate a newsletter digest for Substack"
"Create the digest and give me the Markdown version"

Output

OutputDescription
HTMLReady to paste into any CMS
MarkdownFor Substack, Notion, Hashnode
Plain textFor email clients
Ghost draftPublished automatically if configured

Substack Note

Substack has no public API. The skill outputs a Markdown version of the digest for you to paste directly into the Substack editor.

Project Structure

newsletter-digest/
├── SKILL.md
├── README.md
├── .env.example
├── package.json
├── feeds.json            (your RSS feed list, edit this)
├── evals/
│   └── evals.json
├── references/
│   ├── digest-format.md  (format rules, length targets, attribution)
│   └── output-template.md (HTML templates for all 3 formats)
└── scripts/
    ├── fetch-feeds.js    (RSS fetching, dedup, date filtering)
    └── ghost-publish.js  (Ghost Admin API posting)

License

MIT


Supporting file: references/digest-format.md

Digest Format Reference

Rules for structuring newsletter digests. Read this before generating any content.


Three Digest Formats

Format 1: Weekly Roundup

Use for: General weekly digest covering top stories across all monitored feeds.

Target length: 350-500 words.

Structure:

  1. This Week in [Topic/Industry] — one sentence capturing the week's theme
  2. Top Story — 100-150 words on the single most significant story. Include one specific data point or quote from the source.
  3. Also Worth Reading — 3-5 stories, each 40-60 words with a source attribution link
  4. Quick Takes — 3-5 one-line bullets for minor stories
  5. Until Next Week — 1-2 sentence closing

Example section structure:

This Week in Developer Tools

The npm ecosystem had a rough week.

Top Story
[Title as H3]
[100-150 word summary. Every stat from the source. Source attribution link at end.]

Also Worth Reading
[Title as H3, linked to article]
[40-60 words. Key insight. [Source: Name](URL)]

Quick Takes
- [One-line summary. Source.](URL)
- [One-line summary. Source.](URL)

Until Next Week
[Closing sentence. No CTA filler.]

Format 2: Topic Deep Dive

Use for: A focused issue on a single topic (e.g., "AI agents this week", "security incidents this week").

Target length: 450-650 words.

Structure:

  1. The Big Picture — 80-100 words on why this topic matters this week
  2. Key Developments — 3-4 sections, each 80-100 words, covering one development each
  3. What to Watch — 2-3 bullet points on what happens next
  4. Resources — list of all source articles with URLs

Format 3: Curated Picks

Use for: "Editor's choice" digest with opinionated selection of the best reads.

Target length: 250-350 words.

Structure:

  1. This Week's Picks — one sentence framing the selection
  2. 5 picks — each with title (linked), 30-40 word description, and a one-line "Why read it" note
  3. One to skip — optional: one overhyped story and why it did not make the cut

Length Rules

FormatMinTargetMax
Weekly Roundup300400500
Topic Deep Dive400550650
Curated Picks200300380

If Gemini output is too long, cut the Quick Takes section first, then trim the Also Worth Reading summaries.


Attribution Rules

Every non-obvious claim needs a source link. Format:

  • Inline: [Source: Publication Name](https://full-url)
  • Section header links: ### [Story Title](https://full-url)
  • Bullet links: - [Headline](https://full-url) — one-line summary

Never write a data point, statistic, or quote without a linked attribution.


Tone Rules

  • Write for a reader who is busy. They scan. Use short paragraphs.
  • No hype. No "this is huge." Let the facts speak.
  • No first-person plural ("we noticed"). Write as a neutral observer.
  • One idea per paragraph, maximum three sentences per paragraph.
  • Dates: use full dates (April 10, 2026) not relative dates (this Tuesday).

HTML Output Rules

When generating HTML for Ghost:

  • Use <h2> for section headings (e.g., "Top Story", "Also Worth Reading")
  • Use <h3> for individual story titles
  • Use <p> for body text
  • Use <ul> and <li> for Quick Takes and bullet lists
  • Use <a href="URL"> for all source links
  • Do not use <div> with inline styles
  • Do not use markdown syntax in the HTML output

When generating Markdown for Substack:

  • Use ## for section headings
  • Use ### for story titles
  • Use [text](url) for links
  • Use - for bullet points

Supporting file: references/output-template.md

Output Templates

Three templates — one per digest format. Replace every [BRACKETED FIELD] with content from the fetched articles. Never leave bracket text in the final output. Skip sections that have no source material rather than inventing content.


Template 1: Weekly Roundup

<h2>This Week in [INDUSTRY/TOPIC]</h2>
<p>[ONE SENTENCE capturing the week's theme or dominant story. Specific, not generic.]</p>

<h2>Top Story</h2>
<h3><a href="[ARTICLE_URL]">[ARTICLE_TITLE]</a></h3>
<p>[100-150 word summary of the most significant story this week. Include one specific data point or quote directly from the article. No invented statistics.] <a href="[ARTICLE_URL]">[SOURCE_NAME]</a></p>

<h2>Also Worth Reading</h2>

<h3><a href="[ARTICLE_2_URL]">[ARTICLE_2_TITLE]</a></h3>
<p>[40-60 word summary. Key insight from the article.] <a href="[ARTICLE_2_URL]">[SOURCE_2_NAME]</a></p>

<h3><a href="[ARTICLE_3_URL]">[ARTICLE_3_TITLE]</a></h3>
<p>[40-60 word summary. Key insight from the article.] <a href="[ARTICLE_3_URL]">[SOURCE_3_NAME]</a></p>

<h3><a href="[ARTICLE_4_URL]">[ARTICLE_4_TITLE]</a></h3>
<p>[40-60 word summary. Key insight from the article.] <a href="[ARTICLE_4_URL]">[SOURCE_4_NAME]</a></p>

<h2>Quick Takes</h2>
<ul>
  <li><a href="[ARTICLE_5_URL]">[ARTICLE_5_TITLE]</a> — [One-line summary.]</li>
  <li><a href="[ARTICLE_6_URL]">[ARTICLE_6_TITLE]</a> — [One-line summary.]</li>
  <li><a href="[ARTICLE_7_URL]">[ARTICLE_7_TITLE]</a> — [One-line summary.]</li>
</ul>

<p>[1-2 sentence closing. No CTA filler. No "see you next week".]</p>

Worked example:

<h2>This Week in Developer Tools</h2>
<p>A major npm supply chain incident and two new runtime releases dominated developer news.</p>

<h2>Top Story</h2>
<h3><a href="https://blog.npmjs.org/post/supply-chain">npm Detects Malicious Package Injecting Crypto Miner</a></h3>
<p>The npm security team removed 47 packages after discovering a supply chain attack targeting Node.js build environments. The packages had been downloaded 2.3 million times before detection. The attack injected a crypto miner into postinstall scripts. npm is rolling out mandatory provenance attestation for all new package versions by June 2026. <a href="https://blog.npmjs.org/post/supply-chain">npm Blog</a></p>

<h2>Also Worth Reading</h2>

<h3><a href="https://bun.sh/blog/bun-1.2">Bun 1.2 Ships with Built-In S3 and SQL Support</a></h3>
<p>Bun 1.2 adds first-party APIs for S3 storage and SQL databases without any npm packages. The release also brings a 20% startup time improvement. <a href="https://bun.sh/blog/bun-1.2">Bun Blog</a></p>

<h2>Quick Takes</h2>
<ul>
  <li><a href="https://nodejs.org/en/blog/release/v22.14.0">Node.js 22.14.0 Released</a> — Minor patch with V8 12.4 backports and a fix for the http2 memory leak.</li>
  <li><a href="https://deno.com/blog/deno-2.2">Deno 2.2 Adds WebGPU Compute Shaders</a> — First runtime to support GPU compute from server-side JavaScript.</li>
</ul>

<p>Four feeds, 34 articles, one interesting week.</p>

Template 2: Topic Deep Dive

<h2>The Big Picture</h2>
<p>[80-100 words on why this topic is significant this week. Ground in specific events, not general claims. One data point from a source.]</p>

<h2>[DEVELOPMENT_1_HEADING]</h2>
<h3><a href="[ARTICLE_URL]">[ARTICLE_TITLE]</a></h3>
<p>[80-100 word summary. Specific facts, no invented details.] <a href="[ARTICLE_URL]">[SOURCE_NAME]</a></p>

<h2>[DEVELOPMENT_2_HEADING]</h2>
<h3><a href="[ARTICLE_URL]">[ARTICLE_TITLE]</a></h3>
<p>[80-100 word summary.] <a href="[ARTICLE_URL]">[SOURCE_NAME]</a></p>

<h2>[DEVELOPMENT_3_HEADING]</h2>
<h3><a href="[ARTICLE_URL]">[ARTICLE_TITLE]</a></h3>
<p>[80-100 word summary.] <a href="[ARTICLE_URL]">[SOURCE_NAME]</a></p>

<h2>What to Watch</h2>
<ul>
  <li>[Next development to follow, grounded in current events.]</li>
  <li>[Second thing to watch.]</li>
  <li>[Third thing to watch.]</li>
</ul>

<h2>This Week's Sources</h2>
<ul>
  <li><a href="[URL_1]">[TITLE_1]</a> — [SOURCE_NAME_1]</li>
  <li><a href="[URL_2]">[TITLE_2]</a> — [SOURCE_NAME_2]</li>
</ul>

Template 3: Curated Picks

<h2>This Week's Picks</h2>
<p>[One sentence framing the selection — what connects these picks or what made them stand out.]</p>

<h3>1. <a href="[ARTICLE_1_URL]">[ARTICLE_1_TITLE]</a></h3>
<p>[30-40 word description. Key takeaway.]</p>
<p><strong>Why read it:</strong> [One sentence. Specific reason.] <a href="[ARTICLE_1_URL]">[SOURCE_1_NAME]</a></p>

<h3>2. <a href="[ARTICLE_2_URL]">[ARTICLE_2_TITLE]</a></h3>
<p>[30-40 word description. Key takeaway.]</p>
<p><strong>Why read it:</strong> [One sentence. Specific reason.] <a href="[ARTICLE_2_URL]">[SOURCE_2_NAME]</a></p>

<h3>3. <a href="[ARTICLE_3_URL]">[ARTICLE_3_TITLE]</a></h3>
<p>[30-40 word description.]</p>
<p><strong>Why read it:</strong> [One sentence.] <a href="[ARTICLE_3_URL]">[SOURCE_3_NAME]</a></p>

<h3>4. <a href="[ARTICLE_4_URL]">[ARTICLE_4_TITLE]</a></h3>
<p>[30-40 word description.]</p>
<p><strong>Why read it:</strong> [One sentence.] <a href="[ARTICLE_4_URL]">[SOURCE_4_NAME]</a></p>

<h3>5. <a href="[ARTICLE_5_URL]">[ARTICLE_5_TITLE]</a></h3>
<p>[30-40 word description.]</p>
<p><strong>Why read it:</strong> [One sentence.] <a href="[ARTICLE_5_URL]">[SOURCE_5_NAME]</a></p>

Fill-in Rules

  1. Replace every [BRACKETED FIELD] with content from the fetched articles
  2. Never leave bracket text in the output
  3. Every URL must be an absolute URL (starts with https://)
  4. Every non-obvious claim needs a linked source attribution
  5. Skip a section if there is no source material for it
  6. Check word count before presenting — see references/digest-format.md for targets
  7. Do not use markdown in HTML output; do not use HTML tags in Markdown output
  8. Write the Markdown version after the HTML version by converting heading tags and links

How do I install Newsletter digest in Cursor, Claude Code, or Codex?

Run npx skills add varnan-tech/opendirectory --skill newsletter-digest in the project where you want it, then ask your agent for the skill by name. The --skill flag installs only Newsletter digest, not every skill in the repository.

Where does Newsletter digest come from and what license is it under?

Newsletter digest comes from the varnan-tech/opendirectory repository on GitHub. That repository has 624 GitHub stars. The skill is published under the MIT license.

Prefer plain text? Read the Newsletter digest guide as markdown.