Mmcp.market

baoyu-wechat-summary skill

by guanyang·guanyang/open-agent-hub·973 stars·MIT

Summarizes WeChat group chat highlights into a structured digest using the local wx-cli binary (https://github.com/jackwener/wx-cli). Generates a normal digest by default; a roast (毒舌) version is opt-in. Maintains per-group history (history.json + history-digests.jsonl), per-user profiles, and per-group fact memory (memory.md) across runs, with privacy guardrails baked in. Use when the user asks to "总结群聊", "群聊精华", "群聊摘要", "summarize group chat", "group chat digest", mentions a WeChat group name with a time range, says "帮我看看 XX 群最近聊了什么", "XX 群有什么值得看的", or asks to "回溯画像" / "初始化画像" / "backfill profiles". Adds the roast version when the user says "毒舌版", "roast 版", "再来个毒舌的", or similar.

A100/100content scan

Is the baoyu-wechat-summary skill safe?

Clean: nothing in its files matched our rules. We read 5 files in the folder on 2026-09-28.

No findings.

Install the baoyu-wechat-summary skill

A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.

git clone --depth 1 https://github.com/guanyang/open-agent-hub.git /tmp/open-agent-hub
mkdir -p ~/.claude/skills
cp -r /tmp/open-agent-hub/skills/baoyu-wechat-summary ~/.claude/skills/baoyu-wechat-summary
available in every project

In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub

The instructions your agent would load

SKILL.md as published, without the frontmatter. Read it on GitHub

WeChat Group Summary

群聊精华提取专家。把零散的微信群聊记录提炼成结构化、可读性强的简报,并维护跨次运行的群聊历史与群友画像。底层依赖外部 wx-cli 二进制(wx 命令),不打包脚本。

⚠️ Sandbox restriction

wx-cli reads from ~/.wx-cli/ (config, cache, daemon socket) and from WeChat's data directory (~/Library/Containers/com.tencent.xinWeChat/ on macOS). Both paths are outside Claude Code's default sandbox. Every wx command in this skill needs to run with dangerouslyDisableSandbox: true from the start — don't waste a sandbox attempt first. The user can use /sandbox to view/edit restrictions.

References(按需加载)

本文件只保留工作流骨架;细节拆在 references/ 下,执行到对应步骤时再读,不要一开始全部读入:

User Input Tools

When this skill prompts the user, follow this tool-selection rule (priority order):

  1. Prefer built-in user-input tools exposed by the current agent runtime — e.g., AskUserQuestion, requestuserinput, clarify, ask_user, or any equivalent.
  2. Fallback: if no such tool exists, emit a numbered plain-text message and ask the user to reply with the chosen number/answer for each question.
  3. Batching: if the tool supports multiple questions per call, combine all applicable questions into a single call; if only single-question, ask them one at a time in priority order.

Concrete AskUserQuestion references below are examples — substitute the local equivalent in other runtimes.

Prerequisites

快速验证环境:wx --version 有输出且 wx sessions 返回数据即可继续。任何一步失败,或是首次在新环境运行 → 读 references/setup.md(完整环境检查、wx-cli 命令速查、排障手册),停在第一个失败项并给用户确切的修复命令。绝不自动安装、绝不替用户跑 sudo。

Preferences (EXTEND.md)

Check EXTEND.md in priority order — the first one found wins:

Supported keys

EXTEND.md is plain text with key: value or key=value lines, # for comments, case-insensitive keys.

A starter template lives at EXTEND.md.example.

First-Time Setup (BLOCKING)

If no EXTEND.md is found, do NOT silently proceed.

Step A — Try to auto-discover selfwxid and selfdisplay first. Run (in order, stop at the first that succeeds):

# 1. If wx-cli exposes a whoami, use it
wx whoami --json 2>/dev/null

# 2. Otherwise, find self-sent messages in recent sessions
wx sessions --json --limit 20 2>/dev/null

For option 2, scan the sessions for any private/group thread the user has sent into and read one of their own fromwxid / fromnickname pairs. If you can confidently pre-fill both values, use them as defaults in the question below; otherwise leave the fields blank for the user to fill in.

Step B — Confirm with one AskUserQuestion call (batched), pre-filling whatever auto-discovery found:

  • selfwxid (e.g., wxidabc123) — fall-back hint: the user can find it with wx contacts --query "", or by inspecting any of their own sent messages in wx sessions --json
  • self_display (e.g., 宝玉) — how they want their messages attributed
  • default_version — pick one of normal / roast / both
  • dataroot — where digest folders live. Default: {projectroot}/wechat. Enter a custom absolute path (e.g. ~/Documents/wechat-digests) or leave blank for default.
  • Save location — pick one of project / XDG / home

Write EXTEND.md to the chosen path. If the user provided a non-default data_root, include it as an uncommented line; otherwise omit it (the default applies automatically). Confirm "Preferences saved to [path]. Edit it any time to change defaults.", then continue with the digest workflow.

Workflow

Step 1: Parse the user's request

Extract:

  • Group name (or partial name for fuzzy matching)
  • Time range — interpret flexibly:
  • "最近 1 天" / "今天" / "last 24 hours" → 1 day
  • "最近 3 天" → 3 days
  • "最近 7 天" / "这周" → 7 days
  • "最近 30 天" / "最近一个月" → 30 days
  • "某天" (e.g. "3 月 5 号") → that specific date
  • "某天到某天" (e.g. "3 月 1 号到 3 月 5 号") → date range
  • "从上次开始" / "继续" / "接着上次" / "since last" → incremental mode: read history.json for this group, use lastdigest.lastmessage_time as the start
  • No time specified → incremental mode. If no history.json exists yet, fall back to defaulttimerange from EXTEND.md if set, else last 24 hours.
  • Version(s) to generate:
  • Start from default_version in EXTEND.md.

Convert relative ranges into absolute --since YYYY-MM-DD --until YYYY-MM-DD pairs using today's local date.

Step 2: Find the group + resolve folder path

wx contacts --query "<group_name>" --json

Filter for entries whose username ends in @chatroom. If multiple groups match, use AskUserQuestion to disambiguate. If none match, fall back to wx sessions --json and search there before asking the user.

Once resolved, compute the folder path:

{data_root}/{group_id}-{sanitized_group_name}/

where dataroot is from EXTEND.md (default {projectroot}/wechat).

Sanitize the group name — replace any of / \ : ? " < > | NUL and control characters with . Trim trailing dots and whitespace. Don't strip emoji or Chinese characters.

Group-rename detection: list existing folders under {dataroot}/ and find any folder whose name starts with {groupid}-. If one exists but the suffix differs (group was renamed), rename the existing folder to the new {groupid}-{sanitizednew_name} form. If a target with the new name already exists (rare), keep both and prefer the existing one for this run.

Step 2.5: Look up the group owner(群主)

群主是谁必须有据可查,不能凭历史摘要、群友玩笑或印象推断(群主可能换届,历史摘要里的说法会过期):

wx members "<group_name_or_id>" --json
  • 检查输出中是否有 owner / role 字段标识群主;有则以此为准
  • 如果 wx-cli 版本不暴露群主信息,则查 memory.md「群基本档案」里有出处的记录;两处都没有 → 摘要里不要断言谁是群主
  • 查到的结果与「群基本档案」不一致时以本次查询为准,更新档案并追加修订记录(注明查询日期)

Step 3: Fetch messages

Always redirect the fetch to a $TMPDIR file — this file is the single source of truth for the whole run: Round 3's attribution audit greps it, and the statistics are computed from it. Never write the digest purely from conversation memory.

For small batches (single-day digest, typically < 200 messages), you may additionally pipe JSON into the agent directly for reading:

wx history "<group_name_or_id>" --since YYYY-MM-DD --until YYYY-MM-DD -n 5000 --json

For large batches (weekly / monthly digests, > 200 messages), the $TMPDIR redirect also keeps the raw payload out of conversation context:

wx history "<group_name_or_id>" --since YYYY-MM-DD --until YYYY-MM-DD -n 5000 --json > "$TMPDIR/wx-messages.json"
wc -c "$TMPDIR/wx-messages.json"
jq 'length' "$TMPDIR/wx-messages.json"

Then read the file in slices via Read with offset + limit, or process with jq queries (e.g. jq '.[0:200]', jq '[.[] | {id, from_nickname, timestamp, content: (.content | .[0:50])}]' for a lightweight skeleton pass). Reading all 500+ messages at once will burn token budget unnecessarily.

Notes:

  • --since is inclusive; --until is interpreted as a date (the whole day). If the user asked for "today only", set both to today.
  • -n 5000 is a defensive cap; for very active groups, raise it and re-fetch.
  • Filter the returned messages by their timestamp to be safe (some daemons may return adjacent days).
  • Range splitting: for ranges > 7 days OR > 500 messages, prefer generating per-3-day digests and then a meta-summary over forcing one giant digest — the categorization quality degrades sharply past a week's worth of unrelated topics.

Incremental mode: after the fetch, drop any message whose timestamp is <= the lastmessagetime from history.json, and write the filtered set back to the $TMPDIR file (so audits and stats run on exactly what the digest covers). Caution: lastmessagetime is MM-DD HH:MM — plain string comparison breaks across a year boundary (12-31 vs 01-01); compare by date semantics there. If zero messages remain, tell the user "上次摘要后没有新消息,已跳过生成" and exit.

Step 3.5: Parse the message schema

wx history --json returns an array of message objects. Use the fields that are present; tolerate missing fields:

  • id / msgid / localid — message identifier (use whichever wx-cli emits). Reference IDs in working notes as anchors when building the skeleton.
  • fromwxid** — stable sender identifier
  • fromnickname** — display name (may be the group remark or original nickname)
  • content — text payload. Examples:
  • Plain text → use as-is
  • [图片] → opaque placeholder; see image handling below
  • [表情] → emoji/sticker; skip in body unless surrounded by discussion
  • [视频] / [文件] → media reference; skip unless discussed
  • [链接] or [链接/文件] → shared article; the title IS the information — quote it and credit the sharer
  • [系统] ... revokemsg → revoked; exclude from digest and from leaderboard
  • timestamp — convert to MM-DD HH:MM for display (and use full ISO for generated_at)
  • chattype** — sanity-check group

Step 3.6: Resolve self + ambiguous nicknames

  • Substitute selfdisplay for every message whose fromwxid matches self_wxid (from EXTEND.md). Apply this in the leaderboard, portraits, and body text. The user MUST appear under their real display name and count toward stats — never skip them.
  • Scan all unique senders for ambiguous handles: ≤2 characters, common programming words (nil, null, test, admin, user, undefined), single emoji, or otherwise low-information. For each, run wx contacts --query "" --json --limit 5 and pick a meaningful name in this priority: remark > nickname > wxid. Apply the substitution everywhere in the digest.
  • 硬规则:nil、空白、单标点这类占位符样式的名字绝不允许原样出现在摘要里。contacts 查不到 remark 时,用「昵称(wxid 后 4 位)」形式区分(如 nil(…n77g)),确保读者知道这是谁、且与其他人不混淆。已解析过的映射写入 memory.md「群基本档案」,下期直接复用不再重查。

Step 3.7: Load user profiles

For each unique sender appearing in this batch:

  • Look in {folder}/profiles/{wxid}-*.md by wxid prefix match. Read the matched file if found.
  • If includeroast, also look in {folder}/profiles-roast/{wxid}-.md for the roast pass.

More skills from guanyang/open-agent-hub

  • Aacademy-guideStop and check this skill before finishing any reply to a question about how to use Claude or a Claude product — it recommends matching courses, tutorials, and use cases from Claude Academy (academy.claude.com), Anthropic's learning hub. Trigger on: "how do I", "how can I", "getting started with", "what can Claude do", "teach me", "learn to use"; questions about artifacts, projects, skills, plugins, connectors, MCP; requests about rolling Claude out to a team, class, or organization; and any ask for training materials, onboarding content, or learning resources. Use it when the user is learning how to use a feature or product — not when they are mid-task and just want the task done. This skill composes with other skills: after consulting product documentation to answer how a Claude feature works, also check here for a matching course or tutorial — a docs-grounded answer and an Academy recommendation belong together. Only recommend on a strong match; never invent Academy content.
  • Aadvanced-evaluationThis skill should be used for advanced LLM evaluation: LLM-as-judge systems, direct scoring, pairwise comparison, rubric calibration, evaluator bias mitigation, confidence scoring, and automated quality assessment.
  • Aalgorithmic-artCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
  • Abaoyu-article-illustratorAnalyzes article structure, identifies positions requiring visual aids, generates illustrations with Type × Style × Palette three-dimension approach. Use when user asks to "illustrate article", "add images", "generate images for article", or "为文章配图".
  • Abaoyu-comicKnowledge comic creator supporting multiple art styles and tones. Creates original educational comics with detailed panel layouts and batch-capable image generation. Use when user asks to create "知识漫画", "教育漫画", "biography comic", "tutorial comic", or "Logicomix-style comic".
  • Abaoyu-compress-imageCompresses images to WebP (default) or PNG with automatic tool selection. Use when user asks to "compress image", "optimize image", "convert to webp", or reduce image file size.
  • Abaoyu-cover-imageGenerates article cover images with 5 dimensions (type, palette, rendering, text, mood) combining 11 color palettes and 7 rendering styles. Supports cinematic (2.35:1), widescreen (16:9), and square (1:1) aspects. Use when user asks to "generate cover image", "create article cover", or "make cover".
  • Abaoyu-danger-gemini-webGenerates images and text via reverse-engineered Gemini Web API. Supports text generation, image generation from prompts, reference images for vision input, and multi-turn conversations. Use when other skills need image generation backend, or when user requests "generate image with Gemini", "Gemini text generation", or needs vision-capable AI generation.
  • Abaoyu-danger-x-to-markdownConverts X (Twitter) tweets and articles to markdown with YAML front matter. Uses reverse-engineered API requiring user consent. Use when user mentions "X to markdown", "tweet to markdown", "save tweet", or provides x.com/twitter.com URLs for conversion.
  • Abaoyu-diagramCreate professional, dark-themed SVG diagrams of any type — architecture diagrams, flowcharts, sequence diagrams, structural diagrams, mind maps, timelines, illustrative/conceptual diagrams, and more. Use this skill whenever the user asks for any kind of technical or conceptual diagram, visualization of a system, process flow, data flow, component relationship, network topology, decision tree, org chart, state machine, or any visual representation of structure/logic/process. Also trigger when the user says "画个图" "画一个架构图" "diagram" "flowchart" "sequence diagram" "draw me a ..." or uploads content and asks to visualize it. Output is always a standalone .svg file.
  • Abaoyu-electron-extractExtracts resources and JavaScript from any installed Electron app (`.asar` bundle), restoring original sources from `.js.map` files when available or formatting minified code with Prettier otherwise. Use when user wants to "extract Electron app", "decompile Electron", "get the source code of <app>", "inspect app.asar", "看 Electron 应用源码", "提取 .asar", or asks how a desktop Electron app is built. Skips `node_modules` and supports both macOS and Windows.
  • Abaoyu-format-markdownFormats plain text or markdown files with frontmatter, titles, summaries, headings, bold, lists, and code blocks. Use when user asks to "format markdown", "beautify article", "add formatting", or improve article layout. Outputs to {filename}-formatted.md.

All agent skills → · MCP servers