@rubytech/create-maxy-code 0.1.416 → 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 (204) 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 +1 -1
  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 +5 -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.js +105 -0
  48. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.js.map +1 -1
  49. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.d.ts +2 -0
  50. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.d.ts.map +1 -0
  51. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.js +78 -0
  52. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.js.map +1 -0
  53. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-tool-account.test.js +2 -2
  54. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-tool-account.test.js.map +1 -1
  55. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts +0 -5
  56. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
  57. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +2 -12
  58. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  59. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts +1 -0
  60. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
  61. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +106 -10
  62. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  63. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  64. package/payload/platform/plugins/outlook/PLUGIN.md +40 -7
  65. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.d.ts +2 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.d.ts.map +1 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js +137 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js.map +1 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.d.ts +2 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.d.ts.map +1 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js +186 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js.map +1 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.d.ts +2 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.d.ts.map +1 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js +110 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js.map +1 -0
  77. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.d.ts +2 -0
  78. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.d.ts.map +1 -0
  79. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.js +108 -0
  80. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.js.map +1 -0
  81. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js +13 -0
  82. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js.map +1 -1
  83. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.d.ts +2 -0
  84. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.d.ts.map +1 -0
  85. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.js +32 -0
  86. package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.js.map +1 -0
  87. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.d.ts +2 -0
  88. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.d.ts.map +1 -0
  89. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.js +67 -0
  90. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.js.map +1 -0
  91. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js +7 -5
  92. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js.map +1 -1
  93. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.d.ts +2 -0
  94. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.d.ts.map +1 -0
  95. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.js +141 -0
  96. package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.js.map +1 -0
  97. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts +69 -0
  98. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts.map +1 -0
  99. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js +129 -0
  100. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js.map +1 -0
  101. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.d.ts +39 -0
  102. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.d.ts.map +1 -0
  103. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.js +101 -0
  104. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.js.map +1 -0
  105. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.d.ts.map +1 -1
  106. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js +3 -2
  107. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js.map +1 -1
  108. package/payload/platform/plugins/outlook/mcp/dist/index.js +187 -5
  109. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  110. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +34 -1
  111. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -1
  112. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +96 -7
  113. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
  114. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +31 -0
  115. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -0
  116. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +30 -0
  117. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -0
  118. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts +41 -17
  119. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts.map +1 -1
  120. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js +87 -28
  121. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js.map +1 -1
  122. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.d.ts +17 -0
  123. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.d.ts.map +1 -0
  124. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.js +38 -0
  125. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.js.map +1 -0
  126. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts +29 -0
  127. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts.map +1 -0
  128. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js +50 -0
  129. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js.map +1 -0
  130. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.d.ts +34 -0
  131. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.d.ts.map +1 -0
  132. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.js +46 -0
  133. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.js.map +1 -0
  134. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.d.ts +15 -0
  135. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.d.ts.map +1 -0
  136. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.js +27 -0
  137. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.js.map +1 -0
  138. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.d.ts +11 -0
  139. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.d.ts.map +1 -0
  140. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.js +20 -0
  141. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.js.map +1 -0
  142. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts +17 -0
  143. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts.map +1 -0
  144. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js +26 -0
  145. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js.map +1 -0
  146. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +11 -0
  147. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -0
  148. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +26 -0
  149. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -0
  150. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts +14 -0
  151. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -0
  152. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +26 -0
  153. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -0
  154. package/payload/platform/plugins/outlook/mcp/scripts/verify-doc-impl.sh +2 -2
  155. package/payload/platform/plugins/outlook/references/auth.md +51 -54
  156. package/payload/platform/plugins/outlook/references/graph-surfaces.md +97 -4
  157. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +34 -9
  158. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  159. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +9 -0
  160. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  161. package/payload/platform/services/claude-session-manager/dist/config.d.ts +18 -0
  162. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  163. package/payload/platform/services/claude-session-manager/dist/config.js +16 -0
  164. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  165. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  166. package/payload/platform/services/claude-session-manager/dist/http-server.js +7 -2
  167. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  168. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  169. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +7 -2
  170. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  171. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  172. package/payload/server/public/assets/{AdminLoginScreens-CBlE6FB4.js → AdminLoginScreens-CBTx7ZPK.js} +1 -1
  173. package/payload/server/public/assets/{AdminShell-d1WQ3lLu.js → AdminShell-DPHUeXea.js} +1 -1
  174. package/payload/server/public/assets/{Checkbox-B0pbYJDQ.js → Checkbox-BHTxekRB.js} +1 -1
  175. package/payload/server/public/assets/{Transcript-CYaAPBFX.js → Transcript-5kLbBInN.js} +1 -1
  176. package/payload/server/public/assets/{admin-CVh9HO-f.js → admin-BWCLE32N.js} +1 -1
  177. package/payload/server/public/assets/{browser-C4f_D4Ih.js → browser-CRvCPsvV.js} +1 -1
  178. package/payload/server/public/assets/{calendar-WUxQ4fVo.js → calendar-BI-kd-QP.js} +1 -1
  179. package/payload/server/public/assets/chat-DFy8hb1y.js +1 -0
  180. package/payload/server/public/assets/chevron-left-Bggm5B5U.js +1 -0
  181. package/payload/server/public/assets/data-HvZ69Ya1.js +1 -0
  182. package/payload/server/public/assets/{graph-BNXE6mKP.js → graph-BFSyW_5i.js} +1 -1
  183. package/payload/server/public/assets/{graph-labels-Csnovm_c.js → graph-labels-DEjD_qJh.js} +1 -1
  184. package/payload/server/public/assets/{maximize-2-WRUJsg5n.js → maximize-2-BcMJNeCB.js} +1 -1
  185. package/payload/server/public/assets/{operator-CXtygMh6.js → operator-Dtvm9ero.js} +1 -1
  186. package/payload/server/public/assets/{page-DjpQp_ir.js → page-C_pm3hl3.js} +1 -1
  187. package/payload/server/public/assets/{page-IQDLdebG.js → page-TXi9dmaB.js} +1 -1
  188. package/payload/server/public/assets/{public-DSeYu61E.js → public-DBx3U0r8.js} +1 -1
  189. package/payload/server/public/assets/{rotate-ccw-BayMWwfc.js → rotate-ccw-8ti3QkeY.js} +1 -1
  190. package/payload/server/public/assets/useSubAccountSwitcher-BUvlETHN.css +1 -0
  191. package/payload/server/public/assets/{useSubAccountSwitcher-C9aLg8yI.js → useSubAccountSwitcher-Bc5dOBdI.js} +1 -1
  192. package/payload/server/public/browser.html +4 -4
  193. package/payload/server/public/calendar.html +5 -5
  194. package/payload/server/public/chat.html +9 -9
  195. package/payload/server/public/data.html +8 -8
  196. package/payload/server/public/graph.html +9 -9
  197. package/payload/server/public/index.html +11 -11
  198. package/payload/server/public/operator.html +11 -11
  199. package/payload/server/public/public.html +9 -9
  200. package/payload/server/server.js +8 -2
  201. package/payload/server/public/assets/chat-NJ2HXhOf.js +0 -1
  202. package/payload/server/public/assets/chevron-left-Da-iZGi_.js +0 -1
  203. package/payload/server/public/assets/data-ZUdT44Ba.js +0 -1
  204. package/payload/server/public/assets/useSubAccountSwitcher-CRZfyJXR.css +0 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "outlook",
