@rubytech/create-realagent-code 0.1.572 → 0.1.574

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 (373) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/config/brand.json +2 -1
  3. package/payload/platform/lib/admins-write/__tests__/index.test.ts +97 -0
  4. package/payload/platform/lib/admins-write/dist/index.d.ts +12 -0
  5. package/payload/platform/lib/admins-write/dist/index.d.ts.map +1 -1
  6. package/payload/platform/lib/admins-write/dist/index.js +27 -5
  7. package/payload/platform/lib/admins-write/dist/index.js.map +1 -1
  8. package/payload/platform/lib/admins-write/src/index.ts +35 -5
  9. package/payload/platform/lib/admins-write/vitest.config.ts +14 -0
  10. package/payload/platform/lib/dispatch-read/dist/session.d.ts.map +1 -1
  11. package/payload/platform/lib/dispatch-read/dist/session.js +19 -4
  12. package/payload/platform/lib/dispatch-read/dist/session.js.map +1 -1
  13. package/payload/platform/lib/dispatch-read/src/__tests__/session.test.ts +91 -0
  14. package/payload/platform/lib/dispatch-read/src/session.ts +25 -6
  15. package/payload/platform/lib/routine-templates/dist/index.d.ts +2 -2
  16. package/payload/platform/lib/routine-templates/dist/index.d.ts.map +1 -1
  17. package/payload/platform/lib/routine-templates/dist/index.js +9 -1
  18. package/payload/platform/lib/routine-templates/dist/index.js.map +1 -1
  19. package/payload/platform/lib/routine-templates/src/index.ts +14 -2
  20. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  21. package/payload/platform/plugins/admin/PLUGIN.md +8 -3
  22. package/payload/platform/plugins/admin/hooks/__tests__/html-structure-gate.test.sh +264 -0
  23. package/payload/platform/plugins/admin/hooks/__tests__/quote-render-pdf-conformance.test.sh +122 -24
  24. package/payload/platform/plugins/admin/hooks/__tests__/specialist-dispatch-gate.test.sh +158 -0
  25. package/payload/platform/plugins/admin/hooks/html-structure-gate.sh +165 -0
  26. package/payload/platform/plugins/admin/hooks/quote-render-pdf-conformance.sh +111 -19
  27. package/payload/platform/plugins/admin/hooks/specialist-dispatch-gate.sh +159 -0
  28. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.d.ts +27 -0
  29. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.d.ts.map +1 -0
  30. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.js +29 -0
  31. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.js.map +1 -0
  32. package/payload/platform/plugins/admin/mcp/dist/binding-validate.d.ts +11 -0
  33. package/payload/platform/plugins/admin/mcp/dist/binding-validate.d.ts.map +1 -0
  34. package/payload/platform/plugins/admin/mcp/dist/binding-validate.js +20 -0
  35. package/payload/platform/plugins/admin/mcp/dist/binding-validate.js.map +1 -0
  36. package/payload/platform/plugins/admin/mcp/dist/index.js +137 -2
  37. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  38. package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +32 -2
  39. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +192 -90
  40. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +18 -0
  41. package/payload/platform/plugins/docs/references/admin-ui.md +71 -31
  42. package/payload/platform/plugins/docs/references/channel-wake-and-prompt.md +50 -57
  43. package/payload/platform/plugins/docs/references/internals.md +6 -0
  44. package/payload/platform/plugins/docs/references/outlook-guide.md +31 -1
  45. package/payload/platform/plugins/docs/references/telegram-guide.md +23 -0
  46. package/payload/platform/plugins/docs/references/troubleshooting.md +10 -0
  47. package/payload/platform/plugins/email/PLUGIN.md +1 -1
  48. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js +36 -5
  49. package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js.map +1 -1
  50. package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +10 -5
  51. package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -1
  52. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +12 -6
  53. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
  54. package/payload/platform/plugins/email/mcp/dist/lib/imap.js +18 -8
  55. package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
  56. package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.d.ts.map +1 -1
  57. package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js +41 -10
  58. package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js.map +1 -1
  59. package/payload/platform/plugins/email/references/email-reference.md +12 -0
  60. package/payload/platform/plugins/outlook/PLUGIN.md +3 -1
  61. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.d.ts +2 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.d.ts.map +1 -0
  63. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.js +177 -0
  64. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.js.map +1 -0
  65. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.d.ts +2 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.d.ts.map +1 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.js +130 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.js.map +1 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.d.ts +2 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.d.ts.map +1 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.js +162 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.js.map +1 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.d.ts +2 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.d.ts.map +1 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.js +168 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.js.map +1 -0
  77. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.d.ts +64 -0
  78. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.d.ts.map +1 -0
  79. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.js +110 -0
  80. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.js.map +1 -0
  81. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.d.ts +119 -0
  82. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.d.ts.map +1 -0
  83. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.js +0 -0
  84. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.js.map +1 -0
  85. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.d.ts +8 -0
  86. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.d.ts.map +1 -0
  87. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.js +247 -0
  88. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.js.map +1 -0
  89. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts.map +1 -1
  90. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js +10 -0
  91. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js.map +1 -1
  92. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
  93. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +21 -0
  94. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
  95. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts +16 -0
  96. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
  97. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +5 -1
  98. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
  99. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts +4 -0
  100. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts.map +1 -1
  101. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js +2 -1
  102. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js.map +1 -1
  103. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
  104. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +24 -0
  105. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
  106. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts.map +1 -1
  107. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js +2 -1
  108. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js.map +1 -1
  109. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -1
  110. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +29 -0
  111. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -1
  112. package/payload/platform/plugins/scheduling/PLUGIN.md +4 -0
  113. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.d.ts +2 -0
  114. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.d.ts.map +1 -0
  115. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.js +21 -0
  116. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.js.map +1 -0
  117. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.d.ts +13 -0
  118. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.d.ts.map +1 -0
  119. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.js +10 -0
  120. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.js.map +1 -0
  121. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +54 -0
  122. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  123. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +78 -5
  124. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -1
  125. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +133 -2
  126. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
  127. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +11 -0
  128. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
  129. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +30 -1
  130. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  131. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
  132. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +8 -0
  133. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
  134. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
  135. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +37 -6
  136. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
  137. package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
  138. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.d.ts +32 -0
  139. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.d.ts.map +1 -0
  140. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.js +144 -0
  141. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.js.map +1 -0
  142. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  143. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +3 -0
  144. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  145. package/payload/platform/services/claude-session-manager/dist/html-structure-census.d.ts +44 -0
  146. package/payload/platform/services/claude-session-manager/dist/html-structure-census.d.ts.map +1 -0
  147. package/payload/platform/services/claude-session-manager/dist/html-structure-census.js +185 -0
  148. package/payload/platform/services/claude-session-manager/dist/html-structure-census.js.map +1 -0
  149. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  150. package/payload/platform/services/claude-session-manager/dist/http-server.js +32 -5
  151. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  152. package/payload/platform/services/claude-session-manager/dist/index.js +125 -0
  153. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  154. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +12 -1
  155. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  156. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +13 -1
  157. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  158. package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.d.ts.map +1 -1
  159. package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.js +7 -0
  160. package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.js.map +1 -1
  161. package/payload/platform/services/claude-session-manager/dist/quote-print-census.d.ts +42 -0
  162. package/payload/platform/services/claude-session-manager/dist/quote-print-census.d.ts.map +1 -0
  163. package/payload/platform/services/claude-session-manager/dist/quote-print-census.js +254 -0
  164. package/payload/platform/services/claude-session-manager/dist/quote-print-census.js.map +1 -0
  165. package/payload/platform/services/claude-session-manager/dist/specialist-census.d.ts +92 -0
  166. package/payload/platform/services/claude-session-manager/dist/specialist-census.d.ts.map +1 -0
  167. package/payload/platform/services/claude-session-manager/dist/specialist-census.js +227 -0
  168. package/payload/platform/services/claude-session-manager/dist/specialist-census.js.map +1 -0
  169. package/payload/platform/services/telegram-channel/dist/jsonl.d.ts +8 -0
  170. package/payload/platform/services/telegram-channel/dist/jsonl.d.ts.map +1 -0
  171. package/payload/platform/services/telegram-channel/dist/jsonl.js +42 -0
  172. package/payload/platform/services/telegram-channel/dist/jsonl.js.map +1 -0
  173. package/payload/platform/services/telegram-channel/dist/notification.d.ts +0 -31
  174. package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
  175. package/payload/platform/services/telegram-channel/dist/notification.js +4 -33
  176. package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
  177. package/payload/platform/services/telegram-channel/dist/server.d.ts +0 -5
  178. package/payload/platform/services/telegram-channel/dist/server.d.ts.map +1 -1
  179. package/payload/platform/services/telegram-channel/dist/server.js +7 -101
  180. package/payload/platform/services/telegram-channel/dist/server.js.map +1 -1
  181. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +0 -66
  182. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  183. package/payload/platform/services/whatsapp-channel/dist/notification.js +2 -64
  184. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  185. package/payload/platform/services/whatsapp-channel/dist/server.d.ts +0 -12
  186. package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
  187. package/payload/platform/services/whatsapp-channel/dist/server.js +15 -268
  188. package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
  189. package/payload/platform/templates/account-settings.json +8 -4
  190. package/payload/server/public/activity.html +6 -6
  191. package/payload/server/public/agents.html +5 -5
  192. package/payload/server/public/assets/{AdminLoginScreens-CMdj1W5p.js → AdminLoginScreens-Dp6k1XgD.js} +1 -1
  193. package/payload/server/public/assets/AdminLoginScreens-Dp6k1XgD.js.br +0 -0
  194. package/payload/server/public/assets/AdminLoginScreens-Dp6k1XgD.js.gz +0 -0
  195. package/payload/server/public/assets/{AdminShell-CZcaW3BQ.js → AdminShell-D-wB90c3.js} +1 -1
  196. package/payload/server/public/assets/AdminShell-D-wB90c3.js.br +0 -0
  197. package/payload/server/public/assets/AdminShell-D-wB90c3.js.gz +0 -0
  198. package/payload/server/public/assets/{activity-CAhibgb-.js → activity-BJxhblz-.js} +1 -1
  199. package/payload/server/public/assets/activity-BJxhblz-.js.br +0 -0
  200. package/payload/server/public/assets/activity-BJxhblz-.js.gz +0 -0
  201. package/payload/server/public/assets/{admin-xEXv3w9e.js → admin-DzEi8shs.js} +1 -1
  202. package/payload/server/public/assets/admin-DzEi8shs.js.br +0 -0
  203. package/payload/server/public/assets/admin-DzEi8shs.js.gz +0 -0
  204. package/payload/server/public/assets/{agents-CiAmzTaT.js → agents-DTL8kjfD.js} +1 -1
  205. package/payload/server/public/assets/agents-DTL8kjfD.js.br +0 -0
  206. package/payload/server/public/assets/agents-DTL8kjfD.js.gz +0 -0
  207. package/payload/server/public/assets/{browser-D36BiYhS.js → browser-UZp75zhx.js} +1 -1
  208. package/payload/server/public/assets/browser-UZp75zhx.js.br +0 -0
  209. package/payload/server/public/assets/browser-UZp75zhx.js.gz +0 -0
  210. package/payload/server/public/assets/{calendar-CJAM-iXn.js → calendar-Dfo0O2K_.js} +1 -1
  211. package/payload/server/public/assets/calendar-Dfo0O2K_.js.br +0 -0
  212. package/payload/server/public/assets/calendar-Dfo0O2K_.js.gz +0 -0
  213. package/payload/server/public/assets/chat-ByJAvEWZ.js +1 -0
  214. package/payload/server/public/assets/chat-ByJAvEWZ.js.br +0 -0
  215. package/payload/server/public/assets/chat-ByJAvEWZ.js.gz +0 -0
  216. package/payload/server/public/assets/chevron-left-iG7sYNm7.js +1 -0
  217. package/payload/server/public/assets/chevron-left-iG7sYNm7.js.br +0 -0
  218. package/payload/server/public/assets/clock-xSs0UF10.js +1 -0
  219. package/payload/server/public/assets/clock-xSs0UF10.js.br +0 -0
  220. package/payload/server/public/assets/clock-xSs0UF10.js.gz +0 -0
  221. package/payload/server/public/assets/{copy-axBe92iY.js → copy-CGI2jioK.js} +1 -1
  222. package/payload/server/public/assets/copy-CGI2jioK.js.br +0 -0
  223. package/payload/server/public/assets/copy-CGI2jioK.js.gz +0 -0
  224. package/payload/server/public/assets/data-dvwK4BcP.js +1 -0
  225. package/payload/server/public/assets/data-dvwK4BcP.js.br +0 -0
  226. package/payload/server/public/assets/data-dvwK4BcP.js.gz +0 -0
  227. package/payload/server/public/assets/{dispatch-D_i2ko7K.js → dispatch-Dx9-ty1K.js} +1 -1
  228. package/payload/server/public/assets/dispatch-Dx9-ty1K.js.br +0 -0
  229. package/payload/server/public/assets/dispatch-Dx9-ty1K.js.gz +0 -0
  230. package/payload/server/public/assets/{field-DFgkqq1P.js → field-D-P6CsWA.js} +1 -1
  231. package/payload/server/public/assets/field-D-P6CsWA.js.br +0 -0
  232. package/payload/server/public/assets/field-D-P6CsWA.js.gz +0 -0
  233. package/payload/server/public/assets/{file-text-CEFoq0Je.js → file-text-RWintp9q.js} +1 -1
  234. package/payload/server/public/assets/file-text-RWintp9q.js.br +0 -0
  235. package/payload/server/public/assets/file-text-RWintp9q.js.gz +0 -0
  236. package/payload/server/public/assets/{graph-BrpbilNr.js → graph-CpBlfYrJ.js} +1 -1
  237. package/payload/server/public/assets/graph-CpBlfYrJ.js.br +0 -0
  238. package/payload/server/public/assets/graph-CpBlfYrJ.js.gz +0 -0
  239. package/payload/server/public/assets/{graph-labels-BtmcWzo7.js → graph-labels-BOMyPppX.js} +1 -1
  240. package/payload/server/public/assets/graph-labels-BOMyPppX.js.br +0 -0
  241. package/payload/server/public/assets/graph-labels-BOMyPppX.js.gz +0 -0
  242. package/payload/server/public/assets/jsx-runtime-DxsQ5Y-z.css +1 -0
  243. package/payload/server/public/assets/jsx-runtime-DxsQ5Y-z.css.br +0 -0
  244. package/payload/server/public/assets/jsx-runtime-DxsQ5Y-z.css.gz +0 -0
  245. package/payload/server/public/assets/{operator-Dl7dJt1G.js → operator-DFgW6GiH.js} +1 -1
  246. package/payload/server/public/assets/operator-DFgW6GiH.js.br +0 -0
  247. package/payload/server/public/assets/operator-DFgW6GiH.js.gz +0 -0
  248. package/payload/server/public/assets/{page-nx31Ij0T.js → page-BRShHSH0.js} +1 -1
  249. package/payload/server/public/assets/page-BRShHSH0.js.br +0 -0
  250. package/payload/server/public/assets/page-BRShHSH0.js.gz +0 -0
  251. package/payload/server/public/assets/{page-zC66xzNT.js → page-BbBCu9iP.js} +5 -5
  252. package/payload/server/public/assets/page-BbBCu9iP.js.br +0 -0
  253. package/payload/server/public/assets/page-BbBCu9iP.js.gz +0 -0
  254. package/payload/server/public/assets/play-BJxUaf6-.js +1 -0
  255. package/payload/server/public/assets/play-BJxUaf6-.js.br +0 -0
  256. package/payload/server/public/assets/play-BJxUaf6-.js.gz +0 -0
  257. package/payload/server/public/assets/{public-DEKnH5Q0.js → public-DkObqkzL.js} +1 -1
  258. package/payload/server/public/assets/public-DkObqkzL.js.br +0 -0
  259. package/payload/server/public/assets/public-DkObqkzL.js.gz +0 -0
  260. package/payload/server/public/assets/{rotate-ccw-CBex8gon.js → rotate-ccw-DgMO69nh.js} +1 -1
  261. package/payload/server/public/assets/rotate-ccw-DgMO69nh.js.br +0 -0
  262. package/payload/server/public/assets/rotate-ccw-DgMO69nh.js.gz +0 -0
  263. package/payload/server/public/assets/routines-D9kvg_Xu.js +2 -0
  264. package/payload/server/public/assets/routines-D9kvg_Xu.js.br +0 -0
  265. package/payload/server/public/assets/routines-D9kvg_Xu.js.gz +0 -0
  266. package/payload/server/public/assets/{skills-BmxjPOmq.js → skills-l5I9HZ3D.js} +1 -1
  267. package/payload/server/public/assets/skills-l5I9HZ3D.js.br +0 -0
  268. package/payload/server/public/assets/skills-l5I9HZ3D.js.gz +0 -0
  269. package/payload/server/public/assets/{tasks-BTFYO9vT.js → tasks-C2qJMv6i.js} +1 -1
  270. package/payload/server/public/assets/tasks-C2qJMv6i.js.br +0 -0
  271. package/payload/server/public/assets/tasks-C2qJMv6i.js.gz +0 -0
  272. package/payload/server/public/assets/{triangle-alert-px1YRJJ7.js → triangle-alert-BnC67uSs.js} +1 -1
  273. package/payload/server/public/assets/triangle-alert-BnC67uSs.js.br +0 -0
  274. package/payload/server/public/assets/triangle-alert-BnC67uSs.js.gz +0 -0
  275. package/payload/server/public/assets/{useCopyFeedback-nMXwRcDX.js → useCopyFeedback-1RmgkTFh.js} +1 -1
  276. package/payload/server/public/assets/useCopyFeedback-1RmgkTFh.js.br +0 -0
  277. package/payload/server/public/assets/useCopyFeedback-1RmgkTFh.js.gz +0 -0
  278. package/payload/server/public/assets/{useMediaQuery-DjbOTk2X.js → useMediaQuery-BQslddHQ.js} +1 -1
  279. package/payload/server/public/assets/useMediaQuery-BQslddHQ.js.br +0 -0
  280. package/payload/server/public/assets/useMediaQuery-BQslddHQ.js.gz +0 -0
  281. package/payload/server/public/assets/{useVoiceRecorder-Cx7AOmib.js → useVoiceRecorder-BeZNQEC4.js} +1 -1
  282. package/payload/server/public/assets/useVoiceRecorder-BeZNQEC4.js.br +0 -0
  283. package/payload/server/public/assets/useVoiceRecorder-BeZNQEC4.js.gz +0 -0
  284. package/payload/server/public/assets/{wrench-Cexvlx6J.js → wrench-D4ufQG6C.js} +1 -1
  285. package/payload/server/public/assets/wrench-D4ufQG6C.js.br +0 -0
  286. package/payload/server/public/assets/wrench-D4ufQG6C.js.gz +0 -0
  287. package/payload/server/public/browser.html +5 -5
  288. package/payload/server/public/calendar.html +8 -8
  289. package/payload/server/public/chat.html +14 -14
  290. package/payload/server/public/data.html +12 -12
  291. package/payload/server/public/dispatch.html +5 -5
  292. package/payload/server/public/field.html +3 -3
  293. package/payload/server/public/graph.html +10 -10
  294. package/payload/server/public/index.html +14 -14
  295. package/payload/server/public/operator.html +16 -16
  296. package/payload/server/public/public.html +14 -14
  297. package/payload/server/public/routines.html +8 -8
  298. package/payload/server/public/skills.html +6 -6
  299. package/payload/server/public/tasks.html +7 -7
  300. package/payload/server/server.js +1088 -694
  301. package/payload/server/public/assets/AdminLoginScreens-CMdj1W5p.js.br +0 -0
  302. package/payload/server/public/assets/AdminLoginScreens-CMdj1W5p.js.gz +0 -0
  303. package/payload/server/public/assets/AdminShell-CZcaW3BQ.js.br +0 -0
  304. package/payload/server/public/assets/AdminShell-CZcaW3BQ.js.gz +0 -0
  305. package/payload/server/public/assets/activity-CAhibgb-.js.br +0 -0
  306. package/payload/server/public/assets/activity-CAhibgb-.js.gz +0 -0
  307. package/payload/server/public/assets/admin-xEXv3w9e.js.br +0 -0
  308. package/payload/server/public/assets/admin-xEXv3w9e.js.gz +0 -0
  309. package/payload/server/public/assets/agents-CiAmzTaT.js.br +0 -0
  310. package/payload/server/public/assets/agents-CiAmzTaT.js.gz +0 -0
  311. package/payload/server/public/assets/browser-D36BiYhS.js.br +0 -0
  312. package/payload/server/public/assets/browser-D36BiYhS.js.gz +0 -0
  313. package/payload/server/public/assets/calendar-CJAM-iXn.js.br +0 -0
  314. package/payload/server/public/assets/calendar-CJAM-iXn.js.gz +0 -0
  315. package/payload/server/public/assets/chat-DhZSvtZK.js +0 -1
  316. package/payload/server/public/assets/chat-DhZSvtZK.js.br +0 -0
  317. package/payload/server/public/assets/chat-DhZSvtZK.js.gz +0 -0
  318. package/payload/server/public/assets/chevron-left-CXEcNlc3.js +0 -1
  319. package/payload/server/public/assets/chevron-left-CXEcNlc3.js.br +0 -0
  320. package/payload/server/public/assets/clock-DdxIJwTr.js +0 -1
  321. package/payload/server/public/assets/clock-DdxIJwTr.js.br +0 -0
  322. package/payload/server/public/assets/clock-DdxIJwTr.js.gz +0 -0
  323. package/payload/server/public/assets/copy-axBe92iY.js.br +0 -0
  324. package/payload/server/public/assets/copy-axBe92iY.js.gz +0 -0
  325. package/payload/server/public/assets/data-DUvkI-zq.js +0 -1
  326. package/payload/server/public/assets/data-DUvkI-zq.js.br +0 -0
  327. package/payload/server/public/assets/data-DUvkI-zq.js.gz +0 -0
  328. package/payload/server/public/assets/dispatch-D_i2ko7K.js.br +0 -0
  329. package/payload/server/public/assets/dispatch-D_i2ko7K.js.gz +0 -0
  330. package/payload/server/public/assets/field-DFgkqq1P.js.br +0 -0
  331. package/payload/server/public/assets/field-DFgkqq1P.js.gz +0 -0
  332. package/payload/server/public/assets/file-text-CEFoq0Je.js.br +0 -0
  333. package/payload/server/public/assets/file-text-CEFoq0Je.js.gz +0 -0
  334. package/payload/server/public/assets/graph-BrpbilNr.js.br +0 -0
  335. package/payload/server/public/assets/graph-BrpbilNr.js.gz +0 -0
  336. package/payload/server/public/assets/graph-labels-BtmcWzo7.js.br +0 -0
  337. package/payload/server/public/assets/graph-labels-BtmcWzo7.js.gz +0 -0
  338. package/payload/server/public/assets/jsx-runtime-XuYKjgVb.css +0 -1
  339. package/payload/server/public/assets/jsx-runtime-XuYKjgVb.css.br +0 -0
  340. package/payload/server/public/assets/jsx-runtime-XuYKjgVb.css.gz +0 -0
  341. package/payload/server/public/assets/operator-Dl7dJt1G.js.br +0 -3
  342. package/payload/server/public/assets/operator-Dl7dJt1G.js.gz +0 -0
  343. package/payload/server/public/assets/page-nx31Ij0T.js.br +0 -0
  344. package/payload/server/public/assets/page-nx31Ij0T.js.gz +0 -0
  345. package/payload/server/public/assets/page-zC66xzNT.js.br +0 -0
  346. package/payload/server/public/assets/page-zC66xzNT.js.gz +0 -0
  347. package/payload/server/public/assets/play-MbU8O2iC.js +0 -1
  348. package/payload/server/public/assets/play-MbU8O2iC.js.br +0 -0
  349. package/payload/server/public/assets/play-MbU8O2iC.js.gz +0 -0
  350. package/payload/server/public/assets/public-DEKnH5Q0.js.br +0 -0
  351. package/payload/server/public/assets/public-DEKnH5Q0.js.gz +0 -0
  352. package/payload/server/public/assets/rotate-ccw-CBex8gon.js.br +0 -0
  353. package/payload/server/public/assets/rotate-ccw-CBex8gon.js.gz +0 -0
  354. package/payload/server/public/assets/routines-BqCmbvFJ.js +0 -2
  355. package/payload/server/public/assets/routines-BqCmbvFJ.js.br +0 -0
  356. package/payload/server/public/assets/routines-BqCmbvFJ.js.gz +0 -0
  357. package/payload/server/public/assets/skills-BmxjPOmq.js.br +0 -0
  358. package/payload/server/public/assets/skills-BmxjPOmq.js.gz +0 -0
  359. package/payload/server/public/assets/tasks-BTFYO9vT.js.br +0 -0
  360. package/payload/server/public/assets/tasks-BTFYO9vT.js.gz +0 -0
  361. package/payload/server/public/assets/triangle-alert-px1YRJJ7.js.br +0 -0
  362. package/payload/server/public/assets/triangle-alert-px1YRJJ7.js.gz +0 -0
  363. package/payload/server/public/assets/useCopyFeedback-nMXwRcDX.js.br +0 -0
  364. package/payload/server/public/assets/useCopyFeedback-nMXwRcDX.js.gz +0 -0
  365. package/payload/server/public/assets/useMediaQuery-DjbOTk2X.js.br +0 -0
  366. package/payload/server/public/assets/useMediaQuery-DjbOTk2X.js.gz +0 -0
  367. package/payload/server/public/assets/useVoiceRecorder-Cx7AOmib.js.br +0 -0
  368. package/payload/server/public/assets/useVoiceRecorder-Cx7AOmib.js.gz +0 -0
  369. package/payload/server/public/assets/wrench-Cexvlx6J.js.br +0 -0
  370. package/payload/server/public/assets/wrench-Cexvlx6J.js.gz +0 -0
  371. /package/payload/server/public/assets/{jsx-runtime-C5Hcfj84.js → jsx-runtime-5lmxFBIw.js} +0 -0
  372. /package/payload/server/public/assets/{jsx-runtime-C5Hcfj84.js.br → jsx-runtime-5lmxFBIw.js.br} +0 -0
  373. /package/payload/server/public/assets/{jsx-runtime-C5Hcfj84.js.gz → jsx-runtime-5lmxFBIw.js.gz} +0 -0
