返回 Skill 列表
extension
分类: 数据与分析无需 API Key

舆情传播溯源助手

社交媒体传播溯源工具。追踪推文、截图、新闻、热帖的来源与完整传播链路——基于主动溯源引擎(递归 API 调用 + 搜索引擎反查 + 多轮迭代深度搜索),跨中英文平台(微博、知乎、IT 之家、36 氪、Reddit、Hacker News、YouTube、GitHub)发现传播节点,重建时间线、按浏览量/互动量分级影响力,并生成可视化 HTML 传播路线图(支持导出长图与 PDF)。

person作者: user_5f968195hubcommunity

舆情传播溯源助手 V4.0

追踪社交媒体内容的来源与完整传播链路,并生成可视化 HTML 传播路线图。 本 skill 的核心是主动溯源引擎——并非仅获取用户提供的链接数据,而是通过 递归 API 调用、文本分析、跨中英文平台的多轮迭代深度搜索以及搜索引擎反查, 主动发现传播链中的未知节点。

V4 enhancements:

  • 公共化版本:去除内部定制内容,面向所有用户通用化
  • Deep search protocol: Mandatory multi-round iterative search covering Chinese media, English platforms (Reddit, HN, YouTube, GitHub), and broad discovery
  • Impact data: Prominent display of views/engagement on every node card, with 5-tier impact classification (M/10W/W/K/百级)
  • Mermaid topology: High-quality propagation topology graph using Mermaid flowchart (rendered via mermaid.js CDN), replacing the previous force-directed JS engine
  • Quantitative thresholds: Hard minimums for search depth before visualization

When to Use

Activate this skill when any of the following conditions are met:

  • The user provides a social media screenshot and asks to find the original source
  • The user provides tweet URLs and asks to map the propagation chain
  • The user mentions "溯源", "传播路线", "trace", "propagation map", "信息来源"
  • The user wants to understand how a piece of information spread across platforms

Workflow

Execute the following phases in order. The tracing engine (Phases 0 → 2.5) is the most critical part — invest the most effort here. A beautiful template with shallow data produces worse results than a simple template with deep, verified data.


Phase 0: Input Preprocessing

Normalize and deduplicate all user input before processing. Users (often non-technical) may provide messy input — handle it gracefully.

  1. Extract URLs from user input using regex:

    https?://(?:x\.com|twitter\.com|vxtwitter\.com|fxtwitter\.com)/(\w+)/status/(\d+)
    

    URLs may be mixed with Chinese text, scattered across multiple messages, or include tracking parameters (?s=20&t=...).

  2. Normalize all URLs to https://x.com/{user}/status/{id} format. Strip query parameters and fragments.

  3. Deduplicate by tweet_id — the same tweet may appear as different domain URLs.

  4. Incremental merging — if the user provides URLs in batches (across multiple messages), merge new URLs into the existing node pool without re-fetching already processed tweets.

For detailed normalization rules, read: {SKILL_DIR}/references/methodology.md (Section 一).


Phase 1: Information Extraction

Extract clues from the user's input (screenshots or URLs):

  1. For screenshots: Apply the "onion peeling" method — identify nested layers of content. Social media screenshots frequently contain embedded screenshots of other content. Work from the outermost layer inward:

    • Layer 1: Who posted this? (platform + username)
    • Layer 2: What content is embedded? (article screenshot? another tweet?)
    • Layer 3: What does that embedded content reference? (chat screenshot? URL?)
    • Layer N: What is the ultimate original source?
  2. For each layer, identify:

    • Username / @handle
    • Platform (identify by UI characteristics)
    • Timestamp
    • Watermarks (often reveal the original publisher)
    • Embedded URLs
    • Key phrases (for search engine lookups)
  3. For tweet URLs: Parse the user and tweet ID from each URL.

For platform identification reference, read: {SKILL_DIR}/references/methodology.md (Section 二).


Phase 2: Data Acquisition

Fetch complete data for all identified nodes.

Twitter/X Tweets

Use the bundled script for batch fetching with recursive mode enabled:

