Home / All Skills / Content & Media Creation / last-30-days-research
Content & Media Creation · mvanhorn/last30days-skill

last-30-days-research

Research what people actually say about any topic in the last 30 days. Pulls posts and engagement from Reddit, X, YouTube, TikTok, Hacker News, Polymarket, GitHub, and the web. Includes a doctor health check to diagnose broken or missing sources.

L5 Restricted · Isolated sandbox & strict auditV2 Human-AuditedCredential / SessionExecute CommandExternal WriteNetwork AccessWrite FileDual-pass Audit
Author mvanhornGitHub mvanhorn/last30days-skill ↗Stars 62074License MIT(仓库根 LICENSE:'MIT License / Copyright (c) 2026 Matt Van Horn';SKILL.md frontmatter `license: MIT`;GitHub API spdx_id=MIT)Commit ac0ed3b7f6
Control levels describe skill capabilities and suggested control measures; they do not represent quality or safety certifications, nor do they dictate usability. Usage decisions rest entirely with users and administrators. Different agent hosts apply varying constraints; do not assume hosts provide automatic protection. Third-party skill copyrights belong to their original authors. Use at your own risk.

1How It Works & Mechanism

This skill combines an extensive prompt contract with a multi-source Python engine: 2,394 lines of SKILL.md dictate how the model plans, invokes the engine, and synthesizes output, while scripts/last30days.py and its 98 lib modules handle the actual data fetching and aggregation (~62,000 lines of Python).

skills/last30days/SKILL.md
You are inside the `/last30days` SKILL. This is a specific research tool with a 1400+ line instruction contract (the rest of this file) that defines EXACTLY how to produce the research output. It is not a generic "last 30 days of X" research prompt. Do NOT treat `/last30days` as a search keyword you can improvise against.
Measured scale: 2,394 lines in SKILL.md; 134 files in skills/last30days; 98 modules in scripts/lib; totaling ~62,681 lines of Python under scripts (via wc -l). This operates at an entirely different scale compared to a "pure prompt skill"—its functional depth lives in the code, while its operational discipline lives in the documentation.

The model is enforced to act as a "planner": named-entity topics require a model-generated --plan (a JSON query plan containing resolved handles/subreddits/hashtags), reserving the engine's internal planner strictly for headless/cron workflows.

skills/last30days/SKILL.md
**LAW 7 - YOU ARE THE PLANNER. `--plan` IS MANDATORY ON NAMED-ENTITY TOPICS.** If you are the reasoning model hosting this skill (Claude Code, Codex, Hermes, Gemini, or any agent runtime that invoked `/last30days`), YOU generate the JSON query plan. You do not need an API key, "LLM provider" credentials, or an external planning service - you ARE the LLM.
This rule emerged from an actual incident: SKILL.md documents an occurrence on 2026-04-19 where the model invoked the engine bare and misinterpreted the stderr message ('No --plan and no LLM provider configured. Using deterministic fallback…') as "I have no API key so I cannot run this," when in reality it simply omitted the planning step. Consequently, the document added an explicit counter-statement: 'YOU ARE THE PROVIDER'.

Engine invocations are strictly templated: always locate scripts/last30days.py via ${SKILL_DIR} relative to the currently loaded SKILL.md, produce readable output using --emit=compact, and persist reports under a unified --save-dir.

skills/last30days/SKILL.md
SKILL_DIR="<absolute path of the directory containing the SKILL.md you just Read>"
The design rationale for SKILL_DIR substitution is explicitly documented: 'The SKILL_DIR substitution in the engine Bash calls uses the directory of the SKILL.md the model just Read — no resolver list, no precedence walk.' This eliminates ambiguity across multiple installation copies (marketplace cache / ~/.codex / npx installations) using the file just read. Additionally, STEP 0 specifically addresses a known stale copy bug where Claude Code marketplace directories lag behind by one or more versions.

Output is treated as a rigid contract rather than prose: 11 LAW rules govern the first-line badge, titles, dash usage, paragraph structure, verbatim passthrough of engine footers, prohibition of dumping raw evidence blocks, and weaving community quotes; violations constitute measurable failures (exemplified by 0/8 regression logs).

