mcpField
L
last30flames

last30flames

github.com/firecrawl生产力4235 次安装16 周前更新
代码仓库

关于 last30flames

用于近期网络主题研究的技能,会收集带来源的研究上下文,再由运行它的模型撰写简报。它并行查询网页、Hacker News、Lobste.rs、Bluesky 和 GitHub,并支持主题消歧、对比研究及保存上下文。

主要功能

  1. 01并行收集五类来源
  2. 02网页内容抓取为完整 Markdown
  3. 03按公开 API 获取互动数据
  4. 04歧义主题解析与查询细化
  5. 05自动拆分对比主题
  6. 06保存并复用研究上下文

适用场景

  1. 01撰写带引用的近期主题简报
  2. 02比较两个或多个产品近期动态
  3. 03追踪项目的 GitHub 活动及社区反响
  4. 04保存研究上下文供后续会话使用

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/firecrawl/last30flames --skill last30flames

安装后在 Claude Code 中输入/last30flames确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.env.example
bun.lock
package.json
tsconfig.json
scripts/
bluesky.ts
config.ts
derive-sides.test.ts
derive-sides.ts
firecrawl.ts
format.test.ts
format.ts
github.ts
hackernews.ts
htmlify.ts
index.ts
lobsters.ts
resolve.ts
run.sh
types.ts
url.ts

详细介绍

last30flames

围绕一个主题研究近期网络内容,并撰写一份简短、有来源依据的简报。

此技能由一个轻量引擎和你的综合分析组成。引擎会收集来源并输出一份整洁、带编号的研究上下文;你(运行此技能的模型)阅读该上下文并撰写简报。

**无需密钥。**引擎不会调用大模型(由你进行综合分析),并通过 Firecrawl CLI 访问 Firecrawl;未设置密钥时,CLI 会使用无需密钥的免费层。如果环境中已设置 FIRECRAWL_API_KEY,CLI 会自动使用它,以获得更高的限额和并发能力——因此,密钥只是速度升级选项,而非必需条件。用户无需重新安装,先在无密钥状态下启动,之后再设置 FIRECRAWL_API_KEY(或运行 firecrawl login),下一次运行时即可完成身份验证。

工作原理

五个来源并行运行:

  • Firecrawl Search——将网页搜索结果抓取为完整页面 Markdown,而非摘要片段。
  • Hacker News(公共 Algolia API)——积分数 + 评论数。
  • Lobste.rs(公共 JSON Feed)——积分数 + 评论数。
  • Bluesky(公共 AT Protocol API)——点赞数 + 转发数 + 回复数。
  • GitHub(官方 API)——星标数 + 最近的推送活动。

互动数据仅来自公开提供这些数据的 API。此技能绝不会访问 Reddit、X、TikTok、Instagram,或任何需要登录或 Cookie 的内容。

运行引擎

任何支持技能的 Agent 框架都可以运行此引擎。你已经知道 SKILL.md 的绝对路径,因为你刚刚读过它;接下来调用它旁边的 scripts/run.sh。该脚本会自动定位自身,首次运行时安装依赖,并接受主题以及可选的 --days N 时间范围(任意数字,例如 7、30、365;默认值为 30):

bash <SKILL_DIR>/scripts/run.sh "<TOPIC>" --days 30

将 <SKILL_DIR> 替换为此文件所在的目录。不要依赖 $CLAUDE_PLUGIN_ROOT 或当前工作目录——启动器会处理这两者。唯一的要求是有 bun 二进制文件;无需 API 密钥(仅在需要提高 Firecrawl 限额时设置 FIRECRAWL_API_KEY)。

进度会输出到 stderr;带编号的研究上下文会输出到 stdout。请阅读 stdout——它就是你的证据。

先消除有歧义主题的歧义(建议)

如果主题可能指向多个对象——某个人的姓名、与常见事物同名的产品(“Apple”“Cursor”)、单独的用户名——请先运行一次成本较低的解析流程,再进行主要收集:

bash <SKILL_DIR>/scripts/run.sh --resolve "<TOPIC>"