# Recursive mode: automatically traces qrtURL chains
python3 {SKILL_DIR}/scripts/fetch_tweets.py URL1 URL2 ... --recursive --output tweets.json

# Without recursion (if only basic data needed):
python3 {SKILL_DIR}/scripts/fetch_tweets.py URL1 URL2 ... --output tweets.json

The script:

  • Tries api.vxtwitter.com first, then falls back to api.fxtwitter.com
  • Returns JSON with: text, date, date_epoch, likes, retweets, replies, views, qrtURL, media_urls
  • In --recursive mode: automatically follows qrtURL chains upward (up to --depth 5)
  • Includes retry with exponential backoff, request interval control, and deduplication
  • Tags each result with _discovered_via and _depth metadata

If the script is unavailable, manually call the APIs via web_fetch:

  • Primary: https://api.vxtwitter.com/{user}/status/{id}
  • Fallback: https://api.fxtwitter.com/{user}/status/{id}

CRITICAL: Never attempt to directly fetch from x.com — it will be blocked. Nitter instances (xcancel.com, nitter.privacydev.net) are unreliable as of 2025+.

For complete API documentation, read: {SKILL_DIR}/references/api_reference.md.

News Articles / Media Reports

  1. Use web_search with title keywords + media name to find the original source
  2. Use web_fetch to retrieve the full article
  3. Compare publication times across outlets to identify the first publisher
  4. Check for watermarks in screenshots — they usually point to the original publisher

Platforms Without Direct Access

For Discord, Slack, WeChat, or other private platforms: extract information from screenshots and mark timestamps as "approximate" or "as shown in screenshot".


Phase 2.5: Active Tracing Engine ⚡ (CORE)

This is the most critical phase. Do not skip or abbreviate it. The quality of the final propagation map is directly determined by the depth and breadth of data collected in this phase. A beautiful template with shallow data produces worse results than a simple template with deep, verified data.

After Phase 2 fetches the initial data, proactively discover unknown nodes through three parallel tracing paths, then execute multi-round iterative search until the quantitative thresholds are met.

Path A: qrtURL Recursive Backtracking (trace upward to source)

For each fetched tweet with a non-empty qrtURL:
  1. Parse the qrtURL to extract user + tweet_id
  2. Fetch the referenced tweet via API
  3. Check the new tweet's qrtURL
  4. Repeat until qrtURL is empty (reached source) or depth > 5
  5. Maintain visited-URL set to prevent infinite loops

This is the most reliable tracing method — qrtURL provides structural proof of the quote-tweet relationship. If fetch_tweets.py --recursive was used in Phase 2, this path is already covered.

Path B: Tweet Text Clue Extraction (expand outward)

For each fetched tweet's text field, extract:

1. @mention usernames
   → web_search: "from:{username} {event_keywords}" to find their related tweets
   → Focus on mentions in high-engagement tweets

2. Embedded tweet URLs (in the text body)
   → Regex: https?://(x\.com|twitter\.com)/\w+/status/\d+
   → Fetch directly via API

3. Embedded non-tweet URLs (media articles, blog posts)
   → web_fetch to retrieve the linked content
   → Extract title, publication date, author for timeline placement

Path C: Deep Search Engine Discovery (MANDATORY — who cited this?)

Path C is no longer optional or only for "important nodes" — it is mandatory for ALL tracing tasks. This path discovers the majority of cross-platform propagation nodes that API-based tracing cannot reach.

C1. X/Twitter Discussion Search
web_search: site:x.com "{key phrase from tweet text}"
web_search: site:x.com "{event keywords}" "{key person handle}"
web_search: site:x.com "{event keywords}" — general discovery
C2. Chinese Media & Tech Coverage
web_search: "{event keywords}" site:ithome.com OR site:36kr.com OR site:odaily.news
web_search: "{event title}" 报道 OR 资讯 OR 新闻
web_search: "{event keywords}" site:weibo.com
web_search: "{event keywords}" site:zhihu.com
C3. English-Language Platform Search
web_search: "{event keywords}" site:reddit.com
web_search: "{event keywords}" site:news.ycombinator.com OR "Hacker News"
web_search: "{event keywords}" site:youtube.com
web_search: "{event keywords}" site:github.com discussions OR issues
C4. General & Broad Discovery (catch-all for unexpected platforms)
web_search: "{event keywords}" — unscoped, to discover platforms you didn't predict
web_search: "{event title in English}" — if event has English relevance
web_search: "{event title in Chinese}" — if event has Chinese relevance
C5. Timeline Gap Filling
When gap > 6 hours between two known nodes:
web_search: "{event keywords}" after:{date1} before:{date2}

