@wirecat/mail-cli 0.4.0 → 0.6.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 (281) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +41 -10
  3. package/dist/bin/mail.js +2 -2
  4. package/dist/bundle/{all-profiles-55XPXQHY.js → all-profiles-GBFTKUHA.js} +9 -9
  5. package/dist/bundle/{anthropic-K5B6I4LB.js → anthropic-PTSCWUG6.js} +6 -6
  6. package/dist/bundle/{app-server-VWWLQLTZ.js → app-server-5VJ2WCKJ.js} +46 -46
  7. package/dist/bundle/{bun-EO7AI6YP.js → bun-2KRUBPIN.js} +2 -2
  8. package/dist/bundle/{bun-sqlite-F24A4IOP.js → bun-sqlite-ELSRSJBM.js} +5 -5
  9. package/dist/bundle/{chunk-X7AXH2IC.js → chunk-3KY7DA5A.js} +428 -434
  10. package/dist/bundle/{chunk-ANRI6EZY.js → chunk-4PKHZQIM.js} +8 -8
  11. package/dist/bundle/{chunk-CADRRSQK.js → chunk-56PI2BRH.js} +1 -1
  12. package/dist/bundle/{chunk-2ADB5DSG.js → chunk-5AQKM47C.js} +3 -3
  13. package/dist/bundle/{chunk-VP5GCMHM.js → chunk-5KHJUYHQ.js} +8 -8
  14. package/dist/bundle/{chunk-HUB42T2Z.js → chunk-6MV2TBDB.js} +57 -54
  15. package/dist/bundle/{chunk-4KLJN3LK.js → chunk-AGX7NR3S.js} +26 -13
  16. package/dist/bundle/{chunk-ZD3WUGR2.js → chunk-B337KHJ5.js} +4 -4
  17. package/dist/bundle/{chunk-5BVIWP3S.js → chunk-BM445GYF.js} +2 -2
  18. package/dist/bundle/{chunk-H7K2DN3R.js → chunk-BVIHT7KR.js} +9 -9
  19. package/dist/bundle/{chunk-EDKV6D6T.js → chunk-DA46WQEA.js} +1 -1
  20. package/dist/bundle/{chunk-UO7X2VW4.js → chunk-DV4RSEAH.js} +6 -6
  21. package/dist/bundle/{chunk-JZFIHVRB.js → chunk-ES4PWHBJ.js} +28 -28
  22. package/dist/bundle/{chunk-7X64JS6S.js → chunk-FIQOBLHS.js} +1 -1
  23. package/dist/bundle/{chunk-TI6VBZKJ.js → chunk-FUB3X25H.js} +4 -4
  24. package/dist/bundle/{chunk-VWXCEEUH.js → chunk-H4VFIH5W.js} +3 -3
  25. package/dist/bundle/{chunk-JKHI3PH7.js → chunk-J4C32YKH.js} +1 -1
  26. package/dist/bundle/{chunk-F6JTOQIK.js → chunk-J5MYH4L5.js} +12 -6
  27. package/dist/bundle/{chunk-QYWDC7NP.js → chunk-JFJTDL22.js} +47 -46
  28. package/dist/bundle/{chunk-UZDHK26H.js → chunk-JIQAFFPV.js} +2 -2
  29. package/dist/bundle/{chunk-BHKI5OCD.js → chunk-JKA2AICL.js} +2 -2
  30. package/dist/bundle/{dist-FMN7UZ7R.js → chunk-JKLQHPED.js} +16 -116
  31. package/dist/bundle/{chunk-J3QXTBD2.js → chunk-JLRMSNPX.js} +18 -18
  32. package/dist/bundle/{chunk-HORM6VRV.js → chunk-K5JUROGN.js} +1 -1
  33. package/dist/bundle/{chunk-SY3SP7EI.js → chunk-KUQYWIVR.js} +6 -6
  34. package/dist/bundle/{chunk-7QQ4EMYF.js → chunk-LWTG5UOF.js} +2 -2
  35. package/dist/bundle/{chunk-YSSMDVT3.js → chunk-M7V3GSJQ.js} +1 -1
  36. package/dist/bundle/chunk-MD2J3POF.js +52 -0
  37. package/dist/bundle/{chunk-SWRNMYDL.js → chunk-NCWO2FNC.js} +2 -2
  38. package/dist/bundle/{chunk-LKDK5YMI.js → chunk-NOU6MWEM.js} +2 -2
  39. package/dist/bundle/{chunk-LQ37ALDJ.js → chunk-NXJLC2WK.js} +8 -8
  40. package/dist/bundle/{chunk-ZAR67WKR.js → chunk-NZB4WGQS.js} +6 -6
  41. package/dist/bundle/{chunk-5RUTHKXZ.js → chunk-O555ZEQR.js} +4 -4
  42. package/dist/bundle/{chunk-MGBGE2Y4.js → chunk-O7VK7CJX.js} +2 -2
  43. package/dist/bundle/{chunk-WFBTPZK3.js → chunk-OHV5RDFE.js} +4 -4
  44. package/dist/bundle/{chunk-HJEMHZRU.js → chunk-P5B7IFOG.js} +2 -2
  45. package/dist/bundle/{chunk-VWHRIGYJ.js → chunk-PBYDT3CG.js} +13 -3
  46. package/dist/bundle/{chunk-7IYDIU4P.js → chunk-PHPC72DP.js} +7 -7
  47. package/dist/bundle/{chunk-ID24SLH3.js → chunk-PKU6V4EQ.js} +17 -17
  48. package/dist/bundle/{chunk-P7P5MNAU.js → chunk-QZBT6BOU.js} +1 -1
  49. package/dist/bundle/{chunk-NL5LNYGX.js → chunk-RAZOSYEO.js} +23 -23
  50. package/dist/bundle/{chunk-CCNHVZ3G.js → chunk-RDSAI6DC.js} +398 -293
  51. package/dist/bundle/{chunk-CSI73XJ5.js → chunk-SAZJDKEI.js} +8 -8
  52. package/dist/bundle/{chunk-QX7RCLRS.js → chunk-SQLCCKEL.js} +1 -1
  53. package/dist/bundle/{chunk-ORYYYM5Y.js → chunk-TKJDGAHT.js} +23 -23
  54. package/dist/bundle/{chunk-RLSGMMGC.js → chunk-TPNC5VCJ.js} +4 -4
  55. package/dist/bundle/{chunk-IIO6NXCA.js → chunk-UAXBLHZK.js} +2 -2
  56. package/dist/bundle/{chunk-2NZGUKYK.js → chunk-VEAP5RVI.js} +10 -8
  57. package/dist/bundle/{chunk-6BNMEOVS.js → chunk-VF24ZAPX.js} +4 -4
  58. package/dist/bundle/{chunk-FFKNUVVD.js → chunk-WCL3WBH5.js} +3 -3
  59. package/dist/bundle/{chunk-M4NTQ247.js → chunk-WGK4AIRL.js} +12 -12
  60. package/dist/bundle/{chunk-OM4ZBLT7.js → chunk-XERTHQ6D.js} +88 -34
  61. package/dist/bundle/{chunk-6BR6JMCR.js → chunk-XZGLY2LU.js} +14 -14
  62. package/dist/bundle/{chunk-2LP46EUH.js → chunk-Y7JKWQC2.js} +96 -94
  63. package/dist/bundle/{chunk-F7KAJNNK.js → chunk-YBJMBPL7.js} +6 -6
  64. package/dist/bundle/{chunk-YYTWV5GU.js → chunk-ZMMIIBTM.js} +73 -57
  65. package/dist/bundle/{chunk-EOEYP7CJ.js → chunk-ZPGLWMNH.js} +3 -3
  66. package/dist/bundle/{chunk-UJYCKCFR.js → chunk-ZRYFEEXZ.js} +3 -3
  67. package/dist/bundle/command-contract-NZF4B5OR.js +34 -0
  68. package/dist/bundle/{decode-ON4KBMEX.js → decode-HVXDCQ63.js} +5 -5
  69. package/dist/bundle/{dispatch-EUKKT3PD.js → dispatch-GDAH4JHS.js} +8 -8
  70. package/dist/bundle/dist-43DZXMBL.js +134 -0
  71. package/dist/bundle/{echarts-XPA226QR.js → echarts-LZ74IXHG.js} +2 -2
  72. package/dist/bundle/{embed-QERDAB73.js → embed-OQF5U2C6.js} +6 -6
  73. package/dist/bundle/{embedder-I76YT3E5.js → embedder-OCWQAWKO.js} +9 -9
  74. package/dist/bundle/{failure-OAIC5VAP.js → failure-6COJAO7T.js} +2 -2
  75. package/dist/bundle/{first-run-KZJFR55N.js → first-run-MTZPUPGA.js} +11 -11
  76. package/dist/bundle/first-screen-4PBS6QK5.js +32 -0
  77. package/dist/bundle/{instructions-NN3BCFIM.js → instructions-M6F4FP7U.js} +1 -1
  78. package/dist/bundle/mail.js +12 -11
  79. package/dist/bundle/{mcp-L7SRVDRN.js → mcp-GAPDLFWA.js} +2 -2
  80. package/dist/bundle/{node-2S75QJ6B.js → node-NYBBFHGN.js} +2 -2
  81. package/dist/bundle/{node-sqlite-RC7WM3EG.js → node-sqlite-CWCNWO75.js} +5 -5
  82. package/dist/bundle/{oauth-FUHLZCKV.js → oauth-DVX45EME.js} +7 -7
  83. package/dist/bundle/{open-JOKT7LKY.js → open-M7EQWWHL.js} +4 -4
  84. package/dist/bundle/{openai-U3IMQ6UI.js → openai-63KRU5H2.js} +14 -14
  85. package/dist/bundle/{process-LKODK722.js → process-DV5GQIGM.js} +1 -1
  86. package/dist/bundle/{program-RMLIQXCA.js → program-EPR3QCMX.js} +20570 -7622
  87. package/dist/bundle/{prompt-23VYMNNB.js → prompt-EPWPWTB3.js} +5 -5
  88. package/dist/bundle/{recognize-TXO3462R.js → recognize-R46KDXK4.js} +4 -4
  89. package/dist/bundle/{remote-5F4ZOASM.js → remote-RENCYB5X.js} +7 -7
  90. package/dist/bundle/{rerank-TXSDPEFE.js → rerank-VHPC5O73.js} +7 -7
  91. package/dist/bundle/{serve-TWYECYWM.js → serve-KCH3ORYO.js} +9 -9
  92. package/dist/bundle/server-FMCPE2ZK.js +63 -0
  93. package/dist/bundle/{server-3S3BKE6D.js → server-HZVXSK7B.js} +38 -38
  94. package/dist/bundle/{sqlite-runtime-BEOBGC6K.js → sqlite-runtime-XP7ZJCKJ.js} +5 -5
  95. package/dist/bundle/{state-ERWIUTQQ.js → state-GQ4MEQJ5.js} +6 -6
  96. package/dist/bundle/{store-2JO4JGQL.js → store-CQNLNINW.js} +13 -13
  97. package/dist/bundle/{store-4RY5UMOP.js → store-WT7YTR3Y.js} +15 -15
  98. package/dist/bundle/store-maintenance-command-YYR42IT4.js +52 -0
  99. package/dist/commands/attachments.d.ts +3 -0
  100. package/dist/commands/attachments.d.ts.map +1 -0
  101. package/dist/commands/attachments.js +97 -0
  102. package/dist/commands/attachments.js.map +1 -0
  103. package/dist/commands/context.d.ts.map +1 -1
  104. package/dist/commands/context.js +11 -1
  105. package/dist/commands/context.js.map +1 -1
  106. package/dist/commands/drafts-send.d.ts +7 -0
  107. package/dist/commands/drafts-send.d.ts.map +1 -0
  108. package/dist/commands/drafts-send.js +58 -0
  109. package/dist/commands/drafts-send.js.map +1 -0
  110. package/dist/commands/drafts.d.ts +3 -0
  111. package/dist/commands/drafts.d.ts.map +1 -0
  112. package/dist/commands/drafts.js +239 -0
  113. package/dist/commands/drafts.js.map +1 -0
  114. package/dist/commands/export.d.ts +3 -0
  115. package/dist/commands/export.d.ts.map +1 -0
  116. package/dist/commands/export.js +275 -0
  117. package/dist/commands/export.js.map +1 -0
  118. package/dist/commands/folders.d.ts.map +1 -1
  119. package/dist/commands/folders.js +120 -2
  120. package/dist/commands/folders.js.map +1 -1
  121. package/dist/commands/messages.d.ts +25 -0
  122. package/dist/commands/messages.d.ts.map +1 -0
  123. package/dist/commands/messages.js +502 -0
  124. package/dist/commands/messages.js.map +1 -0
  125. package/dist/commands/read.d.ts +4 -1
  126. package/dist/commands/read.d.ts.map +1 -1
  127. package/dist/commands/read.js +12 -2
  128. package/dist/commands/read.js.map +1 -1
  129. package/dist/commands/rules.d.ts +3 -0
  130. package/dist/commands/rules.d.ts.map +1 -0
  131. package/dist/commands/rules.js +292 -0
  132. package/dist/commands/rules.js.map +1 -0
  133. package/dist/commands/send.d.ts +39 -0
  134. package/dist/commands/send.d.ts.map +1 -0
  135. package/dist/commands/send.js +309 -0
  136. package/dist/commands/send.js.map +1 -0
  137. package/dist/commands/server-search.d.ts +8 -0
  138. package/dist/commands/server-search.d.ts.map +1 -0
  139. package/dist/commands/server-search.js +38 -0
  140. package/dist/commands/server-search.js.map +1 -0
  141. package/dist/commands/stats.d.ts +3 -0
  142. package/dist/commands/stats.d.ts.map +1 -0
  143. package/dist/commands/stats.js +90 -0
  144. package/dist/commands/stats.js.map +1 -0
  145. package/dist/commands/sync.d.ts +7 -0
  146. package/dist/commands/sync.d.ts.map +1 -1
  147. package/dist/commands/sync.js +22 -7
  148. package/dist/commands/sync.js.map +1 -1
  149. package/dist/commands/tags.d.ts +3 -0
  150. package/dist/commands/tags.d.ts.map +1 -0
  151. package/dist/commands/tags.js +144 -0
  152. package/dist/commands/tags.js.map +1 -0
  153. package/dist/config.d.ts +13 -0
  154. package/dist/config.d.ts.map +1 -1
  155. package/dist/config.js +47 -1
  156. package/dist/config.js.map +1 -1
  157. package/dist/export/format.d.ts +19 -0
  158. package/dist/export/format.d.ts.map +1 -0
  159. package/dist/export/format.js +40 -0
  160. package/dist/export/format.js.map +1 -0
  161. package/dist/export/journal.d.ts +32 -0
  162. package/dist/export/journal.d.ts.map +1 -0
  163. package/dist/export/journal.js +84 -0
  164. package/dist/export/journal.js.map +1 -0
  165. package/dist/export/write.d.ts +14 -0
  166. package/dist/export/write.d.ts.map +1 -0
  167. package/dist/export/write.js +42 -0
  168. package/dist/export/write.js.map +1 -0
  169. package/dist/identity.d.ts.map +1 -1
  170. package/dist/identity.js +3 -0
  171. package/dist/identity.js.map +1 -1
  172. package/dist/mail/backend.d.ts +81 -1
  173. package/dist/mail/backend.d.ts.map +1 -1
  174. package/dist/mail/changes.d.ts +91 -0
  175. package/dist/mail/changes.d.ts.map +1 -0
  176. package/dist/mail/changes.js +198 -0
  177. package/dist/mail/changes.js.map +1 -0
  178. package/dist/mail/cleanup.d.ts +41 -0
  179. package/dist/mail/cleanup.d.ts.map +1 -0
  180. package/dist/mail/cleanup.js +119 -0
  181. package/dist/mail/cleanup.js.map +1 -0
  182. package/dist/mail/compose.d.ts +73 -0
  183. package/dist/mail/compose.d.ts.map +1 -0
  184. package/dist/mail/compose.js +122 -0
  185. package/dist/mail/compose.js.map +1 -0
  186. package/dist/mail/doctor.d.ts +25 -0
  187. package/dist/mail/doctor.d.ts.map +1 -0
  188. package/dist/mail/doctor.js +39 -0
  189. package/dist/mail/doctor.js.map +1 -0
  190. package/dist/mail/drafts.d.ts +54 -0
  191. package/dist/mail/drafts.d.ts.map +1 -0
  192. package/dist/mail/drafts.js +104 -0
  193. package/dist/mail/drafts.js.map +1 -0
  194. package/dist/mail/imap/connection.d.ts +7 -0
  195. package/dist/mail/imap/connection.d.ts.map +1 -1
  196. package/dist/mail/imap/connection.js +24 -2
  197. package/dist/mail/imap/connection.js.map +1 -1
  198. package/dist/mail/imap/index.d.ts +1 -1
  199. package/dist/mail/imap/index.d.ts.map +1 -1
  200. package/dist/mail/imap/index.js +12 -2
  201. package/dist/mail/imap/index.js.map +1 -1
  202. package/dist/mail/imap/messages.d.ts +5 -6
  203. package/dist/mail/imap/messages.d.ts.map +1 -1
  204. package/dist/mail/imap/messages.js +14 -28
  205. package/dist/mail/imap/messages.js.map +1 -1
  206. package/dist/mail/imap/read.d.ts.map +1 -1
  207. package/dist/mail/imap/read.js +27 -13
  208. package/dist/mail/imap/read.js.map +1 -1
  209. package/dist/mail/imap/search.d.ts +14 -0
  210. package/dist/mail/imap/search.d.ts.map +1 -0
  211. package/dist/mail/imap/search.js +49 -0
  212. package/dist/mail/imap/search.js.map +1 -0
  213. package/dist/mail/imap/write.d.ts +5 -0
  214. package/dist/mail/imap/write.d.ts.map +1 -0
  215. package/dist/mail/imap/write.js +93 -0
  216. package/dist/mail/imap/write.js.map +1 -0
  217. package/dist/mail/organise.d.ts +116 -0
  218. package/dist/mail/organise.d.ts.map +1 -0
  219. package/dist/mail/organise.js +531 -0
  220. package/dist/mail/organise.js.map +1 -0
  221. package/dist/mail/rethread.d.ts +1 -2
  222. package/dist/mail/rethread.d.ts.map +1 -1
  223. package/dist/mail/rethread.js +8 -3
  224. package/dist/mail/rethread.js.map +1 -1
  225. package/dist/mail/rules/apply.d.ts +40 -0
  226. package/dist/mail/rules/apply.d.ts.map +1 -0
  227. package/dist/mail/rules/apply.js +114 -0
  228. package/dist/mail/rules/apply.js.map +1 -0
  229. package/dist/mail/rules/file.d.ts +9 -0
  230. package/dist/mail/rules/file.d.ts.map +1 -0
  231. package/dist/mail/rules/file.js +51 -0
  232. package/dist/mail/rules/file.js.map +1 -0
  233. package/dist/mail/rules/filters.d.ts +11 -0
  234. package/dist/mail/rules/filters.d.ts.map +1 -0
  235. package/dist/mail/rules/filters.js +150 -0
  236. package/dist/mail/rules/filters.js.map +1 -0
  237. package/dist/mail/rules/folders.d.ts +11 -0
  238. package/dist/mail/rules/folders.d.ts.map +1 -0
  239. package/dist/mail/rules/folders.js +17 -0
  240. package/dist/mail/rules/folders.js.map +1 -0
  241. package/dist/mail/rules/query.d.ts +15 -0
  242. package/dist/mail/rules/query.d.ts.map +1 -0
  243. package/dist/mail/rules/query.js +103 -0
  244. package/dist/mail/rules/query.js.map +1 -0
  245. package/dist/mail/rules/store.d.ts +9 -0
  246. package/dist/mail/rules/store.d.ts.map +1 -0
  247. package/dist/mail/rules/store.js +17 -0
  248. package/dist/mail/rules/store.js.map +1 -0
  249. package/dist/mail/save.d.ts +12 -0
  250. package/dist/mail/save.d.ts.map +1 -0
  251. package/dist/mail/save.js +71 -0
  252. package/dist/mail/save.js.map +1 -0
  253. package/dist/mail/send.d.ts +67 -0
  254. package/dist/mail/send.d.ts.map +1 -0
  255. package/dist/mail/send.js +172 -0
  256. package/dist/mail/send.js.map +1 -0
  257. package/dist/mail/smtp.d.ts +4 -0
  258. package/dist/mail/smtp.d.ts.map +1 -0
  259. package/dist/mail/smtp.js +97 -0
  260. package/dist/mail/smtp.js.map +1 -0
  261. package/dist/program.d.ts.map +1 -1
  262. package/dist/program.js +28 -6
  263. package/dist/program.js.map +1 -1
  264. package/dist/providers.d.ts +71 -6
  265. package/dist/providers.d.ts.map +1 -1
  266. package/dist/providers.js +38 -9
  267. package/dist/providers.js.map +1 -1
  268. package/dist/reasons.d.ts +9 -0
  269. package/dist/reasons.d.ts.map +1 -0
  270. package/dist/reasons.js +21 -0
  271. package/dist/reasons.js.map +1 -0
  272. package/dist/version.d.ts +1 -1
  273. package/dist/version.js +1 -1
  274. package/package.json +8 -5
  275. package/skills/mail-cli/SKILL.md +30 -3
  276. package/dist/bundle/chunk-XJ5TBPCK.js +0 -27
  277. package/dist/bundle/command-contract-L65UZ7AF.js +0 -34
  278. package/dist/bundle/first-screen-EORANEAK.js +0 -32
  279. package/dist/bundle/server-2GEAXKX2.js +0 -63
  280. package/dist/bundle/store-maintenance-command-T7D4OTN7.js +0 -52
  281. /package/dist/bundle/{chunk-NPGVOZVK.js → chunk-WJWLHLQ7.js} +0 -0
