Compare commits
3 Commits
4d35b53eab
...
v2.9.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 49d993b162 | |||
| 6afc094bb1 | |||
| f6a1769e35 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "last30days",
|
"name": "last30days",
|
||||||
"description": "Research any topic from the last 30 days across Reddit, X, YouTube, and the web",
|
"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": {
|
"author": {
|
||||||
"name": "mvanhorn"
|
"name": "mvanhorn"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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/),
|
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).
|
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
|
## [2.9.0] - 2026-03-05
|
||||||
|
|
||||||
### Highlights
|
### 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.
|
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.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.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
|
[2.1.0]: https://github.com/mvanhorn/last30days-skill/compare/v1.0.0...v2.1.0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: last30days
|
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."
|
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'
|
argument-hint: 'last30 AI video tools, last30 best project management tools'
|
||||||
allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch
|
allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch
|
||||||
@@ -30,7 +30,7 @@ metadata:
|
|||||||
- prompts
|
- 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.
|
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.
|
||||||
|
|
||||||
@@ -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...")
|
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
|
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:
|
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.1*
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Confirm briefly** after saving: `Saved to ~/Documents/Last30Days/{slug}.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## WAIT FOR USER'S RESPONSE
|
## WAIT FOR USER'S RESPONSE
|
||||||
|
|
||||||
After showing the stats summary with your invitation, **STOP and wait** for the user to respond.
|
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
|
- 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
|
- Fetches public Reddit thread data from `reddit.com` for engagement metrics
|
||||||
- Stores research findings in local SQLite database (watchlist mode only)
|
- 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:**
|
**What this skill does NOT do:**
|
||||||
- Does not post, like, or modify content on any platform
|
- Does not post, like, or modify content on any platform
|
||||||
|
|||||||
@@ -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()`)
|
||||||
+8
-4
@@ -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.
|
`/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
|
## 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)
|
## Beta Test Results (v2.9)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user