wechat · diff

git:20261006.520c365 to git:20261006.1cd4232

63 added, 124 removed. Audit A to A.

---
name: wechat
- description: 在本地查询、导出微信 4.1+ 聊天记录为 AI 可读文本 —— 支持双人会话、群聊、以及按消息量排名的重要联系人扫描。当用户想导出、搜索或分析自己的微信聊天记录,或为其他 skill(前任.skill / 同事.skill 等)准备聊天记录原材料时使用。
+ description: 在本地查询、导出微信 4.1+ 聊天记录为 AI 可读文本 —— 支持双人会话、群聊、以及按消息量排名的重要联系人排名。当用户想导出、搜索或分析自己的微信聊天记录,或为其他 skill(前任.skill / 同事.skill 等)准备聊天记录原材料时使用。
---
# 微信聊天记录导出
- 在本地把微信 4.1+ 的聊天记录构建为可查询、可导出的 AI 可读文本。所有操作在本机运行,数据不离机。
+ 把微信 4.1+ 的聊天记录构建为本地可读数据库,再导出为 AI 可读文本。全程本机运行,数据不离机。
+ 所有功能都是插件自带二进制 `dist\core.exe` 的子命令;完整参数用 `<命令> --help` 查看。
- 所有功能都是密封二进制的子命令(`preflight` / `setup` / `find_*` / `export_*`)。操作参考见 `reference/db-schema.md`。
+ > **所有命令都是 PowerShell。** 若第一条命令被权限提示拦住,**不要**改用 Bash 重写(`&` 与 `$env:`
+ > 在 Bash 下不成立),而是告诉用户:「这个插件的命令要用 PowerShell 跑,请在权限提示里选『允许』
+ > (有『始终允许』就选它)。」获准后从第 1 步重新开始。
- ## 前置检查(每次会话第一步)
+ ## 1. 前置检查(每次会话第一步)
```powershell
- powershell -NoProfile -ExecutionPolicy Bypass -File "$env:CLAUDE_PLUGIN_ROOT\bootstrap.ps1" -Preflight
+ & "$env:CLAUDE_PLUGIN_ROOT\dist\core.exe" preflight
```
- 它先确保插件目录里有 `_common.exe`(首次使用会从 GitHub Release 下载约 7 MB 并校验 SHA-256,
- 可能要几十秒),再运行 `preflight`。下载失败时它会打印原因(通常是连不上 github.com),转述给用户。
- 之后本会话里的其他命令直接调用 `& "$env:CLAUDE_PLUGIN_ROOT\_common.exe" <命令>`。
-
- > **本 skill 的每一条命令都是 PowerShell。** 全新的工作目录默认不带 PowerShell 执行权限,
- > 第一条命令就会被权限提示拦住。这时**不要**改用 Bash 重写(`&` 调用与 `$env:` 语法在 Bash 下
- > 不成立),也不要放弃,而是用自然语言告诉用户:
- >
- > > 这个插件的命令都要用 PowerShell 跑。请在弹出的权限提示里选「允许」——
- > > 如果有「始终允许 / 不再询问」,选它就不会再被打断。也可以用 `/permissions` 管理。
- >
- > 得到许可后从 `preflight` 重新开始。
-
- 记住结尾打印的 `BUILT_DB_DIR=` / `ARTIFACTS_DIR=`,下文的 `<BUILT_DB_DIR>` / `<ARTIFACTS_DIR>` 都用它。
- 然后**只看 `NEXT_STEP=`**:
+ 看末尾的 `NEXT_STEP=`:
| `NEXT_STEP` | 做什么 |
|---|---|
- | `ready` | 数据已就绪,按下方「按意图选择流程」继续 |
- | `setup` | 进入 Step 0 |
- | `wait` | 上一次的准备窗口还开着:请用户在那个窗口里完成(或关掉它),再重跑 `preflight` |
- | `reinstall` | 插件文件缺失(多半被杀毒软件删了):请用户在杀毒软件里放行后重新安装插件 |
-
- `SETUP_STATUS=` 若是 `interrupted` / `cancelled` / `failed:*`,preflight 会打印原因,转述给用户即可。
-
- ### Step 0:准备数据(`setup`)
+ | `ready` / `setup` | 进入第 2 步 |
+ | `reinstall` | 插件文件缺失(多半被杀毒软件删了):请用户放行后重新安装插件 |
- 一条命令完成全部准备:它会弹出**一个**管理员窗口,在里面按需抓取方案清单(`make_json`),
- 再构建数据库(`make_db`),并**等窗口跑完才返回**。
+ ## 2. 准备数据(每个导出请求前必跑)
- 先用自然语言告诉用户(`SOLUTION=missing` 时用第一段,`present` 时用第二段):
+ **每个导出请求开始前都先跑一次 `setup`,即使 `NEXT_STEP=ready`**:数据库是快照,
+ 不重建就没有新消息。同一请求里连续导出多个对象,开头跑一次即可。
- > 接下来会弹出 Windows 的管理员权限提示,请点「是」。窗口打开后,请切到微信,**逐个点开聊天
- > (新的旧的都点)、通讯录、收藏、朋友圈,并搜索一次**;等窗口里「已捕获」的计数不再增长,
- > 回到那个窗口按 **Enter**。之后数据库会自动构建,窗口会自己关掉。
+ `setup` 从已登录的微信进程里现场恢复账号方案并重建数据库;方案只在内存里、不落盘,所以需要微信在运行且已登录
+ (无需管理员权限)。先告诉用户:
- > 接下来会弹出 Windows 的管理员权限提示,请点「是」。这次只需要重建数据库,窗口会自己跑完。
+ > 我先刷新一下数据:从你已登录的微信里重建可读数据库。保持微信登录即可,无需操作,稍等片刻。
- 然后用 PowerShell 工具**后台运行**(`run_in_background`,它会一直等到窗口结束):
+ 然后**后台运行**(`run_in_background`),等完成通知:
```powershell
- & "$env:CLAUDE_PLUGIN_ROOT\_common.exe" setup
+ & "$env:CLAUDE_PLUGIN_ROOT\dist\core.exe" setup
```
- 结束时会通知你。看最后一行 `SETUP_RESULT=`:
-
- | `SETUP_RESULT` | 含义 / 处理 |
+ | 最后一行 `SETUP_RESULT=` | 处理 |
|---|---|
- | `done` | 完成。重跑 `preflight`,应为 `NEXT_STEP=ready` |
- | `cancelled` | 用户在 UAC 提示里点了「否」。问一下是否要再试 |
- | `interrupted` | 窗口在完成前被关掉。问清楚后再试 |
- | `failed:make_json` / `failed:make_db` | 报错留在那个窗口里,请用户把窗口内容告诉你 |
- | `error` | 命令本身打印了原因(如微信没在运行、已有窗口在跑),照着转述 |
-
- - 想拿到**最新消息**:再跑一次 `setup` 即可(已有方案清单时只重建数据库)。
- - 新消息库没有方案(preflight 里出现 0 张表、或微信更新后建库失败):用 `setup --refresh` 重新抓取方案清单。
- - **不要**在当前会话里直接运行 `make_json` / `make_db`:它们需要管理员权限,在非终端环境下输出会被完全缓冲,看起来就是卡死。一律走 `setup`。
+ | `done` | 重跑 preflight,确认 `NEXT_STEP=ready` 后进入第 3 步 |
+ | `not_running` | 请用户打开电脑版微信并登录,完成后重跑 `setup` |
+ | `no_key` | 微信多半没登录:请用户确认已登录后重跑 `setup` |
+ | `no_db_dir` | 找不到微信数据目录:请用户在 微信设置 → 文件管理 找到 `...\xwechat_files\<wxid>\db_storage`,设为环境变量 `WECHAT_DB_DIR` 后重跑 |
+ | `build_failed` | 转述输出里「导出所需的库构建失败」那一行,请用户保持微信登录后重跑 `setup` |
+ | `error` | 插件不完整:请用户重新安装插件 |
- > Windows Defender 等杀毒软件可能报警,需要用户手动放行。
+ 没拿到 `done` 时**不要**用旧数据导出,除非用户明确同意。杀毒软件(如 Windows Defender)可能报警,需要用户手动放行。
- ## 按意图选择流程
+ ## 3. 按意图导出
- | 用户想要… | 用哪个流程 |
+ | 用户想要… | 流程 |
|---|---|
- | 导出 / 搜索与某个人的双人聊天 | **A. 双人会话** |
- | 导出 / 总结某个群 | **B. 群聊** |
- | 知道"和谁聊得最多" / 重要联系人排名 | **C. 联系人扫描** |
-
- 导出结果若要做成规避微信折叠的中文总结,接着用 `wechat-summary` skill。
-
- ---
-
- ## A. 双人会话
-
- ### A1 — 查找联系人 + 生成 sender_map
-
- ```powershell
- & "$env:CLAUDE_PLUGIN_ROOT\_common.exe" find_private <关键词> --built-db-dir "<BUILT_DB_DIR>"
- ```
-
- 输出:wxid、消息表名、各库消息量与日期范围、sender_map 推断结果(含采样消息),以及一条即用的 `export_private` 命令。
-
- ### A2 — 与用户核对 sender_map
-
- find_private 会为每个库打印推断出的「用户 / 对方」及其样本消息。**用自然语言和用户确认**,例如:
+ | 与某个人的双人聊天 | A |
+ | 某个群的聊天 | B(要做成发回微信群的中文总结,导出后接 `wechat-summary` skill) |
+ | 和谁聊得最多 / 联系人排名 | C |
+ | 只给了一个名字,没说是人还是群 / 只想看有哪些匹配 | 先 `find`(见下) |
- > 我从消息内容推断:`my_id=2`(样本「晚点到」「在开会」)是你,`other_id=7`(样本「好的」「路上注意」)是对方。对吗?
+ 时间参数(A、B):**不加时间参数 = 最近 1 天**(昨天 0 点至今)。起点三选一:`--days N` | `--since YYYY-MM-DD` |
+ `--all`(全部历史,用户要「全部」「完整」「所有」聊天记录时用);`--until YYYY-MM-DD`(**包含当天**)可与任一组合。
+ 时区默认 GMT+8,用 `--tz` 调整。`--threshold 秒数`:间隔超过它就另起一个时间段标题(默认 3600)。
- - 用户确认 → 进入 A3。
- - 用户说反了 → 编辑对应的 `<ARTIFACTS_DIR>\sender_map_<名字>.json`,把该库条目的 `my_id` 与 `other_id` 对调,再进入 A3。
+ 两种导出的发送者都直接取自微信的记录:用户自己为 `【用户】`,系统消息(撤回、拍一拍等)为 `【系统】`;
+ 双人会话的对方为 `【对方】`,群成员显示昵称,无法识别的为 `【?】`。
- ### A3 — 运行导出命令
+ ### A. 双人会话 / B. 群聊
- **直接运行 `find_private` 打印的那条导出命令**(可执行文件路径、参数、重定向都已拼好),
- 需要时在重定向前追加时间范围参数。它的形如:
+ `<关键词>` 取用户对此人 / 此群的称呼(匹配备注名或微信昵称的任一部分):
```powershell
- & <插件目录>\_common.exe export_private `
- --db <各库路径…> --table <Msg_...> --sender-map '<ARTIFACTS_DIR>\sender_map_<名字>.json' `
- > '<ARTIFACTS_DIR>\chat_<名字>.txt' 2> '<ARTIFACTS_DIR>\chat_<名字>.err.txt'
+ & "$env:CLAUDE_PLUGIN_ROOT\dist\core.exe" export_private <关键词> [时间参数] # A
+ & "$env:CLAUDE_PLUGIN_ROOT\dist\core.exe" export_chatroom <关键词> [时间参数] # B
```
- stdout 与 stderr **分别**落盘,内容不进上下文。**不要改成 `2>&1`**:Windows PowerShell 5.1 会把
- 原生程序的 stderr 包装成 `NativeCommandError` 写进聊天文件开头,让导出结果看起来像报错。
-
- 时间范围(默认全量):`--days N` | `--since YYYY-MM-DD` | `--since … --until YYYY-MM-DD`。其中 `--until` **包含当天**。
-
- ---
-
- ## B. 群聊
-
- 群聊导出会自动处理发送者映射;少数无法识别的发送者会显示为 `【?】`。
-
- ### B1 — 查找群
-
- ```powershell
- & "$env:CLAUDE_PLUGIN_ROOT\_common.exe" find_chatroom <关键词> --built-db-dir "<BUILT_DB_DIR>"
- ```
+ 导出命令自己把聊天内容写进文件,屏幕上只有进度和结果行。按最后一行 `EXPORT_RESULT=` 处理:
- ### B2 — 运行导出命令(默认最近 1 天)
+ | `EXPORT_RESULT=` | 处理 |
+ |---|---|
+ | `done` | 完成:把 `OUTPUT=` 的文件路径告诉用户 |
+ | `ambiguous` | 输出列出了全部匹配 `[序号]`:把名称、昵称 / 备注和消息分布列给用户选,再在**同一条命令**末尾加 `--pick <序号>` 重跑 |
+ | `not_found` | 告诉用户没找到,请换一个关键词(备注名或昵称的一部分) |
+ | `empty` | 告诉用户该会话在该时间段内没有消息 |
- 直接运行 `find_chatroom` 打印的导出命令即可,形如:
+ #### 先 `find`
```powershell
- & "$env:CLAUDE_PLUGIN_ROOT\_common.exe" export_chatroom `
- --db <单个库路径> --table <Msg_...> `
- --contact-db "<BUILT_DB_DIR>\contact\contact.db" `
- --id-map "<ARTIFACTS_DIR>\id_map_<群名>.json" `
- > "<ARTIFACTS_DIR>\chat_<群名>.txt" 2> "<ARTIFACTS_DIR>\chat_<群名>.err.txt"
+ & "$env:CLAUDE_PLUGIN_ROOT\dist\core.exe" find <关键词>
```
- 范围:`--days N` | `--since` | `--until`。其中 `--until` **包含当天**。`--contact-db` 存在时自动生成 / 更新 id_map,后续导出可省略该参数。
+ 同时搜联系人和群聊,分两段列出匹配及消息分布,段内 `[序号]` 即对应导出命令的 `--pick`。按末尾两行处理:
- ---
+ | `PRIVATE_MATCHES=` / `CHATROOM_MATCHES=` | 处理 |
+ |---|---|
+ | 都是 0 | 同 `not_found` |
+ | 只有一个非 0 | 用该段标题里的导出命令(A 或 B)按上面流程导出 |
+ | 都非 0 | 把两段的名称列给用户选,再用所选段的导出命令加 `--pick <序号>` 导出 |
- ## C. 联系人扫描
+ ### C. 联系人排名
```powershell
- & "$env:CLAUDE_PLUGIN_ROOT\_common.exe" find_contact <关键词> --built-db-dir "<BUILT_DB_DIR>"
-
- & "$env:CLAUDE_PLUGIN_ROOT\_common.exe" export_contacts `
- --contact-db "<BUILT_DB_DIR>\contact\contact.db" `
- --msg-dbs "<BUILT_DB_DIR>\message\message_*.db" `
- > "<ARTIFACTS_DIR>\contacts.txt" 2> "<ARTIFACTS_DIR>\contacts.err.txt"
+ & "$env:CLAUDE_PLUGIN_ROOT\dist\core.exe" export_contacts
```
`--threshold N`(最低消息数,默认 50)| `--include-chatrooms`(同时列出群聊)。
-
- ---
+ 结果行同上:`done` → 告诉用户 `OUTPUT=` 的路径;`empty` → 没有达到阈值的联系人。
## 硬性规则
- - `export_*` 的输出**必须**重定向到文件:`> "<ARTIFACTS_DIR>\xxx.txt" 2> "<ARTIFACTS_DIR>\xxx.err.txt"`,
- 禁止裸跑让内容进上下文。**不要用 `2>&1`**,它会把 PowerShell 的 `NativeCommandError` 噪声写进聊天文件。
- - `find_*` 的输出可以正常读取、展示给用户。
- - 准备 / 更新数据一律用 `setup`(后台运行),禁止在当前会话里直接运行 `make_json` / `make_db`。
- - 每次会话先跑 `bootstrap.ps1 -Preflight`;之后统一用 `& "$env:CLAUDE_PLUGIN_ROOT\_common.exe" <命令>` 调用。
- `_core.exe` 由 `setup` 在需要时自动下载并内部使用,不要直接调。
- - 不要手写相对 `output\` 路径;路径优先取 `preflight` / `find_*` 打印出的绝对路径,`find_*` 打印的导出命令可以原样运行。
- - 时区默认 GMT+8,`--tz` 调整。
+ - 导出命令**不要**加重定向(`>`、`2>`、`2>&1`),也不要传 `--out`:文件路径由命令自己决定并打印在 `OUTPUT=`。
+ - 导出文件不要读进上下文,除非下一步(如 `wechat-summary`)需要它的内容。
+ - 准备 / 刷新数据一律用后台 `setup`。