关于 tech-news-digest
面向需要制作科技资讯日报和周报的团队的可配置工作流,强调证据与编辑规则。它汇集并合并来源、去重内容,并在生成多种格式前验证规范报告。
主要功能
- 01并行收集六类来源
- 02合并来源并去重
- 03按主题筛选摘要内容
- 04日报与周报编辑规则
- 05Markdown 验证及 PDF、邮件输出
适用场景
- 01制作每日科技资讯摘要
- 02撰写每周主题综述
- 03跟踪版本发布及项目发现
- 04将报告输出为邮件或 PDF
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ draco-agent/ tech-news-digest --skill tech-news-digest安装后在 Claude Code 中输入/tech-news-digest确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdCHANGELOG.mdCONTRIBUTING.md.gitignoreLICENSEREADME_CN.mdrequirements.txt.github/workflows/test.ymlconfig/schema.jsonconfig/defaults/topics.jsonsources.jsonreferences/digest-prompt.mdreferences/templates/email.mddiscord.mdmarkdown.mdpdf.mdscripts/fetch-github.pyenrich-articles.pyconfig_loader.pyfetch-reddit.pyfetch-rss.pyfetch-twitter.pygenerate-pdf.pymerge-sources.pysanitize-html.pyfetch-web.pyrun-pipeline.pysource-health.pysend-email.pysummarize-merged.py详细介绍
科技新闻摘要
以证据为依据的科技摘要,统一收集内容,并在各种格式中共享同一份编辑精选。请将 references/digest-prompt.md 作为权威模式政策。
编辑规范
- 每日版保留原有分区:2–4 句概述;已配置的主题(通常为 LLM、AI Agent、Crypto、Frontier Tech;每个主题以 3–5 条符合条件的内容为目标);KOL 观点 ≤3 条;发布内容 ≤3 个仓库;项目发现 ≤3 条;博客精选 ≤3 条;总计 ≤30 条不重复内容。新闻/博客说明通常包含 2–3 句简洁内容,涵盖变化、证据和影响。保留空标题并附上覆盖情况说明,绝不填充无关内容。只优化分区内的内容:要求缩短 GitHub 发布内容,不应演变为重新设计整份报告或压缩成一条消息摘要。
- 每周版 ≤35 条不重复内容:概述;按配置顺序排列的主题分区(通常为 LLM、AI Agent、Crypto、Frontier Tech),每个主题以 2–4 篇有实质内容的综合分析为建议目标。每篇综合分析用 2–4 句简洁文字串联本周进展、证据和影响,而非简单拼接标题。保留空主题、重点发布、项目和观点/阅读分区标题,并附上如实的非项目符号覆盖情况说明。重点发布 ≤5 个仓库(中文说明 ≤80 个字符);项目 ≤3 条;观点/深度阅读 ≤4 条;可选的下周关注 ≤3 条待发布内容、修复或不确定事项。不要强行安排实验;事实性关注内容须附引用,明确标为计划中/未执行的实验可仅适用狭义引用豁免。
- 上限不是配额。综合分析中的证据事件和独立关注事项都计入数量。保留两种模式中的主题分区;不设全局三主题限制。正文长度限制:每日版 ≤6500 个字符,每周版 ≤10000 个字符,不包括 URL 目标;绝不为凑满上限而填充内容。
- 强制安全覆盖:遵循
references/digest-prompt.md中的主要警报/搜索检查和交付前检查。保留现有主题;只有任一模式出现可信且紧急的事件时,才在概述后使用可选的🛡️ 安全警报;每周版还可针对影响重大的非紧急风险设置专门的可选安全/风险分区。无内容时省略,并在现有上限内计数和去重。记录检查和决策;采集失败不能作为没有事件的证据。 - 优先考虑相关性、影响和证据,而非内部评分。非同寻常的说法需要原始技术证据,并尽可能进行独立评估,否则应排除或降低表述力度。不公开评分、社交指标或运行统计数据。每日版保留有实质内容且不重复的 KOL 观点。对于重要的覆盖缺口,可用一条简短说明提醒,不提供原始计数;详情留在最终运行日志中。
- 对整份报告中的事件和规范 URL 去重。每日版重复内容必须有增量进展;每周版可综合每日版内容。每日版保留博客精选;每周版的观点/深度阅读可包含原创观点、论文、文档、事后分析或评论文章。
- 项目发现不等于已验证的热门项目;不得根据累计数据推断增长,也不得重复收录缺乏实质变化的成熟仓库。遵循提示词中的重大版本发布规则,保留精确版本号和官方链接。
- 使用普通项目符号和加粗标题;简洁的行内 Discord 链接
[来源](<URL>)。按分区分块,每块 ≤1700 个字符(包括编号)。采用指定语言;配置为简体中文时,说明也须使用简体中文。 - 交付前使用
python3 scripts/validate-digest.py --input FILE --mode daily或--mode weekly验证规范归档;修复所有错误。每周生产运行时,按配置主题的顺序,为每个主题追加一个--topic-heading 'EXACT LOCALIZED HEADING';没有这些标志,校验关卡无法推断自定义标题。缺少验证或验证失败都会阻止交付。还须人工核实综合分析中的不重复事件数量、必需的非主题标题/概述、安全内容位置、证据和覆盖情况是否如实,以及不同格式间是否一致。 - Discord、Markdown、邮件和 PDF 使用相同的内容选择和判断。运行统计/运行时间归因应放在最终日志中,而非正文。
- 旧版
ITEMS_PER_SECTION、BLOG_PICKS_COUNT和EXTRA_SECTIONS是建议参数,现已由模式规则取代:忽略其数量/额外分区,尤其是重复的每周趋势内容。
快速开始
-
配置设置:默认配置位于
config/defaults/。复制到工作区以进行自定义:mkdir -p workspace/config cp config/defaults/sources.json workspace/config/tech-news-digest-sources.json cp config/defaults/topics.json workspace/config/tech-news-digest-topics.json -
环境变量:
TWITTERAPI_IO_KEY- twitterapi.io API 密钥(可选,优先使用)X_BEARER_TOKEN- Twitter/X 官方 API bearer token(可选,备用)TAVILY_API_KEY- Tavily Search API 密钥,可替代 Brave(可选)WEB_SEARCH_BACKEND- 网络搜索后端:auto|brave|tavily(可选,默认:auto)BRAVE_API_KEYS- Brave Search API 密钥,多个密钥以逗号分隔以便轮换(可选)BRAVE_API_KEY- 单个 Brave 密钥的备用项(可选)GITHUB_TOKEN- GitHub 个人访问令牌(可选,可提高速率限制)
-
生成摘要:
# Unified pipeline (recommended) — runs all 6 sources in parallel + merge python3 scripts/run-pipeline.py \ --defaults config/defaults \ --config workspace/config \ --hours 48 --freshness pd \ --archive-dir workspace/archive/tech-news-digest/ \ --output /tmp/td-merged.json --verbose --force -
选择并验证:按照
references/digest-prompt.md操作;在将相同的选择渲染为 Discord、电子邮件和 PDF 格式之前,先验证规范 Markdown。
配置文件
sources.json - 统一数据源
{
"sources": [
{
"id": "openai-rss",
"type": "rss",
"name": "OpenAI Blog",
"url": "https://openai.com/blog/rss.xml",
"enabled": true,
"priority": true,
"topics": ["llm", "ai-agent"],
"note": "Official OpenAI updates"
},
{
"id": "sama-twitter",
"type": "twitter",
"name": "Sam Altman",
"handle": "sama",
"enabled": true,
"priority": true,
"topics": ["llm", "frontier-tech"],
"note": "OpenAI CEO"
}
]
}
topics.json - 增强型主题定义
{
"topics": [
{
"id": "llm",
"emoji": "🧠",
"label": "LLM / Large Models",
"description": "Large Language Models, foundation models, breakthroughs",
"search": {
"queries": ["LLM latest news", "large language model breakthroughs"],
"must_include": ["LLM", "large language model", "foundation model"],
"exclude": ["tutorial", "beginner guide"]
},
"display": {
"max_items": 8,
"style": "detailed"
}
}
]
}
脚本流程
run-pipeline.py - 统一流程(推荐)
python3 scripts/run-pipeline.py \
--defaults config/defaults [--config CONFIG_DIR] \
--hours 48 --freshness pd \
--archive-dir workspace/archive/tech-news-digest/ \
--output /tmp/td-merged.json --verbose --force
- 功能:并行运行全部 6 个抓取步骤,然后合并、去重并评分
- 输出:可用于生成报告的最终合并 JSON(总耗时约 30 秒)
- 元数据:将每个步骤的耗时和计数保存到
*.meta.json - GitHub 身份验证:如果未设置
$GITHUB_TOKEN,则自动生成 GitHub App 令牌 - 备用方案:如果此脚本失败,请运行下面的单独脚本
单独脚本(备用)
fetch-rss.py - RSS 订阅源抓取器
python3 scripts/fetch-rss.py [--defaults DIR] [--config DIR] [--hours 48] [--output FILE] [--verbose]
- 并行抓取(10 个工作线程,每个主机最多 2 个并发请求),使用带随机抖动的退避策略重试,支持 feedparser + 正则表达式备用方案
- 超时:每个订阅源 30 秒;在
$TECH_NEWS_DIGEST_STATE_DIR中使用 ETag/Last-Modified 缓存
fetch-twitter.py - Twitter/X KOL 监控器
python3 scripts/fetch-twitter.py [--defaults DIR] [--config DIR] [--hours 48] [--output FILE] [--backend auto|official|twitterapiio]
- 自动检测后端:设置了
TWITTERAPI_IO_KEY时使用 twitterapi.io,否则在设置了X_BEARER_TOKEN时使用官方 X API v2 - 处理速率限制、互动指标,并使用退避策略重试
fetch-web.py - 网络搜索引擎
python3 scripts/fetch-web.py [--defaults DIR] [--config DIR] [--freshness pd] [--output FILE]
- 自动检测 Brave API 速率限制:付费套餐 → 并行查询,免费套餐 → 顺序查询
- 未配置 API 时:生成供 Agent 使用的搜索界面
fetch-github.py - GitHub 发布监控器
python3 scripts/fetch-github.py [--defaults DIR] [--config DIR] [--hours 168] [--output FILE]
- 并行抓取(10 个工作线程),超时 30 秒
- 身份验证优先级:
$GITHUB_TOKEN→ 自动生成 GitHub App 令牌 →ghCLI →releases.atom - 没有令牌(或遇到 403/429 速率限制)时,会读取
github.com/<repo>/releases.atom,无需身份验证, 不消耗 REST 配额,还能显示仅含标签的仓库,例如torvalds/linux - Atom 订阅源会列出所有标签,因此仅保留标签中带有
<major>.<minor>版本号的条目(v2.13.0、v6.19-rc4)。这样可排除 PyTorch 的trunk/<sha>和viable/strict/<epoch>等 CI 标签,避免它们挤占真正的发布条目
fetch-github.py --trending - 项目发现(旧版标志)
python3 scripts/fetch-github.py --trending [--hours 48] [--output FILE] [--verbose]
- 搜索 GitHub API 以发现候选项目;搜索结果并不能证明项目确实热门。
- 中性内部基础分为 5,不代表增长信号。没有
daily_stars_est或基于总量推算的增长。每日发现数量 ≤3,每周 ≤3;必须有当前尝试该项目的理由。
fetch-reddit.py - Reddit 帖子抓取器
python3 scripts/fetch-reddit.py [--defaults DIR] [--config DIR] [--hours 48] [--output FILE]
- 并行抓取(4 个工作线程),使用公开 JSON API(无需身份验证)
- 13 个 subreddit,并按分数筛选
enrich-articles.py - 文章全文增强
python3 scripts/enrich-articles.py --input merged.json --output enriched.json [--min-score 10] [--max-articles 15] [--verbose]
- 为高分文章抓取全文
- Cloudflare Markdown for Agents(优先)→ HTML 提取(备用)→ 跳过(付费墙/社交内容)
- 博客域名白名单,采用较低的分数阈值(≥3)
- 并行抓取(5 个工作线程,超时 10 秒)
merge-sources.py - 质量评分与去重
python3 scripts/merge-sources.py --rss FILE --twitter FILE --web FILE --github FILE --reddit FILE
- 质量评分、URL 去重(剥离跟踪参数,保留查询参数)、标题相似度去重(75%)、过往摘要惩罚
- 多来源加分:每增加一种来源类型,且有其他来源印证同一条新闻,即加 5 分
- 主题优先级根据
topics.json中的顺序确定;传入--defaults/--config以保持同步 - 输出:按主题分组并按得分排序的文章
validate-config.py - 配置验证器
python3 scripts/validate-config.py [--defaults DIR] [--config DIR] [--verbose]
- JSON schema 验证、主题引用检查、重复 ID 检测
generate-pdf.py - PDF 报告生成器
python3 scripts/generate-pdf.py --input report.md --output digest.pdf [--verbose]
- 将 Markdown 摘要转换为经过样式设计的 A4 PDF,并采用中文排版(Noto Sans CJK SC)
- Emoji 图标、页眉/页脚、蓝色强调主题。需要
weasyprint。
sanitize-html.py - 安全 HTML 邮件转换器
python3 scripts/sanitize-html.py --input report.md --output email.html [--verbose]
- 将 Markdown 转换为可防范 XSS 的 HTML 邮件,并内嵌 CSS
- URL 白名单(仅限 http/https),文本内容经过 HTML 转义
source-health.py - 来源健康监控器
python3 scripts/source-health.py --rss FILE --twitter FILE --github FILE --reddit FILE --web FILE [--verbose]
- 在
$TECH_NEWS_DIGEST_STATE_DIR/source-health.json中跟踪各来源过去 7 天的成功/失败记录 - 报告不健康的来源(失败率 >50%,至少 2 个样本)
summarize-merged.py - 合并数据摘要
python3 scripts/summarize-merged.py --input merged.json [--top N] [--topic TOPIC]
- 生成便于阅读的合并数据摘要,供 LLM 使用
- 显示每个主题下排名靠前的文章及其得分和指标
用户自定义
工作区配置覆盖
将自定义配置放在 workspace/config/ 中,以覆盖默认配置:
- 来源:追加新来源;将
"enabled": false以禁用默认来源 - 主题:覆盖主题定义、搜索查询和显示设置
- 合并逻辑:
- ID 相同的来源 → 优先采用用户版本
- ID 为新值的来源 → 追加到默认配置
- ID 相同的主题 → 用户版本完全替换默认配置
工作区覆盖示例
// workspace/config/tech-news-digest-sources.json
{
"sources": [
{
"id": "simonwillison-rss",
"enabled": false,
"note": "Disabled: too noisy for my use case"
},
{
"id": "my-custom-blog",
"type": "rss",
"name": "My Custom Tech Blog",
"url": "https://myblog.com/rss",
"enabled": true,
"priority": true,
"topics": ["frontier-tech"]
}
]
}
模板与输出
规范 Markdown(references/templates/markdown.md)
- 日报/周报结构由
references/digest-prompt.md规定;所有格式共用一份经过验证的筛选结果。
Discord 模板(references/templates/discord.md)
- 使用纯文本项目符号、加粗标题和内联
[来源](<URL>)链接;按章节拆分,每段不超过 1700 个字符(包括编号)。
邮件模板(references/templates/email.md)
- 使用
sanitize-html.py转换经过验证的 Markdown,再通过send-email.py发送 HTML 文件。 - 使用相同的筛选结果,不添加额外的元数据章节或运行统计信息。
PDF 模板(references/templates/pdf.md)
- 使用相同的规范报告,采用 A4 中文排版并添加页码。
- 通过
scripts/generate-pdf.py生成(需要weasyprint);不包含仅用于 PDF 的内容。
默认来源(216 个已启用)
- RSS 订阅源(93 个):AI 实验室、arXiv、研究博客、科技新闻、加密货币新闻、中国科技媒体、YouTube 频道
- Twitter/X 意见领袖(76 个):AI 研究人员、模型实验室、加密货币领域领军人物、科技高管
- GitHub 仓库(47 个):主要开源项目(llama.cpp、vLLM、SGLang、LangGraph、MCP 等)
- Reddit(13 个,默认禁用):Reddit 会屏蔽数据中心 IP;设置
REDDIT_CLIENT_ID/REDDIT_CLIENT_SECRET,并在你的覆盖配置中重新启用 - 网页搜索(4 个主题):LLM、AI Agent、加密货币、前沿科技
另外还有 7 个 RSS/GitHub 默认来源因上游订阅源失效而默认禁用;每个来源都附有说明原因的 note。
所有来源均已预先配置适当的主题标签和优先级。
依赖项
pip install -r requirements.txt
可选但建议安装:
feedparser>=6.0.0- 更好的 RSS 解析(不可用时回退到正则表达式)jsonschema>=4.0.0- 配置验证
所有脚本仅使用 Python 3.8+ 标准库即可运行。
监控与运维
健康检查
# Validate configuration
python3 scripts/validate-config.py --verbose
# Test RSS feeds
python3 scripts/fetch-rss.py --hours 1 --verbose
# Check Twitter API
python3 scripts/fetch-twitter.py --hours 1 --verbose
归档管理
- 摘要会自动归档到
<workspace>/archive/tech-news-digest/ - 使用过往摘要标题进行重复检测
- 自动清理旧归档(90 天以上)
错误处理
- 网络故障:采用指数退避重试
- 速率限制:自动重试,并设置适当的延迟
- 内容无效:优雅降级并记录详细日志
- 配置错误:进行架构验证并提供有用的提示
API 密钥与环境
在 ~/.zshenv 或类似文件中设置:
# Twitter (at least one required for Twitter source)
export TWITTERAPI_IO_KEY="your_key" # twitterapi.io key (preferred)
export X_BEARER_TOKEN="your_bearer_token" # Official X API v2 (fallback)
export TWITTER_API_BACKEND="auto" # auto|twitterapiio|official (default: auto)
# Web Search (optional, enables web search layer)
export WEB_SEARCH_BACKEND="auto" # auto|brave|tavily (default: auto)
export TAVILY_API_KEY="tvly-xxx" # Tavily Search API (free 1000/mo)
# Brave Search (alternative)
export BRAVE_API_KEYS="key1,key2,key3" # Multiple keys, comma-separated rotation
export BRAVE_API_KEY="key1" # Single key fallback
export BRAVE_PLAN="free" # Override rate limit detection: free|pro
# Reddit (required to enable the Reddit layer — it ships disabled)
export REDDIT_CLIENT_ID="xxx" # Script-type app from reddit.com/prefs/apps
export REDDIT_CLIENT_SECRET="xxx"
export REDDIT_USERNAME="xxx" # Optional, User-Agent string only
# GitHub (optional, unlocks richer release notes)
export GITHUB_TOKEN="ghp_xxx" # PAT (simplest)
export GH_APP_ID="12345" # Or use GitHub App for auto-token
export GH_APP_INSTALL_ID="67890"
export GH_APP_KEY_FILE="/path/to/key.pem"
- Twitter:优先使用
TWITTERAPI_IO_KEY(每月 $3-5);X_BEARER_TOKEN作为备用;auto模式会优先尝试 twitterapiio - 网络搜索:Tavily(
auto模式下优先)或 Brave;可选,如果不可用则回退到 Agent 的 web_search - GitHub:如果未设置 PAT,则从 GitHub App 自动生成令牌;未认证时回退(60 次请求/小时)
- Reddit:默认禁用——Reddit 会对数据中心 IP 返回 403。设置
REDDIT_CLIENT_ID/REDDIT_CLIENT_SECRET并重新启用相应来源,即可使用 OAuth API
Cron / 计划任务集成
OpenClaw Cron(推荐)
Cron 提示词不要硬编码流水线步骤。应改为引用 references/digest-prompt.md,并且只传递配置参数。这样可以确保流水线逻辑保留在技能仓库中,并在所有安装版本中保持一致。
现有的 cron 作业可能仍会传递 ITEMS_PER_SECTION、BLOG_PICKS_COUNT 和 EXTRA_SECTIONS。为保持兼容性,请接受这些参数,但忽略其中的配额和额外分区设置;模式策略优先于这些参数。新示例不会包含这些参数。
每日摘要 Cron 提示词
Read <SKILL_DIR>/references/digest-prompt.md and follow the complete workflow to generate a daily digest.
Replace placeholders with:
- MODE = daily
- TIME_WINDOW = past 1-2 days
- FRESHNESS = pd
- RSS_HOURS = 48
- ENRICH = true
- SUBJECT = Daily Tech Digest - YYYY-MM-DD
- WORKSPACE = <your workspace path>
- SKILL_DIR = <your skill install path>
- DISCORD_CHANNEL_ID = <your channel id>
- EMAIL = (optional)
- LANGUAGE = English
- TEMPLATE = discord
Follow every step in the prompt template strictly. Do not skip any steps.
每周摘要 Cron 提示词
Read <SKILL_DIR>/references/digest-prompt.md and follow the complete workflow to generate a weekly digest.
Replace placeholders with:
- MODE = weekly
- TIME_WINDOW = past 7 days
- FRESHNESS = pw
- RSS_HOURS = 168
- ENRICH = true
- SUBJECT = Weekly Tech Digest - YYYY-MM-DD
- WORKSPACE = <your workspace path>
- SKILL_DIR = <your skill install path>
- DISCORD_CHANNEL_ID = <your channel id>
- EMAIL = (optional)
- LANGUAGE = English
- TEMPLATE = discord
Follow every step in the prompt template strictly. Do not skip any steps.
为什么采用这种模式?
- 单一事实来源:流水线逻辑位于
digest-prompt.md中,而不是分散在各个 cron 配置中 - 可移植:在不同的 OpenClaw 实例上使用同一技能,只需更改路径和频道 ID
- 易于维护:更新技能后,所有 cron 作业都会自动采用更改
- 反模式:不要将流水线步骤复制到 cron 提示词中——否则会逐渐与实际逻辑不一致
多频道投递限制
OpenClaw 强制执行跨提供商隔离:单个会话只能向一个提供商发送消息(例如 Discord 或 Telegram,不能同时发送)。如果需要将摘要投递到多个平台,请为每个提供商创建单独的 cron 作业:
# Job 1: Discord + Email
- DISCORD_CHANNEL_ID = <your-discord-channel-id>
- EMAIL = [email protected]
- TEMPLATE = discord
# Job 2: Telegram DM
- DISCORD_CHANNEL_ID = (none)
- EMAIL = (none)
- TEMPLATE = telegram
在第二个作业的提示词中,将 DISCORD_CHANNEL_ID 投递目标替换为目标平台的投递目标。
这是安全功能,并非错误——它可以防止意外的跨上下文数据泄露。
安全说明
执行模型
此技能采用提示词模板模式:Agent 会读取 digest-prompt.md 并遵循其中的指示。这是标准的 OpenClaw 技能执行模型——Agent 会解读技能文件中提供的结构化指示。所有指示都随技能包一起分发,可在安装前进行审查。
网络访问
Python 脚本会向以下地址发起出站请求:
- RSS 源 URL(在
tech-news-digest-sources.json中配置) - Twitter/X API(
api.x.com或api.twitterapi.io) - Brave Search API(
api.search.brave.com) - Tavily Search API(
api.tavily.com) - GitHub API(
api.github.com) - Reddit JSON API(
reddit.com)
不会向任何其他端点发送数据。所有 API 密钥均从技能元数据中声明的环境变量读取。
Shell 安全
邮件投递使用 send-email.py 构建规范的 MIME 多部分消息,其中包含 HTML 正文和可选的 PDF 附件。主题格式是硬编码的(Daily Tech Digest - YYYY-MM-DD)。PDF 通过 weasyprint 使用 generate-pdf.py 生成。提示词模板明确禁止将不可信内容(文章标题、推文文本等)插入 shell 参数。电子邮件地址和主题必须仅使用静态占位值。
文件访问
脚本从 config/ 读取文件,并写入 workspace/archive/。不会访问工作区以外的文件。
支持与故障排除
常见问题
- RSS 源无法正常使用:检查网络连接,使用
--verbose查看详情 - Twitter 速率限制:减少源的数量或延长间隔
- 配置错误:运行
validate-config.py查看具体问题 - 未找到文章:检查时间范围(
--hours)和源是否已启用
调试模式
所有脚本都支持 --verbose 标志,可用于详细日志记录和故障排查。
性能调优
- 并行工作线程:根据系统调整脚本中的
MAX_WORKERS - 超时设置:网络较慢时增大
TIMEOUT - 文章数量限制:根据需要调整
MAX_ARTICLES_PER_FEED
安全注意事项
Shell 执行
摘要提示词会指示 Agent 通过 shell 命令运行 Python 脚本。所有脚本路径和参数都是技能定义的常量,不会将用户输入插入命令中。有两个脚本使用 subprocess:
run-pipeline.py用于编排子抓取脚本(均位于scripts/目录中)fetch-github.py包含两个子进程调用:- 使用
openssl dgst -sha256 -sign进行 JWT 签名(仅当设置了GH_APP_*环境变量时才会执行;签署的是自行构造的 JWT 载荷,不涉及任何用户内容) - 使用
gh auth token作为 CLI 回退方案(仅当安装了gh时才会执行;从 gh 自己的凭据存储中读取)
- 使用
不会将用户提供或抓取的内容插入子进程参数中。邮件投递使用 send-email.py 以编程方式构建 MIME 消息,不涉及 shell 插值。PDF 生成通过 weasyprint 使用 generate-pdf.py。邮件主题仅使用静态格式字符串构建,绝不会根据抓取的数据构建。
凭据与文件访问
脚本不会直接读取 ~/.config/、~/.ssh/ 或任何凭据文件。所有 API 令牌均从技能元数据中声明的环境变量读取。GitHub 身份验证的依次尝试顺序如下:
$GITHUB_TOKEN环境变量(由你决定提供什么)- GitHub App 令牌生成(仅当设置了
GH_APP_ID、GH_APP_INSTALL_ID和GH_APP_KEY_FILE时才会执行——通过opensslCLI 内联进行 JWT 签名,不涉及外部脚本) gh auth tokenCLI(委托给 gh 自己的安全凭据存储)- 未经身份验证(每小时 60 次请求,是安全的回退方案)
如果不希望自动发现凭据,只需设置 $GITHUB_TOKEN,脚本便会直接使用它,而不会尝试步骤 2–3。
依赖项安装
此技能不会安装任何包。requirements.txt 仅供参考,其中列出了可选依赖项(feedparser、jsonschema)。所有脚本均可使用 Python 3.8+ 标准库运行。如果需要,用户可以在虚拟环境中安装可选依赖项;此技能绝不会运行 pip install。
输入清理
- URL 解析会拒绝非 HTTP(S) 协议(javascript:、data: 等)
- RSS 回退解析使用简单、不会发生回溯的正则表达式模式(无 ReDoS 风险)
- 所有抓取的内容都仅作为不可信数据用于显示
网络访问
脚本会向已配置的 RSS 源、Twitter API、GitHub API、Reddit JSON API、Brave Search API 和 Tavily Search API 发出出站 HTTP 请求。不会创建任何入站连接或侦听器。