3
- "description": "Microsoft 365 / Outlook.com via Microsoft Graph (read-only first cut). Per-account OAuth Auth Code + PKCE; no client secret. Tools — outlook-account-register: PKCE register; outlook-mail-list / outlook-mail-search: inbox; outlook-calendar-list / outlook-calendar-event: calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count.",
3
+ "description": "Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read + draft + send; contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox; outlook-mail-send / outlook-draft / outlook-draft-send: compose and send; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count.",
4
4
  "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "Rubytech LLC"
@@ -1,22 +1,49 @@
1
1
  ---
2
2
  name: outlook
3
- description: Microsoft 365 / Outlook.com via Microsoft Graph (read-only first cut). Per-account OAuth Auth Code + PKCE; no client secret. Tools — outlook-account-register: PKCE register; outlook-mail-list / outlook-mail-search: inbox; outlook-calendar-list / outlook-calendar-event: calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count.
3
+ description: Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read + draft + send; contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox; outlook-mail-send / outlook-draft / outlook-draft-send: compose and send; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count.
4
4
  tools:
5
5
  - name: outlook-account-register
6
6
  publicAllowlist: false
7
7
  adminAllowlist: false
8
+ - name: outlook-account-register-poll
9
+ publicAllowlist: false
10
+ adminAllowlist: false
8
11
  - name: outlook-mail-list
9
12
  publicAllowlist: false
10
13
  adminAllowlist: false
11
14
  - name: outlook-mail-search
12
15
  publicAllowlist: false
13
16
  adminAllowlist: false
17
+ - name: outlook-mail-send
18
+ publicAllowlist: false
19
+ adminAllowlist: false
20
+ - name: outlook-draft
21
+ publicAllowlist: false
22
+ adminAllowlist: false
23
+ - name: outlook-draft-send
24
+ publicAllowlist: false
25
+ adminAllowlist: false
14
26
  - name: outlook-calendar-list
15
27
  publicAllowlist: false
16
28
  adminAllowlist: false
17
29
  - name: outlook-calendar-event
18
30
  publicAllowlist: false
19
31
  adminAllowlist: false
