weflow-cli 1.5.0 → 1.6.1

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 (332) hide show
  1. package/ARCHITECTURE.md +105 -0
  2. package/CHANGELOG.md +121 -0
  3. package/CONTRIBUTING.md +45 -0
  4. package/LICENSE +21 -21
  5. package/OPERATIONS.md +272 -0
  6. package/README.en.md +281 -0
  7. package/README.md +334 -149
  8. package/SECURITY.md +47 -0
  9. package/bin/weflow-cli.ts +4050 -581
  10. package/dist/bin/weflow-cli.js +4310 -588
  11. package/dist/bin/weflow-cli.js.map +1 -1
  12. package/dist/mcp-server/index.js +178 -236
  13. package/dist/mcp-server/index.js.map +1 -1
  14. package/dist/src/core/dbPathService.d.ts +15 -1
  15. package/dist/src/core/dbPathService.d.ts.map +1 -1
  16. package/dist/src/core/dbPathService.js +177 -19
  17. package/dist/src/core/dbPathService.js.map +1 -1
  18. package/dist/src/core/keyService.d.ts +8 -0
  19. package/dist/src/core/keyService.d.ts.map +1 -1
  20. package/dist/src/core/keyService.js +127 -22
  21. package/dist/src/core/keyService.js.map +1 -1
  22. package/dist/src/core/ntCore.d.ts +59 -1
  23. package/dist/src/core/ntCore.d.ts.map +1 -1
  24. package/dist/src/core/ntCore.js +201 -65
  25. package/dist/src/core/ntCore.js.map +1 -1
  26. package/dist/src/core/sqlcipherCore.d.ts.map +1 -1
  27. package/dist/src/core/sqlcipherCore.js +18 -1
  28. package/dist/src/core/sqlcipherCore.js.map +1 -1
  29. package/dist/src/core/wcdbCore.d.ts.map +1 -1
  30. package/dist/src/core/wcdbCore.js +3 -6
  31. package/dist/src/core/wcdbCore.js.map +1 -1
  32. package/dist/src/services/assistantDaemon.d.ts +19 -0
  33. package/dist/src/services/assistantDaemon.d.ts.map +1 -0
  34. package/dist/src/services/assistantDaemon.js +117 -0
  35. package/dist/src/services/assistantDaemon.js.map +1 -0
  36. package/dist/src/services/assistantMemory.d.ts +36 -0
  37. package/dist/src/services/assistantMemory.d.ts.map +1 -0
  38. package/dist/src/services/assistantMemory.js +182 -0
  39. package/dist/src/services/assistantMemory.js.map +1 -0
  40. package/dist/src/services/assistantPrivacy.d.ts +25 -0
  41. package/dist/src/services/assistantPrivacy.d.ts.map +1 -0
  42. package/dist/src/services/assistantPrivacy.js +77 -0
  43. package/dist/src/services/assistantPrivacy.js.map +1 -0
  44. package/dist/src/services/assistantRouting.d.ts +18 -0
  45. package/dist/src/services/assistantRouting.d.ts.map +1 -0
  46. package/dist/src/services/assistantRouting.js +68 -0
  47. package/dist/src/services/assistantRouting.js.map +1 -0
  48. package/dist/src/services/assistantService.d.ts +37 -0
  49. package/dist/src/services/assistantService.d.ts.map +1 -0
  50. package/dist/src/services/assistantService.js +284 -0
  51. package/dist/src/services/assistantService.js.map +1 -0
  52. package/dist/src/services/assistantTools.d.ts +24 -0
  53. package/dist/src/services/assistantTools.d.ts.map +1 -0
  54. package/dist/src/services/assistantTools.js +582 -0
  55. package/dist/src/services/assistantTools.js.map +1 -0
  56. package/dist/src/services/chatService.d.ts +44 -0
  57. package/dist/src/services/chatService.d.ts.map +1 -1
  58. package/dist/src/services/chatService.js +105 -4
  59. package/dist/src/services/chatService.js.map +1 -1
  60. package/dist/src/services/configService.d.ts +55 -0
  61. package/dist/src/services/configService.d.ts.map +1 -1
  62. package/dist/src/services/configService.js +147 -6
  63. package/dist/src/services/configService.js.map +1 -1
  64. package/dist/src/services/evidenceService.d.ts +30 -0
  65. package/dist/src/services/evidenceService.d.ts.map +1 -0
  66. package/dist/src/services/evidenceService.js +98 -0
  67. package/dist/src/services/evidenceService.js.map +1 -0
  68. package/dist/src/services/exportService.d.ts +13 -20
  69. package/dist/src/services/exportService.d.ts.map +1 -1
  70. package/dist/src/services/exportService.js +113 -47
  71. package/dist/src/services/exportService.js.map +1 -1
  72. package/dist/src/services/initKeyService.d.ts +19 -0
  73. package/dist/src/services/initKeyService.d.ts.map +1 -0
  74. package/dist/src/services/initKeyService.js +80 -0
  75. package/dist/src/services/initKeyService.js.map +1 -0
  76. package/dist/src/services/messageContract.d.ts +23 -0
  77. package/dist/src/services/messageContract.d.ts.map +1 -0
  78. package/dist/src/services/messageContract.js +49 -0
  79. package/dist/src/services/messageContract.js.map +1 -0
  80. package/dist/src/services/messageQuery.d.ts +7 -0
  81. package/dist/src/services/messageQuery.d.ts.map +1 -0
  82. package/dist/src/services/messageQuery.js +30 -0
  83. package/dist/src/services/messageQuery.js.map +1 -0
  84. package/dist/src/services/wechat-formatter.js +14 -14
  85. package/dist/src/services/wechatMessageService.d.ts.map +1 -1
  86. package/dist/src/services/wechatMessageService.js +31 -3
  87. package/dist/src/services/wechatMessageService.js.map +1 -1
  88. package/dist/src/services/whitelistService.d.ts +52 -4
  89. package/dist/src/services/whitelistService.d.ts.map +1 -1
  90. package/dist/src/services/whitelistService.js +183 -17
  91. package/dist/src/services/whitelistService.js.map +1 -1
  92. package/dist/src/types.d.ts +20 -0
  93. package/dist/src/types.d.ts.map +1 -1
  94. package/dist/src/utils/dateRange.d.ts +15 -0
  95. package/dist/src/utils/dateRange.d.ts.map +1 -0
  96. package/dist/src/utils/dateRange.js +48 -0
  97. package/dist/src/utils/dateRange.js.map +1 -0
  98. package/dist/src/utils/mcpSecurity.d.ts +5 -0
  99. package/dist/src/utils/mcpSecurity.d.ts.map +1 -0
  100. package/dist/src/utils/mcpSecurity.js +39 -0
  101. package/dist/src/utils/mcpSecurity.js.map +1 -0
  102. package/dist/src/utils/packageRoot.d.ts +2 -0
  103. package/dist/src/utils/packageRoot.d.ts.map +1 -0
  104. package/dist/src/utils/packageRoot.js +16 -0
  105. package/dist/src/utils/packageRoot.js.map +1 -0
  106. package/dist/src/utils/python.d.ts +2 -0
  107. package/dist/src/utils/python.d.ts.map +1 -0
  108. package/dist/src/utils/python.js +72 -0
  109. package/dist/src/utils/python.js.map +1 -0
  110. package/dist/src/utils/pythonProcessEnv.d.ts +3 -0
  111. package/dist/src/utils/pythonProcessEnv.d.ts.map +1 -0
  112. package/dist/src/utils/pythonProcessEnv.js +46 -0
  113. package/dist/src/utils/pythonProcessEnv.js.map +1 -0
  114. package/dist/src/utils/talkerUtils.d.ts +4 -1
  115. package/dist/src/utils/talkerUtils.d.ts.map +1 -1
  116. package/dist/src/utils/talkerUtils.js +9 -9
  117. package/dist/src/utils/talkerUtils.js.map +1 -1
  118. package/dist/src/utils/wechatEmoji.d.ts +5 -0
  119. package/dist/src/utils/wechatEmoji.d.ts.map +1 -0
  120. package/dist/src/utils/wechatEmoji.js +35 -0
  121. package/dist/src/utils/wechatEmoji.js.map +1 -0
  122. package/docs/AI_INTERFACE.md +189 -0
  123. package/docs/BRANCHES.md +87 -0
  124. package/docs/DATA_CONTRACT.md +74 -0
  125. package/docs/DECISIONS.md +270 -0
  126. package/docs/DEEPSEEK_V4_FLASH/346/226/275/345/267/245/346/226/207/346/241/243.md +234 -0
  127. package/docs/EVIDENCE_GUIDE.md +96 -0
  128. package/docs/MCP.md +95 -0
  129. package/docs/PARTNERS.md +41 -0
  130. package/docs/PROJECT_STATE.md +96 -0
  131. package/docs/RELEASING.md +124 -0
  132. package/docs/ROADMAP.md +191 -0
  133. package/docs/SETUP.md +103 -0
  134. package/docs/images/weflow-architecture-gpt-image-2.png +0 -0
  135. package/docs/images/weflow-architecture.png +0 -0
  136. package/docs/images/weflow-architecture.svg +65 -0
  137. package/mcp-server/index.ts +169 -269
  138. package/package.json +81 -72
  139. package/requirements-3x.txt +4 -0
  140. package/requirements-voice.txt +15 -0
  141. package/requirements.txt +9 -0
  142. package/resources/js/marked.min.js +69 -0
  143. package/resources/wechat-emoji/666.png +0 -0
  144. package/resources/wechat-emoji/Awesome.png +0 -0
  145. package/resources/wechat-emoji/Concerned.png +0 -0
  146. package/resources/wechat-emoji/Cry.png +0 -0
  147. package/resources/wechat-emoji/Emm.png +0 -0
  148. package/resources/wechat-emoji/Facepalm.png +0 -0
  149. package/resources/wechat-emoji/Grin.png +0 -0
  150. package/resources/wechat-emoji/OK.png +0 -0
  151. package/resources/wechat-emoji/Respect.png +0 -0
  152. package/resources/wechat-emoji/Sick.png +0 -0
  153. package/resources/wechat-emoji/Sleep.png +0 -0
  154. package/resources/wechat-emoji/Smile.png +0 -0
  155. package/resources/wechat-emoji//344/272/262/344/272/262.png +0 -0
  156. package/resources/wechat-emoji//344/276/277/344/276/277.png +0 -0
  157. package/resources/wechat-emoji//345/201/267/347/254/221.png +0 -0
  158. package/resources/wechat-emoji//345/202/262/346/205/242.png +0 -0
  159. package/resources/wechat-emoji//345/206/215/350/247/201.png +0 -0
  160. package/resources/wechat-emoji//345/207/213/350/260/242.png +0 -0
  161. package/resources/wechat-emoji//345/212/240/346/262/271.png +0 -0
  162. package/resources/wechat-emoji//345/213/276/345/274/225.png +0 -0
  163. package/resources/wechat-emoji//345/217/221/345/221/206.png +0 -0
  164. package/resources/wechat-emoji//345/217/221/346/200/222.png +0 -0
  165. package/resources/wechat-emoji//345/217/221/346/212/226.png +0 -0
  166. package/resources/wechat-emoji//345/217/257/346/200/234.png +0 -0
  167. package/resources/wechat-emoji//345/217/263/345/223/274/345/223/274.png +0 -0
  168. package/resources/wechat-emoji//345/217/271/346/260/224.png +0 -0
  169. package/resources/wechat-emoji//345/220/203/347/223/234.png +0 -0
  170. package/resources/wechat-emoji//345/220/210/345/215/201.png +0 -0
  171. package/resources/wechat-emoji//345/220/220.png +0 -0
  172. package/resources/wechat-emoji//345/221/262/347/211/231.png +0 -0
  173. package/resources/wechat-emoji//345/222/222/351/252/202.png +0 -0
  174. package/resources/wechat-emoji//345/222/226/345/225/241.png +0 -0
  175. package/resources/wechat-emoji//345/223/207.png +0 -0
  176. package/resources/wechat-emoji//345/225/244/351/205/222.png +0 -0
  177. package/resources/wechat-emoji//345/230/230.png +0 -0
  178. package/resources/wechat-emoji//345/230/264/345/224/207.png +0 -0
  179. package/resources/wechat-emoji//345/230/277/345/223/210.png +0 -0
  180. package/resources/wechat-emoji//345/233/247.png +0 -0
  181. package/resources/wechat-emoji//345/233/260.png +0 -0
  182. package/resources/wechat-emoji//345/235/217/347/254/221.png +0 -0
  183. package/resources/wechat-emoji//345/244/247/345/223/255.png +0 -0
  184. package/resources/wechat-emoji//345/244/251/345/225/212.png +0 -0
  185. package/resources/wechat-emoji//345/244/252/351/230/263.png +0 -0
  186. package/resources/wechat-emoji//345/244/261/346/234/233.png +0 -0
  187. package/resources/wechat-emoji//345/245/270/347/254/221.png +0 -0
  188. package/resources/wechat-emoji//345/245/275/347/232/204.png +0 -0
  189. package/resources/wechat-emoji//345/247/224/345/261/210.png +0 -0
  190. package/resources/wechat-emoji//345/256/263/347/276/236.png +0 -0
  191. package/resources/wechat-emoji//345/260/264/345/260/254.png +0 -0
  192. package/resources/wechat-emoji//345/272/206/347/245/235.png +0 -0
  193. package/resources/wechat-emoji//345/274/261.png +0 -0
  194. package/resources/wechat-emoji//345/274/272.png +0 -0
  195. package/resources/wechat-emoji//345/276/227/346/204/217.png +0 -0
  196. package/resources/wechat-emoji//345/276/256/347/254/221.png +0 -0
  197. package/resources/wechat-emoji//345/277/203/347/242/216.png +0 -0
  198. package/resources/wechat-emoji//345/277/253/345/223/255/344/272/206.png +0 -0
  199. package/resources/wechat-emoji//346/201/220/346/203/247.png +0 -0
  200. package/resources/wechat-emoji//346/202/240/351/227/262.png +0 -0
  201. package/resources/wechat-emoji//346/203/212/346/201/220.png +0 -0
  202. package/resources/wechat-emoji//346/203/212/350/256/266.png +0 -0
  203. package/resources/wechat-emoji//346/204/211/345/277/253.png +0 -0
  204. package/resources/wechat-emoji//346/206/250/347/254/221.png +0 -0
  205. package/resources/wechat-emoji//346/211/223/350/204/270.png +0 -0
  206. package/resources/wechat-emoji//346/212/223/347/213/202.png +0 -0
  207. package/resources/wechat-emoji//346/212/240/351/274/273.png +0 -0
  208. package/resources/wechat-emoji//346/212/261/346/213/263.png +0 -0
  209. package/resources/wechat-emoji//346/213/245/346/212/261.png +0 -0
  210. package/resources/wechat-emoji//346/213/263/345/244/264.png +0 -0
  211. package/resources/wechat-emoji//346/215/202/350/204/270.png +0 -0
  212. package/resources/wechat-emoji//346/217/241/346/211/213.png +0 -0
  213. package/resources/wechat-emoji//346/222/207/345/230/264.png +0 -0
  214. package/resources/wechat-emoji//346/223/246/346/261/227.png +0 -0
  215. package/resources/wechat-emoji//346/225/262/346/211/223.png +0 -0
  216. package/resources/wechat-emoji//346/227/240/350/257/255.png +0 -0
  217. package/resources/wechat-emoji//346/227/272/346/237/264.png +0 -0
  218. package/resources/wechat-emoji//346/231/225.png +0 -0
  219. package/resources/wechat-emoji//346/234/210/344/272/256.png +0 -0
  220. package/resources/wechat-emoji//346/234/272/346/231/272.png +0 -0
  221. package/resources/wechat-emoji//346/261/227.png +0 -0
  222. package/resources/wechat-emoji//346/265/201/346/263/252.png +0 -0
  223. package/resources/wechat-emoji//347/202/270/345/274/271.png +0 -0
  224. package/resources/wechat-emoji//347/203/237/350/212/261.png +0 -0
  225. package/resources/wechat-emoji//347/210/206/347/253/271.png +0 -0
  226. package/resources/wechat-emoji//347/210/261/345/277/203.png +0 -0
  227. package/resources/wechat-emoji//347/214/252/345/244/264.png +0 -0
  228. package/resources/wechat-emoji//347/216/253/347/221/260.png +0 -0
  229. package/resources/wechat-emoji//347/224/237/347/227/205.png +0 -0
  230. package/resources/wechat-emoji//347/226/221/351/227/256.png +0 -0
  231. package/resources/wechat-emoji//347/231/274.png +0 -0
  232. package/resources/wechat-emoji//347/231/275/347/234/274.png +0 -0
  233. package/resources/wechat-emoji//347/232/261/347/234/211.png +0 -0
  234. package/resources/wechat-emoji//347/235/241.png +0 -0
  235. package/resources/wechat-emoji//347/240/264/346/266/225/344/270/272/347/254/221.png +0 -0
  236. package/resources/wechat-emoji//347/244/274/347/211/251.png +0 -0
  237. package/resources/wechat-emoji//347/244/276/344/274/232/347/244/276/344/274/232.png +0 -0
  238. package/resources/wechat-emoji//347/246/217.png +0 -0
  239. package/resources/wechat-emoji//347/254/221/350/204/270.png +0 -0
  240. package/resources/wechat-emoji//347/272/242/345/214/205.png +0 -0
  241. package/resources/wechat-emoji//347/277/273/347/231/275/347/234/274.png +0 -0
  242. package/resources/wechat-emoji//350/200/266.png +0 -0
  243. package/resources/wechat-emoji//350/203/234/345/210/251.png +0 -0
  244. package/resources/wechat-emoji//350/204/270/347/272/242.png +0 -0
  245. package/resources/wechat-emoji//350/211/262.png +0 -0
  246. package/resources/wechat-emoji//350/213/246/346/266/251.png +0 -0
  247. package/resources/wechat-emoji//350/217/234/345/210/200.png +0 -0
  248. package/resources/wechat-emoji//350/233/213/347/263/225.png +0 -0
  249. package/resources/wechat-emoji//350/241/260.png +0 -0
  250. package/resources/wechat-emoji//350/243/202/345/274/200.png +0 -0
  251. package/resources/wechat-emoji//350/256/251/346/210/221/347/234/213/347/234/213.png +0 -0
  252. package/resources/wechat-emoji//350/260/203/347/232/256.png +0 -0
  253. package/resources/wechat-emoji//350/267/263/350/267/263.png +0 -0
  254. package/resources/wechat-emoji//350/275/254/345/234/210.png +0 -0
  255. package/resources/wechat-emoji//351/204/231/350/247/206.png +0 -0
  256. package/resources/wechat-emoji//351/227/255/345/230/264.png +0 -0
  257. package/resources/wechat-emoji//351/230/264/351/231/251.png +0 -0
  258. package/resources/wechat-emoji//351/232/276/350/277/207.png +0 -0
  259. package/resources/wechat-emoji//351/252/267/351/253/205.png +0 -0
  260. package/resources/wechat-emoji//351/274/223/346/216/214.png +0 -0
  261. package/scripts/_batch_link_sources.py +73 -73
  262. package/scripts/_utils.py +29 -0
  263. package/scripts/annual_report.py +796 -796
  264. package/scripts/auto_tag.py +128 -128
  265. package/scripts/biz_daily.py +210 -53
  266. package/scripts/chat_report.py +10 -0
  267. package/scripts/chat_stats.py +702 -702
  268. package/scripts/classify_daily.py +17 -11
  269. package/scripts/create_reading_notes.py +370 -370
  270. package/scripts/daily_stats.py +132 -0
  271. package/scripts/enrich_backlinks.py +163 -163
  272. package/scripts/export_chat_html.py +1704 -107
  273. package/scripts/extract_todos.py +445 -404
  274. package/scripts/fav_server.py +119 -12
  275. package/scripts/fix_topics.py +111 -111
  276. package/scripts/generate_ai_report.py +1 -1
  277. package/scripts/generate_html.py +597 -277
  278. package/scripts/inspection_records.py +354 -0
  279. package/scripts/mcp_bridge.py +398 -398
  280. package/scripts/nt_decrypt.py +702 -48
  281. package/scripts/pipeline.py +27 -19
  282. package/scripts/promote_all.py +312 -310
  283. package/scripts/promote_ideas.py +299 -297
  284. package/scripts/rag_chat.py +194 -191
  285. package/scripts/semantic_search.py +435 -431
  286. package/scripts/sync_fav.py +201 -146
  287. package/scripts/sync_weread.py +192 -192
  288. package/scripts/vault_rag.py +140 -139
  289. package/scripts/vault_search.py +141 -141
  290. package/scripts/wechat_emoji.py +132 -0
  291. package/scripts/wechat_emoticon.py +433 -0
  292. package/scripts/wechat_image.py +258 -0
  293. package/scripts/wechat_voice.py +327 -0
  294. package/src/core/dbPathService.ts +163 -18
  295. package/src/core/keyService.ts +137 -25
  296. package/src/core/ntCore.ts +215 -62
  297. package/src/core/sqlcipherCore.ts +17 -1
  298. package/src/core/wcdbCore.ts +3 -7
  299. package/src/services/assistantDaemon.ts +111 -0
  300. package/src/services/assistantMemory.ts +193 -0
  301. package/src/services/assistantPrivacy.ts +87 -0
  302. package/src/services/assistantRouting.ts +92 -0
  303. package/src/services/assistantService.ts +295 -0
  304. package/src/services/assistantTools.ts +549 -0
  305. package/src/services/chatService.ts +133 -4
  306. package/src/services/configService.ts +194 -6
  307. package/src/services/evidenceService.ts +129 -0
  308. package/src/services/exportService.ts +113 -48
  309. package/src/services/initKeyService.ts +83 -0
  310. package/src/services/messageContract.ts +77 -0
  311. package/src/services/messageQuery.ts +38 -0
  312. package/src/services/wechat-formatter.ts +348 -348
  313. package/src/services/wechatMessageService.ts +25 -3
  314. package/src/services/wereadService.ts +308 -308
  315. package/src/services/whitelistService.ts +209 -22
  316. package/src/types.ts +20 -0
  317. package/src/utils/dateRange.ts +58 -0
  318. package/src/utils/mcpSecurity.ts +39 -0
  319. package/src/utils/packageRoot.ts +14 -0
  320. package/src/utils/python.ts +73 -0
  321. package/src/utils/pythonProcessEnv.ts +45 -0
  322. package/src/utils/talkerUtils.ts +14 -2
  323. package/dist/src/utils/errors.d.ts +0 -25
  324. package/dist/src/utils/errors.d.ts.map +0 -1
  325. package/dist/src/utils/errors.js +0 -43
  326. package/dist/src/utils/errors.js.map +0 -1
  327. package/dist/src/utils/pythonRunner.d.ts +0 -27
  328. package/dist/src/utils/pythonRunner.d.ts.map +0 -1
  329. package/dist/src/utils/pythonRunner.js +0 -62
  330. package/dist/src/utils/pythonRunner.js.map +0 -1
  331. package/src/utils/errors.ts +0 -42
  332. package/src/utils/pythonRunner.ts +0 -81
