@rubytech/create-maxy-code 0.1.414 → 0.1.417

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 (218) hide show
  1. package/dist/__tests__/outlook-client-id-env.test.js +46 -0
  2. package/dist/index.js +31 -0
  3. package/dist/port-resolution.js +8 -1
  4. package/package.json +1 -1
  5. package/payload/platform/config/brand.json +1 -0
  6. package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.d.ts +2 -0
  7. package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.d.ts.map +1 -0
  8. package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.js +81 -0
  9. package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.js.map +1 -0
  10. package/payload/platform/lib/account-enumeration/dist/index.d.ts +17 -0
  11. package/payload/platform/lib/account-enumeration/dist/index.d.ts.map +1 -1
  12. package/payload/platform/lib/account-enumeration/dist/index.js +46 -9
  13. package/payload/platform/lib/account-enumeration/dist/index.js.map +1 -1
  14. package/payload/platform/lib/account-enumeration/src/__tests__/is-provisioned.test.ts +86 -0
  15. package/payload/platform/lib/account-enumeration/src/index.ts +45 -9
  16. package/payload/platform/lib/account-scope/dist/index.d.ts +14 -5
  17. package/payload/platform/lib/account-scope/dist/index.d.ts.map +1 -1
  18. package/payload/platform/lib/account-scope/dist/index.js +14 -5
  19. package/payload/platform/lib/account-scope/dist/index.js.map +1 -1
  20. package/payload/platform/lib/account-scope/src/index.ts +22 -5
  21. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +43 -10
  22. package/payload/platform/plugins/docs/references/outlook-guide.md +42 -9
  23. package/payload/platform/plugins/email/references/email-reference.md +1 -1
  24. package/payload/platform/plugins/filesystem/PLUGIN.md +1 -1
  25. package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/scope.test.js +16 -2
  26. package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/scope.test.js.map +1 -1
  27. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.d.ts +1 -1
  28. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.d.ts.map +1 -1
  29. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.js +8 -3
  30. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.js.map +1 -1
  31. package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/handlers.test.js +2 -2
  32. package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/handlers.test.js.map +1 -1
  33. package/payload/platform/plugins/memory/PLUGIN.md +2 -2
  34. package/payload/platform/plugins/memory/mcp/dist/index-testable.d.ts.map +1 -1
  35. package/payload/platform/plugins/memory/mcp/dist/index-testable.js +14 -5
  36. package/payload/platform/plugins/memory/mcp/dist/index-testable.js.map +1 -1
  37. package/payload/platform/plugins/memory/mcp/dist/index.js +6 -2
  38. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  39. package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.d.ts +29 -0
  40. package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.d.ts.map +1 -0
  41. package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.js +44 -0
  42. package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.js.map +1 -0
  43. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.d.ts +2 -0
  44. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.d.ts.map +1 -0
  45. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.js +22 -0
  46. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.js.map +1 -0
  47. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.d.ts +2 -0
  48. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.d.ts.map +1 -0
  49. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.js +204 -0
  50. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.js.map +1 -0
  51. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.d.ts +2 -0
  52. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.d.ts.map +1 -0
  53. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.js +78 -0
  54. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.js.map +1 -0
  55. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-tool-account.test.js +2 -2
  56. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-tool-account.test.js.map +1 -1
  57. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts +0 -5
  58. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
  59. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +2 -12
  60. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  61. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts +17 -0
  62. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
  63. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +137 -6
  64. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  65. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  66. package/payload/platform/plugins/outlook/PLUGIN.md +40 -7
  67. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.d.ts +2 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.d.ts.map +1 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js +137 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js.map +1 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.d.ts +2 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.d.ts.map +1 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js +186 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js.map +1 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.d.ts +2 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.d.ts.map +1 -0
  77. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js +110 -0
  78. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js.map +1 -0
  79. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.d.ts +2 -0
  80. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.d.ts.map +1 -0
  81. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.js +108 -0
  82. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.js.map +1 -0
  83. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js +13 -0
  84. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js.map +1 -1
  85. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.d.ts +2 -0
  86. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.d.ts.map +1 -0
  87. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.js +32 -0
  88. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.js.map +1 -0
  89. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.d.ts +2 -0
  90. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.d.ts.map +1 -0
  91. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.js +67 -0
  92. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.js.map +1 -0
  93. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js +7 -5
  94. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js.map +1 -1
  95. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.d.ts +2 -0
  96. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.d.ts.map +1 -0
  97. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.js +141 -0
  98. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.js.map +1 -0
  99. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts +69 -0
  100. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts.map +1 -0
  101. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js +129 -0
  102. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js.map +1 -0
  103. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.d.ts +39 -0
  104. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.d.ts.map +1 -0
  105. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.js +101 -0
  106. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.js.map +1 -0
  107. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.d.ts.map +1 -1
  108. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js +3 -2
  109. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js.map +1 -1
  110. package/payload/platform/plugins/outlook/mcp/dist/index.js +187 -5
  111. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  112. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +34 -1
  113. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -1
  114. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +96 -7
  115. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
  116. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +31 -0
  117. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -0
  118. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +30 -0
  119. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -0
  120. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts +41 -17
  121. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts.map +1 -1
  122. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js +87 -28
  123. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js.map +1 -1
  124. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.d.ts +17 -0
  125. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.d.ts.map +1 -0
  126. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.js +38 -0
  127. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.js.map +1 -0
  128. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts +29 -0
  129. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts.map +1 -0
  130. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js +50 -0
  131. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js.map +1 -0
  132. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.d.ts +34 -0
  133. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.d.ts.map +1 -0
  134. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.js +46 -0
  135. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.js.map +1 -0
  136. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.d.ts +15 -0
  137. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.d.ts.map +1 -0
  138. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.js +27 -0
  139. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.js.map +1 -0
  140. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.d.ts +11 -0
  141. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.d.ts.map +1 -0
  142. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.js +20 -0
  143. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.js.map +1 -0
  144. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts +17 -0
  145. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts.map +1 -0
  146. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js +26 -0
  147. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js.map +1 -0
  148. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +11 -0
  149. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -0
  150. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +26 -0
  151. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -0
  152. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts +14 -0
  153. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -0
  154. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +26 -0
  155. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -0
  156. package/payload/platform/plugins/outlook/mcp/scripts/verify-doc-impl.sh +2 -2
  157. package/payload/platform/plugins/outlook/references/auth.md +51 -54
  158. package/payload/platform/plugins/outlook/references/graph-surfaces.md +97 -4
  159. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +34 -9
  160. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  161. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +9 -0
  162. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  163. package/payload/platform/services/claude-session-manager/dist/config.d.ts +18 -0
  164. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  165. package/payload/platform/services/claude-session-manager/dist/config.js +16 -0
  166. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  167. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  168. package/payload/platform/services/claude-session-manager/dist/http-server.js +34 -10
  169. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  170. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  171. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +7 -2
  172. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  173. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +9 -0
  174. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  175. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +9 -0
  176. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  177. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +5 -5
  178. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  179. package/payload/platform/services/whatsapp-channel/dist/notification.js +6 -5
  180. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  181. package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
  182. package/payload/platform/services/whatsapp-channel/dist/server.js +11 -11
  183. package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
  184. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  185. package/payload/server/public/assets/{AdminLoginScreens-CYPTMmTk.js → AdminLoginScreens-CBTx7ZPK.js} +1 -1
  186. package/payload/server/public/assets/AdminShell-DPHUeXea.js +2 -0
  187. package/payload/server/public/assets/{Checkbox-B0pbYJDQ.js → Checkbox-BHTxekRB.js} +1 -1
  188. package/payload/server/public/assets/{Transcript-CYaAPBFX.js → Transcript-5kLbBInN.js} +1 -1
  189. package/payload/server/public/assets/{admin-BKDMSRto.js → admin-BWCLE32N.js} +1 -1
  190. package/payload/server/public/assets/{browser-CxeMDDZA.js → browser-CRvCPsvV.js} +1 -1
  191. package/payload/server/public/assets/{calendar-DiIiTY9-.js → calendar-BI-kd-QP.js} +1 -1
  192. package/payload/server/public/assets/chat-DFy8hb1y.js +1 -0
  193. package/payload/server/public/assets/chevron-left-Bggm5B5U.js +1 -0
  194. package/payload/server/public/assets/data-HvZ69Ya1.js +1 -0
  195. package/payload/server/public/assets/{graph-DC3dwnMZ.js → graph-BFSyW_5i.js} +1 -1
  196. package/payload/server/public/assets/{graph-labels-Csnovm_c.js → graph-labels-DEjD_qJh.js} +1 -1
  197. package/payload/server/public/assets/{maximize-2-WRUJsg5n.js → maximize-2-BcMJNeCB.js} +1 -1
  198. package/payload/server/public/assets/{operator-BpzeHTAw.js → operator-Dtvm9ero.js} +1 -1
  199. package/payload/server/public/assets/{page-8jJOxx6y.js → page-C_pm3hl3.js} +1 -1
  200. package/payload/server/public/assets/{page-IQDLdebG.js → page-TXi9dmaB.js} +1 -1
  201. package/payload/server/public/assets/{public-Dqg7jwjq.js → public-DBx3U0r8.js} +1 -1
  202. package/payload/server/public/assets/{rotate-ccw-BayMWwfc.js → rotate-ccw-8ti3QkeY.js} +1 -1
  203. package/payload/server/public/assets/useSubAccountSwitcher-BUvlETHN.css +1 -0
  204. package/payload/server/public/assets/{useSubAccountSwitcher-C9aLg8yI.js → useSubAccountSwitcher-Bc5dOBdI.js} +1 -1
  205. package/payload/server/public/browser.html +4 -4
  206. package/payload/server/public/calendar.html +5 -5
  207. package/payload/server/public/chat.html +9 -9
  208. package/payload/server/public/data.html +8 -8
  209. package/payload/server/public/graph.html +9 -9
  210. package/payload/server/public/index.html +11 -11
  211. package/payload/server/public/operator.html +11 -11
  212. package/payload/server/public/public.html +9 -9
  213. package/payload/server/server.js +13 -31
  214. package/payload/server/public/assets/AdminShell-CZH_EZIy.js +0 -2
  215. package/payload/server/public/assets/chat-C56Oqvt1.js +0 -1
  216. package/payload/server/public/assets/chevron-left-Da-iZGi_.js +0 -1
  217. package/payload/server/public/assets/data-ZUdT44Ba.js +0 -1
  218. package/payload/server/public/assets/useSubAccountSwitcher-CRZfyJXR.css +0 -1
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Build a Microsoft Graph message resource from the tool input shape shared by
3
+ * outlook-mail-send and outlook-draft. Graph stores one body with a single
4
+ * contentType, so `isHtml` chooses HTML vs Text for the whole message.
5
+ */
6
+ function toRecipients(addrs) {
7
+ return (addrs ?? [])
8
+ .map((a) => a.trim())
9
+ .filter((a) => a.length > 0)
10
+ .map((address) => ({ emailAddress: { address } }));
11
+ }
12
+ export function buildMessage(input) {
13
+ const to = toRecipients(input.to);
14
+ if (to.length === 0) {
15
+ throw new Error("outlook: at least one 'to' recipient is required.");
16
+ }
17
+ const cc = toRecipients(input.cc);
18
+ const bcc = toRecipients(input.bcc);
19
+ const message = {
20
+ subject: input.subject,
21
+ body: { contentType: input.isHtml ? "HTML" : "Text", content: input.body },
22
+ toRecipients: to,
23
+ };
24
+ if (cc.length > 0)
25
+ message.ccRecipients = cc;
26
+ if (bcc.length > 0)
27
+ message.bccRecipients = bcc;
28
+ return message;
29
+ }
30
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/lib/message.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuBH,SAAS,YAAY,CAAC,KAA2B;IAC/C,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAmB;IAC9C,MAAM,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,OAAO,GAAiB;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE;QAC1E,YAAY,EAAE,EAAE;KACjB,CAAC;IACF,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,YAAY,GAAG,EAAE,CAAC;IAC7C,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,aAAa,GAAG,GAAG,CAAC;IAChD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1,26 +1,50 @@
1
+ import type { PendingStore } from "../auth/pending-store.js";
1
2
  import type { TokenStore } from "../auth/token-store.js";
