{"id":"90efd099-67f9-48f5-9999-e4b6afd30437","shortId":"pGvTqS","kind":"skill","title":"baoyu-wechat-summary","tagline":"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) and per-u","description":"# WeChat Group Summary\n\n群聊精华提取专家。把零散的微信群聊记录提炼成结构化、可读性强的简报，并维护跨次运行的群聊历史与群友画像。底层依赖外部 [wx-cli](https://github.com/jackwener/wx-cli) 二进制（`wx` 命令），不打包脚本。\n\n> **⚠️ Sandbox restriction**\n>\n> 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.\n\n## User Input Tools\n\nWhen this skill prompts the user, follow this tool-selection rule (priority order):\n\n1. **Prefer built-in user-input tools** exposed by the current agent runtime — e.g., `AskUserQuestion`, `request_user_input`, `clarify`, `ask_user`, or any equivalent.\n2. **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.\n3. **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.\n\nConcrete `AskUserQuestion` references below are examples — substitute the local equivalent in other runtimes.\n\n## Prerequisites\n\nBefore invoking the workflow, verify the environment. Run these checks in order; stop at the first failure and surface the exact next command the user needs.\n\n1. **wx-cli installed** — run `wx --version`. If missing, tell the user to install it themselves (`npm install -g @jackwener/wx-cli` or use one of the alternatives at https://github.com/jackwener/wx-cli). **Do NOT auto-install** — this repo forbids piped/silent installs.\n2. **`~/.wx-cli` directory owned by the current user** — `sudo wx init` historically chowned this directory to root, which breaks every subsequent non-sudo `wx` call. Check:\n   ```bash\n   ls -la ~/.wx-cli/ 2>/dev/null | head -5\n   ```\n   If the directory exists but the owner is `root` (or anything other than `$(whoami)`), tell the user to repair it themselves:\n   ```bash\n   sudo chown -R $(whoami) ~/.wx-cli\n   sudo rm -f ~/.wx-cli/daemon.pid ~/.wx-cli/daemon.sock\n   wx daemon start\n   ```\n   The skill should NOT run `sudo` on the user's behalf.\n3. **wx-cli initialized** — `wx sessions` should return data. If it fails with \"no keys\" / \"init required\", instruct the user to run `wx init` while WeChat is running (on macOS, `codesign --force --deep --sign - /Applications/WeChat.app` first). Prefer non-sudo init; only fall back to `sudo wx init` if the user's wx-cli version requires it — and warn them that they'll need step 2's chown after.\n4. **WeChat 4.x running and logged in** — required for the daemon to find data files.\n\n## Preferences (EXTEND.md)\n\nCheck EXTEND.md in priority order — the first one found wins:\n\n| Priority | Path | Scope |\n|----------|------|-------|\n| 1 | `.baoyu-skills/baoyu-wechat-summary/EXTEND.md` (relative to project root) | Project |\n| 2 | `${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-wechat-summary/EXTEND.md` | XDG |\n| 3 | `$HOME/.baoyu-skills/baoyu-wechat-summary/EXTEND.md` | User home |\n\n| Result | Action |\n|--------|--------|\n| Found | Read, parse, apply. On first use in session, briefly remind: \"Using preferences from [path]. Edit it to change defaults.\" |\n| Not found | **MUST** run first-time setup (BLOCKING) before generating any digest — do NOT silently use defaults. |\n\n### Supported keys\n\nEXTEND.md is plain text with `key: value` or `key=value` lines, `#` for comments, case-insensitive keys.\n\n| Key | Type | Default | Purpose |\n|-----|------|---------|---------|\n| `self_wxid` | string | (required) | The owning account's wxid. Messages whose `from_wxid` matches this are attributed to the user. |\n| `self_display` | string | (required) | Display name to substitute for the user's own messages in digest text. |\n| `default_version` | `normal` / `roast` / `both` | `normal` | Which version(s) to generate when the user doesn't say otherwise. |\n| `default_time_range` | string (e.g. `7d`, `24h`, `1d`) | (none) | Default range when the user omits time and there's no incremental anchor. |\n| `data_root` | path | `{project_root}/wechat` | Override where digest folders live. |\n\nA starter template lives at [EXTEND.md.example](EXTEND.md.example).\n\n### First-Time Setup (BLOCKING)\n\nIf no EXTEND.md is found, do NOT silently proceed.\n\n**Step A — Try to auto-discover `self_wxid` and `self_display` first.** Run (in order, stop at the first that succeeds):\n\n```bash\n# 1. If wx-cli exposes a whoami, use it\nwx whoami --json 2>/dev/null\n\n# 2. Otherwise, find self-sent messages in recent sessions\nwx sessions --json --limit 20 2>/dev/null\n```\n\nFor option 2, scan the sessions for any private/group thread the user has sent into and read one of their own `from_wxid` / `from_nickname` 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.\n\n**Step B — Confirm with one `AskUserQuestion` call (batched), pre-filling whatever auto-discovery found:**\n\n- `self_wxid` (e.g., `wxid_abc123`) — fall-back hint: the user can find it with `wx contacts --query \"<own nickname>\"`, or by inspecting any of their own sent messages in `wx sessions --json`\n- `self_display` (e.g., `宝玉`) — how they want their messages attributed\n- `default_version` — pick one of `normal` / `roast` / `both`\n- `data_root` — where digest folders live. Default: `{project_root}/wechat`. Enter a custom absolute path (e.g. `~/Documents/wechat-digests`) or leave blank for default.\n- Save location — pick one of project / XDG / home\n\nWrite 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.\n\n## Workflow\n\n### Step 1: Parse the user's request\n\nExtract:\n\n- **Group name** (or partial name for fuzzy matching)\n- **Time range** — interpret flexibly:\n  - \"最近 1 天\" / \"今天\" / \"last 24 hours\" → 1 day\n  - \"最近 3 天\" → 3 days\n  - \"最近 7 天\" / \"这周\" → 7 days\n  - \"最近 30 天\" / \"最近一个月\" → 30 days\n  - \"某天\" (e.g. \"3 月 5 号\") → that specific date\n  - \"某天到某天\" (e.g. \"3 月 1 号到 3 月 5 号\") → date range\n  - \"从上次开始\" / \"继续\" / \"接着上次\" / \"since last\" → **incremental mode**: read `history.json` for this group, use `last_digest.last_message_time` as the start\n  - No time specified → **incremental mode**. If no `history.json` exists yet, fall back to `default_time_range` from EXTEND.md if set, else last 24 hours.\n- **Version(s) to generate**:\n  - Start from `default_version` in EXTEND.md.\n  - User request overrides: keywords \"毒舌\"/\"roast\"/\"挑衅\"/\"再来个毒的\"/\"sass\" → force `include_roast=true`. Keywords \"只要正经的\"/\"normal only\"/\"不要毒舌\" → force `include_normal=true, include_roast=false`. \"都来一份\"/\"两个版本都要\"/\"both\" → both.\n  - At least one of `include_normal`/`include_roast` must end up true.\n\nConvert relative ranges into absolute `--since YYYY-MM-DD --until YYYY-MM-DD` pairs using today's local date.\n\n### Step 2: Find the group + resolve folder path\n\n```bash\nwx contacts --query \"<group_name>\" --json\n```\n\nFilter 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.\n\nOnce resolved, compute the folder path:\n\n```\n{data_root}/{group_id}-{sanitized_group_name}/\n```\n\nwhere `data_root` is from EXTEND.md (default `{project_root}/wechat`).\n\n**Sanitize the group name** — replace any of `/ \\ : * ? \" < > | NUL` and control characters with `_`. Trim trailing dots and whitespace. Don't strip emoji or Chinese characters.\n\n**Group-rename detection**: list existing folders under `{data_root}/` and find any folder whose name starts with `{group_id}-`. If one exists but the suffix differs (group was renamed), rename the existing folder to the new `{group_id}-{sanitized_new_name}` form. If a target with the new name already exists (rare), keep both and prefer the existing one for this run.\n\n### Step 3: Fetch messages\n\nFor small batches (single-day digest, typically < 200 messages), pipe JSON into the agent directly:\n\n```bash\nwx history \"<group_name_or_id>\" --since YYYY-MM-DD --until YYYY-MM-DD -n 5000 --json\n```\n\nFor **large batches** (weekly / monthly digests, > 200 messages), redirect to `$TMPDIR` first so the raw payload never sits in conversation context:\n\n```bash\nwx history \"<group_name_or_id>\" --since YYYY-MM-DD --until YYYY-MM-DD -n 5000 --json > \"$TMPDIR/wx-messages.json\"\nwc -c \"$TMPDIR/wx-messages.json\"\njq 'length' \"$TMPDIR/wx-messages.json\"\n```\n\nThen 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.\n\nNotes:\n\n- `--since` is inclusive; `--until` is interpreted as a date (the whole day). If the user asked for \"today only\", set both to today.\n- `-n 5000` is a defensive cap; for very active groups, raise it and re-fetch.\n- Filter the returned messages by their `timestamp` to be safe (some daemons may return adjacent days).\n- **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.\n\n**Incremental mode**: after the fetch, drop any message whose `timestamp` is `<=` the `last_message_time` from `history.json`. If zero messages remain, tell the user \"上次摘要后没有新消息，已跳过生成\" and exit.\n\n### Step 3.5: Parse the message schema\n\n`wx history --json` returns an array of message objects. Use the fields that are present; tolerate missing fields:\n\n- **`id` / `msg_id` / `local_id`** — message identifier (use whichever wx-cli emits). Reference IDs in working notes as anchors when building the skeleton.\n- **`from_wxid`** — stable sender identifier\n- **`from_nickname`** — display name (may be the group remark or original nickname)\n- **`content`** — text payload. Examples:\n  - Plain text → use as-is\n  - `[图片]` → opaque placeholder; see image handling below\n  - `[表情]` → emoji/sticker; skip in body unless surrounded by discussion\n  - `[视频]` / `[文件]` → media reference; skip unless discussed\n  - `[链接] <title>` or `[链接/文件] <title>` → shared article; the title IS the information — quote it and credit the sharer\n  - `[系统] ... revokemsg` → revoked; exclude from digest and from leaderboard\n- **`timestamp`** — convert to `MM-DD HH:MM` for display (and use full ISO for `generated_at`)\n- **`chat_type`** — sanity-check `group`\n- **Quote/reply** — try `quote_id`, `reply_to`, `quoted_msg_id`, or any nested `quote` object. If present, use it as strong attribution. If absent, fall back to context but flag the inferred link as uncertain.\n\n### Step 3.6: Resolve self + ambiguous nicknames\n\n- Substitute `self_display` for every message whose `from_wxid` 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.\n- 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 \"<nick>\" --json --limit 5` and pick a meaningful name in this priority: remark > nickname > wxid. Apply the substitution everywhere in the digest.\n\n### Step 3.7: Load user profiles\n\nFor each unique sender appearing in this batch:\n\n- Look in `{folder}/profiles/{wxid}-*.md` by `wxid` prefix match. Read the matched file if found.\n- If `include_roast`, **also** look in `{folder}/profiles-roast/{wxid}-*.md` for the roast pass.\n\nCompile a condensed **profile context block** as internal working memory — do NOT write it into the final digest. Example shape:\n\n```\n== 群友历史画像（来自 profiles/）==\nK. H：空中直播员 / 生活百科全书。常见话题：旅行、金融、美食。经典金句：\"要不要买moderna\"。\n可可苏玛：...\n```\n\nRules:\n\n- Only load profiles for users active in this batch — never preload everyone.\n- Profile is **background**, not template. Current messages are still the primary source.\n- Use historical labels for **continuity** (\"又双叒叕化身空中直播员\") or **contrast** (\"一向省钱的 XX 今天居然...\").\n- **Strict separation**: normal pass reads only `profiles/`, roast pass reads only `profiles-roast/`. Never cross-load.\n\nSee [references/profiles.md](references/profiles.md) for the full file format.\n\n### Step 3.8: Detect existing in-chat digests (optional)\n\nSome users (e.g., the original 宝玉 workflow) post digests directly into the group as messages. If we don't notice these, the new digest will re-cover the same ground.\n\nScan the fetched messages for signals of a prior in-chat digest:\n\n- `from_wxid == self_wxid` AND\n- `content` contains `群聊精华` OR `消息统计:` OR `📊 消息统计` OR a leaderboard pattern (e.g. `^\\d+\\. .+: \\d+ 条`), AND\n- `content` length > 1500 chars.\n\nIf a match is found:\n\n1. Extract the digest's covered date or range from the title line (e.g., `xxx 群聊精华 · 2026-05-12` or `... · 2026-05-10 ~ 2026-05-12`).\n2. Surface the finding to the user via `AskUserQuestion`:\n   - \"Detected an in-chat digest by you covering {范围}. Use {范围 end + 1} as the start instead of `history.json`?\"\n   - Options: `Yes, skip up to {end of detected range}` / `No, use history.json` / `No, cover everything in the requested range`.\n3. Apply the chosen anchor.\n\nThis is a heuristic — when uncertain (multiple matches, malformed title), default to `history.json` and tell the user what was skipped.\n\nGenerate the digest in three rounds so nothing slips through. The methodology stays here in SKILL.md; the content/style rules live in [references/output-formats.md](references/output-formats.md) — read that file in Round 2 before drafting.\n\n#### Round 1 — Build the skeleton\n\nRead every message in order. **Skip image fetching/decoding** in this round. List every distinct discussion topic. Bias toward over-listing — trim in Round 3.\n\nInternal working format (not written to the final file):\n\n```\n== 话题清单（共 N 条消息）==\n1. [HH:MM-HH:MM] 话题名称（参与者：A, B, C）— 一句话概括（锚点 id：54052, 54055, 54063）\n2. [HH:MM-HH:MM] 话题名称（参与者：D, E）— 一句话概括（锚点 id：54100-54112）\n...\n\n== 可能需要图片上下文的话题 ==\n- 话题 3：锚点 id=49661（图片是讨论主体）\n\n== 发言统计 ==\n1. XXX — N 条  2. YYY — N 条  ...\n```\n\nTopic principles:\n\n- Topic-switch signals: time gap > 30 min, participant change, content jump.\n- 2+ participants OR substantive content qualifies as a topic; pure emoji-banter does not.\n- **Strict attribution**: each topic must record \"who said what\". Don't fuse adjacent messages from different senders just because they're close in time — when minutes apart or interleaved with others, split into separate topics. Prefer two topics over one wrongly-merged topic.\n- **Carry anchor IDs**: list the key message IDs for each topic. In Round 2, jump back to these IDs in the raw messages and verify content, don't guess from context. If `quote_id` / `reply_to` is present, use the ID chain — that's the most reliable attribution.\n\n**Flag-for-images criteria** (any one triggers): an explicit comment on an image (`看发型是X？`, `这是谁？`, `笑死`), multiple people piling onto the same image without saying what it is, an image as the core information (晒单/截图/资料), an explanatory line right after an image (`gpt-image-2`, `太可怕了`), or cross-sender ambiguity (B says \"这个看着像 X\" but the previous image is from A).\n\n#### Round 2 — Flesh out + write the digest\n\nFor each topic in the skeleton, jump back to its anchor IDs and expand into full content with quotes and clear attribution. Then write the digest file.\n\n**Image handling** (limited — wx-cli does not decode chat images):\n\nFor each flagged topic, check whether a description file already exists at `{folder}/imgs/{message_id}.txt`. If yes, read it (one-line plain text) and weave its content into the topic. If no, treat the image as opaque (`[图片]`) and write around it — describe what the surrounding messages tell us, but don't invent visual content.\n\nThe `imgs/` directory exists as an **extension point**: a user (or a future wx-cli capability) can drop `{message_id}.txt` files with one-line descriptions, and the skill will pick them up. The skill itself does NOT generate these files in this version.\n\n**Use the profile context block** (from Step 3.7):\n\n- Echo continuity for matching behavior (\"又双叒叕直播飞行体验\")\n- Highlight contrast for departures (\"一向话少的 XX 今天突然爆发\")\n- Callback past quotes (\"继上次'要不要买 moderna'之后，这次又...\")\n- Don't sacrifice current material to force a callback.\n\n**Roast pass — profile usage extras** (only when generating the roast version):\n\n- 历史槽点可做 callback joke\n- Running gag 可以升级和迭代\n- 历史毒舌语录可以引用或翻新\n- 但当期素材优先，不要为了 callback 硬凑\n\n**Writing order**: write the body categories first, then the opening overview based on the finished body (so the hook is accurate).\n\nDetailed structure, voice, formatting rules, and content guidelines are in [references/output-formats.md](references/output-formats.md). Load that file now if not already loaded.\n\n#### Round 3 — Audit\n\nWalk the Round 1 skeleton against the finished digest. Check:\n\n- Any listed topic missing from the digest?\n- Quotes, names, product/tool names preserved verbatim?\n- Categorization makes sense — is anything in the wrong bucket?\n\nFix in place. When clean, confirm and proceed.\n\n### Step 7: Save the digest file(s)\n\nIf `include_normal`:\n\n- Single date → `{folder}/YYYY-MM-DD.md`\n- Date range → `{folder}/YYYY-MM-DD_YYYY-MM-DD.md`\n- Overwrite if the same date/range already exists.\n\nIf `include_roast`:\n\n- Same naming, but with `-roast` suffix: `YYYY-MM-DD-roast.md` or `YYYY-MM-DD_YYYY-MM-DD-roast.md`.\n\nBoth versions share the same statistics (message count, leaderboard) and the same underlying skeleton.\n\n### Step 8: Save history (two files)\n\nMaintain two files in the group folder:\n\n#### `history.json` — single record, fast read\n\nAlways reflects only the most recent normal digest. Overwrite on each run when `include_normal=true`.\n\n```json\n{\n  \"group_id\": \"12345678901@chatroom\",\n  \"group_name\": \"相亲相爱一家人\",\n  \"folder\": \"12345678901@chatroom-相亲相爱一家人\",\n  \"last_digest\": {\n    \"file\": \"2026-03-12.md\",\n    \"date_range\": \"2026-03-12\",\n    \"generated_at\": \"2026-03-12T10:30:00+08:00\",\n    \"message_count\": 150,\n    \"last_message_time\": \"03-12 18:45\"\n  }\n}\n```\n\n- `group_name` updates on every run (handles renames).\n- `folder` records the current folder basename for cross-reference.\n- `last_message_time` is the timestamp of the most recent message included, in `MM-DD HH:MM` — used by incremental mode.\n- Roast-only runs do NOT touch this file.\n\n#### `history-digests.jsonl` — append-only archive\n\nOne JSON object per line, same shape as `last_digest`. Every normal-version run appends one line (in chronological order). Used by backfill and historical lookups. Never read for incremental mode (which only needs the latest).\n\n```jsonl\n{\"file\":\"2026-03-10.md\",\"date_range\":\"2026-03-10\",\"generated_at\":\"2026-03-10T09:00:00+08:00\",\"message_count\":420,\"last_message_time\":\"03-10 22:30\"}\n{\"file\":\"2026-03-11.md\",\"date_range\":\"2026-03-11\",\"generated_at\":\"2026-03-11T09:05:00+08:00\",\"message_count\":312,\"last_message_time\":\"03-11 23:10\"}\n{\"file\":\"2026-03-12.md\",\"date_range\":\"2026-03-12\",\"generated_at\":\"2026-03-12T10:30:00+08:00\",\"message_count\":150,\"last_message_time\":\"03-12 18:45\"}\n```\n\nIf a normal digest with the same `file` name is regenerated, append a new line anyway (the JSONL is a strict log; readers can dedupe by `file` if they need to).\n\n### Step 8.5: Update user profiles\n\nFor each user with 3+ messages in this batch who appeared in the 群友画像 section:\n\n- If `include_normal`, update `{folder}/profiles/{wxid}-{nickname}.md`.\n- If `include_roast`, update `{folder}/profiles-roast/{wxid}-{nickname}.md`.\n\nCounts, frontmatter updates, append-only rules for quotes and events, and privacy guardrails are detailed in [references/profiles.md](references/profiles.md). Load that file when running this step.\n\n### Completion checklist\n\nProfile updates are easy to forget once the digest is on disk. Before reporting the run as \"done\", verify every applicable file:\n\n- [ ] `{folder}/YYYY-MM-DD.md` written (if `include_normal`)\n- [ ] `{folder}/YYYY-MM-DD-roast.md` written (if `include_roast`)\n- [ ] `{folder}/history.json` overwritten with the new `last_digest` (if `include_normal`)\n- [ ] `{folder}/history-digests.jsonl` appended one line (if `include_normal`)\n- [ ] `{folder}/profiles/{wxid}-*.md` updated for every user with 3+ messages (if `include_normal`)\n- [ ] `{folder}/profiles-roast/{wxid}-*.md` updated for every user with 3+ messages (if `include_roast`)\n\nIf any item is unchecked, finish it before declaring success. Don't ship a digest with a stale `history.json` — incremental mode depends on it.\n\n### Step 9: Backfill (user-triggered)\n\nWhen the user says \"回溯画像\" / \"初始化画像\" / \"backfill profiles\":\n\n1. Confirm the target group (if not specified, ask which one).\n2. List all digest files in `{folder}/` and `history-digests.jsonl`.\n3. Read existing digests in batches of 10–15 to avoid context blowup.\n4. For users appearing in 3+ digests, seed profile files using their leaderboard counts, portrait paragraphs, and quoted lines from the historical digests.\n5. Write to `profiles/` (and `profiles-roast/` if any `-roast.md` files exist).\n6. Report back: how many profiles were created, how many users covered.\n\nFull procedure in [references/profiles.md](references/profiles.md).\n\n## Storage layout\n\n```\n{data_root}/                                        # default: {project_root}/wechat/\n└── {group_id}-{group_name}/                        # e.g. 12345678901@chatroom-相亲相爱一家人/\n    ├── history.json                                # last digest pointer (fast)\n    ├── history-digests.jsonl                       # append-only archive\n    ├── 2026-03-12.md                               # normal digest, single date\n    ├── 2026-03-12-roast.md                         # roast digest (only if generated)\n    ├── 2026-03-10_2026-03-12.md                    # normal digest, date range\n    ├── profiles/                                   # normal user profiles\n    │   ├── onlytiancai-胡浩🐸.md\n    │   └── ...\n    ├── profiles-roast/                             # roast user profiles (only if any roast generated)\n    │   ├── onlytiancai-胡浩🐸.md\n    │   └── ...\n    └── imgs/                                       # optional image-description files\n        ├── 49661.txt                               # one-line plain text description\n        └── ...\n```\n\n## wx-cli quick reference\n\n| Command | Purpose |\n|---------|---------|\n| `wx --version` | Sanity-check that wx-cli is installed |\n| `wx sessions --json` | List recent sessions; useful for verifying init and finding the user's own wxid |\n| `wx contacts --query \"<name>\" --json` | Fuzzy-match contacts/groups by display name, remark, or wxid |\n| `wx history \"<group>\" --since DATE --until DATE -n N --json` | Pull a group's messages within a date range as JSON |\n| `wx members \"<group>\" --json` | List a group's members (rarely needed; mostly for completeness) |\n| `wx stats \"<group>\" --since DATE` | wx-cli's built-in stats; we compute our own from `wx history` JSON so the format matches our digest |\n| `wx daemon status` / `wx daemon stop` / `wx daemon logs --follow` | Daemon lifecycle (troubleshooting) |\n\nAll `wx` commands accept `--json` for machine-readable output. Default output is YAML — only use it for human eyeballing during debugging.\n\n## Troubleshooting\n\nWhen a `wx` command fails, diagnose by the symptom, not by retrying blindly. Common patterns:\n\n| Symptom | Cause | Fix (tell the user to run these — do NOT run `sudo` for them) |\n|---------|-------|----------------------------------------------------------------|\n| `Operation not permitted` / `Access denied to ~/.wx-cli` | Sandbox is on | Re-run the command with `dangerouslyDisableSandbox: true`. Persistent fix: `/sandbox` to allow `~/.wx-cli` and the WeChat data dir. |\n| `无法写入 /Users/<u>/.wx-cli` / `Permission denied` | `~/.wx-cli` is owned by root (legacy `sudo wx init`) | `sudo chown -R $(whoami) ~/.wx-cli && sudo rm -f ~/.wx-cli/daemon.{pid,sock} && wx daemon start` |\n| `wx history` hangs / times out / returns nothing | Daemon is stuck | `wx daemon stop && rm -f ~/.wx-cli/daemon.{pid,sock} && wx daemon start`, then retry |\n| `no keys` / `init required` after the daemon was working | Keys went stale (WeChat restart, version upgrade) | Make sure WeChat is running, then `wx init --force` (non-sudo first; only `sudo` if your wx-cli version requires it) |\n| `wx contacts` returns zero rows for a group you know exists | Group is folded into 折叠群 or the daemon hasn't indexed it yet | `wx sessions --json` and search there; if missing, run `wx daemon stop && wx daemon start` and retry |\n| Messages returned but `--since` / `--until` window looks wrong | Date string not in `YYYY-MM-DD` format, or off-by-one timezone | Confirm the dates are local-time `YYYY-MM-DD`. Re-filter the JSON by `timestamp` locally as a belt-and-suspenders step. |\n| Empty result for a chat that should have activity | `-n` cap too low for a noisy group | Raise `-n` (e.g. to 20000) and re-fetch |\n\n**Recovery order when nothing makes sense:**\n\n1. Is WeChat running?\n2. Is `~/.wx-cli` owned by `$(whoami)`?\n3. Is the daemon healthy? (`wx daemon status`)\n4. Restart the daemon (`wx daemon stop && wx daemon start`)\n5. Last resort: `wx init --force` (while WeChat is running)\n\nNever auto-retry inside the skill — every failure should produce a clear diagnostic plus the exact command the user needs to run.\n\n## Notes and limitations\n\n- **Image content is opaque**. wx-cli does not decode chat images. The skill respects an `imgs/{message_id}.txt` extension point but does not auto-populate it. When a topic depends heavily on an image with no description file, the digest should say so honestly rather than invent visual content.\n- **Reply attribution is best-effort**. If wx-cli's output exposes a quote/reply field, use it. Otherwise fall back to context and flag uncertain inferences in working notes.\n- **Local time only**. Date parsing uses the agent's local time zone. Cross-time-zone group members may show timestamps that don't match their wall clock. Per the format rules, never use timestamps to infer sleep or location.\n- **wx-cli reinit**. If `wx history` suddenly returns nothing after a WeChat restart, the keys may be stale. Tell the user to run `sudo wx init --force` (while WeChat is running) and retry.","tags":["baoyu","wechat","summary","skills","jimliu","agent-skills","claude-skills","codex-skills","openclaw-skills"],"capabilities":["skill","source-jimliu","skill-baoyu-wechat-summary","topic-agent-skills","topic-claude-skills","topic-codex-skills","topic-openclaw-skills"],"categories":["baoyu-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/JimLiu/baoyu-skills/baoyu-wechat-summary","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add JimLiu/baoyu-skills","source_repo":"https://github.com/JimLiu/baoyu-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 18712 github stars · SKILL.md body (26,752 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:52:37.839Z","embedding":null,"createdAt":"2026-05-14T06:53:26.899Z","updatedAt":"2026-05-18T18:52:37.839Z","lastSeenAt":"2026-05-18T18:52:37.839Z","tsv":"'+08':2839,2958,2985,3012 '-03':2829,2834,2948,2953,2975,2980,3002,3007 '-05':2040,2044,2047 '-10':2045,2949,2954,2967 '-11':2976,2981,2994 '-12':2041,2048,2830,2835,2848,3003,3008,3021 '-3':1468 '-5':344 '-54112':2227 '/.wx-cli':74,311,340,371,3585,3602,3610,3613,3626,3826 '/.wx-cli/daemon':3630,3651 '/.wx-cli/daemon.pid':375 '/.wx-cli/daemon.sock':376 '/applications/wechat.app':426 '/baoyu-skills/baoyu-wechat-summary/extend.md':508 '/baoyu-wechat-summary/extend.md':497 '/dev/null':342,723,740 '/documents/wechat-digests':876 '/history-digests.jsonl':3167 '/history.json':3156 '/imgs':2489 '/jackwener/wx-cli)':62 '/jackwener/wx-cli).':23,299 '/library/containers/com.tencent.xinwechat':85 '/profiles':1817,3080,3175 '/profiles-roast':1837,3089,3189 '/sandbox':123,3599 '/users':3609 '/wechat':659,869,1187,3333 '/yyyy-mm-dd-roast.md':3150 '/yyyy-mm-dd.md':2737,3144 '/yyyy-mm-dd_yyyy-mm-dd.md':2741 '0':1373,1382 '00':2838,2840,2956,2957,2959,2984,2986,3011,3013 '03':2847,2966,2993,3020 '05':2983 '1':144,269,493,709,939,959,965,997,2023,2071,2154,2196,2236,2687,3240,3820 '10':2996,3267 '12345678901':2812,2818,3339 '15':3268 '150':2843,3016 '1500':2016 '18':2849,3022 '1d':639 '2':170,310,341,458,503,722,724,739,743,1121,1756,2049,2150,2213,2240,2258,2330,2413,2432,3251,3824 '20':738 '200':1287,1317,1374 '20000':3809 '2026':2039,2043,2046,2828,2833,2947,2952,2974,2979,3001,3006 '2026-03-10.md':2944 '2026-03-10_2026-03-12.md':3364 '2026-03-11.md':2971 '2026-03-12-roast.md':3358 '2026-03-12.md':2825,2998,3353 '22':2968 '23':2995 '24':963,1046 '24h':638 '3':197,391,510,968,970,986,995,999,1276,2097,2182,2230,2682,3064,3183,3197,3260,3278,3830 '3.5':1524 '3.6':1705 '3.7':1802,2587 '3.8':1941 '30':979,982,2252,2837,2969,3010 '312':2989 '4':462,464,3273,3838 '420':2962 '45':2850,3023 '49661':2233 '49661.txt':3398 '5':988,1001,1782,3296,3848 '50':1383 '500':1391,1463 '5000':1309,1346,1425 '54052':2210 '54055':2211 '54063':2212 '54100':2226 '6':3309 '7':973,976,1460,2725 '7d':637 '8':2776 '8.5':3056 '9':3227 'abc123':815 'absent':1692 'absolut':873,1103 'accept':3529 'access':3582 'account':583 'accur':2660 'action':515 'activ':1432,1884,3796 'adjac':1454,2285 'admin':1764 'agent':157,1293,3973 'allow':3601 'alreadi':1262,2485,2679,2747 'also':1833 'altern':295 'alway':2793 'ambigu':1708,1754,2419 'anchor':653,1566,2101,2318,2448 'anyth':355,2711 'anyway':3039 'apart':2299 'appear':1736,1810,3070,3276 'append':2902,2920,3035,3097,3168,3350 'append-on':2901,3096,3349 'appli':519,917,1724,1794,2098 'applic':209,3141 'archiv':2904,3352 'around':2519 'array':1534 'articl':1626 'as-i':1595 'ask':165,185,220,1162,1416,3248 'askuserquest':160,230,800,1146,2057 'attempt':117 'attribut':593,851,1690,2274,2364,2459,3937 'audit':2683 'auto':303,691,808,3860,3910 'auto-discov':690 'auto-discoveri':807 'auto-instal':302 'auto-popul':3909 'auto-retri':3859 'automat':918 'avoid':3270 'b':796,2205,2420 'back':435,818,1035,1153,1694,2332,2445,3311,3956 'backfil':2928,3228,3238 'background':1893 'banter':2270 'baoyu':2,495 'baoyu-skil':494 'baoyu-wechat-summari':1 'base':2651 'basenam':2864 'bash':337,366,708,1128,1295,1332 'batch':198,802,1281,1313,1813,1887,3068,3265 'behalf':390 'behavior':2592 'belt':3784 'belt-and-suspend':3783 'best':3940 'best-effort':3939 'bias':2174 'binari':20 'blank':788,879 'blind':3561 'block':544,676,1849,2584 'blowup':3272 'bodi':1609,1731,2644,2655 'break':328 'briefli':525 'bucket':2715 'budget':1398 'build':1568,2155 'built':147,3496 'built-in':146,3495 'burn':1396 'c':1350,2206 'cach':76 'call':206,214,335,801 'callback':2601,2617,2630,2638 'cap':1429,3798 'capabl':2550 'carri':2317 'case':570 'case-insensit':569 'categor':1483,2707 'categori':2645 'caus':3565 'chain':2358 'chang':534,929,2255 'char':2017 'charact':1198,1211,1757 'chat':8,1664,1946,1991,2062,2474,3792,3894 'chatroom':1140,2813,2820,3341 'chatroom-相亲相爱一家人':2819,3340 'check':252,336,480,1668,2480,2693,3416 'checklist':3120 'chines':1210 'chosen':192,894,2100 'chown':322,368,460,3623 'chronolog':2924 'clarifi':164 'claud':92 'clean':2720 'clear':2458,3870 'cli':19,59,71,272,394,446,713,1558,2470,2549,3407,3420,3493,3694,3890,3945,4008 'clock':3993 'close':2294 'code':93 'codesign':422 'combin':207 'command':99,265,3410,3528,3552,3593,3875 'comment':568,2375 'common':1758,3562 'compil':1844 'complet':3119,3486 'comput':1167,3500 'concret':229 'condens':1846 'confid':770 'config':75,505 'confirm':797,919,2721,3241,3762 'contact':827,1130,1778,3441,3699 'contacts/groups':3447 'contain':1999 'content':1380,1381,1588,1998,2014,2256,2262,2342,2454,2505,2533,2667,3885,3935 'content/style':2139 'context':1331,1696,1848,2347,2583,3271,3958 'continu':932,1907,2589 'contrast':1910,2595 'control':1197 'convers':1330 'convert':1099,1648 'core':2398 'count':1743,2768,2842,2961,2988,3015,3093,3286 'cover':1976,2028,2066,2091,3320 'creat':3316 'credit':1635 'criteria':2369 'cross':1930,2417,2867,3979 'cross-load':1929 'cross-refer':2866 'cross-send':2416 'cross-time-zon':3978 'current':156,316,1896,2612,2862 'custom':872 'd':2010,2011,2221 'daemon':77,378,473,1451,3514,3517,3520,3523,3634,3643,3647,3655,3665,3716,3732,3735,3833,3836,3841,3843,3846 'dangerouslydisablesandbox':107,3595 'data':83,400,476,654,860,904,1171,1179,1220,3328,3606 'date':992,1003,1119,1409,2029,2735,2738,2826,2945,2972,2999,3357,3367,3457,3459,3470,3490,3747,3764,3969 'date/range':2746 'day':966,971,977,983,1284,1412,1455,1461,1469 'dd':1108,1113,1302,1307,1339,1344,1652,2884,3754,3772 'debug':3547 'declar':3210 'decod':2473,3893 'dedup':3048 'deep':424 'default':29,95,535,553,575,614,632,641,779,852,866,881,903,916,930,1037,1054,1184,2112,3330,3536 'defens':1428 'degrad':1485 'deni':3583,3612 'departur':2597 'depend':3223,3916 'describ':2521 'descript':2483,2561,3396,3404,3923 'detail':2661,3108 'detect':1215,1942,2058,2085 'diagnos':3554 'diagnost':3871 'differ':1238,2288 'digest':13,27,548,612,662,863,935,1285,1316,1470,1481,1643,1800,1861,1947,1957,1972,1992,2026,2063,2124,2437,2463,2692,2700,2728,2800,2823,2914,3027,3129,3162,3216,3254,3263,3279,3295,3345,3355,3360,3366,3512,3926 'dir':3607 'direct':1294,1958 'directori':84,312,324,347,2536 'disambigu':1148 'discov':692 'discoveri':809 'discuss':1613,1620,2172 'disk':3132 'display':598,601,697,843,1578,1656,1712,1740,3449 'distinct':2171 'doesn':628 'done':3138 'dot':1202 'draft':2152 'drop':1500,2552 'e':2222 'e.g':159,636,813,844,875,985,994,1371,1951,2009,2036,3338,3807 'easi':3124 'echo':2588 'edit':531,924 'effort':3941 'els':1044 'emit':177,1559 'emoji':1208,1768,2269 'emoji-bant':2268 'emoji/sticker':1606 'empti':3788 'end':1096,1138,2070,2083 'enter':870 'entri':1135 'environ':249 'equival':169,238 'event':3103 'everi':97,329,1714,2159,2170,2855,2915,3140,3180,3194,3865 'everyon':1890 'everyth':2092 'everywher':1797 'exact':263,3874 'exampl':234,1591,1862 'exclud':1641 'exist':176,348,1032,1217,1234,1244,1263,1270,1943,2486,2537,2748,3262,3308,3708 'exit':1522 'expand':2451 'explanatori':2404 'explicit':2374 'expos':153,714,3948 'extend.md':479,481,556,679,891,1041,1057,1183,1723 'extend.md.example':670,671 'extens':2540,3904 'extra':2622 'extract':945,2024 'eyebal':3545 'f':374,3629,3650 'fail':403,3553 'failur':259,3866 'fall':434,817,1034,1152,1693,3955 'fall-back':816 'fallback':171 'fals':1082 'fast':2791,3347 'fetch':1277,1439,1499,1982,3813 'fetching/decoding':2165 'field':787,1540,1546,3951 'file':477,1358,1827,1938,2147,2191,2464,2484,2556,2576,2675,2729,2780,2783,2824,2899,2943,2970,2997,3031,3050,3114,3142,3255,3282,3307,3397,3924 'fill':773,793,805 'filter':1133,1440,3775 'final':1860,2190 'find':475,726,823,1122,1223,2052,3434 'finish':2654,2691,3207 'first':118,258,427,486,521,541,673,698,705,1322,2646,3687 'first-tim':540,672 'fix':2716,3566,3598 'flag':1698,2366,2478,3960 'flag-for-imag':2365 'flesh':2433 'flexibl':957 'fold':3711 'folder':663,864,1126,1169,1218,1225,1245,1816,1836,2488,2736,2740,2787,2817,2859,2863,3079,3088,3143,3149,3155,3166,3174,3188,3257 'follow':136,3522 'forbid':307 'forc':423,1067,1076,1478,2615,3683,3853,4033 'forget':3126 'form':1254 'format':1939,2185,2664,3509,3755,3996 'found':488,516,537,681,810,1829,2022 'frontmatt':3094 'full':1659,1937,2453,3321 'fuse':2284 'futur':2546 'fuzzi':952,3445 'fuzzy-match':3444 'g':288 'gag':2633 'gap':2251 'generat':24,546,624,1051,1466,1662,2122,2574,2625,2831,2950,2977,3004,3363,3387 'giant':1480 'github.com':22,61,298 'github.com/jackwener/wx-cli)':60 'github.com/jackwener/wx-cli).':21,297 'gpt':2411 'gpt-imag':2410 'ground':1979 'group':7,41,50,946,1016,1124,1143,1173,1176,1190,1213,1230,1239,1249,1433,1583,1669,1961,2786,2810,2814,2851,3244,3334,3336,3465,3479,3705,3709,3804,3982 'group-renam':1212 'guardrail':3106 'guess':2345 'guidelin':2668 'h':1868 'handl':1603,1755,2466,2857 'hang':3638 'hasn':3717 'head':343 'healthi':3834 'heavili':3917 'heurist':2105 'hh':1653,2197,2200,2214,2217,2885 'highlight':9,2594 'hint':819 'histor':321,1904,2930,3294 'histori':42,1297,1334,1530,2778,3455,3505,3637,4012 'history-digests.jsonl':44,2900,3259,3348 'history.json':43,1013,1031,1511,2077,2089,2114,2788,3220,3343 'home':506,513,889 'home/.baoyu-skills/baoyu-wechat-summary/extend.md':511 'home/.config':507 'honest':3930 'hook':2658 'hour':964,1047 'human':3544 'id':1174,1231,1250,1376,1547,1549,1551,1561,1673,1678,2209,2225,2232,2319,2324,2335,2350,2357,2449,2491,2554,2811,3335,3902 'identifi':1553,1575 'imag':1602,2164,2368,2378,2388,2395,2409,2412,2427,2465,2475,2513,3395,3884,3895,3920 'image-descript':3394 'img':2535,3392,3900 'in-chat':1944,1989,2060 'includ':906,1068,1077,1080,1091,1093,1831,2732,2750,2806,2880,3076,3085,3147,3153,3164,3172,3186,3200 'inclus':1403 'increment':652,1010,1027,1495,2889,2935,3221 'index':3719 'infer':1700,3962,4002 'inform':1631,1773,2399 'init':320,407,415,432,439,3432,3621,3661,3682,3852,4032 'initi':395 'input':128,151,163 'insensit':571 'insid':3862 'inspect':831 'instal':273,283,287,304,309,3422 'instead':2075 'instruct':409 'interleav':2301 'intern':1851,2183 'interpret':956,1406 'invent':2531,3933 'invok':244 'iso':1660 'item':3204 'jackwener/wx-cli':289 'joke':2631 'jq':1352,1369,1372,1375 'json':721,736,841,1132,1157,1290,1310,1347,1531,1780,2809,2906,3425,3443,3462,3473,3476,3506,3530,3724,3777 'jsonl':2942,3041 'jump':2257,2331,2444 'k':1867 'keep':1265 'key':406,555,561,564,572,573,2322,3660,3668,4021 'keyword':1061,1071 'know':3707 'la':339 'label':1905 'larg':1312 'last':962,1009,1045,1507,2822,2844,2869,2913,2963,2990,3017,3161,3344,3849 'last_digest.last':1018 'latest':2941 'layout':3327 'leaderboard':1646,1728,2007,2769,3285 'least':1088 'leav':785,878 'legaci':3618 'length':1353,2015 'lifecycl':3524 'lightweight':1386 'limit':737,1365,1781,2467,3883 'line':566,911,2035,2405,2499,2560,2909,2922,3038,3170,3291,3401 'link':1701 'list':1216,2169,2178,2320,2695,3252,3426,3477 'live':664,668,865,2141 'll':455 'load':1803,1880,1931,2673,2680,3112 'local':16,237,1118,1550,3767,3780,3966,3975 'local-tim':3766 'locat':883,4005 'log':468,3045,3521 'look':1814,1834,3745 'lookup':2931 'low':1772,3800 'low-inform':1771 'ls':338 'machin':3533 'machine-read':3532 'maco':87,421 'maintain':38,2781 'make':2708,3675,3818 'malform':2110 'mani':3313,3318 'match':590,953,1144,1151,1719,1823,1826,2020,2109,2591,3446,3510,3990 'materi':2613 'may':1452,1580,3984,4022 'md':1819,1839,3083,3092,3177,3191,3376,3391 'meaning':1786 'media':1616 'member':3475,3481,3983 'memori':1853 'merg':2315 'messag':183,586,610,730,837,850,1019,1278,1288,1318,1392,1443,1464,1502,1508,1514,1527,1536,1552,1715,1897,1963,1983,2160,2286,2323,2339,2490,2525,2553,2767,2841,2845,2870,2879,2960,2964,2987,2991,3014,3018,3065,3184,3198,3467,3739,3901 'meta':1475 'meta-summari':1474 'methodolog':2133 'min':2253 'minut':2298 'miss':278,1545,2697,3729 'mm':1107,1112,1301,1306,1338,1343,1651,1654,2199,2201,2216,2218,2883,2886,3753,3771 'mm-dd':1650,2882 'mm-hh':2198,2215 'mode':1011,1028,1496,2890,2936,3222 'moderna':2606 'month':1315 'most':3484 'msg':1548,1677 'multipl':203,1142,2108,2382 'must':538,1095,1735,2277 'n':1308,1345,1424,2194,2238,2242,3460,3461,3797,3806 'name':602,947,950,1177,1191,1227,1253,1261,1579,1741,1787,2702,2704,2753,2815,2852,3032,3337,3450 'need':103,268,456,2939,3053,3483,3878 'nest':1681 'never':1327,1746,1888,1928,2932,3858,3998 'new':1248,1252,1260,1971,3037,3160 'next':264 'nicknam':765,1378,1577,1587,1709,1792,3082,3091 'nil':1761 'noisi':3803 'non':332,430,902,3685 'non-default':901 'non-sudo':331,429,3684 'none':640,1150 'normal':26,616,619,857,1073,1078,1092,1916,2733,2799,2807,2917,3026,3077,3148,3165,3173,3187,3354,3365,3370 'normal-vers':2916 'note':1400,1564,3881,3965 'noth':2129,3642,3817,4015 'notic':1968 'npm':286 'nul':1195 'null':1762 'number':179 'number/answer':193 'object':1537,1683,2907 'off-by-on':3757 'offset':1364 'omit':646,913 'one':222,292,487,758,799,855,885,1089,1233,1271,1479,2312,2371,2498,2559,2905,2921,3169,3250,3400,3760 'one-lin':2497,2558,3399 'onlytiancai':3374,3389 'onlytiancai-胡浩':3373,3388 'onto':2385 'opaqu':1599,2515,3887 'open':2649 'oper':3579 'opt':36 'opt-in':35 'option':742,1948,2078,3393 'order':143,228,254,484,701,2162,2641,2925,3815 'origin':1586,1953 'other':2303 'otherwis':631,725,784,912,1770,3954 'output':3535,3537,3947 'outsid':91 'over-list':2176 'overrid':660,1060 'overview':2650 'overwrit':2742,2801 'overwritten':3157 'own':313,582,3615,3827 'owner':351 'pair':766,1114 'paragraph':3288 'pars':518,940,1525,3970 'partial':949 'particip':2254,2259 'pass':1388,1843,1917,1922,2619 'past':1487,2602 'path':89,491,530,656,874,895,923,1127,1170 'pattern':2008,3563 'payload':1326,1590 'peopl':2383 'per':40,47,205,1467,2908,3994 'per-group':39 'per-u':46 'permiss':3611 'permit':3581 'persist':3597 'pick':854,884,1784,2566 'pid':3631,3652 'pile':2384 'pipe':1289 'piped/silent':308 'place':2718 'placehold':1600 'plain':181,558,1592,2500,3402 'plain-text':180 'plus':3872 'point':2541,3905 'pointer':3346 'popul':3911 'portrait':1729,3287 'post':1956 'pre':772,804 'pre-fil':771,803 'prefer':145,428,478,528,920,1268,1465,2308 'prefix':1822 'preload':1889 'prerequisit':242 'present':1543,1685,2354 'preserv':2705 'previous':2426 'primari':1901 'principl':2245 'prior':1988 'prioriti':142,227,483,490,1790 'privaci':3105 'private/group':749 'procedur':3322 'proceed':685,2723 'process':1367 'produc':3868 'product/tool':2703 'profil':1805,1847,1866,1881,1891,1920,1926,2582,2620,3059,3121,3239,3281,3299,3302,3314,3369,3372,3378,3382 'profiles-roast':1925,3301,3377 'program':1759 'project':500,502,657,867,887,1185,3331 'prompt':133 'provid':899 'pull':3463 'pure':2267 'purpos':576,3411 'qualifi':2263 'qualiti':1484 'queri':828,1131,1370,1779,3442 'question':196,204,210,219,782 'quick':3408 'quot':1632,1672,1676,1682,2349,2456,2603,2701,3101,3290 'quote/reply':1670,3950 'r':369,3624 'rais':1434,3805 'rang':634,642,955,1004,1039,1101,1456,1459,2031,2086,2096,2739,2827,2946,2973,3000,3368,3471 'rare':1264,3482 'rather':3931 'raw':1325,2338 're':1438,1975,2293,3590,3774,3812 're-cov':1974 're-fetch':1437,3811 're-filt':3773 're-run':3589 'read':72,517,757,1012,1356,1362,1389,1824,1918,1923,2145,2158,2495,2792,2933,3261 'readabl':3534 'reader':3046 'real':1739 'recent':732,2798,2878,3427 'record':2278,2790,2860 'recoveri':3814 'redirect':1319 'refer':231,1560,1617,2868,3409 'references/output-formats.md':2143,2144,2671,2672 'references/profiles.md':1933,1934,3110,3111,3324,3325 'reflect':2794 'regener':3034 'reinit':4009 'relat':498,1100 'reliabl':2363 'remain':1515 'remark':1584,1791,3451 'remind':526 'renam':1214,1241,1242,2858 'repair':363 'replac':1192 'repli':189,1674,2351,3936 'repo':306 'report':3134,3310 'request':161,944,1059,2095 'requir':408,448,470,580,600,3662,3696 'resolv':1125,1166,1706 'resort':3850 'respect':3898 'restart':3672,3839,4019 'restrict':68,126 'result':514,3789 'retri':3560,3658,3738,3861,4039 'return':399,1442,1453,1532,3641,3700,3740,4014 'revok':1640 'revokemsg':1639 'right':2406 'rm':373,3628,3649 'roast':31,617,858,1063,1069,1081,1094,1832,1842,1921,1927,2618,2627,2751,2756,2892,3086,3154,3201,3303,3359,3379,3380,3386 'roast-on':2891 'roast.md':3306 'root':326,353,501,655,658,861,868,905,1172,1180,1186,1221,3329,3332,3617 'round':2127,2149,2153,2168,2181,2329,2431,2681,2686 'row':3702 'rule':141,1878,2140,2665,3099,3997 'run':105,250,274,384,413,419,466,539,699,1274,1776,2632,2804,2856,2894,2919,3116,3136,3571,3575,3591,3679,3730,3823,3857,3880,4029,4037 'runtim':158,241 'sacrific':2611 'safe':1449 'said':2280 'sandbox':67,96,116,3586 'sanit':1175,1188,1251 'saniti':1667,3415 'sanity-check':1666,3414 'sass':1066 'save':882,921,2726,2777 'say':630,2390,2421,3235,3928 'scan':744,1749,1980 'schema':1528 'scope':492 'search':1159,3726 'section':3074 'see':1601,1932 'seed':3280 'select':140 'self':577,597,693,696,728,811,842,1707,1711,1720,1995 'self-sent':727 'sender':1574,1752,1809,2289,2418 'sens':2709,3819 'sent':729,754,836 'separ':1915,2306 'session':397,524,733,735,746,840,1156,3424,3428,3723 'set':1043,1420 'setup':543,675 'shape':1863,2911 'share':1625,2763 'sharer':1637 'sharpli':1486 'ship':3214 'show':3985 'sign':425 'signal':1985,2249 'silent':551,684 'sinc':1008,1104,1298,1335,1401,3456,3489,3742 'singl':213,218,1283,1767,2734,2789,3356 'single-day':1282 'single-quest':217 'sit':1328 'skeleton':1387,1570,2157,2443,2688,2774 'skill':102,132,381,496,2564,2570,3864,3897 'skill-baoyu-wechat-summary' 'skill.md':2137 'skip':1607,1618,1747,2080,2121,2163 'sleep':4003 'slice':1360 'slip':2130 'small':1280 'sock':3632,3653 'socket':78 'sourc':1902 'source-jimliu' 'specif':991 'specifi':1026,3247 'split':1457,2304 'stabl':1573 'stale':3219,3670,4024 'start':111,379,1023,1052,1228,2074,3635,3656,3736,3847 'starter':666 'stat':1745,3488,3498 'statist':2766 'status':3515,3837 'stay':2134 'step':457,686,795,938,1120,1275,1523,1704,1801,1940,2586,2724,2775,3055,3118,3226,3787 'still':1899 'stop':255,702,3518,3648,3733,3844 'storag':3326 'strict':1914,2273,3044 'string':579,599,635,3748 'strip':1207 'strong':1689 'structur':12,2662 'stuck':3645 'subsequ':330 'substant':2261 'substitut':235,604,1710,1796 'succeed':707 'success':3211 'sudden':4013 'sudo':318,333,367,372,385,431,437,3576,3619,3622,3627,3686,3689,4030 'suffix':1237,2757 'summar':5 'summari':4,51,1476 'support':202,554 'sure':3676 'surfac':261,2050 'surround':1611,2524 'suspend':3786 'switch':2248 'symptom':3557,3564 't09':2955,2982 't10':2836,3009 'target':1257,3243 'tell':279,359,1516,2116,2526,3567,4025 'templat':667,1895 'test':1763 'text':182,559,613,1589,1593,1732,2501,3403 'thread':750 'three':2126 'time':225,542,633,647,674,927,954,1020,1025,1038,1509,2250,2296,2846,2871,2965,2992,3019,3639,3768,3967,3976,3980 'timestamp':1379,1446,1504,1647,2874,3779,3986,4000 'timezon':3761 'titl':1628,2034,2111 'tmpdir':1321 'tmpdir/wx-messages.json':1348,1351,1354 'today':1116,1418,1423 'token':1397 'toler':1544 'tool':129,139,152,175,201 'tool-select':138 'topic':1494,2173,2244,2247,2266,2276,2307,2310,2316,2327,2440,2479,2508,2696,3915 'topic-agent-skills' 'topic-claude-skills' 'topic-codex-skills' 'topic-openclaw-skills' 'topic-switch':2246 'touch':2897 'toward':1744,2175 'trail':1201 'treat':2511 'tri':688,1671 'trigger':2372,3231 'trim':1200,2179 'troubleshoot':3525,3548 'true':108,1070,1079,1098,2808,3596 'two':2309,2779,2782 'txt':2492,2555,3903 'type':574,1665 'typic':1286 'u':48 'uncertain':1703,2107,3961 'uncheck':3206 'uncom':910 'undefin':1766 'under':2773 'uniqu':1751,1808 'unless':1610,1619 'unnecessarili':1399 'unrel':1493 'updat':2853,3057,3078,3087,3095,3122,3178,3192 'upgrad':3674 'us':2527 'usag':2621 'use':14,122,291,522,527,552,717,776,1017,1115,1145,1538,1554,1594,1658,1686,1903,2068,2088,2355,2580,2887,2926,3283,3429,3541,3952,3971,3999 'user':120,127,135,150,162,166,187,267,281,317,361,388,411,442,512,596,607,627,645,752,791,821,898,942,1058,1164,1415,1518,1734,1765,1804,1883,1950,2055,2118,2543,3058,3062,3181,3195,3230,3234,3275,3319,3371,3381,3436,3569,3877,4027 'user-input':149 'user-trigg':3229 'usernam':1137 'valu':562,565,775 'verbatim':2706 'verifi':247,2341,3139,3431 'version':33,276,447,615,621,853,1048,1055,2579,2628,2762,2918,3413,3673,3695 'via':1361,2056 'view/edit':125 'visual':2532,3934 'voic':2663 'walk':2684 'wall':3992 'want':848 'warn':451 'wast':114 'wc':1349 'weav':2503 'wechat':3,6,49,81,417,463,3605,3671,3677,3822,3855,4018,4035 'week':1314,1489 'went':3669 'whatev':806 'whether':2481 'whichev':1555 'whitespac':1204 'whoami':358,370,716,720,3625,3829 'whole':1411 'whose':587,1136,1226,1503,1716 'win':489 'window':3744 'within':3468 'without':2389 'word':1760 'work':1563,1852,2184,3667,3964 'workflow':246,936,937,1955 'worth':1491 'write':890,1856,2435,2461,2518,2640,2642,3297 'written':2187,3145,3151 'wrong':2314,2714,3746 'wrongly-merg':2313 'wx':18,58,64,70,98,271,275,319,334,377,393,396,414,438,445,712,719,734,826,839,1129,1155,1296,1333,1529,1557,1777,2469,2548,3406,3412,3419,3423,3440,3454,3474,3487,3492,3504,3513,3516,3519,3527,3551,3620,3633,3636,3646,3654,3681,3693,3698,3722,3731,3734,3835,3842,3845,3851,3889,3944,4007,4011,4031 'wx-cli':17,57,69,270,392,444,711,1556,2468,2547,3405,3418,3491,3692,3888,3943,4006 'wxid':578,585,589,694,763,812,814,1572,1718,1721,1793,1818,1821,1838,1994,1996,3081,3090,3176,3190,3439,3453 'x':465,2423 'xdg':504,509,888 'xx':1912,2599 'xxx':2037,2237 'yaml':3539 'yes':2079,2494 'yet':1033,3721 'yyy':2241 'yyyi':1106,1111,1300,1305,1337,1342,3752,3770 'yyyy-mm-dd':1105,1110,1299,1304,1336,1341,3751,3769 'yyyy-mm-dd-roast.md':2758 'yyyy-mm-dd_yyyy-mm-dd-roast.md':2760 'zero':1513,3701 'zone':3977,3981 '一句话概括':2207,2223 '一向省钱的':1911 '一向话少的':2598 '上次摘要后没有新消息':1519 '不打包脚本':66 '不要为了':2637 '不要毒舌':1075 '两个版本都要':1084 '之后':2607 '二进制':63 '今天':961 '今天居然':1913 '今天突然爆发':2600 '从上次开始':1005 '但当期素材优先':2636 '共':2193 '再来个毒的':1065 '初始化画像':3237 '历史槽点可做':2629 '历史毒舌语录可以引用或翻新':2635 '参与者':2203,2220 '又双叒叕化身空中直播员':1908 '又双叒叕直播飞行体验':2593 '发言统计':2235 '只要正经的':1072 '可以升级和迭代':2634 '可可苏玛':1877 '可能需要图片上下文的话题':2228 '可读性强的简报':54 '号':989,1002 '号到':998 '命令':65 '回溯画像':3236 '图片':1598,2516 '图片是讨论主体':2234 '天':960,969,974,980 '太可怕了':2414 '宝玉':845,1954 '已跳过生成':1520 '常见话题':1871 '并维护跨次运行的群聊历史与群友画像':55 '底层依赖外部':56 '截图':2401 '把零散的微信群聊记录提炼成结构化':53 '折叠群':3713 '挑衅':1064 '接着上次':1007 '文件':1615,1624 '旅行':1872 '无法写入':3608 '晒单':2400 '最近':958,967,972,978 '最近一个月':981 '月':987,996,1000 '条':2012,2239,2243 '条消息':2195 '来自':1865 '某天':984 '某天到某天':993 '毒舌':32,1062 '消息统计':2002,2004 '生活百科全书':1870 '相亲相爱一家人':2816,2821,3342 '看发型是x':2379 '硬凑':2639 '空中直播员':1869 '笑死':2381 '系统':1638 '经典金句':1875 '继上次':2604 '继续':1006 '美食':1874 '群友历史画像':1864 '群友画像':3073 '群聊精华':2000,2038 '群聊精华提取专家':52 '胡浩':3375,3390 '范围':2067,2069 '表情':1605 '要不要买':2605 '要不要买moderna':1876 '视频':1614 '话题':2229 '话题名称':2202,2219 '话题清单':2192 '资料':2402 '这个看着像':2422 '这周':975 '这是谁':2380 '这次又':2608 '都来一份':1083 '金融':1873 '链接':1621,1623 '锚点':2208,2224,2231","prices":[{"id":"2d1e7763-0b4d-4e42-9deb-db09a1ddd9c5","listingId":"90efd099-67f9-48f5-9999-e4b6afd30437","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"JimLiu","category":"baoyu-skills","install_from":"skills.sh"},"createdAt":"2026-05-14T06:53:26.899Z"}],"sources":[{"listingId":"90efd099-67f9-48f5-9999-e4b6afd30437","source":"github","sourceId":"JimLiu/baoyu-skills/baoyu-wechat-summary","sourceUrl":"https://github.com/JimLiu/baoyu-skills/tree/main/skills/baoyu-wechat-summary","isPrimary":false,"firstSeenAt":"2026-05-14T06:53:26.899Z","lastSeenAt":"2026-05-18T18:52:37.839Z"}],"details":{"listingId":"90efd099-67f9-48f5-9999-e4b6afd30437","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"JimLiu","slug":"baoyu-wechat-summary","github":{"repo":"JimLiu/baoyu-skills","stars":18712,"topics":["agent-skills","claude-skills","codex-skills","openclaw-skills"],"license":null,"html_url":"https://github.com/JimLiu/baoyu-skills","pushed_at":"2026-05-18T02:11:02Z","description":null,"skill_md_sha":"5ed238e83646e3e00c5a8885342350dc570fbeb0","skill_md_path":"skills/baoyu-wechat-summary/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/JimLiu/baoyu-skills/tree/main/skills/baoyu-wechat-summary"},"layout":"multi","source":"github","category":"baoyu-skills","frontmatter":{"name":"baoyu-wechat-summary","description":"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) and per-user profiles 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."},"skills_sh_url":"https://skills.sh/JimLiu/baoyu-skills/baoyu-wechat-summary"},"updatedAt":"2026-05-18T18:52:37.839Z"}}