skills/last30days/SKILL.md
**BADGE (MANDATORY, FIRST LINE OF OUTPUT):** The Python engine now emits the badge as the first line of its `--emit=compact` stdout. Your correct behavior is to PASS THROUGH the script's output verbatim.
Examples from the LAW list: LAW 1 forbids 'Sources:' blocks (explicitly superseding the WebSearch tool contract), LAW 3 forbids em/en dashes, LAW 4 forbids ## subsection headers (except in COMPARISON queries), LAW 5 requires passing the engine footer through verbatim, LAW 6 forbids outputting raw clusters inside <!-- EVIDENCE FOR SYNTHESIS -->, LAW 9 requires quoting at least two attributed community comments verbatim, and LAW 11 mandates the 3-command protocol for discovery runs. Documented dates and phenomena provide verifiable engineering incident records.

Discovery and trending queries follow a 3-command "model-as-judge" protocol: nominate-only → judgments → finalize (with optional angles), delegating topic naming and editorial angles to the model while the engine handles aggregation and rendering.

skills/last30days/SKILL.md
"${LAST30DAYS_PYTHON}" "${SKILL_DIR}/scripts/last30days.py" --discover --nominate-only --save-dir="${LAST30DAYS_MEMORY_DIR}"
The three steps correspond to: --discover --nominate-only, --discover --judgments "$JUDGMENTS_FILE", and --discover --finalize --angles "$ANGLES_FILE" --emit=compact; it also specifies falling back to a one-shot --discover if two legs fail (explicitly stating: 'never leave the user with no output').

Several offline fast-paths bypass the live research pipeline: library search, library feed, and topic queue commands read directly from local SQLite / saved briefs without network access, model calls, or setup steps.

skills/last30days/SKILL.md
This is deterministic offline FTS over the existing saved-brief scanner plus per-run SQLite store sightings; it does not call a model or the network.
The three fast-paths are library search (FTS search over historical research), library feed (generates and publishes local index.html + feed.xml), and queue list|cover (topic queue management). The persistence directory defaults to $HOME/Documents/Last30Days (overridable via LAST30DAYS_MEMORY_DIR), with briefs stored separately under ~/.local/share/last30days/briefs.

The security design explicitly front-loads access to sensitive resources: a mandatory `--preflight` check runs before the first research task, reading configuration, declaring planned browser cookie modes and target write paths, and listing available commands and endpoint overrides—without reading cookies, writing files, or executing research.

skills/last30days/SKILL.md
**2. Permission preflight.** Run `"${LAST30DAYS_PYTHON:-python3}" "${SKILL_DIR}/scripts/last30days.py" --preflight` using the directory of the `SKILL.md` you loaded, then summarize the human-readable result before setup: config source, project config trust/ignore state, planned browser-cookie mode, planned writes, optional commands, and active/ignored endpoint overrides. This is safe: it does not read browser-cookie values, does not write setup/config/report files, and does not run research.
This is backed in code by permission_preflight.build() (docstring: 'Build a stable, secret-free permission preflight object.') and distinguishes between safe=True (enforcing zero network access for doctor/--diagnose/--preflight) and standard execution paths.

API keys and browser cookies are handled via separate credential channels and remain disabled by default: keys resolve through env vars → global .env (~/.config/last30days/.env) → project .env (only if LAST30DAYS_TRUST_PROJECT_CONFIG=1) → macOS Keychain → 1Password; reading browser cookies is off by default (inactive unless FROM_BROWSER is set).

skills/last30days/scripts/lib/env.py
Default (FROM_BROWSER unset): no browser-cookie reads. The Chromium family (Chrome, Brave, Edge, Vivaldi, Opera, Arc, Chromium) is available only when explicitly selected because reading their cookies on macOS requires the browser's Safe Storage Keychain key, which triggers a system password prompt that cannot be reliably suppressed.
The core rationale: reading Chromium cookies requires browser Safe Storage Keychain keys, which trigger non-suppressible system password prompts; thus, it requires explicit opt-in (FROM_BROWSER=auto indicates consent to Keychain prompts). The setup_wizard field specification similarly mandates: 'browser_cookie_scan_attempted: bool (True only after explicit consent)'.