Multi-Round Iterative Search Protocol 🔄

Do NOT stop after one pass of Paths A/B/C. Use iterative search to progressively deepen the propagation map:

Round 1: Execute Paths A → B → C with initial data
  → Collect all newly discovered nodes
  → If 3+ new nodes found → trigger Round 2

Round 2: For each new node discovered in Round 1:
  → Extract new keywords, handles, and clues
  → Re-execute Path C with these new search terms
  → If 3+ new nodes found → trigger Round 3

Round 3 (final): Same as Round 2 but with Round 2's discoveries
  → After Round 3, stop iterating regardless of results

Maximum 3 rounds of iteration. If no new nodes are found in a round, stop early.

Quantitative Search Thresholds ✅ (HARD REQUIREMENTS)

Before proceeding to Phase 3, the following minimums MUST be met:

| Metric | Minimum Requirement | Action if Not Met | |:---|:---|:---| | Total web_search calls | ≥ 10 | Execute more searches from C1-C5 templates | | Platform coverage | ≥ 4 distinct platforms searched | Add missing platforms from C1-C4 | | Propagation nodes discovered | ≥ 8 (for events with any virality) | Broaden search terms, try synonyms | | Chinese-language sources checked | ≥ 3 searches | Add C2 searches | | English-language sources checked | ≥ 2 searches | Add C3 searches |

Exception: If the event is genuinely small-scale (< 1000 total views across all nodes), the node count threshold can be relaxed to ≥ 5, but all other thresholds still apply.

Priority: Execute Path A first (fastest, most reliable), then Path B, then Path C (most comprehensive). Path C is the most important for cross-platform discovery — invest the most web_search calls here.

For detailed tracing strategies and the full search completeness scorecard, read: {SKILL_DIR}/references/methodology.md (Sections 三, 十二, 十三).


Phase 3: Timeline Reconstruction + Impact Ranking + Completeness Check

  1. Normalize all timestamps to UTC+8 (for Chinese audience context)

    • vxtwitter/fxtwitter return UTC — add 8 hours
    • Use date_epoch (Unix timestamp) when available for precision
    • Screenshot timestamps may be in the poster's local timezone — note uncertainty
  2. Sort all nodes chronologically and identify:

    • The earliest node (original source)
    • The latest node
    • Time gaps between propagation phases
  3. Rank all nodes by impact (for card display order within each phase):

    • Primary sort: views descending (if available from API)
    • Secondary sort: (likes + retweets + replies) descending
    • Nodes without any engagement data go last
    • Important: views = 0 from API may mean "data not available" rather than "zero views". When views is 0, fall back to engagement metrics for ranking, and display "浏览量数据不可用" instead of "0 次浏览"
  4. Assign impact tier to each node based on views (or total engagement if views unavailable): | Tier | Range | Display Label | Visual Treatment | |:---|:---|:---|:---| | M级 | ≥ 1,000,000 | "XXX万 次浏览" | Largest font, strongest accent color | | 10W级 | 100,000 - 999,999 | "XX.X万 次浏览" | Large font, strong accent | | W级 | 10,000 - 99,999 | "X.X万 次浏览" | Medium font, moderate accent | | K级 | 1,000 - 9,999 | "XXXX 次浏览" | Normal font, subtle accent | | 百级 | < 1,000 | "XXX 次浏览" | Small font, muted color |

  5. Classify each propagation relationship: | Type | Description | Identifier | |:---|:---|:---| | Original post | First-hand information | Earliest + no references | | Platform relay | Shared on different platform | Different platform + contains link | | Quote tweet | X/Twitter Quote Tweet | qrtURL field is non-empty | | Screenshot cite | Screenshot + own commentary | Has image + no qrtURL | | Media coverage | Journalist writes article | Has byline + editorial narration | | Media repost | Verbatim republication | Identical content + credits source |

  6. Identify hub nodes — the most influential propagation points:

    • Highest engagement (likes + retweets + replies)
    • Most cited/referenced by others
    • Changed the narrative frame
    • Triggered cross-community spread
  7. Assign dynamic roles from the semantic color palette (see Phase 4 color system). Choose 3-8 role types that best fit the specific event. Do NOT force-fit into exactly 4 roles — let the data determine the roles.

