weflow-cli 1.15.1 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +59 -1
  2. package/OPERATIONS.md +16 -1
  3. package/README.en.md +21 -2
  4. package/README.md +34 -6
  5. package/bin/weflow-cli.ts +389 -6
  6. package/dist/bin/weflow-cli.js +422 -8
  7. package/dist/bin/weflow-cli.js.map +1 -1
  8. package/dist/src/core/ntCore.d.ts +47 -0
  9. package/dist/src/core/ntCore.d.ts.map +1 -1
  10. package/dist/src/core/ntCore.js +24 -0
  11. package/dist/src/core/ntCore.js.map +1 -1
  12. package/dist/src/services/assistantService.d.ts +8 -1
  13. package/dist/src/services/assistantService.d.ts.map +1 -1
  14. package/dist/src/services/assistantService.js +47 -8
  15. package/dist/src/services/assistantService.js.map +1 -1
  16. package/dist/src/services/assistantTools.d.ts +8 -0
  17. package/dist/src/services/assistantTools.d.ts.map +1 -1
  18. package/dist/src/services/assistantTools.js +67 -11
  19. package/dist/src/services/assistantTools.js.map +1 -1
  20. package/dist/src/services/configService.d.ts.map +1 -1
  21. package/dist/src/services/configService.js +3 -2
  22. package/dist/src/services/configService.js.map +1 -1
  23. package/dist/src/services/cursorProbe.d.ts +44 -0
  24. package/dist/src/services/cursorProbe.d.ts.map +1 -0
  25. package/dist/src/services/cursorProbe.js +183 -0
  26. package/dist/src/services/cursorProbe.js.map +1 -0
  27. package/dist/src/services/qchatImport.d.ts +89 -0
  28. package/dist/src/services/qchatImport.d.ts.map +1 -0
  29. package/dist/src/services/qchatImport.js +273 -0
  30. package/dist/src/services/qchatImport.js.map +1 -0
  31. package/dist/src/services/setupVenv.d.ts +43 -0
  32. package/dist/src/services/setupVenv.d.ts.map +1 -0
  33. package/dist/src/services/setupVenv.js +198 -0
  34. package/dist/src/services/setupVenv.js.map +1 -0
  35. package/dist/src/utils/python.d.ts +10 -0
  36. package/dist/src/utils/python.d.ts.map +1 -1
  37. package/dist/src/utils/python.js +27 -4
  38. package/dist/src/utils/python.js.map +1 -1
  39. package/docs/DATA_CONTRACT.md +25 -0
  40. package/docs/DECISIONS.md +92 -30
  41. package/docs/FUNCTIONAL-IMPROVEMENT-SPEC.md +365 -365
  42. package/docs/HEALTH-CHECK.md +104 -104
  43. package/docs/JEV/345/272/224/347/224/250/346/226/275/345/267/245/346/226/207/346/241/243.md +310 -310
  44. package/docs/NEXT_ACTIONS.md +236 -236
  45. package/docs/NPM-PUBLISH.md +130 -130
  46. package/docs/POSITIONING.md +68 -68
  47. package/docs/PROJECT_STATE.md +6 -3
  48. package/docs/REPLAY.md +169 -0
  49. package/docs/SYNC_CONTRACT.md +197 -180
  50. package/package.json +89 -88
  51. package/requirements-3x.txt +4 -4
  52. package/requirements-voice.txt +15 -15
  53. package/resources/js/graph3d/NOTICE.txt +35 -35
  54. package/resources/js/graph3d/d3-binarytree.min.js +2 -2
  55. package/resources/js/graph3d/d3-dispatch.min.js +2 -2
  56. package/resources/js/graph3d/d3-force-3d.min.js +2 -2
  57. package/resources/js/graph3d/d3-octree.min.js +2 -2
  58. package/resources/js/graph3d/d3-quadtree.min.js +2 -2
  59. package/resources/js/graph3d/d3-timer.min.js +2 -2
  60. package/resources/js/graph3d/three.min.js +6 -6
  61. package/resources/js/graph3d/viewer2d.js +550 -448
  62. package/resources/panel/quick-menu.cjs +197 -197
  63. package/scripts/_utils.py +1338 -1338
  64. package/scripts/article_notes.py +423 -423
  65. package/scripts/bonds.py +11 -0
  66. package/scripts/chat_notes.py +86 -3
  67. package/scripts/check_readme_commands.py +427 -426
  68. package/scripts/contact_schema.py +339 -339
  69. package/scripts/create_reading_notes.py +11 -11
  70. package/scripts/daily_task.ps1 +213 -177
  71. package/scripts/fav_notes.py +321 -321
  72. package/scripts/graph_2d.py +156 -151
  73. package/scripts/graph_3d.py +672 -646
  74. package/scripts/health_check.py +473 -473
  75. package/scripts/imported_chats.py +68 -0
  76. package/scripts/install_tasks.ps1 +105 -91
  77. package/scripts/leads.py +179 -0
  78. package/scripts/network.py +206 -206
  79. package/scripts/nt_decrypt.py +135 -1
  80. package/scripts/on_this_day.py +178 -178
  81. package/scripts/opinion_timeline.py +138 -138
  82. package/scripts/promises.py +185 -185
  83. package/scripts/replay.py +803 -0
  84. package/scripts/run_hidden.vbs +25 -0
  85. package/scripts/semantic_search.py +73 -5
  86. package/scripts/user_notes.py +315 -315
  87. package/scripts/voice_transcribe.py +139 -139
  88. package/scripts/watch_issues.py +212 -212
  89. package/scripts/watch_mail.py +131 -131
  90. package/src/core/ntCore.ts +59 -0
  91. package/src/services/assistantService.ts +48 -8
  92. package/src/services/assistantTools.ts +73 -10
  93. package/src/services/configService.ts +3 -2
  94. package/src/services/cursorProbe.ts +222 -0
  95. package/src/services/qchatImport.ts +327 -0
  96. package/src/services/setupVenv.ts +238 -0
  97. package/src/services/syncService.ts +363 -363
  98. package/src/services/syncState.ts +275 -275
  99. package/src/services/wechatMedia.ts +166 -166
  100. package/src/utils/python.ts +33 -4