Credential writes follow a restricted flow: `setup --store-key <NAME>` reads a single line from stdin and writes to the global .env with 0o600 permissions, echoing back only NAME=**** and a single JSON line to stdout, ensuring secret values never leak into stdout/stderr.

skills/last30days/scripts/last30days.py
Reads exactly one line from stdin (bounded to ``STORE_KEY_MAX_BYTES``), strips whitespace, and writes it to the global ``.env`` as a 0o600 secret through ``setup_wizard.write_api_key``. An existing line for the same name is replaced, so a rejected credential can be rotated by running the command again. The value never reaches stdout or stderr: stdout carries ``NAME=****`` plus a JSON line ``{"persisted": bool, "key": NAME}``.
Accepts only names included in the env.KEYCHAIN_KEYS whitelist (exiting with code 2 otherwise); code comments note that on official-only hosts (LAST30DAYS_HOST=grok-bot), error prompts must not reveal legacy credential keys—demonstrating granular disclosure controls across host environments.

2Core Capabilities

01Last-30-day sentiment and discussion retrieval across ~30 sources: Reddit (including comments), X, YouTube (including transcripts), TikTok, Instagram, Threads, LinkedIn, Hacker News, Polymarket, Digg, Bluesky, TruthSocial, Xiaohongshu, GitHub, StockTwits, Trustpilot, Amazon, arXiv, Techmeme, DripStack, web search, and more
02Multi-backend automated chain selection with fallback prediction (collect-then-pick: probes all candidates before selecting an active one, preventing unauthenticated primary backends from masking usable fallbacks)
03Evidence clustering and synthesis ranked by upvotes/likes/trading volume (engine generates ranked clusters; model drafts bold-lead-in prose and quotes community comments verbatim)
04Discovery/Trending mode: model nominates topics, filters out spam, evaluates content value, drafts podcast/X article angles, and finalizes into a topic-per-section brief
05Local research library (FTS over historical briefs / index.html + feed.xml generation / topic queue list & cover), fully offline with zero token/quota consumption
06Doctor health check and remediation prescriptions (four-state per-source audit: WORKING / TURNED ON - UNVERIFIED / NOT WORKING / COULD BE ON, plus CLI-health and postmortem diagnostics)
07Visual delivery: shareable HTML briefs (with XSS-hardened rendering) and optional publishing to ht-ml.app (explicit opt-in, public by default)
08Structured exports: --emit=json (agent flat contract or raw internal dump) for consumption by downstream scripts and pipelines
09Output discipline contract (11 LAW rules + first-line badge + self-check checklist) converting unstructured generation into an auditable output format

3External Dependencies

KindDependency / Endpoint
clipython3 ≥ 3.12(引擎自身;SKILL.md 用 ${LAST30DAYS_PYTHON:-python3} 调用)
cliyt-dlp(YouTube 搜索与字幕;首次 setup 会尝试安装)、digg-pp-cli(Digg)、arXiv 与 Techmeme 的 Printing Press CLI
cliagentcookie(Linux 上的外部 cookie sidecar,仅当 PATH 存在该命令且未设 AGENTCOOKIE=off 时启用)
climacOS `security`(Keychain 取密钥)与 openssl(Chromium cookie 解密)、`pass`(1Password/密码库取密钥)
apiScrapeCreators(TikTok/Instagram/Threads/Pinterest/LinkedIn/YouTube 评论等;frontmatter 的 primaryEnv)
apiLLM/搜索类可选密钥(推理与规划回退用):OpenAI、xAI、Google/Gemini、OpenRouter、Perplexity、Brave、Exa、Serper、Parallel、Apify、GitHub token、X API bearer、XQUIK、BrightData
network免密钥公开端点(默认路径即可用):Reddit 公开 JSON/RSS、HN Algolia、Polymarket Gamma API、GitHub API、Arctic Shift、Bluesky、StockTwits、TruthSocial、Digg、r.jina.ai
networkHTML 简报托管发布(显式 --publish 才发;文档提醒页面默认公开可被索引)
package第三方 vendored 组件:scripts/lib/vendor/ 下的 X 搜索客户端(.skillignore 注明 'still installed')

4Recommended Governance & Evidence

