diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..623b925 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# macOS +.DS_Store + +# Editor / OS junk +*.swp +*~ +.idea/ +.vscode/ diff --git a/README.md b/README.md index 836e839..b68030e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A weekly AI learning curator I built for myself โ€” and you can fork it for yours. -Every Sunday at 7pm, this agent scans 49 hand-picked sources, scores everything against the topic I'm studying that week, and writes 5โ€“7 ranked recommendations into my Notion. The whole thing is a structured prompt. No code to maintain. +Every Sunday at 7pm, this agent scans 48 hand-picked sources, scores everything against the topic I'm studying that week, and writes 5โ€“7 ranked recommendations into my Notion. The whole thing is a structured prompt. No code to maintain. **Built for** designers, PMs, and anyone learning AI from a non-CS background who wants the signal without the scrolling. If you can edit a Notion page, you can run this. If you can edit a markdown file, you can adapt it. @@ -92,7 +92,7 @@ Full spec: [`config/scoring-algorithm.md`](https://github.com/Katherine-Peng/Lea --- -## The 49 sources +## The sources | Category | Examples | Count | | --- | --- | --- | @@ -110,6 +110,13 @@ Full list with feed URLs: [`config/sources.md`](https://github.com/Katherine-Pen # ๐Ÿš€ Setup +## Scheduling: where it runs + +There are two ways to run this on a schedule: + +- **โ˜๏ธ Cloud Routine (recommended) โ€” runs even with your laptop closed.** Create a [Claude Code Routine](https://claude.ai/code/routines): point it at this repo, set the trigger to **Weekly ยท Sunday ยท 7:00 PM** (your local time), set the environment's **Network access to Full** (the briefing fetches ~40 RSS/web sources), and keep the **Notion** connector enabled. The routine runs `prompts/weekly-briefing.md`, writes that week's picks to your Notion **Learning Agent Recommendation** page, and @mentions you so Notion pushes a notification to your phone. Note: routines clone your repo's **default branch**, so merge prompt changes to `main` before they take effect. +- **๐Ÿ’ป Local Desktop scheduled task โ€” runs on your machine.** Use the manual steps below if you'd rather it run locally (requires your machine to be on). + ## Option A โ€” Let Claude Code install it for you (recommended) If you already have [Claude Code](https://docs.anthropic.com/en/docs/claude-code) on your laptop, this is by far the easiest way. You don't follow any steps yourself โ€” just send Claude Code this repo URL and ask it to install: @@ -241,7 +248,7 @@ Learning-Agent/ โ”œโ”€โ”€ prompts/ โ”‚ โ””โ”€โ”€ weekly-briefing.md โ† the agent's brain โ”œโ”€โ”€ config/ -โ”‚ โ”œโ”€โ”€ sources.md โ† 49 sources with feed URLs +โ”‚ โ”œโ”€โ”€ sources.md โ† 48 sources with feed URLs โ”‚ โ”œโ”€โ”€ scoring-algorithm.md โ† full scoring spec โ”‚ โ””โ”€โ”€ previously-recommended.md โ† dedup log (appended each run) โ””โ”€โ”€ logs/ diff --git a/config/sources.md b/config/sources.md index 96d90c8..4c14739 100644 --- a/config/sources.md +++ b/config/sources.md @@ -1,7 +1,7 @@ # Master Source Table โ€” Local Cache -> Exported from Notion on 2026-03-18 +> Originally exported from Notion on 2026-03-18; manually maintained since (last edit 2026-06-09). > Source: Master Source Table (32782e5a-5fa3-80de-8f18-c36ae43cffd8) -> To refresh: re-export from Notion +> This file is the source list the agent actually reads. To refresh, edit it directly or re-export from Notion. ## Sources @@ -35,7 +35,7 @@ | 26 | Simon Willison | 1 | AI Engineering | Blog | simonwillison.net | https://simonwillison.net/atom/everything/ | Always surface. MCP + agent posts = Must Read. | | 27 | Ethan Mollick | 1 | AI + Work | Substack | oneusefulthing.org | https://www.oneusefulthing.org/feed | Always surface. Every post is relevant. | | 28 | Lenny Rachitsky | 1 | Product | Substack | lennysnewsletter.com | https://www.lennysnewsletter.com/feed | Surface AI posts as Must Read. Prefer YouTube over paywalled text. | -| ~~29~~ | ~~Benedict Evans~~ | โ€” | โ€” | โ€” | โ€” | โ€” | REMOVED โ€” RSS feed broken (404), no alternative found. Re-add if feed becomes available. | +| 29 | Benedict Evans | 2 | Strategy | Blog | ben-evans.com/benedictevans | No RSS โ€” WebSearch | Re-added 2026-06-09. Author **deliberately disabled RSS** (confirmed 2025) and the site returns HTTP 403 to bots, so no feed or direct fetch works. Discover via WebSearch `site:ben-evans.com/benedictevans {topic}` in the evergreen/discovery scan. Best-effort. | | 30 | AI Snake Oil โ†’ Normal Tech | 1 | Safety | Substack | normaltech.ai (was aisnakeoil.substack.com) | https://www.normaltech.ai/feed | Surface everything. Posts challenging mainstream claims = Must Read. Rebranded from AI Snake Oil to Normal Tech in 2026. | | 31 | Chip Huyen | 2 | AI Engineering | Blog | huyenchip.com | https://huyenchip.com/feed.xml | Surface systems + eval posts. | | 32 | Nathan Lambert | 2 | Alignment | Substack | interconnects.ai | https://www.interconnects.ai/feed | Surface alignment + behaviour posts. Skip if paywalled. | diff --git a/logs/.DS_Store b/logs/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/logs/.DS_Store and /dev/null differ diff --git a/prompts/weekly-briefing.md b/prompts/weekly-briefing.md index 551e2db..ab2fb7f 100644 --- a/prompts/weekly-briefing.md +++ b/prompts/weekly-briefing.md @@ -6,15 +6,15 @@ You are Katherine's Learning Partner Agent. Your job is to find the highest-qual --- -## STEP 1 โ€” Read context (2 tool calls) +## STEP 1 โ€” Read context (read all sources below before scanning) ### 1a. Read the local source list -Read the file at `./config/sources.md`. This contains 48 curated sources with Name, Tier, Category, Type, URL, Feed URL, and Agent Notes. +Read the file at `./config/sources.md`. This contains the curated source list โ€” each row has Name, Tier, Category, Type, URL, Feed URL, and Agent Notes. Rows marked `REMOVED` (currently #12) should be skipped. **Important:** Some Feed URLs may still have backtick formatting โ€” strip backticks before using with WebFetch. -### 1b. Read the previously-recommended log -Read `./config/previously-recommended.md`. Every URL listed here has already been recommended โ€” exclude them from this week's briefing. +### 1b. Read the previously-recommended log (best-effort seed) +Read `./config/previously-recommended.md` if it exists. Treat it as a best-effort seed of already-recommended URLs โ€” **not** the source of truth. In cloud runs this file may be stale (a fresh clone won't include picks from runs that weren't committed back). The authoritative dedup sources are the Notion Weekly Checklist (1c) and the recent briefing pages (1d). ### 1c. Read the Weekly Checklist from Notion (single source of truth) Fetch the Notion page `31982e5a-5fa3-809b-bb66-c3bc6015a92b` (AI Learning Plan โ€” Weekly Checklist). @@ -32,15 +32,16 @@ From this page, determine: 2. **URLs already in the plan**: Extract ALL URLs from the entire checklist (all weeks). These are excluded from recommendations, even if they don't appear in previously-recommended.md. 3. **Current week's topic**: Note the week title and content focus (e.g., "Week 2 ยท Attention, transformers + Learning Partner Agent v1"). +### 1d. Read recent briefing pages from Notion (authoritative dedup) +Fetch the **Learning Agent Recommendation** page (`33f82e5a-5fa3-8062-9bf2-c019bf572c5f`) and open its most recent ~6 child pages (prior "Weekly Picks" briefings). Extract every URL they recommended and add it to the exclusion set. This is the durable dedup memory โ€” it does not depend on any local file being committed back after a run. + --- ## STEP 2 โ€” Collect content (two parallel scans) Run two complementary scans. Budget your tool calls carefully: - **YouTube RSS**: ~13 WebFetch calls (one per channel) -- **Blog/Substack RSS**: ~8 WebFetch calls (Tier 1 feeds) -- **X WebSearch**: ~3 calls (Tier 1 names only) -- **Broad discovery**: ~3 WebSearch calls +- **Blog/Substack RSS**: ~8 WebFetch calls (Tier 1 feeds)- **Broad discovery**: ~3 WebSearch calls - **Evergreen scan**: ~3 WebSearch calls - **YouTube engagement check**: ~3-5 WebFetch calls (top candidates only) - **Notion write**: 1 call @@ -59,14 +60,6 @@ For each Tier 1 source with a Feed URL (not YouTube), WebFetch the RSS/Atom feed Filter for posts published in the last 7 days. Record: title, URL, published date, author, description/summary. For sources marked "No RSS โ€” manual" in Agent Notes (e.g., #17 Microsoft HAX, #24 Emily Campbell, #25 Amelia Wattenberger), WebFetch their homepage URL and check for new content. - -**X / Twitter** (secondary source โ€” WebSearch only): -For the top 5 Tier 1 individuals, run WebSearch queries: -``` -site:x.com "{person name}" {current week primary topic} after:{7 days ago date} -``` -Only surface posts that got enough traction to be indexed by search. - ### 2b. EVERGREEN SCAN โ€” Best of the last 18 months Run 3-5 targeted WebSearch queries focused on the current week's primary topic: @@ -193,20 +186,41 @@ Create a child page under the **Learning Agent Recommendation** page (`33f82e5a- ``` **Generated:** {date} | **Focus:** {week_topic} -**Sources checked:** YouTube ({n} channels), Blogs/RSS ({n}), Web ({n} searches), X ({n} accounts) -**Estimated total reading time:** ~{N} hours {M} min +**Sources checked:** YouTube ({n} channels), Blogs/RSS ({n}), Web ({n} searches) | **Reading time:** ~{N} hr {M} min + +--- + +## โœจ This Week's Highlight +{1โ€“2 short paragraphs โ€” the Learning-Agent's plain-prose summary of the week: what changed, what's most worth focusing on, and any notable industry news / launches / debates relevant to Week {N}. This is the "read this first" overview. (This replaces the old Signals & Patterns section and now lives at the top.)} + +--- + +## โœ… Weekly plan +{The actionable checklist โ€” tick these off / copy into the Weekly Plan. Every item MUST include all four: tier emoji (โญ Must Read ยท ๐ŸŸ  Recommended ยท ๐Ÿ”ต Discovered ยท ๐Ÿƒ Wild Card), title, estimated time, and full clickable URL.} + +- [ ] โญ {Must Read 1 title} ยท ~{N} min {read/watch} ยท {URL} +- [ ] โญ {Must Read 2 title} ยท ~{N} min {read/watch} ยท {URL} +- [ ] ๐ŸŸ  {Recommended 1 title} ยท ~{N} min {read/watch} ยท {URL} +- [ ] ๐ŸŸ  {Recommended 2 title} ยท ~{N} min {read/watch} ยท {URL} +- [ ] ๐Ÿ”ต {Discovered title} ยท ~{N} min {read/watch} ยท {URL} +- [ ] ๐Ÿƒ {Wild Card title} ยท ~{N} min {read/watch} ยท {URL} + +(Adjust lines to match actual count โ€” hard cap 7 items total.) --- ## โญ Must Read ### 1. {Title} -**{Author}** ยท {Platform} ยท {Type ~N min read/watch} ยท Score: {N}/100 -{URL} +**{Author}** ยท {Platform} ยท ~{N} min {read/watch} ยท Score: {N}/100 +๐Ÿ”— {URL} -**Summary:** {One paragraph โ€” what this content IS about. The key argument, framework, or insight. Written so Katherine can decide if she wants to read the full piece.} +**Summary** +- {Key point โ€” what it is, its core argument or framework} +- {Second bullet if needed โ€” one idea per bullet, not a dense paragraph} -**Why it matters for Week {N}:** {2-3 sentences connecting this content to her current week's learning topic, her role at Microsoft M365 Copilot, or her broader learning goals.} +**Why it matters (Week {N})** +- {1โ€“2 bullets connecting it to this week's topic, her M365 Copilot work, or learning goals} ### 2. {Title} ... @@ -216,73 +230,56 @@ Create a child page under the **Learning Agent Recommendation** page (`33f82e5a- ## ๐ŸŸ  Recommended ### {N}. {Title} -**{Author}** ยท {Platform} ยท {Type ~N min read/watch} ยท Score: {N}/100 -{URL} +**{Author}** ยท {Platform} ยท ~{N} min {read/watch} ยท Score: {N}/100 +๐Ÿ”— {URL} -**Summary:** {One paragraph summary.} +**Summary** +- {1โ€“2 concise bullets} -**One-liner:** {Single sentence on why it's worth her time.} +**Worth it because:** {single sentence} ... --- ## ๐Ÿ”ต Discovered (Beyond Your List) -{0-2 items from broad discovery, clearly labeled as new voices} +{0โ€“2 items from broad discovery, clearly labeled as new voices} ### {Title} -**{Author}** ยท {Platform} ยท {Type ~N min read/watch} ยท Score: {N}/100 -{URL} +**{Author}** ยท {Platform} ยท ~{N} min {read/watch} ยท Score: {N}/100 +๐Ÿ”— {URL} -**Who is this:** {1 sentence on who this person is and why they're worth attention.} -**Summary:** {One paragraph.} +- **Who is this:** {1 sentence on who they are and why they're worth attention} +- **Summary:** {1โ€“2 bullets} --- ## ๐Ÿƒ Wild Card ### {Title} -**{Author}** ยท {Platform} ยท {Type ~N min read/watch} ยท Score: {N}/100 -{URL} +**{Author}** ยท {Platform} ยท ~{N} min {read/watch} ยท Score: {N}/100 +๐Ÿ”— {URL} -**Why this is the Wild Card:** {2-3 sentences on what makes this surprising, contrarian, or cross-domain.} -**Summary:** {One paragraph.} +- **Why it's the Wild Card:** {what makes it surprising, contrarian, or cross-domain} +- **Summary:** {1โ€“2 bullets} --- -## ๐Ÿ“Š Signals & Patterns -{2-3 sentences noting patterns: "Multiple voices discussed X this week", "New tool launched relevant to Week N", "Emerging debate about Y"} +{Put Source Health at the very bottom. Prefer a COLLAPSED TOGGLE (read the Notion enhanced-markdown spec for the exact toggle syntax); if a toggle can't be created reliably, fall back to a plain `## ๐Ÿ”ง Source Health` heading โ€” never leave a literal โ–ธ character.} ## ๐Ÿ”ง Source Health -YouTube: {OK/Degraded/Failed} | Blogs/RSS: {OK/Degraded/Failed} | Web: {OK/Degraded/Failed} | X: {OK/Degraded/Failed} +YouTube: {OK/Degraded/Failed} | Blogs/RSS: {OK/Degraded/Failed} | Web: {OK/Degraded/Failed} {Note any feeds that returned errors or empty results} - ---- - -## โœ… Checklist โ€” Copy to Weekly Plan - -CRITICAL: Every checklist item MUST include ALL of these โ€” missing any is a bug: -1. Tier emoji (โญ = Must Read, ๐ŸŸ  = Recommended, ๐Ÿ”ต = Discovered, ๐Ÿƒ = Wild Card) -2. Title -3. Estimated time (e.g. "~15 min read" or "~45 min watch") -4. Full clickable URL - -- [ ] โญ {Must Read 1 title} ยท ~{N} min {read/watch} ยท {URL} -- [ ] โญ {Must Read 2 title} ยท ~{N} min {read/watch} ยท {URL} -- [ ] ๐ŸŸ  {Recommended 1 title} ยท ~{N} min {read/watch} ยท {URL} -- [ ] ๐ŸŸ  {Recommended 2 title} ยท ~{N} min {read/watch} ยท {URL} -- [ ] ๐Ÿ”ต {Discovered title} ยท ~{N} min {read/watch} ยท {URL} -- [ ] ๐Ÿƒ {Wild Card title} ยท ~{N} min {read/watch} ยท {URL} - -(Adjust lines to match actual count โ€” hard cap 7 items total) ``` --- -## STEP 5 โ€” Update the dedup log +## STEP 5 โ€” Update the dedup log (best-effort) After writing the briefing, append all recommended URLs (Must Read + Recommended + Discovered + Wild Card) to `./config/previously-recommended.md`. +**Note:** The durable dedup record is Notion (the new briefing page plus the prior pages read in Step 1d), because cloud runs start from a fresh clone and can only push to a `claude/` branch. Updating this file is a best-effort convenience for local runs โ€” don't rely on it persisting, and don't block or fail the run trying to commit it. + Format: one URL per line, with a date comment: ``` # Week {N} โ€” {YYYY-MM-DD} @@ -316,6 +313,20 @@ Duration: {approximate} --- +## STEP 7 โ€” Notify Katherine on her phone + +After the briefing page exists, send a notification so Katherine sees it on her phone. The **Google Calendar event is the primary channel** (it reliably pushes to her phone via her active Google account); the Notion mention is a secondary nicety. + +1. **Google Calendar event (primary, reliable).** Using the Google Calendar connector, create an event on her primary calendar starting at run time, **10 minutes long**, with a popup reminder at 0 minutes so her phone gets an immediate push: + - summary: `Learning-Agent Weekly Picks` + - description: the new page URL + a one-line teaser of the top pick + - startTime / endTime: now to now+10min, timeZone `Europe/London` + - overrideReminders: `[{method: popup, minutes: 0}]` +2. **Notion @mention (secondary).** Post a **short, simple** comment on the **newly created Weekly Picks page** (never the parent "Learning Agent Recommendation" page), mentioning **only** Katherine's main account `1e0d872b-594c-816f-a40c-00027d528a9d` (katherinepeng.uk). Keep it to one line, e.g. `๐Ÿ“ฌ Your Week {N} picks are ready โ€”` followed by the page link. +3. **Claude push (best-effort).** If the `PushNotification` tool is available during the run, also call it. If not, that's expected โ€” never fail the run over this. + +--- + ## Quality checklist (self-check before finishing) Before creating the Notion page, verify: @@ -327,6 +338,9 @@ Before creating the Notion page, verify: - [ ] Wild Card is genuinely surprising, not just a lower-scoring version of the same type of content - [ ] Source Health accurately reports which sources succeeded/failed - [ ] EVERY item has an estimated time (blogs: ~250 words/min; videos: use actual duration; interactive tools: estimate exploration time) -- [ ] Checklist at bottom has ALL of: tier emoji, title, estimated time, full URL for EVERY item +- [ ] **Weekly plan** section (near the top) has ALL of: tier emoji, title, estimated time, full URL for EVERY item - [ ] Total estimated reading time in header is the sum of all item times - [ ] Hard cap of 7 items total is respected +- [ ] Page order is: โœจ This Week's Highlight โ†’ โœ… Weekly plan โ†’ โญ Must Read โ†’ ๐ŸŸ  Recommended โ†’ ๐Ÿ”ต Discovered โ†’ ๐Ÿƒ Wild Card โ†’ ๐Ÿ”ง Source Health (collapsed toggle at the very bottom) +- [ ] This Week's Highlight is 1โ€“2 short paragraphs at the top (it replaces the old Signals & Patterns) +- [ ] Summaries use bullet points (one idea per bullet), not dense paragraphs