Completeness Self-Check ✅

Before proceeding to visualization, verify:

| Check Item | Criteria | Action if Failed | |:---|:---|:---| | Timeline gaps | > 6 hours between adjacent nodes | Run Path C search to fill | | Orphan nodes | Node with no reference relationships | Verify or label as "independent spread" | | Untraced qrtURL | Node has qrtURL but referenced tweet not fetched | Fetch it | | Source confirmation | Earliest node's qrtURL is confirmed empty | If not empty, continue backtracking | | High-engagement untraced | Top 3 engagement nodes have been reverse-searched | Run Path C | | Confidence labels | Every non-API node has a confidence label | Add labels |

If the self-check reveals gaps, return to Phase 2.5 to fill them. If gaps persist after additional tracing (genuinely no more nodes found), note this in the analysis.

For the complete self-check specification, read: {SKILL_DIR}/references/methodology.md (Section 六).


Phase 4: HTML Visualization

Generate a single-file HTML propagation map using the template at: {SKILL_DIR}/assets/propagation-map-template.html

Read the template for the full CSS design system, component structure, and inline comments. The final HTML uses mermaid.js CDN for topology rendering (requires internet connection).

External dependencies (CDN only — no other external resources allowed):

  • mermaid.js: https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js (topology rendering)
  • html2canvas: https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js (image export, loaded on-demand)

Dynamic Color Palette System

Do NOT use hardcoded CSS classes for roles. Instead, inject colors via inline style attributes. The palette provides 8 semantic color tiers:

| Tier | Semantic | Main | Dark | Light | |:---|:---|:---|:---|:---| | 1 | Event origin | #3b82f6 | #1e3a5f | #60a5fa | | 2 | Key relay | #8b5cf6 | #2e2558 | #a78bfa | | 3 | Media coverage | #ec4899 | #3b1838 | #f472b6 | | 4 | Community spread | #f97316 | #3b2010 | #fb923c | | 5 | Escalation | #ef4444 | #3b1818 | #f87171 | | 6 | Reversal | #10b981 | #1a3b2e | #34d399 | | 7 | Official response | #06b6d4 | #1a2e3b | #22d3ee | | 8 | Cooling down | #6b7280 | #1e2530 | #9ca3af |

Select 3-8 tiers based on the actual event. Each role maps to one tier. Use the Dark color for tag backgrounds, Light for tag text, Main for timeline dots.

For role selection guidelines, read: {SKILL_DIR}/references/methodology.md (Section 七).

Page Structure

