Daily Digest Process an Obsidian daily note by classifying raw items, fetching/researching content, creating structured notes, and replacing raw items with wikilinks. Prerequisites Skill Required Purpose doc-obsidian Yes Vault CRUD via notesmd-cli + search via qmd res-x For X/Twitter URLs Fetch tweet content via xAI res-deep For loose ideas Multi-round research Optional dependency: scrapling -- headless browser fallback for sites that block WebFetch (403, empty content, captcha pages). Install with: uv tool install 'scrapling[all]' Workflow Step 0: Setup → Step 1: Scan & Classify → Step 2: Process → Step 3: Create Notes → Step 4: Update Daily → Step 5: Re-index & Report Step 0: Setup Run all three checks:
1. Vault path
VAULT
$( notesmd-cli print-default --path-only )
2. Read daily note (today or user-specified date)
DATE
$( date '+%Y-%m-%d' ) notesmd-cli print " $DATE "
3. xAI key (needed for res-x and res-deep full mode)
security find-generic-password -s "xai-api" -w ~/Library/Keychains/claude-keys.keychain-db 2
/dev/null && echo "XAI_AVAILABLE=true" || echo "XAI_AVAILABLE=false" If user specifies a date, use that instead of today. Step 1: Scan & Classify Parse the daily note and classify every item. Items live in these sections:
Notes
,
Log
,
Links
. Classification Rules Type Pattern Action Skip [[wikilink]] anywhere in line Already processed — skip Skip Section headers (
), frontmatter, empty lines, task checkboxes Structural — skip X tweet URL matching https://(x.com|twitter.com)/\w+/status/\d+ Fetch via res-x X article URL matching https://(x.com|twitter.com)/i/article/[\w-]+ Fetch via res-x GitHub repo URL matching https://github.com/[\w-]+/[\w-]+ WebFetch repo page Web URL Any other https://... URL WebFetch page Loose idea Non-empty text that is not a URL, not a wikilink, not structural Deep research via res-deep Present Classification Before processing, show the user a classification table:
Daily Digest:
| # | Section | Type | Item (truncated) | Action |
|---|---|---|---|---|
| 1 | Links | X tweet | https://x.com/user/status/123... | res-x fetch |
| 2 | Notes | Loose idea | Train a model to click on... | res-deep |
| 3 | Links | GitHub | https://github.com/org/repo | WebFetch |
| 4 | Log | Skip | [[already-processed]] — ... | skip |
| Ask user to confirm or exclude items before proceeding. User may: | ||||
| Approve all | ||||
| Exclude specific items by number | ||||
| Change action for an item (e.g., skip an idea, or upgrade a URL to res-deep) | ||||
| Step 2: Process Items | ||||
| Process approved items. Run independent fetches in parallel where possible. | ||||
| X/Twitter URLs | ||||
| Requires xAI key (XAI_AVAILABLE=true). | ||||
| uv run ~/.claude/skills/res-x/scripts/x_fetch.py fetch | ||||
| "URL1" | ||||
| "URL2" | ||||
| "URL3" | ||||
| The script batches 3 URLs per API call. Extract from results: | ||||
| Author handle and display name | ||||
| Full tweet text | ||||
| Engagement metrics (likes, reposts, replies, views) | ||||
| Thread context and quoted tweets if present | ||||
| If XAI_AVAILABLE=false, report that X URLs require xAI key and skip them. | ||||
| GitHub URLs | ||||
| WebFetch: https://github.com/{owner}/{repo} | ||||
| Prompt: "Extract: repo name, description, star count, language, license, last update date, and a 2-3 sentence summary of what this project does based on the README." | ||||
| Scrapling fallback: | ||||
| If WebFetch returns 403, empty content, a captcha page, or a blocked response, retry using the | ||||
| auto-escalation protocol | ||||
| from cli-web-scrape: | ||||
| scrapling extract get "URL" /tmp/scrapling-fallback.md | ||||
| → Read → validate content | ||||
| If content is thin (JS-only shell, no data) → | ||||
| scrapling extract fetch "URL" /tmp/scrapling-fallback.md --network-idle --disable-resources | ||||
| → Read → validate | ||||
| If still blocked → | ||||
| scrapling extract stealthy-fetch "URL" /tmp/scrapling-fallback.md --solve-cloudflare | ||||
| All tiers fail → note failure and move on | ||||
| Web URLs | ||||
| WebFetch: | ||||
| Prompt: "Extract: page title, author if available, publication date if available, and a 3-5 sentence summary of the key content." | ||||
| Scrapling fallback: | ||||
| If WebFetch returns 403, empty content, a captcha page, or a blocked response, retry using the | ||||
| auto-escalation protocol | ||||
| from cli-web-scrape: | ||||
| scrapling extract get "URL" /tmp/scrapling-fallback.md | ||||
| → Read → validate content | ||||
| If content is thin (JS-only shell, no data) → | ||||
| scrapling extract fetch "URL" /tmp/scrapling-fallback.md --network-idle --disable-resources | ||||
| → Read → validate | ||||
| If still blocked → | ||||
| scrapling extract stealthy-fetch "URL" /tmp/scrapling-fallback.md --solve-cloudflare | ||||
| All tiers fail → note failure and move on | ||||
| Loose Ideas | ||||
| Invoke res-deep skill with the idea text as the query. Use | ||||
| quick | ||||
| depth (1 round, 10-15 sources) unless user requests deeper research. | ||||
| For ideas, the res-deep output becomes the note body directly. | ||||
| Step 3: Create Notes | ||||
| For each processed item, create an Obsidian note. | ||||
| Note Naming | ||||
| Type | ||||
| Naming Pattern | ||||
| Example | ||||
| X tweet | ||||
| {topic}-{descriptor} | ||||
| from content | ||||
| scrapling-undetectable-web-scraping | ||||
| X article | ||||
| {author}-x-article-{date} | ||||
| irabukht-x-article-2026-02-23 | ||||
| GitHub repo | ||||
| {repo-name} | ||||
| scrapling | ||||
| or | ||||
| huggingface-skills-agent-plugins | ||||
| Web page | ||||
| {topic}-{descriptor} | ||||
| from title | ||||
| kubernetes-practical-learning-path | ||||
| Loose idea | ||||
| {concept}-{descriptor} | ||||
| agent-sort-through-the-slop | ||||
| Deep research | ||||
| {topic}-deep-research | ||||
| scrapling-deep-research | ||||
| All names: kebab-case, lowercase, no special characters. | ||||
| Check for existing notes with same name before creating. If exists, append | ||||
| -2 | ||||
| or ask user. | ||||
| Note Structure | ||||
| For X tweets / web pages / GitHub repos (quick captures): | ||||
| notesmd-cli create | ||||
| "NOTE_NAME" | ||||
| --content | ||||
| "--- | ||||
| tags: [TYPE_TAG] | ||||
| source: SOURCE_URL | ||||
| author: AUTHOR | ||||
| date: DATE | ||||
| --- | ||||
| # TITLE | ||||
| ## Key Points | ||||
| - Point 1 | ||||
| - Point 2 | ||||
| - Point 3 | ||||
| ## Summary | ||||
| Brief paragraph summarizing the content. | ||||
| ## Source | ||||
| - Original" | ||||
| Type tags: | ||||
| tweet | ||||
| for X, | ||||
| github | ||||
| for GitHub, | ||||
| web | ||||
| for web pages, | ||||
| idea | ||||
| for ideas. | ||||
| For deep research (ideas): | ||||
| The res-deep skill produces its own structured output. Create the note with that output as body, adding frontmatter: | ||||
| notesmd-cli create | ||||
| "NOTE_NAME" | ||||
| --content | ||||
| "--- | ||||
| tags: [idea, research] | ||||
| date: DATE | ||||
| --- | ||||
| {res-deep output here}" | ||||
| Step 4: Update Daily Note | ||||
| For each processed item, replace the raw text in the daily note with a wikilink. | ||||
| Wikilink Format by Section | ||||
| ## Links section | ||||
| (URLs from bookmarks/saves): | ||||
| - [[note-name]] — @author: summary with key metrics (stars, likes, etc.) | ||||
| ## Notes section | ||||
| (ideas and thoughts): | ||||
| - [[note-name]] — Brief: what the idea/research covers | ||||
| ## Log section | ||||
| (activity entries): | ||||
| - [[note-name]] — Summary of what was captured | ||||
| Edit Procedure | ||||
| Read the daily note: | ||||
| notesmd-cli print "$DATE" | ||||
| Resolve vault path: | ||||
| VAULT=$(notesmd-cli print-default --path-only) | ||||
| Use the Edit tool to replace each raw item with its wikilink line | ||||
| Replace one item at a time to avoid Edit conflicts | ||||
| Verify the final note by reading it again | ||||
| Rules | ||||
| Preserve existing wikilinks — never modify already-processed lines | ||||
| Keep section structure intact (## headers, empty lines between items) | ||||
| If an item spans multiple lines (e.g., a paragraph idea), replace all lines with one wikilink line | ||||
| The wikilink summary should be concise (under 120 chars) but include key metrics when available | ||||
| Step 5: Re-index & Report | ||||
| Re-index Vault | ||||
| qmd update | ||||
| && | ||||
| qmd embed | ||||
| Summary Report | ||||
| Present a summary table: | ||||
| ## Digest Complete: | ||||
| # | Type | Note Created | Status | |
| --- | ------ | ------------- | -------- | |
| 1 | X tweet | [[note-name]] | Created | |
| 2 | Loose idea | [[note-name]] | Created (res-deep quick) | |
| 3 | GitHub | [[note-name]] | Created | |
| 4 | Web URL | — | Failed (403) | |
| Notes created: 3 | ||||
| Items skipped: 2 (already processed) | ||||
| Items failed: 1 | ||||
| Vault re-indexed: Yes | ||||
| Modes | ||||
| Full (default) | ||||
| Process all unprocessed items in the daily note. | ||||
| "Process my daily note" / "Daily digest" | ||||
| Selective | ||||
| Process only specific items or sections. | ||||
| "Process only the links in today's daily note" | ||||
| "Digest just the X URLs" | ||||
| Date Override | ||||
| Process a specific date's daily note. | ||||
| "Process yesterday's daily note" | ||||
| "Digest 2026-02-20" | ||||
| Dry Run | ||||
| Classify and show the table (Step 1) without processing. | ||||
| "What's unprocessed in my daily note?" | ||||
| "Show me what needs digesting" | ||||
| Constraints | ||||
| DO: | ||||
| Always run Step 0 (vault path + daily note + xAI check) first | ||||
| Present classification table and wait for user approval before processing | ||||
| Process items in parallel where independent (multiple WebFetch calls, multiple X URLs in one batch) | ||||
| Check for existing notes before creating to avoid duplicates | ||||
| Read the daily note before editing — never guess content | ||||
| Resolve vault path dynamically via | ||||
| notesmd-cli print-default --path-only | ||||
| DON'T: | ||||
| Process items the user excluded from the classification table | ||||
| Modify already-processed wikilink lines | ||||
| Hardcode vault paths | ||||
| Skip the classification approval step | ||||
| Run res-deep at default/deep depth unless user explicitly requests it — use quick for daily digest | ||||
| Create notes without frontmatter |