From f6a1769e35920ea374286faf5a8c5d44d4a4e96f Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Thu, 5 Mar 2026 19:06:27 -0800 Subject: [PATCH 1/4] feat(skill): auto-save research results to ~/Documents/Last30Days/ Every run now automatically saves the complete briefing (synthesis, stats, follow-up suggestions) as a topic-named .md file in the user's Documents folder. Agent mode also saves. No Python script changes - this is purely a SKILL.md instruction addition. Inspired by @devin_explores manually saving results to build a personal research library. Co-Authored-By: Claude Opus 4.6 --- SKILL.md | 48 ++++++ ...eat-auto-save-results-to-documents-plan.md | 152 ++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 docs/plans/2026-03-05-feat-auto-save-results-to-documents-plan.md diff --git a/SKILL.md b/SKILL.md index 8d41c8a..a8e9d11 100644 --- a/SKILL.md +++ b/SKILL.md @@ -123,6 +123,8 @@ If `--agent` appears in ARGUMENTS (e.g., `/last30days plaud granola --agent`): 5. **Skip** the follow-up invitation ("I'm now an expert on X...") 6. **Output** the complete research report and stop - do not wait for further input +Agent mode still saves the research briefing to `~/Documents/Last30Days/` using the same logic as interactive mode (see "Save Research to Documents" section). + Agent mode report format: ``` @@ -496,6 +498,51 @@ For `/last30days war in Iran` (NEWS): --- +## Save Research to Documents + +After displaying the invitation, save the complete research briefing to the user's Documents folder. This happens automatically on every run. + +1. **Create the directory** (if it doesn't exist): + ```bash + mkdir -p ~/Documents/Last30Days + ``` + +2. **Generate the filename** from TOPIC: + - Lowercase the topic + - Replace spaces and special characters with hyphens + - Remove consecutive hyphens + - Trim to 60 characters max + - Example: "Claude Code Best Practices" -> `claude-code-best-practices` + +3. **Check for duplicates**: If `~/Documents/Last30Days/{slug}.md` already exists, append today's date: `{slug}-YYYY-MM-DD.md` + +4. **Use the Write tool** to save to `~/Documents/Last30Days/{slug}.md` with this exact structure: + +```markdown +# {TOPIC} + +> Researched {date} | Query type: {QUERY_TYPE} | Target tool: {TARGET_TOOL or "general"} + +## What I learned + +{The full synthesis section you just displayed - all topics, patterns, and citations} + +## Stats + +{The full stats box with source counts and engagement - copy exactly as displayed} + +## Follow-up suggestions + +{The 2-3 specific suggestions from the invitation block} + +--- +*Generated by [last30days](https://github.com/mvanhorn/last30days-skill) v2.9* +``` + +5. **Confirm briefly** after saving: `Saved to ~/Documents/Last30Days/{slug}.md` + +--- + ## WAIT FOR USER'S RESPONSE After showing the stats summary with your invitation, **STOP and wait** for the user to respond. @@ -607,6 +654,7 @@ Want another prompt? Just tell me what you're creating next. - Optionally sends search queries to Brave Search API, Parallel AI API, or OpenRouter API for web search - Fetches public Reddit thread data from `reddit.com` for engagement metrics - Stores research findings in local SQLite database (watchlist mode only) +- Saves research briefings as .md files to ~/Documents/Last30Days/ **What this skill does NOT do:** - Does not post, like, or modify content on any platform diff --git a/docs/plans/2026-03-05-feat-auto-save-results-to-documents-plan.md b/docs/plans/2026-03-05-feat-auto-save-results-to-documents-plan.md new file mode 100644 index 0000000..8800f01 --- /dev/null +++ b/docs/plans/2026-03-05-feat-auto-save-results-to-documents-plan.md @@ -0,0 +1,152 @@ +--- +title: "feat: Auto-save research results to ~/Documents/Last30Days/" +type: feat +status: completed +date: 2026-03-05 +--- + +# feat: Auto-save research results to ~/Documents/Last30Days/ + +## Overview + +Every time the last30days skill completes a research run, automatically save the full briefing - inquiry, synthesis, stats, and follow-up suggestions - as a topic-named `.md` file in `~/Documents/Last30Days/`. Inspired by how users like @devin_explores are already manually saving results to build a personal research library (see screenshot - 17 topic files in a `Last30Days` Finder folder, each 9-34 KB). + +## Problem Statement / Motivation + +The skill's most valuable output - the assistant's synthesized "What I learned" briefing with stats and citations - only exists in the conversation. Once the session ends, it's gone. Users like @devin_explores work around this by manually copying output into .md files. Meanwhile, the Python script already writes raw data to `~/.local/share/last30days/out/`, but: + +1. It overwrites on every run (no history) +2. It only contains pre-synthesis data (scored items), not the assistant's expert briefing +3. It's in a hidden dot-directory users don't naturally browse + +The feature makes saving automatic and puts files where users expect them - the Documents folder, visible in Finder/file explorer. + +## Proposed Solution + +Add a **Write tool step in SKILL.md** after the synthesis/stats/invitation block that saves the complete briefing to `~/Documents/Last30Days/{topic-slug}.md`. This is a SKILL.md-only change (no Python script modifications needed) because the content to save is the assistant's synthesized output, which only exists in the SKILL.md flow. + +### Why SKILL.md, not the Python script + +The Python script (`last30days.py`) runs first and produces raw scored items. The assistant then synthesizes these into the "What I learned" briefing, stats block, and invitation. The synthesis is the valuable part - it's what @devin_explores is saving. The script can't produce this because it runs before synthesis happens. + +### File naming + +Convert the TOPIC variable to a kebab-case slug for the filename: +- "Claude Code best practices" -> `claude-code-best-practices.md` +- "best rap songs 2026" -> `best-rap-songs-2026.md` +- "nano banana 2 prompting guide" -> `nano-banana-2-prompting-guide.md` + +This matches the screenshot pattern exactly (e.g., `anthropic-claude-code-best-practices.md`, `seedance-video-prompting-guide.md`). + +If a file with the same slug already exists, append a date suffix: `claude-code-best-practices-2026-03-05.md`. This handles re-researching the same topic without overwriting previous results. + +### File content + +The saved .md file should contain the complete research output in this order: + +```markdown +# {TOPIC} + +> Researched {date} | Query type: {QUERY_TYPE} | Target tool: {TARGET_TOOL or "general"} + +## What I learned + +{The full synthesis section - topics, patterns, citations} + +## Stats + +{The full stats box with source counts and engagement} + +## Follow-up suggestions + +{The 2-3 specific suggestions from the invitation block} + +--- +*Generated by [last30days](https://github.com/mvanhorn/last30days-skill) v2.9* +``` + +### Implementation location in SKILL.md + +Insert a new section between the current "LAST - Invitation" display and the "WAIT FOR USER'S RESPONSE" section. The Write tool call happens silently - no user prompt, no opt-in. Just save and briefly confirm. + +## Technical Considerations + +- **Cross-platform paths**: `~/Documents/` exists on macOS and most Linux desktops. On systems where it doesn't exist, `mkdir -p` handles creation. Windows WSL users get it too. +- **Permissions**: The Write tool in Claude Code can write to `~/Documents/` without issues. No sandbox concerns since this is the user's own Documents folder. +- **Filename sanitization**: Strip special characters, collapse whitespace to hyphens, lowercase. Keep it simple - no need for a library, just basic string ops in the SKILL.md instructions. +- **File size**: Based on the screenshot (9-34 KB files), the synthesis output is well within reasonable bounds. +- **No opt-out flag needed initially**: This is the default behavior. If users complain, a `--no-save` flag can be added later. Start with always-on since the screenshot proves users want this. + +## Acceptance Criteria + +- [x] Running `/last30days {topic}` creates `~/Documents/Last30Days/{topic-slug}.md` automatically +- [x] File contains: title, date, query metadata, full synthesis, stats block, follow-up suggestions +- [x] Filename is kebab-case slug of the topic (e.g., `claude-code-skills-guide.md`) +- [x] Duplicate topics get a date suffix instead of overwriting +- [x] Directory `~/Documents/Last30Days/` is created automatically if it doesn't exist +- [x] A brief confirmation line appears after the stats (e.g., "Saved to ~/Documents/Last30Days/claude-code-skills-guide.md") +- [x] Agent mode (`--agent`) also saves the file +- [x] No changes to the Python script - this is purely a SKILL.md addition + +## Implementation Steps + +### Step 1: Add save instructions to SKILL.md + +Insert a new section after the invitation block (after line ~496, before "WAIT FOR USER'S RESPONSE" at line ~499): + +**New section in `SKILL.md`:** + +```markdown +## Save Research to Documents + +After displaying the invitation, save the complete research briefing: + +1. Generate the filename from TOPIC: + - Lowercase the topic + - Replace spaces and special characters with hyphens + - Remove consecutive hyphens + - Trim to 60 characters max + - Example: "Claude Code Best Practices" -> "claude-code-best-practices" + +2. Check if file already exists. If so, append today's date: + - "claude-code-best-practices.md" exists -> use "claude-code-best-practices-2026-03-05.md" + +3. Use the Write tool to save to ~/Documents/Last30Days/{slug}.md with this content: + - H1 title: the TOPIC + - Metadata line: date, QUERY_TYPE, TARGET_TOOL + - Full "What I learned" synthesis (everything you just displayed) + - Full stats block + - Follow-up suggestions from the invitation + - Footer with skill attribution + +4. Confirm briefly: "Saved to ~/Documents/Last30Days/{slug}.md" +``` + +### Step 2: Update agent mode section + +The `--agent` mode section (line ~116) skips interactive elements but should still save. Add a note that agent mode saves the file with the same logic. + +### Step 3: Update Security & Permissions section + +Add to the "What this skill does" list (line ~599): +- "Saves research briefings as .md files to ~/Documents/Last30Days/" + +## Success Metrics + +- Users accumulate a browsable library of .md research files in their Documents folder +- No more manual copy-paste workflow to save results +- Files are immediately findable in Finder/file explorer search + +## Dependencies & Risks + +- **Low risk**: Write tool is already in the skill's `allowed-tools` list +- **Low risk**: ~/Documents/ is a standard, user-owned directory +- **Edge case**: If the skill is interrupted mid-run (before synthesis), no file is saved - this is correct behavior since there's nothing to save yet +- **Edge case**: Very long topics could produce unwieldy filenames - the 60-char truncation handles this + +## Sources & References + +- Screenshot from @devin_explores showing manual .md file library in ~/Documents/Last30Days/ +- Current output pipeline: `scripts/lib/render.py:798` (`write_outputs()`) writes to `~/.local/share/last30days/out/` +- SKILL.md synthesis flow: lines 275-496 (internalize research -> show summary -> invitation) +- Existing `--emit` modes: `scripts/last30days.py:1700` (`output_result()`) From 49d993b162fc4f8f0fb80f1be799aecc93027327 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Thu, 5 Mar 2026 19:15:42 -0800 Subject: [PATCH 2/4] feat(release): v2.9.1 - auto-save research to ~/Documents/Last30Days/ Bump version to 2.9.1, update changelog and release notes. Credit @devin_explores for inspiring the feature. Co-Authored-By: Claude Opus 4.6 --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 19 +++++++++++++++++++ SKILL.md | 6 +++--- release-notes.md | 12 ++++++++---- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 180cbc5..a8fd6dd 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "last30days", "description": "Research any topic from the last 30 days across Reddit, X, YouTube, and the web", - "version": "2.1.0", + "version": "2.9.1", "author": { "name": "mvanhorn" }, diff --git a/CHANGELOG.md b/CHANGELOG.md index a9320f2..f56fb5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.9.1] - 2026-03-05 + +### Highlights + +Auto-save research briefings to `~/Documents/Last30Days/` as topic-named .md files. Every run now builds a personal research library automatically - no more manual copy-paste. + +### Added + +- Auto-save complete research briefings (synthesis, stats, follow-up suggestions) to `~/Documents/Last30Days/{topic-slug}.md` after every run +- Kebab-case filename generation from topic (e.g., "Claude Code skills" -> `claude-code-skills.md`) +- Duplicate topic handling: appends date suffix instead of overwriting (e.g., `claude-code-skills-2026-03-05.md`) +- Agent mode (`--agent`) also saves research files +- Brief confirmation after save: "Saved to ~/Documents/Last30Days/{slug}.md" + +### Credits + +- [@devin_explores](https://x.com/devin_explores) -- Inspired this feature by sharing their workflow of saving every last30days run into organized .md files ([PR #51](https://github.com/mvanhorn/last30days-skill/pull/51)) + ## [2.9.0] - 2026-03-05 ### Highlights @@ -114,6 +132,7 @@ Three headline features: watchlists for always-on bots, YouTube transcripts as a Initial public release. Reddit + X search via OpenAI Responses API and xAI API. +[2.9.1]: https://github.com/mvanhorn/last30days-skill/compare/v2.9.0...v2.9.1 [2.9.0]: https://github.com/mvanhorn/last30days-skill/compare/v2.8.0...v2.9.0 [2.8.0]: https://github.com/mvanhorn/last30days-skill/compare/v2.6.0...v2.8.0 [2.1.0]: https://github.com/mvanhorn/last30days-skill/compare/v1.0.0...v2.1.0 diff --git a/SKILL.md b/SKILL.md index a8e9d11..ae86517 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,6 +1,6 @@ --- name: last30days -version: "2.9" +version: "2.9.1" description: "Research a topic from the last 30 days. Also triggered by 'last30'. Sources: Reddit, X, YouTube, TikTok, Instagram, Hacker News, Polymarket, web. Become an expert and write copy-paste-ready prompts." argument-hint: 'last30 AI video tools, last30 best project management tools' allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch @@ -30,7 +30,7 @@ metadata: - prompts --- -# last30days v2.9: Research Any Topic from the Last 30 Days +# last30days v2.9.1: Research Any Topic from the Last 30 Days Research ANY topic across Reddit, X, YouTube, TikTok, Hacker News, Polymarket, and the web. Surface what people are actually discussing, recommending, betting on, and debating right now. @@ -536,7 +536,7 @@ After displaying the invitation, save the complete research briefing to the user {The 2-3 specific suggestions from the invitation block} --- -*Generated by [last30days](https://github.com/mvanhorn/last30days-skill) v2.9* +*Generated by [last30days](https://github.com/mvanhorn/last30days-skill) v2.9.1* ``` 5. **Confirm briefly** after saving: `Saved to ~/Documents/Last30Days/{slug}.md` diff --git a/release-notes.md b/release-notes.md index 949d048..5e9a146 100644 --- a/release-notes.md +++ b/release-notes.md @@ -2,15 +2,19 @@ The AI world reinvents itself every month. This skill keeps you current. `/last30days` researches your topic across **Reddit, X, YouTube, TikTok, Instagram, Hacker News, Polymarket, and the web** from the last 30 days, finds what the community is actually upvoting, sharing, betting on, and saying on camera, and writes you a grounded narrative with real citations. +## What's New in v2.9.1 + +**Auto-save to ~/Documents/Last30Days/.** Every run now saves the complete research briefing - synthesis, stats, and follow-up suggestions - as a topic-named `.md` file to your Documents folder. Build a personal research library without lifting a finger. Inspired by [@devin_explores](https://x.com/devin_explores) who was already doing this manually. + ## Three Headline Features in v2.9 -**1. ScrapeCreators Reddit as default.** One `SCRAPECREATORS_API_KEY` now covers Reddit, TikTok, and Instagram — three sources, one key. No more `OPENAI_API_KEY` required for Reddit search. Faster, more reliable, and simpler to configure. +**1. ScrapeCreators Reddit as default.** One `SCRAPECREATORS_API_KEY` now covers Reddit, TikTok, and Instagram - three sources, one key. No more `OPENAI_API_KEY` required for Reddit search. Faster, more reliable, and simpler to configure. -**2. Smart subreddit discovery.** Relevance-weighted scoring replaces pure frequency count. Each candidate subreddit is scored by `frequency × recency × topic-word match`, and a `UTILITY_SUBS` blocklist filters noise subs like r/tipofmytongue. Search "Claude Code skills" and get r/ClaudeAI, r/ClaudeCode, r/openclaw — not generic programming subs. +**2. Smart subreddit discovery.** Relevance-weighted scoring replaces pure frequency count. Each candidate subreddit is scored by `frequency x recency x topic-word match`, and a `UTILITY_SUBS` blocklist filters noise subs like r/tipofmytongue. Search "Claude Code skills" and get r/ClaudeAI, r/ClaudeCode, r/openclaw - not generic programming subs. -**3. Top comments elevated.** The best comment on each Reddit thread now carries a 10% weight in engagement scoring and displays prominently with `💬` and upvote counts. Reddit's value is in the comments — now the skill surfaces them. +**3. Top comments elevated.** The best comment on each Reddit thread now carries a 10% weight in engagement scoring and displays prominently with upvote counts. Reddit's value is in the comments - now the skill surfaces them. -Plus: **Instagram Reels** (v2.8), **Polymarket prediction markets** (v2.5), **YouTube transcripts** (v2.1), **bundled X search** — no external CLI needed. +Plus: **Instagram Reels** (v2.8), **Polymarket prediction markets** (v2.5), **YouTube transcripts** (v2.1), **bundled X search** - no external CLI needed. ## Beta Test Results (v2.9) From 8cbbe87c3e0dc587d67b687f19a47e7d1518fedb Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Thu, 5 Mar 2026 19:27:18 -0800 Subject: [PATCH 3/4] docs: add v2.9.1 auto-save note to README Co-Authored-By: Claude Opus 4.6 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4194836..17c025f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# /last30days v2.9 +# /last30days v2.9.1 **The AI world reinvents itself every month. This skill keeps you current.** /last30days researches your topic across Reddit, X, YouTube, TikTok, Instagram, Hacker News, Polymarket, and the web from the last 30 days, finds what the community is actually upvoting, sharing, betting on, and saying on camera, and writes you a grounded narrative with real citations. Whether it's Seedance 2.0 access, paper.design prompts, or the latest Nano Banana Pro techniques, you'll know what people who are paying attention already know. +**New in v2.9.1 — Auto-save to ~/Documents/Last30Days/:** Every run now saves the complete briefing as a topic-named `.md` file to your Documents folder. Build a personal research library automatically. Inspired by [@devin_explores](https://x.com/devin_explores). + **New in v2.9 — ScrapeCreators Reddit + Top Comments + Smart Discovery:** Reddit now runs on [ScrapeCreators](https://scrapecreators.com) by default — one `SCRAPECREATORS_API_KEY` covers Reddit, TikTok, and Instagram (3 sources, 1 key). Smart subreddit discovery finds the right communities automatically, and top comments are elevated with a 10% scoring weight and `💬` display with upvote counts. [Details below.](#whats-new-in-v29) From 18f6273f7c285c53e971fb3a39d87161c240f330 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Fri, 6 Mar 2026 10:33:34 -0800 Subject: [PATCH 4/4] fix: save research silently via background Bash, not Write tool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Write tool displays "Wrote N lines..." after the invitation, ruining the end-of-run experience. Now saves via background Bash with a subtle 📎 footer line in the invitation text. Co-Authored-By: Claude Opus 4.6 --- SKILL.md | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/SKILL.md b/SKILL.md index ae86517..8faf843 100644 --- a/SKILL.md +++ b/SKILL.md @@ -500,25 +500,23 @@ For `/last30days war in Iran` (NEWS): ## Save Research to Documents -After displaying the invitation, save the complete research briefing to the user's Documents folder. This happens automatically on every run. +After displaying the invitation, save the complete research briefing to `~/Documents/Last30Days/`. This happens automatically on every run. -1. **Create the directory** (if it doesn't exist): - ```bash - mkdir -p ~/Documents/Last30Days - ``` +**Generate the filename** from TOPIC: +- Lowercase, replace spaces/special chars with hyphens, remove consecutive hyphens, trim to 60 chars +- Example: "Claude Code Best Practices" → `claude-code-best-practices.md` +- If file already exists, append today's date: `{slug}-YYYY-MM-DD.md` -2. **Generate the filename** from TOPIC: - - Lowercase the topic - - Replace spaces and special characters with hyphens - - Remove consecutive hyphens - - Trim to 60 characters max - - Example: "Claude Code Best Practices" -> `claude-code-best-practices` +**End your invitation with a single `📎` footer line:** -3. **Check for duplicates**: If `~/Documents/Last30Days/{slug}.md` already exists, append today's date: `{slug}-YYYY-MM-DD.md` +``` +📎 ~/Documents/Last30Days/{slug}.md +``` -4. **Use the Write tool** to save to `~/Documents/Last30Days/{slug}.md` with this exact structure: +**Then immediately save using a background Bash command** (`run_in_background: true`): -```markdown +```bash +mkdir -p ~/Documents/Last30Days && cat > ~/Documents/Last30Days/{slug}.md << 'RESEARCH_EOF' # {TOPIC} > Researched {date} | Query type: {QUERY_TYPE} | Target tool: {TARGET_TOOL or "general"} @@ -537,15 +535,20 @@ After displaying the invitation, save the complete research briefing to the user --- *Generated by [last30days](https://github.com/mvanhorn/last30days-skill) v2.9.1* +RESEARCH_EOF ``` -5. **Confirm briefly** after saving: `Saved to ~/Documents/Last30Days/{slug}.md` +**CRITICAL RULES:** +1. NEVER use the `Write` tool — it displays "Wrote N lines..." which ruins the experience +2. ALWAYS use `run_in_background: true` so the Bash call is nearly invisible +3. The `📎` line is part of your text message, not a separate tool call +4. The invitation + `📎` line must be the LAST visible thing on screen --- ## WAIT FOR USER'S RESPONSE -After showing the stats summary with your invitation, **STOP and wait** for the user to respond. +**STOP and wait** for the user to respond. ---