@@ -36,10 +36,21 @@ export async function emailDraftSend(params) {
36
36
  }
37
37
  const isGmail = config.imapHost === "imap.gmail.com" || config.smtpHost === "smtp.gmail.com";
38
38
  if (isGmail) {
39
- diag("emailDraftSend", "gmail-delete-before-send", `uid=${params.uid}`);
40
39
  // Remove the account's own copy of this message before sending, so Gmail's
41
40
  // SMTP auto-file to Sent is not suppressed by the duplicate Message-ID (1871).
42
- await deleteDraft(config, password, params.uid);
41
+ const del = await deleteDraft(config, password, params.uid);
42
+ diag("emailDraftSend", "gmail-delete-before-send", `uid=${params.uid} outcome=${del.outcome}`);
43
+ if (del.outcome === "refused") {
44
+ // A refused delete leaves the duplicate in place, so the suppression 1871
45
+ // exists to prevent is guaranteed. Sending anyway submits a message whose
46
+ // Sent copy cannot appear and then reports it as sent, which is the defect
47
+ // Task 2514 removes. `absent` and `removed` both leave no copy behind and
48
+ // proceed.
49
+ diag("emailDraftSend", "refused", `uid=${params.uid} folder=${del.folder} reason=delete-refused`);
50
+ throw new Error(`Draft UID ${params.uid} was not sent: the server refused to delete it from ${del.folder}. ` +
51
+ `Sending while that copy is still there suppresses the Sent copy, so delivery could not be ` +
52
+ `confirmed afterwards. The draft is untouched. Try again.`);
53
+ }
43
54
  try {
44
55
  await sendRaw(config, password, draft.source, {
45
56
  from: config.agentAddress,
@@ -58,30 +69,50 @@ export async function emailDraftSend(params) {
58
69
  }
59
70
  // Gmail files the sent copy under the draft's own Message-ID, not sendRaw's
60
71
  // nodemailer return. Confirm and ledger by the draft id.
72
+ //
73
+ // The window named in the result below is derived from these, never written
74
+ // as a literal: a stale number in a result about an unconfirmed send is the
75
+ // same class of defect this task removes (2514).
76
+ const CONFIRM_ATTEMPTS = 6;
77
+ const CONFIRM_DELAY_MS = 2000;
78
+ const confirmWindowSeconds = (CONFIRM_ATTEMPTS * CONFIRM_DELAY_MS) / 1000;
61
79
  const draftMessageId = draft.messageId;
62
80
  const confirm = draftMessageId
63
- ? await confirmSentCopy(config, password, draftMessageId, { attempts: 6, delayMs: 2000 })
81
+ ? await confirmSentCopy(config, password, draftMessageId, {
82
+ attempts: CONFIRM_ATTEMPTS,
83
+ delayMs: CONFIRM_DELAY_MS,
84
+ })
64
85
  : null;
65
- let filedNote;
86
+ const idNote = `(Message-ID: ${draftMessageId ?? "none"})`;
87
+ const sentTo = `Draft UID ${params.uid} sent to ${recipients.join(", ")} ${idNote}`;
88
+ let result;
66
89
  let copy;
67
90
  if (confirm === null) {
68
- filedNote = "sent, but the draft carried no Message-ID so the Sent copy was not verified";
91
+ result = `${sentTo}; sent, but the draft carried no Message-ID so the Sent copy was not verified.`;
69
92
  copy = null;
70
93
  }
71
94
  else if (confirm.found) {
72
- filedNote = `copy confirmed in ${confirm.sentFolder} (UID ${confirm.sentUid})`;
95
+ result = `${sentTo}; copy confirmed in ${confirm.sentFolder} (UID ${confirm.sentUid}).`;
73
96
  copy = "found";
74
97
  }
75
98
  else if (confirm.reason === "no-sent-folder") {
76
- filedNote = "sent, but this server advertises no Sent folder to confirm a copy in";
99
+ result = `${sentTo}; sent, but this server advertises no Sent folder to confirm a copy in.`;
77
100
  copy = "no-sent-folder";
78
101
  }
79
102
  else if (confirm.reason === "not-in-sent") {
80
- filedNote = "sent, but a Sent copy could not be confirmed within 12 seconds";
103
+ // The folder was searched and the copy was absent, so nothing here may
104
+ // assert delivery. This result previously opened "sent to …" and a reader
105
+ // seeing the draft still in Drafts concluded the send had not happened; it
106
+ // had, and the message went out twice (Task 2514).
107
+ result =
108
+ `SMTP accepted draft UID ${params.uid} for ${recipients.join(", ")} ${idNote}; ` +
109
+ `no copy appeared in ${confirm.sentFolder} within ${confirmWindowSeconds} seconds, so ` +
110
+ `delivery is unconfirmed. Do not resend without checking the recipient: a resend may ` +
111
+ `deliver the message twice.`;
81
112
  copy = "not-in-sent";
82
113
  }
83
114
  else {
84
- filedNote = `sent, but the Sent folder could not be checked (${confirm.error})`;
115
+ result = `${sentTo}; sent, but the Sent folder could not be checked (${confirm.error}).`;
85
116
  copy = "check-failed";
86
117
  }
87
118
  if (draftMessageId && copy) {
@@ -101,7 +132,7 @@ export async function emailDraftSend(params) {
101
132
  // Observability only. Never turn a completed send into an error.
102
133
  }
103
134
  }
104
- return `Draft UID ${params.uid} sent to ${recipients.join(", ")} (Message-ID: ${draftMessageId ?? "none"}); ${filedNote}.`;
135
+ return result;
105
136
  }
106
137
  let messageId;
107
138
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"email-draft-send.js","sourceRoot":"","sources":["../../src/tools/email-draft-send.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"email-draft-send.js","sourceRoot":"","sources":["../../src/tools/email-draft-send.ts"],"names":[],"mappings":"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"}
@@ -134,6 +134,12 @@ Four outcomes are reported, and they are deliberately distinct:
134
134
 
135
135
  A send whose copy cannot be located is still a successful send, and the result says both things plainly. Collapsing them into one word is what allowed a sent-copy claim to go unchallenged for four days when no copy was being filed at all.
136
136
 
137
+ One of the four reads differently on `email-draft-send` against Gmail, because there the missing copy has a known cause. That result does not open by naming recipients the message was "sent to". It opens on what is actually established, which is that SMTP accepted the message. It then names the folder searched and the window searched for, and warns that resending may deliver the message twice:
138
+
139
+ > `SMTP accepted draft UID 28384 for <address> (Message-ID: <id>); no copy appeared in [Gmail]/Sent Mail within 12 seconds, so delivery is unconfirmed. Do not resend without checking the recipient: a resend may deliver the message twice.`
140
+
141
+ The other three clauses are unchanged there. They describe a server that could not be asked; this one describes a send that cannot be trusted, and a reader who saw the draft still sitting in Drafts previously took the old "sent to …" opening as proof the send had not happened. It had, and the message went out twice.
142
+
137
143
  Every send also appends one row to `config/email-sent-ledger.jsonl` recording the observed outcome. That ledger is the left-hand side of the hourly sweep below; it is written after the read-back, so it records what happened, not what was intended.
138
144
 
139
145
  ## The hourly sent-copy sweep
@@ -163,6 +169,12 @@ Both `email-send` and `email-reply` accept an optional `attachments` array of ab
163
169
 
164
170
  `email-draft` composes a message and stores it unsent in the mailbox's Drafts folder; `email-draft-edit` revises a stored draft; `email-draft-send` dispatches one; `email-draft-list` reads the folder back. Nothing is sent until the operator (or `email-draft-send`) says so.
165
171
 
172
+ ### Sending a Gmail draft removes it first, and stops if that fails
173
+
174
+ Gmail suppresses its own Sent-filing when the account already holds a message with the same Message-ID, so on Gmail `email-draft-send` deletes the stored draft before handing the message to SMTP. That delete has three outcomes and they are not interchangeable. `removed` and `absent` both leave no copy behind, so the send proceeds. `refused` means the server declined and the copy is still there, so the send stops before SMTP with an error naming the UID and the folder. Nothing is restored on that path because nothing was removed, and the draft is exactly where the operator left it.
175
+
176
+ Sending anyway is what this refusal exists to prevent: the duplicate guarantees the Sent copy cannot appear, so the message goes out and then reports as unconfirmable, which reads to the next person as a send that never happened.
177
+
166
178
  ### Verifying a draft is there
167
179
 
168
180
  `email-draft-list` is the only tool that can confirm a draft's presence. `email-status` reports connectivity and an inbox count; `email-read` and `email-search` are inbox/sent only. It resolves the folder through the same `resolveDraftsFolder` the write path uses, so its answer is about the folder the draft was actually written to.
@@ -137,6 +137,7 @@ Microsoft Graph access for Outlook.com / Microsoft 365 mailboxes. Mail is read (
137
137
  - **Mail (ingest to graph):** `outlook-mail-ingest` writes operator-reviewed messages into the business graph as `:ConversationArchive {source:'email'}` threads, the analogue of the IMAP `email-ingest`. Input is `decisions`: one `{messageId, disposition:'ingest'|'discard'}` per listed message. Each `ingest` message's full body + envelope is fetched via `runMailFetchBody`, threads are grouped by Graph `conversationId`, and participant resolution is closed-set — every From/To/Cc address must already resolve to a `:Person.email` or `:AdminUser.email` for the `accountId`, or its thread is skipped and the address is returned to the operator (no `:Person` auto-create). Resolvable threads dispatch one at a time through the shared `plugins/memory/bin/conversation-archive-ingest.sh --source email` (same RFC822 thread-JSON shape the `email` normaliser consumes). This is the plugin's only Neo4j coupling (`neo4j-driver`). Human-in-the-loop: nothing enters the graph without an explicit per-message decision; the `outlook-mail-ingest` skill drives the list → summarise → ask → ingest loop. Requires `Mail.Read`.
138
138
  - **Mail (OTP):** `outlook-mail-otp-extract` polls the inbox for a one-time verification code from a named sender, reading full bodies to extract it — used during service authentication.
139
139
  - **Mail (send / draft):** `outlook-mail-send` sends a new message — via `POST /me/sendMail` with no attachments, or composed as a draft, attached, and sent when `attachments` is present (`/me/sendMail` carries attachments inline and cannot fit a large file); `outlook-draft` creates a draft, attaches any files, and returns its id — either a new message (`to` + `subject` required) or, with `replyToMessageId`, a threaded reply created via `POST /me/messages/{id}/createReply` that lands under the original conversation (the only way to draft a reply without sending it; `outlook-mail-reply` threads but always sends). On the threaded path Graph sets the recipients and `RE:` subject from the original and composes the body above its own quote — the same email `outlook-mail-reply` sends — so that path is plain text only and `to`, `subject`, and `isHtml: true` are refused rather than silently dropped; `replyAll` and `cc`/`bcc` work as on reply. The draft result carries `to`, the recipients the draft holds, so the self-addressed case above is visible without fetching the draft back; on this path it is reported rather than refused, because a draft is not sent. `outlook-draft-edit` updates an existing draft in place (Graph drafts are mutable) and edits its attachments — `attachments` adds files, `removeAttachments` takes them off by name or attachment id, and both together replace a file in one call; `outlook-draft-send` sends an existing draft by id. Recipients are to/cc/bcc arrays; body is HTML or plain text via `isHtml`; `attachments` are file paths inside the account directory, capped at 25 MB per file and validated before any Graph write. Success asserted on Graph 202. Requires `Mail.Send` + `Mail.ReadWrite`; a mailbox on the old read-only consent returns an actionable "re-register to grant send" signal.
140
+ - **Draft attribution:** every draft the plugin creates and every draft it sends is recorded in an append-only ledger at `platform/config/outlook-draft-ledger.jsonl`. The `created` row is written the moment Graph returns the draft id, before any attach or send, so a draft stranded by a later failure is still watched; `outlook-mail-send`'s no-attachment route drafts nothing and writes nothing. An hourly reconcile spawned by the scheduling heartbeat classifies each open draft against live mailbox state: `still-draft`, `sent-by-maxy`, `sent-not-by-maxy`, `deleted`, `unreadable`. **An empty Drafts folder beside a copy in Sent Items is not evidence this plugin sent anything** — an external mail client signed in to the same mailbox produces identical folder state, and a message that has left the Drafts folder still fetches by id and still returns `from: null` while it remains a draft object. The reconcile's `outcome=` is the only sanctioned statement; agents must not assert a send from folder state. `parentFolderId` is the discriminator, not `isDraft`, and every mail read now returns both. Naming the external client requires the tenant's Microsoft 365 unified audit log, which these delegated scopes cannot read (see out of scope). See `.docs/outlook-draft-attribution.md`.
140
141
  - **Calendar (read + control):** `outlook-calendar-list` and `outlook-calendar-event` read events; `outlook-calendar-create` books an event; `outlook-calendar-update` reschedules or edits one; `outlook-calendar-cancel` cancels a meeting (notifying attendees when the account organises it) or deletes a personal appointment; `outlook-calendar-respond` accepts, declines, or tentatively accepts an invite; `outlook-calendar-freebusy` reports availability for one or more addresses over a window. Writes require the `Calendars.ReadWrite` consent; a mailbox on stale read-only consent returns a distinct signal naming the scope and `outlook-account-register`.
141
142
  - **Contacts (read-only):** `outlook-contacts-list` returns contacts.
142
143
  - **Health:** `outlook-mailbox-info` reports auth state, refresh-window status, and top-level folder count for one mailbox (name it with `mailbox` when several are attached). `outlook-mailbox-list` lists every attached mailbox with its email, scopes, and token health, reading local stores only, never the network. It reports an `addressable` count and a per-mailbox `status` (`ok` / `blank-email` / `refresh-expired` / `unreadable`) so an authenticated, addressable mailbox is distinguishable from one that is merely present: a bare `count` of 1 is not "connected" unless that mailbox is `status:ok`. Use these to answer "did mailbox X auth?" without grepping logs.
@@ -151,7 +152,8 @@ Microsoft Graph access for Outlook.com / Microsoft 365 mailboxes. Mail is read (
151
152
  - OneDrive, Files, Sites — separate plugin; different endpoints.
152
153
  - Push notifications via `/subscriptions` — first cut polls.
153
154
  - On-premises Exchange — Microsoft Graph deprecated hybrid REST 2023-07. The plugin detects on-prem mailboxes and routes the operator to the IMAP path (`email` plugin).
154
- - M365 admin scopes (`User.Read.All`, `AuditLog.Read.All`) — separate plugin.
155
+ - M365 admin scopes (`User.Read.All`, `AuditLog.Read.All`) — separate plugin. This is why the draft reconcile can report that a draft left the Drafts folder without a Real Agent send, but cannot name what sent it: the client string lives on a `Send` record in the tenant's unified audit log, which the mailbox owner's M365 administrator pulls.
156
+ - Blocking or refusing a send when the draft ledger disagrees with the mailbox. The reconcile observes; enforcement is deliberately not built.
155
157
 
156
158
  ## References
157
159
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=draft-ledger-write-sites.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-ledger-write-sites.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/draft-ledger-write-sites.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,177 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { TokenStore } from "../auth/token-store.js";
7
+ import { runDraft } from "../tools/draft.js";
8
+ import { runDraftSend } from "../tools/draft-send.js";
9
+ import { runMailSend } from "../tools/mail-send.js";
10
+ import { runMailReply } from "../tools/mail-reply.js";
11
+ import { readDraftLedger } from "../lib/draft-ledger.js";
12
+ /**
13
+ * Task 2530. The ledger's own unit tests prove the file works; these prove the
14
+ * four tools actually write to it. A send path that quietly stopped writing
15
+ * would make a real Maxy send read as `sent-not-by-maxy` later, which is the
16
+ * one wrong answer this whole mechanism exists to avoid.
17
+ */
18
+ function configWithToken(accountId, mailbox) {
19
+ const dir = mkdtempSync(join(tmpdir(), "outlook-ledgersite-"));
20
+ const tokenStore = new TokenStore(accountId, dir);
21
+ tokenStore.store("access-token", "refresh-token", 3600, { scopes: ["Mail.ReadWrite", "Mail.Send"] });
22
+ return { clientId: "test-client", tenantId: "common", accountId, tokenStore, mailboxAddress: mailbox };
23
+ }
24
+ /** Every Graph write answers 201 with a fixed id; sends answer 202. */
25
+ function mockGraph() {
26
+ const original = globalThis.fetch;
27
+ globalThis.fetch = (async (input, init) => {
28
+ const req = input instanceof Request ? input : null;
29
+ const url = req ? req.url : typeof input === "string" ? input : input.toString();
30
+ if (!url.includes("graph.microsoft.com"))
31
+ return original(input, init);
32
+ if (url.endsWith("/send") || url.endsWith("/sendMail"))
33
+ return new Response(null, { status: 202 });
34
+ return new Response(JSON.stringify({ id: "GRAPHID", conversationId: "CONV1", toRecipients: [{ emailAddress: { address: "g@example.com" } }] }), { status: 201, headers: { "content-type": "application/json" } });
35
+ });
36
+ return {
37
+ restore: () => {
38
+ globalThis.fetch = original;
39
+ },
40
+ };
41
+ }
42
+ /**
43
+ * A temp tree shaped like a real install: `<base>/platform` is PLATFORM_ROOT and
44
+ * `<base>/data/accounts/<id>` is where attachment paths must resolve, because
45
+ * `resolveAccountDir` reads `join(platformRoot, "..", "data", "accounts", id)`.
46
+ * A flat temp dir would put the account dir in the OS temp root itself.
47
+ *
48
+ * `fn` receives the account directory so an attachment test can write into it.
49
+ */
50
+ async function withLedger(accountId, fn) {
51
+ const base = mkdtempSync(join(tmpdir(), "outlook-ledgerroot-"));
52
+ const root = join(base, "platform");
53
+ const accountDir = join(base, "data", "accounts", accountId);
54
+ mkdirSync(join(root, "config"), { recursive: true });
55
+ mkdirSync(accountDir, { recursive: true });
56
+ const prevRoot = process.env.PLATFORM_ROOT;
57
+ const prevAccountDir = process.env.ACCOUNT_DIR;
58
+ process.env.PLATFORM_ROOT = root;
59
+ delete process.env.ACCOUNT_DIR;
60
+ const mock = mockGraph();
61
+ try {
62
+ await fn(accountDir);
63
+ return readDraftLedger();
64
+ }
65
+ finally {
66
+ mock.restore();
67
+ if (prevRoot === undefined)
68
+ delete process.env.PLATFORM_ROOT;
69
+ else
70
+ process.env.PLATFORM_ROOT = prevRoot;
71
+ if (prevAccountDir !== undefined)
72
+ process.env.ACCOUNT_DIR = prevAccountDir;
73
+ rmSync(base, { recursive: true, force: true });
74
+ }
75
+ }
76
+ test("outlook-draft writes one created row carrying mailbox and subject", async () => {
77
+ const rows = await withLedger("acct-w1", async () => {
78
+ await runDraft(configWithToken("acct-w1", "rob@example.com"), {
79
+ to: ["g@example.com"],
80
+ subject: "Extending our work",
81
+ body: "hi",
82
+ });
83
+ });
84
+ assert.equal(rows.length, 1);
85
+ assert.equal(rows[0].event, "created");
86
+ assert.equal(rows[0].tool, "draft");
87
+ assert.equal(rows[0].draftId, "GRAPHID");
88
+ assert.equal(rows[0].mailbox, "rob@example.com");
89
+ assert.equal(rows[0].subject, "Extending our work");
90
+ assert.equal(rows[0].conversationId, null, "a standalone draft has no conversation");
91
+ });
92
+ test("a threaded draft carries the conversationId instead of a subject", async () => {
93
+ const rows = await withLedger("acct-w2", async () => {
94
+ await runDraft(configWithToken("acct-w2", "rob@example.com"), {
95
+ replyToMessageId: "PARENT",
96
+ body: "hi",
97
+ });
98
+ });
99
+ assert.equal(rows.length, 1);
100
+ assert.equal(rows[0].conversationId, "CONV1");
101
+ assert.equal(rows[0].subject, undefined, "Graph sets the subject on a threaded draft");
102
+ });
103
+ test("outlook-draft-send writes one sent row", async () => {
104
+ const rows = await withLedger("acct-w3", async () => {
105
+ await runDraftSend(configWithToken("acct-w3", "rob@example.com"), { draftId: "D1" });
106
+ });
107
+ assert.equal(rows.length, 1);
108
+ assert.equal(rows[0].event, "sent");
109
+ assert.equal(rows[0].tool, "draft-send");
110
+ assert.equal(rows[0].route, "draft-send");
111
+ assert.equal(rows[0].draftId, "D1");
112
+ });
113
+ test("the sendMail route writes NO row — it drafts nothing and Graph returns no id", async () => {
114
+ // A row here would carry an empty draftId that can never pair with a created
115
+ // row and can never be pruned by one: a line nothing reads, growing forever.
116
+ const rows = await withLedger("acct-w4", async () => {
117
+ await runMailSend(configWithToken("acct-w4", "rob@example.com"), {
118
+ to: ["g@example.com"],
119
+ subject: "No attachments",
120
+ body: "hi",
121
+ });
122
+ });
123
+ assert.deepEqual(rows, []);
124
+ });
125
+ test("outlook-mail-reply writes created then sent for the draft Graph composed", async () => {
126
+ const rows = await withLedger("acct-w5", async () => {
127
+ await runMailReply(configWithToken("acct-w5", "rob@example.com"), {
128
+ messageId: "PARENT",
129
+ body: "hi",
130
+ });
131
+ });
132
+ assert.equal(rows.length, 2);
133
+ assert.equal(rows[0].event, "created");
134
+ assert.equal(rows[0].tool, "mail-reply");
135
+ assert.equal(rows[0].conversationId, "CONV1");
136
+ assert.equal(rows[1].event, "sent");
137
+ assert.equal(rows[1].route, "reply");
138
+ assert.equal(rows[0].draftId, rows[1].draftId);
139
+ });
140
+ test("mail-send's attachment route writes created before the send, then sent", async () => {
141
+ // The route DOES draft. Anything throwing between the create and the send
142
+ // strands that draft in Drafts; without the created row the reconcile is
143
+ // blind to it.
144
+ const rows = await withLedger("acct-w7", async (accountDir) => {
145
+ // Inside the account dir: resolveOutboundAttachments refuses any path that
146
+ // does not realpath under it.
147
+ const file = join(accountDir, "quote.pdf");
148
+ writeFileSync(file, "pdf-bytes");
149
+ await runMailSend(configWithToken("acct-w7", "rob@example.com"), {
150
+ to: ["g@example.com"],
151
+ subject: "With attachment",
152
+ body: "hi",
153
+ attachments: [file],
154
+ });
155
+ });
156
+ assert.equal(rows.length, 2);
157
+ assert.equal(rows[0].event, "created");
158
+ assert.equal(rows[0].tool, "mail-send");
159
+ assert.equal(rows[0].subject, "With attachment");
160
+ assert.equal(rows[1].event, "sent");
161
+ assert.equal(rows[1].route, "draft-send");
162
+ assert.equal(rows[0].draftId, rows[1].draftId);
163
+ });
164
+ test("a draft and its send pair up on the same draftId", async () => {
165
+ // The pairing is what lets the reconcile answer sent-by-maxy from the ledger
166
+ // alone, with no Graph call.
167
+ const rows = await withLedger("acct-w6", async () => {
168
+ const config = configWithToken("acct-w6", "rob@example.com");
169
+ await runDraft(config, { to: ["g@example.com"], subject: "Paired", body: "hi" });
170
+ await runDraftSend(config, { draftId: "GRAPHID" });
171
+ });
172
+ assert.equal(rows.length, 2);
173
+ assert.equal(rows[0].draftId, rows[1].draftId);
174
+ assert.equal(rows[0].event, "created");
175
+ assert.equal(rows[1].event, "sent");
176
+ });
177
+ //# sourceMappingURL=draft-ledger-write-sites.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-ledger-write-sites.test.js","sourceRoot":"","sources":["../../src/__tests__/draft-ledger-write-sites.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAyB,MAAM,wBAAwB,CAAC;AAEhF;;;;;GAKG;AAEH,SAAS,eAAe,CAAC,SAAiB,EAAE,OAAsB;IAChE,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAClD,UAAU,CAAC,KAAK,CAAC,cAAc,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,gBAAgB,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACrG,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;AACzG,CAAC;AAED,uEAAuE;AACvE,SAAS,SAAS;IAChB,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;IAClC,UAAU,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,KAA6B,EAAE,IAAkB,EAAE,EAAE;QAC9E,MAAM,GAAG,GAAG,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACpD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjF,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAAE,OAAO,QAAQ,CAAC,KAAuC,EAAE,IAAI,CAAC,CAAC;QACzG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACnG,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,EAC1H,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,CACjE,CAAC;IACJ,CAAC,CAAiB,CAAC;IACnB,OAAO;QACL,OAAO,EAAE,GAAG,EAAE;YACZ,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC;QAC9B,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,UAAU,CACvB,SAAiB,EACjB,EAAyC;IAEzC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAC7D,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC3C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;IACjC,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC/B,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC;QACrB,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;;YACxD,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC1C,IAAI,cAAc,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,cAAc,CAAC;QAC3E,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,IAAI,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;IACnF,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;YAC5D,EAAE,EAAE,CAAC,eAAe,CAAC;YACrB,OAAO,EAAE,oBAAoB;YAC7B,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IACpD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,wCAAwC,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;IAClF,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;YAC5D,gBAAgB,EAAE,QAAQ;YAC1B,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,4CAA4C,CAAC,CAAC;AACzF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;IACxD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,YAAY,CAAC,eAAe,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;IAC9F,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,WAAW,CAAC,eAAe,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;YAC/D,EAAE,EAAE,CAAC,eAAe,CAAC;YACrB,OAAO,EAAE,gBAAgB;YACzB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;IAC1F,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,YAAY,CAAC,eAAe,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;YAChE,SAAS,EAAE,QAAQ;YACnB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;IACxF,0EAA0E;IAC1E,yEAAyE;IACzE,eAAe;IACf,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;QAC5D,2EAA2E;QAC3E,8BAA8B;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC3C,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjC,MAAM,WAAW,CAAC,eAAe,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE;YAC/D,EAAE,EAAE,CAAC,eAAe,CAAC;YACrB,OAAO,EAAE,iBAAiB;YAC1B,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,CAAC,IAAI,CAAC;SACpB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;IAClE,6EAA6E;IAC7E,6BAA6B;IAC7B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QAC7D,MAAM,QAAQ,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACjF,MAAM,YAAY,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=draft-ledger.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-ledger.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/draft-ledger.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,130 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, mkdirSync, rmSync, readFileSync, writeFileSync, statSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { appendDraftLedger, readDraftLedger, writeDraftLedger, ledgerPath, } from "../lib/draft-ledger.js";
7
+ function withRoot(fn) {
8
+ const root = mkdtempSync(join(tmpdir(), "outlook-ledger-"));
9
+ mkdirSync(join(root, "config"), { recursive: true });
10
+ const prev = process.env.PLATFORM_ROOT;
11
+ process.env.PLATFORM_ROOT = root;
12
+ try {
13
+ fn();
14
+ }
15
+ finally {
16
+ if (prev === undefined)
17
+ delete process.env.PLATFORM_ROOT;
18
+ else
19
+ process.env.PLATFORM_ROOT = prev;
20
+ rmSync(root, { recursive: true, force: true });
21
+ }
22
+ }
23
+ const CREATED = {
24
+ at: "2026-08-07T11:52:25.000Z",
25
+ accountId: "acc-1",
26
+ mailbox: "rob@example.com",
27
+ draftId: "AAA",
28
+ event: "created",
29
+ tool: "draft",
30
+ subject: "Extending our work",
31
+ conversationId: null,
32
+ };
33
+ test("append writes one JSON line per entry and read returns them in order", () => {
34
+ withRoot(() => {
35
+ appendDraftLedger(CREATED);
36
+ appendDraftLedger({ ...CREATED, at: "2026-08-07T12:00:00.000Z", draftId: "BBB" });
37
+ const rows = readDraftLedger();
38
+ assert.equal(rows.length, 2);
39
+ assert.equal(rows[0].draftId, "AAA");
40
+ assert.equal(rows[1].draftId, "BBB");
41
+ assert.equal(rows[0].subject, "Extending our work");
42
+ });
43
+ });
44
+ test("append never rewrites the file — a concurrent row is not lost", () => {
45
+ withRoot(() => {
46
+ appendDraftLedger(CREATED);
47
+ appendDraftLedger({
48
+ at: "2026-08-07T11:55:00.000Z",
49
+ accountId: "acc-1",
50
+ mailbox: "rob@example.com",
51
+ draftId: "BBB",
52
+ event: "sent",
53
+ tool: "draft-send",
54
+ route: "draft-send",
55
+ });
56
+ const raw = readFileSync(ledgerPath(), "utf8");
57
+ assert.equal(raw.trim().split("\n").length, 2);
58
+ });
59
+ });
60
+ test("a malformed line is skipped, never thrown on", () => {
61
+ withRoot(() => {
62
+ appendDraftLedger(CREATED);
63
+ writeFileSync(ledgerPath(), readFileSync(ledgerPath(), "utf8") + "{not json\n");
64
+ const rows = readDraftLedger();
65
+ assert.equal(rows.length, 1);
66
+ assert.equal(rows[0].draftId, "AAA");
67
+ });
68
+ });
69
+ test("reading an absent ledger returns an empty array", () => {
70
+ withRoot(() => {
71
+ assert.deepEqual(readDraftLedger(), []);
72
+ });
73
+ });
74
+ test("writeDraftLedger replaces the file with exactly the rows given", () => {
75
+ withRoot(() => {
76
+ appendDraftLedger(CREATED);
77
+ appendDraftLedger({ ...CREATED, draftId: "BBB" });
78
+ writeDraftLedger([{ ...CREATED, draftId: "CCC" }]);
79
+ const rows = readDraftLedger();
80
+ assert.deepEqual(rows.map((r) => r.draftId), ["CCC"]);
81
+ });
82
+ });
83
+ test("writeDraftLedger with no rows leaves a readable empty file", () => {
84
+ withRoot(() => {
85
+ appendDraftLedger(CREATED);
86
+ writeDraftLedger([]);
87
+ assert.deepEqual(readDraftLedger(), []);
88
+ });
89
+ });
90
+ test("the ledger file is written 0600", () => {
91
+ withRoot(() => {
92
+ appendDraftLedger(CREATED);
93
+ assert.equal(statSync(ledgerPath()).mode & 0o777, 0o600);
94
+ });
95
+ });
96
+ test("a write failure logs and returns rather than throwing", () => {
97
+ // PLATFORM_ROOT pointed at a path that cannot be created: the append must not
98
+ // propagate. Observability must never take out the mail.
99
+ const prev = process.env.PLATFORM_ROOT;
100
+ process.env.PLATFORM_ROOT = "/dev/null/nope";
101
+ try {
102
+ assert.doesNotThrow(() => appendDraftLedger(CREATED));
103
+ }
104
+ finally {
105
+ if (prev === undefined)
106
+ delete process.env.PLATFORM_ROOT;
107
+ else
108
+ process.env.PLATFORM_ROOT = prev;
109
+ }
110
+ });
111
+ test("no PLATFORM_ROOT means no ledger path, and nothing is written anywhere", () => {
112
+ // There is no directory-relative fallback by design: guessing a path is how
113
+ // the email ledger's fallback ends up writing a stray plugins/config/ into
114
+ // the source tree under test.
115
+ const prev = process.env.PLATFORM_ROOT;
116
+ delete process.env.PLATFORM_ROOT;
117
+ try {
118
+ assert.equal(ledgerPath(), null);
119
+ assert.doesNotThrow(() => appendDraftLedger(CREATED));
120
+ assert.deepEqual(readDraftLedger(), []);
121
+ assert.throws(() => writeDraftLedger([CREATED]), /PLATFORM_ROOT is not set/);
122
+ }
123
+ finally {
124
+ if (prev === undefined)
125
+ delete process.env.PLATFORM_ROOT;
126
+ else
127
+ process.env.PLATFORM_ROOT = prev;
128
+ }
129
+ });
130
+ //# sourceMappingURL=draft-ledger.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-ledger.test.js","sourceRoot":"","sources":["../../src/__tests__/draft-ledger.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=draft-reconcile.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-reconcile.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/draft-reconcile.test.ts"],"names":[],"mappings":""}