Files
wx-cli/SKILL.md
T
jakevinandBobbyCat 9d5a78ac04 docs(macOS): document TCC csreq invalidation after re-signing WeChat (#48)
macOS TCC binds permissions to (bundle id, csreq) where csreq encodes
the app's code signature. `codesign --force --deep --sign -` on
WeChat changes the csreq, silently invalidating every existing TCC
grant for com.tencent.xinWeChat — yet System Settings still paints
each toggle as ON because the UI only checks bundle id, hiding the
drift. WeChat then reprompts for screen recording / camera /
microphone / file access despite "looking allowed".

Three doc-only updates, no code changes:

- README.md quick start: add the `tccutil reset` loop right after the
  codesign step, plus a one-line callout pointing at the deep-dive
  section.
- SKILL.md macOS init flow: same loop in the agent-readable order, so
  agents executing the steps don't skip it.
- docs/macos-permission-guide.md: new section 五 with first-principles
  root cause, the reset loop, the macOS 26 "录屏与系统录音 / 仅系统
  录音" UI split footgun, and ad-hoc signature verification.

Builds on the BobbyCat PR #29 — keeps the symptom description and the
macOS 26 UI split note, expands scope from ScreenCapture-only to all
TCC services that re-signing actually breaks (Camera / Microphone /
AppleEvents / AddressBook / Documents / Downloads / Desktop), drops
the misleading TCC.db sqlite query (path varies by macOS version, can
need FDA, and is no more useful than just trying WeChat's screenshot
again), and explicitly leaves the reset as a manual step rather than
auto-running it from `wx init` because it would wipe currently-working
grants.

Co-authored-by: BobbyCat <114374951+BobbyCats@users.noreply.github.com>
2026-05-14 15:13:50 +08:00

9.1 KiB
Raw Blame History

name, description
name description
wx-cli wx-cli — 从本地微信数据库查询聊天记录、联系人、会话、收藏等。用户提到微信聊天记录、联系人、消息历史、群成员、收藏内容时,使用此 skill 安装并调用 wx-cli。

wx-cli

Triggers

  • 查微信聊天记录
  • 微信消息历史
  • 微信联系人
  • 微信群成员
  • 微信群昵称 / 群名片
  • 微信收藏
  • wechat history / messages / contacts
  • wx-cli
  • 帮我看看微信里
  • 搜索微信消息

Prerequisites

  • macOS(Apple Silicon / Intel)或 Linux
  • 微信桌面版 4.x 已安装并登录
  • Node.js >= 14(npm 安装方式)或 curl(shell 安装方式)
  • 首次 wx init 需要 sudo(内存扫描提取密钥)

安装

方式一:npm(推荐)

npm install -g @jackwener/wx-cli

方式二:curl

curl -fsSL https://raw.githubusercontent.com/jackwener/wx-cli/main/install.sh | bash

安装后验证:

wx --version

初始化(首次使用,只需一次)

macOS(必须按顺序执行)

第一步:对 WeChat 重新签名(只需做一次,WeChat 更新后需重做)

codesign --force --deep --sign - /Applications/WeChat.app

如果报错 signature in use 或某个 dylib 签名损坏,先修复再签名:

codesign --remove-signature "/Applications/WeChat.app/Contents/Frameworks/vlc_plugins/librtp_mpeg4_plugin.dylib"
codesign --force --deep --sign - /Applications/WeChat.app

第二步:清理 WeChat 在 macOS TCC 隐私数据库里的旧授权记录(重签名后必做)

macOS TCC 按 bundle id + csreq 联合校验权限;csreq 编码自代码签名。重签名后旧 csreq 和新签名不再匹配,旧授权记录会 silent 失效(System Settings 仍把开关画成"已允许",运行时实际拒绝)。把 WeChat 在 TCC 里的旧记录抹掉,让 macOS 在下次微信请求权限时按新签名重新生成 csreq:

tccutil reset ScreenCapture com.tencent.xinWeChat   # 截图 / 屏幕共享
tccutil reset Camera com.tencent.xinWeChat          # 视频通话 / 扫码
tccutil reset Microphone com.tencent.xinWeChat      # 语音消息 / 通话
tccutil reset AppleEvents com.tencent.xinWeChat     # 自动化 / 输入法
tccutil reset AddressBook com.tencent.xinWeChat     # 通讯录
tccutil reset SystemPolicyDocumentsFolder com.tencent.xinWeChat
tccutil reset SystemPolicyDownloadsFolder com.tencent.xinWeChat
tccutil reset SystemPolicyDesktopFolder com.tencent.xinWeChat

tccutil 对没有授权过的 service 会报 "No such bundle identifier",是 no-op,不影响其他 service 的 reset。

第三步:重启 WeChat

killall WeChat && open /Applications/WeChat.app
# 等待微信完全登录后再继续

之后微信触发权限请求时按 GUI 提示重新允许即可。在 macOS 26 上,把 WeChat 加进 隐私与安全 → 录屏与系统录音 的上半区,不要只勾下半区的"仅系统录音"——后者不能授予截图权限。

第四步:初始化

sudo wx init

Linux

sudo wx init

wx init 会自动:

  1. 检测微信数据目录
  2. 扫描进程内存,提取所有数据库密钥
  3. 写入 ~/.wx-cli/config.json

初始化完成后,后续所有命令无需 sudo,daemon 在首次调用时自动启动。


命令速查

所有命令默认输出 YAML,更省 token & 易读;--json 可切换为 JSON(方便 jq 处理等)。

会话与消息

# 最近 20 个会话
wx sessions

# 有未读消息的会话
wx unread

# 只看真人(私聊 + 群聊)的未读,过滤公众号与折叠入口
wx unread --filter private,group

# 上次检查后的新消息(增量)
wx new-messages
wx new-messages --json          # JSON 输出,适合 agent 解析

# 聊天记录(支持昵称/备注名)
wx history "张三"
wx history "张三" -n 2000
wx history "AI群" --since 2026-04-01 --until 2026-04-15 -n 100

# 全库搜索
wx search "关键词"
wx search "关键词" -n 500
wx search "会议" --in "工作群" --since 2026-01-01

history / search / export 都支持 -n / --limit 指定返回条数。默认值只是为了避免一次输出过多,不是硬上限。

sessions / unread / history / new-messages / stats 的输出都带 chat_type 字段,agent 可据此分流:

取值 含义 username 特征
private 真人私聊 wxid_* 或自定义短号
group 群聊 *@chatroom
official_account 公众号 / 订阅号 / 服务号 / 系统通知 gh_*、biz_*、mphelper、qqsafe、@opencustomerservicemsg
folded 折叠入口(订阅号折叠、折叠群聊的聚合条目) brandsessionholder、@placeholder_foldgroup

wx unread --filter 支持 private / group / official / folded / all,逗号分隔多选。默认 all。

群聊消息里的 last_sender、sender 和 stats.top_senders 会优先显示群昵称(群名片)。如果本地数据库没有群昵称,再回退到联系人备注、微信昵称或 username。

引用消息(appmsg type=57)在 history / search / new-messages 输出里会展开为两行:第一行是当前回复,第二行以 ↳ 开头显示被引用原文,例如:

[引用] 当前回复
  ↳ 发送者: 被引用内容

--type link / --type file 会覆盖微信 appmsg 的链接、文件、合并聊天记录和引用消息等变体;search --type link 也会匹配解压并格式化后的引用原文。

联系人与群组

# 联系人列表 / 搜索
wx contacts
wx contacts --query "李"

# 群成员列表
wx members "AI交流群"

wx members --json 每个成员包含:

  • username:微信内部 username
  • display:推荐展示名,优先使用群昵称
  • contact_display:联系人备注或微信昵称
  • group_nickname:群昵称;没有记录时为空字符串
  • is_owner:是否群主

Agent 展示群成员时优先用 display。需要区分群昵称和联系人名时,再读取 group_nickname 与 contact_display。

朋友圈(SNS)

三个命令,作用各不同:

# 1) 互动通知(点赞 / 评论,默认仅未读)
wx sns-notifications
wx sns-notifications --include-read --since 2026-04-01 -n 100

# 2) 时间线:浏览本地缓存的朋友圈帖子
wx sns-feed                                    # 近 20 条
wx sns-feed --user "张三"                      # 只看某人
wx sns-feed --since 2026-04-01 --until 2026-04-18 -n 100

# 3) 全文搜索:在正文里找关键词
wx sns-search "关键词"
wx sns-search "婚礼" --user "李四" --since 2023-01-01 -n 50

字段区分:

  • sns-notifications 返回"通知"条目:type(like/comment)、from_nickname、content(评论正文,点赞为空)、feed_preview + feed_author(对应的原帖)
  • sns-feed / sns-search 返回"帖子"条目:author、content(朋友圈正文)、media、media_count(图片/视频数)、location、timestamp;media 字段含每张图的 url/thumb/key/token/md5/enc_idx/size,供下游做图片代理或离线渲染。media_count = media.len(),按 DOM 解析的合法 <media> 子节点计数(malformed XML 返回 0)

只保存你本地刷到过的朋友圈(微信 app 按需下载)。没刷到过的帖子不在本地,任何命令都拿不到。

收藏与统计

# 全部收藏
wx favorites

# 按类型筛选:text / image / article / card / video
wx favorites --type image

# 搜索收藏内容
wx favorites --query "关键词"

# 聊天统计(发言人、消息类型、活跃时段)
wx stats "AI群"
wx stats "AI群" --since 2026-01-01

导出

# 导出为 Markdown(默认)
wx export "张三" --format markdown -o chat.md
wx export "张三" -n 2000 --format markdown -o chat.md

# 导出为 JSON
wx export "AI群" --since 2026-01-01 --format json -o chat.json

Daemon 管理

wx daemon status
wx daemon stop
wx daemon logs --follow

Agent 使用建议

查询结果需要程序处理时,统一加 --json:

wx sessions --json
wx new-messages --json
wx search "关键词" --json
wx history "张三" --json -n 50

CHAT 参数支持昵称、备注名、微信 ID,模糊匹配。不确定准确名称时,先用 wx contacts --query 搜索。


数据文件位置

~/.wx-cli/
├── config.json       # 配置
├── all_keys.json     # 数据库密钥(敏感,勿分享)
├── daemon.sock       # Unix socket
├── daemon.pid / .log
└── cache/            # 解密后的数据库缓存

常见问题

微信重启后密钥失效:重新运行 sudo wx init --force(微信必须正在运行)。

daemon 无响应:wx daemon stop 后重新调用任意命令自动重启。

找不到聊天:用 wx contacts --query 确认昵称/备注名,或用微信 ID 直接查询。

为什么只能获取 500 条消息?:这是默认输出条数,不是硬限制。显式传 -n 即可,例如 wx history "张三" -n 2000 或 wx export "张三" -n 2000 -o chat.md。