32
+ - name: outlook-calendar-create
33
+ publicAllowlist: false
34
+ adminAllowlist: false
35
+ - name: outlook-calendar-update
36
+ publicAllowlist: false
37
+ adminAllowlist: false
38
+ - name: outlook-calendar-cancel
39
+ publicAllowlist: false
40
+ adminAllowlist: false
41
+ - name: outlook-calendar-respond
42
+ publicAllowlist: false
43
+ adminAllowlist: false
44
+ - name: outlook-calendar-freebusy
45
+ publicAllowlist: false
46
+ adminAllowlist: false
20
47
  - name: outlook-contacts-list
21
48
  publicAllowlist: false
22
49
  adminAllowlist: false
@@ -37,24 +64,30 @@ mcp:
37
64
  PLATFORM_ROOT: ${PLATFORM_ROOT}
38
65
  ACCOUNT_ID: ${ACCOUNT_ID}
39
66
  SESSION_ID: ${SESSION_ID}
67
+ OUTLOOK_CLIENT_ID: ${OUTLOOK_CLIENT_ID}
68
+ OUTLOOK_TENANT_ID: ${OUTLOOK_TENANT_ID}
40
69
  mcp-manifest: auto
41
70
  ---
42
71
 
43
72
  # Outlook
44
73
 
45
- Read-only Microsoft Graph access for Outlook.com / Microsoft 365 mailboxes. Admin agent only — public agent surface is explicitly excluded.
74
+ Microsoft Graph access for Outlook.com / Microsoft 365 mailboxes. Mail is read, draft, and send; contacts are read-only; calendar is read + control. Admin agent only — public agent surface is explicitly excluded.
46
75
 
47
76
  ## Capabilities
48
77
 
49
- - **Register:** `outlook-account-register` — initiates OAuth Auth Code + PKCE flow against the operator's Entra app. Returns an authorization URL the operator opens in the VNC browser to consent. Tokens persist per-account, encrypted on disk (AES-256-CBC).
50
- - **Mail (read-only):** `outlook-mail-list` returns recent messages; `outlook-mail-search` runs a Graph `$search` query.
51
- - **Calendar (read-only):** `outlook-calendar-list` returns events in a future range; `outlook-calendar-event` returns a single event with full body + attendees.
78
+ - **Register:** `outlook-account-register` — starts the OAuth device-code flow against the brand's Entra app and returns a user code + verification URL immediately. The operator opens `microsoft.com/devicelogin` on any device, enters the code, and consents. `outlook-account-register-poll` completes registration — one check per call. Tokens persist per-account, encrypted on disk (AES-256-CBC).
79
+ - **Mail (read):** `outlook-mail-list` returns recent messages; `outlook-mail-search` runs a Graph `$search` query.
80
+ - **Mail (send / draft):** `outlook-mail-send` sends via `POST /me/sendMail` (success asserted on Graph 202); `outlook-draft` creates a draft and returns its id; `outlook-draft-send` sends an existing draft by id. Recipients are to/cc/bcc arrays; body is HTML or plain text via `isHtml`. Requires `Mail.Send` + `Mail.ReadWrite`; a mailbox on the old read-only consent returns an actionable "re-register to grant send" signal.
81
+ - **Calendar (read + control):** `outlook-calendar-list` and `outlook-calendar-event` read events; `outlook-calendar-create` books an event; `outlook-calendar-update` reschedules or edits one; `outlook-calendar-cancel` cancels a meeting (notifying attendees when the account organises it) or deletes a personal appointment; `outlook-calendar-respond` accepts, declines, or tentatively accepts an invite; `outlook-calendar-freebusy` reports availability for one or more addresses over a window. Writes require the `Calendars.ReadWrite` consent; a mailbox on stale read-only consent returns a distinct signal naming the scope and `outlook-account-register`.
52
82
  - **Contacts (read-only):** `outlook-contacts-list` returns contacts.
53
83
  - **Health:** `outlook-mailbox-info` reports auth state, refresh-window status, and top-level folder count. Use this to answer "did account X auth?" without grepping logs.
54
84
 
55
85
  ## Out of scope
56
86
 
57
- - Send / draft / move / flag — write surfaces are deferred to a follow-up task.
87
+ - Mail move / flag / delete — write surfaces beyond send and draft are not implemented.
88
+ - Contacts write — read-only.
89
+ - Recurring-series occurrence editing (edit-this-occurrence) beyond whole-series create/update.
90
+ - The `scheduling` (Neo4j graph) plugin and any auto-sync between it and the Outlook calendar.
58
91
  - OneDrive, Files, Sites — separate plugin; different endpoints.
59
92
  - Push notifications via `/subscriptions` — first cut polls.
60
93
  - On-premises Exchange — Microsoft Graph deprecated hybrid REST 2023-07. The plugin detects on-prem mailboxes and routes the operator to the IMAP path (`email` plugin).
@@ -64,7 +97,7 @@ Read-only Microsoft Graph access for Outlook.com / Microsoft 365 mailboxes. Admi
64
97
 