Generate the following sections in order:

  1. Title + subtitle (event name + date range)
  2. Info banner (optional — key metrics grid, when quantitative data is available): Use the .info-banner component to display 4-6 headline metrics (e.g., total views, media count, timeline span, key engagement stats). Only include when the event has clear quantitative data points. Omit for events where data is mostly qualitative.
    <div class="info-banner">
      <div class="info-item"><div class="info-num">778,967</div><div class="info-label">原始推文浏览量</div></div>
      <div class="info-item"><div class="info-num">20+</div><div class="info-label">媒体报道数</div></div>
    </div>
    
  3. Legend (dynamically generated — only include actually used roles) CRITICAL: Legend items use a CSS .legend-dot as the color indicator. Do NOT add emoji circles (🔵🔴🟢🟠🟣💗 etc.) in the legend text — this causes a double-icon visual bug. Write only the role name in plain text after the dot.
    <div class="legend-item"><div class="legend-dot" style="background:#3b82f6"></div>事件引爆</div><div class="legend-item"><div class="legend-dot" style="background:#3b82f6"></div>🔵 事件引爆</div>
    
  4. Phase sections (N phases, grouped by propagation layer):
    • Each phase has: badge number, title, description, card(s)
    • Phases connected by arrow connectors with descriptive labels
  5. Timeline (dual-mode: horizontal if ≤ 7 nodes, vertical if > 7 nodes)
  6. Topology map (Mermaid flowchart rendered via mermaid.js CDN, with fallback text)
  7. Relationship map (From → Action → To rows)
  8. Flow summary (compact chain visualization)
  9. Analysis section (hub nodes, narrative, cross-community patterns)

Card Component

Each node is rendered as a card. Cards within each phase are sorted by impact (views descending, then engagement descending). Each card contains:

  • Avatar (emoji), display name, @handle

  • Top-right area (.card-top-right — role tag, timestamp, and confidence badge stacked vertically to prevent overlap):

    • Role tag (.card-tag — color injected via inline style)
    • Timestamp (UTC+8)
    • Confidence badge:
      • <span class="confidence verified">✅ API 已验证</span> — data from API with date_epoch
      • <span class="confidence approximate">⚠️ 近似</span> — screenshot/timezone uncertainty
      • <span class="confidence uncertain">❓ 推测</span> — indirect evidence only

    HTML structure (card-tag is INSIDE card-top-right, NOT absolutely positioned):

    <div class="card-top">
      <div class="avatar">👩‍💻</div>
      <div class="card-meta">
        <div class="card-name">用户名</div>
        <div class="card-handle">@handle</div>
      </div>
      <div class="card-top-right">
        <span class="card-tag" style="background:#1e3a5f;color:#60a5fa">🔵 原始信源</span>
        <div class="card-time">Mar 14, 2026<br>20:46 (UTC+8)</div>
        <span class="confidence verified">✅ API 已验证</span>
      </div>
    </div>
    
  • Platform badge (color-coded)

  • Content summary (with .highlight for key phrases)

  • Impact stats block (MANDATORY for API-verified nodes):

    <div class="impact-stats">
      <span class="impact-level-m">77.9万 次浏览</span>
      <!-- OR for lower tiers: -->
      <span class="impact-level-k">1,542 次浏览</span>
    </div>
    

    Impact tiers use different CSS classes: .impact-level-m, .impact-level-10w, .impact-level-w, .impact-level-k, .impact-level-low

    • When views = 0 from API: show <span class="impact-level-na">浏览量数据不可用</span>
    • When no API data at all: omit the impact stats block entirely
    • For media/blog nodes: If the article page shows a visible read count or comment count, include an impact-stats block with that data (mark as approximate). If no readable metrics exist, omit the block.
  • Engagement stats (likes, retweets, replies — specific numbers for API-verified data only)

  • Original URL link

Topology Graph — Mermaid Flowchart

For Mermaid flowchart syntax reference (node shapes, connections, subgraphs, classDef styling, mermaid.initialize() configuration, and common pitfalls), consult: {SKILL_DIR}/references/mermaid-flowchart-reference.md

Populate the {{MERMAID_TOPOLOGY_CODE}} placeholder in the HTML template with a complete Mermaid flowchart definition. The template renders it via mermaid.js CDN.