Suggested Controls for Safe Operation
For Agent Runtime
Isolated environment, per-use explicit authorization
For Administrators
Strict authorization, full audit, compliance signoff
Evidence & Triggers (File Paths & Excerpts)
  • 本地凭据 / 浏览器配置: Accessing user login cookies/sessions/keychains: Process environment variables and ~/.config/last30days/.env (overridable via LAST30DAYS_CONFIG_DIR, empty string activates no-config mode): YES
  • scripts/: Executing local scripts or system commands: python3 scripts/last30days.py <subcommand> (invoked on every run; includes --preflight / --welcome / setup)
  • 外部 API: Posting content, creating resources, or mutating data on external platforms: None
  • 本地工作目录: File read/write and artifact emission: Persisting research artifacts: Markdown reports and {slug}-raw.md under --save-dir (defaults to $HOME/Documents/Last30Days)
Audit Notes: Risk Level: Orange. Highly capable but interacts with sensitive resources; review each item before execution. Rationale: This is not just a prompt, but a Python codebase of over 60,000 lines that spawns child processes on your machine (yt-dlp / digg / openssl / security / pass / agentcookie / box-chrome), reads and writes to your home directory (~/Documents/Last30Days, ~/.local/share/last30days, and ~/.config/last30days/.env storing credentials with 0o600 permissions), and can optionally decrypt browser login cookies (Chromium family, extracting X auth_token + ct0) or fetch credentials from macOS Keychain and 1Password; it also dispatches requests to ~30 external services (including paid third-party scrapers) and can publish HTML briefs to third-party hosting (public by default). It is rated Orange rather than Yellow because credential decryption, multi-source external traffic, and home directory writes coexist, combined with Python 3.12+ execution and automated CLI tool installation workflows. It avoids Red because sensitive features remain off by default (browser cookies are not read, publishing requires --publish, project configs are untrusted), supported by a standalone --preflight permission contract and doctor audits, with cookie values kept out of logs. Recommendation: Run --preflight first to inspect planned write paths and cookie modes; leave FROM_BROWSER disabled if not querying X; store keys in ~/.config/last30days/.env (0600) or Keychain, and never commit secrets to repositories.

5Second-Pass Verification

  • [ok] skill 路径(任务书标『待定位』) — 实际相对路径 skills/last30days(仓库 skills/ 下仅此一个子目录)。frontmatter name 为 'last30days',与任务书展示名 'Last 30 Days Research'/slug 'last-30-days-research' 不同名——本报告 skill.name 保留 frontmatter 真值 'last30days',文件名按任务书 slug 输出。
  • [ok] 『1400+ 行指令契约』的量级声明 — SKILL.md 实测 2394 行(含契约与实现细节),『1400+』是保守表述,未夸大;OUTPUT CONTRACT 段落确实前置在文件开头附近(v3.0.8 起从第 ~1094 行前移),与文档自述一致。
  • [ok] 『模型是规划者(--plan)』是否被代码支持 — SKILL.md 规定命名实体主题必须带 --plan;引擎侧确实消费 --plan(文档另说明缺省时用内部 planner 或确定性回退,仅 headless/cron 路径)。文档同时记录了把引擎 stderr 的 'provider' 一词误读为『需要凭证』的真实事故,属可复核的工程记录。
  • [discrepancy] 浏览器 cookie 读取的默认状态(第一遍若笼统写『会读浏览器 cookie』则夸大) — 第二遍核对 env.py:'Default (FROM_BROWSER unset): no browser-cookie reads.',FROM_BROWSER=off 亦返回空;Linux 侧 agentcookie 还需 PATH 存在该二进制且未设 AGENTCOOKIE=off,MacBook 之外的 box-chrome CDP 路径需人工登录。结论修正为『能力存在、默认关闭、需显式同意』,已在 security 与 capabilities 中如实表述(不作默认行为)。
  • [ok] 密钥来源分层与项目配置信任策略 — env.py 明确 CONFIG_FILE = Path.home()/'.config'/'last30days'/'.env'(可用 LAST30DAYS_CONFIG_DIR 覆盖),项目 .env 需 LAST30DAYS_TRUST_PROJECT_CONFIG;Keychain 仅 Darwin + security 在 PATH,LAST30DAYS_SKIP_KEYCHAIN 可关;另有 pass(1) 通道与 LAST30DAYS_KEYCHAIN_ALIASES 别名支持。
  • [ok] 权限预检的『安全』承诺是否属实 — permission_preflight.build() docstring 为 'Build a stable, secret-free permission preflight object.';pipeline.py 中 browser_cookies 的 reads_values 在 safe 模式下恒为 False;代码注释要求 safe=True(doctor/--diagnose/--preflight)保持无网络。与 SKILL.md 的『does not read browser-cookie values, does not write … and does not run research』一致。
  • [ok] 发布到第三方托管是默认还是 opt-in — last30days.py 的 --publish 帮助文本写明 'Publish --emit=html output to ht-ml.app (explicit opt-in; public by default)';SKILL.md 在 library feed 段要求先向用户解释页面公开可被索引再执行。非默认行为。
  • [discrepancy] 外部依赖数量(避免把文档链接当成调用点) — 第一遍若按 https:// 出现频次直接列依赖会把文档链接(如 github.com、nodejs.org、ffmpeg.org、example.com)算进去。第二遍逐条回落到代码调用点:api.scrapecreators.com / api.github.com / hn.algolia.com / gamma-api.polymarket.com / arctic-shift.photon-reddit.com / api.x.ai / api.openai.com / generativelanguage.googleapis.com / openrouter.ai / api.perplexity.ai / api.stocktwits.com / bsky.social / truthsocial.com / di.gg / r.jina.ai / api.ht-ml.app 为真实请求端点;github.com、nodejs.org、ffmpeg.org、example.com 等仅出现在文档字符串或占位示例,未计入。