65
98
  | Reference | Topics |
66
99
  |-----------|--------|
67
- | [auth.md](references/auth.md) | Entra app registration, PKCE flow, vendored upstream SHA, re-vendor procedure |
100
+ | [auth.md](references/auth.md) | Entra app registration, device-code flow, public-client requirement |
68
101
  | [graph-surfaces.md](references/graph-surfaces.md) | Graph endpoint and response shape per tool |
69
102
 
70
103
  ## Skills
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=account-register.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-register.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/account-register.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,137 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, rmSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { PendingStore } from "../auth/pending-store.js";
7
+ import { TokenStore } from "../auth/token-store.js";
8
+ import { runAccountRegisterStart, runAccountRegisterPoll } from "../tools/account-register.js";
9
+ const mk = () => {
10
+ const dir = mkdtempSync(join(tmpdir(), "outlook-reg-"));
11
+ return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
12
+ };
13
+ function withFetch(seq) {
14
+ const original = globalThis.fetch;
15
+ let i = 0;
16
+ globalThis.fetch = (async () => (seq[Math.min(i++, seq.length - 1)])());
17
+ return () => { globalThis.fetch = original; };
18
+ }
19
+ function captureStderr() {
20
+ const chunks = [];
21
+ const orig = process.stderr.write.bind(process.stderr);
22
+ process.stderr.write = ((s) => {
23
+ chunks.push(String(s));
24
+ return true;
25
+ });
26
+ return { text: () => chunks.join(""), restore: () => { process.stderr.write = orig; } };
27
+ }
28
+ const json = (o, status = 200) => new Response(JSON.stringify(o), { status, headers: { "Content-Type": "application/json" } });
29
+ const cfg = { clientId: "cid", tenantId: "common" };
30
+ const pendingEntry = () => ({
31
+ deviceCode: "DEV",
32
+ scopes: ["Mail.Read"],
33
+ intervalSec: 5,
34
+ expiresAtMs: Date.now() + 900_000,
35
+ issuedAtMs: Date.now(),
36
+ });
37
+ test("start writes pending entry and logs devicecode-issued before returning", async () => {
38
+ const { dir, cleanup } = mk();
39
+ const restore = withFetch([() => json({
40
+ device_code: "DEV", user_code: "WXYZ-1234",
41
+ verification_uri: "https://microsoft.com/devicelogin", expires_in: 900, interval: 5,
42
+ })]);
43
+ const cap = captureStderr();
44
+ try {
45
+ const ps = new PendingStore("acct-1", dir);
46
+ const res = await runAccountRegisterStart({ accountId: "acct-1", ...cfg, pendingStore: ps });
47
+ cap.restore();
48
+ assert.equal(res.status, "pending");
49
+ assert.equal(res.userCode, "WXYZ-1234");
50
+ assert.equal(ps.read()?.deviceCode, "DEV");
51
+ assert.match(cap.text(), /devicecode-issued/);
52
+ assert.match(cap.text(), /userCode=WXYZ-1234/);
53
+ assert.match(cap.text(), /pending-store-census account=acct-1 live=1/);
54
+ }
55
+ finally {
56
+ cap.restore();
57
+ restore();
58
+ cleanup();
59
+ }
60
+ });
61
+ test("poll authorization_pending -> pending", async () => {
62
+ const { dir, cleanup } = mk();
63
+ const ps = new PendingStore("acct-2", dir);
64
+ ps.write(pendingEntry());
65
+ const restore = withFetch([() => json({ error: "authorization_pending" }, 400)]);
66
+ try {
67
+ const out = await runAccountRegisterPoll({ accountId: "acct-2", ...cfg, tokenStore: new TokenStore("acct-2", dir), pendingStore: ps });
68
+ assert.equal(out.status, "pending");
69
+ }
70
+ finally {
71
+ restore();
72
+ cleanup();
73
+ }
74
+ });
75
+ test("poll success -> registered, tokens persisted, pending cleared", async () => {
76
+ const { dir, cleanup } = mk();
77
+ const ps = new PendingStore("acct-3", dir);
78
+ ps.write(pendingEntry());
79
+ const ts = new TokenStore("acct-3", dir);
80
+ const restore = withFetch([
81
+ () => json({ access_token: "AT", refresh_token: "RT", expires_in: 3600, token_type: "Bearer", scope: "offline_access User.Read Mail.ReadWrite Mail.Send Calendars.ReadWrite Contacts.Read" }),
82
+ () => json({ id: "graph-123", mail: "a@b.com" }),
83
+ ]);
84
+ try {
85
+ const out = await runAccountRegisterPoll({ accountId: "acct-3", ...cfg, tokenStore: ts, pendingStore: ps });
86
+ assert.equal(out.status, "registered");
87
+ if (out.status === "registered")
88
+ assert.equal(out.graphUserId, "graph-123");
89
+ assert.equal(ts.read()?.accessToken, "AT");
90
+ assert.equal(ps.census(), 0);
91
+ }
92
+ finally {
93
+ restore();
94
+ cleanup();
95
+ }
96
+ });
97
+ test("poll expired_token -> expired and pending cleared", async () => {
98
+ const { dir, cleanup } = mk();
99
+ const ps = new PendingStore("acct-4", dir);
100
+ ps.write(pendingEntry());
101
+ const restore = withFetch([() => json({ error: "expired_token" }, 400)]);
102
+ try {
103
+ const out = await runAccountRegisterPoll({ accountId: "acct-4", ...cfg, tokenStore: new TokenStore("acct-4", dir), pendingStore: ps });
104
+ assert.equal(out.status, "expired");
105
+ assert.equal(ps.census(), 0);
106
+ }
107
+ finally {
108
+ restore();
109
+ cleanup();
110
+ }
111
+ });
112
+ test("poll access_denied -> denied and pending cleared", async () => {
113
+ const { dir, cleanup } = mk();
114
+ const ps = new PendingStore("acct-5", dir);
115
+ ps.write(pendingEntry());
116
+ const restore = withFetch([() => json({ error: "access_denied" }, 400)]);
117
+ try {
118
+ const out = await runAccountRegisterPoll({ accountId: "acct-5", ...cfg, tokenStore: new TokenStore("acct-5", dir), pendingStore: ps });
119
+ assert.equal(out.status, "denied");
120
+ assert.equal(ps.census(), 0);
121
+ }
122
+ finally {
123
+ restore();
124
+ cleanup();
125
+ }
126
+ });
127
+ test("poll with no pending entry -> expired", async () => {
128
+ const { dir, cleanup } = mk();
129
+ try {
130
+ const out = await runAccountRegisterPoll({ accountId: "acct-6", ...cfg, tokenStore: new TokenStore("acct-6", dir), pendingStore: new PendingStore("acct-6", dir) });
131
+ assert.equal(out.status, "expired");
132
+ }
133
+ finally {
134
+ cleanup();
135
+ }
136
+ });
137
+ //# sourceMappingURL=account-register.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-register.test.js","sourceRoot":"","sources":["../../src/__tests__/account-register.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAE/F,MAAM,EAAE,GAAG,GAAG,EAAE;IACd,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;IACxD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/E,CAAC,CAAC;AACF,SAAS,SAAS,CAAC,GAA0B;IAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;IAClC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,UAAU,CAAC,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAiB,CAAC;IACxF,OAAO,GAAG,EAAE,GAAG,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AACD,SAAS,aAAa;IACpB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,CAAC,MAAM,CAAC,KAA2C,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE;QAC3E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAI,OAAO,CAAC,MAAM,CAAC,KAAiB,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACvG,CAAC;AACD,MAAM,IAAI,GAAG,CAAC,CAAU,EAAE,MAAM,GAAG,GAAG,EAAE,EAAE,CACxC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAC/F,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACpD,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,CAAC;IAC1B,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,CAAC,WAAW,CAAC;IACrB,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;IACjC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;CACvB,CAAC,CAAC;AAEH,IAAI,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;IACxF,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YACpC,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW;YAC1C,gBAAgB,EAAE,mCAAmC,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;SACpF,CAAC,CAAC,CAAC,CAAC;IACL,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,uBAAuB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7F,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,4CAA4C,CAAC,CAAC;IACzE,CAAC;YAAS,CAAC;QAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACvD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QACvI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;IAC/E,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,SAAS,CAAC;QACxB,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,qFAAqF,EAAE,CAAC;QAC7L,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KACjD,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5G,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACvC,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAC5E,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;IACnE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QACvI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;IAClE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QACvI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACvD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACpK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AAC1B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=calendar-write.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-write.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/calendar-write.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,186 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { TokenStore } from "../auth/token-store.js";
7
+ import { runCalendarCreate } from "../tools/calendar-create.js";
8
+ import { runCalendarUpdate } from "../tools/calendar-update.js";
9
+ import { runCalendarCancel } from "../tools/calendar-cancel.js";
10
+ import { runCalendarRespond } from "../tools/calendar-respond.js";
11
+ import { runCalendarFreebusy } from "../tools/calendar-freebusy.js";
12
+ // A config whose TokenStore already holds a fresh (non-expiring) token, so the
13
+ // SDK auth provider returns it without a refresh fetch. Only the Graph call
14
+ // itself hits the mocked fetch.
15
+ function configWithToken(accountId) {
16
+ const dir = mkdtempSync(join(tmpdir(), "outlook-cal-"));
17
+ const tokenStore = new TokenStore(accountId, dir);
18
+ tokenStore.store("access-token", "refresh-token", 3600, { scopes: ["Calendars.ReadWrite"] });
19
+ return { clientId: "test-client", tenantId: "common", accountId, tokenStore };
20
+ }
21
+ /**
22
+ * Route Graph requests to per-call responses so multi-call tools (cancel does a
23
+ * GET probe then a POST/DELETE) get the right shape at each step. `routes` is
24
+ * matched in order; the first whose `match(method, url)` returns true serves.
25
+ */
26
+ function mockGraphRouter(routes) {
27
+ const calls = [];
28
+ const original = globalThis.fetch;
29
+ globalThis.fetch = (async (input, init) => {
30
+ const req = input instanceof Request ? input : null;
31
+ const url = req ? req.url : typeof input === "string" ? input : input.toString();
32
+ if (!url.includes("graph.microsoft.com")) {
33
+ return original(input, init);
34
+ }
35
+ const method = req?.method ?? init?.method ?? "GET";
36
+ let body = null;
37
+ if (req)
38
+ body = await req.clone().text().catch(() => null);
39
+ else if (typeof init?.body === "string")
40
+ body = init.body;
41
+ calls.push({ url, method, body });
42
+ const route = routes.find((r) => r.match(method, url));
43
+ if (!route)
44
+ return new Response(null, { status: 500 });
45
+ const payload = route.body === null ? null : JSON.stringify(route.body);
46
+ const headers = route.body === null ? undefined : { "content-type": "application/json" };
47
+ return new Response(payload, { status: route.status, headers });
48
+ });
49
+ return { restore: () => { globalThis.fetch = original; }, calls };
50
+ }
51
+ function mockGraph(status, body) {
52
+ return mockGraphRouter([{ match: () => true, status, body }]);
53
+ }
54
+ const startEnd = {
55
+ start: { dateTime: "2026-07-10T09:00:00", timeZone: "Europe/London" },
56
+ end: { dateTime: "2026-07-10T10:00:00", timeZone: "Europe/London" },
57
+ };
58
+ test("calendar-create: Graph 201 + {id} → eventId + webLink; POST /me/events with HTML body", async () => {
59
+ const mock = mockGraph(201, { id: "EV1", webLink: "https://ol/EV1" });
60
+ try {
61
+ const out = await runCalendarCreate(configWithToken("acct-cc-1"), {
62
+ subject: "Sync",
63
+ body: "hello",
64
+ ...startEnd,
65
+ });
66
+ assert.deepEqual(out, { eventId: "EV1", webLink: "https://ol/EV1" });
67
+ assert.match(mock.calls[0].url, /\/me\/events$/);
68
+ assert.equal(mock.calls[0].method, "POST");
69
+ assert.match(mock.calls[0].body ?? "", /"contentType":"HTML"/);
70
+ }
71
+ finally {
72
+ mock.restore();
73
+ }
74
+ });
75
+ test("calendar-create: non-201 → throws (no-throw is not created)", async () => {
76
+ const mock = mockGraph(200, {});
77
+ try {
78
+ await assert.rejects(runCalendarCreate(configWithToken("acct-cc-2"), { subject: "S", ...startEnd }), /201/);
79
+ }
80
+ finally {
81
+ mock.restore();
82
+ }
83
+ });
84
+ test("calendar-update: Graph 200 → updated; PATCH /me/events/{id}", async () => {
85
+ const mock = mockGraph(200, { id: "EV1" });
86
+ try {
87
+ const out = await runCalendarUpdate(configWithToken("acct-cu-1"), {
88
+ eventId: "EV1",
89
+ start: { dateTime: "2026-07-10T11:00:00", timeZone: "Europe/London" },
90
+ });
91
+ assert.deepEqual(out, { eventId: "EV1", updated: true });
92
+ assert.match(mock.calls[0].url, /\/me\/events\/EV1$/);
93
+ assert.equal(mock.calls[0].method, "PATCH");
94
+ }
95
+ finally {
96
+ mock.restore();
97
+ }
98
+ });
99
+ test("calendar-cancel: organiser meeting → GET probe then POST /cancel (202) → mode cancel", async () => {
100
+ const mock = mockGraphRouter([
101
+ { match: (m) => m === "GET", status: 200, body: { isOrganizer: true, attendees: [{ email: "a@x" }] } },
102
+ { match: (m, u) => m === "POST" && /\/cancel$/.test(u), status: 202, body: null },
103
+ ]);
104
+ try {
105
+ const out = await runCalendarCancel(configWithToken("acct-cx-1"), { eventId: "EV1", comment: "moved" });
106
+ assert.deepEqual(out, { eventId: "EV1", mode: "cancel" });
107
+ assert.ok(mock.calls.some((c) => c.method === "POST" && /\/EV1\/cancel$/.test(c.url)), JSON.stringify(mock.calls));
108
+ }
109
+ finally {
110
+ mock.restore();
111
+ }
112
+ });
113
+ test("calendar-cancel: personal appointment → DELETE (204) → mode delete", async () => {
114
+ const mock = mockGraphRouter([
115
+ { match: (m) => m === "GET", status: 200, body: { isOrganizer: false, attendees: [] } },
116
+ { match: (m) => m === "DELETE", status: 204, body: null },
117
+ ]);
118
+ try {
119
+ const out = await runCalendarCancel(configWithToken("acct-cx-2"), { eventId: "EV2" });
120
+ assert.deepEqual(out, { eventId: "EV2", mode: "delete" });
121
+ assert.ok(mock.calls.some((c) => c.method === "DELETE" && /\/events\/EV2$/.test(c.url)), JSON.stringify(mock.calls));
122
+ }
123
+ finally {
124
+ mock.restore();
125
+ }
126
+ });
127
+ test("calendar-respond: tentative maps to POST /tentativelyAccept (202)", async () => {
128
+ const mock = mockGraph(202, null);
129
+ try {
130
+ const out = await runCalendarRespond(configWithToken("acct-cr-1"), { eventId: "EV1", action: "tentative" });
131
+ assert.deepEqual(out, { eventId: "EV1", action: "tentative" });
132
+ assert.match(mock.calls[0].url, /\/me\/events\/EV1\/tentativelyAccept$/);
133
+ assert.equal(mock.calls[0].method, "POST");
134
+ }
135
+ finally {
136
+ mock.restore();
137
+ }
138
+ });
139
+ test("calendar-respond: accept → POST /accept (202)", async () => {
140
+ const mock = mockGraph(202, null);
141
+ try {
142
+ const out = await runCalendarRespond(configWithToken("acct-cr-2"), { eventId: "EV1", action: "accept" });
143
+ assert.equal(out.action, "accept");
144
+ assert.match(mock.calls[0].url, /\/me\/events\/EV1\/accept$/);
145
+ }
146
+ finally {
147
+ mock.restore();
148
+ }
149
+ });
150
+ test("calendar-freebusy: one entry per address; an error entry is not counted in resolved", async () => {
151
+ const mock = mockGraph(200, {
152
+ value: [
153
+ { scheduleId: "a@x.com", availabilityView: "0", scheduleItems: [] },
154
+ {
155
+ scheduleId: "bad@nowhere.com",
156
+ availabilityView: "",
157
+ scheduleItems: [],
158
+ error: { message: "ScheduleMailboxNotFound", responseCode: "MailboxNotFound" },
159
+ },
160
+ ],
161
+ });
162
+ try {
163
+ const out = await runCalendarFreebusy(configWithToken("acct-fb-1"), {
164
+ schedules: ["a@x.com", "bad@nowhere.com"],
165
+ ...startEnd,
166
+ });
167
+ assert.equal(out.requested, 2);
168
+ assert.equal(out.resolved, 1);
169
+ assert.equal(out.availability[1].error, "ScheduleMailboxNotFound");
170
+ assert.deepEqual(out.availability[1].busy, []);
171
+ assert.match(mock.calls[0].url, /\/me\/calendar\/getSchedule$/);
172
+ }
173
+ finally {
174
+ mock.restore();
175
+ }
176
+ });
177
+ test("calendar write: Graph 403 → error names Calendars.ReadWrite + outlook-account-register", async () => {
178
+ const mock = mockGraph(403, { error: { code: "ErrorAccessDenied", message: "Access is denied." } });
179
+ try {
180
+ await assert.rejects(runCalendarCreate(configWithToken("acct-403"), { subject: "S", ...startEnd }), (err) => /Calendars\.ReadWrite/.test(err.message) && /outlook-account-register/.test(err.message));
181
+ }
182
+ finally {
183
+ mock.restore();
184
+ }
185
+ });
186
+ //# sourceMappingURL=calendar-write.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-write.test.js","sourceRoot":"","sources":["../../src/__tests__/calendar-write.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=device-flow.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/device-flow.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,110 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { readFileSync } from "node:fs";
4
+ import { fileURLToPath } from "node:url";
5
+ import { dirname, resolve } from "node:path";
6
+ import { _internals, startDeviceCode, pollDeviceToken } from "../auth/device-flow.js";
7
+ function mockFetch(handler) {
8
+ const calls = [];
9
+ const original = globalThis.fetch;
10
+ globalThis.fetch = (async (url, init) => {
11
+ const u = typeof url === "string" ? url : url instanceof URL ? url.toString() : url.url;
12
+ calls.push({ url: u, body: String(init?.body ?? "") });
13
+ return handler(u, init);
14
+ });
15
+ return { calls, restore: () => { globalThis.fetch = original; } };
16
+ }
17
+ const json = (o, status = 200) => new Response(JSON.stringify(o), { status, headers: { "Content-Type": "application/json" } });
18
+ test("startDeviceCode returns the five fields and posts client_id+scope", async () => {
19
+ const m = mockFetch(() => json({
20
+ device_code: "DEV", user_code: "ABCD-EFGH",
21
+ verification_uri: "https://microsoft.com/devicelogin",
22
+ expires_in: 900, interval: 5,
23
+ }));
24
+ try {
25
+ const s = await startDeviceCode({ clientId: "cid", tenantId: "common" });
26
+ assert.equal(s.userCode, "ABCD-EFGH");
27
+ assert.equal(s.verificationUri, "https://microsoft.com/devicelogin");
28
+ assert.equal(s.verificationUriComplete, "https://microsoft.com/devicelogin?otc=ABCD-EFGH");
29
+ assert.equal(s.expiresInSec, 900);
30
+ assert.equal(s.intervalSec, 5);
31
+ assert.equal(s.deviceCode, "DEV");
32
+ assert.match(m.calls[0].url, /oauth2\/v2\.0\/devicecode/);
33
+ assert.match(m.calls[0].body, /client_id=cid/);
34
+ assert.match(m.calls[0].body, /scope=/);
35
+ }
36
+ finally {
37
+ m.restore();
38
+ }
39
+ });
40
+ test("startDeviceCode uses verification_uri_complete when the endpoint provides it", async () => {
41
+ const m = mockFetch(() => json({
42
+ device_code: "DEV", user_code: "WXYZ",
43
+ verification_uri: "https://microsoft.com/devicelogin",
44
+ verification_uri_complete: "https://microsoft.com/devicelogin?given=1",
45
+ expires_in: 900, interval: 5,
46
+ }));
47
+ try {
48
+ const s = await startDeviceCode({ clientId: "c", tenantId: "common" });
49
+ assert.equal(s.verificationUriComplete, "https://microsoft.com/devicelogin?given=1");
50
+ }
51
+ finally {
52
+ m.restore();
53
+ }
54
+ });
55
+ test("startDeviceCode requests the full read+send scope set", () => {
56
+ assert.deepEqual([..._internals.SCOPES].sort(), ["Calendars.ReadWrite", "Contacts.Read", "Mail.ReadWrite", "Mail.Send", "User.Read", "offline_access"].sort());
57
+ });
58
+ test("pollDeviceToken maps authorization_pending -> pending", async () => {
59
+ const m = mockFetch(() => json({ error: "authorization_pending" }, 400));
60
+ try {
61
+ assert.deepEqual(await pollDeviceToken({ clientId: "c", tenantId: "common" }, "D"), { kind: "pending" });
62
+ }
63
+ finally {
64
+ m.restore();
65
+ }
66
+ });
67
+ test("pollDeviceToken maps slow_down / expired_token / access_denied", async () => {
68
+ for (const [err, kind] of [["slow_down", "slow_down"], ["expired_token", "expired"], ["access_denied", "denied"]]) {
69
+ const m = mockFetch(() => json({ error: err }, 400));
70
+ try {
71
+ assert.deepEqual(await pollDeviceToken({ clientId: "c", tenantId: "common" }, "D"), { kind });
72
+ }
73
+ finally {
74
+ m.restore();
75
+ }
76
+ }
77
+ });
78
+ test("pollDeviceToken throws on an unrecognised error", async () => {
79
+ const m = mockFetch(() => json({ error: "invalid_client" }, 400));
80
+ try {
81
+ await assert.rejects(pollDeviceToken({ clientId: "c", tenantId: "common" }, "D"), /invalid_client/);
82
+ }
83
+ finally {
84
+ m.restore();
85
+ }
86
+ });
87
+ test("pollDeviceToken 200 -> success with tokenResponse + scopes", async () => {
88
+ const m = mockFetch(() => json({
89
+ access_token: "AT", refresh_token: "RT", expires_in: 3600, token_type: "Bearer",
90
+ scope: "offline_access User.Read Mail.ReadWrite Mail.Send Calendars.ReadWrite Contacts.Read",
91
+ }));
92
+ try {
93
+ const out = await pollDeviceToken({ clientId: "c", tenantId: "common" }, "D");
94
+ assert.equal(out.kind, "success");
95
+ if (out.kind === "success") {
96
+ assert.equal(out.tokenResponse.access_token, "AT");
97
+ assert.ok(out.scopes.includes("Mail.Send"));
98
+ }
99
+ }
100
+ finally {
101
+ m.restore();
102
+ }
103
+ });
104
+ test("regression: device-flow.ts binds no HTTP server", () => {
105
+ const here = dirname(fileURLToPath(import.meta.url));
106
+ const src = readFileSync(resolve(here, "../../src/auth/device-flow.ts"), "utf8");
107
+ assert.ok(!/createServer/.test(src), "must not import/use createServer");
108
+ assert.ok(!/\.listen\(/.test(src), "must not bind a listener");
109
+ });
110
+ //# sourceMappingURL=device-flow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.test.js","sourceRoot":"","sources":["../../src/__tests__/device-flow.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=graph-client-retry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-client-retry.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/graph-client-retry.test.ts"],"names":[],"mappings":""}