| name | vv-horizon-briefing |
| description | Fetch tech news from configured sources, score and filter with AI, generate daily briefing with deep analysis |
Horizon Briefing
Generate a daily tech briefing from configured data sources (GitHub, HackerNews, RSS, Reddit, Telegram). Fetches content via a Python script, then uses AI to score, filter, summarize, and deeply analyze top items. No external AI API key required.
Trigger
User types /vv-horizon-briefing or asks to "generate a briefing" / "run horizon briefing".
Phase 1: Environment Check
- Locate
config.json in the current working directory. If not found:
- Show the user two options:
- A) Create a custom config — read
references/config-schema.md from this skill directory and show the example
- B) Use the built-in preset — copy
assets/presets/default-config.json to config.json (LLM/Agent engineering sources: HackerNews, Reddit r/LocalLLaMA + r/MachineLearning, 量子位, 新智元, Simon Willison, Hugging Face, LangChain, ArXiv cs.AI, Google Cloud Blog, GitHub releases for anthropics/anthropic-sdk-python and langchain-ai/langchain)
- If user chooses B, copy the preset file and continue
- Stop until config exists
- Check Python deps:
python3 -c "import httpx; import feedparser; import bs4; print('OK')"
- If deps are missing, tell the user and ask if they want to run
scripts/install_deps.sh. If the user declines, stop and explain manual install.
Phase 2: Fetch Data
- Ask the user: "抓取最近几天的内容?(默认 3 天,输入数字或直接回车)"
- Read
config.json and extract output.output_dir (if present). Determine the base output directory:
- If
output.output_dir is set, use it as {base_dir}
- Otherwise, use
./data as {base_dir}
- Determine today's date as
{YYYY-MM-DD}. Create the output directory {base_dir}/{YYYY-MM-DD}/ if it does not exist.
- Run with the user's input (default 3 if no input):
python3 <skill_dir>/scripts/fetch.py --config config.json --days N
- If the script exits with a non-zero code or
fetched.json is not created, report the error output to the user and stop — do not proceed to Phase 3.
- Move
fetched.json to {base_dir}/{YYYY-MM-DD}/fetched.json. Read it from that path. The file is a JSON object with an items array and a config_snapshot object.
- Report item count and source count to the user.
Phase 3: Score and Filter
Read references/scoring-criteria.md from this skill directory before scoring.
Score each item 0–10 using the 5-dimension rubric (新颖性, 影响力, 技术深度, 社区信号, 时效性 — 2 points each). Sort descending, take top N from config_snapshot.top_n (default 10).
- For 100+ items: score in batches of ~30. After all batches are complete, merge all scores into one list, sort descending, and take the global top N. In case of a tie, prefer the item with higher 时效性.
- If total items ≤ top_n: skip the "other items" section in the summary (Phase 4) — there are no non-top items to list.
Output a scoring summary table to the user showing rank, title, and score.
Phase 3.5: Source Analysis
After scoring, before generating summaries:
- Count items and average score per source
- Identify the top source (most high-scoring items)
- Extract 3 trending themes from top-N item titles and content
- Compose the
{source_analysis} paragraph:
共抓取 {total} 条,来自 {source_count} 个源。
最活跃源:{top_source}({n} 条,均分 {avg}/10)
今日热点主题:{theme_1}、{theme_2}、{theme_3}
Phase 4: Generate Summary
Read references/summary-writing-guide.md from this skill directory before writing.
For each language in config_snapshot.languages, generate a summary following assets/templates/summary.md:
- Language handling:
"en" = English, "zh" = Chinese
- CRITICAL Pangu Spacing Rule for zh: Every CJK character MUST have a space on both sides when adjacent to any ASCII character (letters, digits, punctuation, symbols). [Note: if the ASCII character is a single digit, then do not insert space.] This applies to ALL text: headings, body, links, metadata, source analysis. Examples:
Anthropic 发布了 Claude 4 (not Anthropic发布了Claude4), 评分 8/10 (not 评分8/10). No exceptions — even in markdown link text and bullet points. After writing the summary, scan every line and fix any violations before writing the file.
- Each item gets a
{one_sentence_abstract} — one complete sentence, not a title rewrite. CRITICAL: Every abstract MUST contain at least one specific fact — a number, version, percentage, metric, or named entity. Vague abstracts like "某公司发布了新模型" FAIL — write "某公司发布了 405B 参数的模型 X v3.1,性能提升 23%". If the source content is too short to extract specific data, infer from title keywords or note the significance explicitly (e.g. "首次开源" counts as a specific claim).
- Include the
{source_analysis} paragraph from Phase 3.5
- For
{other_items_by_category}: take all scored items NOT in top-N, group them by category (infer category from title/content, e.g. 模型发布、工具框架、研究论文、行业动态), render each group as a markdown section with bullet links: - [{title}]({url}) · {source_type} · {score}/10
Write to: {base_dir}/{YYYY-MM-DD}/summary-{lang}.md
Phase 4.5: Pangu Spacing Self-Check
After writing summary-zh.md (if zh is in config languages), run a self-check:
- Re-read the written
summary-zh.md file
- Scan every line for CJK characters directly adjacent to ASCII characters without a space
- Fix all violations: insert a space between every CJK-ASCII boundary (both directions) [Note: if the ASCII character is a single digit, then do not insert space.]
- Rewrite the corrected version to the same file path
For articles in Phase 5, the Pangu spacing rule is embedded in each sub-agent prompt — no separate check needed here.
Phase 5: Deep Analysis (Parallel)
Before dispatching, read both reference files from this skill directory:
references/article-writing-guide.md → store as {writing_guide}
assets/templates/article.md → store as {article_template}
Dispatch one independent agent per top-N item using the Agent tool. All agents run concurrently — do NOT generate articles yourself, delegate entirely.
Sub-agent prompt template
Construct the following prompt for each item (substitute all placeholders with actual values, including the full contents of {writing_guide} and {article_template}):
You are writing a deep analysis article for a tech briefing.
Pangu Spacing Rule (CRITICAL): Every CJK character MUST have a space on both sides when adjacent to any ASCII character (letters, digits, punctuation, symbols). [Note: if the ASCII character is a single digit, then do not insert space.] Examples: Anthropic 发布了 Claude 4 (not Anthropic发布了Claude4), 评分 8/10 (not 评分8/10). No exceptions — apply to headings, body text, inline code references, and all content. Scan the entire article for violations before writing the file.
Item data:
- Title: {title}
- URL: {url}
- Source: {source_type} · {sub_source}
- Score: {score}/10
- Published: {published_time}
- Content: {content}
- Comments: {comments} ← omit this line entirely if no comments data
Article template (fill every placeholder section):
{article_template}
Writing guide (follow strictly):
{writing_guide}
Output: Write the completed article to:
{base_dir}/{YYYY-MM-DD}/articles/{N}-{title_slug}-{lang}.md
{N} = rank number (1-based)
{title_slug} = lowercase title, spaces→hyphens, non-alphanumeric removed, truncated to 50 chars
{lang} = language code from config (e.g. zh)
Do not return the article text in your response. Write the file and confirm the path written.
Dispatch
Call Agent once per top-N item with the above prompt (all calls in a single message, in parallel). Wait for all agents to complete before proceeding to Phase 6.
Collect each agent's reported output path and any errors for the Phase 6 report.
Phase 6: Completion Report
- Total items fetched, items selected, files generated (list paths), any errors
Notes
- The fetch script handles all network requests. Do not use WebFetch or curl for source data.
- All AI analysis is done by Claude in-context. No external AI API calls.
- If 0 items are fetched, skip phases 3–5.
- RSS
content fields may contain multiple article snippets separated by --- From rss ---. When scoring or writing articles, use only the text before the first separator as the primary content.