@@ -0,0 +1,234 @@
1
+ # DeepSeek V4 Flash 施工文档
2
+
3
+ > 用途:交给 DeepSeek V4 Flash 或其他代码 Agent 执行 WeFlow CLI 的后续开发。
4
+ > 项目:WeFlow CLI 1.5.x 由于当前仓库可能存在尚未提交的维护者改动,施工前必须先检查工作区,不得覆盖或重置已有修改。
5
+
6
+ ## 1. 施工目标
7
+
8
+ 将 WeFlow CLI 继续建设为安全、可验证、可供 Agent 使用的本地数据底座,优先解决聊天记录 HTML 导出的可靠性,再逐步完善稳定数据契约、公众号日报、知识工作流和受控 AI 能力。
9
+
10
+ 本轮首要目标是:
11
+
12
+ 1. 图片、表情、转发文章和链接在 HTML 导出中尽可能完整显示。
13
+ 2. 媒体必须和正确的消息关联,不能为了提高显示数量而把其他消息或其他会话的图片配进来。
14
+ 3. 转发文章既要保留可用缩略图,也要保留标题、描述和原始跳转链接。
15
+ 4. 大会话导出不能因远程封面或网络请求无限等待。
16
+ 5. 所有改动都要能由测试或脱敏的本机验证证明,不能只凭代码推测已修复。
17
+
18
+ 完整的长期路线见 [ROADMAP.md](ROADMAP.md)。本文件是施工执行书,优先级高于路线图中的远期事项。
19
+
20
+ ## 2. 开工前检查
21
+
22
+ 在任何编辑前执行并记录结果:
23
+
24
+ ```powershell
25
+ git status --short
26
+ git log --oneline -12
27
+ npm run build
28
+ npm test
29
+ python -m unittest discover -s test -p '*_test.py' -q
30
+ ```
31
+
32
+ 如果已有测试失败,先记录失败测试和原因,不能把既有失败归到本次施工,也不能为了变绿而删除或放宽测试。
33
+
34
+ 重点阅读:
35
+
36
+ - `AGENTS.md`:仓库级规则和敏感数据要求。
37
+ - `docs/PROJECT_STATE.md`:当前真实能力、限制和已验证状态。
38
+ - `docs/DECISIONS.md`:已经确定的安全、数据契约和导出设计取舍。
39
+ - `ARCHITECTURE.md`:模块边界和数据流。
40
+ - `SECURITY.md`:隐私、云端 AI、日志和本地服务边界。
41
+ - `docs/DATA_CONTRACT.md`:下游使用的消息契约。
42
+
43
+ ## 3. 不可违反的边界
44
+
45
+ - 只能处理用户本人拥有或明确获授权的数据。
46
+ - 不读取、提交、打印或上传真实数据库、密钥、令牌、完整本地路径、账号标识、真实聊天内容或真实导出文件。
47
+ - 不重置、清理、覆盖或回滚维护者已有的工作区修改。
48
+ - 不使用未经确认的全盘扫描、无界媒体扫描或无界网络请求作为默认流程。
49
+ - 不用未经验证的 local ID 单独关联媒体;local ID 可能在分片或会话之间重复。
50
+ - 不把远程 URL 当作本地图片已经成功显示的证明。
51
+ - 不把“AI 分析完成”表述为法律意见、事实认定或安全保证。
52
+ - 不新增个人微信自动发消息、拉群、群管理或未验证的客户端自动化能力。
53
+ - 不将写操作、云端分析、发布或配置修改加入默认只读 MCP 工具。
54
+ - 不运行 `npm audit fix --force`,除非维护者另行安排独立升级和完整验证。
55
+
56
+ ## 4. P0:聊天导出施工顺序
57
+
58
+ ### 4.1 先建立可观察的导出结果
59
+
60
+ 检查 `scripts/export_chat_html.py` 和 `src/services/exportService.ts`,确保导出结果能够区分:
61
+
62
+ - 消息总数;
63
+ - 图片/表情/转发卡片消息数;
64
+ - 本地缓存命中数;
65
+ - 远程资源成功数;
66
+ - 无法可靠匹配而显示占位的数量;
67
+ - 链接保留数量;
68
+ - 是否因为超时、数据库错误或环境缺少依赖而降级。
69
+
70
+ 统计可以写入终端或机器可读结果,但必须只输出计数、状态和脱敏错误码。不要输出消息正文、图片内容、密钥、路径或账号标识。
71
+
72
+ ### 4.2 修复消息类型判断
73
+
74
+ 微信可能把图片或转发文章存成带高位编码的扩展类型。处理时:
75
+
76
+ 1. 保留原始类型值用于判断其是否为编码扩展类型。
77
+ 2. 使用规范化类型决定通用渲染类别。
78
+ 3. 对带 `title`、`url`、`type` 等 appmsg 元数据的消息,优先进入卡片渲染分支。
79
+ 4. 对同时拥有本地缩略图和文章元数据的消息,同时渲染图片和链接。
80
+ 5. 没有可靠媒体时仍保留标题、描述或原始链接,不把它变成空白气泡。
81
+
82
+ 任何新增分支都必须测试普通图片、表情、普通链接、转发文章、高位编码转发文章和缺失媒体。
83
+
84
+ ### 4.3 设计媒体匹配优先级
85
+
86
+ 建议按下列顺序匹配,并在代码和测试中保持一致:
87
+
88
+ 1. 资源库提供的非零 server message ID 到媒体 MD5 映射。
89
+ 2. 当前会话缓存中的 `local_id + timestamp` 精确组合。
90
+ 3. 当前会话中某个 local ID 只有唯一媒体候选时的保守兜底。
91
+ 4. 消息内容或文件名明确携带的媒体 MD5。
92
+ 5. 已验证的本地 V2 媒体解码路径。
93
+ 6. 消息自带的远程缩略图或 CDN 地址。
94
+
95
+ 以下情况必须拒绝匹配:
96
+
97
+ - server ID 为零且没有其他可靠身份;
98
+ - local ID 对应多个不同媒体;
99
+ - 候选只来自其他会话目录;
100
+ - 只有时间相近但没有消息身份;
101
+ - 文件不是通过真实图片签名验证的图片。
102
+
103
+ ### 4.4 控制远程资源
104
+
105
+ 远程封面和表情只能作为补充。为单次导出设置请求超时、重试次数、总时间预算、响应大小上限和允许的协议/主机范围。预算耗尽后立即保留本地内容和链接,不得让整个导出失败或长时间挂起。
106
+
107
+ 优先顺序必须是:先读取当前会话本地缓存,再尝试账号媒体兜底,最后才访问远程地址。账号级扫描应有明确上限,并且不得把扫描到的无身份媒体直接绑定到消息。
108
+
109
+ ## 5. P1:数据底座施工
110
+
111
+ 在 P0 的导出结果稳定后,再处理数据接口:
112
+
113
+ 1. 检查 `docs/DATA_CONTRACT.md`、`src/services/messageContract.ts` 和 MCP 的消息工具是否语义一致。
114
+ 2. 补充媒体状态、来源、缺失原因和覆盖统计时,保持 `weflow-message/v1` 向后兼容。
115
+ 3. 新增字段必须允许缺失;未知消息类型必须原样保留或以明确的 unknown 类型返回。
116
+ 4. 日期范围、分页、数量上限和 `mayHaveMore` 语义必须在 CLI JSON 与 MCP 中一致。
117
+ 5. MCP 仍保持默认只读,不传递数据库路径、密钥、任意文件内容或无界聊天记录。
118
+ 6. 为合作项目提供合成数据示例,禁止把真实聊天记录当 fixture。
119
+
120
+ ## 6. P2:日报和阅读器施工
121
+
122
+ 只有在导出和契约没有回归后才进入日报工作:
123
+
124
+ - 保持来源级分类优先;已有公众号类别时不重复进行文章主题分类。
125
+ - `daily --no-ai` 必须不调用 AI,但仍能抓取、生成 HTML、写入本地索引和补齐必要的前一日报告。
126
+ - 日报抓取需要去重、有限重试、失败状态和可重跑能力。
127
+ - 阅读器继续只监听回环地址,读写接口保留路径校验和来源校验。
128
+ - 定时任务必须能报告成功、失败或跳过,不能静默重复启动阅读器。
129
+
130
+ ## 7. P3:受控 AI 施工
131
+
132
+ AI 功能必须满足以下顺序:
133
+
134
+ 1. 用户明确选择数据范围。
135
+ 2. 执行前提供预览,说明是否联网、使用哪个模型、输入规模和可能成本。
136
+ 3. 严格模式下过滤第三方聊天内容和常见个人信息。
137
+ 4. 本地模型优先作为可选路径;关闭 AI 后基础查询、导出和日报仍可用。
138
+ 5. 输出保留来源和引用;法律相关功能只能整理线索、时间线和材料清单,不得宣称法律结论。
139
+ 6. 云端调用和本地写入均要有可审计的脱敏状态,不记录原文和密钥。
140
+
141
+ ## 8. 必须补齐的测试
142
+
143
+ ### Python 导出测试
144
+
145
+ 至少覆盖:
146
+
147
+ - 普通图片按精确会话缓存命中;
148
+ - 同一 local ID 对应不同图片时拒绝唯一兜底;
149
+ - 高位编码图片类型可以显示本地图片;
150
+ - 高位编码转发文章同时显示图片、标题和链接;
151
+ - 普通 appmsg 链接保留标题、描述和 URL;
152
+ - 资源库 server ID 映射只接受非零且匹配的消息;
153
+ - 缺失媒体时显示可读占位而不是错误图片;
154
+ - 远程请求预算耗尽后本地媒体仍能导出;
155
+ - 非图片文件不会生成 `<img>`;
156
+ - 账号目录中的无关图片不会被绑定到当前会话。
157
+
158
+ ### TypeScript 回归
159
+
160
+ 涉及服务、CLI、MCP、配置或路径时,运行:
161
+
162
+ ```powershell
163
+ npm run build
164
+ npm test
165
+ ```
166
+
167
+ ### 脱敏本机验收
168
+
169
+ 在用户授权的本机环境运行完整导出后,只记录下列信息:
170
+
171
+ - 导出是否成功;
172
+ - 消息总数;
173
+ - 图片/表情/链接命中数;
174
+ - 占位数量;
175
+ - 是否发生超时或降级。
176
+
177
+ 打开 HTML 人工抽查至少三类内容:普通图片、转发文章、无法恢复媒体的消息。抽查结果不得复制聊天文字或上传截图。
178
+
179
+ ## 9. 推荐验证命令
180
+
181
+ 开发源码布局:
182
+
183
+ ```powershell
184
+ npm run build
185
+ npm test
186
+ python -m unittest discover -s test -p '*_test.py' -v
187
+ git diff --check
188
+ ```
189
+
190
+ 导出真实数据时,使用用户已确认的会话选择方式和当前项目的 CLI,不要把密钥或数据库参数写进命令行。优先使用日期范围或单个会话进行验证,避免无边界导出。
191
+
192
+ 编译布局也必须验证资源解析:
193
+
194
+ ```powershell
195
+ node cli.cjs capabilities --json
196
+ node cli.cjs check --json
197
+ node cli.cjs export <已授权会话> html --json
198
+ ```
199
+
200
+ 命令中的尖括号内容只表示本机交互时替换的占位符,不得写入文档、日志或提交记录。
201
+
202
+ ## 10. 施工完成标准
203
+
204
+ DeepSeek V4 Flash 只有在以下条件全部满足时才能报告完成:
205
+
206
+ - 改动前后工作区差异清晰,未覆盖维护者已有修改。
207
+ - `npm run build` 通过。
208
+ - `npm test` 全部通过。
209
+ - Python 导出专项测试全部通过。
210
+ - `git diff --check` 通过。
211
+ - 至少一次脱敏本机导出证明图片和转发链接的实际渲染结果。
212
+ - 导出统计能解释成功、缺失、降级和超时情况。
213
+ - 文档已同步:需要时更新 `PROJECT_STATE.md`、`DECISIONS.md`、`CHANGELOG.md` 和相关契约文档。
214
+ - 检查差异中没有真实隐私数据、密钥、令牌、账号标识、数据库、日志或导出文件。
215
+
216
+ 如果真实环境仍无法可靠关联某类媒体,应明确报告“无法验证”及阻断原因,保留安全占位,不得把推测结果写成修复完成。
217
+
218
+ ## 11. 提交规则
219
+
220
+ 施工 Agent 默认只修改代码、测试和必要文档,不自动提交或推送。提交前输出:
221
+
222
+ 1. 改动文件清单;
223
+ 2. 每个改动的目的;
224
+ 3. 测试命令和结果;
225
+ 4. 仍存在的限制;
226
+ 5. 敏感信息检查结果。
227
+
228
+ 提交信息应简短、准确、说明用户可见结果,例如:
229
+
230
+ ```text
231
+ fix: preserve encoded forwarded media links in HTML export
232
+ ```
233
+
234
+ 不得在提交信息、Issue、PR 或公开文档中写入真实本地数据和调试输出。
@@ -0,0 +1,96 @@
1
+ # 电子数据证据指南
2
+
3
+ > 本文是软件使用和证据保全说明,不是法律意见。不同案件、诉讼程序和地区的判断可能不同;准备提交前应咨询律师或向有权处理案件的机构核验。
4
+
5
+ ## 1. 项目能做什么
6
+
7
+ WeFlow CLI 可以在用户本人设备上,对用户本人有权访问的本地聊天数据进行:
8
+
9
+ - 按会话提取消息及其本地消息 ID、时间、发送方和消息类型。
10
+ - 保存一份只读意义上的原始提取副本。
11
+ - 计算 `SHA-256`,便于发现保全包生成后是否被改动。
12
+ - 记录提取时间、数据范围、消息数量和用户授权声明。
13
+ - 生成保全说明,提示保留原设备、原数据库、官方导出记录和完整上下文。
14
+
15
+ 工具不判断“这条消息一定有法律效力”,不替代公证、司法鉴定、律师意见或法院对证据的审查,也不应修改、补写或伪造消息。
16
+
17
+ ## 2. 中国大陆民事证据规则的基本框架
18
+
19
+ 根据《中华人民共和国民事诉讼法》关于电子数据的证据类型,以及最高人民法院《民事诉讼证据的若干规定》(法释〔2019〕19号)关于电子数据的规定,聊天记录、短信、电子邮件、即时通信、通信群组信息、登录和身份认证信息、电子交易记录,以及保存在终端设备中的文字、图片、音视频等,可能属于电子数据。
20
+
21
+ 能否被采信通常要结合案件审查,不能只看文件后缀或是否有截图。实际重点通常包括:
22
+
23
+ 1. **真实性**:是否确实来自相关账号、设备、平台或生成环境;账号由谁控制,消息是否可能被冒用。
24
+ 2. **完整性**:是否有连续上下文,是否存在删改、截取、拼接、转换或缺页。
25
+ 3. **关联性**:是否能证明争议事实,时间、人物、金额、承诺和事件之间是否对应。
26
+ 4. **合法来源**:取得和保存方式是否侵犯他人隐私、商业秘密或其他合法权益,是否违反程序要求。
27
+ 5. **可核验性**:能否回到原设备、原应用、原数据库、平台记录、备份或其他独立证据进行复核。
28
+
29
+ 电子数据由中立第三方平台保存、在正常业务活动中形成、由档案管理机构保存,或者与其他证据相互印证时,可能具有更强的证明力;这仍然不是自动采信。
30
+
31
+ ## 3. 哪些材料通常更有帮助
32
+
33
+ 以下材料应尽量组合保存,而不是只提交其中一张截图:
34
+
35
+ - 原设备、原微信账号、原始数据库或官方备份/迁移记录。
36
+ - 连续、完整的聊天上下文,包括会话名称、参与者、时间、前后消息和附件关系。
37
+ - 可回溯的消息 ID、原始文件、导出时间、工具版本和操作记录。
38
+ - 原始媒体文件及其文件哈希,不要只保存压缩后的截图。
39
+ - 对方身份、账号归属、联系方式和实际履行情况等独立佐证。
40
+ - 转账、订单、合同、邮件、物流、通话记录等与聊天内容相互印证的材料。
41
+ - 必要时由公证、司法鉴定、平台出具记录或其他有权机构进行进一步固定和核验。
42
+
43
+ 截图可以帮助阅读和定位,但单独的截图通常难以证明完整来源和未被编辑。AI 摘要、主题分类、情绪判断和“法律证据提取结果”只能作为整理线索,不能当作原始证据。
44
+
45
+ ## 4. 使用证据保全命令
46
+
47
+ 先完成初始化,然后针对明确会话创建本地证据包:
48
+
49
+ ```powershell
50
+ weflow-cli evidence "联系人或群聊" --output "./output/evidence" --case "争议事项说明"
51
+ ```
52
+
53
+ 证据包包括:
54
+
55
+ - `messages.json`:从本地数据提取的消息副本。
56
+ - `manifest.json`:消息数量、时间范围、消息 ID、生成时间和 SHA-256。
57
+ - `README.md`:保全边界和后续建议。
58
+
59
+ 建议创建后立即:
60
+
61
+ 1. 记录谁在什么设备、什么时间、用什么版本创建了保全包。
62
+ 2. 保留原设备和原始数据库,不在原文件上编辑或覆盖。
63
+ 3. 只对副本做脱敏、标注、摘要和分析,并分别计算处理前后的哈希。
64
+ 4. 保留完整上下文,不要只导出对自己有利的片段。
65
+ 5. 限制证据包访问权限,不通过公开 Issue、网盘链接或未经审查的 MCP 发送。
66
+ 6. 交由律师、公证机构、司法鉴定机构或办案机构判断下一步固定方式。
67
+
68
+ 哈希只能证明某个文件在两个时间点之间是否发生变化,不能单独证明文件内容真实、账号属于谁、消息没有在更早之前被修改,也不能证明法院一定采信。
69
+
70
+ ## 5. AI 线索分析(可选)
71
+
72
+ 如果需要让 AI 帮助浏览某个会话,可以使用:
73
+
74
+ ```powershell
75
+ weflow-cli evidence-review "联系人或群聊" --output "./output/evidence-review"
76
+ ```
77
+
78
+ 该命令只生成“疑似争议线索、待核验法律主题、材料缺口和保全建议”,要求每项尽量引用消息 ID;它不认定违法、不判断证据必然有效,也不替代律师、鉴定、公证或法院审查。
79
+
80
+ - 默认拒绝把聊天正文发送到云端;建议配置 Ollama 或 LM Studio,在本机完成分析。
81
+ - 只有明确确认后才使用 `--allow-cloud`;云端仍受 `assistantPrivacy` 隐私模式约束,`strict` 模式会屏蔽第三方聊天正文。
82
+ - AI 输出只能作为整理线索,必须回看 `messages.json`、原设备和完整上下文,不得把 AI 生成内容当作原始证据。
83
+
84
+ ## 6. 隐私和授权边界
85
+
86
+ 本功能仅限用户本人设备和本人有权访问的数据。不得用它监控配偶、员工或其他第三方,不得在未获授权的设备上提取数据。聊天记录通常包含第三方个人信息,向律师、机构或云端服务提供前应先确认必要性、授权范围和脱敏方案。
87
+
88
+ WeFlow CLI 默认在本机生成证据包,不会自动上传。使用云端 AI 分析时,证据原文可能离开本机,必须由用户单独确认;证据保全本身不需要调用 AI。
89
+
90
+ ## 7. 参考依据
91
+
92
+ - 《中华人民共和国民事诉讼法》:国家法律法规数据库 https://flk.npc.gov.cn/
93
+ - 《最高人民法院关于民事诉讼证据的若干规定》(法释〔2019〕19号):最高人民法院 https://www.court.gov.cn/
94
+ - 最高人民法院司法解释和诉讼指南:最高人民法院 https://www.court.gov.cn/
95
+
96
+ 官方条文、司法解释和案件规则可能更新。使用前应在国家法律法规数据库、最高人民法院官网或当地有权机构核对最新文本。
package/docs/MCP.md ADDED
@@ -0,0 +1,95 @@
1
+ # MCP Integration
2
+
3
+ ## Read-only message export
4
+
5
+ The local stdio MCP server provides `wechat.export_messages` for downstream projects that need the same versioned message contract as the CLI export.
6
+
7
+ Example input:
8
+
9
+ ```json
10
+ {
11
+ "contact": "wxid_example",
12
+ "limit": 100,
13
+ "from": "YYYY-MM-DD",
14
+ "to": "YYYY-MM-DD"
15
+ }
16
+ ```
17
+
18
+ The tool returns a JSON string with `schema: "weflow-message/v1"` and `coverage` metadata for the requested range, returned count, conservative `mayHaveMore` status, and returned time bounds. `limit` defaults to 100 and is capped at 1000. `from` and `to` are inclusive local dates. Use a session ID when a display name is ambiguous.
19
+
20
+ This tool is read-only. It does not expose database paths, keys, configuration, or unrestricted filesystem access, and it does not invoke AI. Unknown WeChat message codes remain in the output with their original `localType` and `messageType: "other"`.
21
+
22
+ WeFlow CLI exposes article, knowledge-base, and selected local-data functions through an MCP server over stdio. The server reads the project's local `output/` directory and only contacts external services when a requested tool requires it. The available inventory follows `mcp-server/index.ts`; do not hard-code a tool count in client documentation.
23
+
24
+ External article fetching accepts only credential-free HTTPS URLs on the exact `mp.weixin.qq.com` host. Redirects must remain on that host and all network reads have finite timeout, redirect, result-count, and response-size limits.
25
+
26
+ ## Configure a client
27
+
28
+ From the project root, generate the baseline configuration:
29
+
30
+ ```powershell
31
+ weflow-cli mcp-config --output .mcp.json --dry-run --json-result
32
+ weflow-cli mcp-config --output .mcp.json --yes
33
+ ```
34
+
35
+ Without `--output`, `weflow-cli mcp-config` remains a read-only command that prints the configuration to stdout.
36
+
37
+ The generated server starts with Node.js and `tsx`:
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "weflow": {
43
+ "command": "npx",
44
+ "args": ["tsx", "mcp-server/index.ts"],
45
+ "cwd": "${workspaceFolder}"
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ Copy this entry into your MCP client's configuration and ensure `cwd` points to the cloned WeFlow CLI directory. Restart the client after saving the configuration.
52
+
53
+ ## Available tools
54
+
55
+ | Tool | Purpose | Local data required |
56
+ | --- | --- | --- |
57
+ | `wechat.search_articles` | Search captured official-account articles. | `output/biz-daily/` |
58
+ | `wechat.get_daily` | Read a daily article collection. | `output/biz-daily/` |
59
+ | `wechat.get_review` | Read an AI learning review. | `output/reviews/Daily/` |
60
+ | `wechat.get_stats` | Show article, knowledge-base, and local WeChat data statistics. | Generated output |
61
+ | `wechat.get_concepts` | List compiled concepts. | Vault Wiki output |
62
+ | `wechat.get_concept` | Read one compiled concept. | Vault Wiki output |
63
+ | `wechat.format_article` | Convert Markdown to WeChat-ready HTML. | None |
64
+ | `wechat.list_themes` | List available article themes. | None |
65
+ | `wechat.fetch_article` | Fetch and convert a public WeChat article. | Network access |
66
+ | `wechat.search_public` | Search public WeChat articles. | Network access |
67
+ | `wechat.list_sessions` | List recent chat sessions with last-message snippets. | Decrypted WeChat database |
68
+ | `wechat.get_messages` | Read recent messages with one contact. | Decrypted WeChat database |
69
+ | `wechat.search_favorites` | Search WeChat favorites (official-account articles, notes, links). | Decrypted WeChat database |
70
+ | `wechat.read_favorite` | Fetch and read the body of a favorited article. | Decrypted WeChat database, network access |
71
+ | `wechat.get_daily_report` | Filter daily reports by topic/keyword with AI summaries. | `output/biz-daily/` |
72
+ | `wechat.get_sns` | Read the Moments timeline or statistics. | Decrypted WeChat database |
73
+ | `wechat.get_weread` | Read WeRead shelf, notebooks, or search books. | `wereadApiKey` config |
74
+ | `wechat.get_todos` | List todos extracted from chat history. | `scripts/extract_todos.py`, Python |
75
+ | `wechat.search_knowledge` | Fuzzy-search concept pages in the knowledge base. | Vault Wiki output |
76
+ | `wechat.search_memory` | Search long-term assistant memory. | `~/.weflow-cli/assistant_memory.json` |
77
+
78
+ The chat-data tools share service code with the optional `weflow-cli assistant` WeChat bot, but access is still controlled by the MCP client's permissions and local configuration. The bot and MCP transport are not interchangeable message channels.
79
+
80
+ ## Safety boundary
81
+
82
+ - The server inherits the permissions of the MCP client. Only add it to a client you trust.
83
+ - Article and knowledge-base tools read files under the current project directory. Keep `cwd` scoped to your intended WeFlow CLI checkout.
84
+ - Chat-data tools (`list_sessions`, `get_messages`, `search_favorites`, `get_sns`, `get_todos`) read your locally decrypted WeChat database. Only run this MCP server on machines where that is acceptable, and never expose the stdio server over a network.
85
+ - `read_favorite`, `fetch_article`, and `search_public` make network requests; `read_favorite` rejects private/loopback URLs.
86
+ - The default MCP surface is read-only. It does not publish drafts, save assistant memory, send messages, mutate todos, or change configuration. Side effects remain in explicit CLI or assistant workflows with their own confirmation boundary.
87
+ - Do not place API keys in `.mcp.json`. Use environment variables where a client supports them.
88
+
89
+ ## Troubleshooting
90
+
91
+ | Symptom | Check |
92
+ | --- | --- |
93
+ | Server fails to start | Run `npm install` in the configured `cwd`, then run `npx tsx mcp-server/index.ts`. |
94
+ | No articles found | Generate a daily collection first, then confirm `output/biz-daily/` exists under `cwd`. |
95
+ | Client cannot find `npx` | Configure an absolute Node.js command path or install Node.js 18+. |
@@ -0,0 +1,41 @@
1
+ # 合作伙伴记录
2
+
3
+ > 本文档记录 WeFlow CLI 与外部项目之间的技术协作边界。这里只记录公开的项目事实、接口约定和工程改进,不记录任何用户数据。
4
+
5
+ ## she-love-me
6
+
7
+ ### 感谢
8
+
9
+ 感谢 `she-love-me` 项目采用 WeFlow CLI 作为本地微信数据来源,并围绕真实使用场景反馈兼容性需求。对方的接入需求帮助我们发现:如果希望支持更多下游应用,数据导出格式、字段含义和版本兼容规则必须明确记录,而不能只依赖当前实现。
10
+
11
+ ### 我们完成的改进
12
+
13
+ - 保留原有 `weflow-cli export <contact> json` 调用方式,避免影响已有使用者。
14
+ - 新增可选的 `weflow-message/v1` 版本化 JSON 契约,为下游应用提供稳定的消息结构。
15
+ - 增加 `messageType` 标准化字段,覆盖常见文本、图片、语音、视频、表情、链接等类型。
16
+ - 对未知消息类型保留原始 `localType` 和原始字段,并归类为 `other`,避免因类型不认识而丢失消息。
17
+ - 新增只读 MCP 工具 `wechat.export_messages`,支持会话、日期范围和数量限制。
18
+ - MCP 默认限制返回数量,不暴露数据库路径、密钥、配置或任意文件系统访问,也不隐式调用 AI。
19
+ - 将接口语义和隐私边界记录在 [DATA_CONTRACT.md](DATA_CONTRACT.md) 与 [MCP.md](MCP.md) 中,并加入构建和回归测试。
20
+
21
+ ### 合作边界
22
+
23
+ `she-love-me` 是独立的外部项目,WeFlow CLI 只提供通用的本地只读数据接口,不直接维护对方的业务代码或内部数据转换逻辑。下游项目应自行完成:
24
+
25
+ - 将公共消息契约转换为自身的业务模型;
26
+ - 处理未知消息类型、缺失发送者和媒体不可用等情况;
27
+ - 将导出数据和分析结果保存在用户本地;
28
+ - 在把用户选择的数据发送到云端模型前取得明确授权并进行隐私处理。
29
+
30
+ WeFlow CLI 不接收或提交真实微信数据库、密钥、聊天记录、账号标识、日志或其他个人信息作为合作材料。
31
+
32
+ ### 当前状态
33
+
34
+ - 数据接口:`export ... json --contract weflow-v1` 已实现。
35
+ - MCP 接口:`wechat.export_messages` 已实现为本地 stdio 只读工具。
36
+ - 验证:TypeScript 构建和现有回归测试通过。
37
+ - 兼容性:已规范化常见消息类型,但不宣称覆盖所有微信未来格式;未知类型必须由下游安全保留和降级处理。
38
+
39
+ ### 后续协作方式
40
+
41
+ 后续如需扩展接口,优先通过公开的字段契约、合成 fixtures、最小复现和版本化变更进行协作。涉及真实用户数据、云端 AI、写入操作、消息发送或平台自动化的需求,必须单独进行隐私和安全评审。
@@ -0,0 +1,96 @@
1
+ # Project State
2
+
3
+ > Last reviewed: 2026-09-08. This is the current maintenance snapshot, not a release note. Keep it factual and update it with meaningful project changes.
4
+
5
+ ## Purpose
6
+
7
+ WeFlow CLI is a local-first command-line tool and MCP server for user-authorized WeChat data workflows: local chat queries and exports, official-account daily reading, favorites, knowledge workflows, and an optional local assistant.
8
+
9
+ ## Current Baseline
10
+
11
+ - Source package version: `1.5.1`. The npm registry may remain on an earlier version until a maintainer publishes a release.
12
+ - Runtime: Node.js 18+; Python 3.10+ is required for database and daily-reading workflows.
13
+ - Main development command: `npm run dev -- <command>`.
14
+ - Compiled/package command: `node cli.cjs <command>`; CLI, MCP, database, export, and assistant services resolve resources from the same package root in both source and compiled layouts.
15
+ - Build check: `npm run build`.
16
+ - Regression check: `npm test`.
17
+ - Downstream data contract: local JSON export is the first compatibility boundary for `she-love-me` and future consumers; see `docs/DATA_CONTRACT.md`.
18
+ - Supported focus: Windows WeChat 4.x; Linux WeChat 4.x has an NT database path; macOS requires user-provided local access credentials for initialization.
19
+
20
+ ## Verified Capabilities
21
+
22
+ | Area | Current state | Main entry points |
23
+ | --- | --- | --- |
24
+ | Local chat data | Query sessions, contacts, messages, favorites, Moments cache, and exports. HTML chat exports decode NT compressed media records, locally cached WeChat 4.x V2 image containers, entity-escaped emoji XML, and remote emoticons; app cards preserve links and embed available公众号/Bilibili covers. Media matching prefers server-message resources, exact local-message-ID plus timestamp pairs, and a unique local-ID fallback; high-bit encoded image rows are resolved through the same conversation cache. | `sessions`, `contacts`, `messages`, `export`, `fav`, `sns` |
25
+ | Initialization | Verify and reuse existing local database access by default; refresh only when needed. Missing-key tests can run without changing saved configuration. | `init`, `init --refresh`, `init --test-missing-keys`, `config forget-keys`, `check` |
26
+ | Official-account daily | Filter configured sources, preserve source categories, backfill incomplete yesterday output before an unqualified today run, fetch articles, create summaries, generate a local HTML reader, and synchronize reader favorites into local files. | `daily`, `daily favorites`, `daily-stats`, `daily-server` |
27
+ | Knowledge workflows | Wiki compilation, semantic search, RAG, WeRead sync, reviews, reading notes, and staged Vault promotion. | `wiki`, `vault`, `search`, `chat`, `weread`, `review` |
28
+ | MCP | Local stdio MCP server exposes bounded read and local transformation tools, including the `wechat.export_messages` versioned message contract. Publishing, messaging, memory writes, todo mutation, configuration changes, and deletion are excluded. | `mcp-config`, `mcp-server/index.ts` |
29
+ | Assistant | Optional WeChat Bot-channel assistant with local memory and privacy gates. | `login-wechat`, `assistant` |
30
+
31
+ The 67-test TypeScript regression suite covers home-path expansion, custom NT data-root discovery, bounded daily-favorites synchronization, confirmed no-AI daily generation, no-AI Vault promotion, Vault content mutation previews, Vault initialization and synchronization confirmation, MCP configuration write confirmation, source/compiled Python resource lookup, outbound PII redaction, local-inference bypass, strict message-body masking, MCP path/date/URL validation and live tool discovery, message-contract preservation, local-date export bounds, export result metadata, evidence-package safety, assistant routing and lifecycle confirmation, message-channel authentication confirmation, todo and access-control mutation confirmation, message-send preview/confirmation, local-reader port validation, redacted configuration status, access-list JSON, database-key reset confirmation, human-gated initialization and key capture, content-free account-scan and assistant-log diagnostics, confirmed Vault RAG, confirmed semantic search and RAG chat, structured todo reminders, strict knowledge limits, report previews, and cover-image signature validation. Core automation entry points now include `capabilities --json`, `config show --json`, `whitelist list --json`, `blacklist list --json`, `check --json`, `init --dry-run --json`, `scan --json`, `dbkey --dry-run --json`, `sessions --json`, `messages --json`, `contacts --json`, `export ... --json`, `fav export ... --json-result`, `sns ... --json`, `daily-stats --json`, `daily --no-ai --dry-run --json`, `daily-server --status --json`, `assistant status --json`, `assistant log --json`, `todos list --json`, `todos remind --json`, `evidence --json`, `evidence-review --dry-run --json`, Vault mutation previews, confirmed `vault rag`, confirmed `search` and `chat`, daily-favorite previews, `search-index --dry-run --json`, `pipeline run --dry-run --json`, report-generator previews, login/logout previews, and `mcp-config --output <file> --dry-run --json-result`. CI runs both the build and this suite on Node 20 with Python 3.10 available for path-discovery coverage.
32
+
33
+ The daily workflow supports `dailyAiEnabled=false` for a persistent no-AI mode, or `daily --no-ai` for a single run. Both the CLI and direct Python entry points honor the setting. Fetching, HTML generation, and local indexes remain available in that mode. Machine execution requires `daily --yes --json`; it keeps progress logs on stderr and returns a machine-readable completion result on stdout after checking the required local artifacts.
34
+
35
+ Date-bounded message exports and `wechat.export_messages` page through the selected conversation before applying the result limit. Older matching dates are therefore not hidden by a newer, nonmatching first page. Versioned envelopes report requested bounds, returned count, and conservative `mayHaveMore` metadata; a stable incremental cursor is not yet exposed.
36
+
37
+ ## Security Baseline
38
+
39
+ - Process only data the user owns or is explicitly authorized to access.
40
+ - Sensitive configuration fields are encrypted at rest with machine- and user-bound AES-256-GCM.
41
+ - The daily reader binds to `127.0.0.1`; its API rejects cross-origin mutations, validates local paths, and restricts image proxy requests.
42
+ - The assistant denies all senders until `assistantWhitelist` is explicitly configured. Group routing is experimental and remains denied unless the upstream explicitly supplies group metadata, the group and sender are both allowlisted, and the bot is mentioned. New or incomplete configurations use `strict` privacy mode for cloud inference.
43
+ - MCP path inputs are constrained to their expected data roots. MCP clients remain trusted local integrations and must be reviewed before configuration.
44
+ - The default MCP tool list is read-only: it excludes publishing, messaging, assistant-memory writes, todo mutation, configuration changes, and deletion. Conversation display names must resolve uniquely before chat data is read.
45
+ - Public reports and commits must not contain databases, keys, tokens, wxid values, real chat content, or unredacted logs.
46
+ - Todo status changes and deletion use a preview/confirm protocol. Machine callers receive `CONFIRMATION_REQUIRED` unless the user-approved execution includes `--yes`.
47
+ - AI and database credentials, selected-conversation identifiers, private queries and filters, export locations and display names, and NT scan roots are inherited by workers through environment variables and are not copied into child-process command arguments. Long-lived worker environments clear unrelated internal values before startup.
48
+ - `config set-env` and `fav set-key --from-env` provide command-history-safe secret input. Their JSON workflows require a read-only preview followed by explicit `--yes`, and never return secret values or discovered database paths. Bulk clearing of configuration, access lists, or audit history requires interactive confirmation or explicit `--yes`.
49
+ - Core JSON reads validate pagination before database access. `messages --start/--end` now applies its Unix-second time range before offset and limit instead of silently ignoring the options.
50
+ - `scan --json` and `assistant log --json` return metadata only. They intentionally omit local paths, account identifiers, nicknames, and log content. `evidence-review` requires preview and confirmation, and its machine result omits both analysis text and the output path.
51
+ - `init --dry-run --json` exposes a content-free plan. JSON execution returns `INTERACTIVE_REQUIRED`; database verification, directory discovery, key capture, and configuration writes remain an explicit terminal workflow.
52
+ - `vault rag` requires a read-only preview and explicit confirmation before reading local knowledge or calling the configured AI provider. The question is inherited by the Python worker through the environment rather than copied into process arguments.
53
+ - `search` and `chat` use the same preview/confirmation boundary. Queries, questions, and optional conversation restrictions are inherited through the worker environment instead of appearing in process arguments; machine callers cannot start interactive RAG chat.
54
+ - `daily-server --status --json` remains read-only. Machine startup uses `daily-server --dry-run --json` followed by `daily-server --yes --json`; the confirmed process is detached and remains bound to loopback. The legacy `fav-server` compatibility entry enforces the same preview and confirmation rules.
55
+
56
+ Documentation was synchronized with the `1.5.1` source baseline on 2026-09-09. Command behavior is defined by `bin/weflow-cli.ts`; detached reader startup waits for service readiness, and release packages can lag behind the GitHub source until published.
57
+
58
+ ## Active Constraints
59
+
60
+ - Issue #7 remains open pending reporter verification. HTML emoji export preserves the emoji label and matches resource records only by nonzero server-message identity; local IDs are not unique across shards or conversations. WeChat 4.x V2 image containers are decoded with an account-specific media key derived from local `kvcomm` data and verified against a real cached V2 header. Remote emoticons use AES-CBC with the message key as both key and IV. Entity-escaped emoji XML is normalized before extracting MD5 and media URLs; failed encrypted downloads fall back across available thumbnail/CDN fields. Signature-only default `[打脸]` messages use the bundled official Facepalm asset when no message-specific resource is available. Forwarded app cards remain structured links with available covers, and Bilibili share pages can resolve covers through their BV metadata endpoint when no `og:image` is present. Thirteen synthetic Python regression tests cover these paths; run `python -m unittest discover -s test -p '*_test.py' -v`. CI also runs these tests. This does not establish compatibility with every real WeChat media format.
61
+
62
+ - WeChat platform behavior, database formats, account restrictions, and terms can change without notice. Local operation is not a legal, account-safety, or platform-compatibility guarantee.
63
+ - The daily workflow can take substantial time when many configured sources publish on the same day. It fetches article bodies sequentially to reduce upstream pressure.
64
+ - The OC Bot channel is separate from a personal WeChat message stream. `send` can only reply through an already established Bot-channel conversation with a valid context token; it cannot initiate messages to existing personal contacts, post as the user's personal account, or send into ordinary personal WeChat groups.
65
+ - The current official OC/iLink payload model has not been verified to support group events or group invitations. The project does not implement client automation or protocol bypasses to add a bot to groups.
66
+ - Cloud AI workflows may transmit user-selected, privacy-filtered input to the configured provider. Local inference avoids that network transfer.
67
+ - `vault promote ideas` and `vault promote all` run without AI by default. AI generation requires explicit `--with-ai` and an API key. CLI execution also requires preview and confirmation. `vault init` creates both the existing article-sync folders and the structured directories required by promotion workflows.
68
+ - `vault init`, semantic-index construction, the knowledge pipeline, and report generators require preview and confirmation for machine execution. Preview JSON contains counts and behavior flags but omits local paths, conversation names, and generated content.
69
+ - Automatic data-directory discovery checks common user locations only. Cross-drive name search requires `init --search-drives`; structural disk search requires `init --full-scan`. Both can be slow on large, removable, or network-attached volumes.
70
+ - Dependency audit findings must be reviewed before dependency upgrades; do not run breaking `npm audit fix --force` without validation.
71
+ - The WCDB native query entry point has no parameter-binding ABI. Calls that supply parameters are rejected rather than falling back to interpolated SQL; existing internal callers are unchanged.
72
+
73
+ ## Current Priorities
74
+
75
+ 1. Keep initialization and database access compatible with supported WeChat 4.x variants, with reproducible issue diagnostics that contain no secrets.
76
+ 2. Keep the daily reader reliable for configured sources and categories without widening access to local data.
77
+ 3. Maintain security boundaries around local servers, assistant access, MCP tools, and cloud AI disclosure.
78
+ 4. Evaluate external collaboration through read-only, synthetic-data, versioned interfaces before connecting real user data.
79
+ 5. Make Bot-channel send capability and its limitations unambiguous in CLI naming and help text before extending messaging features.
80
+
81
+ ## External Collaboration Position
82
+
83
+ For projects such as Yance, WeFlow CLI remains an independent local data-access layer. Early collaboration may cover read-only schemas, anonymized fixtures, and controlled MCP adapters. It must not require sharing real databases, credentials, keys, full local directories, or direct database access by an external product.
84
+
85
+ ## Related Documents
86
+
87
+ - Architecture and data flow: [ARCHITECTURE.md](../ARCHITECTURE.md)
88
+ - Setup and troubleshooting: [OPERATIONS.md](../OPERATIONS.md)
89
+ - Security and reporting: [SECURITY.md](../SECURITY.md)
90
+ - MCP surface: [MCP.md](MCP.md)
91
+ - Design rationale: [DECISIONS.md](DECISIONS.md)
92
+ - Partner integration record: [PARTNERS.md](PARTNERS.md)
93
+ - AI integration surface: [AI_INTERFACE.md](AI_INTERFACE.md)
94
+ - Overall improvement and expansion plan: [ROADMAP.md](ROADMAP.md)
95
+ - DeepSeek V4 Flash施工文档: [DEEPSEEK_V4_FLASH施工文档.md](DEEPSEEK_V4_FLASH施工文档.md)
96
+ - User-visible releases: [CHANGELOG.md](../CHANGELOG.md)