Mermaid Code Generation Rules
  1. Direction: Use flowchart TD (top-down) — propagation flows from source downward

  2. classDef color mapping (MUST define at the top of every diagram):

    classDef origin fill:#1e3a5f,stroke:#3b82f6,color:#60a5fa,stroke-width:2px
    classDef relay fill:#2e2558,stroke:#8b5cf6,color:#a78bfa,stroke-width:2px
    classDef media fill:#3b1838,stroke:#ec4899,color:#f472b6,stroke-width:2px
    classDef community fill:#3b2010,stroke:#f97316,color:#fb923c,stroke-width:2px
    classDef escalation fill:#3b1818,stroke:#ef4444,color:#f87171,stroke-width:2px
    classDef reversal fill:#1a3b2e,stroke:#10b981,color:#34d399,stroke-width:2px
    classDef official fill:#1a2e3b,stroke:#06b6d4,color:#22d3ee,stroke-width:2px
    classDef cooling fill:#1e2530,stroke:#6b7280,color:#9ca3af,stroke-width:2px
    

    Only define classDef entries for roles actually used in this event.

  3. Subgraph layering: Group nodes by propagation layer

    subgraph L0["🔵 源头层"]
      node_id["Display Name"]:::origin
    end
    subgraph L1["🟣 中继层"]
      ...
    end
    
  4. Node ID naming: Use snake_case derived from username/handle (e.g., sam_codes, devwatch, ithome_report). Node IDs must be unique and contain only alphanumeric characters and underscores.

  5. Node labels: Use ["Display Text"] with double quotes wrapping. Keep labels concise (≤ 15 characters). Include platform if cross-platform: ["Sam Lee (X)"]

  6. Connection labels: Use -->|"label"| format. Labels ≤ 8 characters. Language consistency: Labels MUST match the page language — use Chinese labels for Chinese reports (e.g., -->|"引用转推"|), English for English reports. Examples: -->|"引用转推"|, -->|"截图评论"|, -->|"采写报道"|

  7. Special character escaping: Any label containing Chinese punctuation, parentheses, or quotes MUST be wrapped in double quotes: ["标签内容"], -->|"传播行为"|

  8. Before embedding in HTML: First output the Mermaid code in a ````mermaidcode block in the chat response so the user can preview it. Confirm there are no syntax errors (no unmatched quotes, no undefined nodes, all subgraphs closed). Then embed it into the HTML{{MERMAID_TOPOLOGY_CODE}}` placeholder.

Example Mermaid Topology Code
flowchart TD
    classDef origin fill:#1e3a5f,stroke:#3b82f6,color:#60a5fa,stroke-width:2px
    classDef relay fill:#2e2558,stroke:#8b5cf6,color:#a78bfa,stroke-width:2px
    classDef media fill:#3b1838,stroke:#ec4899,color:#f472b6,stroke-width:2px
    classDef community fill:#3b2010,stroke:#f97316,color:#fb923c,stroke-width:2px

    subgraph L0["🔵 源头层"]
        sam_codes["Sam Lee"]:::origin
    end

    subgraph L1["🟣 中继层"]
        devwatch["DevWatch"]:::relay
        lumenkit["LumenKit项目"]:::relay
    end

    subgraph L2["🩷 媒体层"]
        ithome["IT之家"]:::media
        techcrunch["TechCrunch"]:::media
    end

    subgraph L3["🟠 社区层"]
        reddit_post["Reddit讨论"]:::community
        hacker_news["HN讨论"]:::community
    end

    sam_codes -->|"开源公告"| devwatch
    sam_codes -->|"发布项目"| lumenkit
    devwatch -->|"采写报道"| ithome
    devwatch -->|"采写报道"| techcrunch
    ithome -->|"截图评论"| reddit_post
    lumenkit -->|"社区讨论"| hacker_news

Timeline Mode Selection

  • Horizontal mode (.tl-track-h): Use when total timeline nodes ≤ 7. Renders as a gradient horizontal bar with positioned dots.
  • Vertical mode (.tl-track-v): Use when total timeline nodes > 7. Renders as a vertical track with alternating content blocks.

Print & PDF Export (V3.2) + Image Export (V3.3)

The template includes two floating export buttons (bottom-right corner):

📸 导出长图(主推 — V3.3 新增)

Generates a pixel-perfect PNG screenshot of the entire page, preserving the dark theme, gradients, rounded corners, and all visual effects exactly as seen in the browser.

  • Uses html2canvas (loaded via CDN on first click, ~40KB)
  • 2x resolution for retina/high-DPI quality
  • Mermaid SVG is pre-rasterized before capture to ensure topology graph is included
  • Fixed windowWidth: 1280 ensures consistent output across different screen sizes
  • Best for: social media sharing (WeChat, Feishu, DingTalk direct preview — no PDF reader needed)
  • The ignoreElements callback hides the export button container during capture
📄 导出 PDF(次要)

Uses browser's native Print → Save as PDF with comprehensive @media print styles:

  • Mermaid topology preserved: Before printing, the export script automatically converts the Mermaid SVG into a 2x resolution PNG image embedded inline. This ensures the topology graph appears in the PDF (previously it was hidden).
  • White background with dark text: All cards, sections, and labels switch to print-friendly colors while preserving role color coding on tags and legend dots.
  • Page break protection: Every card, phase, analysis block, timeline, relationship map has break-inside: avoid to prevent mid-element page splits. Phase headers use break-after: avoid to stay attached to their content.
  • Forced color preservation: Uses print-color-adjust: exact globally so role tags, platform badges, legend dots, and timeline dots retain their semantic colors in PDF.
  • Export button auto-hides in print output.

User instruction: After the HTML opens in the browser, click the 「📄 导出 PDF」 button in the bottom-right corner. The browser's print dialog will open with optimized settings. Select "Save as PDF" as the destination.


Output

Deliver two artifacts:

  1. Text summary: A structured markdown table showing the complete timeline and propagation chain, presented in the chat response. Include a Mermaid graph diagram as a text-based complement to the HTML topology map:

    graph LR
      A[Source] -->|action| B[Relay]
      B -->|action| C[Media]
    
  2. HTML file: The visual propagation map, saved to the user's working directory and opened via preview_url or browser

    ⚠️ Large file write caution: The final HTML typically exceeds 15KB and may hit the single-write token limit of some AI IDEs, causing truncated/corrupted output. If the file cannot be written in one pass, split into sequential writes: write the <head> + CSS first, then append phase sections in batches, then append scripts. Use write_to_file for the first chunk and replace_in_file or append for subsequent chunks. Always verify the closing </html> tag is present after the final write.

After delivering the HTML file, always inform the user about both export options:

💡 导出长图(推荐):点击右下角橙色「📸 导出长图」按钮,自动生成与页面 1:1 还原的高清 PNG 长图, 可直接在微信/飞书群聊中分享预览。

📄 导出 PDF:点击蓝色「📄 导出 PDF」按钮,浏览器会弹出打印对话框,选择「另存为 PDF」。


Tips for Best Results

  • Invest most effort in tracing (Phase 2 + 2.5), not in template formatting
  • Search deeply: Execute at least 10 web_search calls covering 4+ platforms. The propagation map is only as good as the data behind it
  • When multiple tweets are provided, batch-fetch them all with --recursive for efficiency
  • Always cross-reference timestamps — if a "repost" appears earlier than the "original", the propagation direction may need to be reversed
  • Pay special attention to qrtURL — it reveals hidden quote-tweet relationships
  • Screenshots with watermarks are goldmines for identifying original publishers
  • When data is ambiguous, mark the confidence level rather than guessing
  • Impact data is critical: For every API-verified node, prominently display views, likes, retweets, and replies. Users need to understand the scale of reach. When views = 0, display "浏览量数据不可用" — do NOT show 0 as if nobody read it
  • Sort cards within each phase by impact (views → engagement) so the most influential nodes appear first
  • For engagement stats: only display specific numbers from API responses. Never show fabricated or estimated engagement numbers — show nothing instead
  • When the event spans multiple days or has 20+ nodes, consider grouping into macro-phases and using vertical timeline mode
  • Mermaid topology: Always preview the Mermaid code in a code block in chat before embedding into HTML. Check for syntax errors (unmatched quotes, undefined nodes, unclosed subgraphs). Refer to {SKILL_DIR}/references/mermaid-flowchart-reference.md for syntax guidance and common pitfalls
  • Use Mermaid graphs in chat responses as a quick visual complement before generating HTML