diff --git a/variants/open/SKILL.md b/variants/open/SKILL.md new file mode 100644 index 0000000..7e24b16 --- /dev/null +++ b/variants/open/SKILL.md @@ -0,0 +1,77 @@ +--- +name: last30days +version: "2.1-open" +description: "Research topics, manage watchlists, and get morning briefings — all from Reddit, X, YouTube, and the web." +argument-hint: 'AI video tools, watch add "NVIDIA news", briefing, history --trending' +allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch +--- + +# last30days (open variant): Research + Watchlist + Briefings + +Multi-mode research skill with persistent knowledge accumulation. + +## Command Routing + +Parse the user's first argument to determine the mode: + +| First word | Mode | Reference | +|---|---|---| +| `watch` | Watchlist management | `references/watchlist.md` | +| `briefing` | Morning briefing | `references/briefing.md` | +| `history` | Query accumulated knowledge | `references/history.md` | +| *(anything else)* | One-shot research | `references/research.md` | + +## Setup: Find Skill Root + +```bash +for dir in \ + "." \ + "${CLAUDE_PLUGIN_ROOT:-}" \ + "$HOME/.claude/skills/last30days" \ + "$HOME/.agents/skills/last30days" \ + "$HOME/.codex/skills/last30days"; do + [ -n "$dir" ] && [ -f "$dir/scripts/last30days.py" ] && SKILL_ROOT="$dir" && break +done + +if [ -z "${SKILL_ROOT:-}" ]; then + echo "ERROR: Could not find scripts/last30days.py" >&2 + exit 1 +fi +``` + +Use `$SKILL_ROOT` for all script and reference file paths. + +## Load Context + +At session start, read `${SKILL_ROOT}/variants/open/context.md` for user preferences and source quality notes. Update it after interactions. + +## Shared Configuration + +- **Database**: `~/.local/share/last30days/research.db` (SQLite, WAL mode) +- **Briefings**: `~/.local/share/last30days/briefs/` +- **API keys**: `~/.config/last30days/.env` or environment variables +- **Key priority**: env vars > config file + +### API Keys + +| Key | Required | Purpose | +|---|---|---| +| `OPENAI_API_KEY` | For Reddit | Reddit search via OpenAI responses API | +| `XAI_API_KEY` | For X (fallback) | X search via xAI Grok API | +| `PARALLEL_API_KEY` | Optional | Web search via Parallel AI | +| `BRAVE_API_KEY` | Optional | Web search via Brave Search | +| `OPENROUTER_API_KEY` | Optional | Web search via Perplexity Sonar Pro | + +Bird CLI provides free X search if installed. YouTube search uses yt-dlp (free). + +Run `python3 "${SKILL_ROOT}/scripts/last30days.py" --diagnose` to check source availability. + +## Routing Logic + +After determining the mode, **read the corresponding reference file** using the Read tool: + +``` +Read: ${SKILL_ROOT}/variants/open/references/{mode}.md +``` + +Then follow the instructions in that reference file exactly. diff --git a/variants/open/context.md b/variants/open/context.md new file mode 100644 index 0000000..86221ae --- /dev/null +++ b/variants/open/context.md @@ -0,0 +1,16 @@ +# last30days Context + +Agent memory for improving research quality over time. + +## User Preferences + + + +## Source Quality Notes + + + + +## Interaction History + + diff --git a/variants/open/references/briefing.md b/variants/open/references/briefing.md new file mode 100644 index 0000000..d9f3ef2 --- /dev/null +++ b/variants/open/references/briefing.md @@ -0,0 +1,82 @@ +# Morning Briefing + +Synthesize accumulated findings into a formatted briefing. + +## Commands + +| Command | Action | +|---|---| +| `briefing` | Generate today's briefing | +| `briefing --weekly` | Weekly digest with trends | +| `briefing --since YYYY-MM-DD` | Briefing since specific date | + +## Generate Briefing + +```bash +python3 "${SKILL_ROOT}/scripts/briefing.py" generate [--weekly] [--since DATE] +``` + +The script returns JSON with per-topic findings, staleness info, and cost data. + +## Staleness Check + +Before synthesizing, check each topic's freshness: +- **Fresh** (< 12h): show normally +- **Aging** (12-36h): note when last run was +- **Stale** (> 36h): warn user, suggest running `watch run-one "topic"` + +## Daily Briefing Format + +``` +Good morning! Here's your research briefing for [DATE]. + +TL;DR: [One sentence about the top finding across all topics] + +--- + +**[Topic 1]** (N new findings) +Top signal: [Highest engagement finding with source] +Also trending: [2nd finding], [3rd finding] + +**[Topic 2]** (N new findings) +Top signal: [Highest engagement finding] +Also trending: [2nd finding] + +--- +Cost: $X.XX / $Y.YY budget | N topics active | N findings today +``` + +## Weekly Digest Format + +``` +Weekly digest for week of [DATE]: + +**[Topic 1]** +This week: N findings (up/down X% from last week) +Trending up: [engagement increasing] +Key voices: @handle1, r/sub1 + +**[Topic 2]** +This week: N findings +Trending down: [engagement decreasing] +``` + +## Synthesis Rules + +- Lead with people, not publications +- 3-5 topics max per briefing +- 2-3 findings per topic +- Include cost/budget footer +- Note any failed or stale topics + +## No Data Handling + +If no topics or no findings: +``` +No briefing data available. + +To get started: +1. Add a topic: /last30days watch add "your topic" +2. Run research: /last30days watch run-all +3. Generate briefing: /last30days briefing +``` diff --git a/variants/open/references/history.md b/variants/open/references/history.md new file mode 100644 index 0000000..73688bc --- /dev/null +++ b/variants/open/references/history.md @@ -0,0 +1,102 @@ +# History & Knowledge Query + +Query the accumulated findings database. + +## Commands + +| Command | Action | +|---|---| +| `history "topic"` | Show findings for a topic | +| `history "topic" --since=7d` | Findings from last N days | +| `history --search "query"` | Full-text search across all findings | +| `history --trending` | Topics with most recent activity | +| `history --stats` | Watchlist health dashboard | + +## Topic History + +```bash +python3 "${SKILL_ROOT}/scripts/store.py" query "TOPIC" [--since DAYS] +``` + +Display findings grouped by date (newest first): +``` +**[Topic Name]** — N findings since [date] + +[DATE] +- [Reddit] Title (score pts, N comments) — r/subreddit +- [X] Tweet text... (N likes) — @handle +- [YouTube] Video title (N views) — channel + +[EARLIER DATE] +- ... +``` + +Mark updated findings (engagement changed since first seen). + +## Full-Text Search + +```bash +python3 "${SKILL_ROOT}/scripts/store.py" search "QUERY" +``` + +Uses FTS5 with BM25 ranking. Show results across all topics: +``` +Search: "QUERY" — N results + +1. [Reddit] Title — r/subreddit (topic: AI video) + ...snippet with **highlighted** matches... + +2. [X] Tweet text — @handle (topic: NVIDIA) + ...snippet... +``` + +## Trending Topics + +```bash +python3 "${SKILL_ROOT}/scripts/store.py" trending +``` + +Show topics ranked by recent activity: +``` +Trending topics (last 7 days): + +1. AI video tools — 12 new findings, engagement up 45% +2. NVIDIA news — 8 new findings, engagement steady +3. Claude Code — 3 new findings, engagement down 20% +``` + +## Stats Dashboard + +```bash +python3 "${SKILL_ROOT}/scripts/store.py" stats +``` + +Display as a health dashboard: +``` +Watchlist Health +- Active topics: N +- Total findings: N +- Database size: N KB + +Research Runs (7 days) +- Successful: N +- Failed: N +- Cost: $X.XX + +Source Breakdown +- Reddit: N findings +- X: N findings +- YouTube: N findings +- Web: N findings +``` + +## No Data Handling + +If no findings exist: +``` +No research history yet. + +To start building knowledge: +1. Run research: /last30days "your topic" +2. Or add a watchlist topic: /last30days watch add "topic" +``` diff --git a/variants/open/references/research.md b/variants/open/references/research.md new file mode 100644 index 0000000..a760dba --- /dev/null +++ b/variants/open/references/research.md @@ -0,0 +1,137 @@ +# One-Shot Research Mode + +Research ANY topic across Reddit, X, YouTube, and the web. Surface what people are actually discussing, recommending, and debating right now. + +## Parse User Intent + +Before doing anything, parse the user's input for: + +1. **TOPIC**: What they want to learn about +2. **TARGET TOOL** (if specified): Where they'll use the prompts +3. **QUERY TYPE**: + - **PROMPTING** — "X prompts", "prompting for X" → copy-paste prompts + - **RECOMMENDATIONS** — "best X", "top X" → list of specific things + - **NEWS** — "what's happening with X" → current events + - **GENERAL** — anything else → broad understanding + +**Do NOT ask about target tool before research.** Run research first, ask after. + +**Display your parsing** before calling tools: + +``` +I'll research {TOPIC} across Reddit, X, YouTube, and the web. + +Parsed intent: +- TOPIC = {TOPIC} +- TARGET_TOOL = {TARGET_TOOL or "unknown"} +- QUERY_TYPE = {QUERY_TYPE} + +Research typically takes 2-8 minutes. Starting now. +``` + +--- + +## Research Execution + +**Step 1: Run the research script (FOREGROUND)** + +```bash +python3 "${SKILL_ROOT}/scripts/last30days.py" "$ARGUMENTS" --emit=compact --store 2>&1 +``` + +Use a **timeout of 300000** (5 minutes). The `--store` flag persists findings for watchlist/briefing integration. + +The script auto-detects: API keys, Bird CLI, yt-dlp, web search backends. + +**Read the ENTIRE output.** It contains Reddit, X, YouTube, AND web sections. + +--- + +**Step 2: WebSearch (supplement)** + +After the script finishes, use your WebSearch tool for additional coverage. + +Choose queries based on QUERY_TYPE: + +- **RECOMMENDATIONS**: `best {TOPIC} recommendations`, `{TOPIC} list examples` +- **NEWS**: `{TOPIC} news 2026`, `{TOPIC} announcement update` +- **PROMPTING**: `{TOPIC} prompts examples 2026`, `{TOPIC} techniques tips` +- **GENERAL**: `{TOPIC} 2026`, `{TOPIC} discussion` + +Rules: +- **USE THE USER'S EXACT TERMINOLOGY** +- EXCLUDE reddit.com, x.com, twitter.com (covered by script) +- Do NOT output "Sources:" list + +--- + +## Synthesis + +**Judge Agent rules:** +1. Weight Reddit/X HIGHER (engagement signals) +2. Weight YouTube HIGH (views + transcript content) +3. Weight web LOWER (no engagement data) +4. Identify cross-source patterns (strongest signals) +5. Extract top 3-5 actionable insights + +**Ground synthesis in ACTUAL research, not pre-existing knowledge.** + +### Citation Rules + +- Cite sparingly: 1-2 sources per topic +- Priority: @handles > r/subreddits > YouTube channels > web sources +- Use publication names, never raw URLs +- Lead with people, not publications + +--- + +## Display Results + +**1. "What I learned"** (format depends on QUERY_TYPE) + +**If RECOMMENDATIONS** — show specific items with sources: +``` +Most mentioned: + +[Name] - {n}x mentions +Use Case: [what it does] +Sources: @handle1, r/sub, blog.com +``` + +**If PROMPTING/NEWS/GENERAL** — show synthesis: +``` +What I learned: + +**{Topic 1}** — [1-2 sentences, per @handle or r/sub] + +KEY PATTERNS: +1. [Pattern] — per @handle +2. [Pattern] — per r/sub +``` + +**2. Stats box** (calculate from actual output): +``` +--- +All agents reported back! +|- Reddit: {N} threads | {N} upvotes | {N} comments +|- X: {N} posts | {N} likes | {N} reposts +|- YouTube: {N} videos | {N} views | {N} with transcripts +|- Web: {N} pages (supplementary) +|- Top voices: @{handle1}, @{handle2} | r/{sub1}, r/{sub2} +--- +``` + +**3. Invitation** with 2-3 specific follow-up suggestions based on research. + +--- + +## Follow-Up + +After research, you are an **EXPERT** on this topic. + +- **QUESTION** → Answer from research (no new searches) +- **GO DEEPER** → Elaborate from findings +- **CREATE/PROMPT** → Write ONE prompt using research insights +- **Different topic** → Run new research + +When writing prompts, match the FORMAT the research recommends (JSON, structured, etc.). diff --git a/variants/open/references/watchlist.md b/variants/open/references/watchlist.md new file mode 100644 index 0000000..272b1b1 --- /dev/null +++ b/variants/open/references/watchlist.md @@ -0,0 +1,107 @@ +# Watchlist Management + +Manage topics you want to track continuously. Findings accumulate in the SQLite database for briefings and history queries. + +## Commands + +| Command | Action | +|---|---| +| `watch add "topic"` | Add a topic (daily schedule) | +| `watch add "topic" --weekly` | Add with weekly schedule | +| `watch "topic"` | Shorthand for `watch add` | +| `watch remove "topic"` | Remove a topic | +| `watch list` | Show all topics with status | +| `watch config delivery [channel]` | Set delivery channel | +| `watch config budget AMOUNT` | Set daily cost budget | +| `watch run-all` | Run research for all topics now | +| `watch run-one "topic"` | Run research for one topic now | + +## Adding a Topic + +```bash +python3 "${SKILL_ROOT}/scripts/watchlist.py" add "TOPIC_NAME" [--weekly] [--queries "q1,q2"] +``` + +The script auto-bootstraps the SQLite database on first add. + +**Default schedule**: Daily at 8am (`0 8 * * *`). +**Weekly**: Mondays at 8am (`0 8 * * 1`). + +**After adding**, confirm to the user: +``` +Added "TOPIC_NAME" to watchlist. +Schedule: daily at 8am (or weekly on Mondays) + +To run research now: /last30days watch run-one "TOPIC_NAME" +To set up automated runs: add a cron/launchd job for `python3 ${SKILL_ROOT}/scripts/watchlist.py run-all` +``` + +## Removing a Topic + +```bash +python3 "${SKILL_ROOT}/scripts/watchlist.py" remove "TOPIC_NAME" +``` + +Show confirmation or "not found" message. + +## Listing Topics + +```bash +python3 "${SKILL_ROOT}/scripts/watchlist.py" list +``` + +Display as a formatted table: +``` +Topic | Schedule | Last Run | Findings | Status +--------------+--------------+--------------+----------+-------- +AI video | daily 8am | 2h ago | 47 | ok +NVIDIA news | weekly Mon | 3d ago | 23 | ok + +Budget: $0.42 / $5.00 today +``` + +## Running Research + +```bash +# All enabled topics (with budget guard) +python3 "${SKILL_ROOT}/scripts/watchlist.py" run-all + +# Single topic +python3 "${SKILL_ROOT}/scripts/watchlist.py" run-one "TOPIC_NAME" +``` + +Show results: new findings count, updated findings, duration, and any errors. + +## Configuration + +```bash +# Set delivery channel (for future notification support) +python3 "${SKILL_ROOT}/scripts/watchlist.py" config delivery telegram + +# Set daily budget limit +python3 "${SKILL_ROOT}/scripts/watchlist.py" config budget 10.00 +``` + +## Scheduling + +The watchlist doesn't auto-schedule. To automate, set up a system job: + +**macOS (launchd)**: +```bash +# Run daily at 8am +crontab -e +# Add: 0 8 * * * python3 /path/to/scripts/watchlist.py run-all +``` + +**Linux (cron)**: +```bash +crontab -e +# Add: 0 8 * * * python3 /path/to/scripts/watchlist.py run-all +``` + +## Error Handling + +- Duplicate topic: update the existing schedule +- Topic not found on remove: show "not found" message +- Budget exceeded: skip remaining topics, show which were skipped +- Research failure: record error, continue to next topic