@@ -0,0 +1,309 @@
1
+ import { CliError } from "@wirecat/cli-base";
2
+ import { annotate } from "@wirecat/cli-base/commands";
3
+ import { answerEntity, baseContext, bufferedInput, environmentOf, itemOf, outputFor, ownerOnlyOption, REMOTE_WRITE, renderAnswer, } from "@wirecat/cli-core/cli";
4
+ import { levelFor, newOperationId, readUpload } from "@wirecat/cli-core/sends";
5
+ import { Command } from "commander";
6
+ import * as v from "valibot";
7
+ import { configuration, SEND_OTHERS_KEY } from "../config.js";
8
+ import { IDENTITY } from "../identity.js";
9
+ import { forgotAttachment, forwardSubject, messageIdFor, originalOf, peopleOf, quoted, referencesOf, replyCopies, replyPeople, replySubject, } from "../mail/compose.js";
10
+ import { everyone, fetchOriginal, othersOf, sendOut } from "../mail/send.js";
11
+ import { DEFAULT_SYNC, providerFor } from "../providers.js";
12
+ import { collect, contextOf } from "./context.js";
13
+ import { organising } from "./messages.js";
14
+ import { foldersFor } from "./sync.js";
15
+ const OPERATION_ID = /^-?[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
16
+ export const mailSend = v.looseObject({
17
+ sent: v.boolean(),
18
+ already_sent: v.optional(v.boolean()),
19
+ operation_id: v.string(),
20
+ message_id: v.string(),
21
+ from: v.string(),
22
+ to: v.array(v.string()),
23
+ cc: v.array(v.string()),
24
+ bcc: v.array(v.string()),
25
+ subject: v.string(),
26
+ attachments: v.array(v.strictObject({ name: v.string(), bytes: v.number() })),
27
+ text_chars: v.number(),
28
+ accepted: v.optional(v.number()),
29
+ rejected: v.optional(v.number()),
30
+ sent_copy: v.optional(v.nullable(v.string())),
31
+ stored: v.optional(v.boolean()),
32
+ marked_original: v.optional(v.nullable(v.boolean())),
33
+ hint: v.optional(v.string()),
34
+ });
35
+ export const operationIdOf = (given) => {
36
+ if (given === undefined)
37
+ return newOperationId();
38
+ if (!OPERATION_ID.test(given))
39
+ throw new CliError("validation_error", "--operation-id is the operation_id an outcome_unknown answer named", {
40
+ param: "operation-id",
41
+ });
42
+ return given;
43
+ };
44
+ /** The owner's own addresses: the profile's address and a login that is an address too. */
45
+ export const ownerOf = (opened, command) => {
46
+ const { mailbox } = contextOf(command).settings;
47
+ return new Set([mailbox.address, mailbox.login]
48
+ .filter((one) => typeof one === "string" && one.includes("@"))
49
+ .map((one) => one.toLowerCase())
50
+ .concat(opened.mailbox.key.account));
51
+ };
52
+ const sendingOf = (opened, command) => {
53
+ const { settings } = contextOf(command);
54
+ const address = opened.mailbox.key.account;
55
+ const provider = providerFor(address, settings.mailbox.host);
56
+ return {
57
+ mailbox: opened.mailbox,
58
+ backend: opened.backend,
59
+ guard: opened.guard,
60
+ profile: opened.profile,
61
+ env: opened.env,
62
+ owner: ownerOf(opened, command),
63
+ savesSent: provider?.smtp.savesSent === true,
64
+ syncFolders: async () => {
65
+ const defaults = provider?.sync ?? DEFAULT_SYNC;
66
+ const folders = await foldersFor(undefined, settings.mailbox.folders, defaults, () => opened.mailbox.folders());
67
+ return { folders, mode: defaults.mode ?? "imap" };
68
+ },
69
+ warn: (message) => outputFor(command).renderer.warn(message),
70
+ agentWithoutOthers: environmentOf(command).agent !== undefined && !othersSetInConfig(command),
71
+ };
72
+ };
73
+ /** Only the config file opens mail to others for an agent: an `mcp serve --permission` level arrives as a flag. */
74
+ const othersSetInConfig = (command) => {
75
+ const { settings } = baseContext(command, configuration.resolveSettings);
76
+ const { key } = levelFor(settings.permissions, SEND_OTHERS_KEY, configuration.permissions?.defaults ?? {});
77
+ const from = key ? settings.permissionSources[key] : undefined;
78
+ return key !== undefined && key !== null && key.startsWith(SEND_OTHERS_KEY) && from !== undefined && from !== "flag";
79
+ };
80
+ export const filesOf = async (command, paths, anyFile) => {
81
+ const { env } = contextOf(command);
82
+ const files = [];
83
+ for (const path of paths) {
84
+ const upload = await readUpload("file", path, { app: IDENTITY, env, anyFile });
85
+ if (upload.source.kind !== "file")
86
+ continue;
87
+ files.push({ name: upload.name, path: upload.source.path, bytes: upload.source.size });
88
+ }
89
+ return files;
90
+ };
91
+ const shownPerson = ({ address, name }) => (name ? `${name} <${address}>` : address);
92
+ const summaryOf = (draft) => ({
93
+ from: shownPerson(draft.from),
94
+ to: draft.to.map(shownPerson),
95
+ cc: draft.cc.map(shownPerson),
96
+ bcc: draft.bcc.map(shownPerson),
97
+ subject: draft.subject,
98
+ attachments: [
99
+ ...draft.files.map(({ name, bytes }) => ({ name, bytes })),
100
+ ...(draft.message ? [{ name: draft.message.name, bytes: draft.message.raw.byteLength }] : []),
101
+ ],
102
+ text_chars: draft.text.length,
103
+ });
104
+ /** What the y/N question shows: everything that leaves, and the start of the text, so a yes is a yes to this mail. */
105
+ const summaryText = (draft) => {
106
+ const summary = summaryOf(draft);
107
+ const lines = draft.text.split("\n").slice(0, 6);
108
+ return [
109
+ "About to send:",
110
+ ` From: ${summary.from}`,
111
+ ` To: ${summary.to.join(", ") || "-"}`,
112
+ ...(summary.cc.length ? [` Cc: ${summary.cc.join(", ")}`] : []),
113
+ ...(summary.bcc.length ? [` Bcc: ${summary.bcc.join(", ")}`] : []),
114
+ ` Subject: ${summary.subject}`,
115
+ ...summary.attachments.map(({ name, bytes }) => ` Attach: ${name} (${bytes} bytes)`),
116
+ " ----",
117
+ ...lines.map((line) => ` ${line}`),
118
+ ...(draft.text.split("\n").length > lines.length ? [" …"] : []),
119
+ "",
120
+ ].join("\n");
121
+ };
122
+ /** The summary before the terminal's question, only when there is one; an agent's or a `--yes` run asks nothing. */
123
+ const showBeforeAsking = (command, draft, key, owner) => {
124
+ const given = command.optsWithGlobals();
125
+ if (environmentOf(command).agent || given.yes || given.json || given.jsonl)
126
+ return;
127
+ const settings = configuration.resolveSettings(command.optsWithGlobals(), { env: contextOf(command).env });
128
+ const defaults = configuration.permissions?.defaults ?? {};
129
+ const asks = [key, ...(othersOf(draft, owner).length ? [SEND_OTHERS_KEY] : [])].some((one) => levelFor(settings.permissions, one, defaults).level === "ask");
130
+ if (asks)
131
+ outputFor(command).streams.diagnostic(summaryText(draft));
132
+ };
133
+ const answer = (command, draft, outcome) => renderAnswer(command, outputFor(command), itemOf({ ...outcome, message_id: draft.messageId, ...summaryOf(draft) }), () => outcome.sent
134
+ ? `sent to ${everyone(draft).length} ${everyone(draft).length === 1 ? "recipient" : "recipients"}: ${draft.subject}\n`
135
+ : `${String(outcome.hint ?? "not sent")}\n`);
136
+ /** Checks, previews or sends, and answers; the outcome of a send that left, for what the caller does after. */
137
+ export const go = async (command, opened, outgoing, dryRun) => {
138
+ const { draft } = outgoing;
139
+ if (everyone(draft).length === 0)
140
+ throw new CliError("validation_error", "the message has nobody to go to; give --to", { param: "to" });
141
+ if (forgotAttachment(draft.text, draft.files.length > 0 || draft.message !== undefined))
142
+ outputFor(command).renderer.warn("the text speaks of an attachment, and nothing is attached (--file)");
143
+ if (dryRun) {
144
+ answer(command, draft, {
145
+ sent: false,
146
+ operation_id: outgoing.operationId,
147
+ hint: "a preview: nothing was sent; the same command without --dry-run sends it",
148
+ });
149
+ return undefined;
150
+ }
151
+ const sending = sendingOf(opened, command);
152
+ showBeforeAsking(command, draft, outgoing.key, sending.owner);
153
+ const sent = await sendOut(sending, outgoing);
154
+ answer(command, draft, {
155
+ sent: !sent.alreadySent,
156
+ already_sent: sent.alreadySent,
157
+ operation_id: sent.operationId,
158
+ accepted: sent.accepted,
159
+ rejected: sent.rejected,
160
+ sent_copy: sent.sentCopy,
161
+ stored: sent.stored,
162
+ marked_original: sent.markedOriginal,
163
+ ...(sent.alreadySent
164
+ ? { hint: "Sent already holds this message: it went the first time, and nothing was sent again" }
165
+ : {}),
166
+ });
167
+ return sent;
168
+ };
169
+ const sendAction = async function (text, flags) {
170
+ if (flags.replyAll && flags.replyTo === undefined)
171
+ throw new CliError("validation_error", "--reply-all answers the message --reply-to names", { param: "reply-all" });
172
+ if (flags.replyTo === undefined && flags.subject === undefined)
173
+ throw new CliError("validation_error", "a new message needs --subject", { param: "subject" });
174
+ const operationId = operationIdOf(flags.operationId);
175
+ const body = text ?? (await readText(this));
176
+ if (!body.trim() && !flags.file?.length)
177
+ throw new CliError("validation_error", "the message has no text: give it, or pipe it on stdin", { param: "text" });
178
+ const files = await filesOf(this, flags.file ?? [], flags.allowAnyFile === true);
179
+ await organising(this, async (opened) => {
180
+ const from = { address: opened.mailbox.key.account };
181
+ const owner = ownerOf(opened, this);
182
+ const given = {
183
+ to: peopleOf(flags.to ?? [], "--to"),
184
+ cc: peopleOf(flags.cc ?? [], "--cc"),
185
+ bcc: peopleOf(flags.bcc ?? [], "--bcc"),
186
+ };
187
+ let draft;
188
+ let original;
189
+ if (flags.replyTo !== undefined) {
190
+ const fetched = await fetchOriginal(opened.mailbox, opened.backend, flags.replyTo, opened.profile);
191
+ const parent = await originalOf(fetched.raw);
192
+ const to = given.to.length ? given.to : replyPeople(parent, owner, false);
193
+ draft = {
194
+ from,
195
+ to,
196
+ cc: [...(flags.replyAll ? replyCopies(parent, owner, to) : []), ...given.cc],
197
+ bcc: given.bcc,
198
+ subject: flags.subject ?? replySubject(parent.subject),
199
+ text: quoted(body, parent),
200
+ messageId: messageIdFor(operationId, from.address),
201
+ date: new Date(),
202
+ ...(parent.messageId ? { inReplyTo: parent.messageId } : {}),
203
+ references: referencesOf(parent),
204
+ files,
205
+ };
206
+ original = { folder: fetched.folder, validity: fetched.validity, uid: fetched.uid, flag: "\\Answered" };
207
+ }
208
+ else {
209
+ draft = {
210
+ from,
211
+ ...given,
212
+ subject: flags.subject ?? "",
213
+ text: body,
214
+ messageId: messageIdFor(operationId, from.address),
215
+ date: new Date(),
216
+ files,
217
+ };
218
+ }
219
+ await go(this, opened, {
220
+ draft,
221
+ kind: "message",
222
+ key: "messages.send",
223
+ operationId,
224
+ retry: flags.operationId !== undefined,
225
+ ...(original ? { original } : {}),
226
+ }, flags.dryRun === true);
227
+ });
228
+ };
229
+ const readText = async (command) => {
230
+ const input = environmentOf(command).stdin ?? process.stdin;
231
+ if (input.isTTY)
232
+ return "";
233
+ return (await bufferedInput(input)).toString("utf8");
234
+ };
235
+ const recipients = (command) => command
236
+ .option("--to <address>", "who it goes to: an address, or several split by commas; repeat it for more (a reply: instead of its sender)", collect)
237
+ .option("--cc <address>", "a copy to this address; repeat it for more", collect)
238
+ .option("--bcc <address>", "a hidden copy to this address; repeat it for more", collect);
239
+ const sending = (command) => command
240
+ .option("--file <file>", "attach this file, as named, never a pattern; repeat it for more", collect)
241
+ .addOption(ownerOnlyOption("--allow-any-file", "attach a file even from credential folders or this CLI's own folders"))
242
+ .option("--operation-id <id>", "repeat a send whose outcome was unknown; Sent is checked first, so it goes once")
243
+ .option("--yes", "answer the question before sending to anyone but you")
244
+ .option("--dry-run", "build the message and show what would go; send nothing");
245
+ export const sendCommand = () => answerEntity(sending(recipients(annotate(new Command("send"), {
246
+ effects: REMOTE_WRITE,
247
+ examples: [
248
+ `${IDENTITY.command} ya messages send --to ann@example.com --subject "Lunch" "See you at noon."`,
249
+ `${IDENTITY.command} ya messages send --reply-to 'msg:email/me%40example.com/thread-1/1001' "Thanks, done."`,
250
+ `${IDENTITY.command} ya messages send --to ann@example.com --subject Report --file ./report.pdf "The report."`,
251
+ ],
252
+ }))), "mail_send", mailSend)
253
+ .summary("send an email, or reply to one, over SMTP")
254
+ .description("send an email from this profile's address over its SMTP server, with the same app password; without [text] " +
255
+ "the text is read from stdin. Mail to anyone but you asks first (permissions.messages.send.others). " +
256
+ "Sent gets a copy where the provider does not file one itself")
257
+ .argument("[text]", "the text of the message; read from stdin when left out")
258
+ .option("--subject <text>", "the subject; a reply takes the original's with Re:")
259
+ .option("--reply-to <message>", "answer this msg:email/… reference: In-Reply-To, References, Re: and the quote")
260
+ .option("--reply-all", "with --reply-to, also to everyone the original went to, except you")
261
+ .action(sendAction);
262
+ const forwardAction = async function (reference, text, flags) {
263
+ const files = await filesOf(this, flags.file ?? [], flags.allowAnyFile === true);
264
+ await organising(this, async (opened) => {
265
+ const operationId = operationIdOf(flags.operationId);
266
+ const fetched = await fetchOriginal(opened.mailbox, opened.backend, reference, opened.profile);
267
+ const parent = await originalOf(fetched.raw);
268
+ const from = { address: opened.mailbox.key.account };
269
+ const subject = flags.subject ?? forwardSubject(parent.subject);
270
+ const draft = {
271
+ from,
272
+ to: peopleOf(flags.to ?? [], "--to"),
273
+ cc: peopleOf(flags.cc ?? [], "--cc"),
274
+ bcc: peopleOf(flags.bcc ?? [], "--bcc"),
275
+ subject,
276
+ text: text ?? "",
277
+ messageId: messageIdFor(operationId, from.address),
278
+ date: new Date(),
279
+ files,
280
+ message: {
281
+ name: `${(parent.subject || "message").replace(/[\\/:*?"<>|\0]/g, "_").slice(0, 80)}.eml`,
282
+ raw: fetched.raw,
283
+ },
284
+ };
285
+ await go(this, opened, {
286
+ draft,
287
+ kind: "forward",
288
+ key: "messages.forward",
289
+ operationId,
290
+ retry: flags.operationId !== undefined,
291
+ original: { folder: fetched.folder, validity: fetched.validity, uid: fetched.uid, flag: "$Forwarded" },
292
+ }, flags.dryRun === true);
293
+ });
294
+ };
295
+ export const forwardCommand = () => answerEntity(sending(recipients(annotate(new Command("forward"), {
296
+ effects: REMOTE_WRITE,
297
+ examples: [
298
+ `${IDENTITY.command} ya messages forward 'msg:email/me%40example.com/thread-1/1001' --to bob@example.com`,
299
+ `${IDENTITY.command} ya messages forward 'msg:email/me%40example.com/thread-1/1001' --to bob@example.com "FYI"`,
300
+ ],
301
+ }))), "mail_send", mailSend)
302
+ .summary("forward an email, attached whole, over SMTP")
303
+ .description("forward a stored email to other people: the original goes as an attached message with its own attachments, " +
304
+ "Fwd: before its subject. Mail to anyone but you asks first (permissions.messages.send.others)")
305
+ .argument("<message>", "the msg:email/… reference search messages shows")
306
+ .argument("[text]", "a few words above the forwarded message")
307
+ .option("--subject <text>", "the subject instead of the original's with Fwd:")
308
+ .action(forwardAction);
309
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { MailServerAccess } from "@wirecat/cli-core/mail";
2
+ import type { Command } from "commander";
3
+ /**
4
+ * What `search messages --backend` may do with this profile's mailbox: the provider registry picks Gmail's X-GM-RAW
5
+ * or plain UID SEARCH and the folders, unless the profile names its own.
6
+ */
7
+ export declare const serverAccess: (command: Command) => MailServerAccess;
8
+ //# sourceMappingURL=server-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-search.d.ts","sourceRoot":"","sources":["../../src/commands/server-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC;;;GAGG;AACH,eAAO,MAAM,YAAY,YAAa,OAAO,KAAG,gBA4B/C,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { DEFAULT_SEARCH, providerFor } from "../providers.js";
2
+ import { contextOf, openMail } from "./context.js";
3
+ import { foldersFor } from "./sync.js";
4
+ /**
5
+ * What `search messages --backend` may do with this profile's mailbox: the provider registry picks Gmail's X-GM-RAW
6
+ * or plain UID SEARCH and the folders, unless the profile names its own.
7
+ */
8
+ export const serverAccess = (command) => {
9
+ const context = contextOf(command);
10
+ const { settings } = context;
11
+ return {
12
+ offline: context.flags.offline === true,
13
+ permissions: settings.permissions,
14
+ readOnly: settings.readOnlyLock !== undefined,
15
+ open: async () => {
16
+ const { backend } = await openMail(context);
17
+ const { address, host, folders: configured } = settings.mailbox;
18
+ const search = providerFor(address ?? "", host)?.search ?? DEFAULT_SEARCH;
19
+ const serverQuery = backend.serverQuery;
20
+ try {
21
+ const folders = await foldersFor(undefined, configured, search, () => backend.folderList());
22
+ return {
23
+ source: {
24
+ ...backend,
25
+ ...(serverQuery ? { query: (criteria, folder) => serverQuery(criteria, folder, search.syntax) } : {}),
26
+ },
27
+ folders,
28
+ close: backend.close,
29
+ };
30
+ }
31
+ catch (error) {
32
+ await backend.close();
33
+ throw error;
34
+ }
35
+ },
36
+ };
37
+ };
38
+ //# sourceMappingURL=server-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-search.js","sourceRoot":"","sources":["../../src/commands/server-search.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAgB,EAAoB,EAAE;IACjE,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAClC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAA;IAC5B,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI;QACvC,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,QAAQ,EAAE,QAAQ,CAAC,YAAY,KAAK,SAAS;QAC7C,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC3C,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAA;YAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,IAAI,cAAc,CAAA;YACzE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;YACvC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;gBAC3F,OAAO;oBACL,MAAM,EAAE;wBACN,GAAG,OAAO;wBACV,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACtG;oBACD,OAAO;oBACP,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB,CAAA;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;gBACrB,MAAM,KAAK,CAAA;YACb,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const statsCommand: () => Command;
3
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/commands/stats.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;AAkG3C,eAAO,MAAM,YAAY,QAAO,OAM3B,CAAA"}
@@ -0,0 +1,90 @@
1
+ import { CliError } from "@wirecat/cli-base";
2
+ import { annotate } from "@wirecat/cli-base/commands";
3
+ import { answerEntity, baseContext, LOCAL_READ, listOf, outputFor, renderAnswer } from "@wirecat/cli-core/cli";
4
+ import { Command, Option } from "commander";
5
+ import * as v from "valibot";
6
+ import { configuration } from "../config.js";
7
+ import { IDENTITY } from "../identity.js";
8
+ import { openMailStore } from "../store.js";
9
+ import { contextOf } from "./context.js";
10
+ import { wholeNumberFor } from "./sync.js";
11
+ const GROUPS = ["sender", "list", "domain"];
12
+ const mailGroup = v.strictObject({
13
+ group: v.string(),
14
+ emails: v.number(),
15
+ unread: v.number(),
16
+ bytes: v.number(),
17
+ last_email_at: v.nullable(v.string()),
18
+ untrusted: v.array(v.string()),
19
+ });
20
+ const keyOf = (by, fact) => {
21
+ if (by === "list")
22
+ return fact.listId;
23
+ if (by === "sender")
24
+ return fact.fromAddress?.toLowerCase() ?? null;
25
+ return fact.fromAddress?.split("@").at(-1)?.toLowerCase() ?? null;
26
+ };
27
+ const topLeaf = () => answerEntity(annotate(new Command("top"), {
28
+ effects: LOCAL_READ,
29
+ partial: true,
30
+ examples: [
31
+ `${IDENTITY.command} ya stats messages top`,
32
+ `${IDENTITY.command} ya stats messages top --by list --limit 10`,
33
+ ],
34
+ }), "mail_group", mailGroup)
35
+ .summary("senders, lists or domains with the most stored mail")
36
+ .description("group this profile's stored mail by sender, mailing list (List-Id) or sender domain, the biggest group first; " +
37
+ "unread and size help decide what to unsubscribe from or clean up")
38
+ .addOption(new Option("--by <group>", "what to group by").choices([...GROUPS]).default("sender"))
39
+ .option("--limit <n>", "how many groups, at most 200", wholeNumberFor("limit"), 20)
40
+ .action(async function (args) {
41
+ const context = contextOf(this);
42
+ const address = context.settings.mailbox.address;
43
+ if (!address)
44
+ throw new CliError("configuration_error", `profile ${context.profile} has no address`);
45
+ const limit = Math.min(args.limit, 200);
46
+ const groups = await baseContext(this, configuration.resolveSettings).run(async () => {
47
+ const store = await openMailStore(context.env);
48
+ context.environment.trackCloseable?.(store);
49
+ try {
50
+ const stored = await store.accounts
51
+ .storedAccount({ provider: "email", account: address.toLowerCase() })
52
+ .catch(() => null);
53
+ if (stored === null)
54
+ throw new CliError("not_found", `no mail is stored yet; run \`${IDENTITY.command} ${context.profile} sync\` first`);
55
+ const totals = new Map();
56
+ for (const fact of await store.mail.emailFacts({ accountId: stored.id })) {
57
+ const key = keyOf(args.by, fact);
58
+ if (!key)
59
+ continue;
60
+ const total = totals.get(key) ?? { emails: 0, unread: 0, bytes: 0, last: 0 };
61
+ total.emails++;
62
+ if (!fact.read)
63
+ total.unread++;
64
+ total.bytes += fact.size ?? 0;
65
+ total.last = Math.max(total.last, fact.receivedAt ?? 0);
66
+ totals.set(key, total);
67
+ }
68
+ return [...totals.entries()].sort(([, a], [, b]) => b.emails - a.emails || b.bytes - a.bytes);
69
+ }
70
+ finally {
71
+ await store.close();
72
+ }
73
+ });
74
+ const items = groups.slice(0, limit).map(([group, total]) => ({
75
+ group,
76
+ emails: total.emails,
77
+ unread: total.unread,
78
+ bytes: total.bytes,
79
+ last_email_at: total.last ? new Date(total.last).toISOString() : null,
80
+ untrusted: ["group"],
81
+ }));
82
+ renderAnswer(this, outputFor(this), listOf("stats messages top", { items, limit, has_more: groups.length > limit }), () => items
83
+ .map((one) => `${String(one.emails).padStart(6)} ${String(one.unread).padStart(6)} unread ${one.group}\n`)
84
+ .join(""));
85
+ });
86
+ export const statsCommand = () => new Command("stats")
87
+ .summary("statistics about stored mail")
88
+ .description("counts over the mail sync stored")
89
+ .addCommand(new Command("messages").summary("stored emails").description("counts of stored emails").addCommand(topLeaf()));
90
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/commands/stats.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,10 @@
1
1
  import { Command } from "commander";
2
+ import { type SyncFolders } from "../providers.js";
3
+ export declare const wholeNumberFor: (flag: string) => (value: string) => number;
4
+ /** The provider's folders by role (INBOX and Sent, All Mail on Gmail), unless the profile or `--folder` names some. */
5
+ export declare const foldersFor: (explicit: string[] | undefined, configured: string[] | undefined, defaults: Pick<SyncFolders, "roles" | "otherwise">, list: () => Promise<{
6
+ path: string;
7
+ role: string | null;
8
+ }[]>) => Promise<string[]>;
2
9
  export declare const syncCommand: () => Command;
3
10
  //# sourceMappingURL=sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkGnC,eAAO,MAAM,WAAW,QAAO,OA0JzB,CAAA"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAgD7E,eAAO,MAAM,cAAc,SAClB,MAAM,aACL,MAAM,KAAG,MAMhB,CAAA;AAEH,uHAAuH;AACvH,eAAO,MAAM,UAAU,aACX,MAAM,EAAE,GAAG,SAAS,cAClB,MAAM,EAAE,GAAG,SAAS,YACtB,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,WAAW,CAAC,QAC5C,MAAM,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,CAAC,KAC3D,OAAO,CAAC,MAAM,EAAE,CAMlB,CAAA;AA2BD,eAAO,MAAM,WAAW,QAAO,OAuKzB,CAAA"}
@@ -2,7 +2,7 @@ import { CliError } from "@wirecat/cli-base";
2
2
  import { annotate } from "@wirecat/cli-base/commands";
3
3
  import { timezoneOf, zonedMoment } from "@wirecat/cli-base/query";
4
4
  import { answerEntity, baseContext, environmentOf, FETCH, itemOf, outputFor, renderAnswer, runBudgetOf, } from "@wirecat/cli-core/cli";
5
- import { storedMailRules, syncMail } from "@wirecat/cli-core/mail";
5
+ import { storedMailRuleSet, syncMail } from "@wirecat/cli-core/mail";
6
6
  import { Command } from "commander";
7
7
  import * as v from "valibot";
8
8
  import { configuration } from "../config.js";
@@ -46,7 +46,7 @@ const issuesOf = (report) => [
46
46
  ? [{ code: BUDGET_CODES[report.stopped], reason: `budget.${report.stopped}`, source: "sync" }]
47
47
  : []),
48
48
  ];
