1实现原理 · 为什么它能做到
本 skill 是『超长提示词契约 + 一个多源 Python 引擎』的组合:2394 行 SKILL.md 规定模型该怎么规划、怎么调引擎、怎么合成输出;真正的取数与聚合由 scripts/last30days.py 及其 98 个 lib 模块承担(约 6.2 万行 Python)。
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.
模型被要求充当『规划者』:命名实体类主题必须自带 --plan(JSON 查询计划,含已解析的 handle/subreddit/hashtag),引擎的内部 planner 只服务 headless/cron 路径。
**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.
引擎的调用方式被模板化:一律用 ${SKILL_DIR} 定位当前加载的 SKILL.md 所在目录下的 scripts/last30days.py,以 --emit=compact 产出可读输出,并统一 --save-dir 落盘。
SKILL_DIR="<absolute path of the directory containing the SKILL.md you just Read>"
输出不是散文而是一份契约:11 条 LAW 规定首行徽章、标题、破折号、段落结构、必须原样透传引擎页脚、禁止倾倒原始证据块、必须编织社区评论等;违反是可观测的失败(文档用 0/8 回归事故反证)。
**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.
发现/趋势类查询是『模型当裁判』的三命令协议:nominate-only → judgments → finalize(可选 angles),把话题命名与内容角度交给模型,引擎只做汇总与渲染。
"${LAST30DAYS_PYTHON}" "${SKILL_DIR}/scripts/last30days.py" --discover --nominate-only --save-dir="${LAST30DAYS_MEMORY_DIR}"
有若干绕过研究流程的离线快路径:库检索、库订阅源、话题队列三条命令直接读本地 SQLite/已存简报,明确不联网、不调模型、不做 setup。
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.
安全侧的设计是把「会读敏感东西」这件事显式前置:第一次研究前必须跑 `--preflight`,它只读配置、声明计划中的浏览器 cookie 模式与计划写入路径、列出可选命令与端点覆盖,但绝不读 cookie、不写文件、不跑研究。
**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.
密钥与浏览器 cookie 是两条独立的凭证通道,且都默认关闭:密钥来自环境变量 → 全局 .env(~/.config/last30days/.env)→ 项目 .env(需 LAST30DAYS_TRUST_PROJECT_CONFIG=1 才信任)→ macOS Keychain → 1Password;浏览器 cookie 读取默认关闭(FROM_BROWSER 未设即不读)。
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.
凭证写入也走受控通道:`setup --store-key <NAME>` 从 stdin 读一行、按 0o600 写入全局 .env,stdout 只回 NAME=**** 与一行 JSON,密钥值绝不进入 stdout/stderr。
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}``.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | python3 ≥ 3.12(引擎自身;SKILL.md 用 ${LAST30DAYS_PYTHON:-python3} 调用) |
| cli | yt-dlp(YouTube 搜索与字幕;首次 setup 会尝试安装)、digg-pp-cli(Digg)、arXiv 与 Techmeme 的 Printing Press CLI |
| cli | agentcookie(Linux 上的外部 cookie sidecar,仅当 PATH 存在该命令且未设 AGENTCOOKIE=off 时启用) |
| cli | macOS `security`(Keychain 取密钥)与 openssl(Chromium cookie 解密)、`pass`(1Password/密码库取密钥) |
| api | ScrapeCreators(TikTok/Instagram/Threads/Pinterest/LinkedIn/YouTube 评论等;frontmatter 的 primaryEnv) |
| api | LLM/搜索类可选密钥(推理与规划回退用):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 |
| network | HTML 简报托管发布(显式 --publish 才发;文档提醒页面默认公开可被索引) |
| package | 第三方 vendored 组件:scripts/lib/vendor/ 下的 X 搜索客户端(.skillignore 注明 'still installed') |
4风险提醒 风险提醒:橙色 · 评估后使用
- 凭证与浏览器 cookie 的能力面很大 — 启用后可解密 macOS Chromium 家族 cookie(取 X 的 auth_token/ct0),并从 Keychain 或 1Password 取 API 密钥。默认虽关闭,但一旦开启,等于把浏览器登录态与密码库交给该流程;共享/受管机器上应保持 FROM_BROWSER 关闭并避免把 key 写进项目 .env。
- 外部内容注入面大 — 工作方式就是抓取并合成第三方文本(社媒评论、字幕、网页),其中的诱导性文本会进入模型上下文。输出 LAW 管格式不管信任,无法从机制上防止模型被检索内容影响;对高对抗场景(舆情操纵话题)应把结果当线索而非结论。
- 会跑子进程并按需安装 CLI — setup 会尝试安装 yt-dlp、digg-pp-cli、arXiv/Techmeme 的 CLI(macOS 走 Homebrew、Windows 走 pip 路径);运行期还会调 openssl/security/pass/agentcookie/box-chrome。这些外部二进制不在本仓库内,其安全性与版本由用户环境决定。
- 发布路径会把内容交给第三方 — --publish 把 HTML 简报发到 ht-ml.app,文档明言页面默认公开、可能被爬取或索引;敏感话题或含内部数据的研究不应发布。
- 文档体量与自举依赖带来误用风险 — 2394 行契约要求模型先读再动手,但现实是模型常只读前 1000 行(文档自己记录了 4 次这类事故并把规则前移)。用户若在弱宿主/短上下文环境使用,容易触发 LAW 违规(自造标题、多出 Sources 块、倾倒原始证据),输出质量波动大。另有 STEP 0 的陈旧副本问题:Claude Code 的 marketplace 目录可能滞后一个或多个版本,需按提示改读缓存路径。
- 第三方抓取服务与平台条款 — ScrapeCreators/BrightData 等抓取 TikTok/IG/LinkedIn 等平台内容,以及浏览器 cookie 复用登录态访问 X,可能与平台服务条款冲突;使用者需自担合规判断(本 skill 不含合规声明)。
5第二遍独立确认
- [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 等仅出现在文档字符串或占位示例,未计入。
6结论
41f1dd6604aec716…ac0ed3b7f6