@rubytech/create-maxy-code 0.1.446 → 0.1.448

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 (232) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  3. package/payload/platform/lib/graph-style/dist/index.js +6 -0
  4. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  5. package/payload/platform/lib/graph-style/src/index.ts +7 -0
  6. package/payload/platform/neo4j/schema.cypher +35 -1
  7. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  8. package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +1 -0
  9. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +42 -5
  10. package/payload/platform/plugins/docs/references/calendar-booking.md +18 -1
  11. package/payload/platform/plugins/docs/references/claudeai-connectors.md +15 -0
  12. package/payload/platform/plugins/docs/references/outlook-guide.md +8 -3
  13. package/payload/platform/plugins/email/skills/email-composition/SKILL.md +4 -4
  14. package/payload/platform/plugins/memory/references/schema-construction.md +7 -2
  15. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  16. package/payload/platform/plugins/outlook/PLUGIN.md +23 -5
  17. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.d.ts +2 -0
  18. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.d.ts.map +1 -0
  19. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js +70 -0
  20. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js.map +1 -0
  21. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.d.ts +2 -0
  22. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.d.ts.map +1 -0
  23. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.js +22 -0
  24. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.js.map +1 -0
  25. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.d.ts +2 -0
  26. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.d.ts.map +1 -0
  27. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.js +60 -0
  28. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.js.map +1 -0
  29. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.d.ts +2 -0
  30. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.d.ts.map +1 -0
  31. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.js +80 -0
  32. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.js.map +1 -0
  33. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.d.ts +2 -0
  34. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.d.ts.map +1 -0
  35. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.js +90 -0
  36. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.js.map +1 -0
  37. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.d.ts +2 -0
  38. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.d.ts.map +1 -0
  39. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.js +194 -0
  40. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.js.map +1 -0
  41. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.d.ts +2 -0
  42. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.d.ts.map +1 -0
  43. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.js +16 -0
  44. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.js.map +1 -0
  45. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.d.ts +2 -0
  46. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.d.ts.map +1 -0
  47. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.js +103 -0
  48. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.js.map +1 -0
  49. package/payload/platform/plugins/outlook/mcp/dist/index.js +88 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  51. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.d.ts +9 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.d.ts.map +1 -0
  53. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.js +24 -0
  54. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.js.map +1 -0
  55. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.d.ts +2 -0
  56. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.d.ts.map +1 -0
  57. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.js +49 -0
  58. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.js.map +1 -0
  59. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts +58 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts.map +1 -0
  61. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js +127 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js.map +1 -0
  63. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts +28 -0
  64. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts.map +1 -0
  65. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js +54 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js.map +1 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts +21 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +38 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.d.ts +14 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.d.ts.map +1 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.js +39 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.js.map +1 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts +23 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -0
  77. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +44 -0
  78. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -0
  79. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.d.ts +22 -0
  80. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.d.ts.map +1 -0
  81. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.js +90 -0
  82. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.js.map +1 -0
  83. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts +27 -0
  84. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -0
  85. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +75 -0
  86. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -0
  87. package/payload/platform/plugins/outlook/references/graph-surfaces.md +57 -1
  88. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +15 -4
  89. package/payload/platform/plugins/scheduling/PLUGIN.md +15 -0
  90. package/payload/platform/plugins/scheduling/mcp/dist/index.js +29 -1
  91. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  92. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js +53 -1
  93. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js.map +1 -1
  94. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +21 -0
  95. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
  96. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +80 -0
  97. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
  98. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts +4 -0
  99. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts.map +1 -1
  100. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +68 -1
  101. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  102. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.d.ts +2 -0
  103. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.d.ts.map +1 -0
  104. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.js +75 -0
  105. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.js.map +1 -0
  106. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.d.ts +31 -0
  107. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.d.ts.map +1 -0
  108. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.js +41 -0
  109. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.js.map +1 -0
  110. package/payload/platform/plugins/voice-mirror/.claude-plugin/plugin.json +21 -0
  111. package/payload/platform/plugins/voice-mirror/PLUGIN.md +72 -0
  112. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.js +10 -10
  113. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.js.map +1 -1
  114. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.d.ts +1 -1
  115. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.js +4 -4
  116. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.js.map +1 -1
  117. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.js +1 -1
  118. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.js.map +1 -1
  119. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/package-lock.json +2 -2
  120. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/package.json +1 -1
  121. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/scripts/smoke.mjs +9 -9
  122. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/skills/voice-mirror/SKILL.md +1 -1
  123. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  124. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +12 -0
  125. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  126. package/payload/platform/services/claude-session-manager/dist/http-server.js +1 -1
  127. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  128. package/payload/platform/templates/agents/admin/AGENTS.md +1 -1
  129. package/payload/platform/templates/specialists/agents/content-producer.md +1 -1
  130. package/payload/platform/templates/specialists/agents/personal-assistant.md +6 -2
  131. package/payload/premium-plugins/writer-craft/.claude-plugin/plugin.json +1 -14
  132. package/payload/premium-plugins/writer-craft/PLUGIN.md +2 -51
  133. package/payload/server/public/assets/{AdminLoginScreens-D9L-CuWi.js → AdminLoginScreens-Bvf4HKmq.js} +1 -1
  134. package/payload/server/public/assets/AdminShell-CaGc8ODG.js +2 -0
  135. package/payload/server/public/assets/{Checkbox-CFdt8ljo.js → Checkbox-2SswiICc.js} +1 -1
  136. package/payload/server/public/assets/admin-B7GPCzpr.js +1 -0
  137. package/payload/server/public/assets/browser-CodHC_MO.js +1 -0
  138. package/payload/server/public/assets/calendar-DH7cyXKF.js +1 -0
  139. package/payload/server/public/assets/chat-BQyPAEMv.js +1 -0
  140. package/payload/server/public/assets/chevron-left-Cmev0R9v.js +1 -0
  141. package/payload/server/public/assets/data-DWxZzMfL.js +1 -0
  142. package/payload/server/public/assets/{graph-DrE7KupQ.js → graph-BToB78LG.js} +2 -2
  143. package/payload/server/public/assets/graph-labels-JRGrstzM.js +1 -0
  144. package/payload/server/public/assets/maximize-2-CEQRv64B.js +1 -0
  145. package/payload/server/public/assets/operator-Cx8cq2wf.js +1 -0
  146. package/payload/server/public/assets/page-D6kzsk18.js +32 -0
  147. package/payload/server/public/assets/page-TCsQy4eP.js +1 -0
  148. package/payload/server/public/assets/public-B61xcmAr.js +1 -0
  149. package/payload/server/public/assets/{rotate-ccw-Cqp4oqHV.js → rotate-ccw-7_3ol0Z4.js} +1 -1
  150. package/payload/server/public/assets/{tasks-bQKOhMga.js → tasks-BY9ajKXf.js} +1 -1
  151. package/payload/server/public/assets/{time-entry-format-BIL4ZaDK.js → time-entry-format-DmNhIJnM.js} +1 -1
  152. package/payload/server/public/assets/useCopyFeedback-C5-GOl5l.js +1 -0
  153. package/payload/server/public/assets/useSelectionMode-UOUVnP9B.js +1 -0
  154. package/payload/server/public/assets/{useSubAccountSwitcher-CVHKTSst.css → useSubAccountSwitcher-DgM1ergs.css} +1 -1
  155. package/payload/server/public/assets/useVoiceRecorder-BAP3yGxs.js +2 -0
  156. package/payload/server/public/browser.html +5 -5
  157. package/payload/server/public/calendar.html +6 -6
  158. package/payload/server/public/chat.html +12 -12
  159. package/payload/server/public/data.html +10 -10
  160. package/payload/server/public/graph.html +11 -11
  161. package/payload/server/public/index.html +13 -13
  162. package/payload/server/public/operator.html +14 -14
  163. package/payload/server/public/public.html +12 -12
  164. package/payload/server/public/tasks.html +5 -5
  165. package/payload/server/server.js +349 -171
  166. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts +0 -8
  167. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts.map +0 -1
  168. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js +0 -71
  169. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js.map +0 -1
  170. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/package.json +0 -7
  171. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts +0 -51
  172. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts.map +0 -1
  173. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js +0 -196
  174. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js.map +0 -1
  175. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/package.json +0 -7
  176. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.d.ts +0 -3
  177. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.d.ts.map +0 -1
  178. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.js +0 -58
  179. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.js.map +0 -1
  180. package/payload/premium-plugins/writer-craft/mcp/src/index.ts +0 -457
  181. package/payload/premium-plugins/writer-craft/mcp/src/lib/neo4j.ts +0 -56
  182. package/payload/premium-plugins/writer-craft/mcp/src/lib/voice-corpus.ts +0 -154
  183. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-distil-profile.ts +0 -833
  184. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-ingest-session-text.ts +0 -153
  185. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-record-feedback.ts +0 -148
  186. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-retrieve-conditioning.ts +0 -270
  187. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-tag-content.ts +0 -181
  188. package/payload/premium-plugins/writer-craft/mcp/tsconfig.json +0 -8
  189. package/payload/server/public/assets/AdminShell-DSQrvZXq.js +0 -2
  190. package/payload/server/public/assets/admin-Ch4n-G0j.js +0 -1
  191. package/payload/server/public/assets/browser-B2AIxiuk.js +0 -1
  192. package/payload/server/public/assets/calendar-BvItH3B0.js +0 -1
  193. package/payload/server/public/assets/chat-eQFMaX9y.js +0 -1
  194. package/payload/server/public/assets/chevron-left-D2AnCEyE.js +0 -1
  195. package/payload/server/public/assets/data-BzOmbHoe.js +0 -1
  196. package/payload/server/public/assets/file-download-CK9j_Jx2.js +0 -1
  197. package/payload/server/public/assets/graph-labels-CwEtvIRV.js +0 -1
  198. package/payload/server/public/assets/maximize-2-CuzEom3K.js +0 -1
  199. package/payload/server/public/assets/operator-DlboYPPu.js +0 -1
  200. package/payload/server/public/assets/page-BuWH5gNK.js +0 -1
  201. package/payload/server/public/assets/page-Co9E8U5x.js +0 -32
  202. package/payload/server/public/assets/public-DtFpPMTG.js +0 -1
  203. package/payload/server/public/assets/useCopyFeedback-rB8QuqyH.js +0 -1
  204. package/payload/server/public/assets/useVoiceRecorder-Ctny8qWx.js +0 -2
  205. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/lib/mcp-spawn-tee/index.js +0 -0
  206. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/lib/mcp-spawn-tee/package.json +0 -0
  207. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.d.ts +0 -0
  208. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.d.ts.map +0 -0
  209. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.d.ts.map +0 -0
  210. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.d.ts +0 -0
  211. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.d.ts.map +0 -0
  212. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.js +0 -0
  213. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.js.map +0 -0
  214. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.d.ts +0 -0
  215. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.d.ts.map +0 -0
  216. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.js +0 -0
  217. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.js.map +0 -0
  218. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.d.ts +0 -0
  219. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.d.ts.map +0 -0
  220. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.js +0 -0
  221. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.js.map +0 -0
  222. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.d.ts +0 -0
  223. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.d.ts.map +0 -0
  224. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.d.ts +0 -0
  225. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.d.ts.map +0 -0
  226. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.js +0 -0
  227. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.js.map +0 -0
  228. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.d.ts +0 -0
  229. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.d.ts.map +0 -0
  230. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.js +0 -0
  231. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.js.map +0 -0
  232. /package/payload/server/public/assets/{useSubAccountSwitcher-CHEt_m6q.js → useSubAccountSwitcher-DF6bohQA.js} +0 -0
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Outbound attachment resolver for outlook-mail-reply. Mirrors the email
3
+ * plugin's account-scope check (realpath under the account directory, regular
4
+ * file, size cap), then classifies each file by how it must reach the reply
5
+ * draft:
6
+ *
7
+ * - `inline` — at or under Graph's ~3 MB fileAttachment limit; sent as a
8
+ * single base64 `POST /messages/{id}/attachments`.
9
+ * - `session` — above the inline limit and up to the 25 MB account cap; sent
10
+ * through a Graph upload session (see `upload-session.ts`).
11
+ *
12
+ * The account cap (25 MB) matches the email plugin's outbound cap, so an
13
+ * Outlook reply and the equivalent IMAP reply carry the same maximum.
14
+ *
15
+ * Resolution reads no bytes — it returns per-file metadata (path, size, mode)
16
+ * so `mail-reply` can choose the path. Path validation still happens before any
17
+ * Graph write, so a bad path leaves no orphan draft; bytes are read at send
18
+ * time by `toInlineAttachment` (inline) or the upload session (session).
19
+ */
20
+ import { readFileSync, realpathSync, statSync } from "node:fs";
21
+ import { basename, extname, join } from "node:path";
22
+ /** Graph fileAttachment inline limit for POST /messages/{id}/attachments. */
23
+ export const OUTLOOK_ATTACHMENT_INLINE_MAX_BYTES = 3 * 1024 * 1024;
24
+ /** Per-file account cap; parity with the email plugin's outbound cap. */
25
+ export const OUTLOOK_ATTACHMENT_MAX_BYTES = 25 * 1024 * 1024;
26
+ const MIME = {
27
+ ".pdf": "application/pdf",
28
+ ".png": "image/png",
29
+ ".jpg": "image/jpeg",
30
+ ".jpeg": "image/jpeg",
31
+ ".gif": "image/gif",
32
+ ".txt": "text/plain",
33
+ ".csv": "text/csv",
34
+ ".doc": "application/msword",
35
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
36
+ ".xls": "application/vnd.ms-excel",
37
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
38
+ ".zip": "application/zip",
39
+ };
40
+ function contentTypeOf(rp) {
41
+ return MIME[extname(rp).toLowerCase()] ?? "application/octet-stream";
42
+ }
43
+ /** ACCOUNT_DIR (spawn-set) wins; else derive from PLATFORM_ROOT + accountId,
44
+ * matching the email plugin's resolver. Null when neither resolves. */
45
+ export function resolveAccountDir(accountId) {
46
+ const direct = process.env.ACCOUNT_DIR;
47
+ if (direct && direct.trim())
48
+ return direct;
49
+ const platformRoot = process.env.PLATFORM_ROOT;
50
+ if (platformRoot && accountId && !accountId.includes("/") && !accountId.includes("..")) {
51
+ return join(platformRoot, "..", "data", "accounts", accountId);
52
+ }
53
+ return null;
54
+ }
55
+ /**
56
+ * Validate agent-supplied paths and classify each as inline or session. Each
57
+ * path must realpath to a regular file under the account directory and be within
58
+ * the 25 MB account cap. Any violation throws a precise error naming the
59
+ * offending path, so the caller sends nothing rather than a reply that silently
60
+ * drops the file. Absent/empty input returns [] (a text-only reply).
61
+ */
62
+ export function resolveOutboundAttachments(accountId, paths) {
63
+ if (!paths || paths.length === 0)
64
+ return [];
65
+ const dir = resolveAccountDir(accountId);
66
+ if (!dir) {
67
+ throw new Error("Cannot attach files: no account context (ACCOUNT_DIR unset and PLATFORM_ROOT+ACCOUNT_ID unavailable) to validate paths against.");
68
+ }
69
+ let accountResolved;
70
+ try {
71
+ accountResolved = realpathSync(dir);
72
+ }
73
+ catch (err) {
74
+ throw new Error(`Cannot attach files: account directory ${dir} is not accessible (${err instanceof Error ? err.message : String(err)}).`);
75
+ }
76
+ const out = [];
77
+ for (const p of paths) {
78
+ let rp;
79
+ try {
80
+ rp = realpathSync(p);
81
+ }
82
+ catch (err) {
83
+ if (err.code === "ENOENT") {
84
+ throw new Error(`Attachment not found: ${p}`);
85
+ }
86
+ throw new Error(`Cannot read attachment ${p}: ${err instanceof Error ? err.message : String(err)}`);
87
+ }
88
+ if (!rp.startsWith(accountResolved + "/")) {
89
+ throw new Error(`Attachment ${p} is outside the account directory and cannot be sent.`);
90
+ }
91
+ const st = statSync(rp);
92
+ if (!st.isFile()) {
93
+ throw new Error(`Attachment ${p} is not a regular file.`);
94
+ }
95
+ if (st.size > OUTLOOK_ATTACHMENT_MAX_BYTES) {
96
+ throw new Error(`Attachment ${basename(rp)} is ${(st.size / 1024 / 1024).toFixed(1)} MB; Outlook reply attachments are capped at 25 MB per file.`);
97
+ }
98
+ out.push({
99
+ path: rp,
100
+ name: basename(rp),
101
+ contentType: contentTypeOf(rp),
102
+ size: st.size,
103
+ mode: st.size > OUTLOOK_ATTACHMENT_INLINE_MAX_BYTES ? "session" : "inline",
104
+ });
105
+ }
106
+ return out;
107
+ }
108
+ /**
109
+ * Read an inline attachment's bytes and base64-encode them into the Graph
110
+ * fileAttachment shape a reply draft accepts. Only called for `mode: "inline"`
111
+ * files; larger files go through the upload session instead.
112
+ */
113
+ export function toInlineAttachment(att) {
114
+ return {
115
+ "@odata.type": "#microsoft.graph.fileAttachment",
116
+ name: att.name,
117
+ contentType: att.contentType,
118
+ contentBytes: readFileSync(att.path).toString("base64"),
119
+ };
120
+ }
121
+ /** The " with N attachment(s): a, b" suffix for a reply success message. */
122
+ export function attachNote(names) {
123
+ if (names.length === 0)
124
+ return "";
125
+ return ` with ${names.length} attachment(s): ${names.join(", ")}`;
126
+ }
127
+ //# sourceMappingURL=outbound-attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound-attachments.js","sourceRoot":"","sources":["../../src/lib/outbound-attachments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Graph upload-session path for reply attachments above the inline limit.
3
+ *
4
+ * Two steps, distinct in auth and host:
5
+ * 1. `POST /me/messages/{draftId}/attachments/createUploadSession` — through
6
+ * the Graph SDK (auth handled by `postGraph`), returns a pre-authenticated
7
+ * `uploadUrl`.
8
+ * 2. Chunked `PUT` to that `uploadUrl` — a plain fetch to a non-Graph host
9
+ * with NO bearer token (the URL itself is the credential). Each chunk is a
10
+ * multiple of 320 KiB except the last, per Graph's contract, and carries a
11
+ * `Content-Range` header. Graph returns 200 for an intermediate chunk and
12
+ * 201 for the final one.
13
+ *
14
+ * Every non-2xx PUT throws with the response status and body preserved, so a
15
+ * session that stalls mid-chunk is diagnosable rather than silent.
16
+ */
17
+ import type { GraphClientConfig } from "./graph-client.js";
18
+ import type { OutboundAttachment } from "./outbound-attachments.js";
19
+ /** Chunk size for the upload PUT: 3.125 MiB, a whole multiple of 320 KiB as
20
+ * Graph requires for every chunk except the final remainder. */
21
+ export declare const UPLOAD_CHUNK_BYTES: number;
22
+ /**
23
+ * Upload one large attachment to an existing reply draft via a Graph upload
24
+ * session. Returns the number of chunks PUT (for observability). The draft must
25
+ * already exist; the attachment must have passed `resolveOutboundAttachments`.
26
+ */
27
+ export declare function uploadAttachmentSession(config: GraphClientConfig, draftId: string, att: OutboundAttachment): Promise<number>;
28
+ //# sourceMappingURL=upload-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-session.d.ts","sourceRoot":"","sources":["../../src/lib/upload-session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;iEACiE;AACjE,eAAO,MAAM,kBAAkB,QAAkB,CAAC;AAMlD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,MAAM,CAAC,CAoCjB"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Graph upload-session path for reply attachments above the inline limit.
3
+ *
4
+ * Two steps, distinct in auth and host:
5
+ * 1. `POST /me/messages/{draftId}/attachments/createUploadSession` — through
6
+ * the Graph SDK (auth handled by `postGraph`), returns a pre-authenticated
7
+ * `uploadUrl`.
8
+ * 2. Chunked `PUT` to that `uploadUrl` — a plain fetch to a non-Graph host
9
+ * with NO bearer token (the URL itself is the credential). Each chunk is a
10
+ * multiple of 320 KiB except the last, per Graph's contract, and carries a
11
+ * `Content-Range` header. Graph returns 200 for an intermediate chunk and
12
+ * 201 for the final one.
13
+ *
14
+ * Every non-2xx PUT throws with the response status and body preserved, so a
15
+ * session that stalls mid-chunk is diagnosable rather than silent.
16
+ */
17
+ import { readFileSync } from "node:fs";
18
+ import { postGraph } from "./graph-client.js";
19
+ /** Chunk size for the upload PUT: 3.125 MiB, a whole multiple of 320 KiB as
20
+ * Graph requires for every chunk except the final remainder. */
21
+ export const UPLOAD_CHUNK_BYTES = 320 * 1024 * 10;
22
+ /**
23
+ * Upload one large attachment to an existing reply draft via a Graph upload
24
+ * session. Returns the number of chunks PUT (for observability). The draft must
25
+ * already exist; the attachment must have passed `resolveOutboundAttachments`.
26
+ */
27
+ export async function uploadAttachmentSession(config, draftId, att) {
28
+ const { json } = await postGraph(config, `/me/messages/${encodeURIComponent(draftId)}/attachments/createUploadSession`, { AttachmentItem: { attachmentType: "file", name: att.name, size: att.size, contentType: att.contentType } }, { tool: "mail-reply" });
29
+ const uploadUrl = json?.uploadUrl;
30
+ if (!uploadUrl) {
31
+ throw new Error(`outlook-mail-reply: createUploadSession for ${att.name} returned no uploadUrl.`);
32
+ }
33
+ const buf = readFileSync(att.path);
34
+ const total = buf.length;
35
+ let start = 0;
36
+ let chunks = 0;
37
+ while (start < total) {
38
+ const end = Math.min(start + UPLOAD_CHUNK_BYTES, total);
39
+ const slice = buf.subarray(start, end);
40
+ const res = await fetch(uploadUrl, {
41
+ method: "PUT",
42
+ headers: { "Content-Range": `bytes ${start}-${end - 1}/${total}` },
43
+ body: slice,
44
+ });
45
+ if (!res.ok) {
46
+ const text = await res.text().catch(() => "");
47
+ throw new Error(`outlook-mail-reply: upload session PUT ${res.status} for ${att.name} (bytes ${start}-${end - 1}/${total}): ${text.slice(0, 300) || "no response body"}`);
48
+ }
49
+ chunks += 1;
50
+ start = end;
51
+ }
52
+ return chunks;
53
+ }
54
+ //# sourceMappingURL=upload-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-session.js","sourceRoot":"","sources":["../../src/lib/upload-session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C;iEACiE;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;AAMlD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAyB,EACzB,OAAe,EACf,GAAuB;IAEvB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAC9B,MAAM,EACN,gBAAgB,kBAAkB,CAAC,OAAO,CAAC,kCAAkC,EAC7E,EAAE,cAAc,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,EAC5G,EAAE,IAAI,EAAE,YAAY,EAAE,CACvB,CAAC;IACF,MAAM,SAAS,GAAI,IAA6B,EAAE,SAAS,CAAC;IAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,+CAA+C,GAAG,CAAC,IAAI,yBAAyB,CACjF,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,KAAK,GAAG,KAAK,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,kBAAkB,EAAE,KAAK,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YACjC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,eAAe,EAAE,SAAS,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,EAAE,EAAE;YAClE,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,0CAA0C,GAAG,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAI,WAAW,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,kBAAkB,EAAE,CACzJ,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,CAAC,CAAC;QACZ,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ export interface DraftEditArgs {
3
+ draftId: string;
4
+ to?: string[];
5
+ cc?: string[];
6
+ bcc?: string[];
7
+ subject?: string;
8
+ body?: string;
9
+ isHtml?: boolean;
10
+ }
11
+ /**
12
+ * Update an existing draft in place via PATCH /me/messages/{draftId}. Graph
13
+ * drafts are mutable, so no delete-and-reappend. Only the supplied fields are
14
+ * patched; at least one editable field is required. Graph rejects a PATCH on a
15
+ * sent (non-draft) message — that error is surfaced to the caller unchanged.
16
+ */
17
+ export declare function runDraftEdit(config: GraphClientConfig, args: DraftEditArgs): Promise<{
18
+ draftId: string;
19
+ updated: true;
20
+ }>;
21
+ //# sourceMappingURL=draft-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-edit.d.ts","sourceRoot":"","sources":["../../src/tools/draft-edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,CAAC,CAyB7C"}
@@ -0,0 +1,38 @@
1
+ import { patchGraph } from "../lib/graph-client.js";
2
+ import { log } from "../lib/log.js";
3
+ function recip(list) {
4
+ return list.map((address) => ({ emailAddress: { address } }));
5
+ }
6
+ /**
7
+ * Update an existing draft in place via PATCH /me/messages/{draftId}. Graph
8
+ * drafts are mutable, so no delete-and-reappend. Only the supplied fields are
9
+ * patched; at least one editable field is required. Graph rejects a PATCH on a
10
+ * sent (non-draft) message — that error is surfaced to the caller unchanged.
11
+ */
12
+ export async function runDraftEdit(config, args) {
13
+ const patch = {};
14
+ if (args.subject !== undefined)
15
+ patch.subject = args.subject;
16
+ if (args.body !== undefined) {
17
+ patch.body = { contentType: args.isHtml ? "HTML" : "Text", content: args.body };
18
+ }
19
+ if (args.to !== undefined)
20
+ patch.toRecipients = recip(args.to);
21
+ if (args.cc !== undefined)
22
+ patch.ccRecipients = recip(args.cc);
23
+ if (args.bcc !== undefined)
24
+ patch.bccRecipients = recip(args.bcc);
25
+ if (Object.keys(patch).length === 0) {
26
+ throw new Error("outlook-draft-edit: pass at least one field to change (to, cc, bcc, subject, or body).");
27
+ }
28
+ await patchGraph(config, `/me/messages/${encodeURIComponent(args.draftId)}`, patch, { tool: "draft-edit" });
29
+ log({
30
+ event: "draft-edit",
31
+ op: "draft-edit",
32
+ account: config.accountId,
33
+ id: args.draftId,
34
+ fields: Object.keys(patch).join(","),
35
+ });
36
+ return { draftId: args.draftId, updated: true };
37
+ }
38
+ //# sourceMappingURL=draft-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-edit.js","sourceRoot":"","sources":["../../src/tools/draft-edit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAYpC,SAAS,KAAK,CAAC,IAAc;IAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAyB,EACzB,IAAmB;IAEnB,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAClF,CAAC;IACD,IAAI,IAAI,CAAC,EAAE,KAAK,SAAS;QAAE,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/D,IAAI,IAAI,CAAC,EAAE,KAAK,SAAS;QAAE,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/D,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS;QAAE,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAElE,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,CAAC,MAAM,EAAE,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;IAC5G,GAAG,CAAC;QACF,KAAK,EAAE,YAAY;QACnB,EAAE,EAAE,YAAY;QAChB,OAAO,EAAE,MAAM,CAAC,SAAS;QACzB,EAAE,EAAE,IAAI,CAAC,OAAO;QAChB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;KACrC,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ /**
3
+ * Move each named message to Deleted Items (POST /me/messages/{id}/move with
4
+ * destinationId "deleteditems"). Recoverable — never hard-deletes, never
5
+ * expunges. A message already gone (Graph 404) is counted not-moved without
6
+ * failing the rest; any other Graph error aborts the batch.
7
+ */
8
+ export declare function runMailDelete(config: GraphClientConfig, args: {
9
+ ids: string[];
10
+ }): Promise<{
11
+ moved: string[];
12
+ notMoved: string[];
13
+ }>;
14
+ //# sourceMappingURL=mail-delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-delete.d.ts","sourceRoot":"","sources":["../../src/tools/mail-delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAgClD"}
@@ -0,0 +1,39 @@
1
+ import { postGraph } from "../lib/graph-client.js";
2
+ import { log } from "../lib/log.js";
3
+ /**
4
+ * Move each named message to Deleted Items (POST /me/messages/{id}/move with
5
+ * destinationId "deleteditems"). Recoverable — never hard-deletes, never
6
+ * expunges. A message already gone (Graph 404) is counted not-moved without
7
+ * failing the rest; any other Graph error aborts the batch.
8
+ */
9
+ export async function runMailDelete(config, args) {
10
+ const moved = [];
11
+ const notMoved = [];
12
+ for (const id of args.ids) {
13
+ try {
14
+ await postGraph(config, `/me/messages/${encodeURIComponent(id)}/move`, { destinationId: "deleteditems" }, { tool: "mail-delete" });
15
+ moved.push(id);
16
+ }
17
+ catch (err) {
18
+ // Key the "already gone" decision off the structured status code the
19
+ // writeGraph error carries (err.statusCode), never the prose message —
20
+ // matching graph-client's classification doctrine. A 404 means the id was
21
+ // already gone; any other status aborts the batch.
22
+ if (err.statusCode === 404) {
23
+ notMoved.push(id);
24
+ }
25
+ else {
26
+ throw err;
27
+ }
28
+ }
29
+ }
30
+ log({
31
+ event: "mail-delete",
32
+ op: "delete",
33
+ account: config.accountId,
34
+ moved: moved.length,
35
+ notMoved: notMoved.length,
36
+ });
37
+ return { moved, notMoved };
38
+ }
39
+ //# sourceMappingURL=mail-delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-delete.js","sourceRoot":"","sources":["../../src/tools/mail-delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAyB,EACzB,IAAuB;IAEvB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,SAAS,CACb,MAAM,EACN,gBAAgB,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAC7C,EAAE,aAAa,EAAE,cAAc,EAAE,EACjC,EAAE,IAAI,EAAE,aAAa,EAAE,CACxB,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,qEAAqE;YACrE,uEAAuE;YACvE,0EAA0E;YAC1E,mDAAmD;YACnD,IAAK,GAA+B,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IACD,GAAG,CAAC;QACF,KAAK,EAAE,aAAa;QACpB,EAAE,EAAE,QAAQ;QACZ,OAAO,EAAE,MAAM,CAAC,SAAS;QACzB,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,QAAQ,EAAE,QAAQ,CAAC,MAAM;KAC1B,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ export interface FetchBodyResult {
3
+ id: string;
4
+ subject: string | null;
5
+ from: string | null;
6
+ to: string[];
7
+ cc: string[];
8
+ receivedDateTime: string;
9
+ conversationId: string | null;
10
+ isRead: boolean;
11
+ contentType: "html" | "text";
12
+ body: string;
13
+ }
14
+ /**
15
+ * Read the COMPLETE body of one message by id. Graph's bodyPreview (returned by
16
+ * outlook-mail-list/-search) is capped near 255 chars; this requests the full
17
+ * `body` and decodes HTML to text. Never falls back to bodyPreview — an empty
18
+ * body is returned as-is (empty), and the logged `bytes` surfaces a shortfall.
19
+ */
20
+ export declare function runMailFetchBody(config: GraphClientConfig, args: {
21
+ messageId: string;
22
+ }): Promise<FetchBodyResult>;
23
+ //# sourceMappingURL=mail-fetch-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-fetch-body.d.ts","sourceRoot":"","sources":["../../src/tools/mail-fetch-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAKhE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAwBD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAC1B,OAAO,CAAC,eAAe,CAAC,CAqC1B"}
@@ -0,0 +1,44 @@
1
+ import { callGraph } from "../lib/graph-client.js";
2
+ import { htmlToText } from "../lib/html-to-text.js";
3
+ import { log } from "../lib/log.js";
4
+ const SELECT = "id,subject,from,toRecipients,ccRecipients,receivedDateTime,conversationId,isRead,body";
5
+ function addrs(list) {
6
+ return (list ?? []).map((r) => r.emailAddress?.address).filter((a) => !!a);
7
+ }
8
+ /**
9
+ * Read the COMPLETE body of one message by id. Graph's bodyPreview (returned by
10
+ * outlook-mail-list/-search) is capped near 255 chars; this requests the full
11
+ * `body` and decodes HTML to text. Never falls back to bodyPreview — an empty
12
+ * body is returned as-is (empty), and the logged `bytes` surfaces a shortfall.
13
+ */
14
+ export async function runMailFetchBody(config, args) {
15
+ const msg = await callGraph(config, async (client) => (await client
16
+ .api(`/me/messages/${encodeURIComponent(args.messageId)}`)
17
+ .select(SELECT)
18
+ .get()), { tool: "mail-fetch-body" });
19
+ const rawType = (msg.body?.contentType ?? "text").toLowerCase();
20
+ const contentType = rawType === "html" ? "html" : "text";
21
+ const raw = msg.body?.content ?? "";
22
+ const body = contentType === "html" ? htmlToText(raw) : raw;
23
+ log({
24
+ event: "mail-fetch-body",
25
+ op: "fetch-body",
26
+ account: config.accountId,
27
+ id: args.messageId,
28
+ bytes: body.length,
29
+ contentType,
30
+ });
31
+ return {
32
+ id: msg.id,
33
+ subject: msg.subject ?? null,
34
+ from: msg.from?.emailAddress?.address ?? null,
35
+ to: addrs(msg.toRecipients),
36
+ cc: addrs(msg.ccRecipients),
37
+ receivedDateTime: msg.receivedDateTime,
38
+ conversationId: msg.conversationId ?? null,
39
+ isRead: msg.isRead ?? false,
40
+ contentType,
41
+ body,
42
+ };
43
+ }
44
+ //# sourceMappingURL=mail-fetch-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-fetch-body.js","sourceRoot":"","sources":["../../src/tools/mail-fetch-body.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AA8BpC,MAAM,MAAM,GACV,uFAAuF,CAAC;AAE1F,SAAS,KAAK,CAAC,IAAgC;IAC7C,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAyB,EACzB,IAA2B;IAE3B,MAAM,GAAG,GAAG,MAAM,SAAS,CACzB,MAAM,EACN,KAAK,EAAE,MAAM,EAAE,EAAE,CACf,CAAC,MAAM,MAAM;SACV,GAAG,CAAC,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;SACzD,MAAM,CAAC,MAAM,CAAC;SACd,GAAG,EAAE,CAAe,EACzB,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAC5B,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAChE,MAAM,WAAW,GAAoB,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1E,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAE5D,GAAG,CAAC;QACF,KAAK,EAAE,iBAAiB;QACxB,EAAE,EAAE,YAAY;QAChB,OAAO,EAAE,MAAM,CAAC,SAAS;QACzB,EAAE,EAAE,IAAI,CAAC,SAAS;QAClB,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;QAC5B,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,IAAI,IAAI;QAC7C,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;QAC3B,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;QAC3B,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,cAAc,EAAE,GAAG,CAAC,cAAc,IAAI,IAAI;QAC1C,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,KAAK;QAC3B,WAAW;QACX,IAAI;KACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ export interface OtpArgs {
3
+ sender: string;
4
+ subjectPattern?: string;
5
+ timeout?: number;
6
+ }
7
+ export interface OtpResult {
8
+ success: boolean;
9
+ code?: string;
10
+ message: string;
11
+ from?: string;
12
+ subject?: string;
13
+ }
14
+ /**
15
+ * Poll the inbox for a one-time code from a specific sender. Lists recent
16
+ * messages, keeps those whose sender matches `sender` (and optional subject
17
+ * regex), reads each candidate's full body via runMailFetchBody, and extracts
18
+ * the code. Scans immediately, then polls every 5 s until `timeout` (default
19
+ * 60 s). The OTP extractor is shared verbatim with the email plugin.
20
+ */
21
+ export declare function runMailOtpExtract(config: GraphClientConfig, args: OtpArgs): Promise<OtpResult>;
22
+ //# sourceMappingURL=mail-otp-extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-otp-extract.d.ts","sourceRoot":"","sources":["../../src/tools/mail-otp-extract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQhE,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmDD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,SAAS,CAAC,CAqDpB"}
@@ -0,0 +1,90 @@
1
+ import { callGraph } from "../lib/graph-client.js";
2
+ import { runMailFetchBody } from "./mail-fetch-body.js";
3
+ import { extractOtpFromText } from "../lib/otp.js";
4
+ import { log } from "../lib/log.js";
5
+ const POLL_MS = 5_000;
6
+ // Only messages received within this window before the tool was called are
7
+ // candidates. Mirrors the email plugin's recency bound so a stale code sitting
8
+ // in the mailbox from an earlier sign-in is never returned in place of the
9
+ // freshly-requested one.
10
+ const RECENCY_WINDOW_MS = 10 * 60 * 1000;
11
+ async function listCandidates(config, sender, subjectRe, sinceMs) {
12
+ const coll = await callGraph(config, async (client) => (await client
13
+ .api("/me/mailFolders/Inbox/messages")
14
+ .top(15)
15
+ .orderby("receivedDateTime DESC")
16
+ .select("id,subject,from,receivedDateTime")
17
+ .get()), { tool: "mail-otp-extract" });
18
+ const dom = sender.toLowerCase();
19
+ return coll.value
20
+ .filter((m) => {
21
+ const t = m.receivedDateTime ? Date.parse(m.receivedDateTime) : NaN;
22
+ return !Number.isNaN(t) && t >= sinceMs;
23
+ })
24
+ .map((m) => ({ id: m.id, subject: m.subject ?? null, from: m.from?.emailAddress?.address ?? null }))
25
+ .filter((c) => (c.from ?? "").toLowerCase().includes(dom))
26
+ .filter((c) => !subjectRe || subjectRe.test(c.subject ?? ""));
27
+ }
28
+ /**
29
+ * Poll the inbox for a one-time code from a specific sender. Lists recent
30
+ * messages, keeps those whose sender matches `sender` (and optional subject
31
+ * regex), reads each candidate's full body via runMailFetchBody, and extracts
32
+ * the code. Scans immediately, then polls every 5 s until `timeout` (default
33
+ * 60 s). The OTP extractor is shared verbatim with the email plugin.
34
+ */
35
+ export async function runMailOtpExtract(config, args) {
36
+ const timeoutMs = (args.timeout ?? 60) * 1000;
37
+ const start = Date.now();
38
+ // Anchor the recency window at the tool-call time so codes that arrive during
39
+ // polling still qualify, while pre-existing stale codes are excluded.
40
+ const sinceMs = start - RECENCY_WINDOW_MS;
41
+ let subjectRe = null;
42
+ if (args.subjectPattern) {
43
+ try {
44
+ subjectRe = new RegExp(args.subjectPattern, "i");
45
+ }
46
+ catch {
47
+ // invalid regex — ignore the filter
48
+ }
49
+ }
50
+ // Holder (not a bare `let`) so the closure's write survives TS control-flow
51
+ // narrowing when read after the loop.
52
+ const state = { noCode: null };
53
+ const scan = async () => {
54
+ for (const c of await listCandidates(config, args.sender, subjectRe, sinceMs)) {
55
+ const full = await runMailFetchBody(config, { messageId: c.id });
56
+ const code = extractOtpFromText(full.body);
57
+ if (code) {
58
+ log({ event: "mail-otp-extract", op: "otp", account: config.accountId, sender: args.sender, found: true });
59
+ return { success: true, code, message: `OTP extracted: ${code}`, from: c.from ?? undefined, subject: c.subject ?? undefined };
60
+ }
61
+ if (!state.noCode)
62
+ state.noCode = { from: c.from ?? "", subject: c.subject ?? "" };
63
+ }
64
+ return null;
65
+ };
66
+ const first = await scan();
67
+ if (first)
68
+ return first;
69
+ while (Date.now() - start < timeoutMs) {
70
+ await new Promise((r) => setTimeout(r, POLL_MS));
71
+ const hit = await scan();
72
+ if (hit)
73
+ return hit;
74
+ }
75
+ const elapsed = Math.round((Date.now() - start) / 1000);
76
+ log({ event: "mail-otp-extract", op: "otp", account: config.accountId, sender: args.sender, found: false, elapsedSec: elapsed });
77
+ if (state.noCode) {
78
+ return {
79
+ success: false,
80
+ message: `Found email from ${state.noCode.from} ("${state.noCode.subject}") but could not extract a verification code within ${elapsed}s.`,
81
+ from: state.noCode.from,
82
+ subject: state.noCode.subject,
83
+ };
84
+ }
85
+ return {
86
+ success: false,
87
+ message: `No verification email from *${args.sender}* received within ${elapsed}s. Check the sender is correct, or ask the service to resend the code.`,
88
+ };
89
+ }
90
+ //# sourceMappingURL=mail-otp-extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-otp-extract.js","sourceRoot":"","sources":["../../src/tools/mail-otp-extract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,MAAM,OAAO,GAAG,KAAK,CAAC;AAetB,2EAA2E;AAC3E,+EAA+E;AAC/E,2EAA2E;AAC3E,yBAAyB;AACzB,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAiBzC,KAAK,UAAU,cAAc,CAC3B,MAAyB,EACzB,MAAc,EACd,SAAwB,EACxB,OAAe;IAEf,MAAM,IAAI,GAAG,MAAM,SAAS,CAC1B,MAAM,EACN,KAAK,EAAE,MAAM,EAAE,EAAE,CACf,CAAC,MAAM,MAAM;SACV,GAAG,CAAC,gCAAgC,CAAC;SACrC,GAAG,CAAC,EAAE,CAAC;SACP,OAAO,CAAC,uBAAuB,CAAC;SAChC,MAAM,CAAC,kCAAkC,CAAC;SAC1C,GAAG,EAAE,CAAY,EACtB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAC7B,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,IAAI,CAAC,KAAK;SACd,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,MAAM,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;IAC1C,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC;SACnG,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SACzD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAyB,EACzB,IAAa;IAEb,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,8EAA8E;IAC9E,sEAAsE;IACtE,MAAM,OAAO,GAAG,KAAK,GAAG,iBAAiB,CAAC;IAC1C,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,SAAS,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,sCAAsC;IACtC,MAAM,KAAK,GAAyD,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACrF,MAAM,IAAI,GAAG,KAAK,IAA+B,EAAE;QACjD,KAAK,MAAM,CAAC,IAAI,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjE,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,IAAI,EAAE,CAAC;gBACT,GAAG,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3G,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC;YAChI,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,MAAM;gBAAE,KAAK,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QACrF,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;IAC3B,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC;QACzB,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;IACtB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACxD,GAAG,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IACjI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,oBAAoB,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,uDAAuD,OAAO,IAAI;YAC1I,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI;YACvB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;SAC9B,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,+BAA+B,IAAI,CAAC,MAAM,qBAAqB,OAAO,wEAAwE;KACxJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ export interface ReplyArgs {
3
+ messageId: string;
4
+ body: string;
5
+ replyAll?: boolean;
6
+ cc?: string[];
7
+ bcc?: string[];
8
+ attachments?: string[];
9
+ }
10
+ export interface ReplyResult {
11
+ conversationId: string | null;
12
+ to: string[];
13
+ replyAll: boolean;
14
+ attachments: string[];
15
+ }
16
+ /**
17
+ * Reply to a message in-thread via Microsoft Graph. Threading is native: the
18
+ * createReply/createReplyAll draft carries the original conversationId. The
19
+ * body is passed as `comment` (Graph prepends it above the quoted original).
20
+ * cc/bcc are added by PATCHing the draft; attachments are added per-file, then
21
+ * the draft is sent. Attachment paths are validated BEFORE any Graph write so a
22
+ * bad path leaves no orphan draft; a file at or under the inline limit is added
23
+ * as one base64 fileAttachment POST, a larger file (up to the 25 MB account cap)
24
+ * streams through a Graph upload session.
25
+ */
26
+ export declare function runMailReply(config: GraphClientConfig, args: ReplyArgs): Promise<ReplyResult>;
27
+ //# sourceMappingURL=mail-reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-reply.d.ts","sourceRoot":"","sources":["../../src/tools/mail-reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAMhE,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAmBD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,WAAW,CAAC,CAkEtB"}