49
- const wholeNumberFor = (flag) => (value) => {
49
+ export const wholeNumberFor = (flag) => (value) => {
50
50
  if (!/^\d+$/.test(value.trim()) || Number(value) < 1)
51
51
  throw new CliError("validation_error", `--${flag} takes a whole number from 1 upwards, not "${value}"`, {
52
52
  param: flag,
@@ -54,7 +54,7 @@ const wholeNumberFor = (flag) => (value) => {
54
54
  return Number(value);
55
55
  };
56
56
  /** The provider's folders by role (INBOX and Sent, All Mail on Gmail), unless the profile or `--folder` names some. */
57
- const foldersFor = async (explicit, configured, defaults, list) => {
57
+ export const foldersFor = async (explicit, configured, defaults, list) => {
58
58
  if (explicit?.length)
59
59
  return explicit;
60
60
  if (configured?.length)
@@ -80,6 +80,10 @@ const mailSync = v.strictObject({
80
80
  /** With --rescan: stored emails moved to the thread their References name. */
81
81
  rethreaded: v.optional(v.number()),
82
82
  unreadable: v.number(),
83
+ /** Stored rules this build cannot read, left out of the run; a newer mail or memo may read them and decide otherwise. */
84
+ rules_unread: v.optional(v.number()),
85
+ /** What it does not know of them, such as `condition label`. */
86
+ rules_unread_why: v.optional(v.array(v.string())),
83
87
  deletions_skipped: v.optional(v.string()),
84
88
  hint: v.optional(v.string()),
85
89
  });
@@ -113,7 +117,7 @@ export const syncCommand = () => answerEntity(annotate(new Command("sync"), {
113
117
  // A retry is a request of the budget; openMail keeps it from ending after the deadline.
114
118
  const { backend } = await openMail(context, { canRetry: () => budget.take() === null });
115
119
  try {
116
- const { report, rethreaded } = await baseContext(this, configuration.resolveSettings).run(async () => {
120
+ const { report, rethreaded, unreadable } = await baseContext(this, configuration.resolveSettings).run(async () => {
117
121
  const { mailbox } = context.settings;
118
122
  const defaults = providerFor(address, mailbox.host)?.sync ?? DEFAULT_SYNC;
119
123
  const folders = await foldersFor(args.folder, mailbox.folders, defaults, () => backend.folderList());
@@ -121,7 +125,7 @@ export const syncCommand = () => answerEntity(annotate(new Command("sync"), {
121
125
  environmentOf(this).trackCloseable?.(store);
122
126
  try {
123
127
  // The stored rules, as memo passes them: the saved position holds their fingerprint, so both must agree.
124
- const rules = await storedMailRules(store, { address });
128
+ const { rules, unreadable } = await storedMailRuleSet(store, { address });
125
129
  const report = await syncMail(backend, store, {
126
130
  account: { address, mode: defaults.mode ?? "imap", folders, rules },
127
131
  since,
@@ -134,13 +138,18 @@ export const syncCommand = () => answerEntity(annotate(new Command("sync"), {
134
138
  const rethreaded = args.rescan && !report.stopped
135
139
  ? await rethreadStored(backend, store, key, folders, since, () => budget.take() === null)
136
140
  : undefined;
137
- return { report, rethreaded };
141
+ return { report, rethreaded, unreadable };
138
142
  }
139
143
  finally {
140
144
  await store.close();
141
145
  }
142
146
  });
143
- const issues = issuesOf(report);
147
+ const issues = [
148
+ ...issuesOf(report),
149
+ ...(unreadable.length
150
+ ? [{ code: "configuration_error", reason: "mail.rules-unreadable", source: "rules" }]
151
+ : []),
152
+ ];
144
153
  // cli-core reports a run its `max` cut short as incomplete with what it left, but with no reason.
145
154
  const limited = args.limit !== undefined && !report.complete && !report.stopped && report.saved >= args.limit;
146
155
  const stopped = report.stopped ?? (limited ? "limit" : undefined);
@@ -194,6 +203,12 @@ export const syncCommand = () => answerEntity(annotate(new Command("sync"), {
194
203
  remaining: report.remaining ?? 0,
195
204
  ...(rethreaded ? { rethreaded: rethreaded.moved } : {}),
196
205
  unreadable: report.unreadable?.length ?? 0,
206
+ ...(unreadable.length
207
+ ? {
208
+ rules_unread: unreadable.length,
209
+ rules_unread_why: [...new Set(unreadable.map(({ why }) => why))],
210
+ }
211
+ : {}),
197
212
  ...(report.deletionsSkipped ? { deletions_skipped: report.deletionsSkipped } : {}),
198
213
  ...(hint ? { hint } : {}),
199
214
  }, {