package/CHANGELOG.md CHANGED
@@ -17,7 +17,65 @@ purpose** - a hand-written "latest is X" is exactly the claim that goes stale he
17
17
 
18
18
  All notable user-facing changes are recorded here. This project follows [Semantic Versioning](https://semver.org/).
19
19
 
20
- ## 1.15.0
20
+ ## 1.17.0
21
+
22
+ - **`sync cursor-probe`:稳定游标从"一句 false"变成一条看得见的路径(D-027)。**
23
+ `capabilities --json` 新增 `cursorReadiness`(五条判据 × 四个消息后端的代码事实),
24
+ `sync cursor-probe --json` 实测 NT 数据侧——schema 全量检查、身份有界采样(自带
25
+ `exhaustive: false`)。本机实测:211 张表 0 缺列、采样 5,398 行全部带非零 server_id 且
26
+ 0 重复;`stableCursor` 仍为 false,差的在哪、下一块是什么,逐条摊开给下游看。
27
+
28
+ - **`weflow-cli setup`:一条命令装好 Python 环境(自管 venv)。** 在 `~/.weflow-cli/venv`
29
+ 建虚拟环境并安装依赖,之后所有 Python 工作流优先用它——PATH 上只有商店占位 python
30
+ (exit 9009)的那类 issue 从根上消掉。Windows 上自动用 `sqlcipher3-wheels` 预编译轮
31
+ (`sqlcipher3-binary` 根本没有 Windows 发行版);两段式(`--dry-run` 计划 / `--yes` 执行),
32
+ pip 瞬时网络失败重试一次,装完验证 `import sqlcipher3` 与运行时确实优先 venv。
33
+
34
+ - **2D 概念图谱:点一条边看它凭什么连着。** 每条边算出两页 `## 来源` 的交集(共同来源卡片),
35
+ 点边高亮并列出;没有共同来源的边如实说明"来自页面正文里的 [[链接]]"。每边最多带 2 个名字
36
+ (页面体积有界),证据只进页面载荷——布局缓存键不变,旧坐标不作废。3D 不带。
37
+
38
+ - **助手能看对方发来的图片了(D-128,决策先行)。** 开了 `wechatMediaDownload` 的来信图片
39
+ 从"整条忽略"变成一轮:模型可用 `look_at_image` 的 `#信1` 直接看落盘文件。门与看聊天图片
40
+ 同构(strict 双层拦截、每轮两张上限、审计照记);超过 4 MB 不缩放直接说明(证据形态);
41
+ 语音/视频/文件不在本轮。未开下载或没落盘的图片消息行为不变。
42
+
43
+ - **修了主分支上四处红的回归测试**(`npm test` 在 master 上本来就挂着 4 条,stash 验证过与
44
+ 新特性无关):`today` / `promises` 曾把 `--talker` 放进子进程 argv(进程列表可见),改走
45
+ `WEFLOW_TALKER` 环境变量(D-020,`test/privacy-paths` 转绿);`dailyMailTo` 补齐默认值三处
46
+ 登记(`test/config-keys` 三条转绿);`scripts/**/*.vbs` 进 npm 包——`run_hidden.vbs` 之前被
47
+ files allowlist 漏掉(`test/pack-contents` 转绿)。
48
+
49
+ - **`weflow-cli import qchat`:QQ 聊天进知识库与搜索(qchat-cli 一行不用改,D-129)。**
50
+ 读 `qce export --format json` 的导出(单文件或目录),按全局唯一的 messageId 去重合并、
51
+ 重复导入安全;两段式命令面。落盘后两条管道各开一个显式开关:`chat-notes --source qq|all`
52
+ 产 QQ 知识卡(`QQ-` 前缀,与微信卡同形状、同下游),`search-index --include-imports` 把
53
+ QQ 会话收进语义与短语索引(id 带 `chat:qq:` 段)。没有微信库的机器也能用(纯 QQ 场景,
54
+ 端到端有测试)。字段映射表见 `docs/DATA_CONTRACT.md`。
55
+
56
+ - **`replay`:关系网络的时间重放。** `weflow-cli replay` 出按月文本回放(哪些边断了、
57
+ 哪些新长出来、哪些最持久),`--out out.html` 出可播放的单文件动画:按天推进、边用 30 天
58
+ 滚动窗口、节点标签自动避让、播放速度可调;守恒校验内建,稀薄月份显式标注而非假装数据
59
+ 完整;另带静态总结页(断了哪些 / 最持久 / 新出现 + 月度柱状图)。数据全部来自本地库,
60
+ 不联网、不调模型。
61
+
62
+ ## 1.16.0
63
+
64
+ - **`leads` - the offers and asks buried in chat, with the sentence that said them.** Scans recent
65
+ conversations for five signal families (contact details, price, purchase, partnership, a request)
66
+ and ranks them, because the ones worth answering combine "how much" with "here is my number". Every
67
+ hit keeps the original words and whether you have replied yet (没回 / 我回过 / 已跟进 / 已结束).
68
+ Rule-based and offline on purpose: the output is a shortlist to read, not a verdict.
69
+ Two filters had to exist before it was usable - the first version returned eight "leads" in thirty
70
+ days and **every one was a campus-recruiting poster or a shopping promo**, because those are exactly
71
+ the messages salted with 合作 / 采购 / 报价. Adverts are now dropped, a signal must sit inside a
72
+ question or a request, and `@mentions` plus URLs are stripped before matching (group nicknames often
73
+ contain a phone number, and a URL with a long numeric id reads as one).
74
+ - **`bonds` now shows the last thing said in a cooling conversation.** "已静默 304 天" does not tell
75
+ you whether to reach out; the final line does. That was the missing half of a "who should I contact"
76
+ reminder - the ranking and the silence were already computed.
77
+
78
+ ## 1.15.1
21
79
 
22
80
  - **Four read-only answers to questions WeChat cannot answer.** `weflow-cli today` shows what you were
23
81
  talking about on this day in earlier years (it walks every shard and every conversation table, so
package/OPERATIONS.md CHANGED
@@ -1095,7 +1095,16 @@ powershell -NoProfile -ExecutionPolicy Bypass -File <仓库>\scripts\install_tas
1095
1095
  下游(AI 报告、统计)静默少一半。
1096
1096
 
1097
1097
  动作只有一句"跑那个脚本",具体的事在仓库里的 `scripts/daily_task.ps1`(纯 ASCII、路径全部相对自身)。
1098
- 第一个位置参数是模式(`noon` = 今天;缺省 = 昨天)。它做四件事,每件都有理由:
1098
+ 第一个位置参数是模式(`noon` = 今天;缺省 = 昨天)。
1099
+
1100
+ > **动作是 `wscript.exe //B //Nologo run_hidden.vbs [noon]`,不是直接跑 PowerShell。**
1101
+ > `powershell.exe` 是**控制台程序**:计划任务一触发,Windows 会先给它建控制台窗口,之后 PowerShell
1102
+ > 才轮到隐藏自己 —— 结果就是每次运行都闪出一个黑框,全屏游戏时更明显(2026-10-22 实测:00:05 那次
1103
+ > 弹窗被人顺手关掉,进程以 `0xC000013A`(Ctrl+C 类中断)退出,那天就没有日报也没有邮件)。
1104
+ > `wscript.exe` 是没有控制台的 GUI 进程,`run_hidden.vbs` 内部再用 `WshShell.Run(cmd, 0, True)`
1105
+ > 隐藏子进程并等待它结束 —— 全程零窗口,而 `True` 让任务的"上次运行结果"仍然是真实退出码。
1106
+
1107
+ 它做五件事,每件都有理由:
1099
1108
 
1100
1109
  1. **跑目标天**:日终 `pipeline.py --yesterday --prefetch-bodies`;午报 `pipeline.py --date <今天> --prefetch-bodies`。
1101
1110
  2. **把输出落盘**:`logs/daily-<日期>[-noon].log` 与 `daily-<日期>[-noon].err.log`(`logs/` 已 gitignore)。
@@ -1110,6 +1119,12 @@ powershell -NoProfile -ExecutionPolicy Bypass -File <仓库>\scripts\install_tas
1110
1119
  午报也会写 index.html,只看它会让 00:05 跳过下午、留下一份"看着完整、实际半天"的日报。
1111
1120
  实际判据是 `.articles.json` 的 `generated_at`:**生成于目标日之后**(通常就是次日 00:0x),
1112
1121
  或当晚 23:00 之后,才算这天做完了。
1122
+ 5. **渲染失败单独重试**:`pipeline.py` 的最后一环是渲染 `index.html`,而这一步已经挂过两次
1123
+ (2026-10-18 无输出 11 小时;2026-10-23 在 README 之后中断,日报只剩 13:00 的半天版)。
1124
+ 抓取和摘要那时已经在 `.articles.json` 里,所以脚本会**单独**再跑一次 `generate_html.py`;
1125
+ 它成功就把这次运行当作成功,索引与邮件照常继续。判据是 `.articles.json` 比 `index.html` 新
1126
+ (或页面不存在)——页面比数据新说明这一轮已经渲染过了,不重复。
1127
+ **没有这一步,渲染慢一次就等于早上没有邮件**,因为发信挂在"整天成功"上。
1113
1128
 
1114
1129
  > 为什么不把 python 命令直接写进任务动作:① 实测 `Register-ScheduledTask` 对带嵌套引号的
1115
1130
  > `-Argument` 会报 `0x80004005`,而包一层脚本就不用跟引号搏斗;② 任务动作指向 CLI 那个 npm 包时,
package/README.en.md CHANGED
@@ -19,7 +19,9 @@
19
19
 
20
20
  </div>
21
21
 
22
- **WeFlow CLI turns WeChat into your local second brain**: read and query chat history locally with one command, export readable HTML; turn official-account articles into AI-digested daily reports; read your WeChat favorites; build a semantic-searchable knowledge base — and plug it all into MCP-compatible AI editors like Claude Code. Works on Windows and Linux.
22
+ **WeFlow CLI turns WeChat into your local second brain**: read and query chat history locally with one command, export readable HTML; turn official-account articles into AI-digested daily reports (optionally mailed to you); read your WeChat favorites; build a semantic-searchable knowledge base — voice messages included — and plug it all into MCP-compatible AI editors like Claude Code. Works on Windows and Linux.
23
+
24
+ It is built to answer **questions WeChat itself cannot**: who is waiting on a reply, what I promised someone and whether I followed through, which relationships are cooling, how an account's position shifted over time, and what we were talking about on this day in earlier years.
23
25
 
24
26
  > 🔒 **Local-first**: runs entirely on your machine — zero telemetry, zero cloud reporting. Database keys are stored locally, encrypted with machine-bound AES-256-GCM. AI features only activate after you explicitly configure your own API key. See the [Security & Privacy statement](./SECURITY.md).
25
27
 
@@ -60,6 +62,17 @@ weflow-cli chat "How does RAG work?" # knowledge-base RAG Q&A
60
62
  weflow-cli mcp-config # one-shot MCP client integration
61
63
  ```
62
64
 
65
+ **Questions WeChat cannot answer** (all read-only, no network, no model calls):
66
+
67
+ ```text
68
+ weflow-cli awaiting # who is waiting on a reply
69
+ weflow-cli bonds # relationship temperature: cooling, warming, WeChat-only
70
+ weflow-cli promises --days 180 # what I said I'd do, with the original words and follow-up evidence
71
+ weflow-cli today --years 1,3,5 # what we were talking about on this day in earlier years
72
+ weflow-cli network --with "contact" # shared groups; --intro finds who could introduce you
73
+ weflow-cli timeline --source "account" # one account's articles laid out in time
74
+ ```
75
+
63
76
  ## Platform Support
64
77
 
65
78
  | Capability | Windows | macOS | Linux |
@@ -283,6 +296,10 @@ Management: `weflow-cli assistant status` / `log` / `stop`; send "帮助" in WeC
283
296
  | Who is waiting on a reply | `weflow-cli awaiting --dry-run` · `weflow-cli awaiting --yes` |
284
297
  | Draft a reply (text unless you pick and send) | `weflow-cli draft <contact> --dry-run` · `--yes` (**only** `--pick N --send --yes` actually sends; both flags are required) |
285
298
  | Relationship temperature | `weflow-cli bonds` (who is cooling, who is warming, who only has WeChat; read-only, local, no model) |
299
+ | What I promised whom | `weflow-cli promises --days 180` (original words plus follow-up evidence; rule-based, no model) |
300
+ | This day in earlier years | `weflow-cli today --years 1,3,5` (what you were talking about back then) |
301
+ | People graph | `weflow-cli network --groups` · `--with <name>` (shared groups) · `--intro <name>` (who could introduce you; reads `contact.db` only) |
302
+ | One account over time | `weflow-cli timeline --list` · `--source <account>` (its articles laid out in time) |
286
303
  | Local judgement primitive | `weflow-cli decide --request <file> --dry-run` · `--yes` |
287
304
  | Export chat history | `weflow-cli export <contact> <json\|txt\|html\|excel>` |
288
305
  | Sync checkpoint | `weflow-cli sync run <contact> --since <date>` · `sync status` · `sync verify` |
@@ -290,7 +307,7 @@ Management: `weflow-cli assistant status` / `log` / `stop`; send "帮助" in WeC
290
307
  | Moments cache | `weflow-cli sns timeline` · `weflow-cli sns users` · `weflow-cli sns stats` |
291
308
  | WeChat favorites | `weflow-cli fav list` · `weflow-cli fav export markdown` · `weflow-cli fav set-key` |
292
309
  | WeRead | `weflow-cli weread shelf` · `notes` · `search` · `stats` (get the key from https://weread.qq.com/r/weread-skills; see [OPERATIONS.md](./OPERATIONS.md)) |
293
- | Knowledge base | `weflow-cli vault` · `weflow-cli wiki` · `weflow-cli search <query>` · `weflow-cli chat` (semantic search needs `config set dashscopeApiKey` first) |
310
+ | Knowledge base | `weflow-cli vault` · `weflow-cli wiki` · `weflow-cli search <query>` · `weflow-cli chat` (semantic search needs `config set dashscopeApiKey` first; `search --phrase <words> --line all` also matches voice transcripts) |
294
311
  | Reports & tasks | `weflow-cli report` · `annual-report` · `todos` |
295
312
  | Second-brain assistant | `weflow-cli assistant start` · `status` · `log` · `stop` |
296
313
  | On-device panel | `weflow-cli panel` — floating window; `--status` reads state only, `--ask "…"` asks from the command line |
@@ -356,6 +373,8 @@ For a more complete view of modules and data flow, read [ARCHITECTURE.md](./ARCH
356
373
  - After upgrading WeChat, switching accounts, or migrating computers, you may need to re-initialize or re-scan NT keys.
357
374
  - `init` validates existing local configuration first and does not re-capture keys when that validation passes. Use `weflow-cli init --refresh` only after a migration, an account switch, or an access failure.
358
375
  - To test a first-time initialization or a failed key, prefer `weflow-cli init --test-missing-keys`; it simulates missing keys for that run only and leaves the saved configuration untouched. When keys really have failed, `weflow-cli config forget-keys` clears the database access keys only and asks for confirmation.
376
+ - **Voice transcription runs on your machine** (`faster-whisper`, local model); audio never leaves it, and transcripts are cached by content hash so an interrupted run resumes. It is **not guaranteed accurate** — dialect, accent and background noise all introduce errors; the purpose is "you can find what was said", not a verbatim record. Transcripts join the phrase index only, never the semantic index (no second embedding bill for dialect-approximate text).
377
+ - **Message shards are split by time** (`message_0..3.db`, roughly a year each), so "older chats" depend on whether the shard covering that period is still on the machine; `weflow-cli check --report` lists each shard's read status.
359
378
  - Running `weflow-cli daily` without a date checks yesterday's artifacts first: if yesterday's `README.md`, article index, or `index.html` is missing, it backfills yesterday and only generates today once that succeeds. Passing `--date` or `--dry-run` skips the backfill.
360
379
 
361
380
  ## Documentation & Feedback
package/README.md CHANGED
@@ -19,7 +19,9 @@
19
19
 
20
20
  </div>
21
21
 
22
- **WeFlow CLI 把微信变成你的本地第二大脑**:在本机读取和查询聊天记录、导出可读 HTML;把公众号文章整理成带 AI 摘要的日报;读取微信收藏;构建可语义搜索的知识库;并通过 MCP 接入 Claude Code 等 AI 编辑器。支持 Windows 与 Linux。
22
+ **WeFlow CLI 把微信变成你的本地第二大脑**:在本机读取和查询聊天记录、导出可读 HTML;把公众号文章整理成带 AI 摘要的日报(可邮件推送);读取微信收藏;构建可语义搜索的知识库(连语音消息也能搜);并通过 MCP 接入 Claude Code 等 AI 编辑器。支持 Windows 与 Linux。
23
+
24
+ 它专门回答**几个微信自己回答不了的问题**:谁在等我回话、我答应过谁什么后来做了没有、和谁的关系在变淡、某个号的观点怎么变的、那一年的今天我们在聊什么。
23
25
 
24
26
  > 🔒 **本地优先**:完全在你的电脑上运行——零遥测、零云上报;数据库密钥以机器绑定的 AES-256-GCM 加密存储在本机。AI 功能仅在显式配置你自己的 API Key 后启用。详见[安全与隐私声明](./SECURITY.md)。
25
27
 
@@ -60,6 +62,17 @@ weflow-cli chat "RAG 的原理是什么?" # 知识库 RAG 问答
60
62
  weflow-cli mcp-config # 一键接入 Claude Code 等 MCP 客户端
61
63
  ```
62
64
 
65
+ **几个微信给不出答案的问题**(都只读本地库,不联网、不调模型):
66
+
67
+ ```text
68
+ weflow-cli awaiting # 谁在等我回话
69
+ weflow-cli bonds # 关系温度:谁在冷却、谁只有微信这一条线
70
+ weflow-cli promises --days 180 # 我答应过谁什么,后来做了没有(带原话与后续证据)
71
+ weflow-cli today --years 1,3,5 # 那几年的今天,我们在聊什么
72
+ weflow-cli network --with "联系人A" # 我和他共同在哪些群;--intro 看谁能引荐
73
+ weflow-cli timeline --source "某号" # 这个号历次说法的时间线
74
+ ```
75
+
63
76
  ## 平台支持
64
77
 
65
78
  | 能力 | Windows | macOS | Linux |
@@ -94,7 +107,7 @@ Linux 的自动初始化能力取决于微信发行版、Python 依赖和当前
94
107
  | --- | --- |
95
108
  | 聊天记录 | 查询会话、联系人和消息;导出 **Markdown / JSON / TXT / HTML / Excel**。Markdown 导出把图片**落盘**到 `<会话>_assets/`、正文用相对路径引用(喂给编辑器或别的工具时这才是能用的形态);**文档本体**(微信里的 Word/Excel/PDF/PPT 等)按原名与扩展名拷进 `<会话>_assets/files/`,正文里按原名链接到 `files/` 下;HTML 导出内嵌图片并给出一份媒体覆盖报告(哪些没嵌上、为什么)。**匹配只做一遍**:Markdown 导出写下清单,之后 JSON/TXT/Excel 导出(或 `--media`)会自动带上同样的图片与文档路径。 |
96
109
  | 公众号日报 | 抓取文章、AI 摘要与分类、生成本地阅读页,保留收藏和已读状态。 |
97
- | 个人知识库 | 同步微信读书笔记、构建 Obsidian Vault、语义搜索、RAG 问答和概念 Wiki,以及**双击就能打开**的概念图谱页面(`weflow-cli wiki graph --open` 出 3D、加 `--flat` 出 2D;自包含、不联网、不需要服务器;`--min-degree N` 只看枢纽、`--line wiki\|chat` 只看一条线)。 |
110
+ | 个人知识库 | 同步微信读书笔记、构建 Obsidian Vault、语义搜索、RAG 问答和概念 Wiki,以及**双击就能打开**的概念图谱页面(`weflow-cli wiki graph --open` 出 3D、加 `--flat` 出 2D;自包含、不联网、不需要服务器;`--min-degree N` 只看枢纽、`--line wiki\|chat` 只看一条线;**2D 页里点一条边能看到它凭什么连着**——两页的共同来源卡片,没有共同来源的边也会如实说来自正文链接)。 |
98
111
  | AI 协作 | 通过 MCP 把文章、知识库、日报和受控的本地数据能力交给兼容客户端;工具清单以 `weflow-cli mcp-config` 和 `docs/MCP.md` 为准。 |
99
112
  | 个人回顾 | 聊天月报、年度报告、待办提取与朋友圈本地缓存查询。 |
100
113
  | 微信收藏 | 读取微信"收藏"内容(公众号文章、文字、图片、视频、聊天记录),支持类型过滤、关键词搜索与 Markdown/JSON 导出。 |
@@ -124,7 +137,15 @@ weflow-cli check
124
137
  > - 马上能用:换成 `weflow-cli.cmd check`(`.cmd` 那份包装不走 PowerShell 策略);
125
138
  > - 一次性解决:`Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`,然后重开终端。
126
139
 
127
- 安装标准 Windows 4.x 工作流所需的 Python 依赖:
140
+ 一条命令装好 Python 依赖(推荐)——它会在 `~/.weflow-cli/venv` 建一个本工具**自管**的虚拟环境
141
+ 并安装依赖,之后的 Python 工作流会优先用它,不用再管 PATH 上哪个 Python 可用
142
+ (Windows 上自动改用 `sqlcipher3-wheels` 预编译轮,省去装编译器的麻烦):
143
+
144
+ ```powershell
145
+ weflow-cli setup
146
+ ```
147
+
148
+ 也可以手动安装(效果相同;从源码运行时在仓库根目录执行):
128
149
 
129
150
  ```powershell
130
151
  python -m pip install -r requirements.txt
@@ -265,6 +286,8 @@ weflow-cli panel # 打开本机面板窗口 (不扫码也能用)
265
286
  - 「知识库里怎么讲 RAG 的?」— 概念 Wiki 检索
266
287
  - 「帮我回老王那句话」— 起草回复:先判断对方要什么、风险和该不该给实质内容,再给几条候选。
267
288
  **只产出文本,不会替你发送**;涉钱或风险很高时不给草稿,只说明该先确认什么
289
+ - 「(对方直接发来一张图片)」— 开了 `wechatMediaDownload` 后图片会落盘,助手能直接看图回答
290
+ (隐私模式 strict 下不出境,见下段与 D-128)
268
291
  - 「记住:我的项目叫 weflow-cli」— 写入长期记忆
269
292
 
270
293
  运行机制:守护进程通过微信官方 Bot 通道(iLink)长轮询收发消息,Agent 循环、三层记忆(工作窗口 / 滚动摘要 / 长期事实)、数据库查询全部在本机执行;仅最终提问与回复文本会发送给所配置的 LLM,新装默认就是 `assistantPrivacy=strict`:工具输出中的电话/邮箱/链接等 PII 自动脱敏,且第三方聊天正文不出境(`balanced` 放宽到正文可出境、只对 PII 打码,`open` 全不打码;`ollama` 本地引擎则完全不出网)。会话 24 小时未活跃需重新扫码,单窗口内主动回复有官方条数限制。
@@ -290,24 +313,27 @@ weflow-cli config set assistantGroupRequireMention true
290
313
 
291
314
  | 目标 | 命令 |
292
315
  | --- | --- |
293
- | 检查环境与配置 | `weflow-cli check` · `weflow-cli config show` |
316
+ | 检查环境与配置 | `weflow-cli check` · `weflow-cli setup`(自管 Python venv,一条命令装依赖) · `weflow-cli config show` |
294
317
  | 初始化或手动指定路径 | `weflow-cli init [--path <目录>]` |
295
318
  | 浏览聊天数据 | `weflow-cli sessions` · `weflow-cli messages <联系人>` · `weflow-cli contacts` |
296
319
  | 谁在等我回话 | `weflow-cli awaiting --dry-run` · `weflow-cli awaiting --yes` |
297
320
  | 帮我起草回复(默认只出文字) | `weflow-cli draft <联系人> --dry-run` · `--yes`(**只有** `--pick N --send --yes` 会真的替你发出去;两步缺一不可)|
298
321
  | 关系温度 | `weflow-cli bonds`(谁在冷却、谁在变热、谁只有微信这一条线;只读本地库,不联网、不调模型)|
299
322
  | 我说过要给谁做什么 | `weflow-cli promises --days 180`(带回原话与后续证据,规则判定,不调模型)|
323
+ | 聊天里的生意线索 | `weflow-cli leads --days 60 --min-score 4`(报价/采购/合作/需求信号,带原话与"我回过没有")|
300
324
  | 那年今日 | `weflow-cli today --years 1,3,5`(几年前的今天在聊什么)|
301
325
  | 人脉图谱 | `weflow-cli network --groups` · `--with <名字>`(共同群)· `--intro <名字>`(谁能引荐;只读 contact.db)|
302
326
  | 某号观点演变 | `weflow-cli timeline --list` · `--source <公众号名>`(按时间看它说法的变化)|
327
+ | 关系网络时间重放 | `weflow-cli replay`(按月展开,生成可播放的单文件 HTML;看哪条边断了,不只是图变大)|
303
328
  | 本机判断层 | `weflow-cli decide --request <file> --dry-run` · `--yes` |
304
329
  | 导出聊天记录 | `weflow-cli export <联系人> <json\|txt\|html\|excel>` |
305
- | 同步检查点 | `weflow-cli sync run <联系人> --since <日期>` · `sync status` · `sync verify` |
330
+ | 同步检查点 | `weflow-cli sync run <联系人> --since <日期>` · `sync status` · `sync verify` · `sync cursor-probe`(离稳定增量游标还差什么,实测当前后端)|
331
+ | QQ 聊天导入 | `weflow-cli import qchat <qchat导出>` · `import list` · `import show <会话>` (读 qchat-cli 的 JSON 导出;之后 `chat-notes --source qq` 产知识卡、`search-index --include-imports` 进搜索)|
306
332
  | 公众号日报与阅读器 | `weflow-cli daily` · `weflow-cli daily-server` · `weflow-cli review` |
307
333
  | 朋友圈缓存 | `weflow-cli sns timeline` · `weflow-cli sns users` · `weflow-cli sns stats` |
308
334
  | 微信收藏 | `weflow-cli fav list` · `weflow-cli fav export markdown` · `weflow-cli fav set-key` |
309
335
  | 微信读书 | `weflow-cli weread shelf` · `notes` · `search` · `stats`(key 从 https://weread.qq.com/r/weread-skills 拿,见 [OPERATIONS.md](./OPERATIONS.md)) |
310
- | 知识库 | `weflow-cli vault` · `weflow-cli wiki` · `weflow-cli search <query>` · `weflow-cli chat`(语义检索需先 `config set dashscopeApiKey`)|
336
+ | 知识库 | `weflow-cli vault` · `weflow-cli wiki` · `weflow-cli search <query>` · `weflow-cli chat`(语义检索需先 `config set dashscopeApiKey`;`search --phrase <词> --line all` 连语音转写一起搜)|
311
337
  | 总结与任务 | `weflow-cli report` · `annual-report` · `todos` |
312
338
  | 第二大脑助手 | `weflow-cli assistant start` · `status` · `log` · `stop` |
313
339
  | 本机面板 | `weflow-cli panel`(悬浮窗;`--status` 只看状态,`--ask "…"` 在命令行里问)|
@@ -374,6 +400,8 @@ python scripts/fav_server.py --date YYYY-MM-DD
374
400
  - `init` 会先验证已有本地配置;验证通过时不再重复捕获密钥。仅在迁移、切换账号或访问失败后使用 `weflow-cli init --refresh`。
375
401
  - 测试首次初始化或密钥失效时,优先使用 `weflow-cli init --test-missing-keys`;它只在本次运行模拟密钥缺失,不改动已保存配置。实际密钥失效时可使用 `weflow-cli config forget-keys`,该命令仅清除数据库访问密钥并要求确认。
376
402
  - 不指定日期运行 `weflow-cli daily` 时,会先检查昨天的日报产物;昨天缺少 `README.md`、文章索引或 `index.html` 时,会先补齐昨天,成功后才生成今天。指定 `--date` 或使用 `--dry-run` 时不执行补日报。
403
+ - 语音转写用**本机** Whisper 模型(`faster-whisper`),音频不出本机;转写按内容哈希缓存,可中断续跑。它**不保证准确**——方言、口音和背景音都会带来误差,用途是"能搜到说过什么",不是逐字记录。转写结果只并入短语索引,不进语义索引(不为方言近似文本再付一次嵌入费用)。
404
+ - 消息分片按**时间段**切分(`message_0..3.db` 各覆盖一年多),所以"更早的聊天"取决于那段时间对应的分片是否还在本机;`weflow-cli check --report` 会列出每个分片的读取状态。
377
405
 
378
406
  ## 文档与反馈
379
407