该流程会输出候选身份(网页标题 + 描述、GitHub 仓库和用户候选项),不会抓取任何页面。阅读候选项并决定:

  • 2-4 条经过细化的子查询,用于明确目标对象(例如,对于 AI 编辑器“Cursor”,可使用 "Cursor AI editor"、"Cursor IDE agent")。 每条子查询都会增加 Firecrawl 搜索和抓取的工作量,因此运行时间会随查询数量增加——请使用能明确目标对象的最少数量,通常是 2 条。
  • 如果主题是个人或项目,则确定匹配的 GitHub 登录名和/或 所有者/名称仓库。

然后使用这些信息运行主要收集流程,并为每条子查询传入一次 --query:

bash <SKILL_DIR>/scripts/run.sh "<TOPIC>" --days 30 \
  --query "<subquery 1>" --query "<subquery 2>" \
  --github-user <login> --github-repo <owner/name>

引擎会针对每条子查询搜索网络、Hacker News、Lobste.rs 和 Bluesky(最多 4 条,并去重重叠结果),同时将 GitHub 搜索范围限定为指定的登录名/仓库。所有标志都是可选的——主题清晰具体时,可以完全跳过解析,像以前一样直接运行一次即可。解析流程本身不会做任何决定;决定由你来做。

对比主题(“X vs Y”)

当主题是对比两到三项内容(“cursor vs zed”、“bun versus deno”)时,引擎会在一次运行中为每一方完整收集信息,并按各方对研究上下文进行分组,同时连续编号引文。

主题中无论大小写只要包含“vs”或“versus”,就会自动拆分,因此简单写法即可生效。唯一例外是全大写的“VS”,这样“best VS Code extensions”之类的主题会保留为单方;若要比较名称中包含“VS”的内容,请使用 --compare:

bash <SKILL_DIR>/scripts/run.sh "cursor vs zed" --days 30

网页抓取预算(--limit)由各方共享,因此与单独运行相比,对比中每一方抓取的页面都会更少;如果希望每一方都达到完整的深度,请传入更高的 --limit(例如,两方对比时使用 --limit 10)。

若要让各方的结果更精准,请每一方传入一次 --compare;其后任何 --query、--github-user 或 --github-repo 标志都会归入对应的 --compare 范围(如果名称存在歧义,请先对每一方分别运行 --resolve):

bash <SKILL_DIR>/scripts/run.sh "cursor vs zed" \
  --compare "Cursor" --query "Cursor AI editor" --github-repo getcursor/cursor \
  --compare "Zed" --query "Zed editor" --github-repo zed-industries/zed

根据分组后的上下文综合撰写逐项对比简报:说明各方在这段时间内的变化,然后直接比较(通过互动数据衡量热度、值得注意的发布活动、最适用的场景)。 像往常一样在文中引用双方;编号在各方之间连续,因此不会冲突。

保存并复用上下文(可选)

默认不写入任何文件,只综合撰写简报。只有用户提出要求时才保存(例如“保存上下文”、“我之后还会用到”)。

保存的上下文位于 ~/.last30flames/ 下,按话题文件夹分组,以便将一系列相关调用作为一个整体重新加载。话题文件夹只是一个带名称的子目录;每次调用都会保存到各自的文件中,这样每次调用的 [1]、[2] 引文编号都能保持完整(绝不要将两个上下文合并到一个文件中,否则编号会冲突):

~/.last30flames/<thread>/
  <slug>-<YYYY-MM-DD>.md      # one file per engine call

**保存时:**重定向引擎的 stdout,以保留原始的编号研究上下文(也就是可复用的证据,而不是简报)。先确定话题文件夹:

  • 如果用户指定了话题(“把它保存到我的 ai-agents research”),将其转换为 slug,记为 <thread>。
  • 否则,复用本次对话中之前保存时使用的话题,让相关调用归入同一文件夹。
  • 如果上述情况都不适用,则根据主题生成 <thread>,并告知用户你选择的名称,以便之后引用。

通过将主题转换为 slug 来生成 <slug>(转为小写、用连字符替换空格、删除标点),让文件名能说明这次调用的主题。然后创建文件夹并写入文件,最后报告确切路径:

mkdir -p ~/.last30flames/<thread>
bash <SKILL_DIR>/scripts/run.sh "<TOPIC>" --days 30 > ~/.last30flames/<thread>/<slug>-<YYYY-MM-DD>.md

由于重定向会将研究上下文写入文件而非 stdout,Bash 输出中只会显示 stderr 进度信息。如果用户还想在本次会话中获取简报,请先 Read 已保存的文件以获取上下文,然后照常综合撰写。

如果用户明确指定了其他路径,请按其要求操作。

复用时(后续会话):用户无需记住确切名称。如果他们以较宽泛的方式提及已保存的研究(“加载我的 ai-agents research”),请列出 ~/.last30flames/ 下的话题文件夹,并按话题名称匹配;然后 Read 该文件夹中的每个 .md 文件,并综合其中所有内容,同时将引文按来源文件区分命名空间,避免不同调用的编号冲突。 如果要重新加载单次调用而非整个话题,请根据 <slug>-<date> 名称匹配单个文件。如果没有匹配项,请询问用户保存位置。

由于每个文件名的格式为 <slug>-<YYYY-MM-DD>.md,仅凭文件名就能确定主题和保存日期,无需外部记忆。在综合之前,请根据 --days 窗口检查每个文件的日期:如果当前日期距保存日期已超过指定天数,则时效性已无法保证;请提醒用户上下文已过时,并提供重新获取最新信息的选项。

按复用方式处理的提示(不要重新运行引擎):

last30flames load my ai-agents research
last30flames using my saved ai-agents research, what did I find on local inference?

撰写简报

根据编号来源,撰写几段简洁的文字,要求:

  • 开篇说明这段时间真正的新进展或正在发生的变化,而不是背景信息。
  • 每项说法都要有来源依据,并以内联引用标注,例如 [1]、[3]。
  • 使用互动数据(HN 点数/评论数、GitHub 星标)作为判断人们实际关注点的信号,并优先考虑互动量高的内容。
  • 如实说明证据不足之处,不要编造细节。如果 HN 或 GitHub 返回的信息很少,也要坦诚说明。

简报末尾附上一份精简的 来源 列表,让每条内联引用都可点击。每个实际引用的来源单独占一行,并使用内联引用中的相同编号,格式为 Markdown 链接:

Sources:
[1] [Title of the page](https://example.com/article) - example.com
[3] [Show HN: Something](https://news.ycombinator.com/item?id=123) - news.ycombinator.com

只列出引用过的来源——这是给读者查阅的参考列表,不是研究背景材料的完整罗列。切勿将原始研究背景材料粘贴回来。

可分享的 HTML 简报(可选)

当用户要求提供可分享版本的简报(例如“让这份内容方便分享”“给我一个 HTML 文件”“提供一份可以放进 Slack/邮件/Notion 的版本”)时,除了正常的聊天回复,还要生成一份自包含的深色模式 HTML 文件。该文件使用内联 CSS,不含 JavaScript 或外部资源,可离线使用,并且在任何地方的渲染效果都相同。

首先,将你撰写的简报(包括编号相同的 Sources: 列表)以 Markdown 格式写入线程文件夹,按照上文保存流程中的要求准确选择 <thread> 和 <slug>:

mkdir -p ~/.last30flames/<thread>
# Write the brief markdown to ~/.last30flames/<thread>/<slug>-<YYYY-MM-DD>-brief.md
bun <SKILL_DIR>/scripts/htmlify.ts ~/.last30flames/<thread>/<slug>-<YYYY-MM-DD>-brief.md

转换器会将标题、段落、列表、链接和内联 [N] 引用转换为 HTML——每条引用都会变成指向来源列表中相应条目的可点击跳转链接;转换器会在 Markdown 文件旁写入 <slug>-<YYYY-MM-DD>-brief.html,并打印输出路径。

将该路径告知用户。 如果用户指定了其他输出位置,请通过 -o <path> 传入。

转换的是你撰写的简报,不是原始研究背景材料——切勿将引擎的标准输出转换为 HTML。

评论

支持 Markdown