6Verdict & Scenarios

  • Fetches real data across multiple platforms and sorts by engagement instead of relying on hallucinated trends: zero-key sources work out of the box, paid sources plug in as needed, and backend chains degrade gracefully.
  • Reproducible and verifiable output: 11 LAW rules, a mandatory first-line badge, verbatim engine footer passthrough, and required direct quotes from two community comments maintain consistent reporting style and an intact chain of evidence.
  • Exceptionally disciplined permission design: isolated --preflight contract (no cookie reads, no file writes, no research runs), untrusted project configs by default, disabled cookie access by default, and explicit opt-in for publishing via --publish.
  • Diagnostic and self-healing: doctor provides a four-state audit and clear remediation steps for each source (missing key, missing CLI binary in PATH, expired cookie) rather than leaving users guessing why a source yielded no data.
  • Zero pip dependencies with local persistence: implemented entirely with the Python standard library, featuring three offline fast-paths (library search, feed generation, topic queue) to reuse historical research without wasting API credits.
  • Best for: Ideal for content creators, investment/market researchers, podcast and newsletter writers, and product/growth leads needing to understand what communities are saying about any topic over the last 30 days. Typical usage: `/last30days nvidia earnings reaction`, `/last30days AI video tools`, or `/last30days trending` for topic discovery; can also serve as an automated step in agent workflows (passing --emit=json to downstream scripts). Install via Claude Code marketplace or `npx skills add mvanhorn/last30days-skill -g`. Requires Python 3.12+ with zero pip dependencies.
    Not for: Not suitable for research requiring rigorous academic fact-checking, authoritative primary sources, or citable peer-reviewed literature (it is a community sentiment aggregator, explicitly focused on "what people actually say"); not suitable for restricted environments that disallow local script execution, child process spawning, or home directory writes; not suitable for users unwilling to provide X sessions or API keys to local tooling (can run zero-key sources, but X/YouTube functionality will be constrained); not suitable for those expecting zero configuration across all sources out of the box—TikTok/IG/LinkedIn/YouTube comments require ScrapeCreators, YouTube requires yt-dlp, and select sources require dedicated keys or opt-in flags.
    Install Agent-Ready
    ① Verified Mirror 2026-09-15
    Option A · Direct DownloadDownload last-30-days-research.tar.gz
    sha256: 41f1dd6604aec716…
    Option B · Copy Guide for Agent
    install.json
    Agents automatically download and verify mirrors from this JSON guide.
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit ac0ed3b7f6.