test-driven-development
OBobra/superpowers298k2,631 new stars in the last 7 days
从单篇文章 URL 或文章索引页/归档页中抓取正文并保存到本地 Markdown。用户提到“收藏文章”“保存网页”“批量抓取页面里的文章”“把这个 archive 页前 N 篇拉下来”“保存到 Obsidian / Clippings / 本地”时必须优先使用。尤其适合公开网页、Substack、博客文章页、文章归档页。遇到懒加载列表、动态页面、静态抓取不全时,先用 browser 收集文章 URL,再调用脚本批量落地,以成功率优先。
目标:把「网页文章收藏」做成稳定工作流,而不是一次性手工操作。
本 Skill 是文章进入本地知识系统的入口。它不把网页直接冒充成已经整理好的知识,而是先保存为带来源信息的 source_candidate,供后续人工筛选、知识编译或写作流程继续处理。
默认分工:
新增或抓取的文章默认不是“已整理知识”,而是“待判断资料”。状态字段使用:
unprocessed -> queued -> source_carded -> compiled -> used
ignored / needs_human
保存的 Markdown 应尽量包含以下字段,方便 Obsidian、检测脚本和后续 Agent 读取:
---
type: source_candidate
title: "..."
summary: "..."
source: "https://..."
resource: "https://..."
source_kind: web_article
platform: web
author: "..."
published: "YYYY-MM-DD"
clipped: "ISO时间"
clipper: agent_web_clipper
okf_version: local-okf-v0.2
compile_status: queued
status: unprocessed
training_relevance: medium
topics:
- Agent
candidate_outputs:
- source_card
- writing_fuel
reuse_note: ""
tags:
- clipping
---
字段含义:
type: source_candidate:表示这是候选来源,不是正式 Wiki 页。source_kind:来源类型,例如 wechat_article、x_status、web_article。training_relevance:内容复用相关度。Agent 抓取默认 medium,可用 --training-relevance high|medium|low|unknown 覆盖。topics:OKF 主题标签。脚本会从标题、URL、描述和 tags 粗推,也可用 --topic Agent --topic AI培训 显式指定。candidate_outputs:后续可能拆成的知识资产类型。脚本默认 source_card + writing_fuel,可用 --candidate-output method 等重复追加。compile_status:后续自动检测和编译流程读取的主状态字段。Agent 抓取默认 queued,表示进入候选队列但不自动写正式 Wiki。它覆盖两类任务:
单篇收藏
批量收藏
按下面顺序走,不要反过来:
这个 skill 在分享 zip 给别人后,统一走 wrapper,不要直接打主脚本。
首次运行时,先执行:
bash <web-clipper-root>/scripts/run_web_clipper.sh --help
注意:这条命令有副作用。
它会先运行 bootstrap,可能创建默认 clipping 目录和当前项目下的 .web-clipper/EXTEND.md。
wrapper 会先调用 scripts/bootstrap.sh,自动做这些事:
.web-clipper/EXTEND.md默认把“当前命令所在目录”当成目标项目根目录。
所以要从目标 vault 根目录执行 wrapper,不要在子目录里随手运行。
如果自动安装失败,要明确告诉用户:
如果用户没给保存目录,优先顺序如下:
.web-clipper/EXTEND.md 里的 default_output_dir00_收件箱/Clippings/Clippings/适用:
做法:
scripts/run_web_clipper.sh脚本内部会自动按站点和失败情况选择 extractor:
[email protected],这是当前最短成功路径<article> / <main>defuddledefuddle 失败后 fallback 到 Jina Reader (r.jina.ai)defuddle 失败,再走 Metaso Reader API;Jina 常会拿到微信“环境异常”页,不作为公众号优先路径输出 frontmatter 会包含 extractor 字段,方便排查是哪一路成功。
适用:
<article> / <main> 中defuddle 没拿到正文,但 Jina Reader 能清洗出 Markdown做法:
https://r.jina.ai/<原始URL>适用:
article body not found做法:
METASO_API_KEY如果没有配置 METASO_API_KEY,这层会被跳过,继续走路径 B/C。
适用:
做法:
browser 打开索引页scripts/run_web_clipper.sh --url-file ... 批量落地这个模式很重要:浏览器负责拿链接,脚本负责落地正文。
适用:
web_fetch 被拦做法:
browser 进入文章页write 落地文件只有在 A、B 都不稳时再用 C,因为 C 更重,但成功率高。
适用:
如果当前环境提供 web-access 或等价的浏览器控制 Skill,先完整读取并遵守它,再使用 CDP Proxy。依赖检查、风险提示和 tab 清理都属于执行合同,不能跳过。
执行顺序:
web-access 的依赖检查,确认 Chrome remote debugging 和 Proxy 可用。/eval 读取标题、作者、发布日期、摘要和正文容器。微信公众号优先检查 #js_content,同时检查页面标题和正文长度,排除验证页、环境异常页和空壳页面。extractor: browser_cdp,方便追溯兜底路径。CDP Proxy 是 Browser 运行时故障后的替代执行面,不改变本 Skill 的输出:最终仍是一份结构完整、可进入 OKF / Wiki 流程的本地 Markdown。
如果用户没说明,优先补齐这 4 件事:
默认值:
00_收件箱/Clippings/WEB_CLIPPER_ROOT="<web-clipper-root>"
bash "$WEB_CLIPPER_ROOT/scripts/run_web_clipper.sh" \
--url "<文章URL>" \
--mode single \
--output-dir "<输出目录>" \
--training-relevance medium \
--candidate-output source_card \
--candidate-output writing_fuel
WEB_CLIPPER_ROOT="<web-clipper-root>"
bash "$WEB_CLIPPER_ROOT/scripts/run_web_clipper.sh" \
--url "<索引页URL>" \
--mode batch \
--count 20 \
--output-dir "<输出目录>"
WEB_CLIPPER_ROOT="<web-clipper-root>"
bash "$WEB_CLIPPER_ROOT/scripts/run_web_clipper.sh" \
--url-file /tmp/article_urls.txt \
--mode batch \
--count 20 \
--output-dir "<输出目录>"
如果用户没有显式传 --output-dir,wrapper 会优先读取 .web-clipper/EXTEND.md 的默认目录;如果没有配置,再自动回退到 00_收件箱/Clippings/ 或 Clippings/。
当静态页面拿不全链接时,用 browser.act(kind="evaluate") 执行类似逻辑:
async () => {
const collect = () => [
...new Set(
Array.from(document.querySelectorAll('a[href*="/p/"]'))
.map((a) => a.href)
.filter((h) => !h.includes("/comments")),
),
];
let urls = collect();
for (let i = 0; i < 8 && urls.length < 20; i++) {
window.scrollTo(0, document.body.scrollHeight);
await new Promise((r) => setTimeout(r, 1500));
urls = collect();
}
return urls;
};
然后把结果写到 /tmp/article_urls.txt,每行一个 URL。
每篇文章输出一个 Markdown 文件,推荐结构:
---
type: source_candidate
title: "..."
author: "..."
source: "..."
resource: "..."
archive: "..."
source_kind: web_article
platform: web
published: "YYYY-MM-DD"
clipped: "ISO时间"
clipper: agent_web_clipper
okf_version: local-okf-v0.2
compile_status: queued
status: unprocessed
training_relevance: medium
topics:
- Agent
candidate_outputs:
- source_card
- writing_fuel
reuse_note: ""
tags:
- clipping
---
# 标题
> 摘要
正文...
默认格式:
YYYY-MM-DD 标题.md
如果日期缺失,就用:
unknown-date 标题.md
如果批量任务失败,不要一句“失败了”就结束。按这个顺序排查:
body_html要明确告诉用户卡在哪一层:
已验证:
body_html 提取正文这类站点优先用脚本批量处理;当 archive 页是懒加载时,用浏览器补 URL 收集。
已验证:
defuddle 对可公开访问的公众号文章可直接抓到正文、标题和作者,是当前优先路径defuddle 失败后的兜底,返回完整 Markdown + 图片链接METASO_API_KEY 环境变量完成后,用简短结果回执,不要啰嗦:
已保存到: <目录或文件路径>
类型: clipping / Markdown
理由: 已按要求完成单篇或批量文章收藏
如果是批量任务,再补一行:
这些情况不要硬用本 skill:
defuddle 通过 npx 运行固定版本;Jina Reader 与可选 Metaso fallback 会把目标 URL 发送给第三方服务。METASO_API_KEY 即表示启用可选的 Metaso fallback;使用前应确认账号费用与数据传输边界。.web-clipper/EXTEND.md,执行前应向用户说明这些副作用。OBobra/superpowers298k2,631 new stars in the last 7 days
MAmattpocock/skills288k10,178 new stars in the last 7 days
AFaffaan-m/ECC278k4,046 new stars in the last 7 days
Audit accessibility on Web, iOS, and Android to meet WCAG 2.2, with keyboard navigation and screen-reader support.
AFaffaan-m/ECC278k4,046 new stars in the last 7 days
AFaffaan-m/ECC278k4,046 new stars in the last 7 days
FIfirecrawl/firecrawl191k2,010 new stars in the last 7 days