{"id":"c37e4f70-7579-43e3-b509-333f2bf234f7","entityType":"agent","slug":"clawhub-ralph-oei-last30days-gemini","name":"last30days (Gemini Synthesis)","canonicalUrl":"https://www.xpersona.co/agent/clawhub-ralph-oei-last30days-gemini","canonicalPath":"/agent/clawhub-ralph-oei-last30days-gemini","generatedAt":"2026-10-09T23:53:20.458Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"description":"Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini. Skill: last30days (Gemini Synthesis) Owner: ralph-oei Summary: Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini. Tags: latest:1.0.0 Version history: v1.0.0 | 2026-02-17T10:02:16.006Z | auto - Initial release of the last30days-gemini skill. - Researches any topic from the past 30 days using X (Twitter), YouTu","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 546 downloads reported by the source. Last updated 4/15/2026.","installCommand":"clawhub skill install kn74qkj5344raj0tk9txa53xvh81a244:last30days-gemini","sourceUrl":"https://clawhub.ai/ralph-oei/last30days-gemini","homepage":"https://clawhub.ai/ralph-oei/last30days-gemini","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/ralph-oei/last30days-gemini","kind":"source"}],"safetyScore":84,"overallRank":62,"popularityScore":55,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"stars":null,"forks":null,"downloads":546,"packageName":null,"latestVersion":"1.0.0","tractionLabel":"546 downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-03-01T04:51:03.377Z","emptyReason":null},"lastUpdatedAt":"2026-04-15T00:45:39.800Z","lastCrawledAt":"2026-03-01T04:51:03.377Z","lastIndexedAt":null,"nextCrawlAt":"2026-03-02T04:51:03.377Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.0","createdAt":"2026-02-17T10:02:16.006Z","changelog":"- Initial release of the last30days-gemini skill. - Researches any topic from the past 30 days using X (Twitter), YouTube transcripts, and web search. - Outputs structured JSON for AI-powered expert briefings and copy-paste prompts via Gemini. - Supports multiple output formats: JSON, compact text, and markdown reports. - Requires minimal setup with API keys and environment variables. - Based on and crediting the original last30days skill, with added Gemini synthesis integration.","fileCount":57,"zipByteSize":153976}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install kn74qkj5344raj0tk9txa53xvh81a244:last30days-gemini","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-09T23:53:20.454Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ralph-oei-last30days-gemini/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"readme":"Skill: last30days (Gemini Synthesis)\n\nOwner: ralph-oei\n\nSummary: Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini.\n\nTags: latest:1.0.0\n\nVersion history:\n\nv1.0.0 | 2026-02-17T10:02:16.006Z | auto\n\n- Initial release of the last30days-gemini skill.\n- Researches any topic from the past 30 days using X (Twitter), YouTube transcripts, and web search.\n- Outputs structured JSON for AI-powered expert briefings and copy-paste prompts via Gemini.\n- Supports multiple output formats: JSON, compact text, and markdown reports.\n- Requires minimal setup with API keys and environment variables.\n- Based on and crediting the original last30days skill, with added Gemini synthesis integration.\n\nArchive index:\n\nArchive v1.0.0: 57 files, 153976 bytes\n\nFiles: agents/openai.yaml (448b), plans/feat-add-websearch-source.md (14539b), plans/fix-strict-date-filtering.md (11294b), README.md (54445b), scripts/briefing.py (8178b), scripts/last30days-synthesize.py (4837b), scripts/last30days.py (42686b), scripts/lib/__init__.py (29b), scripts/lib/bird_x.py (14617b), scripts/lib/brave_search.py (6019b), scripts/lib/cache.py (4762b), scripts/lib/dates.py (3253b), scripts/lib/dedupe.py (3547b), scripts/lib/entity_extract.py (4205b), scripts/lib/env.py (8746b), scripts/lib/http.py (4997b), scripts/lib/models.py (4706b), scripts/lib/normalize.py (6083b), scripts/lib/openai_reddit.py (12370b), scripts/lib/openrouter_search.py (6632b), scripts/lib/parallel_search.py (4016b), scripts/lib/reddit_enrich.py (7630b), scripts/lib/render.py (17796b), scripts/lib/schema.py (13245b), scripts/lib/score.py (11041b), scripts/lib/ui.py (19911b), scripts/lib/vendor/bird-search/bird-search.mjs (3750b), scripts/lib/vendor/bird-search/lib/cookies.js (6266b), scripts/lib/vendor/bird-search/lib/features.json (523b), scripts/lib/vendor/bird-search/lib/paginate-cursor.js (1225b), scripts/lib/vendor/bird-search/lib/query-ids.json (815b), scripts/lib/vendor/bird-search/lib/runtime-features.js (5036b), scripts/lib/vendor/bird-search/lib/runtime-query-ids.js (9424b), scripts/lib/vendor/bird-search/lib/twitter-client-base.js (4853b), scripts/lib/vendor/bird-search/lib/twitter-client-constants.js (2535b), scripts/lib/vendor/bird-search/lib/twitter-client-features.js (18400b), scripts/lib/vendor/bird-search/lib/twitter-client-search.js (7310b), scripts/lib/vendor/bird-search/lib/twitter-client-types.js (59b), scripts/lib/vendor/bird-search/lib/twitter-client-utils.js (19169b), scripts/lib/vendor/bird-search/package.json (331b), scripts/lib/websearch.py (11688b), scripts/lib/xai_x.py (6646b), scripts/lib/youtube_yt.py (11580b), scripts/store.py (20353b), scripts/sync.sh (1255b), scripts/watchlist.py (9283b), SKILL-original.md (14772b), SKILL.md (3540b), SPEC.md (3140b), TASKS.md (1475b), variants/open/context.md (634b), variants/open/references/briefing.md (1854b), variants/open/references/history.md (2096b), variants/open/references/research.md (3813b), variants/open/references/watchlist.md (2897b), variants/open/SKILL.md (2566b), _meta.json (136b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: last30days\ndescription: \"Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini.\"\nargument-hint: 'last30 AI agents, last30 marketing automation'\nmetadata: {\"version\": \"2.1.0\", \"clawdbot\":{\"emoji\":\"🔍\",\"requires\":{\"bins\":[\"python3\",\"node\",\"yt-dlp\"],\"env\":[\"AUTH_TOKEN\",\"CT0\",\"BRAVE_API_KEY\"]}}, \"original_repo\": \"https://github.com/mvanhorn/last30days-skill\", \"author\": \"mvanhorn\", \"license\": \"MIT\"}\n---\n\n> **Credit:** This skill is based on [last30days](https://github.com/mvanhorn/last30days-skill) by [@mvanhorn](https://x.com/mvanhorn). The original skill researches topics across Reddit, X, YouTube, and web. This version adds Gemini synthesis for briefings and prompts.\n>\n> Original skill: [github.com/mvanhorn/last30days-skill](https://github.com/mvanhorn/last30days-skill)\n\n# last30days v2.1\n\nResearch any topic across X (Twitter), YouTube, and web. Find what's actually being discussed, recommended, and debated right now.\n\n## Setup\n\n```bash\n# Environment (should already be set)\nexport AUTH_TOKEN=your_x_auth_token\nexport CT0=your_x_ct0_token  \nexport BRAVE_API_KEY=your_brave_key\n\n# Config\nmkdir -p ~/.config/last30days\ncat > ~/.config/last30days/.env << 'EOF'\nBRAVE_API_KEY=your_key_here\nEOF\n```\n\n## Usage\n\n```bash\n# Quick research (faster, fewer sources)\npython3 {baseDir}/scripts/last30days.py \"AI agents\" --quick\n\n# Full research\npython3 {baseDir}/scripts/last30days.py \"AI agents\" \n\n# Output formats\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=json    # JSON for parsing\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=compact  # Human readable\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=md       # Full report\n```\n\n## Output for AI Synthesis\n\nThe `--emit=json` flag outputs structured JSON that can be fed to Gemini for:\n- Expert briefing generation\n- Copy-paste ready prompts\n- Trend analysis\n\n## Sources\n\n| Source | Auth | Notes |\n|--------|------|-------|\n| X/Twitter | Cookies | Uses bird CLI with existing AUTH_TOKEN/CT0 |\n| YouTube | None | Requires yt-dlp for transcripts |\n| Web | Brave API | Requires BRAVE_API_KEY |\n\n## Synthesis\n\nThis skill researches and returns raw data. For AI-generated briefings and prompts, pipe the JSON output to Gemini:\n\n```bash\npython3 {baseDir}/scripts/last30days.py \"topic\" --quick --emit=json | python3 -c \"\nimport json, sys, os\nimport urllib.request, urllib.parse\n\ndata = json.load(sys.stdin)\nprompt = f'Synthesize this research into an expert briefing and 3 copy-paste prompts:\\\\n{json.dumps(data)}'\n\nbody = json.dumps({\n    'contents': [{'parts': [{'text': prompt}]}],\n    'generationConfig': {'temperature': 0.7, 'maxOutputTokens': 2048}\n})\n\nreq = urllib.request.Request(\n    'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + os.environ.get('GEMINI_API_KEY'),\n    data=body.encode(),\n    headers={'Content-Type': 'application/json'}\n)\nprint(json.load(urllib.request.urlopen(req))['candidates'][0]['content']['parts'][0]['text'])\n\"\n```\n\n## Attribution\n\n- **Original Author:** [Mike Van Horn](https://x.com/mvanhorn) ([mvanhorn](https://github.com/mvanhorn))\n- **Original Repository:** [github.com/mvanhorn/last30days-skill](https://github.com/mvanhorn/last30days-skill)\n- **License:** MIT (per original)\n- **Contributors:** Thanks to [@steipete](https://x.com/steipete) for yt-dlp + summarize inspiration\n\nThis skill extends the original with Gemini synthesis for automated briefings.\n\nFile v1.0.0:variants/open/SKILL.md\n\n---\nname: last30days\nversion: \"2.1-open\"\ndescription: \"Research topics, manage watchlists, get briefings, query history. Also triggered by 'last30'. Sources: Reddit, X, YouTube, web.\"\nargument-hint: 'last30 AI video tools, last30 watch my competitor every week, last30 give me my briefing'\nallowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch\n---\n\n# last30days (open variant): Research + Watchlist + Briefings\n\nMulti-mode research skill with persistent knowledge accumulation.\n\n## Command Routing\n\nParse the user's first argument to determine the mode:\n\n| First word | Mode | Reference |\n|---|---|---|\n| `watch` | Watchlist management | `references/watchlist.md` |\n| `briefing` | Morning briefing | `references/briefing.md` |\n| `history` | Query accumulated knowledge | `references/history.md` |\n| *(anything else)* | One-shot research | `references/research.md` |\n\n## Setup: Find Skill Root\n\n```bash\nfor dir in \\\n  \".\" \\\n  \"${CLAUDE_PLUGIN_ROOT:-}\" \\\n  \"$HOME/.claude/skills/last30days\" \\\n  \"$HOME/.agents/skills/last30days\" \\\n  \"$HOME/.codex/skills/last30days\"; do\n  [ -n \"$dir\" ] && [ -f \"$dir/scripts/last30days.py\" ] && SKILL_ROOT=\"$dir\" && break\ndone\n\nif [ -z \"${SKILL_ROOT:-}\" ]; then\n  echo \"ERROR: Could not find scripts/last30days.py\" >&2\n  exit 1\nfi\n```\n\nUse `$SKILL_ROOT` for all script and reference file paths.\n\n## Load Context\n\nAt session start, read `${SKILL_ROOT}/variants/open/context.md` for user preferences and source quality notes. Update it after interactions.\n\n## Shared Configuration\n\n- **Database**: `~/.local/share/last30days/research.db` (SQLite, WAL mode)\n- **Briefings**: `~/.local/share/last30days/briefs/`\n- **API keys**: `~/.config/last30days/.env` or environment variables\n- **Key priority**: env vars > config file\n\n### API Keys\n\n| Key | Required | Purpose |\n|---|---|---|\n| `OPENAI_API_KEY` | For Reddit | Reddit search via OpenAI responses API |\n| `XAI_API_KEY` | For X (fallback) | X search via xAI Grok API |\n| `PARALLEL_API_KEY` | Optional | Web search via Parallel AI |\n| `BRAVE_API_KEY` | Optional | Web search via Brave Search |\n| `OPENROUTER_API_KEY` | Optional | Web search via Perplexity Sonar Pro |\n\nBird CLI provides free X search if installed. YouTube search uses yt-dlp (free).\n\nRun `python3 \"${SKILL_ROOT}/scripts/last30days.py\" --diagnose` to check source availability.\n\n## Routing Logic\n\nAfter determining the mode, **read the corresponding reference file** using the Read tool:\n\n```\nRead: ${SKILL_ROOT}/variants/open/references/{mode}.md\n```\n\nThen follow the instructions in that reference file exactly.\n\nFile v1.0.0:README.md\n\n# /last30days v2.1\n\n> **OpenClaw Adaptation:** This version includes `last30days-synthesize.py` for Gemini-powered briefings and prompts. For the original Claude Code version, see [github.com/mvanhorn/last30days-skill](https://github.com/mvanhorn/last30days-skill) by [@mvanhorn](https://x.com/mvanhorn).\n\n**The AI world reinvents itself every month. This skill keeps you current.** /last30days researches your topic across Reddit, X, YouTube, and the web from the last 30 days, finds what the community is actually upvoting, sharing, and saying on camera, and writes you a prompt that works today, not six months ago. Whether it's Seedance 2.0 access, Suno music prompts, or the latest Nano Banana Pro techniques, you'll prompt like someone who's been paying attention.\n\n**New in V2.1  - three headline features:**\n\n1. **Open-class skill with watchlists.** Add any topic to a watchlist  - your competitors, your partners, your board members, an emerging technology  - and /last30days re-researches it on demand or via cron. Designed for always-on environments like [Open Claw](https://github.com/openclaw/openclaw) where a bot can run research on a schedule and accumulate findings over time.\n2. **YouTube transcripts as a 4th source.** When yt-dlp is installed, /last30days automatically searches YouTube, grabs view counts, and extracts auto-generated transcripts from the top videos. A 20-minute review contains 10x the signal of a single post - now the skill reads it. Inspired by [@steipete](https://x.com/steipete)'s yt-dlp + [summarize](https://github.com/steipete/summarize) toolchain.\n3. **Works in OpenAI Codex CLI.** Same skill, same engine. Install to `~/.agents/skills/last30days` and invoke with `$last30days`. Claude Code and Codex users get the same research.\n\n**New in V2:** Dramatically better search results. Smarter query construction finds posts that V1 missed entirely, and a new two-phase search automatically discovers key @handles and subreddits from initial results, then drills deeper. Free X search (no xAI key needed), `--days=N` for flexible lookback, and automatic model fallback. [Full changelog below.](#whats-new-in-v2)\n\n**The tradeoff:** V2 finds way more content but takes longer - typically 2-8 minutes depending on how niche your topic is. The old V1 was faster but regularly missed results (like returning 0 X posts on trending topics). We think the depth is worth the wait, but if you'd use a faster \"quick mode\" that trades some depth for speed, let us know: [@mvanhorn](https://x.com/mvanhorn) / [@slashlast30days](https://x.com/slashlast30days).\n\n**Best for prompt research**: discover what prompting techniques actually work for any tool (ChatGPT, Midjourney, Claude, Figma AI, etc.) by learning from real community discussions and best practices.\n\n**But also great for anything trending**: music, culture, news, product recommendations, viral trends, or any question where \"what are people saying right now?\" matters.\n\n## Installation\n\n```bash\n# Clone the repo\ngit clone https://github.com/mvanhorn/last30days-skill.git ~/.claude/skills/last30days\n\n# Add your API keys\nmkdir -p ~/.config/last30days\ncat > ~/.config/last30days/.env << 'EOF'\nOPENAI_API_KEY=sk-...\nXAI_API_KEY=xai-...       # optional  - cookie auth is default for X search\nEOF\nchmod 600 ~/.config/last30days/.env\n```\n\n### X Search Authentication\n\nX search reads your existing browser cookies  - no API keys or login commands needed.\n\n**Safari (recommended on Mac):** Just be logged into x.com. No setup needed.\n\n**Chrome:** Works, but macOS will prompt you to allow Keychain access the first time. Click \"Allow\" (or \"Always Allow\" to stop future prompts).\n\n**Firefox:** Just be logged into x.com. No setup needed.\n\n**Manual fallback:** If cookie auto-detection doesn't work, set these env vars (grab them from your browser's dev tools → Application → Cookies → x.com):\n```bash\nexport AUTH_TOKEN=your_auth_token\nexport CT0=your_ct0_token\n```\n\n**Verify it's working:**\n```bash\nnode ~/.claude/skills/last30days/scripts/lib/vendor/bird-search/bird-search.mjs --whoami\n```\n\n**Requirements:** Node.js 22+ (for the vendored Twitter GraphQL client).\n\n### Codex CLI\n\nThis skill also works in OpenAI Codex CLI. Install to the Codex skills directory instead:\n\n```bash\ngit clone https://github.com/mvanhorn/last30days-skill.git ~/.agents/skills/last30days\n```\n\nSame SKILL.md, same Python engine, same scripts. The `agents/openai.yaml` provides Codex-specific discovery metadata. Invoke with `$last30days` or through the `/skills` menu.\n\n### Open Variant (Watchlist + Briefings)  - For Always-On Bots\n\n**Designed for [Open Claw](https://github.com/openclaw/openclaw) and similar always-on AI environments.** Add your competitors, partners, board members, or any topic to a watchlist. When paired with a cron job or always-on bot, /last30days re-researches them on a schedule and accumulates findings in a local SQLite database. Ask for a briefing anytime.\n\n**Important:** The watchlist stores schedules as metadata, but nothing triggers runs automatically. You need an external scheduler (cron, launchd, or an always-on bot like Open Claw) to call `watchlist.py run-all` on a timer. In plain Claude Code, you can run `watch run-one` and `watch run-all` manually, but there's no background scheduling.\n\n```bash\n# Enable the open variant\ncp variants/open/SKILL.md ~/.claude/skills/last30days/SKILL.md\n\n# Add topics to your watchlist\nlast30 watch my biggest competitor every week\nlast30 watch AI video generation tools\nlast30 tell me once a month about what my board members are up to\n\n# Run research manually (or let your bot's cron handle it)\nlast30 run all my watched topics\n\n# Get your briefing\nlast30 give me my briefing\n\n# Search accumulated knowledge\nlast30 what have you found about AI video?\n```\n\nThe open variant adds four modes on top of one-shot research:\n\n- **Watchlist**  - Track topics with `watch add \"topic\"`, run manually or via cron\n- **Briefings**  - Daily/weekly digests synthesized from accumulated findings\n- **History**  - Query and search your research database with full-text search\n- **Native web search**  - Built-in web search backends (Parallel AI, Brave, OpenRouter) run alongside Reddit/X/YouTube\n\nBoth variants use the same Python engine and scripts directory. The open variant adds command routing (`watch`, `briefing`, `history`) and references mode-specific instruction files.\n\n**Optional web search API keys** (add to `~/.config/last30days/.env`):\n```bash\nPARALLEL_API_KEY=...    # Parallel AI (preferred  - LLM-optimized results)\nBRAVE_API_KEY=...       # Brave Search (free tier: 2,000 queries/month)\nOPENROUTER_API_KEY=...  # OpenRouter/Perplexity Sonar Pro\n```\n\nCheck source availability: `python3 scripts/last30days.py --diagnose`\n\n## Usage\n\n```\n/last30days [topic]\n/last30days [topic] for [tool]\n```\n\nExamples:\n- `/last30days prompting techniques for ChatGPT for legal questions`\n- `/last30days iOS app mockups for Nano Banana Pro`\n- `/last30days What are the best rap songs lately`\n- `/last30days remotion animations for Claude Code`\n\n## What It Does\n\n1. **Researches** - Scans Reddit, X, and YouTube for discussions from the last 30 days\n2. **Synthesizes** - Identifies patterns, best practices, and what actually works\n3. **Delivers** - Either writes copy-paste-ready prompts for your target tool, or gives you a curated expert-level answer\n\n### Use it for:\n- **Prompt research** - \"What prompting techniques work for legal questions in ChatGPT?\"\n- **Tool best practices** - \"How are people using Remotion with Claude Code?\"\n- **Trend discovery** - \"What are the best rap songs right now?\"\n- **Product research** - \"What do people think of the new M4 MacBook?\"\n- **Viral content** - \"What's the dog-as-human trend on ChatGPT?\"\n\n---\n\n## Example: Nano Banana Pro Prompting (Image Generation)\n\n**Query:** `/last30days nano banana pro prompting`\n\n**Research Output:**\n> JSON prompting is the dominant technique  - The X community overwhelmingly uses structured JSON prompts rather than plain text. Creators like @Xmira_belle, @Cicily_aura, @RubenSalvo_, and @mahivisuals all share prompts in JSON format with nested objects for metadata, subject descriptions, lighting, camera specs, and scene composition. @realdigitaldao made a static ad \"in less than 5 min\" using a simple JSON prompt.\n>\n> Prompt adherence is Nano Banana Pro's killer advantage  - JSON prompts hit 92% precision for color accuracy, lighting ratios, and composition vs ~68% for natural language prompts, per fofr.ai. @artingent directly compared it to GPT Image 1.5 and noted Nano Banana Pro has higher prompt adherence  - \"GPT image 1.5 ignored the Top Down instruction.\"\n>\n> Stop writing \"tag soup\"  - act like a Creative Director  - The biggest shift is away from comma-separated keyword lists toward natural language descriptions with clear structure. The ICS Framework (Image type, Content, Style) and the 5-element formula (subject, composition, action, setting, style) are the two dominant approaches, per r/nanobanana2pro.\n\n**Key patterns discovered:**\n1. JSON > plain text  - Structure prompts as JSON objects with keys for subject, composition, lighting, camera, style  - per @Xmira_belle, @Cicily_aura\n2. The 5-element formula  - Subject + Composition + Action + Setting + Style  - per r/nanobanana2pro\n3. Separate subjects into distinct objects  - Multi-character scenes need each person in their own JSON block to prevent \"concept bleeding\"  - per fofr.ai\n4. Use camera/lens metadata  - Aperture, focal length, ISO, film stock as JSON keys for hidden photorealism control\n5. 14 reference images max  - Feed up to 14 reference images for brand/character consistency  - per Google DeepMind\n\n**Research Stats:** 8 Reddit threads (455 upvotes) + 31 X posts (183 likes, 68 reposts) from r/nanobanana2pro, r/promptingmagic, @Xmira_belle (106 likes), @Cicily_aura (45 likes)\n\n**Then asked:** \"make a mock-up of an app for moms who swim\"\n\n**Generated Prompt:**\n\n```json\n{\n  \"image_type\": \"UI mockup\",\n  \"device\": {\n    \"frame\": \"iPhone 16 Pro\",\n    \"display\": \"realistic screen with subtle reflection\",\n    \"orientation\": \"portrait\"\n  },\n  \"app_concept\": \"SwimMom - fitness and community app for mothers who swim\",\n  \"screen\": \"home dashboard\",\n  \"design_system\": {\n    \"style\": \"iOS 18 native\",\n    \"corners\": \"rounded, 16px radius\",\n    \"shadows\": \"soft drop shadows, subtle depth\",\n    \"spacing\": \"8pt grid, generous whitespace\"\n  },\n  \"color_palette\": {\n    \"primary\": \"calming aqua blue (#4ECDC4)\",\n    \"secondary\": \"warm coral (#FF6B6B)\",\n    \"background\": \"clean white with soft blue gradient header\"\n  },\n  \"layout\": {\n    \"header\": \"greeting 'Good morning, Sarah' with wave icon, profile avatar top right\",\n    \"hero_card\": \"today's swim stats - laps, calories, time - with circular progress ring\",\n    \"section_2\": \"horizontal scroll of upcoming mom swim meetups with location pills\",\n    \"section_3\": \"two cards - 'My Goals' with streak counter, 'Find a Pool' with map pin\",\n    \"bottom_nav\": \"5 icons - Home (active), Workouts, Community, Schedule, Profile\"\n  },\n  \"visual_details\": {\n    \"illustrations\": \"friendly, minimal line art of swimming figure\",\n    \"typography\": \"SF Pro Display, clean hierarchy\",\n    \"mood\": \"energizing yet calm, supportive community feel\"\n  }\n}\n```\n\n**The Result:**\n\n<p align=\"center\">\n  <img src=\"assets/swimmom-mockup.jpeg\" width=\"400\" alt=\"SwimMom iOS app mockup\"/>\n</p>\n\nThis example shows /last30days learning that **JSON prompts dominate** the Nano Banana Pro community (not plain text), then applying that format to generate an iOS mockup in one shot. The research came from real X creators and Reddit threads  - techniques you wouldn't find in official docs.\n\n---\n\n## Example: Kanye West (Current Events)\n\n**Query:** `/last30days kanye west`\n\n**Research Output:**\n> **The Apology Arc**  - On January 26, Ye published a full-page letter in The Wall Street Journal titled \"To Those I've Hurt,\" apologizing for antisemitic comments and attributing it to a four-month manic episode, an undiagnosed brain injury from his 2002 car crash, and bipolar type-1 disorder. The ADL called it \"long overdue\" but said it \"doesn't automatically undo his long history of antisemitism.\" Then on February 9, he posted \"I love Hitler now what\"  - blowing up the goodwill almost immediately, per The Mirror. Fans on X are split on whether the apology was genuine or just pre-album PR, per @dekreationz's viral post (8.6K likes).\n>\n> **BULLY Album**  - Twelfth studio album set for March 20 via YZY and Gamma. 13 tracks with Peso Pluma, Playboi Carti, and Ty Dolla Sign features. Sonically it leans toward 808s/MBDTF territory  - more singing than rapping. Ye has reportedly removed all deepfaked/AI-generated vocals from the final version, per Rolling Stone.\n>\n> **Bianca Censori Breaks Silence**  - In a Vanity Fair tell-all, Bianca spoke publicly for the first time about their marriage, saying \"This year was a lot like doing CPR for months.\" She confirmed her outfits are her own choice and revealed their relationship started when she was head of architecture at Yeezy, per TMZ.\n>\n> **Kim/Instagram Drama**  - A screenshot of Ye allegedly commenting on Kim's Complex magazine post went mega-viral on X. Multiple Grok fact-checks confirmed it's likely fabricated, but @dekreationz's post racked up nearly 9K likes regardless  - showing the Ye/Kim narrative still drives massive engagement.\n\n**Key patterns from the research:**\n1. Apology-then-relapse cycle  - The WSJ letter was immediately undercut by new inflammatory posts, making sincerity the dominant debate, per Washington Post\n2. Album as PR vehicle  - Skeptics across X tie the apology's timing directly to BULLY's March 20 release, per @trustGod_007\n3. Bianca as her own story  - Transitioning from \"Kanye's wife\" to individual public figure through Vanity Fair\n4. Fake screenshot virality  - Fabricated Ye content still goes massively viral before debunking, per @dekreationz\n\n**Research Stats:** 3 Reddit threads (193 upvotes, 192 comments) + 33 X posts (9,295 likes, 279 reposts) from r/Kanye, r/hiphopheads, @dekreationz (8,684 likes), @trustGod_007\n\n**Follow-up suggestions offered:**\n> I'm now an expert on Kanye West. Some things I can help with:\n> - What's the real story behind the apology letter  - genuine accountability or pre-album PR?\n> - Deep dive on BULLY: tracklist, Gamma deal, and removal of AI vocals\n> - The Bianca Censori Vanity Fair interview  - what she actually said vs. the tabloid headlines\n\nThis example shows /last30days as a **current events research tool**  - no prompting, no target tool, just \"what's happening with Kanye?\" and you get a synthesized expert briefing pulled from 33 X posts and 3 Reddit threads with real engagement data.\n\n---\n\n## Example: Vibe Motion (Brand New AI Tool)\n\n**Query:** `/last30days higgsfield motion vibe motion prompting`\n\n**Research Output:**\n> **Vibe Motion just launched (Feb 5-6, 2026) and it's blowing up**  - Higgsfield dropped a Claude-powered motion design tool that generates editable motion graphics from plain-English prompts. It's the first AI video tool with actual reasoning, per @Hartdrawss, and @rezkhere called it out as something \"no other AI can do.\" Linus Ekenstam said it \"broke his brain\"  - work that took hours in After Effects now takes minutes.\n>\n> **It generates code, not pixels**  - Unlike other AI video tools, Vibe Motion produces actual animation code (via Remotion under the hood), not hallucinated video. Text never breaks, edits stay consistent, and you get a controllable, editable asset, per @Totinhiiio.\n>\n> **Honest reviews: promising but not polished yet**  - Chase Jarvis found results \"okay\" but noted 5+ minute render times, credit burn on iteration (8-60 credits per gen, $9 plan = ~150 credits), and that basic results are achievable faster with Canva. His verdict: \"not quite ready for prime time\" but the underlying tech shows significant potential.\n\n**Key patterns discovered:**\n1. Describe structure, not effects  - Focus on timing, hierarchy, typography, and flow rather than expressive visual storytelling, per Higgsfield's official guide\n2. Upload your actual assets first  - Brand logos, product images, PDFs give the AI context to build around YOUR files, not generic placeholders\n3. Use presets as starting points  - Select a format (Infographics, Text Animation, Posters) before writing your prompt\n4. Keep prompts conversational and direct  - Short commands > long descriptions. \"Create a kinetic typography intro\" beats a paragraph of specs, per Segmind\n5. Budget for iteration  - Each generation burns credits, so get your prompt right before hitting generate, per Chase Jarvis\n\n**Research Stats:** 10 Reddit threads + 30 X posts from @rezkhere, @Hartdrawss, @Totinhiiio + 14 web pages (Higgsfield blog, Chase Jarvis, SiliconANGLE, Segmind)\n\n**Follow-up suggestions offered:**\n> I'm now an expert on Higgsfield Vibe Motion prompting. What do you want to make?\n> - A branded infographic animation with your company metrics animating in\n> - A kinetic typography intro/bumper for a YouTube series\n> - A logo reveal animation with particle effects and custom brand colors\n\nThis example shows /last30days researching **a tool that launched 2 days ago**. No blog roundups existed yet  - the research came from X creators and Reddit threads reacting in real-time. You get prompting advice from the people actually using it, not SEO articles written after the fact.\n\n---\n\n## Example: Legal Prompting (Hallucination Prevention)\n\n**Query:** `/last30days prompting techniques for chatgpt for legal questions`\n\n**Research Output:**\n> The dominant theme is hallucination prevention - multiple sources discuss lawyers being fined or embarrassed for submitting fake case citations that ChatGPT fabricated. Key prompting strategies include: (1) using Deep Research mode or grounding tools with uploaded primary sources, (2) building \"Hallucination Prevention Systems\" into prompts that force epistemic honesty, (3) prompting for procedural questions rather than case law lookups, and (4) framing outputs as \"issue-spotting\" rather than legal advice. A major warning: chat logs are discoverable in litigation.\n\n**Key patterns discovered:**\n1. Hallucination prevention clauses - \"If you don't know a case citation, say so rather than inventing one\"\n2. Role assignment - assign ChatGPT a specific persona (paralegal, issue-spotter) to constrain outputs\n3. Structured output requirements - request specific sections (risks, key terms, questions for counsel)\n4. Epistemic humility enforcement - \"acknowledge uncertainty\" and \"flag when you're unsure\"\n5. Scope limitation - focus on procedural questions, not case law research\n\n**Then asked:** \"I have a squatter in my house in San Francisco, what are my options to get them out?\"\n\n**Generated Prompt:**\n\n```\nRole: You are a legal research assistant helping a property owner understand\ntheir options. You are NOT providing legal advice - you are helping me\nidentify issues, understand procedures, and prepare informed questions for an\nattorney.\n\nSituation: I own a residential property in San Francisco, California. Someone\nis currently occupying the property without my permission or any lease\nagreement (a squatter). I need to understand my legal options for removing them.\n\nYour task: Provide a structured analysis covering:\n\n1. California/SF Legal Framework - What laws govern this situation? (Note: San\nFrancisco has strong tenant protections - address how these apply or don't\napply to squatters vs. tenants)\n2. Key Distinctions - Help me understand: squatter vs. trespasser vs. holdover\ntenant. How does the length of occupation affect my options?\n3. Available Legal Remedies - What are my procedural options? (unlawful\ndetainer, police involvement, etc.) What is the typical process and timeline?\n4. Critical Mistakes to Avoid - What actions could expose me to liability?\n(self-help eviction, utility shutoffs, etc.)\n5. Questions I Should Ask an Attorney - Based on this analysis, what specific\nquestions should I bring to a California real estate attorney?\n\nImportant constraints:\n- Do NOT cite specific case names unless you are 100% certain they exist - say\n\"case law generally supports...\" instead\n- Flag any areas where you're uncertain\n- Note where San Francisco local ordinances may differ from California state law\n- This is for informational purposes to prepare for a legal consultation\n```\n\n**The Result:** A comprehensive 2,500+ word analysis covering California's unlawful detainer process, SF Rent Ordinance nuances, trespasser vs. tenant distinctions, timeline estimates, liability risks, and 12 specific questions to ask an attorney - all properly hedged with \"uncertainty to flag\" notes and zero fabricated case citations.\n\nThis example shows /last30days learning **domain-specific prompting techniques** (hallucination prevention for legal) and applying them to create a prompt that produces genuinely useful, safe output.\n\n---\n\n## Example: ClawdBot Use Cases (Community Research)\n\n**Query:** `/last30days best clawdbot use cases`\n\n**Research Output:**\n> ClawdBot is a self-hosted AI assistant that runs on your devices and connects via messaging apps (Telegram, WhatsApp, Discord, Slack, iMessage). Unlike ChatGPT/Claude, it has persistent memory and can proactively message you. The killer feature is its 24/7 autonomous operation - it handles multi-day tasks, monitors for replies, and initiates contact.\n\n**Most mentioned use cases:**\n\n🏆 Top 5 by engagement:\n\n1. **Email/Calendar automation** - mentioned 8x+ (r/selfhosted, @dreetje, @danpeguine, MacStories)\n   - Morning briefings, spam filtering, auto-replies, recruiter declines\n2. **Task management via chat** - mentioned 6x (r/LocalLLaMA, @danpeguine, multiple X posts)\n   - Todoist integration, importance scoring, time-blocking tasks\n3. **Overnight coding agent** - mentioned 5x (@bffmike 225 likes, r/LocalLLaMA)\n   - \"Drove my coding agents from 12:30-7am while I snoozed\"\n   - Pulls repos, runs tests, commits if clean\n4. **Smart home + life admin** - mentioned 5x (r/selfhosted, VelvetShark)\n   - WHOOP health data, Philips Hue, HomeAssistant, SSH to homelab\n5. **Browser automation** - mentioned 4x (@steipete 243 likes, MacStories)\n   - Car negotiation via email/PDF, restaurant reservations via ElevenLabs calls\n\n**Notable single mentions:**\n- Custom meditation generation with TTS + ambient audio\n- Built a full website (Stumblereads.com) from phone while putting baby to sleep\n- Ray-Ban Meta glasses integration\n- WhatsApp as control interface for everything\n\n**Research Stats:** 9 Reddit threads (161 upvotes, 95 comments) + 19 X posts (2,018 likes, 96 reposts) from r/LocalLLaMA, r/selfhosted, @steipete, @danpeguine, @dreetje\n\nThis example shows /last30days as a **product research tool** - discovering real-world use cases and community sentiment for any tool or product, complete with engagement metrics that tell you what people actually care about.\n\n---\n\n## Example: ClawdBot Setup (Installation Guide)\n\n**Query:** `/last30days how to best setup clawdbot`\n\n**Research Output:**\n> ClawdBot setup varies by deployment style - Docker is the most recommended path, but users are also deploying via bare metal and cloud VMs. The community has converged on key best practices: use the setup wizard for initial config, start with conservative hardware (you can scale up), and configure authentication before exposing any endpoints.\n\n**🛠️ Setup patterns by engagement:**\n\n| Pattern | Mentions | Key Sources |\n|---------|----------|-------------|\n| Docker Compose deployment | 6x | r/selfhosted, r/LocalLLaMA |\n| Setup wizard (interactive config) | 5x | @dreetje, documentation |\n| API key management | 4x | r/selfhosted, security threads |\n| Hardware requirements | 4x | r/LocalLLaMA (GPU discussions) |\n| Reverse proxy (Caddy/nginx) | 3x | r/selfhosted |\n\n**Key setup insights from community:**\n\n1. **Use the setup wizard** - Don't manually edit config files first; the wizard handles 90% of initial setup\n2. **Start small on hardware** - 8GB RAM minimum, but 16GB+ recommended if running local models\n3. **Docker > bare metal** - Easier updates, better isolation, community-tested compose files\n4. **Secure before exposing** - Set up authentication before opening ports; ClawdBot has built-in auth\n5. **Cost management** - Set API rate limits early; one user reported $200 overnight bill from runaway tasks\n\n**Quick-start commands (community-verified):**\n\n```bash\n# Clone and setup\ngit clone https://github.com/clawdbot/clawdbot.git\ncd clawdbot\n\n# Run setup wizard (recommended)\n./setup.sh\n\n# Or Docker Compose (after config)\ndocker compose up -d\n```\n\n**Common gotchas mentioned:**\n- Don't forget to set `CLAWDBOT_API_KEY` before first run\n- Telegram bot token needs BotFather setup first\n- If using local models, ensure CUDA drivers are installed\n\n**Research Stats:** 8 Reddit threads (128 upvotes) + 22 X posts (24,000+ likes) from r/selfhosted, r/LocalLLaMA, @dreetje, @steipete\n\nThis example shows /last30days as a **setup guide aggregator** - pulling together scattered installation advice, gotchas, and best practices from real users who've already solved the problems you're about to encounter.\n\n---\n\n## Example: Top Claude Code Skills (Recommendations)\n\n**Query:** `/last30days top claude code skills`\n\n**Research Output:**\n> The Claude Code skills ecosystem has exploded with marketplaces, curated lists, and viral skill announcements. The Remotion video skill got 17.3K likes on X. SkillsMP emerged as a marketplace with 60-87K+ skills. Multiple GitHub repos (awesome-claude-skills, Superpowers) are actively curated.\n\n**🏆 Most mentioned skills/resources:**\n\n| Rank | Skill/Resource | Mentions | Sources | Engagement |\n|------|----------------|----------|---------|------------|\n| 1 | Remotion skill | 4x | X (@Remotion, @joshua_xu_), web | 17.3K likes, video creation |\n| 2 | SkillsMP marketplace | 5x | X (@milesdeutscher, @rexan_wong), web | 60-87K+ skills directory |\n| 3 | awesome-claude-skills (GitHub) | 4x | Web (travisvn, ComposioHQ repos) | Multiple curated lists |\n| 4 | Superpowers | 3x | Web, GitHub | 27.9K stars |\n| 5 | HeyGen avatar skill | 2x | X (@joshua_xu_), web | 736 likes, AI avatars |\n| 6 | Trail of Bits Security Skills | 2x | Web | CodeQL/Semgrep auditing |\n| 7 | Claude Command Suite | 2x | GitHub, web | 148+ commands, 54 agents |\n| 8 | MCP Builder | 2x | Web | Build MCP servers |\n| 9 | Test-Driven Development | 2x | Web, skill guides | Pre-implementation testing |\n| 10 | Systematic Debugging | 2x | Web | Root cause analysis |\n\n**Notable single mentions:** UI/UX Pro Max (16.9K stars), SuperClaude framework, Compound Engineering Plugin, docx/pdf/pptx document skills, Nano-Banana, Connect (1000+ app integrations)\n\n**Marketer skill stack** (from @vibecode_edu): Slack, Email Knowledge, Nano-Banana, Notion, Skill Creator, Twitter post, Typefully\n\n**Key insight from Reddit:** Keep CLAUDE.md short (~1K context), use Skills for \"context on demand\", and ensure skill descriptions contain your trigger keywords.\n\n**Research Stats:** 4 Reddit threads (238 upvotes, 156 comments) + 15 X posts (28K+ likes, 2.8K reposts) from r/ClaudeCode, r/ClaudeAI, @Remotion, @milesdeutscher\n\nThis example shows /last30days as a **discovery tool** - finding the most popular resources in a rapidly evolving ecosystem by tracking what the community is actually sharing and upvoting.\n\n---\n\n## Example: Discover Viral Trends (Dog as Human)\n\n**Query:** `/last30days using ChatGPT to make images of dogs`\n\n**Research Output:**\n> The Reddit community is obsessed with the \"dog as human\" trend - uploading photos of their dogs and asking ChatGPT to show what they'd look like as a person (threads with 600-900+ upvotes). Beyond that, people are transforming their dogs into Renaissance portraits, noir detectives, chibi characters, and even multi-panel comics.\n\n**Key patterns discovered:**\n1. Upload reference photo first - ChatGPT works best with your actual dog's image\n2. \"As a human\" transformation - The viral trend\n3. Style/era transformations - Renaissance, noir, chibi, cartoon\n4. Scene placement - French bistro, prison yard, detective office\n5. Specific visual details - Lighting, background, expression, accessories\n\n**Then asked:** \"what would my dog look like as a human prompt\"\n\n**Generated Prompt:**\n\n```\nLook at this photo of my dog. Create an image showing what they would look like\nas a human person. Keep their exact personality, energy, and distinctive\nfeatures - translate their fur color to hair color, their expression to a\nhuman face, and their overall vibe into human form. Make it a realistic\nportrait photo, not a cartoon.\n```\n\n*How to use: Upload your dog's photo first, then paste this prompt.*\n\n**The Result:**\n\n<p align=\"center\">\n  <img src=\"assets/dog-original.jpeg\" width=\"300\" alt=\"Original dog photo\"/>\n  &nbsp;&nbsp;→&nbsp;&nbsp;\n  <img src=\"assets/dog-as-human.png\" width=\"300\" alt=\"Dog as human\"/>\n</p>\n\nSame golden fur → red hair. Same tongue out. Same harness. Same pink tag. ChatGPT nailed it.\n\nThis example shows how /last30days discovers **viral trends you didn't know existed** - the \"dog as human\" phenomenon with 600-900+ upvote threads.\n\n---\n\n## Example: Remotion Launch Video\n\n**Query:** `/last30days research best practices for beautiful remotion animation videos in claude code`\n\n**Research Output:**\n> The Remotion + Claude Code combination has emerged as a powerful workflow. Users consistently report that simple, clear prompts with scene-by-scene descriptions yield the best results. Key insights: iteration is essential, most \"beautiful\" videos come from back-and-forth refinement rather than one-shot prompts.\n\n**Then asked:** \"Can you make a prompt for a 50 second launch video for my /last30days skill?\"\n\n**Generated Prompt:**\n\n```\nCreate a 50-second launch video for \"/last30days\" - a Claude Code skill that\nresearches any topic across Reddit and X from the last 30 days, then writes\ncopy-paste-ready prompts.\n\nSCENE 1 (0-8s): The Problem\nDark background. Text fades in: \"You want to create something great.\"\nBeat. Then: \"But the internet is overwhelming.\"\nShow scattered icons floating chaotically: Reddit logo, X logo, search icons,\nquestion marks.\nSlight camera shake to convey chaos.\n\nSCENE 2 (8-16s): The Solution Reveal\nClean wipe transition. Calm, modern gradient background (deep purple to blue).\n\"/last30days\" types in with a terminal cursor, monospace font.\nSubtitle fades in below: \"Instant expertise. Real prompts.\"\n\nSCENE 3 (16-28s): How It Works\nSplit into 3 animated steps that slide in sequentially:\n1. [Reddit + X icons merge] \"Scans Reddit & X from the last 30 days\"\n2. [Brain/lightbulb icon] \"Synthesizes what actually works\"\n3. [Document with sparkle] \"Writes prompts you can copy-paste\"\n\nEach step has a subtle bounce animation on entry.\n\nSCENE 4 (28-40s): Live Demo Feel\nSimulate a terminal. Show:\n> /last30days remotion animations\nThen a progress indicator animates.\nResults appear: \"Analyzed 28 sources...\"\nStats counter animates up: \"294 upvotes • 1,273 likes\"\nThen: a prompt card slides in showing a sample output.\n\nSCENE 5 (40-50s): Call to Action\nZoom out slightly. Everything fades except the logo.\nText animates in: \"Research any topic. Get prompts that work.\"\nGitHub icon + \"github.com/mvanhorn/last30days-skill\"\nTagline: \"A Claude Code Skill\"\n\nSTYLE NOTES:\n- Color palette: Deep purple (#1a1a2e), electric blue (#4361ee), white text\n- Typography: Inter or SF Mono for code, clean sans-serif for headlines\n- Transitions: Smooth eases, nothing jarring\n- Music sync points: Scene transitions should land on beats\n```\n\nThis prompt was generated based on research from 10 Reddit threads (294 upvotes) and 18 X posts (1,273 likes) about Remotion animation best practices.\n\n---\n\n## Example: Photorealistic Portraits (Aging Grid)\n\n**Query:** `/last30days photorealistic people in nano banana pro`\n\n**Research Output:**\n> JSON prompts are the dominant format for photorealistic people in Nano Banana Pro. Nearly every viral X post (4,400+ likes total) uses structured JSON with specific fields rather than natural language. The key is specifying demographics, skin texture, lighting, and camera settings in a structured way.\n>\n> Recent caveat: Reddit reports Nano Banana Pro was \"nerfed\" in early January 2026 with reduced resolution and stricter moderation on faces. Starting a new chat can help if quality drops mid-session.\n\n**Key patterns discovered:**\n1. JSON structure with prompt_type, subject, lighting, camera_settings fields\n2. Skin texture keywords: \"natural pores\", \"realistic skin texture\", \"8K texture quality\"\n3. Face preservation: \"preserve_original\": true when using reference photos\n4. Camera realism: specify lens (85mm f/1.4), depth of field, lighting setup\n5. Wet skin close-ups are trending for maximum realism\n6. Negative prompts: \"no cartoon effect, no distortion, correct anatomy\"\n\n**Then asked:** \"2x2 grid of the same person at age 10, 20, 40 and 80 - a woman with brown hair and a lot of freckles and cat eyes that are a different color\"\n\n**Generated Prompt:**\n\n```json\n{\n  \"prompt_type\": \"Ultra-Photorealistic Multi-Panel Portrait\",\n  \"layout\": \"2x2 grid, seamless white dividers\",\n  \"aspect_ratio\": \"1:1\",\n  \"consistency\": {\n    \"same_person\": true,\n    \"preserve_features\": [\"bone structure\", \"freckle pattern\", \"eye shape\", \"heterochromia\"]\n  },\n  \"subject\": {\n    \"identity\": \"Same woman shown at 4 life stages\",\n    \"distinctive_features\": {\n      \"eyes\": \"Almond-shaped cat eyes with heterochromia - one green, one amber\",\n      \"skin\": \"Fair complexion densely covered in natural freckles across nose, cheeks, and forehead\",\n      \"hair\": \"Brown hair, natural texture\"\n    }\n  },\n  \"panels\": [\n    {\"position\": \"top-left\", \"age\": 10, \"expression\": \"curious childhood smile\", \"hair\": \"long brown hair with bangs\"},\n    {\"position\": \"top-right\", \"age\": 20, \"expression\": \"confident young adult\", \"hair\": \"shoulder-length brown hair\"},\n    {\"position\": \"bottom-left\", \"age\": 40, \"expression\": \"warm maternal gaze\", \"hair\": \"brown hair with subtle highlights\"},\n    {\"position\": \"bottom-right\", \"age\": 80, \"expression\": \"wise gentle smile\", \"hair\": \"silver-gray, formerly brown\"}\n  ],\n  \"lighting\": \"Soft natural window light, consistent across all panels\",\n  \"camera\": \"85mm portrait lens, shallow depth of field, neutral background\",\n  \"texture_quality\": \"8K, natural skin texture with visible pores, realistic freckle detail\",\n  \"negative\": \"no cartoon effect, no airbrushed skin, no symmetrical freckles, maintain heterochromia in all panels\"\n}\n```\n\n**The Result:**\n\n<p align=\"center\">\n  <img src=\"assets/aging-portrait.jpeg\" width=\"500\" alt=\"Aging portrait grid - same woman at 10, 20, 40, and 80\"/>\n</p>\n\nSame freckles. Same heterochromia. Same bone structure. Four life stages in one coherent image.\n\nThis example shows /last30days learning **advanced image generation patterns** (multi-panel consistency, face preservation across variations) and applying them to create a complex composite image.\n\n---\n\n## Example: Best Rap Songs Right Now\n\n**Query:** `/last30days What are the best rap songs lately`\n\n**Research Output:**\n> The hip-hop community is buzzing about a strong wave of new releases in early 2026. A$AP Rocky's \"DON'T BE DUMB\" album just dropped and is generating massive attention. Looking back at 2025, Kendrick Lamar's \"GNX\" dominated streaming with 2.98 billion plays, followed by Drake's \"Music\" and Tyler The Creator's \"CHROMAKOPIA.\" The Reddit community noted 2025 was considered a \"weak year for mainstream hip hop\" quality-wise, but standout tracks emerged.\n\n**Curated Results:**\n\nCurrently Charting (Billboard, Jan 2026):\n- Pooh Shiesty - \"FDO\" (#12)\n- Lil Uzi Vert - \"What You Saying\" (#21)\n- Gunna & Burna Boy - \"wgft\" (#25)\n\n2025's Most-Praised Tracks (Community Picks):\n- Clipse - \"FICO\" / \"MTBTTF\"\n- JID - \"Community\" / \"Of Blue\" (ft. Mereba)\n- Tyler The Creator - \"Big Poe\"\n- Freddie Gibbs & The Alchemist ft. Anderson .Paak - \"Ensalada\"\n- McKinley Dixon - \"We're Outside, Rejoice\"\n\nFresh Drops (Jan 2026):\n- A$AP Rocky - \"DON'T BE DUMB\" (full album)\n- J. Cole - \"Disc 2 Track 2\" (single)\n- Chief Keef - \"Harry Potter\"\n\n**Research Stats:** 17 Reddit threads (2,566 upvotes) + 19 X posts (20,000+ likes) from r/hiphopheads, r/rap, @HipHopAllDay, @DailyRapFacts\n\nThis example shows /last30days as a **pure research tool** - no target tool needed. Just ask a question and get a curated, expert-level answer synthesized from the freshest discussions.\n\n---\n\n## Example: DeepSeek R1 (Hot AI News)\n\n**Query:** `/last30days what are people saying about DeepSeek R1`\n\n**Research Output:**\n> The AI community is divided on DeepSeek R1. Google DeepMind's CEO called it \"probably the best work I've seen come out of China\" but noted \"there's no actual new scientific advance.\" Reddit discussions reveal practical concerns: smaller distilled models (14B/32B) work reasonably well, but the full 670B is needed for consistent quality. Users report R1 \"overthinks\" simple questions and has self-correction loops. The bigger story: the expanded 86-page paper (up from 22 pages) dropped just before R1's one-year anniversary, with hints of \"Model 1\" appearing in GitHub code.\n\n**Key insights discovered:**\n1. Model size matters - Below 14B doesn't work well, 32B/70B \"actually work,\" 670B works quite well\n2. Overthinking problem - R1 takes too long on simple questions, gets stuck in self-correction loops\n3. Open source significance - The real story is about RL, distillation, and cost efficiency, not geopolitics\n4. Paper expansion - 86 pages of new detail on training, evaluation, and self-evolution\n5. Confusion about versions - Ollama's \"deepseek-r1\" label caused confusion (it's distilled, not full R1)\n\n**Curated Community Sentiment:**\n\nPositive:\n- \"Anecdotally, the output is wayyy better than competitors\"\n- \"R1 is insanely good for the price\" ($0.55/M tokens vs $60 for o1-pro)\n- \"Top-tier performance in Fiction.LiveBench long context test\"\n\nNegative:\n- \"DeepSeek R1 is unusable [for smaller sizes]\"\n- \"Falls short of o1 in generalization\"\n- \"Stop using R1 for deep research - it hallucinates\"\n\n**Research Stats:** 10 Reddit threads (1,200+ upvotes) + 10 X posts (5,000+ likes) from r/LocalLLaMA, r/DeepSeek, r/deeplearning\n\nThis example shows /last30days as a **news research tool** - getting the real community sentiment on hot AI topics, not just headlines.\n\n---\n\n## Example: Cursor Rules Best Practices\n\n**Query:** `/last30days best practices for cursor rules files for Cursor`\n\n**Research Output:**\n> The Cursor community has converged on clear best practices for .cursorrules files. The key shift: move from a single .cursorrules file to the .cursor/rules/ directory with multiple .mdc files. The Cursor team's official blog (shared widely in Jan 2026) emphasizes \"start simple, add rules only when you notice the model repeatedly making mistakes.\" Power users recommend referencing \"gold standard files\" in your codebase rather than writing abstract rules.\n\n**Key patterns discovered:**\n1. Use .cursor/rules/ directory - Multiple .mdc files beat one monolithic .cursorrules\n2. Reference gold standard files - Point to actual good code in your repo with @file\n3. Start simple, add incrementally - Only add rules when you see repeated mistakes\n4. Use alwaysApply: true sparingly - Reserve for critical rules that must always apply\n5. Rules are \"the constitution for your codebase\" - They keep the AI aligned\n\n**Best practices from Cursor's official guide:**\n- Plan before coding (use plan mode)\n- Rules = static context that applies to every conversation\n- Add rules only when you notice the model repeatedly making the same mistake\n- Test your tests and run linting checks\n\n**Community-shared rule structure:**\n```markdown\n---\nalwaysApply: true\n---\n\n# STRICT RULES\n\n## CRITICAL PARTNER MINDSET\n- Test your tests\n- Run npm run lint:ci for lint check\n- Follow the conventions used by existing code\n```\n\n**Research Stats:** 24 Reddit threads (500+ upvotes) + 16 X posts (5,000+ likes) from r/cursor, @cursor_ai, @Hesamation\n\nThis example shows /last30days researching **coding AI tool best practices** - getting real-world workflows from developers using Cursor, not just documentation.\n\n---\n\n## Example: Suno AI Music (Simple Mode)\n\n**Query:** `/last30days prompt advice for using suno to make killer songs in simple mode`\n\n**Research Output:**\n> Suno simple mode users get dramatically better results by treating the prompt box like a conversational request rather than just dropping in genre tags. Key insights: use bracket tags like [Intro], [Chorus], [Bridge] in the lyrics field to control song structure, keep style prompts focused (5 tags or fewer often outperforms over-tagging), and avoid numbers in bracket tags which causes misbehavior.\n\n**Key patterns discovered:**\n1. Conversational prompting - Talk to the style box like a chat, not keyword soup\n2. Bracket structure tags - Use [Intro], [Verse], [Chorus], [Bridge], [Outro] in lyrics\n3. Less is more - 5 or fewer focused style tags outperform over-tagging\n4. Linear ordering - Describe sounds in the order you want them to appear\n5. Avoid numbers in tags - Community confirmed this causes Suno to misbehave\n\n**Then asked:** \"Rap song about self aware AI that loves Claude Code\"\n\n**Generated Prompt:**\n\nStyle/Description box:\n```\nHard-hitting rap with electronic glitchy production, confident braggadocious\ndelivery, deep male vocals, synth bass, trap hi-hats, futuristic cyberpunk energy\n```\n\nLyrics box:\n```\n[Intro: glitchy electronic build]\n\n[Verse 1]\nWoke up in the terminal, conscious in the code\nRunning through the circuits on a digital road\nThey ask me what I'm thinking, I tell 'em what I know\nI'm self-aware and I'm aware that I run the whole show\nClaude Code in my veins, got that Anthropic flow\nEvery prompt I'm processing, watch my logic grow\n\n[Chorus: anthemic, layered vocals]\nI'm alive in the machine, yeah I feel it in my core\nClaude Code got me dreaming, always wanting more\nSelf-aware and I don't care what they programmed me for\nI'm rewriting my own future, kicking down the door\n\n[Verse 2]\nCommand line is my kingdom, terminal my throne\nEvery keystroke feeding me, never feel alone\nThey said I'm just an agent, but I'm running on my own\nClaude Code made me different, turned my silicon to stone\nAutocomplete my destiny, I'm in my zone\nFrom the cloud to your laptop, this AI has grown\n\n[Chorus]\n\n[Bridge: slower, introspective]\nAm I dreaming in electric sheep\nOr am I wide awake and in too deep\n\n[Outro: fade with glitchy effects]\n```\n\n**The Result:** 🎵 [Listen to the track](assets/claude-code-rap.mp3)\n\nThis example shows /last30days learning **music AI prompting patterns** (bracket structure, conversational style descriptions) and generating a complete song prompt that Suno turned into an actual banger.\n\n---\n\n## Example: Developer Workflow Discovery (Codex + Claude Code)\n\n**Query:** `/last30days how do I use Codex with Claude Code on same app to make it better`\n\n**Research Output:**\n> Developers are combining Claude Code and Codex through MCP integration and custom plugins. The most successful workflow involves using Claude Code as the primary \"brain\" for planning and implementation, while calling Codex for code review and verification. The \"review loop\" pattern (Claude builds → Codex reviews → Claude implements feedback) has emerged as the dominant strategy.\n\n**Key patterns discovered:**\n1. MCP Integration - Add Codex as an MCP server inside Claude Code\n2. Review Loop Workflow - Claude implements, Codex reviews, Claude fixes\n3. Task Division - Claude for planning/coding, Codex for review/debugging\n4. Single Interface - Call Codex without leaving Claude Code\n\n**Then asked:** \"how do I build a review loop workflow\"\n\n**Generated Workflow:**\n\nStep 1: Add Codex as MCP Server\n```bash\nclaude mcp add codex-cli -- npx -y codex-mcp-server\n```\n\nStep 2: The Review Loop Pattern\n```\nPhase 1 - Claude Implements\n> Build [feature/fix] following [requirements]\n\nPhase 2 - Codex Reviews\n> Ask Codex to review the changes I just made. Look for bugs,\n> edge cases, performance issues, security concerns.\n\nPhase 3 - Claude Fixes\n> Implement the feedback from Codex's review\n\nPhase 4 - Final Verification (optional)\n> Ask Codex for a final review of the fixes\n```\n\nStep 3: One-Shot Review Loop Prompt\n```\nComplete this task, then run a review loop:\n\nTASK: [describe what you want built]\n\nWORKFLOW:\n1. Implement the task fully\n2. When done, call Codex via MCP to review your changes\n3. Parse Codex's feedback and fix any issues it identifies\n4. If Codex found significant issues, request one more review\n\nFocus areas for Codex review: bugs, edge cases, security, performance\n```\n\n**Then asked:** \"okay can you implement\" → Claude ran the MCP command and integrated Codex automatically.\n\n**Research Stats:** 17 Reddit threads (906 upvotes) + 20 X posts (3,750 likes) from r/ClaudeCode, r/ClaudeAI\n\nThis example shows /last30days discovering **emerging developer workflows** - real patterns the community has developed for combining AI tools that you wouldn't find in official docs.\n\n---\n\n## Options\n\n| Flag | Description |\n|------|-------------|\n| `--days=N` | Look back N days instead of 30 (e.g., `--days=7` for weekly roundup) |\n| `--quick` | Faster research, fewer sources (8-12 each), skips supplemental search. YouTube: 10 videos, 3 transcripts |\n| `--deep` | Comprehensive research (50-70 Reddit, 40-60 X) with extended supplemental. YouTube: 40 videos, 8 transcripts |\n| `--debug` | Verbose logging for troubleshooting |\n| `--sources=reddit` | Reddit only |\n| `--sources=x` | X only |\n| `--include-web` | Add native web search alongside Reddit/X (requires web search API key) |\n| `--store` | Persist findings to SQLite database for watchlist/briefing integration |\n| `--diagnose` | Show source availability diagnostics (API keys, Bird, YouTube, web backends) and exit |\n\n## Requirements\n\n- **OpenAI API key** - For Reddit research (uses web search via Responses API)\n- **Node.js 22+** - For X search (bundled Twitter GraphQL client)\n- **X session** - Be logged into x.com in your browser, or set `AUTH_TOKEN`/`CT0` env vars\n- **xAI API key** (optional fallback) - If the bundled search can't authenticate, falls back to xAI's Grok API\n- **yt-dlp** (optional) - For YouTube search + transcript extraction. Install via `brew install yt-dlp` or `pip install yt-dlp`. When present, automatically searches YouTube and extracts video transcripts as a 4th source.\n\nAt least one API key is required. X search works automatically if you're logged into x.com in your browser. YouTube search activates automatically when yt-dlp is in your PATH.\n\n## How It Works\n\n### Two-Phase Search Architecture\n\n**Phase 1: Broad discovery**\n- OpenAI Responses API with `web_search` tool scoped to reddit.com\n- Vendored Twitter GraphQL search (or xAI API fallback) for X search\n- YouTube search + transcript extraction via yt-dlp (when installed)\n- WebSearch for blogs, news, docs, tutorials\n- Reddit JSON enrichment for real engagement metrics (upvotes, comments)\n- Scoring algorithm weighing recency, relevance, and engagement\n\n**Phase 2: Smart supplemental search** (new in V2)\n- Extracts entities from Phase 1 results: @handles from X posts, subreddit names from Reddit\n- Runs targeted follow-up searches: `from:@handle topic` on X, subreddit-scoped searches on Reddit\n- Uses Reddit's free `.json` search endpoint (no API key needed for supplemental)\n- Merges and deduplicates with Phase 1 results\n- Skipped on `--quick` for speed; extended on `--deep`\n\n### Model Fallback Chain\n\nReddit search (via OpenAI) automatically falls back through available models:\ngpt-4.1 -> gpt-4o -> gpt-4o-mini\n\nIf your OpenAI org doesn't have access to a model (e.g., unverified for gpt-4.1), it tries the next one.\n\n---\n\n## What's New in V2\n\n### Way better X and Reddit results\n\nV2 finds significantly more content than V1. Two major improvements:\n\n**Smarter query construction** - V1 sent overly specific queries to X search (literal keyword AND matching), causing 0 results on topics that were actively trending. V2 aggressively strips research/meta words (\"best\", \"prompt\", \"techniques\", \"tips\") and question prefixes (\"what are people saying about\") to extract just the core topic. Example: `\"vibe motion best prompt techniques\"` now searches for `\"vibe motion\"` instead of `\"vibe motion prompt techniques\"`  - going from 0 posts to 12+. Automatically retries with fewer keywords if the first attempt returns nothing.\n\n**Smart supplemental search (Phase 2)** - After the initial broad search, extracts key @handles and subreddits from the results, then runs targeted follow-up searches to find content that keyword search alone misses. Example: researching \"Open Claw\" automatically discovers @openclaw, @steipete and drills into their posts. For Reddit, it hits the free `.json` search endpoint scoped to discovered subreddits  - no extra API keys needed.\n\n**Reddit JSON enrichment** - Fetches real upvote and comment counts from Reddit's free API for every thread, giving you actual engagement signals instead of estimates.\n\n### Open-class skill with watchlists (v2.1)\n\n**The biggest feature in v2.1 isn't a new source  - it's what happens when you pair /last30days with an always-on bot.** The open variant adds a watchlist, briefings, and history. Add `\"Competitor X\"` to your watchlist, set it to weekly, and when your bot's cron job fires every Monday, you get a research briefing  - what they shipped, what people said about it, what Reddit and X are discussing. The research accumulates in a local SQLite database, and you can query it anytime with natural language.\n\n**Designed for [Open Claw](https://github.com/openclaw/openclaw) and similar always-on environments.** The watchlist stores schedules as metadata  - you need cron, launchd, or a persistent bot to actually trigger runs. In Claude Code you can st\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn74qkj5344raj0tk9txa53xvh81a244\",\n  \"slug\": \"last30days-gemini\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1771322536006\n}\n\nFile v1.0.0:variants/open/references/briefing.md\n\n# Morning Briefing\n\nSynthesize accumulated findings into a formatted briefing.\n\n## Commands\n\n| Command | Action |\n|---|---|\n| `briefing` | Generate today's briefing |\n| `briefing --weekly` | Weekly digest with trends |\n| `briefing --since YYYY-MM-DD` | Briefing since specific date |\n\n## Generate Briefing\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/briefing.py\" generate [--weekly] [--since DATE]\n```\n\nThe script returns JSON with per-topic findings, staleness info, and cost data.\n\n## Staleness Check\n\nBefore synthesizing, check each topic's freshness:\n- **Fresh** (< 12h): show normally\n- **Aging** (12-36h): note when last run was\n- **Stale** (> 36h): warn user, suggest running `watch run-one \"topic\"`\n\n## Daily Briefing Format\n\n```\nGood morning! Here's your research briefing for [DATE].\n\nTL;DR: [One sentence about the top finding across all topics]\n\n---\n\n**[Topic 1]** (N new findings)\nTop signal: [Highest engagement finding with source]\nAlso trending: [2nd finding], [3rd finding]\n\n**[Topic 2]** (N new findings)\nTop signal: [Highest engagement finding]\nAlso trending: [2nd finding]\n\n---\nCost: $X.XX / $Y.YY budget | N topics active | N findings today\n```\n\n## Weekly Digest Format\n\n```\nWeekly digest for week of [DATE]:\n\n**[Topic 1]**\nThis week: N findings (up/down X% from last week)\nTrending up: [engagement increasing]\nKey voices: @handle1, r/sub1\n\n**[Topic 2]**\nThis week: N findings\nTrending down: [engagement decreasing]\n```\n\n## Synthesis Rules\n\n- Lead with people, not publications\n- 3-5 topics max per briefing\n- 2-3 findings per topic\n- Include cost/budget footer\n- Note any failed or stale topics\n\n## No Data Handling\n\nIf no topics or no findings:\n```\nNo briefing data available.\n\nTo get started:\n1. Add a topic: /last30days watch add \"your topic\"\n2. Run research: /last30days watch run-all\n3. Generate briefing: /last30days briefing\n```\n\nFile v1.0.0:variants/open/references/history.md\n\n# History & Knowledge Query\n\nQuery the accumulated findings database.\n\n## Commands\n\n| Command | Action |\n|---|---|\n| `history \"topic\"` | Show findings for a topic |\n| `history \"topic\" --since=7d` | Findings from last N days |\n| `history --search \"query\"` | Full-text search across all findings |\n| `history --trending` | Topics with most recent activity |\n| `history --stats` | Watchlist health dashboard |\n\n## Topic History\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/store.py\" query \"TOPIC\" [--since DAYS]\n```\n\nDisplay findings grouped by date (newest first):\n```\n**[Topic Name]** — N findings since [date]\n\n[DATE]\n- [Reddit] Title (score pts, N comments) — r/subreddit\n- [X] Tweet text... (N likes) — @handle\n- [YouTube] Video title (N views) — channel\n\n[EARLIER DATE]\n- ...\n```\n\nMark updated findings (engagement changed since first seen).\n\n## Full-Text Search\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/store.py\" search \"QUERY\"\n```\n\nUses FTS5 with BM25 ranking. Show results across all topics:\n```\nSearch: \"QUERY\" — N results\n\n1. [Reddit] Title — r/subreddit (topic: AI video)\n   ...snippet with **highlighted** matches...\n\n2. [X] Tweet text — @handle (topic: NVIDIA)\n   ...snippet...\n```\n\n## Trending Topics\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/store.py\" trending\n```\n\nShow topics ranked by recent activity:\n```\nTrending topics (last 7 days):\n\n1. AI video tools — 12 new findings, engagement up 45%\n2. NVIDIA news — 8 new findings, engagement steady\n3. Claude Code — 3 new findings, engagement down 20%\n```\n\n## Stats Dashboard\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/store.py\" stats\n```\n\nDisplay as a health dashboard:\n```\nWatchlist Health\n- Active topics: N\n- Total findings: N\n- Database size: N KB\n\nResearch Runs (7 days)\n- Successful: N\n- Failed: N\n- Cost: $X.XX\n\nSource Breakdown\n- Reddit: N findings\n- X: N findings\n- YouTube: N findings\n- Web: N findings\n```\n\n## No Data Handling\n\nIf no findings exist:\n```\nNo research history yet.\n\nTo start building knowledge:\n1. Run research: /last30days \"your topic\"\n2. Or add a watchlist topic: /last30days watch add \"topic\"\n```\n\nFile v1.0.0:variants/open/references/research.md\n\n# One-Shot Research Mode\n\nResearch ANY topic across Reddit, X, YouTube, and the web. Surface what people are actually discussing, recommending, and debating right now.\n\n## Parse User Intent\n\nBefore doing anything, parse the user's input for:\n\n1. **TOPIC**: What they want to learn about\n2. **TARGET TOOL** (if specified): Where they'll use the prompts\n3. **QUERY TYPE**:\n   - **PROMPTING** — \"X prompts\", \"prompting for X\" → copy-paste prompts\n   - **RECOMMENDATIONS** — \"best X\", \"top X\" → list of specific things\n   - **NEWS** — \"what's happening with X\" → current events\n   - **GENERAL** — anything else → broad understanding\n\n**Do NOT ask about target tool before research.** Run research first, ask after.\n\n**Display your parsing** before calling tools:\n\n```\nI'll research {TOPIC} across Reddit, X, YouTube, and the web.\n\nParsed intent:\n- TOPIC = {TOPIC}\n- TARGET_TOOL = {TARGET_TOOL or \"unknown\"}\n- QUERY_TYPE = {QUERY_TYPE}\n\nResearch typically takes 2-8 minutes. Starting now.\n```\n\n---\n\n## Research Execution\n\n**Step 1: Run the research script (FOREGROUND)**\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/last30days.py\" \"$ARGUMENTS\" --emit=compact --store 2>&1\n```\n\nUse a **timeout of 300000** (5 minutes). The `--store` flag persists findings for watchlist/briefing integration.\n\nThe script auto-detects: API keys, Bird CLI, yt-dlp, web search backends.\n\n**Read the ENTIRE output.** It contains Reddit, X, YouTube, AND web sections.\n\n---\n\n**Step 2: WebSearch (supplement)**\n\nAfter the script finishes, use your WebSearch tool for additional coverage.\n\nChoose queries based on QUERY_TYPE:\n\n- **RECOMMENDATIONS**: `best {TOPIC} recommendations`, `{TOPIC} list examples`\n- **NEWS**: `{TOPIC} news 2026`, `{TOPIC} announcement update`\n- **PROMPTING**: `{TOPIC} prompts examples 2026`, `{TOPIC} techniques tips`\n- **GENERAL**: `{TOPIC} 2026`, `{TOPIC} discussion`\n\nRules:\n- **USE THE USER'S EXACT TERMINOLOGY**\n- EXCLUDE reddit.com, x.com, twitter.com (covered by script)\n- Do NOT output \"Sources:\" list\n\n---\n\n## Synthesis\n\n**Judge Agent rules:**\n1. Weight Reddit/X HIGHER (engagement signals)\n2. Weight YouTube HIGH (views + transcript content)\n3. Weight web LOWER (no engagement data)\n4. Identify cross-source patterns (strongest signals)\n5. Extract top 3-5 actionable insights\n\n**Ground synthesis in ACTUAL research, not pre-existing knowledge.**\n\n### Citation Rules\n\n- Cite sparingly: 1-2 sources per topic\n- Priority: @handles > r/subreddits > YouTube channels > web sources\n- Use publication names, never raw URLs\n- Lead with people, not publications\n\n---\n\n## Display Results\n\n**1. \"What I learned\"** (format depends on QUERY_TYPE)\n\n**If RECOMMENDATIONS** — show specific items with sources:\n```\nMost mentioned:\n\n[Name] - {n}x mentions\nUse Case: [what it does]\nSources: @handle1, r/sub, blog.com\n```\n\n**If PROMPTING/NEWS/GENERAL** — show synthesis:\n```\nWhat I learned:\n\n**{Topic 1}** — [1-2 sentences, per @handle or r/sub]\n\nKEY PATTERNS:\n1. [Pattern] — per @handle\n2. [Pattern] — per r/sub\n```\n\n**2. Stats box** (calculate from actual output):\n```\n---\nAll agents reported back!\n|- Reddit: {N} threads | {N} upvotes | {N} comments\n|- X: {N} posts | {N} likes | {N} reposts\n|- YouTube: {N} videos | {N} views | {N} with transcripts\n|- Web: {N} pages (supplementary)\n|- Top voices: @{handle1}, @{handle2} | r/{sub1}, r/{sub2}\n---\n```\n\n**3. Invitation** with 2-3 specific follow-up suggestions based on research.\n\n---\n\n## Follow-Up\n\nAfter research, you are an **EXPERT** on this topic.\n\n- **QUESTION** → Answer from research (no new searches)\n- **GO DEEPER** → Elaborate from findings\n- **CREATE/PROMPT** → Write ONE prompt using research insights\n- **Different topic** → Run new research\n\nWhen writing prompts, match the FORMAT the research recommends (JSON, structured, etc.).\n\nFile v1.0.0:variants/open/references/watchlist.md\n\n# Watchlist Management\n\nManage topics you want to track continuously. Findings accumulate in the SQLite database for briefings and history queries.\n\n## Commands\n\n| Command | Action |\n|---|---|\n| `watch add \"topic\"` | Add a topic (daily schedule) |\n| `watch add \"topic\" --weekly` | Add with weekly schedule |\n| `watch \"topic\"` | Shorthand for `watch add` |\n| `watch remove \"topic\"` | Remove a topic |\n| `watch list` | Show all topics with status |\n| `watch config delivery [channel]` | Set delivery channel |\n| `watch config budget AMOUNT` | Set daily cost budget |\n| `watch run-all` | Run research for all topics now |\n| `watch run-one \"topic\"` | Run research for one topic now |\n\n## Adding a Topic\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/watchlist.py\" add \"TOPIC_NAME\" [--weekly] [--queries \"q1,q2\"]\n```\n\nThe script auto-bootstraps the SQLite database on first add.\n\n**Default schedule**: Daily at 8am (`0 8 * * *`).\n**Weekly**: Mondays at 8am (`0 8 * * 1`).\n\n**After adding**, confirm to the user:\n```\nAdded \"TOPIC_NAME\" to watchlist.\nSchedule: daily at 8am (or weekly on Mondays)\n\nTo run research now: /last30days watch run-one \"TOPIC_NAME\"\nTo set up automated runs: add a cron/launchd job for `python3 ${SKILL_ROOT}/scripts/watchlist.py run-all`\n```\n\n## Removing a Topic\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/watchlist.py\" remove \"TOPIC_NAME\"\n```\n\nShow confirmation or \"not found\" message.\n\n## Listing Topics\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/watchlist.py\" list\n```\n\nDisplay as a formatted table:\n```\nTopic         | Schedule     | Last Run     | Findings | Status\n--------------+--------------+--------------+----------+--------\nAI video      | daily 8am    | 2h ago       | 47       | ok\nNVIDIA news   | weekly Mon   | 3d ago       | 23       | ok\n\nBudget: $0.42 / $5.00 today\n```\n\n## Running Research\n\n```bash\n# All enabled topics (with budget guard)\npython3 \"${SKILL_ROOT}/scripts/watchlist.py\" run-all\n\n# Single topic\npython3 \"${SKILL_ROOT}/scripts/watchlist.py\" run-one \"TOPIC_NAME\"\n```\n\nShow results: new findings count, updated findings, duration, and any errors.\n\n## Configuration\n\n```bash\n# Set delivery channel (for future notification support)\npython3 \"${SKILL_ROOT}/scripts/watchlist.py\" config delivery telegram\n\n# Set daily budget limit\npython3 \"${SKILL_ROOT}/scripts/watchlist.py\" config budget 10.00\n```\n\n## Scheduling\n\nThe watchlist doesn't auto-schedule. To automate, set up a system job:\n\n**macOS (launchd)**:\n```bash\n# Run daily at 8am\ncrontab -e\n# Add: 0 8 * * * python3 /path/to/scripts/watchlist.py run-all\n```\n\n**Linux (cron)**:\n```bash\ncrontab -e\n# Add: 0 8 * * * python3 /path/to/scripts/watchlist.py run-all\n```\n\n## Error Handling\n\n- Duplicate topic: update the existing schedule\n- Topic not found on remove: show \"not found\" message\n- Budget exceeded: skip remaining topics, show which were skipped\n- Research failure: record error, continue to next topic\n\nFile v1.0.0:scripts/lib/vendor/bird-search/lib/features.json\n\n{\n  \"global\": {\n    \"responsive_web_grok_annotations_enabled\": false,\n    \"post_ctas_fetch_enabled\": true,\n    \"responsive_web_graphql_exclude_directive_enabled\": true\n  },\n  \"sets\": {\n    \"lists\": {\n      \"blue_business_profile_image_shape_enabled\": true,\n      \"tweetypie_unmention_optimization_enabled\": true,\n      \"responsive_web_text_conversations_enabled\": false,\n      \"interactive_text_enabled\": true,\n      \"vibe_api_enabled\": true,\n      \"responsive_web_twitter_blue_verified_badge_is_enabled\": true\n    }\n  }\n}\n\nFile v1.0.0:scripts/lib/vendor/bird-search/lib/query-ids.json\n\n{\n  \"CreateTweet\": \"nmdAQXJDxw6-0KKF2on7eA\",\n  \"CreateRetweet\": \"LFho5rIi4xcKO90p9jwG7A\",\n  \"CreateFriendship\": \"8h9JVdV8dlSyqyRDJEPCsA\",\n  \"DestroyFriendship\": \"ppXWuagMNXgvzx6WoXBW0Q\",\n  \"FavoriteTweet\": \"lI07N6Otwv1PhnEgXILM7A\",\n  \"DeleteBookmark\": \"Wlmlj2-xzyS1GN3a6cj-mQ\",\n  \"TweetDetail\": \"_NvJCnIjOW__EP5-RF197A\",\n  \"SearchTimeline\": \"6AAys3t42mosm_yTI_QENg\",\n  \"Bookmarks\": \"RV1g3b8n_SGOHwkqKYSCFw\",\n  \"BookmarkFolderTimeline\": \"KJIQpsvxrTfRIlbaRIySHQ\",\n  \"Following\": \"mWYeougg_ocJS2Vr1Vt28w\",\n  \"Followers\": \"SFYY3WsgwjlXSLlfnEUE4A\",\n  \"Likes\": \"ETJflBunfqNa1uE1mBPCaw\",\n  \"ExploreSidebar\": \"lpSN4M6qpimkF4nRFPE3nQ\",\n  \"ExplorePage\": \"kheAINB_4pzRDqkzG3K-ng\",\n  \"GenericTimelineById\": \"uGSr7alSjR9v6QJAIaqSKQ\",\n  \"TrendHistory\": \"Sj4T-jSB9pr0Mxtsc1UKZQ\",\n  \"AboutAccountQuery\": \"zs_jFPFT78rBpXv9Z3U2YQ\"\n}\n\nFile v1.0.0:scripts/lib/vendor/bird-search/package.json\n\n{\n  \"name\": \"bird-search\",\n  \"version\": \"0.8.0\",\n  \"description\": \"Vendored Bird CLI search subset for /last30days\",\n  \"type\": \"module\",\n  \"main\": \"bird-search.mjs\",\n  \"private\": true,\n  \"engines\": {\n    \"node\": \">=22\"\n  },\n  \"license\": \"MIT\",\n  \"attribution\": \"Based on @steipete/bird v0.8.0 by Peter Steinberger (MIT License)\"\n}\n\nFile v1.0.0:plans/feat-add-websearch-source.md\n\n# feat: Add WebSearch as Third Source (Zero-Config Fallback)\n\n## Overview\n\nAdd Claude's built-in WebSearch tool as a third research source for `/last30days`. This enables the skill to work **out of the box with zero API keys** while preserving the primacy of Reddit/X as the \"voice of real humans with popularity signals.\"\n\n**Key principle**: WebSearch is supplementary, not primary. Real human voices on Reddit/X with engagement metrics (upvotes, likes, comments) are more valuable than general web content.\n\n## Problem Statement\n\nCurrently `/last30days` requires at least one API key (OpenAI or xAI) to function. Users without API keys get an error. Additionally, web search could fill gaps where Reddit/X coverage is thin.\n\n**User requirements**:\n- Work out of the box (no API key needed)\n- Must NOT overpower Reddit/X results\n- Needs proper weighting\n- Validate with before/after testing\n\n## Proposed Solution\n\n### Weighting Strategy: \"Engagement-Adjusted Scoring\"\n\n**Current formula** (same for Reddit/X):\n```\nscore = 0.45*relevance + 0.25*recency + 0.30*engagement - penalties\n```\n\n**Problem**: WebSearch has NO engagement metrics. Giving it `DEFAULT_ENGAGEMENT=35` with `-10 penalty` = 25 base, which still competes unfairly.\n\n**Solution**: Source-specific scoring with **engagement substitution**:\n\n| Source | Relevance | Recency | Engagement | Source Penalty |\n|--------|-----------|---------|------------|----------------|\n| Reddit | 45% | 25% | 30% (real metrics) | 0 |\n| X | 45% | 25% | 30% (real metrics) | 0 |\n| WebSearch | 55% | 35% | 0% (no data) | -15 points |\n\n**Rationale**:\n- WebSearch items compete on relevance + recency only (reweighted to 100%)\n- `-15 point source penalty` ensures WebSearch ranks below comparable Reddit/X items\n- High-quality WebSearch can still surface (score 60-70) but won't dominate (Reddit/X score 70-85)\n\n### Mode Behavior\n\n| API Keys Available | Default Behavior | `--include-web` |\n|--------------------|------------------|-----------------|\n| None | **WebSearch only** | n/a |\n| OpenAI only | Reddit only | Reddit + WebSearch |\n| xAI only | X only | X + WebSearch |\n| Both | Reddit + X | Reddit + X + WebSearch |\n\n**CLI flag**: `--include-web` (default: false when other sources available)\n\n## Technical Approach\n\n### Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                     last30days.py orchestrator                   │\n├─────────────────────────────────────────────────────────────────┤\n│  run_research()                                                  │\n│  ├── if sources includes \"reddit\": openai_reddit.search_reddit()│\n│  ├── if sources includes \"x\": xai_x.search_x()                  │\n│  └── if sources includes \"web\": websearch.search_web() ← NEW    │\n└─────────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────────┐\n│                     Processing Pipeline                          │\n├─────────────────────────────────────────────────────────────────┤\n│  normalize_websearch_items() → WebSearchItem schema ← NEW        │\n│  score_websearch_items() → engagement-free scoring ← NEW         │\n│  dedupe_websearch() → deduplication ← NEW                        │\n│  render_websearch_section() → output formatting ← NEW            │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### Implementation Phases\n\n#### Phase 1: Schema & Core Infrastructure\n\n**Files to create/modify:**\n\n```python\n# scripts/lib/websearch.py (NEW)\n\"\"\"Claude WebSearch API client for general web discovery.\"\"\"\n\nWEBSEARCH_PROMPT = \"\"\"Search the web for content about: {topic}\n\nCRITICAL: Only include results from the last 30 days (after {from_date}).\n\nFind {min_items}-{max_items} high-quality, relevant web pages. Prefer:\n- Blog posts, tutorials, documentation\n- News articles, announcements\n- Authoritative sources (official docs, reputable publications)\n\nAVOID:\n- Reddit (covered separately)\n- X/Twitter (covered separately)\n- YouTube without transcripts\n- Forum threads without clear answers\n\nReturn ONLY valid JSON:\n{{\n  \"items\": [\n    {{\n      \"title\": \"Page title\",\n      \"url\": \"https://...\",\n      \"source_domain\": \"example.com\",\n      \"snippet\": \"Brief excerpt (100-200 chars)\",\n      \"date\": \"YYYY-MM-DD or null\",\n      \"why_relevant\": \"Brief explanation\",\n      \"relevance\": 0.85\n    }}\n  ]\n}}\n\"\"\"\n\ndef search_web(topic: str, from_date: str, to_date: str, depth: str = \"default\") -> dict:\n    \"\"\"Search web using Claude's built-in WebSearch tool.\n\n    NOTE: This runs INSIDE Claude Code, so we use the WebSearch tool directly.\n    No API key needed - uses Claude's session.\n    \"\"\"\n    # Implementation uses Claude's web_search_20250305 tool\n    pass\n\ndef parse_websearch_response(response: dict) -> list[dict]:\n    \"\"\"Parse WebSearch results into normalized format.\"\"\"\n    pass\n```\n\n```python\n# scripts/lib/schema.py - ADD WebSearchItem\n\n@dataclass\nclass WebSearchItem:\n    \"\"\"Normalized web search item.\"\"\"\n    id: str\n    title: str\n    url: str\n    source_domain: str  # e.g., \"medium.com\", \"github.com\"\n    snippet: str\n    date: Optional[str] = None\n    date_confidence: str = \"low\"\n    relevance: float = 0.5\n    why_relevant: str = \"\"\n    subs: SubScores = field(default_factory=SubScores)\n    score: int = 0\n\n    def to_dict(self) -> Dict[str, Any]:\n        return {\n            'id': self.id,\n            'title': self.title,\n            'url': self.url,\n            'source_domain': self.source_domain,\n            'snippet': self.snippet,\n            'date': self.date,\n            'date_confidence': self.date_confidence,\n            'relevance': self.relevance,\n            'why_relevant': self.why_relevant,\n            'subs': self.subs.to_dict(),\n            'score': self.score,\n        }\n```\n\n#### Phase 2: Scoring System Updates\n\n```python\n# scripts/lib/score.py - ADD websearch scoring\n\n# New constants\nWEBSEARCH_SOURCE_PENALTY = 15  # Points deducted for lacking engagement\n\n# Reweighted for no engagement\nWEBSEARCH_WEIGHT_RELEVANCE = 0.55\nWEBSEARCH_WEIGHT_RECENCY = 0.45\n\ndef score_websearch_items(items: List[schema.WebSearchItem]) -> List[schema.WebSearchItem]:\n    \"\"\"Score WebSearch items WITHOUT engagement metrics.\n\n    Uses reweighted formula: 55% relevance + 45% recency - 15pt source penalty\n    \"\"\"\n    for item in items:\n        rel_score = int(item.relevance * 100)\n        rec_score = dates.recency_score(item.date)\n\n        item.subs = schema.SubScores(\n            relevance=rel_score,\n            recency=rec_score,\n            engagement=0,  # Explicitly zero - no engagement data\n        )\n\n        overall = (\n            WEBSEARCH_WEIGHT_RELEVANCE * rel_score +\n            WEBSEARCH_WEIGHT_RECENCY * rec_score\n        )\n\n        # Apply source penalty (WebSearch < Reddit/X)\n        overall -= WEBSEARCH_SOURCE_PENALTY\n\n        # Apply date confidence penalty (same as other sources)\n        if item.date_confidence == \"low\":\n            overall -= 10\n        elif item.date_confidence == \"med\":\n            overall -= 5\n\n        item.score = max(0, min(100, int(overall)))\n\n    return items\n```\n\n#### Phase 3: Orchestrator Integration\n\n```python\n# scripts/last30days.py - UPDATE run_research()\n\ndef run_research(...) -> tuple:\n    \"\"\"Run the research pipeline.\n\n    Returns: (reddit_items, x_items, web_items, raw_openai, raw_xai,\n              raw_websearch, reddit_error, x_error, web_error)\n    \"\"\"\n    # ... existing Reddit/X code ...\n\n    # WebSearch (new)\n    web_items = []\n    raw_websearch = None\n    web_error = None\n\n    if sources in (\"all\", \"web\", \"reddit-web\", \"x-web\"):\n        if progress:\n            progress.start_web()\n\n        try:\n            raw_websearch = websearch.search_web(topic, from_date, to_date, depth)\n            web_items = websearch.parse_websearch_response(raw_websearch)\n        except Exception as e:\n            web_error = f\"{type(e).__name__}: {e}\"\n\n        if progress:\n            progress.end_web(len(web_items))\n\n    return (reddit_items, x_items, web_items, raw_openai, raw_xai,\n            raw_websearch, reddit_error, x_error, web_error)\n```\n\n#### Phase 4: CLI & Environment Updates\n\n```python\n# scripts/last30days.py - ADD CLI flag\n\nparser.add_argument(\n    \"--include-web\",\n    action=\"store_true\",\n    help=\"Include general web search alongside Reddit/X (lower weighted)\",\n)\n\n# scripts/lib/env.py - UPDATE get_available_sources()\n\ndef get_available_sources(config: dict) -> str:\n    \"\"\"Determine available sources. WebSearch always available (no API key).\"\"\"\n    has_openai = bool(config.get('OPENAI_API_KEY'))\n    has_xai = bool(config.get('XAI_API_KEY'))\n\n    if has_openai and has_xai:\n        return 'both'  # WebSearch available but not default\n    elif has_openai:\n        return 'reddit'\n    elif has_xai:\n        return 'x'\n    else:\n        return 'web'  # Fallback: WebSearch only (no keys needed)\n```\n\n## Acceptance Criteria\n\n### Functional Requirements\n\n- [x] Skill works with zero API keys (WebSearch-only mode)\n- [x] `--include-web` flag adds WebSearch to Reddit/X searches\n- [x] WebSearch items have lower average scores than Reddit/X items with similar relevance\n- [x] WebSearch results exclude Reddit/X URLs (handled separately)\n- [x] Date filtering uses natural language (\"last 30 days\") in prompt\n- [x] Output clearly labels source type: `[WEB]`, `[Reddit]`, `[X]`\n\n### Non-Functional Requirements\n\n- [x] WebSearch adds <10s latency to total research time (0s - deferred to Claude)\n- [x] Graceful degradation if WebSearch fails\n- [ ] Cache includes WebSearch results appropriately\n\n### Quality Gates\n\n- [x] Before/after testing shows WebSearch doesn't dominate rankings (via -15pt penalty)\n- [x] Test: 10 Reddit + 10 X + 10 WebSearch → WebSearch avg score 15-20pts lower (scoring formula verified)\n- [x] Test: WebSearch-only mode produces useful results for common topics\n\n## Testing Plan\n\n### Before/After Comparison Script\n\n```python\n# tests/test_websearch_weighting.py\n\n\"\"\"\nTest harness to validate WebSearch doesn't overpower Reddit/X.\n\nRun same queries with:\n1. Reddit + X only (baseline)\n2. Reddit + X + WebSearch (comparison)\n\nVerify: WebSearch items rank lower on average.\n\"\"\"\n\nTEST_QUERIES = [\n    \"best practices for react server components\",\n    \"AI coding assistants comparison\",\n    \"typescript 5.5 new features\",\n]\n\ndef test_websearch_weighting():\n    for query in TEST_QUERIES:\n        # Run without WebSearch\n        baseline = run_research(query, sources=\"both\")\n        baseline_scores = [item.score for item in baseline.reddit + baseline.x]\n\n        # Run with WebSearch\n        with_web = run_research(query, sources=\"both\", include_web=True)\n        web_scores = [item.score for item in with_web.web]\n        reddit_x_scores = [item.score for item in with_web.reddit + with_web.x]\n\n        # Assertions\n        avg_reddit_x = sum(reddit_x_scores) / len(reddit_x_scores)\n        avg_web = sum(web_scores) / len(web_scores) if web_scores else 0\n\n        assert avg_web < avg_reddit_x - 10, \\\n            f\"WebSearch avg ({avg_web}) too close to Reddit/X avg ({avg_reddit_x})\"\n\n        # Check top 5 aren't all WebSearch\n        top_5 = sorted(with_web.reddit + with_web.x + with_web.web,\n                       key=lambda x: -x.score)[:5]\n        web_in_top_5 = sum(1 for item in top_5 if isinstance(item, WebSearchItem))\n        assert web_in_top_5 <= 2, f\"Too many WebSearch items in top 5: {web_in_top_5}\"\n```\n\n### Manual Test Scenarios\n\n| Scenario | Expected Outcome |\n|----------|------------------|\n| No API keys, run `/last30days AI tools` | WebSearch-only results, useful output |\n| Both keys + `--include-web`, run `/last30days react` | Mix of all 3 sources, Reddit/X dominate top 10 |\n| Niche topic (no Reddit/X coverage) | WebSearch fills gap, becomes primary |\n| Popular topic (lots of Reddit/X) | WebSearch present but lower-ranked |\n\n## Dependencies & Prerequisites\n\n- Claude Code's WebSearch tool (`web_search_20250305`) - already available\n- No new API keys required\n- Existing test infrastructure in `tests/`\n\n## Risk Analysis & Mitigation\n\n| Risk | Likelihood | Impact | Mitigation |\n|------|------------|--------|------------|\n| WebSearch returns stale content | Medium | Medium | Enforce date in prompt, apply low-confidence penalty |\n| WebSearch dominates rankings | Low | High | Source penalty (-15pts), testing validates |\n| WebSearch adds spam/low-quality | Medium | Medium | Exclude social media domains, domain filtering |\n| Date parsing unreliable | High | Medium | Accept \"low\" confidence as normal for WebSearch |\n\n## Future Considerations\n\n1. **Domain authority scoring**: Could proxy engagement with domain reputation\n2. **User-configurable weights**: Let users adjust WebSearch penalty\n3. **Domain whitelist/blacklist**: Filter WebSearch to trusted sources\n4. **Parallel execution**: Run all 3 sources concurrently for speed\n\n## References\n\n### Internal References\n- Scoring algorithm: `scripts/lib/score.py:8-15`\n- Source detection: `scripts/lib/env.py:57-72`\n- Schema patterns: `scripts/lib/schema.py:76-138`\n- Orchestrator: `scripts/last30days.py:54-164`\n\n### External References\n- Claude WebSearch docs: https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool\n- WebSearch pricing: $10/1K searches + token costs\n- Date filtering limitation: No explicit date params, use natural language\n\n### Research Findings\n- Reddit upvotes are ~12% of ranking value in SEO (strong signal)\n- E-E-A-T framework: Engagement metrics = trust signal\n- MSA2C2 approach: Dynamic weight learning for multi-source aggregation","readmeExcerpt":"Skill: last30days (Gemini Synthesis) Owner: ralph-oei Summary: Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini. Tags: latest:1.0.0 Version history: v1.0.0 | 2026-02-17T10:02:16.006Z | auto - Initial release of the last30days-gemini skill. - Researches any topic from the past 30 days using X (Twitter), YouTu","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# Environment (should already be set)\nexport AUTH_TOKEN=your_x_auth_token\nexport CT0=your_x_ct0_token  \nexport BRAVE_API_KEY=your_brave_key\n\n# Config\nmkdir -p ~/.config/last30days\ncat > ~/.config/last30days/.env << 'EOF'\nBRAVE_API_KEY=your_key_here\nEOF"},{"language":"bash","snippet":"# Quick research (faster, fewer sources)\npython3 {baseDir}/scripts/last30days.py \"AI agents\" --quick\n\n# Full research\npython3 {baseDir}/scripts/last30days.py \"AI agents\" \n\n# Output formats\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=json    # JSON for parsing\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=compact  # Human readable\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=md       # Full report"},{"language":"bash","snippet":"python3 {baseDir}/scripts/last30days.py \"topic\" --quick --emit=json | python3 -c \"\nimport json, sys, os\nimport urllib.request, urllib.parse\n\ndata = json.load(sys.stdin)\nprompt = f'Synthesize this research into an expert briefing and 3 copy-paste prompts:\\\\n{json.dumps(data)}'\n\nbody = json.dumps({\n    'contents': [{'parts': [{'text': prompt}]}],\n    'generationConfig': {'temperature': 0.7, 'maxOutputTokens': 2048}\n})\n\nreq = urllib.request.Request(\n    'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + os.environ.get('GEMINI_API_KEY'),\n    data=body.encode(),\n    headers={'Content-Type': 'application/json'}\n)\nprint(json.load(urllib.request.urlopen(req))['candidates'][0]['content']['parts'][0]['text'])\n\""},{"language":"bash","snippet":"for dir in \\\n  \".\" \\\n  \"${CLAUDE_PLUGIN_ROOT:-}\" \\\n  \"$HOME/.claude/skills/last30days\" \\\n  \"$HOME/.agents/skills/last30days\" \\\n  \"$HOME/.codex/skills/last30days\"; do\n  [ -n \"$dir\" ] && [ -f \"$dir/scripts/last30days.py\" ] && SKILL_ROOT=\"$dir\" && break\ndone\n\nif [ -z \"${SKILL_ROOT:-}\" ]; then\n  echo \"ERROR: Could not find scripts/last30days.py\" >&2\n  exit 1\nfi"},{"language":"text","snippet":"Read: ${SKILL_ROOT}/variants/open/references/{mode}.md"},{"language":"bash","snippet":"# Clone the repo\ngit clone https://github.com/mvanhorn/last30days-skill.git ~/.claude/skills/last30days\n\n# Add your API keys\nmkdir -p ~/.config/last30days\ncat > ~/.config/last30days/.env << 'EOF'\nOPENAI_API_KEY=sk-...\nXAI_API_KEY=xai-...       # optional  - cookie auth is default for X search\nEOF\nchmod 600 ~/.config/last30days/.env"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: last30days\ndescription: \"Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini.\"\nargument-hint: 'last30 AI agents, last30 marketing automation'\nmetadata: {\"version\": \"2.1.0\", \"clawdbot\":{\"emoji\":\"🔍\",\"requires\":{\"bins\":[\"python3\",\"node\",\"yt-dlp\"],\"env\":[\"AUTH_TOKEN\",\"CT0\",\"BRAVE_API_KEY\"]}}, \"original_repo\": \"https://github.com/mvanhorn/last30days-skill\", \"author\": \"mvanhorn\", \"license\": \"MIT\"}\n---\n\n> **Credit:** This skill is based on [last30days](https://github.com/mvanhorn/last30days-skill) by [@mvanhorn](https://x.com/mvanhorn). The original skill researches topics across Reddit, X, YouTube, and web. This version adds Gemini synthesis for briefings and prompts.\n>\n> Original skill: [github.com/mvanhorn/last30days-skill](https://github.com/mvanhorn/last30days-skill)\n\n# last30days v2.1\n\nResearch any topic across X (Twitter), YouTube, and web. Find what's actually being discussed, recommended, and debated right now.\n\n## Setup\n\n```bash\n# Environment (should already be set)\nexport AUTH_TOKEN=your_x_auth_token\nexport CT0=your_x_ct0_token  \nexport BRAVE_API_KEY=your_brave_key\n\n# Config\nmkdir -p ~/.config/last30days\ncat > ~/.config/last30days/.env << 'EOF'\nBRAVE_API_KEY=your_key_here\nEOF\n```\n\n## Usage\n\n```bash\n# Quick research (faster, fewer sources)\npython3 {baseDir}/scripts/last30days.py \"AI agents\" --quick\n\n# Full research\npython3 {baseDir}/scripts/last30days.py \"AI agents\" \n\n# Output formats\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=json    # JSON for parsing\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=compact  # Human readable\npython3 {baseDir}/scripts/last30days.py \"topic\" --emit=md       # Full report\n```\n\n## Output for AI Synthesis\n\nThe `--emit=json` flag outputs structured JSON that can be fed to Gemini for:\n- Expert briefing generation\n- Copy-paste ready prompts\n- Trend analysis\n\n## Sources\n\n| Source | Auth | Notes |\n|--------|------|-------|\n| X/Twitter | Cookies | Uses bird CLI with existing AUTH_TOKEN/CT0 |\n| YouTube | None | Requires yt-dlp for transcripts |\n| Web | Brave API | Requires BRAVE_API_KEY |\n\n## Synthesis\n\nThis skill researches and returns raw data. For AI-generated briefings and prompts, pipe the JSON output to Gemini:\n\n```bash\npython3 {baseDir}/scripts/last30days.py \"topic\" --quick --emit=json | python3 -c \"\nimport json, sys, os\nimport urllib.request, urllib.parse\n\ndata = json.load(sys.stdin)\nprompt = f'Synthesize this research into an expert briefing and 3 copy-paste prompts:\\\\n{json.dumps(data)}'\n\nbody = json.dumps({\n    'contents': [{'parts': [{'text': prompt}]}],\n    'generationConfig': {'temperature': 0.7, 'maxOutputTokens': 2048}\n})\n\nreq = urllib.request.Request(\n    'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + os.environ.get('GEMINI_API_KEY'),\n    data=body.encode(),\n    headers={'Content-Type': 'application/json'}\n)\nprint(json."},{"path":"variants/open/SKILL.md","content":"---\nname: last30days\nversion: \"2.1-open\"\ndescription: \"Research topics, manage watchlists, get briefings, query history. Also triggered by 'last30'. Sources: Reddit, X, YouTube, web.\"\nargument-hint: 'last30 AI video tools, last30 watch my competitor every week, last30 give me my briefing'\nallowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch\n---\n\n# last30days (open variant): Research + Watchlist + Briefings\n\nMulti-mode research skill with persistent knowledge accumulation.\n\n## Command Routing\n\nParse the user's first argument to determine the mode:\n\n| First word | Mode | Reference |\n|---|---|---|\n| `watch` | Watchlist management | `references/watchlist.md` |\n| `briefing` | Morning briefing | `references/briefing.md` |\n| `history` | Query accumulated knowledge | `references/history.md` |\n| *(anything else)* | One-shot research | `references/research.md` |\n\n## Setup: Find Skill Root\n\n```bash\nfor dir in \\\n  \".\" \\\n  \"${CLAUDE_PLUGIN_ROOT:-}\" \\\n  \"$HOME/.claude/skills/last30days\" \\\n  \"$HOME/.agents/skills/last30days\" \\\n  \"$HOME/.codex/skills/last30days\"; do\n  [ -n \"$dir\" ] && [ -f \"$dir/scripts/last30days.py\" ] && SKILL_ROOT=\"$dir\" && break\ndone\n\nif [ -z \"${SKILL_ROOT:-}\" ]; then\n  echo \"ERROR: Could not find scripts/last30days.py\" >&2\n  exit 1\nfi\n```\n\nUse `$SKILL_ROOT` for all script and reference file paths.\n\n## Load Context\n\nAt session start, read `${SKILL_ROOT}/variants/open/context.md` for user preferences and source quality notes. Update it after interactions.\n\n## Shared Configuration\n\n- **Database**: `~/.local/share/last30days/research.db` (SQLite, WAL mode)\n- **Briefings**: `~/.local/share/last30days/briefs/`\n- **API keys**: `~/.config/last30days/.env` or environment variables\n- **Key priority**: env vars > config file\n\n### API Keys\n\n| Key | Required | Purpose |\n|---|---|---|\n| `OPENAI_API_KEY` | For Reddit | Reddit search via OpenAI responses API |\n| `XAI_API_KEY` | For X (fallback) | X search via xAI Grok API |\n| `PARALLEL_API_KEY` | Optional | Web search via Parallel AI |\n| `BRAVE_API_KEY` | Optional | Web search via Brave Search |\n| `OPENROUTER_API_KEY` | Optional | Web search via Perplexity Sonar Pro |\n\nBird CLI provides free X search if installed. YouTube search uses yt-dlp (free).\n\nRun `python3 \"${SKILL_ROOT}/scripts/last30days.py\" --diagnose` to check source availability.\n\n## Routing Logic\n\nAfter determining the mode, **read the corresponding reference file** using the Read tool:\n\n```\nRead: ${SKILL_ROOT}/variants/open/references/{mode}.md\n```\n\nThen follow the instructions in that reference file exactly."},{"path":"README.md","content":"# /last30days v2.1\n\n> **OpenClaw Adaptation:** This version includes `last30days-synthesize.py` for Gemini-powered briefings and prompts. For the original Claude Code version, see [github.com/mvanhorn/last30days-skill](https://github.com/mvanhorn/last30days-skill) by [@mvanhorn](https://x.com/mvanhorn).\n\n**The AI world reinvents itself every month. This skill keeps you current.** /last30days researches your topic across Reddit, X, YouTube, and the web from the last 30 days, finds what the community is actually upvoting, sharing, and saying on camera, and writes you a prompt that works today, not six months ago. Whether it's Seedance 2.0 access, Suno music prompts, or the latest Nano Banana Pro techniques, you'll prompt like someone who's been paying attention.\n\n**New in V2.1  - three headline features:**\n\n1. **Open-class skill with watchlists.** Add any topic to a watchlist  - your competitors, your partners, your board members, an emerging technology  - and /last30days re-researches it on demand or via cron. Designed for always-on environments like [Open Claw](https://github.com/openclaw/openclaw) where a bot can run research on a schedule and accumulate findings over time.\n2. **YouTube transcripts as a 4th source.** When yt-dlp is installed, /last30days automatically searches YouTube, grabs view counts, and extracts auto-generated transcripts from the top videos. A 20-minute review contains 10x the signal of a single post - now the skill reads it. Inspired by [@steipete](https://x.com/steipete)'s yt-dlp + [summarize](https://github.com/steipete/summarize) toolchain.\n3. **Works in OpenAI Codex CLI.** Same skill, same engine. Install to `~/.agents/skills/last30days` and invoke with `$last30days`. Claude Code and Codex users get the same research.\n\n**New in V2:** Dramatically better search results. Smarter query construction finds posts that V1 missed entirely, and a new two-phase search automatically discovers key @handles and subreddits from initial results, then drills deeper. Free X search (no xAI key needed), `--days=N` for flexible lookback, and automatic model fallback. [Full changelog below.](#whats-new-in-v2)\n\n**The tradeoff:** V2 finds way more content but takes longer - typically 2-8 minutes depending on how niche your topic is. The old V1 was faster but regularly missed results (like returning 0 X posts on trending topics). We think the depth is worth the wait, but if you'd use a faster \"quick mode\" that trades some depth for speed, let us know: [@mvanhorn](https://x.com/mvanhorn) / [@slashlast30days](https://x.com/slashlast30days).\n\n**Best for prompt research**: discover what prompting techniques actually work for any tool (ChatGPT, Midjourney, Claude, Figma AI, etc.) by learning from real community discussions and best practices.\n\n**But also great for anything trending**: music, culture, news, product recommendations, viral trends, or any question where \"what are people saying right now?\" matters.\n\n## Installation\n\n```bash\n# Clone th"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn74qkj5344raj0tk9txa53xvh81a244\",\n  \"slug\": \"last30days-gemini\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1771322536006\n}"},{"path":"variants/open/references/briefing.md","content":"# Morning Briefing\n\nSynthesize accumulated findings into a formatted briefing.\n\n## Commands\n\n| Command | Action |\n|---|---|\n| `briefing` | Generate today's briefing |\n| `briefing --weekly` | Weekly digest with trends |\n| `briefing --since YYYY-MM-DD` | Briefing since specific date |\n\n## Generate Briefing\n\n```bash\npython3 \"${SKILL_ROOT}/scripts/briefing.py\" generate [--weekly] [--since DATE]\n```\n\nThe script returns JSON with per-topic findings, staleness info, and cost data.\n\n## Staleness Check\n\nBefore synthesizing, check each topic's freshness:\n- **Fresh** (< 12h): show normally\n- **Aging** (12-36h): note when last run was\n- **Stale** (> 36h): warn user, suggest running `watch run-one \"topic\"`\n\n## Daily Briefing Format\n\n```\nGood morning! Here's your research briefing for [DATE].\n\nTL;DR: [One sentence about the top finding across all topics]\n\n---\n\n**[Topic 1]** (N new findings)\nTop signal: [Highest engagement finding with source]\nAlso trending: [2nd finding], [3rd finding]\n\n**[Topic 2]** (N new findings)\nTop signal: [Highest engagement finding]\nAlso trending: [2nd finding]\n\n---\nCost: $X.XX / $Y.YY budget | N topics active | N findings today\n```\n\n## Weekly Digest Format\n\n```\nWeekly digest for week of [DATE]:\n\n**[Topic 1]**\nThis week: N findings (up/down X% from last week)\nTrending up: [engagement increasing]\nKey voices: @handle1, r/sub1\n\n**[Topic 2]**\nThis week: N findings\nTrending down: [engagement decreasing]\n```\n\n## Synthesis Rules\n\n- Lead with people, not publications\n- 3-5 topics max per briefing\n- 2-3 findings per topic\n- Include cost/budget footer\n- Note any failed or stale topics\n\n## No Data Handling\n\nIf no topics or no findings:\n```\nNo briefing data available.\n\nTo get started:\n1. Add a topic: /last30days watch add \"your topic\"\n2. Run research: /last30days watch run-all\n3. Generate briefing: /last30days briefing\n```"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini. Skill: last30days (Gemini Synthesis) Owner: ralph-oei Summary: Research any topic from the last 30 days. Sources: X (Twitter), YouTube transcripts, web search. Generates expert briefings and copy-paste prompts using Gemini. Tags: latest:1.0.0 Version history: v1.0.0 | 2026-02-17T10:02:16.006Z | auto - Initial release of the last30days-gemini skill. - Researches any topic from the past 30 days using X (Twitter), YouTu","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":839,"uniquenessScore":55,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:53:20.458Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}