2
- export interface AccountRegisterArgs {
3
- accountId: string;
4
- clientId: string;
5
- tenantId: string;
6
- tokenStore: TokenStore;
3
+ export interface StartResult {
4
+ status: "pending";
5
+ userCode: string;
6
+ verificationUri: string;
7
+ verificationUriComplete: string;
8
+ expiresInSec: number;
9
+ intervalSec: number;
7
10
  }
8
- export interface AccountRegisterResult {
11
+ export type PollResult = {
9
12
  status: "registered";
10
- authUrl: string;
11
13
  graphUserId: string;
12
14
  scopes: string[];
13
15
  tokenExpSec: number;
14
- }
16
+ } | {
17
+ status: "pending";
18
+ intervalSec: number;
19
+ } | {
20
+ status: "expired";
21
+ message?: string;
22
+ } | {
23
+ status: "denied";
24
+ };
25
+ /**
26
+ * Start the device-code flow: request a code, persist a pending entry, and
27
+ * surface the user code + verification URL. The `devicecode-issued` line is
28
+ * logged BEFORE returning so the code is observable even if the caller drops
29
+ * the result. Returns immediately — no blocking wait.
30
+ */
31
+ export declare function runAccountRegisterStart(args: {
32
+ accountId: string;
33
+ clientId: string;
34
+ tenantId: string;
35
+ pendingStore: PendingStore;
36
+ }): Promise<StartResult>;
15
37
  /**
16
- * Run the PKCE register flow end-to-end:
17
- * 1. Bind a loopback callback server, build the auth URL, return URL to operator.
18
- * 2. Wait for the callback (5-min timeout).
19
- * 3. Exchange code tokens; persist encrypted to per-account store.
20
- * 4. Fetch /me to record graphUserId for log lines.
21
- *
22
- * The MCP tool layer prints the auth URL prominently in the tool response so
23
- * the operator can paste it into the VNC browser.
38
+ * One poll of the device-code flow. On success, the unchanged path runs: fetch
39
+ * /me, persist tokens, and clear the pending entry (verified by re-stat). The
40
+ * TTL is checked before hitting the network so an elapsed code names its own
41
+ * expiry rather than surfacing an opaque error.
24
42
  */
25
- export declare function runAccountRegister(args: AccountRegisterArgs): Promise<AccountRegisterResult>;
43
+ export declare function runAccountRegisterPoll(args: {
44
+ accountId: string;
45
+ clientId: string;
46
+ tenantId: string;
47
+ tokenStore: TokenStore;
48
+ pendingStore: PendingStore;
49
+ }): Promise<PollResult>;
26
50
  //# sourceMappingURL=account-register.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-register.d.ts","sourceRoot":"","sources":["../../src/tools/account-register.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAQD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAiDlG"}
1
+ {"version":3,"file":"account-register.d.ts","sourceRoot":"","sources":["../../src/tools/account-register.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AASzD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACpF;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEzB;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,WAAW,CAAC,CA2BvB;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,UAAU,CAAC,CA2EtB"}
@@ -1,31 +1,89 @@
1
- import { startPkceFlow } from "../auth/pkce-flow.js";
1
+ import { startDeviceCode, pollDeviceToken } from "../auth/device-flow.js";
2
2
  import { log } from "../lib/log.js";
3
3
  /**
4
- * Run the PKCE register flow end-to-end:
5
- * 1. Bind a loopback callback server, build the auth URL, return URL to operator.
6
- * 2. Wait for the callback (5-min timeout).
7
- * 3. Exchange code tokens; persist encrypted to per-account store.
8
- * 4. Fetch /me to record graphUserId for log lines.
9
- *
10
- * The MCP tool layer prints the auth URL prominently in the tool response so
11
- * the operator can paste it into the VNC browser.
4
+ * Start the device-code flow: request a code, persist a pending entry, and
5
+ * surface the user code + verification URL. The `devicecode-issued` line is
6
+ * logged BEFORE returning so the code is observable even if the caller drops
7
+ * the result. Returns immediately no blocking wait.
12
8
  */
13
- export async function runAccountRegister(args) {
14
- const flow = await startPkceFlow({
15
- clientId: args.clientId,
16
- tenantId: args.tenantId,
17
- accountId: args.accountId,
9
+ export async function runAccountRegisterStart(args) {
10
+ const start = await startDeviceCode({ clientId: args.clientId, tenantId: args.tenantId });
11
+ const now = Date.now();
12
+ args.pendingStore.write({
13
+ deviceCode: start.deviceCode,
14
+ scopes: start.scopes,
15
+ intervalSec: start.intervalSec,
16
+ expiresAtMs: now + start.expiresInSec * 1000,
17
+ issuedAtMs: now,
18
18
  });
19
- process.stderr.write(`[outlook-mcp] OPERATOR ACTION: open this URL in the VNC browser to authorize Outlook for account=${args.accountId}:\n${flow.authUrl}\n`);
20
- const { tokenResponse, scopes } = await flow.result;
21
- // Fetch /me with the raw access token directly — bypasses TokenStore so we
22
- // can persist a single, complete blob (with graphUserId) in one write. If
23
- // /me fails, no tokens hit disk and the operator simply re-runs register.
24
- const meResp = await fetch("https://graph.microsoft.com/v1.0/me?$select=id,mail,userPrincipalName", {
25
- headers: { Authorization: `Bearer ${tokenResponse.access_token}` },
19
+ log({
20
+ event: "devicecode-issued",
21
+ account: args.accountId,
22
+ userCode: start.userCode,
23
+ verificationUri: start.verificationUri,
24
+ expiresSec: start.expiresInSec,
25
+ intervalSec: start.intervalSec,
26
26
  });
27
+ log({ event: "pending-store-census", account: args.accountId, live: args.pendingStore.census() });
28
+ return {
29
+ status: "pending",
30
+ userCode: start.userCode,
31
+ verificationUri: start.verificationUri,
32
+ verificationUriComplete: start.verificationUriComplete,
33
+ expiresInSec: start.expiresInSec,
34
+ intervalSec: start.intervalSec,
35
+ };
36
+ }
37
+ /**
38
+ * One poll of the device-code flow. On success, the unchanged path runs: fetch
39
+ * /me, persist tokens, and clear the pending entry (verified by re-stat). The
40
+ * TTL is checked before hitting the network so an elapsed code names its own
41
+ * expiry rather than surfacing an opaque error.
42
+ */
43
+ export async function runAccountRegisterPoll(args) {
44
+ const pending = args.pendingStore.read();
45
+ if (!pending) {
46
+ return {
47
+ status: "expired",
48
+ message: "No pending registration for this account. Run outlook-account-register to start.",
49
+ };
50
+ }
51
+ const now = Date.now();
52
+ const elapsedSec = Math.floor((now - pending.issuedAtMs) / 1000);
53
+ if (now > pending.expiresAtMs) {
54
+ log({ event: "devicecode-expired", account: args.accountId, elapsedSec });
55
+ clearPending(args);
56
+ return { status: "expired" };
57
+ }
58
+ const outcome = await pollDeviceToken({ clientId: args.clientId, tenantId: args.tenantId }, pending.deviceCode);
59
+ if (outcome.kind === "pending") {
60
+ log({ event: "devicecode-poll", account: args.accountId, status: "pending", elapsedSec });
61
+ return { status: "pending", intervalSec: pending.intervalSec };
62
+ }
63
+ if (outcome.kind === "slow_down") {
64
+ const bumped = pending.intervalSec + 5;
65
+ args.pendingStore.write({ ...pending, intervalSec: bumped });
66
+ log({ event: "devicecode-poll", account: args.accountId, status: "pending", elapsedSec, slowDown: true });
67
+ return { status: "pending", intervalSec: bumped };
68
+ }
69
+ if (outcome.kind === "expired") {
70
+ log({ event: "devicecode-expired", account: args.accountId, elapsedSec });
71
+ clearPending(args);
72
+ return { status: "expired" };
73
+ }
74
+ if (outcome.kind === "denied") {
75
+ log({ event: "devicecode-denied", account: args.accountId, elapsedSec });
76
+ clearPending(args);
77
+ return { status: "denied" };
78
+ }
79
+ // success — unchanged /me + persist path
80
+ const { tokenResponse, scopes } = outcome;
81
+ const meResp = await fetch("https://graph.microsoft.com/v1.0/me?$select=id,mail,userPrincipalName", { headers: { Authorization: `Bearer ${tokenResponse.access_token}` } });
27
82
  if (!meResp.ok) {
28
83
  const text = await meResp.text();
84
+ log({ event: "me-failed", account: args.accountId, status: meResp.status });
85
+ // The device_code is spent; drop the pending entry so it cannot leak.
86
+ clearPending(args);
29
87
  throw new Error(`Failed to fetch /me after token exchange (status=${meResp.status}): ${text}`);
30
88
  }
31
89
  const me = (await meResp.json());
@@ -39,12 +97,13 @@ export async function runAccountRegister(args) {
39
97
  scopes: scopes.join(","),
40
98
  tokenExpSec,
41
99
  });
42
- return {
43
- status: "registered",
44
- authUrl: flow.authUrl,
45
- graphUserId,
46
- scopes,
47
- tokenExpSec,
48
- };
100
+ clearPending(args);
101
+ return { status: "registered", graphUserId, scopes, tokenExpSec };
102
+ }
103
+ /** Verified clear + census on every terminal poll outcome. */
104
+ function clearPending(args) {
105
+ const verified = args.pendingStore.clearVerified();
106
+ log({ event: "pending-cleared", account: args.accountId, verified });
107
+ log({ event: "pending-store-census", account: args.accountId, live: args.pendingStore.census() });
49
108
  }
50
109
  //# sourceMappingURL=account-register.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-register.js","sourceRoot":"","sources":["../../src/tools/account-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAuBpC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAyB;IAChE,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC;QAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oGAAoG,IAAI,CAAC,SAAS,MAAM,IAAI,CAAC,OAAO,IAAI,CACzI,CAAC;IAEF,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC;IAEpD,2EAA2E;IAC3E,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,uEAAuE,EAAE;QAClG,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,aAAa,CAAC,YAAY,EAAE,EAAE;KACnE,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,oDAAoD,MAAM,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAoB,CAAC;IACpD,MAAM,WAAW,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,iBAAiB,IAAI,SAAS,CAAC;IAE1E,IAAI,CAAC,UAAU,CAAC,KAAK,CACnB,aAAa,CAAC,YAAY,EAC1B,aAAa,CAAC,aAAa,IAAI,IAAI,EACnC,aAAa,CAAC,UAAU,EACxB,EAAE,WAAW,EAAE,MAAM,EAAE,CACxB,CAAC;IAEF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,iBAAiB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxF,GAAG,CAAC;QACF,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,IAAI,CAAC,SAAS;QACvB,WAAW;QACX,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACxB,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW;QACX,MAAM;QACN,WAAW;KACZ,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"account-register.js","sourceRoot":"","sources":["../../src/tools/account-register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ export interface CalendarCancelArgs {
3
+ eventId: string;
4
+ comment?: string;
5
+ }
6
+ export interface CalendarCancelResult {
7
+ eventId: string;
8
+ mode: "cancel" | "delete";
9
+ }
10
+ /**
11
+ * Cancel an event. The mode is auto-determined from a lightweight pre-GET: an
12
+ * organiser of a meeting (has attendees) POSTs `/cancel` so attendees are
13
+ * notified; anything else (a personal appointment, or a meeting the account
14
+ * only attends) is a DELETE. The determined mode is logged and returned.
15
+ */
16
+ export declare function runCalendarCancel(config: GraphClientConfig, args: CalendarCancelArgs): Promise<CalendarCancelResult>;
17
+ //# sourceMappingURL=calendar-cancel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-cancel.d.ts","sourceRoot":"","sources":["../../src/tools/calendar-cancel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC3B;AAOD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA8C/B"}
@@ -0,0 +1,38 @@
1
+ import { callGraph, postGraph, deleteGraph } from "../lib/graph-client.js";
2
+ import { log, trunc } from "../lib/log.js";
3
+ /**
4
+ * Cancel an event. The mode is auto-determined from a lightweight pre-GET: an
5
+ * organiser of a meeting (has attendees) POSTs `/cancel` so attendees are
6
+ * notified; anything else (a personal appointment, or a meeting the account
7
+ * only attends) is a DELETE. The determined mode is logged and returned.
8
+ */
9
+ export async function runCalendarCancel(config, args) {
10
+ const eventId = args.eventId?.trim();
11
+ if (!eventId) {
12
+ throw new Error("calendar-cancel: eventId is required.");
13
+ }
14
+ const probe = await callGraph(config, (client) => client
15
+ .api(`/me/events/${encodeURIComponent(eventId)}`)
16
+ .select("isOrganizer,attendees")
17
+ .get(), { tool: "calendar-cancel" });
18
+ const isMeeting = probe.isOrganizer === true && (probe.attendees?.length ?? 0) > 0;
19
+ const mode = isMeeting ? "cancel" : "delete";
20
+ log({ event: "cal-cancel-request", account: config.accountId, eventId: trunc(eventId, 16), mode });
21
+ if (mode === "cancel") {
22
+ const { status } = await postGraph(config, `/me/events/${encodeURIComponent(eventId)}/cancel`, { Comment: args.comment ?? "" }, { tool: "calendar-cancel" });
23
+ if (status !== 202) {
24
+ log({ event: "event-cancel-failed", account: config.accountId, eventId: trunc(eventId, 16), mode, status });
25
+ throw new Error(`calendar-cancel: expected HTTP 202 from /cancel, got status=${status}.`);
26
+ }
27
+ log({ event: "event-cancelled", account: config.accountId, eventId: trunc(eventId, 16), mode, status });
28
+ return { eventId, mode };
29
+ }
30
+ const { status } = await deleteGraph(config, `/me/events/${encodeURIComponent(eventId)}`, { tool: "calendar-cancel" });
31
+ if (status !== 204) {
32
+ log({ event: "event-cancel-failed", account: config.accountId, eventId: trunc(eventId, 16), mode, status });
33
+ throw new Error(`calendar-cancel: expected HTTP 204 from delete, got status=${status}.`);
34
+ }
35
+ log({ event: "event-cancelled", account: config.accountId, eventId: trunc(eventId, 16), mode, status });
36
+ return { eventId, mode };
37
+ }
38
+ //# sourceMappingURL=calendar-cancel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-cancel.js","sourceRoot":"","sources":["../../src/tools/calendar-cancel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ export interface EventTime {
3
+ dateTime: string;
4
+ timeZone: string;
5
+ }
6
+ export interface EventAttendee {
7
+ email: string;
8
+ name?: string;
9
+ type?: "required" | "optional" | "resource";
10
+ }
11
+ /** Fields shared by create (subject/start/end required) and update (all optional). */
12
+ export interface EventInput {
13
+ subject?: string;
14
+ start?: EventTime;
15
+ end?: EventTime;
16
+ body?: string;
17
+ attendees?: EventAttendee[];
18
+ location?: string;
19
+ isOnlineMeeting?: boolean;
20
+ recurrence?: unknown;
21
+ }
22
+ export interface CalendarCreateResult {
23
+ eventId: string;
24
+ webLink: string | null;
25
+ }
26
+ /** Build a Graph event body from the supplied fields only. Unset keys are omitted. */
27
+ export declare function buildEventBody(input: EventInput): Record<string, unknown>;
28
+ export declare function runCalendarCreate(config: GraphClientConfig, args: EventInput): Promise<CalendarCreateResult>;
29
+ //# sourceMappingURL=calendar-create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-create.d.ts","sourceRoot":"","sources":["../../src/tools/calendar-create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;CAC7C;AAED,sFAAsF;AACtF,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBzE;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,oBAAoB,CAAC,CA0B/B"}
@@ -0,0 +1,50 @@
1
+ import { postGraph } from "../lib/graph-client.js";
2
+ import { log, trunc } from "../lib/log.js";
3
+ /** Build a Graph event body from the supplied fields only. Unset keys are omitted. */
4
+ export function buildEventBody(input) {
5
+ const body = {};
6
+ if (input.subject !== undefined)
7
+ body.subject = input.subject;
8
+ if (input.start !== undefined)
9
+ body.start = input.start;
10
+ if (input.end !== undefined)
11
+ body.end = input.end;
12
+ if (input.body !== undefined)
13
+ body.body = { contentType: "HTML", content: input.body };
14
+ if (input.location !== undefined)
15
+ body.location = { displayName: input.location };
16
+ if (input.attendees !== undefined) {
17
+ body.attendees = input.attendees.map((a) => ({
18
+ emailAddress: { address: a.email, name: a.name },
19
+ type: a.type ?? "required",
20
+ }));
21
+ }
22
+ if (input.isOnlineMeeting !== undefined)
23
+ body.isOnlineMeeting = input.isOnlineMeeting;
24
+ if (input.recurrence !== undefined)
25
+ body.recurrence = input.recurrence;
26
+ return body;
27
+ }
28
+ export async function runCalendarCreate(config, args) {
29
+ if (!args.subject || !args.start || !args.end) {
30
+ throw new Error("calendar-create: subject, start, and end are required.");
31
+ }
32
+ const graphBody = buildEventBody(args);
33
+ log({ event: "cal-create-request", account: config.accountId, subj: trunc(args.subject, 64) });
34
+ const { status, json } = await postGraph(config, "/me/events", graphBody, {
35
+ tool: "calendar-create",
36
+ });
37
+ const body = json;
38
+ if (status !== 201 || !body?.id) {
39
+ log({
40
+ event: "event-create-failed",
41
+ account: config.accountId,
42
+ status,
43
+ graphError: body ? "no-event-id" : "empty-body",
44
+ });
45
+ throw new Error(`calendar-create: expected HTTP 201 with an event id, got status=${status}.`);
46
+ }
47
+ log({ event: "event-created", account: config.accountId, eventId: trunc(body.id, 16), status });
48
+ return { eventId: body.id, webLink: body.webLink ?? null };
49
+ }
50
+ //# sourceMappingURL=calendar-create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-create.js","sourceRoot":"","sources":["../../src/tools/calendar-create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ import type { EventTime } from "./calendar-create.js";
3
+ export interface FreebusyArgs {
4
+ schedules: string[];
5
+ start: EventTime;
6
+ end: EventTime;
7
+ intervalMinutes?: number;
8
+ }
9
+ export interface FreebusyBusyBlock {
10
+ start: string;
11
+ end: string;
12
+ status: string;
13
+ }
14
+ export interface FreebusyEntry {
15
+ address: string;
16
+ availabilityView: string;
17
+ busy: FreebusyBusyBlock[];
18
+ error: string | null;
19
+ }
20
+ export interface FreebusyResult {
21
+ requested: number;
22
+ resolved: number;
23
+ availability: FreebusyEntry[];
24
+ }
25
+ /**
26
+ * Query free/busy for one or more addresses (POST /me/calendar/getSchedule).
27
+ * Graph returns one entry per requested address; an address it cannot resolve
28
+ * (bad address, no permission) comes back with an `error` and an empty
29
+ * availabilityView rather than being omitted. `resolved` counts only the
30
+ * error-free entries, so `resolved < requested` is the partial-result signal
31
+ * and each failed address carries its Graph error rather than reading as free.
32
+ */
33
+ export declare function runCalendarFreebusy(config: GraphClientConfig, args: FreebusyArgs): Promise<FreebusyResult>;
34
+ //# sourceMappingURL=calendar-freebusy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-freebusy.d.ts","sourceRoot":"","sources":["../../src/tools/calendar-freebusy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,SAAS,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,iBAAiB,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,aAAa,EAAE,CAAC;CAC/B;AAaD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,CAuCzB"}
@@ -0,0 +1,46 @@
1
+ import { postGraph } from "../lib/graph-client.js";
2
+ import { log } from "../lib/log.js";
3
+ /**
4
+ * Query free/busy for one or more addresses (POST /me/calendar/getSchedule).
5
+ * Graph returns one entry per requested address; an address it cannot resolve
6
+ * (bad address, no permission) comes back with an `error` and an empty
7
+ * availabilityView rather than being omitted. `resolved` counts only the
8
+ * error-free entries, so `resolved < requested` is the partial-result signal
9
+ * and each failed address carries its Graph error rather than reading as free.
10
+ */
11
+ export async function runCalendarFreebusy(config, args) {
12
+ const schedules = args.schedules?.filter((s) => s && s.trim().length > 0) ?? [];
13
+ if (schedules.length === 0) {
14
+ throw new Error("calendar-freebusy: at least one schedule address is required.");
15
+ }
16
+ const requested = schedules.length;
17
+ log({ event: "freebusy-request", account: config.accountId, requested });
18
+ const graphBody = {
19
+ schedules,
20
+ startTime: args.start,
21
+ endTime: args.end,
22
+ availabilityViewInterval: args.intervalMinutes ?? 60,
23
+ };
24
+ const { status, json } = await postGraph(config, "/me/calendar/getSchedule", graphBody, {
25
+ tool: "calendar-freebusy",
26
+ });
27
+ if (status !== 200) {
28
+ log({ event: "freebusy-failed", account: config.accountId, requested, status });
29
+ throw new Error(`calendar-freebusy: expected HTTP 200, got status=${status}.`);
30
+ }
31
+ const rows = json?.value ?? [];
32
+ const availability = rows.map((row) => ({
33
+ address: row.scheduleId ?? "",
34
+ availabilityView: row.availabilityView ?? "",
35
+ busy: (row.scheduleItems ?? []).map((item) => ({
36
+ start: item.start?.dateTime ?? "",
37
+ end: item.end?.dateTime ?? "",
38
+ status: item.status ?? "unknown",
39
+ })),
40
+ error: row.error ? (row.error.message ?? row.error.responseCode ?? "unresolved") : null,
41
+ }));
42
+ const resolved = availability.filter((entry) => entry.error === null).length;
43
+ log({ event: "freebusy-result", account: config.accountId, requested, resolved });
44
+ return { requested, resolved, availability };
45
+ }
46
+ //# sourceMappingURL=calendar-freebusy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-freebusy.js","sourceRoot":"","sources":["../../src/tools/calendar-freebusy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAwCpC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAyB,EACzB,IAAkB;IAElB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;IACnC,GAAG,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAEzE,MAAM,SAAS,GAAG;QAChB,SAAS;QACT,SAAS,EAAE,IAAI,CAAC,KAAK;QACrB,OAAO,EAAE,IAAI,CAAC,GAAG;QACjB,wBAAwB,EAAE,IAAI,CAAC,eAAe,IAAI,EAAE;KACrD,CAAC;IAEF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,0BAA0B,EAAE,SAAS,EAAE;QACtF,IAAI,EAAE,mBAAmB;KAC1B,CAAC,CAAC;IAEH,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,GAAG,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAChF,MAAM,IAAI,KAAK,CAAC,oDAAoD,MAAM,GAAG,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,IAAI,GAAI,IAAoD,EAAE,KAAK,IAAI,EAAE,CAAC;IAChF,MAAM,YAAY,GAAoB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACvD,OAAO,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE;QAC7B,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,IAAI,EAAE;QAC5C,IAAI,EAAE,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC7C,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE;YACjC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,IAAI,EAAE;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS;SACjC,CAAC,CAAC;QACH,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI;KACxF,CAAC,CAAC,CAAC;IACJ,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;IAE7E,GAAG,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ export type RespondAction = "accept" | "decline" | "tentative";
3
+ export interface CalendarRespondArgs {
4
+ eventId: string;
5
+ action: RespondAction;
6
+ comment?: string;
7
+ sendResponse?: boolean;
8
+ }
9
+ export interface CalendarRespondResult {
10
+ eventId: string;
11
+ action: RespondAction;
12
+ }
13
+ /** Respond to a meeting invite: accept, decline, or tentatively accept. */
14
+ export declare function runCalendarRespond(config: GraphClientConfig, args: CalendarRespondArgs): Promise<CalendarRespondResult>;
15
+ //# sourceMappingURL=calendar-respond.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-respond.d.ts","sourceRoot":"","sources":["../../src/tools/calendar-respond.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;AAQ/D,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,2EAA2E;AAC3E,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,qBAAqB,CAAC,CA0BhC"}
@@ -0,0 +1,27 @@
1
+ import { postGraph } from "../lib/graph-client.js";
2
+ import { log, trunc } from "../lib/log.js";
3
+ const ENDPOINT = {
4
+ accept: "accept",
5
+ decline: "decline",
6
+ tentative: "tentativelyAccept",
7
+ };
8
+ /** Respond to a meeting invite: accept, decline, or tentatively accept. */
9
+ export async function runCalendarRespond(config, args) {
10
+ const eventId = args.eventId?.trim();
11
+ if (!eventId) {
12
+ throw new Error("calendar-respond: eventId is required.");
13
+ }
14
+ const endpoint = ENDPOINT[args.action];
15
+ if (!endpoint) {
16
+ throw new Error(`calendar-respond: unknown action "${args.action}".`);
17
+ }
18
+ log({ event: "cal-respond-request", account: config.accountId, eventId: trunc(eventId, 16), action: args.action });
19
+ const { status } = await postGraph(config, `/me/events/${encodeURIComponent(eventId)}/${endpoint}`, { Comment: args.comment ?? "", SendResponse: args.sendResponse ?? true }, { tool: "calendar-respond" });
20
+ if (status !== 202) {
21
+ log({ event: "event-respond-failed", account: config.accountId, eventId: trunc(eventId, 16), action: args.action, status });
22
+ throw new Error(`calendar-respond: expected HTTP 202, got status=${status}.`);
23
+ }
24
+ log({ event: "event-responded", account: config.accountId, eventId: trunc(eventId, 16), action: args.action, status });
25
+ return { eventId, action: args.action };
26
+ }
27
+ //# sourceMappingURL=calendar-respond.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-respond.js","sourceRoot":"","sources":["../../src/tools/calendar-respond.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAI3C,MAAM,QAAQ,GAAkC;IAC9C,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,mBAAmB;CAC/B,CAAC;AAcF,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAyB,EACzB,IAAyB;IAEzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IACxE,CAAC;IAED,GAAG,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAEnH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,MAAM,EACN,cAAc,kBAAkB,CAAC,OAAO,CAAC,IAAI,QAAQ,EAAE,EACvD,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,EACxE,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAC7B,CAAC;IAEF,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,GAAG,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5H,MAAM,IAAI,KAAK,CAAC,mDAAmD,MAAM,GAAG,CAAC,CAAC;IAChF,CAAC;IAED,GAAG,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { GraphClientConfig } from "../lib/graph-client.js";
2
+ import { type EventInput } from "./calendar-create.js";
3
+ export interface CalendarUpdateArgs extends EventInput {
4
+ eventId: string;
5
+ }
6
+ export interface CalendarUpdateResult {
7
+ eventId: string;
8
+ updated: true;
9
+ }
10
+ export declare function runCalendarUpdate(config: GraphClientConfig, args: CalendarUpdateArgs): Promise<CalendarUpdateResult>;
11
+ //# sourceMappingURL=calendar-update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-update.d.ts","sourceRoot":"","sources":["../../src/tools/calendar-update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvE,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;CACf;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,oBAAoB,CAAC,CAuB/B"}
@@ -0,0 +1,20 @@
1
+ import { patchGraph } from "../lib/graph-client.js";
2
+ import { log, trunc } from "../lib/log.js";
3
+ import { buildEventBody } from "./calendar-create.js";
4
+ export async function runCalendarUpdate(config, args) {
5
+ const eventId = args.eventId?.trim();
6
+ if (!eventId) {
7
+ throw new Error("calendar-update: eventId is required.");
8
+ }
9
+ const { eventId: _drop, ...fields } = args;
10
+ const graphBody = buildEventBody(fields);
11
+ log({ event: "cal-update-request", account: config.accountId, eventId: trunc(eventId, 16) });
12
+ const { status } = await patchGraph(config, `/me/events/${encodeURIComponent(eventId)}`, graphBody, { tool: "calendar-update" });
13
+ if (status !== 200) {
14
+ log({ event: "event-update-failed", account: config.accountId, eventId: trunc(eventId, 16), status });
15
+ throw new Error(`calendar-update: expected HTTP 200, got status=${status}.`);
16
+ }
17
+ log({ event: "event-updated", account: config.accountId, eventId: trunc(eventId, 16), status });
18
+ return { eventId, updated: true };
19
+ }
20
+ //# sourceMappingURL=calendar-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-update.js","sourceRoot":"","sources":["../../src/tools/calendar-update.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAmB,MAAM,sBAAsB,CAAC;AAWvE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAyB,EACzB,IAAwB;IAExB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3C,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAE7F,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,UAAU,CACjC,MAAM,EACN,cAAc,kBAAkB,CAAC,OAAO,CAAC,EAAE,EAC3C,SAAS,EACT,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAC5B,CAAC;IAEF,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,GAAG,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACtG,MAAM,IAAI,KAAK,CAAC,kDAAkD,MAAM,GAAG,CAAC,CAAC;IAC/E,CAAC;IAED,GAAG,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAChG,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACpC,CAAC"}